mirror of
https://github.com/intel/llvm.git
synced 2026-01-22 23:49:22 +08:00
Revert "Correct class-template deprecation behavior"
This reverts commit r298410 (which produces incorrect warnings, see comments on https://reviews.llvm.org/rL298410). llvm-svn: 298504
This commit is contained in:
@@ -302,9 +302,6 @@ 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 = [];
|
||||
@@ -376,7 +373,6 @@ def AbiTag : Attr {
|
||||
let Args = [VariadicStringArgument<"Tags">];
|
||||
let Subjects = SubjectList<[Struct, Var, Function, Namespace], ErrorDiag,
|
||||
"ExpectedStructClassVariableFunctionOrInlineNamespace">;
|
||||
let MeaningfulToClassTemplateDefinition = 1;
|
||||
let Documentation = [AbiTagsDocs];
|
||||
}
|
||||
|
||||
@@ -809,7 +805,6 @@ def Deprecated : InheritableAttr {
|
||||
// An optional string argument that enables us to provide a
|
||||
// Fix-It.
|
||||
StringArgument<"Replacement", 1>];
|
||||
let MeaningfulToClassTemplateDefinition = 1;
|
||||
let Documentation = [DeprecatedDocs];
|
||||
}
|
||||
|
||||
@@ -1728,7 +1723,6 @@ def Visibility : InheritableAttr {
|
||||
let Args = [EnumArgument<"Visibility", "VisibilityType",
|
||||
["default", "hidden", "internal", "protected"],
|
||||
["Default", "Hidden", "Hidden", "Protected"]>];
|
||||
let MeaningfulToClassTemplateDefinition = 1;
|
||||
let Documentation = [Undocumented];
|
||||
}
|
||||
|
||||
|
||||
@@ -7505,12 +7505,6 @@ 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,
|
||||
|
||||
@@ -6723,7 +6723,6 @@ static void DoEmitAvailabilityWarning(Sema &S, AvailabilityResult K,
|
||||
// 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;
|
||||
@@ -6746,8 +6745,6 @@ static void DoEmitAvailabilityWarning(Sema &S, AvailabilityResult K,
|
||||
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:
|
||||
@@ -6866,7 +6863,7 @@ static void DoEmitAvailabilityWarning(Sema &S, AvailabilityResult K,
|
||||
}
|
||||
}
|
||||
else
|
||||
S.Diag(NoteLocation, diag_available_here)
|
||||
S.Diag(D->getLocation(), diag_available_here)
|
||||
<< D << available_here_select_kind;
|
||||
|
||||
if (K == AR_NotYetIntroduced)
|
||||
|
||||
@@ -2846,13 +2846,6 @@ QualType Sema::CheckTemplateIdType(TemplateName Name,
|
||||
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);
|
||||
|
||||
|
||||
@@ -1939,9 +1939,6 @@ 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -328,35 +328,6 @@ static void instantiateOMPDeclareSimdDeclAttr(
|
||||
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,
|
||||
@@ -450,8 +421,7 @@ void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs,
|
||||
|
||||
Attr *NewAttr = sema::instantiateTemplateAttribute(TmplAttr, Context,
|
||||
*this, TemplateArgs);
|
||||
|
||||
if (NewAttr && !DeclContainsAttr(New, NewAttr->getKind()))
|
||||
if (NewAttr)
|
||||
New->addAttr(NewAttr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,38 +23,7 @@ template <> class [[deprecated]] X<int> {}; // expected-note {{'X<int>' has been
|
||||
X<char> x1;
|
||||
X<int> x2; // expected-warning {{'X<int>' is deprecated}}
|
||||
|
||||
template <typename T> class [[deprecated]] X2 {}; //expected-note {{'X2<char>' has been explicitly marked deprecated here}}
|
||||
template <typename T> class [[deprecated]] X2 {};
|
||||
template <> class X2<int> {};
|
||||
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.
|
||||
|
||||
}
|
||||
X2<char> x3; // FIXME: no warning!
|
||||
X2<int> x4;
|
||||
|
||||
@@ -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));// expected-note {{'g' has been explicitly marked deprecated here}}
|
||||
void g();
|
||||
void g() __attribute__((deprecated));
|
||||
void g(); // expected-note {{'g' has been explicitly marked deprecated here}}
|
||||
|
||||
extern int var __attribute__((deprecated)); // expected-note 2 {{'var' has been explicitly marked deprecated here}}
|
||||
extern int var __attribute__((deprecated)); // expected-note {{'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;
|
||||
extern int var; // expected-note {{'var' has been explicitly marked deprecated here}}
|
||||
int w() {
|
||||
return var; // expected-warning {{'var' is deprecated}}
|
||||
}
|
||||
|
||||
int old_fn() __attribute__ ((deprecated));// expected-note {{'old_fn' has been explicitly marked deprecated here}}
|
||||
int old_fn();
|
||||
int old_fn() __attribute__ ((deprecated));
|
||||
int old_fn(); // expected-note {{'old_fn' has been explicitly marked deprecated here}}
|
||||
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, // expected-note 2 {{'bar_dep' has been explicitly marked deprecated here}}
|
||||
invalid_attribute)) bar_dep ; // expected-warning {{unknown attribute 'invalid_attribute' ignored}}
|
||||
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 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)); // expected-note {{'test23_ty' has been explicitly marked deprecated here}}
|
||||
typedef int test23_ty __attribute((deprecated));
|
||||
// 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;
|
||||
typedef int test23_ty; // expected-note {{'test23_ty' has been explicitly marked deprecated here}}
|
||||
#endif
|
||||
test23_ty test23_v; // expected-warning {{'test23_ty' is deprecated}}
|
||||
|
||||
@@ -56,14 +56,14 @@ void f(B* b, C *c) {
|
||||
}
|
||||
|
||||
struct D {
|
||||
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}}
|
||||
virtual void f() __attribute__((deprecated));
|
||||
virtual void f(int) __attribute__((deprecated));
|
||||
virtual void f(int, int) __attribute__((deprecated));
|
||||
};
|
||||
|
||||
void D::f() { }
|
||||
void D::f(int v) { }
|
||||
void D::f(int v1, int v2) { }
|
||||
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 f(D* d) {
|
||||
d->f(); // expected-warning{{'f' is deprecated}}
|
||||
|
||||
@@ -83,8 +83,8 @@ int t5() {
|
||||
}
|
||||
|
||||
|
||||
__attribute ((deprecated)) // expected-note 2 {{'DEPRECATED' has been explicitly marked deprecated here}}
|
||||
@interface DEPRECATED {
|
||||
__attribute ((deprecated))
|
||||
@interface DEPRECATED { // expected-note 2 {{'DEPRECATED' has been explicitly marked deprecated here}}
|
||||
@public int ivar;
|
||||
DEPRECATED *ivar2; // no warning.
|
||||
}
|
||||
|
||||
@@ -44,8 +44,8 @@ void test(C *c) {
|
||||
}
|
||||
|
||||
// rdar://10268422
|
||||
__attribute ((deprecated)) // expected-note {{'DEPRECATED' has been explicitly marked deprecated here}}
|
||||
@interface DEPRECATED
|
||||
__attribute ((deprecated))
|
||||
@interface DEPRECATED // expected-note {{'DEPRECATED' has been explicitly marked deprecated here}}
|
||||
+(id)new;
|
||||
@end
|
||||
|
||||
|
||||
@@ -28,8 +28,8 @@
|
||||
- (void) G {} // No warning, implementing its own deprecated method
|
||||
@end
|
||||
|
||||
__attribute__((deprecated)) // expected-note 2 {{'CL' has been explicitly marked deprecated here}}
|
||||
@interface CL // expected-note 2 {{class declared here}}
|
||||
__attribute__((deprecated))
|
||||
@interface CL // expected-note 2 {{class declared here}} // expected-note 2 {{'CL' has been explicitly marked deprecated here}}
|
||||
@end
|
||||
|
||||
@implementation CL // expected-warning {{Implementing deprecated class}}
|
||||
|
||||
@@ -2451,19 +2451,26 @@ void EmitClangAttrASTVisitor(RecordKeeper &Records, raw_ostream &OS) {
|
||||
OS << "#endif // ATTR_VISITOR_DECLS_ONLY\n";
|
||||
}
|
||||
|
||||
void EmitClangAttrTemplateInstantiateHelper(const std::vector<Record *> &Attrs,
|
||||
raw_ostream &OS,
|
||||
bool AppliesToDecl) {
|
||||
// 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";
|
||||
|
||||
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") &&
|
||||
(!AppliesToDecl ||
|
||||
R.getValueAsBit("MeaningfulToClassTemplateDefinition"));
|
||||
bool ShouldClone = R.getValueAsBit("Clone");
|
||||
|
||||
if (!ShouldClone) {
|
||||
OS << " return nullptr;\n";
|
||||
@@ -2500,27 +2507,8 @@ void EmitClangAttrTemplateInstantiateHelper(const std::vector<Record *> &Attrs,
|
||||
}
|
||||
OS << " } // end switch\n"
|
||||
<< " llvm_unreachable(\"Unknown attribute!\");\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"
|
||||
<< " return nullptr;\n"
|
||||
<< "}\n\n"
|
||||
<< "} // end namespace sema\n"
|
||||
<< "} // end namespace clang\n";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user