diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2015-03-07 00:04:49 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2015-03-07 00:04:49 +0000 |
commit | 499fc534bd0210b73176bb9bc0ffbe6e59512133 (patch) | |
tree | 27f29f6f8efad7ff9a6514366b8ac2f6e0f9d3b5 /lib | |
parent | ff82eb5187dc7b05ff4a5920c449d5b130a77668 (diff) | |
download | clang-499fc534bd0210b73176bb9bc0ffbe6e59512133.tar.gz |
Replace Sema's map of locally-scoped extern "C" declarations with a DeclContext
of extern "C" declarations. This is simpler and vastly more efficient for
modules builds (we no longer need to load *all* extern "C" declarations to
determine if we have a redeclaration).
No functionality change intended.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@231538 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/ASTContext.cpp | 10 | ||||
-rw-r--r-- | lib/AST/Decl.cpp | 7 | ||||
-rw-r--r-- | lib/AST/DeclBase.cpp | 2 | ||||
-rw-r--r-- | lib/CodeGen/CGDecl.cpp | 1 | ||||
-rw-r--r-- | lib/Sema/MultiplexExternalSemaSource.cpp | 6 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 22 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateInstantiateDecl.cpp | 5 | ||||
-rw-r--r-- | lib/Serialization/ASTCommon.cpp | 7 | ||||
-rw-r--r-- | lib/Serialization/ASTReader.cpp | 19 | ||||
-rw-r--r-- | lib/Serialization/ASTWriter.cpp | 26 |
10 files changed, 43 insertions, 62 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 9cfc97b926..20d2aa6818 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -738,7 +738,8 @@ ASTContext::ASTContext(LangOptions &LOpts, SourceManager &SM, FILEDecl(nullptr), jmp_bufDecl(nullptr), sigjmp_bufDecl(nullptr), ucontext_tDecl(nullptr), BlockDescriptorType(nullptr), BlockDescriptorExtendedType(nullptr), cudaConfigureCallDecl(nullptr), - FirstLocalImport(), LastLocalImport(), SourceMgr(SM), LangOpts(LOpts), + FirstLocalImport(), LastLocalImport(), ExternCContext(nullptr), + SourceMgr(SM), LangOpts(LOpts), SanitizerBL(new SanitizerBlacklist(LangOpts.SanitizerBlacklistFiles, SM)), AddrSpaceMap(nullptr), Target(nullptr), PrintingPolicy(LOpts), Idents(idents), Selectors(sels), BuiltinInfo(builtins), @@ -865,6 +866,13 @@ void ASTContext::PrintStats() const { BumpAlloc.PrintStats(); } +ExternCContextDecl *ASTContext::getExternCContextDecl() const { + if (!ExternCContext) + ExternCContext = ExternCContextDecl::Create(*this, getTranslationUnitDecl()); + + return ExternCContext; +} + RecordDecl *ASTContext::buildImplicitRecord(StringRef Name, RecordDecl::TagKind TK) const { SourceLocation Loc; diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index c7aac37524..bd0e503d38 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -3799,6 +3799,13 @@ TranslationUnitDecl *TranslationUnitDecl::Create(ASTContext &C) { return new (C, (DeclContext *)nullptr) TranslationUnitDecl(C); } +void ExternCContextDecl::anchor() { } + +ExternCContextDecl *ExternCContextDecl::Create(const ASTContext &C, + TranslationUnitDecl *DC) { + return new (C, DC) ExternCContextDecl(DC); +} + void LabelDecl::anchor() { } LabelDecl *LabelDecl::Create(ASTContext &C, DeclContext *DC, diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp index 0390d81263..a8e151cc93 100644 --- a/lib/AST/DeclBase.cpp +++ b/lib/AST/DeclBase.cpp @@ -597,6 +597,7 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) { case Block: case Captured: case TranslationUnit: + case ExternCContext: case UsingDirective: case ClassTemplateSpecialization: @@ -907,6 +908,7 @@ bool DeclContext::Encloses(const DeclContext *DC) const { DeclContext *DeclContext::getPrimaryContext() { switch (DeclKind) { case Decl::TranslationUnit: + case Decl::ExternCContext: case Decl::LinkageSpec: case Decl::Block: case Decl::Captured: diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp index fb72a9a543..f79d1373d4 100644 --- a/lib/CodeGen/CGDecl.cpp +++ b/lib/CodeGen/CGDecl.cpp @@ -34,6 +34,7 @@ using namespace CodeGen; void CodeGenFunction::EmitDecl(const Decl &D) { switch (D.getKind()) { case Decl::TranslationUnit: + case Decl::ExternCContext: case Decl::Namespace: case Decl::UnresolvedUsingTypename: case Decl::ClassTemplateSpecialization: diff --git a/lib/Sema/MultiplexExternalSemaSource.cpp b/lib/Sema/MultiplexExternalSemaSource.cpp index a031577767..194c3693c1 100644 --- a/lib/Sema/MultiplexExternalSemaSource.cpp +++ b/lib/Sema/MultiplexExternalSemaSource.cpp @@ -242,12 +242,6 @@ void MultiplexExternalSemaSource::ReadUnusedLocalTypedefNameCandidates( Sources[i]->ReadUnusedLocalTypedefNameCandidates(Decls); } -void MultiplexExternalSemaSource::ReadLocallyScopedExternCDecls( - SmallVectorImpl<NamedDecl*> &Decls) { - for(size_t i = 0; i < Sources.size(); ++i) - Sources[i]->ReadLocallyScopedExternCDecls(Decls); -} - void MultiplexExternalSemaSource::ReadReferencedSelectors( SmallVectorImpl<std::pair<Selector, SourceLocation> > &Sels) { for(size_t i = 0; i < Sources.size(); ++i) diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 462854417e..778b617628 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -4864,27 +4864,13 @@ Sema::RegisterLocallyScopedExternCDecl(NamedDecl *ND, Scope *S) { return; // Note that we have a locally-scoped external with this name. - // FIXME: There can be multiple such declarations if they are functions marked - // __attribute__((overloadable)) declared in function scope in C. - LocallyScopedExternCDecls[ND->getDeclName()] = ND; + Context.getExternCContextDecl()->makeDeclVisibleInContext(ND); } NamedDecl *Sema::findLocallyScopedExternCDecl(DeclarationName Name) { - if (ExternalSource) { - // Load locally-scoped external decls from the external source. - // FIXME: This is inefficient. Maybe add a DeclContext for extern "C" decls? - SmallVector<NamedDecl *, 4> Decls; - ExternalSource->ReadLocallyScopedExternCDecls(Decls); - for (unsigned I = 0, N = Decls.size(); I != N; ++I) { - llvm::DenseMap<DeclarationName, NamedDecl *>::iterator Pos - = LocallyScopedExternCDecls.find(Decls[I]->getDeclName()); - if (Pos == LocallyScopedExternCDecls.end()) - LocallyScopedExternCDecls[Decls[I]->getDeclName()] = Decls[I]; - } - } - - NamedDecl *D = LocallyScopedExternCDecls.lookup(Name); - return D ? D->getMostRecentDecl() : nullptr; + // FIXME: We can have multiple results via __attribute__((overloadable)). + auto Result = Context.getExternCContextDecl()->lookup(Name); + return Result.empty() ? nullptr : *Result.begin(); } /// \brief Diagnose function specifiers on a declaration of an identifier that diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index 1df0701ee9..6936539f1c 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -289,6 +289,11 @@ TemplateDeclInstantiator::VisitTranslationUnitDecl(TranslationUnitDecl *D) { } Decl * +TemplateDeclInstantiator::VisitExternCContextDecl(ExternCContextDecl *D) { + llvm_unreachable("extern \"C\" context cannot be instantiated"); +} + +Decl * TemplateDeclInstantiator::VisitLabelDecl(LabelDecl *D) { LabelDecl *Inst = LabelDecl::Create(SemaRef.Context, Owner, D->getLocation(), D->getIdentifier()); diff --git a/lib/Serialization/ASTCommon.cpp b/lib/Serialization/ASTCommon.cpp index 04425acb4c..85c574c202 100644 --- a/lib/Serialization/ASTCommon.cpp +++ b/lib/Serialization/ASTCommon.cpp @@ -94,6 +94,7 @@ serialization::getDefinitiveDeclContext(const DeclContext *DC) { switch (DC->getDeclKind()) { // These entities may have multiple definitions. case Decl::TranslationUnit: + case Decl::ExternCContext: case Decl::Namespace: case Decl::LinkageSpec: return nullptr; @@ -149,7 +150,11 @@ serialization::getDefinitiveDeclContext(const DeclContext *DC) { bool serialization::isRedeclarableDeclKind(unsigned Kind) { switch (static_cast<Decl::Kind>(Kind)) { - case Decl::TranslationUnit: // Special case of a "merged" declaration. + case Decl::TranslationUnit: + case Decl::ExternCContext: + // Special case of a "merged" declaration. + return true; + case Decl::Namespace: case Decl::NamespaceAlias: case Decl::Typedef: diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index d3721bbe34..7e3a779b07 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -2892,11 +2892,6 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { } break; - case LOCALLY_SCOPED_EXTERN_C_DECLS: - for (unsigned I = 0, N = Record.size(); I != N; ++I) - LocallyScopedExternCDecls.push_back(getGlobalDeclID(F, Record[I])); - break; - case SELECTOR_OFFSETS: { F.SelectorOffsets = (const uint32_t *)Blob.data(); F.LocalNumSelectors = Record[0]; @@ -6284,6 +6279,9 @@ static Decl *getPredefinedDecl(ASTContext &Context, PredefinedDeclIDs ID) { case PREDEF_DECL_BUILTIN_VA_LIST_ID: return Context.getBuiltinVaListDecl(); + + case PREDEF_DECL_EXTERN_C_CONTEXT_ID: + return Context.getExternCContextDecl(); } llvm_unreachable("PredefinedDeclIDs unknown enum value"); } @@ -7326,17 +7324,6 @@ void ASTReader::ReadUnusedLocalTypedefNameCandidates( UnusedLocalTypedefNameCandidates.clear(); } -void -ASTReader::ReadLocallyScopedExternCDecls(SmallVectorImpl<NamedDecl *> &Decls) { - for (unsigned I = 0, N = LocallyScopedExternCDecls.size(); I != N; ++I) { - NamedDecl *D - = dyn_cast_or_null<NamedDecl>(GetDecl(LocallyScopedExternCDecls[I])); - if (D) - Decls.push_back(D); - } - LocallyScopedExternCDecls.clear(); -} - void ASTReader::ReadReferencedSelectors( SmallVectorImpl<std::pair<Selector, SourceLocation> > &Sels) { if (ReferencedSelectorsData.empty()) diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp index 19c7a96625..f92848ad21 100644 --- a/lib/Serialization/ASTWriter.cpp +++ b/lib/Serialization/ASTWriter.cpp @@ -892,7 +892,6 @@ void ASTWriter::WriteBlockInfoBlock() { RECORD(STATISTICS); RECORD(TENTATIVE_DEFINITIONS); RECORD(UNUSED_FILESCOPED_DECLS); - RECORD(LOCALLY_SCOPED_EXTERN_C_DECLS); RECORD(SELECTOR_OFFSETS); RECORD(METHOD_POOL); RECORD(PP_COUNTER_VALUE); @@ -4231,6 +4230,8 @@ void ASTWriter::WriteASTCore(Sema &SemaRef, DeclIDs[Context.ObjCInstanceTypeDecl] = PREDEF_DECL_OBJC_INSTANCETYPE_ID; if (Context.BuiltinVaListDecl) DeclIDs[Context.getBuiltinVaListDecl()] = PREDEF_DECL_BUILTIN_VA_LIST_ID; + if (Context.ExternCContext) + DeclIDs[Context.ExternCContext] = PREDEF_DECL_EXTERN_C_CONTEXT_ID; if (!Chain) { // Make sure that we emit IdentifierInfos (and any attached @@ -4289,20 +4290,6 @@ void ASTWriter::WriteASTCore(Sema &SemaRef, } } - // Build a record containing all of the locally-scoped extern "C" - // declarations in this header file. Generally, this record will be - // empty. - RecordData LocallyScopedExternCDecls; - // FIXME: This is filling in the AST file in densemap order which is - // nondeterminstic! - for (llvm::DenseMap<DeclarationName, NamedDecl *>::iterator - TD = SemaRef.LocallyScopedExternCDecls.begin(), - TDEnd = SemaRef.LocallyScopedExternCDecls.end(); - TD != TDEnd; ++TD) { - if (!TD->second->isFromASTFile()) - AddDeclRef(TD->second, LocallyScopedExternCDecls); - } - // Build a record containing all of the ext_vector declarations. RecordData ExtVectorDecls; AddLazyVectorDecls(*this, SemaRef.ExtVectorDecls, ExtVectorDecls); @@ -4405,6 +4392,10 @@ void ASTWriter::WriteASTCore(Sema &SemaRef, Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob)); UpdateVisibleAbbrev = Stream.EmitAbbrev(Abv); WriteDeclContextVisibleUpdate(TU); + + // If we have any extern "C" names, write out a visible update for them. + if (Context.ExternCContext) + WriteDeclContextVisibleUpdate(Context.ExternCContext); // If the translation unit has an anonymous namespace, and we don't already // have an update block for it, write it as an update block. @@ -4589,11 +4580,6 @@ void ASTWriter::WriteASTCore(Sema &SemaRef, Stream.EmitRecord(WEAK_UNDECLARED_IDENTIFIERS, WeakUndeclaredIdentifiers); - // Write the record containing locally-scoped extern "C" definitions. - if (!LocallyScopedExternCDecls.empty()) - Stream.EmitRecord(LOCALLY_SCOPED_EXTERN_C_DECLS, - LocallyScopedExternCDecls); - // Write the record containing ext_vector type names. if (!ExtVectorDecls.empty()) Stream.EmitRecord(EXT_VECTOR_DECLS, ExtVectorDecls); |