mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
WIP Update to use clang::ModuleMacro instead of clang::MacroInfo.
Untested and still missing a few pieces.
This commit is contained in:
@@ -18,6 +18,7 @@
|
||||
namespace clang {
|
||||
class Decl;
|
||||
class MacroInfo;
|
||||
class ModuleMacro;
|
||||
class Module;
|
||||
class SourceLocation;
|
||||
class SourceRange;
|
||||
@@ -40,18 +41,21 @@ namespace detail {
|
||||
};
|
||||
}
|
||||
|
||||
/// Represents a clang declaration, macro, or module.
|
||||
/// Represents a clang declaration, macro, or module. A macro definition
|
||||
/// imported from a module is recorded as the ModuleMacro, and a macro
|
||||
/// defined locally is represented by the MacroInfo.
|
||||
class ClangNode {
|
||||
template <typename T>
|
||||
using Box = detail::ClangNodeBox<T>;
|
||||
|
||||
llvm::PointerUnion3<Box<clang::Decl>, Box<clang::MacroInfo>,
|
||||
Box<clang::Module>> Ptr;
|
||||
llvm::PointerUnion4<Box<clang::Decl>, Box<clang::MacroInfo>,
|
||||
Box<clang::ModuleMacro>, Box<clang::Module>> Ptr;
|
||||
|
||||
public:
|
||||
ClangNode() = default;
|
||||
ClangNode(const clang::Decl *D) : Ptr(D) {}
|
||||
ClangNode(const clang::MacroInfo *MI) : Ptr(MI) {}
|
||||
ClangNode(const clang::ModuleMacro *MM) : Ptr(MM) {}
|
||||
ClangNode(const clang::Module *Mod) : Ptr(Mod) {}
|
||||
|
||||
bool isNull() const { return Ptr.isNull(); }
|
||||
@@ -60,9 +64,12 @@ public:
|
||||
const clang::Decl *getAsDecl() const {
|
||||
return Ptr.dyn_cast<Box<clang::Decl>>().value;
|
||||
}
|
||||
const clang::MacroInfo *getAsMacro() const {
|
||||
const clang::MacroInfo *getAsMacroInfo() const {
|
||||
return Ptr.dyn_cast<Box<clang::MacroInfo>>().value;
|
||||
}
|
||||
const clang::ModuleMacro *getAsModuleMacro() const {
|
||||
return Ptr.dyn_cast<Box<clang::ModuleMacro>>().value;
|
||||
}
|
||||
const clang::Module *getAsModule() const {
|
||||
return Ptr.dyn_cast<Box<clang::Module>>().value;
|
||||
}
|
||||
@@ -70,13 +77,20 @@ public:
|
||||
const clang::Decl *castAsDecl() const {
|
||||
return Ptr.get<Box<clang::Decl>>().value;
|
||||
}
|
||||
const clang::MacroInfo *castAsMacro() const {
|
||||
const clang::MacroInfo *castAsMacroInfo() const {
|
||||
return Ptr.get<Box<clang::MacroInfo>>().value;
|
||||
}
|
||||
const clang::ModuleMacro *castAsModuleMacro() const {
|
||||
return Ptr.get<Box<clang::ModuleMacro>>().value;
|
||||
}
|
||||
const clang::Module *castAsModule() const {
|
||||
return Ptr.get<Box<clang::Module>>().value;
|
||||
}
|
||||
|
||||
// Get the MacroInfo for a local definition, one imported from a
|
||||
// ModuleMacro, or null if it's neither.
|
||||
const clang::MacroInfo *getAsMacro() const;
|
||||
|
||||
/// Returns the module either the one wrapped directly, the one from a
|
||||
/// clang::ImportDecl or null if it's neither.
|
||||
const clang::Module *getClangModule() const;
|
||||
|
||||
@@ -61,6 +61,12 @@ STATISTIC(NumLazyGenericEnvironments,
|
||||
STATISTIC(NumLazyGenericEnvironmentsLoaded,
|
||||
"# of lazily-deserialized generic environments loaded");
|
||||
|
||||
const clang::MacroInfo *ClangNode::getAsMacro() const {
|
||||
if (auto MM = getAsModuleMacro())
|
||||
return MM->getMacroInfo();
|
||||
return getAsMacroInfo();
|
||||
}
|
||||
|
||||
clang::SourceLocation ClangNode::getLocation() const {
|
||||
if (auto D = getAsDecl())
|
||||
return D->getLocation();
|
||||
|
||||
@@ -1878,15 +1878,21 @@ static bool isDeclaredInModule(const ClangModuleUnit *ModuleFilter,
|
||||
return ModuleFilter == ContainingUnit;
|
||||
}
|
||||
|
||||
static const clang::Module *getClangOwningModule(ClangNode Node,
|
||||
const clang::ASTContext &ClangCtx) {
|
||||
static const clang::Module *
|
||||
getClangOwningModule(ClangNode Node, const clang::ASTContext &ClangCtx) {
|
||||
assert(!Node.getAsModule() && "not implemented for modules");
|
||||
|
||||
if (const clang::Decl *D = Node.getAsDecl()) {
|
||||
auto ExtSource = ClangCtx.getExternalSource();
|
||||
assert(ExtSource);
|
||||
if (const clang::Decl *D = Node.getAsDecl())
|
||||
return ExtSource->getModule(D->getOwningModuleID());
|
||||
if (const clang::MacroInfo *MI = Node.getAsMacro())
|
||||
return ExtSource->getModule(MI->getOwningModuleID());
|
||||
}
|
||||
|
||||
if (const clang::ModuleMacro *M = Node.getAsModuleMacro())
|
||||
return M->getOwningModule();
|
||||
|
||||
// A locally-defined MacroInfo does not have an owning module.
|
||||
assert(Node.getAsMacroInfo());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -2075,6 +2081,17 @@ public:
|
||||
|
||||
} // unnamed namespace
|
||||
|
||||
/// Translate a MacroDefinition to a ClangNode, either a ModuleMacro for
|
||||
/// a definition imported from a module or a MacroInfo for a macro defined
|
||||
/// locally.
|
||||
ClangNode getClangNodeForMacroDefinition(clang::MacroDefinition &M) {
|
||||
if (!M.getModuleMacros().empty())
|
||||
return ClangNode(M.getModuleMacros().back()->getMacroInfo());
|
||||
if (auto *MD = M.getLocalDirective())
|
||||
return ClangNode(MD->getMacroInfo());
|
||||
return ClangNode();
|
||||
}
|
||||
|
||||
void ClangImporter::lookupBridgingHeaderDecls(
|
||||
llvm::function_ref<bool(ClangNode)> filter,
|
||||
llvm::function_ref<void(Decl*)> receiver) const {
|
||||
@@ -2094,10 +2111,12 @@ void ClangImporter::lookupBridgingHeaderDecls(
|
||||
|
||||
auto &ClangPP = Impl.getClangPreprocessor();
|
||||
for (clang::IdentifierInfo *II : Impl.BridgeHeaderMacros) {
|
||||
if (auto *MI = ClangPP.getMacroInfo(II)) {
|
||||
if (filter(MI)) {
|
||||
auto MD = ClangPP.getMacroDefinition(II);
|
||||
if (auto macroNode = getClangNodeForMacroDefinition(MD)) {
|
||||
if (filter(macroNode)) {
|
||||
auto MI = macroNode.getAsMacro();
|
||||
Identifier Name = Impl.getNameImporter().importMacroName(II, MI);
|
||||
if (Decl *imported = Impl.importMacro(Name, MI))
|
||||
if (Decl *imported = Impl.importMacro(Name, macroNode))
|
||||
receiver(imported);
|
||||
}
|
||||
}
|
||||
@@ -2169,12 +2188,14 @@ bool ClangImporter::lookupDeclsFromHeader(StringRef Filename,
|
||||
clang::PreprocessedEntity *PPE = *I;
|
||||
if (!PPE)
|
||||
continue;
|
||||
if (auto *MD = dyn_cast<clang::MacroDefinitionRecord>(PPE)) {
|
||||
auto *II = const_cast<clang::IdentifierInfo*>(MD->getName());
|
||||
if (auto *MI = ClangPP.getMacroInfo(II)) {
|
||||
if (filter(MI)) {
|
||||
if (auto *MDR = dyn_cast<clang::MacroDefinitionRecord>(PPE)) {
|
||||
auto *II = const_cast<clang::IdentifierInfo*>(MDR->getName());
|
||||
auto MD = ClangPP.getMacroDefinition(II);
|
||||
if (auto macroNode = getClangNodeForMacroDefinition(MD)) {
|
||||
if (filter(macroNode)) {
|
||||
auto MI = macroNode.getAsMacro();
|
||||
Identifier Name = Impl.getNameImporter().importMacroName(II, MI);
|
||||
if (Decl *imported = Impl.importMacro(Name, MI))
|
||||
if (Decl *imported = Impl.importMacro(Name, macroNode))
|
||||
receiver(imported);
|
||||
}
|
||||
}
|
||||
@@ -2378,11 +2399,9 @@ static bool isVisibleClangEntry(clang::ASTContext &ctx,
|
||||
}
|
||||
|
||||
// Check whether the macro is defined.
|
||||
auto clangMacro = entry.get<clang::MacroInfo *>();
|
||||
if (auto moduleID = clangMacro->getOwningModuleID()) {
|
||||
if (auto module = ctx.getExternalSource()->getModule(moduleID))
|
||||
return module->NameVisibility == clang::Module::AllVisible;
|
||||
}
|
||||
// auto clangMacro = entry.get<clang::MacroInfo *>();
|
||||
// if (module)
|
||||
// return module->NameVisibility == clang::Module::AllVisible;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -2616,6 +2635,11 @@ const clang::CompilerInstance &ClangImporter::getClangInstance() const {
|
||||
}
|
||||
|
||||
const clang::Module *ClangImporter::getClangOwningModule(ClangNode Node) const {
|
||||
return Impl.getClangOwningModule(Node);
|
||||
}
|
||||
|
||||
const clang::Module *
|
||||
ClangImporter::Implementation::getClangOwningModule(ClangNode Node) const {
|
||||
return ::getClangOwningModule(Node, getClangASTContext());
|
||||
}
|
||||
|
||||
@@ -2943,8 +2967,12 @@ void ClangImporter::Implementation::lookupValue(
|
||||
if (!decl) continue;
|
||||
} else if (!name.isSpecial()) {
|
||||
// Try to import a macro.
|
||||
auto clangMacro = entry.get<clang::MacroInfo *>();
|
||||
if (auto modMacro = entry.dyn_cast<clang::ModuleMacro *>())
|
||||
decl = importMacro(name.getBaseIdentifier(), modMacro);
|
||||
else if (auto clangMacro = entry.dyn_cast<clang::MacroInfo *>())
|
||||
decl = importMacro(name.getBaseIdentifier(), clangMacro);
|
||||
else
|
||||
llvm_unreachable("new kind of lookup table entry");
|
||||
if (!decl) continue;
|
||||
} else {
|
||||
continue;
|
||||
|
||||
@@ -32,28 +32,6 @@
|
||||
using namespace swift;
|
||||
using namespace importer;
|
||||
|
||||
Optional<clang::Module *>
|
||||
ClangImporter::Implementation::getClangSubmoduleForMacro(
|
||||
const clang::MacroInfo *MI) {
|
||||
auto *ExternalSource = getClangASTContext().getExternalSource();
|
||||
return ExternalSource->getModule(MI->getOwningModuleID());
|
||||
}
|
||||
|
||||
ClangModuleUnit *ClangImporter::Implementation::getClangModuleForMacro(
|
||||
const clang::MacroInfo *MI) {
|
||||
auto maybeModule = getClangSubmoduleForMacro(MI);
|
||||
if (!maybeModule)
|
||||
return nullptr;
|
||||
if (!maybeModule.getValue())
|
||||
return ImportedHeaderUnit;
|
||||
|
||||
// Get the parent module because currently we don't represent submodules with
|
||||
// ClangModule.
|
||||
auto *M = maybeModule.getValue()->getTopLevelModule();
|
||||
|
||||
return getWrapperForModule(M);
|
||||
}
|
||||
|
||||
template <typename T = clang::Expr>
|
||||
static const T *
|
||||
parseNumericLiteral(ClangImporter::Implementation &impl,
|
||||
@@ -90,7 +68,7 @@ static ValueDecl *importNumericLiteral(ClangImporter::Implementation &Impl,
|
||||
Identifier name,
|
||||
const clang::Token *signTok,
|
||||
const clang::Token &tok,
|
||||
const clang::MacroInfo *ClangN,
|
||||
ClangNode ClangN,
|
||||
clang::QualType castType) {
|
||||
assert(tok.getKind() == clang::tok::numeric_constant &&
|
||||
"not a numeric token");
|
||||
@@ -189,7 +167,7 @@ static ValueDecl *importStringLiteral(ClangImporter::Implementation &Impl,
|
||||
Identifier name,
|
||||
const clang::Token &tok,
|
||||
MappedStringLiteralKind kind,
|
||||
const clang::MacroInfo *ClangN) {
|
||||
ClangNode ClangN) {
|
||||
assert(isStringToken(tok));
|
||||
|
||||
clang::ActionResult<clang::Expr*> result =
|
||||
@@ -215,7 +193,7 @@ static ValueDecl *importLiteral(ClangImporter::Implementation &Impl,
|
||||
const clang::MacroInfo *MI,
|
||||
Identifier name,
|
||||
const clang::Token &tok,
|
||||
const clang::MacroInfo *ClangN,
|
||||
ClangNode ClangN,
|
||||
clang::QualType castType) {
|
||||
switch (tok.getKind()) {
|
||||
case clang::tok::numeric_constant:
|
||||
@@ -235,7 +213,7 @@ static ValueDecl *importLiteral(ClangImporter::Implementation &Impl,
|
||||
|
||||
static ValueDecl *importNil(ClangImporter::Implementation &Impl,
|
||||
DeclContext *DC, Identifier name,
|
||||
const clang::MacroInfo *clangN) {
|
||||
ClangNode clangN) {
|
||||
// We use a dummy type since we don't have a convenient type for 'nil'. Any
|
||||
// use of this will be an error anyway.
|
||||
auto type = TupleType::getEmpty(Impl.SwiftContext);
|
||||
@@ -310,6 +288,8 @@ static Optional<std::pair<llvm::APSInt, Type>>
|
||||
|
||||
auto rawID = token.getIdentifierInfo();
|
||||
auto macroInfo = impl.getClangPreprocessor().getMacroInfo(rawID);
|
||||
if (!macroInfo)
|
||||
return None;
|
||||
auto importedID = impl.getNameImporter().importMacroName(rawID, macroInfo);
|
||||
impl.importMacro(importedID, macroInfo);
|
||||
|
||||
@@ -332,7 +312,7 @@ static ValueDecl *importMacro(ClangImporter::Implementation &impl,
|
||||
DeclContext *DC,
|
||||
Identifier name,
|
||||
const clang::MacroInfo *macro,
|
||||
const clang::MacroInfo *ClangN,
|
||||
ClangNode ClangN,
|
||||
clang::QualType castType) {
|
||||
if (name.empty()) return nullptr;
|
||||
|
||||
@@ -636,7 +616,8 @@ static ValueDecl *importMacro(ClangImporter::Implementation &impl,
|
||||
}
|
||||
|
||||
ValueDecl *ClangImporter::Implementation::importMacro(Identifier name,
|
||||
clang::MacroInfo *macro) {
|
||||
ClangNode macroNode) {
|
||||
const clang::MacroInfo *macro = macroNode.getAsMacro();
|
||||
if (!macro)
|
||||
return nullptr;
|
||||
|
||||
@@ -665,11 +646,17 @@ ValueDecl *ClangImporter::Implementation::importMacro(Identifier name,
|
||||
// We haven't tried to import this macro yet. Do so now, and cache the
|
||||
// result.
|
||||
|
||||
DeclContext *DC = getClangModuleForMacro(macro);
|
||||
if (!DC)
|
||||
return nullptr;
|
||||
DeclContext *DC;
|
||||
if (const clang::Module *module = getClangOwningModule(macroNode)) {
|
||||
// Get the parent module because currently we don't model Clang submodules
|
||||
// in Swift.
|
||||
DC = getWrapperForModule(module->getTopLevelModule());
|
||||
} else {
|
||||
DC = ImportedHeaderUnit;
|
||||
}
|
||||
|
||||
auto valueDecl = ::importMacro(*this, DC, name, macro, macro, /*castType*/{});
|
||||
auto valueDecl = ::importMacro(*this, DC, name, macro, macroNode,
|
||||
/*castType*/{});
|
||||
ImportedMacros[name].push_back({macro, valueDecl});
|
||||
return valueDecl;
|
||||
}
|
||||
|
||||
@@ -375,7 +375,8 @@ public:
|
||||
/// Multiple macro definitions can map to the same declaration if the
|
||||
/// macros are identically defined.
|
||||
llvm::DenseMap<Identifier,
|
||||
SmallVector<std::pair<clang::MacroInfo *, ValueDecl *>, 2>>
|
||||
SmallVector<std::pair<const clang::MacroInfo *, ValueDecl *>,
|
||||
2>>
|
||||
ImportedMacros;
|
||||
|
||||
// Mapping from macro to value for macros that expand to constant values.
|
||||
@@ -606,10 +607,7 @@ public:
|
||||
///
|
||||
/// The returned module may be null (but not \c None) if \p MI comes from
|
||||
/// an imported header.
|
||||
Optional<clang::Module *>
|
||||
getClangSubmoduleForMacro(const clang::MacroInfo *MI);
|
||||
|
||||
ClangModuleUnit *getClangModuleForMacro(const clang::MacroInfo *MI);
|
||||
const clang::Module *getClangOwningModule(ClangNode Node) const;
|
||||
|
||||
/// Whether NSUInteger can be imported as Int in certain contexts. If false,
|
||||
/// should always be imported as UInt.
|
||||
@@ -667,9 +665,11 @@ public:
|
||||
|
||||
/// \brief Import the given Clang preprocessor macro as a Swift value decl.
|
||||
///
|
||||
/// \p macroNode must be a MacroInfo or a ModuleMacro.
|
||||
///
|
||||
/// \returns The imported declaration, or null if the macro could not be
|
||||
/// translated into Swift.
|
||||
ValueDecl *importMacro(Identifier name, clang::MacroInfo *macro);
|
||||
ValueDecl *importMacro(Identifier name, ClangNode macroNode);
|
||||
|
||||
/// Map a Clang identifier name to its imported Swift equivalent.
|
||||
StringRef getSwiftNameFromClangName(StringRef name);
|
||||
|
||||
@@ -79,44 +79,44 @@ considerReplacingExistingMacro(const clang::MacroInfo *newMacro,
|
||||
assert(PP);
|
||||
assert(newMacro);
|
||||
assert(existingMacro);
|
||||
assert(newMacro->getOwningModuleID() == 0);
|
||||
assert(existingMacro->getOwningModuleID() == 0);
|
||||
// assert(newMacro->getOwningModuleID() == 0);
|
||||
// assert(existingMacro->getOwningModuleID() == 0);
|
||||
|
||||
if (PP->getLangOpts().CurrentModule.empty())
|
||||
// if (PP->getLangOpts().CurrentModule.empty())
|
||||
return MacroConflictAction::Discard;
|
||||
|
||||
clang::ModuleMap &moduleInfo = PP->getHeaderSearchInfo().getModuleMap();
|
||||
const clang::SourceManager &sourceMgr = PP->getSourceManager();
|
||||
|
||||
auto findContainingExplicitModule =
|
||||
[&moduleInfo, &sourceMgr](const clang::MacroInfo *macro)
|
||||
-> const clang::Module * {
|
||||
|
||||
clang::SourceLocation definitionLoc = macro->getDefinitionLoc();
|
||||
assert(definitionLoc.isValid() &&
|
||||
"implicitly-defined macros shouldn't show up in a module's lookup");
|
||||
clang::FullSourceLoc fullLoc(definitionLoc, sourceMgr);
|
||||
|
||||
const clang::Module *module = moduleInfo.inferModuleFromLocation(fullLoc);
|
||||
assert(module && "we are building a module; everything should be modular");
|
||||
|
||||
while (module->isSubModule()) {
|
||||
if (module->IsExplicit)
|
||||
break;
|
||||
module = module->Parent;
|
||||
}
|
||||
return module;
|
||||
};
|
||||
|
||||
const clang::Module *newModule = findContainingExplicitModule(newMacro);
|
||||
const clang::Module *existingModule =
|
||||
findContainingExplicitModule(existingMacro);
|
||||
|
||||
if (existingModule == newModule)
|
||||
return MacroConflictAction::Discard;
|
||||
if (existingModule->isSubModuleOf(newModule))
|
||||
return MacroConflictAction::Replace;
|
||||
return MacroConflictAction::AddAsAlternative;
|
||||
// clang::ModuleMap &moduleInfo = PP->getHeaderSearchInfo().getModuleMap();
|
||||
// const clang::SourceManager &sourceMgr = PP->getSourceManager();
|
||||
//
|
||||
// auto findContainingExplicitModule =
|
||||
// [&moduleInfo, &sourceMgr](const clang::MacroInfo *macro)
|
||||
// -> const clang::Module * {
|
||||
//
|
||||
// clang::SourceLocation definitionLoc = macro->getDefinitionLoc();
|
||||
// assert(definitionLoc.isValid() &&
|
||||
// "implicitly-defined macros shouldn't show up in a module's lookup");
|
||||
// clang::FullSourceLoc fullLoc(definitionLoc, sourceMgr);
|
||||
//
|
||||
// const clang::Module *module = moduleInfo.inferModuleFromLocation(fullLoc);
|
||||
// assert(module && "we are building a module; everything should be modular");
|
||||
//
|
||||
// while (module->isSubModule()) {
|
||||
// if (module->IsExplicit)
|
||||
// break;
|
||||
// module = module->Parent;
|
||||
// }
|
||||
// return module;
|
||||
// };
|
||||
//
|
||||
// const clang::Module *newModule = findContainingExplicitModule(newMacro);
|
||||
// const clang::Module *existingModule =
|
||||
// findContainingExplicitModule(existingMacro);
|
||||
//
|
||||
// if (existingModule == newModule)
|
||||
// return MacroConflictAction::Discard;
|
||||
// if (existingModule->isSubModuleOf(newModule))
|
||||
// return MacroConflictAction::Replace;
|
||||
// return MacroConflictAction::AddAsAlternative;
|
||||
}
|
||||
|
||||
namespace swift {
|
||||
@@ -201,7 +201,7 @@ public:
|
||||
///
|
||||
/// \returns true if we found anything, false otherwise.
|
||||
bool lookupGlobalsAsMembers(SwiftLookupTable::StoredContext context,
|
||||
SmallVectorImpl<uintptr_t> &entries);
|
||||
SmallVectorImpl<uint64_t> &entries);
|
||||
};
|
||||
} // namespace swift
|
||||
|
||||
@@ -432,11 +432,12 @@ static bool isGlobalAsMember(SwiftLookupTable::SingleEntry entry,
|
||||
}
|
||||
|
||||
bool SwiftLookupTable::addLocalEntry(SingleEntry newEntry,
|
||||
SmallVectorImpl<uintptr_t> &entries,
|
||||
SmallVectorImpl<uint64_t> &entries,
|
||||
const clang::Preprocessor *PP) {
|
||||
// Check whether this entry matches any existing entry.
|
||||
auto decl = newEntry.dyn_cast<clang::NamedDecl *>();
|
||||
auto macro = newEntry.dyn_cast<clang::MacroInfo *>();
|
||||
auto moduleMacro = newEntry.dyn_cast<clang::ModuleMacro *>();
|
||||
for (auto &existingEntry : entries) {
|
||||
// If it matches an existing declaration, there's nothing to do.
|
||||
if (decl && isDeclEntry(existingEntry) &&
|
||||
@@ -445,27 +446,30 @@ bool SwiftLookupTable::addLocalEntry(SingleEntry newEntry,
|
||||
|
||||
// If it matches an existing macro, decide on the best course of action.
|
||||
if (macro && isMacroEntry(existingEntry)) {
|
||||
MacroConflictAction action =
|
||||
considerReplacingExistingMacro(macro,
|
||||
mapStoredMacro(existingEntry),
|
||||
PP);
|
||||
switch (action) {
|
||||
case MacroConflictAction::Discard:
|
||||
return false;
|
||||
case MacroConflictAction::Replace:
|
||||
existingEntry = encodeEntry(macro);
|
||||
return false;
|
||||
case MacroConflictAction::AddAsAlternative:
|
||||
break;
|
||||
}
|
||||
// MacroConflictAction action =
|
||||
// considerReplacingExistingMacro(macro,
|
||||
// mapStoredMacro(existingEntry),
|
||||
// PP);
|
||||
// switch (action) {
|
||||
// case MacroConflictAction::Discard:
|
||||
// return false;
|
||||
// case MacroConflictAction::Replace:
|
||||
// existingEntry = encodeEntry(macro);
|
||||
// return false;
|
||||
// case MacroConflictAction::AddAsAlternative:
|
||||
// break;
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
// Add an entry to this context.
|
||||
if (decl)
|
||||
entries.push_back(encodeEntry(decl));
|
||||
else
|
||||
else if (macro)
|
||||
entries.push_back(encodeEntry(macro));
|
||||
else
|
||||
entries.push_back(encodeEntry(moduleMacro));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -502,6 +506,7 @@ void SwiftLookupTable::addEntry(DeclName name, SingleEntry newEntry,
|
||||
auto &entries = LookupTable[name.getBaseIdentifier().str()];
|
||||
auto decl = newEntry.dyn_cast<clang::NamedDecl *>();
|
||||
auto macro = newEntry.dyn_cast<clang::MacroInfo *>();
|
||||
auto moduleMacro = newEntry.dyn_cast<clang::ModuleMacro *>();
|
||||
for (auto &entry : entries) {
|
||||
if (entry.Context == context) {
|
||||
// We have entries for this context.
|
||||
@@ -515,8 +520,10 @@ void SwiftLookupTable::addEntry(DeclName name, SingleEntry newEntry,
|
||||
entry.Context = context;
|
||||
if (decl)
|
||||
entry.DeclsOrMacros.push_back(encodeEntry(decl));
|
||||
else
|
||||
else if (macro)
|
||||
entry.DeclsOrMacros.push_back(encodeEntry(macro));
|
||||
else
|
||||
entry.DeclsOrMacros.push_back(encodeEntry(moduleMacro));
|
||||
entries.push_back(entry);
|
||||
}
|
||||
|
||||
@@ -562,7 +569,8 @@ SwiftLookupTable::lookup(StringRef baseName,
|
||||
|
||||
// Map each of the declarations.
|
||||
for (auto &stored : entry.DeclsOrMacros)
|
||||
result.push_back(mapStored(stored));
|
||||
if (auto entry = mapStored(stored))
|
||||
result.push_back(entry);
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -581,7 +589,7 @@ SwiftLookupTable::lookupGlobalsAsMembers(StoredContext context) {
|
||||
if (!Reader) return result;
|
||||
|
||||
// Lookup this base name in the module extension file.
|
||||
SmallVector<uintptr_t, 2> results;
|
||||
SmallVector<uint64_t, 2> results;
|
||||
(void)Reader->lookupGlobalsAsMembers(context, results);
|
||||
|
||||
// Add an entry to the table so we don't look again.
|
||||
@@ -789,12 +797,41 @@ static void printStoredContext(SwiftLookupTable::StoredContext context,
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t getEncodedDeclID(uint64_t entry) {
|
||||
assert(SwiftLookupTable::isSerializationIDEntry(entry));
|
||||
assert(SwiftLookupTable::isDeclEntry(entry));
|
||||
return entry >> 2;
|
||||
}
|
||||
|
||||
namespace {
|
||||
struct LocalMacroIDs {
|
||||
uint32_t moduleID;
|
||||
uint32_t nameOrMacroID;
|
||||
};
|
||||
}
|
||||
|
||||
static LocalMacroIDs getEncodedModuleMacroIDs(uint64_t entry) {
|
||||
assert(SwiftLookupTable::isSerializationIDEntry(entry));
|
||||
assert(SwiftLookupTable::isMacroEntry(entry));
|
||||
return {static_cast<uint32_t>((entry & 0xFFFFFFFF) >> 2),
|
||||
static_cast<uint32_t>(entry >> 32)};
|
||||
}
|
||||
|
||||
/// Print a stored entry (Clang macro or declaration) for debugging purposes.
|
||||
static void printStoredEntry(const SwiftLookupTable *table, uintptr_t entry,
|
||||
static void printStoredEntry(const SwiftLookupTable *table, uint64_t entry,
|
||||
llvm::raw_ostream &out) {
|
||||
if (SwiftLookupTable::isSerializationIDEntry(entry)) {
|
||||
llvm::errs() << (SwiftLookupTable::isMacroEntry(entry) ? "macro" : "decl")
|
||||
<< " ID #" << SwiftLookupTable::getSerializationID(entry);
|
||||
if (SwiftLookupTable::isDeclEntry(entry)) {
|
||||
llvm::errs() << "decl ID #" << getEncodedDeclID(entry);
|
||||
} else {
|
||||
LocalMacroIDs macroIDs = getEncodedModuleMacroIDs(entry);
|
||||
if (macroIDs.moduleID == 0) {
|
||||
llvm::errs() << "macro ID #" << macroIDs.nameOrMacroID;
|
||||
} else {
|
||||
llvm::errs() << "macro with name ID #" << macroIDs.nameOrMacroID
|
||||
<< "in submodule #" << macroIDs.moduleID;
|
||||
}
|
||||
}
|
||||
} else if (SwiftLookupTable::isMacroEntry(entry)) {
|
||||
llvm::errs() << "Macro";
|
||||
} else {
|
||||
@@ -820,7 +857,7 @@ void SwiftLookupTable::dump() const {
|
||||
llvm::errs() << ": ";
|
||||
|
||||
interleave(entry.DeclsOrMacros.begin(), entry.DeclsOrMacros.end(),
|
||||
[this](uintptr_t entry) {
|
||||
[this](uint64_t entry) {
|
||||
printStoredEntry(this, entry, llvm::errs());
|
||||
},
|
||||
[] {
|
||||
@@ -867,7 +904,7 @@ void SwiftLookupTable::dump() const {
|
||||
|
||||
const auto &entries = GlobalsAsMembers.find(context)->second;
|
||||
interleave(entries.begin(), entries.end(),
|
||||
[this](uintptr_t entry) {
|
||||
[this](uint64_t entry) {
|
||||
printStoredEntry(this, entry, llvm::errs());
|
||||
},
|
||||
[] {
|
||||
@@ -957,8 +994,7 @@ namespace {
|
||||
dataLength += sizeof(uint16_t);
|
||||
|
||||
// Actual entries.
|
||||
dataLength += (sizeof(clang::serialization::DeclID) *
|
||||
entry.DeclsOrMacros.size());
|
||||
dataLength += (sizeof(uint64_t) * entry.DeclsOrMacros.size());
|
||||
}
|
||||
|
||||
endian::Writer<little> writer(out);
|
||||
@@ -978,6 +1014,7 @@ namespace {
|
||||
// # of entries
|
||||
writer.write<uint16_t>(data.size());
|
||||
|
||||
bool isModule = Writer.getLangOpts().isCompilingModule();
|
||||
for (auto &fullEntry : data) {
|
||||
// Context.
|
||||
writer.write<uint8_t>(static_cast<uint8_t>(fullEntry.Context.first));
|
||||
@@ -991,15 +1028,22 @@ namespace {
|
||||
|
||||
// Write the declarations and macros.
|
||||
for (auto &entry : fullEntry.DeclsOrMacros) {
|
||||
uint32_t id;
|
||||
if (SwiftLookupTable::isDeclEntry(entry)) {
|
||||
auto decl = Table.mapStoredDecl(entry);
|
||||
uint64_t id;
|
||||
auto mappedEntry = Table.mapStored(entry, isModule);
|
||||
if (auto *decl = mappedEntry.dyn_cast<clang::NamedDecl *>()) {
|
||||
id = (Writer.getDeclID(decl) << 2) | 0x02;
|
||||
} else if (auto *macro = mappedEntry.dyn_cast<clang::MacroInfo *>()) {
|
||||
id = static_cast<uint64_t>(Writer.getMacroID(macro)) << 32;
|
||||
id |= 0x02 | 0x01;
|
||||
} else {
|
||||
auto macro = Table.mapStoredMacro(entry);
|
||||
id = (Writer.getMacroID(macro) << 2) | 0x02 | 0x01;
|
||||
auto *moduleMacro = mappedEntry.get<clang::ModuleMacro *>();
|
||||
uint32_t nameID = Writer.getIdentifierRef(moduleMacro->getName());
|
||||
uint32_t submoduleID = Writer.getLocalOrImportedSubmoduleID(
|
||||
moduleMacro->getOwningModule());
|
||||
id = (static_cast<uint64_t>(nameID) << 32) | (submoduleID << 2);
|
||||
id |= 0x02 | 0x01;
|
||||
}
|
||||
writer.write<uint32_t>(id);
|
||||
writer.write<uint64_t>(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1014,7 +1058,7 @@ namespace {
|
||||
public:
|
||||
using key_type = std::pair<SwiftLookupTable::ContextKind, StringRef>;
|
||||
using key_type_ref = key_type;
|
||||
using data_type = SmallVector<uintptr_t, 2>;
|
||||
using data_type = SmallVector<uint64_t, 2>;
|
||||
using data_type_ref = data_type &;
|
||||
using hash_value_type = uint32_t;
|
||||
using offset_type = unsigned;
|
||||
@@ -1039,7 +1083,7 @@ namespace {
|
||||
|
||||
// # of entries
|
||||
uint32_t dataLength =
|
||||
sizeof(uint16_t) + sizeof(clang::serialization::DeclID) * data.size();
|
||||
sizeof(uint16_t) + sizeof(uint64_t) * data.size();
|
||||
|
||||
endian::Writer<little> writer(out);
|
||||
writer.write<uint16_t>(keyLength);
|
||||
@@ -1062,16 +1106,24 @@ namespace {
|
||||
writer.write<uint16_t>(data.size());
|
||||
|
||||
// Actual entries.
|
||||
bool isModule = Writer.getLangOpts().isCompilingModule();
|
||||
for (auto &entry : data) {
|
||||
uint32_t id;
|
||||
if (SwiftLookupTable::isDeclEntry(entry)) {
|
||||
auto decl = Table.mapStoredDecl(entry);
|
||||
uint64_t id;
|
||||
auto mappedEntry = Table.mapStored(entry, isModule);
|
||||
if (auto *decl = mappedEntry.dyn_cast<clang::NamedDecl *>()) {
|
||||
id = (Writer.getDeclID(decl) << 2) | 0x02;
|
||||
} else if (auto *macro = mappedEntry.dyn_cast<clang::MacroInfo *>()) {
|
||||
id = static_cast<uint64_t>(Writer.getMacroID(macro)) << 32;
|
||||
id |= 0x02 | 0x01;
|
||||
} else {
|
||||
auto macro = Table.mapStoredMacro(entry);
|
||||
id = (Writer.getMacroID(macro) << 2) | 0x02 | 0x01;
|
||||
auto *moduleMacro = mappedEntry.get<clang::ModuleMacro *>();
|
||||
uint32_t nameID = Writer.getIdentifierRef(moduleMacro->getName());
|
||||
uint32_t submoduleID = Writer.getLocalOrImportedSubmoduleID(
|
||||
moduleMacro->getOwningModule());
|
||||
id = (static_cast<uint64_t>(nameID) << 32) | (submoduleID << 2);
|
||||
id |= 0x02 | 0x01;
|
||||
}
|
||||
writer.write<uint32_t>(id);
|
||||
writer.write<uint64_t>(id);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -1221,7 +1273,7 @@ namespace {
|
||||
unsigned numDeclsOrMacros =
|
||||
endian::readNext<uint16_t, little, unaligned>(data);
|
||||
while (numDeclsOrMacros--) {
|
||||
auto id = endian::readNext<uint32_t, little, unaligned>(data);
|
||||
auto id = endian::readNext<uint64_t, little, unaligned>(data);
|
||||
entry.DeclsOrMacros.push_back(id);
|
||||
}
|
||||
|
||||
@@ -1237,7 +1289,7 @@ namespace {
|
||||
public:
|
||||
using internal_key_type = SwiftLookupTable::StoredContext;
|
||||
using external_key_type = internal_key_type;
|
||||
using data_type = SmallVector<uintptr_t, 2>;
|
||||
using data_type = SmallVector<uint64_t, 2>;
|
||||
using hash_value_type = uint32_t;
|
||||
using offset_type = unsigned;
|
||||
|
||||
@@ -1280,7 +1332,7 @@ namespace {
|
||||
|
||||
// Read all of the entries.
|
||||
while (numEntries--) {
|
||||
auto id = endian::readNext<uint32_t, little, unaligned>(data);
|
||||
auto id = endian::readNext<uint64_t, little, unaligned>(data);
|
||||
result.push_back(id);
|
||||
}
|
||||
|
||||
@@ -1297,7 +1349,7 @@ namespace swift {
|
||||
llvm::OnDiskIterableChainedHashTable<GlobalsAsMembersTableReaderInfo>;
|
||||
} // namespace swift
|
||||
|
||||
clang::NamedDecl *SwiftLookupTable::mapStoredDecl(uintptr_t &entry) {
|
||||
clang::NamedDecl *SwiftLookupTable::mapStoredDecl(uint64_t &entry) {
|
||||
assert(isDeclEntry(entry) && "Not a declaration entry");
|
||||
|
||||
// If we have an AST node here, just cast it.
|
||||
@@ -1307,7 +1359,7 @@ clang::NamedDecl *SwiftLookupTable::mapStoredDecl(uintptr_t &entry) {
|
||||
|
||||
// Otherwise, resolve the declaration.
|
||||
assert(Reader && "Cannot resolve the declaration without a reader");
|
||||
clang::serialization::DeclID declID = getSerializationID(entry);
|
||||
uint32_t declID = getEncodedDeclID(entry);
|
||||
auto decl = cast_or_null<clang::NamedDecl>(
|
||||
Reader->getASTReader().GetLocalDecl(Reader->getModuleFile(),
|
||||
declID));
|
||||
@@ -1317,33 +1369,66 @@ clang::NamedDecl *SwiftLookupTable::mapStoredDecl(uintptr_t &entry) {
|
||||
return decl;
|
||||
}
|
||||
|
||||
clang::MacroInfo *SwiftLookupTable::mapStoredMacro(uintptr_t &entry) {
|
||||
static bool isPCH(SwiftLookupTableReader &reader) {
|
||||
return reader.getModuleFile().Kind == clang::serialization::MK_PCH;
|
||||
}
|
||||
|
||||
SwiftLookupTable::SingleEntry
|
||||
SwiftLookupTable::mapStoredMacro(uint64_t &entry, bool assumeModule) {
|
||||
assert(isMacroEntry(entry) && "Not a macro entry");
|
||||
|
||||
// If we have an AST node here, just cast it.
|
||||
if (isASTNodeEntry(entry)) {
|
||||
if (assumeModule || (Reader && !isPCH(*Reader)))
|
||||
return static_cast<clang::ModuleMacro *>(getPointerFromEntry(entry));
|
||||
else
|
||||
return static_cast<clang::MacroInfo *>(getPointerFromEntry(entry));
|
||||
}
|
||||
|
||||
// Otherwise, resolve the macro.
|
||||
assert(Reader && "Cannot resolve the macro without a reader");
|
||||
clang::serialization::MacroID macroID = getSerializationID(entry);
|
||||
auto macro = cast_or_null<clang::MacroInfo>(
|
||||
Reader->getASTReader().getMacro(
|
||||
Reader->getASTReader().getGlobalMacroID(
|
||||
Reader->getModuleFile(),
|
||||
macroID)));
|
||||
clang::ASTReader &astReader = Reader->getASTReader();
|
||||
|
||||
LocalMacroIDs macroIDs = getEncodedModuleMacroIDs(entry);
|
||||
if (!assumeModule && macroIDs.moduleID == 0) {
|
||||
assert(isPCH(*Reader));
|
||||
// Not a module, and the second key is actually a macroID.
|
||||
auto macro =
|
||||
astReader.getMacro(astReader.getGlobalMacroID(Reader->getModuleFile(),
|
||||
macroIDs.nameOrMacroID));
|
||||
|
||||
// Update the entry now that we've resolved the macro.
|
||||
entry = encodeEntry(macro);
|
||||
return macro;
|
||||
}
|
||||
|
||||
SwiftLookupTable::SingleEntry SwiftLookupTable::mapStored(uintptr_t &entry) {
|
||||
// FIXME: Clang should help us out here, but it doesn't. It can only give us
|
||||
// MacroInfos and not ModuleMacros.
|
||||
assert(!isPCH(*Reader));
|
||||
clang::IdentifierInfo *name =
|
||||
astReader.getLocalIdentifier(Reader->getModuleFile(),
|
||||
macroIDs.nameOrMacroID);
|
||||
auto submoduleID = astReader.getGlobalSubmoduleID(Reader->getModuleFile(),
|
||||
macroIDs.moduleID);
|
||||
clang::Module *submodule = astReader.getSubmodule(submoduleID);
|
||||
assert(submodule);
|
||||
|
||||
clang::Preprocessor &pp = Reader->getASTReader().getPreprocessor();
|
||||
// Force the ModuleMacro to be loaded if this module is visible.
|
||||
(void)pp.getLeafModuleMacros(name);
|
||||
clang::ModuleMacro *macro = pp.getModuleMacro(submodule, name);
|
||||
// This might still be NULL if the module has been imported but not made
|
||||
// visible. We need a better answer here.
|
||||
if (macro)
|
||||
entry = encodeEntry(macro);
|
||||
return macro;
|
||||
}
|
||||
|
||||
SwiftLookupTable::SingleEntry SwiftLookupTable::mapStored(uint64_t &entry,
|
||||
bool assumeModule) {
|
||||
if (isDeclEntry(entry))
|
||||
return mapStoredDecl(entry);
|
||||
|
||||
return mapStoredMacro(entry);
|
||||
return mapStoredMacro(entry, assumeModule);
|
||||
}
|
||||
|
||||
SwiftLookupTableReader::~SwiftLookupTableReader() {
|
||||
@@ -1486,7 +1571,7 @@ SwiftLookupTableReader::getGlobalsAsMembersContexts() {
|
||||
|
||||
bool SwiftLookupTableReader::lookupGlobalsAsMembers(
|
||||
SwiftLookupTable::StoredContext context,
|
||||
SmallVectorImpl<uintptr_t> &entries) {
|
||||
SmallVectorImpl<uint64_t> &entries) {
|
||||
auto table =
|
||||
static_cast<SerializedGlobalsAsMembersTable*>(GlobalsAsMembersTable);
|
||||
if (!table) return false;
|
||||
@@ -1596,49 +1681,52 @@ void importer::addEntryToLookupTable(SwiftLookupTable &table,
|
||||
void importer::addMacrosToLookupTable(SwiftLookupTable &table,
|
||||
NameImporter &nameImporter) {
|
||||
auto &pp = nameImporter.getClangPreprocessor();
|
||||
auto *tu = nameImporter.getClangContext().getTranslationUnitDecl();
|
||||
for (const auto ¯o : pp.macros(false)) {
|
||||
// Find the local history of this macro directive.
|
||||
clang::MacroDirective *MD = pp.getLocalMacroDirectiveHistory(macro.first);
|
||||
|
||||
// Walk the history.
|
||||
for (; MD; MD = MD->getPrevious()) {
|
||||
// Don't look at any definitions that are followed by undefs.
|
||||
// FIXME: This isn't quite correct across explicit submodules -- one
|
||||
// submodule might define a macro, while another defines and then
|
||||
// undefines the same macro. If they are processed in that order, the
|
||||
// history will have the undef at the end, and we'll miss the first
|
||||
// definition.
|
||||
if (isa<clang::UndefMacroDirective>(MD))
|
||||
break;
|
||||
|
||||
// Only interested in macro definitions.
|
||||
auto *defMD = dyn_cast<clang::DefMacroDirective>(MD);
|
||||
if (!defMD)
|
||||
continue;
|
||||
|
||||
// Is this definition from this module?
|
||||
auto info = defMD->getInfo();
|
||||
if (!info || info->isFromASTFile())
|
||||
continue;
|
||||
auto maybeAddMacro = [&](clang::MacroInfo *info,
|
||||
clang::ModuleMacro *moduleMacro) {
|
||||
// If this is a #undef, return.
|
||||
if (!info)
|
||||
return;
|
||||
|
||||
// If we hit a builtin macro, we're done.
|
||||
if (info->isBuiltinMacro())
|
||||
break;
|
||||
return;
|
||||
|
||||
// If we hit a macro with invalid or predefined location, we're done.
|
||||
auto loc = defMD->getLocation();
|
||||
auto loc = info->getDefinitionLoc();
|
||||
if (loc.isInvalid())
|
||||
break;
|
||||
return;
|
||||
if (pp.getSourceManager().getFileID(loc) == pp.getPredefinesFileID())
|
||||
break;
|
||||
return;
|
||||
|
||||
// Add this entry.
|
||||
auto name = nameImporter.importMacroName(macro.first, info);
|
||||
if (name.empty())
|
||||
return;
|
||||
if (moduleMacro)
|
||||
table.addEntry(name, moduleMacro, tu, &pp);
|
||||
else
|
||||
table.addEntry(name, info, tu, &pp);
|
||||
};
|
||||
|
||||
ArrayRef<clang::ModuleMacro *> moduleMacros =
|
||||
macro.second.getActiveModuleMacros(pp, macro.first);
|
||||
if (moduleMacros.empty()) {
|
||||
// Handle the bridging header case.
|
||||
clang::MacroDirective *MD = pp.getLocalMacroDirective(macro.first);
|
||||
if (!MD)
|
||||
continue;
|
||||
table.addEntry(name, info,
|
||||
nameImporter.getClangContext().getTranslationUnitDecl(),
|
||||
&pp);
|
||||
|
||||
// If we hit a builtin macro, we're done.
|
||||
maybeAddMacro(MD->getMacroInfo(), nullptr);
|
||||
} else {
|
||||
for (clang::ModuleMacro *moduleMacro : moduleMacros) {
|
||||
clang::Module *owningModule = moduleMacro->getOwningModule();
|
||||
if (!owningModule->isSubModuleOf(pp.getCurrentModule()))
|
||||
continue;
|
||||
maybeAddMacro(moduleMacro->getMacroInfo(), moduleMacro);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@ namespace clang {
|
||||
class NamedDecl;
|
||||
class DeclContext;
|
||||
class MacroInfo;
|
||||
class ModuleMacro;
|
||||
class ObjCCategoryDecl;
|
||||
class TypedefNameDecl;
|
||||
}
|
||||
@@ -204,7 +205,8 @@ public:
|
||||
static bool contextRequiresName(ContextKind kind);
|
||||
|
||||
/// A single entry referencing either a named declaration or a macro.
|
||||
typedef llvm::PointerUnion<clang::NamedDecl *, clang::MacroInfo *>
|
||||
typedef llvm::PointerUnion3<clang::NamedDecl *, clang::MacroInfo *,
|
||||
clang::ModuleMacro *>
|
||||
SingleEntry;
|
||||
|
||||
/// A stored version of the context of an entity, which is Clang
|
||||
@@ -224,50 +226,51 @@ public:
|
||||
/// The low bit indicates whether we have a declaration or macro
|
||||
/// (declaration = unset, macro = set) and the second lowest bit
|
||||
/// indicates whether we have a serialization ID (set = DeclID or
|
||||
/// MacroID, as appropriate) vs. a pointer (unset,
|
||||
/// clang::NamedDecl * or clang::MacroInfo *). In the ID case, the
|
||||
/// upper N-2 bits are the ID value; in the pointer case, the
|
||||
/// lower two bits will always be clear due to the alignment of
|
||||
/// {IdentifierID,SubmoduleID}, as appropriate) vs. a pointer (unset,
|
||||
/// clang::NamedDecl *, clang::MacroInfo *, clang::ModuleMacro *).
|
||||
/// In the ID case, the upper N-2 bits are the ID value; in the pointer
|
||||
/// case, the lower two bits will always be clear due to the alignment of
|
||||
/// the Clang pointers.
|
||||
llvm::SmallVector<uintptr_t, 2> DeclsOrMacros;
|
||||
llvm::SmallVector<uint64_t, 2> DeclsOrMacros;
|
||||
};
|
||||
|
||||
/// Whether the given entry is a macro entry.
|
||||
static bool isMacroEntry(uintptr_t entry) { return entry & 0x01; }
|
||||
static bool isMacroEntry(uint64_t entry) { return entry & 0x01; }
|
||||
|
||||
/// Whether the given entry is a declaration entry.
|
||||
static bool isDeclEntry(uintptr_t entry) { return !isMacroEntry(entry); }
|
||||
static bool isDeclEntry(uint64_t entry) { return !isMacroEntry(entry); }
|
||||
|
||||
/// Whether the given entry is a serialization ID.
|
||||
static bool isSerializationIDEntry(uintptr_t entry) { return (entry & 0x02); }
|
||||
static bool isSerializationIDEntry(uint64_t entry) { return (entry & 0x02); }
|
||||
|
||||
/// Whether the given entry is an AST node.
|
||||
static bool isASTNodeEntry(uintptr_t entry) {
|
||||
static bool isASTNodeEntry(uint64_t entry) {
|
||||
return !isSerializationIDEntry(entry);
|
||||
}
|
||||
|
||||
/// Retrieve the serialization ID for an entry.
|
||||
static uint32_t getSerializationID(uintptr_t entry) {
|
||||
assert(isSerializationIDEntry(entry) && "Not a serialization entry");
|
||||
return entry >> 2;
|
||||
}
|
||||
|
||||
/// Retrieve the pointer for an entry.
|
||||
static void *getPointerFromEntry(uintptr_t entry) {
|
||||
static void *getPointerFromEntry(uint64_t entry) {
|
||||
assert(isASTNodeEntry(entry) && "Not an AST node entry");
|
||||
const uintptr_t mask = ~static_cast<uintptr_t>(0x03);
|
||||
const uint64_t mask = ~static_cast<uint64_t>(0x03);
|
||||
return reinterpret_cast<void *>(entry & mask);
|
||||
}
|
||||
|
||||
/// Encode a Clang named declaration as an entry in the table.
|
||||
static uintptr_t encodeEntry(clang::NamedDecl *decl) {
|
||||
static uint64_t encodeEntry(clang::NamedDecl *decl) {
|
||||
auto bits = reinterpret_cast<uintptr_t>(decl);
|
||||
assert((bits & 0x03) == 0 && "low bits set?");
|
||||
return bits;
|
||||
}
|
||||
|
||||
// Encode a Clang macro as an entry in the table.
|
||||
static uintptr_t encodeEntry(clang::MacroInfo *macro) {
|
||||
static uint64_t encodeEntry(clang::MacroInfo *macro) {
|
||||
auto bits = reinterpret_cast<uintptr_t>(macro);
|
||||
assert((bits & 0x03) == 0 && "low bits set?");
|
||||
return bits | 0x01;
|
||||
}
|
||||
|
||||
// Encode a Clang macro as an entry in the table.
|
||||
static uint64_t encodeEntry(clang::ModuleMacro *macro) {
|
||||
auto bits = reinterpret_cast<uintptr_t>(macro);
|
||||
assert((bits & 0x03) == 0 && "low bits set?");
|
||||
return bits | 0x01;
|
||||
@@ -286,7 +289,7 @@ private:
|
||||
///
|
||||
/// The values use the same representation as
|
||||
/// FullTableEntry::DeclsOrMacros.
|
||||
llvm::DenseMap<StoredContext, SmallVector<uintptr_t, 2>> GlobalsAsMembers;
|
||||
llvm::DenseMap<StoredContext, SmallVector<uint64_t, 2>> GlobalsAsMembers;
|
||||
|
||||
/// The reader responsible for lazily loading the contents of this table.
|
||||
SwiftLookupTableReader *Reader;
|
||||
@@ -307,20 +310,20 @@ private:
|
||||
/// present.
|
||||
///
|
||||
/// \returns true if the entry was added, false otherwise.
|
||||
bool addLocalEntry(SingleEntry newEntry, SmallVectorImpl<uintptr_t> &entries,
|
||||
bool addLocalEntry(SingleEntry newEntry, SmallVectorImpl<uint64_t> &entries,
|
||||
const clang::Preprocessor *PP);
|
||||
|
||||
public:
|
||||
explicit SwiftLookupTable(SwiftLookupTableReader *reader) : Reader(reader) { }
|
||||
|
||||
/// Maps a stored declaration entry to an actual Clang declaration.
|
||||
clang::NamedDecl *mapStoredDecl(uintptr_t &entry);
|
||||
clang::NamedDecl *mapStoredDecl(uint64_t &entry);
|
||||
|
||||
/// Maps a stored macro entry to an actual Clang macro.
|
||||
clang::MacroInfo *mapStoredMacro(uintptr_t &entry);
|
||||
SingleEntry mapStoredMacro(uint64_t &entry, bool assumeModule = false);
|
||||
|
||||
/// Maps a stored entry to an actual Clang AST node.
|
||||
SingleEntry mapStored(uintptr_t &entry);
|
||||
SingleEntry mapStored(uint64_t &entry, bool assumeModule = false);
|
||||
|
||||
/// Translate a Clang DeclContext into a context kind and name.
|
||||
static llvm::Optional<StoredContext> translateDeclContext(
|
||||
|
||||
Reference in New Issue
Block a user