1d167ca0d26e43292b8b9e8d5300d92784ae0e27dChris Lattner//===--- RAIIObjectsForParser.h - RAII helpers for the parser ---*- C++ -*-===//
2c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner//
3c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner//                     The LLVM Compiler Infrastructure
4c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner//
5c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner// This file is distributed under the University of Illinois Open Source
6c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner// License. See LICENSE.TXT for details.
7c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner//
8c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner//===----------------------------------------------------------------------===//
9c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner//
10d167ca0d26e43292b8b9e8d5300d92784ae0e27dChris Lattner// This file defines and implements the some simple RAII objects that are used
11d167ca0d26e43292b8b9e8d5300d92784ae0e27dChris Lattner// by the parser to manage bits in recursion.
12c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner//
13c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner//===----------------------------------------------------------------------===//
14c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner
15176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines#ifndef LLVM_CLANG_LIB_PARSE_RAIIOBJECTSFORPARSER_H
16176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines#define LLVM_CLANG_LIB_PARSE_RAIIOBJECTSFORPARSER_H
17c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner
18500d3297d2a21edeac4d46cbcbe21bc2352c2a28Chris Lattner#include "clang/Parse/ParseDiagnostic.h"
199257664568bf375b7790131a84d9a4fa30a5b7e3John McCall#include "clang/Parse/Parser.h"
209257664568bf375b7790131a84d9a4fa30a5b7e3John McCall#include "clang/Sema/DelayedDiagnostic.h"
219257664568bf375b7790131a84d9a4fa30a5b7e3John McCall#include "clang/Sema/Sema.h"
22c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner
23c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattnernamespace clang {
24d0d76f1cbeeb6ea2ade6c17820ef4705f2e83a41Chris Lattner  // TODO: move ParsingClassDefinition here.
25d0d76f1cbeeb6ea2ade6c17820ef4705f2e83a41Chris Lattner  // TODO: move TentativeParsingAction here.
269257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
2713489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall  /// \brief A RAII object used to temporarily suppress access-like
2813489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall  /// checking.  Access-like checks are those associated with
2913489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall  /// controlling the use of a declaration, like C++ access control
3013489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall  /// errors and deprecation warnings.  They are contextually
3113489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall  /// dependent, in that they can only be resolved with full
3213489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall  /// information about what's being declared.  They are also
3313489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall  /// suppressed in certain contexts, like the template arguments of
3413489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall  /// an explicit instantiation.  However, those suppression contexts
3513489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall  /// cannot necessarily be fully determined in advance;  for
3613489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall  /// example, something starting like this:
3713489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall  ///   template <> class std::vector<A::PrivateType>
3813489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall  /// might be the entirety of an explicit instantiation:
3913489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall  ///   template <> class std::vector<A::PrivateType>;
4013489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall  /// or just an elaborated type specifier:
4113489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall  ///   template <> class std::vector<A::PrivateType> make_vector<>();
4213489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall  /// Therefore this class collects all the diagnostics and permits
4313489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall  /// them to be re-delayed in a new context.
4413489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall  class SuppressAccessChecks {
4513489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall    Sema &S;
4613489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall    sema::DelayedDiagnosticPool DiagnosticPool;
4713489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall    Sema::ParsingDeclState State;
4813489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall    bool Active;
4913489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall
5013489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall  public:
5113489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall    /// Begin suppressing access-like checks
5213489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall    SuppressAccessChecks(Parser &P, bool activate = true)
536bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        : S(P.getActions()), DiagnosticPool(nullptr) {
5413489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall      if (activate) {
5513489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall        State = S.PushParsingDeclaration(DiagnosticPool);
5613489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall        Active = true;
5713489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall      } else {
5813489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall        Active = false;
5913489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall      }
6013489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall    }
61b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    SuppressAccessChecks(SuppressAccessChecks &&Other)
62b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar      : S(Other.S), DiagnosticPool(std::move(Other.DiagnosticPool)),
63b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar        State(Other.State), Active(Other.Active) {
64b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar      Other.Active = false;
65b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    }
66b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    void operator=(SuppressAccessChecks &&Other) = delete;
6713489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall
6813489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall    void done() {
6913489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall      assert(Active && "trying to end an inactive suppression");
706bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      S.PopParsingDeclaration(State, nullptr);
7113489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall      Active = false;
7213489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall    }
7313489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall
7413489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall    void redelay() {
7513489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall      assert(!Active && "redelaying without having ended first");
7613489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall      if (!DiagnosticPool.pool_empty())
7713489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall        S.redelayDiagnostics(DiagnosticPool);
7813489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall      assert(DiagnosticPool.pool_empty());
7913489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall    }
8013489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall
8113489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall    ~SuppressAccessChecks() {
8213489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall      if (Active) done();
8313489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall    }
8413489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall  };
8513489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall
869257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  /// \brief RAII object used to inform the actions that we're
879257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  /// currently parsing a declaration.  This is active when parsing a
889257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  /// variable's initializer, but not when parsing the body of a
899257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  /// class or function definition.
909257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  class ParsingDeclRAIIObject {
919257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    Sema &Actions;
929257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    sema::DelayedDiagnosticPool DiagnosticPool;
939257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    Sema::ParsingDeclState State;
949257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    bool Popped;
959257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
960e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    ParsingDeclRAIIObject(const ParsingDeclRAIIObject &) = delete;
970e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    void operator=(const ParsingDeclRAIIObject &) = delete;
989257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
999257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  public:
1009257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    enum NoParent_t { NoParent };
1019257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    ParsingDeclRAIIObject(Parser &P, NoParent_t _)
1026bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        : Actions(P.getActions()), DiagnosticPool(nullptr) {
1039257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      push();
1049257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    }
1059257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
1069257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    /// Creates a RAII object whose pool is optionally parented by another.
1079257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    ParsingDeclRAIIObject(Parser &P,
1089257664568bf375b7790131a84d9a4fa30a5b7e3John McCall                          const sema::DelayedDiagnosticPool *parentPool)
1099257664568bf375b7790131a84d9a4fa30a5b7e3John McCall        : Actions(P.getActions()), DiagnosticPool(parentPool) {
1109257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      push();
1119257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    }
1129257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
1139257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    /// Creates a RAII object and, optionally, initialize its
1149257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    /// diagnostics pool by stealing the diagnostics from another
1159257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    /// RAII object (which is assumed to be the current top pool).
1169257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    ParsingDeclRAIIObject(Parser &P, ParsingDeclRAIIObject *other)
1179257664568bf375b7790131a84d9a4fa30a5b7e3John McCall        : Actions(P.getActions()),
1186bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines          DiagnosticPool(other ? other->DiagnosticPool.getParent() : nullptr) {
1199257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      if (other) {
1209257664568bf375b7790131a84d9a4fa30a5b7e3John McCall        DiagnosticPool.steal(other->DiagnosticPool);
1219257664568bf375b7790131a84d9a4fa30a5b7e3John McCall        other->abort();
1229257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      }
1239257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      push();
1249257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    }
1259257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
1269257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    ~ParsingDeclRAIIObject() {
1279257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      abort();
1289257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    }
1299257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
1309257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    sema::DelayedDiagnosticPool &getDelayedDiagnosticPool() {
1319257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      return DiagnosticPool;
1329257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    }
1339257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    const sema::DelayedDiagnosticPool &getDelayedDiagnosticPool() const {
1349257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      return DiagnosticPool;
1359257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    }
1369257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
1379257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    /// Resets the RAII object for a new declaration.
1389257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    void reset() {
1399257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      abort();
1409257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      push();
1419257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    }
1429257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
1439257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    /// Signals that the context was completed without an appropriate
1449257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    /// declaration being parsed.
1459257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    void abort() {
1466bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      pop(nullptr);
1479257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    }
1489257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
1499257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    void complete(Decl *D) {
1509257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      assert(!Popped && "ParsingDeclaration has already been popped!");
1519257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      pop(D);
1529257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    }
1539257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
15413489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall    /// Unregister this object from Sema, but remember all the
15513489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall    /// diagnostics that were emitted into it.
15613489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall    void abortAndRemember() {
1576bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      pop(nullptr);
1589257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    }
1599257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
16013489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall  private:
1619257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    void push() {
1629257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      State = Actions.PushParsingDeclaration(DiagnosticPool);
1639257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      Popped = false;
1649257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    }
1659257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
1669257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    void pop(Decl *D) {
1679257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      if (!Popped) {
1689257664568bf375b7790131a84d9a4fa30a5b7e3John McCall        Actions.PopParsingDeclaration(State, D);
1699257664568bf375b7790131a84d9a4fa30a5b7e3John McCall        Popped = true;
1709257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      }
1719257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    }
1729257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  };
1739257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
1749257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  /// A class for parsing a DeclSpec.
1759257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  class ParsingDeclSpec : public DeclSpec {
1769257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    ParsingDeclRAIIObject ParsingRAII;
1779257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
1789257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  public:
1799257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    ParsingDeclSpec(Parser &P)
1809257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      : DeclSpec(P.getAttrFactory()),
1819257664568bf375b7790131a84d9a4fa30a5b7e3John McCall        ParsingRAII(P, ParsingDeclRAIIObject::NoParent) {}
1829257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    ParsingDeclSpec(Parser &P, ParsingDeclRAIIObject *RAII)
1839257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      : DeclSpec(P.getAttrFactory()),
1849257664568bf375b7790131a84d9a4fa30a5b7e3John McCall        ParsingRAII(P, RAII) {}
1859257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
1869257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    const sema::DelayedDiagnosticPool &getDelayedDiagnosticPool() const {
1879257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      return ParsingRAII.getDelayedDiagnosticPool();
1889257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    }
1899257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
1909257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    void complete(Decl *D) {
1919257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      ParsingRAII.complete(D);
1929257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    }
1939257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
1949257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    void abort() {
1959257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      ParsingRAII.abort();
1969257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    }
1979257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  };
1989257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
1999257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  /// A class for parsing a declarator.
2009257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  class ParsingDeclarator : public Declarator {
2019257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    ParsingDeclRAIIObject ParsingRAII;
2029257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
2039257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  public:
2049257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    ParsingDeclarator(Parser &P, const ParsingDeclSpec &DS, TheContext C)
2059257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      : Declarator(DS, C), ParsingRAII(P, &DS.getDelayedDiagnosticPool()) {
2069257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    }
2079257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
2089257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    const ParsingDeclSpec &getDeclSpec() const {
2099257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      return static_cast<const ParsingDeclSpec&>(Declarator::getDeclSpec());
2109257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    }
2119257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
2129257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    ParsingDeclSpec &getMutableDeclSpec() const {
2139257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      return const_cast<ParsingDeclSpec&>(getDeclSpec());
2149257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    }
2159257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
2169257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    void clear() {
2179257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      Declarator::clear();
2189257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      ParsingRAII.reset();
2199257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    }
2209257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
2219257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    void complete(Decl *D) {
2229257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      ParsingRAII.complete(D);
2239257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    }
2249257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  };
2259257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
226f66a0dda541cd859a928193efba6dc5d7ba8fe54Eli Friedman  /// A class for parsing a field declarator.
227f66a0dda541cd859a928193efba6dc5d7ba8fe54Eli Friedman  class ParsingFieldDeclarator : public FieldDeclarator {
228f66a0dda541cd859a928193efba6dc5d7ba8fe54Eli Friedman    ParsingDeclRAIIObject ParsingRAII;
229f66a0dda541cd859a928193efba6dc5d7ba8fe54Eli Friedman
230f66a0dda541cd859a928193efba6dc5d7ba8fe54Eli Friedman  public:
231f66a0dda541cd859a928193efba6dc5d7ba8fe54Eli Friedman    ParsingFieldDeclarator(Parser &P, const ParsingDeclSpec &DS)
232f66a0dda541cd859a928193efba6dc5d7ba8fe54Eli Friedman      : FieldDeclarator(DS), ParsingRAII(P, &DS.getDelayedDiagnosticPool()) {
233f66a0dda541cd859a928193efba6dc5d7ba8fe54Eli Friedman    }
234f66a0dda541cd859a928193efba6dc5d7ba8fe54Eli Friedman
235f66a0dda541cd859a928193efba6dc5d7ba8fe54Eli Friedman    const ParsingDeclSpec &getDeclSpec() const {
236f66a0dda541cd859a928193efba6dc5d7ba8fe54Eli Friedman      return static_cast<const ParsingDeclSpec&>(D.getDeclSpec());
237f66a0dda541cd859a928193efba6dc5d7ba8fe54Eli Friedman    }
238f66a0dda541cd859a928193efba6dc5d7ba8fe54Eli Friedman
239f66a0dda541cd859a928193efba6dc5d7ba8fe54Eli Friedman    ParsingDeclSpec &getMutableDeclSpec() const {
240f66a0dda541cd859a928193efba6dc5d7ba8fe54Eli Friedman      return const_cast<ParsingDeclSpec&>(getDeclSpec());
241f66a0dda541cd859a928193efba6dc5d7ba8fe54Eli Friedman    }
242f66a0dda541cd859a928193efba6dc5d7ba8fe54Eli Friedman
243f66a0dda541cd859a928193efba6dc5d7ba8fe54Eli Friedman    void complete(Decl *D) {
244f66a0dda541cd859a928193efba6dc5d7ba8fe54Eli Friedman      ParsingRAII.complete(D);
245f66a0dda541cd859a928193efba6dc5d7ba8fe54Eli Friedman    }
246f66a0dda541cd859a928193efba6dc5d7ba8fe54Eli Friedman  };
247f66a0dda541cd859a928193efba6dc5d7ba8fe54Eli Friedman
248c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner  /// ExtensionRAIIObject - This saves the state of extension warnings when
249c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner  /// constructed and disables them.  When destructed, it restores them back to
250c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner  /// the way they used to be.  This is used to handle __extension__ in the
251c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner  /// parser.
252c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner  class ExtensionRAIIObject {
2530e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    ExtensionRAIIObject(const ExtensionRAIIObject &) = delete;
2540e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    void operator=(const ExtensionRAIIObject &) = delete;
255f56faa01936b9cf909623d7f06e3c2569ca4a78eDmitri Gribenko
256d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie    DiagnosticsEngine &Diags;
257c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner  public:
258d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie    ExtensionRAIIObject(DiagnosticsEngine &diags) : Diags(diags) {
25927ceb9d77d929f02a8a811d189a96885629c7c0cChris Lattner      Diags.IncrementAllExtensionsSilenced();
260c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner    }
2611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
262c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner    ~ExtensionRAIIObject() {
26327ceb9d77d929f02a8a811d189a96885629c7c0cChris Lattner      Diags.DecrementAllExtensionsSilenced();
264c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner    }
265c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner  };
26608d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner
26708d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner  /// ColonProtectionRAIIObject - This sets the Parser::ColonIsSacred bool and
26808d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner  /// restores it when destroyed.  This says that "foo:" should not be
26908d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner  /// considered a possible typo for "foo::" for error recovery purposes.
27008d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner  class ColonProtectionRAIIObject {
27108d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner    Parser &P;
27208d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner    bool OldVal;
27308d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner  public:
274932dff777d58a23e3a26967a61bb52697c542fd4Chris Lattner    ColonProtectionRAIIObject(Parser &p, bool Value = true)
275932dff777d58a23e3a26967a61bb52697c542fd4Chris Lattner      : P(p), OldVal(P.ColonIsSacred) {
276932dff777d58a23e3a26967a61bb52697c542fd4Chris Lattner      P.ColonIsSacred = Value;
27708d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner    }
27808d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner
2796fb09c8acc1336a9508cd6223d9fcf87cf31e476Chris Lattner    /// restore - This can be used to restore the state early, before the dtor
2806fb09c8acc1336a9508cd6223d9fcf87cf31e476Chris Lattner    /// is run.
2816fb09c8acc1336a9508cd6223d9fcf87cf31e476Chris Lattner    void restore() {
28208d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner      P.ColonIsSacred = OldVal;
28308d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner    }
2846fb09c8acc1336a9508cd6223d9fcf87cf31e476Chris Lattner
2856fb09c8acc1336a9508cd6223d9fcf87cf31e476Chris Lattner    ~ColonProtectionRAIIObject() {
2866fb09c8acc1336a9508cd6223d9fcf87cf31e476Chris Lattner      restore();
2876fb09c8acc1336a9508cd6223d9fcf87cf31e476Chris Lattner    }
28808d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner  };
28908d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner
290d0d76f1cbeeb6ea2ade6c17820ef4705f2e83a41Chris Lattner  /// \brief RAII object that makes '>' behave either as an operator
291d0d76f1cbeeb6ea2ade6c17820ef4705f2e83a41Chris Lattner  /// or as the closing angle bracket for a template argument list.
292648d846e4f140c30ab9d322870ea3fdd94debba2Benjamin Kramer  class GreaterThanIsOperatorScope {
293d0d76f1cbeeb6ea2ade6c17820ef4705f2e83a41Chris Lattner    bool &GreaterThanIsOperator;
294d0d76f1cbeeb6ea2ade6c17820ef4705f2e83a41Chris Lattner    bool OldGreaterThanIsOperator;
295648d846e4f140c30ab9d322870ea3fdd94debba2Benjamin Kramer  public:
296d0d76f1cbeeb6ea2ade6c17820ef4705f2e83a41Chris Lattner    GreaterThanIsOperatorScope(bool &GTIO, bool Val)
297d0d76f1cbeeb6ea2ade6c17820ef4705f2e83a41Chris Lattner    : GreaterThanIsOperator(GTIO), OldGreaterThanIsOperator(GTIO) {
298d0d76f1cbeeb6ea2ade6c17820ef4705f2e83a41Chris Lattner      GreaterThanIsOperator = Val;
299d0d76f1cbeeb6ea2ade6c17820ef4705f2e83a41Chris Lattner    }
300d0d76f1cbeeb6ea2ade6c17820ef4705f2e83a41Chris Lattner
301d0d76f1cbeeb6ea2ade6c17820ef4705f2e83a41Chris Lattner    ~GreaterThanIsOperatorScope() {
302d0d76f1cbeeb6ea2ade6c17820ef4705f2e83a41Chris Lattner      GreaterThanIsOperator = OldGreaterThanIsOperator;
303d0d76f1cbeeb6ea2ade6c17820ef4705f2e83a41Chris Lattner    }
304d0d76f1cbeeb6ea2ade6c17820ef4705f2e83a41Chris Lattner  };
305d0d76f1cbeeb6ea2ade6c17820ef4705f2e83a41Chris Lattner
3060fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor  class InMessageExpressionRAIIObject {
3070fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor    bool &InMessageExpression;
3080fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor    bool OldValue;
3090fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor
3100fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor  public:
3110fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor    InMessageExpressionRAIIObject(Parser &P, bool Value)
3120fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor      : InMessageExpression(P.InMessageExpression),
3130fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor        OldValue(P.InMessageExpression) {
3140fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor      InMessageExpression = Value;
3150fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor    }
3160fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor
3170fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor    ~InMessageExpressionRAIIObject() {
3180fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor      InMessageExpression = OldValue;
3190fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor    }
3200fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor  };
3210fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor
32236d36806f1972f7ec1d2a3f59155187278c56508Argyrios Kyrtzidis  /// \brief RAII object that makes sure paren/bracket/brace count is correct
32336d36806f1972f7ec1d2a3f59155187278c56508Argyrios Kyrtzidis  /// after declaration/statement parsing, even when there's a parsing error.
32436d36806f1972f7ec1d2a3f59155187278c56508Argyrios Kyrtzidis  class ParenBraceBracketBalancer {
32536d36806f1972f7ec1d2a3f59155187278c56508Argyrios Kyrtzidis    Parser &P;
32636d36806f1972f7ec1d2a3f59155187278c56508Argyrios Kyrtzidis    unsigned short ParenCount, BracketCount, BraceCount;
32736d36806f1972f7ec1d2a3f59155187278c56508Argyrios Kyrtzidis  public:
32836d36806f1972f7ec1d2a3f59155187278c56508Argyrios Kyrtzidis    ParenBraceBracketBalancer(Parser &p)
32936d36806f1972f7ec1d2a3f59155187278c56508Argyrios Kyrtzidis      : P(p), ParenCount(p.ParenCount), BracketCount(p.BracketCount),
33036d36806f1972f7ec1d2a3f59155187278c56508Argyrios Kyrtzidis        BraceCount(p.BraceCount) { }
33136d36806f1972f7ec1d2a3f59155187278c56508Argyrios Kyrtzidis
33236d36806f1972f7ec1d2a3f59155187278c56508Argyrios Kyrtzidis    ~ParenBraceBracketBalancer() {
33336d36806f1972f7ec1d2a3f59155187278c56508Argyrios Kyrtzidis      P.ParenCount = ParenCount;
33436d36806f1972f7ec1d2a3f59155187278c56508Argyrios Kyrtzidis      P.BracketCount = BracketCount;
33536d36806f1972f7ec1d2a3f59155187278c56508Argyrios Kyrtzidis      P.BraceCount = BraceCount;
33636d36806f1972f7ec1d2a3f59155187278c56508Argyrios Kyrtzidis    }
33736d36806f1972f7ec1d2a3f59155187278c56508Argyrios Kyrtzidis  };
33828bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley
33928bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  class PoisonSEHIdentifiersRAIIObject {
34028bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    PoisonIdentifierRAIIObject Ident_AbnormalTermination;
34128bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    PoisonIdentifierRAIIObject Ident_GetExceptionCode;
34228bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    PoisonIdentifierRAIIObject Ident_GetExceptionInfo;
34328bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    PoisonIdentifierRAIIObject Ident__abnormal_termination;
34428bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    PoisonIdentifierRAIIObject Ident__exception_code;
34528bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    PoisonIdentifierRAIIObject Ident__exception_info;
34628bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    PoisonIdentifierRAIIObject Ident___abnormal_termination;
34728bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    PoisonIdentifierRAIIObject Ident___exception_code;
34828bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    PoisonIdentifierRAIIObject Ident___exception_info;
34928bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  public:
35028bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    PoisonSEHIdentifiersRAIIObject(Parser &Self, bool NewValue)
35128bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley      : Ident_AbnormalTermination(Self.Ident_AbnormalTermination, NewValue),
35228bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley        Ident_GetExceptionCode(Self.Ident_GetExceptionCode, NewValue),
35328bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley        Ident_GetExceptionInfo(Self.Ident_GetExceptionInfo, NewValue),
35428bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley        Ident__abnormal_termination(Self.Ident__abnormal_termination, NewValue),
35528bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley        Ident__exception_code(Self.Ident__exception_code, NewValue),
35628bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley        Ident__exception_info(Self.Ident__exception_info, NewValue),
35728bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley        Ident___abnormal_termination(Self.Ident___abnormal_termination, NewValue),
35828bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley        Ident___exception_code(Self.Ident___exception_code, NewValue),
35928bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley        Ident___exception_info(Self.Ident___exception_info, NewValue) {
36028bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    }
36128bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  };
36228bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley
363c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor  /// \brief RAII class that helps handle the parsing of an open/close delimiter
364c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor  /// pair, such as braces { ... } or parentheses ( ... ).
365c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor  class BalancedDelimiterTracker : public GreaterThanIsOperatorScope {
366c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor    Parser& P;
3676af701f29be43e49a25ab098c79940ae4cbb69c7Alexey Bataev    tok::TokenKind Kind, Close, FinalToken;
368c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor    SourceLocation (Parser::*Consumer)();
369c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor    SourceLocation LOpen, LClose;
370c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor
371c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor    unsigned short &getDepth() {
372c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor      switch (Kind) {
373c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor        case tok::l_brace: return P.BraceCount;
374c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor        case tok::l_square: return P.BracketCount;
375c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor        case tok::l_paren: return P.ParenCount;
376c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor        default: llvm_unreachable("Wrong token kind");
377c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor      }
378c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor    }
379c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor
380c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor    enum { MaxDepth = 256 };
381c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor
382c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor    bool diagnoseOverflow();
383c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor    bool diagnoseMissingClose();
384c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor
385c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor  public:
3866af701f29be43e49a25ab098c79940ae4cbb69c7Alexey Bataev    BalancedDelimiterTracker(Parser& p, tok::TokenKind k,
3876af701f29be43e49a25ab098c79940ae4cbb69c7Alexey Bataev                             tok::TokenKind FinalToken = tok::semi)
388c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor      : GreaterThanIsOperatorScope(p.GreaterThanIsOperator, true),
3896af701f29be43e49a25ab098c79940ae4cbb69c7Alexey Bataev        P(p), Kind(k), FinalToken(FinalToken)
390c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor    {
391c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor      switch (Kind) {
392c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor        default: llvm_unreachable("Unexpected balanced token");
393c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor        case tok::l_brace:
394c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor          Close = tok::r_brace;
395c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor          Consumer = &Parser::ConsumeBrace;
396c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor          break;
397c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor        case tok::l_paren:
398c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor          Close = tok::r_paren;
399c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor          Consumer = &Parser::ConsumeParen;
400c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor          break;
401c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor
402c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor        case tok::l_square:
403c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor          Close = tok::r_square;
404c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor          Consumer = &Parser::ConsumeBracket;
405c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor          break;
406c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor      }
407c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor    }
408c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor
409c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor    SourceLocation getOpenLocation() const { return LOpen; }
410c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor    SourceLocation getCloseLocation() const { return LClose; }
411c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor    SourceRange getRange() const { return SourceRange(LOpen, LClose); }
412c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor
413c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor    bool consumeOpen() {
414c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor      if (!P.Tok.is(Kind))
415c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor        return true;
416c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor
4179e738cc9d4b4655c44dadeb22f3a314daf43b995Richard Smith      if (getDepth() < P.getLangOpts().BracketDepth) {
418c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor        LOpen = (P.*Consumer)();
419c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor        return false;
420c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor      }
421c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor
422c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor      return diagnoseOverflow();
423c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor    }
424651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
425651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    bool expectAndConsume(unsigned DiagID = diag::err_expected,
426c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor                          const char *Msg = "",
427c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor                          tok::TokenKind SkipToTok = tok::unknown);
428c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor    bool consumeClose() {
429c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor      if (P.Tok.is(Close)) {
430c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor        LClose = (P.*Consumer)();
431c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor        return false;
432b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar      } else if (P.Tok.is(tok::semi) && P.NextToken().is(Close)) {
433b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar        SourceLocation SemiLoc = P.ConsumeToken();
434b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar        P.Diag(SemiLoc, diag::err_unexpected_semi)
435b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar            << Close << FixItHint::CreateRemoval(SourceRange(SemiLoc, SemiLoc));
436b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar        LClose = (P.*Consumer)();
437b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar        return false;
438b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar      }
439c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor
440c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor      return diagnoseMissingClose();
441c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor    }
442c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor    void skipToEnd();
443c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor  };
444c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor
44508d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner} // end namespace clang
446c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner
447c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner#endif
448