Skip to content

Commit deddadc

Browse files
authored
Merge pull request #2065 from swiftwasm/main
[pull] swiftwasm from main
2 parents 143836e + f0f2246 commit deddadc

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+996
-190
lines changed

docs/ABI/Mangling.rst

+8-1
Original file line numberDiff line numberDiff line change
@@ -523,15 +523,20 @@ Types
523523
FUNCTION-KIND ::= 'U' // uncurried function type (currently not used)
524524
FUNCTION-KIND ::= 'K' // @auto_closure function type (noescape)
525525
FUNCTION-KIND ::= 'B' // objc block function type
526-
FUNCTION-KIND ::= 'L' // objc block function type (escaping) (DWARF only; otherwise use 'B')
526+
FUNCTION-KIND ::= 'zB' C-TYPE // objc block type with non-canonical C type
527+
FUNCTION-KIND ::= 'L' // objc block function type with canonical C type (escaping) (DWARF only; otherwise use 'B' or 'zB' C-TYPE)
527528
FUNCTION-KIND ::= 'C' // C function pointer type
529+
FUNCTION-KIND ::= 'zC' C-TYPE // C function pointer type with with non-canonical C type
528530
FUNCTION-KIND ::= 'A' // @auto_closure function type (escaping)
529531
FUNCTION-KIND ::= 'E' // function type (noescape)
530532
FUNCTION-KIND ::= 'F' // @differentiable function type
531533
FUNCTION-KIND ::= 'G' // @differentiable function type (escaping)
532534
FUNCTION-KIND ::= 'H' // @differentiable(linear) function type
533535
FUNCTION-KIND ::= 'I' // @differentiable(linear) function type (escaping)
534536

537+
C-TYPE is mangled according to the Itanium ABI, and prefixed with the length.
538+
Non-ASCII identifiers are preserved as-is; we do not use Punycode.
539+
535540
function-signature ::= params-type params-type async? throws? // results and parameters
536541

537542
params-type ::= type 'z'? 'h'? // tuple in case of multiple parameters or a single parameter with a single tuple type
@@ -618,7 +623,9 @@ mangled in to disambiguate.
618623
CALLEE-CONVENTION ::= 't' // thin
619624

620625
FUNC-REPRESENTATION ::= 'B' // C block invocation function
626+
FUNC-REPRESENTATION ::= 'zB' C-TYPE // C block invocation function with non-canonical C type
621627
FUNC-REPRESENTATION ::= 'C' // C global function
628+
FUNC-REPRESENTATION ::= 'zC' C-TYPE // C global function with non-canonical C type
622629
FUNC-REPRESENTATION ::= 'M' // Swift method
623630
FUNC-REPRESENTATION ::= 'J' // ObjC method
624631
FUNC-REPRESENTATION ::= 'K' // closure

include/swift/AST/ASTContext.h

+9-1
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,12 @@
2323
#include "swift/AST/Import.h"
2424
#include "swift/AST/SearchPathOptions.h"
2525
#include "swift/AST/Type.h"
26-
#include "swift/AST/Types.h"
2726
#include "swift/AST/TypeAlignments.h"
27+
#include "swift/AST/Types.h"
2828
#include "swift/Basic/LangOptions.h"
2929
#include "swift/Basic/Located.h"
3030
#include "swift/Basic/Malloc.h"
31+
#include "clang/AST/DeclTemplate.h"
3132
#include "llvm/ADT/ArrayRef.h"
3233
#include "llvm/ADT/DenseMap.h"
3334
#include "llvm/ADT/IntrusiveRefCntPtr.h"
@@ -628,6 +629,13 @@ class ASTContext final {
628629
ArrayRef<SILParameterInfo> params, Optional<SILResultInfo> result,
629630
SILFunctionType::Representation trueRep);
630631

632+
/// Instantiates "Impl.Converter" if needed, then calls
633+
/// ClangTypeConverter::getClangTemplateArguments.
634+
std::unique_ptr<TemplateInstantiationError> getClangTemplateArguments(
635+
const clang::TemplateParameterList *templateParams,
636+
ArrayRef<Type> genericArgs,
637+
SmallVectorImpl<clang::TemplateArgument> &templateArgs);
638+
631639
/// Get the Swift declaration that a Clang declaration was exported from,
632640
/// if applicable.
633641
const Decl *getSwiftDeclForExportedClangDecl(const clang::Decl *decl);

include/swift/AST/ASTMangler.h

+3
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,9 @@ class ASTMangler : public Mangler {
318318
const ValueDecl *forDecl = nullptr);
319319
void appendFunctionType(AnyFunctionType *fn, bool isAutoClosure = false,
320320
const ValueDecl *forDecl = nullptr);
321+
void appendClangType(AnyFunctionType *fn);
322+
template <typename FnType>
323+
void appendClangType(FnType *fn, llvm::raw_svector_ostream &os);
321324

