[cfe-commits] r173538 - Preserve Sema::UndefinedInternals across PCH boundaries. Fixes

Nick Lewycky nicholas at mxc.ca
Fri Jan 25 16:35:08 PST 2013


Author: nicholas
Date: Fri Jan 25 18:35:08 2013
New Revision: 173538

URL: http://llvm.org/viewvc/llvm-project?rev=173538&view=rev
Log:
Preserve Sema::UndefinedInternals across PCH boundaries. Fixes
-Wundefined-internal warnings with PCH.

Added:
    cfe/trunk/test/PCH/undefined-internal.c
Modified:
    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/Sema/MultiplexExternalSemaSource.cpp
    cfe/trunk/lib/Sema/Sema.cpp
    cfe/trunk/lib/Sema/SemaLookup.cpp
    cfe/trunk/lib/Serialization/ASTReader.cpp
    cfe/trunk/lib/Serialization/ASTWriter.cpp

Modified: cfe/trunk/include/clang/Sema/ExternalSemaSource.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/ExternalSemaSource.h?rev=173538&r1=173537&r2=173538&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/ExternalSemaSource.h (original)
+++ cfe/trunk/include/clang/Sema/ExternalSemaSource.h Fri Jan 25 18:35:08 2013
@@ -15,6 +15,7 @@
 
 #include "clang/AST/ExternalASTSource.h"
 #include "clang/Sema/Weak.h"
+#include "llvm/ADT/MapVector.h"
 #include <utility>
 
 namespace clang {
@@ -65,6 +66,9 @@ public:
   /// which will be used during typo correction.
   virtual void ReadKnownNamespaces(
                            SmallVectorImpl<NamespaceDecl *> &Namespaces);
+
+  virtual void ReadUndefinedInternals(
+                        llvm::MapVector<NamedDecl*, SourceLocation> &Undefined);
   
   /// \brief Do last resort, unqualified lookup on a LookupResult that
   /// Sema cannot find.

Modified: cfe/trunk/include/clang/Sema/MultiplexExternalSemaSource.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/MultiplexExternalSemaSource.h?rev=173538&r1=173537&r2=173538&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/MultiplexExternalSemaSource.h (original)
+++ cfe/trunk/include/clang/Sema/MultiplexExternalSemaSource.h Fri Jan 25 18:35:08 2013
@@ -252,6 +252,9 @@ public:
   /// \brief Load the set of namespaces that are known to the external source,
   /// which will be used during typo correction.
   virtual void ReadKnownNamespaces(SmallVectorImpl<NamespaceDecl*> &Namespaces);
+
+  virtual void ReadUndefinedInternals(
+                        llvm::MapVector<NamedDecl*, SourceLocation> &Undefined);
   
   /// \brief Do last resort, unqualified lookup on a LookupResult that
   /// Sema cannot find.

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=173538&r1=173537&r2=173538&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Fri Jan 25 18:35:08 2013
@@ -740,7 +740,7 @@ public:
 
   /// UndefinedInternals - all the used, undefined objects with
   /// internal linkage in this translation unit.
-  llvm::DenseMap<NamedDecl*, SourceLocation> UndefinedInternals;
+  llvm::MapVector<NamedDecl*, SourceLocation> UndefinedInternals;
 
   typedef std::pair<ObjCMethodList, ObjCMethodList> GlobalMethods;
   typedef llvm::DenseMap<Selector, GlobalMethods> GlobalMethodPool;
@@ -2234,7 +2234,7 @@ private:
   //
   // The boolean value will be true to indicate that the namespace was loaded
   // from an AST/PCH file, or false otherwise.
-  llvm::DenseMap<NamespaceDecl*, bool> KnownNamespaces;
+  llvm::MapVector<NamespaceDecl*, bool> KnownNamespaces;
 
   /// \brief Whether we have already loaded known namespaces from an extenal
   /// source.

Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=173538&r1=173537&r2=173538&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTBitCodes.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Fri Jan 25 18:35:08 2013
@@ -524,7 +524,11 @@ namespace clang {
 
       /// \brief Record of updates for a macro that was modified after
       /// being deserialized.
-      MACRO_UPDATES = 48
+      MACRO_UPDATES = 48,
+
+      /// \brief Record code for undefined but used internal functions and
+      /// variables.
+      UNDEFINED_INTERNALS = 49
     };
 
     /// \brief Record types used within a source manager block.

Modified: cfe/trunk/include/clang/Serialization/ASTReader.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTReader.h?rev=173538&r1=173537&r2=173538&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTReader.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTReader.h Fri Jan 25 18:35:08 2013
@@ -677,6 +677,9 @@ private:
   /// \brief A list of the namespaces we've seen.
   SmallVector<uint64_t, 4> KnownNamespaces;
 
+  /// \brief A list of undefined decls with internal linkage.
+  SmallVector<uint64_t, 8> UndefinedInternals;
+
   /// \brief A list of modules that were imported by precompiled headers or
   /// any other non-module AST file.
   SmallVector<serialization::SubmoduleID, 2> ImportedModules;
@@ -1505,6 +1508,9 @@ public:
   virtual void ReadKnownNamespaces(
                            SmallVectorImpl<NamespaceDecl *> &Namespaces);
 
+  virtual void ReadUndefinedInternals(
+                       llvm::MapVector<NamedDecl *, SourceLocation> &Undefined);
+
   virtual void ReadTentativeDefinitions(
                  SmallVectorImpl<VarDecl *> &TentativeDefs);
 
@@ -1675,13 +1681,13 @@ public:
 
   /// \brief Read a source location.
   SourceLocation ReadSourceLocation(ModuleFile &ModuleFile,
-                                    const RecordData &Record, unsigned& Idx) {
+                                    const RecordData &Record, unsigned &Idx) {
     return ReadSourceLocation(ModuleFile, Record[Idx++]);
   }
 
   /// \brief Read a source range.
   SourceRange ReadSourceRange(ModuleFile &F,
-                              const RecordData &Record, unsigned& Idx);
+                              const RecordData &Record, unsigned &Idx);
 
   /// \brief Read an integral value
   llvm::APInt ReadAPInt(const RecordData &Record, unsigned &Idx);

