diff options
-rw-r--r-- | include/clang/Serialization/ASTBitCodes.h | 20 | ||||
-rw-r--r-- | include/clang/Serialization/ASTReader.h | 15 | ||||
-rw-r--r-- | include/clang/Serialization/ASTWriter.h | 2 | ||||
-rw-r--r-- | lib/Serialization/ASTReader.cpp | 237 | ||||
-rw-r--r-- | lib/Serialization/ASTWriter.cpp | 178 |
5 files changed, 254 insertions, 198 deletions
diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h index bb316f0713..5c9a3086cb 100644 --- a/include/clang/Serialization/ASTBitCodes.h +++ b/include/clang/Serialization/ASTBitCodes.h @@ -148,7 +148,10 @@ namespace clang { DECLTYPES_BLOCK_ID, /// \brief The block containing DECL_UPDATES records. - DECL_UPDATES_BLOCK_ID + DECL_UPDATES_BLOCK_ID, + + /// \brief The block containing the detailed preprocessing record. + PREPROCESSOR_DETAIL_BLOCK_ID }; /// \brief Record types that occur within the AST block itself. @@ -383,20 +386,23 @@ namespace clang { /// \brief Describes one token. /// [PP_TOKEN, SLoc, Length, IdentInfoID, Kind, Flags] - PP_TOKEN = 3, + PP_TOKEN = 3 + }; + /// \brief Record types used within a preprocessor detail block. + enum PreprocessorDetailRecordTypes { /// \brief Describes a macro instantiation within the preprocessing /// record. - PP_MACRO_INSTANTIATION = 4, + PPD_MACRO_INSTANTIATION = 0, /// \brief Describes a macro definition within the preprocessing record. - PP_MACRO_DEFINITION = 5, + PPD_MACRO_DEFINITION = 1, - /// \brief Describes am inclusion directive within the preprocessing + /// \brief Describes an inclusion directive within the preprocessing /// record. - PP_INCLUSION_DIRECTIVE = 6 + PPD_INCLUSION_DIRECTIVE = 2 }; - + /// \defgroup ASTAST AST file AST constants /// /// The constants in this group describe various components of the diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h index b9bf5f60b6..ae9820b72f 100644 --- a/include/clang/Serialization/ASTReader.h +++ b/include/clang/Serialization/ASTReader.h @@ -280,9 +280,18 @@ private: /// \brief The offset of the start of the set of defined macros. uint64_t MacroStartOffset; + // === Detailed PreprocessingRecord === + + /// \brief The cursor to the start of the (optional) detailed preprocessing + /// record block. + llvm::BitstreamCursor PreprocessorDetailCursor; + + /// \brief The offset of the start of the preprocessor detail cursor. + uint64_t PreprocessorDetailStartOffset; + /// \brief The number of macro definitions in this file. unsigned LocalNumMacroDefinitions; - + /// \brief Offsets of all of the macro definitions in the preprocessing /// record in the AST file. const uint32_t *MacroDefinitionOffsets; @@ -1175,6 +1184,10 @@ public: /// \brief Reads the macro record located at the given offset. PreprocessedEntity *ReadMacroRecord(PerFileData &F, uint64_t Offset); + /// \brief Reads the preprocessed entity located at the current stream + /// position. + PreprocessedEntity *LoadPreprocessedEntity(PerFileData &F); + /// \brief Note that the identifier is a macro whose record will be loaded /// from the given AST file at the given (file-local) offset. void SetIdentifierIsMacro(IdentifierInfo *II, PerFileData &F, diff --git a/include/clang/Serialization/ASTWriter.h b/include/clang/Serialization/ASTWriter.h index 0da5ecca4a..17c09254f4 100644 --- a/include/clang/Serialization/ASTWriter.h +++ b/include/clang/Serialization/ASTWriter.h @@ -47,6 +47,7 @@ class MacroDefinition; class MemorizeStatCalls; class ASTReader; class PreprocessedEntity; +class PreprocessingRecord; class Preprocessor; class Sema; class SourceManager; @@ -311,6 +312,7 @@ private: const Preprocessor &PP, const char* isysroot); void WritePreprocessor(const Preprocessor &PP); + void WritePreprocessorDetail(PreprocessingRecord &PPRec); void WritePragmaDiagnosticMappings(const Diagnostic &Diag); void WriteType(QualType T); uint64_t WriteDeclContextLexicalBlock(ASTContext &Context, DeclContext *DC); diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index d2d20bfdbd..0fc62ab96a 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -1462,111 +1462,113 @@ PreprocessedEntity *ASTReader::ReadMacroRecord(PerFileData &F, uint64_t Offset) Macro->AddTokenToBody(Tok); break; } + } + } + + return 0; +} - case 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 0; - - if (!PP->getPreprocessingRecord()) { - Error("missing preprocessing record in AST file"); - return 0; - } +PreprocessedEntity *ASTReader::LoadPreprocessedEntity(PerFileData &F) { + assert(PP && "Forgot to set Preprocessor ?"); + unsigned Code = F.PreprocessorDetailCursor.ReadCode(); + switch (Code) { + case llvm::bitc::END_BLOCK: + return 0; + + case llvm::bitc::ENTER_SUBBLOCK: + Error("unexpected subblock record in preprocessor detail block"); + return 0; + + case llvm::bitc::DEFINE_ABBREV: + Error("unexpected abbrevation record in preprocessor detail block"); + return 0; + + default: + break; + } - PreprocessingRecord &PPRec = *PP->getPreprocessingRecord(); - if (PreprocessedEntity *PE = PPRec.getPreprocessedEntity(Record[0])) - return PE; - - MacroInstantiation *MI - = new (PPRec) MacroInstantiation(DecodeIdentifierInfo(Record[3]), - SourceRange(ReadSourceLocation(F, Record[1]), - ReadSourceLocation(F, Record[2])), - getMacroDefinition(Record[4])); - PPRec.SetPreallocatedEntity(Record[0], MI); - return MI; + if (!PP->getPreprocessingRecord()) { + Error("no preprocessing record"); + return 0; + } + + // Read the record. + PreprocessingRecord &PPRec = *PP->getPreprocessingRecord(); + const char *BlobStart = 0; + unsigned BlobLen = 0; + RecordData Record; + PreprocessorDetailRecordTypes RecType = + (PreprocessorDetailRecordTypes)F.PreprocessorDetailCursor.ReadRecord( + Code, Record, BlobStart, BlobLen); + switch (RecType) { + case PPD_MACRO_INSTANTIATION: { + if (PreprocessedEntity *PE = PPRec.getPreprocessedEntity(Record[0])) + return PE; + + MacroInstantiation *MI + = new (PPRec) MacroInstantiation(DecodeIdentifierInfo(Record[3]), + SourceRange(ReadSourceLocation(F, Record[1]), + ReadSourceLocation(F, Record[2])), + getMacroDefinition(Record[4])); + PPRec.SetPreallocatedEntity(Record[0], MI); + return MI; + } + + case PPD_MACRO_DEFINITION: { + if (PreprocessedEntity *PE = PPRec.getPreprocessedEntity(Record[0])) + return PE; + + if (Record[1] > MacroDefinitionsLoaded.size()) { + Error("out-of-bounds macro definition record"); + return 0; } - - case 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 0; - - if (!PP->getPreprocessingRecord()) { - Error("missing preprocessing record in AST file"); - return 0; - } - - PreprocessingRecord &PPRec = *PP->getPreprocessingRecord(); - if (PreprocessedEntity *PE = PPRec.getPreprocessedEntity(Record[0])) - return PE; - - if (Record[1] > MacroDefinitionsLoaded.size()) { - Error("out-of-bounds macro definition record"); - return 0; - } - - // Decode the identifier info and then check again; if the macro is - // still defined and associated with the identifier, - IdentifierInfo *II = DecodeIdentifierInfo(Record[4]); - if (!MacroDefinitionsLoaded[Record[1] - 1]) { - MacroDefinition *MD - = new (PPRec) MacroDefinition(II, - ReadSourceLocation(F, Record[5]), - SourceRange( - ReadSourceLocation(F, Record[2]), - ReadSourceLocation(F, Record[3]))); - - PPRec.SetPreallocatedEntity(Record[0], MD); - MacroDefinitionsLoaded[Record[1] - 1] = MD; - - if (DeserializationListener) - DeserializationListener->MacroDefinitionRead(Record[1], MD); - } - - return MacroDefinitionsLoaded[Record[1] - 1]; + + // Decode the identifier info and then check again; if the macro is + // still defined and associated with the identifier, + IdentifierInfo *II = DecodeIdentifierInfo(Record[4]); + if (!MacroDefinitionsLoaded[Record[1] - 1]) { + MacroDefinition *MD + = new (PPRec) MacroDefinition(II, + ReadSourceLocation(F, Record[5]), + SourceRange( + ReadSourceLocation(F, Record[2]), + ReadSourceLocation(F, Record[3]))); + + PPRec.SetPreallocatedEntity(Record[0], MD); + MacroDefinitionsLoaded[Record[1] - 1] = MD; + + if (DeserializationListener) + DeserializationListener->MacroDefinitionRead(Record[1], MD); } - - case PP_INCLUSION_DIRECTIVE: { - // 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 0; - - if (!PP->getPreprocessingRecord()) { - Error("missing preprocessing record in AST file"); - return 0; - } - - PreprocessingRecord &PPRec = *PP->getPreprocessingRecord(); - if (PreprocessedEntity *PE = PPRec.getPreprocessedEntity(Record[0])) - return PE; - - const char *FullFileNameStart = BlobStart + Record[3]; - const FileEntry *File - = PP->getFileManager().getFile(llvm::StringRef(FullFileNameStart, - BlobLen - Record[3])); - - // FIXME: Stable encoding - InclusionDirective::InclusionKind Kind - = static_cast<InclusionDirective::InclusionKind>(Record[5]); - InclusionDirective *ID - = new (PPRec) InclusionDirective(PPRec, Kind, - llvm::StringRef(BlobStart, Record[3]), - Record[4], - File, + + return MacroDefinitionsLoaded[Record[1] - 1]; + } + + case PPD_INCLUSION_DIRECTIVE: { + if (PreprocessedEntity *PE = PPRec.getPreprocessedEntity(Record[0])) + return PE; + + const char *FullFileNameStart = BlobStart + Record[3]; + const FileEntry *File + = PP->getFileManager().getFile(llvm::StringRef(FullFileNameStart, + BlobLen - Record[3])); + + // FIXME: Stable encoding + InclusionDirective::InclusionKind Kind + = static_cast<InclusionDirective::InclusionKind>(Record[5]); + InclusionDirective *ID + = new (PPRec) InclusionDirective(PPRec, Kind, + llvm::StringRef(BlobStart, Record[3]), + Record[4], + File, SourceRange(ReadSourceLocation(F, Record[1]), ReadSourceLocation(F, Record[2]))); - PPRec.SetPreallocatedEntity(Record[0], ID); - return ID; - } - } + PPRec.SetPreallocatedEntity(Record[0], ID); + return ID; + } } + Error("invalid offset in preprocessor detail block"); return 0; } @@ -1600,7 +1602,6 @@ void ASTReader::ReadDefinedMacros() { RecordData Record; while (true) { - uint64_t Offset = Cursor.GetCurrentBitNo(); unsigned Code = Cursor.ReadCode(); if (Code == llvm::bitc::END_BLOCK) break; @@ -1636,14 +1637,6 @@ void ASTReader::ReadDefinedMacros() { case PP_TOKEN: // Ignore tokens. break; - - case PP_MACRO_INSTANTIATION: - case PP_MACRO_DEFINITION: - case PP_INCLUSION_DIRECTIVE: - // Read the macro record. - // FIXME: That's a stupid way to do this. We should reuse this cursor. - ReadMacroRecord(F, Offset); - break; } } } @@ -1691,7 +1684,9 @@ MacroDefinition *ASTReader::getMacroDefinition(MacroID ID) { for (unsigned I = 0, N = Chain.size(); I != N; ++I) { PerFileData &F = *Chain[N - I - 1]; if (Index < F.LocalNumMacroDefinitions) { - ReadMacroRecord(F, F.MacroDefinitionOffsets[Index]); + SavedStreamPosition SavedPosition(F.PreprocessorDetailCursor); + F.PreprocessorDetailCursor.JumpToBit(F.MacroDefinitionOffsets[Index]); + LoadPreprocessedEntity(F); break; } Index -= F.LocalNumMacroDefinitions; @@ -1785,6 +1780,18 @@ ASTReader::ReadASTBlock(PerFileData &F) { F.MacroStartOffset = F.MacroCursor.GetCurrentBitNo(); break; + case PREPROCESSOR_DETAIL_BLOCK_ID: + F.PreprocessorDetailCursor = Stream; + if (Stream.SkipBlock() || + ReadBlockAbbrevs(F.PreprocessorDetailCursor, + PREPROCESSOR_DETAIL_BLOCK_ID)) { + Error("malformed preprocessor detail record in AST file"); + return Failure; + } + F.PreprocessorDetailStartOffset + = F.PreprocessorDetailCursor.GetCurrentBitNo(); + break; + case SOURCE_MANAGER_BLOCK_ID: switch (ReadSourceManagerBlock(F)) { case Success: @@ -2656,7 +2663,15 @@ bool ASTReader::ParseLanguageOptions( } void ASTReader::ReadPreprocessedEntities() { - ReadDefinedMacros(); + for (unsigned I = 0, N = Chain.size(); I != N; ++I) { + PerFileData &F = *Chain[I]; + if (!F.PreprocessorDetailCursor.getBitStreamReader()) + continue; + + SavedStreamPosition SavedPosition(F.PreprocessorDetailCursor); + F.PreprocessorDetailCursor.JumpToBit(F.PreprocessorDetailStartOffset); + while (LoadPreprocessedEntity(F)) { } + } } PreprocessedEntity *ASTReader::ReadPreprocessedEntity(uint64_t Offset) { @@ -2675,7 +2690,11 @@ PreprocessedEntity *ASTReader::ReadPreprocessedEntity(uint64_t Offset) { return 0; } - return ReadMacroRecord(*F, Offset); + // Keep track of where we are in the stream, then jump back there + // after reading this entity. + SavedStreamPosition SavedPosition(F->PreprocessorDetailCursor); + F->PreprocessorDetailCursor.JumpToBit(Offset); + return LoadPreprocessedEntity(*F); } void ASTReader::ReadPragmaDiagnosticMappings(Diagnostic &Diag) { diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp index 14604a2c2f..fdd5800e9c 100644 --- a/lib/Serialization/ASTWriter.cpp +++ b/lib/Serialization/ASTWriter.cpp @@ -752,9 +752,6 @@ void ASTWriter::WriteBlockInfoBlock() { RECORD(PP_MACRO_OBJECT_LIKE); RECORD(PP_MACRO_FUNCTION_LIKE); RECORD(PP_TOKEN); - RECORD(PP_MACRO_INSTANTIATION); - RECORD(PP_MACRO_DEFINITION); - RECORD(PP_INCLUSION_DIRECTIVE); // Decls and Types block. BLOCK(DECLTYPES_BLOCK); @@ -850,6 +847,11 @@ void ASTWriter::WriteBlockInfoBlock() { RECORD(DECL_INDIRECTFIELD); RECORD(DECL_EXPANDED_NON_TYPE_TEMPLATE_PARM_PACK); + BLOCK(PREPROCESSOR_DETAIL_BLOCK); + RECORD(PPD_MACRO_INSTANTIATION); + RECORD(PPD_MACRO_DEFINITION); + RECORD(PPD_INCLUSION_DIRECTIVE); + // Statements and Exprs can occur in the Decls and Types block. AddStmtsExprs(Stream, Record); #undef RECORD @@ -1409,21 +1411,8 @@ void ASTWriter::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(); - unsigned InclusionAbbrev = 0; - if (PPRec) { - using namespace llvm; - BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); - Abbrev->Add(BitCodeAbbrevOp(PP_INCLUSION_DIRECTIVE)); - Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // index - Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // start location - Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // end location - Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // filename length - Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // in quotes - Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // kind - Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); - InclusionAbbrev = Stream.EmitAbbrev(Abbrev); - } + // FIXME: If we are chaining, don't visit all of the macros! 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 @@ -1493,82 +1482,109 @@ void ASTWriter::WritePreprocessor(const Preprocessor &PP) { } ++NumMacros; } + Stream.ExitBlock(); + + if (PPRec) + WritePreprocessorDetail(*PPRec); +} + +void ASTWriter::WritePreprocessorDetail(PreprocessingRecord &PPRec) { + if (PPRec.begin(Chain) == PPRec.end(Chain)) + return; + + // Enter the preprocessor block. + Stream.EnterSubblock(PREPROCESSOR_DETAIL_BLOCK_ID, 3); // If the preprocessor has a preprocessing record, emit it. unsigned NumPreprocessingRecords = 0; - if (PPRec) { - unsigned IndexBase = Chain ? PPRec->getNumPreallocatedEntities() : 0; - for (PreprocessingRecord::iterator E = PPRec->begin(Chain), - EEnd = PPRec->end(Chain); - E != EEnd; ++E) { - Record.clear(); + using namespace llvm; + + // Set up the abbreviation for + unsigned InclusionAbbrev = 0; + { + BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); + Abbrev->Add(BitCodeAbbrevOp(PPD_INCLUSION_DIRECTIVE)); + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // index + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // start location + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // end location + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // filename length + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // in quotes + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // kind + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); + InclusionAbbrev = Stream.EmitAbbrev(Abbrev); + } + + unsigned IndexBase = Chain ? PPRec.getNumPreallocatedEntities() : 0; + RecordData Record; + for (PreprocessingRecord::iterator E = PPRec.begin(Chain), + EEnd = PPRec.end(Chain); + E != EEnd; ++E) { + Record.clear(); - if (MacroDefinition *MD = dyn_cast<MacroDefinition>(*E)) { - // Record this macro definition's location. - MacroID ID = getMacroDefinitionID(MD); - - // Don't write the macro definition if it is from another AST file. - if (ID < FirstMacroID) - continue; - - // Notify the serialization listener that we're serializing this entity. - if (SerializationListener) - SerializationListener->SerializedPreprocessedEntity(*E, - Stream.GetCurrentBitNo()); - - unsigned Position = ID - FirstMacroID; - if (Position != MacroDefinitionOffsets.size()) { - if (Position > MacroDefinitionOffsets.size()) - MacroDefinitionOffsets.resize(Position + 1); - - MacroDefinitionOffsets[Position] = Stream.GetCurrentBitNo(); - } else - MacroDefinitionOffsets.push_back(Stream.GetCurrentBitNo()); - - Record.push_back(IndexBase + 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(PP_MACRO_DEFINITION, Record); + if (MacroDefinition *MD = dyn_cast<MacroDefinition>(*E)) { + // Record this macro definition's location. + MacroID ID = getMacroDefinitionID(MD); + + // Don't write the macro definition if it is from another AST file. + if (ID < FirstMacroID) continue; - } - + // Notify the serialization listener that we're serializing this entity. if (SerializationListener) SerializationListener->SerializedPreprocessedEntity(*E, - Stream.GetCurrentBitNo()); - - if (MacroInstantiation *MI = dyn_cast<MacroInstantiation>(*E)) { - Record.push_back(IndexBase + NumPreprocessingRecords++); - AddSourceLocation(MI->getSourceRange().getBegin(), Record); - AddSourceLocation(MI->getSourceRange().getEnd(), Record); - AddIdentifierRef(MI->getName(), Record); - Record.push_back(getMacroDefinitionID(MI->getDefinition())); - Stream.EmitRecord(PP_MACRO_INSTANTIATION, Record); - continue; - } + Stream.GetCurrentBitNo()); - if (InclusionDirective *ID = dyn_cast<InclusionDirective>(*E)) { - Record.push_back(PP_INCLUSION_DIRECTIVE); - Record.push_back(IndexBase + NumPreprocessingRecords++); - AddSourceLocation(ID->getSourceRange().getBegin(), Record); - AddSourceLocation(ID->getSourceRange().getEnd(), Record); - Record.push_back(ID->getFileName().size()); - Record.push_back(ID->wasInQuotes()); - Record.push_back(static_cast<unsigned>(ID->getKind())); - llvm::SmallString<64> Buffer; - Buffer += ID->getFileName(); - Buffer += ID->getFile()->getName(); - Stream.EmitRecordWithBlob(InclusionAbbrev, Record, Buffer); - continue; - } + unsigned Position = ID - FirstMacroID; + if (Position != MacroDefinitionOffsets.size()) { + if (Position > MacroDefinitionOffsets.size()) + MacroDefinitionOffsets.resize(Position + 1); + + MacroDefinitionOffsets[Position] = Stream.GetCurrentBitNo(); + } else + MacroDefinitionOffsets.push_back(Stream.GetCurrentBitNo()); - llvm_unreachable("Unhandled PreprocessedEntity in ASTWriter"); + Record.push_back(IndexBase + 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(PPD_MACRO_DEFINITION, Record); + continue; } - } + // Notify the serialization listener that we're serializing this entity. + if (SerializationListener) + SerializationListener->SerializedPreprocessedEntity(*E, + Stream.GetCurrentBitNo()); + + if (MacroInstantiation *MI = dyn_cast<MacroInstantiation>(*E)) { + Record.push_back(IndexBase + NumPreprocessingRecords++); + AddSourceLocation(MI->getSourceRange().getBegin(), Record); + AddSourceLocation(MI->getSourceRange().getEnd(), Record); + AddIdentifierRef(MI->getName(), Record); + Record.push_back(getMacroDefinitionID(MI->getDefinition())); + Stream.EmitRecord(PPD_MACRO_INSTANTIATION, Record); + continue; + } + + if (InclusionDirective *ID = dyn_cast<InclusionDirective>(*E)) { + Record.push_back(PPD_INCLUSION_DIRECTIVE); + Record.push_back(IndexBase + NumPreprocessingRecords++); + AddSourceLocation(ID->getSourceRange().getBegin(), Record); + AddSourceLocation(ID->getSourceRange().getEnd(), Record); + Record.push_back(ID->getFileName().size()); + Record.push_back(ID->wasInQuotes()); + Record.push_back(static_cast<unsigned>(ID->getKind())); + llvm::SmallString<64> Buffer; + Buffer += ID->getFileName(); + Buffer += ID->getFile()->getName(); + Stream.EmitRecordWithBlob(InclusionAbbrev, Record, Buffer); + continue; + } + + llvm_unreachable("Unhandled PreprocessedEntity in ASTWriter"); + } Stream.ExitBlock(); // Write the offsets table for the preprocessing record. |