diff options
-rw-r--r-- | clang/include/clang/Basic/DiagnosticSemaKinds.td | 10 | ||||
-rw-r--r-- | clang/include/clang/Parse/Action.h | 15 | ||||
-rw-r--r-- | clang/lib/Parse/ParseExprCXX.cpp | 14 | ||||
-rw-r--r-- | clang/lib/Parse/ParseTemplate.cpp | 6 | ||||
-rw-r--r-- | clang/lib/Parse/Parser.cpp | 6 | ||||
-rw-r--r-- | clang/lib/Sema/Sema.h | 15 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplate.cpp | 46 | ||||
-rw-r--r-- | clang/lib/Sema/TreeTransform.h | 4 | ||||
-rw-r--r-- | clang/test/SemaObjCXX/message.mm | 6 | ||||
-rw-r--r-- | clang/test/SemaTemplate/nested-name-spec-template.cpp | 2 | ||||
-rw-r--r-- | clang/test/SemaTemplate/template-id-expr.cpp | 11 | ||||
-rw-r--r-- | clang/test/SemaTemplate/typename-specifier-4.cpp | 3 | ||||
-rw-r--r-- | clang/test/SemaTemplate/typename-specifier.cpp | 14 |
14 files changed, 84 insertions, 70 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 0a9cb8a22ed..ecd95d30d23 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -1610,9 +1610,8 @@ def note_typename_refers_here : Note< "referenced member %0 is declared here">; def err_typename_missing : Error< "missing 'typename' prior to dependent type name '%0%1'">; -def ext_typename_nondependent : ExtWarn< - "'typename' refers to a non-dependent type name; accepted as a C++0x " - "extension">; +def ext_typename_outside_of_template : ExtWarn< + "'typename' occurs outside of a template">; def err_template_kw_refers_to_non_template : Error< "%0 following the 'template' keyword does not refer to a template">; @@ -1624,9 +1623,8 @@ def note_referenced_class_template : Error< "class template declared here">; def err_template_kw_missing : Error< "missing 'template' keyword prior to dependent template name '%0%1'">; -def ext_template_nondependent : ExtWarn< - "'template' refers to a non-dependent template name; accepted as a C++0x " - "extension">; +def ext_template_outside_of_template : ExtWarn< + "'template' keyword outside of a template">; // C++0x Variadic Templates def err_template_param_pack_default_arg : Error< diff --git a/clang/include/clang/Parse/Action.h b/clang/include/clang/Parse/Action.h index 0b07ded05d3..baca3fb5022 100644 --- a/clang/include/clang/Parse/Action.h +++ b/clang/include/clang/Parse/Action.h @@ -1989,6 +1989,8 @@ public: /// SS will be "MetaFun::", \p TemplateKWLoc contains the location /// of the "template" keyword, and "apply" is the \p Name. /// + /// \param S The scope in which the dependent template name was parsed. + /// /// \param TemplateKWLoc the location of the "template" keyword (if any). /// /// \param SS the nested-name-specifier that precedes the "template" keyword @@ -2004,7 +2006,8 @@ public: /// /// \param EnteringContext whether we are entering the context of this /// template. - virtual TemplateTy ActOnDependentTemplateName(SourceLocation TemplateKWLoc, + virtual TemplateTy ActOnDependentTemplateName(Scope *S, + SourceLocation TemplateKWLoc, CXXScopeSpec &SS, UnqualifiedId &Name, TypeTy *ObjectType, @@ -2246,8 +2249,9 @@ public: /// \param II the identifier we're retrieving (e.g., 'type' in the example). /// \param IdLoc the location of the identifier. virtual TypeResult - ActOnTypenameType(SourceLocation TypenameLoc, const CXXScopeSpec &SS, - const IdentifierInfo &II, SourceLocation IdLoc) { + ActOnTypenameType(Scope *S, SourceLocation TypenameLoc, + const CXXScopeSpec &SS, const IdentifierInfo &II, + SourceLocation IdLoc) { return TypeResult(); } @@ -2260,8 +2264,9 @@ public: /// \param TemplateLoc the location of the 'template' keyword, if any. /// \param Ty the type that the typename specifier refers to. virtual TypeResult - ActOnTypenameType(SourceLocation TypenameLoc, const CXXScopeSpec &SS, - SourceLocation TemplateLoc, TypeTy *Ty) { + ActOnTypenameType(Scope *S, SourceLocation TypenameLoc, + const CXXScopeSpec &SS, SourceLocation TemplateLoc, + TypeTy *Ty) { return TypeResult(); } diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp index 586dac61599..843baa2fe72 100644 --- a/clang/lib/Parse/ParseExprCXX.cpp +++ b/clang/lib/Parse/ParseExprCXX.cpp @@ -165,7 +165,8 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS, // Commit to parsing the template-id. TPA.Commit(); TemplateTy Template - = Actions.ActOnDependentTemplateName(TemplateKWLoc, SS, TemplateName, + = Actions.ActOnDependentTemplateName(CurScope, TemplateKWLoc, SS, + TemplateName, ObjectType, EnteringContext); if (!Template) return true; @@ -319,7 +320,8 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS, << II.getName() << FixItHint::CreateInsertion(Tok.getLocation(), "template "); - Template = Actions.ActOnDependentTemplateName(Tok.getLocation(), SS, + Template = Actions.ActOnDependentTemplateName(CurScope, + Tok.getLocation(), SS, TemplateName, ObjectType, EnteringContext); if (!Template.get()) @@ -1011,7 +1013,7 @@ bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS, case UnqualifiedId::IK_OperatorFunctionId: case UnqualifiedId::IK_LiteralOperatorId: if (AssumeTemplateId) { - Template = Actions.ActOnDependentTemplateName(TemplateKWLoc, SS, + Template = Actions.ActOnDependentTemplateName(CurScope, TemplateKWLoc, SS, Id, ObjectType, EnteringContext); TNK = TNK_Dependent_template_name; @@ -1042,8 +1044,8 @@ bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS, Diag(Id.StartLocation, diag::err_missing_dependent_template_keyword) << Name << FixItHint::CreateInsertion(Id.StartLocation, "template "); - Template = Actions.ActOnDependentTemplateName(TemplateKWLoc, SS, - Id, ObjectType, + Template = Actions.ActOnDependentTemplateName(CurScope, TemplateKWLoc, + SS, Id, ObjectType, EnteringContext); TNK = TNK_Dependent_template_name; if (!Template.get()) @@ -1067,7 +1069,7 @@ bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS, bool MemberOfUnknownSpecialization; TemplateName.setIdentifier(Name, NameLoc); if (ObjectType) { - Template = Actions.ActOnDependentTemplateName(TemplateKWLoc, SS, + Template = Actions.ActOnDependentTemplateName(CurScope, TemplateKWLoc, SS, TemplateName, ObjectType, EnteringContext); TNK = TNK_Dependent_template_name; diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp index 5d248f1d774..ec0e31e703c 100644 --- a/clang/lib/Parse/ParseTemplate.cpp +++ b/clang/lib/Parse/ParseTemplate.cpp @@ -916,9 +916,9 @@ ParsedTemplateArgument Parser::ParseTemplateTemplateArgument() { // template argument. if (isEndOfTemplateArgument(Tok)) { TemplateTy Template - = Actions.ActOnDependentTemplateName(TemplateLoc, SS, Name, - /*ObjectType=*/0, - /*EnteringContext=*/false); + = Actions.ActOnDependentTemplateName(CurScope, TemplateLoc, SS, Name, + /*ObjectType=*/0, + /*EnteringContext=*/false); if (Template.get()) return ParsedTemplateArgument(SS, Template, Name.StartLocation); } diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index 296897080d0..225a793af53 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -919,7 +919,8 @@ bool Parser::TryAnnotateTypeOrScopeToken(bool EnteringContext) { TypeResult Ty; if (Tok.is(tok::identifier)) { // FIXME: check whether the next token is '<', first! - Ty = Actions.ActOnTypenameType(TypenameLoc, SS, *Tok.getIdentifierInfo(), + Ty = Actions.ActOnTypenameType(CurScope, TypenameLoc, SS, + *Tok.getIdentifierInfo(), Tok.getLocation()); } else if (Tok.is(tok::annot_template_id)) { TemplateIdAnnotation *TemplateId @@ -934,7 +935,8 @@ bool Parser::TryAnnotateTypeOrScopeToken(bool EnteringContext) { assert(Tok.is(tok::annot_typename) && "AnnotateTemplateIdTokenAsType isn't working properly"); if (Tok.getAnnotationValue()) - Ty = Actions.ActOnTypenameType(TypenameLoc, SS, SourceLocation(), + Ty = Actions.ActOnTypenameType(CurScope, TypenameLoc, SS, + SourceLocation(), Tok.getAnnotationValue()); else Ty = true; diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 396f144ddf2..c81c12bb86c 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -2937,7 +2937,8 @@ public: SourceLocation NameLoc, const TemplateArgumentListInfo &TemplateArgs); - virtual TemplateTy ActOnDependentTemplateName(SourceLocation TemplateKWLoc, + virtual TemplateTy ActOnDependentTemplateName(Scope *S, + SourceLocation TemplateKWLoc, CXXScopeSpec &SS, UnqualifiedId &Name, TypeTy *ObjectType, @@ -3121,25 +3122,29 @@ public: /// \brief Called when the parser has parsed a C++ typename /// specifier, e.g., "typename T::type". /// + /// \param S The scope in which this typename type occurs. /// \param TypenameLoc the location of the 'typename' keyword /// \param SS the nested-name-specifier following the typename (e.g., 'T::'). /// \param II the identifier we're retrieving (e.g., 'type' in the example). /// \param IdLoc the location of the identifier. virtual TypeResult - ActOnTypenameType(SourceLocation TypenameLoc, const CXXScopeSpec &SS, - const IdentifierInfo &II, SourceLocation IdLoc); + ActOnTypenameType(Scope *S, SourceLocation TypenameLoc, + const CXXScopeSpec &SS, const IdentifierInfo &II, + SourceLocation IdLoc); /// \brief Called when the parser has parsed a C++ typename /// specifier that ends in a template-id, e.g., /// "typename MetaFun::template apply<T1, T2>". /// + /// \param S The scope in which this typename type occurs. /// \param TypenameLoc the location of the 'typename' keyword /// \param SS the nested-name-specifier following the typename (e.g., 'T::'). /// \param TemplateLoc the location of the 'template' keyword, if any. /// \param Ty the type that the typename specifier refers to. virtual TypeResult - ActOnTypenameType(SourceLocation TypenameLoc, const CXXScopeSpec &SS, - SourceLocation TemplateLoc, TypeTy *Ty); + ActOnTypenameType(Scope *S, SourceLocation TypenameLoc, + const CXXScopeSpec &SS, SourceLocation TemplateLoc, + TypeTy *Ty); QualType CheckTypenameType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index fbd4ff446ac..9e31a543722 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -307,7 +307,7 @@ bool Sema::DiagnoseUnknownTypeName(const IdentifierInfo &II, << (NestedNameSpecifier *)SS->getScopeRep() << II.getName() << SourceRange(SS->getRange().getBegin(), IILoc) << FixItHint::CreateInsertion(SS->getRange().getBegin(), "typename "); - SuggestedType = ActOnTypenameType(SourceLocation(), *SS, II, IILoc).get(); + SuggestedType = ActOnTypenameType(S, SourceLocation(), *SS, II, IILoc).get(); } else { assert(SS && SS->isInvalid() && "Invalid scope specifier has already been diagnosed"); diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 5e40bc58bba..b30d4e3e9c3 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -1687,11 +1687,16 @@ Sema::BuildQualifiedTemplateIdExpr(CXXScopeSpec &SS, /// SS will be "MetaFun::", \p TemplateKWLoc contains the location /// of the "template" keyword, and "apply" is the \p Name. Sema::TemplateTy -Sema::ActOnDependentTemplateName(SourceLocation TemplateKWLoc, +Sema::ActOnDependentTemplateName(Scope *S, SourceLocation TemplateKWLoc, CXXScopeSpec &SS, UnqualifiedId &Name, TypeTy *ObjectType, bool EnteringContext) { + if (TemplateKWLoc.isValid() && S && !S->getTemplateParamParent() && + !getLangOptions().CPlusPlus0x) + Diag(TemplateKWLoc, diag::ext_template_outside_of_template) + << FixItHint::CreateRemoval(TemplateKWLoc); + DeclContext *LookupCtx = 0; if (SS.isSet()) LookupCtx = computeDeclContext(SS, EnteringContext); @@ -1732,15 +1737,6 @@ Sema::ActOnDependentTemplateName(SourceLocation TemplateKWLoc, return TemplateTy(); } else { // We found something; return it. - if (ActiveTemplateInstantiations.empty() && - !getLangOptions().CPlusPlus0x && - !SS.isEmpty() && !isDependentScopeSpecifier(SS)) - Diag(TemplateKWLoc.isValid()? TemplateKWLoc - : Name.getSourceRange().getBegin(), - diag::ext_template_nondependent) - << SourceRange(Name.getSourceRange().getBegin()) - << FixItHint::CreateRemoval(TemplateKWLoc); - return Template; } } @@ -5266,13 +5262,19 @@ Sema::ActOnDependentTag(Scope *S, unsigned TagSpec, TagUseKind TUK, } Sema::TypeResult -Sema::ActOnTypenameType(SourceLocation TypenameLoc, const CXXScopeSpec &SS, - const IdentifierInfo &II, SourceLocation IdLoc) { +Sema::ActOnTypenameType(Scope *S, SourceLocation TypenameLoc, + const CXXScopeSpec &SS, const IdentifierInfo &II, + SourceLocation IdLoc) { NestedNameSpecifier *NNS = static_cast<NestedNameSpecifier *>(SS.getScopeRep()); if (!NNS) return true; + if (TypenameLoc.isValid() && S && !S->getTemplateParamParent() && + !getLangOptions().CPlusPlus0x) + Diag(TypenameLoc, diag::ext_typename_outside_of_template) + << FixItHint::CreateRemoval(TypenameLoc); + QualType T = CheckTypenameType(ETK_Typename, NNS, II, TypenameLoc, SS.getRange(), IdLoc); if (T.isNull()) @@ -5295,8 +5297,14 @@ Sema::ActOnTypenameType(SourceLocation TypenameLoc, const CXXScopeSpec &SS, } Sema::TypeResult -Sema::ActOnTypenameType(SourceLocation TypenameLoc, const CXXScopeSpec &SS, - SourceLocation TemplateLoc, TypeTy *Ty) { +Sema::ActOnTypenameType(Scope *S, SourceLocation TypenameLoc, + const CXXScopeSpec &SS, SourceLocation TemplateLoc, + TypeTy *Ty) { + if (TypenameLoc.isValid() && S && !S->getTemplateParamParent() && + !getLangOptions().CPlusPlus0x) + Diag(TypenameLoc, diag::ext_typename_outside_of_template) + << FixItHint::CreateRemoval(TypenameLoc); + TypeSourceInfo *InnerTSI = 0; QualType T = GetTypeFromParser(Ty, &InnerTSI); NestedNameSpecifier *NNS @@ -5397,15 +5405,7 @@ Sema::CheckTypenameType(ElaboratedTypeKeyword Keyword, return Context.getDependentNameType(Keyword, NNS, &II); case LookupResult::Found: - if (TypeDecl *Type = dyn_cast<TypeDecl>(Result.getFoundDecl())) { - if (ActiveTemplateInstantiations.empty() && - !getLangOptions().CPlusPlus0x && !SS.isEmpty() && - !isDependentScopeSpecifier(SS)) - Diag(KeywordLoc.isValid()? KeywordLoc : IILoc, - diag::ext_typename_nondependent) - << SourceRange(IILoc) - << FixItHint::CreateRemoval(KeywordLoc); - + if (TypeDecl *Type = dyn_cast<TypeDecl>(Result.getFoundDecl())) { // We found a type. Build an ElaboratedType, since the // typename-specifier was just sugar. return Context.getElaboratedType(ETK_Typename, NNS, diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index df01be01f11..86e3a25ea25 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -6495,7 +6495,7 @@ TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier, SS.setScopeRep(Qualifier); UnqualifiedId Name; Name.setIdentifier(&II, /*FIXME:*/getDerived().getBaseLocation()); - return getSema().ActOnDependentTemplateName( + return getSema().ActOnDependentTemplateName(/*Scope=*/0, /*FIXME:*/getDerived().getBaseLocation(), SS, Name, @@ -6516,7 +6516,7 @@ TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier, SourceLocation SymbolLocations[3]; // FIXME: Bogus location information. Name.setOperatorFunctionId(/*FIXME:*/getDerived().getBaseLocation(), Operator, SymbolLocations); - return getSema().ActOnDependentTemplateName( + return getSema().ActOnDependentTemplateName(/*Scope=*/0, /*FIXME:*/getDerived().getBaseLocation(), SS, Name, diff --git a/clang/test/SemaObjCXX/message.mm b/clang/test/SemaObjCXX/message.mm index 10b886b203f..76bde6f57ca 100644 --- a/clang/test/SemaObjCXX/message.mm +++ b/clang/test/SemaObjCXX/message.mm @@ -62,15 +62,15 @@ struct identity { // or typename-specifiers. if (false) { if (true) - return [typename identity<I3>::type method]; // expected-warning{{'typename' refers to a non-dependent type name; accepted as a C++0x extension}} + return [typename identity<I3>::type method]; // expected-warning{{occurs outside of a template}} return [::I3 method]; } int* ip1 = {[super method]}; int* ip2 = {[::I3 method]}; - int* ip3 = {[typename identity<I3>::type method]}; // expected-warning{{'typename' refers to a non-dependent type name; accepted as a C++0x extension}} - int* ip4 = {[typename identity<I2_holder>::type().get() method]}; // expected-warning{{'typename' refers to a non-dependent type name; accepted as a C++0x extension}} + int* ip3 = {[typename identity<I3>::type method]}; // expected-warning{{occurs outside of a template}} + int* ip4 = {[typename identity<I2_holder>::type().get() method]}; // expected-warning{{occurs outside of a template}} int array[5] = {[3] = 2}; return [super method]; } diff --git a/clang/test/SemaTemplate/nested-name-spec-template.cpp b/clang/test/SemaTemplate/nested-name-spec-template.cpp index e542507a2f7..0251894f35a 100644 --- a/clang/test/SemaTemplate/nested-name-spec-template.cpp +++ b/clang/test/SemaTemplate/nested-name-spec-template.cpp @@ -21,7 +21,7 @@ namespace N { } M::Promote<int>::type *ret_intptr3(int* ip) { return ip; } - M::template Promote<int>::type *ret_intptr4(int* ip) { return ip; } // expected-warning{{'template' refers to a non-dependent template name; accepted as a C++0x extension}} + M::template Promote<int>::type *ret_intptr4(int* ip) { return ip; } // expected-warning{{'template' keyword outside of a template}} } N::M::Promote<int>::type *ret_intptr5(int* ip) { return ip; } diff --git a/clang/test/SemaTemplate/template-id-expr.cpp b/clang/test/SemaTemplate/template-id-expr.cpp index e8974211b60..de8d7f6c91a 100644 --- a/clang/test/SemaTemplate/template-id-expr.cpp +++ b/clang/test/SemaTemplate/template-id-expr.cpp @@ -62,12 +62,12 @@ struct Y0 { template<typename U> void f() { - Y0::template f1<U>(0); // expected-warning{{'template' refers to a non-dependent template name}} - Y0::template f1(0); // expected-warning{{'template' refers to a non-dependent template name}} + Y0::template f1<U>(0); + Y0::template f1(0); this->template f1(0); - Y0::template f2<U>(0); // expected-warning{{'template' refers to a non-dependent template name}} - Y0::template f2(0);// expected-warning{{'template' refers to a non-dependent template name}} + Y0::template f2<U>(0); + Y0::template f2(0); Y0::template f3(0); // expected-error {{'f3' following the 'template' keyword does not refer to a template}} Y0::template f3(); // expected-error {{'f3' following the 'template' keyword does not refer to a template}} @@ -75,8 +75,7 @@ struct Y0 { int x; x = Y0::f4(0); x = Y0::f4<int>(0); // expected-error {{assigning to 'int' from incompatible type 'void'}} - x = Y0::template f4(0); // expected-error {{assigning to 'int' from incompatible type 'void'}} \ - // expected-warning{{'template' refers to a non-dependent template name}} + x = Y0::template f4(0); // expected-error {{assigning to 'int' from incompatible type 'void'}} x = this->f4(0); x = this->f4<int>(0); // expected-error {{assigning to 'int' from incompatible type 'void'}} diff --git a/clang/test/SemaTemplate/typename-specifier-4.cpp b/clang/test/SemaTemplate/typename-specifier-4.cpp index da11119e5b2..5a313bf2256 100644 --- a/clang/test/SemaTemplate/typename-specifier-4.cpp +++ b/clang/test/SemaTemplate/typename-specifier-4.cpp @@ -27,7 +27,8 @@ struct make_pair { int a0[is_same<metafun_apply2<make_pair, int, float>::type, pair<int, float> >::value? 1 : -1]; int a1[is_same< - typename make_pair::template apply<int, float>, // expected-warning{{'template' refers to a non-dependent template name}} + typename make_pair::template apply<int, float>, // expected-warning{{'template' keyword outside of a template}} \ + // expected-warning{{'typename' occurs outside of a template}} make_pair::apply<int, float> >::value? 1 : -1]; diff --git a/clang/test/SemaTemplate/typename-specifier.cpp b/clang/test/SemaTemplate/typename-specifier.cpp index e066475be99..4c788f6a8a3 100644 --- a/clang/test/SemaTemplate/typename-specifier.cpp +++ b/clang/test/SemaTemplate/typename-specifier.cpp @@ -15,20 +15,22 @@ namespace N { int i; -typename N::A::type *ip1 = &i; // expected-warning{{'typename' refers to a non-dependent type name}} -typename N::B::type *ip2 = &i; // expected-error{{no type named 'type' in 'N::B'}} -typename N::C::type *ip3 = &i; // expected-error{{typename specifier refers to non-type member 'type'}} +typename N::A::type *ip1 = &i; // expected-warning{{'typename' occurs outside of a template}} +typename N::B::type *ip2 = &i; // expected-error{{no type named 'type' in 'N::B'}} \ +// expected-warning{{'typename' occurs outside of a template}} +typename N::C::type *ip3 = &i; // expected-error{{typename specifier refers to non-type member 'type'}} \ +// expected-warning{{'typename' occurs outside of a template}} void test(double d) { typename N::A::type f(typename N::A::type(a)); // expected-warning{{parentheses were disambiguated as a function declarator}} \ - // expected-warning 2{{'typename' refers to a non-dependent type name}} + // expected-warning 2{{'typename' occurs outside of a template}} int five = f(5); using namespace N; - for (typename A::type i = 0; i < 10; ++i) // expected-warning{{'typename' refers to a non-dependent type name}} + for (typename A::type i = 0; i < 10; ++i) // expected-warning{{'typename' occurs outside of a template}} five += 1; - const typename N::A::type f2(d); // expected-warning{{'typename' refers to a non-dependent type name}} + const typename N::A::type f2(d); // expected-warning{{'typename' occurs outside of a template}} } namespace N { |