]> granicus.if.org Git - clang/commitdiff
Record macros in dependent PCHs. Also add various info tables to dependent PCHs;...
authorSebastian Redl <sebastian.redl@getdesigned.at>
Tue, 27 Jul 2010 23:01:28 +0000 (23:01 +0000)
committerSebastian Redl <sebastian.redl@getdesigned.at>
Tue, 27 Jul 2010 23:01:28 +0000 (23:01 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@109554 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Lex/MacroInfo.h
include/clang/Lex/Preprocessor.h
lib/Frontend/PCHReader.cpp
lib/Frontend/PCHWriter.cpp
lib/Lex/MacroInfo.cpp
test/PCH/Inputs/chain-macro1.h [new file with mode: 0644]
test/PCH/Inputs/chain-macro2.h [new file with mode: 0644]
test/PCH/chain-macro.c [new file with mode: 0644]

index 5887041c46b9fa487069bfc1edced6408780f212..6d5896c2d52534e5a71d20551da48f54df7c29b4 100644 (file)
@@ -62,6 +62,9 @@ class MacroInfo {
   /// it has not yet been redefined or undefined.
   bool IsBuiltinMacro : 1;
 
+  /// IsFromPCH - True if this macro was loaded from a PCH file.
+  bool IsFromPCH : 1;
+
 private:
   //===--------------------------------------------------------------------===//
   // State that changes as the macro is used.
@@ -172,6 +175,12 @@ public:
   /// __LINE__, which requires processing before expansion.
   bool isBuiltinMacro() const { return IsBuiltinMacro; }
 
+  /// isFromPCH - Return true if this macro was loaded from a PCH file.
+  bool isFromPCH() const { return IsFromPCH; }
+
+  /// setIsFromPCH - Set whether this macro was loaded from a PCH file.
+  void setIsFromPCH(bool FromPCH = true) { IsFromPCH = FromPCH; }
+
   /// isUsed - Return false if this macro is defined in the main file and has
   /// not yet been used.
   bool isUsed() const { return IsUsed; }
index debba38a7020c9a409d5d5d74fd43e7074551a78..6fd19437f893ccd373176d6463b4b2fe9fa2d088 100644 (file)
@@ -117,7 +117,7 @@ class Preprocessor {
   /// conceptually similar the IdentifierTable. In addition, the current control
   /// flow (in clang::ParseAST()), make it convenient to put here.
   /// FIXME: Make sure the lifetime of Identifiers/Selectors *isn't* tied to
-  /// the lifetime fo the preprocessor.
+  /// the lifetime of the preprocessor.
   SelectorTable Selectors;
 
   /// BuiltinInfo - Information about builtins.
index a0e3148bc73e1141b3b2f0058d3b1152b46dced5..bdc02020b406aa192cf5744bccf19f1f15064985 100644 (file)
@@ -633,7 +633,7 @@ public:
     ID = ID >> 1;
 
     if (!IsInteresting) {
-      // For unintersting identifiers, just build the IdentifierInfo
+      // For uninteresting identifiers, just build the IdentifierInfo
       // and associate it with the persistent ID.
       IdentifierInfo *II = KnownII;
       if (!II)
@@ -1176,6 +1176,7 @@ void PCHReader::ReadMacroRecord(llvm::BitstreamCursor &Stream, uint64_t Offset){
 
       MacroInfo *MI = PP->AllocateMacroInfo(Loc);
       MI->setIsUsed(isUsed);
+      MI->setIsFromPCH();
 
       unsigned NextIndex = 3;
       if (RecType == pch::PP_MACRO_FUNCTION_LIKE) {
index 96c64169cf3f992ca23519eb251fe948b04a767c..f475db5c5bc15cb08a12c1f3fda22328c05342ff 100644 (file)
@@ -1262,7 +1262,8 @@ void PCHWriter::WritePreprocessor(const Preprocessor &PP) {
 
     // Don't emit builtin macros like __LINE__ to the PCH file unless they have
     // been redefined by the header (in which case they are not isBuiltinMacro).
-    if (MI->isBuiltinMacro())
+    // Also skip macros from a PCH file if we're chaining.
+    if (MI->isBuiltinMacro() || (Chain && MI->isFromPCH()))
       continue;
 
     AddIdentifierRef(I->first, Record);
@@ -2372,6 +2373,42 @@ void PCHWriter::WritePCHChain(Sema &SemaRef, MemorizeStatCalls *StatCalls,
                           reinterpret_cast<const char*>(NewGlobalDecls.data()),
                           NewGlobalDecls.size() * sizeof(pch::DeclID));
 
+  // Build a record containing all of the new tentative definitions in this
+  // file, in TentativeDefinitions order.
+  RecordData TentativeDefinitions;
+  for (unsigned i = 0, e = SemaRef.TentativeDefinitions.size(); i != e; ++i) {
+    if (SemaRef.TentativeDefinitions[i]->getPCHLevel() == 0)
+      AddDeclRef(SemaRef.TentativeDefinitions[i], TentativeDefinitions);
+  }
+
+  // Build a record containing all of the static unused functions in this file.
+  RecordData UnusedStaticFuncs;
+  for (unsigned i=0, e = SemaRef.UnusedStaticFuncs.size(); i !=e; ++i) {
+    if (SemaRef.UnusedStaticFuncs[i]->getPCHLevel() == 0)
+      AddDeclRef(SemaRef.UnusedStaticFuncs[i], UnusedStaticFuncs);
+  }
+
+  // Build a record containing all of the locally-scoped external
+  // declarations in this header file. Generally, this record will be
+  // empty.
+  RecordData LocallyScopedExternalDecls;
+  // FIXME: This is filling in the PCH file in densemap order which is
+  // nondeterminstic!
+  for (llvm::DenseMap<DeclarationName, NamedDecl *>::iterator
+         TD = SemaRef.LocallyScopedExternalDecls.begin(),
+         TDEnd = SemaRef.LocallyScopedExternalDecls.end();
+       TD != TDEnd; ++TD) {
+    if (TD->second->getPCHLevel() == 0)
+      AddDeclRef(TD->second, LocallyScopedExternalDecls);
+  }
+
+  // Build a record containing all of the ext_vector declarations.
+  RecordData ExtVectorDecls;
+  for (unsigned I = 0, N = SemaRef.ExtVectorDecls.size(); I != N; ++I) {
+    if (SemaRef.ExtVectorDecls[I]->getPCHLevel() == 0)
+      AddDeclRef(SemaRef.ExtVectorDecls[I], ExtVectorDecls);
+  }
+
   Stream.EnterSubblock(pch::DECLTYPES_BLOCK_ID, 3);
   WriteDeclsBlockAbbrevs();
   while (!DeclTypesToEmit.empty()) {
@@ -2384,17 +2421,41 @@ void PCHWriter::WritePCHChain(Sema &SemaRef, MemorizeStatCalls *StatCalls,
   }
   Stream.ExitBlock();
 
-  // FIXME: Preprocessor
+  WritePreprocessor(PP);
   // FIXME: Method pool
   WriteIdentifierTable(PP);
   WriteTypeDeclOffsets();
-  // FIXME: External unnamed definitions
-  // FIXME: Tentative definitions
-  // FIXME: Unused static functions
-  // FIXME: Locally-scoped external definitions
-  // FIXME: ext_vector type names
+
+  // Write the record containing external, unnamed definitions.
+  if (!ExternalDefinitions.empty())
+    Stream.EmitRecord(pch::EXTERNAL_DEFINITIONS, ExternalDefinitions);
+
+  // Write the record containing tentative definitions.
+  if (!TentativeDefinitions.empty())
+    Stream.EmitRecord(pch::TENTATIVE_DEFINITIONS, TentativeDefinitions);
+
+  // Write the record containing unused static functions.
+  if (!UnusedStaticFuncs.empty())
+    Stream.EmitRecord(pch::UNUSED_STATIC_FUNCS, UnusedStaticFuncs);
+
+  // Write the record containing locally-scoped external definitions.
+  if (!LocallyScopedExternalDecls.empty())
+    Stream.EmitRecord(pch::LOCALLY_SCOPED_EXTERNAL_DECLS,
+                      LocallyScopedExternalDecls);
+
+  // Write the record containing ext_vector type names.
+  if (!ExtVectorDecls.empty())
+    Stream.EmitRecord(pch::EXT_VECTOR_DECLS, ExtVectorDecls);
+
+  // FIXME: Vtable uses
   // FIXME: Dynamic classes declarations
-  // FIXME: Statistics
+
+  Record.clear();
+  Record.push_back(NumStatements);
+  Record.push_back(NumMacros);
+  Record.push_back(NumLexicalDeclContexts);
+  Record.push_back(NumVisibleDeclContexts);
+  Stream.EmitRecord(pch::STATISTICS, Record);
   Stream.ExitBlock();
 }
 
index fda884c4da4c32b0955813df695b04f9e5c0c72e..7a09986e3dd133432a9a37a70dd8ee8b26da164f 100644 (file)
@@ -20,6 +20,7 @@ MacroInfo::MacroInfo(SourceLocation DefLoc) : Location(DefLoc) {
   IsC99Varargs = false;
   IsGNUVarargs = false;
   IsBuiltinMacro = false;
+  IsFromPCH = false;
   IsDisabled = false;
   IsUsed = true;
 
diff --git a/test/PCH/Inputs/chain-macro1.h b/test/PCH/Inputs/chain-macro1.h
new file mode 100644 (file)
index 0000000..2e80e47
--- /dev/null
@@ -0,0 +1 @@
+#define FOOBAR void f();
diff --git a/test/PCH/Inputs/chain-macro2.h b/test/PCH/Inputs/chain-macro2.h
new file mode 100644 (file)
index 0000000..e888228
--- /dev/null
@@ -0,0 +1 @@
+#define BARFOO void g();
diff --git a/test/PCH/chain-macro.c b/test/PCH/chain-macro.c
new file mode 100644 (file)
index 0000000..b4dcdfe
--- /dev/null
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -emit-pch -o %t1 %S/Inputs/chain-macro1.h
+// RUN: %clang_cc1 -emit-pch -o %t2 %S/Inputs/chain-macro2.h -include-pch %t1 -chained-pch
+// RUN: %clang_cc1 -fsyntax-only -verify -include-pch %t2 %s
+// RUN: %clang_cc1 -ast-print -include-pch %t2 %s | FileCheck %s
+
+// CHECK: void f();
+FOOBAR
+// CHECK: void g();
+BARFOO