]> granicus.if.org Git - clang/commitdiff
Add support for coldcc to clang
authorPeter Collingbourne <peter@pcc.me.uk>
Fri, 22 Feb 2013 19:24:35 +0000 (19:24 +0000)
committerPeter Collingbourne <peter@pcc.me.uk>
Fri, 22 Feb 2013 19:24:35 +0000 (19:24 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@175912 91177308-0d34-0410-b5e6-96231b3b80d8

15 files changed:
docs/LanguageExtensions.rst
include/clang-c/Index.h
include/clang/AST/Type.h
include/clang/Basic/Attr.td
include/clang/Basic/Specifiers.h
include/clang/Basic/TargetInfo.h
lib/AST/DumpXML.cpp
lib/AST/Type.cpp
lib/AST/TypePrinter.cpp
lib/Basic/Targets.cpp
lib/CodeGen/CGCall.cpp
lib/Sema/SemaDeclAttr.cpp
lib/Sema/SemaType.cpp
test/CodeGen/coldcc.c [new file with mode: 0644]
tools/libclang/CXType.cpp

index 014e2645d86bc8c14a50ae8f5e43e7fb80298073..40459a445abcdf3423fe9a5a1385c50e0d0922f5 100644 (file)
@@ -1970,3 +1970,12 @@ Clang implements two kinds of checks with this attribute.
    In this case Clang does not warn because the format string ``s`` and
    the corresponding arguments are annotated.  If the arguments are
    incorrect, the caller of ``foo`` will receive a warning.
+
+LLVM-Specific Calling Conventions
+=================================
+
+Clang supports `LLVM's coldcc calling convention
+<http://llvm.org/docs/LangRef.html#calling-conventions>`_ via the ``coldcc``
+GNU-style attribute, or the ``clang::coldcc`` C++11 attribute.  However,
+this calling convention is not guaranteed to be ABI compatible between
+different versions of the compiler.
index c382fb17c1c2ddd95dc065e19917877226834c5b..12a8381ce10f116b1df2d9d2591e6c337e3d12a1 100644 (file)
@@ -2674,6 +2674,7 @@ enum CXCallingConv {
   CXCallingConv_AAPCS_VFP = 7,
   CXCallingConv_PnaclCall = 8,
   CXCallingConv_IntelOclBicc = 9,
+  CXCallingConv_Cold = 10,
 
   CXCallingConv_Invalid = 100,
   CXCallingConv_Unexposed = 200
index df285101e3e5f7fbee4246a141fcfa13ffdd99a2..2284300032893acc79962930d7db1e81b7eb7a44 100644 (file)
@@ -3323,6 +3323,7 @@ public:
     // No operand.
     attr_noreturn,
     attr_cdecl,
+    attr_coldcc,
     attr_fastcall,
     attr_stdcall,
     attr_thiscall,
index 70217d2beb0e9b02b8d7a80ec116c2e4da5befee..c3a44948b78ededaab1df0649377184489bbd5cf 100644 (file)
@@ -277,6 +277,10 @@ def Cold : InheritableAttr {
   let Spellings = [GNU<"cold">, CXX11<"gnu", "cold">];
 }
 
+def ColdCC : InheritableAttr {
+  let Spellings = [GNU<"coldcc">, CXX11<"clang", "coldcc">];
+}
+
 def Common : InheritableAttr {
   let Spellings = [GNU<"common">, CXX11<"gnu", "common">];
 }
index 8706179a1713fecd93252e34d061605fcbc74b2b..3f640b52619b39e7917e20ba6ca4a62e81834286 100644 (file)
@@ -188,6 +188,7 @@ namespace clang {
   enum CallingConv {
     CC_Default,
     CC_C,           // __attribute__((cdecl))
+    CC_Cold,        // __attribute__((coldcc))
     CC_X86StdCall,  // __attribute__((stdcall))
     CC_X86FastCall, // __attribute__((fastcall))
     CC_X86ThisCall, // __attribute__((thiscall))
@@ -198,6 +199,10 @@ namespace clang {
     CC_IntelOclBicc // __attribute__((intel_ocl_bicc))
   };
 
+  inline bool isTargetSpecific(CallingConv CC) {
+    return CC >= CC_X86StdCall;
+  }
+
 } // end namespace clang
 
 #endif // LLVM_CLANG_BASIC_SPECIFIERS_H
index deaa3eeb77237b339c362cf8b7864a88bdb0dcd2..9a8689af85a6c300c8fc4432100b70be1879d317 100644 (file)
@@ -754,13 +754,7 @@ public:
   /// and be substituted with the default calling convention, or (someday)
   /// produce an error (such as using thiscall on a non-instance function).
   virtual CallingConvCheckResult checkCallingConvention(CallingConv CC) const {
-    switch (CC) {
-      default:
-        return CCCR_Warning;
-      case CC_C:
-      case CC_Default:
-        return CCCR_OK;
-    }
+    return CCCR_Warning;
   }
 
 protected:
index be22ae450b62abf0fa9b2b4873844260a45a2a06..230f2df29cb9ba4d7ee602a7813ec2f5e317832a 100644 (file)
@@ -925,6 +925,7 @@ struct XMLDumper : public XMLDeclVisitor<XMLDumper>,
     case CC_AAPCS_VFP: return set("cc", "aapcs_vfp");
     case CC_PnaclCall: return set("cc", "pnaclcall");
     case CC_IntelOclBicc: return set("cc", "intel_ocl_bicc");
+    case CC_Cold: return set("cc", "coldcc");
     }
   }
 
index efd588a57a6f20ec02b715f73862bba0b92e8a59..0cadba2749391d63bc70a10380c7b3ac836ef7aa 100644 (file)
@@ -1547,6 +1547,7 @@ StringRef FunctionType::getNameForCallConv(CallingConv CC) {
     llvm_unreachable("no name for default cc");
 
   case CC_C: return "cdecl";
+  case CC_Cold: return "coldcc";
   case CC_X86StdCall: return "stdcall";
   case CC_X86FastCall: return "fastcall";
   case CC_X86ThisCall: return "thiscall";
index 9d1717a220cdf3b6a7b32bdbdb3eb444e658ea2b..751e2982137fa077a384a6508044c68f6ebcaff5 100644 (file)
@@ -626,6 +626,9 @@ void TypePrinter::printFunctionProtoAfter(const FunctionProtoType *T,
   case CC_C:
     OS << " __attribute__((cdecl))";
     break;
+  case CC_Cold:
+    OS << " __attribute__((coldcc))";
+    break;
   case CC_X86StdCall:
     OS << " __attribute__((stdcall))";
     break;
@@ -1156,6 +1159,7 @@ void TypePrinter::printAttributedAfter(const AttributedType *T,
 
   case AttributedType::attr_noreturn: OS << "noreturn"; break;
   case AttributedType::attr_cdecl: OS << "cdecl"; break;
+  case AttributedType::attr_coldcc: OS << "coldcc"; break;
   case AttributedType::attr_fastcall: OS << "fastcall"; break;
   case AttributedType::attr_stdcall: OS << "stdcall"; break;
   case AttributedType::attr_thiscall: OS << "thiscall"; break;
index eaf2e7d05e6eddf1fdf103cabe5389fdac03aa65..bd80409bd226de8f1950d2d1df10a1793a1eed19 100644 (file)
@@ -1933,8 +1933,7 @@ public:
     // We accept all non-ARM calling conventions
     return (CC == CC_X86ThisCall ||
             CC == CC_X86FastCall ||
-            CC == CC_X86StdCall || 
-            CC == CC_C || 
+            CC == CC_X86StdCall ||
             CC == CC_X86Pascal ||
             CC == CC_IntelOclBicc) ? CCCR_OK : CCCR_Warning;
   }
@@ -3027,9 +3026,7 @@ public:
   }
 
   virtual CallingConvCheckResult checkCallingConvention(CallingConv CC) const {
-    return (CC == CC_Default ||
-            CC == CC_C || 
-            CC == CC_IntelOclBicc) ? CCCR_OK : CCCR_Warning;
+    return CC == CC_IntelOclBicc ? CCCR_OK : CCCR_Warning;
   }
 
   virtual CallingConv getDefaultCallingConv(CallingConvMethodType MT) const {
index 9fd31fe253f5d12350dca5f806af851e39199a07..f2c2d0a85d4c3223212fdf7613a6b1986ff04020 100644 (file)
@@ -37,6 +37,7 @@ using namespace CodeGen;
 static unsigned ClangCallConvToLLVMCallConv(CallingConv CC) {
   switch (CC) {
   default: return llvm::CallingConv::C;
+  case CC_Cold: return llvm::CallingConv::Cold;
   case CC_X86StdCall: return llvm::CallingConv::X86_StdCall;
   case CC_X86FastCall: return llvm::CallingConv::X86_FastCall;
   case CC_X86ThisCall: return llvm::CallingConv::X86_ThisCall;
@@ -135,6 +136,9 @@ CodeGenTypes::arrangeFreeFunctionType(CanQual<FunctionProtoType> FTP) {
 
 static CallingConv getCallingConventionForDecl(const Decl *D) {
   // Set the appropriate calling convention for the Function.
+  if (D->hasAttr<ColdCCAttr>())
+    return CC_Cold;
+
   if (D->hasAttr<StdCallAttr>())
     return CC_X86StdCall;
 
index 5f6f81de148f4c1f8efdaef7b4a473969a7c3077..d764bee097f1609f1fe11dc70afe8fc0f4318775 100644 (file)
@@ -3859,6 +3859,11 @@ static void handleCallConvAttr(Sema &S, Decl *D, const AttributeList &Attr) {
   }
 
   switch (Attr.getKind()) {
+  case AttributeList::AT_ColdCC:
+    D->addAttr(::new (S.Context)
+               ColdCCAttr(Attr.getRange(), S.Context,
+                          Attr.getAttributeSpellingListIndex()));
+    return;
   case AttributeList::AT_FastCall:
     D->addAttr(::new (S.Context)
                FastCallAttr(Attr.getRange(), S.Context,
@@ -3939,6 +3944,7 @@ bool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC,
   // move to TargetAttributesSema one day.
   switch (attr.getKind()) {
   case AttributeList::AT_CDecl: CC = CC_C; break;
+  case AttributeList::AT_ColdCC: CC = CC_Cold; break;
   case AttributeList::AT_FastCall: CC = CC_X86FastCall; break;
   case AttributeList::AT_StdCall: CC = CC_X86StdCall; break;
   case AttributeList::AT_ThisCall: CC = CC_X86ThisCall; break;
@@ -3971,6 +3977,9 @@ bool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC,
   default: llvm_unreachable("unexpected attribute kind");
   }
 
+  if (!isTargetSpecific(CC))
+    return false;
+
   const TargetInfo &TI = Context.getTargetInfo();
   TargetInfo::CallingConvCheckResult A = TI.checkCallingConvention(CC);
   if (A == TargetInfo::CCCR_Warning) {
@@ -4774,6 +4783,7 @@ static void ProcessInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,
     break;
   case AttributeList::AT_StdCall:
   case AttributeList::AT_CDecl:
+  case AttributeList::AT_ColdCC:
   case AttributeList::AT_FastCall:
   case AttributeList::AT_ThisCall:
   case AttributeList::AT_Pascal:
index c47a7f59ac04c072a473113032eb8ff01a85df2b..402e522eeb0249b876f3390f056f0055d2be2aae 100644 (file)
@@ -100,6 +100,7 @@ static void diagnoseBadTypeAttribute(Sema &S, const AttributeList &attr,
 #define FUNCTION_TYPE_ATTRS_CASELIST \
     case AttributeList::AT_NoReturn: \
     case AttributeList::AT_CDecl: \
+    case AttributeList::AT_ColdCC: \
     case AttributeList::AT_FastCall: \
     case AttributeList::AT_StdCall: \
     case AttributeList::AT_ThisCall: \
@@ -3103,6 +3104,8 @@ static AttributeList::Kind getAttrListKind(AttributedType::Kind kind) {
     return AttributeList::AT_NoReturn;
   case AttributedType::attr_cdecl:
     return AttributeList::AT_CDecl;
+  case AttributedType::attr_coldcc:
+    return AttributeList::AT_ColdCC;
   case AttributedType::attr_fastcall:
     return AttributeList::AT_FastCall;
   case AttributedType::attr_stdcall:
diff --git a/test/CodeGen/coldcc.c b/test/CodeGen/coldcc.c
new file mode 100644 (file)
index 0000000..8965cad
--- /dev/null
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown -Werror -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Werror -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple armv7-unknown-unknown -Werror -emit-llvm -o - %s | FileCheck %s
+
+void __attribute__((coldcc)) f1(void);
+
+void f2(void) {
+  f1();
+// CHECK: call coldcc void @f1()
+}
+
+// CHECK: declare coldcc void @f1()
index 945eb11427f3c833c00d48fe6efd4fb6d2359b41..90175c7980e6817a91311997c1ab9928c0b4c756 100644 (file)
@@ -500,6 +500,7 @@ CXCallingConv clang_getFunctionTypeCallingConv(CXType X) {
       TCALLINGCONV(AAPCS_VFP);
       TCALLINGCONV(PnaclCall);
       TCALLINGCONV(IntelOclBicc);
+      TCALLINGCONV(Cold);
     }
 #undef TCALLINGCONV
   }