diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Sema/SemaTemplateDeduction.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Sema/SemaTemplateDeduction.cpp | 129 |
1 files changed, 94 insertions, 35 deletions
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaTemplateDeduction.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaTemplateDeduction.cpp index ae8157e..de04c8a 100644 --- a/contrib/llvm/tools/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -679,7 +679,7 @@ public: new (S.Context) TemplateArgument[Pack.New.size()]; std::copy(Pack.New.begin(), Pack.New.end(), ArgumentPack); NewPack = DeducedTemplateArgument( - TemplateArgument(ArgumentPack, Pack.New.size()), + TemplateArgument(llvm::makeArrayRef(ArgumentPack, Pack.New.size())), Pack.New[0].wasDeducedFromArrayBound()); } @@ -1440,7 +1440,7 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S, // 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. - if (S.RequireCompleteType(Info.getLocation(), Arg, 0)) + if (!S.isCompleteType(Info.getLocation(), Arg)) return Result; // Use data recursion to crawl through the list of base classes. @@ -1517,10 +1517,19 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S, if (!MemPtrArg) return Sema::TDK_NonDeducedMismatch; + QualType ParamPointeeType = MemPtrParam->getPointeeType(); + if (ParamPointeeType->isFunctionType()) + S.adjustMemberFunctionCC(ParamPointeeType, /*IsStatic=*/true, + /*IsCtorOrDtor=*/false, Info.getLocation()); + QualType ArgPointeeType = MemPtrArg->getPointeeType(); + if (ArgPointeeType->isFunctionType()) + S.adjustMemberFunctionCC(ArgPointeeType, /*IsStatic=*/true, + /*IsCtorOrDtor=*/false, Info.getLocation()); + if (Sema::TemplateDeductionResult Result = DeduceTemplateArgumentsByTypeMatch(S, TemplateParams, - MemPtrParam->getPointeeType(), - MemPtrArg->getPointeeType(), + ParamPointeeType, + ArgPointeeType, Info, Deduced, TDF & TDF_IgnoreQualifiers)) return Result; @@ -2075,9 +2084,8 @@ ConvertDeducedTemplateArgument(Sema &S, NamedDecl *Param, } // Create the resulting argument pack. - Output.push_back(TemplateArgument::CreatePackCopy(S.Context, - PackedArgsBuilder.data(), - PackedArgsBuilder.size())); + Output.push_back( + TemplateArgument::CreatePackCopy(S.Context, PackedArgsBuilder)); return false; } @@ -2730,7 +2738,7 @@ CheckOriginalCallArgDeduction(Sema &S, Sema::OriginalCallArg OriginalArg, return false; if (A->isRecordType() && isSimpleTemplateIdType(OriginalParamType) && - S.IsDerivedFrom(A, DeducedA)) + S.IsDerivedFrom(SourceLocation(), A, DeducedA)) return false; return true; @@ -2850,7 +2858,8 @@ Sema::FinishTemplateArgumentDeduction(FunctionTemplateDecl *FunctionTemplate, CurrentInstantiationScope->getPartiallySubstitutedPack(&ExplicitArgs, &NumExplicitArgs) == Param) { - Builder.push_back(TemplateArgument(ExplicitArgs, NumExplicitArgs)); + Builder.push_back(TemplateArgument( + llvm::makeArrayRef(ExplicitArgs, NumExplicitArgs))); // Forget the partially-substituted pack; it's substitution is now // complete. @@ -3028,7 +3037,7 @@ ResolveOverloadForDeduction(Sema &S, TemplateParameterList *TemplateParams, // Gather the explicit template arguments, if any. TemplateArgumentListInfo ExplicitTemplateArgs; if (Ovl->hasExplicitTemplateArgs()) - Ovl->getExplicitTemplateArgs().copyInto(ExplicitTemplateArgs); + Ovl->copyTemplateArgumentsInto(ExplicitTemplateArgs); QualType Match; for (UnresolvedSetIterator I = Ovl->decls_begin(), E = Ovl->decls_end(); I != E; ++I) { @@ -3123,8 +3132,10 @@ static bool AdjustFunctionParmAndArgTypesForDeduction(Sema &S, if (ParamRefType) { // If the argument has incomplete array type, try to complete its type. - if (ArgType->isIncompleteArrayType() && !S.RequireCompleteExprType(Arg, 0)) + if (ArgType->isIncompleteArrayType()) { + S.completeExprArrayBound(Arg); ArgType = Arg->getType(); + } // C++0x [temp.deduct.call]p3: // If P is an rvalue reference to a cv-unqualified template @@ -3203,24 +3214,63 @@ DeduceFromInitializerList(Sema &S, TemplateParameterList *TemplateParams, TemplateDeductionInfo &Info, SmallVectorImpl<DeducedTemplateArgument> &Deduced, unsigned TDF, Sema::TemplateDeductionResult &Result) { - // If the argument is an initializer list then the parameter is an undeduced - // context, unless the parameter type is (reference to cv) - // std::initializer_list<P'>, in which case deduction is done for each element - // of the initializer list as-if it were an argument in a function call, and - // the result is the deduced type if it's the same for all elements. - QualType X; - if (!S.isStdInitializerList(AdjustedParamType, &X)) + + // [temp.deduct.call] p1 (post CWG-1591) + // If removing references and cv-qualifiers from P gives + // std::initializer_list<P0> or P0[N] for some P0 and N and the argument is a + // non-empty initializer list (8.5.4), then deduction is performed instead for + // each element of the initializer list, taking P0 as a function template + // parameter type and the initializer element as its argument, and in the + // P0[N] case, if N is a non-type template parameter, N is deduced from the + // length of the initializer list. Otherwise, an initializer list argument + // causes the parameter to be considered a non-deduced context + + const bool IsConstSizedArray = AdjustedParamType->isConstantArrayType(); + + const bool IsDependentSizedArray = + !IsConstSizedArray && AdjustedParamType->isDependentSizedArrayType(); + + QualType ElTy; // The element type of the std::initializer_list or the array. + + const bool IsSTDList = !IsConstSizedArray && !IsDependentSizedArray && + S.isStdInitializerList(AdjustedParamType, &ElTy); + + if (!IsConstSizedArray && !IsDependentSizedArray && !IsSTDList) return false; Result = Sema::TDK_Success; - - // Recurse down into the init list. - for (unsigned i = 0, e = ILE->getNumInits(); i < e; ++i) { - if ((Result = DeduceTemplateArgumentByListElement( - S, TemplateParams, X, ILE->getInit(i), Info, Deduced, TDF))) - return true; + // If we are not deducing against the 'T' in a std::initializer_list<T> then + // deduce against the 'T' in T[N]. + if (ElTy.isNull()) { + assert(!IsSTDList); + ElTy = S.Context.getAsArrayType(AdjustedParamType)->getElementType(); + } + // Deduction only needs to be done for dependent types. + if (ElTy->isDependentType()) { + for (Expr *E : ILE->inits()) { + if ((Result = DeduceTemplateArgumentByListElement(S, TemplateParams, ElTy, + E, Info, Deduced, TDF))) + return true; + } } + if (IsDependentSizedArray) { + const DependentSizedArrayType *ArrTy = + S.Context.getAsDependentSizedArrayType(AdjustedParamType); + // Determine the array bound is something we can deduce. + if (NonTypeTemplateParmDecl *NTTP = + getDeducedParameterFromExpr(ArrTy->getSizeExpr())) { + // We can perform template argument deduction for the given non-type + // template parameter. + assert(NTTP->getDepth() == 0 && + "Cannot deduce non-type template argument at depth > 0"); + llvm::APInt Size(S.Context.getIntWidth(NTTP->getType()), + ILE->getNumInits()); + Result = DeduceNonTypeTemplateArgument( + S, NTTP, llvm::APSInt(Size), NTTP->getType(), + /*ArrayBound=*/true, Info, Deduced); + } + } return true; } @@ -3908,7 +3958,7 @@ namespace { !Replacement.isNull() && Replacement->isDependentType(); QualType Result = SemaRef.Context.getAutoType(Dependent ? QualType() : Replacement, - TL.getTypePtr()->isDecltypeAuto(), + TL.getTypePtr()->getKeyword(), Dependent); AutoTypeLoc NewTL = TLB.push<AutoTypeLoc>(Result); NewTL.setNameLoc(TL.getNameLoc()); @@ -3976,6 +4026,11 @@ Sema::DeduceAutoType(TypeLoc Type, Expr *&Init, QualType &Result) { if (Result.isNull()) return DAR_FailedAlreadyDiagnosed; return DAR_Succeeded; + } else if (!getLangOpts().CPlusPlus) { + if (isa<InitListExpr>(Init)) { + Diag(Init->getLocStart(), diag::err_auto_init_list_from_c); + return DAR_FailedAlreadyDiagnosed; + } } } @@ -3989,8 +4044,8 @@ Sema::DeduceAutoType(TypeLoc Type, Expr *&Init, QualType &Result) { nullptr, false, false); QualType TemplArg = QualType(TemplParam->getTypeForDecl(), 0); NamedDecl *TemplParamPtr = TemplParam; - FixedSizeTemplateParameterList<1> TemplateParams(Loc, Loc, &TemplParamPtr, - Loc); + FixedSizeTemplateParameterListStorage<1> TemplateParamsSt( + Loc, Loc, TemplParamPtr, Loc); QualType FuncParam = SubstituteAutoTransform(*this, TemplArg).Apply(Type); assert(!FuncParam.isNull() && @@ -4007,20 +4062,24 @@ Sema::DeduceAutoType(TypeLoc Type, Expr *&Init, QualType &Result) { InitListExpr *InitList = dyn_cast<InitListExpr>(Init); if (InitList) { for (unsigned i = 0, e = InitList->getNumInits(); i < e; ++i) { - if (DeduceTemplateArgumentByListElement(*this, &TemplateParams, - TemplArg, - InitList->getInit(i), + if (DeduceTemplateArgumentByListElement(*this, TemplateParamsSt.get(), + TemplArg, InitList->getInit(i), Info, Deduced, TDF)) return DAR_Failed; } } else { - if (AdjustFunctionParmAndArgTypesForDeduction(*this, &TemplateParams, - FuncParam, InitType, Init, - TDF)) + if (!getLangOpts().CPlusPlus && Init->refersToBitField()) { + Diag(Loc, diag::err_auto_bitfield); + return DAR_FailedAlreadyDiagnosed; + } + + if (AdjustFunctionParmAndArgTypesForDeduction( + *this, TemplateParamsSt.get(), FuncParam, InitType, Init, TDF)) return DAR_Failed; - if (DeduceTemplateArgumentsByTypeMatch(*this, &TemplateParams, FuncParam, - InitType, Info, Deduced, TDF)) + if (DeduceTemplateArgumentsByTypeMatch(*this, TemplateParamsSt.get(), + FuncParam, InitType, Info, Deduced, + TDF)) return DAR_Failed; } |