Index: include/clang-c/Index.h =================================================================== --- include/clang-c/Index.h +++ include/clang-c/Index.h @@ -2971,6 +2971,8 @@ CXCallingConv_X86_64SysV = 11, CXCallingConv_X86VectorCall = 12, CXCallingConv_Swift = 13, + CXCallingConv_PreserveMost = 14, + CXCallingConv_PreserveAll = 15, CXCallingConv_Invalid = 100, CXCallingConv_Unexposed = 200 Index: include/clang/AST/Type.h =================================================================== --- include/clang/AST/Type.h +++ include/clang/AST/Type.h @@ -3740,6 +3740,8 @@ attr_inteloclbicc, attr_ms_abi, attr_sysv_abi, + attr_preserve_most, + attr_preserve_all, attr_ptr32, attr_ptr64, attr_sptr, Index: include/clang/Basic/Attr.td =================================================================== --- include/clang/Basic/Attr.td +++ include/clang/Basic/Attr.td @@ -1391,6 +1391,16 @@ let Documentation = [Undocumented]; } +def PreserveMost : InheritableAttr { + let Spellings = [GNU<"preserve_most">]; + let Documentation = [Undocumented]; +} + +def PreserveAll : InheritableAttr { + let Spellings = [GNU<"preserve_all">]; + let Documentation = [Undocumented]; +} + def Target : InheritableAttr { let Spellings = [GCC<"target">]; let Args = [StringArgument<"featuresStr">]; Index: include/clang/Basic/Specifiers.h =================================================================== --- include/clang/Basic/Specifiers.h +++ include/clang/Basic/Specifiers.h @@ -239,7 +239,9 @@ CC_IntelOclBicc, // __attribute__((intel_ocl_bicc)) CC_SpirFunction, // default for OpenCL functions on SPIR target CC_SpirKernel, // inferred for OpenCL kernels on SPIR target - CC_Swift // __attribute__((swiftcall)) + CC_Swift, // __attribute__((swiftcall)) + CC_PreserveMost, // __attribute__((preserve_most)) + CC_PreserveAll, // __attribute__((preserve_all)) }; /// \brief Checks whether the given calling convention supports variadic Index: lib/AST/ItaniumMangle.cpp =================================================================== --- lib/AST/ItaniumMangle.cpp +++ lib/AST/ItaniumMangle.cpp @@ -2165,6 +2165,8 @@ case CC_IntelOclBicc: case CC_SpirFunction: case CC_SpirKernel: + case CC_PreserveMost: + case CC_PreserveAll: // FIXME: we should be mangling all of the above. return ""; Index: lib/AST/Type.cpp =================================================================== --- lib/AST/Type.cpp +++ lib/AST/Type.cpp @@ -2656,6 +2656,8 @@ case CC_SpirFunction: return "spir_function"; case CC_SpirKernel: return "spir_kernel"; case CC_Swift: return "swiftcall"; + case CC_PreserveMost: return "preserve_most"; + case CC_PreserveAll: return "preserve_all"; } llvm_unreachable("Invalid calling convention."); @@ -2999,6 +3001,8 @@ case AttributedType::attr_swiftcall: case AttributedType::attr_vectorcall: case AttributedType::attr_inteloclbicc: + case AttributedType::attr_preserve_most: + case AttributedType::attr_preserve_all: case AttributedType::attr_ms_abi: case AttributedType::attr_sysv_abi: case AttributedType::attr_ptr32: @@ -3056,6 +3060,8 @@ case attr_ms_abi: case attr_sysv_abi: case attr_inteloclbicc: + case attr_preserve_most: + case attr_preserve_all: return true; } llvm_unreachable("invalid attr kind"); Index: lib/AST/TypePrinter.cpp =================================================================== --- lib/AST/TypePrinter.cpp +++ lib/AST/TypePrinter.cpp @@ -726,6 +726,13 @@ break; case CC_Swift: OS << " __attribute__((swiftcall))"; + break; + case CC_PreserveMost: + OS << " __attribute__((preserve_most))"; + break; + case CC_PreserveAll: + OS << " __attribute__((preserve_all))"; + break; } } @@ -1345,6 +1352,12 @@ break; } case AttributedType::attr_inteloclbicc: OS << "inteloclbicc"; break; + case AttributedType::attr_preserve_most: + OS << "preserve_most"; + break; + case AttributedType::attr_preserve_all: + OS << "preserve_all"; + break; } OS << "))"; } Index: lib/Basic/Targets.cpp =================================================================== --- lib/Basic/Targets.cpp +++ lib/Basic/Targets.cpp @@ -4095,6 +4095,8 @@ case CC_X86VectorCall: case CC_IntelOclBicc: case CC_X86_64Win64: + case CC_PreserveMost: + case CC_PreserveAll: return CCCR_OK; default: return CCCR_Warning; @@ -5545,6 +5547,8 @@ switch (CC) { case CC_C: case CC_Swift: + case CC_PreserveMost: + case CC_PreserveAll: return CCCR_OK; default: return CCCR_Warning; Index: lib/CodeGen/CGCall.cpp =================================================================== --- lib/CodeGen/CGCall.cpp +++ lib/CodeGen/CGCall.cpp @@ -57,6 +57,10 @@ case CC_X86VectorCall: return llvm::CallingConv::X86_VectorCall; case CC_SpirFunction: return llvm::CallingConv::SPIR_FUNC; case CC_SpirKernel: return llvm::CallingConv::SPIR_KERNEL; + case CC_PreserveMost: + return llvm::CallingConv::PreserveMost; + case CC_PreserveAll: + return llvm::CallingConv::PreserveAll; } } @@ -174,6 +178,12 @@ if (D->hasAttr()) return IsWindows ? CC_X86_64SysV : CC_C; + if (D->hasAttr()) + return CC_PreserveMost; + + if (D->hasAttr()) + return CC_PreserveAll; + return CC_C; } Index: lib/Sema/SemaDeclAttr.cpp =================================================================== --- lib/Sema/SemaDeclAttr.cpp +++ lib/Sema/SemaDeclAttr.cpp @@ -3777,7 +3777,14 @@ IntelOclBiccAttr(Attr.getRange(), S.Context, Attr.getAttributeSpellingListIndex())); return; - + case AttributeList::AT_PreserveMost: + D->addAttr(::new (S.Context) PreserveMostAttr( + Attr.getRange(), S.Context, Attr.getAttributeSpellingListIndex())); + return; + case AttributeList::AT_PreserveAll: + D->addAttr(::new (S.Context) PreserveAllAttr( + Attr.getRange(), S.Context, Attr.getAttributeSpellingListIndex())); + return; default: llvm_unreachable("unexpected attribute kind"); } @@ -3835,6 +3842,12 @@ return true; } case AttributeList::AT_IntelOclBicc: CC = CC_IntelOclBicc; break; + case AttributeList::AT_PreserveMost: + CC = CC_PreserveMost; + break; + case AttributeList::AT_PreserveAll: + CC = CC_PreserveAll; + break; default: llvm_unreachable("unexpected attribute kind"); } @@ -5597,6 +5610,8 @@ case AttributeList::AT_SysVABI: case AttributeList::AT_Pcs: case AttributeList::AT_IntelOclBicc: + case AttributeList::AT_PreserveMost: + case AttributeList::AT_PreserveAll: handleCallConvAttr(S, D, Attr); break; case AttributeList::AT_OpenCLKernel: Index: lib/Sema/SemaType.cpp =================================================================== --- lib/Sema/SemaType.cpp +++ lib/Sema/SemaType.cpp @@ -112,7 +112,9 @@ case AttributeList::AT_MSABI: \ case AttributeList::AT_SysVABI: \ case AttributeList::AT_Pcs: \ - case AttributeList::AT_IntelOclBicc + case AttributeList::AT_IntelOclBicc: \ + case AttributeList::AT_PreserveMost: \ + case AttributeList::AT_PreserveAll // Function type attributes. #define FUNCTION_TYPE_ATTRS_CASELIST \ @@ -4639,6 +4641,10 @@ return AttributeList::AT_MSABI; case AttributedType::attr_sysv_abi: return AttributeList::AT_SysVABI; + case AttributedType::attr_preserve_most: + return AttributeList::AT_PreserveMost; + case AttributedType::attr_preserve_all: + return AttributeList::AT_PreserveAll; case AttributedType::attr_ptr32: return AttributeList::AT_Ptr32; case AttributedType::attr_ptr64: @@ -5974,6 +5980,10 @@ return AttributedType::attr_ms_abi; case AttributeList::AT_SysVABI: return AttributedType::attr_sysv_abi; + case AttributeList::AT_PreserveMost: + return AttributedType::attr_preserve_most; + case AttributeList::AT_PreserveAll: + return AttributedType::attr_preserve_all; } llvm_unreachable("unexpected attribute kind!"); } Index: test/CodeGen/preserve_all.c =================================================================== --- test/CodeGen/preserve_all.c +++ test/CodeGen/preserve_all.c @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm < %s | FileCheck %s +// RUN: %clang_cc1 -triple arm64-unknown-unknown -emit-llvm < %s | FileCheck %s + +// Check that the preserve_most calling convention attribute at the source level +// is lowered to the corresponding calling convention attrribute at the LLVM IR +// level. +void foo() __attribute__((preserve_all)) { + // CHECK-LABEL: define preserve_allcc void @foo() +} + Index: test/CodeGen/preserve_most.c =================================================================== --- test/CodeGen/preserve_most.c +++ test/CodeGen/preserve_most.c @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm < %s | FileCheck %s +// RUN: %clang_cc1 -triple arm64-unknown-unknown -emit-llvm < %s | FileCheck %s + +// Check that the preserve_most calling convention attribute at the source level +// is lowered to the corresponding calling convention attrribute at the LLVM IR +// level. +void foo() __attribute__((preserve_most)) { + // CHECK-LABEL: define preserve_mostcc void @foo() +} + Index: tools/libclang/CXType.cpp =================================================================== --- tools/libclang/CXType.cpp +++ tools/libclang/CXType.cpp @@ -534,6 +534,8 @@ TCALLINGCONV(AAPCS_VFP); TCALLINGCONV(IntelOclBicc); TCALLINGCONV(Swift); + TCALLINGCONV(PreserveMost); + TCALLINGCONV(PreserveAll); case CC_SpirFunction: return CXCallingConv_Unexposed; case CC_SpirKernel: return CXCallingConv_Unexposed; break;