Skip to content

Commit 2dd8e8b

Browse files
authored
Merge pull request #20200 from rjmccall/basic-builtin-integer-literal
Implement basic support for Builtin.IntegerLiteral
2 parents b5aa1b3 + cf51144 commit 2dd8e8b

Some content is hidden

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

42 files changed

+1142
-131
lines changed

docs/ABI/Mangling.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,7 @@ Types
448448
type ::= 'BB' // Builtin.UnsafeValueBuffer
449449
type ::= 'Bf' NATURAL '_' // Builtin.Float<n>
450450
type ::= 'Bi' NATURAL '_' // Builtin.Int<n>
451+
type ::= 'BI' // Builtin.IntLiteral
451452
type ::= 'BO' // Builtin.UnknownObject
452453
type ::= 'Bo' // Builtin.NativeObject
453454
type ::= 'Bp' // Builtin.RawPointer

include/swift/AST/ASTContext.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -612,6 +612,7 @@ class ASTContext final {
612612
const CanType TheRawPointerType; /// Builtin.RawPointer
613613
const CanType TheUnsafeValueBufferType; /// Builtin.UnsafeValueBuffer
614614
const CanType TheSILTokenType; /// Builtin.SILToken
615+
const CanType TheIntegerLiteralType; /// Builtin.IntegerLiteralType
615616

616617
const CanType TheIEEE32Type; /// 32-bit IEEE floating point
617618
const CanType TheIEEE64Type; /// 64-bit IEEE floating point

include/swift/AST/DiagnosticsParse.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,8 @@ ERROR(sil_operand_not_ref_storage_address,none,
546546
(StringRef, StringRef, ReferenceOwnership))
547547
ERROR(sil_integer_literal_not_integer_type,none,
548548
"integer_literal instruction requires a 'Builtin.Int<n>' type", ())
549+
ERROR(sil_integer_literal_not_well_formed,none,
550+
"integer_literal value not well-formed for type %0", (Type))
549551
ERROR(sil_float_literal_not_float_type,none,
550552
"float_literal instruction requires a 'Builtin.FP<n>' type", ())
551553
ERROR(sil_substitutions_on_non_polymorphic_type,none,

include/swift/AST/TypeMatcher.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ class TypeMatcher {
102102

103103
TRIVIAL_CASE(ErrorType)
104104
TRIVIAL_CASE(BuiltinIntegerType)
105+
TRIVIAL_CASE(BuiltinIntegerLiteralType)
105106
TRIVIAL_CASE(BuiltinFloatType)
106107
TRIVIAL_CASE(BuiltinRawPointerType)
107108
TRIVIAL_CASE(BuiltinNativeObjectType)

include/swift/AST/TypeNodes.def

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,10 @@
9090
TYPE(Error, Type)
9191
UNCHECKED_TYPE(Unresolved, Type)
9292
ABSTRACT_TYPE(Builtin, Type)
93-
BUILTIN_TYPE(BuiltinInteger, BuiltinType)
93+
ABSTRACT_TYPE(AnyBuiltinInteger, BuiltinType)
94+
BUILTIN_TYPE(BuiltinInteger, AnyBuiltinIntegerType)
95+
BUILTIN_TYPE(BuiltinIntegerLiteral, AnyBuiltinIntegerType)
96+
TYPE_RANGE(AnyBuiltinInteger, BuiltinInteger, BuiltinIntegerLiteral)
9497
BUILTIN_TYPE(BuiltinFloat, BuiltinType)
9598
BUILTIN_TYPE(BuiltinRawPointer, BuiltinType)
9699
BUILTIN_TYPE(BuiltinNativeObject, BuiltinType)

include/swift/AST/Types.h

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1436,15 +1436,31 @@ class BuiltinIntegerWidth {
14361436
}
14371437
};
14381438

1439+
/// An abstract base class for the two integer types.
1440+
class AnyBuiltinIntegerType : public BuiltinType {
1441+
protected:
1442+
AnyBuiltinIntegerType(TypeKind kind, const ASTContext &C)
1443+
: BuiltinType(kind, C) {}
1444+
1445+
public:
1446+
static bool classof(const TypeBase *T) {
1447+
return T->getKind() >= TypeKind::First_AnyBuiltinIntegerType &&
1448+
T->getKind() <= TypeKind::Last_AnyBuiltinIntegerType;
1449+
}
1450+
1451+
BuiltinIntegerWidth getWidth() const; // defined inline below
1452+
};
1453+
DEFINE_EMPTY_CAN_TYPE_WRAPPER(AnyBuiltinIntegerType, BuiltinType)
1454+
14391455
/// The builtin integer types. These directly correspond
14401456
/// to LLVM IR integer types. They lack signedness and have an arbitrary
14411457
/// bitwidth.
1442-
class BuiltinIntegerType : public BuiltinType {
1458+
class BuiltinIntegerType : public AnyBuiltinIntegerType {
14431459
friend class ASTContext;
14441460
private:
14451461
BuiltinIntegerWidth Width;
14461462
BuiltinIntegerType(BuiltinIntegerWidth BitWidth, const ASTContext &C)
1447-
: BuiltinType(TypeKind::BuiltinInteger, C), Width(BitWidth) {}
1463+
: AnyBuiltinIntegerType(TypeKind::BuiltinInteger, C), Width(BitWidth) {}
14481464

14491465
public:
14501466
/// Get a builtin integer type.
@@ -1500,8 +1516,31 @@ class BuiltinIntegerType : public BuiltinType {
15001516
return T->getKind() == TypeKind::BuiltinInteger;
15011517
}
15021518
};
1503-
DEFINE_EMPTY_CAN_TYPE_WRAPPER(BuiltinIntegerType, BuiltinType)
1504-
1519+
DEFINE_EMPTY_CAN_TYPE_WRAPPER(BuiltinIntegerType, AnyBuiltinIntegerType)
1520+
1521+
/// BuiltinIntegerLiteralType - The builtin arbitrary-precision integer type.
1522+
/// Useful for constructing integer literals.
1523+
class BuiltinIntegerLiteralType : public AnyBuiltinIntegerType {
1524+
friend class ASTContext;
1525+
BuiltinIntegerLiteralType(const ASTContext &C)
1526+
: AnyBuiltinIntegerType(TypeKind::BuiltinIntegerLiteral, C) {}
1527+
public:
1528+
static bool classof(const TypeBase *T) {
1529+
return T->getKind() == TypeKind::BuiltinIntegerLiteral;
1530+
}
1531+
1532+
BuiltinIntegerWidth getWidth() const = delete;
1533+
};
1534+
DEFINE_EMPTY_CAN_TYPE_WRAPPER(BuiltinIntegerLiteralType, AnyBuiltinIntegerType);
1535+
1536+
inline BuiltinIntegerWidth AnyBuiltinIntegerType::getWidth() const {
1537+
if (auto intTy = dyn_cast<BuiltinIntegerType>(this)) {
1538+
return intTy->getWidth();
1539+
} else {
1540+
return BuiltinIntegerWidth::arbitrary();
1541+
}
1542+
}
1543+
15051544
class BuiltinFloatType : public BuiltinType {
15061545
friend class ASTContext;
15071546
public:

include/swift/Parse/Parser.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1216,6 +1216,8 @@ class Parser {
12161216
ParserResult<Expr> parseExprStringLiteral();
12171217
ParserResult<Expr> parseExprTypeOf();
12181218

1219+
StringRef copyAndStripUnderscores(StringRef text);
1220+
12191221
ParserStatus parseStringSegments(SmallVectorImpl<Lexer::StringSegment> &Segments,
12201222
SmallVectorImpl<Expr*> &Exprs,
12211223
Token EntireTok);

include/swift/SIL/SILType.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,8 @@ class SILType {
516516
static SILType getRawPointerType(const ASTContext &C);
517517
/// Get a builtin integer type as a SILType.
518518
static SILType getBuiltinIntegerType(unsigned bitWidth, const ASTContext &C);
519+
/// Get the IntegerLiteral type as a SILType.
520+
static SILType getBuiltinIntegerLiteralType(const ASTContext &C);
519521
/// Get a builtin floating-point type as a SILType.
520522
static SILType getBuiltinFloatType(BuiltinFloatType::FPKind Kind,
521523
const ASTContext &C);

include/swift/Strings.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ constexpr static const char BUILTIN_TYPE_NAME_INT128[] = "Builtin.Int128";
5454
constexpr static const char BUILTIN_TYPE_NAME_INT256[] = "Builtin.Int256";
5555
/// The name of the Builtin type for Int512
5656
constexpr static const char BUILTIN_TYPE_NAME_INT512[] = "Builtin.Int512";
57+
/// The name of the Builtin type for IntLiteral
58+
constexpr static const char BUILTIN_TYPE_NAME_INTLITERAL[] =
59+
"Builtin.IntLiteral";
5760
/// The name of the Builtin type for Float
5861
constexpr static const char BUILTIN_TYPE_NAME_FLOAT[] = "Builtin.Float";
5962
/// The name of the Builtin type for NativeObject

lib/AST/ASTContext.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,8 @@ ASTContext::ASTContext(LangOptions &langOpts, SearchPathOptions &SearchPathOpts,
511511
BuiltinUnsafeValueBufferType(*this)),
512512
TheSILTokenType(new (*this, AllocationArena::Permanent)
513513
SILTokenType(*this)),
514+
TheIntegerLiteralType(new (*this, AllocationArena::Permanent)
515+
BuiltinIntegerLiteralType(*this)),
514516
TheIEEE32Type(new (*this, AllocationArena::Permanent)
515517
BuiltinFloatType(BuiltinFloatType::IEEE32,*this)),
516518
TheIEEE64Type(new (*this, AllocationArena::Permanent)

lib/AST/ASTDumper.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3193,6 +3193,7 @@ namespace {
31933193
PrintWithColorRAII(OS, ParenthesisColor) << ')';
31943194
}
31953195

3196+
TRIVIAL_TYPE_PRINTER(BuiltinIntegerLiteral, builtin_integer_literal)
31963197
TRIVIAL_TYPE_PRINTER(BuiltinRawPointer, builtin_raw_pointer)
31973198
TRIVIAL_TYPE_PRINTER(BuiltinNativeObject, builtin_native_object)
31983199
TRIVIAL_TYPE_PRINTER(BuiltinBridgeObject, builtin_bridge_object)

lib/AST/ASTMangler.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -717,6 +717,8 @@ void ASTMangler::appendType(Type type) {
717717
llvm_unreachable("impossible width value");
718718
return;
719719
}
720+
case TypeKind::BuiltinIntegerLiteral:
721+
return appendOperator("BI");
720722
case TypeKind::BuiltinRawPointer:
721723
return appendOperator("Bp");
722724
case TypeKind::BuiltinNativeObject:

lib/AST/ASTPrinter.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3369,6 +3369,10 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
33693369
Printer << BUILTIN_TYPE_NAME_UNSAFEVALUEBUFFER;
33703370
}
33713371

3372+
void visitBuiltinIntegerLiteralType(BuiltinIntegerLiteralType *T) {
3373+
Printer << BUILTIN_TYPE_NAME_INTLITERAL;
3374+
}
3375+
33723376
void visitBuiltinVectorType(BuiltinVectorType *T) {
33733377
llvm::SmallString<32> UnderlyingStrVec;
33743378
StringRef UnderlyingStr;

lib/AST/ASTVerifier.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2039,9 +2039,8 @@ class Verifier : public ASTWalker {
20392039
void verifyChecked(IfExpr *E) {
20402040
PrettyStackTraceExpr debugStack(Ctx, "verifying IfExpr", E);
20412041

2042-
auto condTy
2043-
= E->getCondExpr()->getType()->getAs<BuiltinIntegerType>();
2044-
if (!condTy || !condTy->isFixedWidth() || condTy->getFixedWidth() != 1) {
2042+
auto condTy = E->getCondExpr()->getType();
2043+
if (!condTy->isBuiltinIntegerType(1)) {
20452044
Out << "IfExpr condition is not an i1\n";
20462045
abort();
20472046
}

lib/AST/Builtins.cpp

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,9 @@ Type swift::getBuiltinType(ASTContext &Context, StringRef Name) {
9393
if (Name == "Word")
9494
return BuiltinIntegerType::getWordType(Context);
9595

96+
if (Name == "IntLiteral")
97+
return Context.TheIntegerLiteralType;
98+
9699
// Handle 'int8' and friends.
97100
if (Name.substr(0, 3) == "Int") {
98101
unsigned BitWidth;
@@ -348,7 +351,7 @@ static ValueDecl *getCastOperation(ASTContext &Context, Identifier Id,
348351
!CheckOutput->is<BuiltinIntegerType>())
349352
return nullptr;
350353
break;
351-
354+
352355
case BuiltinValueKind::UIToFP:
353356
case BuiltinValueKind::SIToFP:
354357
if (CheckOutput.isNull() || !CheckInput->is<BuiltinIntegerType>() ||
@@ -1074,16 +1077,20 @@ static ValueDecl *getStaticReportOperation(ASTContext &Context, Identifier Id) {
10741077
return getBuiltinFunction(Id, ArgElts, ResultTy);
10751078
}
10761079

1077-
static ValueDecl *getCheckedTruncOperation(ASTContext &Context,
1078-
Identifier Id,
1079-
Type InputTy,
1080-
Type OutputTy) {
1081-
auto InTy = InputTy->getAs<BuiltinIntegerType>();
1080+
static ValueDecl *getCheckedTruncOperation(ASTContext &Context, Identifier Id,
1081+
Type InputTy, Type OutputTy,
1082+
bool AllowLiteral) {
1083+
auto InTy = InputTy->getAs<AnyBuiltinIntegerType>();
10821084
auto OutTy = OutputTy->getAs<BuiltinIntegerType>();
10831085
if (!InTy || !OutTy)
10841086
return nullptr;
1085-
if (InTy->getLeastWidth() < OutTy->getGreatestWidth())
1087+
if (isa<BuiltinIntegerLiteralType>(InTy)) {
1088+
if (!AllowLiteral)
1089+
return nullptr;
1090+
} else if (cast<BuiltinIntegerType>(InTy)->getLeastWidth()
1091+
< OutTy->getGreatestWidth()) {
10861092
return nullptr;
1093+
}
10871094

10881095
Type OverflowBitTy = BuiltinIntegerType::get(1, Context);
10891096
TupleTypeElt ResultElts[] = { Type(OutTy), OverflowBitTy };
@@ -1107,7 +1114,7 @@ static ValueDecl *getCheckedConversionOperation(ASTContext &Context,
11071114
static ValueDecl *getIntToFPWithOverflowOperation(ASTContext &Context,
11081115
Identifier Id, Type InputTy,
11091116
Type OutputTy) {
1110-
auto InTy = InputTy->getAs<BuiltinIntegerType>();
1117+
auto InTy = InputTy->getAs<AnyBuiltinIntegerType>();
11111118
auto OutTy = OutputTy->getAs<BuiltinFloatType>();
11121119
if (!InTy || !OutTy)
11131120
return nullptr;
@@ -1828,12 +1835,15 @@ ValueDecl *swift::getBuiltinValueDecl(ASTContext &Context, Identifier Id) {
18281835
if (!Types.empty()) return nullptr;
18291836
return getStaticReportOperation(Context, Id);
18301837

1831-
case BuiltinValueKind::UToSCheckedTrunc:
18321838
case BuiltinValueKind::SToSCheckedTrunc:
18331839
case BuiltinValueKind::SToUCheckedTrunc:
1840+
if (Types.size() != 2) return nullptr;
1841+
return getCheckedTruncOperation(Context, Id, Types[0], Types[1], true);
1842+
1843+
case BuiltinValueKind::UToSCheckedTrunc:
18341844
case BuiltinValueKind::UToUCheckedTrunc:
18351845
if (Types.size() != 2) return nullptr;
1836-
return getCheckedTruncOperation(Context, Id, Types[0], Types[1]);
1846+
return getCheckedTruncOperation(Context, Id, Types[0], Types[1], false);
18371847

18381848
case BuiltinValueKind::SUCheckedConversion:
18391849
case BuiltinValueKind::USCheckedConversion:

lib/AST/Type.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ bool CanType::isReferenceTypeImpl(CanType type, bool functionsCount) {
201201
case TypeKind::Error:
202202
case TypeKind::Unresolved:
203203
case TypeKind::BuiltinInteger:
204+
case TypeKind::BuiltinIntegerLiteral:
204205
case TypeKind::BuiltinFloat:
205206
case TypeKind::BuiltinRawPointer:
206207
case TypeKind::BuiltinUnsafeValueBuffer:
@@ -4018,6 +4019,7 @@ ReferenceCounting TypeBase::getReferenceCounting() {
40184019
case TypeKind::Error:
40194020
case TypeKind::Unresolved:
40204021
case TypeKind::BuiltinInteger:
4022+
case TypeKind::BuiltinIntegerLiteral:
40214023
case TypeKind::BuiltinFloat:
40224024
case TypeKind::BuiltinRawPointer:
40234025
case TypeKind::BuiltinUnsafeValueBuffer:

lib/Demangling/Demangler.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -982,6 +982,10 @@ NodePointer Demangler::demangleBuiltinType() {
982982
Ty = createNode(Node::Kind::BuiltinTypeName, name);
983983
break;
984984
}
985+
case 'I':
986+
Ty = createNode(Node::Kind::BuiltinTypeName,
987+
BUILTIN_TYPE_NAME_INTLITERAL);
988+
break;
985989
case 'v': {
986990
int elts = demangleIndex() - 1;
987991
if (elts <= 0 || elts > maxTypeSize)

lib/Demangling/Remangler.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -681,6 +681,8 @@ void Remangler::mangleBuiltinTypeName(Node *node) {
681681
Buffer << 'p';
682682
} else if (text == BUILTIN_TYPE_NAME_SILTOKEN) {
683683
Buffer << 't';
684+
} else if (text == BUILTIN_TYPE_NAME_INTLITERAL) {
685+
Buffer << 'I';
684686
} else if (text == BUILTIN_TYPE_NAME_WORD) {
685687
Buffer << 'w';
686688
} else if (text.consume_front(BUILTIN_TYPE_NAME_INT)) {

lib/IRGen/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ add_swift_host_library(swiftIRGen STATIC
2121
GenFunc.cpp
2222
GenHeap.cpp
2323
GenInit.cpp
24+
GenIntegerLiteral.cpp
2425
GenKeyPath.cpp
2526
GenMeta.cpp
2627
GenObjC.cpp

lib/IRGen/GenBuiltin.cpp

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "Explosion.h"
2929
#include "GenCall.h"
3030
#include "GenCast.h"
31+
#include "GenIntegerLiteral.h"
3132
#include "IRGenFunction.h"
3233
#include "IRGenModule.h"
3334
#include "LoadableTypeInfo.h"
@@ -690,10 +691,20 @@ if (Builtin.ID == BuiltinValueKind::id) { \
690691
if (Builtin.ID == BuiltinValueKind::SToSCheckedTrunc ||
691692
Builtin.ID == BuiltinValueKind::UToUCheckedTrunc ||
692693
Builtin.ID == BuiltinValueKind::SToUCheckedTrunc) {
694+
bool Signed = (Builtin.ID == BuiltinValueKind::SToSCheckedTrunc);
695+
696+
auto FromType = Builtin.Types[0]->getCanonicalType();
697+
auto ToTy = cast<llvm::IntegerType>(
698+
IGF.IGM.getStorageTypeForLowered(Builtin.Types[1]->getCanonicalType()));
699+
700+
// Handle the arbitrary-precision truncate specially.
701+
if (isa<BuiltinIntegerLiteralType>(FromType)) {
702+
emitIntegerLiteralCheckedTrunc(IGF, args, ToTy, Signed, out);
703+
return;
704+
}
705+
693706
auto FromTy =
694-
IGF.IGM.getStorageTypeForLowered(Builtin.Types[0]->getCanonicalType());
695-
auto ToTy =
696-
IGF.IGM.getStorageTypeForLowered(Builtin.Types[1]->getCanonicalType());
707+
IGF.IGM.getStorageTypeForLowered(FromType);
697708

698709
// Compute the result for SToSCheckedTrunc_IntFrom_IntTo(Arg):
699710
// Res = trunc_IntTo(Arg)
@@ -709,7 +720,6 @@ if (Builtin.ID == BuiltinValueKind::id) { \
709720
// return (Res, OverflowFlag)
710721
llvm::Value *Arg = args.claimNext();
711722
llvm::Value *Res = IGF.Builder.CreateTrunc(Arg, ToTy);
712-
bool Signed = (Builtin.ID == BuiltinValueKind::SToSCheckedTrunc);
713723
llvm::Value *Ext = Signed ? IGF.Builder.CreateSExt(Res, FromTy) :
714724
IGF.Builder.CreateZExt(Res, FromTy);
715725
llvm::Value *OverflowCond = IGF.Builder.CreateICmpEQ(Arg, Ext);
@@ -767,6 +777,13 @@ if (Builtin.ID == BuiltinValueKind::id) { \
767777
// We are currently emitting code for '_convertFromBuiltinIntegerLiteral',
768778
// which will call the builtin and pass it a non-compile-time-const parameter.
769779
if (Builtin.ID == BuiltinValueKind::IntToFPWithOverflow) {
780+
if (Builtin.Types[0]->is<BuiltinIntegerLiteralType>()) {
781+
auto toType =
782+
IGF.IGM.getStorageTypeForLowered(Builtin.Types[1]->getCanonicalType());
783+
auto result = emitIntegerLiteralToFP(IGF, args, toType);
784+
out.add(result);
785+
return;
786+
}
770787
auto ToTy =
771788
IGF.IGM.getStorageTypeForLowered(Builtin.Types[1]->getCanonicalType());
772789
llvm::Value *Arg = args.claimNext();

0 commit comments

Comments
 (0)