diff options
author | Douglas Gregor <dgregor@apple.com> | 2012-10-11 00:46:49 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2012-10-11 00:46:49 +0000 |
commit | 6c6c54a59a6e7dbe63ff6a9bbab76f6e0c7c8462 (patch) | |
tree | cea015c280d1666e0a42bdb2f208d8829a5f4cc9 /include | |
parent | 8b03277b0bc18ab73be11b6067474d515fdad271 (diff) |
Deserialize macro history when we deserialize an identifier that has
macro history.
When deserializing macro history, we arrange history such that the
macros that have definitions (that haven't been #undef'd) and are
visible come at the beginning of the list, which is what the
preprocessor and other clients of Preprocessor::getMacroInfo()
expect. If additional macro definitions become visible later, they'll
be moved toward the front of the list. Note that it's possible to have
ambiguities, but we don't diagnose them yet.
There is a partially-implemented design decision here that, if a
particular identifier has been defined or #undef'd within the
translation unit, that definition (or #undef) hides any macro
definitions that come from imported modules. There's still a little
work to do to ensure that the right #undef'ing happens.
Additionally, we'll need to scope the update records for #undefs, so
they only kick in when the submodule containing that update record
becomes visible.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@165682 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include')
-rw-r--r-- | include/clang/Lex/ExternalPreprocessorSource.h | 3 | ||||
-rw-r--r-- | include/clang/Lex/MacroInfo.h | 23 | ||||
-rw-r--r-- | include/clang/Lex/Preprocessor.h | 8 | ||||
-rw-r--r-- | include/clang/Serialization/ASTReader.h | 59 |
4 files changed, 67 insertions, 26 deletions
diff --git a/include/clang/Lex/ExternalPreprocessorSource.h b/include/clang/Lex/ExternalPreprocessorSource.h index f172b5c8d2..d2e2412192 100644 --- a/include/clang/Lex/ExternalPreprocessorSource.h +++ b/include/clang/Lex/ExternalPreprocessorSource.h @@ -28,9 +28,6 @@ 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; - /// \brief Update an out-of-date identifier. virtual void updateOutOfDateIdentifier(IdentifierInfo &II) = 0; }; diff --git a/include/clang/Lex/MacroInfo.h b/include/clang/Lex/MacroInfo.h index db6cdef290..a7bcfb9db1 100644 --- a/include/clang/Lex/MacroInfo.h +++ b/include/clang/Lex/MacroInfo.h @@ -105,7 +105,12 @@ private: /// \brief Whether the macro has public (when described in a module). bool IsPublic : 1; - + + /// \brief Whether the macro definition is currently "hidden". + /// Note that this is transient state that is never serialized to the AST + /// file. + bool IsHidden : 1; + ~MacroInfo() { assert(ArgumentList == 0 && "Didn't call destroy before dtor!"); } @@ -149,10 +154,8 @@ public: /// \brief Get the location where macro was undefined. SourceLocation getUndefLoc() const { return UndefLocation; } - /// \brief Set previous definition of the macro with the same name. Can only - /// be set once. + /// \brief Set previous definition of the macro with the same name. void setPreviousDefinition(MacroInfo *PreviousDef) { - assert(!PreviousDefinition && "PreviousDefiniton is already set!"); PreviousDefinition = PreviousDef; } @@ -326,7 +329,17 @@ public: /// \brief Determine the location where this macro was explicitly made /// public or private within its module. SourceLocation getVisibilityLocation() { return VisibilityLocation; } - + + /// \brief Determine whether this macro is currently defined (and has not + /// been #undef'd) or has been hidden. + bool isDefined() const { return UndefLocation.isInvalid() && !IsHidden; } + + /// \brief Determine whether this macro definition is hidden. + bool isHidden() const { return IsHidden; } + + /// \brief Set whether this macro definition is hidden. + void setHidden(bool Val) { IsHidden = Val; } + private: unsigned getDefinitionLengthSlow(SourceManager &SM) const; }; diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h index 12b99af6e0..2c0814c910 100644 --- a/include/clang/Lex/Preprocessor.h +++ b/include/clang/Lex/Preprocessor.h @@ -517,8 +517,12 @@ public: MacroInfo *getMacroInfoHistory(IdentifierInfo *II) const; /// \brief Specify a macro for this identifier. - void setMacroInfo(IdentifierInfo *II, MacroInfo *MI, - bool LoadedFromAST = false); + void setMacroInfo(IdentifierInfo *II, MacroInfo *MI); + /// \brief Add a MacroInfo that was loaded from an AST file. + void addLoadedMacroInfo(IdentifierInfo *II, MacroInfo *MI); + /// \brief Make the given MacroInfo, that was loaded from an AST file and + /// previously hidden, visible. + void makeLoadedMacroInfoVisible(IdentifierInfo *II, MacroInfo *MI); /// \brief Undefine a macro for this identifier. void clearMacroInfo(IdentifierInfo *II); diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h index c7e3bb8ba9..3a938a24c7 100644 --- a/include/clang/Serialization/ASTReader.h +++ b/include/clang/Serialization/ASTReader.h @@ -415,8 +415,35 @@ private: /// global submodule ID to produce a local ID. GlobalSubmoduleMapType GlobalSubmoduleMap; + /// \brief An entity that has been hidden. + class HiddenName { + /// \brief The hidden declaration or macro. + llvm::PointerUnion<Decl *, MacroInfo *> DeclOrMacro; + + /// \brief The name being defined to a macro, for the macro case. + IdentifierInfo *Identifier; + + public: + HiddenName(Decl *D) : DeclOrMacro(D), Identifier() { } + HiddenName(IdentifierInfo *II, MacroInfo *MI) + : DeclOrMacro(MI), Identifier(II) { } + + bool isDecl() const { return DeclOrMacro.is<Decl*>(); } + bool isMacro() const { return !isDecl(); } + + Decl *getDecl() const { + assert(isDecl() && "Hidden name is not a declaration"); + return DeclOrMacro.get<Decl *>(); + } + + std::pair<IdentifierInfo *, MacroInfo *> getMacro() const { + assert(isMacro() && "Hidden name is not a macro!"); + return std::make_pair(Identifier, DeclOrMacro.get<MacroInfo *>()); + } + }; + /// \brief A set of hidden declarations. - typedef llvm::SmallVector<llvm::PointerUnion<Decl *, IdentifierInfo *>, 2> + typedef llvm::SmallVector<HiddenName, 2> HiddenNames; typedef llvm::DenseMap<Module *, HiddenNames> HiddenNamesMapType; @@ -468,9 +495,13 @@ private: /// global method pool for this selector. llvm::DenseMap<Selector, unsigned> SelectorGeneration; - /// \brief Mapping from identifiers that represent macros whose definitions - /// have not yet been deserialized to the global ID of the macro. - llvm::DenseMap<IdentifierInfo *, serialization::MacroID> UnreadMacroIDs; + typedef llvm::DenseMap<IdentifierInfo *, + llvm::SmallVector<serialization::MacroID, 2> > + PendingMacroIDsMap; + + /// \brief Mapping from identifiers that have a macro history to the global + /// IDs have not yet been deserialized to the global IDs of those macros. + PendingMacroIDsMap PendingMacroIDs; typedef ContinuousRangeMap<unsigned, ModuleFile *, 4> GlobalPreprocessedEntityMapType; @@ -1390,6 +1421,9 @@ public: } virtual IdentifierInfo *GetIdentifier(serialization::IdentifierID ID) { + // Note that we are loading an identifier. + Deserializing AnIdentifier(this); + return DecodeIdentifierInfo(ID); } @@ -1555,23 +1589,17 @@ public: serialization::PreprocessedEntityID getGlobalPreprocessedEntityID(ModuleFile &M, unsigned LocalID) const; - /// \brief Note that the identifier is a macro whose record will be loaded - /// from the given AST file at the given (file-local) offset. + /// \brief Note that the identifier has a macro history. /// /// \param II The name of the macro. /// - /// \param ID The global macro ID. - /// - /// \param Visible Whether the macro should be made visible. - void setIdentifierIsMacro(IdentifierInfo *II, serialization::MacroID ID, - bool Visible); + /// \param IDs The global macro IDs that are associated with this identifier. + void setIdentifierIsMacro(IdentifierInfo *II, + ArrayRef<serialization::MacroID> IDs); /// \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 Update an out-of-date identifier. virtual void updateOutOfDateIdentifier(IdentifierInfo &II); @@ -1580,8 +1608,7 @@ public: /// \brief Read the macro definition corresponding to this iterator /// into the unread macro record offsets table. - void LoadMacroDefinition( - llvm::DenseMap<IdentifierInfo *,serialization::MacroID>::iterator Pos); + void LoadMacroDefinition(PendingMacroIDsMap::iterator Pos); /// \brief Load all external visible decls in the given DeclContext. void completeVisibleDeclsMap(const DeclContext *DC); |