diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-11-30 06:16:57 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-11-30 06:16:57 +0000 |
commit | 89d9980bbc2e4a4ac86673e6ec16fb9f5babb63b (patch) | |
tree | b60c5afbdb4f5fd6f12cf38e98ebb6c2746cc163 /lib/Serialization/ASTReader.cpp | |
parent | bdc4b366e80c125184a3b3c56fa4619cb4ac9e45 (diff) |
When using a precompiled preamble with detailed preprocessing records,
trap the serialized preprocessing records (macro definitions, macro
instantiations, macro definitions) from the generation of the
precompiled preamble, then replay those when walking the list of
preprocessed entities. This eliminates a bug where clang_getCursor()
wasn't able to find preprocessed-entity cursors in the preamble.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@120396 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Serialization/ASTReader.cpp')
-rw-r--r-- | lib/Serialization/ASTReader.cpp | 67 |
1 files changed, 44 insertions, 23 deletions
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index 1cac948d03..57002eb5d0 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -1339,7 +1339,7 @@ bool ASTReader::ReadBlockAbbrevs(llvm::BitstreamCursor &Cursor, } } -void ASTReader::ReadMacroRecord(PerFileData &F, uint64_t Offset) { +PreprocessedEntity *ASTReader::ReadMacroRecord(PerFileData &F, uint64_t Offset) { assert(PP && "Forgot to set Preprocessor ?"); llvm::BitstreamCursor &Stream = F.MacroCursor; @@ -1356,14 +1356,14 @@ void ASTReader::ReadMacroRecord(PerFileData &F, uint64_t Offset) { unsigned Code = Stream.ReadCode(); switch (Code) { case llvm::bitc::END_BLOCK: - return; + return 0; case llvm::bitc::ENTER_SUBBLOCK: // No known subblocks, always skip them. Stream.ReadSubBlockID(); if (Stream.SkipBlock()) { Error("malformed block record in AST file"); - return; + return 0; } continue; @@ -1387,12 +1387,12 @@ void ASTReader::ReadMacroRecord(PerFileData &F, uint64_t Offset) { // of the definition of the macro we were looking for. We're // done. if (Macro) - return; + return 0; IdentifierInfo *II = DecodeIdentifierInfo(Record[0]); if (II == 0) { Error("macro must have a name in AST file"); - return; + return 0; } SourceLocation Loc = ReadSourceLocation(F, Record[1]); bool isUsed = Record[2]; @@ -1459,16 +1459,16 @@ void ASTReader::ReadMacroRecord(PerFileData &F, uint64_t Offset) { // of the definition of the macro we were looking for. We're // done. if (Macro) - return; + return 0; if (!PP->getPreprocessingRecord()) { Error("missing preprocessing record in AST file"); - return; + return 0; } PreprocessingRecord &PPRec = *PP->getPreprocessingRecord(); - if (PPRec.getPreprocessedEntity(Record[0])) - return; + if (PreprocessedEntity *PE = PPRec.getPreprocessedEntity(Record[0])) + return PE; MacroInstantiation *MI = new (PPRec) MacroInstantiation(DecodeIdentifierInfo(Record[3]), @@ -1476,7 +1476,7 @@ void ASTReader::ReadMacroRecord(PerFileData &F, uint64_t Offset) { ReadSourceLocation(F, Record[2])), getMacroDefinition(Record[4])); PPRec.SetPreallocatedEntity(Record[0], MI); - return; + return MI; } case PP_MACRO_DEFINITION: { @@ -1484,20 +1484,20 @@ void ASTReader::ReadMacroRecord(PerFileData &F, uint64_t Offset) { // of the definition of the macro we were looking for. We're // done. if (Macro) - return; + return 0; if (!PP->getPreprocessingRecord()) { Error("missing preprocessing record in AST file"); - return; + return 0; } PreprocessingRecord &PPRec = *PP->getPreprocessingRecord(); - if (PPRec.getPreprocessedEntity(Record[0])) - return; + if (PreprocessedEntity *PE = PPRec.getPreprocessedEntity(Record[0])) + return PE; if (Record[1] > MacroDefinitionsLoaded.size()) { Error("out-of-bounds macro definition record"); - return; + return 0; } // Decode the identifier info and then check again; if the macro is @@ -1518,7 +1518,7 @@ void ASTReader::ReadMacroRecord(PerFileData &F, uint64_t Offset) { DeserializationListener->MacroDefinitionRead(Record[1], MD); } - return; + return MacroDefinitionsLoaded[Record[1] - 1]; } case PP_INCLUSION_DIRECTIVE: { @@ -1526,21 +1526,21 @@ void ASTReader::ReadMacroRecord(PerFileData &F, uint64_t Offset) { // of the definition of the macro we were looking for. We're // done. if (Macro) - return; + return 0; if (!PP->getPreprocessingRecord()) { Error("missing preprocessing record in AST file"); - return; + return 0; } PreprocessingRecord &PPRec = *PP->getPreprocessingRecord(); - if (PPRec.getPreprocessedEntity(Record[0])) - return; + 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])); + = PP->getFileManager().getFile(llvm::StringRef(FullFileNameStart, + BlobLen - Record[3])); // FIXME: Stable encoding InclusionDirective::InclusionKind Kind @@ -1553,10 +1553,12 @@ void ASTReader::ReadMacroRecord(PerFileData &F, uint64_t Offset) { SourceRange(ReadSourceLocation(F, Record[1]), ReadSourceLocation(F, Record[2]))); PPRec.SetPreallocatedEntity(Record[0], ID); - return; + return ID; } } } + + return 0; } void ASTReader::SetIdentifierIsMacro(IdentifierInfo *II, PerFileData &F, @@ -2638,6 +2640,25 @@ void ASTReader::ReadPreprocessedEntities() { ReadDefinedMacros(); } +PreprocessedEntity *ASTReader::ReadPreprocessedEntity(uint64_t Offset) { + PerFileData *F = 0; + for (unsigned I = 0, N = Chain.size(); I != N; ++I) { + if (Offset < Chain[I]->SizeInBits) { + F = Chain[I]; + break; + } + + Offset -= Chain[I]->SizeInBits; + } + + if (!F) { + Error("Malformed preprocessed entity offset"); + return 0; + } + + return ReadMacroRecord(*F, Offset); +} + void ASTReader::ReadUserDiagnosticMappings(Diagnostic &Diag) { unsigned Idx = 0; while (Idx < UserDiagMappings.size()) { |