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