r298410 - Correct class-template deprecation behavior
Keane, Erich via cfe-commits
cfe-commits at lists.llvm.org
Tue Mar 21 13:28:22 PDT 2017
Ended up being simpler than I expected. I added -r298433 To fix this.
The issue is that the test had a conditional based on the "C" version, so I explicitly added a test for C89 and C99, which the PS4 is apparently not defaulting to.
Thanks!
-Erich
-----Original Message-----
From: Yung, Douglas [mailto:douglas.yung at sony.com]
Sent: Tuesday, March 21, 2017 12:59 PM
To: Keane, Erich <erich.keane at intel.com>
Cc: cfe-commits <cfe-commits at lists.llvm.org>
Subject: RE: r298410 - Correct class-template deprecation behavior
Hi Erich,
Your change is causing the Sema/attr-deprecated.c test to fail on the PS4 bot (http://lab.llvm.org:8011/builders/llvm-clang-lld-x86_64-scei-ps4-windows10pro-fast/builds/7087). Can you take a look?
Douglas Yung
> -----Original Message-----
> From: cfe-commits [mailto:cfe-commits-bounces at lists.llvm.org] On
> Behalf Of Erich Keane via cfe-commits
> Sent: Tuesday, March 21, 2017 10:49
> To: cfe-commits at lists.llvm.org
> Subject: r298410 - Correct class-template deprecation behavior
>
> Author: erichkeane
> Date: Tue Mar 21 12:49:17 2017
> New Revision: 298410
>
> URL: http://llvm.org/viewvc/llvm-project?rev=298410&view=rev
> Log:
> Correct class-template deprecation behavior
>
> Based on the comment in the test, and my reading of the standard, a
> deprecated warning should be issued in the following case:
> template<typename T> [[deprecated]] class Foo{}; Foo<int> f;
>
> This was not the case, because the ClassTemplateSpecializationDecl
> creation did not also copy the deprecated attribute.
>
> Note: I did NOT audit the complete set of attributes to see WHICH ones
> should be copied, so instead I simply copy ONLY the deprecated attribute.
>
> Differential Revision: https://reviews.llvm.org/D27486
>
> Modified:
> cfe/trunk/include/clang/Basic/Attr.td
> cfe/trunk/include/clang/Sema/Sema.h
> cfe/trunk/lib/Sema/SemaDeclAttr.cpp
> cfe/trunk/lib/Sema/SemaTemplate.cpp
> cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
> cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
> cfe/trunk/test/CXX/dcl.dcl/dcl.attr/dcl.attr.deprecated/p1.cpp
> cfe/trunk/test/Sema/attr-deprecated.c
> cfe/trunk/test/SemaCXX/attr-deprecated.cpp
> cfe/trunk/test/SemaObjC/attr-deprecated.m
> cfe/trunk/test/SemaObjC/special-dep-unavail-warning.m
> cfe/trunk/test/SemaObjC/warn-deprecated-implementations.m
> cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp
>
> Modified: cfe/trunk/include/clang/Basic/Attr.td
> URL: http://llvm.org/viewvc/llvm-
> project/cfe/trunk/include/clang/Basic/Attr.td?rev=298410&r1=298409&r2=
> 298410&v
> iew=diff
> ======================================================================
> ========
> --- cfe/trunk/include/clang/Basic/Attr.td (original)
> +++ cfe/trunk/include/clang/Basic/Attr.td Tue Mar 21 12:49:17 2017
> @@ -302,6 +302,9 @@ class Attr {
> // Set to true if this attribute can be duplicated on a subject
> when merging
> // attributes. By default, attributes are not merged.
> bit DuplicatesAllowedWhileMerging = 0;
> + // Set to true if this attribute is meaningful when applied to or
> + inherited // in a class template definition.
> + bit MeaningfulToClassTemplateDefinition = 0;
> // Lists language options, one of which is required to be true for the
> // attribute to be applicable. If empty, no language options are required.
> list<LangOpt> LangOpts = [];
> @@ -373,6 +376,7 @@ def AbiTag : Attr {
> let Args = [VariadicStringArgument<"Tags">];
> let Subjects = SubjectList<[Struct, Var, Function, Namespace], ErrorDiag,
> "ExpectedStructClassVariableFunctionOrInlineNamespace">;
> + let MeaningfulToClassTemplateDefinition = 1;
> let Documentation = [AbiTagsDocs];
> }
>
> @@ -805,6 +809,7 @@ def Deprecated : InheritableAttr {
> // An optional string argument that enables us to provide a
> // Fix-It.
> StringArgument<"Replacement", 1>];
> + let MeaningfulToClassTemplateDefinition = 1;
> let Documentation = [DeprecatedDocs]; }
>
> @@ -1723,6 +1728,7 @@ def Visibility : InheritableAttr {
> let Args = [EnumArgument<"Visibility", "VisibilityType",
> ["default", "hidden", "internal", "protected"],
> ["Default", "Hidden", "Hidden",
> "Protected"]>];
> + let MeaningfulToClassTemplateDefinition = 1;
> let Documentation = [Undocumented]; }
>
>
> Modified: cfe/trunk/include/clang/Sema/Sema.h
> URL: http://llvm.org/viewvc/llvm-
> project/cfe/trunk/include/clang/Sema/Sema.h?rev=298410&r1=298409&r2=29
> 8410&vie
> w=diff
> ======================================================================
> ========
> --- cfe/trunk/include/clang/Sema/Sema.h (original)
> +++ cfe/trunk/include/clang/Sema/Sema.h Tue Mar 21 12:49:17 2017
> @@ -7505,6 +7505,12 @@ public:
> LateInstantiatedAttrVec *LateAttrs = nullptr,
> LocalInstantiationScope *OuterMostScope =
> nullptr);
>
> + void
> + InstantiateAttrsForDecl(const MultiLevelTemplateArgumentList &TemplateArgs,
> + const Decl *Pattern, Decl *Inst,
> + LateInstantiatedAttrVec *LateAttrs = nullptr,
> + LocalInstantiationScope *OuterMostScope =
> + nullptr);
> +
> bool
> InstantiateClassTemplateSpecialization(SourceLocation PointOfInstantiation,
> ClassTemplateSpecializationDecl
> *ClassTemplateSpec,
>
> Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
> URL: http://llvm.org/viewvc/llvm-
> project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=298410&r1=298409&r2=29
> 8410&vie
> w=diff
> ======================================================================
> ========
> --- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Tue Mar 21 12:49:17 2017
> @@ -6723,6 +6723,7 @@ static void DoEmitAvailabilityWarning(Se
> // Diagnostics for deprecated or unavailable.
> unsigned diag, diag_message, diag_fwdclass_message;
> unsigned diag_available_here =
> diag::note_availability_specified_here;
> + SourceLocation NoteLocation = D->getLocation();
>
> // Matches 'diag::note_property_attribute' options.
> unsigned property_note_select;
> @@ -6745,6 +6746,8 @@ static void DoEmitAvailabilityWarning(Se
> diag_fwdclass_message = diag::warn_deprecated_fwdclass_message;
> property_note_select = /* deprecated */ 0;
> available_here_select_kind = /* deprecated */ 2;
> + if (auto *attr = D->getAttr<DeprecatedAttr>())
> + NoteLocation = attr->getLocation();
> break;
>
> case AR_Unavailable:
> @@ -6863,7 +6866,7 @@ static void DoEmitAvailabilityWarning(Se
> }
> }
> else
> - S.Diag(D->getLocation(), diag_available_here)
> + S.Diag(NoteLocation, diag_available_here)
> << D << available_here_select_kind;
>
> if (K == AR_NotYetIntroduced)
>
> Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
> URL: http://llvm.org/viewvc/llvm-
> project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=298410&r1=298409&r2=29
> 8410&vie
> w=diff
> ======================================================================
> ========
> --- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaTemplate.cpp Tue Mar 21 12:49:17 2017
> @@ -2846,6 +2846,13 @@ QualType Sema::CheckTemplateIdType(Templ
> Decl->setLexicalDeclContext(ClassTemplate->getLexicalDeclContext());
> }
>
> + if (Decl->getSpecializationKind() == TSK_Undeclared) {
> + MultiLevelTemplateArgumentList TemplateArgLists;
> + TemplateArgLists.addOuterTemplateArguments(Converted);
> + InstantiateAttrsForDecl(TemplateArgLists, ClassTemplate-
> >getTemplatedDecl(),
> + Decl);
> + }
> +
> // Diagnose uses of this specialization.
> (void)DiagnoseUseOfDecl(Decl, TemplateLoc);
>
>
> Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
> URL: http://llvm.org/viewvc/llvm-
> project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=298410&r1=2
> 98409&r2
> =298410&view=diff
> ======================================================================
> ========
> --- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Tue Mar 21 12:49:17
> +++ 2017
> @@ -1939,6 +1939,9 @@ namespace clang {
> namespace sema {
> Attr *instantiateTemplateAttribute(const Attr *At, ASTContext &C,
> Sema &S,
> const MultiLevelTemplateArgumentList
> &TemplateArgs);
> + Attr *instantiateTemplateAttributeForDecl(
> + const Attr *At, ASTContext &C, Sema &S,
> + const MultiLevelTemplateArgumentList &TemplateArgs);
> }
> }
>
>
> Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
> URL: http://llvm.org/viewvc/llvm-
> project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=298410&
> r1=29840
> 9&r2=298410&view=diff
> ======================================================================
> ========
> --- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Tue Mar 21
> +++ 12:49:17 2017
> @@ -328,6 +328,35 @@ static void instantiateOMPDeclareSimdDec
> Attr.getRange());
> }
>
> +bool DeclContainsAttr(Decl* D, attr::Kind K) {
> + if (!D->hasAttrs())
> + return false;
> + for (auto&& attr : D->getAttrs())
> + if (attr->getKind() == K)
> + return true;
> + return false;
> +}
> +
> +void Sema::InstantiateAttrsForDecl(
> + const MultiLevelTemplateArgumentList &TemplateArgs, const Decl *Tmpl,
> + Decl *New, LateInstantiatedAttrVec *LateAttrs,
> + LocalInstantiationScope *OuterMostScope) {
> + if (NamedDecl *ND = dyn_cast<NamedDecl>(New)) {
> + for (const auto *TmplAttr : Tmpl->attrs()) {
> + // FIXME: If any of the special case versions from
> +InstantiateAttrs
> become
> + // applicable to template declaration, we'll need to add them here.
> + CXXThisScopeRAII ThisScope(
> + *this, dyn_cast_or_null<CXXRecordDecl>(ND->getDeclContext()),
> + /*TypeQuals*/ 0, ND->isCXXInstanceMember());
> +
> + Attr *NewAttr = sema::instantiateTemplateAttributeForDecl(
> + TmplAttr, Context, *this, TemplateArgs);
> + if (NewAttr && !DeclContainsAttr(New, NewAttr->getKind()))
> + New->addAttr(NewAttr);
> + }
> + }
> +}
> +
> void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList
> &TemplateArgs,
> const Decl *Tmpl, Decl *New,
> LateInstantiatedAttrVec *LateAttrs, @@
> -421,7
> +450,8 @@ void Sema::InstantiateAttrs(const MultiL
>
> Attr *NewAttr = sema::instantiateTemplateAttribute(TmplAttr, Context,
> *this,
> TemplateArgs);
> - if (NewAttr)
> +
> + if (NewAttr && !DeclContainsAttr(New, NewAttr->getKind()))
> New->addAttr(NewAttr);
> }
> }
>
> Modified:
> cfe/trunk/test/CXX/dcl.dcl/dcl.attr/dcl.attr.deprecated/p1.cpp
> URL: http://llvm.org/viewvc/llvm-
> project/cfe/trunk/test/CXX/dcl.dcl/dcl.attr/dcl.attr.deprecated/p1.cpp
> ?rev=298
> 410&r1=298409&r2=298410&view=diff
> ======================================================================
> ========
> --- cfe/trunk/test/CXX/dcl.dcl/dcl.attr/dcl.attr.deprecated/p1.cpp
> (original)
> +++ cfe/trunk/test/CXX/dcl.dcl/dcl.attr/dcl.attr.deprecated/p1.cpp Tue
> +++ Mar 21 12:49:17 2017
> @@ -23,7 +23,38 @@ template <> class [[deprecated]] X<int> X<char>
> x1; X<int> x2; // expected-warning {{'X<int>' is deprecated}}
>
> -template <typename T> class [[deprecated]] X2 {};
> +template <typename T> class [[deprecated]] X2 {}; //expected-note
> +{{'X2<char>' has been explicitly marked deprecated here}}
> template <> class X2<int> {};
> -X2<char> x3; // FIXME: no warning!
> -X2<int> x4;
> +X2<char> x3; // expected-warning {{'X2<char>' is deprecated}} X2<int>
> +x4; // No warning, the specialization removes it.
> +
> +template <typename T> class [[deprecated]] X3; //expected-note
> +{{'X3<char>' has been explicitly marked deprecated here}} template <>
> +class X3<int>; X3<char> *x5; // expected-warning {{'X3<char>' is
> +deprecated}} X3<int> *x6; // No warning, the specialization removes it.
> +
> +template <typename T> struct A;
> +A<int> *p;
> +template <typename T> struct [[deprecated]] A;//expected-note
> +{{'A<int>' has been explicitly marked deprecated here}} expected-note
> +{{'A<float>' has been explicitly marked deprecated here}} A<int> *q;
> +// expected-warning {{'A<int>' is deprecated}} A<float> *r; //
> +expected-warning {{'A<float>' is deprecated}}
> +
> +template <typename T> struct B;
> +B<int> *p2;
> +template <typename T> struct [[deprecated]] B;//expected-note
> +{{'B<int>' has been explicitly marked deprecated here}} expected-note
> +{{'B<float>' has been explicitly marked deprecated here}} B<int> *q2;
> +// expected-warning {{'B<int>' is deprecated}} B<float> *r2; //
> +expected-warning {{'B<float>' is deprecated}}
> +
> +template <typename T>
> +T some_func(T t) {
> + struct [[deprecated]] FunS{}; // expected-note {{'FunS' has been
> +explicitly marked deprecated here}}
> + FunS f;// expected-warning {{'FunS' is deprecated}}
> +
> +}
> +
> +template <typename T>
> +[[deprecated]]T some_func2(T t) {
> + struct FunS2{};
> + FunS2 f;// No warning, entire function is deprecated, so usage here
> +should
> be fine.
> +
> +}
>
> Modified: cfe/trunk/test/Sema/attr-deprecated.c
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/attr-
> deprecated.c?rev=298410&r1=298409&r2=298410&view=diff
> ======================================================================
> ========
> --- cfe/trunk/test/Sema/attr-deprecated.c (original)
> +++ cfe/trunk/test/Sema/attr-deprecated.c Tue Mar 21 12:49:17 2017
> @@ -1,10 +1,10 @@
> // RUN: %clang_cc1 %s -verify -fsyntax-only
>
> int f() __attribute__((deprecated)); // expected-note 2 {{'f' has
> been explicitly marked deprecated here}} -void g()
> __attribute__((deprecated)); - void g(); // expected-note {{'g' has
> been explicitly marked deprecated here}}
> +void g() __attribute__((deprecated));// expected-note {{'g' has been
> +explicitly marked deprecated here}} void g();
>
> -extern int var __attribute__((deprecated)); // expected-note {{'var'
> has been explicitly marked deprecated here}}
> +extern int var __attribute__((deprecated)); // expected-note 2 {{'var'
> +has been explicitly marked deprecated here}}
>
> int a() {
> int (*ptr)() = f; // expected-warning {{'f' is deprecated}} @@
> -17,13
> +17,13 @@ int a() { }
>
> // test if attributes propagate to variables -extern int var; //
> expected- note {{'var' has been explicitly marked deprecated here}}
> +extern int var;
> int w() {
> return var; // expected-warning {{'var' is deprecated}} }
>
> -int old_fn() __attribute__ ((deprecated)); -int old_fn(); //
> expected-note {{'old_fn' has been explicitly marked deprecated here}}
> +int old_fn() __attribute__ ((deprecated));// expected-note {{'old_fn'
> +has been explicitly marked deprecated here}} int old_fn();
> int (*fn_ptr)() = old_fn; // expected-warning {{'old_fn' is
> deprecated}}
>
> int old_fn() {
> @@ -44,8 +44,8 @@ void test1(struct foo *F) { typedef struct foo
> foo_dep __attribute__((deprecated)); // expected-note 12 {{'foo_dep'
> has been explicitly marked deprecated here}}
> foo_dep *test2; // expected-warning {{'foo_dep' is deprecated}}
>
> -struct __attribute__((deprecated,
> - invalid_attribute)) bar_dep ; // expected-warning
> {{unknown attribute 'invalid_attribute' ignored}} expected-note 2 {{'bar_dep'
> has been explicitly marked deprecated here}}
> +struct __attribute__((deprecated, // expected-note 2 {{'bar_dep' has
> +been
> explicitly marked deprecated here}}
> + invalid_attribute)) bar_dep ; //
> +expected-warning {{unknown attribute 'invalid_attribute' ignored}}
>
> struct bar_dep *test3; // expected-warning {{'bar_dep' is deprecated}}
>
> @@ -121,11 +121,11 @@ struct test22 {
> __attribute((deprecated)) foo_dep e, f; };
>
> -typedef int test23_ty __attribute((deprecated));
> +typedef int test23_ty __attribute((deprecated)); // expected-note
> +{{'test23_ty' has been explicitly marked deprecated here}}
> // Redefining a typedef is a C11 feature.
> #if __STDC_VERSION__ <= 199901L
> // expected-note at -3 {{'test23_ty' has been explicitly marked
> deprecated here}} #else -typedef int test23_ty; // expected-note
> {{'test23_ty' has been explicitly marked deprecated here}}
> +typedef int test23_ty;
> #endif
> test23_ty test23_v; // expected-warning {{'test23_ty' is deprecated}}
>
> Modified: cfe/trunk/test/SemaCXX/attr-deprecated.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/attr-
> deprecated.cpp?rev=298410&r1=298409&r2=298410&view=diff
> ======================================================================
> ========
> --- cfe/trunk/test/SemaCXX/attr-deprecated.cpp (original)
> +++ cfe/trunk/test/SemaCXX/attr-deprecated.cpp Tue Mar 21 12:49:17
> +++ 2017
> @@ -56,14 +56,14 @@ void f(B* b, C *c) { }
>
> struct D {
> - virtual void f() __attribute__((deprecated));
> - virtual void f(int) __attribute__((deprecated));
> - virtual void f(int, int) __attribute__((deprecated));
> + virtual void f() __attribute__((deprecated));// expected-note{{'f'
> + has been explicitly marked deprecated here}} virtual void f(int)
> + __attribute__((deprecated));// expected-note{{'f' has been
> + explicitly marked deprecated here}} virtual void f(int, int)
> + __attribute__((deprecated));// expected-note{{'f' has been
> + explicitly marked deprecated here}}
> };
>
> -void D::f() { } // expected-note{{'f' has been explicitly marked
> deprecated here}} -void D::f(int v) { } // expected-note{{'f' has been
> explicitly marked deprecated here}} -void D::f(int v1, int v2) { } //
> expected-note{{'f' has been explicitly marked deprecated here}}
> +void D::f() { }
> +void D::f(int v) { }
> +void D::f(int v1, int v2) { }
>
> void f(D* d) {
> d->f(); // expected-warning{{'f' is deprecated}}
>
> Modified: cfe/trunk/test/SemaObjC/attr-deprecated.m
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/attr-
> deprecated.m?rev=298410&r1=298409&r2=298410&view=diff
> ======================================================================
> ========
> --- cfe/trunk/test/SemaObjC/attr-deprecated.m (original)
> +++ cfe/trunk/test/SemaObjC/attr-deprecated.m Tue Mar 21 12:49:17 2017
> @@ -83,8 +83,8 @@ int t5() {
> }
>
>
> -__attribute ((deprecated))
> - at interface DEPRECATED { // expected-note 2 {{'DEPRECATED' has been
> explicitly marked deprecated here}}
> +__attribute ((deprecated)) // expected-note 2 {{'DEPRECATED' has been
> +explicitly marked deprecated here}} @interface DEPRECATED {
> @public int ivar;
> DEPRECATED *ivar2; // no warning.
> }
>
> Modified: cfe/trunk/test/SemaObjC/special-dep-unavail-warning.m
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/special-de
> p- unavail-warning.m?rev=298410&r1=298409&r2=298410&view=diff
> ======================================================================
> ========
> --- cfe/trunk/test/SemaObjC/special-dep-unavail-warning.m (original)
> +++ cfe/trunk/test/SemaObjC/special-dep-unavail-warning.m Tue Mar 21
> +++ 12:49:17 2017
> @@ -44,8 +44,8 @@ void test(C *c) {
> }
>
> // rdar://10268422
> -__attribute ((deprecated))
> - at interface DEPRECATED // expected-note {{'DEPRECATED' has been
> explicitly marked deprecated here}}
> +__attribute ((deprecated)) // expected-note {{'DEPRECATED' has been
> +explicitly marked deprecated here}} @interface DEPRECATED
> +(id)new;
> @end
>
>
> Modified: cfe/trunk/test/SemaObjC/warn-deprecated-implementations.m
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/warn-
> deprecated-implementations.m?rev=298410&r1=298409&r2=298410&view=diff
> ======================================================================
> ========
> --- cfe/trunk/test/SemaObjC/warn-deprecated-implementations.m
> (original)
> +++ cfe/trunk/test/SemaObjC/warn-deprecated-implementations.m Tue Mar
> +++ 21
> +++ 12:49:17 2017
> @@ -28,8 +28,8 @@
> - (void) G {} // No warning, implementing its own deprecated method
> @end
>
> -__attribute__((deprecated))
> - at interface CL // expected-note 2 {{class declared here}} //
> expected-note 2 {{'CL' has been explicitly marked deprecated here}}
> +__attribute__((deprecated)) // expected-note 2 {{'CL' has been
> +explicitly marked deprecated here}} @interface CL // expected-note 2
> +{{class declared here}}
> @end
>
> @implementation CL // expected-warning {{Implementing deprecated
> class}}
>
> Modified: cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp
> URL: http://llvm.org/viewvc/llvm-
> project/cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp?rev=298410&r1=29
> 8409&r2=
> 298410&view=diff
> ======================================================================
> ========
> --- cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp (original)
> +++ cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp Tue Mar 21 12:49:17
> +++ 2017
> @@ -2451,26 +2451,19 @@ void EmitClangAttrASTVisitor(RecordKeepe
> OS << "#endif // ATTR_VISITOR_DECLS_ONLY\n"; }
>
> -// Emits code to instantiate dependent attributes on templates.
> -void EmitClangAttrTemplateInstantiate(RecordKeeper &Records,
> raw_ostream &OS) {
> - emitSourceFileHeader("Template instantiation code for attributes",
> OS);
> -
> - std::vector<Record*> Attrs =
> Records.getAllDerivedDefinitions("Attr");
> -
> - OS << "namespace clang {\n"
> - << "namespace sema {\n\n"
> - << "Attr *instantiateTemplateAttribute(const Attr *At, ASTContext &C, "
> - << "Sema &S,\n"
> - << " const MultiLevelTemplateArgumentList &TemplateArgs) {\n"
> - << " switch (At->getKind()) {\n";
> +void EmitClangAttrTemplateInstantiateHelper(const std::vector<Record
> +*>
> &Attrs,
> + raw_ostream &OS,
> + bool AppliesToDecl) {
>
> + OS << " switch (At->getKind()) {\n";
> for (const auto *Attr : Attrs) {
> const Record &R = *Attr;
> if (!R.getValueAsBit("ASTNode"))
> continue;
> -
> OS << " case attr::" << R.getName() << ": {\n";
> - bool ShouldClone = R.getValueAsBit("Clone");
> + bool ShouldClone = R.getValueAsBit("Clone") &&
> + (!AppliesToDecl ||
> +
> + R.getValueAsBit("MeaningfulToClassTemplateDefinition"));
>
> if (!ShouldClone) {
> OS << " return nullptr;\n";
> @@ -2507,8 +2500,27 @@ void EmitClangAttrTemplateInstantiate(Re
> }
> OS << " } // end switch\n"
> << " llvm_unreachable(\"Unknown attribute!\");\n"
> - << " return nullptr;\n"
> - << "}\n\n"
> + << " return nullptr;\n";
> +}
> +
> +// Emits code to instantiate dependent attributes on templates.
> +void EmitClangAttrTemplateInstantiate(RecordKeeper &Records,
> +raw_ostream &OS) {
> + emitSourceFileHeader("Template instantiation code for attributes",
> +OS);
> +
> + std::vector<Record*> Attrs =
> + Records.getAllDerivedDefinitions("Attr");
> +
> + OS << "namespace clang {\n"
> + << "namespace sema {\n\n"
> + << "Attr *instantiateTemplateAttribute(const Attr *At, ASTContext &C, "
> + << "Sema &S,\n"
> + << " const MultiLevelTemplateArgumentList &TemplateArgs) {\n";
> + EmitClangAttrTemplateInstantiateHelper(Attrs, OS,
> + /*AppliesToDecl*/false); OS << "}\n\n"
> + << "Attr *instantiateTemplateAttributeForDecl(const Attr *At,\n"
> + << " ASTContext &C, Sema &S,\n"
> + << " const MultiLevelTemplateArgumentList &TemplateArgs) {\n";
> + EmitClangAttrTemplateInstantiateHelper(Attrs, OS,
> + /*AppliesToDecl*/true); OS << "}\n\n"
> << "} // end namespace sema\n"
> << "} // end namespace clang\n"; }
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
More information about the cfe-commits
mailing list