From 9891212476a7832851ca137ca281e2cbb9412899 Mon Sep 17 00:00:00 2001 From: Sebastian Redl Date: Tue, 27 Jul 2010 23:01:28 +0000 Subject: [PATCH] Record macros in dependent PCHs. Also add various info tables to dependent PCHs; tests for this to follow. llvm-svn: 109554 --- clang/include/clang/Lex/MacroInfo.h | 9 +++ clang/include/clang/Lex/Preprocessor.h | 2 +- clang/lib/Frontend/PCHReader.cpp | 3 +- clang/lib/Frontend/PCHWriter.cpp | 77 +++++++++++++++++++++++--- clang/lib/Lex/MacroInfo.cpp | 1 + clang/test/PCH/Inputs/chain-macro1.h | 1 + clang/test/PCH/Inputs/chain-macro2.h | 1 + clang/test/PCH/chain-macro.c | 9 +++ 8 files changed, 93 insertions(+), 10 deletions(-) create mode 100644 clang/test/PCH/Inputs/chain-macro1.h create mode 100644 clang/test/PCH/Inputs/chain-macro2.h create mode 100644 clang/test/PCH/chain-macro.c diff --git a/clang/include/clang/Lex/MacroInfo.h b/clang/include/clang/Lex/MacroInfo.h index 5887041c46b9..6d5896c2d525 100644 --- a/clang/include/clang/Lex/MacroInfo.h +++ b/clang/include/clang/Lex/MacroInfo.h @@ -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; } diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h index debba38a7020..6fd19437f893 100644 --- a/clang/include/clang/Lex/Preprocessor.h +++ b/clang/include/clang/Lex/Preprocessor.h @@ -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. diff --git a/clang/lib/Frontend/PCHReader.cpp b/clang/lib/Frontend/PCHReader.cpp index a0e3148bc73e..bdc02020b406 100644 --- a/clang/lib/Frontend/PCHReader.cpp +++ b/clang/lib/Frontend/PCHReader.cpp @@ -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) { diff --git a/clang/lib/Frontend/PCHWriter.cpp b/clang/lib/Frontend/PCHWriter.cpp index 96c64169cf3f..f475db5c5bc1 100644 --- a/clang/lib/Frontend/PCHWriter.cpp +++ b/clang/lib/Frontend/PCHWriter.cpp @@ -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(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::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(); } diff --git a/clang/lib/Lex/MacroInfo.cpp b/clang/lib/Lex/MacroInfo.cpp index fda884c4da4c..7a09986e3dd1 100644 --- a/clang/lib/Lex/MacroInfo.cpp +++ b/clang/lib/Lex/MacroInfo.cpp @@ -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/clang/test/PCH/Inputs/chain-macro1.h b/clang/test/PCH/Inputs/chain-macro1.h new file mode 100644 index 000000000000..2e80e47aead0 --- /dev/null +++ b/clang/test/PCH/Inputs/chain-macro1.h @@ -0,0 +1 @@ +#define FOOBAR void f(); diff --git a/clang/test/PCH/Inputs/chain-macro2.h b/clang/test/PCH/Inputs/chain-macro2.h new file mode 100644 index 000000000000..e888228a4c00 --- /dev/null +++ b/clang/test/PCH/Inputs/chain-macro2.h @@ -0,0 +1 @@ +#define BARFOO void g(); diff --git a/clang/test/PCH/chain-macro.c b/clang/test/PCH/chain-macro.c new file mode 100644 index 000000000000..b4dcdfe644d7 --- /dev/null +++ b/clang/test/PCH/chain-macro.c @@ -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