[PATCH] D27486: Correct class-template deprecation behavior

2017-03-21 Thread Erich Keane via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL298410: Correct class-template deprecation behavior 
(authored by erichkeane).

Changed prior to commit:
  https://reviews.llvm.org/D27486?vs=84330=92514#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D27486

Files:
  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

Index: cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp
===
--- cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp
+++ cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp
@@ -2451,26 +2451,19 @@
   OS << "#endif  // ATTR_VISITOR_DECLS_ONLY\n";
 }
 
-// Emits code to instantiate dependent attributes on templates.
-void EmitClangAttrTemplateInstantiate(RecordKeeper , raw_ostream ) {
-  emitSourceFileHeader("Template instantiation code for attributes", OS);
-
-  std::vector Attrs = Records.getAllDerivedDefinitions("Attr");
-
-  OS << "namespace clang {\n"
- << "namespace sema {\n\n"
- << "Attr *instantiateTemplateAttribute(const Attr *At, ASTContext , "
- << "Sema ,\n"
- << "const MultiLevelTemplateArgumentList ) {\n"
- << "  switch (At->getKind()) {\n";
+void EmitClangAttrTemplateInstantiateHelper(const std::vector ,
+raw_ostream ,
+bool AppliesToDecl) {
 
+  OS << "  switch (At->getKind()) {\n";
   for (const auto *Attr : Attrs) {
 const Record  = *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 @@
   }
   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 , raw_ostream ) {
+  emitSourceFileHeader("Template instantiation code for attributes", OS);
+
+  std::vector Attrs = Records.getAllDerivedDefinitions("Attr");
+
+  OS << "namespace clang {\n"
+ << "namespace sema {\n\n"
+ << "Attr *instantiateTemplateAttribute(const Attr *At, ASTContext , "
+ << "Sema ,\n"
+ << "const MultiLevelTemplateArgumentList ) {\n";
+  EmitClangAttrTemplateInstantiateHelper(Attrs, OS, /*AppliesToDecl*/false);
+  OS << "}\n\n"
+ << "Attr *instantiateTemplateAttributeForDecl(const Attr *At,\n"
+ << " ASTContext , Sema ,\n"
+ << "const MultiLevelTemplateArgumentList ) {\n";
+  EmitClangAttrTemplateInstantiateHelper(Attrs, OS, /*AppliesToDecl*/true);
+  OS << "}\n\n"
  << "} // end namespace sema\n"
  << "} // end namespace clang\n";
 }
Index: cfe/trunk/include/clang/Sema/Sema.h
===
--- cfe/trunk/include/clang/Sema/Sema.h
+++ cfe/trunk/include/clang/Sema/Sema.h
@@ -7505,6 +7505,12 @@
 LateInstantiatedAttrVec *LateAttrs = nullptr,
 LocalInstantiationScope *OuterMostScope = nullptr);
 
