diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2013-02-20 00:54:57 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2013-02-20 00:54:57 +0000 |
commit | 9818a1d443e97677dd3422305de9cc2b1fb2a8c1 (patch) | |
tree | f6b547c4fcc33ff4bae563473287cddfeff4e21c | |
parent | 206f49966f66ad7cbfe3d37c14fa7e6e7410f3be (diff) |
[preprocessor] Split the MacroInfo class into two separate concepts, MacroInfo class
for the data specific to a macro definition (e.g. what the tokens are), and
MacroDirective class which encapsulates the changes to the "macro namespace"
(e.g. the location where the macro name became active, the location where it was undefined, etc.)
(A MacroDirective always points to a MacroInfo object.)
Usually a macro definition (MacroInfo) is where a macro name becomes active (MacroDirective) but
splitting the concepts allows us to better model the effect of modules to the macro namespace
(also as a bonus it allows better modeling of push_macro/pop_macro #pragmas).
Modules can have their own macro history, separate from the local (current translation unit)
macro history; MacroDirectives will be used to model the macro history (changes to macro namespace).
For example, if "@import A;" imports macro FOO, there will be a new local MacroDirective created
to indicate that "FOO" became active at the import location. Module "A" itself will contain another
MacroDirective in its macro history (at the point of the definition of FOO) and both MacroDirectives
will point to the same MacroInfo object.
Introducing the separation of macro concepts is the first part towards better modeling of module macros.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@175585 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/Lex/MacroInfo.h | 171 | ||||
-rw-r--r-- | include/clang/Lex/PPMutationListener.h | 4 | ||||
-rw-r--r-- | include/clang/Lex/Preprocessor.h | 44 | ||||
-rw-r--r-- | include/clang/Serialization/ASTDeserializationListener.h | 4 | ||||
-rw-r--r-- | include/clang/Serialization/ASTReader.h | 21 | ||||
-rw-r--r-- | include/clang/Serialization/ASTWriter.h | 14 | ||||
-rw-r--r-- | lib/Frontend/PrintPreprocessedOutput.cpp | 2 | ||||
-rw-r--r-- | lib/Lex/MacroInfo.cpp | 59 | ||||
-rw-r--r-- | lib/Lex/PPDirectives.cpp | 53 | ||||
-rw-r--r-- | lib/Lex/PPMacroExpansion.cpp | 95 | ||||
-rw-r--r-- | lib/Lex/Pragma.cpp | 17 | ||||
-rw-r--r-- | lib/Lex/Preprocessor.cpp | 11 | ||||
-rw-r--r-- | lib/Sema/Sema.cpp | 3 | ||||
-rw-r--r-- | lib/Sema/SemaCodeComplete.cpp | 5 | ||||
-rw-r--r-- | lib/Serialization/ASTReader.cpp | 52 | ||||
-rw-r--r-- | lib/Serialization/ASTWriter.cpp | 56 | ||||
-rw-r--r-- | tools/libclang/CIndex.cpp | 16 |
17 files changed, 322 insertions, 305 deletions
diff --git a/include/clang/Lex/MacroInfo.h b/include/clang/Lex/MacroInfo.h index aeedd735e3..80b66e4a26 100644 --- a/include/clang/Lex/MacroInfo.h +++ b/include/clang/Lex/MacroInfo.h @@ -32,24 +32,12 @@ class MacroInfo { SourceLocation Location; /// EndLocation - The location of the last token in the macro. SourceLocation EndLocation; - /// \brief The location where the macro was #undef'd, or an invalid location - /// for macros that haven't been undefined. - SourceLocation UndefLocation; - /// \brief Previous definition, the identifier of this macro was defined to, - /// or NULL. - MacroInfo *PreviousDefinition; /// Arguments - The list of arguments for a function-like macro. This can be /// empty, for, e.g. "#define X()". In a C99-style variadic macro, this /// includes the \c __VA_ARGS__ identifier on the list. IdentifierInfo **ArgumentList; unsigned NumArguments; - - /// \brief The location at which this macro was either explicitly exported - /// from its module or marked as private. - /// - /// If invalid, this macro has not been explicitly given any visibility. - SourceLocation VisibilityLocation; /// \brief This is the list of tokens that the macro is defined to. SmallVector<Token, 8> ReplacementTokens; @@ -78,12 +66,6 @@ class MacroInfo { /// \brief Whether this macro contains the sequence ", ## __VA_ARGS__" bool HasCommaPasting : 1; - - /// \brief True if this macro was loaded from an AST file. - bool IsFromAST : 1; - - /// \brief Whether this macro changed after it was loaded from an AST file. - bool ChangedAfterLoad : 1; private: //===--------------------------------------------------------------------===// @@ -105,18 +87,6 @@ private: /// \brief Must warn if the macro is unused at the end of translation unit. bool IsWarnIfUnused : 1; - - /// \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; - - /// \brief Whether the definition of this macro is ambiguous, due to - /// multiple definitions coming in from multiple modules. - bool IsAmbiguous : 1; ~MacroInfo() { assert(ArgumentList == 0 && "Didn't call destroy before dtor!"); @@ -124,7 +94,6 @@ private: public: MacroInfo(SourceLocation DefLoc); - MacroInfo(const MacroInfo &MI, llvm::BumpPtrAllocator &PPAllocator); /// FreeArgumentList - Free the argument list of the macro, restoring it to a /// state where it can be reused for other devious purposes. @@ -151,29 +120,6 @@ public: /// SourceLocation getDefinitionEndLoc() const { return EndLocation; } - /// \brief Set the location where macro was undefined. Can only be set once. - void setUndefLoc(SourceLocation UndefLoc) { - assert(UndefLocation.isInvalid() && "UndefLocation is already set!"); - assert(UndefLoc.isValid() && "Invalid UndefLoc!"); - UndefLocation = UndefLoc; - } - - /// \brief Get the location where macro was undefined. - SourceLocation getUndefLoc() const { return UndefLocation; } - - /// \brief Set previous definition of the macro with the same name. - void setPreviousDefinition(MacroInfo *PreviousDef) { - PreviousDefinition = PreviousDef; - } - - /// \brief Get previous definition of the macro with the same name. - MacroInfo *getPreviousDefinition() { return PreviousDefinition; } - - /// \brief Find macro definition active in the specified source location. If - /// this macro was not defined there, return NULL. - const MacroInfo *findDefinitionAtLoc(SourceLocation L, - SourceManager &SM) const; - /// \brief Get length in characters of the macro definition. unsigned getDefinitionLength(SourceManager &SM) const { if (IsDefinitionLengthCached) @@ -259,20 +205,6 @@ public: bool hasCommaPasting() const { return HasCommaPasting; } void setHasCommaPasting() { HasCommaPasting = true; } - /// isFromAST - Return true if this macro was loaded from an AST file. - bool isFromAST() const { return IsFromAST; } - - /// setIsFromAST - Set whether this macro was loaded from an AST file. - void setIsFromAST(bool FromAST = true) { IsFromAST = FromAST; } - - /// \brief Determine whether this macro has changed since it was loaded from - /// an AST file. - bool hasChangedAfterLoad() const { return ChangedAfterLoad; } - - /// \brief Note whether this macro has changed after it was loaded from an - /// AST file. - void setChangedAfterLoad(bool CAL = true) { ChangedAfterLoad = CAL; } - /// isUsed - Return false if this macro is defined in the main file and has /// not yet been used. bool isUsed() const { return IsUsed; } @@ -326,6 +258,93 @@ public: IsDisabled = true; } +private: + unsigned getDefinitionLengthSlow(SourceManager &SM) const; +}; + +class MacroDirective { + MacroInfo *Info; + + /// \brief Previous definition, the identifier of this macro was defined to, + /// or NULL. + MacroDirective *Previous; + + SourceLocation Loc; + + /// \brief The location where the macro was #undef'd, or an invalid location + /// for macros that haven't been undefined. + SourceLocation UndefLocation; + + /// \brief The location at which this macro was either explicitly exported + /// from its module or marked as private. + /// + /// If invalid, this macro has not been explicitly given any visibility. + SourceLocation VisibilityLocation; + + /// \brief True if this macro was loaded from an AST file. + bool IsImported : 1; + + /// \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; + + /// \brief Whether the definition of this macro is ambiguous, due to + /// multiple definitions coming in from multiple modules. + bool IsAmbiguous : 1; + + /// \brief Whether this macro changed after it was loaded from an AST file. + bool ChangedAfterLoad : 1; + +public: + explicit MacroDirective(MacroInfo *MI) + : Info(MI), Previous(0), Loc(MI->getDefinitionLoc()), + IsImported(false), IsPublic(true), IsHidden(false), IsAmbiguous(false), + ChangedAfterLoad(false) { + assert(MI && "MacroInfo is null"); + } + + MacroDirective(MacroInfo *MI, SourceLocation Loc, bool isImported) + : Info(MI), Previous(0), Loc(Loc), + IsImported(isImported), IsPublic(true), IsHidden(false), + IsAmbiguous(false), ChangedAfterLoad(false) { + assert(MI && "MacroInfo is null"); + } + + SourceLocation getLocation() const { return Loc; } + + /// \brief Set the location where macro was undefined. Can only be set once. + void setUndefLoc(SourceLocation UndefLoc) { + assert(UndefLocation.isInvalid() && "UndefLocation is already set!"); + assert(UndefLoc.isValid() && "Invalid UndefLoc!"); + UndefLocation = UndefLoc; + } + + const MacroInfo *getInfo() const { return Info; } + MacroInfo *getInfo() { return Info; } + + /// \brief Get the location where macro was undefined. + SourceLocation getUndefLoc() const { return UndefLocation; } + + /// \brief Set previous definition of the macro with the same name. + void setPrevious(MacroDirective *Prev) { + Previous = Prev; + } + + /// \brief Get previous definition of the macro with the same name. + const MacroDirective *getPrevious() const { return Previous; } + + /// \brief Get previous definition of the macro with the same name. + MacroDirective *getPrevious() { return Previous; } + + /// \brief Find macro definition active in the specified source location. If + /// this macro was not defined there, return NULL. + const MacroDirective *findDirectiveAtLoc(SourceLocation L, + SourceManager &SM) const; + /// \brief Set the export location for this macro. void setVisibility(bool Public, SourceLocation Loc) { VisibilityLocation = Loc; @@ -338,7 +357,10 @@ public: /// \brief Determine the location where this macro was explicitly made /// public or private within its module. - SourceLocation getVisibilityLocation() { return VisibilityLocation; } + SourceLocation getVisibilityLocation() const { return VisibilityLocation; } + + /// \brief True if this macro was loaded from an AST file. + bool isImported() const { return IsImported; } /// \brief Determine whether this macro is currently defined (and has not /// been #undef'd) or has been hidden. @@ -356,9 +378,14 @@ public: /// \brief Set whether this macro definition is ambiguous. void setAmbiguous(bool Val) { IsAmbiguous = Val; } - -private: - unsigned getDefinitionLengthSlow(SourceManager &SM) const; + + /// \brief Determine whether this macro has changed since it was loaded from + /// an AST file. + bool hasChangedAfterLoad() const { return ChangedAfterLoad; } + + /// \brief Note whether this macro has changed after it was loaded from an + /// AST file. + void setChangedAfterLoad(bool CAL = true) { ChangedAfterLoad = CAL; } }; } // end namespace clang diff --git a/include/clang/Lex/PPMutationListener.h b/include/clang/Lex/PPMutationListener.h index 5319c66fa2..995842974a 100644 --- a/include/clang/Lex/PPMutationListener.h +++ b/include/clang/Lex/PPMutationListener.h @@ -17,7 +17,7 @@ namespace clang { -class MacroInfo; +class MacroDirective; /// \brief A record that describes an update to a macro that was /// originally loaded to an AST file and has been modified within the @@ -35,7 +35,7 @@ public: virtual ~PPMutationListener(); /// \brief A macro has been #undef'd. - virtual void UndefinedMacro(MacroInfo *MI) { } + virtual void UndefinedMacro(MacroDirective *MD) { } }; } // end namespace clang diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h index df243f97d8..c1c55db41a 100644 --- a/include/clang/Lex/Preprocessor.h +++ b/include/clang/Lex/Preprocessor.h @@ -313,7 +313,7 @@ class Preprocessor : public RefCountedBase<Preprocessor> { /// Macros - For each IdentifierInfo that was associated with a macro, we /// keep a mapping to the history of all macro definitions and #undefs in /// the reverse order (the latest one is in the head of the list). - llvm::DenseMap<const IdentifierInfo*, MacroInfo*> Macros; + llvm::DenseMap<const IdentifierInfo*, MacroDirective*> Macros; friend class ASTReader; /// \brief Macros that we want to warn because they are not used at the end @@ -534,29 +534,43 @@ public: /// \brief Given an identifier, return the MacroInfo it is \#defined to /// or null if it isn't \#define'd. - MacroInfo *getMacroInfo(IdentifierInfo *II) const { + MacroDirective *getMacroDirective(IdentifierInfo *II) const { if (!II->hasMacroDefinition()) return 0; - MacroInfo *MI = getMacroInfoHistory(II); - assert(MI->getUndefLoc().isInvalid() && "Macro is undefined!"); - return MI; + MacroDirective *MD = getMacroDirectiveHistory(II); + assert(MD->getUndefLoc().isInvalid() && "Macro is undefined!"); + return MD; + } + + const MacroInfo *getMacroInfo(IdentifierInfo *II) const { + return const_cast<Preprocessor*>(this)->getMacroInfo(II); + } + + MacroInfo *getMacroInfo(IdentifierInfo *II) { + if (MacroDirective *MD = getMacroDirective(II)) + return MD->getInfo(); + return 0; } /// \brief Given an identifier, return the (probably #undef'd) MacroInfo /// representing the most recent macro definition. One can iterate over all /// previous macro definitions from it. This method should only be called for /// identifiers that hadMacroDefinition(). - MacroInfo *getMacroInfoHistory(const IdentifierInfo *II) const; + MacroDirective *getMacroDirectiveHistory(const IdentifierInfo *II) const; /// \brief Specify a macro for this identifier. - void setMacroInfo(IdentifierInfo *II, MacroInfo *MI); + void setMacroDirective(IdentifierInfo *II, MacroInfo *MI, + SourceLocation Loc, bool isImported); + void setMacroDirective(IdentifierInfo *II, MacroInfo *MI) { + setMacroDirective(II, MI, MI->getDefinitionLoc(), false); + } /// \brief Add a MacroInfo that was loaded from an AST file. - void addLoadedMacroInfo(IdentifierInfo *II, MacroInfo *MI, - MacroInfo *Hint = 0); + void addLoadedMacroInfo(IdentifierInfo *II, MacroDirective *MD, + MacroDirective *Hint = 0); /// \brief Make the given MacroInfo, that was loaded from an AST file and /// previously hidden, visible. - void makeLoadedMacroInfoVisible(IdentifierInfo *II, MacroInfo *MI); + void makeLoadedMacroInfoVisible(IdentifierInfo *II, MacroDirective *MD); /// \brief Undefine a macro for this identifier. void clearMacroInfo(IdentifierInfo *II); @@ -565,7 +579,7 @@ public: /// IdentifierInfo::hasMacroDefinition() set and an empty /// MacroInfo::getUndefLoc() at the head of the list. typedef llvm::DenseMap<const IdentifierInfo *, - MacroInfo*>::const_iterator macro_iterator; + MacroDirective*>::const_iterator macro_iterator; macro_iterator macro_begin(bool IncludeExternalMacros = true) const; macro_iterator macro_end(bool IncludeExternalMacros = true) const; @@ -1194,9 +1208,6 @@ public: /// \brief Allocate a new MacroInfo object with the provided SourceLocation. MacroInfo *AllocateMacroInfo(SourceLocation L); - /// \brief Allocate a new MacroInfo object which is clone of \p MI. - MacroInfo *CloneMacroInfo(const MacroInfo &MI); - /// \brief Turn the specified lexer token into a fully checked and spelled /// filename, e.g. as an operand of \#include. /// @@ -1272,6 +1283,9 @@ private: /// \brief Allocate a new MacroInfo object. MacroInfo *AllocateMacroInfo(); + MacroDirective *AllocateMacroDirective(MacroInfo *MI, SourceLocation Loc, + bool isImported); + /// \brief Release the specified MacroInfo for re-use. /// /// This memory will be reused for allocating new MacroInfo objects. @@ -1424,7 +1438,7 @@ private: // Macro handling. void HandleDefineDirective(Token &Tok); void HandleUndefDirective(Token &Tok); - void UndefineMacro(IdentifierInfo *II, MacroInfo *MI, + void UndefineMacro(IdentifierInfo *II, MacroDirective *MD, SourceLocation UndefLoc); // Conditional Inclusion. diff --git a/include/clang/Serialization/ASTDeserializationListener.h b/include/clang/Serialization/ASTDeserializationListener.h index 0218129fb6..b54f791994 100644 --- a/include/clang/Serialization/ASTDeserializationListener.h +++ b/include/clang/Serialization/ASTDeserializationListener.h @@ -23,7 +23,7 @@ class Decl; class ASTReader; class QualType; class MacroDefinition; -class MacroInfo; +class MacroDirective; class Module; class ASTDeserializationListener { @@ -39,7 +39,7 @@ public: virtual void IdentifierRead(serialization::IdentID ID, IdentifierInfo *II) { } /// \brief A macro was read from the AST file. - virtual void MacroRead(serialization::MacroID ID, MacroInfo *MI) { } + virtual void MacroRead(serialization::MacroID ID, MacroDirective *MD) { } /// \brief A type was deserialized from the AST file. The ID here has the /// qualifier bits already removed, and T is guaranteed to be locally /// unqualified. diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h index b8943e7347..68f7720771 100644 --- a/include/clang/Serialization/ASTReader.h +++ b/include/clang/Serialization/ASTReader.h @@ -71,6 +71,7 @@ class CXXCtorInitializer; class GlobalModuleIndex; class GotoStmt; class MacroDefinition; +class MacroDirective; class NamedDecl; class OpaqueValueExpr; class Preprocessor; @@ -426,7 +427,7 @@ private: /// If the pointer at index I is non-NULL, then it refers to the /// MacroInfo for the identifier with ID=I+1 that has already /// been loaded. - std::vector<MacroInfo *> MacrosLoaded; + std::vector<MacroDirective *> MacrosLoaded; typedef ContinuousRangeMap<serialization::MacroID, ModuleFile *, 4> GlobalMacroMapType; @@ -473,7 +474,7 @@ private: union { Decl *D; - MacroInfo *MI; + MacroDirective *MD; }; IdentifierInfo *Id; @@ -481,11 +482,11 @@ private: public: HiddenName(Decl *D) : Kind(Declaration), Loc(), D(D), Id() { } - HiddenName(IdentifierInfo *II, MacroInfo *MI) - : Kind(MacroVisibility), Loc(), MI(MI), Id(II) { } + HiddenName(IdentifierInfo *II, MacroDirective *MD) + : Kind(MacroVisibility), Loc(), MD(MD), Id(II) { } - HiddenName(IdentifierInfo *II, MacroInfo *MI, SourceLocation Loc) - : Kind(MacroUndef), Loc(Loc.getRawEncoding()), MI(MI), Id(II) { } + HiddenName(IdentifierInfo *II, MacroDirective *MD, SourceLocation Loc) + : Kind(MacroUndef), Loc(Loc.getRawEncoding()), MD(MD), Id(II) { } NameKind getKind() const { return Kind; } @@ -494,10 +495,10 @@ private: return D; } - std::pair<IdentifierInfo *, MacroInfo *> getMacro() const { + std::pair<IdentifierInfo *, MacroDirective *> getMacro() const { assert((getKind() == MacroUndef || getKind() == MacroVisibility) && "Hidden name is not a macro!"); - return std::make_pair(Id, MI); + return std::make_pair(Id, MD); } SourceLocation getMacroUndefLoc() const { @@ -1604,7 +1605,7 @@ public: unsigned LocalID); /// \brief Retrieve the macro with the given ID. - MacroInfo *getMacro(serialization::MacroID ID, MacroInfo *Hint = 0); + MacroDirective *getMacro(serialization::MacroID ID, MacroDirective *Hint = 0); /// \brief Retrieve the global macro ID corresponding to the given local /// ID within the given module file. @@ -1763,7 +1764,7 @@ public: Expr *ReadSubExpr(); /// \brief Reads the macro record located at the given offset. - void ReadMacroRecord(ModuleFile &F, uint64_t Offset, MacroInfo *Hint = 0); + void ReadMacroRecord(ModuleFile &F, uint64_t Offset, MacroDirective *Hint = 0); /// \brief Determine the global preprocessed entity ID that corresponds to /// the given local ID within the given module. diff --git a/include/clang/Serialization/ASTWriter.h b/include/clang/Serialization/ASTWriter.h index d632ba5c6e..b966ae1228 100644 --- a/include/clang/Serialization/ASTWriter.h +++ b/include/clang/Serialization/ASTWriter.h @@ -53,7 +53,7 @@ class MacroDefinition; class OpaqueValueExpr; class OpenCLOptions; class ASTReader; -class MacroInfo; +class MacroDirective; class Module; class PreprocessedEntity; class PreprocessingRecord; @@ -230,7 +230,7 @@ private: serialization::MacroID NextMacroID; /// \brief Map that provides the ID numbers of each macro. - llvm::DenseMap<MacroInfo *, serialization::MacroID> MacroIDs; + llvm::DenseMap<MacroDirective *, serialization::MacroID> MacroIDs; /// @name FlushStmt Caches /// @{ @@ -267,7 +267,7 @@ private: /// table, indexed by the Selector ID (-1). std::vector<uint32_t> SelectorOffsets; - typedef llvm::MapVector<MacroInfo *, MacroUpdate> MacroUpdatesMap; + typedef llvm::MapVector<MacroDirective *, MacroUpdate> MacroUpdatesMap; /// \brief Updates to macro definitions that were loaded from an AST file. MacroUpdatesMap MacroUpdates; @@ -510,7 +510,7 @@ public: void AddIdentifierRef(const IdentifierInfo *II, RecordDataImpl &Record); /// \brief Emit a reference to a macro. - void addMacroRef(MacroInfo *MI, RecordDataImpl &Record); + void addMacroRef(MacroDirective *MI, RecordDataImpl &Record); /// \brief Emit a Selector (which is a smart pointer reference). void AddSelectorRef(Selector, RecordDataImpl &Record); @@ -530,7 +530,7 @@ public: serialization::IdentID getIdentifierRef(const IdentifierInfo *II); /// \brief Get the unique number used to refer to the given macro. - serialization::MacroID getMacroRef(MacroInfo *MI); + serialization::MacroID getMacroRef(MacroDirective *MI); /// \brief Emit a reference to a type. void AddTypeRef(QualType T, RecordDataImpl &Record); @@ -693,7 +693,7 @@ public: // ASTDeserializationListener implementation void ReaderInitialized(ASTReader *Reader); void IdentifierRead(serialization::IdentID ID, IdentifierInfo *II); - void MacroRead(serialization::MacroID ID, MacroInfo *MI); + void MacroRead(serialization::MacroID ID, MacroDirective *MI); void TypeRead(serialization::TypeIdx Idx, QualType T); void SelectorRead(serialization::SelectorID ID, Selector Sel); void MacroDefinitionRead(serialization::PreprocessedEntityID ID, @@ -701,7 +701,7 @@ public: void ModuleRead(serialization::SubmoduleID ID, Module *Mod); // PPMutationListener implementation. - virtual void UndefinedMacro(MacroInfo *MI); + virtual void UndefinedMacro(MacroDirective *MD); // ASTMutationListener implementation. virtual void CompletedTagDefinition(const TagDecl *D); diff --git a/lib/Frontend/PrintPreprocessedOutput.cpp b/lib/Frontend/PrintPreprocessedOutput.cpp index 4024093138..c85945b894 100644 --- a/lib/Frontend/PrintPreprocessedOutput.cpp +++ b/lib/Frontend/PrintPreprocessedOutput.cpp @@ -592,7 +592,7 @@ static void DoPrintMacros(Preprocessor &PP, raw_ostream *OS) { for (Preprocessor::macro_iterator I = PP.macro_begin(), E = PP.macro_end(); I != E; ++I) { if (I->first->hasMacroDefinition()) - MacrosByID.push_back(id_macro_pair(I->first, I->second)); + MacrosByID.push_back(id_macro_pair(I->first, I->second->getInfo())); } llvm::array_pod_sort(MacrosByID.begin(), MacrosByID.end(), MacroIDCompare); diff --git a/lib/Lex/MacroInfo.cpp b/lib/Lex/MacroInfo.cpp index d1875c79d0..ed6cc6edaf 100644 --- a/lib/Lex/MacroInfo.cpp +++ b/lib/Lex/MacroInfo.cpp @@ -17,7 +17,6 @@ using namespace clang; MacroInfo::MacroInfo(SourceLocation DefLoc) : Location(DefLoc), - PreviousDefinition(0), ArgumentList(0), NumArguments(0), IsDefinitionLengthCached(false), @@ -26,54 +25,10 @@ MacroInfo::MacroInfo(SourceLocation DefLoc) IsGNUVarargs(false), IsBuiltinMacro(false), HasCommaPasting(false), - IsFromAST(false), - ChangedAfterLoad(false), IsDisabled(false), IsUsed(false), IsAllowRedefinitionsWithoutWarning(false), - IsWarnIfUnused(false), - IsPublic(true), - IsHidden(false), - IsAmbiguous(false) { -} - -MacroInfo::MacroInfo(const MacroInfo &MI, llvm::BumpPtrAllocator &PPAllocator) - : Location(MI.Location), - EndLocation(MI.EndLocation), - UndefLocation(MI.UndefLocation), - PreviousDefinition(0), - ArgumentList(0), - NumArguments(0), - ReplacementTokens(MI.ReplacementTokens), - DefinitionLength(MI.DefinitionLength), - IsDefinitionLengthCached(MI.IsDefinitionLengthCached), - IsFunctionLike(MI.IsFunctionLike), - IsC99Varargs(MI.IsC99Varargs), - IsGNUVarargs(MI.IsGNUVarargs), - IsBuiltinMacro(MI.IsBuiltinMacro), - HasCommaPasting(MI.HasCommaPasting), - IsFromAST(MI.IsFromAST), - ChangedAfterLoad(MI.ChangedAfterLoad), - IsDisabled(MI.IsDisabled), - IsUsed(MI.IsUsed), - IsAllowRedefinitionsWithoutWarning(MI.IsAllowRedefinitionsWithoutWarning), - IsWarnIfUnused(MI.IsWarnIfUnused), - IsPublic(MI.IsPublic), - IsHidden(MI.IsHidden), - IsAmbiguous(MI.IsAmbiguous) { - setArgumentList(MI.ArgumentList, MI.NumArguments, PPAllocator); -} - -const MacroInfo *MacroInfo::findDefinitionAtLoc(SourceLocation L, - SourceManager &SM) const { - assert(L.isValid() && "SourceLocation is invalid."); - for (const MacroInfo *MI = this; MI; MI = MI->PreviousDefinition) { - if (MI->Location.isInvalid() || // For macros defined on the command line. - SM.isBeforeInTranslationUnit(MI->Location, L)) - return (MI->UndefLocation.isInvalid() || - SM.isBeforeInTranslationUnit(L, MI->UndefLocation)) ? MI : NULL; - } - return NULL; + IsWarnIfUnused(false) { } unsigned MacroInfo::getDefinitionLengthSlow(SourceManager &SM) const { @@ -151,3 +106,15 @@ bool MacroInfo::isIdenticalTo(const MacroInfo &Other, Preprocessor &PP) const { return true; } + +const MacroDirective * +MacroDirective::findDirectiveAtLoc(SourceLocation L, SourceManager &SM) const { + assert(L.isValid() && "SourceLocation is invalid."); + for (const MacroDirective *MD = this; MD; MD = MD->Previous) { + if (MD->getLocation().isInvalid() || // For macros defined on the command line. + SM.isBeforeInTranslationUnit(MD->getLocation(), L)) + return (MD->UndefLocation.isInvalid() || + SM.isBeforeInTranslationUnit(L, MD->UndefLocation)) ? MD : NULL; + } + return NULL; +} diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp index c8e1f4fc3e..18250281c1 100644 --- a/lib/Lex/PPDirectives.cpp +++ b/lib/Lex/PPDirectives.cpp @@ -57,10 +57,12 @@ MacroInfo *Preprocessor::AllocateMacroInfo(SourceLocation L) { return MI; } -MacroInfo *Preprocessor::CloneMacroInfo(const MacroInfo &MacroToClone) { - MacroInfo *MI = AllocateMacroInfo(); - new (MI) MacroInfo(MacroToClone, BP); - return MI; +MacroDirective *Preprocessor::AllocateMacroDirective(MacroInfo *MI, + SourceLocation Loc, + bool isImported) { + MacroDirective *MD = BP.Allocate<MacroDirective>(); + new (MD) MacroDirective(MI, Loc, isImported); + return MD; } /// \brief Release the specified MacroInfo to be reused for allocating @@ -1110,22 +1112,22 @@ void Preprocessor::HandleMacroPublicDirective(Token &Tok) { CheckEndOfDirective("__public_macro"); // Okay, we finally have a valid identifier to undef. - MacroInfo *MI = getMacroInfo(MacroNameTok.getIdentifierInfo()); + MacroDirective *MD = getMacroDirective(MacroNameTok.getIdentifierInfo()); // If the macro is not defined, this is an error. - if (MI == 0) { + if (MD == 0) { Diag(MacroNameTok, diag::err_pp_visibility_non_macro) << MacroNameTok.getIdentifierInfo(); return; } // Note that this macro has now been exported. - MI->setVisibility(/*IsPublic=*/true, MacroNameTok.getLocation()); - + MD->setVisibility(/*IsPublic=*/true, MacroNameTok.getLocation()); + // If this macro definition came from a PCH file, mark it // as having changed since serialization. - if (MI->isFromAST()) - MI->setChangedAfterLoad(); + if (MD->isImported()) + MD->setChangedAfterLoad(); } /// \brief Handle a #private directive. @@ -1141,22 +1143,22 @@ void Preprocessor::HandleMacroPrivateDirective(Token &Tok) { CheckEndOfDirective("__private_macro"); // Okay, we finally have a valid identifier to undef. - MacroInfo *MI = getMacroInfo(MacroNameTok.getIdentifierInfo()); + MacroDirective *MD = getMacroDirective(MacroNameTok.getIdentifierInfo()); // If the macro is not defined, this is an error. - if (MI == 0) { + if (MD == 0) { Diag(MacroNameTok, diag::err_pp_visibility_non_macro) << MacroNameTok.getIdentifierInfo(); return; } // Note that this macro has now been marked private. - MI->setVisibility(/*IsPublic=*/false, MacroNameTok.getLocation()); - + MD->setVisibility(/*IsPublic=*/false, MacroNameTok.getLocation()); + // If this macro definition came from a PCH file, mark it // as having changed since serialization. - if (MI->isFromAST()) - MI->setChangedAfterLoad(); + if (MD->isImported()) + MD->setChangedAfterLoad(); } //===----------------------------------------------------------------------===// @@ -1918,7 +1920,7 @@ void Preprocessor::HandleDefineDirective(Token &DefineTok) { // Finally, if this identifier already had a macro defined for it, verify that // the macro bodies are identical, and issue diagnostics if they are not. - if (MacroInfo *OtherMI = getMacroInfo(MacroNameTok.getIdentifierInfo())) { + if (const MacroInfo *OtherMI=getMacroInfo(MacroNameTok.getIdentifierInfo())) { // It is very common for system headers to have tons of macro redefinitions // and for warnings to be disabled in system headers. If this is the case, // then don't bother calling MacroInfo::isIdenticalTo. @@ -1940,7 +1942,7 @@ void Preprocessor::HandleDefineDirective(Token &DefineTok) { WarnUnusedMacroLocs.erase(OtherMI->getDefinitionLoc()); } - setMacroInfo(MacroNameTok.getIdentifierInfo(), MI); + setMacroDirective(MacroNameTok.getIdentifierInfo(), MI); assert(!MI->isUsed()); // If we need warning for not using the macro, add its location in the @@ -1973,7 +1975,8 @@ void Preprocessor::HandleUndefDirective(Token &UndefTok) { CheckEndOfDirective("undef"); // Okay, we finally have a valid identifier to undef. - MacroInfo *MI = getMacroInfo(MacroNameTok.getIdentifierInfo()); + MacroDirective *MD = getMacroDirective(MacroNameTok.getIdentifierInfo()); + const MacroInfo *MI = MD ? MD->getInfo() : 0; // If the callbacks want to know, tell them about the macro #undef. // Note: no matter if the macro was defined or not. @@ -1989,17 +1992,17 @@ void Preprocessor::HandleUndefDirective(Token &UndefTok) { if (MI->isWarnIfUnused()) WarnUnusedMacroLocs.erase(MI->getDefinitionLoc()); - UndefineMacro(MacroNameTok.getIdentifierInfo(), MI, + UndefineMacro(MacroNameTok.getIdentifierInfo(), MD, MacroNameTok.getLocation()); } -void Preprocessor::UndefineMacro(IdentifierInfo *II, MacroInfo *MI, +void Preprocessor::UndefineMacro(IdentifierInfo *II, MacroDirective *MD, SourceLocation UndefLoc) { - MI->setUndefLoc(UndefLoc); - if (MI->isFromAST()) { - MI->setChangedAfterLoad(); + MD->setUndefLoc(UndefLoc); + if (MD->isImported()) { + MD->setChangedAfterLoad(); if (Listener) - Listener->UndefinedMacro(MI); + Listener->UndefinedMacro(MD); } clearMacroInfo(II); diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp index bda31ed294..3e68fbdf01 100644 --- a/lib/Lex/PPMacroExpansion.cpp +++ b/lib/Lex/PPMacroExpansion.cpp @@ -32,7 +32,8 @@ #include <ctime> using namespace clang; -MacroInfo *Preprocessor::getMacroInfoHistory(const IdentifierInfo *II) const { +MacroDirective * +Preprocessor::getMacroDirectiveHistory(const IdentifierInfo *II) const { assert(II->hadMacroDefinition() && "Identifier has not been not a macro!"); macro_iterator Pos = Macros.find(II); @@ -42,32 +43,32 @@ MacroInfo *Preprocessor::getMacroInfoHistory(const IdentifierInfo *II) const { |