From 05536d7183de6dfd55b445c92e63313d3aa25a2b Mon Sep 17 00:00:00 2001 From: Michael Gottesman Date: Thu, 7 Aug 2025 13:59:17 -0700 Subject: [PATCH] [ast] Convert swift::getBuiltinType to use a covered switch for BuiltinTypeKind. This is an NFC change. The idea is that this will make it easier to add new BuiltinTypeKinds. I missed this code when adding Builtin.ImplicitIsolationActor. By adding a covered switch, we can make sure this code is updated in the future. --- lib/AST/Builtins.cpp | 136 ++++++++++++++++++++++++++----------------- 1 file changed, 84 insertions(+), 52 deletions(-) diff --git a/lib/AST/Builtins.cpp b/lib/AST/Builtins.cpp index 1cc678274ed4a..6778477c96966 100644 --- a/lib/AST/Builtins.cpp +++ b/lib/AST/Builtins.cpp @@ -59,13 +59,50 @@ IntrinsicInfo::getOrCreateAttributes(ASTContext &Ctx) const { } Type swift::getBuiltinType(ASTContext &Context, StringRef Name) { - if (Name == "FixedArray") { - return BuiltinUnboundGenericType::get(TypeKind::BuiltinFixedArray, Context); + // We first map to a kind using a StringSwitch so that we can perform an + // exhaustive switch making it easier to know to update this code. + auto kind = + llvm::StringSwitch>(Name) + .Case("FixedArray", BuiltinTypeKind::BuiltinFixedArray) + .StartsWith("Vec", BuiltinTypeKind::BuiltinVector) + .Case("RawPointer", BuiltinTypeKind::BuiltinRawPointer) + .Case("RawUnsafeContinuation", + BuiltinTypeKind::BuiltinRawUnsafeContinuation) + .Case("Job", BuiltinTypeKind::BuiltinJob) + .Case("DefaultActorStorage", + BuiltinTypeKind::BuiltinDefaultActorStorage) + .Case("NonDefaultDistributedActorStorage", + BuiltinTypeKind::BuiltinNonDefaultDistributedActorStorage) + .Case("Executor", BuiltinTypeKind::BuiltinExecutor) + .Case("NativeObject", BuiltinTypeKind::BuiltinNativeObject) + .Case("BridgeObject", BuiltinTypeKind::BuiltinBridgeObject) + .Case("UnsafeValueBuffer", BuiltinTypeKind::BuiltinUnsafeValueBuffer) + .Case("PackIndex", BuiltinTypeKind::BuiltinPackIndex) + .StartsWith("FP", BuiltinTypeKind::BuiltinFloat) + .Case("Word", BuiltinTypeKind::BuiltinInteger) + .Case("IntLiteral", BuiltinTypeKind::BuiltinIntegerLiteral) + .StartsWith("Int", BuiltinTypeKind::BuiltinInteger) + .Default({}); + + // Handle types that are not BuiltinTypeKinds. + if (!kind) { + if (Name == "SILToken") + return Context.TheSILTokenType; + + // AnyObject is the empty class-constrained existential. + if (Name == "AnyObject") + return CanType(ProtocolCompositionType::theAnyObjectType(Context)); + + return Type(); } - // Vectors are VecNxT, where "N" is the number of elements and - // T is the element type. - if (Name.starts_with("Vec")) { + switch (*kind) { + case BuiltinTypeKind::BuiltinFixedArray: + return BuiltinUnboundGenericType::get(TypeKind::BuiltinFixedArray, Context); + + case BuiltinTypeKind::BuiltinVector: { + // Vectors are VecNxT, where "N" is the number of elements and + // T is the element type. Name = Name.substr(3); StringRef::size_type xPos = Name.find('x'); if (xPos == StringRef::npos) @@ -82,67 +119,62 @@ Type swift::getBuiltinType(ASTContext &Context, StringRef Name) { return BuiltinVectorType::get(Context, elementType, numElements); } - - if (Name == "RawPointer") + case BuiltinTypeKind::BuiltinRawPointer: return Context.TheRawPointerType; - if (Name == "RawUnsafeContinuation") + case BuiltinTypeKind::BuiltinRawUnsafeContinuation: return Context.TheRawUnsafeContinuationType; - if (Name == "Job") + case BuiltinTypeKind::BuiltinJob: return Context.TheJobType; - if (Name == "DefaultActorStorage") + case BuiltinTypeKind::BuiltinDefaultActorStorage: return Context.TheDefaultActorStorageType; - if (Name == "NonDefaultDistributedActorStorage") + case BuiltinTypeKind::BuiltinNonDefaultDistributedActorStorage: return Context.TheNonDefaultDistributedActorStorageType; - if (Name == "Executor") + case BuiltinTypeKind::BuiltinExecutor: return Context.TheExecutorType; - if (Name == "NativeObject") + case BuiltinTypeKind::BuiltinNativeObject: return Context.TheNativeObjectType; - if (Name == "BridgeObject") + case BuiltinTypeKind::BuiltinBridgeObject: return Context.TheBridgeObjectType; - if (Name == "SILToken") - return Context.TheSILTokenType; - if (Name == "UnsafeValueBuffer") + case BuiltinTypeKind::BuiltinUnsafeValueBuffer: return Context.TheUnsafeValueBufferType; - if (Name == "PackIndex") + case BuiltinTypeKind::BuiltinPackIndex: return Context.ThePackIndexType; - - if (Name == "FPIEEE32") - return Context.TheIEEE32Type; - if (Name == "FPIEEE64") - return Context.TheIEEE64Type; + case BuiltinTypeKind::BuiltinFloat: + // Target specific FP types. + if (Name == "FPIEEE32") + return Context.TheIEEE32Type; + if (Name == "FPIEEE64") + return Context.TheIEEE64Type; + if (Name == "FPIEEE16") + return Context.TheIEEE16Type; + if (Name == "FPIEEE80") + return Context.TheIEEE80Type; + if (Name == "FPIEEE128") + return Context.TheIEEE128Type; + if (Name == "FPPPC128") + return Context.ThePPC128Type; + return Type(); + case BuiltinTypeKind::BuiltinInteger: + if (Name == "Word") + return BuiltinIntegerType::getWordType(Context); - if (Name == "Word") - return BuiltinIntegerType::getWordType(Context); + if (Name == "Int") { + return BuiltinUnboundGenericType::get(TypeKind::BuiltinInteger, Context); + } - if (Name == "IntLiteral") + // Handle 'int8' and friends. + if (Name.substr(0, 3) == "Int") { + unsigned BitWidth; + if (!Name.substr(3).getAsInteger(10, BitWidth) && BitWidth <= 2048 && + BitWidth != 0) // Cap to prevent unsound things. + return BuiltinIntegerType::get(BitWidth, Context); + } + return Type(); + case BuiltinTypeKind::BuiltinIntegerLiteral: return Context.TheIntegerLiteralType; - - if (Name == "Int") { - return BuiltinUnboundGenericType::get(TypeKind::BuiltinInteger, Context); - } - - // Handle 'int8' and friends. - if (Name.substr(0, 3) == "Int") { - unsigned BitWidth; - if (!Name.substr(3).getAsInteger(10, BitWidth) && - BitWidth <= 2048 && BitWidth != 0) // Cap to prevent unsound things. - return BuiltinIntegerType::get(BitWidth, Context); + case BuiltinTypeKind::BuiltinUnboundGeneric: + return Type(); } - - // Target specific FP types. - if (Name == "FPIEEE16") - return Context.TheIEEE16Type; - if (Name == "FPIEEE80") - return Context.TheIEEE80Type; - if (Name == "FPIEEE128") - return Context.TheIEEE128Type; - if (Name == "FPPPC128") - return Context.ThePPC128Type; - - // AnyObject is the empty class-constrained existential. - if (Name == "AnyObject") - return CanType( - ProtocolCompositionType::theAnyObjectType(Context)); return Type(); }