diff options
Diffstat (limited to 'clang')
-rw-r--r-- | clang/include/clang/AST/ExprCXX.h | 2 | ||||
-rw-r--r-- | clang/include/clang/Sema/Sema.h | 5 | ||||
-rw-r--r-- | clang/lib/AST/ExprCXX.cpp | 12 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 8 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExprMember.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplate.cpp | 8 | ||||
-rw-r--r-- | clang/lib/Sema/TreeTransform.h | 16 | ||||
-rw-r--r-- | clang/test/SemaTemplate/template-id-expr.cpp | 14 | ||||
-rw-r--r-- | clang/test/SemaTemplate/template-id-printing.cpp | 9 |
10 files changed, 53 insertions, 29 deletions
diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h index fcc417ad1db..40c5a4f6a21 100644 --- a/clang/include/clang/AST/ExprCXX.h +++ b/clang/include/clang/AST/ExprCXX.h @@ -2022,7 +2022,7 @@ public: SourceLocation TemplateKWLoc, const DeclarationNameInfo &NameInfo, bool ADL, - const TemplateArgumentListInfo &Args, + const TemplateArgumentListInfo *Args, UnresolvedSetIterator Begin, UnresolvedSetIterator End); diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 8aca77f51ab..b4bbd7f9074 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -2369,7 +2369,6 @@ public: bool HasTrailingLParen); ExprResult BuildQualifiedDeclarationNameExpr(CXXScopeSpec &SS, - SourceLocation TemplateKWLoc, const DeclarationNameInfo &NameInfo); ExprResult BuildDependentDeclRefExpr(const CXXScopeSpec &SS, SourceLocation TemplateKWLoc, @@ -4001,12 +4000,12 @@ public: SourceLocation TemplateKWLoc, LookupResult &R, bool RequiresADL, - const TemplateArgumentListInfo &TemplateArgs); + const TemplateArgumentListInfo *TemplateArgs); ExprResult BuildQualifiedTemplateIdExpr(CXXScopeSpec &SS, SourceLocation TemplateKWLoc, const DeclarationNameInfo &NameInfo, - const TemplateArgumentListInfo &TemplateArgs); + const TemplateArgumentListInfo *TemplateArgs); TemplateNameKind ActOnDependentTemplateName(Scope *S, CXXScopeSpec &SS, diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp index af8498daa7b..df223eb32c3 100644 --- a/clang/lib/AST/ExprCXX.cpp +++ b/clang/lib/AST/ExprCXX.cpp @@ -200,15 +200,17 @@ UnresolvedLookupExpr::Create(ASTContext &C, SourceLocation TemplateKWLoc, const DeclarationNameInfo &NameInfo, bool ADL, - const TemplateArgumentListInfo &Args, - UnresolvedSetIterator Begin, - UnresolvedSetIterator End) + const TemplateArgumentListInfo *Args, + UnresolvedSetIterator Begin, + UnresolvedSetIterator End) { + assert(Args || TemplateKWLoc.isValid()); + unsigned num_args = Args ? Args->size() : 0; void *Mem = C.Allocate(sizeof(UnresolvedLookupExpr) + - ASTTemplateKWAndArgsInfo::sizeFor(Args.size())); + ASTTemplateKWAndArgsInfo::sizeFor(num_args)); return new (Mem) UnresolvedLookupExpr(C, NamingClass, QualifierLoc, TemplateKWLoc, NameInfo, - ADL, /*Overload*/ true, &Args, + ADL, /*Overload*/ true, Args, Begin, End, /*StdIsAssociated=*/false); } diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 15dfb0b8c20..a47421d801d 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -1652,8 +1652,8 @@ ExprResult Sema::ActOnIdExpression(Scope *S, R, TemplateArgs); } - if (TemplateArgs) - return BuildTemplateIdExpr(SS, TemplateKWLoc, R, ADL, *TemplateArgs); + if (TemplateArgs || TemplateKWLoc.isValid()) + return BuildTemplateIdExpr(SS, TemplateKWLoc, R, ADL, TemplateArgs); return BuildDeclarationNameExpr(SS, R, ADL); } @@ -1664,11 +1664,11 @@ ExprResult Sema::ActOnIdExpression(Scope *S, /// this path. ExprResult Sema::BuildQualifiedDeclarationNameExpr(CXXScopeSpec &SS, - SourceLocation TemplateKWLoc, const DeclarationNameInfo &NameInfo) { DeclContext *DC; if (!(DC = computeDeclContext(SS, false)) || DC->isDependentContext()) - return BuildDependentDeclRefExpr(SS, TemplateKWLoc, NameInfo, 0); + return BuildDependentDeclRefExpr(SS, /*TemplateKWLoc=*/SourceLocation(), + NameInfo, /*TemplateArgs=*/0); if (RequireCompleteDeclContext(SS, DC)) return ExprError(); diff --git a/clang/lib/Sema/SemaExprMember.cpp b/clang/lib/Sema/SemaExprMember.cpp index 1545d6ef205..92cf619d92a 100644 --- a/clang/lib/Sema/SemaExprMember.cpp +++ b/clang/lib/Sema/SemaExprMember.cpp @@ -232,8 +232,8 @@ Sema::BuildPossibleImplicitMemberExpr(const CXXScopeSpec &SS, case IMA_Mixed_StaticContext: case IMA_Unresolved_StaticContext: case IMA_Field_Uneval_Context: - if (TemplateArgs) - return BuildTemplateIdExpr(SS, TemplateKWLoc, R, false, *TemplateArgs); + if (TemplateArgs || TemplateKWLoc.isValid()) + return BuildTemplateIdExpr(SS, TemplateKWLoc, R, false, TemplateArgs); return BuildDeclarationNameExpr(SS, R, false); case IMA_Error_StaticContext: diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 5fe136a1662..fa103819bd2 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -9310,9 +9310,9 @@ BuildRecoveryCallExpr(Sema &SemaRef, Scope *S, Expr *Fn, if ((*R.begin())->isCXXClassMember()) NewFn = SemaRef.BuildPossibleImplicitMemberExpr(SS, TemplateKWLoc, R, ExplicitTemplateArgs); - else if (ExplicitTemplateArgs) + else if (ExplicitTemplateArgs || TemplateKWLoc.isValid()) NewFn = SemaRef.BuildTemplateIdExpr(SS, TemplateKWLoc, R, false, - *ExplicitTemplateArgs); + ExplicitTemplateArgs); else NewFn = SemaRef.BuildDeclarationNameExpr(SS, R, false); diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 86c5a5b1f84..44480a47cab 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -2203,7 +2203,7 @@ ExprResult Sema::BuildTemplateIdExpr(const CXXScopeSpec &SS, SourceLocation TemplateKWLoc, LookupResult &R, bool RequiresADL, - const TemplateArgumentListInfo &TemplateArgs) { + const TemplateArgumentListInfo *TemplateArgs) { // FIXME: Can we do any checking at this point? I guess we could check the // template arguments that we have against the template name, if the template // name refers to a single template. That's not a terribly common case, @@ -2237,13 +2237,13 @@ ExprResult Sema::BuildQualifiedTemplateIdExpr(CXXScopeSpec &SS, SourceLocation TemplateKWLoc, const DeclarationNameInfo &NameInfo, - const TemplateArgumentListInfo &TemplateArgs) { + const TemplateArgumentListInfo *TemplateArgs) { + assert(TemplateArgs || TemplateKWLoc.isValid()); DeclContext *DC; if (!(DC = computeDeclContext(SS, false)) || DC->isDependentContext() || RequireCompleteDeclContext(SS, DC)) - return BuildDependentDeclRefExpr(SS, TemplateKWLoc, NameInfo, - &TemplateArgs); + return BuildDependentDeclRefExpr(SS, TemplateKWLoc, NameInfo, TemplateArgs); bool MemberOfUnknownSpecialization; LookupResult R(*this, NameInfo, LookupOrdinaryName); diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 6bbb8316e59..806b8780aa9 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -2032,12 +2032,11 @@ public: CXXScopeSpec SS; SS.Adopt(QualifierLoc); - if (TemplateArgs) + if (TemplateArgs || TemplateKWLoc.isValid()) return getSema().BuildQualifiedTemplateIdExpr(SS, TemplateKWLoc, - NameInfo, *TemplateArgs); + NameInfo, TemplateArgs); - return getSema().BuildQualifiedDeclarationNameExpr(SS, TemplateKWLoc, - NameInfo); + return getSema().BuildQualifiedDeclarationNameExpr(SS, NameInfo); } /// \brief Build a new template-id expression. @@ -2048,7 +2047,7 @@ public: SourceLocation TemplateKWLoc, LookupResult &R, bool RequiresADL, - const TemplateArgumentListInfo &TemplateArgs) { + const TemplateArgumentListInfo *TemplateArgs) { return getSema().BuildTemplateIdExpr(SS, TemplateKWLoc, R, RequiresADL, TemplateArgs); } @@ -7361,8 +7360,9 @@ TreeTransform<Derived>::TransformUnresolvedLookupExpr( SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc(); - // If we have no template arguments, it's a normal declaration name. - if (!Old->hasExplicitTemplateArgs()) + // If we have neither explicit template arguments, nor the template keyword, + // it's a normal declaration name. + if (!Old->hasExplicitTemplateArgs() && !TemplateKWLoc.isValid()) return getDerived().RebuildDeclarationNameExpr(SS, R, Old->requiresADL()); // If we have template arguments, rebuild them, then rebuild the @@ -7374,7 +7374,7 @@ TreeTransform<Derived>::TransformUnresolvedLookupExpr( return ExprError(); return getDerived().RebuildTemplateIdExpr(SS, TemplateKWLoc, R, - Old->requiresADL(), TransArgs); + Old->requiresADL(), &TransArgs); } template<typename Derived> diff --git a/clang/test/SemaTemplate/template-id-expr.cpp b/clang/test/SemaTemplate/template-id-expr.cpp index de8d7f6c91a..4416f92723a 100644 --- a/clang/test/SemaTemplate/template-id-expr.cpp +++ b/clang/test/SemaTemplate/template-id-expr.cpp @@ -82,3 +82,17 @@ struct Y0 { x = this->template f4(0); // expected-error {{assigning to 'int' from incompatible type 'void'}} } }; + +struct A { + template<int I> + struct B { + static void b1(); + }; +}; + +template<int I> +void f5() { + A::template B<I>::template b1(); // expected-error {{'b1' following the 'template' keyword does not refer to a template}} +} + +template void f5<0>(); // expected-note {{in instantiation of function template specialization 'f5<0>' requested here}} diff --git a/clang/test/SemaTemplate/template-id-printing.cpp b/clang/test/SemaTemplate/template-id-printing.cpp index 3b9e25196dc..047589b1ce4 100644 --- a/clang/test/SemaTemplate/template-id-printing.cpp +++ b/clang/test/SemaTemplate/template-id-printing.cpp @@ -130,3 +130,12 @@ void test() { } } // namespace DSME + +namespace DSDRE_withImplicitTemplateArgs { + +template <typename T> void foo() { + // CHECK: T::template bar(); + T::template bar(); +} + +} // namespace DSDRE_withImplicitTemplateArgs |