diff options
author | Saleem Abdulrasool <compnerd@compnerd.org> | 2018-10-24 23:28:28 +0000 |
---|---|---|
committer | Saleem Abdulrasool <compnerd@compnerd.org> | 2018-10-24 23:28:28 +0000 |
commit | 81a650ee87eb679e85a4ca3b1565c5fbd362a472 (patch) | |
tree | 6974432a98b0b6876d5ba3e165a8ad6169c23672 /clang/lib/AST/ASTContext.cpp | |
parent | ed9513472c111f6bbf1e34d33a4b5b45aa3c8d76 (diff) | |
download | bcm5719-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.cpp | 74 |
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); |