+  void
+  InstantiateAttrsForDecl(const MultiLevelTemplateArgumentList ,
+  const Decl *Pattern, Decl *Inst,
+  LateInstantiatedAttrVec *LateAttrs = nullptr,
+  LocalInstantiationScope *OuterMostScope = nullptr);
+
   bool
   InstantiateClassTemplateSpecialization(SourceLocation PointOfInstantiation,
ClassTemplateSpecializationDecl *ClassTemplateSpec,
Index: cfe/trunk/include/clang/Basic/Attr.td
===
--- cfe/trunk/include/clang/Basic/Attr.td
+++ cfe/trunk/include/clang/Basic/Attr.td
@@ -302,6 +302,9 @@
   // 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 

[PATCH] D27486: Correct class-template deprecation behavior

2017-02-16 Thread Erich Keane via Phabricator via cfe-commits
erichkeane added a comment.

@rsmith  did you ever get a chance to re-review this?  Is this what you were 
wanting for this?


https://reviews.llvm.org/D27486



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D27486: Correct class-template deprecation behavior

2017-02-09 Thread Richard Smith via Phabricator via cfe-commits
rsmith added inline comments.



Comment at: include/clang/Basic/Attr.td:301
   bit DuplicatesAllowedWhileMerging = 0;
+  // Set to true if this attribute should apply to template declarations,
+  // remains false if this should only be applied to the definition.

erichkeane wrote:
> rsmith wrote:
> > I find this confusing -- it seems to suggest the attribute would be applied 
> > to the template declaration, not the templated declaration. I also think 
> > that the property we're modelling here is something more general than 
> > something about templates -- rather, I think the property is "is this 
> > attribute only meaningful when applied to / inherited into a defintiion?" 
> > It would also be useful to make clear that this only applies to class 
> > templates; for function templates, we always instantiate all the attributes 
> > with the declaration.
> > 
> > Looking through our current attribute set, it looks like at least `AbiTag` 
> > should also get this set, and maybe also `Visibility`. (Though I wonder if 
> > there would be any problem with always instantiating the full attribute set 
> > for a class declaration.)
> > (Though I wonder if there would be any problem with always instantiating 
> > the full attribute set for a class declaration.)
> 
> This is definitely a good point.  It seems that just about every other usage 
> of instantiating attributes happens right after creation, class template 
> specialization is the lone exception it seems.
> 
> If I were to simply revert most of this change, then alter my 
> SemaTemplate.cpp changes to just call InstantiateAttrs and presumably remove 
> the other call to InstantiateAttrs (since it results in 2 sets of 
> attributes), would you consider that to be more acceptable?
> 
> 
> 
Yes, I think we should at least try that and see if there's a reason why we 
would need the extra complexity here.


https://reviews.llvm.org/D27486



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D27486: Correct class-template deprecation behavior

2017-01-13 Thread Erich Keane via Phabricator via cfe-commits
erichkeane added a comment.

I've actually figured out how to fix the diagnosis location.  I switched the 
diagnosis to use the location of the actual [[deprecated]] attribute instead of 
the Declaration location.  IMO, this is a BETTER note anyway (since the arrow 
points to the actual [[deprecated]] label!).  I'll be uploading a new diff once 
I clean up a few things.


https://reviews.llvm.org/D27486



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D27486: Correct class-template deprecation behavior

2017-01-11 Thread Erich Keane via Phabricator via cfe-commits
erichkeane added a comment.

Thanks for the feedback Richard!  I'll look into whether instantiating the full 
attribute set upon creation is a possibility.




Comment at: include/clang/Basic/Attr.td:301
   bit DuplicatesAllowedWhileMerging = 0;
+  // Set to true if this attribute should apply to template declarations,
+  // remains false if this should only be applied to the definition.

rsmith wrote:
> I find this confusing -- it seems to suggest the attribute would be applied 
> to the template declaration, not the templated declaration. I also think that 
> the property we're modelling here is something more general than something 
> about templates -- rather, I think the property is "is this attribute only 
> meaningful when applied to / inherited into a defintiion?" It would also be 
> useful to make clear that this only applies to class templates; for function 
> templates, we always instantiate all the attributes with the declaration.
> 
> Looking through our current attribute set, it looks like at least `AbiTag` 
> should also get this set, and maybe also `Visibility`. (Though I wonder if 
> there would be any problem with always instantiating the full attribute set 
> for a class declaration.)
> (Though I wonder if there would be any problem with always instantiating the 
> full attribute set for a class declaration.)

This is definitely a good point.  It seems that just about every other usage of 
instantiating attributes happens right after creation, class template 
specialization is the lone exception it seems.

If I were to simply revert most of this change, then alter my SemaTemplate.cpp 
changes to just call InstantiateAttrs and presumably remove the other call to 
InstantiateAttrs (since it results in 2 sets of attributes), would you consider 
that to be more acceptable?





https://reviews.llvm.org/D27486



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D27486: Correct class-template deprecation behavior

2017-01-11 Thread Richard Smith via Phabricator via cfe-commits
rsmith added inline comments.



Comment at: include/clang/Basic/Attr.td:301
   bit DuplicatesAllowedWhileMerging = 0;
+  // Set to true if this attribute should apply to template declarations,
+  // remains false if this should only be applied to the definition.

I find this confusing -- it seems to suggest the attribute would be applied to 
the template declaration, not the templated declaration. I also think that the 
property we're modelling here is something more general than something about 
templates -- rather, I think the property is "is this attribute only meaningful 
when applied to / inherited into a defintiion?" It would also be useful to make 
clear that this only applies to class templates; for function templates, we 
always instantiate all the attributes with the declaration.

Looking through our current attribute set, it looks like at least `AbiTag` 
should also get this set, and maybe also `Visibility`. (Though I wonder if 
there would be any problem with always instantiating the full attribute set for 
a class declaration.)



Comment at: lib/Sema/SemaTemplate.cpp:2406-2407
+  TemplateArgLists.addOuterTemplateArguments(Converted);
+  InstantiateAttrsForDecl(TemplateArgLists,
+  ClassTemplate->getTemplatedDecl(), Decl);
   ClassTemplate->AddSpecialization(Decl, InsertPos);

You should also presumably do this when instantiating a member `CXXRecordDecl` 
nested within a class template, and when instantiating a local class in a 
function template.

What should happen if more attributes are added between uses of the template? 
Example:

```
template struct A;
A *p;
template struct [[deprecated]] A;
A *q; // warn here?
```


https://reviews.llvm.org/D27486



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D27486: Correct class-template deprecation behavior

2017-01-04 Thread Erich Keane via Phabricator via cfe-commits
erichkeane added a comment.

Thanks for your help here Aaron.

I agree about waiting for @rsmith, thanks!


https://reviews.llvm.org/D27486



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D27486: Correct class-template deprecation behavior

2017-01-04 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman accepted this revision.
aaron.ballman added a comment.
This revision is now accepted and ready to land.

This LGTM, but you should wait for @rsmith to sign off as well.


https://reviews.llvm.org/D27486



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D27486: Correct class-template deprecation behavior

2017-01-04 Thread Erich Keane via Phabricator via cfe-commits
erichkeane added a comment.

Marking Aaron's comments done.


https://reviews.llvm.org/D27486



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D27486: Correct class-template deprecation behavior

2017-01-04 Thread Erich Keane via Phabricator via cfe-commits
erichkeane updated this revision to Diff 83081.
erichkeane marked 3 inline comments as done.
erichkeane added a comment.

Aaron's new comments


https://reviews.llvm.org/D27486

Files:
  include/clang/Basic/Attr.td
  include/clang/Sema/Sema.h
  lib/Sema/SemaTemplate.cpp
  lib/Sema/SemaTemplateInstantiate.cpp
  lib/Sema/SemaTemplateInstantiateDecl.cpp
  test/CXX/dcl.dcl/dcl.attr/dcl.attr.deprecated/p1.cpp
  utils/TableGen/ClangAttrEmitter.cpp

Index: lib/Sema/SemaTemplateInstantiate.cpp
===
--- lib/Sema/SemaTemplateInstantiate.cpp
+++ lib/Sema/SemaTemplateInstantiate.cpp
@@ -1882,6 +1882,8 @@
   namespace sema {
 Attr *instantiateTemplateAttribute(const Attr *At, ASTContext , Sema ,
 const MultiLevelTemplateArgumentList );
+Attr *instantiateTemplateAttributeForDecl(const Attr *At, ASTContext , Sema ,
+const MultiLevelTemplateArgumentList );
   }
 }
 
Index: lib/Sema/SemaTemplate.cpp
===
--- lib/Sema/SemaTemplate.cpp
+++ lib/Sema/SemaTemplate.cpp
@@ -2401,6 +2401,10 @@
 ClassTemplate->getLocation(),
  ClassTemplate,
  Converted, nullptr);
+  MultiLevelTemplateArgumentList TemplateArgLists;
+  TemplateArgLists.addOuterTemplateArguments(Converted);
+  InstantiateAttrsForDecl(TemplateArgLists,
+  ClassTemplate->getTemplatedDecl(), Decl);
   ClassTemplate->AddSpecialization(Decl, InsertPos);
   if (ClassTemplate->isOutOfLine())
 Decl->setLexicalDeclContext(ClassTemplate->getLexicalDeclContext());
Index: lib/Sema/SemaTemplateInstantiateDecl.cpp
===
--- lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -308,6 +308,26 @@
   Attr.getRange());
 }
 
+void Sema::InstantiateAttrsForDecl(
+const MultiLevelTemplateArgumentList , const Decl *Tmpl,
+Decl *New, LateInstantiatedAttrVec *LateAttrs,
+LocalInstantiationScope *OuterMostScope) {
+  if (NamedDecl *ND = dyn_cast(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(ND->getDeclContext()),
+  /*TypeQuals*/ 0, ND->isCXXInstanceMember());
+
+  Attr *NewAttr = sema::instantiateTemplateAttributeForDecl(
+  TmplAttr, Context, *this, TemplateArgs);
+  if (NewAttr)
+New->addAttr(NewAttr);
+}
+  }
+}
+
 void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList ,
 const Decl *Tmpl, Decl *New,
 LateInstantiatedAttrVec *LateAttrs,
@@ -945,6 +965,7 @@
 }
   }
 
+  SemaRef.InstantiateAttrsForDecl(TemplateArgs, D, Enum);
   SemaRef.InstantiateAttrs(TemplateArgs, D, Enum);
 
   Enum->setInstantiationOfMemberEnum(D, TSK_ImplicitInstantiation);
@@ -1033,6 +1054,7 @@
 }
 
 if (EnumConst) {
+  SemaRef.InstantiateAttrsForDecl(TemplateArgs, EC, EnumConst);
   SemaRef.InstantiateAttrs(TemplateArgs, EC, EnumConst);
 
   EnumConst->setAccess(Enum->getAccess());
Index: utils/TableGen/ClangAttrEmitter.cpp
===
--- utils/TableGen/ClangAttrEmitter.cpp
+++ utils/TableGen/ClangAttrEmitter.cpp
@@ -2452,26 +2452,21 @@
   OS << "#endif  // ATTR_VISITOR_DECLS_ONLY\n";
 }
 
-// Emits code to instantiate dependent attributes on templates.
-void EmitClangAttrTemplateInstantiate(RecordKeeper , raw_ostream ) {
-  emitSourceFileHeader("Template instantiation code for attributes", OS);
-
-  std::vector Attrs = Records.getAllDerivedDefinitions("Attr");
-
-  OS << "namespace clang {\n"
- << "namespace sema {\n\n"
- << "Attr *instantiateTemplateAttribute(const Attr *At, ASTContext , "
- << "Sema ,\n"
- << "const MultiLevelTemplateArgumentList ) {\n"
- << "  switch (At->getKind()) {\n";
+void EmitClangAttrTemplateInstantiateHelper(const std::vector ,
+raw_ostream ,
+bool AppliesToDecl) {
+  OS << "  switch (At->getKind()) {\n";
 
   for (const auto *Attr : Attrs) {
 const Record  = *Attr;
 if (!R.getValueAsBit("ASTNode"))
   continue;
 
 OS << "case attr::" << R.getName() << ": {\n";
-bool ShouldClone = R.getValueAsBit("Clone");
+
+bool ShouldClone =
+R.getValueAsBit("Clone") &&
+R.getValueAsBit("AppliesToTemplateDeclaration") == AppliesToDecl;
 
 if (!ShouldClone) {
   OS << "  return nullptr;\n";
@@ -2508,8 

[PATCH] D27486: Correct class-template deprecation behavior

2017-01-04 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added inline comments.



Comment at: lib/Sema/SemaTemplateInstantiateDecl.cpp:322
+  CXXThisScopeRAII ThisScope(*this, ThisContext, /*TypeQuals*/ 0,
+ ND && ND->isCXXInstanceMember());
+

No need to check for `ND` here; already done above. You might also want to 
remove `ThisContext` and just sink the initialization.



Comment at: utils/TableGen/ClangAttrEmitter.cpp:2520
+ << "const MultiLevelTemplateArgumentList ) {\n";
+  EmitClangAttrTemplateInstantiateHelper(Attrs, OS, /*DeclTime=*/false);
+  OS << "}\n\n"

DeclTime -> AppliesToDecl



Comment at: utils/TableGen/ClangAttrEmitter.cpp:2525
+ << "const MultiLevelTemplateArgumentList ) {\n";
+  EmitClangAttrTemplateInstantiateHelper(Attrs, OS, /*DeclTime=*/true);
+

DeclTime -> AppliesToDecl


https://reviews.llvm.org/D27486



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D27486: Correct class-template deprecation behavior

2017-01-04 Thread Erich Keane via Phabricator via cfe-commits
erichkeane updated this revision to Diff 83072.
erichkeane marked 2 inline comments as done.
erichkeane added a comment.

Updated based on Aarons comments.


https://reviews.llvm.org/D27486

Files:
  include/clang/Basic/Attr.td
  include/clang/Sema/Sema.h
  lib/Sema/SemaTemplate.cpp
  lib/Sema/SemaTemplateInstantiate.cpp
  lib/Sema/SemaTemplateInstantiateDecl.cpp
  test/CXX/dcl.dcl/dcl.attr/dcl.attr.deprecated/p1.cpp
  utils/TableGen/ClangAttrEmitter.cpp

Index: lib/Sema/SemaTemplateInstantiate.cpp
===
--- lib/Sema/SemaTemplateInstantiate.cpp
+++ lib/Sema/SemaTemplateInstantiate.cpp
@@ -1882,6 +1882,8 @@
   namespace sema {
 Attr *instantiateTemplateAttribute(const Attr *At, ASTContext , Sema ,
 const MultiLevelTemplateArgumentList );
+Attr *instantiateTemplateAttributeForDecl(const Attr *At, ASTContext , Sema ,
+const MultiLevelTemplateArgumentList );
   }
 }
 
Index: lib/Sema/SemaTemplate.cpp
===
--- lib/Sema/SemaTemplate.cpp
+++ lib/Sema/SemaTemplate.cpp
@@ -2401,6 +2401,10 @@
 ClassTemplate->getLocation(),
  ClassTemplate,
  Converted, nullptr);
+  MultiLevelTemplateArgumentList TemplateArgLists;
+  TemplateArgLists.addOuterTemplateArguments(Converted);
+  InstantiateAttrsForDecl(TemplateArgLists,
+  ClassTemplate->getTemplatedDecl(), Decl);
   ClassTemplate->AddSpecialization(Decl, InsertPos);
   if (ClassTemplate->isOutOfLine())
 Decl->setLexicalDeclContext(ClassTemplate->getLexicalDeclContext());
Index: lib/Sema/SemaTemplateInstantiateDecl.cpp
===
--- lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -308,6 +308,27 @@
   Attr.getRange());
 }
 
+void Sema::InstantiateAttrsForDecl(
+const MultiLevelTemplateArgumentList , const Decl *Tmpl,
+Decl *New, LateInstantiatedAttrVec *LateAttrs,
+LocalInstantiationScope *OuterMostScope) {
+  if (NamedDecl *ND = dyn_cast(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.
+  CXXRecordDecl *ThisContext =
+  dyn_cast_or_null(ND->getDeclContext());
+  CXXThisScopeRAII ThisScope(*this, ThisContext, /*TypeQuals*/ 0,
+ ND && ND->isCXXInstanceMember());
+
+  Attr *NewAttr = sema::instantiateTemplateAttributeForDecl(
+  TmplAttr, Context, *this, TemplateArgs);
+  if (NewAttr)
+New->addAttr(NewAttr);
+}
+  }
+}
+
 void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList ,
 const Decl *Tmpl, Decl *New,
 LateInstantiatedAttrVec *LateAttrs,
@@ -945,6 +966,7 @@
 }
   }
 
+  SemaRef.InstantiateAttrsForDecl(TemplateArgs, D, Enum);
   SemaRef.InstantiateAttrs(TemplateArgs, D, Enum);
 
   Enum->setInstantiationOfMemberEnum(D, TSK_ImplicitInstantiation);
@@ -1033,6 +1055,7 @@
 }
 
 if (EnumConst) {
+  SemaRef.InstantiateAttrsForDecl(TemplateArgs, EC, EnumConst);
   SemaRef.InstantiateAttrs(TemplateArgs, EC, EnumConst);
 
   EnumConst->setAccess(Enum->getAccess());
Index: utils/TableGen/ClangAttrEmitter.cpp
===
--- utils/TableGen/ClangAttrEmitter.cpp
+++ utils/TableGen/ClangAttrEmitter.cpp
@@ -2452,26 +2452,21 @@
   OS << "#endif  // ATTR_VISITOR_DECLS_ONLY\n";
 }
 
