r178037 - [Preprocessor/Modules] Separate the macro directives kinds into their own MacroDirective's subclasses.
Argyrios Kyrtzidis
akyrtzi at gmail.com
Tue Mar 26 10:17:01 PDT 2013
Author: akirtzidis
Date: Tue Mar 26 12:17:01 2013
New Revision: 178037
URL: http://llvm.org/viewvc/llvm-project?rev=178037&view=rev
Log:
[Preprocessor/Modules] Separate the macro directives kinds into their own MacroDirective's subclasses.
For each macro directive (define, undefine, visibility) have a separate object that gets chained
to the macro directive history. This has several benefits:
-No need to mutate a MacroDirective when there is a undefine/visibility directive. Stuff like
PPMutationListener become unnecessary.
-No need to keep extra source locations for the undef/visibility locations for the define directive object
(which is the majority of the directives)
-Much easier to hide/unhide a section in the macro directive history.
-Easier to track the effects of the directives across different submodules.
Modified:
cfe/trunk/include/clang/Lex/MacroInfo.h
cfe/trunk/include/clang/Lex/Preprocessor.h
cfe/trunk/lib/Frontend/CompilerInstance.cpp
cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp
cfe/trunk/lib/Lex/MacroInfo.cpp
cfe/trunk/lib/Lex/PPDirectives.cpp
cfe/trunk/lib/Lex/PPExpressions.cpp
cfe/trunk/lib/Lex/PPMacroExpansion.cpp
cfe/trunk/lib/Lex/Pragma.cpp
cfe/trunk/lib/Lex/PreprocessingRecord.cpp
cfe/trunk/lib/Lex/Preprocessor.cpp
cfe/trunk/lib/Sema/SemaCodeComplete.cpp
cfe/trunk/lib/Serialization/ASTReader.cpp
cfe/trunk/lib/Serialization/ASTWriter.cpp
cfe/trunk/tools/libclang/CIndex.cpp
Modified: cfe/trunk/include/clang/Lex/MacroInfo.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/MacroInfo.h?rev=178037&r1=178036&r2=178037&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/MacroInfo.h (original)
+++ cfe/trunk/include/clang/Lex/MacroInfo.h Tue Mar 26 12:17:01 2013
@@ -299,6 +299,8 @@ private:
friend class Preprocessor;
};
+class DefMacroDirective;
+
/// \brief Encapsulates changes to the "macros namespace" (the location where
/// the macro name became active, the location where it was undefined, etc.).
///
@@ -314,76 +316,56 @@ private:
/// will point to the same MacroInfo object.
///
class MacroDirective {
- MacroInfo *Info;
+public:
+ enum Kind {
+ MD_Define,
+ MD_Undefine,
+ MD_Visibility
+ };
- /// \brief Previous definition, the identifier of this macro was defined to,
- /// or NULL.
+protected:
+ /// \brief Previous macro directive for the same identifier, 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 MacroDirective kind.
+ unsigned MDKind : 2;
/// \brief True if the macro directive was loaded from a PCH file.
bool IsFromPCH : 1;
- /// \brief True if this macro was imported from a module.
- 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".
+ /// \brief Whether the macro directive is currently "hidden".
///
/// Note that this is transient state that is never serialized to the AST
/// file.
bool IsHidden : 1;
+ // Used by DefMacroDirective -----------------------------------------------//
+
+ /// \brief True if this macro was imported from a module.
+ bool IsImported : 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;
+ // Used by VisibilityMacroDirective ----------------------------------------//
-public:
- explicit MacroDirective(MacroInfo *MI)
- : Info(MI), Previous(0), Loc(MI->getDefinitionLoc()),
- IsFromPCH(false), IsImported(false), IsPublic(true), IsHidden(false),
- IsAmbiguous(false), ChangedAfterLoad(false) {
- assert(MI && "MacroInfo is null");
- }
+ /// \brief Whether the macro has public visibility (when described in a
+ /// module).
+ bool IsPublic : 1;
- MacroDirective(MacroInfo *MI, SourceLocation Loc, bool isImported)
- : Info(MI), Previous(0), Loc(Loc),
- IsFromPCH(false), IsImported(isImported), IsPublic(true), IsHidden(false),
- IsAmbiguous(false), ChangedAfterLoad(false) {
- assert(MI && "MacroInfo is null");
+ MacroDirective(Kind K, SourceLocation Loc)
+ : Previous(0), Loc(Loc), MDKind(K), IsFromPCH(false), IsHidden(false),
+ IsImported(false), IsAmbiguous(false),
+ IsPublic(true) {
}
- 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;
- }
-
- /// \brief The data for the macro definition.
- const MacroInfo *getInfo() const { return Info; }
- MacroInfo *getInfo() { return Info; }
+public:
+ Kind getKind() const { return Kind(MDKind); }
- /// \brief Get the location where macro was undefined.
- SourceLocation getUndefLoc() const { return UndefLocation; }
+ SourceLocation getLocation() const { return Loc; }
/// \brief Set previous definition of the macro with the same name.
void setPrevious(MacroDirective *Prev) {
@@ -396,42 +378,104 @@ public:
/// \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 Return true if the macro directive was loaded from a PCH file.
+ bool isFromPCH() const { return IsFromPCH; }
- /// \brief Set the export location for this macro.
- void setVisibility(bool Public, SourceLocation Loc) {
- VisibilityLocation = Loc;
- IsPublic = Public;
+ void setIsFromPCH() { IsFromPCH = true; }
+
+ /// \brief Determine whether this macro directive is hidden.
+ bool isHidden() const { return IsHidden; }
+
+ /// \brief Set whether this macro directive is hidden.
+ void setHidden(bool Val) { IsHidden = Val; }
+
+ class DefInfo {
+ DefMacroDirective *DefDirective;
+ SourceLocation UndefLoc;
+ bool IsPublic;
+
+ public:
+ DefInfo() : DefDirective(0) { }
+
+ DefInfo(DefMacroDirective *DefDirective, SourceLocation UndefLoc,
+ bool isPublic)
+ : DefDirective(DefDirective), UndefLoc(UndefLoc), IsPublic(isPublic) { }
+
+ const DefMacroDirective *getDirective() const { return DefDirective; }
+ DefMacroDirective *getDirective() { return DefDirective; }
+
+ inline SourceLocation getLocation() const;
+ inline MacroInfo *getMacroInfo();
+ const MacroInfo *getMacroInfo() const {
+ return const_cast<DefInfo*>(this)->getMacroInfo();
+ }
+
+ SourceLocation getUndefLocation() const { return UndefLoc; }
+ bool isUndefined() const { return UndefLoc.isValid(); }
+
+ bool isPublic() const { return IsPublic; }
+
+ bool isValid() const { return DefDirective != 0; }
+ bool isInvalid() const { return !isValid(); }
+
+ operator bool() const { return isValid(); }
+
+ inline DefInfo getPreviousDefinition(bool AllowHidden = false);
+ const DefInfo getPreviousDefinition(bool AllowHidden = false) const {
+ return const_cast<DefInfo*>(this)->getPreviousDefinition(AllowHidden);
+ }
+ };
+
+ /// \brief Traverses the macro directives history and returns the next
+ /// macro definition directive along with info about its undefined location
+ /// (if there is one) and if it is public or private.
+ DefInfo getDefinition(bool AllowHidden = false);
+ const DefInfo getDefinition(bool AllowHidden = false) const {
+ return const_cast<MacroDirective*>(this)->getDefinition(AllowHidden);
}
- /// \brief Determine whether this macro is part of the public API of its
- /// module.
- bool isPublic() const { return IsPublic; }
-
- /// \brief Determine the location where this macro was explicitly made
- /// public or private within its module.
- SourceLocation getVisibilityLocation() const { return VisibilityLocation; }
+ bool isDefined(bool AllowHidden = false) const {
+ if (const DefInfo Def = getDefinition(AllowHidden))
+ return !Def.isUndefined();
+ return false;
+ }
- /// \brief Return true if the macro directive was loaded from a PCH file.
- bool isFromPCH() const { return IsFromPCH; }
+ const MacroInfo *getMacroInfo(bool AllowHidden = false) const {
+ return getDefinition(AllowHidden).getMacroInfo();
+ }
+ MacroInfo *getMacroInfo(bool AllowHidden = false) {
+ return getDefinition(AllowHidden).getMacroInfo();
+ }
- void setIsFromPCH() { IsFromPCH = true; }
+ /// \brief Find macro definition active in the specified source location. If
+ /// this macro was not defined there, return NULL.
+ const DefInfo findDirectiveAtLoc(SourceLocation L, SourceManager &SM) const;
- /// \brief True if this macro was imported from a module.
- bool isImported() const { return IsImported; }
+ static bool classof(const MacroDirective *) { return true; }
+};
- /// \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 A directive for a defined macro or a macro imported from a module.
+class DefMacroDirective : public MacroDirective {
+ MacroInfo *Info;
- /// \brief Determine whether this macro definition is hidden.
- bool isHidden() const { return IsHidden; }
+public:
+ explicit DefMacroDirective(MacroInfo *MI)
+ : MacroDirective(MD_Define, MI->getDefinitionLoc()), Info(MI) {
+ assert(MI && "MacroInfo is null");
+ }
- /// \brief Set whether this macro definition is hidden.
- void setHidden(bool Val) { IsHidden = Val; }
+ DefMacroDirective(MacroInfo *MI, SourceLocation Loc, bool isImported)
+ : MacroDirective(MD_Define, Loc), Info(MI) {
+ assert(MI && "MacroInfo is null");
+ IsImported = isImported;
+ }
+
+ /// \brief The data for the macro definition.
+ const MacroInfo *getInfo() const { return Info; }
+ MacroInfo *getInfo() { return Info; }
+
+ /// \brief True if this macro was imported from a module.
+ bool isImported() const { return IsImported; }
/// \brief Determine whether this macro definition is ambiguous with
/// other macro definitions.
@@ -440,15 +484,63 @@ public:
/// \brief Set whether this macro definition is ambiguous.
void setAmbiguous(bool Val) { IsAmbiguous = Val; }
- /// \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; }
+ static bool classof(const MacroDirective *MD) {
+ return MD->getKind() == MD_Define;
+ }
+ static bool classof(const DefMacroDirective *) { return true; }
+};
+
+/// \brief A directive for an undefined macro.
+class UndefMacroDirective : public MacroDirective {
+public:
+ explicit UndefMacroDirective(SourceLocation UndefLoc)
+ : MacroDirective(MD_Undefine, UndefLoc) {
+ assert(UndefLoc.isValid() && "Invalid UndefLoc!");
+ }
+
+ static bool classof(const MacroDirective *MD) {
+ return MD->getKind() == MD_Undefine;
+ }
+ static bool classof(const UndefMacroDirective *) { return true; }
+};
+
+/// \brief A directive for setting the module visibility of a macro.
+class VisibilityMacroDirective : public MacroDirective {
+public:
+ explicit VisibilityMacroDirective(SourceLocation Loc, bool Public)
+ : MacroDirective(MD_Visibility, Loc) {
+ IsPublic = Public;
+ }
+
+ /// \brief Determine whether this macro is part of the public API of its
+ /// module.
+ bool isPublic() const { return IsPublic; }
+
+ static bool classof(const MacroDirective *MD) {
+ return MD->getKind() == MD_Visibility;
+ }
+ static bool classof(const VisibilityMacroDirective *) { return true; }
};
+inline SourceLocation MacroDirective::DefInfo::getLocation() const {
+ if (isInvalid())
+ return SourceLocation();
+ return DefDirective->getLocation();
+}
+
+inline MacroInfo *MacroDirective::DefInfo::getMacroInfo() {
+ if (isInvalid())
+ return 0;
+ return DefDirective->getInfo();
+}
+
+inline MacroDirective::DefInfo
+MacroDirective::DefInfo::getPreviousDefinition(bool AllowHidden) {
+ if (isInvalid() || DefDirective->getPrevious() == 0)
+ return DefInfo();
+ return DefDirective->getPrevious()->getDefinition(AllowHidden);
+}
+
} // end namespace clang
#endif
Modified: cfe/trunk/include/clang/Lex/Preprocessor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/Preprocessor.h?rev=178037&r1=178036&r2=178037&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/Preprocessor.h (original)
+++ cfe/trunk/include/clang/Lex/Preprocessor.h Tue Mar 26 12:17:01 2013
@@ -532,14 +532,14 @@ public:
/// associated with this preprocessor, if any.
PPMutationListener *getPPMutationListener() const { return Listener; }
- /// \brief Given an identifier, return the MacroInfo it is \#defined to
- /// or null if it isn't \#define'd.
+ /// \brief Given an identifier, return its latest MacroDirective if it is
+ // \#defined or null if it isn't \#define'd.
MacroDirective *getMacroDirective(IdentifierInfo *II) const {
if (!II->hasMacroDefinition())
return 0;
MacroDirective *MD = getMacroDirectiveHistory(II);
- assert(MD->getUndefLoc().isInvalid() && "Macro is undefined!");
+ assert(MD->isDefined() && "Macro is undefined!");
return MD;
}
@@ -549,7 +549,7 @@ public:
MacroInfo *getMacroInfo(IdentifierInfo *II) {
if (MacroDirective *MD = getMacroDirective(II))
- return MD->getInfo();
+ return MD->getMacroInfo();
return 0;
}
@@ -559,27 +559,20 @@ public:
/// identifiers that hadMacroDefinition().
MacroDirective *getMacroDirectiveHistory(const IdentifierInfo *II) const;
- /// \brief Specify a macro for this identifier.
- void setMacroDirective(IdentifierInfo *II, MacroDirective *MD);
- MacroDirective *setMacroDirective(IdentifierInfo *II, MacroInfo *MI,
- SourceLocation Loc, bool isImported) {
- MacroDirective *MD = AllocateMacroDirective(MI, Loc, isImported);
- setMacroDirective(II, MD);
+ /// \brief Add a directive to the macro directive history for this identifier.
+ void appendMacroDirective(IdentifierInfo *II, MacroDirective *MD);
+ DefMacroDirective *appendDefMacroDirective(IdentifierInfo *II, MacroInfo *MI,
+ SourceLocation Loc,
+ bool isImported) {
+ DefMacroDirective *MD = AllocateDefMacroDirective(MI, Loc, isImported);
+ appendMacroDirective(II, MD);
return MD;
}
- MacroDirective *setMacroDirective(IdentifierInfo *II, MacroInfo *MI) {
- return setMacroDirective(II, MI, MI->getDefinitionLoc(), false);
+ DefMacroDirective *appendDefMacroDirective(IdentifierInfo *II, MacroInfo *MI){
+ return appendDefMacroDirective(II, MI, MI->getDefinitionLoc(), false);
}
/// \brief Set a MacroDirective that was loaded from a PCH file.
void setLoadedMacroDirective(IdentifierInfo *II, MacroDirective *MD);
- /// \brief Add a MacroInfo that was loaded from an AST file.
- 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, MacroDirective *MD);
- /// \brief Undefine a macro for this identifier.
- void clearMacroInfo(IdentifierInfo *II);
/// macro_iterator/macro_begin/macro_end - This allows you to walk the macro
/// history table. Currently defined macros have
@@ -1294,8 +1287,12 @@ private:
/// \brief Allocate a new MacroInfo object.
MacroInfo *AllocateMacroInfo();
- MacroDirective *AllocateMacroDirective(MacroInfo *MI, SourceLocation Loc,
- bool isImported);
+ DefMacroDirective *AllocateDefMacroDirective(MacroInfo *MI,
+ SourceLocation Loc,
+ bool isImported);
+ UndefMacroDirective *AllocateUndefMacroDirective(SourceLocation UndefLoc);
+ VisibilityMacroDirective *AllocateVisibilityMacroDirective(SourceLocation Loc,
+ bool isPublic);
/// \brief Release the specified MacroInfo for re-use.
///
@@ -1449,8 +1446,6 @@ private:
// Macro handling.
void HandleDefineDirective(Token &Tok);
void HandleUndefDirective(Token &Tok);
- void UndefineMacro(IdentifierInfo *II, MacroDirective *MD,
- SourceLocation UndefLoc);
// Conditional Inclusion.
void HandleIfdefDirective(Token &Tok, bool isIfndef,
Modified: cfe/trunk/lib/Frontend/CompilerInstance.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInstance.cpp?rev=178037&r1=178036&r2=178037&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/CompilerInstance.cpp (original)
+++ cfe/trunk/lib/Frontend/CompilerInstance.cpp Tue Mar 26 12:17:01 2013
@@ -923,10 +923,11 @@ static void checkConfigMacro(Preprocesso
// If this identifier does not currently have a macro definition,
// check whether it had one on the command line.
if (!Id->hasMacroDefinition()) {
- MacroDirective *UndefMD = PP.getMacroDirectiveHistory(Id);
- for (MacroDirective *MD = UndefMD; MD; MD = MD->getPrevious()) {
-
- FileID FID = SourceMgr.getFileID(MD->getLocation());
+ MacroDirective::DefInfo LatestDef =
+ PP.getMacroDirectiveHistory(Id)->getDefinition();
+ for (MacroDirective::DefInfo Def = LatestDef; Def;
+ Def = Def.getPreviousDefinition()) {
+ FileID FID = SourceMgr.getFileID(Def.getLocation());
if (FID.isInvalid())
continue;
@@ -942,8 +943,8 @@ static void checkConfigMacro(Preprocesso
// Complain.
PP.Diag(ImportLoc, diag::warn_module_config_macro_undef)
<< true << ConfigMacro << Mod->getFullModuleName();
- if (UndefMD->getUndefLoc().isValid())
- PP.Diag(UndefMD->getUndefLoc(), diag::note_module_def_undef_here)
+ if (LatestDef.isUndefined())
+ PP.Diag(LatestDef.getUndefLocation(), diag::note_module_def_undef_here)
<< true;
return;
}
@@ -954,10 +955,12 @@ static void checkConfigMacro(Preprocesso
// This identifier has a macro definition. Check whether we had a definition
// on the command line.
- MacroDirective *DefMD = PP.getMacroDirective(Id);
- MacroDirective *PredefinedMD = 0;
- for (MacroDirective *MD = DefMD; MD; MD = MD->getPrevious()) {
- FileID FID = SourceMgr.getFileID(MD->getLocation());
+ MacroDirective::DefInfo LatestDef =
+ PP.getMacroDirectiveHistory(Id)->getDefinition();
+ MacroDirective::DefInfo PredefinedDef;
+ for (MacroDirective::DefInfo Def = LatestDef; Def;
+ Def = Def.getPreviousDefinition()) {
+ FileID FID = SourceMgr.getFileID(Def.getLocation());
if (FID.isInvalid())
continue;
@@ -969,32 +972,32 @@ static void checkConfigMacro(Preprocesso
if (!StringRef(Buffer->getBufferIdentifier()).equals("<built-in>"))
continue;
- PredefinedMD = MD;
+ PredefinedDef = Def;
break;
}
// If there was no definition for this macro in the predefines buffer,
// complain.
- if (!PredefinedMD ||
- (!PredefinedMD->getLocation().isValid() &&
- PredefinedMD->getUndefLoc().isValid())) {
+ if (!PredefinedDef ||
+ (!PredefinedDef.getLocation().isValid() &&
+ PredefinedDef.getUndefLocation().isValid())) {
PP.Diag(ImportLoc, diag::warn_module_config_macro_undef)
<< false << ConfigMacro << Mod->getFullModuleName();
- PP.Diag(DefMD->getLocation(), diag::note_module_def_undef_here)
+ PP.Diag(LatestDef.getLocation(), diag::note_module_def_undef_here)
<< false;
return;
}
// If the current macro definition is the same as the predefined macro
// definition, it's okay.
- if (DefMD == PredefinedMD ||
- DefMD->getInfo()->isIdenticalTo(*PredefinedMD->getInfo(), PP))
+ if (LatestDef.getMacroInfo() == PredefinedDef.getMacroInfo() ||
+ LatestDef.getMacroInfo()->isIdenticalTo(*PredefinedDef.getMacroInfo(),PP))
return;
// The macro definitions differ.
PP.Diag(ImportLoc, diag::warn_module_config_macro_undef)
<< false << ConfigMacro << Mod->getFullModuleName();
- PP.Diag(DefMD->getLocation(), diag::note_module_def_undef_here)
+ PP.Diag(LatestDef.getLocation(), diag::note_module_def_undef_here)
<< false;
}
Modified: cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp?rev=178037&r1=178036&r2=178037&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp (original)
+++ cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp Tue Mar 26 12:17:01 2013
@@ -318,7 +318,7 @@ void PrintPPOutputPPCallbacks::Ident(Sou
/// MacroDefined - This hook is called whenever a macro definition is seen.
void PrintPPOutputPPCallbacks::MacroDefined(const Token &MacroNameTok,
const MacroDirective *MD) {
- const MacroInfo *MI = MD->getInfo();
+ const MacroInfo *MI = MD->getMacroInfo();
// Only print out macro definitions in -dD mode.
if (!DumpDefines ||
// Ignore __FILE__ etc.
@@ -602,7 +602,7 @@ static void DoPrintMacros(Preprocessor &
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->getInfo()));
+ MacrosByID.push_back(id_macro_pair(I->first, I->second->getMacroInfo()));
}
llvm::array_pod_sort(MacrosByID.begin(), MacrosByID.end(), MacroIDCompare);
Modified: cfe/trunk/lib/Lex/MacroInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/MacroInfo.cpp?rev=178037&r1=178036&r2=178037&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/MacroInfo.cpp (original)
+++ cfe/trunk/lib/Lex/MacroInfo.cpp Tue Mar 26 12:17:01 2013
@@ -108,14 +108,40 @@ bool MacroInfo::isIdenticalTo(const Macr
return true;
}
-const MacroDirective *
+MacroDirective::DefInfo MacroDirective::getDefinition(bool AllowHidden) {
+ MacroDirective *MD = this;
+ SourceLocation UndefLoc;
+ Optional<bool> isPublic;
+ for (; MD; MD = MD->getPrevious()) {
+ if (!AllowHidden && MD->isHidden())
+ continue;
+
+ if (DefMacroDirective *DefMD = dyn_cast<DefMacroDirective>(MD))
+ return DefInfo(DefMD, UndefLoc,
+ !isPublic.hasValue() || isPublic.getValue());
+
+ if (UndefMacroDirective *UndefMD = dyn_cast<UndefMacroDirective>(MD)) {
+ UndefLoc = UndefMD->getLocation();
+ continue;
+ }
+
+ VisibilityMacroDirective *VisMD = cast<VisibilityMacroDirective>(MD);
+ if (!isPublic.hasValue())
+ isPublic = VisMD->isPublic();
+ }
+
+ return DefInfo();
+}
+
+const MacroDirective::DefInfo
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;
+ for (DefInfo Def = getDefinition(); Def; Def = Def.getPreviousDefinition()) {
+ if (Def.getLocation().isInvalid() || // For macros defined on the command line.
+ SM.isBeforeInTranslationUnit(Def.getLocation(), L))
+ return (!Def.isUndefined() ||
+ SM.isBeforeInTranslationUnit(L, Def.getUndefLocation()))
+ ? Def : DefInfo();
}
- return NULL;
+ return DefInfo();
}
Modified: cfe/trunk/lib/Lex/PPDirectives.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPDirectives.cpp?rev=178037&r1=178036&r2=178037&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/PPDirectives.cpp (original)
+++ cfe/trunk/lib/Lex/PPDirectives.cpp Tue Mar 26 12:17:01 2013
@@ -70,11 +70,26 @@ MacroInfo *Preprocessor::AllocateDeseria
return MI;
}
-MacroDirective *Preprocessor::AllocateMacroDirective(MacroInfo *MI,
- SourceLocation Loc,
- bool isImported) {
- MacroDirective *MD = BP.Allocate<MacroDirective>();
- new (MD) MacroDirective(MI, Loc, isImported);
+DefMacroDirective *
+Preprocessor::AllocateDefMacroDirective(MacroInfo *MI, SourceLocation Loc,
+ bool isImported) {
+ DefMacroDirective *MD = BP.Allocate<DefMacroDirective>();
+ new (MD) DefMacroDirective(MI, Loc, isImported);
+ return MD;
+}
+
+UndefMacroDirective *
+Preprocessor::AllocateUndefMacroDirective(SourceLocation UndefLoc) {
+ UndefMacroDirective *MD = BP.Allocate<UndefMacroDirective>();
+ new (MD) UndefMacroDirective(UndefLoc);
+ return MD;
+}
+
+VisibilityMacroDirective *
+Preprocessor::AllocateVisibilityMacroDirective(SourceLocation Loc,
+ bool isPublic) {
+ VisibilityMacroDirective *MD = BP.Allocate<VisibilityMacroDirective>();
+ new (MD) VisibilityMacroDirective(Loc, isPublic);
return MD;
}
@@ -1130,15 +1145,8 @@ void Preprocessor::HandleMacroPublicDire
}
// Note that this macro has now been exported.
- MD->setVisibility(/*IsPublic=*/true, MacroNameTok.getLocation());
-
- // If this macro directive came from a PCH file, mark it as having changed
- // since serialization.
- if (MD->isFromPCH()) {
- MD->setChangedAfterLoad();
- assert(II->isFromAST());
- II->setChangedSinceDeserialization();
- }
+ appendMacroDirective(II, AllocateVisibilityMacroDirective(
+ MacroNameTok.getLocation(), /*IsPublic=*/true));
}
/// \brief Handle a #private directive.
@@ -1164,15 +1172,8 @@ void Preprocessor::HandleMacroPrivateDir
}
// Note that this macro has now been marked private.
- MD->setVisibility(/*IsPublic=*/false, MacroNameTok.getLocation());
-
- // If this macro directive came from a PCH file, mark it as having changed
- // since serialization.
- if (MD->isFromPCH()) {
- MD->setChangedAfterLoad();
- assert(II->isFromAST());
- II->setChangedSinceDeserialization();
- }
+ appendMacroDirective(II, AllocateVisibilityMacroDirective(
+ MacroNameTok.getLocation(), /*IsPublic=*/false));
}
//===----------------------------------------------------------------------===//
@@ -1960,7 +1961,8 @@ void Preprocessor::HandleDefineDirective
WarnUnusedMacroLocs.erase(OtherMI->getDefinitionLoc());
}
- MacroDirective *MD = setMacroDirective(MacroNameTok.getIdentifierInfo(), MI);
+ DefMacroDirective *MD =
+ appendDefMacroDirective(MacroNameTok.getIdentifierInfo(), MI);
assert(!MI->isUsed());
// If we need warning for not using the macro, add its location in the
@@ -1994,7 +1996,7 @@ void Preprocessor::HandleUndefDirective(
// Okay, we finally have a valid identifier to undef.
MacroDirective *MD = getMacroDirective(MacroNameTok.getIdentifierInfo());
- const MacroInfo *MI = MD ? MD->getInfo() : 0;
+ const MacroInfo *MI = MD ? MD->getMacroInfo() : 0;
// If the callbacks want to know, tell them about the macro #undef.
// Note: no matter if the macro was defined or not.
@@ -2010,20 +2012,8 @@ void Preprocessor::HandleUndefDirective(
if (MI->isWarnIfUnused())
WarnUnusedMacroLocs.erase(MI->getDefinitionLoc());
- UndefineMacro(MacroNameTok.getIdentifierInfo(), MD,
- MacroNameTok.getLocation());
-}
-
-void Preprocessor::UndefineMacro(IdentifierInfo *II, MacroDirective *MD,
- SourceLocation UndefLoc) {
- MD->setUndefLoc(UndefLoc);
- if (MD->isFromPCH()) {
- MD->setChangedAfterLoad();
- if (Listener)
- Listener->UndefinedMacro(MD);
- }
-
- clearMacroInfo(II);
+ appendMacroDirective(MacroNameTok.getIdentifierInfo(),
+ AllocateUndefMacroDirective(MacroNameTok.getLocation()));
}
@@ -2058,7 +2048,7 @@ void Preprocessor::HandleIfdefDirective(
IdentifierInfo *MII = MacroNameTok.getIdentifierInfo();
MacroDirective *MD = getMacroDirective(MII);
- MacroInfo *MI = MD ? MD->getInfo() : 0;
+ MacroInfo *MI = MD ? MD->getMacroInfo() : 0;
if (CurPPLexer->getConditionalStackDepth() == 0) {
// If the start of a top-level #ifdef and if the macro is not defined,
Modified: cfe/trunk/lib/Lex/PPExpressions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPExpressions.cpp?rev=178037&r1=178036&r2=178037&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/PPExpressions.cpp (original)
+++ cfe/trunk/lib/Lex/PPExpressions.cpp Tue Mar 26 12:17:01 2013
@@ -116,7 +116,7 @@ static bool EvaluateDefined(PPValue &Res
// If there is a macro, mark it used.
if (Result.Val != 0 && ValueLive) {
Macro = PP.getMacroDirective(II);
- PP.markMacroAsUsed(Macro->getInfo());
+ PP.markMacroAsUsed(Macro->getMacroInfo());
}
// Invoke the 'defined' callback.
Modified: cfe/trunk/lib/Lex/PPMacroExpansion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPMacroExpansion.cpp?rev=178037&r1=178036&r2=178037&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/PPMacroExpansion.cpp (original)
+++ cfe/trunk/lib/Lex/PPMacroExpansion.cpp Tue Mar 26 12:17:01 2013
@@ -41,15 +41,17 @@ Preprocessor::getMacroDirectiveHistory(c
return Pos->second;
}
-/// \brief Specify a macro for this identifier.
-void Preprocessor::setMacroDirective(IdentifierInfo *II, MacroDirective *MD) {
+void Preprocessor::appendMacroDirective(IdentifierInfo *II, MacroDirective *MD){
assert(MD && "MacroDirective should be non-zero!");
+ assert(!MD->getPrevious() && "Already attached to a MacroDirective history.");
MacroDirective *&StoredMD = Macros[II];
MD->setPrevious(StoredMD);
StoredMD = MD;
- II->setHasMacroDefinition(true);
- if (II->isFromAST())
+ II->setHasMacroDefinition(MD->isDefined());
+ bool isImportedMacro = isa<DefMacroDirective>(MD) &&
+ cast<DefMacroDirective>(MD)->isImported();
+ if (II->isFromAST() && !isImportedMacro)
II->setChangedSinceDeserialization();
}
@@ -66,112 +68,6 @@ void Preprocessor::setLoadedMacroDirecti
II->setHasMacroDefinition(false);
}
-void Preprocessor::addLoadedMacroInfo(IdentifierInfo *II, MacroDirective *MD,
- MacroDirective *Hint) {
- assert(MD && "Missing macro?");
- assert(MD->isImported() && "Macro is not from an AST?");
- assert(!MD->getPrevious() && "Macro already in chain?");
-
- MacroDirective *&StoredMD = Macros[II];
-
- // Easy case: this is the first macro definition for this macro.
- if (!StoredMD) {
- StoredMD = MD;
-
- if (MD->isDefined())
- II->setHasMacroDefinition(true);
- return;
- }
-
- // If this macro is a definition and this identifier has been neither
- // defined nor undef'd in the current translation unit, add this macro
- // to the end of the chain of definitions.
- if (MD->isDefined() && StoredMD->isImported()) {
- // Simple case: if this is the first actual definition, just put it at
- // th beginning.
- if (!StoredMD->isDefined()) {
- MD->setPrevious(StoredMD);
- StoredMD = MD;
-
- II->setHasMacroDefinition(true);
- return;
- }
-
- // Find the end of the definition chain.
- MacroDirective *Prev;
- MacroDirective *PrevPrev = StoredMD;
- bool Ambiguous = StoredMD->isAmbiguous();
- bool MatchedOther = false;
- do {
- Prev = PrevPrev;
-
- // If the macros are not identical, we have an ambiguity.
- if (!Prev->getInfo()->isIdenticalTo(*MD->getInfo(), *this)) {
- if (!Ambiguous) {
- Ambiguous = true;
- StoredMD->setAmbiguous(true);
- }
- } else {
- MatchedOther = true;
- }
- } while ((PrevPrev = Prev->getPrevious()) &&
- PrevPrev->isDefined());
-
- // If there are ambiguous definitions, and we didn't match any other
- // definition, then mark us as ambiguous.
- if (Ambiguous && !MatchedOther)
- MD->setAmbiguous(true);
-
- // Wire this macro information into the chain.
- MD->setPrevious(Prev->getPrevious());
- Prev->setPrevious(MD);
- return;
- }
-
- // The macro is not a definition; put it at the end of the list.
- MacroDirective *Prev = Hint? Hint : StoredMD;
- while (Prev->getPrevious())
- Prev = Prev->getPrevious();
- Prev->setPrevious(MD);
-}
-
-void Preprocessor::makeLoadedMacroInfoVisible(IdentifierInfo *II,
- MacroDirective *MD) {
- assert(MD->isImported() && "Macro must be from the AST");
-
- MacroDirective *&StoredMD = Macros[II];
- if (StoredMD == MD) {
- // Easy case: this is the first macro anyway.
- II->setHasMacroDefinition(MD->isDefined());
- return;
- }
-
- // Go find the macro and pull it out of the list.
- // FIXME: Yes, this is O(N), and making a pile of macros visible or hidden
- // would be quadratic, but it's extremely rare.
- MacroDirective *Prev = StoredMD;
- while (Prev->getPrevious() != MD)
- Prev = Prev->getPrevious();
- Prev->setPrevious(MD->getPrevious());
- MD->setPrevious(0);
-
- // Add the macro back to the list.
- addLoadedMacroInfo(II, MD);
-
- II->setHasMacroDefinition(StoredMD->isDefined());
- if (II->isFromAST())
- II->setChangedSinceDeserialization();
-}
-
-/// \brief Undefine a macro for this identifier.
-void Preprocessor::clearMacroInfo(IdentifierInfo *II) {
- assert(II->hasMacroDefinition() && "Macro is not defined!");
- assert(Macros[II]->getUndefLoc().isValid() && "Macro is still defined!");
- II->setHasMacroDefinition(false);
- if (II->isFromAST())
- II->setChangedSinceDeserialization();
-}
-
/// RegisterBuiltinMacro - Register the specified identifier in the identifier
/// table and mark it as a builtin macro to be expanded.
static IdentifierInfo *RegisterBuiltinMacro(Preprocessor &PP, const char *Name){
@@ -181,7 +77,7 @@ static IdentifierInfo *RegisterBuiltinMa
// Mark it as being a macro that is builtin.
MacroInfo *MI = PP.AllocateMacroInfo(SourceLocation());
MI->setIsBuiltinMacro();
- PP.setMacroDirective(Id, MI);
+ PP.appendDefMacroDirective(Id, MI);
return Id;
}
@@ -315,7 +211,7 @@ bool Preprocessor::isNextPPTokenLParen()
/// expanded as a macro, handle it and return the next token as 'Identifier'.
bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier,
MacroDirective *MD) {
- MacroInfo *MI = MD->getInfo();
+ MacroInfo *MI = MD->getMacroInfo();
// If this is a macro expansion in the "#if !defined(x)" line for the file,
// then the macro could expand to different things in other contexts, we need
Modified: cfe/trunk/lib/Lex/Pragma.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/Pragma.cpp?rev=178037&r1=178036&r2=178037&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/Pragma.cpp (original)
+++ cfe/trunk/lib/Lex/Pragma.cpp Tue Mar 26 12:17:01 2013
@@ -703,9 +703,10 @@ void Preprocessor::HandlePragmaPopMacro(
if (iter != PragmaPushMacroInfo.end()) {
// Forget the MacroInfo currently associated with IdentInfo.
if (MacroDirective *CurrentMD = getMacroDirective(IdentInfo)) {
- if (CurrentMD->getInfo()->isWarnIfUnused())
- WarnUnusedMacroLocs.erase(CurrentMD->getInfo()->getDefinitionLoc());
- UndefineMacro(IdentInfo, CurrentMD, MessageLoc);
+ MacroInfo *MI = CurrentMD->getMacroInfo();
+ if (MI->isWarnIfUnused())
+ WarnUnusedMacroLocs.erase(MI->getDefinitionLoc());
+ appendMacroDirective(IdentInfo, AllocateUndefMacroDirective(MessageLoc));
}
// Get the MacroInfo we want to reinstall.
@@ -713,10 +714,8 @@ void Preprocessor::HandlePragmaPopMacro(
if (MacroToReInstall) {
// Reinstall the previously pushed macro.
- setMacroDirective(IdentInfo, MacroToReInstall, MessageLoc,
- /*isImported=*/false);
- } else if (IdentInfo->hasMacroDefinition()) {
- clearMacroInfo(IdentInfo);
+ appendDefMacroDirective(IdentInfo, MacroToReInstall, MessageLoc,
+ /*isImported=*/false);
}
// Pop PragmaPushMacroInfo stack.
Modified: cfe/trunk/lib/Lex/PreprocessingRecord.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PreprocessingRecord.cpp?rev=178037&r1=178036&r2=178037&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/PreprocessingRecord.cpp (original)
+++ cfe/trunk/lib/Lex/PreprocessingRecord.cpp Tue Mar 26 12:17:01 2013
@@ -385,31 +385,34 @@ void PreprocessingRecord::Ifdef(SourceLo
const MacroDirective *MD) {
// This is not actually a macro expansion but record it as a macro reference.
if (MD)
- addMacroExpansion(MacroNameTok, MD->getInfo(), MacroNameTok.getLocation());
+ addMacroExpansion(MacroNameTok, MD->getMacroInfo(),
+ MacroNameTok.getLocation());
}
void PreprocessingRecord::Ifndef(SourceLocation Loc, const Token &MacroNameTok,
const MacroDirective *MD) {
// This is not actually a macro expansion but record it as a macro reference.
if (MD)
- addMacroExpansion(MacroNameTok, MD->getInfo(), MacroNameTok.getLocation());
+ addMacroExpansion(MacroNameTok, MD->getMacroInfo(),
+ MacroNameTok.getLocation());
}
void PreprocessingRecord::Defined(const Token &MacroNameTok,
const MacroDirective *MD) {
// This is not actually a macro expansion but record it as a macro reference.
if (MD)
- addMacroExpansion(MacroNameTok, MD->getInfo(), MacroNameTok.getLocation());
+ addMacroExpansion(MacroNameTok, MD->getMacroInfo(),
+ MacroNameTok.getLocation());
}
void PreprocessingRecord::MacroExpands(const Token &Id,const MacroDirective *MD,
SourceRange Range) {
- addMacroExpansion(Id, MD->getInfo(), Range);
+ addMacroExpansion(Id, MD->getMacroInfo(), Range);
}
void PreprocessingRecord::MacroDefined(const Token &Id,
const MacroDirective *MD) {
- const MacroInfo *MI = MD->getInfo();
+ const MacroInfo *MI = MD->getMacroInfo();
SourceRange R(MI->getDefinitionLoc(), MI->getDefinitionEndLoc());
MacroDefinition *Def
= new (*this) MacroDefinition(Id.getIdentifierInfo(), R);
@@ -421,7 +424,7 @@ void PreprocessingRecord::MacroUndefined
const MacroDirective *MD) {
// Note: MI may be null (when #undef'ining an undefined macro).
if (MD)
- MacroDefinitions.erase(MD->getInfo());
+ MacroDefinitions.erase(MD->getMacroInfo());
}
void PreprocessingRecord::InclusionDirective(
Modified: cfe/trunk/lib/Lex/Preprocessor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/Preprocessor.cpp?rev=178037&r1=178036&r2=178037&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/Preprocessor.cpp (original)
+++ cfe/trunk/lib/Lex/Preprocessor.cpp Tue Mar 26 12:17:01 2013
@@ -306,15 +306,15 @@ StringRef Preprocessor::getLastMacroWith
StringRef BestSpelling;
for (Preprocessor::macro_iterator I = macro_begin(), E = macro_end();
I != E; ++I) {
- if (!I->second->getInfo()->isObjectLike())
+ if (!I->second->getMacroInfo()->isObjectLike())
continue;
- const MacroDirective *
- MD = I->second->findDirectiveAtLoc(Loc, SourceMgr);
- if (!MD)
+ const MacroDirective::DefInfo
+ Def = I->second->findDirectiveAtLoc(Loc, SourceMgr);
+ if (!Def)
continue;
- if (!MacroDefinitionEquals(MD->getInfo(), Tokens))
+ if (!MacroDefinitionEquals(Def.getMacroInfo(), Tokens))
continue;
- SourceLocation Location = I->second->getInfo()->getDefinitionLoc();
+ SourceLocation Location = Def.getLocation();
// Choose the macro defined latest.
if (BestLocation.isInvalid() ||
(Location.isValid() &&
@@ -643,7 +643,7 @@ void Preprocessor::HandleIdentifier(Toke
// If this is a macro to be expanded, do it.
if (MacroDirective *MD = getMacroDirective(&II)) {
- MacroInfo *MI = MD->getInfo();
+ MacroInfo *MI = MD->getMacroInfo();
if (!DisableMacroExpansion) {
if (!Identifier.isExpandDisabled() && MI->isEnabled()) {
if (!HandleMacroExpandedIdentifier(Identifier, MD))
Modified: cfe/trunk/lib/Sema/SemaCodeComplete.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCodeComplete.cpp?rev=178037&r1=178036&r2=178037&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCodeComplete.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCodeComplete.cpp Tue Mar 26 12:17:01 2013
@@ -2575,7 +2575,7 @@ CodeCompletionResult::CreateCodeCompleti
if (Kind == RK_Macro) {
const MacroDirective *MD = PP.getMacroDirectiveHistory(Macro);
assert(MD && "Not a macro?");
- const MacroInfo *MI = MD->getInfo();
+ const MacroInfo *MI = MD->getMacroInfo();
Result.AddTypedTextChunk(
Result.getAllocator().CopyString(Macro->getName()));
Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=178037&r1=178036&r2=178037&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Tue Mar 26 12:17:01 2013
@@ -1476,8 +1476,8 @@ void ASTReader::resolvePendingMacro(Iden
MacroInfo *MI = getMacro(GMacID);
SubmoduleID SubModID = MI->getOwningModuleID();
- MacroDirective *MD = PP.AllocateMacroDirective(MI, ImportLoc,
- /*isImported=*/true);
+ MacroDirective *MD = PP.AllocateDefMacroDirective(MI, ImportLoc,
+ /*isImported=*/true);
// Determine whether this macro definition is visible.
bool Hidden = false;
@@ -1494,7 +1494,6 @@ void ASTReader::resolvePendingMacro(Iden
}
}
}
- MD->setHidden(Hidden);
if (!Hidden)
installImportedMacro(II, MD);
@@ -1527,22 +1526,30 @@ void ASTReader::installPCHMacroDirective
MacroDirective *Latest = 0, *Earliest = 0;
unsigned Idx = 0, N = Record.size();
while (Idx < N) {
- GlobalMacroID GMacID = getGlobalMacroID(M, Record[Idx++]);
- MacroInfo *MI = getMacro(GMacID);
+ MacroDirective *MD = 0;
SourceLocation Loc = ReadSourceLocation(M, Record, Idx);
- SourceLocation UndefLoc = ReadSourceLocation(M, Record, Idx);
- SourceLocation VisibilityLoc = ReadSourceLocation(M, Record, Idx);
- bool isImported = Record[Idx++];
- bool isPublic = Record[Idx++];
- bool isAmbiguous = Record[Idx++];
-
- MacroDirective *MD = PP.AllocateMacroDirective(MI, Loc, isImported);
- if (UndefLoc.isValid())
- MD->setUndefLoc(UndefLoc);
- if (VisibilityLoc.isValid())
- MD->setVisibility(isPublic, VisibilityLoc);
- MD->setAmbiguous(isAmbiguous);
- MD->setIsFromPCH();
+ MacroDirective::Kind K = (MacroDirective::Kind)Record[Idx++];
+ switch (K) {
+ case MacroDirective::MD_Define: {
+ GlobalMacroID GMacID = getGlobalMacroID(M, Record[Idx++]);
+ MacroInfo *MI = getMacro(GMacID);
+ bool isImported = Record[Idx++];
+ bool isAmbiguous = Record[Idx++];
+ DefMacroDirective *DefMD =
+ PP.AllocateDefMacroDirective(MI, Loc, isImported);
+ DefMD->setAmbiguous(isAmbiguous);
+ MD = DefMD;
+ break;
+ }
+ case MacroDirective::MD_Undefine:
+ MD = PP.AllocateUndefMacroDirective(Loc);
+ break;
+ case MacroDirective::MD_Visibility: {
+ bool isPublic = Record[Idx++];
+ MD = PP.AllocateVisibilityMacroDirective(Loc, isPublic);
+ break;
+ }
+ }
if (!Latest)
Latest = MD;
@@ -1557,13 +1564,18 @@ void ASTReader::installPCHMacroDirective
void ASTReader::installImportedMacro(IdentifierInfo *II, MacroDirective *MD) {
assert(II && MD);
+ DefMacroDirective *DefMD = cast<DefMacroDirective>(MD);
MacroDirective *Prev = PP.getMacroDirective(II);
- if (Prev && !Prev->getInfo()->isIdenticalTo(*MD->getInfo(), PP)) {
- Prev->setAmbiguous(true);
- MD->setAmbiguous(true);
+ if (Prev) {
+ MacroDirective::DefInfo PrevDef = Prev->getDefinition();
+ if (DefMD->getInfo() != PrevDef.getMacroInfo() &&
+ !PrevDef.getMacroInfo()->isIdenticalTo(*DefMD->getInfo(), PP)) {
+ PrevDef.getDirective()->setAmbiguous(true);
+ DefMD->setAmbiguous(true);
+ }
}
- PP.setMacroDirective(II, MD);
+ PP.appendMacroDirective(II, MD);
}
InputFile ASTReader::getInputFile(ModuleFile &F, unsigned ID, bool Complain) {
@@ -2723,21 +2735,12 @@ void ASTReader::makeNamesVisible(const H
}
case HiddenName::MacroVisibility: {
std::pair<IdentifierInfo *, MacroDirective *> Macro = Names[I].getMacro();
- Macro.second->setHidden(!Macro.second->isPublic());
- if (Macro.second->isDefined()) {
- installImportedMacro(Macro.first, Macro.second);
- }
+ installImportedMacro(Macro.first, Macro.second);
break;
}
case HiddenName::MacroUndef: {
- std::pair<IdentifierInfo *, MacroDirective *> Macro = Names[I].getMacro();
- if (Macro.second->isDefined()) {
- Macro.second->setUndefLoc(Names[I].getMacroUndefLoc());
- if (PPMutationListener *Listener = PP.getPPMutationListener())
- Listener->UndefinedMacro(Macro.second);
- PP.makeLoadedMacroInfoVisible(Macro.first, Macro.second);
- }
+ // FIXME: Remove HiddenName::MacroUndef and PPMutationListener.
break;
}
}
Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=178037&r1=178036&r2=178037&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Tue Mar 26 12:17:01 2013
@@ -1833,8 +1833,9 @@ static int compareMacroDirectives(const
static bool shouldIgnoreMacro(MacroDirective *MD, bool IsModule,
const Preprocessor &PP) {
- if (MD->getInfo()->isBuiltinMacro())
- return true;
+ if (MacroInfo *MI = MD->getMacroInfo())
+ if (MI->isBuiltinMacro())
+ return true;
if (IsModule) {
SourceLocation Loc = MD->getLocation();
@@ -1902,25 +1903,30 @@ void ASTWriter::WritePreprocessor(const
// If the macro or identifier need no updates, don't write the macro history
// for this one.
- if (MD->isFromPCH() && !MD->hasChangedAfterLoad() &&
+ // FIXME: Chain the macro history instead of re-writing it.
+ if (MD->isFromPCH() &&
Name->isFromAST() && !Name->hasChangedSinceDeserialization())
continue;
// Emit the macro directives in reverse source order.
for (; MD; MD = MD->getPrevious()) {
- if (shouldIgnoreMacro(MD, IsModule, PP))
+ if (MD->isHidden())
continue;
- MacroID InfoID = getMacroRef(MD->getInfo(), Name);
- if (InfoID == 0)
+ if (shouldIgnoreMacro(MD, IsModule, PP))
continue;
- Record.push_back(InfoID);
AddSourceLocation(MD->getLocation(), Record);
- AddSourceLocation(MD->getUndefLoc(), Record);
- AddSourceLocation(MD->getVisibilityLocation(), Record);
- Record.push_back(MD->isImported());
- Record.push_back(MD->isPublic());
- Record.push_back(MD->isAmbiguous());
+ Record.push_back(MD->getKind());
+ if (DefMacroDirective *DefMD = dyn_cast<DefMacroDirective>(MD)) {
+ MacroID InfoID = getMacroRef(DefMD->getInfo(), Name);
+ Record.push_back(InfoID);
+ Record.push_back(DefMD->isImported());
+ Record.push_back(DefMD->isAmbiguous());
+
+ } else if (VisibilityMacroDirective *
+ VisMD = dyn_cast<VisibilityMacroDirective>(MD)) {
+ Record.push_back(VisMD->isPublic());
+ }
}
if (Record.empty())
continue;
@@ -2898,48 +2904,78 @@ class ASTIdentifierTableTrait {
return false;
}
- MacroDirective *getFirstPublicSubmoduleMacro(MacroDirective *MD,
- SubmoduleID &ModID) {
- if (shouldIgnoreMacro(MD, IsModule, PP))
- return 0;
- ModID = getSubmoduleID(MD);
- if (ModID == 0)
- return 0;
- if (MD->isDefined() && MD->isPublic())
- return MD;
- return getNextPublicSubmoduleMacro(MD, ModID);
+ DefMacroDirective *getFirstPublicSubmoduleMacro(MacroDirective *MD,
+ SubmoduleID &ModID) {
+ ModID = 0;
+ if (DefMacroDirective *DefMD = getPublicSubmoduleMacro(MD, ModID))
+ if (!shouldIgnoreMacro(DefMD, IsModule, PP))
+ return DefMD;
+ return 0;
}
- MacroDirective *getNextPublicSubmoduleMacro(MacroDirective *MD,
- SubmoduleID &ModID) {
- while (MD) {
- MD = getNextSubmoduleMacro(MD, ModID);
- if (MD && MD->isDefined() && MD->isPublic())
- return MD;
- }
+ DefMacroDirective *getNextPublicSubmoduleMacro(DefMacroDirective *MD,
+ SubmoduleID &ModID) {
+ if (DefMacroDirective *
+ DefMD = getPublicSubmoduleMacro(MD->getPrevious(), ModID))
+ if (!shouldIgnoreMacro(DefMD, IsModule, PP))
+ return DefMD;
return 0;
}
- MacroDirective *getNextSubmoduleMacro(MacroDirective *CurrMD,
- SubmoduleID &CurrModID) {
- SubmoduleID OrigID = CurrModID;
- while ((CurrMD = CurrMD->getPrevious())) {
- if (shouldIgnoreMacro(CurrMD, IsModule, PP))
- return 0;
- CurrModID = getSubmoduleID(CurrMD);
- if (CurrModID == 0)
- return 0;
- if (CurrModID != OrigID)
- return CurrMD;
+ /// \brief Traverses the macro directives history and returns the latest
+ /// macro that is public and not undefined in the same submodule.
+ /// A macro that is defined in submodule A and undefined in submodule B,
+ /// will still be considered as defined/exported from submodule A.
+ DefMacroDirective *getPublicSubmoduleMacro(MacroDirective *MD,
+ SubmoduleID &ModID) {
+ if (!MD)
+ return 0;
+
+ bool isUndefined = false;
+ Optional<bool> isPublic;
+ for (; MD; MD = MD->getPrevious()) {
+ if (MD->isHidden())
+ continue;
+
+ SubmoduleID ThisModID = getSubmoduleID(MD);
+ if (ThisModID == 0) {
+ isUndefined = false;
+ isPublic = Optional<bool>();
+ continue;
+ }
+ if (ThisModID != ModID){
+ ModID = ThisModID;
+ isUndefined = false;
+ isPublic = Optional<bool>();
+ }
+
+ if (DefMacroDirective *DefMD = dyn_cast<DefMacroDirective>(MD)) {
+ if (!isUndefined && (!isPublic.hasValue() || isPublic.getValue()))
+ return DefMD;
+ continue;
+ }
+
+ if (isa<UndefMacroDirective>(MD)) {
+ isUndefined = true;
+ continue;
+ }
+
+ VisibilityMacroDirective *VisMD = cast<VisibilityMacroDirective>(MD);
+ if (!isPublic.hasValue())
+ isPublic = VisMD->isPublic();
}
+
return 0;
}
SubmoduleID getSubmoduleID(MacroDirective *MD) {
- MacroInfo *MI = MD->getInfo();
- if (unsigned ID = MI->getOwningModuleID())
- return ID;
- return Writer.inferSubmoduleIDFromLocation(MI->getDefinitionLoc());
+ if (DefMacroDirective *DefMD = dyn_cast<DefMacroDirective>(MD)) {
+ MacroInfo *MI = DefMD->getInfo();
+ if (unsigned ID = MI->getOwningModuleID())
+ return ID;
+ return Writer.inferSubmoduleIDFromLocation(MI->getDefinitionLoc());
+ }
+ return Writer.inferSubmoduleIDFromLocation(MD->getLocation());
}
public:
@@ -2969,8 +3005,9 @@ public:
DataLen += 4; // MacroDirectives offset.
if (IsModule) {
SubmoduleID ModID;
- for (MacroDirective *MD = getFirstPublicSubmoduleMacro(Macro, ModID);
- MD; MD = getNextPublicSubmoduleMacro(MD, ModID)) {
+ for (DefMacroDirective *
+ DefMD = getFirstPublicSubmoduleMacro(Macro, ModID);
+ DefMD; DefMD = getNextPublicSubmoduleMacro(DefMD, ModID)) {
DataLen += 4; // MacroInfo ID.
}
DataLen += 4;
@@ -3025,9 +3062,10 @@ public:
if (IsModule) {
// Write the IDs of macros coming from different submodules.
SubmoduleID ModID;
- for (MacroDirective *MD = getFirstPublicSubmoduleMacro(Macro, ModID);
- MD; MD = getNextPublicSubmoduleMacro(MD, ModID)) {
- MacroID InfoID = Writer.getMacroID(MD->getInfo());
+ for (DefMacroDirective *
+ DefMD = getFirstPublicSubmoduleMacro(Macro, ModID);
+ DefMD; DefMD = getNextPublicSubmoduleMacro(DefMD, ModID)) {
+ MacroID InfoID = Writer.getMacroID(DefMD->getInfo());
assert(InfoID);
clang::io::Emit32(Out, InfoID);
}
Modified: cfe/trunk/tools/libclang/CIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=178037&r1=178036&r2=178037&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndex.cpp (original)
+++ cfe/trunk/tools/libclang/CIndex.cpp Tue Mar 26 12:17:01 2013
@@ -6305,10 +6305,12 @@ MacroInfo *cxindex::getMacroInfo(const I
ASTUnit *Unit = cxtu::getASTUnit(TU);
Preprocessor &PP = Unit->getPreprocessor();
MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
- while (MD) {
- if (MacroDefLoc == MD->getInfo()->getDefinitionLoc())
- return MD->getInfo();
- MD = MD->getPrevious();
+ if (MD) {
+ for (MacroDirective::DefInfo
+ Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
+ if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
+ return Def.getMacroInfo();
+ }
}
return 0;
@@ -6364,7 +6366,7 @@ MacroDefinition *cxindex::checkForMacroI
if (!InnerMD)
return 0;
- return PPRec->findMacroDefinition(InnerMD->getInfo());
+ return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
}
MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
More information about the cfe-commits
mailing list