mirror of
https://github.com/intel/llvm.git
synced 2026-01-22 07:01:03 +08:00
Fix the recently-added warning about 'typename' and 'template'
disambiguation keywords outside of templates in C++98/03. Previously, the warning would fire when the associated nested-name-specifier was not dependent, but that was a misreading of the C++98/03 standard: now, we complain only when we're outside of any template. llvm-svn: 106161
This commit is contained in:
@@ -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<
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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'}}
|
||||
|
||||
@@ -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];
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user