-// Emits code to instantiate dependent attributes on templates.
-void EmitClangAttrTemplateInstantiate(RecordKeeper , raw_ostream ) {
-  emitSourceFileHeader("Template instantiation code for attributes", OS);
-
-  std::vector Attrs = Records.getAllDerivedDefinitions("Attr");
-
-  OS << "namespace clang {\n"
- << "namespace sema {\n\n"
- << "Attr *instantiateTemplateAttribute(const Attr *At, ASTContext , "
- << "Sema ,\n"
- << "const MultiLevelTemplateArgumentList ) {\n"
- << "  switch (At->getKind()) {\n";
+void EmitClangAttrTemplateInstantiateHelper(const std::vector ,
+raw_ostream ,
+bool AppliesToDecl) {
+  OS << "  switch (At->getKind()) {\n";
 
   for (const auto *Attr : Attrs) {
 const Record  = *Attr;
 if (!R.getValueAsBit("ASTNode"))
   continue;
 
 OS << "case attr::" << R.getName() << ": {\n";
-bool ShouldClone = R.getValueAsBit("Clone");
+
+bool ShouldClone =
+R.getValueAsBit("Clone") &&
+R.getValueAsBit("AppliesToTemplateDeclaration") == 

[PATCH] D27486: Correct class-template deprecation behavior

2017-01-04 Thread Erich Keane via Phabricator via cfe-commits
erichkeane marked 6 inline comments as done.
erichkeane added a comment.

All Aaron's comments addressed in a patch that is on its way!




Comment at: lib/Sema/SemaTemplateInstantiateDecl.cpp:320
+CXXRecordDecl *ThisContext =
+dyn_cast_or_null(ND->getDeclContext());
+CXXThisScopeRAII ThisScope(*this, ThisContext, /*TypeQuals*/ 0,

aaron.ballman wrote:
> Are you sure `ND` is always non-null? If so, then you should use `cast<>` 
> above instead of `dyn_cast<>`.
I hadn't thought much about it actually, this is from a section in 
InstantiateAttrs (see 410 in this file).  Also reinspecting, it seems that ND 
can be moved above the for-loop as well, so I'm going to do that, so that we 
can perhaps save the attributes in that case.



Comment at: utils/TableGen/ClangAttrEmitter.cpp:2456
+void EmitClangAttrTemplateInstantiateHelper(const std::vector ,
+raw_ostream , bool DeclTime) {
+ OS << "  switch (At->getKind()) {\n";

aaron.ballman wrote:
> What does "time" mean in `DeclTime`?
Right, good point.  I'll choose a better name in the next patch.


https://reviews.llvm.org/D27486



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D27486: Correct class-template deprecation behavior

2017-01-04 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added inline comments.



Comment at: include/clang/Basic/Attr.td:301
   bit DuplicatesAllowedWhileMerging = 0;
+  // Set to true if this attribute should apply to template declaration,
+  // remains false if this should only be applied on definition.

template declaration -> template declarations



Comment at: include/clang/Basic/Attr.td:302
+  // Set to true if this attribute should apply to template declaration,
+  // remains false if this should only be applied on definition.
+  bit AppliesToTemplateDeclaration = 0;

on definition -> to the definition



Comment at: include/clang/Sema/Sema.h:7388-7391
+  void InstantiateAttrsForDecl(const MultiLevelTemplateArgumentList 
,
+const Decl *Pattern, Decl *Inst,
+LateInstantiatedAttrVec *LateAttrs = nullptr,
+LocalInstantiationScope *OuterMostScope = nullptr);

Did clang-format produce this formatting?



Comment at: lib/Sema/SemaTemplateInstantiateDecl.cpp:320
+CXXRecordDecl *ThisContext =
+dyn_cast_or_null(ND->getDeclContext());
+CXXThisScopeRAII ThisScope(*this, ThisContext, /*TypeQuals*/ 0,

Are you sure `ND` is always non-null? If so, then you should use `cast<>` above 
instead of `dyn_cast<>`.



Comment at: utils/TableGen/ClangAttrEmitter.cpp:2456
+void EmitClangAttrTemplateInstantiateHelper(const std::vector ,
+raw_ostream , bool DeclTime) {
+ OS << "  switch (At->getKind()) {\n";

What does "time" mean in `DeclTime`?



Comment at: utils/TableGen/ClangAttrEmitter.cpp:2507
+}
+// Emits code to instantiate dependent attributes on templates.
+void EmitClangAttrTemplateInstantiate(RecordKeeper , raw_ostream ) {

Add a newline above this comment to separate it from the previous function body.


https://reviews.llvm.org/D27486



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D27486: Correct class-template deprecation behavior

2017-01-03 Thread Erich Keane via Phabricator via cfe-commits
erichkeane updated this revision to Diff 82909.
erichkeane added a comment.

Updated based on Richard Smith's suggestion, all tests pass with no alteration, 
and the initial incorrect behavior was corrected in an existing test.


https://reviews.llvm.org/D27486

Files:
  include/clang/Basic/Attr.td
  include/clang/Sema/Sema.h
  lib/Sema/SemaTemplate.cpp
  lib/Sema/SemaTemplateInstantiate.cpp
  lib/Sema/SemaTemplateInstantiateDecl.cpp
  test/CXX/dcl.dcl/dcl.attr/dcl.attr.deprecated/p1.cpp
  utils/TableGen/ClangAttrEmitter.cpp

Index: lib/Sema/SemaTemplateInstantiate.cpp
===
--- lib/Sema/SemaTemplateInstantiate.cpp
+++ lib/Sema/SemaTemplateInstantiate.cpp
@@ -1882,6 +1882,8 @@
   namespace sema {
 Attr *instantiateTemplateAttribute(const Attr *At, ASTContext , Sema ,
 const MultiLevelTemplateArgumentList );
+Attr *instantiateTemplateAttributeForDecl(const Attr *At, ASTContext , Sema ,
+const MultiLevelTemplateArgumentList );
   }
 }
 
Index: lib/Sema/SemaTemplate.cpp
===
--- lib/Sema/SemaTemplate.cpp
+++ lib/Sema/SemaTemplate.cpp
@@ -2401,6 +2401,10 @@
 ClassTemplate->getLocation(),
  ClassTemplate,
  Converted, nullptr);
+  MultiLevelTemplateArgumentList TemplateArgLists;
+  TemplateArgLists.addOuterTemplateArguments(Converted);
+  InstantiateAttrsForDecl(TemplateArgLists,
+  ClassTemplate->getTemplatedDecl(), Decl);
   ClassTemplate->AddSpecialization(Decl, InsertPos);
   if (ClassTemplate->isOutOfLine())
 Decl->setLexicalDeclContext(ClassTemplate->getLexicalDeclContext());
Index: lib/Sema/SemaTemplateInstantiateDecl.cpp
===
--- lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -308,6 +308,26 @@
   Attr.getRange());
 }
 
+void Sema::InstantiateAttrsForDecl(
+const MultiLevelTemplateArgumentList , const Decl *Tmpl,
+Decl *New, LateInstantiatedAttrVec *LateAttrs,
+LocalInstantiationScope *OuterMostScope) {
+  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.
+NamedDecl *ND = dyn_cast(New);
+CXXRecordDecl *ThisContext =
+dyn_cast_or_null(ND->getDeclContext());
+CXXThisScopeRAII ThisScope(*this, ThisContext, /*TypeQuals*/ 0,
+   ND && ND->isCXXInstanceMember());
+
+Attr *NewAttr = sema::instantiateTemplateAttributeForDecl(TmplAttr, Context, *this,
+   TemplateArgs);
+if (NewAttr)
+  New->addAttr(NewAttr);
+  }
+}
+
 void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList ,
 const Decl *Tmpl, Decl *New,
 LateInstantiatedAttrVec *LateAttrs,
@@ -945,6 +965,7 @@
 }
   }
 
+  SemaRef.InstantiateAttrsForDecl(TemplateArgs, D, Enum);
   SemaRef.InstantiateAttrs(TemplateArgs, D, Enum);
 
   Enum->setInstantiationOfMemberEnum(D, TSK_ImplicitInstantiation);
@@ -1033,6 +1054,7 @@
 }
 
 if (EnumConst) {
+  SemaRef.InstantiateAttrsForDecl(TemplateArgs, EC, EnumConst);
   SemaRef.InstantiateAttrs(TemplateArgs, EC, EnumConst);
 
   EnumConst->setAccess(Enum->getAccess());
Index: utils/TableGen/ClangAttrEmitter.cpp
===
--- utils/TableGen/ClangAttrEmitter.cpp
+++ utils/TableGen/ClangAttrEmitter.cpp
@@ -2452,26 +2452,20 @@
   OS << "#endif  // ATTR_VISITOR_DECLS_ONLY\n";
 }
 
