diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index c6facd4e9e4af..e28ec936e4c2f 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -8081,7 +8081,7 @@ class Sema final { /// Determine whether a particular identifier might be the name in a C++1z /// deduction-guide declaration. bool isDeductionGuideName(Scope *S, const IdentifierInfo &Name, - SourceLocation NameLoc, + SourceLocation NameLoc, CXXScopeSpec &SS, ParsedTemplateTy *Template = nullptr); bool DiagnoseUnknownTemplateName(const IdentifierInfo &II, diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index e28d609464123..2bbe2ba82139d 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -3696,11 +3696,12 @@ void Parser::ParseDeclarationSpecifiers( // Likewise, if this is a context where the identifier could be a template // name, check whether this is a deduction guide declaration. + CXXScopeSpec SS; if (getLangOpts().CPlusPlus17 && (DSContext == DeclSpecContext::DSC_class || DSContext == DeclSpecContext::DSC_top_level) && Actions.isDeductionGuideName(getCurScope(), *Tok.getIdentifierInfo(), - Tok.getLocation()) && + Tok.getLocation(), SS) && isConstructorDeclarator(/*Unqualified*/ true, /*DeductionGuide*/ true)) goto DoneWithDeclSpec; diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp index 8f56316cefcdf..123cf432b0969 100644 --- a/clang/lib/Parse/ParseExprCXX.cpp +++ b/clang/lib/Parse/ParseExprCXX.cpp @@ -2911,9 +2911,9 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, ParsedType ObjectType, if (!Ty) return true; Result.setConstructorName(Ty, IdLoc, IdLoc); - } else if (getLangOpts().CPlusPlus17 && - AllowDeductionGuide && SS.isEmpty() && - Actions.isDeductionGuideName(getCurScope(), *Id, IdLoc, + } else if (getLangOpts().CPlusPlus17 && AllowDeductionGuide && + SS.isEmpty() && + Actions.isDeductionGuideName(getCurScope(), *Id, IdLoc, SS, &TemplateName)) { // We have parsed a template-name naming a deduction guide. Result.setDeductionGuideName(TemplateName, IdLoc); diff --git a/clang/lib/Parse/ParseTentative.cpp b/clang/lib/Parse/ParseTentative.cpp index 934087e59b809..02aa59ec6fa1f 100644 --- a/clang/lib/Parse/ParseTentative.cpp +++ b/clang/lib/Parse/ParseTentative.cpp @@ -74,9 +74,8 @@ bool Parser::isCXXDeclarationStatement( switch (Tok.getKind()) { case tok::identifier: { IdentifierInfo *II = Tok.getIdentifierInfo(); - bool isDeductionGuide = - Actions.isDeductionGuideName(getCurScope(), *II, Tok.getLocation(), - /*Template=*/nullptr); + bool isDeductionGuide = Actions.isDeductionGuideName( + getCurScope(), *II, Tok.getLocation(), SS, /*Template=*/nullptr); if (Actions.isCurrentClassName(*II, getCurScope(), &SS) || isDeductionGuide) { if (isConstructorDeclarator(/*Unqualified=*/SS.isEmpty(), diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index ca1b86c06097e..4fe4b9192ecd3 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -316,9 +316,8 @@ TemplateNameKind Sema::isTemplateName(Scope *S, } bool Sema::isDeductionGuideName(Scope *S, const IdentifierInfo &Name, - SourceLocation NameLoc, - ParsedTemplateTy *Template) { - CXXScopeSpec SS; + SourceLocation NameLoc, CXXScopeSpec &SS, + ParsedTemplateTy *Template /*=nullptr*/) { bool MemberOfUnknownSpecialization = false; // We could use redeclaration lookup here, but we don't need to: the diff --git a/clang/test/Interpreter/disambiguate-decl-stmt.cpp b/clang/test/Interpreter/disambiguate-decl-stmt.cpp index 6f97310475980..85160b6d8a9bf 100644 --- a/clang/test/Interpreter/disambiguate-decl-stmt.cpp +++ b/clang/test/Interpreter/disambiguate-decl-stmt.cpp @@ -7,6 +7,10 @@ extern "C" int printf(const char*,...); // Decls which are hard to disambiguate +// Templates +namespace ns1 { template void tmplt(T &) {}} +int arg_tmplt = 12; ns1::tmplt(arg_tmplt); + // ParseStatementOrDeclaration returns multiple statements. #ifdef MS int g_bFlag = 1;