//===--- CXX.h - Public interfaces for the C++ grammar -----------*- C++-*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This file defines public interfaces for the C++ grammar // (pseudo/lib/cxx/cxx.bnf). It provides a fast way to access core building // pieces of the LR parser, e.g. Grammar, LRTable, rather than parsing the // grammar file at the runtime. // // We do a compilation of the C++ BNF grammar at build time, and generate // critical data sources. The implementation of the interfaces are based on the // generated data sources. // // FIXME: not everything is fully compiled yet. The implementation of the // interfaces are still parsing the grammar file at the runtime. // //===----------------------------------------------------------------------===// #ifndef CLANG_PSEUDO_CXX_CXX_H #define CLANG_PSEUDO_CXX_CXX_H #include "clang-pseudo/Language.h" #include "clang-pseudo/grammar/Grammar.h" namespace clang { namespace pseudo { namespace cxx { // We want enums to be scoped but implicitly convertible to RuleID etc. // So create regular (unscoped) enums inside subnamespaces of `detail`. // Then add aliases for them outside `detail`. namespace detail { namespace symbols { enum Symbol : SymbolID { #define NONTERMINAL(X, Y) X = Y, #include "CXXSymbols.inc" #undef NONTERMINAL }; } // namespace symbols namespace extensions { enum Extension : ExtensionID { #define EXTENSION(X, Y) X = Y, #include "CXXSymbols.inc" #undef EXTENSION }; } // namespace extensions namespace rules { // For each symbol we close the last symbol's enum+namespace and open new ones. // We need a dummy namespace+enum so that this works for the first rule. namespace dummy { enum Dummy { //clang-format off #define NONTERMINAL(NAME, ID) \ }; \ } \ namespace NAME { \ enum Rule : RuleID { //clang-format on #define RULE(LHS, RHS, ID) RHS = ID, #include "CXXSymbols.inc" }; } } // namespace rules } // namespace detail // Symbol represents nonterminal symbols in the C++ grammar. // It provides a simple uniform way to access a particular nonterminal. using Symbol = detail::symbols::Symbol; using Extension = detail::extensions::Extension; namespace rule { #define NONTERMINAL(NAME, ID) using NAME = detail::rules::NAME::Rule; #include "CXXSymbols.inc" } // namespace rule // Returns the Language for the cxx.bnf grammar. const Language &getLanguage(); } // namespace cxx } // namespace pseudo } // namespace clang #endif // CLANG_PSEUDO_CXX_CXX_H