diff options
-rw-r--r-- | clang/include/clang/Parse/Parser.h | 6 | ||||
-rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 96 | ||||
-rw-r--r-- | clang/lib/Parse/ParseDeclCXX.cpp | 5 | ||||
-rw-r--r-- | clang/lib/Parse/ParseExpr.cpp | 6 | ||||
-rw-r--r-- | clang/lib/Parse/ParseExprCXX.cpp | 16 | ||||
-rw-r--r-- | clang/lib/Parse/ParseTentative.cpp | 19 | ||||
-rw-r--r-- | clang/lib/Parse/Parser.cpp | 40 | ||||
-rw-r--r-- | clang/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-nodeduct.cpp | 3 | ||||
-rw-r--r-- | clang/test/Parser/cxx-template-argument.cpp | 2 | ||||
-rw-r--r-- | clang/test/SemaCXX/member-pointer.cpp | 3 | ||||
-rw-r--r-- | clang/test/SemaCXX/nested-name-spec.cpp | 5 | ||||
-rw-r--r-- | clang/test/SemaTemplate/dependent-base-classes.cpp | 1 | ||||
-rw-r--r-- | clang/test/SemaTemplate/explicit-specialization-member.cpp | 2 | ||||
-rw-r--r-- | clang/test/SemaTemplate/nested-name-spec-template.cpp | 1 | ||||
-rw-r--r-- | clang/test/SemaTemplate/temp_arg.cpp | 7 |
15 files changed, 124 insertions, 88 deletions
diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index 4a367484c9d..c4488e2f68c 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -320,9 +320,9 @@ private: /// This returns true if the token was annotated. bool TryAnnotateTypeOrScopeToken(bool EnteringContext = false); - /// TryAnnotateCXXScopeToken - Like TryAnnotateTypeOrScopeToken but only - /// annotates C++ scope specifiers. This returns true if the token was - /// annotated. + /// TryAnnotateCXXScopeToken - Like TryAnnotateTypeOrScopeToken but + /// only annotates C++ scope specifiers. This returns true if there + /// was an unrecoverable error. bool TryAnnotateCXXScopeToken(bool EnteringContext = false); /// TryAltiVecToken - Check for context-sensitive AltiVec identifier tokens, diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 62b10a316e6..5dc4bd2f609 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -859,10 +859,13 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, return; case tok::coloncolon: // ::foo::bar - // Annotate C++ scope specifiers. If we get one, loop. - if (TryAnnotateCXXScopeToken(true)) - continue; - goto DoneWithDeclSpec; + // C++ scope specifier. Annotate and loop, or bail out on error. + if (TryAnnotateCXXScopeToken(true)) { + if (!DS.hasTypeSpecifier()) + DS.SetTypeSpecError(); + goto DoneWithDeclSpec; + } + continue; case tok::annot_cxxscope: { if (DS.hasTypeSpecifier()) @@ -1020,8 +1023,15 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, case tok::identifier: { // In C++, check to see if this is a scope specifier like foo::bar::, if // so handle it as such. This is important for ctor parsing. - if (getLang().CPlusPlus && TryAnnotateCXXScopeToken(true)) - continue; + if (getLang().CPlusPlus) { + if (TryAnnotateCXXScopeToken(true)) { + if (!DS.hasTypeSpecifier()) + DS.SetTypeSpecError(); + goto DoneWithDeclSpec; + } + if (!Tok.is(tok::identifier)) + continue; + } // This identifier can only be a typedef name if we haven't already seen // a type-specifier. Without this check we misparse: @@ -1313,7 +1323,11 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, // C++ typename-specifier: case tok::kw_typename: - if (TryAnnotateTypeOrScopeToken()) + if (TryAnnotateTypeOrScopeToken()) { + DS.SetTypeSpecError(); + goto DoneWithDeclSpec; + } + if (!Tok.is(tok::kw_typename)) continue; break; @@ -1423,10 +1437,11 @@ bool Parser::ParseOptionalTypeSpecifier(DeclSpec &DS, bool& isInvalid, // Annotate typenames and C++ scope specifiers. If we get one, just // recurse to handle whatever we get. if (TryAnnotateTypeOrScopeToken()) - return ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec, DiagID, - TemplateInfo, SuppressDeclarations); - // Otherwise, not a type specifier. - return false; + return true; + if (Tok.is(tok::identifier)) + return false; + return ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec, DiagID, + TemplateInfo, SuppressDeclarations); case tok::coloncolon: // ::foo::bar if (NextToken().is(tok::kw_new) || // ::new NextToken().is(tok::kw_delete)) // ::delete @@ -1435,10 +1450,9 @@ bool Parser::ParseOptionalTypeSpecifier(DeclSpec &DS, bool& isInvalid, // Annotate typenames and C++ scope specifiers. If we get one, just // recurse to handle whatever we get. if (TryAnnotateTypeOrScopeToken()) - return ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec, DiagID, - TemplateInfo, SuppressDeclarations); - // Otherwise, not a type specifier. - return false; + return true; + return ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec, DiagID, + TemplateInfo, SuppressDeclarations); // simple-type-specifier: case tok::annot_typename: { @@ -1848,8 +1862,11 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS, Attr.reset(ParseGNUAttributes()); CXXScopeSpec SS; - if (getLang().CPlusPlus && ParseOptionalCXXScopeSpecifier(SS, 0, false)) { - if (Tok.isNot(tok::identifier)) { + if (getLang().CPlusPlus) { + if (ParseOptionalCXXScopeSpecifier(SS, 0, false)) + return; + + if (SS.isSet() && Tok.isNot(tok::identifier)) { Diag(Tok, diag::err_expected_ident); if (Tok.isNot(tok::l_brace)) { // Has no name and is not a definition. @@ -2016,21 +2033,19 @@ bool Parser::isTypeSpecifierQualifier() { // Annotate typenames and C++ scope specifiers. If we get one, just // recurse to handle whatever we get. if (TryAnnotateTypeOrScopeToken()) - return isTypeSpecifierQualifier(); - // Otherwise, not a type specifier. - return false; + return true; + if (Tok.is(tok::identifier)) + return false; + return isTypeSpecifierQualifier(); case tok::coloncolon: // ::foo::bar if (NextToken().is(tok::kw_new) || // ::new NextToken().is(tok::kw_delete)) // ::delete return false; - // Annotate typenames and C++ scope specifiers. If we get one, just - // recurse to handle whatever we get. if (TryAnnotateTypeOrScopeToken()) - return isTypeSpecifierQualifier(); - // Otherwise, not a type specifier. - return false; + return true; + return isTypeSpecifierQualifier(); // GNU attributes support. case tok::kw___attribute: @@ -2101,14 +2116,15 @@ bool Parser::isDeclarationSpecifier() { if (TryAltiVecVectorToken()) return true; // Fall through. - case tok::kw_typename: // typename T::type // Annotate typenames and C++ scope specifiers. If we get one, just // recurse to handle whatever we get. if (TryAnnotateTypeOrScopeToken()) - return isDeclarationSpecifier(); - // Otherwise, not a declaration specifier. - return false; + return true; + if (Tok.is(tok::identifier)) + return false; + return isDeclarationSpecifier(); + case tok::coloncolon: // ::foo::bar if (NextToken().is(tok::kw_new) || // ::new NextToken().is(tok::kw_delete)) // ::delete @@ -2117,9 +2133,8 @@ bool Parser::isDeclarationSpecifier() { // Annotate typenames and C++ scope specifiers. If we get one, just // recurse to handle whatever we get. if (TryAnnotateTypeOrScopeToken()) - return isDeclarationSpecifier(); - // Otherwise, not a declaration specifier. - return false; + return true; + return isDeclarationSpecifier(); // storage-class-specifier case tok::kw_typedef: @@ -2200,7 +2215,10 @@ bool Parser::isConstructorDeclarator() { // Parse the C++ scope specifier. CXXScopeSpec SS; - ParseOptionalCXXScopeSpecifier(SS, 0, true); + if (ParseOptionalCXXScopeSpecifier(SS, 0, true)) { + TPA.Revert(); + return false; + } // Parse the constructor name. if (Tok.is(tok::identifier) || Tok.is(tok::annot_template_id)) { @@ -2351,7 +2369,9 @@ void Parser::ParseDeclaratorInternal(Declarator &D, (Tok.is(tok::coloncolon) || Tok.is(tok::identifier) || Tok.is(tok::annot_cxxscope))) { CXXScopeSpec SS; - if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, true)) { + ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, true); // ignore fail + + if (SS.isSet()) { if (Tok.isNot(tok::star)) { // The scope spec really belongs to the direct-declarator. D.getCXXScopeSpec() = SS; @@ -2507,9 +2527,13 @@ void Parser::ParseDirectDeclarator(Declarator &D) { if (getLang().CPlusPlus && D.mayHaveIdentifier()) { // ParseDeclaratorInternal might already have parsed the scope. - bool afterCXXScope = D.getCXXScopeSpec().isSet() || + bool afterCXXScope = D.getCXXScopeSpec().isSet(); + if (!afterCXXScope) { ParseOptionalCXXScopeSpecifier(D.getCXXScopeSpec(), /*ObjectType=*/0, true); + afterCXXScope = D.getCXXScopeSpec().isSet(); + } + if (afterCXXScope) { if (Actions.ShouldEnterDeclaratorScope(CurScope, D.getCXXScopeSpec())) // Change the declaration context for name lookup, until this function @@ -2799,7 +2823,7 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D, // K&R-style function: void foo(a,b,c) if (!getLang().CPlusPlus && Tok.is(tok::identifier) && !TryAltiVecVectorToken()) { - if (!TryAnnotateTypeOrScopeToken()) { + if (TryAnnotateTypeOrScopeToken() || !Tok.is(tok::annot_typename)) { // K&R identifier lists can't have typedefs as identifiers, per // C99 6.7.5.3p11. if (RequiresArg) { diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index 225ce256b11..dbbfb9518b3 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -645,7 +645,8 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, // "FOO : BAR" is not a potential typo for "FOO::BAR". ColonProtectionRAIIObject X(*this); - if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, true)) + ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, true); + if (SS.isSet()) if (Tok.isNot(tok::identifier) && Tok.isNot(tok::annot_template_id)) Diag(Tok, diag::err_expected_ident); } @@ -1163,7 +1164,7 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS, // Access declarations. if (!TemplateInfo.Kind && (Tok.is(tok::identifier) || Tok.is(tok::coloncolon)) && - TryAnnotateCXXScopeToken() && + !TryAnnotateCXXScopeToken() && Tok.is(tok::annot_cxxscope)) { bool isAccessDecl = false; if (NextToken().is(tok::identifier)) diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index f69740bf8bd..af91021d33c 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -626,6 +626,8 @@ Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression, Next.is(tok::l_paren)) { // If TryAnnotateTypeOrScopeToken annotates the token, tail recurse. if (TryAnnotateTypeOrScopeToken()) + return ExprError(); + if (!Tok.is(tok::identifier)) return ParseCastExpression(isUnaryExpression, isAddressOfOperand); } } @@ -790,7 +792,7 @@ Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression, if (SavedKind == tok::kw_typename) { // postfix-expression: typename-specifier '(' expression-list[opt] ')' - if (!TryAnnotateTypeOrScopeToken()) + if (TryAnnotateTypeOrScopeToken()) return ExprError(); } @@ -852,6 +854,8 @@ Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression, // ::foo::bar -> global qualified name etc. If TryAnnotateTypeOrScopeToken // annotates the token, tail recurse. if (TryAnnotateTypeOrScopeToken()) + return ExprError(); + if (!Tok.is(tok::coloncolon)) return ParseCastExpression(isUnaryExpression, isAddressOfOperand); // ::new -> [C++] new-expression diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp index 7998b26f9bc..f1e989f4a7b 100644 --- a/clang/lib/Parse/ParseExprCXX.cpp +++ b/clang/lib/Parse/ParseExprCXX.cpp @@ -55,7 +55,7 @@ using namespace clang; /// member access expression, e.g., the \p T:: in \p p->T::m. /// -/// \returns true if a scope specifier was parsed. +/// \returns true if there was an error parsing a scope specifier bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS, Action::TypeTy *ObjectType, bool EnteringContext, @@ -67,7 +67,7 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS, SS.setScopeRep(Tok.getAnnotationValue()); SS.setRange(Tok.getAnnotationRange()); ConsumeToken(); - return true; + return false; } bool HasScopeSpecifier = false; @@ -168,10 +168,10 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS, = Actions.ActOnDependentTemplateName(TemplateKWLoc, SS, TemplateName, ObjectType, EnteringContext); if (!Template) - break; + return true; if (AnnotateTemplateIdToken(Template, TNK_Dependent_template_name, &SS, TemplateName, TemplateKWLoc, false)) - break; + return true; continue; } @@ -188,7 +188,7 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS, = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue()); if (CheckForDestructor && GetLookAheadToken(2).is(tok::tilde)) { *MayBePseudoDestructor = true; - return HasScopeSpecifier; + return false; } if (TemplateId->Kind == TNK_Type_template || @@ -258,7 +258,7 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS, !Actions.isNonTypeNestedNameSpecifier(CurScope, SS, Tok.getLocation(), II, ObjectType)) { *MayBePseudoDestructor = true; - return HasScopeSpecifier; + return false; } // We have an identifier followed by a '::'. Lookup this name @@ -303,7 +303,7 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS, ConsumeToken(); if (AnnotateTemplateIdToken(Template, TNK, &SS, TemplateName, SourceLocation(), false)) - break; + return true; continue; } } @@ -319,7 +319,7 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS, if (CheckForDestructor && Tok.is(tok::tilde)) *MayBePseudoDestructor = true; - return HasScopeSpecifier; + return false; } /// ParseCXXIdExpression - Handle id-expression. diff --git a/clang/lib/Parse/ParseTentative.cpp b/clang/lib/Parse/ParseTentative.cpp index 6251a2f3675..516a9a620b6 100644 --- a/clang/lib/Parse/ParseTentative.cpp +++ b/clang/lib/Parse/ParseTentative.cpp @@ -491,7 +491,8 @@ Parser::TPResult Parser::TryParseDeclarator(bool mayBeAbstract, while (1) { if (Tok.is(tok::coloncolon) || Tok.is(tok::identifier)) - TryAnnotateCXXScopeToken(true); + if (TryAnnotateCXXScopeToken(true)) + return TPResult::Error(); if (Tok.is(tok::star) || Tok.is(tok::amp) || Tok.is(tok::caret) || (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::star))) { @@ -681,9 +682,10 @@ Parser::TPResult Parser::isCXXDeclarationSpecifier() { // Annotate typenames and C++ scope specifiers. If we get one, just // recurse to handle whatever we get. if (TryAnnotateTypeOrScopeToken()) - return isCXXDeclarationSpecifier(); - // Otherwise, not a typename. - return TPResult::False(); + return TPResult::Error(); + if (Tok.is(tok::identifier)) + return TPResult::False(); + return isCXXDeclarationSpecifier(); case tok::coloncolon: { // ::foo::bar const Token &Next = NextToken(); @@ -694,9 +696,8 @@ Parser::TPResult Parser::isCXXDeclarationSpecifier() { // Annotate typenames and C++ scope specifiers. If we get one, just // recurse to handle whatever we get. if (TryAnnotateTypeOrScopeToken()) - return isCXXDeclarationSpecifier(); - // Otherwise, not a typename. - return TPResult::False(); + return TPResult::Error(); + return isCXXDeclarationSpecifier(); } // decl-specifier: @@ -762,7 +763,9 @@ Parser::TPResult Parser::isCXXDeclarationSpecifier() { case tok::annot_cxxscope: // foo::bar or ::foo::bar, but already parsed // We've already annotated a scope; try to annotate a type. - if (!(TryAnnotateTypeOrScopeToken() && Tok.is(tok::annot_typename))) + if (TryAnnotateTypeOrScopeToken()) + return TPResult::Error(); + if (!Tok.is(tok::annot_typename)) return TPResult::False(); // If that succeeded, fallthrough into the generic simple-type-id case. diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index 24162373e0e..a6ae9cfd0d3 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -891,8 +891,7 @@ Parser::OwningExprResult Parser::ParseSimpleAsm(SourceLocation *EndLoc) { /// specifier, and another one to get the actual type inside /// ParseDeclarationSpecifiers). /// -/// This returns true if the token was annotated or an unrecoverable error -/// occurs. +/// This returns true if an error occurred. /// /// Note that this routine emits an error if you call it with ::new or ::delete /// as the current tokens, so only call it in contexts where these are invalid. @@ -910,11 +909,11 @@ bool Parser::TryAnnotateTypeOrScopeToken(bool EnteringContext) { // simple-template-id SourceLocation TypenameLoc = ConsumeToken(); CXXScopeSpec SS; - bool HadNestedNameSpecifier - = ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, false); - if (!HadNestedNameSpecifier) { + if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, false)) + return true; + if (!SS.isSet()) { Diag(Tok.getLocation(), diag::err_expected_qualified_after_typename); - return false; + return true; } TypeResult Ty; @@ -928,7 +927,7 @@ bool Parser::TryAnnotateTypeOrScopeToken(bool EnteringContext) { if (TemplateId->Kind == TNK_Function_template) { Diag(Tok, diag::err_typename_refers_to_non_type_template) << Tok.getAnnotationRange(); - return false; + return true; } AnnotateTemplateIdTokenAsType(0); @@ -942,7 +941,7 @@ bool Parser::TryAnnotateTypeOrScopeToken(bool EnteringContext) { } else { Diag(Tok, diag::err_expected_type_name_after_typename) << SS.getRange(); - return false; + return true; } SourceLocation EndLoc = Tok.getLastLoc(); @@ -951,7 +950,7 @@ bool Parser::TryAnnotateTypeOrScopeToken(bool EnteringContext) { Tok.setAnnotationEndLoc(EndLoc); Tok.setLocation(TypenameLoc); PP.AnnotateCachedTokens(Tok); - return true; + return false; } // Remembers whether the token was originally a scope annotation. @@ -959,7 +958,8 @@ bool Parser::TryAnnotateTypeOrScopeToken(bool EnteringContext) { CXXScopeSpec SS; if (getLang().CPlusPlus) - ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, EnteringContext); + if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, EnteringContext)) + return true; if (Tok.is(tok::identifier)) { // Determine whether the identifier is a type name. @@ -976,7 +976,7 @@ bool Parser::TryAnnotateTypeOrScopeToken(bool EnteringContext) { // In case the tokens were cached, have Preprocessor replace // them with the annotation token. PP.AnnotateCachedTokens(Tok); - return true; + return false; } if (!getLang().CPlusPlus) { @@ -1001,7 +1001,7 @@ bool Parser::TryAnnotateTypeOrScopeToken(bool EnteringContext) { // If an unrecoverable error occurred, we need to return true here, // because the token stream is in a damaged state. We may not return // a valid identifier. - return Tok.isNot(tok::identifier); + return true; } } } @@ -1021,12 +1021,12 @@ bool Parser::TryAnnotateTypeOrScopeToken(bool EnteringContext) { // to produce a type annotation token. Update the template-id // annotation token to a type annotation token now. AnnotateTemplateIdTokenAsType(&SS); - return true; + return false; } } if (SS.isEmpty()) - return Tok.isNot(tok::identifier) && Tok.isNot(tok::coloncolon); + return false; // A C++ scope specifier that isn't followed by a typename. // Push the current token back into the token stream (or revert it if it is @@ -1044,7 +1044,7 @@ bool Parser::TryAnnotateTypeOrScopeToken(bool EnteringContext) { // just reverted back to the state we were in before being called. if (!wasScopeAnnotation) PP.AnnotateCachedTokens(Tok); - return true; + return false; } /// TryAnnotateScopeToken - Like TryAnnotateTypeOrScopeToken but only @@ -1061,10 +1061,10 @@ bool Parser::TryAnnotateCXXScopeToken(bool EnteringContext) { "Cannot be a type or scope token!"); CXXScopeSpec SS; - if (!ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, EnteringContext)) - // If the token left behind is not an identifier, we either had an error or - // successfully turned it into an annotation token. - return Tok.isNot(tok::identifier); + if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, EnteringContext)) + return true; + if (!SS.isSet()) + return false; // Push the current token back into the token stream (or revert it if it is // cached) and use an annotation scope token for current token. @@ -1079,7 +1079,7 @@ bool Parser::TryAnnotateCXXScopeToken(bool EnteringContext) { // In case the tokens were cached, have Preprocessor replace them with the // annotation token. PP.AnnotateCachedTokens(Tok); - return true; + return false; } // Anchor the Parser::FieldCallback vtable to this translation unit. diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-nodeduct.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-nodeduct.cpp index a8b83d4854e..eb5465cc19b 100644 --- a/clang/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-nodeduct.cpp +++ b/clang/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-nodeduct.cpp @@ -33,5 +33,4 @@ template <typename T> void g(T); template <typename T> void g(T, T); int typeof2[is_same<__typeof__(g<float>), void (int)>::value? 1 : -1]; // \ - // expected-error{{cannot determine the type of an overloaded function}} \ - // FIXME: expected-error{{use of undeclared identifier}} + // expected-error{{cannot determine the type of an overloaded function}} diff --git a/clang/test/Parser/cxx-template-argument.cpp b/clang/test/Parser/cxx-template-argument.cpp index 80389a07b0a..532b4c9894b 100644 --- a/clang/test/Parser/cxx-template-argument.cpp +++ b/clang/test/Parser/cxx-template-argument.cpp @@ -5,5 +5,5 @@ template<typename T> struct A {}; // Check for template argument lists followed by junk // FIXME: The diagnostics here aren't great... A<int+> int x; // expected-error {{expected '>'}} expected-error {{expected unqualified-id}} -A<int x; // expected-error {{expected '>'}} expected-error {{C++ requires a type specifier for all declarations}} +A<int x; // expected-error {{expected '>'}} diff --git a/clang/test/SemaCXX/member-pointer.cpp b/clang/test/SemaCXX/member-pointer.cpp index 3d9d5b5ebbb..d6050cd7337 100644 --- a/clang/test/SemaCXX/member-pointer.cpp +++ b/clang/test/SemaCXX/member-pointer.cpp @@ -12,8 +12,7 @@ int A::*pdi1; int (::A::*pdi2); int (A::*pfi)(int); -int B::*pbi; // expected-error {{expected a class or namespace}} \ - // expected-error{{does not point into a class}} +int B::*pbi; // expected-error {{expected a class or namespace}} int C::*pci; // expected-error {{'pci' does not point into a class}} void A::*pdv; // expected-error {{'pdv' declared as a member pointer to void}} int& A::*pdr; // expected-error {{'pdr' declared as a member pointer to a reference}} diff --git a/clang/test/SemaCXX/nested-name-spec.cpp b/clang/test/SemaCXX/nested-name-spec.cpp index 8a217b31208..247e91b2eb3 100644 --- a/clang/test/SemaCXX/nested-name-spec.cpp +++ b/clang/test/SemaCXX/nested-name-spec.cpp @@ -13,8 +13,9 @@ namespace A { } A:: ; // expected-error {{expected unqualified-id}} -::A::ax::undef ex3; // expected-error {{no member named}} -A::undef1::undef2 ex4; // expected-error {{no member named 'undef1'}} +// FIXME: redundant errors +::A::ax::undef ex3; // expected-error {{no member named}} expected-error {{unknown type name}} +A::undef1::undef2 ex4; // expected-error {{no member named 'undef1'}} expected-error {{unknown type name}} int A::C::Ag1() { return 0; } diff --git a/clang/test/SemaTemplate/dependent-base-classes.cpp b/clang/test/SemaTemplate/dependent-base-classes.cpp index 80d20b09b82..cd90f634106 100644 --- a/clang/test/SemaTemplate/dependent-base-classes.cpp +++ b/clang/test/SemaTemplate/dependent-base-classes.cpp @@ -57,7 +57,6 @@ namespace PR6031 { int foo() { class NoDepBase::Nested nested; // expected-error{{'Nested' does not name a tag member in the specified scope}} typedef typename NoDepBase::template MemberTemplate<T>::type type; // expected-error{{'MemberTemplate' following the 'template' keyword does not refer to a template}} \ - // FIXME: expected-error{{expected an identifier or template-id after '::'}} \ // FIXME: expected-error{{unqualified-id}} return NoDepBase::a; // expected-error{{no member named 'a' in 'struct PR6031::NoDepBase'}} } diff --git a/clang/test/SemaTemplate/explicit-specialization-member.cpp b/clang/test/SemaTemplate/explicit-specialization-member.cpp index 417cdc1f198..cb0a39a9d0c 100644 --- a/clang/test/SemaTemplate/explicit-specialization-member.cpp +++ b/clang/test/SemaTemplate/explicit-specialization-member.cpp @@ -16,7 +16,7 @@ namespace PR6161 { // expected-error{{expected class name}} \ // expected-note{{attempt to specialize declaration here}} { - static locale::id id; // expected-error{{use of undeclared identifier}} + static locale::id id; // expected-error{{use of undeclared identifier}} FIXME: expected-error {{unknown type name}} }; numpunct<char>::~numpunct(); // expected-error{{template specialization requires 'template<>'}} \ // expected-error{{specialization of member 'PR6161::numpunct<char>::~numpunct' does not specialize an instantiated member}} diff --git a/clang/test/SemaTemplate/nested-name-spec-template.cpp b/clang/test/SemaTemplate/nested-name-spec-template.cpp index 704b8cfce12..1691db74a11 100644 --- a/clang/test/SemaTemplate/nested-name-spec-template.cpp +++ b/clang/test/SemaTemplate/nested-name-spec-template.cpp @@ -49,6 +49,5 @@ struct ::N::A<int>::X { template<typename T> struct TestA { typedef typename N::template B<T>::type type; // expected-error{{'B' following the 'template' keyword does not refer to a template}} \ - // expected-error{{identifier or template-id}} \ // expected-error{{expected member name}} }; diff --git a/clang/test/SemaTemplate/temp_arg.cpp b/clang/test/SemaTemplate/temp_arg.cpp index 3c9fcb50661..80bbda785d0 100644 --- a/clang/test/SemaTemplate/temp_arg.cpp +++ b/clang/test/SemaTemplate/temp_arg.cpp @@ -10,3 +10,10 @@ A<int, 0, X> * a1; A<float, 1, X, double> *a2; // expected-error{{too many template arguments for class template 'A'}} A<float, 1> *a3; // expected-error{{too few template arguments for class template 'A'}} + +namespace test0 { + template <class t> class foo {}; + template <class t> class bar { + bar(::test0::foo<tee> *ptr) {} // FIXME(redundant): expected-error 2 {{use of undeclared identifier 'tee'}} + }; +} |