summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2015-03-07 00:04:49 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2015-03-07 00:04:49 +0000
commit499fc534bd0210b73176bb9bc0ffbe6e59512133 (patch)
tree27f29f6f8efad7ff9a6514366b8ac2f6e0f9d3b5
parentff82eb5187dc7b05ff4a5920c449d5b130a77668 (diff)
downloadclang-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
-rw-r--r--include/clang/AST/ASTContext.h2
-rw-r--r--include/clang/AST/DataRecursiveASTVisitor.h2
-rw-r--r--include/clang/AST/Decl.h37
-rw-r--r--include/clang/AST/RecursiveASTVisitor.h2
-rw-r--r--include/clang/Basic/DeclNodes.td1
-rw-r--r--include/clang/Sema/ExternalSemaSource.h10
-rw-r--r--include/clang/Sema/MultiplexExternalSemaSource.h10
-rw-r--r--include/clang/Sema/Sema.h27
-rw-r--r--include/clang/Serialization/ASTBitCodes.h11
-rw-r--r--include/clang/Serialization/ASTReader.h9
-rw-r--r--lib/AST/ASTContext.cpp10
-rw-r--r--lib/AST/Decl.cpp7
-rw-r--r--lib/AST/DeclBase.cpp2
-rw-r--r--lib/CodeGen/CGDecl.cpp1
-rw-r--r--lib/Sema/MultiplexExternalSemaSource.cpp6
-rw-r--r--lib/Sema/SemaDecl.cpp22
-rw-r--r--lib/Sema/SemaTemplateInstantiateDecl.cpp5
-rw-r--r--lib/Serialization/ASTCommon.cpp7
-rw-r--r--lib/Serialization/ASTReader.cpp19
-rw-r--r--lib/Serialization/ASTWriter.cpp26
-rw-r--r--tools/libclang/CIndex.cpp1
21 files changed, 94 insertions, 123 deletions
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index de6b8c668d..b62760f6ae 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -383,6 +383,7 @@ private:
ImportDecl *LastLocalImport;
TranslationUnitDecl *TUDecl;
+ mutable ExternCContextDecl *ExternCContext;
/// \brief The associated SourceManager object.a
SourceManager &SourceMgr;
@@ -782,6 +783,7 @@ public:
TranslationUnitDecl *getTranslationUnitDecl() const { return TUDecl; }
+ ExternCContextDecl *getExternCContextDecl() const;
// Builtin Types.
CanQualType VoidTy;
diff --git a/include/clang/AST/DataRecursiveASTVisitor.h b/include/clang/AST/DataRecursiveASTVisitor.h
index c0526e1cfd..cc967e652f 100644
--- a/include/clang/AST/DataRecursiveASTVisitor.h
+++ b/include/clang/AST/DataRecursiveASTVisitor.h
@@ -1284,6 +1284,8 @@ DEF_TRAVERSE_DECL(
// D->getAnonymousNamespace().
})
+DEF_TRAVERSE_DECL(ExternCContextDecl, {})
+
DEF_TRAVERSE_DECL(NamespaceAliasDecl, {
// We shouldn't traverse an aliased namespace, since it will be
// defined (and, therefore, traversed) somewhere else.
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index 63ef79616f..5380339f50 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -104,6 +104,43 @@ public:
}
};
+/// \brief Declaration context for names declared as extern "C" in C++. This
+/// is neither the semantic nor lexical context for such declarations, but is
+/// used to check for conflicts with other extern "C" declarations. Example:
+///
+/// \code
+/// namespace N { extern "C" void f(); } // #1
+/// void N::f() {} // #2
+/// namespace M { extern "C" void f(); } // #3
+/// \endcode
+///
+/// The semantic context of #1 is namespace N and its lexical context is the
+/// LinkageSpecDecl; the semantic context of #2 is namespace N and its lexical
+/// context is the TU. However, both declarations are also visible in the
+/// extern "C" context.
+///
+/// The declaration at #3 finds it is a redeclaration of \c N::f through
+/// lookup in the extern "C" context.
+class ExternCContextDecl : public Decl, public DeclContext {
+ virtual void anchor();
+
+ explicit ExternCContextDecl(TranslationUnitDecl *TU)
+ : Decl(ExternCContext, TU, SourceLocation()),
+ DeclContext(ExternCContext) {}
+public:
+ static ExternCContextDecl *Create(const ASTContext &C,
+ TranslationUnitDecl *TU);
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classofKind(Kind K) { return K == ExternCContext; }
+ static DeclContext *castToDeclContext(const ExternCContextDecl *D) {
+ return static_cast<DeclContext *>(const_cast<ExternCContextDecl*>(D));
+ }
+ static ExternCContextDecl *castFromDeclContext(const DeclContext *DC) {
+ return static_cast<ExternCContextDecl *>(const_cast<DeclContext*>(DC));
+ }
+};
+
/// NamedDecl - This represents a decl with a name. Many decls have names such
/// as ObjCMethodDecl, but not \@class, etc.
class NamedDecl : public Decl {
diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h
index ff8e74b650..f91008fde2 100644
--- a/include/clang/AST/RecursiveASTVisitor.h
+++ b/include/clang/AST/RecursiveASTVisitor.h
@@ -1356,6 +1356,8 @@ DEF_TRAVERSE_DECL(
// D->getAnonymousNamespace().
})
+DEF_TRAVERSE_DECL(ExternCContextDecl, {})
+
DEF_TRAVERSE_DECL(NamespaceAliasDecl, {
// We shouldn't traverse an aliased namespace, since it will be
// defined (and, therefore, traversed) somewhere else.
diff --git a/include/clang/Basic/DeclNodes.td b/include/clang/Basic/DeclNodes.td
index 18bca57419..dece8f9ed2 100644
--- a/include/clang/Basic/DeclNodes.td
+++ b/include/clang/Basic/DeclNodes.td
@@ -11,6 +11,7 @@ class DDecl<Decl base, bit abstract = 0> : Decl<abstract> {
class DeclContext { }
def TranslationUnit : Decl, DeclContext;
+def ExternCContext : Decl, DeclContext;
def Named : Decl<1>;
def Namespace : DDecl<Named>, DeclContext;
def UsingDirective : DDecl<Named>;
diff --git a/include/clang/Sema/ExternalSemaSource.h b/include/clang/Sema/ExternalSemaSource.h
index 168835b178..1083784fb7 100644
--- a/include/clang/Sema/ExternalSemaSource.h
+++ b/include/clang/Sema/ExternalSemaSource.h
@@ -137,16 +137,6 @@ public:
virtual void ReadUnusedLocalTypedefNameCandidates(
llvm::SmallSetVector<const TypedefNameDecl *, 4> &Decls) {};
- /// \brief Read the set of locally-scoped external declarations known to the
- /// external Sema source.
- ///
- /// The external source should append its own locally-scoped external
- /// declarations to the given vector of declarations. Note that this routine
- /// may be invoked multiple times; the external source should take care not
- /// to introduce the same declarations repeatedly.
- virtual void ReadLocallyScopedExternCDecls(
- SmallVectorImpl<NamedDecl *> &Decls) {}
-
/// \brief Read the set of referenced selectors known to the
/// external Sema source.
///
diff --git a/include/clang/Sema/MultiplexExternalSemaSource.h b/include/clang/Sema/MultiplexExternalSemaSource.h
index 50e2553f2b..d90eefd302 100644
--- a/include/clang/Sema/MultiplexExternalSemaSource.h
+++ b/include/clang/Sema/MultiplexExternalSemaSource.h
@@ -283,16 +283,6 @@ public:
void ReadUnusedLocalTypedefNameCandidates(
llvm::SmallSetVector<const TypedefNameDecl *, 4> &Decls) override;
- /// \brief Read the set of locally-scoped extern "C" declarations known to the
- /// external Sema source.
- ///
- /// The external source should append its own locally-scoped external
- /// declarations to the given vector of declarations. Note that this routine
- /// may be invoked multiple times; the external source should take care not
- /// to introduce the same declarations repeatedly.
- void ReadLocallyScopedExternCDecls(
- SmallVectorImpl<NamedDecl*> &Decls) override;
-
/// \brief Read the set of referenced selectors known to the
/// external Sema source.
///
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index 8e03911af3..460111f522 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -410,33 +410,6 @@ public:
/// we are currently parsing the initializer.
llvm::SmallPtrSet<const Decl*, 4> ParsingInitForAutoVars;
- /// \brief A mapping from external names to the most recent
- /// locally-scoped extern "C" declaration with that name.
- ///
- /// This map contains external declarations introduced in local
- /// scopes, e.g.,
- ///
- /// \code
- /// extern "C" void f() {
- /// void foo(int, int);
- /// }
- /// \endcode
- ///
- /// Here, the name "foo" will be associated with the declaration of
- /// "foo" within f. This name is not visible outside of
- /// "f". However, we still find it in two cases:
- ///
- /// - If we are declaring another global or extern "C" entity with
- /// the name "foo", we can find "foo" as a previous declaration,
- /// so that the types of this external declaration can be checked
- /// for compatibility.
- ///
- /// - If we would implicitly declare "foo" (e.g., due to a call to
- /// "foo" in C when no prototype or definition is visible), then
- /// we find this declaration of "foo" and complain that it is
- /// not visible.
- llvm::DenseMap<DeclarationName, NamedDecl *> LocallyScopedExternCDecls;
-
/// \brief Look for a locally scoped extern "C" declaration by the given name.
NamedDecl *findLocallyScopedExternCDecl(DeclarationName Name);
diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h
index 71c55c6095..1e26927fbf 100644
--- a/include/clang/Serialization/ASTBitCodes.h
+++ b/include/clang/Serialization/ASTBitCodes.h
@@ -385,9 +385,7 @@ namespace clang {
/// \brief Record code for the array of tentative definitions.
TENTATIVE_DEFINITIONS = 9,
- /// \brief Record code for the array of locally-scoped extern "C"
- /// declarations.
- LOCALLY_SCOPED_EXTERN_C_DECLS = 10,
+ // ID 10 used to be for a list of extern "C" declarations.
/// \brief Record code for the table of offsets into the
/// Objective-C method pool.
@@ -925,14 +923,17 @@ namespace clang {
PREDEF_DECL_OBJC_INSTANCETYPE_ID = 8,
/// \brief The internal '__builtin_va_list' typedef.
- PREDEF_DECL_BUILTIN_VA_LIST_ID = 9
+ PREDEF_DECL_BUILTIN_VA_LIST_ID = 9,
+
+ /// \brief The extern "C" context.
+ PREDEF_DECL_EXTERN_C_CONTEXT_ID = 10,
};
/// \brief The number of declaration IDs that are predefined.
///
/// For more information about predefined declarations, see the
/// \c PredefinedDeclIDs type and the PREDEF_DECL_*_ID constants.
- const unsigned int NUM_PREDEF_DECL_IDS = 10;
+ const unsigned int NUM_PREDEF_DECL_IDS = 11;
/// \brief Record codes for each kind of declaration.
///
diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h
index 8ccf94c0e2..1037160ab2 100644
--- a/include/clang/Serialization/ASTReader.h
+++ b/include/clang/Serialization/ASTReader.h
@@ -770,12 +770,6 @@ private:
/// \brief Fields containing data that is used for semantic analysis
//@{
- /// \brief The IDs of all locally scoped extern "C" decls in the chain.
- ///
- /// Sema tracks these to validate that the types are consistent across all
- /// local extern "C" declarations.
- SmallVector<uint64_t, 16> LocallyScopedExternCDecls;
-
/// \brief The IDs of all potentially unused typedef names in the chain.
///
/// Sema tracks these to emit warnings.
@@ -1795,9 +1789,6 @@ public:
void ReadUnusedLocalTypedefNameCandidates(
llvm::SmallSetVector<const TypedefNameDecl *, 4> &Decls) override;
- void ReadLocallyScopedExternCDecls(
- SmallVectorImpl<NamedDecl *> &Decls) override;
-
void ReadReferencedSelectors(
SmallVectorImpl<std::pair<Selector, SourceLocation> > &Sels) override;
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);
diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp
index 9729531c0f..d9f3f42e32 100644
--- a/tools/libclang/CIndex.cpp
+++ b/tools/libclang/CIndex.cpp
@@ -4951,6 +4951,7 @@ CXCursor clang_getCursorDefinition(CXCursor C) {
// nonetheless harmless.
case Decl::Empty:
case Decl::TranslationUnit:
+ case Decl::ExternCContext:
break;
// Declaration kinds for which the definition is not resolvable.