r199438 - Clean up variable template handling a bit, and correct the behavior of name
Richard Smith
richard-llvm at metafoo.co.uk
Thu Jan 16 15:39:20 PST 2014
Author: rsmith
Date: Thu Jan 16 17:39:20 2014
New Revision: 199438
URL: http://llvm.org/viewvc/llvm-project?rev=199438&view=rev
Log:
Clean up variable template handling a bit, and correct the behavior of name
lookup when declaring a variable template specialization.
Modified:
cfe/trunk/include/clang/AST/DeclTemplate.h
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/AST/ASTImporter.cpp
cfe/trunk/lib/AST/DeclTemplate.cpp
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaTemplate.cpp
cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
cfe/trunk/test/CXX/temp/temp.spec/cxx1y-variable-template-no-body.cpp
cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p2-0x.cpp
cfe/trunk/test/SemaCXX/cxx1y-variable-templates_top_level.cpp
Modified: cfe/trunk/include/clang/AST/DeclTemplate.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclTemplate.h?rev=199438&r1=199437&r2=199438&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclTemplate.h (original)
+++ cfe/trunk/include/clang/AST/DeclTemplate.h Thu Jan 16 17:39:20 2014
@@ -2704,8 +2704,8 @@ public:
/// \brief Create a variable template node.
static VarTemplateDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L, DeclarationName Name,
- TemplateParameterList *Params, NamedDecl *Decl,
- VarTemplateDecl *PrevDecl);
+ TemplateParameterList *Params,
+ VarDecl *Decl);
/// \brief Create an empty variable template node.
static VarTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=199438&r1=199437&r2=199438&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Thu Jan 16 17:39:20 2014
@@ -5141,7 +5141,7 @@ public:
SourceLocation RAngleLoc);
DeclResult ActOnVarTemplateSpecialization(
- Scope *S, VarTemplateDecl *VarTemplate, Declarator &D, TypeSourceInfo *DI,
+ Scope *S, Declarator &D, TypeSourceInfo *DI,
SourceLocation TemplateKWLoc, TemplateParameterList *TemplateParams,
StorageClass SC, bool IsPartialSpecialization);
Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=199438&r1=199437&r2=199438&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Thu Jan 16 17:39:20 2014
@@ -4241,8 +4241,7 @@ Decl *ASTNodeImporter::VisitVarTemplateD
return 0;
VarTemplateDecl *D2 = VarTemplateDecl::Create(
- Importer.getToContext(), DC, Loc, Name, TemplateParams, D2Templated,
- /*PrevDecl=*/0);
+ Importer.getToContext(), DC, Loc, Name, TemplateParams, D2Templated);
D2Templated->setDescribedVarTemplate(D2);
D2->setAccess(D->getAccess());
Modified: cfe/trunk/lib/AST/DeclTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclTemplate.cpp?rev=199438&r1=199437&r2=199438&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclTemplate.cpp (original)
+++ cfe/trunk/lib/AST/DeclTemplate.cpp Thu Jan 16 17:39:20 2014
@@ -941,11 +941,8 @@ VarTemplateDecl *VarTemplateDecl::getDef
VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation L, DeclarationName Name,
TemplateParameterList *Params,
- NamedDecl *Decl,
- VarTemplateDecl *PrevDecl) {
- VarTemplateDecl *New = new (C, DC) VarTemplateDecl(DC, L, Name, Params, Decl);
- New->setPreviousDecl(PrevDecl);
- return New;
+ VarDecl *Decl) {
+ return new (C, DC) VarTemplateDecl(DC, L, Name, Params, Decl);
}
VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C,
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=199438&r1=199437&r2=199438&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Thu Jan 16 17:39:20 2014
@@ -3000,14 +3000,17 @@ void Sema::MergeVarDecl(VarDecl *New, Lo
if (New->isInvalidDecl())
return;
+ VarTemplateDecl *NewTemplate = New->getDescribedVarTemplate();
+
// Verify the old decl was also a variable or variable template.
VarDecl *Old = 0;
- if (Previous.isSingleResult() &&
- (Old = dyn_cast<VarDecl>(Previous.getFoundDecl()))) {
- if (New->getDescribedVarTemplate())
- Old = Old->getDescribedVarTemplate() ? Old : 0;
- else
- Old = Old->getDescribedVarTemplate() ? 0 : Old;
+ VarTemplateDecl *OldTemplate = 0;
+ if (Previous.isSingleResult()) {
+ if (NewTemplate) {
+ OldTemplate = dyn_cast<VarTemplateDecl>(Previous.getFoundDecl());
+ Old = OldTemplate ? OldTemplate->getTemplatedDecl() : 0;
+ } else
+ Old = dyn_cast<VarDecl>(Previous.getFoundDecl());
}
if (!Old) {
Diag(New->getLocation(), diag::err_redefinition_different_kind)
@@ -3020,6 +3023,13 @@ void Sema::MergeVarDecl(VarDecl *New, Lo
if (!shouldLinkPossiblyHiddenDecl(Old, New))
return;
+ // Ensure the template parameters are compatible.
+ if (NewTemplate &&
+ !TemplateParameterListsAreEqual(NewTemplate->getTemplateParameters(),
+ OldTemplate->getTemplateParameters(),
+ /*Complain=*/true, TPL_TemplateMatch))
+ return;
+
// C++ [class.mem]p1:
// A member shall not be declared twice in the member-specification [...]
//
@@ -3145,14 +3155,13 @@ void Sema::MergeVarDecl(VarDecl *New, Lo
// Keep a chain of previous declarations.
New->setPreviousDecl(Old);
+ if (NewTemplate)
+ NewTemplate->setPreviousDecl(OldTemplate);
// Inherit access appropriately.
New->setAccess(Old->getAccess());
-
- if (VarTemplateDecl *VTD = New->getDescribedVarTemplate()) {
- if (New->isStaticDataMember() && New->isOutOfLine())
- VTD->setAccess(New->getAccess());
- }
+ if (NewTemplate)
+ NewTemplate->setAccess(New->getAccess());
}
/// ParsedFreeStandingDeclSpec - This method is invoked when a declspec with
@@ -5065,9 +5074,9 @@ Sema::ActOnVariableDeclarator(Scope *S,
bool IsVariableTemplateSpecialization = false;
bool IsPartialSpecialization = false;
bool IsVariableTemplate = false;
- VarTemplateDecl *PrevVarTemplate = 0;
VarDecl *NewVD = 0;
VarTemplateDecl *NewTemplate = 0;
+ TemplateParameterList *TemplateParams = 0;
if (!getLangOpts().CPlusPlus) {
NewVD = VarDecl::Create(Context, DC, D.getLocStart(),
D.getIdentifierLoc(), II,
@@ -5129,18 +5138,33 @@ Sema::ActOnVariableDeclarator(Scope *S,
}
}
- NamedDecl *PrevDecl = 0;
- if (Previous.begin() != Previous.end())
- PrevDecl = (*Previous.begin())->getUnderlyingDecl();
- PrevVarTemplate = dyn_cast_or_null<VarTemplateDecl>(PrevDecl);
-
// Match up the template parameter lists with the scope specifier, then
// determine whether we have a template or a template specialization.
- TemplateParameterList *TemplateParams =
- MatchTemplateParametersToScopeSpecifier(
- D.getDeclSpec().getLocStart(), D.getIdentifierLoc(),
- D.getCXXScopeSpec(), TemplateParamLists,
- /*never a friend*/ false, IsExplicitSpecialization, Invalid);
+ TemplateParams = MatchTemplateParametersToScopeSpecifier(
+ D.getDeclSpec().getLocStart(), D.getIdentifierLoc(),
+ D.getCXXScopeSpec(), TemplateParamLists,
+ /*never a friend*/ false, IsExplicitSpecialization, Invalid);
+
+ if (D.getName().getKind() == UnqualifiedId::IK_TemplateId &&
+ !TemplateParams) {
+ TemplateIdAnnotation *TemplateId = D.getName().TemplateId;
+
+ // We have encountered something that the user meant to be a
+ // specialization (because it has explicitly-specified template
+ // arguments) but that was not introduced with a "template<>" (or had
+ // too few of them).
+ // FIXME: Differentiate between attempts for explicit instantiations
+ // (starting with "template") and the rest.
+ Diag(D.getIdentifierLoc(), diag::err_template_spec_needs_header)
+ << SourceRange(TemplateId->LAngleLoc, TemplateId->RAngleLoc)
+ << FixItHint::CreateInsertion(D.getDeclSpec().getLocStart(),
+ "template<> ");
+ IsVariableTemplateSpecialization = true;
+ TemplateParams = TemplateParameterList::Create(Context, SourceLocation(),
+ SourceLocation(), 0, 0,
+ SourceLocation());
+ }
+
if (TemplateParams) {
if (!TemplateParams->size() &&
D.getName().getKind() != UnqualifiedId::IK_TemplateId) {
@@ -5151,6 +5175,7 @@ Sema::ActOnVariableDeclarator(Scope *S,
<< II
<< SourceRange(TemplateParams->getTemplateLoc(),
TemplateParams->getRAngleLoc());
+ TemplateParams = 0;
} else {
// Only C++1y supports variable templates (N3651).
Diag(D.getIdentifierLoc(),
@@ -5160,11 +5185,9 @@ Sema::ActOnVariableDeclarator(Scope *S,
if (D.getName().getKind() == UnqualifiedId::IK_TemplateId) {
// This is an explicit specialization or a partial specialization.
- // Check that we can declare a specialization here
-
+ // FIXME: Check that we can declare a specialization here.
IsVariableTemplateSpecialization = true;
IsPartialSpecialization = TemplateParams->size() > 0;
-
} else { // if (TemplateParams->size() > 0)
// This is a template declaration.
IsVariableTemplate = true;
@@ -5172,89 +5195,17 @@ Sema::ActOnVariableDeclarator(Scope *S,
// Check that we can declare a template here.
if (CheckTemplateDeclScope(S, TemplateParams))
return 0;
-
- // If there is a previous declaration with the same name, check
- // whether this is a valid redeclaration.
- if (PrevDecl && !isDeclInScope(PrevDecl, DC, S))
- PrevDecl = PrevVarTemplate = 0;
-
- if (PrevVarTemplate) {
- // Ensure that the template parameter lists are compatible.
- if (!TemplateParameterListsAreEqual(
- TemplateParams, PrevVarTemplate->getTemplateParameters(),
- /*Complain=*/true, TPL_TemplateMatch))
- return 0;
- } else if (PrevDecl && PrevDecl->isTemplateParameter()) {
- // Maybe we will complain about the shadowed template parameter.
- DiagnoseTemplateParameterShadow(D.getIdentifierLoc(), PrevDecl);
-
- // Just pretend that we didn't see the previous declaration.
- PrevDecl = 0;
- } else if (PrevDecl) {
- // C++ [temp]p5:
- // ... a template name declared in namespace scope or in class
- // scope shall be unique in that scope.
- Diag(D.getIdentifierLoc(), diag::err_redefinition_different_kind)
- << Name;
- Diag(PrevDecl->getLocation(), diag::note_previous_definition);
- return 0;
- }
-
- // Check the template parameter list of this declaration, possibly
- // merging in the template parameter list from the previous variable
- // template declaration.
- if (CheckTemplateParameterList(
- TemplateParams,
- PrevVarTemplate ? PrevVarTemplate->getTemplateParameters()
- : 0,
- (D.getCXXScopeSpec().isSet() && DC && DC->isRecord() &&
- DC->isDependentContext())
- ? TPC_ClassTemplateMember
- : TPC_VarTemplate))
- Invalid = true;
-
- if (D.getCXXScopeSpec().isSet()) {
- // If the name of the template was qualified, we must be defining
- // the template out-of-line.
- if (!D.getCXXScopeSpec().isInvalid() && !Invalid &&
- !PrevVarTemplate) {
- Diag(D.getIdentifierLoc(), diag::err_member_decl_does_not_match)
- << Name << DC << /*IsDefinition*/true
- << D.getCXXScopeSpec().getRange();
- Invalid = true;
- }
- }
}
}
- } else if (D.getName().getKind() == UnqualifiedId::IK_TemplateId) {
- TemplateIdAnnotation *TemplateId = D.getName().TemplateId;
-
- // We have encountered something that the user meant to be a
- // specialization (because it has explicitly-specified template
- // arguments) but that was not introduced with a "template<>" (or had
- // too few of them).
- // FIXME: Differentiate between attempts for explicit instantiations
- // (starting with "template") and the rest.
- Diag(D.getIdentifierLoc(), diag::err_template_spec_needs_header)
- << SourceRange(TemplateId->LAngleLoc, TemplateId->RAngleLoc)
- << FixItHint::CreateInsertion(D.getDeclSpec().getLocStart(),
- "template<> ");
- IsVariableTemplateSpecialization = true;
}
if (IsVariableTemplateSpecialization) {
- if (!PrevVarTemplate) {
- Diag(D.getIdentifierLoc(), diag::err_var_spec_no_template)
- << IsPartialSpecialization;
- return 0;
- }
-
SourceLocation TemplateKWLoc =
TemplateParamLists.size() > 0
? TemplateParamLists[0]->getTemplateLoc()
: SourceLocation();
DeclResult Res = ActOnVarTemplateSpecialization(
- S, PrevVarTemplate, D, TInfo, TemplateKWLoc, TemplateParams, SC,
+ S, D, TInfo, TemplateKWLoc, TemplateParams, SC,
IsPartialSpecialization);
if (Res.isInvalid())
return 0;
@@ -5268,7 +5219,7 @@ Sema::ActOnVariableDeclarator(Scope *S,
if (IsVariableTemplate) {
NewTemplate =
VarTemplateDecl::Create(Context, DC, D.getIdentifierLoc(), Name,
- TemplateParams, NewVD, PrevVarTemplate);
+ TemplateParams, NewVD);
NewVD->setDescribedVarTemplate(NewTemplate);
}
@@ -5453,6 +5404,11 @@ Sema::ActOnVariableDeclarator(Scope *S,
if (!getLangOpts().CPlusPlus) {
D.setRedeclaration(CheckVariableDeclaration(NewVD, Previous));
} else {
+ // If this is an explicit specialization of a static data member, check it.
+ if (IsExplicitSpecialization && !NewVD->isInvalidDecl() &&
+ CheckMemberSpecialization(NewVD, Previous))
+ NewVD->setInvalidDecl();
+
// Merge the decl with the existing one if appropriate.
if (!Previous.empty()) {
if (Previous.isSingleResult() &&
@@ -5473,20 +5429,34 @@ Sema::ActOnVariableDeclarator(Scope *S,
NewVD->setInvalidDecl();
}
- if (!IsVariableTemplateSpecialization) {
- if (PrevVarTemplate) {
- LookupResult PrevDecl(*this, GetNameForDeclarator(D),
- LookupOrdinaryName, ForRedeclaration);
- PrevDecl.addDecl(PrevVarTemplate->getTemplatedDecl());
- D.setRedeclaration(CheckVariableDeclaration(NewVD, PrevDecl));
- } else
- D.setRedeclaration(CheckVariableDeclaration(NewVD, Previous));
- }
+ if (!IsVariableTemplateSpecialization)
+ D.setRedeclaration(CheckVariableDeclaration(NewVD, Previous));
- // This is an explicit specialization of a static data member. Check it.
- if (IsExplicitSpecialization && !NewVD->isInvalidDecl() &&
- CheckMemberSpecialization(NewVD, Previous))
- NewVD->setInvalidDecl();
+ if (NewTemplate) {
+ VarTemplateDecl *PrevVarTemplate =
+ NewVD->getPreviousDecl()
+ ? NewVD->getPreviousDecl()->getDescribedVarTemplate()
+ : 0;
+
+ // Check the template parameter list of this declaration, possibly
+ // merging in the template parameter list from the previous variable
+ // template declaration.
+ if (CheckTemplateParameterList(
+ TemplateParams,
+ PrevVarTemplate ? PrevVarTemplate->getTemplateParameters()
+ : 0,
+ (D.getCXXScopeSpec().isSet() && DC && DC->isRecord() &&
+ DC->isDependentContext())
+ ? TPC_ClassTemplateMember
+ : TPC_VarTemplate))
+ NewVD->setInvalidDecl();
+
+ // If we are providing an explicit specialization of a static variable
+ // template, make a note of that.
+ if (PrevVarTemplate &&
+ PrevVarTemplate->getInstantiatedFromMemberTemplate())
+ PrevVarTemplate->setMemberSpecialization();
+ }
}
ProcessPragmaWeak(S, NewVD);
@@ -5507,12 +5477,9 @@ Sema::ActOnVariableDeclarator(Scope *S,
}
}
- // If we are providing an explicit specialization of a static variable
- // template, make a note of that.
- if (PrevVarTemplate && PrevVarTemplate->getInstantiatedFromMemberTemplate())
- PrevVarTemplate->setMemberSpecialization();
-
if (NewTemplate) {
+ if (NewVD->isInvalidDecl())
+ NewTemplate->setInvalidDecl();
ActOnDocumentableDecl(NewTemplate);
return NewTemplate;
}
Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=199438&r1=199437&r2=199438&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Thu Jan 16 17:39:20 2014
@@ -2340,11 +2340,9 @@ static bool isSameAsPrimaryTemplate(Temp
}
DeclResult Sema::ActOnVarTemplateSpecialization(
- Scope *S, VarTemplateDecl *VarTemplate, Declarator &D, TypeSourceInfo *DI,
- SourceLocation TemplateKWLoc, TemplateParameterList *TemplateParams,
- VarDecl::StorageClass SC, bool IsPartialSpecialization) {
- assert(VarTemplate && "A variable template id without template?");
-
+ Scope *S, Declarator &D, TypeSourceInfo *DI, SourceLocation TemplateKWLoc,
+ TemplateParameterList *TemplateParams, VarDecl::StorageClass SC,
+ bool IsPartialSpecialization) {
// D must be variable template id.
assert(D.getName().getKind() == UnqualifiedId::IK_TemplateId &&
"Variable template specialization is declared with a template it.");
@@ -2357,7 +2355,14 @@ DeclResult Sema::ActOnVarTemplateSpecial
TemplateId->NumArgs);
TemplateArgumentListInfo TemplateArgs(LAngleLoc, RAngleLoc);
translateTemplateArguments(TemplateArgsPtr, TemplateArgs);
- TemplateName Name(VarTemplate);
+ TemplateName Name = TemplateId->Template.get();
+
+ // The template-id must name a variable template.
+ VarTemplateDecl *VarTemplate =
+ dyn_cast<VarTemplateDecl>(Name.getAsTemplateDecl());
+ if (!VarTemplate)
+ return Diag(D.getIdentifierLoc(), diag::err_var_spec_no_template)
+ << IsPartialSpecialization;
// Check for unexpanded parameter packs in any of the template arguments.
for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=199438&r1=199437&r2=199438&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Thu Jan 16 17:39:20 2014
@@ -76,8 +76,18 @@ Sema::getTemplateInstantiationArgs(Named
// If this variable template specialization was instantiated from a
// specialized member that is a variable template, we're done.
assert(Spec->getSpecializedTemplate() && "No variable template?");
- if (Spec->getSpecializedTemplate()->isMemberSpecialization())
- return Result;
+ llvm::PointerUnion<VarTemplateDecl*,
+ VarTemplatePartialSpecializationDecl*> Specialized
+ = Spec->getSpecializedTemplateOrPartial();
+ if (VarTemplatePartialSpecializationDecl *Partial =
+ Specialized.dyn_cast<VarTemplatePartialSpecializationDecl *>()) {
+ if (Partial->isMemberSpecialization())
+ return Result;
+ } else {
+ VarTemplateDecl *Tmpl = Specialized.get<VarTemplateDecl *>();
+ if (Tmpl->isMemberSpecialization())
+ return Result;
+ }
}
// If we have a template template parameter with translation unit context,
Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=199438&r1=199437&r2=199438&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Thu Jan 16 17:39:20 2014
@@ -1033,8 +1033,9 @@ Decl *TemplateDeclInstantiator::VisitVar
VarTemplateDecl *Inst = VarTemplateDecl::Create(
SemaRef.Context, DC, D->getLocation(), D->getIdentifier(), InstParams,
- VarInst, PrevVarTemplate);
+ VarInst);
VarInst->setDescribedVarTemplate(Inst);
+ Inst->setPreviousDecl(PrevVarTemplate);
Inst->setAccess(D->getAccess());
if (!PrevVarTemplate)
@@ -3516,7 +3517,18 @@ VarTemplateSpecializationDecl *Sema::Bui
// or may not be the declaration in the class; if it's in the class, we want
// to instantiate a member in the class (a declaration), and if it's outside,
// we want to instantiate a definition.
- FromVar = FromVar->getFirstDecl();
+ //
+ // If we're instantiating an explicitly-specialized member template or member
+ // partial specialization, don't do this. The member specialization completely
+ // replaces the original declaration in this case.
+ bool IsMemberSpec = false;
+ if (VarTemplatePartialSpecializationDecl *PartialSpec =
+ dyn_cast<VarTemplatePartialSpecializationDecl>(FromVar))
+ IsMemberSpec = PartialSpec->isMemberSpecialization();
+ else if (VarTemplateDecl *FromTemplate = FromVar->getDescribedVarTemplate())
+ IsMemberSpec = FromTemplate->isMemberSpecialization();
+ if (!IsMemberSpec)
+ FromVar = FromVar->getFirstDecl();
MultiLevelTemplateArgumentList MultiLevelList(TemplateArgList);
TemplateDeclInstantiator Instantiator(*this, FromVar->getDeclContext(),
Modified: cfe/trunk/test/CXX/temp/temp.spec/cxx1y-variable-template-no-body.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.spec/cxx1y-variable-template-no-body.cpp?rev=199438&r1=199437&r2=199438&view=diff
==============================================================================
--- cfe/trunk/test/CXX/temp/temp.spec/cxx1y-variable-template-no-body.cpp (original)
+++ cfe/trunk/test/CXX/temp/temp.spec/cxx1y-variable-template-no-body.cpp Thu Jan 16 17:39:20 2014
@@ -24,14 +24,14 @@ template int pi0 = 10; // expected-error
#endif
template<typename T>
-T pi1 = T(3.1415926535897932385);
+T pi1 = T(3.1415926535897932385); // expected-note 0-2 {{here}}
// Should recover as if specialization
template float pi1<float> = 1.0; // expected-error {{explicit template instantiation cannot have a definition; if this definition is meant to be an explicit specialization, add '<>' after the 'template' keyword}}
#ifndef FIXING
namespace expected_global {
- template<> double pi1<double> = 1.5; // expected-error {{no variable template matches specialization}}
+ template<> double pi1<double> = 1.5; // expected-error {{variable template specialization of 'pi1' must originally be declared in the global scope}}
template int pi1<int> = 10; // expected-error {{explicit template instantiation cannot have a definition; if this definition is meant to be an explicit specialization, add '<>' after the 'template' keyword}} \
- expected-error {{no variable template matches specialization}}
+ expected-error {{variable template specialization of 'pi1' must originally be declared in the global scope}}
}
#endif
Modified: cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p2-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p2-0x.cpp?rev=199438&r1=199437&r2=199438&view=diff
==============================================================================
--- cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p2-0x.cpp (original)
+++ cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p2-0x.cpp Thu Jan 16 17:39:20 2014
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s -Wno-c++1y-extensions
// This test creates cases where implicit instantiations of various entities
// would cause a diagnostic, but provides expliict specializations for those
@@ -10,6 +10,8 @@ struct NonDefaultConstructible {
NonDefaultConstructible(int);
};
+// FIXME: The "must originally be declared in namespace" diagnostics throughout
+// this file are wrong.
// C++ [temp.expl.spec]p1:
// An explicit specialization of any of the following:
@@ -90,6 +92,44 @@ template<> struct N0::X0<volatile void>
void f1(void *);
};
+// -- variable template [C++1y]
+namespace N0 {
+template<typename T> int v0; // expected-note +{{here}}
+template<> extern int v0<char[1]>;
+template<> extern int v0<char[2]>;
+template<> extern int v0<char[5]>;
+template<> extern int v0<char[6]>;
+}
+using N0::v0;
+
+template<typename T> int v1; // expected-note +{{here}}
+template<> extern int v1<char[3]>;
+template<> extern int v1<char[4]>;
+template<> extern int v1<char[7]>;
+template<> extern int v1<char[8]>;
+
+template<> int N0::v0<int[1]>;
+template<> int v0<int[2]>; // FIXME: ill-formed
+template<> int ::v1<int[3]>; // expected-warning {{extra qualification}}
+template<> int v1<int[4]>;
+
+template<> int N0::v0<char[1]>;
+template<> int v0<char[2]>; // FIXME: ill-formed
+template<> int ::v1<char[3]>; // expected-warning {{extra qualification}}
+template<> int v1<char[4]>;
+
+namespace N1 {
+template<> int N0::v0<int[5]>; // expected-error {{must originally be declared in namespace 'N0'}} expected-error {{does not enclose namespace}}
+template<> int v0<int[6]>; // expected-error {{must originally be declared in namespace 'N0'}}
+template<> int ::v1<int[7]>; // expected-error {{must originally be declared in the global scope}} expected-error {{cannot name the global scope}}
+template<> int v1<int[8]>; // expected-error {{must originally be declared in the global scope}}
+
+template<> int N0::v0<char[5]>; // expected-error {{does not enclose namespace 'N0'}}
+template<> int v0<char[6]>; // FIXME: ill-formed
+template<> int ::v1<char[7]>; // expected-error {{cannot name the global scope}}
+template<> int v1<char[8]>; // FIXME: ill-formed
+}
+
// -- member function of a class template
template<> void N0::X0<void*>::f1(void *) { }
Modified: cfe/trunk/test/SemaCXX/cxx1y-variable-templates_top_level.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx1y-variable-templates_top_level.cpp?rev=199438&r1=199437&r2=199438&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx1y-variable-templates_top_level.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx1y-variable-templates_top_level.cpp Thu Jan 16 17:39:20 2014
@@ -81,7 +81,7 @@ namespace odr_tmpl {
template<typename T> T v; // expected-note {{previous definition is here}}
template<typename T> int v; // expected-error {{redefinition of 'v'}}
- template<typename T> int v1; // expected-note {{previous template declaration is here}}
+ template<typename T> extern int v1; // expected-note {{previous template declaration is here}}
template<int I> int v1; // expected-error {{template parameter has a different kind in template redeclaration}}
}
namespace pvt_use {
@@ -90,11 +90,8 @@ namespace odr_tmpl {
}
namespace pvt_diff_params {
- // FIXME: (?) Redefinitions should simply be not allowed, whether the
- // template parameters match or not. However, this current behaviour also
- // matches that of class templates...
- template<typename T, typename> T v; // expected-note 2{{previous template declaration is here}}
- template<typename T> T v; // expected-error {{too few template parameters in template redeclaration}}
+ template<typename T, typename> T v; // expected-note {{previous template declaration is here}}
+ template<typename T> T v; // expected-error {{too few template parameters in template redeclaration}} expected-note {{previous template declaration is here}}
template<typename T, typename, typename> T v; // expected-error {{too many template parameters in template redeclaration}}
}
@@ -391,7 +388,7 @@ namespace nested {
namespace n1 {
template<typename T>
- T pi1a = T(3.1415926535897932385);
+ T pi1a = T(3.1415926535897932385); // expected-note {{explicitly specialized declaration is here}}
#ifndef PRECXX11
// expected-note at -2 {{explicit instantiation refers here}}
#endif
@@ -413,7 +410,7 @@ namespace nested {
#endif
float f1 = pi1a<float>;
- template<> double pi1a<double> = 5.2; // expected-error {{no variable template matches specialization}}
+ template<> double pi1a<double> = 5.2; // expected-error {{variable template specialization of 'pi1a' must originally be declared in namespace 'n1'}}
double d1 = pi1a<double>;
}
More information about the cfe-commits
mailing list