r298410 - Correct class-template deprecation behavior

Keane, Erich via cfe-commits cfe-commits at lists.llvm.org
Tue Mar 21 13:18:37 PDT 2017


I saw that, I was digging into it, then went to lunch.  I'm hoping to push a fix by EOD if I can.

Thanks for the heads up though!

-----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