-// Emits code to instantiate dependent attributes on templates.
-void EmitClangAttrTemplateInstantiate(RecordKeeper , raw_ostream ) {
-  emitSourceFileHeader("Template instantiation code for attributes", OS);
-
-  std::vector Attrs = Records.getAllDerivedDefinitions("Attr");
-
-  OS << "namespace clang {\n"
- << "namespace sema {\n\n"
- << "Attr *instantiateTemplateAttribute(const Attr *At, ASTContext , "
- << "Sema ,\n"
- << "const MultiLevelTemplateArgumentList ) {\n"
- << "  switch (At->getKind()) {\n";
+void EmitClangAttrTemplateInstantiateHelper(const std::vector ,
+raw_ostream , bool DeclTime) {
+ OS << "  switch (At->getKind()) {\n";
 
   for (const auto *Attr : Attrs) {
 const Record  = *Attr;
 if (!R.getValueAsBit("ASTNode"))
   continue;
 
 OS << "case attr::" << R.getName() << ": {\n";
-bool ShouldClone = R.getValueAsBit("Clone");
+
+bool ShouldClone =
+R.getValueAsBit("Clone") &&
+

[PATCH] D27486: Correct class-template deprecation behavior

2016-12-09 Thread Erich Keane via Phabricator via cfe-commits
erichkeane updated this revision to Diff 80907.
erichkeane added a comment.

I've been trying to do what @rsmith suggested, so this is a WIP checkpoint, I 
was hoping you could take a look and tell me if I'm on the right track.  I 
beleive I'm very nearly done, and all but 1 of the tests pass, which if you 
have spare cycles and could suggest something, I would much appreciate it.  
Currently:

template struct C { 
enum [[deprecated]] Enum {c0;}};

void foo() {
CEnum x; // Used to warn, no longer does
x = C::c0; // Used to warn, no longer does
}


https://reviews.llvm.org/D27486

Files:
  include/clang/Basic/Attr.td
  include/clang/Sema/Sema.h
  lib/Sema/SemaTemplate.cpp
  lib/Sema/SemaTemplateInstantiate.cpp
  lib/Sema/SemaTemplateInstantiateDecl.cpp
  test/CXX/dcl.dcl/dcl.attr/dcl.attr.deprecated/p1.cpp
  utils/TableGen/ClangAttrEmitter.cpp

Index: lib/Sema/SemaTemplateInstantiate.cpp
===
--- lib/Sema/SemaTemplateInstantiate.cpp
+++ lib/Sema/SemaTemplateInstantiate.cpp
@@ -1858,6 +1858,8 @@
   namespace sema {
 Attr *instantiateTemplateAttribute(const Attr *At, ASTContext , Sema ,
 const MultiLevelTemplateArgumentList );
+Attr *instantiateTemplateAttributeForDecl(const Attr *At, ASTContext , Sema ,
+const MultiLevelTemplateArgumentList );
   }
 }
 
Index: lib/Sema/SemaTemplate.cpp
===
--- lib/Sema/SemaTemplate.cpp
+++ lib/Sema/SemaTemplate.cpp
@@ -2352,6 +2352,10 @@
 ClassTemplate->getLocation(),
  ClassTemplate,
  Converted, nullptr);
+  MultiLevelTemplateArgumentList TemplateArgLists;
+  TemplateArgLists.addOuterTemplateArguments(Converted);
+  InstantiateAttrsForDecl(TemplateArgLists,
+  ClassTemplate->getTemplatedDecl(), Decl);
   ClassTemplate->AddSpecialization(Decl, InsertPos);
   if (ClassTemplate->isOutOfLine())
 Decl->setLexicalDeclContext(ClassTemplate->getLexicalDeclContext());
Index: lib/Sema/SemaTemplateInstantiateDecl.cpp
===
--- lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -308,6 +308,26 @@
   Attr.getRange());
 }
 
+void Sema::InstantiateAttrsForDecl(
+const MultiLevelTemplateArgumentList , const Decl *Tmpl,
+Decl *New, LateInstantiatedAttrVec *LateAttrs,
+LocalInstantiationScope *OuterMostScope) {
+  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.
+NamedDecl *ND = dyn_cast(New);
+CXXRecordDecl *ThisContext =
+dyn_cast_or_null(ND->getDeclContext());
+CXXThisScopeRAII ThisScope(*this, ThisContext, /*TypeQuals*/ 0,
+   ND && ND->isCXXInstanceMember());
+
+Attr *NewAttr = sema::instantiateTemplateAttributeForDecl(TmplAttr, Context, *this,
+   TemplateArgs);
+if (NewAttr)
+  New->addAttr(NewAttr);
+  }
+}
+
 void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList ,
 const Decl *Tmpl, Decl *New,
 LateInstantiatedAttrVec *LateAttrs,
Index: utils/TableGen/ClangAttrEmitter.cpp
===
--- utils/TableGen/ClangAttrEmitter.cpp
+++ utils/TableGen/ClangAttrEmitter.cpp
@@ -2452,26 +2452,20 @@
   OS << "#endif  // ATTR_VISITOR_DECLS_ONLY\n";
 }
 
