@@ -7494,89 +7494,16 @@ NamedDecl *Sema::ActOnVariableDeclarator(
74947494 NTCUC_AutoVar, NTCUK_Destruct);
74957495 } else {
74967496 bool Invalid = false;
7497-
7498- if (DC->isRecord() && !CurContext->isRecord()) {
7499- // This is an out-of-line definition of a static data member.
7500- switch (SC) {
7501- case SC_None:
7502- break;
7503- case SC_Static:
7504- Diag(D.getDeclSpec().getStorageClassSpecLoc(),
7505- diag::err_static_out_of_line)
7506- << FixItHint::CreateRemoval(D.getDeclSpec().getStorageClassSpecLoc());
7507- break;
7508- case SC_Auto:
7509- case SC_Register:
7510- case SC_Extern:
7511- // [dcl.stc] p2: The auto or register specifiers shall be applied only
7512- // to names of variables declared in a block or to function parameters.
7513- // [dcl.stc] p6: The extern specifier cannot be used in the declaration
7514- // of class members
7515-
7516- Diag(D.getDeclSpec().getStorageClassSpecLoc(),
7517- diag::err_storage_class_for_static_member)
7518- << FixItHint::CreateRemoval(D.getDeclSpec().getStorageClassSpecLoc());
7519- break;
7520- case SC_PrivateExtern:
7521- llvm_unreachable("C storage class in c++!");
7522- }
7523- }
7524-
7525- if (SC == SC_Static && CurContext->isRecord()) {
7526- if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(DC)) {
7527- // Walk up the enclosing DeclContexts to check for any that are
7528- // incompatible with static data members.
7529- const DeclContext *FunctionOrMethod = nullptr;
7530- const CXXRecordDecl *AnonStruct = nullptr;
7531- for (DeclContext *Ctxt = DC; Ctxt; Ctxt = Ctxt->getParent()) {
7532- if (Ctxt->isFunctionOrMethod()) {
7533- FunctionOrMethod = Ctxt;
7534- break;
7535- }
7536- const CXXRecordDecl *ParentDecl = dyn_cast<CXXRecordDecl>(Ctxt);
7537- if (ParentDecl && !ParentDecl->getDeclName()) {
7538- AnonStruct = ParentDecl;
7539- break;
7540- }
7541- }
7542- if (FunctionOrMethod) {
7543- // C++ [class.static.data]p5: A local class shall not have static data
7544- // members.
7545- Diag(D.getIdentifierLoc(),
7546- diag::err_static_data_member_not_allowed_in_local_class)
7547- << Name << RD->getDeclName()
7548- << llvm::to_underlying(RD->getTagKind());
7549- } else if (AnonStruct) {
7550- // C++ [class.static.data]p4: Unnamed classes and classes contained
7551- // directly or indirectly within unnamed classes shall not contain
7552- // static data members.
7553- Diag(D.getIdentifierLoc(),
7554- diag::err_static_data_member_not_allowed_in_anon_struct)
7555- << Name << llvm::to_underlying(AnonStruct->getTagKind());
7556- Invalid = true;
7557- } else if (RD->isUnion()) {
7558- // C++98 [class.union]p1: If a union contains a static data member,
7559- // the program is ill-formed. C++11 drops this restriction.
7560- Diag(D.getIdentifierLoc(),
7561- getLangOpts().CPlusPlus11
7562- ? diag::warn_cxx98_compat_static_data_member_in_union
7563- : diag::ext_static_data_member_in_union) << Name;
7564- }
7565- }
7566- }
7567-
75687497 // Match up the template parameter lists with the scope specifier, then
75697498 // determine whether we have a template or a template specialization.
7570- bool InvalidScope = false;
75717499 TemplateParams = MatchTemplateParametersToScopeSpecifier(
75727500 D.getDeclSpec().getBeginLoc(), D.getIdentifierLoc(),
75737501 D.getCXXScopeSpec(),
75747502 D.getName().getKind() == UnqualifiedIdKind::IK_TemplateId
75757503 ? D.getName().TemplateId
75767504 : nullptr,
75777505 TemplateParamLists,
7578- /*never a friend*/ false, IsMemberSpecialization, InvalidScope);
7579- Invalid |= InvalidScope;
7506+ /*never a friend*/ false, IsMemberSpecialization, Invalid);
75807507
75817508 if (TemplateParams) {
75827509 if (DC->isDependentContext()) {
@@ -7625,6 +7552,102 @@ NamedDecl *Sema::ActOnVariableDeclarator(
76257552 "should have a 'template<>' for this decl");
76267553 }
76277554
7555+ bool IsExplicitSpecialization =
7556+ IsVariableTemplateSpecialization && !IsPartialSpecialization;
7557+
7558+ // C++ [temp.expl.spec]p2:
7559+ // The declaration in an explicit-specialization shall not be an
7560+ // export-declaration. An explicit specialization shall not use a
7561+ // storage-class-specifier other than thread_local.
7562+ //
7563+ // We use the storage-class-specifier from DeclSpec because we may have
7564+ // added implicit 'extern' for declarations with __declspec(dllimport)!
7565+ if (SCSpec != DeclSpec::SCS_unspecified &&
7566+ (IsExplicitSpecialization || IsMemberSpecialization)) {
7567+ Diag(D.getDeclSpec().getStorageClassSpecLoc(),
7568+ diag::ext_explicit_specialization_storage_class)
7569+ << FixItHint::CreateRemoval(D.getDeclSpec().getStorageClassSpecLoc());
7570+ }
7571+
7572+ if (CurContext->isRecord()) {
7573+ if (SC == SC_Static) {
7574+ if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(DC)) {
7575+ // Walk up the enclosing DeclContexts to check for any that are
7576+ // incompatible with static data members.
7577+ const DeclContext *FunctionOrMethod = nullptr;
7578+ const CXXRecordDecl *AnonStruct = nullptr;
7579+ for (DeclContext *Ctxt = DC; Ctxt; Ctxt = Ctxt->getParent()) {
7580+ if (Ctxt->isFunctionOrMethod()) {
7581+ FunctionOrMethod = Ctxt;
7582+ break;
7583+ }
7584+ const CXXRecordDecl *ParentDecl = dyn_cast<CXXRecordDecl>(Ctxt);
7585+ if (ParentDecl && !ParentDecl->getDeclName()) {
7586+ AnonStruct = ParentDecl;
7587+ break;
7588+ }
7589+ }
7590+ if (FunctionOrMethod) {
7591+ // C++ [class.static.data]p5: A local class shall not have static
7592+ // data members.
7593+ Diag(D.getIdentifierLoc(),
7594+ diag::err_static_data_member_not_allowed_in_local_class)
7595+ << Name << RD->getDeclName()
7596+ << llvm::to_underlying(RD->getTagKind());
7597+ } else if (AnonStruct) {
7598+ // C++ [class.static.data]p4: Unnamed classes and classes contained
7599+ // directly or indirectly within unnamed classes shall not contain
7600+ // static data members.
7601+ Diag(D.getIdentifierLoc(),
7602+ diag::err_static_data_member_not_allowed_in_anon_struct)
7603+ << Name << llvm::to_underlying(AnonStruct->getTagKind());
7604+ Invalid = true;
7605+ } else if (RD->isUnion()) {
7606+ // C++98 [class.union]p1: If a union contains a static data member,
7607+ // the program is ill-formed. C++11 drops this restriction.
7608+ Diag(D.getIdentifierLoc(),
7609+ getLangOpts().CPlusPlus11
7610+ ? diag::warn_cxx98_compat_static_data_member_in_union
7611+ : diag::ext_static_data_member_in_union)
7612+ << Name;
7613+ }
7614+ }
7615+ } else if (IsVariableTemplate || IsPartialSpecialization) {
7616+ // There is no such thing as a member field template.
7617+ Diag(D.getIdentifierLoc(), diag::err_template_member)
7618+ << II << TemplateParams->getSourceRange();
7619+ // Recover by pretending this is a static data member template.
7620+ SC = SC_Static;
7621+ }
7622+ } else if (DC->isRecord()) {
7623+ // This is an out-of-line definition of a static data member.
7624+ switch (SC) {
7625+ case SC_None:
7626+ break;
7627+ case SC_Static:
7628+ Diag(D.getDeclSpec().getStorageClassSpecLoc(),
7629+ diag::err_static_out_of_line)
7630+ << FixItHint::CreateRemoval(
7631+ D.getDeclSpec().getStorageClassSpecLoc());
7632+ break;
7633+ case SC_Auto:
7634+ case SC_Register:
7635+ case SC_Extern:
7636+ // [dcl.stc] p2: The auto or register specifiers shall be applied only
7637+ // to names of variables declared in a block or to function parameters.
7638+ // [dcl.stc] p6: The extern specifier cannot be used in the declaration
7639+ // of class members
7640+
7641+ Diag(D.getDeclSpec().getStorageClassSpecLoc(),
7642+ diag::err_storage_class_for_static_member)
7643+ << FixItHint::CreateRemoval(
7644+ D.getDeclSpec().getStorageClassSpecLoc());
7645+ break;
7646+ case SC_PrivateExtern:
7647+ llvm_unreachable("C storage class in c++!");
7648+ }
7649+ }
7650+
76287651 if (IsVariableTemplateSpecialization) {
76297652 SourceLocation TemplateKWLoc =
76307653 TemplateParamLists.size() > 0
@@ -7670,8 +7693,6 @@ NamedDecl *Sema::ActOnVariableDeclarator(
76707693 // the variable (matching the scope specifier), store them.
76717694 // An explicit variable template specialization does not own any template
76727695 // parameter lists.
7673- bool IsExplicitSpecialization =
7674- IsVariableTemplateSpecialization && !IsPartialSpecialization;
76757696 unsigned VDTemplateParamLists =
76767697 (TemplateParams && !IsExplicitSpecialization) ? 1 : 0;
76777698 if (TemplateParamLists.size() > VDTemplateParamLists)
@@ -10073,25 +10094,45 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
1007310094 NewFD->setImplicitlyInline(ImplicitInlineCXX20);
1007410095 }
1007510096
10076- if (SC == SC_Static && isa<CXXMethodDecl>(NewFD) &&
10077- !CurContext->isRecord()) {
10078- // C++ [class.static]p1:
10079- // A data or function member of a class may be declared static
10080- // in a class definition, in which case it is a static member of
10081- // the class.
10097+ if (!isFriend && SC != SC_None) {
10098+ // C++ [temp.expl.spec]p2:
10099+ // The declaration in an explicit-specialization shall not be an
10100+ // export-declaration. An explicit specialization shall not use a
10101+ // storage-class-specifier other than thread_local.
10102+ //
10103+ // We diagnose friend declarations with storage-class-specifiers
10104+ // elsewhere.
10105+ if (isFunctionTemplateSpecialization || isMemberSpecialization) {
10106+ Diag(D.getDeclSpec().getStorageClassSpecLoc(),
10107+ diag::ext_explicit_specialization_storage_class)
10108+ << FixItHint::CreateRemoval(
10109+ D.getDeclSpec().getStorageClassSpecLoc());
10110+ }
1008210111
10083- // Complain about the 'static' specifier if it's on an out-of-line
10084- // member function definition.
10112+ if (SC == SC_Static && !CurContext->isRecord() && DC->isRecord()) {
10113+ assert(isa<CXXMethodDecl>(NewFD) &&
10114+ "Out-of-line member function should be a CXXMethodDecl");
10115+ // C++ [class.static]p1:
10116+ // A data or function member of a class may be declared static
10117+ // in a class definition, in which case it is a static member of
10118+ // the class.
1008510119
10086- // MSVC permits the use of a 'static' storage specifier on an out-of-line
10087- // member function template declaration and class member template
10088- // declaration (MSVC versions before 2015), warn about this.
10089- Diag(D.getDeclSpec().getStorageClassSpecLoc(),
10090- ((!getLangOpts().isCompatibleWithMSVC(LangOptions::MSVC2015) &&
10091- cast<CXXRecordDecl>(DC)->getDescribedClassTemplate()) ||
10092- (getLangOpts().MSVCCompat && NewFD->getDescribedFunctionTemplate()))
10093- ? diag::ext_static_out_of_line : diag::err_static_out_of_line)
10094- << FixItHint::CreateRemoval(D.getDeclSpec().getStorageClassSpecLoc());
10120+ // Complain about the 'static' specifier if it's on an out-of-line
10121+ // member function definition.
10122+
10123+ // MSVC permits the use of a 'static' storage specifier on an
10124+ // out-of-line member function template declaration and class member
10125+ // template declaration (MSVC versions before 2015), warn about this.
10126+ Diag(D.getDeclSpec().getStorageClassSpecLoc(),
10127+ ((!getLangOpts().isCompatibleWithMSVC(LangOptions::MSVC2015) &&
10128+ cast<CXXRecordDecl>(DC)->getDescribedClassTemplate()) ||
10129+ (getLangOpts().MSVCCompat &&
10130+ NewFD->getDescribedFunctionTemplate()))
10131+ ? diag::ext_static_out_of_line
10132+ : diag::err_static_out_of_line)
10133+ << FixItHint::CreateRemoval(
10134+ D.getDeclSpec().getStorageClassSpecLoc());
10135+ }
1009510136 }
1009610137
1009710138 // C++11 [except.spec]p15:
@@ -10459,27 +10500,6 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
1045910500 Previous))
1046010501 NewFD->setInvalidDecl();
1046110502 }
10462-
10463- // C++ [dcl.stc]p1:
10464- // A storage-class-specifier shall not be specified in an explicit
10465- // specialization (14.7.3)
10466- // FIXME: We should be checking this for dependent specializations.
10467- FunctionTemplateSpecializationInfo *Info =
10468- NewFD->getTemplateSpecializationInfo();
10469- if (Info && SC != SC_None) {
10470- if (SC != Info->getTemplate()->getTemplatedDecl()->getStorageClass())
10471- Diag(NewFD->getLocation(),
10472- diag::err_explicit_specialization_inconsistent_storage_class)
10473- << SC
10474- << FixItHint::CreateRemoval(
10475- D.getDeclSpec().getStorageClassSpecLoc());
10476-
10477- else
10478- Diag(NewFD->getLocation(),
10479- diag::ext_explicit_specialization_storage_class)
10480- << FixItHint::CreateRemoval(
10481- D.getDeclSpec().getStorageClassSpecLoc());
10482- }
1048310503 } else if (isMemberSpecialization && !FunctionTemplate) {
1048410504 if (CheckMemberSpecialization(NewFD, Previous))
1048510505 NewFD->setInvalidDecl();
0 commit comments