summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST/ASTContext.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/AST/ASTContext.cpp
parented9513472c111f6bbf1e34d33a4b5b45aa3c8d76 (diff)
downloadbcm5719-llvm-81a650ee87eb679e85a4ca3b1565c5fbd362a472.tar.gz
bcm5719-llvm-81a650ee87eb679e85a4ca3b1565c5fbd362a472.zip
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/AST/ASTContext.cpp')
-rw-r--r--clang/lib/AST/ASTContext.cpp74
1 files changed, 56 insertions, 18 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 2a38d5e6049..321f4f96701 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -5763,28 +5763,66 @@ TypedefDecl *ASTContext::getCFConstantStringDecl() const {
CFConstantStringTagDecl = buildImplicitRecord("__NSConstantString_tag");
CFConstantStringTagDecl->startDefinition();
- QualType FieldTypes[4];
- const char *FieldNames[4];
-
- // const int *isa;
- FieldTypes[0] = getPointerType(IntTy.withConst());
- FieldNames[0] = "isa";
- // int flags;
- FieldTypes[1] = IntTy;
- FieldNames[1] = "flags";
- // const char *str;
- FieldTypes[2] = getPointerType(CharTy.withConst());
- FieldNames[2] = "str";
- // long length;
- FieldTypes[3] = LongTy;
- FieldNames[3] = "length";
+ struct {
+ QualType Type;
+ const char *Name;
+ } Fields[5];
+ unsigned Count = 0;
+
+ /// Objective-C ABI
+ ///
+ /// typedef struct __NSConstantString_tag {
+ /// const char *isa;
+ /// int flags;
+ /// const char *str;
+ /// long length;
+ /// } __NSConstantString;
+ ///
+ /// Swift ABI (4.1, 4.2)
+ ///
+ /// typedef struct __NSConstantString_tag {
+ /// uintptr_t _cfisa;
+ /// uintptr_t _swift_rc;
+ /// _Atomic(uint64_t) _cfinfoa;
+ /// const char *_ptr;
+ /// uint32_t _length;
+ /// } __NSConstantString;
+ ///
+ /// Swift ABI (5.0)
+ ///
+ /// typedef struct __NSConstantString_tag {
+ /// uintptr_t _cfisa;
+ /// uintptr_t _swift_rc;
+ /// _Atomic(uint64_t) _cfinfoa;
+ /// const char *_ptr;
+ /// uintptr_t _length;
+ /// } __NSConstantString;
+
+ const auto CFRuntime = getLangOpts().CFRuntime;
+ if (static_cast<unsigned>(CFRuntime) <
+ static_cast<unsigned>(LangOptions::CoreFoundationABI::Swift)) {
+ Fields[Count++] = { getPointerType(IntTy.withConst()), "isa" };
+ Fields[Count++] = { IntTy, "flags" };
+ Fields[Count++] = { getPointerType(CharTy.withConst()), "str" };
+ Fields[Count++] = { LongTy, "length" };
+ } else {
+ Fields[Count++] = { getUIntPtrType(), "_cfisa" };
+ Fields[Count++] = { getUIntPtrType(), "_swift_rc" };
+ Fields[Count++] = { getFromTargetType(Target->getUInt64Type()), "_swift_rc" };
+ Fields[Count++] = { getPointerType(CharTy.withConst()), "_ptr" };
+ if (CFRuntime == LangOptions::CoreFoundationABI::Swift4_1 ||
+ CFRuntime == LangOptions::CoreFoundationABI::Swift4_2)
+ Fields[Count++] = { IntTy, "_ptr" };
+ else
+ Fields[Count++] = { getUIntPtrType(), "_ptr" };
+ }
// Create fields
- for (unsigned i = 0; i < 4; ++i) {
+ for (unsigned i = 0; i < Count; ++i) {
FieldDecl *Field =
FieldDecl::Create(*this, CFConstantStringTagDecl, SourceLocation(),
- SourceLocation(), &Idents.get(FieldNames[i]),
- FieldTypes[i], /*TInfo=*/nullptr,
+ SourceLocation(), &Idents.get(Fields[i].Name),
+ Fields[i].Type, /*TInfo=*/nullptr,
/*BitWidth=*/nullptr, /*Mutable=*/false, ICIS_NoInit);
Field->setAccess(AS_public);
CFConstantStringTagDecl->addDecl(Field);
OpenPOWER on IntegriCloud