]> granicus.if.org Git - clang/commitdiff
Replace Sema's map of locally-scoped extern "C" declarations with a DeclContext
authorRichard Smith <richard-llvm@metafoo.co.uk>
Sat, 7 Mar 2015 00:04:49 +0000 (00:04 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Sat, 7 Mar 2015 00:04:49 +0000 (00:04 +0000)
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

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

index de6b8c668de30697b06b97717c564da34977b87b..b62760f6ae3bfc50645e382e293165a2209fb5d8 100644 (file)
@@ -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;
index c0526e1cfd458eec69a19f9abfc6e4a1b02b81dc..cc967e652fd0c970e778a75be04ea8e8d78da1fb 100644 (file)
@@ -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.
index 63ef79616f7b5981d4b4ee9c9f0fc06352b78902..5380339f509e78ae051697068d9cd61f2098d0dc 100644 (file)
@@ -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 {
index ff8e74b650d2a724433f970b2edc8ed2a044f023..f91008fde26787fa1f965527cddb5c9cb87e82b9 100644 (file)
@@ -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.
index 18bca5741962417418b539a28e84e9f682af8a2c..dece8f9ed2ec6860e3f7f2cc9ac7bbabc1599cee 100644 (file)
@@ -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>;
index 168835b17874e19ac0c8e0d9d84018033f6e31b7..1083784fb7f005f868597c5461da59bf2be6e380 100644 (file)
@@ -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.
   ///
index 50e2553f2bf0d4e924ae773aa1b8f565f9b4fd55..d90eefd302d96e6bb73e2ceea4828ca795186032 100644 (file)
@@ -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.
   ///
index 8e03911af34006007b70ec5208f7a0301553a61d..460111f522dfb53a0d3d6266701d3ed81672e382 100644 (file)
@@ -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);
 
index 71c55c60958ca1be1e3f62e89e6af2d7494f1568..1e26927fbffb529df726c4a73750fe6b582cb2b0 100644 (file)
@@ -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.
     ///
index 8ccf94c0e2ea165bedc73ae0abaa9aae1d44c2df..1037160ab2522d66df37611a106957244d376f9b 100644 (file)
@@ -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;
 
index 9cfc97b926d32ca11c8d4cf912a11f8e614736ae..20d2aa68187a955b5c8a55bdcc580619487fde2e 100644 (file)
@@ -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;
index c7aac37524ee06879a2a7f596553c1bfe0ce7d07..bd0e503d386b1d023787859b0a2246ed433eb004 100644 (file)
@@ -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,
index 0390d81263a2bb1d08df7931299043209aa3f098..a8e151cc937d83da1e520f7e58c18fc299f6e7c5 100644 (file)
@@ -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:
index fb72a9a54339ba62a69036252c2bb5da0a269a1d..f79d1373d41a2bdbbed83ee280a3127e18d968da 100644 (file)
@@ -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:
index a031577767522b2fd0e230761b665da46ba85c30..194c3693c1d5b9f2211e064d52ee0478ea010fc8 100644 (file)
@@ -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)
index 462854417e1038a6ed9ef2614346de177296a9b4..778b617628e1aabd637b2256cf4857cd832c2955 100644 (file)
@@ -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
index 1df0701ee9f45a0a089b211eda7a2c9965929db9..6936539f1caaa5a19712933e84d39c932706c067 100644 (file)
@@ -288,6 +288,11 @@ TemplateDeclInstantiator::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
   llvm_unreachable("Translation units cannot be instantiated");
 }
 
+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(),
index 04425acb4c5d43c3c22b11120b7f119a9e0adeff..85c574c2021ab1c40f462eade7be44d9e9c435ad 100644 (file)
@@ -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:
index d3721bbe34234e067525cb44f84aa55cf9760637..7e3a779b076c1a294d8b0257ec41210e4750e950 100644 (file)
@@ -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())
index 19c7a966253c9f51f2773f75d1abeb0670b01f26..f92848ad21f8618eaadb6086a5df1acdde07ab48 100644 (file)
@@ -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);
index 9729531c0f85c6862174c50bf511d1ac87979abf..d9f3f42e32452995d50bdcb7d83c8d9149fb0e49 100644 (file)
@@ -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.