diff options
Diffstat (limited to 'lib/Sema')
| -rw-r--r-- | lib/Sema/SemaCUDA.cpp | 6 | ||||
| -rw-r--r-- | lib/Sema/SemaCodeComplete.cpp | 17 | ||||
| -rw-r--r-- | lib/Sema/SemaOpenMP.cpp | 64 | ||||
| -rw-r--r-- | lib/Sema/SemaOverload.cpp | 4 | ||||
| -rw-r--r-- | lib/Sema/SemaTemplate.cpp | 14 | ||||
| -rw-r--r-- | lib/Sema/SemaTemplateDeduction.cpp | 270 | ||||
| -rw-r--r-- | lib/Sema/TreeTransform.h | 14 | 
7 files changed, 206 insertions, 183 deletions
| diff --git a/lib/Sema/SemaCUDA.cpp b/lib/Sema/SemaCUDA.cpp index 6f272ec839f5..282633bbc9e1 100644 --- a/lib/Sema/SemaCUDA.cpp +++ b/lib/Sema/SemaCUDA.cpp @@ -228,10 +228,8 @@ void Sema::EraseUnwantedCUDAMatches(        [&](const Pair &M1, const Pair &M2) { return GetCFP(M1) < GetCFP(M2); }));    // Erase all functions with lower priority. -  Matches.erase( -      llvm::remove_if( -          Matches, [&](const Pair &Match) { return GetCFP(Match) < BestCFP; }), -      Matches.end()); +  llvm::erase_if(Matches, +                 [&](const Pair &Match) { return GetCFP(Match) < BestCFP; });  }  /// When an implicitly-declared special member has to invoke more than one diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp index d76bde574677..3eef366b75b3 100644 --- a/lib/Sema/SemaCodeComplete.cpp +++ b/lib/Sema/SemaCodeComplete.cpp @@ -7471,6 +7471,23 @@ void Sema::CodeCompleteObjCMethodDeclSelector(Scope *S,    }    Results.ExitScope(); + +  if (!AtParameterName && !SelIdents.empty() && +      SelIdents.front()->getName().startswith("init")) { +    for (const auto &M : PP.macros()) { +      if (M.first->getName() != "NS_DESIGNATED_INITIALIZER") +        continue; +      Results.EnterNewScope(); +      CodeCompletionBuilder Builder(Results.getAllocator(), +                                    Results.getCodeCompletionTUInfo()); +      Builder.AddTypedTextChunk( +          Builder.getAllocator().CopyString(M.first->getName())); +      Results.AddResult(CodeCompletionResult(Builder.TakeString(), CCP_Macro, +                                             CXCursor_MacroDefinition)); +      Results.ExitScope(); +    } +  } +    HandleCodeCompleteResults(this, CodeCompleter,                               CodeCompletionContext::CCC_Other,                              Results.data(),Results.size()); diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp index 804aadc0ff77..edceb537df75 100644 --- a/lib/Sema/SemaOpenMP.cpp +++ b/lib/Sema/SemaOpenMP.cpp @@ -1700,7 +1700,8 @@ void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {    case OMPD_teams_distribute_parallel_for_simd:    case OMPD_teams_distribute_parallel_for:    case OMPD_target_teams_distribute: -  case OMPD_target_teams_distribute_parallel_for: { +  case OMPD_target_teams_distribute_parallel_for: +  case OMPD_target_teams_distribute_parallel_for_simd: {      QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);      QualType KmpInt32PtrTy =          Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); @@ -2439,6 +2440,12 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(      AllowedNameModifiers.push_back(OMPD_target);      AllowedNameModifiers.push_back(OMPD_parallel);      break; +  case OMPD_target_teams_distribute_parallel_for_simd: +    Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( +        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); +    AllowedNameModifiers.push_back(OMPD_target); +    AllowedNameModifiers.push_back(OMPD_parallel); +    break;    case OMPD_declare_target:    case OMPD_end_declare_target:    case OMPD_threadprivate: @@ -6375,6 +6382,52 @@ StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective(        Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);  } +StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( +    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, +    SourceLocation EndLoc, +    llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { +  if (!AStmt) +    return StmtError(); + +  CapturedStmt *CS = cast<CapturedStmt>(AStmt); +  // 1.2.2 OpenMP Language Terminology +  // Structured block - An executable statement with a single entry at the +  // top and a single exit at the bottom. +  // The point of exit cannot be a branch out of the structured block. +  // longjmp() and throw() must not violate the entry/exit criteria. +  CS->getCapturedDecl()->setNothrow(); + +  OMPLoopDirective::HelperExprs B; +  // In presence of clause 'collapse' with number of loops, it will +  // define the nested loops number. +  auto NestedLoopCount = CheckOpenMPLoop( +      OMPD_target_teams_distribute_parallel_for_simd, +      getCollapseNumberExpr(Clauses), +      nullptr /*ordered not a clause on distribute*/, AStmt, *this, *DSAStack, +      VarsWithImplicitDSA, B); +  if (NestedLoopCount == 0) +    return StmtError(); + +  assert((CurContext->isDependentContext() || B.builtAll()) && +         "omp target teams distribute parallel for simd loop exprs were not " +         "built"); + +  if (!CurContext->isDependentContext()) { +    // Finalize the clauses that need pre-built expressions for CodeGen. +    for (auto C : Clauses) { +      if (auto *LC = dyn_cast<OMPLinearClause>(C)) +        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), +                                     B.NumIterations, *this, CurScope, +                                     DSAStack)) +          return StmtError(); +    } +  } + +  getCurFunction()->setHasBranchProtectedScope(); +  return OMPTargetTeamsDistributeParallelForSimdDirective::Create( +      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); +} +  OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,                                               SourceLocation StartLoc,                                               SourceLocation LParenLoc, @@ -7397,7 +7450,8 @@ OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,      if (CurrDir == OMPD_target || CurrDir == OMPD_target_parallel ||          CurrDir == OMPD_target_teams ||          CurrDir == OMPD_target_teams_distribute || -        CurrDir == OMPD_target_teams_distribute_parallel_for) { +        CurrDir == OMPD_target_teams_distribute_parallel_for || +        CurrDir == OMPD_target_teams_distribute_parallel_for_simd) {        OpenMPClauseKind ConflictKind;        if (DSAStack->checkMappableExprComponentListsForDecl(                VD, /*CurrentRegionOnly=*/true, @@ -7657,7 +7711,8 @@ OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,        if (CurrDir == OMPD_target || CurrDir == OMPD_target_parallel ||            CurrDir == OMPD_target_teams ||            CurrDir == OMPD_target_teams_distribute || -          CurrDir == OMPD_target_teams_distribute_parallel_for) { +          CurrDir == OMPD_target_teams_distribute_parallel_for || +          CurrDir == OMPD_target_teams_distribute_parallel_for_simd) {          OpenMPClauseKind ConflictKind;          if (DSAStack->checkMappableExprComponentListsForDecl(                  VD, /*CurrentRegionOnly=*/true, @@ -10175,7 +10230,8 @@ checkMappableExpressionList(Sema &SemaRef, DSAStackTy *DSAS,        // attribute clause on the same construct        if ((DKind == OMPD_target || DKind == OMPD_target_teams ||             DKind == OMPD_target_teams_distribute || -           DKind == OMPD_target_teams_distribute_parallel_for) && VD) { +           DKind == OMPD_target_teams_distribute_parallel_for || +           DKind == OMPD_target_teams_distribute_parallel_for_simd) && VD) {          auto DVar = DSAS->getTopDSA(VD, false);          if (isOpenMPPrivate(DVar.CKind)) {            SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 47e3df20d911..b5c0e634fa50 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -8958,9 +8958,7 @@ OverloadCandidateSet::BestViableFunction(Sema &S, SourceLocation Loc,                 S.IdentifyCUDAPreference(Caller, Cand->Function) ==                     Sema::CFP_WrongSide;        }; -      Candidates.erase(std::remove_if(Candidates.begin(), Candidates.end(), -                                      IsWrongSideCandidate), -                       Candidates.end()); +      llvm::erase_if(Candidates, IsWrongSideCandidate);      }    } diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index facc5d1b375b..66a10ef7993e 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -4244,7 +4244,7 @@ namespace {      UnnamedLocalNoLinkageFinder(Sema &S, SourceRange SR) : S(S), SR(SR) { }      bool Visit(QualType T) { -      return inherited::Visit(T.getTypePtr()); +      return T.isNull() ? false : inherited::Visit(T.getTypePtr());      }  #define TYPE(Class, Parent) \ @@ -4497,17 +4497,7 @@ bool Sema::CheckTemplateArgument(TemplateTypeParmDecl *Param,    //    // C++11 allows these, and even in C++03 we allow them as an extension with    // a warning. -  bool NeedsCheck; -  if (LangOpts.CPlusPlus11) -    NeedsCheck = -        !Diags.isIgnored(diag::warn_cxx98_compat_template_arg_unnamed_type, -                         SR.getBegin()) || -        !Diags.isIgnored(diag::warn_cxx98_compat_template_arg_local_type, -                         SR.getBegin()); -  else -    NeedsCheck = Arg->hasUnnamedOrLocalType(); - -  if (NeedsCheck) { +  if (LangOpts.CPlusPlus11 || Arg->hasUnnamedOrLocalType()) {      UnnamedLocalNoLinkageFinder Finder(*this, SR);      (void)Finder.Visit(Context.getCanonicalType(Arg));    } diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp index 0bc85a2f2635..7f1fd91c46f0 100644 --- a/lib/Sema/SemaTemplateDeduction.cpp +++ b/lib/Sema/SemaTemplateDeduction.cpp @@ -288,19 +288,22 @@ checkDeducedTemplateArguments(ASTContext &Context,          X.pack_size() != Y.pack_size())        return DeducedTemplateArgument(); +    llvm::SmallVector<TemplateArgument, 8> NewPack;      for (TemplateArgument::pack_iterator XA = X.pack_begin(),                                        XAEnd = X.pack_end(),                                           YA = Y.pack_begin();           XA != XAEnd; ++XA, ++YA) { -      // FIXME: Do we need to merge the results together here? -      if (checkDeducedTemplateArguments(Context, -                    DeducedTemplateArgument(*XA, X.wasDeducedFromArrayBound()), -                    DeducedTemplateArgument(*YA, Y.wasDeducedFromArrayBound())) -            .isNull()) +      TemplateArgument Merged = checkDeducedTemplateArguments( +          Context, DeducedTemplateArgument(*XA, X.wasDeducedFromArrayBound()), +          DeducedTemplateArgument(*YA, Y.wasDeducedFromArrayBound())); +      if (Merged.isNull())          return DeducedTemplateArgument(); +      NewPack.push_back(Merged);      } -    return X; +    return DeducedTemplateArgument( +        TemplateArgument::CreatePackCopy(Context, NewPack), +        X.wasDeducedFromArrayBound() && Y.wasDeducedFromArrayBound());    }    llvm_unreachable("Invalid TemplateArgument Kind!"); @@ -672,17 +675,20 @@ public:      // for that pack, then clear out the deduced argument.      for (auto &Pack : Packs) {        DeducedTemplateArgument &DeducedArg = Deduced[Pack.Index]; -      if (!DeducedArg.isNull()) { +      if (!Pack.New.empty() || !DeducedArg.isNull()) { +        while (Pack.New.size() < PackElements) +          Pack.New.push_back(DeducedTemplateArgument());          Pack.New.push_back(DeducedArg);          DeducedArg = DeducedTemplateArgument();        }      } +    ++PackElements;    }    /// \brief Finish template argument deduction for a set of argument packs,    /// producing the argument packs and checking for consistency with prior    /// deductions. -  Sema::TemplateDeductionResult finish(bool HasAnyArguments) { +  Sema::TemplateDeductionResult finish() {      // Build argument packs for each of the parameter packs expanded by this      // pack expansion.      for (auto &Pack : Packs) { @@ -691,7 +697,7 @@ public:        // Build or find a new value for this pack.        DeducedTemplateArgument NewPack; -      if (HasAnyArguments && Pack.New.empty()) { +      if (PackElements && Pack.New.empty()) {          if (Pack.DeferredDeduction.isNull()) {            // We were not able to deduce anything for this parameter pack            // (because it only appeared in non-deduced contexts), so just @@ -758,6 +764,7 @@ private:    TemplateParameterList *TemplateParams;    SmallVectorImpl<DeducedTemplateArgument> &Deduced;    TemplateDeductionInfo &Info; +  unsigned PackElements = 0;    SmallVector<DeducedPack, 2> Packs;  }; @@ -861,10 +868,7 @@ DeduceTemplateArguments(Sema &S,      QualType Pattern = Expansion->getPattern();      PackDeductionScope PackScope(S, TemplateParams, Deduced, Info, Pattern); -    bool HasAnyArguments = false;      for (; ArgIdx < NumArgs; ++ArgIdx) { -      HasAnyArguments = true; -        // Deduce template arguments from the pattern.        if (Sema::TemplateDeductionResult Result              = DeduceTemplateArgumentsByTypeMatch(S, TemplateParams, Pattern, @@ -877,7 +881,7 @@ DeduceTemplateArguments(Sema &S,      // Build argument packs for each of the parameter packs expanded by this      // pack expansion. -    if (auto Result = PackScope.finish(HasAnyArguments)) +    if (auto Result = PackScope.finish())        return Result;    } @@ -1935,10 +1939,7 @@ DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams,      // Keep track of the deduced template arguments for each parameter pack      // expanded by this pack expansion (the outer index) and for each      // template argument (the inner SmallVectors). -    bool HasAnyArguments = false;      for (; hasTemplateArgumentForDeduction(Args, ArgIdx); ++ArgIdx) { -      HasAnyArguments = true; -        // Deduce template arguments from the pattern.        if (Sema::TemplateDeductionResult Result              = DeduceTemplateArguments(S, TemplateParams, Pattern, Args[ArgIdx], @@ -1950,7 +1951,7 @@ DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams,      // Build argument packs for each of the parameter packs expanded by this      // pack expansion. -    if (auto Result = PackScope.finish(HasAnyArguments)) +    if (auto Result = PackScope.finish())        return Result;    } @@ -2145,6 +2146,16 @@ ConvertDeducedTemplateArgument(Sema &S, NamedDecl *Param,        InnerArg.setDeducedFromArrayBound(Arg.wasDeducedFromArrayBound());        assert(InnerArg.getKind() != TemplateArgument::Pack &&               "deduced nested pack"); +      if (P.isNull()) { +        // We deduced arguments for some elements of this pack, but not for +        // all of them. This happens if we get a conditionally-non-deduced +        // context in a pack expansion (such as an overload set in one of the +        // arguments). +        S.Diag(Param->getLocation(), +               diag::err_template_arg_deduced_incomplete_pack) +          << Arg << Param; +        return true; +      }        if (ConvertArg(InnerArg, PackedArgsBuilder.size()))          return true; @@ -3192,67 +3203,59 @@ static Sema::TemplateDeductionResult DeduceTemplateArgumentByListElement(  /// \brief Attempt template argument deduction from an initializer list  ///        deemed to be an argument in a function call. -static bool +static Sema::TemplateDeductionResult  DeduceFromInitializerList(Sema &S, TemplateParameterList *TemplateParams,                            QualType AdjustedParamType, InitListExpr *ILE,                            TemplateDeductionInfo &Info,                            SmallVectorImpl<DeducedTemplateArgument> &Deduced, -                          unsigned TDF, Sema::TemplateDeductionResult &Result) { - -  // [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; -  // 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(); +                          unsigned TDF) { +  // C++ [temp.deduct.call]p1: (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, 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 +  // +  // FIXME: Remove references and cv-qualifiers here? Consider +  //          std::initializer_list<std::initializer_list<T>&&> +  QualType ElTy; +  auto *ArrTy = S.Context.getAsArrayType(AdjustedParamType); +  if (ArrTy) +    ElTy = ArrTy->getElementType(); +  else if (!S.isStdInitializerList(AdjustedParamType, &ElTy)) { +    //   Otherwise, an initializer list argument causes the parameter to be +    //   considered a non-deduced context +    return Sema::TDK_Success;    } +    // 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 (auto Result = DeduceTemplateArgumentByListElement( +              S, TemplateParams, ElTy, E, Info, Deduced, TDF)) +        return Result;      }    } -  if (IsDependentSizedArray) { -    const DependentSizedArrayType *ArrTy = -        S.Context.getAsDependentSizedArrayType(AdjustedParamType); + +  //   in the P0[N] case, if N is a non-type template parameter, N is deduced +  //   from the length of the initializer list. +  // FIXME: We're not supposed to get here if N would be deduced as 0. +  if (auto *DependentArrTy = dyn_cast_or_null<DependentSizedArrayType>(ArrTy)) {      // Determine the array bound is something we can deduce.      if (NonTypeTemplateParmDecl *NTTP = -            getDeducedParameterFromExpr(Info, ArrTy->getSizeExpr())) { +            getDeducedParameterFromExpr(Info, DependentArrTy->getSizeExpr())) {        // We can perform template argument deduction for the given non-type        // template parameter.        llvm::APInt Size(S.Context.getIntWidth(NTTP->getType()),                         ILE->getNumInits()); -      Result = DeduceNonTypeTemplateArgument( -          S, TemplateParams, NTTP, llvm::APSInt(Size), NTTP->getType(), -          /*ArrayBound=*/true, Info, Deduced); +      if (auto Result = DeduceNonTypeTemplateArgument( +              S, TemplateParams, NTTP, llvm::APSInt(Size), NTTP->getType(), +              /*ArrayBound=*/true, Info, Deduced)) +        return Result;      }    } -  return true; + +  return Sema::TDK_Success;  }  /// \brief Perform template argument deduction by matching a parameter type @@ -3268,15 +3271,10 @@ DeduceTemplateArgumentByListElement(Sema &S,                                      unsigned TDF) {    // Handle the case where an init list contains another init list as the    // element. -  if (InitListExpr *ILE = dyn_cast<InitListExpr>(Arg)) { -    Sema::TemplateDeductionResult Result; -    if (!DeduceFromInitializerList(S, TemplateParams, -                                   ParamType.getNonReferenceType(), ILE, Info, -                                   Deduced, TDF, Result)) -      return Sema::TDK_Success; // Just ignore this expression. - -    return Result; -  } +  if (InitListExpr *ILE = dyn_cast<InitListExpr>(Arg)) +    return DeduceFromInitializerList(S, TemplateParams, +                                     ParamType.getNonReferenceType(), ILE, Info, +                                     Deduced, TDF);    // For all other cases, just match by type.    QualType ArgType = Arg->getType(); @@ -3363,58 +3361,51 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments(        ParamTypes.push_back(Function->getParamDecl(I)->getType());    } -  // Deduce template arguments from the function parameters. -  Deduced.resize(TemplateParams->size()); -  unsigned ArgIdx = 0;    SmallVector<OriginalCallArg, 4> OriginalCallArgs; -  for (unsigned ParamIdx = 0, NumParamTypes = ParamTypes.size(); -       ParamIdx != NumParamTypes; ++ParamIdx) { -    QualType OrigParamType = ParamTypes[ParamIdx]; -    QualType ParamType = OrigParamType; -    const PackExpansionType *ParamExpansion -      = dyn_cast<PackExpansionType>(ParamType); -    if (!ParamExpansion) { -      // Simple case: matching a function parameter to a function argument. -      if (ArgIdx >= CheckArgs) -        break; +  // Deduce an argument of type ParamType from an expression with index ArgIdx. +  auto DeduceCallArgument = [&](QualType ParamType, unsigned ArgIdx) { +    Expr *Arg = Args[ArgIdx]; +    QualType ArgType = Arg->getType(); +    QualType OrigParamType = ParamType; -      Expr *Arg = Args[ArgIdx++]; -      QualType ArgType = Arg->getType(); +    unsigned TDF = 0; +    if (AdjustFunctionParmAndArgTypesForDeduction(*this, TemplateParams, +                                                  ParamType, ArgType, Arg, +                                                  TDF)) +      return Sema::TDK_Success; -      unsigned TDF = 0; -      if (AdjustFunctionParmAndArgTypesForDeduction(*this, TemplateParams, -                                                    ParamType, ArgType, Arg, -                                                    TDF)) -        continue; +    // If we have nothing to deduce, we're done. +    if (!hasDeducibleTemplateParameters(*this, FunctionTemplate, ParamType)) +      return Sema::TDK_Success; -      // If we have nothing to deduce, we're done. -      if (!hasDeducibleTemplateParameters(*this, FunctionTemplate, ParamType)) -        continue; +    // If the argument is an initializer list ... +    if (InitListExpr *ILE = dyn_cast<InitListExpr>(Arg)) +      return DeduceFromInitializerList(*this, TemplateParams, ParamType, ILE, +                                       Info, Deduced, TDF); -      // If the argument is an initializer list ... -      if (InitListExpr *ILE = dyn_cast<InitListExpr>(Arg)) { -        TemplateDeductionResult Result; -        // Removing references was already done. -        if (!DeduceFromInitializerList(*this, TemplateParams, ParamType, ILE, -                                       Info, Deduced, TDF, Result)) -          continue; +    // Keep track of the argument type and corresponding parameter index, +    // so we can check for compatibility between the deduced A and A. +    OriginalCallArgs.push_back(OriginalCallArg(OrigParamType, ArgIdx, ArgType)); -        if (Result) -          return Result; -        // Don't track the argument type, since an initializer list has none. -        continue; -      } +    return DeduceTemplateArgumentsByTypeMatch(*this, TemplateParams, ParamType, +                                              ArgType, Info, Deduced, TDF); +  }; -      // Keep track of the argument type and corresponding parameter index, -      // so we can check for compatibility between the deduced A and A. -      OriginalCallArgs.push_back(OriginalCallArg(OrigParamType, ArgIdx-1, -                                                 ArgType)); +  // Deduce template arguments from the function parameters. +  Deduced.resize(TemplateParams->size()); +  for (unsigned ParamIdx = 0, NumParamTypes = ParamTypes.size(), ArgIdx = 0; +       ParamIdx != NumParamTypes; ++ParamIdx) { +    QualType ParamType = ParamTypes[ParamIdx]; -      if (TemplateDeductionResult Result -            = DeduceTemplateArgumentsByTypeMatch(*this, TemplateParams, -                                                 ParamType, ArgType, -                                                 Info, Deduced, TDF)) +    const PackExpansionType *ParamExpansion = +        dyn_cast<PackExpansionType>(ParamType); +    if (!ParamExpansion) { +      // Simple case: matching a function parameter to a function argument. +      if (ArgIdx >= CheckArgs) +        break; + +      if (auto Result = DeduceCallArgument(ParamType, ArgIdx++))          return Result;        continue; @@ -3429,6 +3420,9 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments(      //   the function parameter pack. For a function parameter pack that does      //   not occur at the end of the parameter-declaration-list, the type of      //   the parameter pack is a non-deduced context. +    // FIXME: This does not say that subsequent parameters are also non-deduced. +    // See also DR1388 / DR1399, which effectively says we should keep deducing +    // after the pack.      if (ParamIdx + 1 < NumParamTypes)        break; @@ -3436,57 +3430,13 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments(      PackDeductionScope PackScope(*this, TemplateParams, Deduced, Info,                                   ParamPattern); -    bool HasAnyArguments = false; -    for (; ArgIdx < Args.size(); ++ArgIdx) { -      HasAnyArguments = true; - -      QualType OrigParamType = ParamPattern; -      ParamType = OrigParamType; -      Expr *Arg = Args[ArgIdx]; -      QualType ArgType = Arg->getType(); - -      unsigned TDF = 0; -      if (AdjustFunctionParmAndArgTypesForDeduction(*this, TemplateParams, -                                                    ParamType, ArgType, Arg, -                                                    TDF)) { -        // We can't actually perform any deduction for this argument, so stop -        // deduction at this point. -        ++ArgIdx; -        break; -      } - -      // As above, initializer lists need special handling. -      if (InitListExpr *ILE = dyn_cast<InitListExpr>(Arg)) { -        TemplateDeductionResult Result; -        if (!DeduceFromInitializerList(*this, TemplateParams, ParamType, ILE, -                                       Info, Deduced, TDF, Result)) { -          ++ArgIdx; -          break; -        } - -        if (Result) -          return Result; -      } else { - -        // Keep track of the argument type and corresponding argument index, -        // so we can check for compatibility between the deduced A and A. -        if (hasDeducibleTemplateParameters(*this, FunctionTemplate, ParamType)) -          OriginalCallArgs.push_back(OriginalCallArg(OrigParamType, ArgIdx, -                                                     ArgType)); - -        if (TemplateDeductionResult Result -            = DeduceTemplateArgumentsByTypeMatch(*this, TemplateParams, -                                                 ParamType, ArgType, Info, -                                                 Deduced, TDF)) -          return Result; -      } - -      PackScope.nextPackElement(); -    } +    for (; ArgIdx < Args.size(); PackScope.nextPackElement(), ++ArgIdx) +      if (auto Result = DeduceCallArgument(ParamPattern, ArgIdx)) +        return Result;      // Build argument packs for each of the parameter packs expanded by this      // pack expansion. -    if (auto Result = PackScope.finish(HasAnyArguments)) +    if (auto Result = PackScope.finish())        return Result;      // After we've matching against a parameter pack, we're done. diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 3ab6019f0ec3..66892936e573 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -7766,6 +7766,20 @@ TreeTransform<Derived>::TransformOMPTargetTeamsDistributeParallelForDirective(    return Res;  } +template <typename Derived> +StmtResult TreeTransform<Derived>:: +    TransformOMPTargetTeamsDistributeParallelForSimdDirective( +        OMPTargetTeamsDistributeParallelForSimdDirective *D) { +  DeclarationNameInfo DirName; +  getDerived().getSema().StartOpenMPDSABlock( +      OMPD_target_teams_distribute_parallel_for_simd, DirName, nullptr, +      D->getLocStart()); +  auto Res = getDerived().TransformOMPExecutableDirective(D); +  getDerived().getSema().EndOpenMPDSABlock(Res.get()); +  return Res; +} + +  //===----------------------------------------------------------------------===//  // OpenMP clause transformation  //===----------------------------------------------------------------------===// | 
