diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2013-03-26 17:17:01 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2013-03-26 17:17:01 +0000 |
commit | c56fff7fd231aebf4b152f60f8f11ef91835c48a (patch) | |
tree | 22119f54c12ae692e50e7ed4930160f950e37f2f /lib/Serialization | |
parent | 1232e279b4a0d98885b9672d3bb5905488360e49 (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.cpp | 69 | ||||
-rw-r--r-- | lib/Serialization/ASTWriter.cpp | 136 |
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); } |