aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/CodeGen/CodeGenModule.cpp
diff options
context:
space:
mode:
authorSaleem Abdulrasool <compnerd@compnerd.org>2018-10-24 23:28:28 +0000
committerSaleem Abdulrasool <compnerd@compnerd.org>2018-10-24 23:28:28 +0000
commit81a650ee87eb679e85a4ca3b1565c5fbd362a472 (patch)
tree6974432a98b0b6876d5ba3e165a8ad6169c23672 /clang/lib/CodeGen/CodeGenModule.cpp
parented9513472c111f6bbf1e34d33a4b5b45aa3c8d76 (diff)
downloadllvm-81a650ee87eb679e85a4ca3b1565c5fbd362a472.zip
llvm-81a650ee87eb679e85a4ca3b1565c5fbd362a472.tar.gz
llvm-81a650ee87eb679e85a4ca3b1565c5fbd362a472.tar.bz2
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
Diffstat (limited to 'clang/lib/CodeGen/CodeGenModule.cpp')
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp52
1 files changed, 46 insertions, 6 deletions
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<unsigned>(CFRuntime) >=
+ static_cast<unsigned>(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<llvm::ConstantExpr>(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<llvm::IntegerType>(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();