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.y...@sony.com] Sent: Tuesday, March 21, 2017 12:59 PM To: Keane, Erich <erich.ke...@intel.com> Cc: cfe-commits <cfe-commits@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-boun...@lists.llvm.org] On > Behalf Of Erich Keane via cfe-commits > Sent: Tuesday, March 21, 2017 10:49 > To: cfe-commits@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@-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)) > -@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)) > -@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)) > -@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@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits