[cfe-commits] r95528 - in /cfe/trunk: lib/Sema/SemaTemplateDeduction.cpp test/SemaTemplate/deduction.cpp

Chandler Carruth chandlerc at gmail.com
Sun Feb 7 13:33:29 PST 2010


Author: chandlerc
Date: Sun Feb  7 15:33:28 2010
New Revision: 95528

URL: http://llvm.org/viewvc/llvm-project?rev=95528&view=rev
Log:
Require a complete type before examining base classes during template argument
deduction. This requires refactoring the deduction to have access to the Sema
object instead of merely the ASTContext. Still leaves something to be desired
due to poor source location.

Fixes PR6257 and half of PR6259.

Modified:
    cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
    cfe/trunk/test/SemaTemplate/deduction.cpp

Modified: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp?rev=95528&r1=95527&r2=95528&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Sun Feb  7 15:33:28 2010
@@ -49,7 +49,7 @@
 using namespace clang;
 
 static Sema::TemplateDeductionResult
-DeduceTemplateArguments(ASTContext &Context,
+DeduceTemplateArguments(Sema &S,
                         TemplateParameterList *TemplateParams,
                         const TemplateArgument &Param,
                         const TemplateArgument &Arg,
@@ -72,7 +72,7 @@
 /// \brief Deduce the value of the given non-type template parameter
 /// from the given constant.
 static Sema::TemplateDeductionResult
-DeduceNonTypeTemplateArgument(ASTContext &Context,
+DeduceNonTypeTemplateArgument(Sema &S,
                               NonTypeTemplateParmDecl *NTTP,
                               llvm::APSInt Value,
                               Sema::TemplateDeductionInfo &Info,
@@ -84,7 +84,7 @@
     QualType T = NTTP->getType();
 
     // FIXME: Make sure we didn't overflow our data type!
-    unsigned AllowedBits = Context.getTypeSize(T);
+    unsigned AllowedBits = S.Context.getTypeSize(T);
     if (Value.getBitWidth() != AllowedBits)
       Value.extOrTrunc(AllowedBits);
     Value.setIsSigned(T->isSignedIntegerType());
@@ -126,7 +126,7 @@
 ///
 /// \returns true if deduction succeeded, false otherwise.
 static Sema::TemplateDeductionResult
-DeduceNonTypeTemplateArgument(ASTContext &Context,
+DeduceNonTypeTemplateArgument(Sema &S,
                               NonTypeTemplateParmDecl *NTTP,
                               Expr *Value,
                               Sema::TemplateDeductionInfo &Info,
@@ -152,8 +152,8 @@
   if (Deduced[NTTP->getIndex()].getKind() == TemplateArgument::Expression) {
     // Compare the expressions for equality
     llvm::FoldingSetNodeID ID1, ID2;
-    Deduced[NTTP->getIndex()].getAsExpr()->Profile(ID1, Context, true);
-    Value->Profile(ID2, Context, true);
+    Deduced[NTTP->getIndex()].getAsExpr()->Profile(ID1, S.Context, true);
+    Value->Profile(ID2, S.Context, true);
     if (ID1 == ID2)
       return Sema::TDK_Success;
    
@@ -169,7 +169,7 @@
 ///
 /// \returns true if deduction succeeded, false otherwise.
 static Sema::TemplateDeductionResult
-DeduceNonTypeTemplateArgument(ASTContext &Context,
+DeduceNonTypeTemplateArgument(Sema &S,
                               NonTypeTemplateParmDecl *NTTP,
                               Decl *D,
                               Sema::TemplateDeductionInfo &Info,
@@ -202,7 +202,7 @@
 }
 
 static Sema::TemplateDeductionResult
-DeduceTemplateArguments(ASTContext &Context,
+DeduceTemplateArguments(Sema &S,
                         TemplateParameterList *TemplateParams,
                         TemplateName Param,
                         TemplateName Arg,
@@ -221,13 +221,13 @@
     TemplateArgument &ExistingArg = Deduced[TempParam->getIndex()];
     if (ExistingArg.isNull()) {
       // This is the first deduction for this template template parameter.
-      ExistingArg = TemplateArgument(Context.getCanonicalTemplateName(Arg));
+      ExistingArg = TemplateArgument(S.Context.getCanonicalTemplateName(Arg));
       return Sema::TDK_Success;
     }
     
     // Verify that the previous binding matches this deduction.
     assert(ExistingArg.getKind() == TemplateArgument::Template);
-    if (Context.hasSameTemplateName(ExistingArg.getAsTemplate(), Arg))
+    if (S.Context.hasSameTemplateName(ExistingArg.getAsTemplate(), Arg))
       return Sema::TDK_Success;
     
     // Inconsistent deduction.
@@ -238,7 +238,7 @@
   }
   
   // Verify that the two template names are equivalent.
-  if (Context.hasSameTemplateName(Param, Arg))
+  if (S.Context.hasSameTemplateName(Param, Arg))
     return Sema::TDK_Success;
   
   // Mismatch of non-dependent template parameter to argument.
@@ -250,7 +250,7 @@
 /// \brief Deduce the template arguments by comparing the template parameter
 /// type (which is a template-id) with the template argument type.
 ///
-/// \param Context the AST context in which this deduction occurs.
+/// \param S the Sema
 ///
 /// \param TemplateParams the template parameters that we are deducing
 ///
@@ -266,7 +266,7 @@
 /// "success" result means that template argument deduction has not yet failed,
 /// but it may still fail, later, for other reasons.
 static Sema::TemplateDeductionResult
-DeduceTemplateArguments(ASTContext &Context,
+DeduceTemplateArguments(Sema &S,
                         TemplateParameterList *TemplateParams,
                         const TemplateSpecializationType *Param,
                         QualType Arg,
@@ -279,7 +279,7 @@
         = dyn_cast<TemplateSpecializationType>(Arg)) {
     // Perform template argument deduction for the template name.
     if (Sema::TemplateDeductionResult Result
-          = DeduceTemplateArguments(Context, TemplateParams,
+          = DeduceTemplateArguments(S, TemplateParams,
                                     Param->getTemplateName(),
                                     SpecArg->getTemplateName(),
                                     Info, Deduced))
@@ -291,7 +291,7 @@
     unsigned NumArgs = std::min(SpecArg->getNumArgs(), Param->getNumArgs());
     for (unsigned I = 0; I != NumArgs; ++I)
       if (Sema::TemplateDeductionResult Result
-            = DeduceTemplateArguments(Context, TemplateParams,
+            = DeduceTemplateArguments(S, TemplateParams,
                                       Param->getArg(I),
                                       SpecArg->getArg(I),
                                       Info, Deduced))
@@ -314,7 +314,7 @@
 
   // Perform template argument deduction for the template name.
   if (Sema::TemplateDeductionResult Result
-        = DeduceTemplateArguments(Context,
+        = DeduceTemplateArguments(S,
                                   TemplateParams,
                                   Param->getTemplateName(),
                                TemplateName(SpecArg->getSpecializedTemplate()),
@@ -328,7 +328,7 @@
 
   for (unsigned I = 0; I != NumArgs; ++I)
     if (Sema::TemplateDeductionResult Result
-          = DeduceTemplateArguments(Context, TemplateParams,
+          = DeduceTemplateArguments(S, TemplateParams,
                                     Param->getArg(I),
                                     ArgArgs.get(I),
                                     Info, Deduced))
@@ -340,7 +340,7 @@
 /// \brief Deduce the template arguments by comparing the parameter type and
 /// the argument type (C++ [temp.deduct.type]).
 ///
-/// \param Context the AST context in which this deduction occurs.
+/// \param S the semantic analysis object within which we are deducing
 ///
 /// \param TemplateParams the template parameters that we are deducing
 ///
@@ -359,7 +359,7 @@
 /// "success" result means that template argument deduction has not yet failed,
 /// but it may still fail, later, for other reasons.
 static Sema::TemplateDeductionResult
-DeduceTemplateArguments(ASTContext &Context,
+DeduceTemplateArguments(Sema &S,
                         TemplateParameterList *TemplateParams,
                         QualType ParamIn, QualType ArgIn,
                         Sema::TemplateDeductionInfo &Info,
@@ -367,8 +367,8 @@
                         unsigned TDF) {
   // We only want to look at the canonical types, since typedefs and
   // sugar are not part of template argument deduction.
-  QualType Param = Context.getCanonicalType(ParamIn);
-  QualType Arg = Context.getCanonicalType(ArgIn);
+  QualType Param = S.Context.getCanonicalType(ParamIn);
+  QualType Arg = S.Context.getCanonicalType(ArgIn);
 
   // C++0x [temp.deduct.call]p4 bullet 1:
   //   - If the original P is a reference type, the deduced A (i.e., the type
@@ -376,10 +376,10 @@
   //     transformed A.
   if (TDF & TDF_ParamWithReferenceType) {
     Qualifiers Quals;
-    QualType UnqualParam = Context.getUnqualifiedArrayType(Param, Quals);
+    QualType UnqualParam = S.Context.getUnqualifiedArrayType(Param, Quals);
     Quals.setCVRQualifiers(Quals.getCVRQualifiers() &
                            Arg.getCVRQualifiersThroughArrayTypes());
-    Param = Context.getQualifiedType(UnqualParam, Quals);
+    Param = S.Context.getQualifiedType(UnqualParam, Quals);
   }
 
   // If the parameter type is not dependent, there is nothing to deduce.
@@ -409,9 +409,9 @@
     // FIXME: address spaces, ObjC GC qualifiers
     if (isa<ArrayType>(Arg)) {
       Qualifiers Quals;
-      Arg = Context.getUnqualifiedArrayType(Arg, Quals);
+      Arg = S.Context.getUnqualifiedArrayType(Arg, Quals);
       if (Quals) {
-        Arg = Context.getQualifiedType(Arg, Quals);
+        Arg = S.Context.getQualifiedType(Arg, Quals);
         RecanonicalizeArg = true;
       }
     }
@@ -426,11 +426,11 @@
     }
 
     assert(TemplateTypeParm->getDepth() == 0 && "Can't deduce with depth > 0");
-    assert(Arg != Context.OverloadTy && "Unresolved overloaded function");
+    assert(Arg != S.Context.OverloadTy && "Unresolved overloaded function");
     QualType DeducedType = Arg;
     DeducedType.removeCVRQualifiers(Param.getCVRQualifiers());
     if (RecanonicalizeArg)
-      DeducedType = Context.getCanonicalType(DeducedType);
+      DeducedType = S.Context.getCanonicalType(DeducedType);
 
     if (Deduced[Index].isNull())
       Deduced[Index] = TemplateArgument(DeducedType);
@@ -479,7 +479,7 @@
         return Sema::TDK_NonDeducedMismatch;
 
       unsigned SubTDF = TDF & (TDF_IgnoreQualifiers | TDF_DerivedClass);
-      return DeduceTemplateArguments(Context, TemplateParams,
+      return DeduceTemplateArguments(S, TemplateParams,
                                    cast<PointerType>(Param)->getPointeeType(),
                                      PointerArg->getPointeeType(),
                                      Info, Deduced, SubTDF);
@@ -491,7 +491,7 @@
       if (!ReferenceArg)
         return Sema::TDK_NonDeducedMismatch;
 
-      return DeduceTemplateArguments(Context, TemplateParams,
+      return DeduceTemplateArguments(S, TemplateParams,
                            cast<LValueReferenceType>(Param)->getPointeeType(),
                                      ReferenceArg->getPointeeType(),
                                      Info, Deduced, 0);
@@ -503,7 +503,7 @@
       if (!ReferenceArg)
         return Sema::TDK_NonDeducedMismatch;
 
-      return DeduceTemplateArguments(Context, TemplateParams,
+      return DeduceTemplateArguments(S, TemplateParams,
                            cast<RValueReferenceType>(Param)->getPointeeType(),
                                      ReferenceArg->getPointeeType(),
                                      Info, Deduced, 0);
@@ -512,12 +512,12 @@
     //     T [] (implied, but not stated explicitly)
     case Type::IncompleteArray: {
       const IncompleteArrayType *IncompleteArrayArg =
-        Context.getAsIncompleteArrayType(Arg);
+        S.Context.getAsIncompleteArrayType(Arg);
       if (!IncompleteArrayArg)
         return Sema::TDK_NonDeducedMismatch;
 
-      return DeduceTemplateArguments(Context, TemplateParams,
-                     Context.getAsIncompleteArrayType(Param)->getElementType(),
+      return DeduceTemplateArguments(S, TemplateParams,
+                     S.Context.getAsIncompleteArrayType(Param)->getElementType(),
                                      IncompleteArrayArg->getElementType(),
                                      Info, Deduced, 0);
     }
@@ -525,16 +525,16 @@
     //     T [integer-constant]
     case Type::ConstantArray: {
       const ConstantArrayType *ConstantArrayArg =
-        Context.getAsConstantArrayType(Arg);
+        S.Context.getAsConstantArrayType(Arg);
       if (!ConstantArrayArg)
         return Sema::TDK_NonDeducedMismatch;
 
       const ConstantArrayType *ConstantArrayParm =
-        Context.getAsConstantArrayType(Param);
+        S.Context.getAsConstantArrayType(Param);
       if (ConstantArrayArg->getSize() != ConstantArrayParm->getSize())
         return Sema::TDK_NonDeducedMismatch;
 
-      return DeduceTemplateArguments(Context, TemplateParams,
+      return DeduceTemplateArguments(S, TemplateParams,
                                      ConstantArrayParm->getElementType(),
                                      ConstantArrayArg->getElementType(),
                                      Info, Deduced, 0);
@@ -542,15 +542,15 @@
 
     //     type [i]
     case Type::DependentSizedArray: {
-      const ArrayType *ArrayArg = Context.getAsArrayType(Arg);
+      const ArrayType *ArrayArg = S.Context.getAsArrayType(Arg);
       if (!ArrayArg)
         return Sema::TDK_NonDeducedMismatch;
 
       // Check the element type of the arrays
       const DependentSizedArrayType *DependentArrayParm
-        = Context.getAsDependentSizedArrayType(Param);
+        = S.Context.getAsDependentSizedArrayType(Param);
       if (Sema::TemplateDeductionResult Result
-            = DeduceTemplateArguments(Context, TemplateParams,
+            = DeduceTemplateArguments(S, TemplateParams,
                                       DependentArrayParm->getElementType(),
                                       ArrayArg->getElementType(),
                                       Info, Deduced, 0))
@@ -569,12 +569,12 @@
       if (const ConstantArrayType *ConstantArrayArg
             = dyn_cast<ConstantArrayType>(ArrayArg)) {
         llvm::APSInt Size(ConstantArrayArg->getSize());
-        return DeduceNonTypeTemplateArgument(Context, NTTP, Size,
+        return DeduceNonTypeTemplateArgument(S, NTTP, Size,
                                              Info, Deduced);
       }
       if (const DependentSizedArrayType *DependentArrayArg
             = dyn_cast<DependentSizedArrayType>(ArrayArg))
-        return DeduceNonTypeTemplateArgument(Context, NTTP,
+        return DeduceNonTypeTemplateArgument(S, NTTP,
                                              DependentArrayArg->getSizeExpr(),
                                              Info, Deduced);
 
@@ -606,7 +606,7 @@
 
       // Check return types.
       if (Sema::TemplateDeductionResult Result
-            = DeduceTemplateArguments(Context, TemplateParams,
+            = DeduceTemplateArguments(S, TemplateParams,
                                       FunctionProtoParam->getResultType(),
                                       FunctionProtoArg->getResultType(),
                                       Info, Deduced, 0))
@@ -615,7 +615,7 @@
       for (unsigned I = 0, N = FunctionProtoParam->getNumArgs(); I != N; ++I) {
         // Check argument types.
         if (Sema::TemplateDeductionResult Result
-              = DeduceTemplateArguments(Context, TemplateParams,
+              = DeduceTemplateArguments(S, TemplateParams,
                                         FunctionProtoParam->getArgType(I),
                                         FunctionProtoArg->getArgType(I),
                                         Info, Deduced, 0))
@@ -636,7 +636,7 @@
 
       // Try to deduce template arguments from the template-id.
       Sema::TemplateDeductionResult Result
-        = DeduceTemplateArguments(Context, TemplateParams, SpecParam, Arg,
+        = DeduceTemplateArguments(S, TemplateParams, SpecParam, Arg,
                                   Info, Deduced);
 
       if (Result && (TDF & TDF_DerivedClass)) {
@@ -649,7 +649,15 @@
         // More importantly:
         //   These alternatives are considered only if type deduction would
         //   otherwise fail.
-        if (const RecordType *RecordT = dyn_cast<RecordType>(Arg)) {
+        if (const RecordType *RecordT = Arg->getAs<RecordType>()) {
+          // We cannot inspect base classes as part of deduction when the type
+          // is incomplete, so either instantiate any templates necessary to
+          // complete the type, or skip over it if it cannot be completed.
+          // FIXME: The location given becomes the PoI, so we should thread
+          // a better location through the TemplateDeductionInfo.
+          if (S.RequireCompleteType(RecordT->getDecl()->getLocStart(), Arg, 0))
+            return Result;
+
           // Use data recursion to crawl through the list of base classes.
           // Visited contains the set of nodes we have already visited, while
           // ToVisit is our stack of records that we still need to visit.
@@ -670,7 +678,7 @@
             // deduction from it.
             if (NextT != RecordT) {
               Sema::TemplateDeductionResult BaseResult
-                = DeduceTemplateArguments(Context, TemplateParams, SpecParam,
+                = DeduceTemplateArguments(S, TemplateParams, SpecParam,
                                           QualType(NextT, 0), Info, Deduced);
 
               // If template argument deduction for this base was successful,
@@ -715,14 +723,14 @@
         return Sema::TDK_NonDeducedMismatch;
 
       if (Sema::TemplateDeductionResult Result
-            = DeduceTemplateArguments(Context, TemplateParams,
+            = DeduceTemplateArguments(S, TemplateParams,
                                       MemPtrParam->getPointeeType(),
                                       MemPtrArg->getPointeeType(),
                                       Info, Deduced,
                                       TDF & TDF_IgnoreQualifiers))
         return Result;
 
-      return DeduceTemplateArguments(Context, TemplateParams,
+      return DeduceTemplateArguments(S, TemplateParams,
                                      QualType(MemPtrParam->getClass(), 0),
                                      QualType(MemPtrArg->getClass(), 0),
                                      Info, Deduced, 0);
@@ -740,7 +748,7 @@
       if (!BlockPtrArg)
         return Sema::TDK_NonDeducedMismatch;
 
-      return DeduceTemplateArguments(Context, TemplateParams,
+      return DeduceTemplateArguments(S, TemplateParams,
                                      BlockPtrParam->getPointeeType(),
                                      BlockPtrArg->getPointeeType(), Info,
                                      Deduced, 0);
@@ -761,7 +769,7 @@
 }
 
 static Sema::TemplateDeductionResult
-DeduceTemplateArguments(ASTContext &Context,
+DeduceTemplateArguments(Sema &S,
                         TemplateParameterList *TemplateParams,
                         const TemplateArgument &Param,
                         const TemplateArgument &Arg,
@@ -774,7 +782,7 @@
 
   case TemplateArgument::Type:
     if (Arg.getKind() == TemplateArgument::Type)
-      return DeduceTemplateArguments(Context, TemplateParams, Param.getAsType(),
+      return DeduceTemplateArguments(S, TemplateParams, Param.getAsType(),
                                      Arg.getAsType(), Info, Deduced, 0);
     Info.FirstArg = Param;
     Info.SecondArg = Arg;
@@ -782,7 +790,7 @@
       
   case TemplateArgument::Template:
     if (Arg.getKind() == TemplateArgument::Template)
-      return DeduceTemplateArguments(Context, TemplateParams, 
+      return DeduceTemplateArguments(S, TemplateParams, 
                                      Param.getAsTemplate(),
                                      Arg.getAsTemplate(), Info, Deduced);
     Info.FirstArg = Param;
@@ -826,14 +834,14 @@
           = getDeducedParameterFromExpr(Param.getAsExpr())) {
       if (Arg.getKind() == TemplateArgument::Integral)
         // FIXME: Sign problems here
-        return DeduceNonTypeTemplateArgument(Context, NTTP,
+        return DeduceNonTypeTemplateArgument(S, NTTP,
                                              *Arg.getAsIntegral(),
                                              Info, Deduced);
       if (Arg.getKind() == TemplateArgument::Expression)
-        return DeduceNonTypeTemplateArgument(Context, NTTP, Arg.getAsExpr(),
+        return DeduceNonTypeTemplateArgument(S, NTTP, Arg.getAsExpr(),
                                              Info, Deduced);
       if (Arg.getKind() == TemplateArgument::Declaration)
-        return DeduceNonTypeTemplateArgument(Context, NTTP, Arg.getAsDecl(),
+        return DeduceNonTypeTemplateArgument(S, NTTP, Arg.getAsDecl(),
                                              Info, Deduced);
       
       assert(false && "Type/value mismatch");
@@ -854,7 +862,7 @@
 }
 
 static Sema::TemplateDeductionResult
-DeduceTemplateArguments(ASTContext &Context,
+DeduceTemplateArguments(Sema &S,
                         TemplateParameterList *TemplateParams,
                         const TemplateArgumentList &ParamList,
                         const TemplateArgumentList &ArgList,
@@ -863,7 +871,7 @@
   assert(ParamList.size() == ArgList.size());
   for (unsigned I = 0, N = ParamList.size(); I != N; ++I) {
     if (Sema::TemplateDeductionResult Result
-          = DeduceTemplateArguments(Context, TemplateParams,
+          = DeduceTemplateArguments(S, TemplateParams,
                                     ParamList[I], ArgList[I],
                                     Info, Deduced))
       return Result;
@@ -951,7 +959,7 @@
   llvm::SmallVector<TemplateArgument, 4> Deduced;
   Deduced.resize(Partial->getTemplateParameters()->size());
   if (TemplateDeductionResult Result
-        = ::DeduceTemplateArguments(Context,
+        = ::DeduceTemplateArguments(*this,
                                     Partial->getTemplateParameters(),
                                     Partial->getTemplateArgs(),
                                     TemplateArgs, Info, Deduced))
@@ -1380,7 +1388,7 @@
     unsigned TDF = 0;
 
     Sema::TemplateDeductionResult Result
-      = DeduceTemplateArguments(S.Context, TemplateParams,
+      = DeduceTemplateArguments(S, TemplateParams,
                                 ParamType, ArgType,
                                 Info, Deduced, TDF);
     if (Result) continue;
@@ -1549,7 +1557,7 @@
       TDF |= TDF_DerivedClass;
 
     if (TemplateDeductionResult Result
-        = ::DeduceTemplateArguments(Context, TemplateParams,
+        = ::DeduceTemplateArguments(*this, TemplateParams,
                                     ParamType, ArgType, Info, Deduced,
                                     TDF))
       return Result;
@@ -1617,7 +1625,7 @@
   if (!ArgFunctionType.isNull()) {
     // Deduce template arguments from the function type.
     if (TemplateDeductionResult Result
-          = ::DeduceTemplateArguments(Context, TemplateParams,
+          = ::DeduceTemplateArguments(*this, TemplateParams,
                                       FunctionType, ArgFunctionType, Info,
                                       Deduced, 0))
       return Result;
@@ -1716,7 +1724,7 @@
       (P->isMemberPointerType() && P->isMemberPointerType()))
     TDF |= TDF_IgnoreQualifiers;
   if (TemplateDeductionResult Result
-        = ::DeduceTemplateArguments(Context, TemplateParams,
+        = ::DeduceTemplateArguments(*this, TemplateParams,
                                     P, A, Info, Deduced, TDF))
     return Result;
 
@@ -1767,7 +1775,7 @@
 /// \brief Deduce the template arguments during partial ordering by comparing 
 /// the parameter type and the argument type (C++0x [temp.deduct.partial]).
 ///
-/// \param Context the AST context in which this deduction occurs.
+/// \param S the semantic analysis object within which we are deducing
 ///
 /// \param TemplateParams the template parameters that we are deducing
 ///
@@ -1783,14 +1791,14 @@
 /// "success" result means that template argument deduction has not yet failed,
 /// but it may still fail, later, for other reasons.
 static Sema::TemplateDeductionResult
-DeduceTemplateArgumentsDuringPartialOrdering(ASTContext &Context,
+DeduceTemplateArgumentsDuringPartialOrdering(Sema &S,
                                           TemplateParameterList *TemplateParams,
                                              QualType ParamIn, QualType ArgIn,
                                              Sema::TemplateDeductionInfo &Info,
                              llvm::SmallVectorImpl<TemplateArgument> &Deduced,
     llvm::SmallVectorImpl<DeductionQualifierComparison> *QualifierComparisons) {
-  CanQualType Param = Context.getCanonicalType(ParamIn);
-  CanQualType Arg = Context.getCanonicalType(ArgIn);
+  CanQualType Param = S.Context.getCanonicalType(ParamIn);
+  CanQualType Arg = S.Context.getCanonicalType(ArgIn);
 
   // C++0x [temp.deduct.partial]p5:
   //   Before the partial ordering is done, certain transformations are 
@@ -1837,7 +1845,7 @@
   //   described in 14.9.2.5. If deduction succeeds for a given type, the type
   //   from the argument template is considered to be at least as specialized
   //   as the type from the parameter template.
-  return DeduceTemplateArguments(Context, TemplateParams, Param, Arg, Info,
+  return DeduceTemplateArguments(S, TemplateParams, Param, Arg, Info,
                                  Deduced, TDF_None);
 }
 
@@ -1874,7 +1882,7 @@
     //     used.
     unsigned NumParams = std::min(Proto1->getNumArgs(), Proto2->getNumArgs());
     for (unsigned I = 0; I != NumParams; ++I)
-      if (DeduceTemplateArgumentsDuringPartialOrdering(S.Context,
+      if (DeduceTemplateArgumentsDuringPartialOrdering(S,
                                                        TemplateParams,
                                                        Proto2->getArgType(I),
                                                        Proto1->getArgType(I),
@@ -1889,7 +1897,7 @@
   case TPOC_Conversion:
     //   - In the context of a call to a conversion operator, the return types
     //     of the conversion function templates are used.
-    if (DeduceTemplateArgumentsDuringPartialOrdering(S.Context,
+    if (DeduceTemplateArgumentsDuringPartialOrdering(S,
                                                      TemplateParams,
                                                      Proto2->getResultType(),
                                                      Proto1->getResultType(),
@@ -1902,7 +1910,7 @@
   case TPOC_Other:
     //   - In other contexts (14.6.6.2) the function template’s function type 
     //     is used.
-    if (DeduceTemplateArgumentsDuringPartialOrdering(S.Context,
+    if (DeduceTemplateArgumentsDuringPartialOrdering(S,
                                                      TemplateParams,
                                                      FD2->getType(),
                                                      FD1->getType(),
@@ -2191,7 +2199,7 @@
   
   // Determine whether PS1 is at least as specialized as PS2
   Deduced.resize(PS2->getTemplateParameters()->size());
-  bool Better1 = !DeduceTemplateArgumentsDuringPartialOrdering(Context,
+  bool Better1 = !DeduceTemplateArgumentsDuringPartialOrdering(*this,
                                                   PS2->getTemplateParameters(),
                                                   Context.getTypeDeclType(PS2),
                                                   Context.getTypeDeclType(PS1),
@@ -2202,7 +2210,7 @@
   // Determine whether PS2 is at least as specialized as PS1
   Deduced.clear();
   Deduced.resize(PS1->getTemplateParameters()->size());
-  bool Better2 = !DeduceTemplateArgumentsDuringPartialOrdering(Context,
+  bool Better2 = !DeduceTemplateArgumentsDuringPartialOrdering(*this,
                                                   PS1->getTemplateParameters(),
                                                   Context.getTypeDeclType(PS1),
                                                   Context.getTypeDeclType(PS2),

Modified: cfe/trunk/test/SemaTemplate/deduction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/deduction.cpp?rev=95528&r1=95527&r2=95528&view=diff

==============================================================================
--- cfe/trunk/test/SemaTemplate/deduction.cpp (original)
+++ cfe/trunk/test/SemaTemplate/deduction.cpp Sun Feb  7 15:33:28 2010
@@ -86,3 +86,15 @@
 template <typename T, int N> void f(const T (&a)[N]);
 int iarr[] = { 1 };
 void test_PR5911() { f(iarr); }
+
+// Must not examine base classes of incomplete type during template argument
+// deduction.
+namespace PR6257 {
+  template <typename T> struct X {
+    template <typename U> X(const X<U>& u);
+  };
+  struct A;
+  void f(A& a);
+  void f(const X<A>& a);
+  void test(A& a) { (void)f(a); }
+}





More information about the cfe-commits mailing list