Modified: cfe/trunk/lib/Sema/MultiplexExternalSemaSource.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/MultiplexExternalSemaSource.cpp?rev=173538&r1=173537&r2=173538&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/MultiplexExternalSemaSource.cpp (original)
+++ cfe/trunk/lib/Sema/MultiplexExternalSemaSource.cpp Fri Jan 25 18:35:08 2013
@@ -200,6 +200,12 @@ void MultiplexExternalSemaSource::ReadKn
   for(size_t i = 0; i < Sources.size(); ++i)
     Sources[i]->ReadKnownNamespaces(Namespaces);
 }
+
+void MultiplexExternalSemaSource::ReadUndefinedInternals(
+                        llvm::MapVector<NamedDecl*, SourceLocation> &Undefined){
+  for(size_t i = 0; i < Sources.size(); ++i)
+    Sources[i]->ReadUndefinedInternals(Undefined);
+}
   
 bool MultiplexExternalSemaSource::LookupUnqualified(LookupResult &R, Scope *S){ 
   for(size_t i = 0; i < Sources.size(); ++i)

Modified: cfe/trunk/lib/Sema/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=173538&r1=173537&r2=173538&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.cpp (original)
+++ cfe/trunk/lib/Sema/Sema.cpp Fri Jan 25 18:35:08 2013
@@ -385,7 +385,7 @@ static void checkUndefinedInternals(Sema
 
   // Collect all the still-undefined entities with internal linkage.
   SmallVector<UndefinedInternal, 16> undefined;
-  for (llvm::DenseMap<NamedDecl*,SourceLocation>::iterator
+  for (llvm::MapVector<NamedDecl*,SourceLocation>::iterator
          i = S.UndefinedInternals.begin(), e = S.UndefinedInternals.end();
        i != e; ++i) {
     NamedDecl *decl = i->first;
@@ -407,23 +407,9 @@ static void checkUndefinedInternals(Sema
         continue;
     }
 
-    // We build a FullSourceLoc so that we can sort with array_pod_sort.
-    FullSourceLoc loc(i->second, S.Context.getSourceManager());
-    undefined.push_back(UndefinedInternal(decl, loc));
-  }
-
-  if (undefined.empty()) return;
-
-  // Sort (in order of use site) so that we're not (as) dependent on
-  // the iteration order through an llvm::DenseMap.
-  llvm::array_pod_sort(undefined.begin(), undefined.end());
-
-  for (SmallVectorImpl<UndefinedInternal>::iterator
-         i = undefined.begin(), e = undefined.end(); i != e; ++i) {
-    NamedDecl *decl = i->decl;
     S.Diag(decl->getLocation(), diag::warn_undefined_internal)
       << isa<VarDecl>(decl) << decl;
-    S.Diag(i->useLoc, diag::note_used_here);
+    S.Diag(i->second, diag::note_used_here);
   }
 }
 
@@ -736,6 +722,8 @@ void Sema::ActOnEndOfTranslationUnit() {
       }
     }
 
+    if (ExternalSource)
+      ExternalSource->ReadUndefinedInternals(UndefinedInternals);
     checkUndefinedInternals(*this);
   }
 
