Implement chained PCH support for the macro definitions stored within

the "detailed" preprocessing record.

llvm-svn: 115417
This commit is contained in:
Douglas Gregor 2010-10-02 19:29:26 +00:00
parent a2f2c27b20
commit 9109629e55
7 changed files with 66 additions and 25 deletions

View File

@ -22,6 +22,7 @@ namespace clang {
class Decl; class Decl;
class ASTReader; class ASTReader;
class QualType; class QualType;
class MacroDefinition;
class ASTDeserializationListener { class ASTDeserializationListener {
protected: protected:
@ -42,6 +43,9 @@ public:
virtual void DeclRead(serialization::DeclID ID, const Decl *D) = 0; virtual void DeclRead(serialization::DeclID ID, const Decl *D) = 0;
/// \brief A selector was read from the AST file. /// \brief A selector was read from the AST file.
virtual void SelectorRead(serialization::SelectorID iD, Selector Sel) = 0; virtual void SelectorRead(serialization::SelectorID iD, Selector Sel) = 0;
/// \brief A macro definition was read from the AST file.
virtual void MacroDefinitionRead(serialization::MacroID,
MacroDefinition *MD) = 0;
}; };
} }

View File

@ -829,6 +829,11 @@ public:
return static_cast<unsigned>(SelectorsLoaded.size()); return static_cast<unsigned>(SelectorsLoaded.size());
} }
/// \brief Returns the number of macro definitions found in the chain.
unsigned getTotalNumMacroDefinitions() const {
return static_cast<unsigned>(MacroDefinitionsLoaded.size());
}
/// \brief Reads a TemplateArgumentLocInfo appropriate for the /// \brief Reads a TemplateArgumentLocInfo appropriate for the
/// given TemplateArgument kind. /// given TemplateArgument kind.
TemplateArgumentLocInfo TemplateArgumentLocInfo

View File

@ -172,6 +172,12 @@ private:
/// defined. /// defined.
llvm::DenseMap<const IdentifierInfo *, uint64_t> MacroOffsets; llvm::DenseMap<const IdentifierInfo *, uint64_t> MacroOffsets;
/// \brief The first ID number we can use for our own macro definitions.
serialization::MacroID FirstMacroID;
/// \brief The decl ID that will be assigned to the next new macro definition.
serialization::MacroID NextMacroID;
/// \brief Mapping from macro definitions (as they occur in the preprocessing /// \brief Mapping from macro definitions (as they occur in the preprocessing
/// record) to the macro IDs. /// record) to the macro IDs.
llvm::DenseMap<const MacroDefinition *, serialization::MacroID> llvm::DenseMap<const MacroDefinition *, serialization::MacroID>
@ -481,7 +487,8 @@ public:
void IdentifierRead(serialization::IdentID ID, IdentifierInfo *II); void IdentifierRead(serialization::IdentID ID, IdentifierInfo *II);
void TypeRead(serialization::TypeIdx Idx, QualType T); void TypeRead(serialization::TypeIdx Idx, QualType T);
void DeclRead(serialization::DeclID ID, const Decl *D); void DeclRead(serialization::DeclID ID, const Decl *D);
void SelectorRead(serialization::SelectorID iD, Selector Sel); void SelectorRead(serialization::SelectorID ID, Selector Sel);
void MacroDefinitionRead(serialization::MacroID ID, MacroDefinition *MD);
}; };
/// \brief AST and semantic-analysis consumer that generates a /// \brief AST and semantic-analysis consumer that generates a

View File

