diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2017-12-18 20:11:37 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2017-12-18 20:11:37 +0000 |
commit | 461a67fa15370a9ec88f8f8a240bf7c123bb2029 (patch) | |
tree | 6942083d7d56bba40ec790a453ca58ad3baf6832 /lib/Sema/SemaTemplate.cpp | |
parent | 75c3240472ba6ac2669ee72ca67eb72d4e2851fc (diff) | |
download | src-461a67fa15370a9ec88f8f8a240bf7c123bb2029.tar.gz src-461a67fa15370a9ec88f8f8a240bf7c123bb2029.zip |
Vendor import of clang trunk r321017:vendor/clang/clang-trunk-r321017
Notes
Notes:
svn path=/vendor/clang/dist/; revision=326941
svn path=/vendor/clang/clang-trunk-r321017/; revision=326942; tag=vendor/clang/clang-trunk-r321017
Diffstat (limited to 'lib/Sema/SemaTemplate.cpp')
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 144 |
1 files changed, 68 insertions, 76 deletions
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index e9b38551683c..c70a8ba8f126 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/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(), |