1 //===-- ASTUtils.h ----------------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_ASTUTILS_H 10 #define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_ASTUTILS_H 11 12 #include "clang/Basic/ASTSourceDescriptor.h" 13 #include "clang/Sema/Lookup.h" 14 #include "clang/Sema/MultiplexExternalSemaSource.h" 15 #include "clang/Sema/Sema.h" 16 #include "clang/Sema/SemaConsumer.h" 17 #include <optional> 18 19 namespace clang { 20 21 class Module; 22 23 } // namespace clang 24 25 namespace lldb_private { 26 27 /// Wraps an ExternalASTSource into an ExternalSemaSource. Doesn't take 28 /// ownership of the provided source. 29 class ExternalASTSourceWrapper : public clang::ExternalSemaSource { 30 ExternalASTSource *m_Source; 31 32 public: ExternalASTSourceWrapper(ExternalASTSource * Source)33 ExternalASTSourceWrapper(ExternalASTSource *Source) : m_Source(Source) { 34 assert(m_Source && "Can't wrap nullptr ExternalASTSource"); 35 } 36 37 ~ExternalASTSourceWrapper() override; 38 GetExternalDecl(clang::GlobalDeclID ID)39 clang::Decl *GetExternalDecl(clang::GlobalDeclID ID) override { 40 return m_Source->GetExternalDecl(ID); 41 } 42 GetExternalSelector(uint32_t ID)43 clang::Selector GetExternalSelector(uint32_t ID) override { 44 return m_Source->GetExternalSelector(ID); 45 } 46 GetNumExternalSelectors()47 uint32_t GetNumExternalSelectors() override { 48 return m_Source->GetNumExternalSelectors(); 49 } 50 GetExternalDeclStmt(uint64_t Offset)51 clang::Stmt *GetExternalDeclStmt(uint64_t Offset) override { 52 return m_Source->GetExternalDeclStmt(Offset); 53 } 54 55 clang::CXXCtorInitializer ** GetExternalCXXCtorInitializers(uint64_t Offset)56 GetExternalCXXCtorInitializers(uint64_t Offset) override { 57 return m_Source->GetExternalCXXCtorInitializers(Offset); 58 } 59 60 clang::CXXBaseSpecifier * GetExternalCXXBaseSpecifiers(uint64_t Offset)61 GetExternalCXXBaseSpecifiers(uint64_t Offset) override { 62 return m_Source->GetExternalCXXBaseSpecifiers(Offset); 63 } 64 updateOutOfDateIdentifier(const clang::IdentifierInfo & II)65 void updateOutOfDateIdentifier(const clang::IdentifierInfo &II) override { 66 m_Source->updateOutOfDateIdentifier(II); 67 } 68 FindExternalVisibleDeclsByName(const clang::DeclContext * DC,clang::DeclarationName Name)69 bool FindExternalVisibleDeclsByName(const clang::DeclContext *DC, 70 clang::DeclarationName Name) override { 71 return m_Source->FindExternalVisibleDeclsByName(DC, Name); 72 } 73 completeVisibleDeclsMap(const clang::DeclContext * DC)74 void completeVisibleDeclsMap(const clang::DeclContext *DC) override { 75 m_Source->completeVisibleDeclsMap(DC); 76 } 77 getModule(unsigned ID)78 clang::Module *getModule(unsigned ID) override { 79 return m_Source->getModule(ID); 80 } 81 82 std::optional<clang::ASTSourceDescriptor> getSourceDescriptor(unsigned ID)83 getSourceDescriptor(unsigned ID) override { 84 return m_Source->getSourceDescriptor(ID); 85 } 86 hasExternalDefinitions(const clang::Decl * D)87 ExtKind hasExternalDefinitions(const clang::Decl *D) override { 88 return m_Source->hasExternalDefinitions(D); 89 } 90 FindExternalLexicalDecls(const clang::DeclContext * DC,llvm::function_ref<bool (clang::Decl::Kind)> IsKindWeWant,llvm::SmallVectorImpl<clang::Decl * > & Result)91 void FindExternalLexicalDecls( 92 const clang::DeclContext *DC, 93 llvm::function_ref<bool(clang::Decl::Kind)> IsKindWeWant, 94 llvm::SmallVectorImpl<clang::Decl *> &Result) override { 95 m_Source->FindExternalLexicalDecls(DC, IsKindWeWant, Result); 96 } 97 98 void FindFileRegionDecls(clang::FileID File,unsigned Offset,unsigned Length,llvm::SmallVectorImpl<clang::Decl * > & Decls)99 FindFileRegionDecls(clang::FileID File, unsigned Offset, unsigned Length, 100 llvm::SmallVectorImpl<clang::Decl *> &Decls) override { 101 m_Source->FindFileRegionDecls(File, Offset, Length, Decls); 102 } 103 CompleteRedeclChain(const clang::Decl * D)104 void CompleteRedeclChain(const clang::Decl *D) override { 105 m_Source->CompleteRedeclChain(D); 106 } 107 CompleteType(clang::TagDecl * Tag)108 void CompleteType(clang::TagDecl *Tag) override { 109 m_Source->CompleteType(Tag); 110 } 111 CompleteType(clang::ObjCInterfaceDecl * Class)112 void CompleteType(clang::ObjCInterfaceDecl *Class) override { 113 m_Source->CompleteType(Class); 114 } 115 ReadComments()116 void ReadComments() override { m_Source->ReadComments(); } 117 StartedDeserializing()118 void StartedDeserializing() override { m_Source->StartedDeserializing(); } 119 FinishedDeserializing()120 void FinishedDeserializing() override { m_Source->FinishedDeserializing(); } 121 StartTranslationUnit(clang::ASTConsumer * Consumer)122 void StartTranslationUnit(clang::ASTConsumer *Consumer) override { 123 m_Source->StartTranslationUnit(Consumer); 124 } 125 126 void PrintStats() override; 127 layoutRecordType(const clang::RecordDecl * Record,uint64_t & Size,uint64_t & Alignment,llvm::DenseMap<const clang::FieldDecl *,uint64_t> & FieldOffsets,llvm::DenseMap<const clang::CXXRecordDecl *,clang::CharUnits> & BaseOffsets,llvm::DenseMap<const clang::CXXRecordDecl *,clang::CharUnits> & VirtualBaseOffsets)128 bool layoutRecordType( 129 const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment, 130 llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets, 131 llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> 132 &BaseOffsets, 133 llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> 134 &VirtualBaseOffsets) override { 135 return m_Source->layoutRecordType(Record, Size, Alignment, FieldOffsets, 136 BaseOffsets, VirtualBaseOffsets); 137 } 138 }; 139 140 /// Wraps an ASTConsumer into an SemaConsumer. Doesn't take ownership of the 141 /// provided consumer. If the provided ASTConsumer is also a SemaConsumer, 142 /// the wrapper will also forward SemaConsumer functions. 143 class ASTConsumerForwarder : public clang::SemaConsumer { 144 clang::ASTConsumer *m_c; 145 clang::SemaConsumer *m_sc; 146 147 public: ASTConsumerForwarder(clang::ASTConsumer * c)148 ASTConsumerForwarder(clang::ASTConsumer *c) : m_c(c) { 149 m_sc = llvm::dyn_cast<clang::SemaConsumer>(m_c); 150 } 151 152 ~ASTConsumerForwarder() override; 153 Initialize(clang::ASTContext & Context)154 void Initialize(clang::ASTContext &Context) override { 155 m_c->Initialize(Context); 156 } 157 HandleTopLevelDecl(clang::DeclGroupRef D)158 bool HandleTopLevelDecl(clang::DeclGroupRef D) override { 159 return m_c->HandleTopLevelDecl(D); 160 } 161 HandleInlineFunctionDefinition(clang::FunctionDecl * D)162 void HandleInlineFunctionDefinition(clang::FunctionDecl *D) override { 163 m_c->HandleInlineFunctionDefinition(D); 164 } 165 HandleInterestingDecl(clang::DeclGroupRef D)166 void HandleInterestingDecl(clang::DeclGroupRef D) override { 167 m_c->HandleInterestingDecl(D); 168 } 169 HandleTranslationUnit(clang::ASTContext & Ctx)170 void HandleTranslationUnit(clang::ASTContext &Ctx) override { 171 m_c->HandleTranslationUnit(Ctx); 172 } 173 HandleTagDeclDefinition(clang::TagDecl * D)174 void HandleTagDeclDefinition(clang::TagDecl *D) override { 175 m_c->HandleTagDeclDefinition(D); 176 } 177 HandleTagDeclRequiredDefinition(const clang::TagDecl * D)178 void HandleTagDeclRequiredDefinition(const clang::TagDecl *D) override { 179 m_c->HandleTagDeclRequiredDefinition(D); 180 } 181 HandleCXXImplicitFunctionInstantiation(clang::FunctionDecl * D)182 void HandleCXXImplicitFunctionInstantiation(clang::FunctionDecl *D) override { 183 m_c->HandleCXXImplicitFunctionInstantiation(D); 184 } 185 HandleTopLevelDeclInObjCContainer(clang::DeclGroupRef D)186 void HandleTopLevelDeclInObjCContainer(clang::DeclGroupRef D) override { 187 m_c->HandleTopLevelDeclInObjCContainer(D); 188 } 189 HandleImplicitImportDecl(clang::ImportDecl * D)190 void HandleImplicitImportDecl(clang::ImportDecl *D) override { 191 m_c->HandleImplicitImportDecl(D); 192 } 193 CompleteTentativeDefinition(clang::VarDecl * D)194 void CompleteTentativeDefinition(clang::VarDecl *D) override { 195 m_c->CompleteTentativeDefinition(D); 196 } 197 AssignInheritanceModel(clang::CXXRecordDecl * RD)198 void AssignInheritanceModel(clang::CXXRecordDecl *RD) override { 199 m_c->AssignInheritanceModel(RD); 200 } 201 HandleCXXStaticMemberVarInstantiation(clang::VarDecl * D)202 void HandleCXXStaticMemberVarInstantiation(clang::VarDecl *D) override { 203 m_c->HandleCXXStaticMemberVarInstantiation(D); 204 } 205 HandleVTable(clang::CXXRecordDecl * RD)206 void HandleVTable(clang::CXXRecordDecl *RD) override { 207 m_c->HandleVTable(RD); 208 } 209 GetASTMutationListener()210 clang::ASTMutationListener *GetASTMutationListener() override { 211 return m_c->GetASTMutationListener(); 212 } 213 GetASTDeserializationListener()214 clang::ASTDeserializationListener *GetASTDeserializationListener() override { 215 return m_c->GetASTDeserializationListener(); 216 } 217 218 void PrintStats() override; 219 InitializeSema(clang::Sema & S)220 void InitializeSema(clang::Sema &S) override { 221 if (m_sc) 222 m_sc->InitializeSema(S); 223 } 224 225 /// Inform the semantic consumer that Sema is no longer available. ForgetSema()226 void ForgetSema() override { 227 if (m_sc) 228 m_sc->ForgetSema(); 229 } 230 shouldSkipFunctionBody(clang::Decl * D)231 bool shouldSkipFunctionBody(clang::Decl *D) override { 232 return m_c->shouldSkipFunctionBody(D); 233 } 234 }; 235 236 /// A ExternalSemaSource multiplexer that prioritizes its sources. 237 /// 238 /// This ExternalSemaSource will forward all requests to its attached sources. 239 /// However, unlike a normal multiplexer it will not forward a request to all 240 /// sources, but instead give priority to certain sources. If a source with a 241 /// higher priority can fulfill a request, all sources with a lower priority 242 /// will not receive the request. 243 /// 244 /// This class is mostly use to multiplex between sources of different 245 /// 'quality', e.g. a C++ modules and debug information. The C++ module will 246 /// provide more accurate replies to the requests, but might not be able to 247 /// answer all requests. The debug information will be used as a fallback then 248 /// to provide information that is not in the C++ module. 249 class SemaSourceWithPriorities : public clang::ExternalSemaSource { 250 251 private: 252 /// The sources ordered in decreasing priority. 253 llvm::SmallVector<clang::ExternalSemaSource *, 2> Sources; 254 255 public: 256 /// Construct a SemaSourceWithPriorities with a 'high quality' source that 257 /// has the higher priority and a 'low quality' source that will be used 258 /// as a fallback. SemaSourceWithPriorities(clang::ExternalSemaSource & high_quality_source,clang::ExternalSemaSource & low_quality_source)259 SemaSourceWithPriorities(clang::ExternalSemaSource &high_quality_source, 260 clang::ExternalSemaSource &low_quality_source) { 261 Sources.push_back(&high_quality_source); 262 Sources.push_back(&low_quality_source); 263 } 264 265 ~SemaSourceWithPriorities() override; 266 addSource(clang::ExternalSemaSource & source)267 void addSource(clang::ExternalSemaSource &source) { 268 Sources.push_back(&source); 269 } 270 271 //===--------------------------------------------------------------------===// 272 // ExternalASTSource. 273 //===--------------------------------------------------------------------===// 274 GetExternalDecl(clang::GlobalDeclID ID)275 clang::Decl *GetExternalDecl(clang::GlobalDeclID ID) override { 276 for (size_t i = 0; i < Sources.size(); ++i) 277 if (clang::Decl *Result = Sources[i]->GetExternalDecl(ID)) 278 return Result; 279 return nullptr; 280 } 281 CompleteRedeclChain(const clang::Decl * D)282 void CompleteRedeclChain(const clang::Decl *D) override { 283 for (size_t i = 0; i < Sources.size(); ++i) 284 Sources[i]->CompleteRedeclChain(D); 285 } 286 GetExternalSelector(uint32_t ID)287 clang::Selector GetExternalSelector(uint32_t ID) override { 288 clang::Selector Sel; 289 for (size_t i = 0; i < Sources.size(); ++i) { 290 Sel = Sources[i]->GetExternalSelector(ID); 291 if (!Sel.isNull()) 292 return Sel; 293 } 294 return Sel; 295 } 296 GetNumExternalSelectors()297 uint32_t GetNumExternalSelectors() override { 298 for (size_t i = 0; i < Sources.size(); ++i) 299 if (uint32_t total = Sources[i]->GetNumExternalSelectors()) 300 return total; 301 return 0; 302 } 303 GetExternalDeclStmt(uint64_t Offset)304 clang::Stmt *GetExternalDeclStmt(uint64_t Offset) override { 305 for (size_t i = 0; i < Sources.size(); ++i) 306 if (clang::Stmt *Result = Sources[i]->GetExternalDeclStmt(Offset)) 307 return Result; 308 return nullptr; 309 } 310 311 clang::CXXBaseSpecifier * GetExternalCXXBaseSpecifiers(uint64_t Offset)312 GetExternalCXXBaseSpecifiers(uint64_t Offset) override { 313 for (size_t i = 0; i < Sources.size(); ++i) 314 if (clang::CXXBaseSpecifier *R = 315 Sources[i]->GetExternalCXXBaseSpecifiers(Offset)) 316 return R; 317 return nullptr; 318 } 319 320 clang::CXXCtorInitializer ** GetExternalCXXCtorInitializers(uint64_t Offset)321 GetExternalCXXCtorInitializers(uint64_t Offset) override { 322 for (auto *S : Sources) 323 if (auto *R = S->GetExternalCXXCtorInitializers(Offset)) 324 return R; 325 return nullptr; 326 } 327 hasExternalDefinitions(const clang::Decl * D)328 ExtKind hasExternalDefinitions(const clang::Decl *D) override { 329 for (const auto &S : Sources) 330 if (auto EK = S->hasExternalDefinitions(D)) 331 if (EK != EK_ReplyHazy) 332 return EK; 333 return EK_ReplyHazy; 334 } 335 FindExternalVisibleDeclsByName(const clang::DeclContext * DC,clang::DeclarationName Name)336 bool FindExternalVisibleDeclsByName(const clang::DeclContext *DC, 337 clang::DeclarationName Name) override { 338 for (size_t i = 0; i < Sources.size(); ++i) 339 if (Sources[i]->FindExternalVisibleDeclsByName(DC, Name)) 340 return true; 341 return false; 342 } 343 completeVisibleDeclsMap(const clang::DeclContext * DC)344 void completeVisibleDeclsMap(const clang::DeclContext *DC) override { 345 // FIXME: Only one source should be able to complete the decls map. 346 for (size_t i = 0; i < Sources.size(); ++i) 347 Sources[i]->completeVisibleDeclsMap(DC); 348 } 349 FindExternalLexicalDecls(const clang::DeclContext * DC,llvm::function_ref<bool (clang::Decl::Kind)> IsKindWeWant,llvm::SmallVectorImpl<clang::Decl * > & Result)350 void FindExternalLexicalDecls( 351 const clang::DeclContext *DC, 352 llvm::function_ref<bool(clang::Decl::Kind)> IsKindWeWant, 353 llvm::SmallVectorImpl<clang::Decl *> &Result) override { 354 for (size_t i = 0; i < Sources.size(); ++i) { 355 Sources[i]->FindExternalLexicalDecls(DC, IsKindWeWant, Result); 356 if (!Result.empty()) 357 return; 358 } 359 } 360 361 void FindFileRegionDecls(clang::FileID File,unsigned Offset,unsigned Length,llvm::SmallVectorImpl<clang::Decl * > & Decls)362 FindFileRegionDecls(clang::FileID File, unsigned Offset, unsigned Length, 363 llvm::SmallVectorImpl<clang::Decl *> &Decls) override { 364 for (size_t i = 0; i < Sources.size(); ++i) 365 Sources[i]->FindFileRegionDecls(File, Offset, Length, Decls); 366 } 367 CompleteType(clang::TagDecl * Tag)368 void CompleteType(clang::TagDecl *Tag) override { 369 for (clang::ExternalSemaSource *S : Sources) { 370 S->CompleteType(Tag); 371 // Stop after the first source completed the type. 372 if (Tag->isCompleteDefinition()) 373 break; 374 } 375 } 376 CompleteType(clang::ObjCInterfaceDecl * Class)377 void CompleteType(clang::ObjCInterfaceDecl *Class) override { 378 for (size_t i = 0; i < Sources.size(); ++i) 379 Sources[i]->CompleteType(Class); 380 } 381 ReadComments()382 void ReadComments() override { 383 for (size_t i = 0; i < Sources.size(); ++i) 384 Sources[i]->ReadComments(); 385 } 386 StartedDeserializing()387 void StartedDeserializing() override { 388 for (size_t i = 0; i < Sources.size(); ++i) 389 Sources[i]->StartedDeserializing(); 390 } 391 FinishedDeserializing()392 void FinishedDeserializing() override { 393 for (size_t i = 0; i < Sources.size(); ++i) 394 Sources[i]->FinishedDeserializing(); 395 } 396 StartTranslationUnit(clang::ASTConsumer * Consumer)397 void StartTranslationUnit(clang::ASTConsumer *Consumer) override { 398 for (size_t i = 0; i < Sources.size(); ++i) 399 Sources[i]->StartTranslationUnit(Consumer); 400 } 401 402 void PrintStats() override; 403 getModule(unsigned ID)404 clang::Module *getModule(unsigned ID) override { 405 for (size_t i = 0; i < Sources.size(); ++i) 406 if (auto M = Sources[i]->getModule(ID)) 407 return M; 408 return nullptr; 409 } 410 layoutRecordType(const clang::RecordDecl * Record,uint64_t & Size,uint64_t & Alignment,llvm::DenseMap<const clang::FieldDecl *,uint64_t> & FieldOffsets,llvm::DenseMap<const clang::CXXRecordDecl *,clang::CharUnits> & BaseOffsets,llvm::DenseMap<const clang::CXXRecordDecl *,clang::CharUnits> & VirtualBaseOffsets)411 bool layoutRecordType( 412 const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment, 413 llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets, 414 llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> 415 &BaseOffsets, 416 llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> 417 &VirtualBaseOffsets) override { 418 for (size_t i = 0; i < Sources.size(); ++i) 419 if (Sources[i]->layoutRecordType(Record, Size, Alignment, FieldOffsets, 420 BaseOffsets, VirtualBaseOffsets)) 421 return true; 422 return false; 423 } 424 getMemoryBufferSizes(MemoryBufferSizes & sizes)425 void getMemoryBufferSizes(MemoryBufferSizes &sizes) const override { 426 for (auto &Source : Sources) 427 Source->getMemoryBufferSizes(sizes); 428 } 429 430 //===--------------------------------------------------------------------===// 431 // ExternalSemaSource. 432 //===--------------------------------------------------------------------===// 433 InitializeSema(clang::Sema & S)434 void InitializeSema(clang::Sema &S) override { 435 for (auto &Source : Sources) 436 Source->InitializeSema(S); 437 } 438 ForgetSema()439 void ForgetSema() override { 440 for (auto &Source : Sources) 441 Source->ForgetSema(); 442 } 443 ReadMethodPool(clang::Selector Sel)444 void ReadMethodPool(clang::Selector Sel) override { 445 for (auto &Source : Sources) 446 Source->ReadMethodPool(Sel); 447 } 448 updateOutOfDateSelector(clang::Selector Sel)449 void updateOutOfDateSelector(clang::Selector Sel) override { 450 for (auto &Source : Sources) 451 Source->updateOutOfDateSelector(Sel); 452 } 453 ReadKnownNamespaces(llvm::SmallVectorImpl<clang::NamespaceDecl * > & Namespaces)454 void ReadKnownNamespaces( 455 llvm::SmallVectorImpl<clang::NamespaceDecl *> &Namespaces) override { 456 for (auto &Source : Sources) 457 Source->ReadKnownNamespaces(Namespaces); 458 } 459 ReadUndefinedButUsed(llvm::MapVector<clang::NamedDecl *,clang::SourceLocation> & Undefined)460 void ReadUndefinedButUsed( 461 llvm::MapVector<clang::NamedDecl *, clang::SourceLocation> &Undefined) 462 override { 463 for (auto &Source : Sources) 464 Source->ReadUndefinedButUsed(Undefined); 465 } 466 ReadMismatchingDeleteExpressions(llvm::MapVector<clang::FieldDecl *,llvm::SmallVector<std::pair<clang::SourceLocation,bool>,4>> & Exprs)467 void ReadMismatchingDeleteExpressions( 468 llvm::MapVector<clang::FieldDecl *, 469 llvm::SmallVector<std::pair<clang::SourceLocation, bool>, 470 4>> &Exprs) override { 471 for (auto &Source : Sources) 472 Source->ReadMismatchingDeleteExpressions(Exprs); 473 } 474 LookupUnqualified(clang::LookupResult & R,clang::Scope * S)475 bool LookupUnqualified(clang::LookupResult &R, clang::Scope *S) override { 476 for (auto &Source : Sources) { 477 Source->LookupUnqualified(R, S); 478 if (!R.empty()) 479 break; 480 } 481 482 return !R.empty(); 483 } 484 ReadTentativeDefinitions(llvm::SmallVectorImpl<clang::VarDecl * > & Defs)485 void ReadTentativeDefinitions( 486 llvm::SmallVectorImpl<clang::VarDecl *> &Defs) override { 487 for (auto &Source : Sources) 488 Source->ReadTentativeDefinitions(Defs); 489 } 490 ReadUnusedFileScopedDecls(llvm::SmallVectorImpl<const clang::DeclaratorDecl * > & Decls)491 void ReadUnusedFileScopedDecls( 492 llvm::SmallVectorImpl<const clang::DeclaratorDecl *> &Decls) override { 493 for (auto &Source : Sources) 494 Source->ReadUnusedFileScopedDecls(Decls); 495 } 496 ReadDelegatingConstructors(llvm::SmallVectorImpl<clang::CXXConstructorDecl * > & Decls)497 void ReadDelegatingConstructors( 498 llvm::SmallVectorImpl<clang::CXXConstructorDecl *> &Decls) override { 499 for (auto &Source : Sources) 500 Source->ReadDelegatingConstructors(Decls); 501 } 502 ReadExtVectorDecls(llvm::SmallVectorImpl<clang::TypedefNameDecl * > & Decls)503 void ReadExtVectorDecls( 504 llvm::SmallVectorImpl<clang::TypedefNameDecl *> &Decls) override { 505 for (auto &Source : Sources) 506 Source->ReadExtVectorDecls(Decls); 507 } 508 ReadUnusedLocalTypedefNameCandidates(llvm::SmallSetVector<const clang::TypedefNameDecl *,4> & Decls)509 void ReadUnusedLocalTypedefNameCandidates( 510 llvm::SmallSetVector<const clang::TypedefNameDecl *, 4> &Decls) override { 511 for (auto &Source : Sources) 512 Source->ReadUnusedLocalTypedefNameCandidates(Decls); 513 } 514 ReadReferencedSelectors(llvm::SmallVectorImpl<std::pair<clang::Selector,clang::SourceLocation>> & Sels)515 void ReadReferencedSelectors( 516 llvm::SmallVectorImpl<std::pair<clang::Selector, clang::SourceLocation>> 517 &Sels) override { 518 for (auto &Source : Sources) 519 Source->ReadReferencedSelectors(Sels); 520 } 521 ReadWeakUndeclaredIdentifiers(llvm::SmallVectorImpl<std::pair<clang::IdentifierInfo *,clang::WeakInfo>> & WI)522 void ReadWeakUndeclaredIdentifiers( 523 llvm::SmallVectorImpl<std::pair<clang::IdentifierInfo *, clang::WeakInfo>> 524 &WI) override { 525 for (auto &Source : Sources) 526 Source->ReadWeakUndeclaredIdentifiers(WI); 527 } 528 ReadUsedVTables(llvm::SmallVectorImpl<clang::ExternalVTableUse> & VTables)529 void ReadUsedVTables( 530 llvm::SmallVectorImpl<clang::ExternalVTableUse> &VTables) override { 531 for (auto &Source : Sources) 532 Source->ReadUsedVTables(VTables); 533 } 534 ReadPendingInstantiations(llvm::SmallVectorImpl<std::pair<clang::ValueDecl *,clang::SourceLocation>> & Pending)535 void ReadPendingInstantiations( 536 llvm::SmallVectorImpl< 537 std::pair<clang::ValueDecl *, clang::SourceLocation>> &Pending) 538 override { 539 for (auto &Source : Sources) 540 Source->ReadPendingInstantiations(Pending); 541 } 542 ReadLateParsedTemplates(llvm::MapVector<const clang::FunctionDecl *,std::unique_ptr<clang::LateParsedTemplate>> & LPTMap)543 void ReadLateParsedTemplates( 544 llvm::MapVector<const clang::FunctionDecl *, 545 std::unique_ptr<clang::LateParsedTemplate>> &LPTMap) 546 override { 547 for (auto &Source : Sources) 548 Source->ReadLateParsedTemplates(LPTMap); 549 } 550 551 clang::TypoCorrection CorrectTypo(const clang::DeclarationNameInfo & Typo,int LookupKind,clang::Scope * S,clang::CXXScopeSpec * SS,clang::CorrectionCandidateCallback & CCC,clang::DeclContext * MemberContext,bool EnteringContext,const clang::ObjCObjectPointerType * OPT)552 CorrectTypo(const clang::DeclarationNameInfo &Typo, int LookupKind, 553 clang::Scope *S, clang::CXXScopeSpec *SS, 554 clang::CorrectionCandidateCallback &CCC, 555 clang::DeclContext *MemberContext, bool EnteringContext, 556 const clang::ObjCObjectPointerType *OPT) override { 557 for (auto &Source : Sources) { 558 if (clang::TypoCorrection C = 559 Source->CorrectTypo(Typo, LookupKind, S, SS, CCC, 560 MemberContext, EnteringContext, OPT)) 561 return C; 562 } 563 return clang::TypoCorrection(); 564 } 565 MaybeDiagnoseMissingCompleteType(clang::SourceLocation Loc,clang::QualType T)566 bool MaybeDiagnoseMissingCompleteType(clang::SourceLocation Loc, 567 clang::QualType T) override { 568 for (auto &Source : Sources) { 569 if (Source->MaybeDiagnoseMissingCompleteType(Loc, T)) 570 return true; 571 } 572 return false; 573 } 574 }; 575 576 } // namespace lldb_private 577 #endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_ASTUTILS_H 578