aboutsummaryrefslogtreecommitdiff
path: root/lib/Serialization
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2013-03-26 17:17:01 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2013-03-26 17:17:01 +0000
commitc56fff7fd231aebf4b152f60f8f11ef91835c48a (patch)
tree22119f54c12ae692e50e7ed4930160f950e37f2f /lib/Serialization
parent1232e279b4a0d98885b9672d3bb5905488360e49 (diff)
[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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@178037 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Serialization')
-rw-r--r--lib/Serialization/ASTReader.cpp69
-rw-r--r--lib/Serialization/ASTWriter.cpp136
2 files changed, 123 insertions, 82 deletions
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index c6dbfe1498..837524dec8 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -1476,8 +1476,8 @@ void ASTReader::resolvePendingMacro(IdentifierInfo *II,
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(IdentifierInfo *II,
}
}
}
- MD->setHidden(Hidden);
if (!Hidden)
installImportedMacro(II, MD);
@@ -1527,22 +1526,30 @@ void ASTReader::installPCHMacroDirectives(IdentifierInfo *II,
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::installPCHMacroDirectives(IdentifierInfo *II,
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 HiddenNames &Names) {
}
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;
}
}
diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp
index 725896309e..95e32a37fe 100644
--- a/lib/Serialization/ASTWriter.cpp
+++ b/lib/Serialization/ASTWriter.cpp
@@ -1833,8 +1833,9 @@ static int compareMacroDirectives(const void *XPtr, const void *YPtr) {
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 Preprocessor &PP, bool IsModule) {
// 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);
}