]> granicus.if.org Git - clang/commitdiff
Handle CC and NoReturn when instantiating members of class templates.
authorRafael Espindola <rafael.espindola@gmail.com>
Sun, 1 Dec 2013 16:54:29 +0000 (16:54 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Sun, 1 Dec 2013 16:54:29 +0000 (16:54 +0000)
Before we were considering them only when instantiating templates.

This fixes pr18033.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@196050 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Sema/Sema.h
lib/Sema/SemaTemplate.cpp
lib/Sema/SemaTemplateDeduction.cpp
test/SemaCXX/decl-microsoft-call-conv.cpp

index fbb46ff60b8250881baaa49ed63f34b4e7356cdb..06edb443cdef0f72278f07a6e84fc3997b4c023d 100644 (file)
@@ -5776,6 +5776,8 @@ public:
   // C++ Template Argument Deduction (C++ [temp.deduct])
   //===--------------------------------------------------------------------===//
 
+  QualType adjustCCAndNoReturn(QualType ArgFunctionType, QualType FunctionType);
+
   /// \brief Describes the result of template argument deduction.
   ///
   /// The TemplateDeductionResult enumeration describes the result of
index e995ae1c36e8b81a2d8a4baa59c416a90e155556..7b901d2df876ca9ed3fe1ede316b37a438f287ce 100644 (file)
@@ -7436,7 +7436,8 @@ DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
     NamedDecl *Prev = *P;
     if (!HasExplicitTemplateArgs) {
       if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Prev)) {
-        if (Context.hasSameUnqualifiedType(Method->getType(), R)) {
+        QualType Adjusted = adjustCCAndNoReturn(R, Method->getType());
+        if (Context.hasSameUnqualifiedType(Method->getType(), Adjusted)) {
           Matches.clear();
 
           Matches.addDecl(Method, P.getAccess());
index 56df8bab9ba7f295377d51dcdb53fca414086e19..8d66ff68efa64a4e5c8360379d6b11d2fffb0de5 100644 (file)
@@ -3501,6 +3501,28 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments(
                                          Specialization, Info, &OriginalCallArgs);
 }
 
+QualType Sema::adjustCCAndNoReturn(QualType ArgFunctionType,
+                                   QualType FunctionType) {
+  if (ArgFunctionType.isNull())
+    return ArgFunctionType;
+
+  const FunctionProtoType *FunctionTypeP =
+      FunctionType->castAs<FunctionProtoType>();
+  CallingConv CC = FunctionTypeP->getCallConv();
+  bool NoReturn = FunctionTypeP->getNoReturnAttr();
+  const FunctionProtoType *ArgFunctionTypeP =
+      ArgFunctionType->getAs<FunctionProtoType>();
+  if (ArgFunctionTypeP->getCallConv() == CC &&
+      ArgFunctionTypeP->getNoReturnAttr() == NoReturn)
+    return ArgFunctionType;
+
+  FunctionType::ExtInfo EI = ArgFunctionTypeP->getExtInfo().withCallingConv(CC);
+  EI = EI.withNoReturn(NoReturn);
+  ArgFunctionTypeP =
+      cast<FunctionProtoType>(Context.adjustFunctionType(ArgFunctionTypeP, EI));
+  return QualType(ArgFunctionTypeP, 0);
+}
+
 /// \brief Deduce template arguments when taking the address of a function
 /// template (C++ [temp.deduct.funcaddr]) or matching a specialization to
 /// a template.
@@ -3538,23 +3560,8 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
   TemplateParameterList *TemplateParams
     = FunctionTemplate->getTemplateParameters();
   QualType FunctionType = Function->getType();
-  if (!InOverloadResolution && !ArgFunctionType.isNull()) {
-    const FunctionProtoType *FunctionTypeP =
-        FunctionType->castAs<FunctionProtoType>();
-    CallingConv CC = FunctionTypeP->getCallConv();
-    bool NoReturn = FunctionTypeP->getNoReturnAttr();
-    const FunctionProtoType *ArgFunctionTypeP =
-        ArgFunctionType->getAs<FunctionProtoType>();
-    if (ArgFunctionTypeP->getCallConv() != CC ||
-        ArgFunctionTypeP->getNoReturnAttr() != NoReturn) {
-      FunctionType::ExtInfo EI =
-          ArgFunctionTypeP->getExtInfo().withCallingConv(CC);
-      EI = EI.withNoReturn(NoReturn);
-      ArgFunctionTypeP = cast<FunctionProtoType>(
-          Context.adjustFunctionType(ArgFunctionTypeP, EI));
-      ArgFunctionType = QualType(ArgFunctionTypeP, 0);
-    }
-  }
+  if (!InOverloadResolution)
+    ArgFunctionType = adjustCCAndNoReturn(ArgFunctionType, FunctionType);
 
   // Substitute any explicit template arguments.
   LocalInstantiationScope InstScope(*this);
index a1a6d0b28951d8d31471c61e542234d3d4abb4e7..9f1463245ba29c89b673a5cbd7df0104150e0874 100644 (file)
@@ -183,3 +183,11 @@ namespace test4 {
   };
   extern template void foo::bar(const void *);
 }
+
+namespace test5 {
+  template <class T>
+  class valarray {
+    void bar();
+  };
+  extern template void valarray<int>::bar();
+}