forked from OSchip/llvm-project
[modules] Refactor macro emission. No functionality change.
llvm-svn: 235263
This commit is contained in:
parent
43d413b698
commit
cf97cf6693
|
@ -2011,12 +2011,6 @@ public:
|
||||||
};
|
};
|
||||||
} // end anonymous namespace
|
} // end anonymous namespace
|
||||||
|
|
||||||
static int compareMacroDirectives(
|
|
||||||
const std::pair<const IdentifierInfo *, MacroDirective *> *X,
|
|
||||||
const std::pair<const IdentifierInfo *, MacroDirective *> *Y) {
|
|
||||||
return X->first->getName().compare(Y->first->getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool shouldIgnoreMacro(MacroDirective *MD, bool IsModule,
|
static bool shouldIgnoreMacro(MacroDirective *MD, bool IsModule,
|
||||||
const Preprocessor &PP) {
|
const Preprocessor &PP) {
|
||||||
if (MacroInfo *MI = MD->getMacroInfo())
|
if (MacroInfo *MI = MD->getMacroInfo())
|
||||||
|
@ -2068,8 +2062,8 @@ void ASTWriter::WritePreprocessor(const Preprocessor &PP, bool IsModule) {
|
||||||
// emitting each to the PP section.
|
// emitting each to the PP section.
|
||||||
|
|
||||||
// Construct the list of macro directives that need to be serialized.
|
// Construct the list of macro directives that need to be serialized.
|
||||||
SmallVector<std::pair<const IdentifierInfo *, MacroDirective *>, 2>
|
typedef std::pair<const IdentifierInfo *, MacroDirective *> MacroChain;
|
||||||
MacroDirectives;
|
SmallVector<MacroChain, 2> MacroDirectives;
|
||||||
for (Preprocessor::macro_iterator
|
for (Preprocessor::macro_iterator
|
||||||
I = PP.macro_begin(/*IncludeExternalMacros=*/false),
|
I = PP.macro_begin(/*IncludeExternalMacros=*/false),
|
||||||
E = PP.macro_end(/*IncludeExternalMacros=*/false);
|
E = PP.macro_end(/*IncludeExternalMacros=*/false);
|
||||||
|
@ -2080,13 +2074,15 @@ void ASTWriter::WritePreprocessor(const Preprocessor &PP, bool IsModule) {
|
||||||
// Sort the set of macro definitions that need to be serialized by the
|
// Sort the set of macro definitions that need to be serialized by the
|
||||||
// name of the macro, to provide a stable ordering.
|
// name of the macro, to provide a stable ordering.
|
||||||
llvm::array_pod_sort(MacroDirectives.begin(), MacroDirectives.end(),
|
llvm::array_pod_sort(MacroDirectives.begin(), MacroDirectives.end(),
|
||||||
&compareMacroDirectives);
|
[](const MacroChain *A, const MacroChain *B) -> int {
|
||||||
|
return A->first->getName().compare(B->first->getName());
|
||||||
|
});
|
||||||
|
|
||||||
// Emit the macro directives as a list and associate the offset with the
|
// Emit the macro directives as a list and associate the offset with the
|
||||||
// identifier they belong to.
|
// identifier they belong to.
|
||||||
for (unsigned I = 0, N = MacroDirectives.size(); I != N; ++I) {
|
for (auto &Chain : MacroDirectives) {
|
||||||
const IdentifierInfo *Name = MacroDirectives[I].first;
|
const IdentifierInfo *Name = Chain.first;
|
||||||
MacroDirective *MD = MacroDirectives[I].second;
|
MacroDirective *MD = Chain.second;
|
||||||
|
|
||||||
// If the macro or identifier need no updates, don't write the macro history
|
// If the macro or identifier need no updates, don't write the macro history
|
||||||
// for this one.
|
// for this one.
|
||||||
|
@ -3133,41 +3129,11 @@ static NamedDecl *getDeclForLocalLookup(const LangOptions &LangOpts,
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
class ASTIdentifierTableTrait {
|
class PublicMacroIterator {
|
||||||
ASTWriter &Writer;
|
ASTWriter &Writer;
|
||||||
Preprocessor &PP;
|
Preprocessor &PP;
|
||||||
IdentifierResolver &IdResolver;
|
|
||||||
bool IsModule;
|
bool IsModule;
|
||||||
|
MacroDirective *Macro;
|
||||||
/// \brief Determines whether this is an "interesting" identifier
|
|
||||||
/// that needs a full IdentifierInfo structure written into the hash
|
|
||||||
/// table.
|
|
||||||
bool isInterestingIdentifier(IdentifierInfo *II, MacroDirective *&Macro) {
|
|
||||||
if (II->isPoisoned() ||
|
|
||||||
II->isExtensionToken() ||
|
|
||||||
II->getObjCOrBuiltinID() ||
|
|
||||||
II->hasRevertedTokenIDToIdentifier() ||
|
|
||||||
II->getFETokenInfo<void>())
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return hadMacroDefinition(II, Macro);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool hadMacroDefinition(IdentifierInfo *II, MacroDirective *&Macro) {
|
|
||||||
if (!II->hadMacroDefinition())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (Macro || (Macro = PP.getMacroDirectiveHistory(II))) {
|
|
||||||
if (!IsModule)
|
|
||||||
return !shouldIgnoreMacro(Macro, IsModule, PP);
|
|
||||||
|
|
||||||
MacroState State;
|
|
||||||
if (getFirstPublicSubmoduleMacro(Macro, State))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum class SubmoduleMacroState {
|
enum class SubmoduleMacroState {
|
||||||
/// We've seen nothing about this macro.
|
/// We've seen nothing about this macro.
|
||||||
|
@ -3178,31 +3144,39 @@ class ASTIdentifierTableTrait {
|
||||||
/// module's definition of this macro is private.
|
/// module's definition of this macro is private.
|
||||||
Done
|
Done
|
||||||
};
|
};
|
||||||
typedef llvm::DenseMap<SubmoduleID, SubmoduleMacroState> MacroState;
|
llvm::DenseMap<SubmoduleID, SubmoduleMacroState> State;
|
||||||
|
|
||||||
MacroDirective *
|
public:
|
||||||
getFirstPublicSubmoduleMacro(MacroDirective *MD, MacroState &State) {
|
PublicMacroIterator(ASTWriter &Writer, Preprocessor &PP, bool IsModule,
|
||||||
if (MacroDirective *NextMD = getPublicSubmoduleMacro(MD, State))
|
IdentifierInfo *II)
|
||||||
return NextMD;
|
: Writer(Writer), PP(PP), IsModule(IsModule), Macro(nullptr) {
|
||||||
return nullptr;
|
if (!II->hadMacroDefinition())
|
||||||
|
return;
|
||||||
|
|
||||||
|
Macro = PP.getMacroDirectiveHistory(II);
|
||||||
|
|
||||||
|
if (IsModule)
|
||||||
|
Macro = skipUnexportedMacros(Macro);
|
||||||
|
else if (shouldIgnoreMacro(Macro, IsModule, PP))
|
||||||
|
Macro = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
MacroDirective *
|
MacroDirective *operator*() const { return Macro; }
|
||||||
getNextPublicSubmoduleMacro(MacroDirective *MD, MacroState &State) {
|
PublicMacroIterator &operator++() {
|
||||||
if (MacroDirective *NextMD =
|
Macro = skipUnexportedMacros(Macro->getPrevious());
|
||||||
getPublicSubmoduleMacro(MD->getPrevious(), State))
|
return *this;
|
||||||
return NextMD;
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
explicit operator bool() const { return Macro; }
|
||||||
|
|
||||||
|
private:
|
||||||
/// \brief Traverses the macro directives history and returns the next
|
/// \brief Traverses the macro directives history and returns the next
|
||||||
/// public macro definition or undefinition that has not been found so far.
|
/// public macro definition or undefinition that has not been found so far.
|
||||||
///
|
///
|
||||||
/// A macro that is defined in submodule A and undefined in submodule B
|
/// A macro that is defined in submodule A and undefined in submodule B
|
||||||
/// will still be considered as defined/exported from submodule A.
|
/// will still be considered as defined/exported from submodule A.
|
||||||
MacroDirective *getPublicSubmoduleMacro(MacroDirective *MD,
|
MacroDirective *skipUnexportedMacros(MacroDirective *MD) {
|
||||||
MacroState &State) {
|
if (!MD || !IsModule)
|
||||||
if (!MD)
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
Optional<bool> IsPublic;
|
Optional<bool> IsPublic;
|
||||||
|
@ -3216,7 +3190,8 @@ class ASTIdentifierTableTrait {
|
||||||
if (MD->isImported())
|
if (MD->isImported())
|
||||||
return MD;
|
return MD;
|
||||||
|
|
||||||
SubmoduleID ModID = getSubmoduleID(MD);
|
SubmoduleID ModID =
|
||||||
|
Writer.inferSubmoduleIDFromLocation(MD->getLocation());
|
||||||
auto &S = State[ModID];
|
auto &S = State[ModID];
|
||||||
assert(ModID && "found macro in no submodule");
|
assert(ModID && "found macro in no submodule");
|
||||||
|
|
||||||
|
@ -3237,6 +3212,31 @@ class ASTIdentifierTableTrait {
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class ASTIdentifierTableTrait {
|
||||||
|
ASTWriter &Writer;
|
||||||
|
Preprocessor &PP;
|
||||||
|
IdentifierResolver &IdResolver;
|
||||||
|
bool IsModule;
|
||||||
|
|
||||||
|
/// \brief Determines whether this is an "interesting" identifier that needs a
|
||||||
|
/// full IdentifierInfo structure written into the hash table. Notably, this
|
||||||
|
/// doesn't check whether the name has macros defined; use PublicMacroIterator
|
||||||
|
/// to check that.
|
||||||
|
bool isInterestingIdentifier(IdentifierInfo *II) {
|
||||||
|
if (PublicMacroIterator(Writer, PP, IsModule, II))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (II->isPoisoned() ||
|
||||||
|
II->isExtensionToken() ||
|
||||||
|
II->getObjCOrBuiltinID() ||
|
||||||
|
II->hasRevertedTokenIDToIdentifier() ||
|
||||||
|
II->getFETokenInfo<void>())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
ArrayRef<SubmoduleID>
|
ArrayRef<SubmoduleID>
|
||||||
getOverriddenSubmodules(MacroDirective *MD,
|
getOverriddenSubmodules(MacroDirective *MD,
|
||||||
|
@ -3322,20 +3322,18 @@ public:
|
||||||
EmitKeyDataLength(raw_ostream& Out, IdentifierInfo* II, IdentID ID) {
|
EmitKeyDataLength(raw_ostream& Out, IdentifierInfo* II, IdentID ID) {
|
||||||
unsigned KeyLen = II->getLength() + 1;
|
unsigned KeyLen = II->getLength() + 1;
|
||||||
unsigned DataLen = 4; // 4 bytes for the persistent ID << 1
|
unsigned DataLen = 4; // 4 bytes for the persistent ID << 1
|
||||||
MacroDirective *Macro = nullptr;
|
PublicMacroIterator Macros(Writer, PP, IsModule, II);
|
||||||
if (isInterestingIdentifier(II, Macro)) {
|
if (Macros || isInterestingIdentifier(II)) {
|
||||||
DataLen += 2; // 2 bytes for builtin ID
|
DataLen += 2; // 2 bytes for builtin ID
|
||||||
DataLen += 2; // 2 bytes for flags
|
DataLen += 2; // 2 bytes for flags
|
||||||
if (hadMacroDefinition(II, Macro)) {
|
if (Macros) {
|
||||||
DataLen += 4; // MacroDirectives offset.
|
DataLen += 4; // MacroDirectives offset.
|
||||||
if (IsModule) {
|
if (IsModule) {
|
||||||
MacroState State;
|
|
||||||
SmallVector<SubmoduleID, 16> Scratch;
|
SmallVector<SubmoduleID, 16> Scratch;
|
||||||
for (MacroDirective *MD = getFirstPublicSubmoduleMacro(Macro, State);
|
for (; Macros; ++Macros) {
|
||||||
MD; MD = getNextPublicSubmoduleMacro(MD, State)) {
|
|
||||||
DataLen += 4; // MacroInfo ID or ModuleID.
|
DataLen += 4; // MacroInfo ID or ModuleID.
|
||||||
if (unsigned NumOverrides =
|
if (unsigned NumOverrides =
|
||||||
getOverriddenSubmodules(MD, Scratch).size())
|
getOverriddenSubmodules(*Macros, Scratch).size())
|
||||||
DataLen += 4 * (1 + NumOverrides);
|
DataLen += 4 * (1 + NumOverrides);
|
||||||
}
|
}
|
||||||
DataLen += 4; // 0 terminator.
|
DataLen += 4; // 0 terminator.
|
||||||
|
@ -3384,8 +3382,9 @@ public:
|
||||||
IdentID ID, unsigned) {
|
IdentID ID, unsigned) {
|
||||||
using namespace llvm::support;
|
using namespace llvm::support;
|
||||||
endian::Writer<little> LE(Out);
|
endian::Writer<little> LE(Out);
|
||||||
MacroDirective *Macro = nullptr;
|
|
||||||
if (!isInterestingIdentifier(II, Macro)) {
|
PublicMacroIterator Macros(Writer, PP, IsModule, II);
|
||||||
|
if (!Macros && !isInterestingIdentifier(II)) {
|
||||||
LE.write<uint32_t>(ID << 1);
|
LE.write<uint32_t>(ID << 1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -3395,7 +3394,7 @@ public:
|
||||||
assert((Bits & 0xffff) == Bits && "ObjCOrBuiltinID too big for ASTReader.");
|
assert((Bits & 0xffff) == Bits && "ObjCOrBuiltinID too big for ASTReader.");
|
||||||
LE.write<uint16_t>(Bits);
|
LE.write<uint16_t>(Bits);
|
||||||
Bits = 0;
|
Bits = 0;
|
||||||
bool HadMacroDefinition = hadMacroDefinition(II, Macro);
|
bool HadMacroDefinition = !!Macros;
|
||||||
Bits = (Bits << 1) | unsigned(HadMacroDefinition);
|
Bits = (Bits << 1) | unsigned(HadMacroDefinition);
|
||||||
Bits = (Bits << 1) | unsigned(IsModule);
|
Bits = (Bits << 1) | unsigned(IsModule);
|
||||||
Bits = (Bits << 1) | unsigned(II->isExtensionToken());
|
Bits = (Bits << 1) | unsigned(II->isExtensionToken());
|
||||||
|
@ -3408,11 +3407,9 @@ public:
|
||||||
LE.write<uint32_t>(Writer.getMacroDirectivesOffset(II));
|
LE.write<uint32_t>(Writer.getMacroDirectivesOffset(II));
|
||||||
if (IsModule) {
|
if (IsModule) {
|
||||||
// Write the IDs of macros coming from different submodules.
|
// Write the IDs of macros coming from different submodules.
|
||||||
MacroState State;
|
|
||||||
SmallVector<SubmoduleID, 16> Scratch;
|
SmallVector<SubmoduleID, 16> Scratch;
|
||||||
for (MacroDirective *MD = getFirstPublicSubmoduleMacro(Macro, State);
|
for (; Macros; ++Macros) {
|
||||||
MD; MD = getNextPublicSubmoduleMacro(MD, State)) {
|
if (DefMacroDirective *DefMD = dyn_cast<DefMacroDirective>(*Macros)) {
|
||||||
if (DefMacroDirective *DefMD = dyn_cast<DefMacroDirective>(MD)) {
|
|
||||||
// FIXME: If this macro directive was created by #pragma pop_macros,
|
// FIXME: If this macro directive was created by #pragma pop_macros,
|
||||||
// or if it was created implicitly by resolving conflicting macros,
|
// or if it was created implicitly by resolving conflicting macros,
|
||||||
// it may be for a different submodule from the one in the MacroInfo
|
// it may be for a different submodule from the one in the MacroInfo
|
||||||
|
@ -3421,13 +3418,13 @@ public:
|
||||||
assert(InfoID);
|
assert(InfoID);
|
||||||
LE.write<uint32_t>(InfoID << 1);
|
LE.write<uint32_t>(InfoID << 1);
|
||||||
} else {
|
} else {
|
||||||
auto *UndefMD = cast<UndefMacroDirective>(MD);
|
auto *UndefMD = cast<UndefMacroDirective>(*Macros);
|
||||||
SubmoduleID Mod = UndefMD->isImported()
|
SubmoduleID Mod = UndefMD->isImported()
|
||||||
? UndefMD->getOwningModuleID()
|
? UndefMD->getOwningModuleID()
|
||||||
: getSubmoduleID(UndefMD);
|
: getSubmoduleID(UndefMD);
|
||||||
LE.write<uint32_t>((Mod << 1) | 1);
|
LE.write<uint32_t>((Mod << 1) | 1);
|
||||||
}
|
}
|
||||||
emitMacroOverrides(Out, getOverriddenSubmodules(MD, Scratch));
|
emitMacroOverrides(Out, getOverriddenSubmodules(*Macros, Scratch));
|
||||||
}
|
}
|
||||||
LE.write<uint32_t>((uint32_t)-1);
|
LE.write<uint32_t>((uint32_t)-1);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue