aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-06-16 22:31:08 +0000
committerDouglas Gregor <dgregor@apple.com>2010-06-16 22:31:08 +0000
commit1a15dae8be2b28e02b6639aa92b832465c5be420 (patch)
treee0208461ea4e3d921f512bb2d2421ce2f983e7e0 /lib
parent13927a431dd733336cfd664bf0840747a71b0a43 (diff)
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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@106161 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Parse/ParseExprCXX.cpp14
-rw-r--r--lib/Parse/ParseTemplate.cpp6
-rw-r--r--lib/Parse/Parser.cpp6
-rw-r--r--lib/Sema/Sema.h15
-rw-r--r--lib/Sema/SemaDecl.cpp2
-rw-r--r--lib/Sema/SemaTemplate.cpp46
-rw-r--r--lib/Sema/TreeTransform.h4
7 files changed, 51 insertions, 42 deletions
diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp
index 586dac6159..843baa2fe7 100644
--- a/lib/Parse/ParseExprCXX.cpp
+++ b/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/lib/Parse/ParseTemplate.cpp b/lib/Parse/ParseTemplate.cpp
index 5d248f1d77..ec0e31e703 100644
--- a/lib/Parse/ParseTemplate.cpp
+++ b/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/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index 296897080d..225a793af5 100644
--- a/lib/Parse/Parser.cpp
+++ b/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/lib/Sema/Sema.h b/lib/Sema/Sema.h
index 396f144ddf..c81c12bb86 100644
--- a/lib/Sema/Sema.h
+++ b/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/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index fbd4ff446a..9e31a54372 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/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/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index 5e40bc58bb..b30d4e3e9c 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/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/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index df01be01f1..86e3a25ea2 100644
--- a/lib/Sema/TreeTransform.h
+++ b/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,