@@ -1080,6 +1068,10 @@ void ExternalSemaSource::ReadKnownNamesp
                            SmallVectorImpl<NamespaceDecl *> &Namespaces) {
 }
 
+void ExternalSemaSource::ReadUndefinedInternals(
+                      llvm::MapVector<NamedDecl *, SourceLocation> &Undefined) {
+}
+
 void PrettyDeclStackTraceEntry::print(raw_ostream &OS) const {
   SourceLocation Loc = this->Loc;
   if (!Loc.isValid() && TheDecl) Loc = TheDecl->getLocation();

Modified: cfe/trunk/lib/Sema/SemaLookup.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=173538&r1=173537&r2=173538&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaLookup.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLookup.cpp Fri Jan 25 18:35:08 2013
@@ -3857,7 +3857,7 @@ TypoCorrection Sema::CorrectTypo(const D
         KnownNamespaces[ExternalKnownNamespaces[I]] = true;
     }
     
-    for (llvm::DenseMap<NamespaceDecl*, bool>::iterator 
+    for (llvm::MapVector<NamespaceDecl*, bool>::iterator 
            KNI = KnownNamespaces.begin(),
            KNIEnd = KnownNamespaces.end();
          KNI != KNIEnd; ++KNI)

Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=173538&r1=173537&r2=173538&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Fri Jan 25 18:35:08 2013
@@ -2461,7 +2461,24 @@ bool ASTReader::ReadASTBlock(ModuleFile 
       for (unsigned I = 0, N = Record.size(); I != N; ++I)
         KnownNamespaces.push_back(getGlobalDeclID(F, Record[I]));
       break;
-        
+
+    case UNDEFINED_INTERNALS:
+      if (UndefinedInternals.size() % 2 != 0) {
+        Error("Invalid existing UndefinedInternals");
+        return true;
+      }
+
+      if (Record.size() % 2 != 0) {
+        Error("invalid undefined internals record");
+        return true;
+      }
+      for (unsigned I = 0, N = Record.size(); I != N; /* in loop */) {
+        UndefinedInternals.push_back(getGlobalDeclID(F, Record[I++]));
+        UndefinedInternals.push_back(
+            ReadSourceLocation(F, Record, I).getRawEncoding());
+      }
+      break;
+
     case IMPORTED_MODULES: {
       if (F.Kind != MK_Module) {
         // If we aren't loading a module (which has its own exports), make
@@ -5934,6 +5951,17 @@ void ASTReader::ReadKnownNamespaces(
   }
 }
 
+void ASTReader::ReadUndefinedInternals(
+                       llvm::MapVector<NamedDecl*, SourceLocation> &Undefined) {
+  for (unsigned Idx = 0, N = UndefinedInternals.size(); Idx != N;) {
+    NamedDecl *D = cast<NamedDecl>(GetDecl(UndefinedInternals[Idx++]));
+    SourceLocation Loc =
+        SourceLocation::getFromRawEncoding(UndefinedInternals[Idx++]);
+    Undefined.insert(std::make_pair(D, Loc));
+  }
+}
+    
+
 void ASTReader::ReadTentativeDefinitions(
                   SmallVectorImpl<VarDecl *> &TentativeDefs) {
   for (unsigned I = 0, N = TentativeDefinitions.size(); I != N; ++I) {

Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=173538&r1=173537&r2=173538&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Fri Jan 25 18:35:08 2013
@@ -824,6 +824,7 @@ void ASTWriter::WriteBlockInfoBlock() {
   RECORD(OPENCL_EXTENSIONS);
   RECORD(DELEGATING_CTORS);
   RECORD(KNOWN_NAMESPACES);
+  RECORD(UNDEFINED_INTERNALS);
   RECORD(MODULE_OFFSET_MAP);
   RECORD(SOURCE_MANAGER_LINE_TABLE);
   RECORD(OBJC_CATEGORIES_MAP);
@@ -3581,7 +3582,7 @@ void ASTWriter::WriteASTCore(Sema &SemaR
 
   // Build a record containing all of the known namespaces.
   RecordData KnownNamespaces;
-  for (llvm::DenseMap<NamespaceDecl*, bool>::iterator 
+  for (llvm::MapVector<NamespaceDecl*, bool>::iterator
             I = SemaRef.KnownNamespaces.begin(),
          IEnd = SemaRef.KnownNamespaces.end();
        I != IEnd; ++I) {
@@ -3589,6 +3590,16 @@ void ASTWriter::WriteASTCore(Sema &SemaR
       AddDeclRef(I->first, KnownNamespaces);
   }
 
+  // Build a record of all used, undefined objects with internal linkage.
+  RecordData UndefinedInternals;
+  for (llvm::MapVector<NamedDecl*, SourceLocation>::iterator
+            I = SemaRef.UndefinedInternals.begin(),
+         IEnd = SemaRef.UndefinedInternals.end();
+       I != IEnd; ++I) {
+    AddDeclRef(I->first, UndefinedInternals);
+    AddSourceLocation(I->second, UndefinedInternals);
+  }
+
   // Write the control block
   WriteControlBlock(PP, Context, isysroot, OutputFile);
 
@@ -3803,6 +3814,10 @@ void ASTWriter::WriteASTCore(Sema &SemaR
   // Write the known namespaces.
   if (!KnownNamespaces.empty())
     Stream.EmitRecord(KNOWN_NAMESPACES, KnownNamespaces);
+
+  // Write the undefined internal functions and variables.
+  if (!UndefinedInternals.empty())
+    Stream.EmitRecord(UNDEFINED_INTERNALS, UndefinedInternals);
   
   // Write the visible updates to DeclContexts.
   for (llvm::SmallPtrSet<const DeclContext *, 16>::iterator

Added: cfe/trunk/test/PCH/undefined-internal.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/undefined-internal.c?rev=173538&view=auto
==============================================================================
--- cfe/trunk/test/PCH/undefined-internal.c (added)
+++ cfe/trunk/test/PCH/undefined-internal.c Fri Jan 25 18:35:08 2013
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -emit-pch %s -o %t
+// RUN: %clang_cc1 -include-pch %t %s -verify
+#ifndef HEADER_H
+#define HEADER_H
+static void f();
+static void g();
+void h() {
+  f();
+  g();
+}
+#else
+static void g() {}
+// expected-warning at 5{{function 'f' has internal linkage but is not defined}}
+// expected-note at 8{{used here}}
+#endif





More information about the cfe-commits mailing list