diff options
| author | Erich Keane <erich.keane@intel.com> | 2017-03-23 18:51:54 +0000 |
|---|---|---|
| committer | Erich Keane <erich.keane@intel.com> | 2017-03-23 18:51:54 +0000 |
| commit | a32910da1ac5f7c3a2a97d1e5e2050cebe109ae7 (patch) | |
| tree | 1fe265e3a57a7b15191170fe17e15218b8b382aa /clang/utils | |
| parent | 9ebefeb9b1ee22c3ad5036dad131cb960d709662 (diff) | |
| download | bcm5719-llvm-a32910da1ac5f7c3a2a97d1e5e2050cebe109ae7.tar.gz bcm5719-llvm-a32910da1ac5f7c3a2a97d1e5e2050cebe109ae7.zip | |
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
llvm-svn: 298634
Diffstat (limited to 'clang/utils')
| -rw-r--r-- | clang/utils/TableGen/ClangAttrEmitter.cpp | 44 |
1 files changed, 28 insertions, 16 deletions
diff --git a/clang/utils/TableGen/ClangAttrEmitter.cpp b/clang/utils/TableGen/ClangAttrEmitter.cpp index 990b860deae..c516b53101f 100644 --- a/clang/utils/TableGen/ClangAttrEmitter.cpp +++ b/clang/utils/TableGen/ClangAttrEmitter.cpp @@ -2451,26 +2451,19 @@ void EmitClangAttrASTVisitor(RecordKeeper &Records, raw_ostream &OS) { 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(RecordKeeper &Records, raw_ostream &OS) { } 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"; } |

