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
15d167ca0d26e43292b8b9e8d5300d92784ae0e27dChris Lattner#ifndef LLVM_CLANG_PARSE_RAII_OBJECTS_FOR_PARSER_H
16d167ca0d26e43292b8b9e8d5300d92784ae0e27dChris Lattner#define LLVM_CLANG_PARSE_RAII_OBJECTS_FOR_PARSER_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)
5313489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall        : S(P.getActions()), DiagnosticPool(NULL) {
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    }
6113489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall
6213489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall    void done() {
6313489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall      assert(Active && "trying to end an inactive suppression");
6413489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall      S.PopParsingDeclaration(State, NULL);
6513489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall      Active = false;
6613489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall    }
6713489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall
6813489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall    void redelay() {
6913489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall      assert(!Active && "redelaying without having ended first");
7013489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall      if (!DiagnosticPool.pool_empty())
7113489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall        S.redelayDiagnostics(DiagnosticPool);
7213489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall      assert(DiagnosticPool.pool_empty());
7313489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall    }
7413489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall
7513489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall    ~SuppressAccessChecks() {
7613489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall      if (Active) done();
7713489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall    }
7813489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall  };
7913489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall
809257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  /// \brief RAII object used to inform the actions that we're
819257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  /// currently parsing a declaration.  This is active when parsing a
829257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  /// variable's initializer, but not when parsing the body of a
839257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  /// class or function definition.
849257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  class ParsingDeclRAIIObject {
859257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    Sema &Actions;
869257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    sema::DelayedDiagnosticPool DiagnosticPool;
879257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    Sema::ParsingDeclState State;
889257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    bool Popped;
899257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
909257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    // Do not implement.
919257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    ParsingDeclRAIIObject(const ParsingDeclRAIIObject &other);
929257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    ParsingDeclRAIIObject &operator=(const ParsingDeclRAIIObject &other);
939257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
949257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  public:
959257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    enum NoParent_t { NoParent };
969257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    ParsingDeclRAIIObject(Parser &P, NoParent_t _)
979257664568bf375b7790131a84d9a4fa30a5b7e3John McCall        : Actions(P.getActions()), DiagnosticPool(NULL) {
989257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      push();
999257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    }
1009257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
1019257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    /// Creates a RAII object whose pool is optionally parented by another.
1029257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    ParsingDeclRAIIObject(Parser &P,
1039257664568bf375b7790131a84d9a4fa30a5b7e3John McCall                          const sema::DelayedDiagnosticPool *parentPool)
1049257664568bf375b7790131a84d9a4fa30a5b7e3John McCall        : Actions(P.getActions()), DiagnosticPool(parentPool) {
1059257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      push();
1069257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    }
1079257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
1089257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    /// Creates a RAII object and, optionally, initialize its
1099257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    /// diagnostics pool by stealing the diagnostics from another
1109257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    /// RAII object (which is assumed to be the current top pool).
1119257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    ParsingDeclRAIIObject(Parser &P, ParsingDeclRAIIObject *other)
1129257664568bf375b7790131a84d9a4fa30a5b7e3John McCall        : Actions(P.getActions()),
1139257664568bf375b7790131a84d9a4fa30a5b7e3John McCall          DiagnosticPool(other ? other->DiagnosticPool.getParent() : NULL) {
1149257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      if (other) {
1159257664568bf375b7790131a84d9a4fa30a5b7e3John McCall        DiagnosticPool.steal(other->DiagnosticPool);
1169257664568bf375b7790131a84d9a4fa30a5b7e3John McCall        other->abort();
1179257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      }
1189257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      push();
1199257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    }
1209257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
1219257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    ~ParsingDeclRAIIObject() {
1229257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      abort();
1239257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    }
1249257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
1259257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    sema::DelayedDiagnosticPool &getDelayedDiagnosticPool() {
1269257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      return DiagnosticPool;
1279257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    }
1289257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    const sema::DelayedDiagnosticPool &getDelayedDiagnosticPool() const {
1299257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      return DiagnosticPool;
1309257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    }
1319257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
1329257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    /// Resets the RAII object for a new declaration.
1339257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    void reset() {
1349257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      abort();
1359257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      push();
1369257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    }
1379257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
1389257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    /// Signals that the context was completed without an appropriate
1399257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    /// declaration being parsed.
1409257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    void abort() {
1419257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      pop(0);
1429257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    }
1439257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
1449257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    void complete(Decl *D) {
1459257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      assert(!Popped && "ParsingDeclaration has already been popped!");
1469257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      pop(D);
1479257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    }
1489257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
14913489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall    /// Unregister this object from Sema, but remember all the
15013489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall    /// diagnostics that were emitted into it.
15113489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall    void abortAndRemember() {
15213489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall      pop(0);
1539257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    }
1549257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
15513489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall  private:
1569257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    void push() {
1579257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      State = Actions.PushParsingDeclaration(DiagnosticPool);
1589257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      Popped = false;
1599257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    }
1609257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
1619257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    void pop(Decl *D) {
1629257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      if (!Popped) {
1639257664568bf375b7790131a84d9a4fa30a5b7e3John McCall        Actions.PopParsingDeclaration(State, D);
1649257664568bf375b7790131a84d9a4fa30a5b7e3John McCall        Popped = true;
1659257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      }
1669257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    }
1679257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  };
1689257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
1699257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  /// A class for parsing a DeclSpec.
1709257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  class ParsingDeclSpec : public DeclSpec {
1719257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    ParsingDeclRAIIObject ParsingRAII;
1729257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
1739257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  public:
1749257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    ParsingDeclSpec(Parser &P)
1759257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      : DeclSpec(P.getAttrFactory()),
1769257664568bf375b7790131a84d9a4fa30a5b7e3John McCall        ParsingRAII(P, ParsingDeclRAIIObject::NoParent) {}
1779257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    ParsingDeclSpec(Parser &P, ParsingDeclRAIIObject *RAII)
1789257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      : DeclSpec(P.getAttrFactory()),
1799257664568bf375b7790131a84d9a4fa30a5b7e3John McCall        ParsingRAII(P, RAII) {}
1809257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
1819257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    const sema::DelayedDiagnosticPool &getDelayedDiagnosticPool() const {
1829257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      return ParsingRAII.getDelayedDiagnosticPool();
1839257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    }
1849257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
1859257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    void complete(Decl *D) {
1869257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      ParsingRAII.complete(D);
1879257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    }
1889257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
1899257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    void abort() {
1909257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      ParsingRAII.abort();
1919257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    }
1929257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  };
1939257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
1949257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  /// A class for parsing a declarator.
1959257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  class ParsingDeclarator : public Declarator {
1969257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    ParsingDeclRAIIObject ParsingRAII;
1979257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
1989257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  public:
1999257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    ParsingDeclarator(Parser &P, const ParsingDeclSpec &DS, TheContext C)
2009257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      : Declarator(DS, C), ParsingRAII(P, &DS.getDelayedDiagnosticPool()) {
2019257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    }
2029257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
2039257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    const ParsingDeclSpec &getDeclSpec() const {
2049257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      return static_cast<const ParsingDeclSpec&>(Declarator::getDeclSpec());
2059257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    }
2069257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
2079257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    ParsingDeclSpec &getMutableDeclSpec() const {
2089257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      return const_cast<ParsingDeclSpec&>(getDeclSpec());
2099257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    }
2109257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
2119257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    void clear() {
2129257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      Declarator::clear();
2139257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      ParsingRAII.reset();
2149257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    }
2159257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
2169257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    void complete(Decl *D) {
2179257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      ParsingRAII.complete(D);
2189257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    }
2199257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  };
2209257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
221f66a0dda541cd859a928193efba6dc5d7ba8fe54Eli Friedman  /// A class for parsing a field declarator.
222f66a0dda541cd859a928193efba6dc5d7ba8fe54Eli Friedman  class ParsingFieldDeclarator : public FieldDeclarator {
223f66a0dda541cd859a928193efba6dc5d7ba8fe54Eli Friedman    ParsingDeclRAIIObject ParsingRAII;
224f66a0dda541cd859a928193efba6dc5d7ba8fe54Eli Friedman
225f66a0dda541cd859a928193efba6dc5d7ba8fe54Eli Friedman  public:
226f66a0dda541cd859a928193efba6dc5d7ba8fe54Eli Friedman    ParsingFieldDeclarator(Parser &P, const ParsingDeclSpec &DS)
227f66a0dda541cd859a928193efba6dc5d7ba8fe54Eli Friedman      : FieldDeclarator(DS), ParsingRAII(P, &DS.getDelayedDiagnosticPool()) {
228f66a0dda541cd859a928193efba6dc5d7ba8fe54Eli Friedman    }
229f66a0dda541cd859a928193efba6dc5d7ba8fe54Eli Friedman
230f66a0dda541cd859a928193efba6dc5d7ba8fe54Eli Friedman    const ParsingDeclSpec &getDeclSpec() const {
231f66a0dda541cd859a928193efba6dc5d7ba8fe54Eli Friedman      return static_cast<const ParsingDeclSpec&>(D.getDeclSpec());
232f66a0dda541cd859a928193efba6dc5d7ba8fe54Eli Friedman    }
233f66a0dda541cd859a928193efba6dc5d7ba8fe54Eli Friedman
234f66a0dda541cd859a928193efba6dc5d7ba8fe54Eli Friedman    ParsingDeclSpec &getMutableDeclSpec() const {
235f66a0dda541cd859a928193efba6dc5d7ba8fe54Eli Friedman      return const_cast<ParsingDeclSpec&>(getDeclSpec());
236f66a0dda541cd859a928193efba6dc5d7ba8fe54Eli Friedman    }
237f66a0dda541cd859a928193efba6dc5d7ba8fe54Eli Friedman
238f66a0dda541cd859a928193efba6dc5d7ba8fe54Eli Friedman    void complete(Decl *D) {
239f66a0dda541cd859a928193efba6dc5d7ba8fe54Eli Friedman      ParsingRAII.complete(D);
240f66a0dda541cd859a928193efba6dc5d7ba8fe54Eli Friedman    }
241f66a0dda541cd859a928193efba6dc5d7ba8fe54Eli Friedman  };
242f66a0dda541cd859a928193efba6dc5d7ba8fe54Eli Friedman
243c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner  /// ExtensionRAIIObject - This saves the state of extension warnings when
244c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner  /// constructed and disables them.  When destructed, it restores them back to
245c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner  /// the way they used to be.  This is used to handle __extension__ in the
246c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner  /// parser.
247c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner  class ExtensionRAIIObject {
248c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner    void operator=(const ExtensionRAIIObject &);     // DO NOT IMPLEMENT
249c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner    ExtensionRAIIObject(const ExtensionRAIIObject&); // DO NOT IMPLEMENT
250d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie    DiagnosticsEngine &Diags;
251c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner  public:
252d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie    ExtensionRAIIObject(DiagnosticsEngine &diags) : Diags(diags) {
25327ceb9d77d929f02a8a811d189a96885629c7c0cChris Lattner      Diags.IncrementAllExtensionsSilenced();
254c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner    }
2551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
256c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner    ~ExtensionRAIIObject() {
25727ceb9d77d929f02a8a811d189a96885629c7c0cChris Lattner      Diags.DecrementAllExtensionsSilenced();
258c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner    }
259c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner  };
26008d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner
26108d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner  /// ColonProtectionRAIIObject - This sets the Parser::ColonIsSacred bool and
26208d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner  /// restores it when destroyed.  This says that "foo:" should not be
26308d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner  /// considered a possible typo for "foo::" for error recovery purposes.
26408d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner  class ColonProtectionRAIIObject {
26508d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner    Parser &P;
26608d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner    bool OldVal;
26708d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner  public:
268932dff777d58a23e3a26967a61bb52697c542fd4Chris Lattner    ColonProtectionRAIIObject(Parser &p, bool Value = true)
269932dff777d58a23e3a26967a61bb52697c542fd4Chris Lattner      : P(p), OldVal(P.ColonIsSacred) {
270932dff777d58a23e3a26967a61bb52697c542fd4Chris Lattner      P.ColonIsSacred = Value;
27108d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner    }
27208d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner
2736fb09c8acc1336a9508cd6223d9fcf87cf31e476Chris Lattner    /// restore - This can be used to restore the state early, before the dtor
2746fb09c8acc1336a9508cd6223d9fcf87cf31e476Chris Lattner    /// is run.
2756fb09c8acc1336a9508cd6223d9fcf87cf31e476Chris Lattner    void restore() {
27608d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner      P.ColonIsSacred = OldVal;
27708d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner    }
2786fb09c8acc1336a9508cd6223d9fcf87cf31e476Chris Lattner
2796fb09c8acc1336a9508cd6223d9fcf87cf31e476Chris Lattner    ~ColonProtectionRAIIObject() {
2806fb09c8acc1336a9508cd6223d9fcf87cf31e476Chris Lattner      restore();
2816fb09c8acc1336a9508cd6223d9fcf87cf31e476Chris Lattner    }
28208d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner  };
28308d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner
284d0d76f1cbeeb6ea2ade6c17820ef4705f2e83a41Chris Lattner  /// \brief RAII object that makes '>' behave either as an operator
285d0d76f1cbeeb6ea2ade6c17820ef4705f2e83a41Chris Lattner  /// or as the closing angle bracket for a template argument list.
286648d846e4f140c30ab9d322870ea3fdd94debba2Benjamin Kramer  class GreaterThanIsOperatorScope {
287d0d76f1cbeeb6ea2ade6c17820ef4705f2e83a41Chris Lattner    bool &GreaterThanIsOperator;
288d0d76f1cbeeb6ea2ade6c17820ef4705f2e83a41Chris Lattner    bool OldGreaterThanIsOperator;
289648d846e4f140c30ab9d322870ea3fdd94debba2Benjamin Kramer  public:
290d0d76f1cbeeb6ea2ade6c17820ef4705f2e83a41Chris Lattner    GreaterThanIsOperatorScope(bool &GTIO, bool Val)
291d0d76f1cbeeb6ea2ade6c17820ef4705f2e83a41Chris Lattner    : GreaterThanIsOperator(GTIO), OldGreaterThanIsOperator(GTIO) {
292d0d76f1cbeeb6ea2ade6c17820ef4705f2e83a41Chris Lattner      GreaterThanIsOperator = Val;
293d0d76f1cbeeb6ea2ade6c17820ef4705f2e83a41Chris Lattner    }
294d0d76f1cbeeb6ea2ade6c17820ef4705f2e83a41Chris Lattner
295d0d76f1cbeeb6ea2ade6c17820ef4705f2e83a41Chris Lattner    ~GreaterThanIsOperatorScope() {
296d0d76f1cbeeb6ea2ade6c17820ef4705f2e83a41Chris Lattner      GreaterThanIsOperator = OldGreaterThanIsOperator;
297d0d76f1cbeeb6ea2ade6c17820ef4705f2e83a41Chris Lattner    }
298d0d76f1cbeeb6ea2ade6c17820ef4705f2e83a41Chris Lattner  };
299d0d76f1cbeeb6ea2ade6c17820ef4705f2e83a41Chris Lattner
3000fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor  class InMessageExpressionRAIIObject {
3010fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor    bool &InMessageExpression;
3020fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor    bool OldValue;
3030fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor
3040fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor  public:
3050fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor    InMessageExpressionRAIIObject(Parser &P, bool Value)
3060fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor      : InMessageExpression(P.InMessageExpression),
3070fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor        OldValue(P.InMessageExpression) {
3080fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor      InMessageExpression = Value;
3090fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor    }
3100fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor
3110fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor    ~InMessageExpressionRAIIObject() {
3120fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor      InMessageExpression = OldValue;
3130fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor    }
3140fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor  };
3150fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor
31636d36806f1972f7ec1d2a3f59155187278c56508Argyrios Kyrtzidis  /// \brief RAII object that makes sure paren/bracket/brace count is correct
31736d36806f1972f7ec1d2a3f59155187278c56508Argyrios Kyrtzidis  /// after declaration/statement parsing, even when there's a parsing error.
31836d36806f1972f7ec1d2a3f59155187278c56508Argyrios Kyrtzidis  class ParenBraceBracketBalancer {
31936d36806f1972f7ec1d2a3f59155187278c56508Argyrios Kyrtzidis    Parser &P;
32036d36806f1972f7ec1d2a3f59155187278c56508Argyrios Kyrtzidis    unsigned short ParenCount, BracketCount, BraceCount;
32136d36806f1972f7ec1d2a3f59155187278c56508Argyrios Kyrtzidis  public:
32236d36806f1972f7ec1d2a3f59155187278c56508Argyrios Kyrtzidis    ParenBraceBracketBalancer(Parser &p)
32336d36806f1972f7ec1d2a3f59155187278c56508Argyrios Kyrtzidis      : P(p), ParenCount(p.ParenCount), BracketCount(p.BracketCount),
32436d36806f1972f7ec1d2a3f59155187278c56508Argyrios Kyrtzidis        BraceCount(p.BraceCount) { }
32536d36806f1972f7ec1d2a3f59155187278c56508Argyrios Kyrtzidis
32636d36806f1972f7ec1d2a3f59155187278c56508Argyrios Kyrtzidis    ~ParenBraceBracketBalancer() {
32736d36806f1972f7ec1d2a3f59155187278c56508Argyrios Kyrtzidis      P.ParenCount = ParenCount;
32836d36806f1972f7ec1d2a3f59155187278c56508Argyrios Kyrtzidis      P.BracketCount = BracketCount;
32936d36806f1972f7ec1d2a3f59155187278c56508Argyrios Kyrtzidis      P.BraceCount = BraceCount;
33036d36806f1972f7ec1d2a3f59155187278c56508Argyrios Kyrtzidis    }
33136d36806f1972f7ec1d2a3f59155187278c56508Argyrios Kyrtzidis  };
33228bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley
33328bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  class PoisonSEHIdentifiersRAIIObject {
33428bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    PoisonIdentifierRAIIObject Ident_AbnormalTermination;
33528bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    PoisonIdentifierRAIIObject Ident_GetExceptionCode;
33628bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    PoisonIdentifierRAIIObject Ident_GetExceptionInfo;
33728bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    PoisonIdentifierRAIIObject Ident__abnormal_termination;
33828bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    PoisonIdentifierRAIIObject Ident__exception_code;
33928bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    PoisonIdentifierRAIIObject Ident__exception_info;
34028bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    PoisonIdentifierRAIIObject Ident___abnormal_termination;
34128bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    PoisonIdentifierRAIIObject Ident___exception_code;
34228bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    PoisonIdentifierRAIIObject Ident___exception_info;
34328bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  public:
34428bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    PoisonSEHIdentifiersRAIIObject(Parser &Self, bool NewValue)
34528bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley      : Ident_AbnormalTermination(Self.Ident_AbnormalTermination, NewValue),
34628bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley        Ident_GetExceptionCode(Self.Ident_GetExceptionCode, NewValue),
34728bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley        Ident_GetExceptionInfo(Self.Ident_GetExceptionInfo, NewValue),
34828bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley        Ident__abnormal_termination(Self.Ident__abnormal_termination, NewValue),
34928bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley        Ident__exception_code(Self.Ident__exception_code, NewValue),
35028bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley        Ident__exception_info(Self.Ident__exception_info, NewValue),
35128bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley        Ident___abnormal_termination(Self.Ident___abnormal_termination, NewValue),
35228bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley        Ident___exception_code(Self.Ident___exception_code, NewValue),
35328bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley        Ident___exception_info(Self.Ident___exception_info, NewValue) {
35428bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    }
35528bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  };
35628bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley
357c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor  /// \brief RAII class that helps handle the parsing of an open/close delimiter
358c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor  /// pair, such as braces { ... } or parentheses ( ... ).
359c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor  class BalancedDelimiterTracker : public GreaterThanIsOperatorScope {
360c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor    Parser& P;
361c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor    tok::TokenKind Kind, Close;
362c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor    SourceLocation (Parser::*Consumer)();
363c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor    SourceLocation LOpen, LClose;
364c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor
365c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor    unsigned short &getDepth() {
366c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor      switch (Kind) {
367c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor        case tok::l_brace: return P.BraceCount;
368c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor        case tok::l_square: return P.BracketCount;
369c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor        case tok::l_paren: return P.ParenCount;
370c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor        default: llvm_unreachable("Wrong token kind");
371c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor      }
372c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor    }
373c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor
374c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor    enum { MaxDepth = 256 };
375c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor
376c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor    bool diagnoseOverflow();
377c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor    bool diagnoseMissingClose();
378c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor
379c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor  public:
380c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor    BalancedDelimiterTracker(Parser& p, tok::TokenKind k)
381c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor      : GreaterThanIsOperatorScope(p.GreaterThanIsOperator, true),
382c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor        P(p), Kind(k)
383c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor    {
384c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor      switch (Kind) {
385c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor        default: llvm_unreachable("Unexpected balanced token");
386c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor        case tok::l_brace:
387c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor          Close = tok::r_brace;
388c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor          Consumer = &Parser::ConsumeBrace;
389c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor          break;
390c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor        case tok::l_paren:
391c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor          Close = tok::r_paren;
392c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor          Consumer = &Parser::ConsumeParen;
393c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor          break;
394c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor
395c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor        case tok::l_square:
396c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor          Close = tok::r_square;
397c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor          Consumer = &Parser::ConsumeBracket;
398c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor          break;
399c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor      }
400c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor    }
401c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor
402c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor    SourceLocation getOpenLocation() const { return LOpen; }
403c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor    SourceLocation getCloseLocation() const { return LClose; }
404c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor    SourceRange getRange() const { return SourceRange(LOpen, LClose); }
405c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor
406c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor    bool consumeOpen() {
407c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor      if (!P.Tok.is(Kind))
408c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor        return true;
409c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor
410c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor      if (getDepth() < MaxDepth) {
411c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor        LOpen = (P.*Consumer)();
412c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor        return false;
413c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor      }
414c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor
415c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor      return diagnoseOverflow();
416c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor    }
417c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor
418c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor    bool expectAndConsume(unsigned DiagID,
419c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor                          const char *Msg = "",
420c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor                          tok::TokenKind SkipToTok = tok::unknown);
421c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor    bool consumeClose() {
422c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor      if (P.Tok.is(Close)) {
423c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor        LClose = (P.*Consumer)();
424c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor        return false;
425c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor      }
426c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor
427c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor      return diagnoseMissingClose();
428c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor    }
429c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor    void skipToEnd();
430c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor  };
431c86c40b912e53fb11ff8f745ed616035b8b7259cDouglas Gregor
43208d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner} // end namespace clang
433c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner
434c46d1a1f8af67a87689d7db9eaf96027282ccaeaChris Lattner#endif
435