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