322325
void appendFunctionSignature(AnyFunctionType *fn,
323326
const ValueDecl *forDecl = nullptr);

include/swift/AST/ClangModuleLoader.h

+14
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@
1414
#define SWIFT_AST_CLANG_MODULE_LOADER_H
1515

1616
#include "swift/AST/ModuleLoader.h"
17+
#include "swift/AST/SubstitutionMap.h"
1718
#include "swift/Basic/TaggedUnion.h"
19+
#include "clang/AST/DeclTemplate.h"
1820

1921
namespace clang {
2022
class ASTContext;
@@ -219,6 +221,18 @@ class ClangModuleLoader : public ModuleLoader {
219221
/// based on subtleties like the target module interface format.
220222
virtual bool isSerializable(const clang::Type *type,
221223
bool checkCanonical) const = 0;
224+
225+
virtual clang::FunctionDecl *
226+
instantiateCXXFunctionTemplate(ASTContext &ctx,
227+
clang::FunctionTemplateDecl *func,
228+
SubstitutionMap subst) = 0;
229+
};
230+
231+
/// Used to describe a template instantiation error.
232+
struct TemplateInstantiationError {
233+
/// Generic types that could not be converted to QualTypes using the
234+
/// ClangTypeConverter.
235+
SmallVector<Type, 4> failedTypes;
222236
};
223237

224238
} // namespace swift

include/swift/AST/Decl.h

+4-3
Original file line numberDiff line numberDiff line change
@@ -5960,9 +5960,10 @@ class FuncDecl : public AbstractFunctionDecl {
59605960
DeclContext *Parent);
59615961

59625962
static FuncDecl *createImported(ASTContext &Context, SourceLoc FuncLoc,
5963-
DeclName Name, SourceLoc NameLoc,
5964-
bool Async, bool Throws,
5965-
ParameterList *BodyParams, Type FnRetType,
5963+
DeclName Name, SourceLoc NameLoc, bool Async,
5964+
bool Throws, ParameterList *BodyParams,
5965+
Type FnRetType,
5966+
GenericParamList *GenericParams,
59665967
DeclContext *Parent, ClangNode ClangN);
59675968

59685969
bool isStatic() const;

include/swift/AST/DiagnosticsSema.def

