r298634 - Correct class-template deprecation behavior-REDUX
Erich Keane via cfe-commits
cfe-commits at lists.llvm.org
Thu Mar 23 11:51:54 PDT 2017
Author: erichkeane
Date: Thu Mar 23 13:51:54 2017
New Revision: 298634
URL: http://llvm.org/viewvc/llvm-project?rev=298634&view=rev
Log:
Correct class-template deprecation behavior-REDUX
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.
Previous DiffRev: https://reviews.llvm.org/D27486, was reverted.
This patch fixes the issues brought up here by the reverter: https://reviews.llvm.org/rL298410
Differential Revision: https://reviews.llvm.org/D31245
Added:
cfe/trunk/test/SemaCXX/template-multiple-attr-propagation.cpp (with props)
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=298634&r1=298633&r2=298634&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Attr.td (original)
+++ cfe/trunk/include/clang/Basic/Attr.td Thu Mar 23 13:51:54 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 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=298634&r1=298633&r2=298634&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Thu Mar 23 13:51:54 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=298634&r1=298633&r2=298634&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Thu Mar 23 13:51:54 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 (const 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=298634&r1=298633&r2=298634&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Thu Mar 23 13:51:54 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=298634&r1=298633&r2=298634&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Thu Mar 23 13:51:54 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=298634&r1=298633&r2=298634&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Thu Mar 23 13:51:54 2017
@@ -328,6 +328,34 @@ static void instantiateOMPDeclareSimdDec
Attr.getRange());
}
+static bool DeclContainsAttr(const Decl *D, const Attr *NewAttr) {
+ if (!D->hasAttrs() || NewAttr->duplicatesAllowed())
+ return false;
+ return llvm::find_if(D->getAttrs(), [NewAttr](const Attr *Attr) {
+ return Attr->getKind() == NewAttr->getKind();
+ }) != D->getAttrs().end();
+}
+
+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))
+ New->addAttr(NewAttr);
+ }
+ }
+}
+
void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs,
const Decl *Tmpl, Decl *New,
LateInstantiatedAttrVec *LateAttrs,
@@ -421,7 +449,8 @@ void Sema::InstantiateAttrs(const MultiL
Attr *NewAttr = sema::instantiateTemplateAttribute(TmplAttr, Context,
*this, TemplateArgs);
- if (NewAttr)
+
+ if (NewAttr && !DeclContainsAttr(New, NewAttr))
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=298634&r1=298633&r2=298634&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 Thu Mar 23 13:51:54 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=298634&r1=298633&r2=298634&view=diff
==============================================================================
--- cfe/trunk/test/Sema/attr-deprecated.c (original)
+++ cfe/trunk/test/Sema/attr-deprecated.c Thu Mar 23 13:51:54 2017
@@ -1,10 +1,12 @@
// RUN: %clang_cc1 %s -verify -fsyntax-only
+// RUN: %clang_cc1 %s -std=c89 -verify -fsyntax-only
+// RUN: %clang_cc1 %s -std=c99 -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 +19,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 +46,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 +123,12 @@ struct test22 {
__attribute((deprecated)) foo_dep e, f;
};
-typedef int test23_ty __attribute((deprecated));
+typedef int test23_ty __attribute((deprecated));
// 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}}
+// expected-note at -5 {{'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=298634&r1=298633&r2=298634&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/attr-deprecated.cpp (original)
+++ cfe/trunk/test/SemaCXX/attr-deprecated.cpp Thu Mar 23 13:51:54 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}}
Added: cfe/trunk/test/SemaCXX/template-multiple-attr-propagation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/template-multiple-attr-propagation.cpp?rev=298634&view=auto
==============================================================================
--- cfe/trunk/test/SemaCXX/template-multiple-attr-propagation.cpp (added)
+++ cfe/trunk/test/SemaCXX/template-multiple-attr-propagation.cpp Thu Mar 23 13:51:54 2017
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 %s -Wthread-safety-analysis -verify -fexceptions
+// expected-no-diagnostics
+
+class Mutex {
+public:
+ void Lock() __attribute__((exclusive_lock_function()));
+ void Unlock() __attribute__((unlock_function()));
+};
+
+class A {
+public:
+ Mutex mu1, mu2;
+
+ void foo() __attribute__((exclusive_locks_required(mu1))) __attribute__((exclusive_locks_required(mu2))) {}
+
+ template <class T>
+ void bar() __attribute__((exclusive_locks_required(mu1))) __attribute__((exclusive_locks_required(mu2))) {
+ foo();
+ }
+};
+
+void f() {
+ A a;
+ a.mu1.Lock();
+ a.mu2.Lock();
+ a.bar<int>();
+ a.mu2.Unlock();
+ a.mu1.Unlock();
+}
Propchange: cfe/trunk/test/SemaCXX/template-multiple-attr-propagation.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cfe/trunk/test/SemaCXX/template-multiple-attr-propagation.cpp
------------------------------------------------------------------------------
svn:keywords = Author Date Id Rev URL
Propchange: cfe/trunk/test/SemaCXX/template-multiple-attr-propagation.cpp
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: cfe/trunk/test/SemaObjC/attr-deprecated.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/attr-deprecated.m?rev=298634&r1=298633&r2=298634&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/attr-deprecated.m (original)
+++ cfe/trunk/test/SemaObjC/attr-deprecated.m Thu Mar 23 13:51:54 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}}
+ at 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-dep-unavail-warning.m?rev=298634&r1=298633&r2=298634&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/special-dep-unavail-warning.m (original)
+++ cfe/trunk/test/SemaObjC/special-dep-unavail-warning.m Thu Mar 23 13:51:54 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}}
+ at 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=298634&r1=298633&r2=298634&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/warn-deprecated-implementations.m (original)
+++ cfe/trunk/test/SemaObjC/warn-deprecated-implementations.m Thu Mar 23 13:51:54 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}}
+ at 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=298634&r1=298633&r2=298634&view=diff
==============================================================================
--- cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp (original)
+++ cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp Thu Mar 23 13:51:54 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";
}
More information about the cfe-commits
mailing list