-// Emits code to instantiate dependent attributes on templates.
-void EmitClangAttrTemplateInstantiate(RecordKeeper , raw_ostream ) {
-  emitSourceFileHeader("Template instantiation code for attributes", OS);
-
-  std::vector Attrs = Records.getAllDerivedDefinitions("Attr");
-
-  OS << "namespace clang {\n"
- << "namespace sema {\n\n"
- << "Attr *instantiateTemplateAttribute(const Attr *At, ASTContext , "
- << "Sema ,\n"
- << "const MultiLevelTemplateArgumentList ) {\n"
- << "  switch (At->getKind()) {\n";
+void EmitClangAttrTemplateInstantiateHelper(const std::vector ,
+raw_ostream , bool DeclTime) {
+ OS << "  switch (At->getKind()) {\n";
 
   for (const auto *Attr : Attrs) {
 const Record  = *Attr;
 if (!R.getValueAsBit("ASTNode"))
   continue;
 
 OS << "case attr::" << R.getName() << ": {\n";
-bool ShouldClone = R.getValueAsBit("Clone");
+
+bool ShouldClone =
+R.getValueAsBit("Clone") &&
+R.getValueAsBit("AppliesToTemplateDeclaration") == DeclTime;
 
 if (!ShouldClone) {
   OS << "  return nullptr;\n";
@@ -2508,8 +2502,27 

[PATCH] D27486: Correct class-template deprecation behavior

2016-12-07 Thread Erich Keane via Phabricator via cfe-commits
erichkeane added a comment.

Thanks David!
To all - I'm actually doing my best to rewrite this based on Richard's 
suggestions, so look for a 'in progress' update to this review as soon as I get 
something that is reasonably presentable.


https://reviews.llvm.org/D27486



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D27486: Correct class-template deprecation behavior

2016-12-07 Thread David Majnemer via Phabricator via cfe-commits
majnemer added inline comments.



Comment at: lib/Sema/SemaTemplate.cpp:2355
  Converted, nullptr);
+  if (auto *attr = ClassTemplate->getTemplatedDecl()
+   ->getAttr())

Please capitalize `Attr`.



Comment at: lib/Sema/SemaTemplate.cpp:2356
+  if (auto *attr = ClassTemplate->getTemplatedDecl()
+   ->getAttr())
+Decl->addAttr(attr->clone(Context));

I think you can remove the `clang::`


https://reviews.llvm.org/D27486



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D27486: Correct class-template deprecation behavior

2016-12-06 Thread Erich Keane via Phabricator via cfe-commits
erichkeane added a comment.

In https://reviews.llvm.org/D27486#615174, @rsmith wrote:

> Thanks!
>
> If you look at `Sema::InstantiateClass`, we instantiate all of the attributes 
> there. The problem seems to be that that happens only when instantiating the 
> class definition, which happens after the point at which we would diagnose 
> use of a deprecated declaration.
>
> This change will result in us having two copies of the `deprecated` attribute 
> after we instantiate the class definition -- one from instantiating the 
> declaration and another from instantiating the definition.


Well darn, I didn't notice this.

> Perhaps a better way to handle this would be to add a flag to the attribute 
> definitions (in Attr.td) to indicate whether they apply to a declaration or 
> just a definition (and thus whether they should be instantiated with a 
> declaration, or only with a definition), and then instantiate the relevant 
> subset when creating the `ClassTemplateSpecializationDecl` (and other kinds 
> of decl -- I expect the same thing will happen for member classes of class 
> templates, for function templates, and so on).

I can definitely look into this.  I have a feeling (based on the fact that this 
attribute IS picked up by function-template-instantiations) that it likely 
wouldn't be necessary for the others, but I can start to look into the 
scaffolding to get this to happen.

> @aaron.ballman Does that seem reasonable to you? If so, we should do some 
> investigation of the attribute set to figure out what the best default is.

As far as this investigation, I'd suspect that the current behavior (never 
applies to declaration) is likely the correct 'default' is. I suspect that 
there is also a massive work-item to go through the current list to see which 
SHOULD apply to declarations.


https://reviews.llvm.org/D27486



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D27486: Correct class-template deprecation behavior

2016-12-06 Thread Richard Smith via Phabricator via cfe-commits
rsmith added a comment.

Thanks!

If you look at `Sema::InstantiateClass`, we instantiate all of the attributes 
there. The problem seems to be that that happens only when instantiating the 
class definition, which happens after the point at which we would diagnose use 
of a deprecated declaration.

This change will result in us having two copies of the `deprecated` attribute 
after we instantiate the class definition -- one from instantiating the 
declaration and another from instantiating the definition. Perhaps a better way 
to handle this would be to add a flag to the attribute definitions (in Attr.td) 
to indicate whether they apply to a declaration or just a definition (and thus 
whether they should be instantiated with a declaration, or only with a 
definition), and then instantiate the relevant subset when creating the 
`ClassTemplateSpecializationDecl` (and other kinds of decl -- I expect the same 
thing will happen for member classes of class templates, for function 
templates, and so on).

@aaron.ballman Does that seem reasonable to you? If so, we should do some 
investigation of the attribute set to figure out what the best default is.


https://reviews.llvm.org/D27486



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D27486: Correct class-template deprecation behavior

2016-12-06 Thread Erich Keane via Phabricator via cfe-commits
erichkeane removed rL LLVM as the repository for this revision.
erichkeane updated this revision to Diff 80489.
erichkeane added a comment.

Corrected single line statement formatting re-squiggly braces.


https://reviews.llvm.org/D27486

Files:
  lib/Sema/SemaTemplate.cpp
  test/CXX/dcl.dcl/dcl.attr/dcl.attr.deprecated/p1.cpp


Index: lib/Sema/SemaTemplate.cpp
===
--- lib/Sema/SemaTemplate.cpp
+++ lib/Sema/SemaTemplate.cpp
@@ -2352,6 +2352,9 @@
 ClassTemplate->getLocation(),
  ClassTemplate,
  Converted, nullptr);
+  if (auto *attr = ClassTemplate->getTemplatedDecl()
+   ->getAttr())
+Decl->addAttr(attr->clone(Context));
   ClassTemplate->AddSpecialization(Decl, InsertPos);
   if (ClassTemplate->isOutOfLine())
 Decl->setLexicalDeclContext(ClassTemplate->getLexicalDeclContext());
Index: test/CXX/dcl.dcl/dcl.attr/dcl.attr.deprecated/p1.cpp
===
--- test/CXX/dcl.dcl/dcl.attr/dcl.attr.deprecated/p1.cpp
+++ test/CXX/dcl.dcl/dcl.attr/dcl.attr.deprecated/p1.cpp
@@ -23,7 +23,8 @@
 X x1;
 X x2; // expected-warning {{'X' is deprecated}}
 
-template  class [[deprecated]] X2 {};
+template  class [[deprecated]] X2 {}; //expected-note {{'X2' 
has been explicitly marked deprecated here}}
 template <> class X2 {};
