diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -8081,7 +8081,7 @@ /// 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 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -3696,11 +3696,12 @@ // 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 --- a/clang/lib/Parse/ParseExprCXX.cpp +++ b/clang/lib/Parse/ParseExprCXX.cpp @@ -2911,9 +2911,9 @@ 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 --- a/clang/lib/Parse/ParseTentative.cpp +++ b/clang/lib/Parse/ParseTentative.cpp @@ -74,9 +74,8 @@ 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 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -316,9 +316,8 @@ } 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 --- a/clang/test/Interpreter/disambiguate-decl-stmt.cpp +++ b/clang/test/Interpreter/disambiguate-decl-stmt.cpp @@ -7,6 +7,10 @@ // 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;