diff options
author | John McCall <rjmccall@apple.com> | 2010-01-27 03:50:35 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2010-01-27 03:50:35 +0000 |
commit | 86121519cadca11d8865ec713e248a8740657618 (patch) | |
tree | c9b849cfd03d6b3c9ec755b0a0c6aa40eef3cc71 /clang/lib/Sema/SemaDeclAttr.cpp | |
parent | e437c6870abf78b708aa270d4bb2e683a79fd09f (diff) | |
download | bcm5719-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.cpp | 67 |
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; } |