RAIIObjectsForParser.h revision 221345
1234285Sdim//===--- RAIIObjectsForParser.h - RAII helpers for the parser ---*- C++ -*-===//
2234285Sdim//
3234285Sdim//                     The LLVM Compiler Infrastructure
4234285Sdim//
5234285Sdim// This file is distributed under the University of Illinois Open Source
6234285Sdim// License. See LICENSE.TXT for details.
7234285Sdim//
8234285Sdim//===----------------------------------------------------------------------===//
9234285Sdim//
10234285Sdim// This file defines and implements the some simple RAII objects that are used
11234285Sdim// by the parser to manage bits in recursion.
12234285Sdim//
13234285Sdim//===----------------------------------------------------------------------===//
14234285Sdim
15234285Sdim#ifndef LLVM_CLANG_PARSE_RAII_OBJECTS_FOR_PARSER_H
16234285Sdim#define LLVM_CLANG_PARSE_RAII_OBJECTS_FOR_PARSER_H
17234285Sdim
18234285Sdim#include "clang/Parse/ParseDiagnostic.h"
19263508Sdim
20249423Sdimnamespace clang {
21249423Sdim  // TODO: move ParsingDeclRAIIObject here.
22263508Sdim  // TODO: move ParsingClassDefinition here.
23234285Sdim  // TODO: move TentativeParsingAction here.
24234285Sdim
25234285Sdim
26234285Sdim  /// ExtensionRAIIObject - This saves the state of extension warnings when
27263508Sdim  /// constructed and disables them.  When destructed, it restores them back to
28249423Sdim  /// the way they used to be.  This is used to handle __extension__ in the
29249423Sdim  /// parser.
30249423Sdim  class ExtensionRAIIObject {
31234285Sdim    void operator=(const ExtensionRAIIObject &);     // DO NOT IMPLEMENT
32234285Sdim    ExtensionRAIIObject(const ExtensionRAIIObject&); // DO NOT IMPLEMENT
33234285Sdim    Diagnostic &Diags;
34234285Sdim  public:
35263508Sdim    ExtensionRAIIObject(Diagnostic &diags) : Diags(diags) {
36249423Sdim      Diags.IncrementAllExtensionsSilenced();
37263508Sdim    }
38263508Sdim
39263508Sdim    ~ExtensionRAIIObject() {
40263508Sdim      Diags.DecrementAllExtensionsSilenced();
41234285Sdim    }
42234285Sdim  };
43234285Sdim
44234285Sdim  /// ColonProtectionRAIIObject - This sets the Parser::ColonIsSacred bool and
45263508Sdim  /// restores it when destroyed.  This says that "foo:" should not be
46249423Sdim  /// considered a possible typo for "foo::" for error recovery purposes.
47263508Sdim  class ColonProtectionRAIIObject {
48263508Sdim    Parser &P;
49263508Sdim    bool OldVal;
50263508Sdim  public:
51234285Sdim    ColonProtectionRAIIObject(Parser &p, bool Value = true)
52234285Sdim      : P(p), OldVal(P.ColonIsSacred) {
53234285Sdim      P.ColonIsSacred = Value;
54234285Sdim    }
55234285Sdim
56234285Sdim    /// restore - This can be used to restore the state early, before the dtor
57234285Sdim    /// is run.
58234285Sdim    void restore() {
59239462Sdim      P.ColonIsSacred = OldVal;
60239462Sdim    }
61249423Sdim
62249423Sdim    ~ColonProtectionRAIIObject() {
63249423Sdim      restore();
64249423Sdim    }
65249423Sdim  };
66249423Sdim
67249423Sdim  /// \brief RAII object that makes '>' behave either as an operator
68249423Sdim  /// or as the closing angle bracket for a template argument list.
69249423Sdim  class GreaterThanIsOperatorScope {
70249423Sdim    bool &GreaterThanIsOperator;
71249423Sdim    bool OldGreaterThanIsOperator;
72249423Sdim  public:
73249423Sdim    GreaterThanIsOperatorScope(bool &GTIO, bool Val)
74249423Sdim    : GreaterThanIsOperator(GTIO), OldGreaterThanIsOperator(GTIO) {
75249423Sdim      GreaterThanIsOperator = Val;
76249423Sdim    }
77249423Sdim
78234285Sdim    ~GreaterThanIsOperatorScope() {
79234285Sdim      GreaterThanIsOperator = OldGreaterThanIsOperator;
80234285Sdim    }
81234285Sdim  };
82239462Sdim
83239462Sdim  class InMessageExpressionRAIIObject {
84239462Sdim    bool &InMessageExpression;
85239462Sdim    bool OldValue;
86234285Sdim
87234285Sdim  public:
88239462Sdim    InMessageExpressionRAIIObject(Parser &P, bool Value)
89239462Sdim      : InMessageExpression(P.InMessageExpression),
90239462Sdim        OldValue(P.InMessageExpression) {
91239462Sdim      InMessageExpression = Value;
92239462Sdim    }
93239462Sdim
94239462Sdim    ~InMessageExpressionRAIIObject() {
95234285Sdim      InMessageExpression = OldValue;
96234285Sdim    }
97239462Sdim  };
98239462Sdim
99239462Sdim  /// \brief RAII object that makes sure paren/bracket/brace count is correct
100239462Sdim  /// after declaration/statement parsing, even when there's a parsing error.
101239462Sdim  class ParenBraceBracketBalancer {
102239462Sdim    Parser &P;
103234285Sdim    unsigned short ParenCount, BracketCount, BraceCount;
104234285Sdim  public:
105234285Sdim    ParenBraceBracketBalancer(Parser &p)
106263508Sdim      : P(p), ParenCount(p.ParenCount), BracketCount(p.BracketCount),
107249423Sdim        BraceCount(p.BraceCount) { }
108263508Sdim
109263508Sdim    ~ParenBraceBracketBalancer() {
110263508Sdim      P.ParenCount = ParenCount;
111249423Sdim      P.BracketCount = BracketCount;
112263508Sdim      P.BraceCount = BraceCount;
113263508Sdim    }
114263508Sdim  };
115263508Sdim
116234285Sdim  class PoisonSEHIdentifiersRAIIObject {
117234285Sdim    PoisonIdentifierRAIIObject Ident_AbnormalTermination;
118263508Sdim    PoisonIdentifierRAIIObject Ident_GetExceptionCode;
119249423Sdim    PoisonIdentifierRAIIObject Ident_GetExceptionInfo;
120263508Sdim    PoisonIdentifierRAIIObject Ident__abnormal_termination;
121263508Sdim    PoisonIdentifierRAIIObject Ident__exception_code;
122263508Sdim    PoisonIdentifierRAIIObject Ident__exception_info;
123249423Sdim    PoisonIdentifierRAIIObject Ident___abnormal_termination;
124263508Sdim    PoisonIdentifierRAIIObject Ident___exception_code;
125263508Sdim    PoisonIdentifierRAIIObject Ident___exception_info;
126263508Sdim  public:
127263508Sdim    PoisonSEHIdentifiersRAIIObject(Parser &Self, bool NewValue)
128234285Sdim      : Ident_AbnormalTermination(Self.Ident_AbnormalTermination, NewValue),
129234285Sdim        Ident_GetExceptionCode(Self.Ident_GetExceptionCode, NewValue),
130263508Sdim        Ident_GetExceptionInfo(Self.Ident_GetExceptionInfo, NewValue),
131249423Sdim        Ident__abnormal_termination(Self.Ident__abnormal_termination, NewValue),
132234285Sdim        Ident__exception_code(Self.Ident__exception_code, NewValue),
133263508Sdim        Ident__exception_info(Self.Ident__exception_info, NewValue),
134263508Sdim        Ident___abnormal_termination(Self.Ident___abnormal_termination, NewValue),
135263508Sdim        Ident___exception_code(Self.Ident___exception_code, NewValue),
136263508Sdim        Ident___exception_info(Self.Ident___exception_info, NewValue) {
137263508Sdim    }
138249423Sdim  };
139234285Sdim
140263508Sdim} // end namespace clang
141263508Sdim
142263508Sdim#endif
143263508Sdim