summaryrefslogtreecommitdiff
path: root/lib/Sema
diff options
context:
space:
mode:
authorAaron Ballman <aaron@aaronballman.com>2014-11-14 22:34:56 +0000
committerAaron Ballman <aaron@aaronballman.com>2014-11-14 22:34:56 +0000
commit00dccd63cd9db239052a06b113eb28c9b66144fc (patch)
treee84fa7df43d40c96bb885c8c2d6b89c7d2fc3f94 /lib/Sema
parent769c06275fe928e97a21c32cf2edc60bb7a0d16d (diff)
downloadclang-00dccd63cd9db239052a06b113eb28c9b66144fc.tar.gz
[c++1z] Support [[deprecated]] attributes on namespaces. Note that it only applies to situations where the namespace is mentioned. Thus, use on anonymous namespaces is diagnosed.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@222054 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema')
-rw-r--r--lib/Sema/SemaCXXScopeSpec.cpp4
-rw-r--r--lib/Sema/SemaDeclAttr.cpp22
-rw-r--r--lib/Sema/SemaDeclCXX.cpp13
3 files changed, 32 insertions, 7 deletions
diff --git a/lib/Sema/SemaCXXScopeSpec.cpp b/lib/Sema/SemaCXXScopeSpec.cpp
index 0193e80a75..49e8a155c3 100644
--- a/lib/Sema/SemaCXXScopeSpec.cpp
+++ b/lib/Sema/SemaCXXScopeSpec.cpp
@@ -652,6 +652,10 @@ bool Sema::BuildCXXNestedNameSpecifier(Scope *S,
// don't extend the nested-name-specifier. Just return now.
if (ErrorRecoveryLookup)
return false;
+
+ // The use of a nested name specifier may trigger deprecation warnings.
+ DiagnoseUseOfDecl(SD, CCLoc);
+
if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(SD)) {
SS.Extend(Context, Namespace, IdentifierLoc, CCLoc);
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index 1b04e52f15..00f9f80328 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -4139,6 +4139,19 @@ static void handleRequiresCapabilityAttr(Sema &S, Decl *D,
D->addAttr(RCA);
}
+static void handleDeprecatedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
+ if (auto *NSD = dyn_cast<NamespaceDecl>(D)) {
+ if (NSD->isAnonymousNamespace()) {
+ S.Diag(Attr.getLoc(), diag::warn_deprecated_anonymous_namespace);
+ // Do not want to attach the attribute to the namespace because that will
+ // cause confusing diagnostic reports for uses of declarations within the
+ // namespace.
+ return;
+ }
+ }
+ handleAttrWithMessage<DeprecatedAttr>(S, D, Attr);
+}
+
/// Handles semantic checking for features that are common to all attributes,
/// such as checking whether a parameter was properly specified, or the correct
/// number of arguments were passed, etc.
@@ -4283,7 +4296,7 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
handleSimpleAttribute<CXX11NoReturnAttr>(S, D, Attr);
break;
case AttributeList::AT_Deprecated:
- handleAttrWithMessage<DeprecatedAttr>(S, D, Attr);
+ handleDeprecatedAttr(S, D, Attr);
break;
case AttributeList::AT_Destructor:
handleDestructorAttr(S, D, Attr);
@@ -4994,19 +5007,18 @@ static void DoEmitAvailabilityWarning(Sema &S, DelayedDiagnostic::DDKind K,
llvm_unreachable("Neither a deprecation or unavailable kind");
}
- DeclarationName Name = D->getDeclName();
if (!Message.empty()) {
- S.Diag(Loc, diag_message) << Name << Message;
+ S.Diag(Loc, diag_message) << D << Message;
if (ObjCProperty)
S.Diag(ObjCProperty->getLocation(), diag::note_property_attribute)
<< ObjCProperty->getDeclName() << property_note_select;
} else if (!UnknownObjCClass) {
- S.Diag(Loc, diag) << Name;
+ S.Diag(Loc, diag) << D;
if (ObjCProperty)
S.Diag(ObjCProperty->getLocation(), diag::note_property_attribute)
<< ObjCProperty->getDeclName() << property_note_select;
} else {
- S.Diag(Loc, diag_fwdclass_message) << Name;
+ S.Diag(Loc, diag_fwdclass_message) << D;
S.Diag(UnknownObjCClass->getLocation(), diag::note_forward_class);
}
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 0bd1222454..c960f54b94 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -7404,6 +7404,10 @@ Decl *Sema::ActOnUsingDirective(Scope *S,
NamedDecl *Named = R.getFoundDecl();
assert((isa<NamespaceDecl>(Named) || isa<NamespaceAliasDecl>(Named))
&& "expected namespace decl");
+
+ // The use of a nested name specifier may trigger deprecation warnings.
+ DiagnoseUseOfDecl(Named, IdentLoc);
+
// C++ [namespace.udir]p1:
// A using-directive specifies that the names in the nominated
// namespace can be used in the scope in which the
@@ -8494,11 +8498,13 @@ Decl *Sema::ActOnNamespaceAliasDef(Scope *S, SourceLocation NamespaceLoc,
if (PrevDecl && !isDeclInScope(PrevDecl, CurContext, S))
PrevDecl = nullptr;
+ NamedDecl *ND = R.getFoundDecl();
+
if (PrevDecl) {
if (NamespaceAliasDecl *AD = dyn_cast<NamespaceAliasDecl>(PrevDecl)) {
// We already have an alias with the same name that points to the same
// namespace; check that it matches.
- if (!AD->getNamespace()->Equals(getNamespaceDecl(R.getFoundDecl()))) {
+ if (!AD->getNamespace()->Equals(getNamespaceDecl(ND))) {
Diag(AliasLoc, diag::err_redefinition_different_namespace_alias)
<< Alias;
Diag(PrevDecl->getLocation(), diag::note_previous_namespace_alias)
@@ -8515,10 +8521,13 @@ Decl *Sema::ActOnNamespaceAliasDef(Scope *S, SourceLocation NamespaceLoc,
}
}
+ // The use of a nested name specifier may trigger deprecation warnings.
+ DiagnoseUseOfDecl(ND, IdentLoc);
+
NamespaceAliasDecl *AliasDecl =
NamespaceAliasDecl::Create(Context, CurContext, NamespaceLoc, AliasLoc,
Alias, SS.getWithLocInContext(Context),
- IdentLoc, R.getFoundDecl());
+ IdentLoc, ND);
if (PrevDecl)
AliasDecl->setPreviousDecl(cast<NamespaceAliasDecl>(PrevDecl));