-X2 x3; // FIXME: no warning!
-X2 x4;
+X2 x3; // expected-warning {{'X2' is deprecated}}
+X2 x4; // No warning, the specialization removes it.
+


Index: lib/Sema/SemaTemplate.cpp
===
--- lib/Sema/SemaTemplate.cpp
+++ lib/Sema/SemaTemplate.cpp
@@ -2352,6 +2352,9 @@
 ClassTemplate->getLocation(),
  ClassTemplate,
  Converted, nullptr);
+  if (auto *attr = ClassTemplate->getTemplatedDecl()
+   ->getAttr())
+Decl->addAttr(attr->clone(Context));
   ClassTemplate->AddSpecialization(Decl, InsertPos);
   if (ClassTemplate->isOutOfLine())
 Decl->setLexicalDeclContext(ClassTemplate->getLexicalDeclContext());
Index: test/CXX/dcl.dcl/dcl.attr/dcl.attr.deprecated/p1.cpp
===
--- test/CXX/dcl.dcl/dcl.attr/dcl.attr.deprecated/p1.cpp
+++ test/CXX/dcl.dcl/dcl.attr/dcl.attr.deprecated/p1.cpp
@@ -23,7 +23,8 @@
 X x1;
 X x2; // expected-warning {{'X' is deprecated}}
 
-template  class [[deprecated]] X2 {};
+template  class [[deprecated]] X2 {}; //expected-note {{'X2' has been explicitly marked deprecated here}}
 template <> class X2 {};
-X2 x3; // FIXME: no warning!
-X2 x4;
+X2 x3; // expected-warning {{'X2' is deprecated}}
+X2 x4; // No warning, the specialization removes it.
+
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D27486: Correct class-template deprecation behavior

2016-12-06 Thread Erich Keane via Phabricator via cfe-commits
erichkeane created this revision.
erichkeane added reviewers: cfe-commits, chandlerc, majnemer.
erichkeane set the repository for this revision to rL LLVM.

Based on the comment in the test, and my reading of the standard, a deprecated 
warning should be issued in the following case:
template [[deprecated]] class Foo{};  Foo 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.


Repository:
  rL LLVM

https://reviews.llvm.org/D27486

Files:
  lib/Sema/SemaTemplate.cpp
  test/CXX/dcl.dcl/dcl.attr/dcl.attr.deprecated/p1.cpp


Index: lib/Sema/SemaTemplate.cpp
===
--- lib/Sema/SemaTemplate.cpp
+++ lib/Sema/SemaTemplate.cpp
@@ -2352,6 +2352,10 @@
 ClassTemplate->getLocation(),
  ClassTemplate,
  Converted, nullptr);
+  if (auto *attr = ClassTemplate->getTemplatedDecl()
+   ->getAttr()) {
+Decl->addAttr(attr->clone(Context));
+  }
   ClassTemplate->AddSpecialization(Decl, InsertPos);
   if (ClassTemplate->isOutOfLine())
 Decl->setLexicalDeclContext(ClassTemplate->getLexicalDeclContext());
Index: test/CXX/dcl.dcl/dcl.attr/dcl.attr.deprecated/p1.cpp
===
--- test/CXX/dcl.dcl/dcl.attr/dcl.attr.deprecated/p1.cpp
+++ test/CXX/dcl.dcl/dcl.attr/dcl.attr.deprecated/p1.cpp
@@ -23,7 +23,8 @@
 X x1;
 X x2; // expected-warning {{'X' is deprecated}}
 
-template  class [[deprecated]] X2 {};
+template  class [[deprecated]] X2 {}; //expected-note {{'X2' 
has been explicitly marked deprecated here}}
 template <> class X2 {};
-X2 x3; // FIXME: no warning!
-X2 x4;
+X2 x3; // expected-warning {{'X2' is deprecated}}
+X2 x4; // No warning, the specialization removes it.
+


Index: lib/Sema/SemaTemplate.cpp
===
--- lib/Sema/SemaTemplate.cpp
+++ lib/Sema/SemaTemplate.cpp
@@ -2352,6 +2352,10 @@
 ClassTemplate->getLocation(),
  ClassTemplate,
  Converted, nullptr);
+  if (auto *attr = ClassTemplate->getTemplatedDecl()
+   ->getAttr()) {
+Decl->addAttr(attr->clone(Context));
+  }
   ClassTemplate->AddSpecialization(Decl, InsertPos);
   if (ClassTemplate->isOutOfLine())
 Decl->setLexicalDeclContext(ClassTemplate->getLexicalDeclContext());
Index: test/CXX/dcl.dcl/dcl.attr/dcl.attr.deprecated/p1.cpp
===
--- test/CXX/dcl.dcl/dcl.attr/dcl.attr.deprecated/p1.cpp
+++ test/CXX/dcl.dcl/dcl.attr/dcl.attr.deprecated/p1.cpp
@@ -23,7 +23,8 @@
 X x1;
 X x2; // expected-warning {{'X' is deprecated}}
 
-template  class [[deprecated]] X2 {};
+template  class [[deprecated]] X2 {}; //expected-note {{'X2' has been explicitly marked deprecated here}}
 template <> class X2 {};
-X2 x3; // FIXME: no warning!
-X2 x4;
+X2 x3; // expected-warning {{'X2' is deprecated}}
+X2 x4; // No warning, the specialization removes it.
+
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits