aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2012-10-11 00:46:49 +0000
committerDouglas Gregor <dgregor@apple.com>2012-10-11 00:46:49 +0000
commit6c6c54a59a6e7dbe63ff6a9bbab76f6e0c7c8462 (patch)
treecea015c280d1666e0a42bdb2f208d8829a5f4cc9 /include
parent8b03277b0bc18ab73be11b6067474d515fdad271 (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.h3
-rw-r--r--include/clang/Lex/MacroInfo.h23
-rw-r--r--include/clang/Lex/Preprocessor.h8
-rw-r--r--include/clang/Serialization/ASTReader.h59
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);