r298504 - Revert "Correct class-template deprecation behavior"

Martin Bohme via cfe-commits cfe-commits at lists.llvm.org
Wed Mar 22 06:34:37 PDT 2017


Author: mboehme
Date: Wed Mar 22 08:34:37 2017
New Revision: 298504

URL: http://llvm.org/viewvc/llvm-project?rev=298504&view=rev
Log:
Revert "Correct class-template deprecation behavior"

This reverts commit r298410 (which produces incorrect warnings, see
comments on https://reviews.llvm.org/rL298410).

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=298504&r1=298503&r2=298504&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Attr.td (original)
+++ cfe/trunk/include/clang/Basic/Attr.td Wed Mar 22 08:34:37 2017
@@ -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];
 }
 

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=298504&r1=298503&r2=298504&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Wed Mar 22 08:34:37 2017
@@ -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,

Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=298504&r1=298503&r2=298504&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Wed Mar 22 08:34:37 2017
@@ -6723,7 +6723,6 @@ 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;
@@ -6746,8 +6745,6 @@ 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:
@@ -6866,7 +6863,7 @@ static void DoEmitAvailabilityWarning(Se
     }
   }
   else
-    S.Diag(NoteLocation, diag_available_here)
+    S.Diag(D->getLocation(), 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=298504&r1=298503&r2=298504&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Wed Mar 22 08:34:37 2017
@@ -2846,13 +2846,6 @@ 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=298504&r1=298503&r2=298504&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Wed Mar 22 08:34:37 2017
@@ -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);
   }
 }
 

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=298504&r1=298503&r2=298504&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Wed Mar 22 08:34:37 2017
@@ -328,35 +328,6 @@ 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,
@@ -450,8 +421,7 @@ void Sema::InstantiateAttrs(const MultiL
 
       Attr *NewAttr = sema::instantiateTemplateAttribute(TmplAttr, Context,
                                                          *this, TemplateArgs);
-
-      if (NewAttr && !DeclContainsAttr(New, NewAttr->getKind()))
+      if (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=298504&r1=298503&r2=298504&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 Wed Mar 22 08:34:37 2017
@@ -23,38 +23,7 @@ template <> class [[deprecated]] X<int>
 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;

Modified: cfe/trunk/test/Sema/attr-deprecated.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/attr-deprecated.c?rev=298504&r1=298503&r2=298504&view=diff
==============================================================================
--- cfe/trunk/test/Sema/attr-deprecated.c (original)
+++ cfe/trunk/test/Sema/attr-deprecated.c Wed Mar 22 08:34:37 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));// 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 at -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}}

Modified: cfe/trunk/test/SemaCXX/attr-deprecated.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/attr-deprecated.cpp?rev=298504&r1=298503&r2=298504&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/attr-deprecated.cpp (original)
+++ cfe/trunk/test/SemaCXX/attr-deprecated.cpp Wed Mar 22 08:34:37 2017
@@ -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}}

Modified: cfe/trunk/test/SemaObjC/attr-deprecated.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/attr-deprecated.m?rev=298504&r1=298503&r2=298504&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/attr-deprecated.m (original)
+++ cfe/trunk/test/SemaObjC/attr-deprecated.m Wed Mar 22 08:34:37 2017
@@ -83,8 +83,8 @@ int t5() {
 }
 
 
-__attribute ((deprecated)) // expected-note 2 {{'DEPRECATED' has been explicitly marked deprecated here}}
- at interface DEPRECATED { 
+__attribute ((deprecated))  
+ at interface DEPRECATED { // expected-note 2 {{'DEPRECATED' has been explicitly marked deprecated here}}
   @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=298504&r1=298503&r2=298504&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/special-dep-unavail-warning.m (original)
+++ cfe/trunk/test/SemaObjC/special-dep-unavail-warning.m Wed Mar 22 08:34:37 2017
@@ -44,8 +44,8 @@ void test(C *c) {
 }
 
 // rdar://10268422
-__attribute ((deprecated)) // expected-note {{'DEPRECATED' has been explicitly marked deprecated here}}
- at interface DEPRECATED 
+__attribute ((deprecated))
+ at interface DEPRECATED // expected-note {{'DEPRECATED' has been explicitly marked deprecated here}}
 +(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=298504&r1=298503&r2=298504&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/warn-deprecated-implementations.m (original)
+++ cfe/trunk/test/SemaObjC/warn-deprecated-implementations.m Wed Mar 22 08:34:37 2017
@@ -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}}
- at interface CL // expected-note 2 {{class declared here}} 
+__attribute__((deprecated))
+ at 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}}

Modified: cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp?rev=298504&r1=298503&r2=298504&view=diff
==============================================================================
--- cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp (original)
+++ cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp Wed Mar 22 08:34:37 2017
@@ -2451,19 +2451,26 @@ void EmitClangAttrASTVisitor(RecordKeepe
   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 EmitClangAttrTemplateInstantiateHel
   }
   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";
 }




More information about the cfe-commits mailing list