diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Sema/SemaTemplate.cpp')
| -rw-r--r-- | contrib/llvm/tools/clang/lib/Sema/SemaTemplate.cpp | 144 | 
1 files changed, 68 insertions, 76 deletions
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaTemplate.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaTemplate.cpp index e9b38551683c..c70a8ba8f126 100644 --- a/contrib/llvm/tools/clang/lib/Sema/SemaTemplate.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/SemaTemplate.cpp @@ -778,7 +778,7 @@ static void maybeDiagnoseTemplateParameterShadow(Sema &SemaRef, Scope *S,                                                   SourceLocation Loc,                                                   IdentifierInfo *Name) {    NamedDecl *PrevDecl = SemaRef.LookupSingleName( -      S, Name, Loc, Sema::LookupOrdinaryName, Sema::ForRedeclaration); +      S, Name, Loc, Sema::LookupOrdinaryName, Sema::ForVisibleRedeclaration);    if (PrevDecl && PrevDecl->isTemplateParameter())      SemaRef.DiagnoseTemplateParameterShadow(Loc, PrevDecl);  } @@ -1080,7 +1080,7 @@ Sema::ActOnTemplateParameterList(unsigned Depth,                                   SourceLocation ExportLoc,                                   SourceLocation TemplateLoc,                                   SourceLocation LAngleLoc, -                                 ArrayRef<Decl *> Params, +                                 ArrayRef<NamedDecl *> Params,                                   SourceLocation RAngleLoc,                                   Expr *RequiresClause) {    if (ExportLoc.isValid()) @@ -1088,7 +1088,7 @@ Sema::ActOnTemplateParameterList(unsigned Depth,    return TemplateParameterList::Create(        Context, TemplateLoc, LAngleLoc, -      llvm::makeArrayRef((NamedDecl *const *)Params.data(), Params.size()), +      llvm::makeArrayRef(Params.data(), Params.size()),        RAngleLoc, RequiresClause);  } @@ -1133,7 +1133,7 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK,    LookupResult Previous(*this, Name, NameLoc,                          (SS.isEmpty() && TUK == TUK_Friend)                            ? LookupTagName : LookupOrdinaryName, -                        ForRedeclaration); +                        forRedeclarationInCurContext());    if (SS.isNotEmpty() && !SS.isInvalid()) {      SemanticContext = computeDeclContext(SS, true);      if (!SemanticContext) { @@ -1192,8 +1192,8 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK,    // If there is a previous declaration with the same name, check    // whether this is a valid redeclaration. -  ClassTemplateDecl *PrevClassTemplate -    = dyn_cast_or_null<ClassTemplateDecl>(PrevDecl); +  ClassTemplateDecl *PrevClassTemplate = +      dyn_cast_or_null<ClassTemplateDecl>(PrevDecl);    // We may have found the injected-class-name of a class template,    // class template partial specialization, or class template specialization. @@ -1484,6 +1484,9 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK,      CurContext->addDecl(Friend);    } +  if (PrevClassTemplate) +    CheckRedeclarationModuleOwnership(NewTemplate, PrevClassTemplate); +    if (Invalid) {      NewTemplate->setInvalidDecl();      NewClass->setInvalidDecl(); @@ -1834,7 +1837,6 @@ void Sema::DeclareImplicitDeductionGuides(TemplateDecl *Template,    // for which some class template parameter without a default argument never    // appears in a deduced context).    bool AddedAny = false; -  bool AddedCopyOrMove = false;    for (NamedDecl *D : LookupConstructors(Transform.Primary)) {      D = D->getUnderlyingDecl();      if (D->isInvalidDecl() || D->isImplicit()) @@ -1851,20 +1853,22 @@ void Sema::DeclareImplicitDeductionGuides(TemplateDecl *Template,      Transform.transformConstructor(FTD, CD);      AddedAny = true; - -    AddedCopyOrMove |= CD->isCopyOrMoveConstructor();    } -  // Synthesize an X() -> X<...> guide if there were no declared constructors. -  // FIXME: The standard doesn't say (how) to do this. +  // C++17 [over.match.class.deduct] +  //    --  If C is not defined or does not declare any constructors, an +  //    additional function template derived as above from a hypothetical +  //    constructor C().    if (!AddedAny)      Transform.buildSimpleDeductionGuide(None); -  // Synthesize an X(X<...>) -> X<...> guide if there was no declared constructor -  // resembling a copy or move constructor. -  // FIXME: The standard doesn't say (how) to do this. -  if (!AddedCopyOrMove) -    Transform.buildSimpleDeductionGuide(Transform.DeducedType); +  //    -- An additional function template derived as above from a hypothetical +  //    constructor C(C), called the copy deduction candidate. +  cast<CXXDeductionGuideDecl>( +      cast<FunctionTemplateDecl>( +          Transform.buildSimpleDeductionGuide(Transform.DeducedType)) +          ->getTemplatedDecl()) +      ->setIsCopyDeductionCandidate();  }  /// \brief Diagnose the presence of a default template argument on a @@ -2863,11 +2867,9 @@ static Expr *lookThroughRangesV3Condition(Preprocessor &PP, Expr *Cond) {    return Cond;  } -/// Find the failed subexpression within enable_if, and describe it -/// with a string. -static std::pair<Expr *, std::string> -findFailedEnableIfCondition(Sema &S, Expr *Cond) { -  Cond = lookThroughRangesV3Condition(S.PP, Cond); +std::pair<Expr *, std::string> +Sema::findFailedBooleanCondition(Expr *Cond, bool AllowTopLevelCond) { +  Cond = lookThroughRangesV3Condition(PP, Cond);    // Separate out all of the terms in a conjunction.    SmallVector<Expr *, 4> Terms; @@ -2876,27 +2878,37 @@ findFailedEnableIfCondition(Sema &S, Expr *Cond) {    // Determine which term failed.    Expr *FailedCond = nullptr;    for (Expr *Term : Terms) { +    Expr *TermAsWritten = Term->IgnoreParenImpCasts(); + +    // Literals are uninteresting. +    if (isa<CXXBoolLiteralExpr>(TermAsWritten) || +        isa<IntegerLiteral>(TermAsWritten)) +      continue; +      // The initialization of the parameter from the argument is      // a constant-evaluated context.      EnterExpressionEvaluationContext ConstantEvaluated( -      S, Sema::ExpressionEvaluationContext::ConstantEvaluated); +      *this, Sema::ExpressionEvaluationContext::ConstantEvaluated);      bool Succeeded; -    if (Term->EvaluateAsBooleanCondition(Succeeded, S.Context) && +    if (Term->EvaluateAsBooleanCondition(Succeeded, Context) &&          !Succeeded) { -      FailedCond = Term->IgnoreParenImpCasts(); +      FailedCond = TermAsWritten;        break;      }    } -  if (!FailedCond) +  if (!FailedCond) { +    if (!AllowTopLevelCond) +      return { nullptr, "" }; +      FailedCond = Cond->IgnoreParenImpCasts(); +  }    std::string Description;    {      llvm::raw_string_ostream Out(Description); -    FailedCond->printPretty(Out, nullptr, -                            PrintingPolicy(S.Context.getLangOpts())); +    FailedCond->printPretty(Out, nullptr, getPrintingPolicy());    }    return { FailedCond, Description };  } @@ -2980,8 +2992,9 @@ QualType Sema::CheckTemplateIdType(TemplateName Name,              Expr *FailedCond;              std::string FailedDescription;              std::tie(FailedCond, FailedDescription) = -              findFailedEnableIfCondition( -                *this, TemplateArgs[0].getSourceExpression()); +              findFailedBooleanCondition( +                TemplateArgs[0].getSourceExpression(), +                /*AllowTopLevelCond=*/true);              // Remove the old SFINAE diagnostic.              PartialDiagnosticAt OldDiag = @@ -3668,7 +3681,7 @@ DeclResult Sema::ActOnVarTemplateSpecialization(      // Check that this isn't a redefinition of this specialization,      // merging with previous declarations.      LookupResult PrevSpec(*this, GetNameForDeclarator(D), LookupOrdinaryName, -                          ForRedeclaration); +                          forRedeclarationInCurContext());      PrevSpec.addDecl(PrevDecl);      D.setRedeclaration(CheckVariableDeclaration(Specialization, PrevSpec));    } else if (Specialization->isStaticDataMember() && @@ -4792,7 +4805,12 @@ bool Sema::CheckTemplateArgumentList(    // template.    TemplateArgumentListInfo NewArgs = TemplateArgs; -  TemplateParameterList *Params = Template->getTemplateParameters(); +  // Make sure we get the template parameter list from the most +  // recentdeclaration, since that is the only one that has is guaranteed to +  // have all the default template argument information. +  TemplateParameterList *Params = +      cast<TemplateDecl>(Template->getMostRecentDecl()) +          ->getTemplateParameters();    SourceLocation RAngleLoc = NewArgs.getRAngleLoc(); @@ -5116,6 +5134,11 @@ bool UnnamedLocalNoLinkageFinder::VisitDependentSizedExtVectorType(    return Visit(T->getElementType());  } +bool UnnamedLocalNoLinkageFinder::VisitDependentAddressSpaceType( +    const DependentAddressSpaceType *T) { +  return Visit(T->getPointeeType()); +} +  bool UnnamedLocalNoLinkageFinder::VisitVectorType(const VectorType* T) {    return Visit(T->getElementType());  } @@ -5900,7 +5923,7 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,    SourceLocation StartLoc = Arg->getLocStart();    // If the parameter type somehow involves auto, deduce the type now. -  if (getLangOpts().CPlusPlus1z && ParamType->isUndeducedType()) { +  if (getLangOpts().CPlusPlus17 && ParamType->isUndeducedType()) {      // During template argument deduction, we allow 'decltype(auto)' to      // match an arbitrary dependent argument.      // FIXME: The language rules don't say what happens in this case. @@ -5984,8 +6007,8 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,    EnterExpressionEvaluationContext ConstantEvaluated(        *this, Sema::ExpressionEvaluationContext::ConstantEvaluated); -  if (getLangOpts().CPlusPlus1z) { -    // C++1z [temp.arg.nontype]p1: +  if (getLangOpts().CPlusPlus17) { +    // C++17 [temp.arg.nontype]p1:      //   A template-argument for a non-type template parameter shall be      //   a converted constant expression of the type of the template-parameter.      APValue Value; @@ -6152,7 +6175,6 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,      //     -- an integral constant-expression of integral or enumeration      //        type; or      //     -- the name of a non-type template-parameter; or -    SourceLocation NonConstantLoc;      llvm::APSInt Value;      if (!ArgType->isIntegralOrEnumerationType()) {        Diag(Arg->getLocStart(), @@ -8015,15 +8037,6 @@ bool Sema::CheckFunctionTemplateSpecialization(    // Ignore access information;  it doesn't figure into redeclaration checking.    FunctionDecl *Specialization = cast<FunctionDecl>(*Result); -  // C++ Concepts TS [dcl.spec.concept]p7: A program shall not declare [...] -  // an explicit specialization (14.8.3) [...] of a concept definition. -  if (Specialization->getPrimaryTemplate()->isConcept()) { -    Diag(FD->getLocation(), diag::err_concept_specialized) -        << 0 /*function*/ << 1 /*explicitly specialized*/; -    Diag(Specialization->getLocation(), diag::note_previous_declaration); -    return true; -  } -    FunctionTemplateSpecializationInfo *SpecInfo      = Specialization->getTemplateSpecializationInfo();    assert(SpecInfo && "Function template specialization info missing?"); @@ -8910,15 +8923,6 @@ DeclResult Sema::ActOnExplicitInstantiation(Scope *S,      Diag(D.getDeclSpec().getConstexprSpecLoc(),           diag::err_explicit_instantiation_constexpr); -  // C++ Concepts TS [dcl.spec.concept]p1: The concept specifier shall be -  // applied only to the definition of a function template or variable template, -  // declared in namespace scope. -  if (D.getDeclSpec().isConceptSpecified()) { -    Diag(D.getDeclSpec().getConceptSpecLoc(), -         diag::err_concept_specified_specialization) << 0; -    return true; -  } -    // A deduction guide is not on the list of entities that can be explicitly    // instantiated.    if (Name.getNameKind() == DeclarationName::CXXDeductionGuideName) { @@ -8998,15 +9002,6 @@ DeclResult Sema::ActOnExplicitInstantiation(Scope *S,          return true;        } -      // C++ Concepts TS [dcl.spec.concept]p7: A program shall not declare an -      // explicit instantiation (14.8.2) [...] of a concept definition. -      if (PrevTemplate->isConcept()) { -        Diag(D.getIdentifierLoc(), diag::err_concept_specialized) -            << 1 /*variable*/ << 0 /*explicitly instantiated*/; -        Diag(PrevTemplate->getLocation(), diag::note_previous_declaration); -        return true; -      } -        // Translate the parser's template argument list into our AST format.        TemplateArgumentListInfo TemplateArgs =            makeTemplateArgumentListInfo(*this, *D.getName().TemplateId); @@ -9049,7 +9044,6 @@ DeclResult Sema::ActOnExplicitInstantiation(Scope *S,      if (!HasNoEffect) {        // Instantiate static data member or variable template. -        Prev->setTemplateSpecializationKind(TSK, D.getIdentifierLoc());        if (PrevTemplate) {          // Merge attributes. @@ -9217,10 +9211,18 @@ DeclResult Sema::ActOnExplicitInstantiation(Scope *S,        return (Decl*) nullptr;    } -  Specialization->setTemplateSpecializationKind(TSK, D.getIdentifierLoc());    if (Attr)      ProcessDeclAttributeList(S, Specialization, Attr); +  // In MSVC mode, dllimported explicit instantiation definitions are treated as +  // instantiation declarations. +  if (TSK == TSK_ExplicitInstantiationDefinition && +      Specialization->hasAttr<DLLImportAttr>() && +      Context.getTargetInfo().getCXXABI().isMicrosoft()) +    TSK = TSK_ExplicitInstantiationDeclaration; + +  Specialization->setTemplateSpecializationKind(TSK, D.getIdentifierLoc()); +    if (Specialization->isDefined()) {      // Let the ASTConsumer know that this function has been explicitly      // instantiated now, and its linkage might have changed. @@ -9243,16 +9245,6 @@ DeclResult Sema::ActOnExplicitInstantiation(Scope *S,           diag::ext_explicit_instantiation_without_qualified_id)      << Specialization << D.getCXXScopeSpec().getRange(); -  // C++ Concepts TS [dcl.spec.concept]p7: A program shall not declare an -  // explicit instantiation (14.8.2) [...] of a concept definition. -  if (FunTmpl && FunTmpl->isConcept() && -      !D.getDeclSpec().isConceptSpecified()) { -    Diag(D.getIdentifierLoc(), diag::err_concept_specialized) -        << 0 /*function*/ << 0 /*explicitly instantiated*/; -    Diag(FunTmpl->getLocation(), diag::note_previous_declaration); -    return true; -  } -    CheckExplicitInstantiationScope(*this,                     FunTmpl? (NamedDecl *)FunTmpl                            : Specialization->getInstantiatedFromMemberFunction(), @@ -9513,7 +9505,7 @@ Sema::CheckTypenameType(ElaboratedTypeKeyword Keyword,          Expr *FailedCond;          std::string FailedDescription;          std::tie(FailedCond, FailedDescription) = -          findFailedEnableIfCondition(*this, Cond); +          findFailedBooleanCondition(Cond, /*AllowTopLevelCond=*/true);          Diag(FailedCond->getExprLoc(),               diag::err_typename_nested_not_found_requirement) @@ -9591,7 +9583,7 @@ Sema::CheckTypenameType(ElaboratedTypeKeyword Keyword,      //   A type-specifier of the form      //     typename[opt] nested-name-specifier[opt] template-name      //   is a placeholder for a deduced class type [...]. -    if (getLangOpts().CPlusPlus1z) { +    if (getLangOpts().CPlusPlus17) {        if (auto *TD = getAsTypeTemplateDecl(Result.getFoundDecl())) {          return Context.getElaboratedType(              Keyword, QualifierLoc.getNestedNameSpecifier(),  | 
