Skip to content

Commit b26ba2d

Browse files
committed
AST: Add utilities to ASTContext for looking up builtin initializers
1 parent 9d134a8 commit b26ba2d

File tree

3 files changed

+88
-19
lines changed

3 files changed

+88
-19
lines changed

include/swift/AST/ASTContext.h

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ namespace swift {
5353
class AvailabilityContext;
5454
class BoundGenericType;
5555
class ClangNode;
56+
class ConcreteDeclRef;
5657
class ConstructorDecl;
5758
class Decl;
5859
class DeclContext;
@@ -514,7 +515,20 @@ class ASTContext final {
514515
bool hasArrayLiteralIntrinsics() const;
515516

516517
/// Retrieve the declaration of Swift.Bool.init(_builtinBooleanLiteral:)
517-
ConstructorDecl *getBoolBuiltinInitDecl() const;
518+
ConcreteDeclRef getBoolBuiltinInitDecl() const;
519+
520+
/// Retrieve the witness for init(_builtinIntegerLiteral:).
521+
ConcreteDeclRef getIntBuiltinInitDecl(NominalTypeDecl *intDecl) const;
522+
523+
/// Retrieve the witness for init(_builtinFloatLiteral:).
524+
ConcreteDeclRef getFloatBuiltinInitDecl(NominalTypeDecl *floatDecl) const;
525+
526+
/// Retrieve the witness for (_builtinStringLiteral:utf8CodeUnitCount:isASCII:).
527+
ConcreteDeclRef getStringBuiltinInitDecl(NominalTypeDecl *stringDecl) const;
528+
529+
ConcreteDeclRef getBuiltinInitDecl(NominalTypeDecl *decl,
530+
KnownProtocolKind builtinProtocol,
531+
llvm::function_ref<DeclName (ASTContext &ctx)> initName) const;
518532

519533
/// Retrieve the declaration of Swift.==(Int, Int) -> Bool.
520534
FuncDecl *getEqualIntDecl() const;

include/swift/AST/KnownStdlibTypes.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ KNOWN_STDLIB_TYPE_DECL(Float80, NominalTypeDecl, 0)
4848
KNOWN_STDLIB_TYPE_DECL(_MaxBuiltinFloatType, TypeAliasDecl, 0)
4949

5050
KNOWN_STDLIB_TYPE_DECL(String, NominalTypeDecl, 0)
51+
KNOWN_STDLIB_TYPE_DECL(StaticString, NominalTypeDecl, 0)
5152
KNOWN_STDLIB_TYPE_DECL(Substring, NominalTypeDecl, 0)
5253
KNOWN_STDLIB_TYPE_DECL(Array, NominalTypeDecl, 1)
5354
KNOWN_STDLIB_TYPE_DECL(Set, NominalTypeDecl, 1)

lib/AST/ASTContext.cpp

Lines changed: 72 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -183,9 +183,6 @@ FOR_KNOWN_FOUNDATION_TYPES(CACHE_FOUNDATION_DECL)
183183
#define FUNC_DECL(Name, Id) FuncDecl *Get##Name = nullptr;
184184
#include "swift/AST/KnownDecls.def"
185185

186-
/// Swift.Bool.init(_builtinBooleanLiteral:)
187-
ConstructorDecl *BoolBuiltinInitDecl = nullptr;
188-
189186
/// func ==(Int, Int) -> Bool
190187
FuncDecl *EqualIntDecl = nullptr;
191188

@@ -277,6 +274,10 @@ FOR_KNOWN_FOUNDATION_TYPES(CACHE_FOUNDATION_DECL)
277274
/// to the original property with the delegate.
278275
llvm::DenseMap<const VarDecl *, VarDecl *> OriginalDelegatedProperties;
279276

277+
/// The builtin initializer witness for a literal. Used when building
278+
/// LiteralExprs in fully-checked AST.
279+
llvm::DenseMap<const NominalTypeDecl *, ConcreteDeclRef> BuiltinInitWitness;
280+
280281
/// Structure that captures data that is segregated into different
281282
/// arenas.
282283
struct Arena {
@@ -963,27 +964,80 @@ lookupOperatorFunc(const ASTContext &ctx, StringRef oper, Type contextType,
963964
return nullptr;
964965
}
965966

966-
ConstructorDecl *ASTContext::getBoolBuiltinInitDecl() const {
967-
if (getImpl().BoolBuiltinInitDecl)
968-
return getImpl().BoolBuiltinInitDecl;
967+
ConcreteDeclRef ASTContext::getBoolBuiltinInitDecl() const {
968+
auto fn = [&](ASTContext &ctx) {
969+
return DeclName(ctx, DeclBaseName::createConstructor(),
970+
{ Id_builtinBooleanLiteral });
971+
};
972+
auto builtinProtocolKind =
973+
KnownProtocolKind::ExpressibleByBuiltinBooleanLiteral;
974+
return getBuiltinInitDecl(getBoolDecl(), builtinProtocolKind, fn);
975+
}
969976

970-
if (!getBoolDecl())
971-
return nullptr;
977+
ConcreteDeclRef
978+
ASTContext::getIntBuiltinInitDecl(NominalTypeDecl *intDecl) const {
979+
auto fn = [&](ASTContext &ctx) {
980+
return DeclName(ctx, DeclBaseName::createConstructor(),
981+
{ Id_builtinIntegerLiteral });
982+
};
983+
auto builtinProtocolKind =
984+
KnownProtocolKind::ExpressibleByBuiltinIntegerLiteral;
985+
return getBuiltinInitDecl(intDecl, builtinProtocolKind, fn);
986+
}
972987

973-
DeclName initName(*const_cast<ASTContext *>(this),
974-
DeclBaseName::createConstructor(),
975-
{ Id_builtinBooleanLiteral });
976-
auto members = getBoolDecl()->lookupDirect(initName);
988+
ConcreteDeclRef
989+
ASTContext::getFloatBuiltinInitDecl(NominalTypeDecl *floatDecl) const {
990+
auto fn = [&](ASTContext &ctx) {
991+
return DeclName(ctx, DeclBaseName::createConstructor(),
992+
{ Id_builtinFloatLiteral });
993+
};
977994

978-
if (members.size() != 1)
979-
return nullptr;
995+
auto builtinProtocolKind =
996+
KnownProtocolKind::ExpressibleByBuiltinFloatLiteral;
997+
return getBuiltinInitDecl(floatDecl, builtinProtocolKind, fn);
998+
}
999+
1000+
ConcreteDeclRef
1001+
ASTContext::getStringBuiltinInitDecl(NominalTypeDecl *stringDecl) const {
1002+
auto fn = [&](ASTContext &ctx) {
1003+
return DeclName(ctx, DeclBaseName::createConstructor(),
1004+
{ Id_builtinStringLiteral,
1005+
getIdentifier("utf8CodeUnitCount"),
1006+
getIdentifier("isASCII") });
1007+
};
1008+
1009+
auto builtinProtocolKind =
1010+
KnownProtocolKind::ExpressibleByBuiltinStringLiteral;
1011+
return getBuiltinInitDecl(stringDecl, builtinProtocolKind, fn);
1012+
}
1013+
1014+
ConcreteDeclRef
1015+
ASTContext::getBuiltinInitDecl(NominalTypeDecl *decl,
1016+
KnownProtocolKind builtinProtocolKind,
1017+
llvm::function_ref<DeclName (ASTContext &ctx)> initName) const {
1018+
auto &witness = getImpl().BuiltinInitWitness[decl];
1019+
if (witness)
1020+
return witness;
9801021

981-
if (auto init = dyn_cast<ConstructorDecl>(members[0])) {
982-
getImpl().BoolBuiltinInitDecl = init;
983-
return init;
1022+
auto type = decl->getDeclaredType();
1023+
auto builtinProtocol = getProtocol(builtinProtocolKind);
1024+
auto builtinConformance = getStdlibModule()->lookupConformance(
1025+
type, builtinProtocol);
1026+
if (!builtinConformance) {
1027+
assert(false && "Missing required conformance");
1028+
witness = ConcreteDeclRef();
1029+
return witness;
9841030
}
9851031

986-
return nullptr;
1032+
auto *ctx = const_cast<ASTContext *>(this);
1033+
witness = builtinConformance->getWitnessByName(type, initName(*ctx));
1034+
if (!witness) {
1035+
assert(false && "Missing required witness");
1036+
witness = ConcreteDeclRef();
1037+
return witness;
1038+
}
1039+
1040+
return witness;
9871041
}
9881042

9891043
FuncDecl *ASTContext::getEqualIntDecl() const {

0 commit comments

Comments
 (0)