mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Merge pull request #26493 from adrian-prantl/49233932
Introduce a DWARFImporter delegate that can look up clang::Decls by name
This commit is contained in:
@@ -639,8 +639,10 @@ public:
|
||||
/// \param isClang \c true if this module loader is responsible for loading
|
||||
/// Clang modules, which are special-cased in some parts of the
|
||||
/// compiler.
|
||||
/// \param isDWARF \c true if this module loader can load Clang modules
|
||||
/// from DWARF.
|
||||
void addModuleLoader(std::unique_ptr<ModuleLoader> loader,
|
||||
bool isClang = false);
|
||||
bool isClang = false, bool isDWARF = false);
|
||||
|
||||
/// Load extensions to the given nominal type from the external
|
||||
/// module loaders.
|
||||
@@ -683,6 +685,12 @@ public:
|
||||
/// The loader is owned by the AST context.
|
||||
ClangModuleLoader *getClangModuleLoader() const;
|
||||
|
||||
/// Retrieve the DWARF module loader for this ASTContext.
|
||||
///
|
||||
/// If there is no Clang module loader, returns a null pointer.
|
||||
/// The loader is owned by the AST context.
|
||||
ClangModuleLoader *getDWARFModuleLoader() const;
|
||||
|
||||
/// Asks every module loader to verify the ASTs it has loaded.
|
||||
///
|
||||
/// Does nothing in non-asserts (NDEBUG) builds.
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#define SWIFT_AST_CLANG_MODULE_LOADER_H
|
||||
|
||||
#include "swift/AST/ModuleLoader.h"
|
||||
#include "swift/Demangling/Demangle.h"
|
||||
|
||||
namespace clang {
|
||||
class ASTContext;
|
||||
@@ -25,6 +26,7 @@ class Sema;
|
||||
namespace swift {
|
||||
|
||||
class DeclContext;
|
||||
class VisibleDeclConsumer;
|
||||
|
||||
class ClangModuleLoader : public ModuleLoader {
|
||||
private:
|
||||
@@ -58,6 +60,30 @@ public:
|
||||
const DeclContext *overlayDC,
|
||||
const DeclContext *importedDC) = 0;
|
||||
|
||||
/// Look for declarations associated with the given name.
|
||||
///
|
||||
/// \param name The name we're searching for.
|
||||
virtual void lookupValue(DeclName name, VisibleDeclConsumer &consumer) {}
|
||||
|
||||
/// Look up a type declaration by its Clang name.
|
||||
///
|
||||
/// Note that this method does no filtering. If it finds the type in a loaded
|
||||
/// module, it returns it. This is intended for use in reflection / debugging
|
||||
/// contexts where access is not a problem.
|
||||
virtual void lookupTypeDecl(StringRef clangName, Demangle::Node::Kind kind,
|
||||
llvm::function_ref<void(TypeDecl *)> receiver) {}
|
||||
|
||||
/// Look up type a declaration synthesized by the Clang importer itself, using
|
||||
/// a "related entity kind" to determine which type it should be. For example,
|
||||
/// this can be used to find the synthesized error struct for an
|
||||
/// NS_ERROR_ENUM.
|
||||
///
|
||||
/// Note that this method does no filtering. If it finds the type in a loaded
|
||||
/// module, it returns it. This is intended for use in reflection / debugging
|
||||
/// contexts where access is not a problem.
|
||||
virtual void
|
||||
lookupRelatedEntity(StringRef clangName, StringRef relatedEntityKind,
|
||||
llvm::function_ref<void(TypeDecl *)> receiver) {}
|
||||
};
|
||||
|
||||
} // namespace swift
|
||||
|
||||
@@ -35,6 +35,7 @@ class ClangImporterOptions;
|
||||
class ClassDecl;
|
||||
class ModuleDecl;
|
||||
class NominalTypeDecl;
|
||||
class TypeDecl;
|
||||
|
||||
enum class KnownProtocolKind : uint8_t;
|
||||
|
||||
|
||||
@@ -75,6 +75,7 @@ enum class ClangTypeKind {
|
||||
/// from Clang ASTs over to Swift ASTs.
|
||||
class ClangImporter final : public ClangModuleLoader {
|
||||
friend class ClangModuleUnit;
|
||||
friend class DWARFImporter;
|
||||
|
||||
public:
|
||||
class Implementation;
|
||||
@@ -160,15 +161,15 @@ public:
|
||||
/// Look for declarations associated with the given name.
|
||||
///
|
||||
/// \param name The name we're searching for.
|
||||
void lookupValue(DeclName name, VisibleDeclConsumer &consumer);
|
||||
void lookupValue(DeclName name, VisibleDeclConsumer &consumer) override;
|
||||
|
||||
/// Look up a type declaration by its Clang name.
|
||||
///
|
||||
/// Note that this method does no filtering. If it finds the type in a loaded
|
||||
/// module, it returns it. This is intended for use in reflection / debugging
|
||||
/// contexts where access is not a problem.
|
||||
void lookupTypeDecl(StringRef clangName, ClangTypeKind kind,
|
||||
llvm::function_ref<void(TypeDecl*)> receiver);
|
||||
void lookupTypeDecl(StringRef clangName, Demangle::Node::Kind kind,
|
||||
llvm::function_ref<void(TypeDecl*)> receiver) override;
|
||||
|
||||
/// Look up type a declaration synthesized by the Clang importer itself, using
|
||||
/// a "related entity kind" to determine which type it should be. For example,
|
||||
@@ -178,9 +179,9 @@ public:
|
||||
/// Note that this method does no filtering. If it finds the type in a loaded
|
||||
/// module, it returns it. This is intended for use in reflection / debugging
|
||||
/// contexts where access is not a problem.
|
||||
void lookupRelatedEntity(StringRef clangName, ClangTypeKind kind,
|
||||
StringRef relatedEntityKind,
|
||||
llvm::function_ref<void(TypeDecl*)> receiver);
|
||||
void
|
||||
lookupRelatedEntity(StringRef clangName, StringRef relatedEntityKind,
|
||||
llvm::function_ref<void(TypeDecl *)> receiver) override;
|
||||
|
||||
/// Look for textually included declarations from the bridging header.
|
||||
///
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
#define SWIFT_DWARF_IMPORTER_H
|
||||
|
||||
#include "swift/AST/ClangModuleLoader.h"
|
||||
#include "swift/AST/Module.h"
|
||||
#include "swift/Demangling/Demangle.h"
|
||||
|
||||
namespace llvm {
|
||||
}
|
||||
@@ -27,6 +29,25 @@ namespace clang {
|
||||
|
||||
namespace swift {
|
||||
|
||||
/// This interface is implemented by LLDB to serve as a fallback when Clang
|
||||
/// modules can't be imported from source in the debugger.
|
||||
///
|
||||
/// During compile time, ClangImporter-imported Clang modules are compiled with
|
||||
/// -gmodules, which emits a DWARF rendition of all types defined in the module
|
||||
/// into the .pcm file. On Darwin, these types can be collected by
|
||||
/// dsymutil. This delegate allows DWARFImporter to ask LLDB to look up a Clang
|
||||
/// type by name, synthesize a Clang AST from it. DWARFImporter then hands this
|
||||
/// Clang AST to ClangImporter to import the type into Swift.
|
||||
class DWARFImporterDelegate {
|
||||
public:
|
||||
virtual ~DWARFImporterDelegate() {}
|
||||
/// Perform a qualified lookup of a Clang type with this name.
|
||||
/// \param kind Only return results with this type kind.
|
||||
virtual void lookupValue(StringRef name,
|
||||
llvm::Optional<Demangle::Node::Kind> kind,
|
||||
SmallVectorImpl<clang::Decl *> &results) {}
|
||||
};
|
||||
|
||||
/// Class that imports Clang modules into Swift, mapping directly
|
||||
/// from Clang ASTs over to Swift ASTs.
|
||||
class DWARFImporter final : public ClangModuleLoader {
|
||||
@@ -39,6 +60,7 @@ private:
|
||||
Implementation &Impl;
|
||||
|
||||
DWARFImporter(ASTContext &ctx, const ClangImporterOptions &clangImporterOpts,
|
||||
std::unique_ptr<DWARFImporterDelegate> delegate,
|
||||
DependencyTracker *tracker);
|
||||
|
||||
public:
|
||||
@@ -55,8 +77,8 @@ public:
|
||||
/// \returns a new DWARF module importer, or null (with a diagnostic) if
|
||||
/// an error occurred.
|
||||
static std::unique_ptr<DWARFImporter>
|
||||
create(ASTContext &ctx,
|
||||
const ClangImporterOptions &importerOpts,
|
||||
create(ASTContext &ctx, const ClangImporterOptions &importerOpts,
|
||||
std::unique_ptr<DWARFImporterDelegate> delegate = {},
|
||||
DependencyTracker *tracker = nullptr);
|
||||
|
||||
DWARFImporter(const DWARFImporter &) = delete;
|
||||
@@ -80,6 +102,17 @@ public:
|
||||
ModuleDecl *
|
||||
loadModule(SourceLoc importLoc,
|
||||
ArrayRef<std::pair<Identifier, SourceLoc>> path) override;
|
||||
|
||||
ValueDecl *importDecl(clang::Decl *clangDecl);
|
||||
|
||||
void lookupValue(DeclName name, VisibleDeclConsumer &consumer) override {}
|
||||
/// Behaves like \p ClangImporter::lookupValue.
|
||||
void lookupValue(ModuleDecl::AccessPathTy accessPath, DeclName name,
|
||||
NLKind lookupKind, SmallVectorImpl<ValueDecl *> &results);
|
||||
/// Perform a qualified lookup of a Clang type with this name and only return
|
||||
/// results with the specified type kind.
|
||||
void lookupTypeDecl(StringRef rawName, Demangle::Node::Kind kind,
|
||||
llvm::function_ref<void(TypeDecl *)> receiver) override;
|
||||
bool
|
||||
isInOverlayModuleForImportedModule(const DeclContext *overlayDC,
|
||||
const DeclContext *importedDC) override;
|
||||
|
||||
@@ -255,6 +255,9 @@ FOR_KNOWN_FOUNDATION_TYPES(CACHE_FOUNDATION_DECL)
|
||||
/// The module loader used to load Clang modules.
|
||||
ClangModuleLoader *TheClangModuleLoader = nullptr;
|
||||
|
||||
/// The module loader used to load Clang modules from DWARF.
|
||||
ClangModuleLoader *TheDWARFModuleLoader = nullptr;
|
||||
|
||||
/// Map from Swift declarations to raw comments.
|
||||
llvm::DenseMap<const Decl *, RawComment> RawComments;
|
||||
|
||||
@@ -1446,10 +1449,13 @@ void ASTContext::addSearchPath(StringRef searchPath, bool isFramework,
|
||||
}
|
||||
|
||||
void ASTContext::addModuleLoader(std::unique_ptr<ModuleLoader> loader,
|
||||
bool IsClang) {
|
||||
if (IsClang && !getImpl().TheClangModuleLoader)
|
||||
bool IsClang, bool IsDwarf) {
|
||||
if (IsClang && !IsDwarf && !getImpl().TheClangModuleLoader)
|
||||
getImpl().TheClangModuleLoader =
|
||||
static_cast<ClangModuleLoader *>(loader.get());
|
||||
if (IsClang && IsDwarf && !getImpl().TheDWARFModuleLoader)
|
||||
getImpl().TheDWARFModuleLoader =
|
||||
static_cast<ClangModuleLoader *>(loader.get());
|
||||
|
||||
getImpl().ModuleLoaders.push_back(std::move(loader));
|
||||
}
|
||||
@@ -1493,6 +1499,10 @@ ClangModuleLoader *ASTContext::getClangModuleLoader() const {
|
||||
return getImpl().TheClangModuleLoader;
|
||||
}
|
||||
|
||||
ClangModuleLoader *ASTContext::getDWARFModuleLoader() const {
|
||||
return getImpl().TheDWARFModuleLoader;
|
||||
}
|
||||
|
||||
ModuleDecl *ASTContext::getLoadedModule(
|
||||
ArrayRef<std::pair<Identifier, SourceLoc>> ModulePath) const {
|
||||
assert(!ModulePath.empty());
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "swift/AST/ASTDemangler.h"
|
||||
|
||||
#include "swift/AST/ASTContext.h"
|
||||
#include "swift/AST/ClangModuleLoader.h"
|
||||
#include "swift/AST/Decl.h"
|
||||
#include "swift/AST/GenericSignature.h"
|
||||
#include "swift/AST/GenericSignatureBuilder.h"
|
||||
@@ -29,7 +30,6 @@
|
||||
#include "swift/AST/NameLookup.h"
|
||||
#include "swift/AST/Type.h"
|
||||
#include "swift/AST/Types.h"
|
||||
#include "swift/ClangImporter/ClangImporter.h"
|
||||
#include "swift/Demangling/Demangler.h"
|
||||
#include "swift/Demangling/ManglingMacros.h"
|
||||
|
||||
@@ -1023,31 +1023,14 @@ ASTBuilder::findTypeDecl(DeclContext *dc,
|
||||
return result;
|
||||
}
|
||||
|
||||
static Optional<ClangTypeKind>
|
||||
getClangTypeKindForNodeKind(Demangle::Node::Kind kind) {
|
||||
switch (kind) {
|
||||
case Demangle::Node::Kind::Protocol:
|
||||
return ClangTypeKind::ObjCProtocol;
|
||||
case Demangle::Node::Kind::Class:
|
||||
return ClangTypeKind::ObjCClass;
|
||||
case Demangle::Node::Kind::TypeAlias:
|
||||
return ClangTypeKind::Typedef;
|
||||
case Demangle::Node::Kind::Structure:
|
||||
case Demangle::Node::Kind::Enum:
|
||||
return ClangTypeKind::Tag;
|
||||
default:
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
||||
GenericTypeDecl *
|
||||
ASTBuilder::findForeignTypeDecl(StringRef name,
|
||||
StringRef relatedEntityKind,
|
||||
ForeignModuleKind foreignKind,
|
||||
Demangle::Node::Kind kind) {
|
||||
GenericTypeDecl *ASTBuilder::findForeignTypeDecl(StringRef name,
|
||||
StringRef relatedEntityKind,
|
||||
ForeignModuleKind foreignKind,
|
||||
Demangle::Node::Kind kind) {
|
||||
// Check to see if we have an importer loaded.
|
||||
auto importer = static_cast<ClangImporter *>(Ctx.getClangModuleLoader());
|
||||
if (!importer) return nullptr;
|
||||
auto importer = Ctx.getClangModuleLoader();
|
||||
if (!importer)
|
||||
return nullptr;
|
||||
|
||||
// Find the unique declaration that has the right kind.
|
||||
struct Consumer : VisibleDeclConsumer {
|
||||
@@ -1059,8 +1042,10 @@ ASTBuilder::findForeignTypeDecl(StringRef name,
|
||||
|
||||
void foundDecl(ValueDecl *decl, DeclVisibilityKind reason,
|
||||
DynamicLookupInfo dynamicLookupInfo = {}) override {
|
||||
if (HadError) return;
|
||||
if (decl == Result) return;
|
||||
if (HadError)
|
||||
return;
|
||||
if (decl == Result)
|
||||
return;
|
||||
if (!Result) {
|
||||
Result = dyn_cast<GenericTypeDecl>(decl);
|
||||
HadError |= !Result;
|
||||
@@ -1071,33 +1056,27 @@ ASTBuilder::findForeignTypeDecl(StringRef name,
|
||||
}
|
||||
} consumer(kind);
|
||||
|
||||
auto found = [&](TypeDecl *found) {
|
||||
consumer.foundDecl(found, DeclVisibilityKind::VisibleAtTopLevel);
|
||||
};
|
||||
|
||||
switch (foreignKind) {
|
||||
case ForeignModuleKind::SynthesizedByImporter:
|
||||
if (!relatedEntityKind.empty()) {
|
||||
Optional<ClangTypeKind> lookupKind = getClangTypeKindForNodeKind(kind);
|
||||
if (!lookupKind)
|
||||
return nullptr;
|
||||
importer->lookupRelatedEntity(name, lookupKind.getValue(),
|
||||
relatedEntityKind, [&](TypeDecl *found) {
|
||||
consumer.foundDecl(found, DeclVisibilityKind::VisibleAtTopLevel);
|
||||
});
|
||||
importer->lookupRelatedEntity(name, relatedEntityKind, found);
|
||||
break;
|
||||
}
|
||||
importer->lookupValue(Ctx.getIdentifier(name), consumer);
|
||||
if (consumer.Result) {
|
||||
consumer.Result =
|
||||
getAcceptableTypeDeclCandidate(consumer.Result,kind);
|
||||
}
|
||||
if (consumer.Result)
|
||||
consumer.Result = getAcceptableTypeDeclCandidate(consumer.Result, kind);
|
||||
break;
|
||||
case ForeignModuleKind::Imported: {
|
||||
Optional<ClangTypeKind> lookupKind = getClangTypeKindForNodeKind(kind);
|
||||
if (!lookupKind)
|
||||
return nullptr;
|
||||
importer->lookupTypeDecl(name, lookupKind.getValue(),
|
||||
[&](TypeDecl *found) {
|
||||
consumer.foundDecl(found, DeclVisibilityKind::VisibleAtTopLevel);
|
||||
});
|
||||
}
|
||||
case ForeignModuleKind::Imported:
|
||||
importer->lookupTypeDecl(name, kind, found);
|
||||
|
||||
// Try the DWARFImporter if it exists.
|
||||
if (!consumer.Result)
|
||||
if (auto *dwarf_importer = Ctx.getDWARFModuleLoader())
|
||||
dwarf_importer->lookupTypeDecl(name, kind, found);
|
||||
}
|
||||
|
||||
return consumer.Result;
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "swift/Basic/StringExtras.h"
|
||||
#include "swift/Basic/Version.h"
|
||||
#include "swift/ClangImporter/ClangImporterOptions.h"
|
||||
#include "swift/Demangling/Demangle.h"
|
||||
#include "swift/Parse/Lexer.h"
|
||||
#include "swift/Parse/Parser.h"
|
||||
#include "swift/Config.h"
|
||||
@@ -2494,14 +2495,34 @@ void ClangImporter::lookupValue(DeclName name, VisibleDeclConsumer &consumer){
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
ClangImporter::lookupTypeDecl(StringRef rawName, ClangTypeKind kind,
|
||||
llvm::function_ref<void(TypeDecl*)> receiver) {
|
||||
static Optional<ClangTypeKind>
|
||||
getClangTypeKindForNodeKind(Demangle::Node::Kind kind) {
|
||||
switch (kind) {
|
||||
case Demangle::Node::Kind::Protocol:
|
||||
return ClangTypeKind::ObjCProtocol;
|
||||
case Demangle::Node::Kind::Class:
|
||||
return ClangTypeKind::ObjCClass;
|
||||
case Demangle::Node::Kind::TypeAlias:
|
||||
return ClangTypeKind::Typedef;
|
||||
case Demangle::Node::Kind::Structure:
|
||||
case Demangle::Node::Kind::Enum:
|
||||
return ClangTypeKind::Tag;
|
||||
default:
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
||||
void ClangImporter::lookupTypeDecl(
|
||||
StringRef rawName, Demangle::Node::Kind kind,
|
||||
llvm::function_ref<void(TypeDecl *)> receiver) {
|
||||
clang::DeclarationName clangName(
|
||||
&Impl.Instance->getASTContext().Idents.get(rawName));
|
||||
|
||||
clang::Sema::LookupNameKind lookupKind;
|
||||
switch (kind) {
|
||||
auto clang_kind = getClangTypeKindForNodeKind(kind);
|
||||
if (!clang_kind)
|
||||
return;
|
||||
switch (*clang_kind) {
|
||||
case ClangTypeKind::Typedef:
|
||||
lookupKind = clang::Sema::LookupOrdinaryName;
|
||||
break;
|
||||
@@ -2532,17 +2553,17 @@ ClangImporter::lookupTypeDecl(StringRef rawName, ClangTypeKind kind,
|
||||
}
|
||||
|
||||
void ClangImporter::lookupRelatedEntity(
|
||||
StringRef rawName, ClangTypeKind kind, StringRef relatedEntityKind,
|
||||
llvm::function_ref<void(TypeDecl*)> receiver) {
|
||||
StringRef rawName, StringRef relatedEntityKind,
|
||||
llvm::function_ref<void(TypeDecl *)> receiver) {
|
||||
using CISTAttr = ClangImporterSynthesizedTypeAttr;
|
||||
if (relatedEntityKind ==
|
||||
CISTAttr::manglingNameForKind(CISTAttr::Kind::NSErrorWrapper) ||
|
||||
relatedEntityKind ==
|
||||
CISTAttr::manglingNameForKind(CISTAttr::Kind::NSErrorWrapperAnon)) {
|
||||
auto underlyingKind = ClangTypeKind::Tag;
|
||||
auto underlyingKind = Demangle::Node::Kind::Structure;
|
||||
if (relatedEntityKind ==
|
||||
CISTAttr::manglingNameForKind(CISTAttr::Kind::NSErrorWrapperAnon)) {
|
||||
underlyingKind = ClangTypeKind::Typedef;
|
||||
underlyingKind = Demangle::Node::Kind::TypeAlias;
|
||||
}
|
||||
lookupTypeDecl(rawName, underlyingKind,
|
||||
[this, receiver] (const TypeDecl *foundType) {
|
||||
|
||||
@@ -318,6 +318,7 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation
|
||||
public LazyConformanceLoader
|
||||
{
|
||||
friend class ClangImporter;
|
||||
friend class DWARFImporter;
|
||||
using Version = importer::ImportNameVersion;
|
||||
|
||||
public:
|
||||
|
||||
@@ -13,15 +13,18 @@
|
||||
#include "swift/DWARFImporter/DWARFImporter.h"
|
||||
#include "swift/AST/ASTContext.h"
|
||||
#include "swift/AST/Module.h"
|
||||
#include "clang/CodeGen/ObjectFilePCHContainerOperations.h"
|
||||
#include "clang/Frontend/FrontendActions.h"
|
||||
#include "../ClangImporter/ImporterImpl.h"
|
||||
|
||||
using namespace swift;
|
||||
|
||||
std::unique_ptr<DWARFImporter>
|
||||
DWARFImporter::create(ASTContext &ctx,
|
||||
const ClangImporterOptions &importerOpts,
|
||||
DWARFImporter::create(ASTContext &ctx, const ClangImporterOptions &importerOpts,
|
||||
std::unique_ptr<DWARFImporterDelegate> delegate,
|
||||
DependencyTracker *tracker) {
|
||||
std::unique_ptr<DWARFImporter> importer{
|
||||
new DWARFImporter(ctx, importerOpts, tracker)
|
||||
new DWARFImporter(ctx, importerOpts, std::move(delegate), tracker)
|
||||
};
|
||||
return importer;
|
||||
}
|
||||
@@ -29,17 +32,18 @@ DWARFImporter::create(ASTContext &ctx,
|
||||
class DWARFModuleUnit final : public LoadedFile {
|
||||
|
||||
~DWARFModuleUnit() = default;
|
||||
DWARFImporter::Implementation &owner;
|
||||
|
||||
public:
|
||||
DWARFModuleUnit(ModuleDecl &M)
|
||||
: LoadedFile(FileUnitKind::DWARFModule, M) {}
|
||||
DWARFModuleUnit(ModuleDecl &M, DWARFImporter::Implementation &owner)
|
||||
: LoadedFile(FileUnitKind::DWARFModule, M), owner(owner) {}
|
||||
|
||||
virtual bool isSystemModule() const override { return false; }
|
||||
|
||||
virtual void
|
||||
lookupValue(ModuleDecl::AccessPathTy accessPath, DeclName name,
|
||||
NLKind lookupKind,
|
||||
SmallVectorImpl<ValueDecl *> &results) const override {}
|
||||
SmallVectorImpl<ValueDecl *> &results) const override;
|
||||
|
||||
virtual TypeDecl *
|
||||
lookupNestedType(Identifier name,
|
||||
@@ -101,14 +105,17 @@ public:
|
||||
class DWARFImporter::Implementation {
|
||||
public:
|
||||
ASTContext &SwiftContext;
|
||||
clang::ASTContext *ClangASTContext = nullptr;
|
||||
clang::CompilerInstance *Instance = nullptr;
|
||||
clang::Preprocessor *PP = nullptr;
|
||||
clang::Sema *Sema = nullptr;
|
||||
|
||||
std::unique_ptr<DWARFImporterDelegate> delegate;
|
||||
ClangImporter &clangImporter;
|
||||
|
||||
llvm::DenseMap<Identifier, DWARFModuleUnit *> ModuleWrappers;
|
||||
Implementation(ASTContext &ctx, const ClangImporterOptions &clangImporterOpts)
|
||||
: SwiftContext(ctx) {}
|
||||
Implementation(ASTContext &ctx, const ClangImporterOptions &clangImporterOpts,
|
||||
std::unique_ptr<DWARFImporterDelegate> delegate,
|
||||
DependencyTracker *tracker)
|
||||
: SwiftContext(ctx), delegate(std::move(delegate)),
|
||||
clangImporter(
|
||||
*static_cast<ClangImporter *>(ctx.getClangModuleLoader())) {}
|
||||
|
||||
ModuleDecl *loadModule(SourceLoc importLoc,
|
||||
ArrayRef<std::pair<Identifier, SourceLoc>> path) {
|
||||
@@ -122,22 +129,95 @@ public:
|
||||
auto *decl = ModuleDecl::create(name, SwiftContext);
|
||||
decl->setIsNonSwiftModule();
|
||||
decl->setHasResolvedImports();
|
||||
auto wrapperUnit = new (SwiftContext) DWARFModuleUnit(*decl);
|
||||
auto wrapperUnit = new (SwiftContext) DWARFModuleUnit(*decl, *this);
|
||||
ModuleWrappers.insert({name, wrapperUnit});
|
||||
decl->addFile(*wrapperUnit);
|
||||
|
||||
// Force load overlay modules for all imported modules.
|
||||
decl->forAllVisibleModules({}, [](ModuleDecl::ImportedModule import) {});
|
||||
|
||||
// Register the module with the ASTContext so it is available for lookups.
|
||||
ModuleDecl *&loaded = SwiftContext.LoadedModules[name];
|
||||
if (!loaded)
|
||||
loaded = decl;
|
||||
|
||||
return decl;
|
||||
}
|
||||
|
||||
public:
|
||||
ValueDecl *importDecl(clang::Decl *clangDecl) {
|
||||
auto *namedDecl = dyn_cast_or_null<clang::NamedDecl>(clangDecl);
|
||||
if (!namedDecl)
|
||||
return nullptr;
|
||||
return cast_or_null<ValueDecl>(clangImporter.Impl.importDeclReal(
|
||||
namedDecl->getMostRecentDecl(), clangImporter.Impl.CurrentVersion));
|
||||
}
|
||||
|
||||
void lookupValue(ModuleDecl::AccessPathTy accessPath, DeclName name,
|
||||
NLKind lookupKind, SmallVectorImpl<ValueDecl *> &results) {
|
||||
if (!swift::ModuleDecl::matchesAccessPath(accessPath, name))
|
||||
return;
|
||||
|
||||
if (lookupKind != NLKind::QualifiedLookup)
|
||||
return;
|
||||
|
||||
if (!delegate)
|
||||
return;
|
||||
|
||||
SmallVector<clang::Decl *, 4> decls;
|
||||
delegate->lookupValue(name.getBaseIdentifier().str(), llvm::None, decls);
|
||||
for (auto *clangDecl : decls) {
|
||||
auto *decl = importDecl(clangDecl);
|
||||
if (!decl)
|
||||
continue;
|
||||
|
||||
if (decl->getFullName().matchesRef(name) &&
|
||||
decl->getDeclContext()->isModuleScopeContext())
|
||||
results.push_back(decl);
|
||||
}
|
||||
}
|
||||
|
||||
void lookupTypeDecl(StringRef rawName, Demangle::Node::Kind kind,
|
||||
llvm::function_ref<void(TypeDecl *)> receiver) {
|
||||
SmallVector<clang::Decl *, 1> decls;
|
||||
delegate->lookupValue(rawName, kind, decls);
|
||||
for (auto *clangDecl : decls) {
|
||||
if (!isa<clang::TypeDecl>(clangDecl) &&
|
||||
!isa<clang::ObjCContainerDecl>(clangDecl) &&
|
||||
!isa<clang::ObjCCompatibleAliasDecl>(clangDecl)) {
|
||||
continue;
|
||||
}
|
||||
auto *imported = importDecl(clangDecl);
|
||||
if (auto *importedType = dyn_cast_or_null<TypeDecl>(imported))
|
||||
receiver(importedType);
|
||||
}
|
||||
}
|
||||
|
||||
clang::ASTContext &getClangASTContext() const {
|
||||
return clangImporter.getClangASTContext();
|
||||
}
|
||||
clang::Preprocessor &getClangPreprocessor() const {
|
||||
return clangImporter.getClangPreprocessor();
|
||||
}
|
||||
clang::Sema &getClangSema() const { return clangImporter.getClangSema(); }
|
||||
const clang::CompilerInstance &getClangInstance() const {
|
||||
return clangImporter.getClangInstance();
|
||||
}
|
||||
};
|
||||
|
||||
void DWARFModuleUnit::lookupValue(ModuleDecl::AccessPathTy accessPath,
|
||||
DeclName name, NLKind lookupKind,
|
||||
SmallVectorImpl<ValueDecl *> &results) const {
|
||||
owner.lookupValue(accessPath, name, lookupKind, results);
|
||||
}
|
||||
|
||||
DWARFImporter::DWARFImporter(ASTContext &ctx,
|
||||
const ClangImporterOptions &clangImporterOpts,
|
||||
std::unique_ptr<DWARFImporterDelegate> delegate,
|
||||
DependencyTracker *tracker)
|
||||
: ClangModuleLoader(tracker),
|
||||
Impl(*new Implementation(ctx, clangImporterOpts)) {}
|
||||
Impl(*new Implementation(ctx, clangImporterOpts, std::move(delegate),
|
||||
tracker)) {}
|
||||
|
||||
DWARFImporter::~DWARFImporter() { delete &Impl; }
|
||||
|
||||
@@ -159,6 +239,22 @@ DWARFImporter::loadModule(SourceLoc importLoc,
|
||||
return Impl.loadModule(importLoc, path);
|
||||
}
|
||||
|
||||
ValueDecl *DWARFImporter::importDecl(clang::Decl *clangDecl) {
|
||||
return Impl.importDecl(clangDecl);
|
||||
}
|
||||
|
||||
void DWARFImporter::lookupValue(ModuleDecl::AccessPathTy accessPath,
|
||||
DeclName name, NLKind lookupKind,
|
||||
SmallVectorImpl<ValueDecl *> &results) {
|
||||
Impl.lookupValue(accessPath, name, lookupKind, results);
|
||||
}
|
||||
|
||||
void DWARFImporter::lookupTypeDecl(
|
||||
StringRef rawName, Demangle::Node::Kind kind,
|
||||
llvm::function_ref<void(TypeDecl *)> receiver) {
|
||||
Impl.lookupTypeDecl(rawName, kind, receiver);
|
||||
}
|
||||
|
||||
bool DWARFImporter::isInOverlayModuleForImportedModule(
|
||||
const DeclContext *overlayDC, const DeclContext *importedDC) {
|
||||
return false;
|
||||
@@ -177,14 +273,14 @@ ModuleDecl *DWARFImporter::getImportedHeaderModule() const { return nullptr; }
|
||||
void DWARFImporter::verifyAllModules() {};
|
||||
|
||||
clang::ASTContext &DWARFImporter::getClangASTContext() const {
|
||||
return *Impl.ClangASTContext;
|
||||
return Impl.getClangASTContext();
|
||||
}
|
||||
clang::Preprocessor &DWARFImporter::getClangPreprocessor() const {
|
||||
return *Impl.PP;
|
||||
return Impl.getClangPreprocessor();
|
||||
}
|
||||
clang::Sema &DWARFImporter::getClangSema() const { return *Impl.Sema; }
|
||||
clang::Sema &DWARFImporter::getClangSema() const { return Impl.getClangSema(); }
|
||||
const clang::CompilerInstance &DWARFImporter::getClangInstance() const {
|
||||
return *Impl.Instance;
|
||||
return Impl.getClangInstance();
|
||||
}
|
||||
|
||||
void DWARFImporter::printStatistics() const {}
|
||||
|
||||
@@ -380,7 +380,7 @@ bool CompilerInstance::setUpModuleLoaders() {
|
||||
if (Invocation.getLangOptions().EnableDWARFImporter) {
|
||||
auto dwarfImporter =
|
||||
DWARFImporter::create(*Context, Invocation.getClangImporterOptions(),
|
||||
getDependencyTracker());
|
||||
nullptr, getDependencyTracker());
|
||||
if (!dwarfImporter) {
|
||||
Diagnostics.diagnose(SourceLoc(), diag::error_clang_importer_create_fail);
|
||||
return true;
|
||||
|
||||
@@ -5,7 +5,6 @@ add_swift_host_tool(sil-passpipeline-dumper
|
||||
target_link_libraries(sil-passpipeline-dumper
|
||||
PRIVATE
|
||||
swiftClangImporter
|
||||
swiftDWARFImporter
|
||||
swiftFrontend
|
||||
swiftSerialization
|
||||
swiftSILGen
|
||||
|
||||
Reference in New Issue
Block a user