diff options
-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 { /// setMacroInfo - Specify a macro for this identifier. /// -void Preprocessor::setMacroInfo(IdentifierInfo *II, MacroInfo *MI) { +void Preprocessor::setMacroDirective(IdentifierInfo *II, MacroInfo *MI, + SourceLocation Loc, bool isImported) { assert(MI && "MacroInfo should be non-zero!"); - assert(MI->getUndefLoc().isInvalid() && - "Undefined macros cannot be registered"); - MacroInfo *&StoredMI = Macros[II]; - MI->setPreviousDefinition(StoredMI); - StoredMI = MI; - II->setHasMacroDefinition(MI->getUndefLoc().isInvalid()); + MacroDirective *MD = AllocateMacroDirective(MI, Loc, isImported); + MacroDirective *&StoredMD = Macros[II]; + MD->setPrevious(StoredMD); + StoredMD = MD; + II->setHasMacroDefinition(true); if (II->isFromAST()) II->setChangedSinceDeserialization(); } -void Preproc |