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