summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema
diff options
context:
space:
mode:
authorErich Keane <erich.keane@intel.com>2017-03-21 17:49:17 +0000
committerErich Keane <erich.keane@intel.com>2017-03-21 17:49:17 +0000
commit8a8f5f0f00d7c0842871f180c80883e87304f653 (patch)
tree0894364e7dd1bb1ca78942a9e1d022578098d5c9 /clang/lib/Sema
parenta1e3d08666f4daa714218d073ab2828fd2131928 (diff)
downloadbcm5719-llvm-8a8f5f0f00d7c0842871f180c80883e87304f653.tar.gz
bcm5719-llvm-8a8f5f0f00d7c0842871f180c80883e87304f653.zip
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. Differential Revision: https://reviews.llvm.org/D27486 llvm-svn: 298410
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r--clang/lib/Sema/SemaDeclAttr.cpp5
-rw-r--r--clang/lib/Sema/SemaTemplate.cpp7
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiate.cpp3
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiateDecl.cpp32
4 files changed, 45 insertions, 2 deletions
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 1c350a7e38b..b3dc71987f8 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -6723,6 +6723,7 @@ 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;
@@ -6745,6 +6746,8 @@ 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:
@@ -6863,7 +6866,7 @@ static void DoEmitAvailabilityWarning(Sema &S, AvailabilityResult K,
}
}
else
- S.Diag(D->getLocation(), diag_available_here)
+ S.Diag(NoteLocation, diag_available_here)
<< D << available_here_select_kind;
if (K == AR_NotYetIntroduced)
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index f6c6ccbd410..16993192387 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -2846,6 +2846,13 @@ 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);
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 314dfe32561..67e330a6da9 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -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);
}
}
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index cab55ea0bf7..6a4e5324b25 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -328,6 +328,35 @@ 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,
@@ -421,7 +450,8 @@ void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs,
Attr *NewAttr = sema::instantiateTemplateAttribute(TmplAttr, Context,
*this, TemplateArgs);
- if (NewAttr)
+
+ if (NewAttr && !DeclContainsAttr(New, NewAttr->getKind()))
New->addAttr(NewAttr);
}
}
OpenPOWER on IntegriCloud