From 81a650ee87eb679e85a4ca3b1565c5fbd362a472 Mon Sep 17 00:00:00 2001 From: Saleem Abdulrasool Date: Wed, 24 Oct 2018 23:28:28 +0000 Subject: Driver,CodeGen: introduce support for Swift CFString layout Add a new driver level flag `-fcf-runtime-abi=` that allows one to specify the runtime ABI for CoreFoundation. This controls the language interoperability. In particular, this is relevant for generating the CFConstantString classes (primarily through the `__builtin___CFStringMakeConstantString` builtin) which construct a reference to the "CFObject"'s `isa` field. This type differs between swift 4.1 and 4.2+. Valid values for the new option include: - objc [default behaviour] - enable ObjectiveC interoperability - swift-4.1 - enable interoperability with swift 4.1 - swift-4.2 - enable interoperability with swift 4.2 - swift-5.0 - enable interoperability with swift 5.0 - swift [alias] - target the latest swift ABI Furthermore, swift 4.2+ changed the layout for the CFString when building CoreFoundation *without* ObjectiveC interoperability. In such a case, a field was added to the CFObject base type changing it from: <{ const int*, int }> to <{ uintptr_t, uintptr_t, uint64_t }>. In swift 5.0, the CFString type will be further adjusted to change the length from a uint32_t on everything but BE LP64 targets to uint64_t. Note that the default behaviour for clang remains unchanged and the new layout must be explicitly opted into via `-fcf-runtime-abi=swift*`. llvm-svn: 345222 --- clang/lib/CodeGen/CodeGenModule.cpp | 52 ++++++++++++++++++++++++++++++++----- 1 file changed, 46 insertions(+), 6 deletions(-) (limited to 'clang/lib/CodeGen/CodeGenModule.cpp') diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 9f4fbe9..c9f907b 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -4124,12 +4124,37 @@ CodeGenModule::GetAddrOfConstantCFString(const StringLiteral *Literal) { const ASTContext &Context = getContext(); const llvm::Triple &Triple = getTriple(); + const auto CFRuntime = getLangOpts().CFRuntime; + const bool IsSwiftABI = + static_cast(CFRuntime) >= + static_cast(LangOptions::CoreFoundationABI::Swift); + const bool IsSwift4_1 = CFRuntime == LangOptions::CoreFoundationABI::Swift4_1; + // If we don't already have it, get __CFConstantStringClassReference. if (!CFConstantStringClassRef) { + const char *CFConstantStringClassName = "__CFConstantStringClassReference"; llvm::Type *Ty = getTypes().ConvertType(getContext().IntTy); Ty = llvm::ArrayType::get(Ty, 0); - llvm::Constant *C = - CreateRuntimeVariable(Ty, "__CFConstantStringClassReference"); + + switch (CFRuntime) { + default: break; + case LangOptions::CoreFoundationABI::Swift: LLVM_FALLTHROUGH; + case LangOptions::CoreFoundationABI::Swift5_0: LLVM_FALLTHROUGH; + case LangOptions::CoreFoundationABI::Swift4_2: + CFConstantStringClassName = + Triple.isOSDarwin() ? "$s15SwiftFoundation19_NSCFConstantStringCN" + : "$s10Foundation19_NSCFConstantStringCN"; + Ty = IntPtrTy; + break; + case LangOptions::CoreFoundationABI::Swift4_1: + CFConstantStringClassName = + Triple.isOSDarwin() ? "__T015SwiftFoundation19_NSCFConstantStringCN" + : "__T010Foundation19_NSCFConstantStringCN"; + Ty = IntPtrTy; + break; + } + + llvm::Constant *C = CreateRuntimeVariable(Ty, CFConstantStringClassName); if (Triple.isOSBinFormatELF() || Triple.isOSBinFormatCOFF()) { llvm::GlobalValue *GV = nullptr; @@ -4161,7 +4186,8 @@ CodeGenModule::GetAddrOfConstantCFString(const StringLiteral *Literal) { // Decay array -> ptr CFConstantStringClassRef = - llvm::ConstantExpr::getGetElementPtr(Ty, C, Zeros); + IsSwiftABI ? llvm::ConstantExpr::getPtrToInt(C, Ty) + : llvm::ConstantExpr::getGetElementPtr(Ty, C, Zeros); } QualType CFTy = Context.getCFConstantStringType(); @@ -4175,7 +4201,12 @@ CodeGenModule::GetAddrOfConstantCFString(const StringLiteral *Literal) { Fields.add(cast(CFConstantStringClassRef)); // Flags. - Fields.addInt(IntTy, isUTF16 ? 0x07d0 : 0x07C8); + if (IsSwiftABI) { + Fields.addInt(IntPtrTy, IsSwift4_1 ? 0x05 : 0x01); + Fields.addInt(Int64Ty, isUTF16 ? 0x07d0 : 0x07c8); + } else { + Fields.addInt(IntTy, isUTF16 ? 0x07d0 : 0x07C8); + } // String pointer. llvm::Constant *C = nullptr; @@ -4221,8 +4252,17 @@ CodeGenModule::GetAddrOfConstantCFString(const StringLiteral *Literal) { Fields.add(Str); // String length. - auto Ty = getTypes().ConvertType(Context.LongTy); - Fields.addInt(cast(Ty), StringLength); + llvm::IntegerType *LengthTy = + llvm::IntegerType::get(getModule().getContext(), + Context.getTargetInfo().getLongWidth()); + if (IsSwiftABI) { + if (CFRuntime == LangOptions::CoreFoundationABI::Swift4_1 || + CFRuntime == LangOptions::CoreFoundationABI::Swift4_2) + LengthTy = Int32Ty; + else + LengthTy = IntPtrTy; + } + Fields.addInt(LengthTy, StringLength); CharUnits Alignment = getPointerAlign(); -- cgit v1.1