summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaDeclAttr.cpp
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2010-01-27 03:50:35 +0000
committerJohn McCall <rjmccall@apple.com>2010-01-27 03:50:35 +0000
commit86121519cadca11d8865ec713e248a8740657618 (patch)
treec9b849cfd03d6b3c9ec755b0a0c6aa40eef3cc71 /clang/lib/Sema/SemaDeclAttr.cpp
parente437c6870abf78b708aa270d4bb2e683a79fd09f (diff)
downloadbcm5719-llvm-86121519cadca11d8865ec713e248a8740657618.tar.gz
bcm5719-llvm-86121519cadca11d8865ec713e248a8740657618.zip
Implement access-check delays for out-of-line member definitions
using the same framework we use for deprecation warnings. llvm-svn: 94659
Diffstat (limited to 'clang/lib/Sema/SemaDeclAttr.cpp')
-rw-r--r--clang/lib/Sema/SemaDeclAttr.cpp67
1 files changed, 45 insertions, 22 deletions
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 40169b635d4..a391a0eaed1 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -2067,48 +2067,71 @@ void Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD) {
/// on the warning stack.
Action::ParsingDeclStackState Sema::PushParsingDeclaration() {
ParsingDeclDepth++;
- return (ParsingDeclStackState) DelayedDeprecationWarnings.size();
-}
-
-static bool isDeclDeprecated(Decl *D) {
- do {
- if (D->hasAttr<DeprecatedAttr>())
- return true;
- } while ((D = cast_or_null<Decl>(D->getDeclContext())));
- return false;
+ return (ParsingDeclStackState) DelayedDiagnostics.size();
}
void Sema::PopParsingDeclaration(ParsingDeclStackState S, DeclPtrTy Ctx) {
assert(ParsingDeclDepth > 0 && "empty ParsingDeclaration stack");
ParsingDeclDepth--;
- if (DelayedDeprecationWarnings.empty())
+ if (DelayedDiagnostics.empty())
return;
unsigned SavedIndex = (unsigned) S;
- assert(SavedIndex <= DelayedDeprecationWarnings.size() &&
+ assert(SavedIndex <= DelayedDiagnostics.size() &&
"saved index is out of bounds");
- if (Ctx && !isDeclDeprecated(Ctx.getAs<Decl>())) {
- for (unsigned I = 0, E = DelayedDeprecationWarnings.size(); I != E; ++I) {
- SourceLocation Loc = DelayedDeprecationWarnings[I].first;
- NamedDecl *&ND = DelayedDeprecationWarnings[I].second;
- if (ND) {
- Diag(Loc, diag::warn_deprecated) << ND->getDeclName();
-
- // Prevent this from triggering multiple times.
- ND = 0;
+ // We only want to actually emit delayed diagnostics when we
+ // successfully parsed a decl.
+ Decl *D = Ctx ? Ctx.getAs<Decl>() : 0;
+ if (D) {
+ // We really do want to start with 0 here. We get one push for a
+ // decl spec and another for each declarator; in a decl group like:
+ // deprecated_typedef foo, *bar, baz();
+ // only the declarator pops will be passed decls. This is correct;
+ // we really do need to consider delayed diagnostics from the decl spec
+ // for each of the different declarations.
+ for (unsigned I = 0, E = DelayedDiagnostics.size(); I != E; ++I) {
+ if (DelayedDiagnostics[I].Triggered)
+ continue;
+
+ switch (DelayedDiagnostics[I].Kind) {
+ case DelayedDiagnostic::Deprecation:
+ HandleDelayedDeprecationCheck(DelayedDiagnostics[I], D);
+ break;
+
+ case DelayedDiagnostic::Access:
+ HandleDelayedAccessCheck(DelayedDiagnostics[I], D);
+ break;
}
}
}
- DelayedDeprecationWarnings.set_size(SavedIndex);
+ DelayedDiagnostics.set_size(SavedIndex);
+}
+
+static bool isDeclDeprecated(Decl *D) {
+ do {
+ if (D->hasAttr<DeprecatedAttr>())
+ return true;
+ } while ((D = cast_or_null<Decl>(D->getDeclContext())));
+ return false;
+}
+
+void Sema::HandleDelayedDeprecationCheck(Sema::DelayedDiagnostic &DD,
+ Decl *Ctx) {
+ if (isDeclDeprecated(Ctx))
+ return;
+
+ DD.Triggered = true;
+ Diag(DD.Loc, diag::warn_deprecated)
+ << DD.DeprecationData.Decl->getDeclName();
}
void Sema::EmitDeprecationWarning(NamedDecl *D, SourceLocation Loc) {
// Delay if we're currently parsing a declaration.
if (ParsingDeclDepth) {
- DelayedDeprecationWarnings.push_back(std::make_pair(Loc, D));
+ DelayedDiagnostics.push_back(DelayedDiagnostic::makeDeprecation(Loc, D));
return;
}
OpenPOWER on IntegriCloud