r231538 - Replace Sema's map of locally-scoped extern "C" declarations with a DeclContext

Richard Smith richard-llvm at metafoo.co.uk
Fri Mar 6 16:04:49 PST 2015


Author: rsmith
Date: Fri Mar  6 18:04:49 2015
New Revision: 231538

URL: http://llvm.org/viewvc/llvm-project?rev=231538&view=rev
Log:
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.

Modified:
    cfe/trunk/include/clang/AST/ASTContext.h
    cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h
    cfe/trunk/include/clang/AST/Decl.h
    cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
    cfe/trunk/include/clang/Basic/DeclNodes.td
    cfe/trunk/include/clang/Sema/ExternalSemaSource.h
    cfe/trunk/include/clang/Sema/MultiplexExternalSemaSource.h
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/include/clang/Serialization/ASTBitCodes.h
    cfe/trunk/include/clang/Serialization/ASTReader.h
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/AST/Decl.cpp
    cfe/trunk/lib/AST/DeclBase.cpp
    cfe/trunk/lib/CodeGen/CGDecl.cpp
    cfe/trunk/lib/Sema/MultiplexExternalSemaSource.cpp
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
    cfe/trunk/lib/Serialization/ASTCommon.cpp
    cfe/trunk/lib/Serialization/ASTReader.cpp
    cfe/trunk/lib/Serialization/ASTWriter.cpp
    cfe/trunk/tools/libclang/CIndex.cpp

Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=231538&r1=231537&r2=231538&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Fri Mar  6 18:04:49 2015
@@ -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;

Modified: cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h?rev=231538&r1=231537&r2=231538&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h (original)
+++ cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h Fri Mar  6 18:04:49 2015
@@ -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.

Modified: cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=231538&r1=231537&r2=231538&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Fri Mar  6 18:04:49 2015
@@ -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 {

Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=231538&r1=231537&r2=231538&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original)
+++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Fri Mar  6 18:04:49 2015
@@ -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.

Modified: cfe/trunk/include/clang/Basic/DeclNodes.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DeclNodes.td?rev=231538&r1=231537&r2=231538&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DeclNodes.td (original)
+++ cfe/trunk/include/clang/Basic/DeclNodes.td Fri Mar  6 18:04:49 2015
@@ -11,6 +11,7 @@ class DDecl<Decl base, bit abstract = 0>
 class DeclContext { }
 
 def TranslationUnit : Decl, DeclContext;
+def ExternCContext : Decl, DeclContext;
 def Named : Decl<1>;
   def Namespace : DDecl<Named>, DeclContext;
   def UsingDirective : DDecl<Named>;

Modified: cfe/trunk/include/clang/Sema/ExternalSemaSource.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/ExternalSemaSource.h?rev=231538&r1=231537&r2=231538&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/ExternalSemaSource.h (original)
+++ cfe/trunk/include/clang/Sema/ExternalSemaSource.h Fri Mar  6 18:04:49 2015
@@ -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.
   ///

Modified: cfe/trunk/include/clang/Sema/MultiplexExternalSemaSource.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/MultiplexExternalSemaSource.h?rev=231538&r1=231537&r2=231538&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/MultiplexExternalSemaSource.h (original)
+++ cfe/trunk/include/clang/Sema/MultiplexExternalSemaSource.h Fri Mar  6 18:04:49 2015
@@ -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.
   ///

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=231538&r1=231537&r2=231538&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Fri Mar  6 18:04:49 2015
@@ -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);
 

Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=231538&r1=231537&r2=231538&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTBitCodes.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Fri Mar  6 18:04:49 2015
@@ -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.
     ///

Modified: cfe/trunk/include/clang/Serialization/ASTReader.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTReader.h?rev=231538&r1=231537&r2=231538&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTReader.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTReader.h Fri Mar  6 18:04:49 2015
@@ -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;
 

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=231538&r1=231537&r2=231538&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Fri Mar  6 18:04:49 2015
@@ -738,7 +738,8 @@ ASTContext::ASTContext(LangOptions &LOpt
       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;

Modified: cfe/trunk/lib/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=231538&r1=231537&r2=231538&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Fri Mar  6 18:04:49 2015
@@ -3799,6 +3799,13 @@ TranslationUnitDecl *TranslationUnitDecl
   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,

Modified: cfe/trunk/lib/AST/DeclBase.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclBase.cpp?rev=231538&r1=231537&r2=231538&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclBase.cpp (original)
+++ cfe/trunk/lib/AST/DeclBase.cpp Fri Mar  6 18:04:49 2015
@@ -597,6 +597,7 @@ unsigned Decl::getIdentifierNamespaceFor
     case Block:
     case Captured:
     case TranslationUnit:
+    case ExternCContext:
 
     case UsingDirective:
     case ClassTemplateSpecialization:
@@ -907,6 +908,7 @@ bool DeclContext::Encloses(const DeclCon
 DeclContext *DeclContext::getPrimaryContext() {
   switch (DeclKind) {
   case Decl::TranslationUnit:
+  case Decl::ExternCContext:
   case Decl::LinkageSpec:
   case Decl::Block:
   case Decl::Captured:

Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=231538&r1=231537&r2=231538&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDecl.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDecl.cpp Fri Mar  6 18:04:49 2015
@@ -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:

Modified: cfe/trunk/lib/Sema/MultiplexExternalSemaSource.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/MultiplexExternalSemaSource.cpp?rev=231538&r1=231537&r2=231538&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/MultiplexExternalSemaSource.cpp (original)
+++ cfe/trunk/lib/Sema/MultiplexExternalSemaSource.cpp Fri Mar  6 18:04:49 2015
@@ -242,12 +242,6 @@ void MultiplexExternalSemaSource::ReadUn
     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)

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=231538&r1=231537&r2=231538&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Fri Mar  6 18:04:49 2015
@@ -4864,27 +4864,13 @@ Sema::RegisterLocallyScopedExternCDecl(N
     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

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=231538&r1=231537&r2=231538&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Fri Mar  6 18:04:49 2015
@@ -289,6 +289,11 @@ TemplateDeclInstantiator::VisitTranslati
 }
 
 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());

Modified: cfe/trunk/lib/Serialization/ASTCommon.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTCommon.cpp?rev=231538&r1=231537&r2=231538&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTCommon.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTCommon.cpp Fri Mar  6 18:04:49 2015
@@ -94,6 +94,7 @@ serialization::getDefinitiveDeclContext(
   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(
 
 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:

Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=231538&r1=231537&r2=231538&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Fri Mar  6 18:04:49 2015
@@ -2892,11 +2892,6 @@ ASTReader::ReadASTBlock(ModuleFile &F, u
       }
       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(ASTContex
 
   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::ReadUnusedLocalTypedefNa
   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())

Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=231538&r1=231537&r2=231538&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Fri Mar  6 18:04:49 2015
@@ -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 &SemaR
     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 &SemaR
     }
   }
 
-  // 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 &SemaR
   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 &SemaR
     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);

Modified: cfe/trunk/tools/libclang/CIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=231538&r1=231537&r2=231538&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndex.cpp (original)
+++ cfe/trunk/tools/libclang/CIndex.cpp Fri Mar  6 18:04:49 2015
@@ -4951,6 +4951,7 @@ CXCursor clang_getCursorDefinition(CXCur
   // nonetheless harmless.
   case Decl::Empty:
   case Decl::TranslationUnit:
+  case Decl::ExternCContext:
     break;
 
   // Declaration kinds for which the definition is not resolvable.





More information about the cfe-commits mailing list