diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -53,6 +53,7 @@ #include "llvm/ADT/Optional.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/PointerUnion.h" +#include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" @@ -465,7 +466,7 @@ /// a non-constant initializer), or an ImportDecl (which recursively triggers /// initialization of another module). struct PerModuleInitializers { - llvm::SmallVector Initializers; + llvm::SmallSetVector Initializers; llvm::SmallVector LazyInitializers; void resolve(ASTContext &Ctx); @@ -1078,6 +1079,9 @@ /// Get the initializations to perform when importing a module, if any. ArrayRef getModuleInitializers(Module *M); + /// Does the module initializer array contain this decl. + bool moduleInitializerContains(Module *M, const Decl *D); + /// Set the (C++20) module we are building. void setModuleForCodeGen(Module *M) { TopLevelModule = M; } diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -1148,7 +1148,7 @@ LazyInitializers.clear(); for (auto ID : LazyInits) - Initializers.push_back(Source->GetExternalDecl(ID)); + Initializers.insert(Source->GetExternalDecl(ID)); assert(LazyInitializers.empty() && "GetExternalDecl for lazy module initializer added more inits"); @@ -1177,7 +1177,7 @@ auto *&Inits = ModuleInitializers[M]; if (!Inits) Inits = new (*this) PerModuleInitializers; - Inits->Initializers.push_back(D); + Inits->Initializers.insert(D); } void ASTContext::addLazyModuleInitializers(Module *M, ArrayRef IDs) { @@ -1195,7 +1195,17 @@ auto *Inits = It->second; Inits->resolve(*this); - return Inits->Initializers; + return Inits->Initializers.getArrayRef(); +} + +bool ASTContext::moduleInitializerContains(Module *M, const Decl *D) { + auto It = ModuleInitializers.find(M); + if (It == ModuleInitializers.end()) + return false; + + auto *Inits = It->second; + Inits->resolve(*this); + return Inits->Initializers.contains(const_cast(D)); } ExternCContextDecl *ASTContext::getExternCContextDecl() const {