a.makarov updated this revision to Diff 43440.
a.makarov added a comment.

I've updated the patch. Please, re-review it again.
About creating attributed type - I think we shouldn't create it if we ignored 
specified CC attribute. Ignoring specified CC attribute (and emitting the 
warning, of course) leads to substituting it by default; calling convention, 
substituted by default, is the same situation like there is no CC attribute 
specified for chosen function. Thus, from this point of view, we should not 
create AttributedType.


http://reviews.llvm.org/D15373

Files:
  include/clang/Sema/Sema.h
  lib/Sema/SemaDeclAttr.cpp
  lib/Sema/SemaType.cpp
  test/CodeGen/adding_defaulted_attr_to_type.c
  test/Sema/callingconv.c

Index: lib/Sema/SemaType.cpp
===================================================================
--- lib/Sema/SemaType.cpp
+++ lib/Sema/SemaType.cpp
@@ -5913,7 +5913,19 @@
   FunctionType::ExtInfo EI = unwrapped.get()->getExtInfo().withCallingConv(CC);
   QualType Equivalent =
       unwrapped.wrap(S, S.Context.adjustFunctionType(unwrapped.get(), EI));
-  type = S.Context.getAttributedType(CCAttrKind, type, Equivalent);
+
+  // We should add attribute specifier to type only if we didn't subsitute
+  // 'default' calling convention instead of the one provided by the attribute.
+  CallingConv RawCC;
+  bool RecognizedAttr = S.getCCFromAttr(attr, RawCC);
+  assert(!RecognizedAttr &&
+         "Somehow ill-formed calling convention attribute reached here!");
+  TargetInfo::CallingConvCheckResult CCResult =
+      S.Context.getTargetInfo().checkCallingConvention(RawCC);
+  // If calling convention is available (CCCR_OK) or default (CCCR_Ignored), add
+  // it to type.
+  if (CCResult != TargetInfo::CCCR_Warning)
+    type = S.Context.getAttributedType(CCAttrKind, type, Equivalent);
   return true;
 }
 
Index: lib/Sema/SemaDeclAttr.cpp
===================================================================
--- lib/Sema/SemaDeclAttr.cpp
+++ lib/Sema/SemaDeclAttr.cpp
@@ -3701,8 +3701,11 @@
   }
 }
 
-bool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC, 
-                                const FunctionDecl *FD) {
+/// This function simply dispatches passed attribute to corresponding
+/// calling convention.
+/// If attribute is ill-formed, it returns 'true' and makes marks attribute as
+/// invalid.
+bool Sema::getCCFromAttr(const AttributeList &attr, CallingConv &CC) {
   if (attr.isInvalid())
     return true;
 
@@ -3714,19 +3717,31 @@
 
   // TODO: diagnose uses of these conventions on the wrong target.
   switch (attr.getKind()) {
-  case AttributeList::AT_CDecl: CC = CC_C; 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;
-  case AttributeList::AT_Pascal: CC = CC_X86Pascal; break;
-  case AttributeList::AT_VectorCall: CC = CC_X86VectorCall; break;
+  case AttributeList::AT_CDecl:
+    CC = CC_C;
+    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;
+  case AttributeList::AT_Pascal:
+    CC = CC_X86Pascal;
+    break;
+  case AttributeList::AT_VectorCall:
+    CC = CC_X86VectorCall;
+    break;
   case AttributeList::AT_MSABI:
-    CC = Context.getTargetInfo().getTriple().isOSWindows() ? CC_C :
-                                                             CC_X86_64Win64;
+    CC = Context.getTargetInfo().getTriple().isOSWindows() ? CC_C
+                                                           : CC_X86_64Win64;
     break;
   case AttributeList::AT_SysVABI:
-    CC = Context.getTargetInfo().getTriple().isOSWindows() ? CC_X86_64SysV :
-                                                             CC_C;
+    CC = Context.getTargetInfo().getTriple().isOSWindows() ? CC_X86_64SysV
+                                                           : CC_C;
     break;
   case AttributeList::AT_Pcs: {
     StringRef StrRef;
@@ -3741,13 +3756,27 @@
       CC = CC_AAPCS_VFP;
       break;
     }
-
     attr.setInvalid();
     Diag(attr.getLoc(), diag::err_invalid_pcs);
     return true;
   }
-  case AttributeList::AT_IntelOclBicc: CC = CC_IntelOclBicc; break;
-  default: llvm_unreachable("unexpected attribute kind");
+  case AttributeList::AT_IntelOclBicc:
+    CC = CC_IntelOclBicc;
+    break;
+  default:
+    llvm_unreachable("unexpected attribute kind");
+  }
+  return false;
+}
+
+bool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC, 
+                                const FunctionDecl *FD) {
+  if (attr.isInvalid())
+    return true;
+
+  if (getCCFromAttr(attr, CC)) {
+    assert(attr.isInvalid() && "Error occured but attribute is not invalid!");
+    return true;
   }
 
   const TargetInfo &TI = Context.getTargetInfo();
Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h
+++ include/clang/Sema/Sema.h
@@ -2935,6 +2935,7 @@
   bool isValidPointerAttrType(QualType T, bool RefOkay = false);
 
   bool CheckRegparmAttr(const AttributeList &attr, unsigned &value);
+  bool getCCFromAttr(const AttributeList &attr, CallingConv &CC);
   bool CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC, 
                             const FunctionDecl *FD = nullptr);
   bool CheckNoReturnAttr(const AttributeList &attr);
Index: test/CodeGen/adding_defaulted_attr_to_type.c
===================================================================
--- test/CodeGen/adding_defaulted_attr_to_type.c
+++ test/CodeGen/adding_defaulted_attr_to_type.c
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -verify -emit-llvm -o - %s | FileCheck %s
+
+void (__attribute__ ((regparm (3), stdcall )) *f) (int); // expected-warning {{calling convention 'stdcall' ignored for this target}}
+
+// CHECK: @f = common global void (i32)*
Index: test/Sema/callingconv.c
===================================================================
--- test/Sema/callingconv.c
+++ test/Sema/callingconv.c
@@ -66,3 +66,6 @@
 void __attribute__((stdcall)) typedef_fun(int x) { } // expected-error {{function declared 'stdcall' here was previously declared without calling convention}}
 
 struct type_test {} __attribute__((stdcall));  // expected-warning {{'stdcall' attribute only applies to functions and methods}}
+
+
+void (__attribute__ ((regparm (3), stdcall("abacaba") )) *test_ignored) (int); // expected-error {{'stdcall' attribute takes no arguments}}
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to