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
|
/// \param isClang \c true if this module loader is responsible for loading
|
||||||
/// Clang modules, which are special-cased in some parts of the
|
/// Clang modules, which are special-cased in some parts of the
|
||||||
/// compiler.
|
/// compiler.
|
||||||
|
/// \param isDWARF \c true if this module loader can load Clang modules
|
||||||
|
/// from DWARF.
|
||||||
void addModuleLoader(std::unique_ptr<ModuleLoader> loader,
|
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
|
/// Load extensions to the given nominal type from the external
|
||||||
/// module loaders.
|
/// module loaders.
|
||||||
@@ -683,6 +685,12 @@ public:
|
|||||||
/// The loader is owned by the AST context.
|
/// The loader is owned by the AST context.
|
||||||
ClangModuleLoader *getClangModuleLoader() const;
|
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.
|
/// Asks every module loader to verify the ASTs it has loaded.
|
||||||
///
|
///
|
||||||
/// Does nothing in non-asserts (NDEBUG) builds.
|
/// Does nothing in non-asserts (NDEBUG) builds.
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
#define SWIFT_AST_CLANG_MODULE_LOADER_H
|
#define SWIFT_AST_CLANG_MODULE_LOADER_H
|
||||||
|
|
||||||
#include "swift/AST/ModuleLoader.h"
|
#include "swift/AST/ModuleLoader.h"
|
||||||
|
#include "swift/Demangling/Demangle.h"
|
||||||
|
|
||||||
namespace clang {
|
namespace clang {
|
||||||
class ASTContext;
|
class ASTContext;
|
||||||
@@ -25,6 +26,7 @@ class Sema;
|
|||||||
namespace swift {
|
namespace swift {
|
||||||
|
|
||||||
class DeclContext;
|
class DeclContext;
|
||||||
|
class VisibleDeclConsumer;
|
||||||
|
|
||||||
class ClangModuleLoader : public ModuleLoader {
|
class ClangModuleLoader : public ModuleLoader {
|
||||||
private:
|
private:
|
||||||
@@ -58,6 +60,30 @@ public:
|
|||||||
const DeclContext *overlayDC,
|
const DeclContext *overlayDC,
|
||||||
const DeclContext *importedDC) = 0;
|
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
|
} // namespace swift
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ class ClangImporterOptions;
|
|||||||
class ClassDecl;
|
class ClassDecl;
|
||||||
class ModuleDecl;
|
class ModuleDecl;
|
||||||
class NominalTypeDecl;
|
class NominalTypeDecl;
|
||||||
|
class TypeDecl;
|
||||||
|
|
||||||
enum class KnownProtocolKind : uint8_t;
|
enum class KnownProtocolKind : uint8_t;
|
||||||
|
|
||||||
|
|||||||
@@ -75,6 +75,7 @@ enum class ClangTypeKind {
|
|||||||
/// from Clang ASTs over to Swift ASTs.
|
/// from Clang ASTs over to Swift ASTs.
|
||||||
class ClangImporter final : public ClangModuleLoader {
|
class ClangImporter final : public ClangModuleLoader {
|
||||||
friend class ClangModuleUnit;
|
friend class ClangModuleUnit;
|
||||||
|
friend class DWARFImporter;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
class Implementation;
|
class Implementation;
|
||||||
@@ -160,15 +161,15 @@ public:
|
|||||||
/// Look for declarations associated with the given name.
|
/// Look for declarations associated with the given name.
|
||||||
///
|
///
|
||||||
/// \param name The name we're searching for.
|
/// \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.
|
/// Look up a type declaration by its Clang name.
|
||||||
///
|
///
|
||||||
/// Note that this method does no filtering. If it finds the type in a loaded
|
/// 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
|
/// module, it returns it. This is intended for use in reflection / debugging
|
||||||
/// contexts where access is not a problem.
|
/// contexts where access is not a problem.
|
||||||
void lookupTypeDecl(StringRef clangName, ClangTypeKind kind,
|
void lookupTypeDecl(StringRef clangName, Demangle::Node::Kind kind,
|
||||||
llvm::function_ref<void(TypeDecl*)> receiver);
|
llvm::function_ref<void(TypeDecl*)> receiver) override;
|
||||||
|
|
||||||
/// Look up type a declaration synthesized by the Clang importer itself, using
|
/// 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,
|
/// 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
|
/// 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
|
/// module, it returns it. This is intended for use in reflection / debugging
|
||||||
/// contexts where access is not a problem.
|
/// contexts where access is not a problem.
|
||||||
void lookupRelatedEntity(StringRef clangName, ClangTypeKind kind,
|
void
|
||||||
StringRef relatedEntityKind,
|
lookupRelatedEntity(StringRef clangName, StringRef relatedEntityKind,
|
||||||
llvm::function_ref<void(TypeDecl*)> receiver);
|
llvm::function_ref<void(TypeDecl *)> receiver) override;
|
||||||
|
|
||||||
/// Look for textually included declarations from the bridging header.
|
/// Look for textually included declarations from the bridging header.
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -18,6 +18,8 @@
|
|||||||
#define SWIFT_DWARF_IMPORTER_H
|
#define SWIFT_DWARF_IMPORTER_H
|
||||||
|
|
||||||
#include "swift/AST/ClangModuleLoader.h"
|
#include "swift/AST/ClangModuleLoader.h"
|
||||||
|
#include "swift/AST/Module.h"
|
||||||
|
#include "swift/Demangling/Demangle.h"
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
}
|
}
|
||||||
@@ -27,6 +29,25 @@ namespace clang {
|
|||||||
|
|
||||||
namespace swift {
|
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
|
/// Class that imports Clang modules into Swift, mapping directly
|
||||||
/// from Clang ASTs over to Swift ASTs.
|
/// from Clang ASTs over to Swift ASTs.
|
||||||
class DWARFImporter final : public ClangModuleLoader {
|
class DWARFImporter final : public ClangModuleLoader {
|
||||||
@@ -39,6 +60,7 @@ private:
|
|||||||
Implementation &Impl;
|
Implementation &Impl;
|
||||||
|
|
||||||
DWARFImporter(ASTContext &ctx, const ClangImporterOptions &clangImporterOpts,
|
DWARFImporter(ASTContext &ctx, const ClangImporterOptions &clangImporterOpts,
|
||||||
|
std::unique_ptr<DWARFImporterDelegate> delegate,
|
||||||
DependencyTracker *tracker);
|
DependencyTracker *tracker);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -55,8 +77,8 @@ public:
|
|||||||
/// \returns a new DWARF module importer, or null (with a diagnostic) if
|
/// \returns a new DWARF module importer, or null (with a diagnostic) if
|
||||||
/// an error occurred.
|
/// an error occurred.
|
||||||
static std::unique_ptr<DWARFImporter>
|
static std::unique_ptr<DWARFImporter>
|
||||||
create(ASTContext &ctx,
|
create(ASTContext &ctx, const ClangImporterOptions &importerOpts,
|
||||||
const ClangImporterOptions &importerOpts,
|
std::unique_ptr<DWARFImporterDelegate> delegate = {},
|
||||||
DependencyTracker *tracker = nullptr);
|
DependencyTracker *tracker = nullptr);
|
||||||
|
|
||||||
DWARFImporter(const DWARFImporter &) = delete;
|
DWARFImporter(const DWARFImporter &) = delete;
|
||||||
@@ -80,6 +102,17 @@ public:
|
|||||||
ModuleDecl *
|
ModuleDecl *
|
||||||
loadModule(SourceLoc importLoc,
|
loadModule(SourceLoc importLoc,
|
||||||
ArrayRef<std::pair<Identifier, SourceLoc>> path) override;
|
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
|
bool
|
||||||
isInOverlayModuleForImportedModule(const DeclContext *overlayDC,
|
isInOverlayModuleForImportedModule(const DeclContext *overlayDC,
|
||||||
const DeclContext *importedDC) override;
|
const DeclContext *importedDC) override;
|
||||||
|
|||||||
@@ -255,6 +255,9 @@ FOR_KNOWN_FOUNDATION_TYPES(CACHE_FOUNDATION_DECL)
|
|||||||
/// The module loader used to load Clang modules.
|
/// The module loader used to load Clang modules.
|
||||||
ClangModuleLoader *TheClangModuleLoader = nullptr;
|
ClangModuleLoader *TheClangModuleLoader = nullptr;
|
||||||
|
|
||||||
|
/// The module loader used to load Clang modules from DWARF.
|
||||||
|
ClangModuleLoader *TheDWARFModuleLoader = nullptr;
|
||||||
|
|
||||||
/// Map from Swift declarations to raw comments.
|
/// Map from Swift declarations to raw comments.
|
||||||
llvm::DenseMap<const Decl *, RawComment> RawComments;
|
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,
|
void ASTContext::addModuleLoader(std::unique_ptr<ModuleLoader> loader,
|
||||||
bool IsClang) {
|
bool IsClang, bool IsDwarf) {
|
||||||
if (IsClang && !getImpl().TheClangModuleLoader)
|
if (IsClang && !IsDwarf && !getImpl().TheClangModuleLoader)
|
||||||
getImpl().TheClangModuleLoader =
|
getImpl().TheClangModuleLoader =
|
||||||
static_cast<ClangModuleLoader *>(loader.get());
|
static_cast<ClangModuleLoader *>(loader.get());
|
||||||
|
if (IsClang && IsDwarf && !getImpl().TheDWARFModuleLoader)
|
||||||
|
getImpl().TheDWARFModuleLoader =
|
||||||
|
static_cast<ClangModuleLoader *>(loader.get());
|
||||||
|
|
||||||
getImpl().ModuleLoaders.push_back(std::move(loader));
|
getImpl().ModuleLoaders.push_back(std::move(loader));
|
||||||
}
|
}
|
||||||
@@ -1493,6 +1499,10 @@ ClangModuleLoader *ASTContext::getClangModuleLoader() const {
|
|||||||
return getImpl().TheClangModuleLoader;
|
return getImpl().TheClangModuleLoader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ClangModuleLoader *ASTContext::getDWARFModuleLoader() const {
|
||||||
|
return getImpl().TheDWARFModuleLoader;
|
||||||
|
}
|
||||||
|
|
||||||
ModuleDecl *ASTContext::getLoadedModule(
|
ModuleDecl *ASTContext::getLoadedModule(
|
||||||
ArrayRef<std::pair<Identifier, SourceLoc>> ModulePath) const {
|
ArrayRef<std::pair<Identifier, SourceLoc>> ModulePath) const {
|
||||||
assert(!ModulePath.empty());
|
assert(!ModulePath.empty());
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
#include "swift/AST/ASTDemangler.h"
|
#include "swift/AST/ASTDemangler.h"
|
||||||
|
|
||||||
#include "swift/AST/ASTContext.h"
|
#include "swift/AST/ASTContext.h"
|
||||||
|
#include "swift/AST/ClangModuleLoader.h"
|
||||||
#include "swift/AST/Decl.h"
|
#include "swift/AST/Decl.h"
|
||||||
#include "swift/AST/GenericSignature.h"
|
#include "swift/AST/GenericSignature.h"
|
||||||
#include "swift/AST/GenericSignatureBuilder.h"
|
#include "swift/AST/GenericSignatureBuilder.h"
|
||||||
@@ -29,7 +30,6 @@
|
|||||||
#include "swift/AST/NameLookup.h"
|
#include "swift/AST/NameLookup.h"
|
||||||
#include "swift/AST/Type.h"
|
#include "swift/AST/Type.h"
|
||||||
#include "swift/AST/Types.h"
|
#include "swift/AST/Types.h"
|
||||||
#include "swift/ClangImporter/ClangImporter.h"
|
|
||||||
#include "swift/Demangling/Demangler.h"
|
#include "swift/Demangling/Demangler.h"
|
||||||
#include "swift/Demangling/ManglingMacros.h"
|
#include "swift/Demangling/ManglingMacros.h"
|
||||||
|
|
||||||
@@ -1023,31 +1023,14 @@ ASTBuilder::findTypeDecl(DeclContext *dc,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Optional<ClangTypeKind>
|
GenericTypeDecl *ASTBuilder::findForeignTypeDecl(StringRef name,
|
||||||
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,
|
StringRef relatedEntityKind,
|
||||||
ForeignModuleKind foreignKind,
|
ForeignModuleKind foreignKind,
|
||||||
Demangle::Node::Kind kind) {
|
Demangle::Node::Kind kind) {
|
||||||
// Check to see if we have an importer loaded.
|
// Check to see if we have an importer loaded.
|
||||||
auto importer = static_cast<ClangImporter *>(Ctx.getClangModuleLoader());
|
auto importer = Ctx.getClangModuleLoader();
|
||||||
if (!importer) return nullptr;
|
if (!importer)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
// Find the unique declaration that has the right kind.
|
// Find the unique declaration that has the right kind.
|
||||||
struct Consumer : VisibleDeclConsumer {
|
struct Consumer : VisibleDeclConsumer {
|
||||||
@@ -1059,8 +1042,10 @@ ASTBuilder::findForeignTypeDecl(StringRef name,
|
|||||||
|
|
||||||
void foundDecl(ValueDecl *decl, DeclVisibilityKind reason,
|
void foundDecl(ValueDecl *decl, DeclVisibilityKind reason,
|
||||||
DynamicLookupInfo dynamicLookupInfo = {}) override {
|
DynamicLookupInfo dynamicLookupInfo = {}) override {
|
||||||
if (HadError) return;
|
if (HadError)
|
||||||
if (decl == Result) return;
|
return;
|
||||||
|
if (decl == Result)
|
||||||
|
return;
|
||||||
if (!Result) {
|
if (!Result) {
|
||||||
Result = dyn_cast<GenericTypeDecl>(decl);
|
Result = dyn_cast<GenericTypeDecl>(decl);
|
||||||
HadError |= !Result;
|
HadError |= !Result;
|
||||||
@@ -1071,33 +1056,27 @@ ASTBuilder::findForeignTypeDecl(StringRef name,
|
|||||||
}
|
}
|
||||||
} consumer(kind);
|
} consumer(kind);
|
||||||
|
|
||||||
|
auto found = [&](TypeDecl *found) {
|
||||||
|
consumer.foundDecl(found, DeclVisibilityKind::VisibleAtTopLevel);
|
||||||
|
};
|
||||||
|
|
||||||
switch (foreignKind) {
|
switch (foreignKind) {
|
||||||
case ForeignModuleKind::SynthesizedByImporter:
|
case ForeignModuleKind::SynthesizedByImporter:
|
||||||
if (!relatedEntityKind.empty()) {
|
if (!relatedEntityKind.empty()) {
|
||||||
Optional<ClangTypeKind> lookupKind = getClangTypeKindForNodeKind(kind);
|
importer->lookupRelatedEntity(name, relatedEntityKind, found);
|
||||||
if (!lookupKind)
|
|
||||||
return nullptr;
|
|
||||||
importer->lookupRelatedEntity(name, lookupKind.getValue(),
|
|
||||||
relatedEntityKind, [&](TypeDecl *found) {
|
|
||||||
consumer.foundDecl(found, DeclVisibilityKind::VisibleAtTopLevel);
|
|
||||||
});
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
importer->lookupValue(Ctx.getIdentifier(name), consumer);
|
importer->lookupValue(Ctx.getIdentifier(name), consumer);
|
||||||
if (consumer.Result) {
|
if (consumer.Result)
|
||||||
consumer.Result =
|
consumer.Result = getAcceptableTypeDeclCandidate(consumer.Result, kind);
|
||||||
getAcceptableTypeDeclCandidate(consumer.Result,kind);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case ForeignModuleKind::Imported: {
|
case ForeignModuleKind::Imported:
|
||||||
Optional<ClangTypeKind> lookupKind = getClangTypeKindForNodeKind(kind);
|
importer->lookupTypeDecl(name, kind, found);
|
||||||
if (!lookupKind)
|
|
||||||
return nullptr;
|
// Try the DWARFImporter if it exists.
|
||||||
importer->lookupTypeDecl(name, lookupKind.getValue(),
|
if (!consumer.Result)
|
||||||
[&](TypeDecl *found) {
|
if (auto *dwarf_importer = Ctx.getDWARFModuleLoader())
|
||||||
consumer.foundDecl(found, DeclVisibilityKind::VisibleAtTopLevel);
|
dwarf_importer->lookupTypeDecl(name, kind, found);
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return consumer.Result;
|
return consumer.Result;
|
||||||
|
|||||||
@@ -33,6 +33,7 @@
|
|||||||
#include "swift/Basic/StringExtras.h"
|
#include "swift/Basic/StringExtras.h"
|
||||||
#include "swift/Basic/Version.h"
|
#include "swift/Basic/Version.h"
|
||||||
#include "swift/ClangImporter/ClangImporterOptions.h"
|
#include "swift/ClangImporter/ClangImporterOptions.h"
|
||||||
|
#include "swift/Demangling/Demangle.h"
|
||||||
#include "swift/Parse/Lexer.h"
|
#include "swift/Parse/Lexer.h"
|
||||||
#include "swift/Parse/Parser.h"
|
#include "swift/Parse/Parser.h"
|
||||||
#include "swift/Config.h"
|
#include "swift/Config.h"
|
||||||
@@ -2494,14 +2495,34 @@ void ClangImporter::lookupValue(DeclName name, VisibleDeclConsumer &consumer){
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static Optional<ClangTypeKind>
|
||||||
ClangImporter::lookupTypeDecl(StringRef rawName, ClangTypeKind kind,
|
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) {
|
llvm::function_ref<void(TypeDecl *)> receiver) {
|
||||||
clang::DeclarationName clangName(
|
clang::DeclarationName clangName(
|
||||||
&Impl.Instance->getASTContext().Idents.get(rawName));
|
&Impl.Instance->getASTContext().Idents.get(rawName));
|
||||||
|
|
||||||
clang::Sema::LookupNameKind lookupKind;
|
clang::Sema::LookupNameKind lookupKind;
|
||||||
switch (kind) {
|
auto clang_kind = getClangTypeKindForNodeKind(kind);
|
||||||
|
if (!clang_kind)
|
||||||
|
return;
|
||||||
|
switch (*clang_kind) {
|
||||||
case ClangTypeKind::Typedef:
|
case ClangTypeKind::Typedef:
|
||||||
lookupKind = clang::Sema::LookupOrdinaryName;
|
lookupKind = clang::Sema::LookupOrdinaryName;
|
||||||
break;
|
break;
|
||||||
@@ -2532,17 +2553,17 @@ ClangImporter::lookupTypeDecl(StringRef rawName, ClangTypeKind kind,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ClangImporter::lookupRelatedEntity(
|
void ClangImporter::lookupRelatedEntity(
|
||||||
StringRef rawName, ClangTypeKind kind, StringRef relatedEntityKind,
|
StringRef rawName, StringRef relatedEntityKind,
|
||||||
llvm::function_ref<void(TypeDecl *)> receiver) {
|
llvm::function_ref<void(TypeDecl *)> receiver) {
|
||||||
using CISTAttr = ClangImporterSynthesizedTypeAttr;
|
using CISTAttr = ClangImporterSynthesizedTypeAttr;
|
||||||
if (relatedEntityKind ==
|
if (relatedEntityKind ==
|
||||||
CISTAttr::manglingNameForKind(CISTAttr::Kind::NSErrorWrapper) ||
|
CISTAttr::manglingNameForKind(CISTAttr::Kind::NSErrorWrapper) ||
|
||||||
relatedEntityKind ==
|
relatedEntityKind ==
|
||||||
CISTAttr::manglingNameForKind(CISTAttr::Kind::NSErrorWrapperAnon)) {
|
CISTAttr::manglingNameForKind(CISTAttr::Kind::NSErrorWrapperAnon)) {
|
||||||
auto underlyingKind = ClangTypeKind::Tag;
|
auto underlyingKind = Demangle::Node::Kind::Structure;
|
||||||
if (relatedEntityKind ==
|
if (relatedEntityKind ==
|
||||||
CISTAttr::manglingNameForKind(CISTAttr::Kind::NSErrorWrapperAnon)) {
|
CISTAttr::manglingNameForKind(CISTAttr::Kind::NSErrorWrapperAnon)) {
|
||||||
underlyingKind = ClangTypeKind::Typedef;
|
underlyingKind = Demangle::Node::Kind::TypeAlias;
|
||||||
}
|
}
|
||||||
lookupTypeDecl(rawName, underlyingKind,
|
lookupTypeDecl(rawName, underlyingKind,
|
||||||
[this, receiver] (const TypeDecl *foundType) {
|
[this, receiver] (const TypeDecl *foundType) {
|
||||||
|
|||||||
@@ -318,6 +318,7 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation
|
|||||||
public LazyConformanceLoader
|
public LazyConformanceLoader
|
||||||
{
|
{
|
||||||
friend class ClangImporter;
|
friend class ClangImporter;
|
||||||
|
friend class DWARFImporter;
|
||||||
using Version = importer::ImportNameVersion;
|
using Version = importer::ImportNameVersion;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -13,15 +13,18 @@
|
|||||||
#include "swift/DWARFImporter/DWARFImporter.h"
|
#include "swift/DWARFImporter/DWARFImporter.h"
|
||||||
#include "swift/AST/ASTContext.h"
|
#include "swift/AST/ASTContext.h"
|
||||||
#include "swift/AST/Module.h"
|
#include "swift/AST/Module.h"
|
||||||
|
#include "clang/CodeGen/ObjectFilePCHContainerOperations.h"
|
||||||
|
#include "clang/Frontend/FrontendActions.h"
|
||||||
|
#include "../ClangImporter/ImporterImpl.h"
|
||||||
|
|
||||||
using namespace swift;
|
using namespace swift;
|
||||||
|
|
||||||
std::unique_ptr<DWARFImporter>
|
std::unique_ptr<DWARFImporter>
|
||||||
DWARFImporter::create(ASTContext &ctx,
|
DWARFImporter::create(ASTContext &ctx, const ClangImporterOptions &importerOpts,
|
||||||
const ClangImporterOptions &importerOpts,
|
std::unique_ptr<DWARFImporterDelegate> delegate,
|
||||||
DependencyTracker *tracker) {
|
DependencyTracker *tracker) {
|
||||||
std::unique_ptr<DWARFImporter> importer{
|
std::unique_ptr<DWARFImporter> importer{
|
||||||
new DWARFImporter(ctx, importerOpts, tracker)
|
new DWARFImporter(ctx, importerOpts, std::move(delegate), tracker)
|
||||||
};
|
};
|
||||||
return importer;
|
return importer;
|
||||||
}
|
}
|
||||||
@@ -29,17 +32,18 @@ DWARFImporter::create(ASTContext &ctx,
|
|||||||
class DWARFModuleUnit final : public LoadedFile {
|
class DWARFModuleUnit final : public LoadedFile {
|
||||||
|
|
||||||
~DWARFModuleUnit() = default;
|
~DWARFModuleUnit() = default;
|
||||||
|
DWARFImporter::Implementation &owner;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DWARFModuleUnit(ModuleDecl &M)
|
DWARFModuleUnit(ModuleDecl &M, DWARFImporter::Implementation &owner)
|
||||||
: LoadedFile(FileUnitKind::DWARFModule, M) {}
|
: LoadedFile(FileUnitKind::DWARFModule, M), owner(owner) {}
|
||||||
|
|
||||||
virtual bool isSystemModule() const override { return false; }
|
virtual bool isSystemModule() const override { return false; }
|
||||||
|
|
||||||
virtual void
|
virtual void
|
||||||
lookupValue(ModuleDecl::AccessPathTy accessPath, DeclName name,
|
lookupValue(ModuleDecl::AccessPathTy accessPath, DeclName name,
|
||||||
NLKind lookupKind,
|
NLKind lookupKind,
|
||||||
SmallVectorImpl<ValueDecl *> &results) const override {}
|
SmallVectorImpl<ValueDecl *> &results) const override;
|
||||||
|
|
||||||
virtual TypeDecl *
|
virtual TypeDecl *
|
||||||
lookupNestedType(Identifier name,
|
lookupNestedType(Identifier name,
|
||||||
@@ -101,14 +105,17 @@ public:
|
|||||||
class DWARFImporter::Implementation {
|
class DWARFImporter::Implementation {
|
||||||
public:
|
public:
|
||||||
ASTContext &SwiftContext;
|
ASTContext &SwiftContext;
|
||||||
clang::ASTContext *ClangASTContext = nullptr;
|
|
||||||
clang::CompilerInstance *Instance = nullptr;
|
std::unique_ptr<DWARFImporterDelegate> delegate;
|
||||||
clang::Preprocessor *PP = nullptr;
|
ClangImporter &clangImporter;
|
||||||
clang::Sema *Sema = nullptr;
|
|
||||||
|
|
||||||
llvm::DenseMap<Identifier, DWARFModuleUnit *> ModuleWrappers;
|
llvm::DenseMap<Identifier, DWARFModuleUnit *> ModuleWrappers;
|
||||||
Implementation(ASTContext &ctx, const ClangImporterOptions &clangImporterOpts)
|
Implementation(ASTContext &ctx, const ClangImporterOptions &clangImporterOpts,
|
||||||
: SwiftContext(ctx) {}
|
std::unique_ptr<DWARFImporterDelegate> delegate,
|
||||||
|
DependencyTracker *tracker)
|
||||||
|
: SwiftContext(ctx), delegate(std::move(delegate)),
|
||||||
|
clangImporter(
|
||||||
|
*static_cast<ClangImporter *>(ctx.getClangModuleLoader())) {}
|
||||||
|
|
||||||
ModuleDecl *loadModule(SourceLoc importLoc,
|
ModuleDecl *loadModule(SourceLoc importLoc,
|
||||||
ArrayRef<std::pair<Identifier, SourceLoc>> path) {
|
ArrayRef<std::pair<Identifier, SourceLoc>> path) {
|
||||||
@@ -122,22 +129,95 @@ public:
|
|||||||
auto *decl = ModuleDecl::create(name, SwiftContext);
|
auto *decl = ModuleDecl::create(name, SwiftContext);
|
||||||
decl->setIsNonSwiftModule();
|
decl->setIsNonSwiftModule();
|
||||||
decl->setHasResolvedImports();
|
decl->setHasResolvedImports();
|
||||||
auto wrapperUnit = new (SwiftContext) DWARFModuleUnit(*decl);
|
auto wrapperUnit = new (SwiftContext) DWARFModuleUnit(*decl, *this);
|
||||||
ModuleWrappers.insert({name, wrapperUnit});
|
ModuleWrappers.insert({name, wrapperUnit});
|
||||||
decl->addFile(*wrapperUnit);
|
decl->addFile(*wrapperUnit);
|
||||||
|
|
||||||
// Force load overlay modules for all imported modules.
|
// Force load overlay modules for all imported modules.
|
||||||
decl->forAllVisibleModules({}, [](ModuleDecl::ImportedModule import) {});
|
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;
|
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,
|
DWARFImporter::DWARFImporter(ASTContext &ctx,
|
||||||
const ClangImporterOptions &clangImporterOpts,
|
const ClangImporterOptions &clangImporterOpts,
|
||||||
|
std::unique_ptr<DWARFImporterDelegate> delegate,
|
||||||
DependencyTracker *tracker)
|
DependencyTracker *tracker)
|
||||||
: ClangModuleLoader(tracker),
|
: ClangModuleLoader(tracker),
|
||||||
Impl(*new Implementation(ctx, clangImporterOpts)) {}
|
Impl(*new Implementation(ctx, clangImporterOpts, std::move(delegate),
|
||||||
|
tracker)) {}
|
||||||
|
|
||||||
DWARFImporter::~DWARFImporter() { delete &Impl; }
|
DWARFImporter::~DWARFImporter() { delete &Impl; }
|
||||||
|
|
||||||
@@ -159,6 +239,22 @@ DWARFImporter::loadModule(SourceLoc importLoc,
|
|||||||
return Impl.loadModule(importLoc, path);
|
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(
|
bool DWARFImporter::isInOverlayModuleForImportedModule(
|
||||||
const DeclContext *overlayDC, const DeclContext *importedDC) {
|
const DeclContext *overlayDC, const DeclContext *importedDC) {
|
||||||
return false;
|
return false;
|
||||||
@@ -177,14 +273,14 @@ ModuleDecl *DWARFImporter::getImportedHeaderModule() const { return nullptr; }
|
|||||||
void DWARFImporter::verifyAllModules() {};
|
void DWARFImporter::verifyAllModules() {};
|
||||||
|
|
||||||
clang::ASTContext &DWARFImporter::getClangASTContext() const {
|
clang::ASTContext &DWARFImporter::getClangASTContext() const {
|
||||||
return *Impl.ClangASTContext;
|
return Impl.getClangASTContext();
|
||||||
}
|
}
|
||||||
clang::Preprocessor &DWARFImporter::getClangPreprocessor() const {
|
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 {
|
const clang::CompilerInstance &DWARFImporter::getClangInstance() const {
|
||||||
return *Impl.Instance;
|
return Impl.getClangInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DWARFImporter::printStatistics() const {}
|
void DWARFImporter::printStatistics() const {}
|
||||||
|
|||||||
@@ -380,7 +380,7 @@ bool CompilerInstance::setUpModuleLoaders() {
|
|||||||
if (Invocation.getLangOptions().EnableDWARFImporter) {
|
if (Invocation.getLangOptions().EnableDWARFImporter) {
|
||||||
auto dwarfImporter =
|
auto dwarfImporter =
|
||||||
DWARFImporter::create(*Context, Invocation.getClangImporterOptions(),
|
DWARFImporter::create(*Context, Invocation.getClangImporterOptions(),
|
||||||
getDependencyTracker());
|
nullptr, getDependencyTracker());
|
||||||
if (!dwarfImporter) {
|
if (!dwarfImporter) {
|
||||||
Diagnostics.diagnose(SourceLoc(), diag::error_clang_importer_create_fail);
|
Diagnostics.diagnose(SourceLoc(), diag::error_clang_importer_create_fail);
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ add_swift_host_tool(sil-passpipeline-dumper
|
|||||||
target_link_libraries(sil-passpipeline-dumper
|
target_link_libraries(sil-passpipeline-dumper
|
||||||
PRIVATE
|
PRIVATE
|
||||||
swiftClangImporter
|
swiftClangImporter
|
||||||
swiftDWARFImporter
|
|
||||||
swiftFrontend
|
swiftFrontend
|
||||||
swiftSerialization
|
swiftSerialization
|
||||||
swiftSILGen
|
swiftSILGen
|
||||||
|
|||||||
Reference in New Issue
Block a user