1*67e74705SXin Li //===--- RAIIObjectsForParser.h - RAII helpers for the parser ---*- C++ -*-===// 2*67e74705SXin Li // 3*67e74705SXin Li // The LLVM Compiler Infrastructure 4*67e74705SXin Li // 5*67e74705SXin Li // This file is distributed under the University of Illinois Open Source 6*67e74705SXin Li // License. See LICENSE.TXT for details. 7*67e74705SXin Li // 8*67e74705SXin Li //===----------------------------------------------------------------------===// 9*67e74705SXin Li // 10*67e74705SXin Li // This file defines and implements the some simple RAII objects that are used 11*67e74705SXin Li // by the parser to manage bits in recursion. 12*67e74705SXin Li // 13*67e74705SXin Li //===----------------------------------------------------------------------===// 14*67e74705SXin Li 15*67e74705SXin Li #ifndef LLVM_CLANG_LIB_PARSE_RAIIOBJECTSFORPARSER_H 16*67e74705SXin Li #define LLVM_CLANG_LIB_PARSE_RAIIOBJECTSFORPARSER_H 17*67e74705SXin Li 18*67e74705SXin Li #include "clang/Parse/ParseDiagnostic.h" 19*67e74705SXin Li #include "clang/Parse/Parser.h" 20*67e74705SXin Li #include "clang/Sema/DelayedDiagnostic.h" 21*67e74705SXin Li #include "clang/Sema/Sema.h" 22*67e74705SXin Li 23*67e74705SXin Li namespace clang { 24*67e74705SXin Li // TODO: move ParsingClassDefinition here. 25*67e74705SXin Li // TODO: move TentativeParsingAction here. 26*67e74705SXin Li 27*67e74705SXin Li /// \brief A RAII object used to temporarily suppress access-like 28*67e74705SXin Li /// checking. Access-like checks are those associated with 29*67e74705SXin Li /// controlling the use of a declaration, like C++ access control 30*67e74705SXin Li /// errors and deprecation warnings. They are contextually 31*67e74705SXin Li /// dependent, in that they can only be resolved with full 32*67e74705SXin Li /// information about what's being declared. They are also 33*67e74705SXin Li /// suppressed in certain contexts, like the template arguments of 34*67e74705SXin Li /// an explicit instantiation. However, those suppression contexts 35*67e74705SXin Li /// cannot necessarily be fully determined in advance; for 36*67e74705SXin Li /// example, something starting like this: 37*67e74705SXin Li /// template <> class std::vector<A::PrivateType> 38*67e74705SXin Li /// might be the entirety of an explicit instantiation: 39*67e74705SXin Li /// template <> class std::vector<A::PrivateType>; 40*67e74705SXin Li /// or just an elaborated type specifier: 41*67e74705SXin Li /// template <> class std::vector<A::PrivateType> make_vector<>(); 42*67e74705SXin Li /// Therefore this class collects all the diagnostics and permits 43*67e74705SXin Li /// them to be re-delayed in a new context. 44*67e74705SXin Li class SuppressAccessChecks { 45*67e74705SXin Li Sema &S; 46*67e74705SXin Li sema::DelayedDiagnosticPool DiagnosticPool; 47*67e74705SXin Li Sema::ParsingDeclState State; 48*67e74705SXin Li bool Active; 49*67e74705SXin Li 50*67e74705SXin Li public: 51*67e74705SXin Li /// Begin suppressing access-like checks 52*67e74705SXin Li SuppressAccessChecks(Parser &P, bool activate = true) 53*67e74705SXin Li : S(P.getActions()), DiagnosticPool(nullptr) { 54*67e74705SXin Li if (activate) { 55*67e74705SXin Li State = S.PushParsingDeclaration(DiagnosticPool); 56*67e74705SXin Li Active = true; 57*67e74705SXin Li } else { 58*67e74705SXin Li Active = false; 59*67e74705SXin Li } 60*67e74705SXin Li } SuppressAccessChecks(SuppressAccessChecks && Other)61*67e74705SXin Li SuppressAccessChecks(SuppressAccessChecks &&Other) 62*67e74705SXin Li : S(Other.S), DiagnosticPool(std::move(Other.DiagnosticPool)), 63*67e74705SXin Li State(Other.State), Active(Other.Active) { 64*67e74705SXin Li Other.Active = false; 65*67e74705SXin Li } 66*67e74705SXin Li void operator=(SuppressAccessChecks &&Other) = delete; 67*67e74705SXin Li done()68*67e74705SXin Li void done() { 69*67e74705SXin Li assert(Active && "trying to end an inactive suppression"); 70*67e74705SXin Li S.PopParsingDeclaration(State, nullptr); 71*67e74705SXin Li Active = false; 72*67e74705SXin Li } 73*67e74705SXin Li redelay()74*67e74705SXin Li void redelay() { 75*67e74705SXin Li assert(!Active && "redelaying without having ended first"); 76*67e74705SXin Li if (!DiagnosticPool.pool_empty()) 77*67e74705SXin Li S.redelayDiagnostics(DiagnosticPool); 78*67e74705SXin Li assert(DiagnosticPool.pool_empty()); 79*67e74705SXin Li } 80*67e74705SXin Li ~SuppressAccessChecks()81*67e74705SXin Li ~SuppressAccessChecks() { 82*67e74705SXin Li if (Active) done(); 83*67e74705SXin Li } 84*67e74705SXin Li }; 85*67e74705SXin Li 86*67e74705SXin Li /// \brief RAII object used to inform the actions that we're 87*67e74705SXin Li /// currently parsing a declaration. This is active when parsing a 88*67e74705SXin Li /// variable's initializer, but not when parsing the body of a 89*67e74705SXin Li /// class or function definition. 90*67e74705SXin Li class ParsingDeclRAIIObject { 91*67e74705SXin Li Sema &Actions; 92*67e74705SXin Li sema::DelayedDiagnosticPool DiagnosticPool; 93*67e74705SXin Li Sema::ParsingDeclState State; 94*67e74705SXin Li bool Popped; 95*67e74705SXin Li 96*67e74705SXin Li ParsingDeclRAIIObject(const ParsingDeclRAIIObject &) = delete; 97*67e74705SXin Li void operator=(const ParsingDeclRAIIObject &) = delete; 98*67e74705SXin Li 99*67e74705SXin Li public: 100*67e74705SXin Li enum NoParent_t { NoParent }; ParsingDeclRAIIObject(Parser & P,NoParent_t _)101*67e74705SXin Li ParsingDeclRAIIObject(Parser &P, NoParent_t _) 102*67e74705SXin Li : Actions(P.getActions()), DiagnosticPool(nullptr) { 103*67e74705SXin Li push(); 104*67e74705SXin Li } 105*67e74705SXin Li 106*67e74705SXin Li /// Creates a RAII object whose pool is optionally parented by another. ParsingDeclRAIIObject(Parser & P,const sema::DelayedDiagnosticPool * parentPool)107*67e74705SXin Li ParsingDeclRAIIObject(Parser &P, 108*67e74705SXin Li const sema::DelayedDiagnosticPool *parentPool) 109*67e74705SXin Li : Actions(P.getActions()), DiagnosticPool(parentPool) { 110*67e74705SXin Li push(); 111*67e74705SXin Li } 112*67e74705SXin Li 113*67e74705SXin Li /// Creates a RAII object and, optionally, initialize its 114*67e74705SXin Li /// diagnostics pool by stealing the diagnostics from another 115*67e74705SXin Li /// RAII object (which is assumed to be the current top pool). ParsingDeclRAIIObject(Parser & P,ParsingDeclRAIIObject * other)116*67e74705SXin Li ParsingDeclRAIIObject(Parser &P, ParsingDeclRAIIObject *other) 117*67e74705SXin Li : Actions(P.getActions()), 118*67e74705SXin Li DiagnosticPool(other ? other->DiagnosticPool.getParent() : nullptr) { 119*67e74705SXin Li if (other) { 120*67e74705SXin Li DiagnosticPool.steal(other->DiagnosticPool); 121*67e74705SXin Li other->abort(); 122*67e74705SXin Li } 123*67e74705SXin Li push(); 124*67e74705SXin Li } 125*67e74705SXin Li ~ParsingDeclRAIIObject()126*67e74705SXin Li ~ParsingDeclRAIIObject() { 127*67e74705SXin Li abort(); 128*67e74705SXin Li } 129*67e74705SXin Li getDelayedDiagnosticPool()130*67e74705SXin Li sema::DelayedDiagnosticPool &getDelayedDiagnosticPool() { 131*67e74705SXin Li return DiagnosticPool; 132*67e74705SXin Li } getDelayedDiagnosticPool()133*67e74705SXin Li const sema::DelayedDiagnosticPool &getDelayedDiagnosticPool() const { 134*67e74705SXin Li return DiagnosticPool; 135*67e74705SXin Li } 136*67e74705SXin Li 137*67e74705SXin Li /// Resets the RAII object for a new declaration. reset()138*67e74705SXin Li void reset() { 139*67e74705SXin Li abort(); 140*67e74705SXin Li push(); 141*67e74705SXin Li } 142*67e74705SXin Li 143*67e74705SXin Li /// Signals that the context was completed without an appropriate 144*67e74705SXin Li /// declaration being parsed. abort()145*67e74705SXin Li void abort() { 146*67e74705SXin Li pop(nullptr); 147*67e74705SXin Li } 148*67e74705SXin Li complete(Decl * D)149*67e74705SXin Li void complete(Decl *D) { 150*67e74705SXin Li assert(!Popped && "ParsingDeclaration has already been popped!"); 151*67e74705SXin Li pop(D); 152*67e74705SXin Li } 153*67e74705SXin Li 154*67e74705SXin Li /// Unregister this object from Sema, but remember all the 155*67e74705SXin Li /// diagnostics that were emitted into it. abortAndRemember()156*67e74705SXin Li void abortAndRemember() { 157*67e74705SXin Li pop(nullptr); 158*67e74705SXin Li } 159*67e74705SXin Li 160*67e74705SXin Li private: push()161*67e74705SXin Li void push() { 162*67e74705SXin Li State = Actions.PushParsingDeclaration(DiagnosticPool); 163*67e74705SXin Li Popped = false; 164*67e74705SXin Li } 165*67e74705SXin Li pop(Decl * D)166*67e74705SXin Li void pop(Decl *D) { 167*67e74705SXin Li if (!Popped) { 168*67e74705SXin Li Actions.PopParsingDeclaration(State, D); 169*67e74705SXin Li Popped = true; 170*67e74705SXin Li } 171*67e74705SXin Li } 172*67e74705SXin Li }; 173*67e74705SXin Li 174*67e74705SXin Li /// A class for parsing a DeclSpec. 175*67e74705SXin Li class ParsingDeclSpec : public DeclSpec { 176*67e74705SXin Li ParsingDeclRAIIObject ParsingRAII; 177*67e74705SXin Li 178*67e74705SXin Li public: ParsingDeclSpec(Parser & P)179*67e74705SXin Li ParsingDeclSpec(Parser &P) 180*67e74705SXin Li : DeclSpec(P.getAttrFactory()), 181*67e74705SXin Li ParsingRAII(P, ParsingDeclRAIIObject::NoParent) {} ParsingDeclSpec(Parser & P,ParsingDeclRAIIObject * RAII)182*67e74705SXin Li ParsingDeclSpec(Parser &P, ParsingDeclRAIIObject *RAII) 183*67e74705SXin Li : DeclSpec(P.getAttrFactory()), 184*67e74705SXin Li ParsingRAII(P, RAII) {} 185*67e74705SXin Li getDelayedDiagnosticPool()186*67e74705SXin Li const sema::DelayedDiagnosticPool &getDelayedDiagnosticPool() const { 187*67e74705SXin Li return ParsingRAII.getDelayedDiagnosticPool(); 188*67e74705SXin Li } 189*67e74705SXin Li complete(Decl * D)190*67e74705SXin Li void complete(Decl *D) { 191*67e74705SXin Li ParsingRAII.complete(D); 192*67e74705SXin Li } 193*67e74705SXin Li abort()194*67e74705SXin Li void abort() { 195*67e74705SXin Li ParsingRAII.abort(); 196*67e74705SXin Li } 197*67e74705SXin Li }; 198*67e74705SXin Li 199*67e74705SXin Li /// A class for parsing a declarator. 200*67e74705SXin Li class ParsingDeclarator : public Declarator { 201*67e74705SXin Li ParsingDeclRAIIObject ParsingRAII; 202*67e74705SXin Li 203*67e74705SXin Li public: ParsingDeclarator(Parser & P,const ParsingDeclSpec & DS,TheContext C)204*67e74705SXin Li ParsingDeclarator(Parser &P, const ParsingDeclSpec &DS, TheContext C) 205*67e74705SXin Li : Declarator(DS, C), ParsingRAII(P, &DS.getDelayedDiagnosticPool()) { 206*67e74705SXin Li } 207*67e74705SXin Li getDeclSpec()208*67e74705SXin Li const ParsingDeclSpec &getDeclSpec() const { 209*67e74705SXin Li return static_cast<const ParsingDeclSpec&>(Declarator::getDeclSpec()); 210*67e74705SXin Li } 211*67e74705SXin Li getMutableDeclSpec()212*67e74705SXin Li ParsingDeclSpec &getMutableDeclSpec() const { 213*67e74705SXin Li return const_cast<ParsingDeclSpec&>(getDeclSpec()); 214*67e74705SXin Li } 215*67e74705SXin Li clear()216*67e74705SXin Li void clear() { 217*67e74705SXin Li Declarator::clear(); 218*67e74705SXin Li ParsingRAII.reset(); 219*67e74705SXin Li } 220*67e74705SXin Li complete(Decl * D)221*67e74705SXin Li void complete(Decl *D) { 222*67e74705SXin Li ParsingRAII.complete(D); 223*67e74705SXin Li } 224*67e74705SXin Li }; 225*67e74705SXin Li 226*67e74705SXin Li /// A class for parsing a field declarator. 227*67e74705SXin Li class ParsingFieldDeclarator : public FieldDeclarator { 228*67e74705SXin Li ParsingDeclRAIIObject ParsingRAII; 229*67e74705SXin Li 230*67e74705SXin Li public: ParsingFieldDeclarator(Parser & P,const ParsingDeclSpec & DS)231*67e74705SXin Li ParsingFieldDeclarator(Parser &P, const ParsingDeclSpec &DS) 232*67e74705SXin Li : FieldDeclarator(DS), ParsingRAII(P, &DS.getDelayedDiagnosticPool()) { 233*67e74705SXin Li } 234*67e74705SXin Li getDeclSpec()235*67e74705SXin Li const ParsingDeclSpec &getDeclSpec() const { 236*67e74705SXin Li return static_cast<const ParsingDeclSpec&>(D.getDeclSpec()); 237*67e74705SXin Li } 238*67e74705SXin Li getMutableDeclSpec()239*67e74705SXin Li ParsingDeclSpec &getMutableDeclSpec() const { 240*67e74705SXin Li return const_cast<ParsingDeclSpec&>(getDeclSpec()); 241*67e74705SXin Li } 242*67e74705SXin Li complete(Decl * D)243*67e74705SXin Li void complete(Decl *D) { 244*67e74705SXin Li ParsingRAII.complete(D); 245*67e74705SXin Li } 246*67e74705SXin Li }; 247*67e74705SXin Li 248*67e74705SXin Li /// ExtensionRAIIObject - This saves the state of extension warnings when 249*67e74705SXin Li /// constructed and disables them. When destructed, it restores them back to 250*67e74705SXin Li /// the way they used to be. This is used to handle __extension__ in the 251*67e74705SXin Li /// parser. 252*67e74705SXin Li class ExtensionRAIIObject { 253*67e74705SXin Li ExtensionRAIIObject(const ExtensionRAIIObject &) = delete; 254*67e74705SXin Li void operator=(const ExtensionRAIIObject &) = delete; 255*67e74705SXin Li 256*67e74705SXin Li DiagnosticsEngine &Diags; 257*67e74705SXin Li public: ExtensionRAIIObject(DiagnosticsEngine & diags)258*67e74705SXin Li ExtensionRAIIObject(DiagnosticsEngine &diags) : Diags(diags) { 259*67e74705SXin Li Diags.IncrementAllExtensionsSilenced(); 260*67e74705SXin Li } 261*67e74705SXin Li ~ExtensionRAIIObject()262*67e74705SXin Li ~ExtensionRAIIObject() { 263*67e74705SXin Li Diags.DecrementAllExtensionsSilenced(); 264*67e74705SXin Li } 265*67e74705SXin Li }; 266*67e74705SXin Li 267*67e74705SXin Li /// ColonProtectionRAIIObject - This sets the Parser::ColonIsSacred bool and 268*67e74705SXin Li /// restores it when destroyed. This says that "foo:" should not be 269*67e74705SXin Li /// considered a possible typo for "foo::" for error recovery purposes. 270*67e74705SXin Li class ColonProtectionRAIIObject { 271*67e74705SXin Li Parser &P; 272*67e74705SXin Li bool OldVal; 273*67e74705SXin Li public: 274*67e74705SXin Li ColonProtectionRAIIObject(Parser &p, bool Value = true) P(p)275*67e74705SXin Li : P(p), OldVal(P.ColonIsSacred) { 276*67e74705SXin Li P.ColonIsSacred = Value; 277*67e74705SXin Li } 278*67e74705SXin Li 279*67e74705SXin Li /// restore - This can be used to restore the state early, before the dtor 280*67e74705SXin Li /// is run. restore()281*67e74705SXin Li void restore() { 282*67e74705SXin Li P.ColonIsSacred = OldVal; 283*67e74705SXin Li } 284*67e74705SXin Li ~ColonProtectionRAIIObject()285*67e74705SXin Li ~ColonProtectionRAIIObject() { 286*67e74705SXin Li restore(); 287*67e74705SXin Li } 288*67e74705SXin Li }; 289*67e74705SXin Li 290*67e74705SXin Li /// \brief RAII object that makes '>' behave either as an operator 291*67e74705SXin Li /// or as the closing angle bracket for a template argument list. 292*67e74705SXin Li class GreaterThanIsOperatorScope { 293*67e74705SXin Li bool &GreaterThanIsOperator; 294*67e74705SXin Li bool OldGreaterThanIsOperator; 295*67e74705SXin Li public: GreaterThanIsOperatorScope(bool & GTIO,bool Val)296*67e74705SXin Li GreaterThanIsOperatorScope(bool >IO, bool Val) 297*67e74705SXin Li : GreaterThanIsOperator(GTIO), OldGreaterThanIsOperator(GTIO) { 298*67e74705SXin Li GreaterThanIsOperator = Val; 299*67e74705SXin Li } 300*67e74705SXin Li ~GreaterThanIsOperatorScope()301*67e74705SXin Li ~GreaterThanIsOperatorScope() { 302*67e74705SXin Li GreaterThanIsOperator = OldGreaterThanIsOperator; 303*67e74705SXin Li } 304*67e74705SXin Li }; 305*67e74705SXin Li 306*67e74705SXin Li class InMessageExpressionRAIIObject { 307*67e74705SXin Li bool &InMessageExpression; 308*67e74705SXin Li bool OldValue; 309*67e74705SXin Li 310*67e74705SXin Li public: InMessageExpressionRAIIObject(Parser & P,bool Value)311*67e74705SXin Li InMessageExpressionRAIIObject(Parser &P, bool Value) 312*67e74705SXin Li : InMessageExpression(P.InMessageExpression), 313*67e74705SXin Li OldValue(P.InMessageExpression) { 314*67e74705SXin Li InMessageExpression = Value; 315*67e74705SXin Li } 316*67e74705SXin Li ~InMessageExpressionRAIIObject()317*67e74705SXin Li ~InMessageExpressionRAIIObject() { 318*67e74705SXin Li InMessageExpression = OldValue; 319*67e74705SXin Li } 320*67e74705SXin Li }; 321*67e74705SXin Li 322*67e74705SXin Li /// \brief RAII object that makes sure paren/bracket/brace count is correct 323*67e74705SXin Li /// after declaration/statement parsing, even when there's a parsing error. 324*67e74705SXin Li class ParenBraceBracketBalancer { 325*67e74705SXin Li Parser &P; 326*67e74705SXin Li unsigned short ParenCount, BracketCount, BraceCount; 327*67e74705SXin Li public: ParenBraceBracketBalancer(Parser & p)328*67e74705SXin Li ParenBraceBracketBalancer(Parser &p) 329*67e74705SXin Li : P(p), ParenCount(p.ParenCount), BracketCount(p.BracketCount), 330*67e74705SXin Li BraceCount(p.BraceCount) { } 331*67e74705SXin Li ~ParenBraceBracketBalancer()332*67e74705SXin Li ~ParenBraceBracketBalancer() { 333*67e74705SXin Li P.ParenCount = ParenCount; 334*67e74705SXin Li P.BracketCount = BracketCount; 335*67e74705SXin Li P.BraceCount = BraceCount; 336*67e74705SXin Li } 337*67e74705SXin Li }; 338*67e74705SXin Li 339*67e74705SXin Li class PoisonSEHIdentifiersRAIIObject { 340*67e74705SXin Li PoisonIdentifierRAIIObject Ident_AbnormalTermination; 341*67e74705SXin Li PoisonIdentifierRAIIObject Ident_GetExceptionCode; 342*67e74705SXin Li PoisonIdentifierRAIIObject Ident_GetExceptionInfo; 343*67e74705SXin Li PoisonIdentifierRAIIObject Ident__abnormal_termination; 344*67e74705SXin Li PoisonIdentifierRAIIObject Ident__exception_code; 345*67e74705SXin Li PoisonIdentifierRAIIObject Ident__exception_info; 346*67e74705SXin Li PoisonIdentifierRAIIObject Ident___abnormal_termination; 347*67e74705SXin Li PoisonIdentifierRAIIObject Ident___exception_code; 348*67e74705SXin Li PoisonIdentifierRAIIObject Ident___exception_info; 349*67e74705SXin Li public: PoisonSEHIdentifiersRAIIObject(Parser & Self,bool NewValue)350*67e74705SXin Li PoisonSEHIdentifiersRAIIObject(Parser &Self, bool NewValue) 351*67e74705SXin Li : Ident_AbnormalTermination(Self.Ident_AbnormalTermination, NewValue), 352*67e74705SXin Li Ident_GetExceptionCode(Self.Ident_GetExceptionCode, NewValue), 353*67e74705SXin Li Ident_GetExceptionInfo(Self.Ident_GetExceptionInfo, NewValue), 354*67e74705SXin Li Ident__abnormal_termination(Self.Ident__abnormal_termination, NewValue), 355*67e74705SXin Li Ident__exception_code(Self.Ident__exception_code, NewValue), 356*67e74705SXin Li Ident__exception_info(Self.Ident__exception_info, NewValue), 357*67e74705SXin Li Ident___abnormal_termination(Self.Ident___abnormal_termination, NewValue), 358*67e74705SXin Li Ident___exception_code(Self.Ident___exception_code, NewValue), 359*67e74705SXin Li Ident___exception_info(Self.Ident___exception_info, NewValue) { 360*67e74705SXin Li } 361*67e74705SXin Li }; 362*67e74705SXin Li 363*67e74705SXin Li /// \brief RAII class that helps handle the parsing of an open/close delimiter 364*67e74705SXin Li /// pair, such as braces { ... } or parentheses ( ... ). 365*67e74705SXin Li class BalancedDelimiterTracker : public GreaterThanIsOperatorScope { 366*67e74705SXin Li Parser& P; 367*67e74705SXin Li tok::TokenKind Kind, Close, FinalToken; 368*67e74705SXin Li SourceLocation (Parser::*Consumer)(); 369*67e74705SXin Li SourceLocation LOpen, LClose; 370*67e74705SXin Li getDepth()371*67e74705SXin Li unsigned short &getDepth() { 372*67e74705SXin Li switch (Kind) { 373*67e74705SXin Li case tok::l_brace: return P.BraceCount; 374*67e74705SXin Li case tok::l_square: return P.BracketCount; 375*67e74705SXin Li case tok::l_paren: return P.ParenCount; 376*67e74705SXin Li default: llvm_unreachable("Wrong token kind"); 377*67e74705SXin Li } 378*67e74705SXin Li } 379*67e74705SXin Li 380*67e74705SXin Li enum { MaxDepth = 256 }; 381*67e74705SXin Li 382*67e74705SXin Li bool diagnoseOverflow(); 383*67e74705SXin Li bool diagnoseMissingClose(); 384*67e74705SXin Li 385*67e74705SXin Li public: 386*67e74705SXin Li BalancedDelimiterTracker(Parser& p, tok::TokenKind k, 387*67e74705SXin Li tok::TokenKind FinalToken = tok::semi) 388*67e74705SXin Li : GreaterThanIsOperatorScope(p.GreaterThanIsOperator, true), 389*67e74705SXin Li P(p), Kind(k), FinalToken(FinalToken) 390*67e74705SXin Li { 391*67e74705SXin Li switch (Kind) { 392*67e74705SXin Li default: llvm_unreachable("Unexpected balanced token"); 393*67e74705SXin Li case tok::l_brace: 394*67e74705SXin Li Close = tok::r_brace; 395*67e74705SXin Li Consumer = &Parser::ConsumeBrace; 396*67e74705SXin Li break; 397*67e74705SXin Li case tok::l_paren: 398*67e74705SXin Li Close = tok::r_paren; 399*67e74705SXin Li Consumer = &Parser::ConsumeParen; 400*67e74705SXin Li break; 401*67e74705SXin Li 402*67e74705SXin Li case tok::l_square: 403*67e74705SXin Li Close = tok::r_square; 404*67e74705SXin Li Consumer = &Parser::ConsumeBracket; 405*67e74705SXin Li break; 406*67e74705SXin Li } 407*67e74705SXin Li } 408*67e74705SXin Li getOpenLocation()409*67e74705SXin Li SourceLocation getOpenLocation() const { return LOpen; } getCloseLocation()410*67e74705SXin Li SourceLocation getCloseLocation() const { return LClose; } getRange()411*67e74705SXin Li SourceRange getRange() const { return SourceRange(LOpen, LClose); } 412*67e74705SXin Li consumeOpen()413*67e74705SXin Li bool consumeOpen() { 414*67e74705SXin Li if (!P.Tok.is(Kind)) 415*67e74705SXin Li return true; 416*67e74705SXin Li 417*67e74705SXin Li if (getDepth() < P.getLangOpts().BracketDepth) { 418*67e74705SXin Li LOpen = (P.*Consumer)(); 419*67e74705SXin Li return false; 420*67e74705SXin Li } 421*67e74705SXin Li 422*67e74705SXin Li return diagnoseOverflow(); 423*67e74705SXin Li } 424*67e74705SXin Li 425*67e74705SXin Li bool expectAndConsume(unsigned DiagID = diag::err_expected, 426*67e74705SXin Li const char *Msg = "", 427*67e74705SXin Li tok::TokenKind SkipToTok = tok::unknown); consumeClose()428*67e74705SXin Li bool consumeClose() { 429*67e74705SXin Li if (P.Tok.is(Close)) { 430*67e74705SXin Li LClose = (P.*Consumer)(); 431*67e74705SXin Li return false; 432*67e74705SXin Li } else if (P.Tok.is(tok::semi) && P.NextToken().is(Close)) { 433*67e74705SXin Li SourceLocation SemiLoc = P.ConsumeToken(); 434*67e74705SXin Li P.Diag(SemiLoc, diag::err_unexpected_semi) 435*67e74705SXin Li << Close << FixItHint::CreateRemoval(SourceRange(SemiLoc, SemiLoc)); 436*67e74705SXin Li LClose = (P.*Consumer)(); 437*67e74705SXin Li return false; 438*67e74705SXin Li } 439*67e74705SXin Li 440*67e74705SXin Li return diagnoseMissingClose(); 441*67e74705SXin Li } 442*67e74705SXin Li void skipToEnd(); 443*67e74705SXin Li }; 444*67e74705SXin Li 445*67e74705SXin Li } // end namespace clang 446*67e74705SXin Li 447*67e74705SXin Li #endif 448