/// 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
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,
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;
--- /dev/null
+// 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}}
+}