@ -1493,19 +1493,29 @@ void ASTReader::ReadMacroRecord(llvm::BitstreamCursor &Stream, uint64_t Offset){
if (PPRec.getPreprocessedEntity(Record[0])) if (PPRec.getPreprocessedEntity(Record[0]))
return; return;
if (Record[1] >= MacroDefinitionsLoaded.size()) { if (Record[1] > MacroDefinitionsLoaded.size()) {
Error("out-of-bounds macro definition record"); Error("out-of-bounds macro definition record");
return; return;
} }
MacroDefinition *MD // Decode the identifier info and then check again; if the macro is
= new (PPRec) MacroDefinition(DecodeIdentifierInfo(Record[4]), // still defined and associated with the identifier,
IdentifierInfo *II = DecodeIdentifierInfo(Record[4]);
if (!MacroDefinitionsLoaded[Record[1] - 1]) {
MacroDefinition *MD
= new (PPRec) MacroDefinition(II,
SourceLocation::getFromRawEncoding(Record[5]), SourceLocation::getFromRawEncoding(Record[5]),
SourceRange( SourceRange(
SourceLocation::getFromRawEncoding(Record[2]), SourceLocation::getFromRawEncoding(Record[2]),
SourceLocation::getFromRawEncoding(Record[3]))); SourceLocation::getFromRawEncoding(Record[3])));
PPRec.SetPreallocatedEntity(Record[0], MD);
MacroDefinitionsLoaded[Record[1]] = MD; PPRec.SetPreallocatedEntity(Record[0], MD);
MacroDefinitionsLoaded[Record[1] - 1] = MD;
if (DeserializationListener)
DeserializationListener->MacroDefinitionRead(Record[1], MD);
}
return; return;
} }
} }
@ -1582,11 +1592,11 @@ void ASTReader::ReadDefinedMacros() {
} }
MacroDefinition *ASTReader::getMacroDefinition(MacroID ID) { MacroDefinition *ASTReader::getMacroDefinition(MacroID ID) {
if (ID == 0 || ID >= MacroDefinitionsLoaded.size()) if (ID == 0 || ID > MacroDefinitionsLoaded.size())
return 0; return 0;
if (!MacroDefinitionsLoaded[ID]) { if (!MacroDefinitionsLoaded[ID - 1]) {
unsigned Index = ID; unsigned Index = ID - 1;
for (unsigned I = 0, N = Chain.size(); I != N; ++I) { for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
PerFileData &F = *Chain[N - I - 1]; PerFileData &F = *Chain[N - I - 1];
if (Index < F.LocalNumMacroDefinitions) { if (Index < F.LocalNumMacroDefinitions) {
@ -1595,10 +1605,10 @@ MacroDefinition *ASTReader::getMacroDefinition(MacroID ID) {
} }
Index -= F.LocalNumMacroDefinitions; Index -= F.LocalNumMacroDefinitions;
} }
assert(MacroDefinitionsLoaded[ID] && "Broken chain"); assert(MacroDefinitionsLoaded[ID - 1] && "Broken chain");
} }
return MacroDefinitionsLoaded[ID]; return MacroDefinitionsLoaded[ID - 1];
} }
/// \brief If we are loading a relocatable PCH file, and the filename is /// \brief If we are loading a relocatable PCH file, and the filename is

View File

