aguinet updated this revision to Diff 298461.
aguinet added a comment.
Update format + llvm tests
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D89490/new/
https://reviews.llvm.org/D89490
Files:
clang/include/clang-c/Index.h
clang/include/clang/Basic/Attr.td
clang/include/clang/Basic/AttrDocs.td
clang/include/clang/Basic/Specifiers.h
clang/lib/AST/ItaniumMangle.cpp
clang/lib/AST/Type.cpp
clang/lib/AST/TypePrinter.cpp
clang/lib/Basic/Targets/AArch64.cpp
clang/lib/CodeGen/CGCall.cpp
clang/lib/CodeGen/CGDebugInfo.cpp
clang/lib/CodeGen/ItaniumCXXABI.cpp
clang/lib/CodeGen/TargetInfo.cpp
clang/lib/Sema/SemaChecking.cpp
clang/lib/Sema/SemaDeclAttr.cpp
clang/lib/Sema/SemaType.cpp
clang/test/CodeGen/darwin_abi.c
clang/test/CodeGen/darwin_abi_empty_structs.cpp
clang/test/CodeGen/darwin_abi_vaarg.c
clang/test/CodeGen/debug-info-cc.c
clang/test/CodeGenCXX/darwinabi-returnthis.cpp
clang/tools/libclang/CXType.cpp
llvm/include/llvm/BinaryFormat/Dwarf.def
llvm/include/llvm/IR/CallingConv.h
llvm/lib/AsmParser/LLLexer.cpp
llvm/lib/AsmParser/LLParser.cpp
llvm/lib/AsmParser/LLToken.h
llvm/lib/IR/AsmWriter.cpp
llvm/lib/Target/AArch64/AArch64CallingConvention.cpp
llvm/lib/Target/AArch64/AArch64FastISel.cpp
llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
llvm/lib/Target/AArch64/AArch64ISelLowering.h
llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp
llvm/lib/Target/AArch64/AArch64Subtarget.h
llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp
llvm/test/CodeGen/AArch64/darwin_abi.ll
llvm/test/CodeGen/AArch64/darwin_abi_vararg.ll
Index: llvm/test/CodeGen/AArch64/darwin_abi_vararg.ll
===================================================================
--- /dev/null
+++ llvm/test/CodeGen/AArch64/darwin_abi_vararg.ll
@@ -0,0 +1,39 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=aarch64-pc-linux | FileCheck %s
+
+target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
+target triple = "aarch64-pc-linux"
+
+%struct.__va_list = type { i8*, i8*, i8*, i32, i32 }
+
+define dso_local aarch64_darwincc void @foo(i32 %n, ...) local_unnamed_addr #0 {
+; CHECK-LABEL: foo:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: sub sp, sp, #48 // =48
+; CHECK-NEXT: stp x29, x30, [sp, #32] // 16-byte Folded Spill
+; CHECK-NEXT: add x29, sp, #32 // =32
+; CHECK-NEXT: add x8, x29, #16 // =16
+; CHECK-NEXT: mov x1, sp
+; CHECK-NEXT: str xzr, [sp, #24]
+; CHECK-NEXT: str x8, [sp]
+; CHECK-NEXT: bl vfoo
+; CHECK-NEXT: ldp x29, x30, [sp, #32] // 16-byte Folded Reload
+; CHECK-NEXT: add sp, sp, #48 // =48
+; CHECK-NEXT: ret
+entry:
+ %va = alloca %struct.__va_list, align 8
+ %0 = bitcast %struct.__va_list* %va to i8*
+ call void @llvm.va_start(i8* nonnull %0)
+ call void @vfoo(i32 %n, %struct.__va_list* nonnull %va) #1
+ call void @llvm.va_end(i8* nonnull %0)
+ ret void
+}
+
+declare void @llvm.va_start(i8*) #1
+
+declare dso_local void @vfoo(i32, %struct.__va_list*) local_unnamed_addr #0
+
+declare void @llvm.va_end(i8*) #1
+
+attributes #0 = { nounwind "disable-tail-calls"="false" "frame-pointer"="non-leaf" "target-cpu"="generic" }
+attributes #1 = { nounwind }
Index: llvm/test/CodeGen/AArch64/darwin_abi.ll
===================================================================
--- /dev/null
+++ llvm/test/CodeGen/AArch64/darwin_abi.ll
@@ -0,0 +1,29 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=aarch64-pc-linux | FileCheck %s
+
+target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
+target triple = "aarch64-pc-linux"
+
+define dso_local aarch64_darwincc signext i16 @f1(i16 signext %a) local_unnamed_addr #0 {
+; CHECK-LABEL: f1:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: add w8, w0, #1 // =1
+; CHECK-NEXT: sxth w0, w8
+; CHECK-NEXT: ret
+entry:
+ %add = add i16 %a, 1
+ ret i16 %add
+}
+
+define dso_local aarch64_darwincc zeroext i16 @f2(i16 zeroext %a) local_unnamed_addr #0 {
+; CHECK-LABEL: f2:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: add w8, w0, #1 // =1
+; CHECK-NEXT: and w0, w8, #0xffff
+; CHECK-NEXT: ret
+entry:
+ %add = add i16 %a, 1
+ ret i16 %add
+}
+
+attributes #0 = { norecurse nounwind readnone "disable-tail-calls"="false" "frame-pointer"="non-leaf" "target-cpu"="generic" }
Index: llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp
===================================================================
--- llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp
+++ llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp
@@ -474,8 +474,8 @@
uint64_t StackOffset = Handler.StackUsed;
if (F.isVarArg()) {
auto &Subtarget = MF.getSubtarget<AArch64Subtarget>();
- if (!Subtarget.isTargetDarwin()) {
- // FIXME: we need to reimplement saveVarArgsRegisters from
+ if (!Subtarget.isCallingConvDarwin(MF.getFunction().getCallingConv())) {
+ // FIXME: we need to reimplement saveVarArgsRegisters from
// AArch64ISelLowering.
return false;
}
Index: llvm/lib/Target/AArch64/AArch64Subtarget.h
===================================================================
--- llvm/lib/Target/AArch64/AArch64Subtarget.h
+++ llvm/lib/Target/AArch64/AArch64Subtarget.h
@@ -549,6 +549,13 @@
}
}
+ bool isCallingConvDarwin(CallingConv::ID CC) const {
+ if (CC == CallingConv::AArch64Darwin) {
+ return true;
+ }
+ return isTargetDarwin();
+ }
+
void mirFileLoaded(MachineFunction &MF) const override;
// Return the known range for the bit length of SVE data registers. A value
Index: llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp
===================================================================
--- llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp
+++ llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp
@@ -74,7 +74,6 @@
const MCPhysReg *
AArch64RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
assert(MF && "Invalid MachineFunction pointer.");
-
if (MF->getFunction().getCallingConv() == CallingConv::GHC)
// GHC set of callee saved regs is empty as all those regs are
// used for passing STG regs around
@@ -87,22 +86,26 @@
if (MF->getSubtarget<AArch64Subtarget>().isTargetDarwin())
return getDarwinCalleeSavedRegs(MF);
- if (MF->getFunction().getCallingConv() == CallingConv::CFGuard_Check)
+ const auto FCC = MF->getFunction().getCallingConv();
+ if (FCC == CallingConv::AArch64Darwin) {
+ return CSR_Darwin_AArch64_AAPCS_SaveList;
+ }
+ if (FCC == CallingConv::CFGuard_Check)
return CSR_Win_AArch64_CFGuard_Check_SaveList;
if (MF->getSubtarget<AArch64Subtarget>().isTargetWindows())
return CSR_Win_AArch64_AAPCS_SaveList;
- if (MF->getFunction().getCallingConv() == CallingConv::AArch64_VectorCall)
+ if (FCC == CallingConv::AArch64_VectorCall)
return CSR_AArch64_AAVPCS_SaveList;
- if (MF->getFunction().getCallingConv() == CallingConv::AArch64_SVE_VectorCall)
+ if (FCC == CallingConv::AArch64_SVE_VectorCall)
return CSR_AArch64_SVE_AAPCS_SaveList;
if (MF->getSubtarget<AArch64Subtarget>().getTargetLowering()
->supportSwiftError() &&
MF->getFunction().getAttributes().hasAttrSomewhere(
Attribute::SwiftError))
return CSR_AArch64_AAPCS_SwiftError_SaveList;
- if (MF->getFunction().getCallingConv() == CallingConv::PreserveMost)
+ if (FCC == CallingConv::PreserveMost)
return CSR_AArch64_RT_MostRegs_SaveList;
- if (MF->getFunction().getCallingConv() == CallingConv::Win64)
+ if (FCC == CallingConv::Win64)
// This is for OSes other than Windows; Windows is a separate case further
// above.
return CSR_AArch64_AAPCS_X18_SaveList;
@@ -221,6 +224,9 @@
return getDarwinCallPreservedMask(MF, CC);
}
+ if (CC == CallingConv::AArch64Darwin) {
+ return CSR_Darwin_AArch64_AAPCS_RegMask;
+ }
if (CC == CallingConv::AArch64_VectorCall)
return SCS ? CSR_AArch64_AAVPCS_SCS_RegMask : CSR_AArch64_AAVPCS_RegMask;
if (CC == CallingConv::AArch64_SVE_VectorCall)
@@ -291,7 +297,7 @@
// In case that the calling convention does not use the same register for
// both, the function should return NULL (does not currently apply)
assert(CC != CallingConv::GHC && "should not be GHC calling convention.");
- if (MF.getSubtarget<AArch64Subtarget>().isTargetDarwin())
+ if (MF.getSubtarget<AArch64Subtarget>().isCallingConvDarwin(CC))
return CSR_Darwin_AArch64_AAPCS_ThisReturn_RegMask;
return CSR_AArch64_AAPCS_ThisReturn_RegMask;
}
Index: llvm/lib/Target/AArch64/AArch64ISelLowering.h
===================================================================
--- llvm/lib/Target/AArch64/AArch64ISelLowering.h
+++ llvm/lib/Target/AArch64/AArch64ISelLowering.h
@@ -873,6 +873,7 @@
SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerAAPCS_VASTART(SDValue Op, SelectionDAG &DAG) const;
+ SDValue LowerAAPCSFromDarwin_VASTART(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerDarwin_VASTART(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerWin64_VASTART(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const;
Index: llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
===================================================================
--- llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -4079,6 +4079,11 @@
case CallingConv::AArch64_VectorCall:
case CallingConv::AArch64_SVE_VectorCall:
return CC_AArch64_AAPCS;
+ case CallingConv::AArch64Darwin:
+ if (!IsVarArg)
+ return CC_AArch64_DarwinPCS;
+ return Subtarget->isTargetILP32() ? CC_AArch64_DarwinPCS_ILP32_VarArg
+ : CC_AArch64_DarwinPCS_VarArg;
}
}
@@ -4094,7 +4099,9 @@
SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
MachineFunction &MF = DAG.getMachineFunction();
MachineFrameInfo &MFI = MF.getFrameInfo();
- bool IsWin64 = Subtarget->isCallingConvWin64(MF.getFunction().getCallingConv());
+ const auto FCC = MF.getFunction().getCallingConv();
+ const bool IsWin64 = Subtarget->isCallingConvWin64(FCC);
+ const bool IsDarwin = Subtarget->isCallingConvDarwin(FCC);
// Assign locations to all of the incoming arguments.
SmallVector<CCValAssign, 16> ArgLocs;
@@ -4278,7 +4285,7 @@
// varargs
AArch64FunctionInfo *FuncInfo = MF.getInfo<AArch64FunctionInfo>();
if (isVarArg) {
- if (!Subtarget->isTargetDarwin() || IsWin64) {
+ if (!IsDarwin || IsWin64) {
// The AAPCS variadic function ABI is identical to the non-variadic
// one. As a result there may be more arguments in registers and we should
// save them for future reference.
@@ -6429,6 +6436,62 @@
return getAddr(BA, DAG);
}
+SDValue
+AArch64TargetLowering::LowerAAPCSFromDarwin_VASTART(SDValue Op,
+ SelectionDAG &DAG) const {
+ // Linux/AArch64 va_list structure is (AArch64 Procedure Call Standard,
+ // section B.3.):
+ // typedef struct {
+ // void *stack;
+ // void *gr_top;
+ // void *vr_top;
+ // int gr_offs;
+ // int vr_offs;
+ // } va_list;
+ // Darwin/AArch64 va_list is just a pointer to the stack, as all variadic
+ // arguments are pushed to the stack.
+ // So we basically set stack as LowerDarwin_VASTART would do, and then set
+ // the gr_offs & vr_offs fields to zero. This will enforce AAPCS functions
+ // processing va_list objects to only get objects from the stack.
+
+ MachineFunction &MF = DAG.getMachineFunction();
+ AArch64FunctionInfo *FuncInfo = MF.getInfo<AArch64FunctionInfo>();
+ auto PtrVT = getPointerTy(DAG.getDataLayout());
+ SDLoc DL(Op);
+
+ SDValue Chain = Op.getOperand(0);
+ SDValue VAList = Op.getOperand(1);
+ const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
+ SmallVector<SDValue, 4> MemOps;
+
+ // void *__stack at offset 0
+ SDValue Stack = DAG.getFrameIndex(FuncInfo->getVarArgsStackIndex(), PtrVT);
+ MemOps.push_back(
+ DAG.getStore(Chain, DL, Stack, VAList, MachinePointerInfo(SV), Align(8)));
+
+ // void *__gr_top at offset 8. Won't be used.
+ const int GPRSize = 0;
+
+ // void *__vr_top at offset 16. Won't be used.
+ const int FPRSize = 0;
+
+ // int __gr_offs at offset 24
+ SDValue GROffsAddr =
+ DAG.getNode(ISD::ADD, DL, PtrVT, VAList, DAG.getConstant(24, DL, PtrVT));
+ MemOps.push_back(
+ DAG.getStore(Chain, DL, DAG.getConstant(-GPRSize, DL, MVT::i32),
+ GROffsAddr, MachinePointerInfo(SV, 24), Align(4)));
+
+ // int __vr_offs at offset 28
+ SDValue VROffsAddr =
+ DAG.getNode(ISD::ADD, DL, PtrVT, VAList, DAG.getConstant(28, DL, PtrVT));
+ MemOps.push_back(
+ DAG.getStore(Chain, DL, DAG.getConstant(-FPRSize, DL, MVT::i32),
+ VROffsAddr, MachinePointerInfo(SV, 28), Align(4)));
+
+ return DAG.getNode(ISD::TokenFactor, DL, MVT::Other, MemOps);
+}
+
SDValue AArch64TargetLowering::LowerDarwin_VASTART(SDValue Op,
SelectionDAG &DAG) const {
AArch64FunctionInfo *FuncInfo =
@@ -6529,11 +6592,19 @@
SelectionDAG &DAG) const {
MachineFunction &MF = DAG.getMachineFunction();
- if (Subtarget->isCallingConvWin64(MF.getFunction().getCallingConv()))
+ const auto FCC = MF.getFunction().getCallingConv();
+ if (Subtarget->isCallingConvWin64(FCC))
return LowerWin64_VASTART(Op, DAG);
- else if (Subtarget->isTargetDarwin())
- return LowerDarwin_VASTART(Op, DAG);
- else
+ else if (Subtarget->isCallingConvDarwin(FCC)) {
+ if (Subtarget->isTargetDarwin()) {
+ return LowerDarwin_VASTART(Op, DAG);
+ }
+ if (!Subtarget->isTargetWindows()) {
+ return LowerAAPCSFromDarwin_VASTART(Op, DAG);
+ }
+ report_fatal_error("can't lower Darwin vaarg if target OS isn't Darwin or "
+ "has an official AAPCS ABI (e.g. Linux)");
+ } else
return LowerAAPCS_VASTART(Op, DAG);
}
Index: llvm/lib/Target/AArch64/AArch64FastISel.cpp
===================================================================
--- llvm/lib/Target/AArch64/AArch64FastISel.cpp
+++ llvm/lib/Target/AArch64/AArch64FastISel.cpp
@@ -350,7 +350,8 @@
return CC_AArch64_GHC;
if (CC == CallingConv::CFGuard_Check)
return CC_AArch64_Win64_CFGuard_Check;
- return Subtarget->isTargetDarwin() ? CC_AArch64_DarwinPCS : CC_AArch64_AAPCS;
+ return Subtarget->isCallingConvDarwin(CC) ? CC_AArch64_DarwinPCS
+ : CC_AArch64_AAPCS;
}
unsigned AArch64FastISel::fastMaterializeAlloca(const AllocaInst *AI) {
Index: llvm/lib/Target/AArch64/AArch64CallingConvention.cpp
===================================================================
--- llvm/lib/Target/AArch64/AArch64CallingConvention.cpp
+++ llvm/lib/Target/AArch64/AArch64CallingConvention.cpp
@@ -145,7 +145,9 @@
for (auto Reg : RegList)
State.AllocateReg(Reg);
- const Align SlotAlign = Subtarget.isTargetDarwin() ? Align(1) : Align(8);
+ const auto FCC = State.getMachineFunction().getFunction().getCallingConv();
+ const Align SlotAlign =
+ Subtarget.isCallingConvDarwin(FCC) ? Align(1) : Align(8);
return finishStackBlock(PendingMembers, LocVT, ArgFlags, State, SlotAlign);
}
Index: llvm/lib/IR/AsmWriter.cpp
===================================================================
--- llvm/lib/IR/AsmWriter.cpp
+++ llvm/lib/IR/AsmWriter.cpp
@@ -374,6 +374,9 @@
case CallingConv::PTX_Device: Out << "ptx_device"; break;
case CallingConv::X86_64_SysV: Out << "x86_64_sysvcc"; break;
case CallingConv::Win64: Out << "win64cc"; break;
+ case CallingConv::AArch64Darwin:
+ Out << "aarch64_darwincc";
+ break;
case CallingConv::SPIR_FUNC: Out << "spir_func"; break;
case CallingConv::SPIR_KERNEL: Out << "spir_kernel"; break;
case CallingConv::Swift: Out << "swiftcc"; break;
Index: llvm/lib/AsmParser/LLToken.h
===================================================================
--- llvm/lib/AsmParser/LLToken.h
+++ llvm/lib/AsmParser/LLToken.h
@@ -152,6 +152,7 @@
kw_spir_func,
kw_x86_64_sysvcc,
kw_win64cc,
+ kw_aarch64_darwincc,
kw_webkit_jscc,
kw_anyregcc,
kw_swiftcc,
Index: llvm/lib/AsmParser/LLParser.cpp
===================================================================
--- llvm/lib/AsmParser/LLParser.cpp
+++ llvm/lib/AsmParser/LLParser.cpp
@@ -2014,6 +2014,7 @@
/// ::= 'spir_kernel'
/// ::= 'x86_64_sysvcc'
/// ::= 'win64cc'
+/// ::= 'aarch64_darwincc'
/// ::= 'webkit_jscc'
/// ::= 'anyregcc'
/// ::= 'preserve_mostcc'
@@ -2054,35 +2055,96 @@
case lltok::kw_aarch64_sve_vector_pcs:
CC = CallingConv::AArch64_SVE_VectorCall;
break;
- case lltok::kw_msp430_intrcc: CC = CallingConv::MSP430_INTR; break;
- case lltok::kw_avr_intrcc: CC = CallingConv::AVR_INTR; break;
- case lltok::kw_avr_signalcc: CC = CallingConv::AVR_SIGNAL; break;
- case lltok::kw_ptx_kernel: CC = CallingConv::PTX_Kernel; break;
- case lltok::kw_ptx_device: CC = CallingConv::PTX_Device; break;
- case lltok::kw_spir_kernel: CC = CallingConv::SPIR_KERNEL; break;
- case lltok::kw_spir_func: CC = CallingConv::SPIR_FUNC; break;
- case lltok::kw_intel_ocl_bicc: CC = CallingConv::Intel_OCL_BI; break;
- case lltok::kw_x86_64_sysvcc: CC = CallingConv::X86_64_SysV; break;
- case lltok::kw_win64cc: CC = CallingConv::Win64; break;
- case lltok::kw_webkit_jscc: CC = CallingConv::WebKit_JS; break;
- case lltok::kw_anyregcc: CC = CallingConv::AnyReg; break;
- case lltok::kw_preserve_mostcc:CC = CallingConv::PreserveMost; break;
- case lltok::kw_preserve_allcc: CC = CallingConv::PreserveAll; break;
- case lltok::kw_ghccc: CC = CallingConv::GHC; break;
- case lltok::kw_swiftcc: CC = CallingConv::Swift; break;
- case lltok::kw_x86_intrcc: CC = CallingConv::X86_INTR; break;
- case lltok::kw_hhvmcc: CC = CallingConv::HHVM; break;
- case lltok::kw_hhvm_ccc: CC = CallingConv::HHVM_C; break;
- case lltok::kw_cxx_fast_tlscc: CC = CallingConv::CXX_FAST_TLS; break;
- case lltok::kw_amdgpu_vs: CC = CallingConv::AMDGPU_VS; break;
- case lltok::kw_amdgpu_ls: CC = CallingConv::AMDGPU_LS; break;
- case lltok::kw_amdgpu_hs: CC = CallingConv::AMDGPU_HS; break;
- case lltok::kw_amdgpu_es: CC = CallingConv::AMDGPU_ES; break;
- case lltok::kw_amdgpu_gs: CC = CallingConv::AMDGPU_GS; break;
- case lltok::kw_amdgpu_ps: CC = CallingConv::AMDGPU_PS; break;
- case lltok::kw_amdgpu_cs: CC = CallingConv::AMDGPU_CS; break;
- case lltok::kw_amdgpu_kernel: CC = CallingConv::AMDGPU_KERNEL; break;
- case lltok::kw_tailcc: CC = CallingConv::Tail; break;
+ case lltok::kw_msp430_intrcc:
+ CC = CallingConv::MSP430_INTR;
+ break;
+ case lltok::kw_avr_intrcc:
+ CC = CallingConv::AVR_INTR;
+ break;
+ case lltok::kw_avr_signalcc:
+ CC = CallingConv::AVR_SIGNAL;
+ break;
+ case lltok::kw_ptx_kernel:
+ CC = CallingConv::PTX_Kernel;
+ break;
+ case lltok::kw_ptx_device:
+ CC = CallingConv::PTX_Device;
+ break;
+ case lltok::kw_spir_kernel:
+ CC = CallingConv::SPIR_KERNEL;
+ break;
+ case lltok::kw_spir_func:
+ CC = CallingConv::SPIR_FUNC;
+ break;
+ case lltok::kw_intel_ocl_bicc:
+ CC = CallingConv::Intel_OCL_BI;
+ break;
+ case lltok::kw_x86_64_sysvcc:
+ CC = CallingConv::X86_64_SysV;
+ break;
+ case lltok::kw_win64cc:
+ CC = CallingConv::Win64;
+ break;
+ case lltok::kw_aarch64_darwincc:
+ CC = CallingConv::AArch64Darwin;
+ break;
+ case lltok::kw_webkit_jscc:
+ CC = CallingConv::WebKit_JS;
+ break;
+ case lltok::kw_anyregcc:
+ CC = CallingConv::AnyReg;
+ break;
+ case lltok::kw_preserve_mostcc:
+ CC = CallingConv::PreserveMost;
+ break;
+ case lltok::kw_preserve_allcc:
+ CC = CallingConv::PreserveAll;
+ break;
+ case lltok::kw_ghccc:
+ CC = CallingConv::GHC;
+ break;
+ case lltok::kw_swiftcc:
+ CC = CallingConv::Swift;
+ break;
+ case lltok::kw_x86_intrcc:
+ CC = CallingConv::X86_INTR;
+ break;
+ case lltok::kw_hhvmcc:
+ CC = CallingConv::HHVM;
+ break;
+ case lltok::kw_hhvm_ccc:
+ CC = CallingConv::HHVM_C;
+ break;
+ case lltok::kw_cxx_fast_tlscc:
+ CC = CallingConv::CXX_FAST_TLS;
+ break;
+ case lltok::kw_amdgpu_vs:
+ CC = CallingConv::AMDGPU_VS;
+ break;
+ case lltok::kw_amdgpu_ls:
+ CC = CallingConv::AMDGPU_LS;
+ break;
+ case lltok::kw_amdgpu_hs:
+ CC = CallingConv::AMDGPU_HS;
+ break;
+ case lltok::kw_amdgpu_es:
+ CC = CallingConv::AMDGPU_ES;
+ break;
+ case lltok::kw_amdgpu_gs:
+ CC = CallingConv::AMDGPU_GS;
+ break;
+ case lltok::kw_amdgpu_ps:
+ CC = CallingConv::AMDGPU_PS;
+ break;
+ case lltok::kw_amdgpu_cs:
+ CC = CallingConv::AMDGPU_CS;
+ break;
+ case lltok::kw_amdgpu_kernel:
+ CC = CallingConv::AMDGPU_KERNEL;
+ break;
+ case lltok::kw_tailcc:
+ CC = CallingConv::Tail;
+ break;
case lltok::kw_cc: {
Lex.Lex();
return ParseUInt32(CC);
Index: llvm/lib/AsmParser/LLLexer.cpp
===================================================================
--- llvm/lib/AsmParser/LLLexer.cpp
+++ llvm/lib/AsmParser/LLLexer.cpp
@@ -605,6 +605,7 @@
KEYWORD(intel_ocl_bicc);
KEYWORD(x86_64_sysvcc);
KEYWORD(win64cc);
+ KEYWORD(aarch64_darwincc);
KEYWORD(x86_regcallcc);
KEYWORD(webkit_jscc);
KEYWORD(swiftcc);
Index: llvm/include/llvm/IR/CallingConv.h
===================================================================
--- llvm/include/llvm/IR/CallingConv.h
+++ llvm/include/llvm/IR/CallingConv.h
@@ -241,6 +241,8 @@
/// The remainder matches the regular calling convention.
WASM_EmscriptenInvoke = 99,
+ AArch64Darwin = 100,
+
/// The highest possible calling convention ID. Must be some 2^k - 1.
MaxID = 1023
};
Index: llvm/include/llvm/BinaryFormat/Dwarf.def
===================================================================
--- llvm/include/llvm/BinaryFormat/Dwarf.def
+++ llvm/include/llvm/BinaryFormat/Dwarf.def
@@ -788,6 +788,7 @@
HANDLE_DW_CC(0xc9, LLVM_PreserveMost)
HANDLE_DW_CC(0xca, LLVM_PreserveAll)
HANDLE_DW_CC(0xcb, LLVM_X86RegCall)
+HANDLE_DW_CC(0xcc, LLVM_AArch64Darwin)
// From GCC source code (include/dwarf2.h): This DW_CC_ value is not currently
// generated by any toolchain. It is used internally to GDB to indicate OpenCL C
// functions that have been compiled with the IBM XL C for OpenCL compiler and use
Index: clang/tools/libclang/CXType.cpp
===================================================================
--- clang/tools/libclang/CXType.cpp
+++ clang/tools/libclang/CXType.cpp
@@ -658,6 +658,7 @@
TCALLINGCONV(X86RegCall);
TCALLINGCONV(X86VectorCall);
TCALLINGCONV(AArch64VectorCall);
+ TCALLINGCONV(AArch64Darwin);
TCALLINGCONV(Win64);
TCALLINGCONV(X86_64SysV);
TCALLINGCONV(AAPCS);
Index: clang/test/CodeGenCXX/darwinabi-returnthis.cpp
===================================================================
--- /dev/null
+++ clang/test/CodeGenCXX/darwinabi-returnthis.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -triple aarch64-pc-linux-gnu -mconstructor-aliases %s -emit-llvm -O1 -o - | FileCheck %s
+
+struct A {
+ __attribute__((darwin_abi)) A();
+ __attribute__((darwin_abi)) ~A();
+};
+
+// CHECK: define aarch64_darwincc %struct.A* @_ZN1AC2Ev(%struct.A* readnone returned %[[THIS:.*]])
+A::A() {
+ // CHECK: ret %struct.A* %[[THIS]]
+}
+
+// CHECK: define aarch64_darwincc %struct.A* @_ZN1AD2Ev(%struct.A* readnone returned %[[THIS:.*]])
+A::~A() {
+ // CHECK: ret %struct.A* %[[THIS]]
+}
Index: clang/test/CodeGen/debug-info-cc.c
===================================================================
--- clang/test/CodeGen/debug-info-cc.c
+++ clang/test/CodeGen/debug-info-cc.c
@@ -2,26 +2,7 @@
// RUN: %clang_cc1 -triple x86_64-unknown-windows-msvc -o - -emit-llvm -debug-info-kind=limited %s | FileCheck %s --check-prefix=WINDOWS
// RUN: %clang_cc1 -triple i386-pc-linux-gnu -o - -emit-llvm -debug-info-kind=limited %s | FileCheck %s --check-prefix=LINUX32
// RUN: %clang_cc1 -triple armv7--linux-gnueabihf -o - -emit-llvm -debug-info-kind=limited %s | FileCheck %s --check-prefix=ARM
-
-// enum CallingConv {
-// CC_C, // __attribute__((cdecl))
-// CC_X86StdCall, // __attribute__((stdcall))
-// CC_X86FastCall, // __attribute__((fastcall))
-// CC_X86ThisCall, // __attribute__((thiscall))
-// CC_X86VectorCall, // __attribute__((vectorcall))
-// CC_X86Pascal, // __attribute__((pascal))
-// CC_Win64, // __attribute__((ms_abi))
-// CC_X86_64SysV, // __attribute__((sysv_abi))
-// CC_X86RegCall, // __attribute__((regcall))
-// CC_AAPCS, // __attribute__((pcs("aapcs")))
-// CC_AAPCS_VFP, // __attribute__((pcs("aapcs-vfp")))
-// CC_IntelOclBicc, // __attribute__((intel_ocl_bicc))
-// CC_SpirFunction, // default for OpenCL functions on SPIR target
-// CC_OpenCLKernel, // inferred for OpenCL kernels
-// CC_Swift, // __attribute__((swiftcall))
-// CC_PreserveMost, // __attribute__((preserve_most))
-// CC_PreserveAll, // __attribute__((preserve_all))
-// };
+// RUN: %clang_cc1 -triple aarch64-pc-linux -o - -emit-llvm -debug-info-kind=limited %s | FileCheck %s --check-prefix=AARCH64
#ifdef __x86_64__
@@ -118,3 +99,11 @@
return a+b;
}
#endif
+
+#if defined(__aarch64__) && defined(__linux__)
+// AARCH64: !DISubprogram({{.*}}"add_darwinabi", {{.*}}type: ![[FTY:[0-9]+]]
+// AARCH64: ![[FTY]] = !DISubroutineType({{.*}}cc: DW_CC_LLVM_AArch64Darwin,
+__attribute__((darwin_abi)) int add_darwinabi(int a, int b) {
+ return a + b;
+}
+#endif
Index: clang/test/CodeGen/darwin_abi_vaarg.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/darwin_abi_vaarg.c
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -triple aarch64-pc-linux -emit-llvm %s -o - |FileCheck %s
+// Check that va_arg used inside a function with the darwin_abi attribute still
+// uses the Linux ABI lowering.
+
+// CHECK: define internal aarch64_darwincc i32 @vfoo(i32 %n, %struct.__va_list* %[[VA:[[:alnum:]_]+]])
+// CHECK: getelementptr inbounds %struct.__va_list, %struct.__va_list* %[[VA]], i32 0, i32 3
+__attribute__((darwin_abi, noinline)) static int vfoo(int n, __builtin_va_list va) {
+ int res = 0;
+ for (int i = 0; i < n; ++i) {
+ res += __builtin_va_arg(va, int);
+ }
+ return res;
+}
+
+int foo(int n, ...) {
+ __builtin_va_list va;
+ __builtin_va_start(va, n);
+ const int res = vfoo(n, va);
+ __builtin_va_end(va);
+ return res;
+}
Index: clang/test/CodeGen/darwin_abi_empty_structs.cpp
===================================================================
--- /dev/null
+++ clang/test/CodeGen/darwin_abi_empty_structs.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 %s -S -emit-llvm -o - -O1 -triple aarch64-pc-linux | FileCheck %s
+// Verify that "when passing parameters to a function, Apple platforms ignore
+// empty structures unless those structures have a nontrivial destructor or
+// copy constructor." when using darwin_abi
+
+struct Empty {};
+
+__attribute__((darwin_abi)) void foo(int n, Empty E);
+// CHECK: @_Z3bari(i32 %[[ARG:[[:alnum:]_]+]])
+void bar(int n) {
+ // CHECK: call aarch64_darwincc void @_Z3fooi5Empty(i32 %[[ARG]])
+ return foo(n, Empty{});
+}
+
+// CHECK: declare aarch64_darwincc void @_Z3fooi5Empty(i32)
Index: clang/test/CodeGen/darwin_abi.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/darwin_abi.c
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -triple aarch64-pc-linux %s -emit-llvm -o - |FileCheck %s
+// Checks that correct LLVM IR is generated for functions that target
+// the Darwin AArch64 ABI under Linux/AArch64. What we check:
+// * sext/zext on return values and arguments
+// * va_list forwarding from Darwin to Linux support
+
+// CHECK: define aarch64_darwincc signext i16 @f1(i16 signext
+__attribute__((darwin_abi)) short f1(short a) {
+ return a + 1;
+}
+
+// CHECK: define aarch64_darwincc zeroext i16 @f2(i16 zeroext
+__attribute__((darwin_abi)) unsigned short f2(unsigned short a) {
+ return a + 1;
+}
+
+// CHECK: define aarch64_darwincc void @foo(i32 %n, ...)
+// CHECK: call void @llvm.va_start
+void vfoo(int n, __builtin_va_list *va);
+__attribute((darwin_abi)) void foo(int n, ...) {
+ __builtin_va_list va;
+ __builtin_va_start(va, n);
+ vfoo(n, &va);
+ __builtin_va_end(va);
+}
Index: clang/lib/Sema/SemaType.cpp
===================================================================
--- clang/lib/Sema/SemaType.cpp
+++ clang/lib/Sema/SemaType.cpp
@@ -120,6 +120,7 @@
case ParsedAttr::AT_VectorCall: \
case ParsedAttr::AT_AArch64VectorPcs: \
case ParsedAttr::AT_MSABI: \
+ case ParsedAttr::AT_DarwinABI: \
case ParsedAttr::AT_SysVABI: \
case ParsedAttr::AT_Pcs: \
case ParsedAttr::AT_IntelOclBicc: \
@@ -7301,6 +7302,8 @@
return createSimpleAttr<IntelOclBiccAttr>(Ctx, Attr);
case ParsedAttr::AT_MSABI:
return createSimpleAttr<MSABIAttr>(Ctx, Attr);
+ case ParsedAttr::AT_DarwinABI:
+ return createSimpleAttr<DarwinABIAttr>(Ctx, Attr);
case ParsedAttr::AT_SysVABI:
return createSimpleAttr<SysVABIAttr>(Ctx, Attr);
case ParsedAttr::AT_PreserveMost:
Index: clang/lib/Sema/SemaDeclAttr.cpp
===================================================================
--- clang/lib/Sema/SemaDeclAttr.cpp
+++ clang/lib/Sema/SemaDeclAttr.cpp
@@ -4465,6 +4465,9 @@
case ParsedAttr::AT_MSABI:
D->addAttr(::new (S.Context) MSABIAttr(S.Context, AL));
return;
+ case ParsedAttr::AT_DarwinABI:
+ D->addAttr(::new (S.Context) DarwinABIAttr(S.Context, AL));
+ return;
case ParsedAttr::AT_SysVABI:
D->addAttr(::new (S.Context) SysVABIAttr(S.Context, AL));
return;
@@ -4633,6 +4636,10 @@
CC = Context.getTargetInfo().getTriple().isOSWindows() ? CC_C :
CC_Win64;
break;
+ case ParsedAttr::AT_DarwinABI:
+ CC = Context.getTargetInfo().getTriple().isOSDarwin() ? CC_C
+ : CC_AArch64Darwin;
+ break;
case ParsedAttr::AT_SysVABI:
CC = Context.getTargetInfo().getTriple().isOSWindows() ? CC_X86_64SysV :
CC_C;
@@ -7742,6 +7749,7 @@
case ParsedAttr::AT_SwiftCall:
case ParsedAttr::AT_VectorCall:
case ParsedAttr::AT_MSABI:
+ case ParsedAttr::AT_DarwinABI:
case ParsedAttr::AT_SysVABI:
case ParsedAttr::AT_Pcs:
case ParsedAttr::AT_IntelOclBicc:
Index: clang/lib/Sema/SemaChecking.cpp
===================================================================
--- clang/lib/Sema/SemaChecking.cpp
+++ clang/lib/Sema/SemaChecking.cpp
@@ -5612,6 +5612,7 @@
bool IsAArch64 = (TT.getArch() == llvm::Triple::aarch64 ||
TT.getArch() == llvm::Triple::aarch64_32);
bool IsWindows = TT.isOSWindows();
+ bool IsLinux = TT.isOSLinux();
bool IsMSVAStart = BuiltinID == Builtin::BI__builtin_ms_va_start;
if (IsX64 || IsAArch64) {
CallingConv CC = CC_C;
@@ -5627,8 +5628,10 @@
// On x64 Windows, don't allow this in System V ABI functions.
// (Yes, that means there's no corresponding way to support variadic
// System V ABI functions on Windows.)
+ // On Apple ARM64 ABI functions, only allow this on AArch64/Unix.
if ((IsWindows && CC == CC_X86_64SysV) ||
- (!IsWindows && CC == CC_Win64))
+ (!IsWindows && CC == CC_Win64) ||
+ (!IsLinux && CC == CC_AArch64Darwin))
return S.Diag(Fn->getBeginLoc(),
diag::err_va_start_used_in_wrong_abi_function)
<< !IsWindows;
Index: clang/lib/CodeGen/TargetInfo.cpp
===================================================================
--- clang/lib/CodeGen/TargetInfo.cpp
+++ clang/lib/CodeGen/TargetInfo.cpp
@@ -5446,9 +5446,16 @@
private:
ABIKind getABIKind() const { return Kind; }
bool isDarwinPCS() const { return Kind == DarwinPCS; }
+ bool isDarwinPCS(const unsigned CConv) const {
+ return isDarwinPCS() || CConv == llvm::CallingConv::AArch64Darwin;
+ }
+ bool isDarwinPCS(CGFunctionInfo const &FI) const {
+ return isDarwinPCS(FI.getCallingConvention());
+ }
- ABIArgInfo classifyReturnType(QualType RetTy, bool IsVariadic) const;
- ABIArgInfo classifyArgumentType(QualType RetTy) const;
+ ABIArgInfo classifyReturnType(QualType RetTy, bool IsVariadic,
+ unsigned CConv) const;
+ ABIArgInfo classifyArgumentType(QualType RetTy, unsigned CConv) const;
ABIArgInfo coerceIllegalVector(QualType Ty) const;
bool isHomogeneousAggregateBaseType(QualType Ty) const override;
bool isHomogeneousAggregateSmallEnough(const Type *Ty,
@@ -5457,12 +5464,13 @@
bool isIllegalVectorType(QualType Ty) const;
void computeInfo(CGFunctionInfo &FI) const override {
+ const unsigned CConv = FI.getCallingConvention();
if (!::classifyReturnType(getCXXABI(), FI, *this))
FI.getReturnInfo() =
- classifyReturnType(FI.getReturnType(), FI.isVariadic());
+ classifyReturnType(FI.getReturnType(), FI.isVariadic(), CConv);
for (auto &it : FI.arguments())
- it.info = classifyArgumentType(it.type);
+ it.info = classifyArgumentType(it.type, CConv);
}
Address EmitDarwinVAArg(Address VAListAddr, QualType Ty,
@@ -5660,7 +5668,8 @@
return getNaturalAlignIndirect(Ty, /*ByVal=*/false);
}
-ABIArgInfo AArch64ABIInfo::classifyArgumentType(QualType Ty) const {
+ABIArgInfo AArch64ABIInfo::classifyArgumentType(QualType Ty,
+ unsigned CConv) const {
Ty = useFirstFieldIfTransparentUnion(Ty);
// Handle illegal vector types here.
@@ -5676,7 +5685,7 @@
if (EIT->getNumBits() > 128)
return getNaturalAlignIndirect(Ty);
- return (isPromotableIntegerTypeForABI(Ty) && isDarwinPCS()
+ return (isPromotableIntegerTypeForABI(Ty) && isDarwinPCS(CConv)
? ABIArgInfo::getExtend(Ty)
: ABIArgInfo::getDirect());
}
@@ -5693,7 +5702,7 @@
uint64_t Size = getContext().getTypeSize(Ty);
bool IsEmpty = isEmptyRecord(getContext(), Ty, true);
if (IsEmpty || Size == 0) {
- if (!getContext().getLangOpts().CPlusPlus || isDarwinPCS())
+ if (!getContext().getLangOpts().CPlusPlus || isDarwinPCS(CConv))
return ABIArgInfo::getIgnore();
// GNU C mode. The only argument that gets ignored is an empty one with size
@@ -5739,8 +5748,8 @@
return getNaturalAlignIndirect(Ty, /*ByVal=*/false);
}
-ABIArgInfo AArch64ABIInfo::classifyReturnType(QualType RetTy,
- bool IsVariadic) const {
+ABIArgInfo AArch64ABIInfo::classifyReturnType(QualType RetTy, bool IsVariadic,
+ unsigned CConv) const {
if (RetTy->isVoidType())
return ABIArgInfo::getIgnore();
@@ -5763,7 +5772,7 @@
if (EIT->getNumBits() > 128)
return getNaturalAlignIndirect(RetTy);
- return (isPromotableIntegerTypeForABI(RetTy) && isDarwinPCS()
+ return (isPromotableIntegerTypeForABI(RetTy) && isDarwinPCS(CConv)
? ABIArgInfo::getExtend(RetTy)
: ABIArgInfo::getDirect());
}
@@ -5866,7 +5875,7 @@
Address AArch64ABIInfo::EmitAAPCSVAArg(Address VAListAddr,
QualType Ty,
CodeGenFunction &CGF) const {
- ABIArgInfo AI = classifyArgumentType(Ty);
+ ABIArgInfo AI = classifyArgumentType(Ty, llvm::CallingConv::C);
bool IsIndirect = AI.isIndirect();
llvm::Type *BaseTy = CGF.ConvertType(Ty);
Index: clang/lib/CodeGen/ItaniumCXXABI.cpp
===================================================================
--- clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -65,6 +65,20 @@
UseARMGuardVarABI(UseARMGuardVarABI),
Use32BitVTableOffsetABI(false) { }
+ bool HasThisReturn(GlobalDecl GD) const override {
+ // Returns true if AArch64 Darwin ABI is explicitly used.
+ const bool IsCtorOrDtor = (isa<CXXConstructorDecl>(GD.getDecl()) ||
+ (isa<CXXDestructorDecl>(GD.getDecl()) &&
+ GD.getDtorType() != Dtor_Deleting));
+ if (!IsCtorOrDtor) {
+ return false;
+ }
+ auto *FTy =
+ cast<FunctionDecl>(GD.getDecl())->getType()->getAs<FunctionType>();
+ const auto FCC = FTy->getCallConv();
+ return FCC == CallingConv::CC_AArch64Darwin;
+ }
+
bool classifyReturnType(CGFunctionInfo &FI) const override;
RecordArgABI getRecordArgABI(const CXXRecordDecl *RD) const override {
Index: clang/lib/CodeGen/CGDebugInfo.cpp
===================================================================
--- clang/lib/CodeGen/CGDebugInfo.cpp
+++ clang/lib/CodeGen/CGDebugInfo.cpp
@@ -1230,6 +1230,8 @@
return llvm::dwarf::DW_CC_BORLAND_pascal;
case CC_Win64:
return llvm::dwarf::DW_CC_LLVM_Win64;
+ case CC_AArch64Darwin:
+ return llvm::dwarf::DW_CC_LLVM_AArch64Darwin;
case CC_X86_64SysV:
return llvm::dwarf::DW_CC_LLVM_X86_64SysV;
case CC_AAPCS:
Index: clang/lib/CodeGen/CGCall.cpp
===================================================================
--- clang/lib/CodeGen/CGCall.cpp
+++ clang/lib/CodeGen/CGCall.cpp
@@ -50,6 +50,8 @@
case CC_X86FastCall: return llvm::CallingConv::X86_FastCall;
case CC_X86RegCall: return llvm::CallingConv::X86_RegCall;
case CC_X86ThisCall: return llvm::CallingConv::X86_ThisCall;
+ case CC_AArch64Darwin:
+ return llvm::CallingConv::AArch64Darwin;
case CC_Win64: return llvm::CallingConv::Win64;
case CC_X86_64SysV: return llvm::CallingConv::X86_64_SysV;
case CC_AAPCS: return llvm::CallingConv::ARM_AAPCS;
@@ -198,7 +200,8 @@
FTP);
}
-static CallingConv getCallingConventionForDecl(const Decl *D, bool IsWindows) {
+static CallingConv getCallingConventionForDecl(const Decl *D, bool IsWindows,
+ bool IsDarwin) {
// Set the appropriate calling convention for the Function.
if (D->hasAttr<StdCallAttr>())
return CC_X86StdCall;
@@ -230,6 +233,9 @@
if (D->hasAttr<MSABIAttr>())
return IsWindows ? CC_C : CC_Win64;
+ if (D->hasAttr<DarwinABIAttr>())
+ return IsDarwin ? CC_C : CC_AArch64Darwin;
+
if (D->hasAttr<SysVABIAttr>())
return IsWindows ? CC_X86_64SysV : CC_C;
@@ -485,7 +491,9 @@
FunctionType::ExtInfo einfo;
bool IsWindows = getContext().getTargetInfo().getTriple().isOSWindows();
- einfo = einfo.withCallingConv(getCallingConventionForDecl(MD, IsWindows));
+ bool IsDarwin = getContext().getTargetInfo().getTriple().isOSDarwin();
+ einfo = einfo.withCallingConv(
+ getCallingConventionForDecl(MD, IsWindows, IsDarwin));
if (getContext().getLangOpts().ObjCAutoRefCount &&
MD->hasAttr<NSReturnsRetainedAttr>())
Index: clang/lib/Basic/Targets/AArch64.cpp
===================================================================
--- clang/lib/Basic/Targets/AArch64.cpp
+++ clang/lib/Basic/Targets/AArch64.cpp
@@ -513,6 +513,7 @@
case CC_PreserveAll:
case CC_OpenCLKernel:
case CC_AArch64VectorCall:
+ case CC_AArch64Darwin:
case CC_Win64:
return CCCR_OK;
default:
Index: clang/lib/AST/TypePrinter.cpp
===================================================================
--- clang/lib/AST/TypePrinter.cpp
+++ clang/lib/AST/TypePrinter.cpp
@@ -957,6 +957,9 @@
case CC_Win64:
OS << " __attribute__((ms_abi))";
break;
+ case CC_AArch64Darwin:
+ OS << " __attribute__((darwin_abi))";
+ break;
case CC_X86_64SysV:
OS << " __attribute__((sysv_abi))";
break;
@@ -1640,6 +1643,9 @@
case attr::VectorCall: OS << "vectorcall"; break;
case attr::Pascal: OS << "pascal"; break;
case attr::MSABI: OS << "ms_abi"; break;
+ case attr::DarwinABI:
+ OS << "darwin_abi";
+ break;
case attr::SysVABI: OS << "sysv_abi"; break;
case attr::RegCall: OS << "regcall"; break;
case attr::Pcs: {
Index: clang/lib/AST/Type.cpp
===================================================================
--- clang/lib/AST/Type.cpp
+++ clang/lib/AST/Type.cpp
@@ -3121,6 +3121,8 @@
case CC_X86Pascal: return "pascal";
case CC_X86VectorCall: return "vectorcall";
case CC_Win64: return "ms_abi";
+ case CC_AArch64Darwin:
+ return "darwin_abi";
case CC_X86_64SysV: return "sysv_abi";
case CC_X86RegCall : return "regcall";
case CC_AAPCS: return "aapcs";
@@ -3548,6 +3550,7 @@
case attr::AArch64VectorPcs:
case attr::Pascal:
case attr::MSABI:
+ case attr::DarwinABI:
case attr::SysVABI:
case attr::IntelOclBicc:
case attr::PreserveMost:
Index: clang/lib/AST/ItaniumMangle.cpp
===================================================================
--- clang/lib/AST/ItaniumMangle.cpp
+++ clang/lib/AST/ItaniumMangle.cpp
@@ -2900,6 +2900,8 @@
return "sysv_abi";
case CC_Win64:
return "ms_abi";
+ case CC_AArch64Darwin:
+ return "darwin_abi";
case CC_Swift:
return "swiftcall";
}
Index: clang/include/clang/Basic/Specifiers.h
===================================================================
--- clang/include/clang/Basic/Specifiers.h
+++ clang/include/clang/Basic/Specifiers.h
@@ -268,24 +268,25 @@
/// CallingConv - Specifies the calling convention that a function uses.
enum CallingConv {
- CC_C, // __attribute__((cdecl))
- CC_X86StdCall, // __attribute__((stdcall))
- CC_X86FastCall, // __attribute__((fastcall))
- CC_X86ThisCall, // __attribute__((thiscall))
- CC_X86VectorCall, // __attribute__((vectorcall))
- CC_X86Pascal, // __attribute__((pascal))
- CC_Win64, // __attribute__((ms_abi))
- CC_X86_64SysV, // __attribute__((sysv_abi))
- CC_X86RegCall, // __attribute__((regcall))
- CC_AAPCS, // __attribute__((pcs("aapcs")))
- CC_AAPCS_VFP, // __attribute__((pcs("aapcs-vfp")))
- CC_IntelOclBicc, // __attribute__((intel_ocl_bicc))
- CC_SpirFunction, // default for OpenCL functions on SPIR target
- CC_OpenCLKernel, // inferred for OpenCL kernels
- CC_Swift, // __attribute__((swiftcall))
- CC_PreserveMost, // __attribute__((preserve_most))
- CC_PreserveAll, // __attribute__((preserve_all))
+ CC_C, // __attribute__((cdecl))
+ CC_X86StdCall, // __attribute__((stdcall))
+ CC_X86FastCall, // __attribute__((fastcall))
+ CC_X86ThisCall, // __attribute__((thiscall))
+ CC_X86VectorCall, // __attribute__((vectorcall))
+ CC_X86Pascal, // __attribute__((pascal))
+ CC_Win64, // __attribute__((ms_abi))
+ CC_X86_64SysV, // __attribute__((sysv_abi))
+ CC_X86RegCall, // __attribute__((regcall))
+ CC_AAPCS, // __attribute__((pcs("aapcs")))
+ CC_AAPCS_VFP, // __attribute__((pcs("aapcs-vfp")))
+ CC_IntelOclBicc, // __attribute__((intel_ocl_bicc))
+ CC_SpirFunction, // default for OpenCL functions on SPIR target
+ CC_OpenCLKernel, // inferred for OpenCL kernels
+ CC_Swift, // __attribute__((swiftcall))
+ CC_PreserveMost, // __attribute__((preserve_most))
+ CC_PreserveAll, // __attribute__((preserve_all))
CC_AArch64VectorCall, // __attribute__((aarch64_vector_pcs))
+ CC_AArch64Darwin, // __attribute__((darwin_abi))
};
/// Checks whether the given calling convention supports variadic
Index: clang/include/clang/Basic/AttrDocs.td
===================================================================
--- clang/include/clang/Basic/AttrDocs.td
+++ clang/include/clang/Basic/AttrDocs.td
@@ -2252,6 +2252,15 @@
}];
}
+def DarwinABIDocs : Documentation {
+ let Category = DocCatCallingConvs;
+ let Content = [{
+On Linux ARM64 targets, this attribute changes the calling convention of
+a function to match the default convention used on Apple ARM64. This
+attribute has no effect on Apple targets or non-Linux ARM64 targets.
+ }];
+}
+
def StdCallDocs : Documentation {
let Category = DocCatCallingConvs;
let Content = [{
Index: clang/include/clang/Basic/Attr.td
===================================================================
--- clang/include/clang/Basic/Attr.td
+++ clang/include/clang/Basic/Attr.td
@@ -1477,6 +1477,12 @@
let Documentation = [MSABIDocs];
}
+def DarwinABI : DeclOrTypeAttr {
+ let Spellings = [GCC<"darwin_abi">];
+// let Subjects = [Function, ObjCMethod];
+ let Documentation = [DarwinABIDocs];
+}
+
def MSP430Interrupt : InheritableAttr, TargetSpecificAttr<TargetMSP430> {
// NOTE: If you add any additional spellings, ARMInterrupt's, MipsInterrupt's
// and AnyX86Interrupt's spellings must match.
Index: clang/include/clang-c/Index.h
===================================================================
--- clang/include/clang-c/Index.h
+++ clang/include/clang-c/Index.h
@@ -3394,6 +3394,7 @@
CXCallingConv_PreserveMost = 14,
CXCallingConv_PreserveAll = 15,
CXCallingConv_AArch64VectorCall = 16,
+ CXCallingConv_AArch64Darwin = 17,
CXCallingConv_Invalid = 100,
CXCallingConv_Unexposed = 200
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits