hokein created this revision. hokein added a reviewer: sammccall. Herald added a project: clang.
Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D82631 Files: clang/include/clang/AST/NestedNameSpecifier.h clang/lib/AST/NestedNameSpecifier.cpp clang/lib/Sema/SemaDecl.cpp clang/test/SemaTemplate/missing-typename-recovery.cpp Index: clang/test/SemaTemplate/missing-typename-recovery.cpp =================================================================== --- /dev/null +++ clang/test/SemaTemplate/missing-typename-recovery.cpp @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// There should be no extra errors about missing 'typename' keywords. +void f() { + decltype(undef())::Type T; // expected-error {{use of undeclared identifier}} +} Index: clang/lib/Sema/SemaDecl.cpp =================================================================== --- clang/lib/Sema/SemaDecl.cpp +++ clang/lib/Sema/SemaDecl.cpp @@ -750,7 +750,10 @@ Diag(IILoc, IsTemplateName ? diag::err_no_member_template : diag::err_typename_nested_not_found) << II << DC << SS->getRange(); - else if (isDependentScopeSpecifier(*SS)) { + else if (SS->isValid() && SS->getScopeRep()->containsErrors()) { + SuggestedType = + ActOnTypenameType(S, SourceLocation(), *SS, *II, IILoc).get(); + } else if (isDependentScopeSpecifier(*SS)) { unsigned DiagID = diag::err_typename_missing; if (getLangOpts().MSVCCompat && isMicrosoftMissingTypename(SS, S)) DiagID = diag::ext_typename_missing; Index: clang/lib/AST/NestedNameSpecifier.cpp =================================================================== --- clang/lib/AST/NestedNameSpecifier.cpp +++ clang/lib/AST/NestedNameSpecifier.cpp @@ -243,6 +243,10 @@ return getDependence() & NestedNameSpecifierDependence::UnexpandedPack; } +bool NestedNameSpecifier::containsErrors() const { + return getDependence() & NestedNameSpecifierDependence::Error; +} + /// Print this nested name specifier to the given output /// stream. void NestedNameSpecifier::print(raw_ostream &OS, const PrintingPolicy &Policy, Index: clang/include/clang/AST/NestedNameSpecifier.h =================================================================== --- clang/include/clang/AST/NestedNameSpecifier.h +++ clang/include/clang/AST/NestedNameSpecifier.h @@ -214,6 +214,9 @@ /// parameter pack (for C++11 variadic templates). bool containsUnexpandedParameterPack() const; + /// Whether this nested name specifier contains an error. + bool containsErrors() const; + /// Print this nested name specifier to the given output stream. If /// `ResolveTemplateArguments` is true, we'll print actual types, e.g. /// `ns::SomeTemplate<int, MyClass>` instead of
Index: clang/test/SemaTemplate/missing-typename-recovery.cpp =================================================================== --- /dev/null +++ clang/test/SemaTemplate/missing-typename-recovery.cpp @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// There should be no extra errors about missing 'typename' keywords. +void f() { + decltype(undef())::Type T; // expected-error {{use of undeclared identifier}} +} Index: clang/lib/Sema/SemaDecl.cpp =================================================================== --- clang/lib/Sema/SemaDecl.cpp +++ clang/lib/Sema/SemaDecl.cpp @@ -750,7 +750,10 @@ Diag(IILoc, IsTemplateName ? diag::err_no_member_template : diag::err_typename_nested_not_found) << II << DC << SS->getRange(); - else if (isDependentScopeSpecifier(*SS)) { + else if (SS->isValid() && SS->getScopeRep()->containsErrors()) { + SuggestedType = + ActOnTypenameType(S, SourceLocation(), *SS, *II, IILoc).get(); + } else if (isDependentScopeSpecifier(*SS)) { unsigned DiagID = diag::err_typename_missing; if (getLangOpts().MSVCCompat && isMicrosoftMissingTypename(SS, S)) DiagID = diag::ext_typename_missing; Index: clang/lib/AST/NestedNameSpecifier.cpp =================================================================== --- clang/lib/AST/NestedNameSpecifier.cpp +++ clang/lib/AST/NestedNameSpecifier.cpp @@ -243,6 +243,10 @@ return getDependence() & NestedNameSpecifierDependence::UnexpandedPack; } +bool NestedNameSpecifier::containsErrors() const { + return getDependence() & NestedNameSpecifierDependence::Error; +} + /// Print this nested name specifier to the given output /// stream. void NestedNameSpecifier::print(raw_ostream &OS, const PrintingPolicy &Policy, Index: clang/include/clang/AST/NestedNameSpecifier.h =================================================================== --- clang/include/clang/AST/NestedNameSpecifier.h +++ clang/include/clang/AST/NestedNameSpecifier.h @@ -214,6 +214,9 @@ /// parameter pack (for C++11 variadic templates). bool containsUnexpandedParameterPack() const; + /// Whether this nested name specifier contains an error. + bool containsErrors() const; + /// Print this nested name specifier to the given output stream. If /// `ResolveTemplateArguments` is true, we'll print actual types, e.g. /// `ns::SomeTemplate<int, MyClass>` instead of
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits