aboutsummaryrefslogtreecommitdiff
path: root/lib/Frontend
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Frontend')
-rw-r--r--lib/Frontend/PCHReader.cpp125
-rw-r--r--lib/Frontend/PCHWriter.cpp89
2 files changed, 206 insertions, 8 deletions
diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp
index 36cddd32e5..7d8fee94f0 100644
--- a/lib/Frontend/PCHReader.cpp
+++ b/lib/Frontend/PCHReader.cpp
@@ -21,6 +21,7 @@
#include "clang/AST/Type.h"
#include "clang/AST/TypeLocVisitor.h"
#include "clang/Lex/MacroInfo.h"
+#include "clang/Lex/PreprocessingRecord.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Lex/HeaderSearch.h"
#include "clang/Basic/OnDiskHashTable.h"
@@ -326,8 +327,9 @@ PCHReader::PCHReader(Preprocessor &PP, ASTContext *Context,
IdentifierOffsets(0),
MethodPoolLookupTable(0), MethodPoolLookupTableData(0),
TotalSelectorsInMethodPool(0), SelectorOffsets(0),
- TotalNumSelectors(0), Comments(0), NumComments(0), isysroot(isysroot),
- NumStatHits(0), NumStatMisses(0),
+ TotalNumSelectors(0), MacroDefinitionOffsets(0),
+ NumPreallocatedPreprocessingEntities(0), Comments(0), NumComments(0),
+ isysroot(isysroot), NumStatHits(0), NumStatMisses(0),
NumSLocEntriesRead(0), NumStatementsRead(0),
NumMacrosRead(0), NumMethodPoolSelectorsRead(0), NumMethodPoolMisses(0),
NumLexicalDeclContextsRead(0), NumVisibleDeclContextsRead(0),
@@ -343,8 +345,9 @@ PCHReader::PCHReader(SourceManager &SourceMgr, FileManager &FileMgr,
IdentifierOffsets(0),
MethodPoolLookupTable(0), MethodPoolLookupTableData(0),
TotalSelectorsInMethodPool(0), SelectorOffsets(0),
- TotalNumSelectors(0), Comments(0), NumComments(0), isysroot(isysroot),
- NumStatHits(0), NumStatMisses(0),
+ TotalNumSelectors(0), MacroDefinitionOffsets(0),
+ NumPreallocatedPreprocessingEntities(0), Comments(0), NumComments(0),
+ isysroot(isysroot), NumStatHits(0), NumStatMisses(0),
NumSLocEntriesRead(0), NumStatementsRead(0),
NumMacrosRead(0), NumMethodPoolSelectorsRead(0), NumMethodPoolMisses(0),
NumLexicalDeclContextsRead(0), NumVisibleDeclContextsRead(0),
@@ -1047,12 +1050,14 @@ void PCHReader::ReadMacroRecord(uint64_t Offset) {
MacroInfo *MI = PP->AllocateMacroInfo(Loc);
MI->setIsUsed(isUsed);
+ unsigned NextIndex = 3;
if (RecType == pch::PP_MACRO_FUNCTION_LIKE) {
// Decode function-like macro info.
bool isC99VarArgs = Record[3];
bool isGNUVarArgs = Record[4];
MacroArgs.clear();
unsigned NumArgs = Record[5];
+ NextIndex = 6 + NumArgs;
for (unsigned i = 0; i != NumArgs; ++i)
MacroArgs.push_back(DecodeIdentifierInfo(Record[6+i]));
@@ -1070,6 +1075,13 @@ void PCHReader::ReadMacroRecord(uint64_t Offset) {
// Remember that we saw this macro last so that we add the tokens that
// form its body to it.
Macro = MI;
+
+ if (NextIndex + 1 == Record.size() && PP->getPreprocessingRecord()) {
+ // We have a macro definition. Load it now.
+ PP->getPreprocessingRecord()->RegisterMacroDefinition(Macro,
+ getMacroDefinition(Record[NextIndex]));
+ }
+
++NumMacrosRead;
break;
}
@@ -1090,6 +1102,64 @@ void PCHReader::ReadMacroRecord(uint64_t Offset) {
Macro->AddTokenToBody(Tok);
break;
}
+
+ case pch::PP_MACRO_INSTANTIATION: {
+ // If we already have a macro, that means that we've hit the end
+ // of the definition of the macro we were looking for. We're
+ // done.
+ if (Macro)
+ return;
+
+ if (!PP->getPreprocessingRecord()) {
+ Error("missing preprocessing record in PCH file");
+ return;
+ }
+
+ PreprocessingRecord &PPRec = *PP->getPreprocessingRecord();
+ if (PPRec.getPreprocessedEntity(Record[0]))
+ return;
+
+ MacroInstantiation *MI
+ = new (PPRec) MacroInstantiation(DecodeIdentifierInfo(Record[3]),
+ SourceRange(
+ SourceLocation::getFromRawEncoding(Record[1]),
+ SourceLocation::getFromRawEncoding(Record[2])),
+ getMacroDefinition(Record[4]));
+ PPRec.SetPreallocatedEntity(Record[0], MI);
+ return;
+ }
+
+ case pch::PP_MACRO_DEFINITION: {
+ // If we already have a macro, that means that we've hit the end
+ // of the definition of the macro we were looking for. We're
+ // done.
+ if (Macro)
+ return;
+
+ if (!PP->getPreprocessingRecord()) {
+ Error("missing preprocessing record in PCH file");
+ return;
+ }
+
+ PreprocessingRecord &PPRec = *PP->getPreprocessingRecord();
+ if (PPRec.getPreprocessedEntity(Record[0]))
+ return;
+
+ if (Record[1] >= MacroDefinitionsLoaded.size()) {
+ Error("out-of-bounds macro definition record");
+ return;
+ }
+
+ MacroDefinition *MD
+ = new (PPRec) MacroDefinition(DecodeIdentifierInfo(Record[4]),
+ SourceLocation::getFromRawEncoding(Record[5]),
+ SourceRange(
+ SourceLocation::getFromRawEncoding(Record[2]),
+ SourceLocation::getFromRawEncoding(Record[3])));
+ PPRec.SetPreallocatedEntity(Record[0], MD);
+ MacroDefinitionsLoaded[Record[1]] = MD;
+ return;
+ }
}
}
}
@@ -1139,16 +1209,32 @@ void PCHReader::ReadDefinedMacros() {
case pch::PP_MACRO_OBJECT_LIKE:
case pch::PP_MACRO_FUNCTION_LIKE:
- DecodeIdentifierInfo(Record[0]);
+ DecodeIdentifierInfo(Record[0]);
break;
case pch::PP_TOKEN:
// Ignore tokens.
break;
+
+ case pch::PP_MACRO_INSTANTIATION:
+ case pch::PP_MACRO_DEFINITION:
+ // Read the macro record.
+ ReadMacroRecord(Cursor.GetCurrentBitNo());
+ break;
}
}
}
+MacroDefinition *PCHReader::getMacroDefinition(pch::IdentID ID) {
+ if (ID == 0 || ID >= MacroDefinitionsLoaded.size())
+ return 0;
+
+ if (!MacroDefinitionsLoaded[ID])
+ ReadMacroRecord(MacroDefinitionOffsets[ID]);
+
+ return MacroDefinitionsLoaded[ID];
+}
+
/// \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.
@@ -1431,6 +1517,19 @@ PCHReader::ReadPCHBlock() {
}
break;
}
+
+ case pch::MACRO_DEFINITION_OFFSETS:
+ MacroDefinitionOffsets = (const uint32_t *)BlobStart;
+ if (PP) {
+ if (!PP->getPreprocessingRecord())
+ PP->createPreprocessingRecord();
+ PP->getPreprocessingRecord()->SetExternalSource(*this, Record[0]);
+ } else {
+ NumPreallocatedPreprocessingEntities = Record[0];
+ }
+
+ MacroDefinitionsLoaded.resize(Record[1]);
+ break;
}
}
Error("premature end of bitstream in PCH file");
@@ -1562,6 +1661,18 @@ PCHReader::PCHReadResult PCHReader::ReadPCH(const std::string &FileName) {
return Success;
}
+void PCHReader::setPreprocessor(Preprocessor &pp) {
+ PP = &pp;
+
+ if (NumPreallocatedPreprocessingEntities) {
+ if (!PP->getPreprocessingRecord())
+ PP->createPreprocessingRecord();
+ PP->getPreprocessingRecord()->SetExternalSource(*this,
+ NumPreallocatedPreprocessingEntities);
+ NumPreallocatedPreprocessingEntities = 0;
+ }
+}
+
void PCHReader::InitializeContext(ASTContext &Ctx) {
Context = &Ctx;
assert(Context && "Passed null context!");
@@ -1823,6 +1934,10 @@ bool PCHReader::ParseLanguageOptions(
return false;
}
+void PCHReader::ReadPreprocessedEntities() {
+ ReadDefinedMacros();
+}
+
void PCHReader::ReadComments(std::vector<SourceRange> &Comments) {
Comments.resize(NumComments);
std::copy(this->Comments, this->Comments + NumComments,
diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp
index e55599b7ec..df41ca1e59 100644
--- a/lib/Frontend/PCHWriter.cpp
+++ b/lib/Frontend/PCHWriter.cpp
@@ -21,6 +21,7 @@
#include "clang/AST/Type.h"
#include "clang/AST/TypeLocVisitor.h"
#include "clang/Lex/MacroInfo.h"
+#include "clang/Lex/PreprocessingRecord.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Lex/HeaderSearch.h"
#include "clang/Basic/FileManager.h"
@@ -565,7 +566,9 @@ void PCHWriter::WriteBlockInfoBlock() {
RECORD(EXT_VECTOR_DECLS);
RECORD(COMMENT_RANGES);
RECORD(VERSION_CONTROL_BRANCH_REVISION);
-
+ RECORD(UNUSED_STATIC_FUNCS);
+ RECORD(MACRO_DEFINITION_OFFSETS);
+
// SourceManager Block.
BLOCK(SOURCE_MANAGER_BLOCK);
RECORD(SM_SLOC_FILE_ENTRY);
@@ -579,7 +582,9 @@ void PCHWriter::WriteBlockInfoBlock() {
RECORD(PP_MACRO_OBJECT_LIKE);
RECORD(PP_MACRO_FUNCTION_LIKE);
RECORD(PP_TOKEN);
-
+ RECORD(PP_MACRO_INSTANTIATION);
+ RECORD(PP_MACRO_DEFINITION);
+
// Decls and Types block.
BLOCK(DECLTYPES_BLOCK);
RECORD(TYPE_EXT_QUAL);
@@ -1174,6 +1179,7 @@ void PCHWriter::WritePreprocessor(const Preprocessor &PP) {
// Loop over all the macro definitions that are live at the end of the file,
// emitting each to the PP section.
+ PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
for (Preprocessor::macro_iterator I = PP.macro_begin(), E = PP.macro_end();
I != E; ++I) {
// FIXME: This emits macros in hash table order, we should do it in a stable
@@ -1203,6 +1209,12 @@ void PCHWriter::WritePreprocessor(const Preprocessor &PP) {
I != E; ++I)
AddIdentifierRef(*I, Record);
}
+
+ // If we have a detailed preprocessing record, record the macro definition
+ // ID that corresponds to this macro.
+ if (PPRec)
+ Record.push_back(getMacroDefinitionID(PPRec->findMacroDefinition(MI)));
+
Stream.EmitRecord(Code, Record);
Record.clear();
@@ -1230,7 +1242,68 @@ void PCHWriter::WritePreprocessor(const Preprocessor &PP) {
}
++NumMacros;
}
+
+ // If the preprocessor has a preprocessing record, emit it.
+ unsigned NumPreprocessingRecords = 0;
+ if (PPRec) {
+ for (PreprocessingRecord::iterator E = PPRec->begin(), EEnd = PPRec->end();
+ E != EEnd; ++E) {
+ Record.clear();
+
+ if (MacroInstantiation *MI = dyn_cast<MacroInstantiation>(*E)) {
+ Record.push_back(NumPreprocessingRecords++);
+ AddSourceLocation(MI->getSourceRange().getBegin(), Record);
+ AddSourceLocation(MI->getSourceRange().getEnd(), Record);
+ AddIdentifierRef(MI->getName(), Record);
+ Record.push_back(getMacroDefinitionID(MI->getDefinition()));
+ Stream.EmitRecord(pch::PP_MACRO_INSTANTIATION, Record);
+ continue;
+ }
+
+ if (MacroDefinition *MD = dyn_cast<MacroDefinition>(*E)) {
+ // Record this macro definition's location.
+ pch::IdentID ID = getMacroDefinitionID(MD);
+ if (ID != MacroDefinitionOffsets.size()) {
+ if (ID > MacroDefinitionOffsets.size())
+ MacroDefinitionOffsets.resize(ID + 1);
+
+ MacroDefinitionOffsets[ID] = Stream.GetCurrentBitNo();
+ } else
+ MacroDefinitionOffsets.push_back(Stream.GetCurrentBitNo());
+
+ Record.push_back(NumPreprocessingRecords++);
+ Record.push_back(ID);
+ AddSourceLocation(MD->getSourceRange().getBegin(), Record);
+ AddSourceLocation(MD->getSourceRange().getEnd(), Record);
+ AddIdentifierRef(MD->getName(), Record);
+ AddSourceLocation(MD->getLocation(), Record);
+ Stream.EmitRecord(pch::PP_MACRO_DEFINITION, Record);
+ continue;
+ }
+ }
+ }
+
Stream.ExitBlock();
+
+ // Write the offsets table for the preprocessing record.
+ if (NumPreprocessingRecords > 0) {
+ // Write the offsets table for identifier IDs.
+ using namespace llvm;
+ BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
+ Abbrev->Add(BitCodeAbbrevOp(pch::MACRO_DEFINITION_OFFSETS));
+ Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of records
+ Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of macro defs
+ Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
+ unsigned MacroDefOffsetAbbrev = Stream.EmitAbbrev(Abbrev);
+
+ Record.clear();
+ Record.push_back(pch::MACRO_DEFINITION_OFFSETS);
+ Record.push_back(NumPreprocessingRecords);
+ Record.push_back(MacroDefinitionOffsets.size());
+ Stream.EmitRecordWithBlob(MacroDefOffsetAbbrev, Record,
+ (const char *)&MacroDefinitionOffsets.front(),
+ MacroDefinitionOffsets.size() * sizeof(uint32_t));
+ }
}
void PCHWriter::WriteComments(ASTContext &Context) {
@@ -2009,7 +2082,7 @@ void PCHWriter::WritePCH(Sema &SemaRef, MemorizeStatCalls *StatCalls,
// Write the remaining PCH contents.
RecordData Record;
- Stream.EnterSubblock(pch::PCH_BLOCK_ID, 4);
+ Stream.EnterSubblock(pch::PCH_BLOCK_ID, 5);
WriteMetadata(Context, isysroot);
WriteLanguageOptions(Context.getLangOptions());
if (StatCalls && !isysroot)
@@ -2149,6 +2222,16 @@ pch::IdentID PCHWriter::getIdentifierRef(const IdentifierInfo *II) {
return ID;
}
+pch::IdentID PCHWriter::getMacroDefinitionID(MacroDefinition *MD) {
+ if (MD == 0)
+ return 0;
+
+ pch::IdentID &ID = MacroDefinitions[MD];
+ if (ID == 0)
+ ID = MacroDefinitions.size();
+ return ID;
+}
+
void PCHWriter::AddSelectorRef(const Selector SelRef, RecordData &Record) {
if (SelRef.getAsOpaquePtr() == 0) {
Record.push_back(0);