diff options
| -rw-r--r-- | clang/include/clang/Basic/IdentifierTable.h | 2 | ||||
| -rw-r--r-- | clang/include/clang/Lex/ExternalPreprocessorSource.h | 3 | ||||
| -rw-r--r-- | clang/include/clang/Lex/Preprocessor.h | 7 | ||||
| -rw-r--r-- | clang/include/clang/Serialization/ASTReader.h | 18 | ||||
| -rw-r--r-- | clang/lib/Lex/PPMacroExpansion.cpp | 15 | ||||
| -rw-r--r-- | clang/lib/Serialization/ASTReader.cpp | 51 |
6 files changed, 93 insertions, 3 deletions
diff --git a/clang/include/clang/Basic/IdentifierTable.h b/clang/include/clang/Basic/IdentifierTable.h index 66c5deea547..0013bd937c4 100644 --- a/clang/include/clang/Basic/IdentifierTable.h +++ b/clang/include/clang/Basic/IdentifierTable.h @@ -71,7 +71,7 @@ class IdentifierInfo { void operator=(const IdentifierInfo&); // NONASSIGNABLE. friend class IdentifierTable; - + public: IdentifierInfo(); diff --git a/clang/include/clang/Lex/ExternalPreprocessorSource.h b/clang/include/clang/Lex/ExternalPreprocessorSource.h index 791d3fe304e..dbf73890337 100644 --- a/clang/include/clang/Lex/ExternalPreprocessorSource.h +++ b/clang/include/clang/Lex/ExternalPreprocessorSource.h @@ -27,6 +27,9 @@ public: /// \brief Read the set of macros defined by this external macro source. virtual void ReadDefinedMacros() = 0; + + /// \brief Read the definition for the given macro. + virtual void LoadMacroDefinition(IdentifierInfo *II) = 0; }; } diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h index 87b62d0a9a7..7b138884e0b 100644 --- a/clang/include/clang/Lex/Preprocessor.h +++ b/clang/include/clang/Lex/Preprocessor.h @@ -262,6 +262,8 @@ private: // Cached tokens state. /// allocation. MacroInfoChain *MICache; + MacroInfo *getInfoForMacro(IdentifierInfo *II) const; + public: Preprocessor(Diagnostic &diags, const LangOptions &opts, const TargetInfo &target, @@ -335,7 +337,10 @@ public: /// getMacroInfo - Given an identifier, return the MacroInfo it is #defined to /// or null if it isn't #define'd. MacroInfo *getMacroInfo(IdentifierInfo *II) const { - return II->hasMacroDefinition() ? Macros.find(II)->second : 0; + if (!II->hasMacroDefinition()) + return 0; + + return getInfoForMacro(II); } /// setMacroInfo - Specify a macro for this identifier. diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h index e855cc79488..9ac7c318529 100644 --- a/clang/include/clang/Serialization/ASTReader.h +++ b/clang/include/clang/Serialization/ASTReader.h @@ -488,6 +488,11 @@ private: /// \brief The macro definitions we have already loaded. llvm::SmallVector<MacroDefinition *, 16> MacroDefinitionsLoaded; + /// \brief Mapping from identifiers that represent macros whose definitions + /// have not yet been deserialized to the global offset where the macro + /// record resides. + llvm::DenseMap<IdentifierInfo *, uint64_t> UnreadMacroRecordOffsets; + /// \name CodeGen-relevant special data /// \brief Fields containing data that is relevant to CodeGen. //@{ @@ -1145,9 +1150,22 @@ public: /// \brief Reads the macro record located at the given offset. void ReadMacroRecord(PerFileData &F, uint64_t Offset); + /// \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, + uint64_t Offset); + /// \brief Read the set of macros defined by this external macro source. virtual void ReadDefinedMacros(); + /// \brief Read the macro definition for this identifier. + virtual void LoadMacroDefinition(IdentifierInfo *II); + + /// \brief Read the macro definition corresponding to this iterator + /// into the unread macro record offsets table. + void LoadMacroDefinition( + llvm::DenseMap<IdentifierInfo *, uint64_t>::iterator Pos); + /// \brief Retrieve the macro definition with the given ID. MacroDefinition *getMacroDefinition(serialization::MacroID ID); diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp index 68fc56f7b78..a9f4cacf6ce 100644 --- a/clang/lib/Lex/PPMacroExpansion.cpp +++ b/clang/lib/Lex/PPMacroExpansion.cpp @@ -20,12 +20,27 @@ #include "clang/Basic/TargetInfo.h" #include "clang/Lex/LexDiagnostic.h" #include "clang/Lex/CodeCompletionHandler.h" +#include "clang/Lex/ExternalPreprocessorSource.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Support/raw_ostream.h" #include <cstdio> #include <ctime> using namespace clang; +MacroInfo *Preprocessor::getInfoForMacro(IdentifierInfo *II) const { + assert(II->hasMacroDefinition() && "Identifier is not a macro!"); + + llvm::DenseMap<IdentifierInfo*, MacroInfo*>::const_iterator Pos + = Macros.find(II); + if (Pos == Macros.end()) { + // Load this macro from the external source. + getExternalSource()->LoadMacroDefinition(II); + Pos = Macros.find(II); + } + assert(Pos != Macros.end() && "Identifier macro info is missing!"); + return Pos->second; +} + /// setMacroInfo - Specify a macro for this identifier. /// void Preprocessor::setMacroInfo(IdentifierInfo *II, MacroInfo *MI) { diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index aa76765dc9d..22d3cbc68f7 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -682,7 +682,7 @@ public: // definition. if (hasMacroDefinition) { uint32_t Offset = ReadUnalignedLE32(d); - Reader.ReadMacroRecord(F, Offset); + Reader.SetIdentifierIsMacro(II, F, Offset); DataLen -= 4; } @@ -1568,6 +1568,22 @@ void ASTReader::ReadMacroRecord(PerFileData &F, uint64_t Offset) { } } +void ASTReader::SetIdentifierIsMacro(IdentifierInfo *II, PerFileData &F, + uint64_t Offset) { + // Note that this identifier has a macro definition. + II->setHasMacroDefinition(true); + + // Adjust the offset based on our position in the chain. + for (unsigned I = 0, N = Chain.size(); I != N; ++I) { + if (Chain[I] == &F) + break; + + Offset += Chain[I]->SizeInBits; + } + + UnreadMacroRecordOffsets[II] = Offset; +} + void ASTReader::ReadDefinedMacros() { for (unsigned I = 0, N = Chain.size(); I != N; ++I) { PerFileData &F = *Chain[N - I - 1]; @@ -1629,6 +1645,39 @@ void ASTReader::ReadDefinedMacros() { } } } + + // Drain the unread macro-record offsets map. + while (!UnreadMacroRecordOffsets.empty()) + LoadMacroDefinition(UnreadMacroRecordOffsets.begin()); +} + +void ASTReader::LoadMacroDefinition( + llvm::DenseMap<IdentifierInfo *, uint64_t>::iterator Pos) { + assert(Pos != UnreadMacroRecordOffsets.end() && "Unknown macro definition"); + PerFileData *F = 0; + uint64_t Offset = Pos->second; + UnreadMacroRecordOffsets.erase(Pos); + + 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 macro record offset"); + return; + } + + ReadMacroRecord(*F, Offset); +} + +void ASTReader::LoadMacroDefinition(IdentifierInfo *II) { + llvm::DenseMap<IdentifierInfo *, uint64_t>::iterator Pos + = UnreadMacroRecordOffsets.find(II); + LoadMacroDefinition(Pos); } MacroDefinition *ASTReader::getMacroDefinition(MacroID ID) { |