+5
Original file line numberDiff line numberDiff line change
@@ -1674,6 +1674,11 @@ ERROR(where_nongeneric_ctx,none,
16741674
ERROR(where_nongeneric_toplevel,none,
16751675
"'where' clause cannot be applied to a non-generic top-level "
16761676
"declaration", ())
1677+
ERROR(unable_to_convert_generic_swift_types,none,
1678+
"could not generate C++ types from the generic Swift types provided. "
1679+
"The following Swift type(s) provided to '%0' were unable to be "
1680+
"converted: %1.",
1681+
(StringRef, StringRef))
16771682

16781683
// Type aliases
16791684
ERROR(type_alias_underlying_type_access,none,

include/swift/AST/ExtInfo.h

+1
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ class ClangTypeInfo {
7070
constexpr ClangTypeInfo(const clang::Type *type) : type(type) {}
7171

7272
friend bool operator==(ClangTypeInfo lhs, ClangTypeInfo rhs);
73+
friend bool operator!=(ClangTypeInfo lhs, ClangTypeInfo rhs);
7374
ClangTypeInfo getCanonical() const;
7475

7576
public:

include/swift/AST/Types.h

+23
Original file line numberDiff line numberDiff line change
@@ -2926,6 +2926,24 @@ class AnyFunctionType : public TypeBase {
29262926
ClangTypeInfo getClangTypeInfo() const;
29272927
ClangTypeInfo getCanonicalClangTypeInfo() const;
29282928

2929+
/// Returns true if the function type stores a Clang type that cannot
2930+
/// be derived from its Swift type. Returns false otherwise, including if
2931+
/// the function type is not @convention(c) or @convention(block).
2932+
///
2933+
/// For example, if you have a function pointer from C getting imported with
2934+
/// the following type:
2935+
///
2936+
/// @convention(c, cType: "void (*)(size_t (*)(size_t))")
2937+
/// (@convention(c, cType: "size_t (*)(size_t)") (Int) -> Int)) -> Void
2938+
///
2939+
/// The parameter's function type will have hasNonDerivableClangType() = true,
2940+
/// but the outer function type will have hasNonDerivableClangType() = false,
2941+
/// because the parameter and result type are sufficient to correctly derive
2942+
/// the Clang type for the outer function type. In terms of mangling,
2943+
/// the parameter type's mangling will incorporate the Clang type but the
2944+
/// outer function type's mangling doesn't need to duplicate that information.
2945+
bool hasNonDerivableClangType();
2946+
29292947
ExtInfo getExtInfo() const {
29302948
return ExtInfo(Bits.AnyFunctionType.ExtInfoBits, getClangTypeInfo());
29312949
}
@@ -4307,6 +4325,11 @@ class SILFunctionType final
43074325

43084326
ClangTypeInfo getClangTypeInfo() const;
43094327

4328+
/// Returns true if the function type stores a Clang type that cannot
4329+
/// be derived from its Swift type. Returns false otherwise, including if
4330+
/// the function type is not @convention(c) or @convention(block).
4331+
bool hasNonDerivableClangType();
4332+
43104333
bool hasSameExtInfoAs(const SILFunctionType *otherFn);
43114334

43124335
/// Given that `this` is a `@differentiable` or `@differentiable(linear)`

include/swift/ClangImporter/ClangImporter.h

+5
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,11 @@ class ClangImporter final : public ClangModuleLoader {
472472

473473
bool isSerializable(const clang::Type *type,
474474
bool checkCanonical) const override;
475+
476+
clang::FunctionDecl *
477+
instantiateCXXFunctionTemplate(ASTContext &ctx,
478+
clang::FunctionTemplateDecl *func,
479+
SubstitutionMap subst) override;
475480
};
476481

477482
ImportDecl *createImportDecl(ASTContext &Ctx, DeclContext *DC, ClangNode ClangN,

include/swift/Demangling/DemangleNodes.def

+3
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ NODE(BoundGenericTypeAlias)
4444
NODE(BoundGenericFunction)
4545
NODE(BuiltinTypeName)
4646
NODE(CFunctionPointer)
47+
NODE(ClangType)
4748
CONTEXT_NODE(Class)
4849
NODE(ClassMetadataBaseOffset)
4950
NODE(ConcreteProtocolConformance)
@@ -120,6 +121,8 @@ NODE(ImplEscaping)
120121
NODE(ImplConvention)
121122
NODE(ImplDifferentiability)
122123
NODE(ImplFunctionAttribute)
124+
NODE(ImplFunctionConvention)
125+
NODE(ImplFunctionConventionName)
123126
NODE(ImplFunctionType)
124127
NODE(ImplInvocationSubstitutions)
125128
CONTEXT_NODE(ImplicitClosure)

include/swift/Demangling/Demangler.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -505,7 +505,7 @@ class Demangler : public NodeFactory {
505505
NodePointer demangleAnyGenericType(Node::Kind kind);
506506
NodePointer demangleExtensionContext();
507507
NodePointer demanglePlainFunction();
508-
NodePointer popFunctionType(Node::Kind kind);
508+
NodePointer popFunctionType(Node::Kind kind, bool hasClangType = false);
509509
NodePointer popFunctionParams(Node::Kind kind);
510510
NodePointer popFunctionParamLabels(NodePointer FuncType);
511511
NodePointer popTuple();
@@ -522,6 +522,7 @@ class Demangler : public NodeFactory {
522522
NodePointer demangleImplResultConvention(Node::Kind ConvKind);
523523
NodePointer demangleImplDifferentiability();
524524
NodePointer demangleImplFunctionType();
525+
NodePointer demangleClangType();
525526
NodePointer demangleMetatype();
526527
NodePointer demanglePrivateContextDescriptor();
527528
NodePointer createArchetypeRef(int depth, int i);

include/swift/Demangling/TypeDecoder.h

+24-8
Original file line numberDiff line numberDiff line change
@@ -631,6 +631,12 @@ class TypeDecoder {
631631
}
632632

633633
unsigned firstChildIdx = 0;
634+
if (Node->getChild(firstChildIdx)->getKind() == NodeKind::ClangType) {
635+
// [TODO: synthesize-Clang-type-from-mangled-name] Use the first child
636+
// to create a ClangTypeInfo.
637+
++firstChildIdx;
638+
}
639+
634640
bool isThrow = false;
635641
if (Node->getChild(firstChildIdx)->getKind()
636642
== NodeKind::ThrowsAnnotation) {
@@ -695,18 +701,28 @@ class TypeDecoder {
695701
} else if (child->getText() == "@callee_guaranteed") {
696702
calleeConvention = ImplParameterConvention::Direct_Guaranteed;
697703
}
698-
} else if (child->getKind() == NodeKind::ImplFunctionAttribute) {
699-
if (!child->hasText())
700-
return MAKE_NODE_TYPE_ERROR0(child, "expected text");
701-
702-
StringRef text = child->getText();
703-
if (text == "@convention(c)") {
704+
} else if (child->getKind() == NodeKind::ImplFunctionConvention) {
705+
if (child->getNumChildren() == 0)
706+
return MAKE_NODE_TYPE_ERROR0(child, "expected grandchildren");
707+
if ((child->getFirstChild()->getKind() !=
708+
NodeKind::ImplFunctionConventionName) ||
709+
!child->getFirstChild()->hasText())
710+
return MAKE_NODE_TYPE_ERROR0(child, "expected convention name");
711+
712+
// [TODO: synthesize-Clang-type-from-mangled-name] If there are two
713+
// grand-children, the second is going to be the mangled Clang type.
714+
StringRef text = child->getFirstChild()->getText();
715+
if (text == "c") {
704716
flags =
705717
flags.withRepresentation(ImplFunctionRepresentation::CFunctionPointer);
706-
} else if (text == "@convention(block)") {
718+
} else if (text == "block") {
707719
flags =
708720
flags.withRepresentation(ImplFunctionRepresentation::Block);
709-
} else if (text == "@async") {
721+
}
722+
} else if (child->getKind() == NodeKind::ImplFunctionAttribute) {
723+
if (!child->hasText())
724+
return MAKE_NODE_TYPE_ERROR0(child, "expected text");
725+
if (child->getText() == "@async") {
710726
flags = flags.withAsync();
711727
}
712728
} else if (child->getKind() == NodeKind::ImplDifferentiable) {

lib/AST/ASTContext.cpp

+19-4
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,13 @@
1818
#include "ClangTypeConverter.h"
1919
#include "ForeignRepresentationInfo.h"
2020
#include "SubstitutionMapStorage.h"
21-
#include "swift/AST/ForeignAsyncConvention.h"
2221
#include "swift/AST/ClangModuleLoader.h"
2322
#include "swift/AST/ConcreteDeclRef.h"
2423
#include "swift/AST/DiagnosticEngine.h"
2524
#include "swift/AST/DiagnosticsSema.h"
2625
#include "swift/AST/ExistentialLayout.h"
2726
#include "swift/AST/FileUnit.h"
27+
#include "swift/AST/ForeignAsyncConvention.h"
2828
#include "swift/AST/ForeignErrorConvention.h"
2929
#include "swift/AST/GenericEnvironment.h"
3030
#include "swift/AST/GenericSignature.h"
@@ -41,19 +41,19 @@
4141
#include "swift/AST/PropertyWrappers.h"
4242
#include "swift/AST/ProtocolConformance.h"
4343
#include "swift/AST/RawComment.h"
44+
#include "swift/AST/SILLayout.h"
4445
#include "swift/AST/SemanticAttrs.h"
4546
#include "swift/AST/SourceFile.h"
4647
#include "swift/AST/SubstitutionMap.h"
47-
#include "swift/AST/SILLayout.h"
4848
#include "swift/AST/TypeCheckRequests.h"
4949
#include "swift/Basic/Compiler.h"
5050
#include "swift/Basic/SourceManager.h"
5151
#include "swift/Basic/Statistic.h"
5252
#include "swift/Basic/StringExtras.h"
53-
#include "swift/Syntax/References.h"
54-
#include "swift/Syntax/SyntaxArena.h"
5553
#include "swift/Strings.h"
5654
#include "swift/Subsystems.h"
55+
#include "swift/Syntax/References.h"
56+
#include "swift/Syntax/SyntaxArena.h"
5757
#include "llvm/ADT/DenseMap.h"
5858
#include "llvm/ADT/Statistic.h"
5959
#include "llvm/ADT/StringMap.h"
@@ -4563,6 +4563,21 @@ ASTContext::getCanonicalClangFunctionType(
45634563
return ty ? ty->getCanonicalTypeInternal().getTypePtr() : nullptr;
45644564
}
45654565

4566+
std::unique_ptr<TemplateInstantiationError>
4567+
ASTContext::getClangTemplateArguments(
4568+
const clang::TemplateParameterList *templateParams,
4569+
ArrayRef<Type> genericArgs,
4570+
SmallVectorImpl<clang::TemplateArgument> &templateArgs) {
4571+
auto &impl = getImpl();
4572+
if (!impl.Converter) {
4573+
auto *cml = getClangModuleLoader();
4574+
impl.Converter.emplace(*this, cml->getClangASTContext(), LangOpts.Target);
4575+
}
4576+
4577+
return impl.Converter->getClangTemplateArguments(templateParams, genericArgs,
4578+
templateArgs);
4579+
}
4580+
45664581
const Decl *
45674582
ASTContext::getSwiftDeclForExportedClangDecl(const clang::Decl *decl) {
45684583
auto &impl = getImpl();

0 commit comments

Comments
 (0)