1 //===--- RAIIObjectsForParser.h - RAII helpers for the parser ---*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file defines and implements the some simple RAII objects that are used 11 // by the parser to manage bits in recursion. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #ifndef LLVM_CLANG_PARSE_RAII_OBJECTS_FOR_PARSER_H 16 #define LLVM_CLANG_PARSE_RAII_OBJECTS_FOR_PARSER_H 17 18 #include "clang/Parse/ParseDiagnostic.h" 19 20 namespace clang { 21 // TODO: move ParsingDeclRAIIObject here. 22 // TODO: move ParsingClassDefinition here. 23 // TODO: move TentativeParsingAction here. 24 25 26 /// ExtensionRAIIObject - This saves the state of extension warnings when 27 /// constructed and disables them. When destructed, it restores them back to 28 /// the way they used to be. This is used to handle __extension__ in the 29 /// parser. 30 class ExtensionRAIIObject { 31 void operator=(const ExtensionRAIIObject &); // DO NOT IMPLEMENT 32 ExtensionRAIIObject(const ExtensionRAIIObject&); // DO NOT IMPLEMENT 33 DiagnosticsEngine &Diags; 34 public: 35 ExtensionRAIIObject(DiagnosticsEngine &diags) : Diags(diags) { 36 Diags.IncrementAllExtensionsSilenced(); 37 } 38 39 ~ExtensionRAIIObject() { 40 Diags.DecrementAllExtensionsSilenced(); 41 } 42 }; 43 44 /// ColonProtectionRAIIObject - This sets the Parser::ColonIsSacred bool and 45 /// restores it when destroyed. This says that "foo:" should not be 46 /// considered a possible typo for "foo::" for error recovery purposes. 47 class ColonProtectionRAIIObject { 48 Parser &P; 49 bool OldVal; 50 public: 51 ColonProtectionRAIIObject(Parser &p, bool Value = true) 52 : P(p), OldVal(P.ColonIsSacred) { 53 P.ColonIsSacred = Value; 54 } 55 56 /// restore - This can be used to restore the state early, before the dtor 57 /// is run. 58 void restore() { 59 P.ColonIsSacred = OldVal; 60 } 61 62 ~ColonProtectionRAIIObject() { 63 restore(); 64 } 65 }; 66 67 /// \brief RAII object that makes '>' behave either as an operator 68 /// or as the closing angle bracket for a template argument list. 69 class GreaterThanIsOperatorScope { 70 bool &GreaterThanIsOperator; 71 bool OldGreaterThanIsOperator; 72 public: 73 GreaterThanIsOperatorScope(bool >IO, bool Val) 74 : GreaterThanIsOperator(GTIO), OldGreaterThanIsOperator(GTIO) { 75 GreaterThanIsOperator = Val; 76 } 77 78 ~GreaterThanIsOperatorScope() { 79 GreaterThanIsOperator = OldGreaterThanIsOperator; 80 } 81 }; 82 83 class InMessageExpressionRAIIObject { 84 bool &InMessageExpression; 85 bool OldValue; 86 87 public: 88 InMessageExpressionRAIIObject(Parser &P, bool Value) 89 : InMessageExpression(P.InMessageExpression), 90 OldValue(P.InMessageExpression) { 91 InMessageExpression = Value; 92 } 93 94 ~InMessageExpressionRAIIObject() { 95 InMessageExpression = OldValue; 96 } 97 }; 98 99 /// \brief RAII object that makes sure paren/bracket/brace count is correct 100 /// after declaration/statement parsing, even when there's a parsing error. 101 class ParenBraceBracketBalancer { 102 Parser &P; 103 unsigned short ParenCount, BracketCount, BraceCount; 104 public: 105 ParenBraceBracketBalancer(Parser &p) 106 : P(p), ParenCount(p.ParenCount), BracketCount(p.BracketCount), 107 BraceCount(p.BraceCount) { } 108 109 ~ParenBraceBracketBalancer() { 110 P.ParenCount = ParenCount; 111 P.BracketCount = BracketCount; 112 P.BraceCount = BraceCount; 113 } 114 }; 115 116 class PoisonSEHIdentifiersRAIIObject { 117 PoisonIdentifierRAIIObject Ident_AbnormalTermination; 118 PoisonIdentifierRAIIObject Ident_GetExceptionCode; 119 PoisonIdentifierRAIIObject Ident_GetExceptionInfo; 120 PoisonIdentifierRAIIObject Ident__abnormal_termination; 121 PoisonIdentifierRAIIObject Ident__exception_code; 122 PoisonIdentifierRAIIObject Ident__exception_info; 123 PoisonIdentifierRAIIObject Ident___abnormal_termination; 124 PoisonIdentifierRAIIObject Ident___exception_code; 125 PoisonIdentifierRAIIObject Ident___exception_info; 126 public: 127 PoisonSEHIdentifiersRAIIObject(Parser &Self, bool NewValue) 128 : Ident_AbnormalTermination(Self.Ident_AbnormalTermination, NewValue), 129 Ident_GetExceptionCode(Self.Ident_GetExceptionCode, NewValue), 130 Ident_GetExceptionInfo(Self.Ident_GetExceptionInfo, NewValue), 131 Ident__abnormal_termination(Self.Ident__abnormal_termination, NewValue), 132 Ident__exception_code(Self.Ident__exception_code, NewValue), 133 Ident__exception_info(Self.Ident__exception_info, NewValue), 134 Ident___abnormal_termination(Self.Ident___abnormal_termination, NewValue), 135 Ident___exception_code(Self.Ident___exception_code, NewValue), 136 Ident___exception_info(Self.Ident___exception_info, NewValue) { 137 } 138 }; 139 140 } // end namespace clang 141 142 #endif 143