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 >IO, 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