r196855 - Take into consideration calling convention when processing specializations.

Rafael Espindola rafael.espindola at gmail.com
Mon Dec 9 16:59:31 PST 2013


Author: rafael
Date: Mon Dec  9 18:59:31 2013
New Revision: 196855

URL: http://llvm.org/viewvc/llvm-project?rev=196855&view=rev
Log:
Take into consideration calling convention when processing specializations.

This fixes pr18141.

Modified:
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaTemplate.cpp
    cfe/trunk/lib/Sema/SemaType.cpp
    cfe/trunk/test/SemaCXX/decl-microsoft-call-conv.cpp

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=196855&r1=196854&r2=196855&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Mon Dec  9 18:59:31 2013
@@ -2570,6 +2570,11 @@ public:
   /// function type typedefs and typename template arguments.
   void adjustMemberFunctionCC(QualType &T, bool IsStatic);
 
+  // Check if there is an explicit attribute, but only look through parens.
+  // The intent is to look for an attribute on the current declarator, but not
+  // one that came from a typedef.
+  bool hasExplicitCallingConv(QualType &T);
+
   /// Get the outermost AttributedType node that sets a calling convention.
   /// Valid types should not have multiple attributes with different CCs.
   const AttributedType *getCallingConvAttributedType(QualType T) const;

Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=196855&r1=196854&r2=196855&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Mon Dec  9 18:59:31 2013
@@ -6654,7 +6654,10 @@ Sema::CheckMemberSpecialization(NamedDec
            I != E; ++I) {
       NamedDecl *D = (*I)->getUnderlyingDecl();
       if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) {
-        if (Context.hasSameType(Function->getType(), Method->getType())) {
+        QualType Adjusted = Function->getType();
+        if (!hasExplicitCallingConv(Adjusted))
+          Adjusted = adjustCCAndNoReturn(Adjusted, Method->getType());
+        if (Context.hasSameType(Adjusted, Method->getType())) {
           Instantiation = Method;
           InstantiatedFrom = Method->getInstantiatedFromMemberFunction();
           MSInfo = Method->getMemberSpecializationInfo();

Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=196855&r1=196854&r2=196855&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Mon Dec  9 18:59:31 2013
@@ -4595,6 +4595,16 @@ static bool handleFunctionTypeAttr(TypeP
   return true;
 }
 
+bool Sema::hasExplicitCallingConv(QualType &T) {
+  QualType R = T.IgnoreParens();
+  while (const AttributedType *AT = dyn_cast<AttributedType>(R)) {
+    if (AT->isCallingConv())
+      return true;
+    R = AT->getModifiedType().IgnoreParens();
+  }
+  return false;
+}
+
 void Sema::adjustMemberFunctionCC(QualType &T, bool IsStatic) {
   FunctionTypeUnwrapper Unwrapped(*this, T);
   const FunctionType *FT = Unwrapped.get();
@@ -4611,15 +4621,8 @@ void Sema::adjustMemberFunctionCC(QualTy
   if (CurCC != FromCC || FromCC == ToCC)
     return;
 
-  // Check if there was an explicit attribute, but only look through parens.
-  // The intent is to look for an attribute on the current declarator, but not
-  // one that came from a typedef.
-  QualType R = T.IgnoreParens();
-  while (const AttributedType *AT = dyn_cast<AttributedType>(R)) {
-    if (AT->isCallingConv())
-      return;
-    R = AT->getModifiedType().IgnoreParens();
-  }
+  if (hasExplicitCallingConv(T))
+    return;
 
   FT = Context.adjustFunctionType(FT, FT->getExtInfo().withCallingConv(ToCC));
   QualType Wrapped = Unwrapped.wrap(*this, FT);

Modified: cfe/trunk/test/SemaCXX/decl-microsoft-call-conv.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/decl-microsoft-call-conv.cpp?rev=196855&r1=196854&r2=196855&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/decl-microsoft-call-conv.cpp (original)
+++ cfe/trunk/test/SemaCXX/decl-microsoft-call-conv.cpp Mon Dec  9 18:59:31 2013
@@ -203,3 +203,29 @@ namespace test6 {
     zed(&foo::bar);
   }
 }
+
+namespace test7 {
+  template <typename T>
+  struct S {
+    void f(T t) {
+      t = 42;
+    }
+  };
+  template<> void S<void*>::f(void*);
+  void g(S<void*> s, void* p) {
+    s.f(p);
+  }
+}
+
+namespace test8 {
+  template <typename T>
+  struct S {
+    void f(T t) { // expected-note {{previous declaration is here}}
+      t = 42; // expected-error {{assigning to 'void *' from incompatible type 'int'}}
+    }
+  };
+  template<> void __cdecl S<void*>::f(void*); // expected-error {{function declared 'cdecl' here was previously declared without calling convention}}
+  void g(S<void*> s, void* p) {
+    s.f(p); // expected-note {{in instantiation of member function 'test8::S<void *>::f' requested here}}
+  }
+}





More information about the cfe-commits mailing list