aboutsummaryrefslogtreecommitdiff
path: root/lib/Parse/RAIIObjectsForParser.h
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2012-05-07 06:16:58 +0000
committerJohn McCall <rjmccall@apple.com>2012-05-07 06:16:58 +0000
commit13489673b84fafaaf49cf5ae4e3bb9a945524dcb (patch)
tree992446022621abc50aac6bed76ada78854358068 /lib/Parse/RAIIObjectsForParser.h
parent3f152e65074b70e8c13c876ed8b552cb1e6194d7 (diff)
Change how we suppress access control in explicit instantiations
so that we actually accumulate all the delayed diagnostics. Do this so that we can restore those diagnostics to good standing if it turns out that we were wrong to suppress, e.g. if the tag specifier is actually an elaborated type specifier and not a declaration. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@156291 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse/RAIIObjectsForParser.h')
-rw-r--r--lib/Parse/RAIIObjectsForParser.h64
1 files changed, 58 insertions, 6 deletions
diff --git a/lib/Parse/RAIIObjectsForParser.h b/lib/Parse/RAIIObjectsForParser.h
index f5a6f8fcf9..64431276bf 100644
--- a/lib/Parse/RAIIObjectsForParser.h
+++ b/lib/Parse/RAIIObjectsForParser.h
@@ -24,6 +24,59 @@ namespace clang {
// TODO: move ParsingClassDefinition here.
// TODO: move TentativeParsingAction here.
+ /// \brief A RAII object used to temporarily suppress access-like
+ /// checking. Access-like checks are those associated with
+ /// controlling the use of a declaration, like C++ access control
+ /// errors and deprecation warnings. They are contextually
+ /// dependent, in that they can only be resolved with full
+ /// information about what's being declared. They are also
+ /// suppressed in certain contexts, like the template arguments of
+ /// an explicit instantiation. However, those suppression contexts
+ /// cannot necessarily be fully determined in advance; for
+ /// example, something starting like this:
+ /// template <> class std::vector<A::PrivateType>
+ /// might be the entirety of an explicit instantiation:
+ /// template <> class std::vector<A::PrivateType>;
+ /// or just an elaborated type specifier:
+ /// template <> class std::vector<A::PrivateType> make_vector<>();
+ /// Therefore this class collects all the diagnostics and permits
+ /// them to be re-delayed in a new context.
+ class SuppressAccessChecks {
+ Sema &S;
+ sema::DelayedDiagnosticPool DiagnosticPool;
+ Sema::ParsingDeclState State;
+ bool Active;
+
+ public:
+ /// Begin suppressing access-like checks
+ SuppressAccessChecks(Parser &P, bool activate = true)
+ : S(P.getActions()), DiagnosticPool(NULL) {
+ if (activate) {
+ State = S.PushParsingDeclaration(DiagnosticPool);
+ Active = true;
+ } else {
+ Active = false;
+ }
+ }
+
+ void done() {
+ assert(Active && "trying to end an inactive suppression");
+ S.PopParsingDeclaration(State, NULL);
+ Active = false;
+ }
+
+ void redelay() {
+ assert(!Active && "redelaying without having ended first");
+ if (!DiagnosticPool.pool_empty())
+ S.redelayDiagnostics(DiagnosticPool);
+ assert(DiagnosticPool.pool_empty());
+ }
+
+ ~SuppressAccessChecks() {
+ if (Active) done();
+ }
+ };
+
/// \brief RAII object used to inform the actions that we're
/// currently parsing a declaration. This is active when parsing a
/// variable's initializer, but not when parsing the body of a
@@ -93,14 +146,13 @@ namespace clang {
pop(D);
}
- private:
- void steal(ParsingDeclRAIIObject &Other) {
- DiagnosticPool.steal(Other.DiagnosticPool);
- State = Other.State;
- Popped = Other.Popped;
- Other.Popped = true;
+ /// Unregister this object from Sema, but remember all the
+ /// diagnostics that were emitted into it.
+ void abortAndRemember() {
+ pop(0);
}
+ private:
void push() {
State = Actions.PushParsingDeclaration(DiagnosticPool);
Popped = false;