summaryrefslogtreecommitdiffstats
path: root/clang/lib/Frontend
diff options
context:
space:
mode:
authorSebastian Redl <sebastian.redl@getdesigned.at>2010-07-30 00:29:29 +0000
committerSebastian Redl <sebastian.redl@getdesigned.at>2010-07-30 00:29:29 +0000
commit07a89a83d4db0b3f241c70d5bbb518631ff90cfd (patch)
tree04d2e40c51deb9492c53f280f108ba097a08c087 /clang/lib/Frontend
parent0c7476ad590d2263111430b5654127d2003afdca (diff)
downloadbcm5719-llvm-07a89a83d4db0b3f241c70d5bbb518631ff90cfd.tar.gz
bcm5719-llvm-07a89a83d4db0b3f241c70d5bbb518631ff90cfd.zip
Make macro weirdness in chained PCH work. This required changing the way PCHReader and PCHWriter are initialized to correctly pick up all initializer. On the upside, this means that there is far less repetition in the dependent PCH now.
llvm-svn: 109823
Diffstat (limited to 'clang/lib/Frontend')
-rw-r--r--clang/lib/Frontend/CompilerInstance.cpp15
-rw-r--r--clang/lib/Frontend/FrontendAction.cpp13
-rw-r--r--clang/lib/Frontend/FrontendActions.cpp6
-rw-r--r--clang/lib/Frontend/GeneratePCH.cpp19
-rw-r--r--clang/lib/Frontend/PCHReader.cpp29
-rw-r--r--clang/lib/Frontend/PCHWriter.cpp36
6 files changed, 76 insertions, 42 deletions
diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp
index ea295687aa0..84e51837bc8 100644
--- a/clang/lib/Frontend/CompilerInstance.cpp
+++ b/clang/lib/Frontend/CompilerInstance.cpp
@@ -37,7 +37,7 @@
using namespace clang;
CompilerInstance::CompilerInstance()
- : Invocation(new CompilerInvocation()), Reader(0) {
+ : Invocation(new CompilerInvocation()) {
}
CompilerInstance::~CompilerInstance() {
@@ -251,13 +251,13 @@ void CompilerInstance::createASTContext() {
// ExternalASTSource
void CompilerInstance::createPCHExternalASTSource(llvm::StringRef Path,
- bool DisablePCHValidation) {
+ bool DisablePCHValidation,
+ void *DeserializationListener){
llvm::OwningPtr<ExternalASTSource> Source;
Source.reset(createPCHExternalASTSource(Path, getHeaderSearchOpts().Sysroot,
DisablePCHValidation,
- getPreprocessor(), getASTContext()));
- // Remember the PCHReader, but in a non-owning way.
- Reader = static_cast<PCHReader*>(Source.get());
+ getPreprocessor(), getASTContext(),
+ DeserializationListener));
getASTContext().setExternalSource(Source);
}
@@ -266,12 +266,15 @@ CompilerInstance::createPCHExternalASTSource(llvm::StringRef Path,
const std::string &Sysroot,
bool DisablePCHValidation,
Preprocessor &PP,
- ASTContext &Context) {
+ ASTContext &Context,
+ void *DeserializationListener) {
llvm::OwningPtr<PCHReader> Reader;
Reader.reset(new PCHReader(PP, &Context,
Sysroot.empty() ? 0 : Sysroot.c_str(),
DisablePCHValidation));
+ Reader->setDeserializationListener(
+ static_cast<PCHDeserializationListener *>(DeserializationListener));
switch (Reader->ReadPCH(Path)) {
case PCHReader::Success:
// Set the predefines buffer as suggested by the PCH reader. Typically, the
diff --git a/clang/lib/Frontend/FrontendAction.cpp b/clang/lib/Frontend/FrontendAction.cpp
index 9efa8c61db8..90b87864b83 100644
--- a/clang/lib/Frontend/FrontendAction.cpp
+++ b/clang/lib/Frontend/FrontendAction.cpp
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include "clang/Frontend/FrontendAction.h"
+#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/Lex/HeaderSearch.h"
#include "clang/Lex/Preprocessor.h"
@@ -112,19 +113,21 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
if (!usesPreprocessorOnly()) {
CI.createASTContext();
- /// Use PCH? If so, we want the PCHReader active before the consumer
- /// is created, because the consumer might be interested in the reader
- /// (e.g. the PCH writer for chaining).
+ llvm::OwningPtr<ASTConsumer> Consumer(CreateASTConsumer(CI, Filename));
+
+ /// Use PCH?
if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) {
assert(hasPCHSupport() && "This action does not have PCH support!");
CI.createPCHExternalASTSource(
CI.getPreprocessorOpts().ImplicitPCHInclude,
- CI.getPreprocessorOpts().DisablePCHValidation);
+ CI.getPreprocessorOpts().DisablePCHValidation,
+ CI.getInvocation().getFrontendOpts().ChainedPCH?
+ Consumer->GetPCHDeserializationListener() : 0);
if (!CI.getASTContext().getExternalSource())
goto failure;
}
- CI.setASTConsumer(CreateASTConsumer(CI, Filename));
+ CI.setASTConsumer(Consumer.take());
if (!CI.hasASTConsumer())
goto failure;
}
diff --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp
index 2d1287f85b6..b0f85f1ad6d 100644
--- a/clang/lib/Frontend/FrontendActions.cpp
+++ b/clang/lib/Frontend/FrontendActions.cpp
@@ -81,11 +81,11 @@ ASTConsumer *GeneratePCHAction::CreateASTConsumer(CompilerInstance &CI,
if (!OS)
return 0;
- PCHReader *Chain = CI.getInvocation().getFrontendOpts().ChainedPCH ?
- CI.getPCHReader() : 0;
+ bool Chaining = CI.getInvocation().getFrontendOpts().ChainedPCH &&
+ !CI.getPreprocessorOpts().ImplicitPCHInclude.empty();
const char *isysroot = CI.getFrontendOpts().RelocatablePCH ?
Sysroot.c_str() : 0;
- return CreatePCHGenerator(CI.getPreprocessor(), OS, Chain, isysroot);
+ return CreatePCHGenerator(CI.getPreprocessor(), OS, Chaining, isysroot);
}
ASTConsumer *InheritanceViewAction::CreateASTConsumer(CompilerInstance &CI,
diff --git a/clang/lib/Frontend/GeneratePCH.cpp b/clang/lib/Frontend/GeneratePCH.cpp
index 422a4b62647..561a68a6ef6 100644
--- a/clang/lib/Frontend/GeneratePCH.cpp
+++ b/clang/lib/Frontend/GeneratePCH.cpp
@@ -37,19 +37,20 @@ namespace {
PCHWriter Writer;
public:
- PCHGenerator(const Preprocessor &PP, PCHReader *Chain,
+ PCHGenerator(const Preprocessor &PP, bool Chaining,
const char *isysroot, llvm::raw_ostream *Out);
virtual void InitializeSema(Sema &S) { SemaPtr = &S; }
virtual void HandleTranslationUnit(ASTContext &Ctx);
+ virtual PCHDeserializationListener *GetPCHDeserializationListener();
};
}
PCHGenerator::PCHGenerator(const Preprocessor &PP,
- PCHReader *Chain,
+ bool Chaining,
const char *isysroot,
llvm::raw_ostream *OS)
- : PP(PP), isysroot(isysroot), Out(OS), SemaPtr(0), StatCalls(0),
- Stream(Buffer), Writer(Stream, Chain) {
+ : PP(PP), isysroot(isysroot), Out(OS), SemaPtr(0),
+ StatCalls(0), Stream(Buffer), Writer(Stream) {
// Install a stat() listener to keep track of all of the stat()
// calls.
@@ -57,7 +58,7 @@ PCHGenerator::PCHGenerator(const Preprocessor &PP,
// If we have a chain, we want new stat calls only, so install the memorizer
// *after* the already installed PCHReader's stat cache.
PP.getFileManager().addStatCache(StatCalls,
- /*AtBeginning=*/!Chain);
+ /*AtBeginning=*/!Chaining);
}
void PCHGenerator::HandleTranslationUnit(ASTContext &Ctx) {
@@ -78,9 +79,13 @@ void PCHGenerator::HandleTranslationUnit(ASTContext &Ctx) {
Buffer.clear();
}
+PCHDeserializationListener *PCHGenerator::GetPCHDeserializationListener() {
+ return &Writer;
+}
+
ASTConsumer *clang::CreatePCHGenerator(const Preprocessor &PP,
llvm::raw_ostream *OS,
- PCHReader *Chain,
+ bool Chaining,
const char *isysroot) {
- return new PCHGenerator(PP, Chain, isysroot, OS);
+ return new PCHGenerator(PP, Chaining, isysroot, OS);
}
diff --git a/clang/lib/Frontend/PCHReader.cpp b/clang/lib/Frontend/PCHReader.cpp
index 69922b0d0fa..6fa7294f870 100644
--- a/clang/lib/Frontend/PCHReader.cpp
+++ b/clang/lib/Frontend/PCHReader.cpp
@@ -460,6 +460,13 @@ PCHReader::PerFileData::PerFileData()
NumPreallocatedPreprocessingEntities(0)
{}
+void
+PCHReader::setDeserializationListener(PCHDeserializationListener *Listener) {
+ DeserializationListener = Listener;
+ if (DeserializationListener)
+ DeserializationListener->SetReader(this);
+}
+
namespace {
class PCHMethodPoolLookupTrait {
@@ -637,9 +644,9 @@ public:
// and associate it with the persistent ID.
IdentifierInfo *II = KnownII;
if (!II)
- II = &Reader.getIdentifierTable().CreateIdentifierInfo(
- k.first, k.first + k.second);
+ II = &Reader.getIdentifierTable().getOwn(k.first, k.first + k.second);
Reader.SetIdentifierInfo(ID, II);
+ II->setIsFromPCH();
return II;
}
@@ -662,8 +669,7 @@ public:
// the new IdentifierInfo.
IdentifierInfo *II = KnownII;
if (!II)
- II = &Reader.getIdentifierTable().CreateIdentifierInfo(
- k.first, k.first + k.second);
+ II = &Reader.getIdentifierTable().getOwn(k.first, k.first + k.second);
Reader.SetIdentifierInfo(ID, II);
// Set or check the various bits in the IdentifierInfo structure.
@@ -683,6 +689,9 @@ public:
uint32_t Offset = ReadUnalignedLE32(d);
Reader.ReadMacroRecord(Stream, Offset);
DataLen -= 4;
+ } else if (II->hasMacroDefinition() && !Reader.isBuiltinMacro(II)) {
+ // A previous part of the chain added a macro, but this part #undefed it.
+ Reader.EraseMacro(II);
}
// Read all of the declarations visible at global scope with this
@@ -695,6 +704,7 @@ public:
Reader.SetGloballyVisibleDecls(II, DeclIDs);
}
+ II->setIsFromPCH();
return II;
}
};
@@ -1379,6 +1389,15 @@ MacroDefinition *PCHReader::getMacroDefinition(pch::IdentID ID) {
return MacroDefinitionsLoaded[ID];
}
+void PCHReader::EraseMacro(IdentifierInfo *II) {
+ PP->setMacroInfo(II, 0);
+}
+
+bool PCHReader::isBuiltinMacro(IdentifierInfo *II) {
+ assert(II->hasMacroDefinition() && "Identifier is not a macro");
+ return PP->getMacroInfo(II)->isBuiltinMacro();
+}
+
/// \brief If we are loading a relocatable PCH file, and the filename is
/// not an absolute path, add the system root to the beginning of the file
/// name.
@@ -1797,8 +1816,6 @@ PCHReader::PCHReadResult PCHReader::ReadPCH(const std::string &FileName) {
Id != IdEnd; ++Id)
Identifiers.push_back(Id->second);
// We need to search the tables in all files.
- // FIXME: What happens if this stuff changes between files, e.g. the
- // dependent PCH undefs a macro from the core file?
for (unsigned J = 0, M = Chain.size(); J != M; ++J) {
PCHIdentifierLookupTable *IdTable
= (PCHIdentifierLookupTable *)Chain[J]->IdentifierLookupTable;
diff --git a/clang/lib/Frontend/PCHWriter.cpp b/clang/lib/Frontend/PCHWriter.cpp
index f475db5c5bc..b574656bb6d 100644
--- a/clang/lib/Frontend/PCHWriter.cpp
+++ b/clang/lib/Frontend/PCHWriter.cpp
@@ -1810,7 +1810,8 @@ public:
for (IdentifierResolver::iterator D = IdentifierResolver::begin(II),
DEnd = IdentifierResolver::end();
D != DEnd; ++D)
- DataLen += sizeof(pch::DeclID);
+ if (!Writer.hasChain() || (*D)->getPCHLevel() == 0)
+ DataLen += sizeof(pch::DeclID);
}
clang::io::Emit16(Out, DataLen);
// We emit the key length after the data length so that every
@@ -1898,9 +1899,7 @@ void PCHWriter::WriteIdentifierTable(Preprocessor &PP) {
ID = IdentifierIDs.begin(), IDEnd = IdentifierIDs.end();
ID != IDEnd; ++ID) {
assert(ID->first && "NULL identifier in identifier table");
- // FIXME: Right now, we only write identifiers that are new to this file.
- // We need to write older identifiers that changed too, though.
- if (ID->second >= FirstIdentID)
+ if (!Chain || !ID->first->isFromPCH())
Generator.insert(ID->first, ID->second);
}
@@ -2142,17 +2141,11 @@ void PCHWriter::SetSelectorOffset(Selector Sel, uint32_t Offset) {
SelectorOffsets[ID - 1] = Offset;
}
-PCHWriter::PCHWriter(llvm::BitstreamWriter &Stream, PCHReader *Chain)
- : Stream(Stream), Chain(Chain), FirstDeclID(1),
+PCHWriter::PCHWriter(llvm::BitstreamWriter &Stream)
+ : Stream(Stream), Chain(0), FirstDeclID(1),
FirstTypeID(pch::NUM_PREDEF_TYPE_IDS), FirstIdentID(1),
CollectedStmts(&StmtsToEmit), NumStatements(0), NumMacros(0),
NumLexicalDeclContexts(0), NumVisibleDeclContexts(0) {
- if (Chain) {
- Chain->setDeserializationListener(this);
- FirstDeclID += Chain->getTotalNumDecls();
- FirstTypeID += Chain->getTotalNumTypes();
- FirstIdentID += Chain->getTotalNumIdentifiers();
- }
NextDeclID = FirstDeclID;
NextTypeID = FirstTypeID;
NextIdentID = FirstIdentID;
@@ -2335,6 +2328,13 @@ void PCHWriter::WritePCHChain(Sema &SemaRef, MemorizeStatCalls *StatCalls,
const char *isysroot) {
using namespace llvm;
+ FirstDeclID += Chain->getTotalNumDecls();
+ FirstTypeID += Chain->getTotalNumTypes();
+ FirstIdentID += Chain->getTotalNumIdentifiers();
+ NextDeclID = FirstDeclID;
+ NextTypeID = FirstTypeID;
+ NextIdentID = FirstIdentID;
+
ASTContext &Context = SemaRef.Context;
Preprocessor &PP = SemaRef.PP;
@@ -2352,9 +2352,6 @@ void PCHWriter::WritePCHChain(Sema &SemaRef, MemorizeStatCalls *StatCalls,
// We don't start with the translation unit, but with its decls that
// don't come from the other PCH.
const TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
- // The TU was loaded before we managed to register ourselves as a listener.
- // Thus we need to add it manually.
- DeclIDs[TU] = 1;
llvm::SmallVector<pch::DeclID, 64> NewGlobalDecls;
for (DeclContext::decl_iterator I = TU->noload_decls_begin(),
E = TU->noload_decls_end();
@@ -2868,6 +2865,15 @@ void PCHWriter::AddCXXBaseSpecifier(const CXXBaseSpecifier &Base,
AddSourceRange(Base.getSourceRange(), Record);
}
+void PCHWriter::SetReader(PCHReader *Reader) {
+ assert(Reader && "Cannot remove chain");
+ assert(FirstDeclID == NextDeclID &&
+ FirstTypeID == NextTypeID &&
+ FirstIdentID == NextIdentID &&
+ "Setting chain after writing has started.");
+ Chain = Reader;
+}
+
void PCHWriter::IdentifierRead(pch::IdentID ID, IdentifierInfo *II) {
IdentifierIDs[II] = ID;
}
OpenPOWER on IntegriCloud