From: Larisse Voufo Date: Thu, 22 Aug 2013 00:59:14 +0000 (+0000) Subject: Refactor for clarity and simplicity. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=567f917df048d42732997a479b2b257403fc88ef;p=clang Refactor for clarity and simplicity. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@188974 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h index 9de98bb9ca..be446f5b61 100644 --- a/include/clang/AST/DeclTemplate.h +++ b/include/clang/AST/DeclTemplate.h @@ -2782,7 +2782,7 @@ public: /// \brief Return the next partial specialization sequence number. unsigned getNextPartialSpecSequenceNumber() { - return getPartialSpecializations().size(); + return getCommonPtr()->PartialSpecializations.size(); } /// \brief Retrieve the partial specializations as an ordered list. diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index a871e55cca..b150c67114 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -1472,8 +1472,7 @@ public: MultiTemplateParamsArg TemplateParamLists, bool &AddToScope); // Returns true if the variable declaration is a redeclaration - bool CheckVariableDeclaration(VarDecl *NewVD, LookupResult &Previous, - bool IsVariableTemplate = false); + bool CheckVariableDeclaration(VarDecl *NewVD, LookupResult &Previous); void CheckVariableDeclarationType(VarDecl *NewVD); void CheckCompleteVariableDeclaration(VarDecl *var); void MaybeSuggestAddingStaticToDecl(const FunctionDecl *D); @@ -1869,7 +1868,7 @@ public: Scope *S, bool MergeTypeWithOld); void mergeObjCMethodDecls(ObjCMethodDecl *New, ObjCMethodDecl *Old); void MergeVarDecl(VarDecl *New, LookupResult &Previous, - bool IsVariableTemplate, bool MergeTypeWithPrevious); + bool MergeTypeWithPrevious); void MergeVarDeclTypes(VarDecl *New, VarDecl *Old, bool MergeTypeWithOld); void MergeVarDeclExceptionSpecs(VarDecl *New, VarDecl *Old); bool MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old, Scope *S); @@ -6432,7 +6431,7 @@ public: const MultiLevelTemplateArgumentList &TemplateArgs, LateInstantiatedAttrVec *LateAttrs = 0, LocalInstantiationScope *StartingScope = 0, - bool ForVarTemplate = false); + bool InstantiatingVarTemplate = false); void InstantiateVariableInitializer( VarDecl *Var, VarDecl *OldVar, const MultiLevelTemplateArgumentList &TemplateArgs); diff --git a/include/clang/Sema/Template.h b/include/clang/Sema/Template.h index 4f0550f580..3aba5519bd 100644 --- a/include/clang/Sema/Template.h +++ b/include/clang/Sema/Template.h @@ -425,7 +425,7 @@ namespace clang { Decl *VisitFunctionDecl(FunctionDecl *D, TemplateParameterList *TemplateParams); Decl *VisitDecl(Decl *D); - Decl *VisitVarDecl(VarDecl *D, bool ForVarTemplate); + Decl *VisitVarDecl(VarDecl *D, bool InstantiatingVarTemplate); // Enable late instantiation of attributes. Late instantiated attributes // will be stored in LA. diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 9f2e757dc2..80863e35e2 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -2887,7 +2887,7 @@ void Sema::MergeVarDeclTypes(VarDecl *New, VarDecl *Old, /// definitions here, since the initializer hasn't been attached. /// void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous, - bool IsVariableTemplate, bool MergeTypeWithPrevious) { + bool MergeTypeWithPrevious) { // If the new decl is already invalid, don't do any other checking. if (New->isInvalidDecl()) return; @@ -2896,7 +2896,7 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous, VarDecl *Old = 0; if (Previous.isSingleResult() && (Old = dyn_cast(Previous.getFoundDecl()))) { - if (IsVariableTemplate) + if (New->getDescribedVarTemplate()) Old = Old->getDescribedVarTemplate() ? Old : 0; else Old = Old->getDescribedVarTemplate() ? 0 : Old; @@ -3039,6 +3039,11 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous, // Inherit access appropriately. New->setAccess(Old->getAccess()); + + if (VarTemplateDecl *VTD = New->getDescribedVarTemplate()) { + if (New->isStaticDataMember() && New->isOutOfLine()) + VTD->setAccess(New->getAccess()); + } } /// ParsedFreeStandingDeclSpec - This method is invoked when a declspec with @@ -4893,10 +4898,9 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, bool IsVariableTemplateSpecialization = false; bool IsPartialSpecialization = false; bool IsVariableTemplate = false; - bool Invalid = false; // TODO: Can we remove this (error-prone)? - TemplateParameterList *TemplateParams = 0; VarTemplateDecl *PrevVarTemplate = 0; - VarDecl *NewVD; + VarDecl *NewVD = 0; + VarTemplateDecl *NewTemplate = 0; if (!getLangOpts().CPlusPlus) { NewVD = VarDecl::Create(Context, DC, D.getLocStart(), D.getIdentifierLoc(), II, @@ -4905,6 +4909,8 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, if (D.isInvalidType()) NewVD->setInvalidDecl(); } else { + bool Invalid = false; + if (DC->isRecord() && !CurContext->isRecord()) { // This is an out-of-line definition of a static data member. switch (SC) { @@ -4963,10 +4969,11 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, // Match up the template parameter lists with the scope specifier, then // determine whether we have a template or a template specialization. - TemplateParams = MatchTemplateParametersToScopeSpecifier( - D.getDeclSpec().getLocStart(), D.getIdentifierLoc(), - D.getCXXScopeSpec(), TemplateParamLists, - /*never a friend*/ false, IsExplicitSpecialization, Invalid); + TemplateParameterList *TemplateParams = + MatchTemplateParametersToScopeSpecifier( + D.getDeclSpec().getLocStart(), D.getIdentifierLoc(), + D.getCXXScopeSpec(), TemplateParamLists, + /*never a friend*/ false, IsExplicitSpecialization, Invalid); if (TemplateParams) { if (!TemplateParams->size() && D.getName().getKind() != UnqualifiedId::IK_TemplateId) { @@ -5090,13 +5097,24 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, NewVD = VarDecl::Create(Context, DC, D.getLocStart(), D.getIdentifierLoc(), II, R, TInfo, SC); + // If this is supposed to be a variable template, create it as such. + if (IsVariableTemplate) { + NewTemplate = + VarTemplateDecl::Create(Context, DC, D.getIdentifierLoc(), Name, + TemplateParams, NewVD, PrevVarTemplate); + NewVD->setDescribedVarTemplate(NewTemplate); + } + // If this decl has an auto type in need of deduction, make a note of the // Decl so we can diagnose uses of it in its own initializer. if (D.getDeclSpec().containsPlaceholderType() && R->getContainedAutoType()) ParsingInitForAutoVars.insert(NewVD); - if (D.isInvalidType() || Invalid) + if (D.isInvalidType() || Invalid) { NewVD->setInvalidDecl(); + if (NewTemplate) + NewTemplate->setInvalidDecl(); + } SetNestedNameSpecifier(NewVD, D); @@ -5120,6 +5138,8 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, // Set the lexical context. If the declarator has a C++ scope specifier, the // lexical context will be different from the semantic context. NewVD->setLexicalDeclContext(CurContext); + if (NewTemplate) + NewTemplate->setLexicalDeclContext(CurContext); if (DeclSpec::TSCS TSCS = D.getDeclSpec().getThreadStorageClassSpec()) { if (NewVD->hasLocalStorage()) { @@ -5178,8 +5198,11 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, << 0 << NewVD->getDeclName() << SourceRange(D.getDeclSpec().getModulePrivateSpecLoc()) << FixItHint::CreateRemoval(D.getDeclSpec().getModulePrivateSpecLoc()); - else + else { NewVD->setModulePrivate(); + if (NewTemplate) + NewTemplate->setModulePrivate(); + } } // Handle attributes prior to checking for duplicates in MergeVarDecl @@ -5238,7 +5261,6 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, } // Diagnose shadowed variables before filtering for scope. - // FIXME: Special treatment for static variable template members (?). if (!D.getCXXScopeSpec().isSet()) CheckShadow(S, NewVD, Previous); @@ -5285,15 +5307,12 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, LookupResult PrevDecl(*this, GetNameForDeclarator(D), LookupOrdinaryName, ForRedeclaration); PrevDecl.addDecl(PrevVarTemplate->getTemplatedDecl()); - D.setRedeclaration( - CheckVariableDeclaration(NewVD, PrevDecl, IsVariableTemplate)); + D.setRedeclaration(CheckVariableDeclaration(NewVD, PrevDecl)); } else - D.setRedeclaration( - CheckVariableDeclaration(NewVD, Previous, IsVariableTemplate)); + D.setRedeclaration(CheckVariableDeclaration(NewVD, Previous)); } // This is an explicit specialization of a static data member. Check it. - // FIXME: Special treatment for static variable template members (?). if (IsExplicitSpecialization && !NewVD->isInvalidDecl() && CheckMemberSpecialization(NewVD, Previous)) NewVD->setInvalidDecl(); @@ -5317,40 +5336,17 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, } } - // If this is not a variable template, return it now. - if (!IsVariableTemplate) - return NewVD; - - // If this is supposed to be a variable template, create it as such. - VarTemplateDecl *NewTemplate = - VarTemplateDecl::Create(Context, DC, D.getIdentifierLoc(), Name, - TemplateParams, NewVD, PrevVarTemplate); - NewVD->setDescribedVarTemplate(NewTemplate); - - if (D.getDeclSpec().isModulePrivateSpecified()) - NewTemplate->setModulePrivate(); - // If we are providing an explicit specialization of a static variable // template, make a note of that. if (PrevVarTemplate && PrevVarTemplate->getInstantiatedFromMemberTemplate()) PrevVarTemplate->setMemberSpecialization(); - // Set the lexical context of this template - NewTemplate->setLexicalDeclContext(CurContext); - if (NewVD->isStaticDataMember() && NewVD->isOutOfLine()) - NewTemplate->setAccess(NewVD->getAccess()); - - PushOnScopeChains(NewTemplate, S); - AddToScope = false; - - if (Invalid) { - NewTemplate->setInvalidDecl(); - NewVD->setInvalidDecl(); + if (NewTemplate) { + ActOnDocumentableDecl(NewTemplate); + return NewTemplate; } - ActOnDocumentableDecl(NewTemplate); - - return NewTemplate; + return NewVD; } /// \brief Diagnose variable or built-in function shadowing. Implements @@ -5716,9 +5712,7 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) { /// Sets NewVD->isInvalidDecl() if an error was encountered. /// /// Returns true if the variable declaration is a redeclaration. -bool Sema::CheckVariableDeclaration(VarDecl *NewVD, - LookupResult &Previous, - bool IsVariableTemplate) { +bool Sema::CheckVariableDeclaration(VarDecl *NewVD, LookupResult &Previous) { CheckVariableDeclarationType(NewVD); // If the decl is already known invalid, don't check it. @@ -5768,7 +5762,7 @@ bool Sema::CheckVariableDeclaration(VarDecl *NewVD, filterNonConflictingPreviousDecls(Context, NewVD, Previous); if (!Previous.empty()) { - MergeVarDecl(NewVD, Previous, IsVariableTemplate, MergeTypeWithPrevious); + MergeVarDecl(NewVD, Previous, MergeTypeWithPrevious); return true; } return false; diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp index 9f84fc665b..9b7b4a8596 100644 --- a/lib/Sema/SemaTemplateInstantiate.cpp +++ b/lib/Sema/SemaTemplateInstantiate.cpp @@ -2254,12 +2254,10 @@ namespace { }; } -bool -Sema::InstantiateClassTemplateSpecialization( - SourceLocation PointOfInstantiation, - ClassTemplateSpecializationDecl *ClassTemplateSpec, - TemplateSpecializationKind TSK, - bool Complain) { +bool Sema::InstantiateClassTemplateSpecialization( + SourceLocation PointOfInstantiation, + ClassTemplateSpecializationDecl *ClassTemplateSpec, + TemplateSpecializationKind TSK, bool Complain) { // Perform the actual instantiation on the canonical declaration. ClassTemplateSpec = cast( ClassTemplateSpec->getCanonicalDecl()); diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index 8d066a0ac2..37511d0b36 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -320,10 +320,11 @@ TemplateDeclInstantiator::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) { // FIXME: Revise for static member templates. Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) { - return VisitVarDecl(D, /*ForVarTemplate=*/false); + return VisitVarDecl(D, /*InstantiatingVarTemplate=*/false); } -Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D, bool ForVarTemplate) { +Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D, + bool InstantiatingVarTemplate) { // If this is the variable for an anonymous struct or union, // instantiate the anonymous struct/union type first. @@ -361,7 +362,7 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D, bool ForVarTemplate) { return 0; SemaRef.BuildVariableInstantiation(Var, D, TemplateArgs, LateAttrs, - StartingScope, ForVarTemplate); + StartingScope, InstantiatingVarTemplate); return Var; } @@ -971,7 +972,8 @@ Decl *TemplateDeclInstantiator::VisitVarTemplateDecl(VarTemplateDecl *D) { } VarDecl *VarInst = - cast_or_null(VisitVarDecl(Pattern, /*ForVarTemplate=*/ true)); + cast_or_null(VisitVarDecl(Pattern, + /*InstantiatingVarTemplate=*/true)); DeclContext *DC = Owner; @@ -2649,8 +2651,6 @@ TemplateDeclInstantiator::InstantiateVarTemplatePartialSpecialization( InstPartialSpec->setInstantiatedFromMember(PartialSpec); InstPartialSpec->setTypeAsWritten(WrittenTy); - InstPartialSpec->setAccess(PartialSpec->getAccess()); - // Add this partial specialization to the set of variable template partial // specializations. The instantiation of the initializer is not necessary. VarTemplate->AddPartialSpecialization(InstPartialSpec, /*InsertPos=*/0); @@ -3314,9 +3314,8 @@ VarTemplateSpecializationDecl *Sema::CompleteVarTemplateSpecializationDecl( void Sema::BuildVariableInstantiation( VarDecl *NewVar, VarDecl *OldVar, const MultiLevelTemplateArgumentList &TemplateArgs, - LateInstantiatedAttrVec *LateAttrs, - LocalInstantiationScope *StartingScope, - bool ForVarTemplate) { + LateInstantiatedAttrVec *LateAttrs, LocalInstantiationScope *StartingScope, + bool InstantiatingVarTemplate) { // If we are instantiating a static data member defined // out-of-line, the instantiation will have the same lexical @@ -3354,15 +3353,14 @@ void Sema::BuildVariableInstantiation( } else if (!isa(NewVar) && OldVar->hasLinkage()) LookupQualifiedName(Previous, NewVar->getDeclContext(), false); - - CheckVariableDeclaration(NewVar, Previous, ForVarTemplate); + CheckVariableDeclaration(NewVar, Previous); if (OldVar->isOutOfLine()) { OldVar->getLexicalDeclContext()->addDecl(NewVar); - if (!ForVarTemplate) + if (!InstantiatingVarTemplate) NewVar->getDeclContext()->makeDeclVisibleInContext(NewVar); } else { - if (!ForVarTemplate) + if (!InstantiatingVarTemplate) NewVar->getDeclContext()->addDecl(NewVar); if (NewVar->getDeclContext()->isFunctionOrMethod()) CurrentInstantiationScope->InstantiatedLocal(OldVar, NewVar); @@ -3370,13 +3368,13 @@ void Sema::BuildVariableInstantiation( // Link instantiations of static data members back to the template from // which they were instantiated. - if (NewVar->isStaticDataMember() && !ForVarTemplate) + if (NewVar->isStaticDataMember() && !InstantiatingVarTemplate) NewVar->setInstantiationOfStaticDataMember(OldVar, TSK_ImplicitInstantiation); if (isa(NewVar)) { // Do not instantiate the variable just yet. - } else if (ForVarTemplate) { + } else if (InstantiatingVarTemplate) { assert(!NewVar->getInit() && "A variable should not have an initializer if it is templated" " and we are instantiating its template"); diff --git a/test/SemaCXX/cxx1y-variable-templates_in_class.cpp b/test/SemaCXX/cxx1y-variable-templates_in_class.cpp index 077394f213..c705354923 100644 --- a/test/SemaCXX/cxx1y-variable-templates_in_class.cpp +++ b/test/SemaCXX/cxx1y-variable-templates_in_class.cpp @@ -2,61 +2,63 @@ // RUN: %clang_cc1 -std=c++11 -verify -fsyntax-only -Wno-c++1y-extensions %s // RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only %s +#define CONST const + class A { - template const T wrong; // expected-error {{member 'wrong' declared as a template}} - template const T wrong_init = 5; // expected-error {{member 'wrong_init' declared as a template}} - template static const T right = T(100); - template static const T right = 5; - template const int right; // expected-error {{member 'right' declared as a template}} - template const float right = 5; // expected-error {{member 'right' declared as a template}} - template<> static const int right = 7; // expected-error {{explicit specialization of 'right' in class scope}} - template<> static const float right; // expected-error {{explicit specialization of 'right' in class scope}} - template static const int right; // expected-error {{template specialization requires 'template<>'}} \ + template CONST T wrong; // expected-error {{member 'wrong' declared as a template}} + template CONST T wrong_init = 5; // expected-error {{member 'wrong_init' declared as a template}} + template static CONST T right = T(100); + template static CONST T right = 5; + template CONST int right; // expected-error {{member 'right' declared as a template}} + template CONST float right = 5; // expected-error {{member 'right' declared as a template}} + template<> static CONST int right = 7; // expected-error {{explicit specialization of 'right' in class scope}} + template<> static CONST float right; // expected-error {{explicit specialization of 'right' in class scope}} + template static CONST int right; // expected-error {{template specialization requires 'template<>'}} \ // expected-error {{explicit specialization of 'right' in class scope}} }; namespace out_of_line { class B0 { - template static const T right = T(100); - template static const T right = T(5); + template static CONST T right = T(100); + template static CONST T right = T(5); }; - template<> const int B0::right = 7; - template const int B0::right; - template<> const int B0::right; - template const int B0::right; + template<> CONST int B0::right = 7; + template CONST int B0::right; + template<> CONST int B0::right; + template CONST int B0::right; class B1 { - template static const T right; - template static const T right; + template static CONST T right; + template static CONST T right; }; - template const T B1::right = T(100); - template const T B1::right = T(5); + template CONST T B1::right = T(100); + template CONST T B1::right = T(5); class B2 { - template static const T right = T(100); // expected-note {{previous definition is here}} - template static const T right = T(5); // expected-note {{previous definition is here}} + template static CONST T right = T(100); // expected-note {{previous definition is here}} + template static CONST T right = T(5); // expected-note {{previous definition is here}} }; - template const T B2::right = T(100); // expected-error {{redefinition of 'right'}} - template const T B2::right = T(5); // expected-error {{redefinition of 'right'}} + template CONST T B2::right = T(100); // expected-error {{redefinition of 'right'}} + template CONST T B2::right = T(5); // expected-error {{redefinition of 'right'}} class B3 { - template static const T right = T(100); - template static const T right = T(5); + template static CONST T right = T(100); + template static CONST T right = T(5); }; - template const T B3::right; // expected-error {{forward declaration of variable template cannot have a nested name specifier}} - template const T B3::right; // expected-error {{forward declaration of variable template partial specialization cannot have a nested name specifier}} + template CONST T B3::right; // expected-error {{forward declaration of variable template cannot have a nested name specifier}} + template CONST T B3::right; // expected-error {{forward declaration of variable template partial specialization cannot have a nested name specifier}} class B4 { - template static const T right; - template static const T right; - template static const T right_def = T(100); - template static const T right_def; // expected-note {{explicit instantiation refers here}} + template static CONST T right; + template static CONST T right; + template static CONST T right_def = T(100); + template static CONST T right_def; // expected-note {{explicit instantiation refers here}} }; - template const T B4::right; // expected-error {{forward declaration of variable template cannot have a nested name specifier}} - template const T B4::right; // expected-error {{forward declaration of variable template partial specialization cannot have a nested name specifier}} \ + template CONST T B4::right; // expected-error {{forward declaration of variable template cannot have a nested name specifier}} + template CONST T B4::right; // expected-error {{forward declaration of variable template partial specialization cannot have a nested name specifier}} \ // expected-note {{explicit instantiation refers here}} - template const int B4::right; // expected-error {{explicit instantiation of undefined static data member template 'right' of class}} - template const int B4::right_def; // expected-error {{explicit instantiation of undefined static data member template 'right_def' of class}} + template CONST int B4::right; // expected-error {{explicit instantiation of undefined static data member template 'right' of class}} + template CONST int B4::right_def; // expected-error {{explicit instantiation of undefined static data member template 'right_def' of class}} } namespace non_const_init { @@ -80,19 +82,19 @@ namespace non_const_init { template int B::wrong_inst_fixed; class C { - template static const T right_inst = T(10); - template static const T right_inst = T(100); + template static CONST T right_inst = T(10); + template static CONST T right_inst = T(100); }; - template const int C::right_inst; - template const int C::right_inst; + template CONST int C::right_inst; + template CONST int C::right_inst; namespace pointers { struct C0 { template static U Data; - template static const U Data = U(); // Okay + template static CONST U Data = U(); // Okay }; - template const int C0::Data; + template CONST int C0::Data; struct C1a { template static U Data; @@ -103,10 +105,10 @@ namespace non_const_init { struct C1b { template static U Data; - template static const U* Data; // Okay, with out-of-line definition + template static CONST U* Data; // Okay, with out-of-line definition }; - template const T* C1b::Data = (T*)(0); - template const int* C1b::Data; + template CONST T* C1b::Data = (T*)(0); + template CONST int* C1b::Data; struct C2a { template static U Data; @@ -116,9 +118,9 @@ namespace non_const_init { struct C2b { // FIXME: ?!? Should this be an error? pointer-types are automatically non-const? template static U Data; - template static const U* Data = (U*)(0); // expected-error {{non-const static data member must be initialized out of line}} + template static CONST U* Data = (U*)(0); // expected-error {{non-const static data member must be initialized out of line}} }; - template const int* C2b::Data; // expected-note {{in instantiation of static data member 'non_const_init::pointers::C2b::Data' requested here}} + template CONST int* C2b::Data; // expected-note {{in instantiation of static data member 'non_const_init::pointers::C2b::Data' requested here}} } } @@ -131,9 +133,9 @@ namespace in_class_template { template class D0 { template static U Data; - template static const U Data = U(); + template static CONST U Data = U(); }; - template const int D0::Data; + template CONST int D0::Data; template class D1 { @@ -152,27 +154,27 @@ namespace in_class_template { template<> template U* D2::Data = (U*)(0) + 1; template int* D1::Data; - + template struct D3 { - template static const U Data = U(100); + template static CONST U Data = U(100); }; - template const int D3::Data; + template CONST int D3::Data; #ifndef PRECXX11 static_assert(D3::Data == 100, ""); #endif namespace bug_files { - // FIXME: A bug has been filed addressing an issue similar to these. + // FIXME: A bug has been filed addressing an issue similar to these. // No error diagnosis should be produced, because an - // explicit specialization of a member templates of class - // template specialization should not inherit the partial + // explicit specialization of a member templates of class + // template specialization should not inherit the partial // specializations from the class template specialization. template class D0 { template static U Data; - template static const U Data = U(10); // expected-note {{previous definition is here}} + template static CONST U Data = U(10); // expected-note {{previous definition is here}} }; template<> template U D0::Data = U(100); // expected-error{{redefinition of 'Data'}} diff --git a/test/SemaCXX/cxx1y-variable-templates_top_level.cpp b/test/SemaCXX/cxx1y-variable-templates_top_level.cpp index 61fccac038..49be0bdcbe 100644 --- a/test/SemaCXX/cxx1y-variable-templates_top_level.cpp +++ b/test/SemaCXX/cxx1y-variable-templates_top_level.cpp @@ -1,11 +1,11 @@ -// RUN: %clang_cc1 -verify -fsyntax-only -Wno-c++11-extensions -Wno-c++1y-extensions %s -// RUN: %clang_cc1 -std=c++11 -verify -fsyntax-only -Wno-c++1y-extensions %s -DCXX11 -// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only %s -DCXX11 +// RUN: %clang_cc1 -verify -fsyntax-only -Wno-c++11-extensions -Wno-c++1y-extensions %s -DPRECXX11 +// RUN: %clang_cc1 -std=c++11 -verify -fsyntax-only -Wno-c++1y-extensions %s +// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only %s -#ifdef CXX11 - #define CONST constexpr -#else +#ifdef PRECXX11 #define CONST const +#else + #define CONST constexpr #endif template @@ -15,7 +15,7 @@ template CONST T cpi = T(3.1415926535897932385); // expected-note {{template is declared here}} template extern CONST T vc; -#ifdef CXX11 +#ifndef PRECXX11 // expected-error@-2 {{constexpr variable declaration must be a definition}} #endif @@ -46,7 +46,7 @@ namespace use_in_top_level_funcs { double use_circular_area(double r) { CONST float t = const_circular_area(2.0) - 12; -#ifdef CXX11 +#ifndef PRECXX11 static_assert(const_circular_area(2) == 12, ""); CONST int test = (t > 0) && (t < 1); static_assert(test, ""); @@ -104,7 +104,7 @@ namespace odr_tmpl { // expected-note {{previous definition is here}} template extern int v; // expected-error {{redefinition of 'v' with a different type: 'int' vs 'T'}} -#ifdef CXX11 +#ifndef PRECXX11 template extern auto v; // expected-error {{declaration of variable 'v' with type 'auto' requires an initializer}} #endif @@ -112,7 +112,7 @@ namespace odr_tmpl { extern int var; // expected-error {{redefinition of 'var' as different kind of symbol}} } -#ifdef CXX11 +#ifndef PRECXX11 namespace pvt_auto { template auto v0; // expected-error {{declaration of variable 'v0' with type 'auto' requires an initializer}} template auto v1 = T(); // expected-note {{previous definition is here}} @@ -159,7 +159,7 @@ namespace explicit_instantiation { template CONST int pi1; // expected-note {{previous explicit instantiation is here}} template CONST int pi1; // expected-error {{duplicate explicit instantiation of 'pi1'}} -#ifdef CXX11 +#ifndef PRECXX11 namespace auto_var { template auto var0 = T(); template auto var0; // expected-error {{'auto' variable template instantiation is not allowed}} @@ -188,7 +188,7 @@ namespace explicit_specialization { template<> CONST int pi2 = 4; -#ifdef CXX11 +#ifndef PRECXX11 void foo() { static_assert(pi2 == 4, ""); static_assert(pi2 == 2, ""); @@ -242,13 +242,13 @@ namespace explicit_specialization { T pi0 = T(3.1415926535897932385); template<> int pi0 = 10; // expected-note 3{{previous definition is here}} -#ifdef CXX11 +#ifndef PRECXX11 // expected-note@-2 {{previous definition is here}} #endif template<> int pi0 = 10; // expected-error {{redefinition of 'pi0'}} template<> CONST int pi0 = 10; // expected-error {{redefinition of 'pi0' with a different type: 'const int' vs 'int'}} template<> float pi0 = 10; // expected-error {{redefinition of 'pi0' with a different type: 'float' vs 'int'}} -#ifdef CXX11 +#ifndef PRECXX11 template<> auto pi0 = 10; // expected-error {{redefinition of 'pi0'}} #endif @@ -289,7 +289,7 @@ namespace explicit_specialization { template CONST int pi2 = 2; } -#ifdef CXX11 +#ifndef PRECXX11 namespace auto_var { template auto var0 = T(); template auto var0 = T(); @@ -314,7 +314,7 @@ namespace explicit_specialization { // TODO: template T var = T(); template T* var = new T(); -#ifdef CXX11 +#ifndef PRECXX11 template auto var = T(); // expected-note {{previous definition is here}} template T var = T(); // expected-error {{redefinition of 'var' with a different type: 'T' vs 'auto'}} #endif @@ -323,7 +323,7 @@ namespace explicit_specialization { namespace narrowing { template T v = {1234}; // expected-warning {{implicit conversion from 'int' to 'char' changes value from 1234 to}} -#ifdef CXX11 +#ifndef PRECXX11 // expected-error@-2 {{constant expression evaluates to 1234 which cannot be narrowed to type 'char'}}\ // expected-note@-2 {{override this message by inserting an explicit cast}} #endif @@ -338,7 +338,7 @@ namespace attributes { // TODO: } -#ifdef CXX11 +#ifndef PRECXX11 namespace arrays { template T* arr = new T[10]{T(10), T(23)}; @@ -390,13 +390,13 @@ namespace nested { namespace n1 { template T pi1a = T(3.1415926535897932385); -#ifdef CXX11 +#ifndef PRECXX11 // expected-note@-2 {{explicit instantiation refers here}} #endif template T pi1b = T(3.1415926535897932385); // expected-note {{explicitly specialized declaration is here}} -#ifdef CXX11 +#ifndef PRECXX11 // expected-note@-2 {{explicit instantiation refers here}} #endif } @@ -406,7 +406,7 @@ namespace nested { int i1 = pi1a; template float pi1a; -#ifdef CXX11 +#ifndef PRECXX11 // expected-error@-2 {{explicit instantiation of 'pi1a' not in a namespace enclosing 'n1'}} #endif float f1 = pi1a; @@ -419,7 +419,7 @@ namespace nested { int i1 = n1::pi1b; template float n1::pi1b; -#ifdef CXX11 +#ifndef PRECXX11 // expected-error@-2 {{explicit instantiation of 'pi1b' not in a namespace enclosing 'n1'}} #endif float f1 = n1::pi1b;