@ -1360,11 +1360,17 @@ void ASTWriter::WritePreprocessor(const Preprocessor &PP) {
if (MacroDefinition *MD = dyn_cast<MacroDefinition>(*E)) { if (MacroDefinition *MD = dyn_cast<MacroDefinition>(*E)) {
// Record this macro definition's location. // Record this macro definition's location.
MacroID ID = getMacroDefinitionID(MD); MacroID ID = getMacroDefinitionID(MD);
if (ID != MacroDefinitionOffsets.size()) {
if (ID > MacroDefinitionOffsets.size())
MacroDefinitionOffsets.resize(ID + 1);
MacroDefinitionOffsets[ID] = Stream.GetCurrentBitNo(); // Don't write the macro definition if it is from another AST file.
if (ID < FirstMacroID)
continue;
unsigned Position = ID - FirstMacroID;
if (Position != MacroDefinitionOffsets.size()) {
if (Position > MacroDefinitionOffsets.size())
MacroDefinitionOffsets.resize(Position + 1);
MacroDefinitionOffsets[Position] = Stream.GetCurrentBitNo();
} else } else
MacroDefinitionOffsets.push_back(Stream.GetCurrentBitNo()); MacroDefinitionOffsets.push_back(Stream.GetCurrentBitNo());
@ -2206,7 +2212,8 @@ ASTWriter::ASTWriter(llvm::BitstreamWriter &Stream)
: Stream(Stream), Chain(0), FirstDeclID(1), NextDeclID(FirstDeclID), : Stream(Stream), Chain(0), FirstDeclID(1), NextDeclID(FirstDeclID),
FirstTypeID(NUM_PREDEF_TYPE_IDS), NextTypeID(FirstTypeID), FirstTypeID(NUM_PREDEF_TYPE_IDS), NextTypeID(FirstTypeID),
FirstIdentID(1), NextIdentID(FirstIdentID), FirstSelectorID(1), FirstIdentID(1), NextIdentID(FirstIdentID), FirstSelectorID(1),
NextSelectorID(FirstSelectorID), CollectedStmts(&StmtsToEmit), NextSelectorID(FirstSelectorID), FirstMacroID(1), NextMacroID(FirstMacroID),
CollectedStmts(&StmtsToEmit),
NumStatements(0), NumMacros(0), NumLexicalDeclContexts(0), NumStatements(0), NumMacros(0), NumLexicalDeclContexts(0),
NumVisibleDeclContexts(0) { NumVisibleDeclContexts(0) {
} }
@ -2439,10 +2446,12 @@ void ASTWriter::WriteASTChain(Sema &SemaRef, MemorizeStatCalls *StatCalls,
FirstTypeID += Chain->getTotalNumTypes(); FirstTypeID += Chain->getTotalNumTypes();
FirstIdentID += Chain->getTotalNumIdentifiers(); FirstIdentID += Chain->getTotalNumIdentifiers();
FirstSelectorID += Chain->getTotalNumSelectors(); FirstSelectorID += Chain->getTotalNumSelectors();
FirstMacroID += Chain->getTotalNumMacroDefinitions();
NextDeclID = FirstDeclID; NextDeclID = FirstDeclID;
NextTypeID = FirstTypeID; NextTypeID = FirstTypeID;
NextIdentID = FirstIdentID; NextIdentID = FirstIdentID;
NextSelectorID = FirstSelectorID; NextSelectorID = FirstSelectorID;
NextMacroID = FirstMacroID;
ASTContext &Context = SemaRef.Context; ASTContext &Context = SemaRef.Context;
Preprocessor &PP = SemaRef.PP; Preprocessor &PP = SemaRef.PP;
@ -2733,7 +2742,7 @@ MacroID ASTWriter::getMacroDefinitionID(MacroDefinition *MD) {
MacroID &ID = MacroDefinitions[MD]; MacroID &ID = MacroDefinitions[MD];
if (ID == 0) if (ID == 0)
ID = MacroDefinitions.size(); ID = NextMacroID++;
return ID; return ID;
} }
@ -3106,6 +3115,7 @@ void ASTWriter::SetReader(ASTReader *Reader) {
FirstTypeID == NextTypeID && FirstTypeID == NextTypeID &&
FirstIdentID == NextIdentID && FirstIdentID == NextIdentID &&
FirstSelectorID == NextSelectorID && FirstSelectorID == NextSelectorID &&
FirstMacroID == NextMacroID &&
"Setting chain after writing has started."); "Setting chain after writing has started.");
Chain = Reader; Chain = Reader;
} }
@ -3125,3 +3135,8 @@ void ASTWriter::DeclRead(DeclID ID, const Decl *D) {
void ASTWriter::SelectorRead(SelectorID ID, Selector S) { void ASTWriter::SelectorRead(SelectorID ID, Selector S) {
SelectorIDs[S] = ID; SelectorIDs[S] = ID;
} }
void ASTWriter::MacroDefinitionRead(serialization::MacroID ID,
MacroDefinition *MD) {
MacroDefinitions[MD] = ID;
}

View File

@ -1,9 +1,9 @@
// Test this without pch. // Test this without pch.
// RUN: %clang_cc1 -include %S/Inputs/chain-macro-override1.h -include %S/Inputs/chain-macro-override2.h -fsyntax-only -verify %s // RUN: %clang_cc1 -include %S/Inputs/chain-macro-override1.h -include %S/Inputs/chain-macro-override2.h -fsyntax-only -verify -detailed-preprocessing-record %s
// Test with pch. // Test with pch.
// RUN: %clang_cc1 -emit-pch -o %t1 %S/Inputs/chain-macro-override1.h // RUN: %clang_cc1 -emit-pch -o %t1 %S/Inputs/chain-macro-override1.h -detailed-preprocessing-record
// RUN: %clang_cc1 -emit-pch -o %t2 %S/Inputs/chain-macro-override2.h -include-pch %t1 -chained-pch // RUN: %clang_cc1 -emit-pch -o %t2 %S/Inputs/chain-macro-override2.h -include-pch %t1 -chained-pch -detailed-preprocessing-record
// RUN: %clang_cc1 -include-pch %t2 -fsyntax-only -verify %s // RUN: %clang_cc1 -include-pch %t2 -fsyntax-only -verify %s
int foo() { int foo() {

View File

@ -1,5 +1,5 @@
// RUN: %clang_cc1 -emit-pch -o %t1 %S/Inputs/chain-macro1.h // RUN: %clang_cc1 -emit-pch -o %t1 -detailed-preprocessing-record %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 -emit-pch -o %t2 -detailed-preprocessing-record %S/Inputs/chain-macro2.h -include-pch %t1 -chained-pch
// RUN: %clang_cc1 -fsyntax-only -verify -include-pch %t2 %s // RUN: %clang_cc1 -fsyntax-only -verify -include-pch %t2 %s
// RUN: %clang_cc1 -ast-print -include-pch %t2 %s | FileCheck %s // RUN: %clang_cc1 -ast-print -include-pch %t2 %s | FileCheck %s