LCOV - code coverage report
Current view: top level - src/torque - torque-parser.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 714 747 95.6 %
Date: 2019-02-19 Functions: 89 91 97.8 %

          Line data    Source code
       1             : // Copyright 2018 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #include <cctype>
       6             : 
       7             : #include "src/torque/earley-parser.h"
       8             : #include "src/torque/torque-parser.h"
       9             : #include "src/torque/utils.h"
      10             : 
      11             : namespace v8 {
      12             : namespace internal {
      13             : namespace torque {
      14             : 
      15        1918 : DEFINE_CONTEXTUAL_VARIABLE(CurrentAst)
      16             : 
      17             : using TypeList = std::vector<TypeExpression*>;
      18             : using GenericParameters = std::vector<std::string>;
      19             : 
      20         654 : struct ExpressionWithSource {
      21             :   Expression* expression;
      22             :   std::string source;
      23             : };
      24             : 
      25         518 : struct TypeswitchCase {
      26             :   SourcePosition pos;
      27             :   base::Optional<std::string> name;
      28             :   TypeExpression* type;
      29             :   Statement* block;
      30             : };
      31             : 
      32             : enum class ParseResultHolderBase::TypeId {
      33             :   kStdString,
      34             :   kBool,
      35             :   kStdVectorOfString,
      36             :   kExpressionPtr,
      37             :   kLocationExpressionPtr,
      38             :   kStatementPtr,
      39             :   kDeclarationPtr,
      40             :   kTypeExpressionPtr,
      41             :   kOptionalTypeExpressionPtr,
      42             :   kLabelBlockPtr,
      43             :   kOptionalLabelBlockPtr,
      44             :   kNameAndTypeExpression,
      45             :   kClassFieldExpression,
      46             :   kStructFieldExpression,
      47             :   kStdVectorOfNameAndTypeExpression,
      48             :   kStdVectorOfClassFieldExpression,
      49             :   kStdVectorOfStructFieldExpression,
      50             :   kIncrementDecrementOperator,
      51             :   kOptionalStdString,
      52             :   kStdVectorOfStatementPtr,
      53             :   kStdVectorOfDeclarationPtr,
      54             :   kStdVectorOfExpressionPtr,
      55             :   kExpressionWithSource,
      56             :   kParameterList,
      57             :   kRangeExpression,
      58             :   kOptionalRangeExpression,
      59             :   kTypeList,
      60             :   kOptionalTypeList,
      61             :   kLabelAndTypes,
      62             :   kStdVectorOfLabelAndTypes,
      63             :   kStdVectorOfLabelBlockPtr,
      64             :   kOptionalStatementPtr,
      65             :   kOptionalExpressionPtr,
      66             :   kTypeswitchCase,
      67             :   kStdVectorOfTypeswitchCase
      68             : };
      69             : 
      70             : template <>
      71             : V8_EXPORT_PRIVATE const ParseResultTypeId ParseResultHolder<std::string>::id =
      72             :     ParseResultTypeId::kStdString;
      73             : template <>
      74             : V8_EXPORT_PRIVATE const ParseResultTypeId ParseResultHolder<bool>::id =
      75             :     ParseResultTypeId::kBool;
      76             : template <>
      77             : V8_EXPORT_PRIVATE const ParseResultTypeId
      78             :     ParseResultHolder<std::vector<std::string>>::id =
      79             :         ParseResultTypeId::kStdVectorOfString;
      80             : template <>
      81             : V8_EXPORT_PRIVATE const ParseResultTypeId ParseResultHolder<Declaration*>::id =
      82             :     ParseResultTypeId::kDeclarationPtr;
      83             : template <>
      84             : V8_EXPORT_PRIVATE const ParseResultTypeId
      85             :     ParseResultHolder<TypeExpression*>::id =
      86             :         ParseResultTypeId::kTypeExpressionPtr;
      87             : template <>
      88             : V8_EXPORT_PRIVATE const ParseResultTypeId
      89             :     ParseResultHolder<base::Optional<TypeExpression*>>::id =
      90             :         ParseResultTypeId::kOptionalTypeExpressionPtr;
      91             : template <>
      92             : V8_EXPORT_PRIVATE const ParseResultTypeId ParseResultHolder<LabelBlock*>::id =
      93             :     ParseResultTypeId::kLabelBlockPtr;
      94             : template <>
      95             : V8_EXPORT_PRIVATE const ParseResultTypeId
      96             :     ParseResultHolder<base::Optional<LabelBlock*>>::id =
      97             :         ParseResultTypeId::kOptionalLabelBlockPtr;
      98             : template <>
      99             : V8_EXPORT_PRIVATE const ParseResultTypeId ParseResultHolder<Expression*>::id =
     100             :     ParseResultTypeId::kExpressionPtr;
     101             : template <>
     102             : V8_EXPORT_PRIVATE const ParseResultTypeId
     103             :     ParseResultHolder<LocationExpression*>::id =
     104             :         ParseResultTypeId::kLocationExpressionPtr;
     105             : template <>
     106             : V8_EXPORT_PRIVATE const ParseResultTypeId ParseResultHolder<Statement*>::id =
     107             :     ParseResultTypeId::kStatementPtr;
     108             : template <>
     109             : V8_EXPORT_PRIVATE const ParseResultTypeId
     110             :     ParseResultHolder<NameAndTypeExpression>::id =
     111             :         ParseResultTypeId::kNameAndTypeExpression;
     112             : template <>
     113             : V8_EXPORT_PRIVATE const ParseResultTypeId
     114             :     ParseResultHolder<ClassFieldExpression>::id =
     115             :         ParseResultTypeId::kClassFieldExpression;
     116             : template <>
     117             : V8_EXPORT_PRIVATE const ParseResultTypeId
     118             :     ParseResultHolder<StructFieldExpression>::id =
     119             :         ParseResultTypeId::kStructFieldExpression;
     120             : template <>
     121             : V8_EXPORT_PRIVATE const ParseResultTypeId
     122             :     ParseResultHolder<std::vector<NameAndTypeExpression>>::id =
     123             :         ParseResultTypeId::kStdVectorOfNameAndTypeExpression;
     124             : template <>
     125             : V8_EXPORT_PRIVATE const ParseResultTypeId
     126             :     ParseResultHolder<std::vector<ClassFieldExpression>>::id =
     127             :         ParseResultTypeId::kStdVectorOfClassFieldExpression;
     128             : template <>
     129             : V8_EXPORT_PRIVATE const ParseResultTypeId
     130             :     ParseResultHolder<std::vector<StructFieldExpression>>::id =
     131             :         ParseResultTypeId::kStdVectorOfStructFieldExpression;
     132             : template <>
     133             : V8_EXPORT_PRIVATE const ParseResultTypeId
     134             :     ParseResultHolder<IncrementDecrementOperator>::id =
     135             :         ParseResultTypeId::kIncrementDecrementOperator;
     136             : template <>
     137             : V8_EXPORT_PRIVATE const ParseResultTypeId
     138             :     ParseResultHolder<base::Optional<std::string>>::id =
     139             :         ParseResultTypeId::kOptionalStdString;
     140             : template <>
     141             : V8_EXPORT_PRIVATE const ParseResultTypeId
     142             :     ParseResultHolder<std::vector<Statement*>>::id =
     143             :         ParseResultTypeId::kStdVectorOfStatementPtr;
     144             : template <>
     145             : V8_EXPORT_PRIVATE const ParseResultTypeId
     146             :     ParseResultHolder<std::vector<Declaration*>>::id =
     147             :         ParseResultTypeId::kStdVectorOfDeclarationPtr;
     148             : template <>
     149             : V8_EXPORT_PRIVATE const ParseResultTypeId
     150             :     ParseResultHolder<std::vector<Expression*>>::id =
     151             :         ParseResultTypeId::kStdVectorOfExpressionPtr;
     152             : template <>
     153             : V8_EXPORT_PRIVATE const ParseResultTypeId
     154             :     ParseResultHolder<ExpressionWithSource>::id =
     155             :         ParseResultTypeId::kExpressionWithSource;
     156             : template <>
     157             : V8_EXPORT_PRIVATE const ParseResultTypeId ParseResultHolder<ParameterList>::id =
     158             :     ParseResultTypeId::kParameterList;
     159             : template <>
     160             : V8_EXPORT_PRIVATE const ParseResultTypeId
     161             :     ParseResultHolder<RangeExpression>::id =
     162             :         ParseResultTypeId::kRangeExpression;
     163             : template <>
     164             : V8_EXPORT_PRIVATE const ParseResultTypeId
     165             :     ParseResultHolder<base::Optional<RangeExpression>>::id =
     166             :         ParseResultTypeId::kOptionalRangeExpression;
     167             : template <>
     168             : V8_EXPORT_PRIVATE const ParseResultTypeId ParseResultHolder<TypeList>::id =
     169             :     ParseResultTypeId::kTypeList;
     170             : template <>
     171             : V8_EXPORT_PRIVATE const ParseResultTypeId
     172             :     ParseResultHolder<base::Optional<TypeList>>::id =
     173             :         ParseResultTypeId::kOptionalTypeList;
     174             : template <>
     175             : V8_EXPORT_PRIVATE const ParseResultTypeId ParseResultHolder<LabelAndTypes>::id =
     176             :     ParseResultTypeId::kLabelAndTypes;
     177             : template <>
     178             : V8_EXPORT_PRIVATE const ParseResultTypeId
     179             :     ParseResultHolder<std::vector<LabelAndTypes>>::id =
     180             :         ParseResultTypeId::kStdVectorOfLabelAndTypes;
     181             : template <>
     182             : V8_EXPORT_PRIVATE const ParseResultTypeId
     183             :     ParseResultHolder<std::vector<LabelBlock*>>::id =
     184             :         ParseResultTypeId::kStdVectorOfLabelBlockPtr;
     185             : template <>
     186             : V8_EXPORT_PRIVATE const ParseResultTypeId
     187             :     ParseResultHolder<base::Optional<Statement*>>::id =
     188             :         ParseResultTypeId::kOptionalStatementPtr;
     189             : template <>
     190             : V8_EXPORT_PRIVATE const ParseResultTypeId
     191             :     ParseResultHolder<base::Optional<Expression*>>::id =
     192             :         ParseResultTypeId::kOptionalExpressionPtr;
     193             : template <>
     194             : V8_EXPORT_PRIVATE const ParseResultTypeId
     195             :     ParseResultHolder<TypeswitchCase>::id = ParseResultTypeId::kTypeswitchCase;
     196             : template <>
     197             : V8_EXPORT_PRIVATE const ParseResultTypeId
     198             :     ParseResultHolder<std::vector<TypeswitchCase>>::id =
     199             :         ParseResultTypeId::kStdVectorOfTypeswitchCase;
     200             : 
     201             : namespace {
     202             : 
     203         748 : base::Optional<ParseResult> AddGlobalDeclaration(
     204             :     ParseResultIterator* child_results) {
     205         748 :   auto declaration = child_results->NextAs<Declaration*>();
     206         748 :   CurrentAst::Get().declarations().push_back(declaration);
     207         748 :   return base::nullopt;
     208             : }
     209             : 
     210         741 : void LintGenericParameters(const GenericParameters& parameters) {
     211        1544 :   for (const std::string& parameter : parameters) {
     212          62 :     if (!IsUpperCamelCase(parameter)) {
     213           0 :       NamingConventionError("Generic parameter", parameter, "UpperCamelCase");
     214             :     }
     215             :   }
     216         741 : }
     217             : 
     218        3203 : void CheckNotDeferredStatement(Statement* statement) {
     219        3203 :   CurrentSourcePosition::Scope source_position(statement->pos);
     220        3203 :   if (BlockStatement* block = BlockStatement::DynamicCast(statement)) {
     221         334 :     if (block->deferred) {
     222             :       LintError(
     223             :           "cannot use deferred with a statement block here, it will have no "
     224           0 :           "effect");
     225             :     }
     226             :   }
     227        3203 : }
     228             : 
     229        2556 : Expression* MakeCall(IdentifierExpression* callee,
     230        2556 :                      base::Optional<Expression*> target,
     231             :                      std::vector<Expression*> arguments,
     232             :                      const std::vector<Statement*>& otherwise) {
     233             :   std::vector<std::string> labels;
     234             : 
     235             :   // All IdentifierExpressions are treated as label names and can be directly
     236             :   // used as labels identifiers. All other statements in a call's otherwise
     237             :   // must create intermediate Labels for the otherwise's statement code.
     238             :   size_t label_id = 0;
     239             :   std::vector<LabelBlock*> temp_labels;
     240        5398 :   for (auto* statement : otherwise) {
     241         286 :     if (auto* e = ExpressionStatement::DynamicCast(statement)) {
     242         400 :       if (auto* id = IdentifierExpression::DynamicCast(e->expression)) {
     243         392 :         if (id->generic_arguments.size() != 0) {
     244           0 :           ReportError("An otherwise label cannot have generic parameters");
     245             :         }
     246         196 :         labels.push_back(id->name);
     247         196 :         continue;
     248             :       }
     249             :     }
     250         360 :     auto label_name = std::string("_label") + std::to_string(label_id++);
     251          90 :     labels.push_back(label_name);
     252             :     auto* label_block =
     253         180 :         MakeNode<LabelBlock>(label_name, ParameterList::Empty(), statement);
     254          90 :     temp_labels.push_back(label_block);
     255             :   }
     256             : 
     257             :   // Create nested try-label expression for all of the temporary Labels that
     258             :   // were created.
     259             :   Expression* result = nullptr;
     260        2556 :   if (target) {
     261         104 :     result = MakeNode<CallMethodExpression>(*target, callee, arguments, labels);
     262             :   } else {
     263        5008 :     result = MakeNode<CallExpression>(callee, arguments, labels);
     264             :   }
     265             : 
     266        5202 :   for (auto* label : temp_labels) {
     267          90 :     result = MakeNode<TryLabelExpression>(false, result, label);
     268             :   }
     269        2556 :   return result;
     270             : }
     271             : 
     272        1094 : Expression* MakeCall(const std::string& callee,
     273             :                      const std::vector<TypeExpression*>& generic_arguments,
     274             :                      const std::vector<Expression*>& arguments,
     275             :                      const std::vector<Statement*>& otherwise) {
     276             :   return MakeCall(MakeNode<IdentifierExpression>(callee, generic_arguments),
     277        5470 :                   base::nullopt, arguments, otherwise);
     278             : }
     279             : 
     280        1414 : base::Optional<ParseResult> MakeCall(ParseResultIterator* child_results) {
     281        1414 :   auto callee = child_results->NextAs<LocationExpression*>();
     282        1414 :   auto args = child_results->NextAs<std::vector<Expression*>>();
     283        1414 :   auto otherwise = child_results->NextAs<std::vector<Statement*>>();
     284             :   IdentifierExpression* target = IdentifierExpression::cast(callee);
     285        2828 :   if (target->name == kSuperMethodName) {
     286           8 :     if (target->namespace_qualification.size() != 0) {
     287             :       ReportError(
     288           0 :           "\"super\" invocation cannot be used with namespace qualification");
     289             :     }
     290           4 :     target = MakeNode<IdentifierExpression>(kSuperMethodName);
     291             :     return ParseResult{
     292           4 :         MakeCall(target, MakeNode<IdentifierExpression>(kThisParameterName),
     293          16 :                  args, otherwise)};
     294             :   } else {
     295        5640 :     return ParseResult{MakeCall(target, base::nullopt, args, otherwise)};
     296             :   }
     297             : }
     298             : 
     299          48 : base::Optional<ParseResult> MakeMethodCall(ParseResultIterator* child_results) {
     300          48 :   auto this_arg = child_results->NextAs<Expression*>();
     301          48 :   auto callee = child_results->NextAs<std::string>();
     302          48 :   auto args = child_results->NextAs<std::vector<Expression*>>();
     303          48 :   auto otherwise = child_results->NextAs<std::vector<Statement*>>();
     304             :   return ParseResult{MakeCall(MakeNode<IdentifierExpression>(callee), this_arg,
     305         240 :                               args, otherwise)};
     306             : }
     307             : 
     308           8 : base::Optional<ParseResult> MakeNew(ParseResultIterator* child_results) {
     309           8 :   TypeExpression* type = child_results->NextAs<TypeExpression*>();
     310           8 :   auto args = child_results->NextAs<std::vector<Expression*>>();
     311          16 :   Expression* result = MakeNode<NewExpression>(type, args);
     312           8 :   return ParseResult{result};
     313             : }
     314             : 
     315        1014 : base::Optional<ParseResult> MakeBinaryOperator(
     316             :     ParseResultIterator* child_results) {
     317        1014 :   auto left = child_results->NextAs<Expression*>();
     318        1014 :   auto op = child_results->NextAs<std::string>();
     319        1014 :   auto right = child_results->NextAs<Expression*>();
     320             :   return ParseResult{MakeCall(op, TypeList{},
     321             :                               std::vector<Expression*>{left, right},
     322        6084 :                               std::vector<Statement*>{})};
     323             : }
     324             : 
     325          46 : base::Optional<ParseResult> MakeIntrinsicCallExpression(
     326             :     ParseResultIterator* child_results) {
     327          46 :   auto callee = child_results->NextAs<std::string>();
     328             :   auto generic_arguments =
     329          46 :       child_results->NextAs<std::vector<TypeExpression*>>();
     330          46 :   auto args = child_results->NextAs<std::vector<Expression*>>();
     331             :   Expression* result =
     332         184 :       MakeNode<IntrinsicCallExpression>(callee, generic_arguments, args);
     333          46 :   return ParseResult{result};
     334             : }
     335             : 
     336          46 : base::Optional<ParseResult> MakeUnaryOperator(
     337             :     ParseResultIterator* child_results) {
     338          46 :   auto op = child_results->NextAs<std::string>();
     339          46 :   auto e = child_results->NextAs<Expression*>();
     340             :   return ParseResult{MakeCall(op, TypeList{}, std::vector<Expression*>{e},
     341         276 :                               std::vector<Statement*>{})};
     342             : }
     343             : 
     344             : template <bool has_varargs>
     345         425 : base::Optional<ParseResult> MakeParameterListFromTypes(
     346             :     ParseResultIterator* child_results) {
     347             :   auto implicit_params =
     348         425 :       child_results->NextAs<std::vector<NameAndTypeExpression>>();
     349         425 :   auto explicit_types = child_results->NextAs<TypeList>();
     350         425 :   ParameterList result;
     351         425 :   result.has_varargs = has_varargs;
     352         850 :   result.implicit_count = implicit_params.size();
     353         893 :   for (NameAndTypeExpression& implicit_param : implicit_params) {
     354          43 :     if (!IsLowerCamelCase(implicit_param.name)) {
     355           0 :       NamingConventionError("Parameter", implicit_param.name, "lowerCamelCase");
     356             :     }
     357          43 :     result.names.push_back(implicit_param.name);
     358          43 :     result.types.push_back(implicit_param.type);
     359             :   }
     360        1605 :   for (auto* explicit_type : explicit_types) {
     361         755 :     result.types.push_back(explicit_type);
     362             :   }
     363        1275 :   return ParseResult{std::move(result)};
     364             : }
     365             : 
     366             : template <bool has_varargs>
     367         508 : base::Optional<ParseResult> MakeParameterListFromNameAndTypeList(
     368             :     ParseResultIterator* child_results) {
     369             :   auto implicit_params =
     370         508 :       child_results->NextAs<std::vector<NameAndTypeExpression>>();
     371             :   auto explicit_params =
     372        1016 :       child_results->NextAs<std::vector<NameAndTypeExpression>>();
     373         508 :   std::string arguments_variable = "";
     374         508 :   if (child_results->HasNext()) {
     375          96 :     arguments_variable = child_results->NextAs<std::string>();
     376             :   }
     377         508 :   ParameterList result;
     378        1200 :   for (NameAndTypeExpression& pair : implicit_params) {
     379         184 :     if (!IsLowerCamelCase(pair.name)) {
     380           0 :       NamingConventionError("Parameter", pair.name, "lowerCamelCase");
     381             :     }
     382             : 
     383             :     result.names.push_back(std::move(pair.name));
     384         184 :     result.types.push_back(pair.type);
     385             :   }
     386        2036 :   for (NameAndTypeExpression& pair : explicit_params) {
     387        1020 :     if (!IsLowerCamelCase(pair.name)) {
     388           0 :       NamingConventionError("Parameter", pair.name, "lowerCamelCase");
     389             :     }
     390             : 
     391             :     result.names.push_back(std::move(pair.name));
     392        1020 :     result.types.push_back(pair.type);
     393             :   }
     394        1016 :   result.implicit_count = implicit_params.size();
     395         508 :   result.has_varargs = has_varargs;
     396             :   result.arguments_variable = arguments_variable;
     397        1524 :   return ParseResult{std::move(result)};
     398             : }
     399             : 
     400         218 : base::Optional<ParseResult> MakeAssertStatement(
     401             :     ParseResultIterator* child_results) {
     402         218 :   auto kind = child_results->NextAs<std::string>();
     403         218 :   auto expr_with_source = child_results->NextAs<ExpressionWithSource>();
     404             :   DCHECK(kind == "assert" || kind == "check");
     405             :   Statement* result = MakeNode<AssertStatement>(
     406         654 :       kind == "assert", expr_with_source.expression, expr_with_source.source);
     407         218 :   return ParseResult{result};
     408             : }
     409             : 
     410          75 : base::Optional<ParseResult> MakeDebugStatement(
     411             :     ParseResultIterator* child_results) {
     412          75 :   auto kind = child_results->NextAs<std::string>();
     413             :   DCHECK(kind == "unreachable" || kind == "debug");
     414         150 :   Statement* result = MakeNode<DebugStatement>(kind, kind == "unreachable");
     415          75 :   return ParseResult{result};
     416             : }
     417             : 
     418         101 : base::Optional<ParseResult> MakeVoidType(ParseResultIterator* child_results) {
     419             :   TypeExpression* result =
     420         101 :       MakeNode<BasicTypeExpression>(std::vector<std::string>{}, false, "void");
     421         101 :   return ParseResult{result};
     422             : }
     423             : 
     424         393 : base::Optional<ParseResult> MakeExternalMacro(
     425             :     ParseResultIterator* child_results) {
     426         393 :   auto transitioning = child_results->NextAs<bool>();
     427         393 :   auto operator_name = child_results->NextAs<base::Optional<std::string>>();
     428             :   auto external_assembler_name =
     429         393 :       child_results->NextAs<base::Optional<std::string>>();
     430         393 :   auto name = child_results->NextAs<std::string>();
     431         786 :   auto generic_parameters = child_results->NextAs<GenericParameters>();
     432         393 :   LintGenericParameters(generic_parameters);
     433             : 
     434         786 :   auto args = child_results->NextAs<ParameterList>();
     435         393 :   auto return_type = child_results->NextAs<TypeExpression*>();
     436         786 :   auto labels = child_results->NextAs<LabelAndTypesVector>();
     437             :   MacroDeclaration* macro = MakeNode<ExternalMacroDeclaration>(
     438             :       transitioning,
     439         393 :       external_assembler_name ? *external_assembler_name : "CodeStubAssembler",
     440        2358 :       name, operator_name, args, return_type, labels);
     441             :   Declaration* result;
     442         393 :   if (generic_parameters.empty()) {
     443         393 :     result = MakeNode<StandardDeclaration>(macro, base::nullopt);
     444             :   } else {
     445           0 :     result = MakeNode<GenericDeclaration>(macro, generic_parameters);
     446             :   }
     447         393 :   return ParseResult{result};
     448             : }
     449             : 
     450           6 : base::Optional<ParseResult> MakeIntrinsicDeclaration(
     451             :     ParseResultIterator* child_results) {
     452           6 :   auto name = child_results->NextAs<std::string>();
     453          12 :   auto generic_parameters = child_results->NextAs<GenericParameters>();
     454           6 :   LintGenericParameters(generic_parameters);
     455             : 
     456          12 :   auto args = child_results->NextAs<ParameterList>();
     457           6 :   auto return_type = child_results->NextAs<TypeExpression*>();
     458             :   IntrinsicDeclaration* macro =
     459          12 :       MakeNode<IntrinsicDeclaration>(name, args, return_type);
     460             :   Declaration* result;
     461           6 :   if (generic_parameters.empty()) {
     462           0 :     result = MakeNode<StandardDeclaration>(macro, base::nullopt);
     463             :   } else {
     464           6 :     result = MakeNode<GenericDeclaration>(macro, generic_parameters);
     465             :   }
     466           6 :   return ParseResult{result};
     467             : }
     468             : 
     469         238 : base::Optional<ParseResult> MakeTorqueMacroDeclaration(
     470             :     ParseResultIterator* child_results) {
     471         238 :   auto transitioning = child_results->NextAs<bool>();
     472         238 :   auto operator_name = child_results->NextAs<base::Optional<std::string>>();
     473         238 :   auto name = child_results->NextAs<std::string>();
     474         238 :   if (!IsUpperCamelCase(name)) {
     475           0 :     NamingConventionError("Macro", name, "UpperCamelCase");
     476             :   }
     477             : 
     478         476 :   auto generic_parameters = child_results->NextAs<GenericParameters>();
     479         238 :   LintGenericParameters(generic_parameters);
     480             : 
     481         476 :   auto args = child_results->NextAs<ParameterList>();
     482         238 :   auto return_type = child_results->NextAs<TypeExpression*>();
     483         476 :   auto labels = child_results->NextAs<LabelAndTypesVector>();
     484         238 :   auto body = child_results->NextAs<base::Optional<Statement*>>();
     485             :   MacroDeclaration* macro = MakeNode<TorqueMacroDeclaration>(
     486         952 :       transitioning, name, operator_name, args, return_type, labels);
     487             :   Declaration* result;
     488         238 :   if (generic_parameters.empty()) {
     489         202 :     if (!body) ReportError("A non-generic declaration needs a body.");
     490         202 :     result = MakeNode<StandardDeclaration>(macro, *body);
     491             :   } else {
     492          36 :     result = MakeNode<GenericDeclaration>(macro, generic_parameters, body);
     493             :   }
     494         238 :   return ParseResult{result};
     495             : }
     496             : 
     497          86 : base::Optional<ParseResult> MakeTorqueBuiltinDeclaration(
     498             :     ParseResultIterator* child_results) {
     499          86 :   auto transitioning = child_results->NextAs<bool>();
     500          86 :   auto javascript_linkage = child_results->NextAs<bool>();
     501          86 :   auto name = child_results->NextAs<std::string>();
     502          86 :   if (!IsUpperCamelCase(name)) {
     503           0 :     NamingConventionError("Builtin", name, "UpperCamelCase");
     504             :   }
     505             : 
     506         172 :   auto generic_parameters = child_results->NextAs<GenericParameters>();
     507          86 :   LintGenericParameters(generic_parameters);
     508             : 
     509         172 :   auto args = child_results->NextAs<ParameterList>();
     510          86 :   auto return_type = child_results->NextAs<TypeExpression*>();
     511          86 :   auto body = child_results->NextAs<base::Optional<Statement*>>();
     512             :   BuiltinDeclaration* builtin = MakeNode<TorqueBuiltinDeclaration>(
     513         172 :       transitioning, javascript_linkage, name, args, return_type);
     514             :   Declaration* result;
     515          86 :   if (generic_parameters.empty()) {
     516          78 :     if (!body) ReportError("A non-generic declaration needs a body.");
     517          78 :     result = MakeNode<StandardDeclaration>(builtin, *body);
     518             :   } else {
     519           8 :     result = MakeNode<GenericDeclaration>(builtin, generic_parameters, body);
     520             :   }
     521          86 :   return ParseResult{result};
     522             : }
     523             : 
     524          24 : base::Optional<ParseResult> MakeConstDeclaration(
     525             :     ParseResultIterator* child_results) {
     526          24 :   auto name = child_results->NextAs<std::string>();
     527          24 :   if (!IsValidNamespaceConstName(name)) {
     528           0 :     NamingConventionError("Constant", name, "kUpperCamelCase");
     529             :   }
     530             : 
     531          24 :   auto type = child_results->NextAs<TypeExpression*>();
     532          24 :   auto expression = child_results->NextAs<Expression*>();
     533             :   Declaration* result =
     534          48 :       MakeNode<ConstDeclaration>(std::move(name), type, expression);
     535          24 :   return ParseResult{result};
     536             : }
     537             : 
     538          81 : base::Optional<ParseResult> MakeExternConstDeclaration(
     539             :     ParseResultIterator* child_results) {
     540          81 :   auto name = child_results->NextAs<std::string>();
     541          81 :   auto type = child_results->NextAs<TypeExpression*>();
     542          81 :   auto literal = child_results->NextAs<std::string>();
     543             :   Declaration* result = MakeNode<ExternConstDeclaration>(std::move(name), type,
     544         243 :                                                          std::move(literal));
     545          81 :   return ParseResult{result};
     546             : }
     547             : 
     548          18 : base::Optional<ParseResult> MakeTypeAliasDeclaration(
     549             :     ParseResultIterator* child_results) {
     550          18 :   auto name = child_results->NextAs<std::string>();
     551          18 :   auto type = child_results->NextAs<TypeExpression*>();
     552          36 :   Declaration* result = MakeNode<TypeAliasDeclaration>(std::move(name), type);
     553          18 :   return ParseResult{result};
     554             : }
     555             : 
     556          87 : base::Optional<ParseResult> MakeTypeDeclaration(
     557             :     ParseResultIterator* child_results) {
     558          87 :   auto transient = child_results->NextAs<bool>();
     559          87 :   auto name = child_results->NextAs<std::string>();
     560          87 :   if (!IsValidTypeName(name)) {
     561           0 :     NamingConventionError("Type", name, "UpperCamelCase");
     562             :   }
     563          87 :   auto extends = child_results->NextAs<base::Optional<std::string>>();
     564          87 :   auto generates = child_results->NextAs<base::Optional<std::string>>();
     565             :   auto constexpr_generates =
     566          87 :       child_results->NextAs<base::Optional<std::string>>();
     567             :   Declaration* result = MakeNode<TypeDeclaration>(
     568             :       std::move(name), transient, std::move(extends), std::move(generates),
     569         522 :       std::move(constexpr_generates));
     570          87 :   return ParseResult{result};
     571             : }
     572             : 
     573          23 : base::Optional<ParseResult> MakeMethodDeclaration(
     574             :     ParseResultIterator* child_results) {
     575          23 :   auto transitioning = child_results->NextAs<bool>();
     576          23 :   auto operator_name = child_results->NextAs<base::Optional<std::string>>();
     577          23 :   auto name = child_results->NextAs<std::string>();
     578          23 :   if (name != kConstructMethodName && !IsUpperCamelCase(name)) {
     579           0 :     NamingConventionError("Method", name, "UpperCamelCase");
     580             :   }
     581             : 
     582          46 :   auto args = child_results->NextAs<ParameterList>();
     583          23 :   auto return_type = child_results->NextAs<TypeExpression*>();
     584          46 :   auto labels = child_results->NextAs<LabelAndTypesVector>();
     585          23 :   auto body = child_results->NextAs<Statement*>();
     586             :   MacroDeclaration* macro = MakeNode<TorqueMacroDeclaration>(
     587          92 :       transitioning, name, operator_name, args, return_type, labels);
     588          23 :   Declaration* result = MakeNode<StandardDeclaration>(macro, body);
     589          23 :   return ParseResult{result};
     590             : }
     591             : 
     592          19 : base::Optional<ParseResult> MakeClassDeclaration(
     593             :     ParseResultIterator* child_results) {
     594          19 :   auto is_extern = child_results->NextAs<bool>();
     595          19 :   auto transient = child_results->NextAs<bool>();
     596          19 :   auto name = child_results->NextAs<std::string>();
     597          19 :   if (!IsValidTypeName(name)) {
     598           0 :     NamingConventionError("Type", name, "UpperCamelCase");
     599             :   }
     600          19 :   auto extends = child_results->NextAs<base::Optional<std::string>>();
     601          19 :   auto generates = child_results->NextAs<base::Optional<std::string>>();
     602          19 :   auto methods = child_results->NextAs<std::vector<Declaration*>>();
     603          38 :   auto fields = child_results->NextAs<std::vector<ClassFieldExpression>>();
     604             :   Declaration* result = MakeNode<ClassDeclaration>(
     605             :       std::move(name), is_extern, transient, std::move(extends),
     606         133 :       std::move(generates), std::move(methods), fields);
     607          19 :   return ParseResult{result};
     608             : }
     609             : 
     610          26 : base::Optional<ParseResult> MakeNamespaceDeclaration(
     611             :     ParseResultIterator* child_results) {
     612          26 :   auto name = child_results->NextAs<std::string>();
     613          26 :   if (!IsSnakeCase(name)) {
     614           0 :     NamingConventionError("Namespace", name, "snake_case");
     615             :   }
     616          26 :   auto declarations = child_results->NextAs<std::vector<Declaration*>>();
     617             :   Declaration* result =
     618          78 :       MakeNode<NamespaceDeclaration>(std::move(name), std::move(declarations));
     619          26 :   return ParseResult{result};
     620             : }
     621             : 
     622         138 : base::Optional<ParseResult> MakeSpecializationDeclaration(
     623             :     ParseResultIterator* child_results) {
     624         138 :   auto name = child_results->NextAs<std::string>();
     625             :   auto generic_parameters =
     626         138 :       child_results->NextAs<std::vector<TypeExpression*>>();
     627         276 :   auto parameters = child_results->NextAs<ParameterList>();
     628         138 :   auto return_type = child_results->NextAs<TypeExpression*>();
     629         276 :   auto labels = child_results->NextAs<LabelAndTypesVector>();
     630         138 :   auto body = child_results->NextAs<Statement*>();
     631         138 :   CheckNotDeferredStatement(body);
     632             :   Declaration* result = MakeNode<SpecializationDeclaration>(
     633             :       std::move(name), std::move(generic_parameters), std::move(parameters),
     634         552 :       return_type, std::move(labels), body);
     635         138 :   return ParseResult{result};
     636             : }
     637             : 
     638          13 : base::Optional<ParseResult> MakeStructDeclaration(
     639             :     ParseResultIterator* child_results) {
     640          13 :   auto name = child_results->NextAs<std::string>();
     641          13 :   auto methods = child_results->NextAs<std::vector<Declaration*>>();
     642          26 :   auto fields = child_results->NextAs<std::vector<StructFieldExpression>>();
     643             :   Declaration* result = MakeNode<StructDeclaration>(
     644          39 :       std::move(name), std::move(methods), std::move(fields));
     645          13 :   return ParseResult{result};
     646             : }
     647             : 
     648          15 : base::Optional<ParseResult> MakeCppIncludeDeclaration(
     649             :     ParseResultIterator* child_results) {
     650          15 :   auto include_path = child_results->NextAs<std::string>();
     651             :   Declaration* result =
     652          30 :       MakeNode<CppIncludeDeclaration>(std::move(include_path));
     653          15 :   return ParseResult{result};
     654             : }
     655             : 
     656          18 : base::Optional<ParseResult> MakeExternalBuiltin(
     657             :     ParseResultIterator* child_results) {
     658          18 :   auto transitioning = child_results->NextAs<bool>();
     659          18 :   auto js_linkage = child_results->NextAs<bool>();
     660          18 :   auto name = child_results->NextAs<std::string>();
     661          36 :   auto generic_parameters = child_results->NextAs<GenericParameters>();
     662          18 :   LintGenericParameters(generic_parameters);
     663             : 
     664          36 :   auto args = child_results->NextAs<ParameterList>();
     665          18 :   auto return_type = child_results->NextAs<TypeExpression*>();
     666             :   BuiltinDeclaration* builtin = MakeNode<ExternalBuiltinDeclaration>(
     667          36 :       transitioning, js_linkage, name, args, return_type);
     668             :   Declaration* result;
     669          18 :   if (generic_parameters.empty()) {
     670          18 :     result = MakeNode<StandardDeclaration>(builtin, base::nullopt);
     671             :   } else {
     672           0 :     result = MakeNode<GenericDeclaration>(builtin, generic_parameters);
     673             :   }
     674          18 :   return ParseResult{result};
     675             : }
     676             : 
     677          14 : base::Optional<ParseResult> MakeExternalRuntime(
     678             :     ParseResultIterator* child_results) {
     679          14 :   auto transitioning = child_results->NextAs<bool>();
     680          14 :   auto name = child_results->NextAs<std::string>();
     681          28 :   auto args = child_results->NextAs<ParameterList>();
     682          14 :   auto return_type = child_results->NextAs<TypeExpression*>();
     683             :   ExternalRuntimeDeclaration* runtime = MakeNode<ExternalRuntimeDeclaration>(
     684          28 :       transitioning, name, args, return_type);
     685          14 :   Declaration* result = MakeNode<StandardDeclaration>(runtime, base::nullopt);
     686          14 :   return ParseResult{result};
     687             : }
     688             : 
     689         327 : base::Optional<ParseResult> StringLiteralUnquoteAction(
     690             :     ParseResultIterator* child_results) {
     691             :   return ParseResult{
     692        1308 :       StringLiteralUnquote(child_results->NextAs<std::string>())};
     693             : }
     694             : 
     695        4596 : base::Optional<ParseResult> MakeBasicTypeExpression(
     696             :     ParseResultIterator* child_results) {
     697             :   auto namespace_qualification =
     698        4596 :       child_results->NextAs<std::vector<std::string>>();
     699        4596 :   auto is_constexpr = child_results->NextAs<bool>();
     700        4596 :   auto name = child_results->NextAs<std::string>();
     701             :   TypeExpression* result = MakeNode<BasicTypeExpression>(
     702       13788 :       std::move(namespace_qualification), is_constexpr, std::move(name));
     703        4596 :   return ParseResult{result};
     704             : }
     705             : 
     706          11 : base::Optional<ParseResult> MakeFunctionTypeExpression(
     707             :     ParseResultIterator* child_results) {
     708          11 :   auto parameters = child_results->NextAs<std::vector<TypeExpression*>>();
     709          11 :   auto return_type = child_results->NextAs<TypeExpression*>();
     710             :   TypeExpression* result =
     711          22 :       MakeNode<FunctionTypeExpression>(std::move(parameters), return_type);
     712          11 :   return ParseResult{result};
     713             : }
     714             : 
     715          26 : base::Optional<ParseResult> MakeUnionTypeExpression(
     716             :     ParseResultIterator* child_results) {
     717          26 :   auto a = child_results->NextAs<TypeExpression*>();
     718          26 :   auto b = child_results->NextAs<TypeExpression*>();
     719          26 :   TypeExpression* result = MakeNode<UnionTypeExpression>(a, b);
     720          26 :   return ParseResult{result};
     721             : }
     722             : 
     723         879 : base::Optional<ParseResult> MakeExpressionStatement(
     724             :     ParseResultIterator* child_results) {
     725         879 :   auto expression = child_results->NextAs<Expression*>();
     726         879 :   Statement* result = MakeNode<ExpressionStatement>(expression);
     727         879 :   return ParseResult{result};
     728             : }
     729             : 
     730         416 : base::Optional<ParseResult> MakeIfStatement(
     731             :     ParseResultIterator* child_results) {
     732         416 :   auto is_constexpr = child_results->NextAs<bool>();
     733         416 :   auto condition = child_results->NextAs<Expression*>();
     734         416 :   auto if_true = child_results->NextAs<Statement*>();
     735         416 :   auto if_false = child_results->NextAs<base::Optional<Statement*>>();
     736             : 
     737         979 :   if (if_false && !(BlockStatement::DynamicCast(if_true) &&
     738         223 :                     (BlockStatement::DynamicCast(*if_false) ||
     739         563 :                      IfStatement::DynamicCast(*if_false)))) {
     740           0 :     ReportError("if-else statements require curly braces");
     741             :   }
     742             : 
     743         416 :   if (is_constexpr) {
     744          51 :     CheckNotDeferredStatement(if_true);
     745          51 :     if (if_false) CheckNotDeferredStatement(*if_false);
     746             :   }
     747             : 
     748             :   Statement* result =
     749         416 :       MakeNode<IfStatement>(is_constexpr, condition, if_true, if_false);
     750         416 :   return ParseResult{result};
     751             : }
     752             : 
     753          19 : base::Optional<ParseResult> MakeTypeswitchStatement(
     754             :     ParseResultIterator* child_results) {
     755          19 :   auto expression = child_results->NextAs<Expression*>();
     756          19 :   auto cases = child_results->NextAs<std::vector<TypeswitchCase>>();
     757             :   CurrentSourcePosition::Scope current_source_position(
     758          19 :       child_results->matched_input().pos);
     759             : 
     760             :   // typeswitch (expression) case (x1 : T1) {
     761             :   //   ...b1
     762             :   // } case (x2 : T2) {
     763             :   //   ...b2
     764             :   // } case (x3 : T3) {
     765             :   //   ...b3
     766             :   // }
     767             :   //
     768             :   // desugars to
     769             :   //
     770             :   // {
     771             :   //   const _value = expression;
     772             :   //   try {
     773             :   //     const x1 : T1 = cast<T1>(_value) otherwise _NextCase;
     774             :   //     ...b1
     775             :   //   } label _NextCase {
     776             :   //     try {
     777             :   //       const x2 : T2 = cast<T2>(%assume_impossible<T1>(_value));
     778             :   //       ...b2
     779             :   //     } label _NextCase {
     780             :   //       const x3 : T3 = %assume_impossible<T1|T2>(_value);
     781             :   //       ...b3
     782             :   //     }
     783             :   //   }
     784             :   // }
     785             : 
     786          19 :   BlockStatement* current_block = MakeNode<BlockStatement>();
     787             :   Statement* result = current_block;
     788             :   {
     789          19 :     CurrentSourcePosition::Scope current_source_position(expression->pos);
     790             :     current_block->statements.push_back(MakeNode<VarDeclarationStatement>(
     791          38 :         true, "_value", base::nullopt, expression));
     792             :   }
     793             : 
     794             :   TypeExpression* accumulated_types;
     795         144 :   for (size_t i = 0; i < cases.size(); ++i) {
     796          53 :     CurrentSourcePosition::Scope current_source_position(cases[i].pos);
     797          53 :     Expression* value = MakeNode<IdentifierExpression>("_value");
     798          53 :     if (i >= 1) {
     799             :       value =
     800          34 :           MakeNode<AssumeTypeImpossibleExpression>(accumulated_types, value);
     801             :     }
     802             :     BlockStatement* case_block;
     803         106 :     if (i < cases.size() - 1) {
     804          34 :       value = MakeCall("Cast", std::vector<TypeExpression*>{cases[i].type},
     805             :                        std::vector<Expression*>{value},
     806             :                        std::vector<Statement*>{MakeNode<ExpressionStatement>(
     807         272 :                            MakeNode<IdentifierExpression>("_NextCase"))});
     808          34 :       case_block = MakeNode<BlockStatement>();
     809             :     } else {
     810             :       case_block = current_block;
     811             :     }
     812          53 :     std::string name = "_case_value";
     813         106 :     if (cases[i].name) name = *cases[i].name;
     814             :     case_block->statements.push_back(
     815         212 :         MakeNode<VarDeclarationStatement>(true, name, cases[i].type, value));
     816         106 :     case_block->statements.push_back(cases[i].block);
     817         106 :     if (i < cases.size() - 1) {
     818          34 :       BlockStatement* next_block = MakeNode<BlockStatement>();
     819             :       current_block->statements.push_back(
     820             :           MakeNode<ExpressionStatement>(MakeNode<TryLabelExpression>(
     821             :               false, MakeNode<StatementExpression>(case_block),
     822             :               MakeNode<LabelBlock>("_NextCase", ParameterList::Empty(),
     823          68 :                                    next_block))));
     824             :       current_block = next_block;
     825             :     }
     826             :     accumulated_types =
     827          68 :         i > 0 ? MakeNode<UnionTypeExpression>(accumulated_types, cases[i].type)
     828         106 :               : cases[i].type;
     829             :   }
     830          19 :   return ParseResult{result};
     831             : }
     832             : 
     833          53 : base::Optional<ParseResult> MakeTypeswitchCase(
     834             :     ParseResultIterator* child_results) {
     835          53 :   auto name = child_results->NextAs<base::Optional<std::string>>();
     836          53 :   auto type = child_results->NextAs<TypeExpression*>();
     837          53 :   auto block = child_results->NextAs<Statement*>();
     838             :   return ParseResult{TypeswitchCase{child_results->matched_input().pos,
     839         265 :                                     std::move(name), type, block}};
     840             : }
     841             : 
     842          36 : base::Optional<ParseResult> MakeWhileStatement(
     843             :     ParseResultIterator* child_results) {
     844          36 :   auto condition = child_results->NextAs<Expression*>();
     845          36 :   auto body = child_results->NextAs<Statement*>();
     846          36 :   Statement* result = MakeNode<WhileStatement>(condition, body);
     847          36 :   CheckNotDeferredStatement(result);
     848          36 :   return ParseResult{result};
     849             : }
     850             : 
     851         490 : base::Optional<ParseResult> MakeReturnStatement(
     852             :     ParseResultIterator* child_results) {
     853         490 :   auto value = child_results->NextAs<base::Optional<Expression*>>();
     854         490 :   Statement* result = MakeNode<ReturnStatement>(value);
     855         490 :   return ParseResult{result};
     856             : }
     857             : 
     858           1 : base::Optional<ParseResult> MakeTailCallStatement(
     859             :     ParseResultIterator* child_results) {
     860           1 :   auto value = child_results->NextAs<Expression*>();
     861           1 :   Statement* result = MakeNode<TailCallStatement>(CallExpression::cast(value));
     862           1 :   return ParseResult{result};
     863             : }
     864             : 
     865         884 : base::Optional<ParseResult> MakeVarDeclarationStatement(
     866             :     ParseResultIterator* child_results) {
     867         884 :   auto kind = child_results->NextAs<std::string>();
     868             :   bool const_qualified = kind == "const";
     869             :   if (!const_qualified) DCHECK_EQ("let", kind);
     870         884 :   auto name = child_results->NextAs<std::string>();
     871         884 :   if (!IsLowerCamelCase(name)) {
     872           0 :     NamingConventionError("Variable", name, "lowerCamelCase");
     873             :   }
     874             : 
     875         884 :   auto type = child_results->NextAs<base::Optional<TypeExpression*>>();
     876             :   base::Optional<Expression*> initializer;
     877         884 :   if (child_results->HasNext())
     878         856 :     initializer = child_results->NextAs<Expression*>();
     879         884 :   if (!initializer && !type) {
     880           0 :     ReportError("Declaration is missing a type.");
     881             :   }
     882             :   Statement* result = MakeNode<VarDeclarationStatement>(
     883        1768 :       const_qualified, std::move(name), type, initializer);
     884         884 :   return ParseResult{result};
     885             : }
     886             : 
     887          17 : base::Optional<ParseResult> MakeBreakStatement(
     888             :     ParseResultIterator* child_results) {
     889          17 :   Statement* result = MakeNode<BreakStatement>();
     890          17 :   return ParseResult{result};
     891             : }
     892             : 
     893          10 : base::Optional<ParseResult> MakeContinueStatement(
     894             :     ParseResultIterator* child_results) {
     895          10 :   Statement* result = MakeNode<ContinueStatement>();
     896          10 :   return ParseResult{result};
     897             : }
     898             : 
     899         155 : base::Optional<ParseResult> MakeGotoStatement(
     900             :     ParseResultIterator* child_results) {
     901         155 :   auto label = child_results->NextAs<std::string>();
     902         155 :   auto arguments = child_results->NextAs<std::vector<Expression*>>();
     903             :   Statement* result =
     904         465 :       MakeNode<GotoStatement>(std::move(label), std::move(arguments));
     905         155 :   return ParseResult{result};
     906             : }
     907             : 
     908        1112 : base::Optional<ParseResult> MakeBlockStatement(
     909             :     ParseResultIterator* child_results) {
     910        1112 :   auto deferred = child_results->NextAs<bool>();
     911        1112 :   auto statements = child_results->NextAs<std::vector<Statement*>>();
     912        5037 :   for (Statement* statement : statements) {
     913        2813 :     CheckNotDeferredStatement(statement);
     914             :   }
     915        2224 :   Statement* result = MakeNode<BlockStatement>(deferred, std::move(statements));
     916        1112 :   return ParseResult{result};
     917             : }
     918             : 
     919          73 : base::Optional<ParseResult> MakeTryLabelExpression(
     920             :     ParseResultIterator* child_results) {
     921          73 :   auto try_block = child_results->NextAs<Statement*>();
     922          73 :   CheckNotDeferredStatement(try_block);
     923             :   Statement* result = try_block;
     924          73 :   auto label_blocks = child_results->NextAs<std::vector<LabelBlock*>>();
     925          73 :   auto catch_block = child_results->NextAs<base::Optional<LabelBlock*>>();
     926         234 :   for (auto block : label_blocks) {
     927             :     result = MakeNode<ExpressionStatement>(MakeNode<TryLabelExpression>(
     928          88 :         false, MakeNode<StatementExpression>(result), block));
     929             :   }
     930          73 :   if (catch_block) {
     931             :     result = MakeNode<ExpressionStatement>(MakeNode<TryLabelExpression>(
     932           5 :         true, MakeNode<StatementExpression>(result), *catch_block));
     933             :   }
     934          73 :   return ParseResult{result};
     935             : }
     936             : 
     937           3 : base::Optional<ParseResult> MakeForOfLoopStatement(
     938             :     ParseResultIterator* child_results) {
     939           3 :   auto var_decl = child_results->NextAs<Statement*>();
     940           3 :   CheckNotDeferredStatement(var_decl);
     941           3 :   auto iterable = child_results->NextAs<Expression*>();
     942           3 :   auto range = child_results->NextAs<base::Optional<RangeExpression>>();
     943           3 :   auto body = child_results->NextAs<Statement*>();
     944           3 :   CheckNotDeferredStatement(body);
     945             :   Statement* result =
     946           3 :       MakeNode<ForOfLoopStatement>(var_decl, iterable, range, body);
     947           3 :   return ParseResult{result};
     948             : }
     949             : 
     950          38 : base::Optional<ParseResult> MakeForLoopStatement(
     951             :     ParseResultIterator* child_results) {
     952          38 :   auto var_decl = child_results->NextAs<base::Optional<Statement*>>();
     953          38 :   auto test = child_results->NextAs<base::Optional<Expression*>>();
     954          38 :   auto action = child_results->NextAs<base::Optional<Expression*>>();
     955             :   base::Optional<Statement*> action_stmt;
     956          38 :   if (action) action_stmt = MakeNode<ExpressionStatement>(*action);
     957          38 :   auto body = child_results->NextAs<Statement*>();
     958          38 :   CheckNotDeferredStatement(body);
     959             :   Statement* result =
     960          38 :       MakeNode<ForLoopStatement>(var_decl, test, action_stmt, body);
     961          38 :   return ParseResult{result};
     962             : }
     963             : 
     964          88 : base::Optional<ParseResult> MakeLabelBlock(ParseResultIterator* child_results) {
     965          88 :   auto label = child_results->NextAs<std::string>();
     966          88 :   if (!IsUpperCamelCase(label)) {
     967           0 :     NamingConventionError("Label", label, "UpperCamelCase");
     968             :   }
     969         176 :   auto parameters = child_results->NextAs<ParameterList>();
     970          88 :   auto body = child_results->NextAs<Statement*>();
     971             :   LabelBlock* result =
     972         264 :       MakeNode<LabelBlock>(std::move(label), std::move(parameters), body);
     973          88 :   return ParseResult{result};
     974             : }
     975             : 
     976           5 : base::Optional<ParseResult> MakeCatchBlock(ParseResultIterator* child_results) {
     977           5 :   auto variable = child_results->NextAs<std::string>();
     978           5 :   auto body = child_results->NextAs<Statement*>();
     979           5 :   if (!IsLowerCamelCase(variable)) {
     980           0 :     NamingConventionError("Exception", variable, "lowerCamelCase");
     981             :   }
     982           5 :   ParameterList parameters;
     983           5 :   parameters.names.push_back(variable);
     984             :   parameters.types.push_back(MakeNode<BasicTypeExpression>(
     985          10 :       std::vector<std::string>{}, false, "Object"));
     986           5 :   parameters.has_varargs = false;
     987             :   LabelBlock* result =
     988           5 :       MakeNode<LabelBlock>("_catch", std::move(parameters), body);
     989           5 :   return ParseResult{result};
     990             : }
     991             : 
     992           3 : base::Optional<ParseResult> MakeRangeExpression(
     993             :     ParseResultIterator* child_results) {
     994           3 :   auto begin = child_results->NextAs<base::Optional<Expression*>>();
     995           3 :   auto end = child_results->NextAs<base::Optional<Expression*>>();
     996             :   RangeExpression result = {begin, end};
     997           6 :   return ParseResult{result};
     998             : }
     999             : 
    1000         218 : base::Optional<ParseResult> MakeExpressionWithSource(
    1001             :     ParseResultIterator* child_results) {
    1002         218 :   auto e = child_results->NextAs<Expression*>();
    1003             :   return ParseResult{
    1004         872 :       ExpressionWithSource{e, child_results->matched_input().ToString()}};
    1005             : }
    1006             : 
    1007        6930 : base::Optional<ParseResult> MakeIdentifierExpression(
    1008             :     ParseResultIterator* child_results) {
    1009             :   auto namespace_qualification =
    1010        6930 :       child_results->NextAs<std::vector<std::string>>();
    1011        6930 :   auto name = child_results->NextAs<std::string>();
    1012             :   auto generic_arguments =
    1013        6930 :       child_results->NextAs<std::vector<TypeExpression*>>();
    1014             :   LocationExpression* result = MakeNode<IdentifierExpression>(
    1015             :       std::move(namespace_qualification), std::move(name),
    1016       20790 :       std::move(generic_arguments));
    1017        6930 :   return ParseResult{result};
    1018             : }
    1019             : 
    1020         575 : base::Optional<ParseResult> MakeFieldAccessExpression(
    1021             :     ParseResultIterator* child_results) {
    1022         575 :   auto object = child_results->NextAs<Expression*>();
    1023         575 :   auto field = child_results->NextAs<std::string>();
    1024             :   LocationExpression* result =
    1025        1150 :       MakeNode<FieldAccessExpression>(object, std::move(field));
    1026         575 :   return ParseResult{result};
    1027             : }
    1028             : 
    1029         209 : base::Optional<ParseResult> MakeElementAccessExpression(
    1030             :     ParseResultIterator* child_results) {
    1031         209 :   auto object = child_results->NextAs<Expression*>();
    1032         209 :   auto field = child_results->NextAs<Expression*>();
    1033         209 :   LocationExpression* result = MakeNode<ElementAccessExpression>(object, field);
    1034         209 :   return ParseResult{result};
    1035             : }
    1036             : 
    1037          21 : base::Optional<ParseResult> MakeStructExpression(
    1038             :     ParseResultIterator* child_results) {
    1039             :   auto namespace_qualification =
    1040          21 :       child_results->NextAs<std::vector<std::string>>();
    1041          21 :   auto name = child_results->NextAs<std::string>();
    1042          21 :   auto expressions = child_results->NextAs<std::vector<Expression*>>();
    1043             :   Expression* result =
    1044             :       MakeNode<StructExpression>(std::move(namespace_qualification),
    1045          63 :                                  std::move(name), std::move(expressions));
    1046          21 :   return ParseResult{result};
    1047             : }
    1048             : 
    1049         399 : base::Optional<ParseResult> MakeAssignmentExpression(
    1050             :     ParseResultIterator* child_results) {
    1051         399 :   auto location = child_results->NextAs<LocationExpression*>();
    1052         399 :   auto op = child_results->NextAs<base::Optional<std::string>>();
    1053         399 :   auto value = child_results->NextAs<Expression*>();
    1054             :   Expression* result =
    1055         798 :       MakeNode<AssignmentExpression>(location, std::move(op), value);
    1056         399 :   return ParseResult{result};
    1057             : }
    1058             : 
    1059         844 : base::Optional<ParseResult> MakeNumberLiteralExpression(
    1060             :     ParseResultIterator* child_results) {
    1061         844 :   auto number = child_results->NextAs<std::string>();
    1062        1688 :   Expression* result = MakeNode<NumberLiteralExpression>(std::move(number));
    1063         844 :   return ParseResult{result};
    1064             : }
    1065             : 
    1066          45 : base::Optional<ParseResult> MakeStringLiteralExpression(
    1067             :     ParseResultIterator* child_results) {
    1068          45 :   auto literal = child_results->NextAs<std::string>();
    1069          90 :   Expression* result = MakeNode<StringLiteralExpression>(std::move(literal));
    1070          45 :   return ParseResult{result};
    1071             : }
    1072             : 
    1073          65 : base::Optional<ParseResult> MakeIncrementDecrementExpressionPostfix(
    1074             :     ParseResultIterator* child_results) {
    1075          65 :   auto location = child_results->NextAs<LocationExpression*>();
    1076          65 :   auto op = child_results->NextAs<IncrementDecrementOperator>();
    1077             :   Expression* result =
    1078          65 :       MakeNode<IncrementDecrementExpression>(location, op, true);
    1079          65 :   return ParseResult{result};
    1080             : }
    1081             : 
    1082          52 : base::Optional<ParseResult> MakeIncrementDecrementExpressionPrefix(
    1083             :     ParseResultIterator* child_results) {
    1084          52 :   auto op = child_results->NextAs<IncrementDecrementOperator>();
    1085          52 :   auto location = child_results->NextAs<LocationExpression*>();
    1086             :   Expression* result =
    1087          52 :       MakeNode<IncrementDecrementExpression>(location, op, false);
    1088          52 :   return ParseResult{result};
    1089             : }
    1090             : 
    1091          24 : base::Optional<ParseResult> MakeLogicalOrExpression(
    1092             :     ParseResultIterator* child_results) {
    1093          24 :   auto left = child_results->NextAs<Expression*>();
    1094          24 :   auto right = child_results->NextAs<Expression*>();
    1095          24 :   Expression* result = MakeNode<LogicalOrExpression>(left, right);
    1096          24 :   return ParseResult{result};
    1097             : }
    1098             : 
    1099          46 : base::Optional<ParseResult> MakeLogicalAndExpression(
    1100             :     ParseResultIterator* child_results) {
    1101          46 :   auto left = child_results->NextAs<Expression*>();
    1102          46 :   auto right = child_results->NextAs<Expression*>();
    1103          46 :   Expression* result = MakeNode<LogicalAndExpression>(left, right);
    1104          46 :   return ParseResult{result};
    1105             : }
    1106             : 
    1107          88 : base::Optional<ParseResult> MakeConditionalExpression(
    1108             :     ParseResultIterator* child_results) {
    1109          88 :   auto condition = child_results->NextAs<Expression*>();
    1110          88 :   auto if_true = child_results->NextAs<Expression*>();
    1111          88 :   auto if_false = child_results->NextAs<Expression*>();
    1112             :   Expression* result =
    1113          88 :       MakeNode<ConditionalExpression>(condition, if_true, if_false);
    1114          88 :   return ParseResult{result};
    1115             : }
    1116             : 
    1117         160 : base::Optional<ParseResult> MakeLabelAndTypes(
    1118             :     ParseResultIterator* child_results) {
    1119         160 :   auto name = child_results->NextAs<std::string>();
    1120         160 :   if (!IsUpperCamelCase(name)) {
    1121           0 :     NamingConventionError("Label", name, "UpperCamelCase");
    1122             :   }
    1123         160 :   auto types = child_results->NextAs<std::vector<TypeExpression*>>();
    1124         480 :   return ParseResult{LabelAndTypes{std::move(name), std::move(types)}};
    1125             : }
    1126             : 
    1127        1247 : base::Optional<ParseResult> MakeNameAndType(
    1128             :     ParseResultIterator* child_results) {
    1129        1247 :   auto name = child_results->NextAs<std::string>();
    1130        1247 :   auto type = child_results->NextAs<TypeExpression*>();
    1131        4988 :   return ParseResult{NameAndTypeExpression{std::move(name), type}};
    1132             : }
    1133             : 
    1134          60 : base::Optional<ParseResult> MakeClassField(ParseResultIterator* child_results) {
    1135          60 :   auto weak = child_results->NextAs<bool>();
    1136          60 :   auto name = child_results->NextAs<std::string>();
    1137          60 :   auto index = child_results->NextAs<base::Optional<std::string>>();
    1138          60 :   auto type = child_results->NextAs<TypeExpression*>();
    1139             :   return ParseResult{
    1140         240 :       ClassFieldExpression{{std::move(name), type}, index, weak}};
    1141             : }
    1142             : 
    1143          37 : base::Optional<ParseResult> MakeStructField(
    1144             :     ParseResultIterator* child_results) {
    1145          37 :   auto name = child_results->NextAs<std::string>();
    1146          37 :   auto type = child_results->NextAs<TypeExpression*>();
    1147         148 :   return ParseResult{StructFieldExpression{{std::move(name), type}}};
    1148             : }
    1149             : 
    1150          11 : base::Optional<ParseResult> ExtractAssignmentOperator(
    1151             :     ParseResultIterator* child_results) {
    1152          11 :   auto op = child_results->NextAs<std::string>();
    1153          22 :   base::Optional<std::string> result = std::string(op.begin(), op.end() - 1);
    1154          44 :   return ParseResult(std::move(result));
    1155             : }
    1156             : 
    1157          56 : struct TorqueGrammar : Grammar {
    1158       47401 :   static bool MatchWhitespace(InputPosition* pos) {
    1159             :     while (true) {
    1160      108956 :       if (MatchChar(std::isspace, pos)) continue;
    1161       48605 :       if (MatchString("//", pos)) {
    1162      115936 :         while (MatchChar([](char c) { return c != '\n'; }, pos)) {
    1163             :         }
    1164             :         continue;
    1165             :       }
    1166       47401 :       return true;
    1167             :     }
    1168             :   }
    1169             : 
    1170       47373 :   static bool MatchIdentifier(InputPosition* pos) {
    1171       47373 :     if (!MatchChar(std::isalpha, pos)) return false;
    1172      168389 :     while (MatchChar(std::isalnum, pos) || MatchString("_", pos)) {
    1173             :     }
    1174             :     return true;
    1175             :   }
    1176             : 
    1177       47373 :   static bool MatchIntrinsicName(InputPosition* pos) {
    1178       47373 :     InputPosition current = *pos;
    1179       47373 :     if (!MatchString("%", &current)) return false;
    1180          52 :     if (!MatchChar(std::isalpha, &current)) return false;
    1181         631 :     while (MatchChar(std::isalnum, &current) || MatchString("_", pos)) {
    1182             :     }
    1183          52 :     *pos = current;
    1184          52 :     return true;
    1185             :   }
    1186             : 
    1187       47373 :   static bool MatchStringLiteral(InputPosition* pos) {
    1188       47373 :     InputPosition current = *pos;
    1189       47373 :     if (MatchString("\"", &current)) {
    1190           0 :       while (
    1191           0 :           (MatchString("\\", &current) && MatchAnyChar(&current)) ||
    1192           0 :           MatchChar([](char c) { return c != '"' && c != '\n'; }, &current)) {
    1193             :       }
    1194           0 :       if (MatchString("\"", &current)) {
    1195           0 :         *pos = current;
    1196           0 :         return true;
    1197             :       }
    1198             :     }
    1199       47373 :     current = *pos;
    1200       47373 :     if (MatchString("'", &current)) {
    1201        5902 :       while (
    1202       11803 :           (MatchString("\\", &current) && MatchAnyChar(&current)) ||
    1203       11802 :           MatchChar([](char c) { return c != '\'' && c != '\n'; }, &current)) {
    1204             :       }
    1205         372 :       if (MatchString("'", &current)) {
    1206         372 :         *pos = current;
    1207         372 :         return true;
    1208             :       }
    1209             :     }
    1210             :     return false;
    1211             :   }
    1212             : 
    1213       47373 :   static bool MatchHexLiteral(InputPosition* pos) {
    1214       47373 :     InputPosition current = *pos;
    1215       47373 :     MatchString("-", &current);
    1216       47373 :     if (MatchString("0x", &current) && MatchChar(std::isxdigit, &current)) {
    1217          57 :       while (MatchChar(std::isxdigit, &current)) {
    1218             :       }
    1219          18 :       *pos = current;
    1220          18 :       return true;
    1221             :     }
    1222             :     return false;
    1223             :   }
    1224             : 
    1225       47373 :   static bool MatchDecimalLiteral(InputPosition* pos) {
    1226       47373 :     InputPosition current = *pos;
    1227             :     bool found_digit = false;
    1228       47373 :     MatchString("-", &current);
    1229       47373 :     while (MatchChar(std::isdigit, &current)) found_digit = true;
    1230       47373 :     MatchString(".", &current);
    1231       47373 :     while (MatchChar(std::isdigit, &current)) found_digit = true;
    1232       47373 :     if (!found_digit) return false;
    1233         844 :     *pos = current;
    1234        2532 :     if ((MatchString("e", &current) || MatchString("E", &current)) &&
    1235         844 :         (MatchString("+", &current) || MatchString("-", &current) || true) &&
    1236           0 :         MatchChar(std::isdigit, &current)) {
    1237           0 :       while (MatchChar(std::isdigit, &current)) {
    1238             :       }
    1239           0 :       *pos = current;
    1240           0 :       return true;
    1241             :     }
    1242             :     return true;
    1243             :   }
    1244             : 
    1245       16996 :   TorqueGrammar() : Grammar(&file) { SetWhitespace(MatchWhitespace); }
    1246             : 
    1247             :   // Result: std::string
    1248             :   Symbol identifier = {Rule({Pattern(MatchIdentifier)}, YieldMatchedInput)};
    1249             : 
    1250             :   // Result: std::string
    1251             :   Symbol intrinsicName = {
    1252             :       Rule({Pattern(MatchIntrinsicName)}, YieldMatchedInput)};
    1253             : 
    1254             :   // Result: std::string
    1255             :   Symbol stringLiteral = {
    1256             :       Rule({Pattern(MatchStringLiteral)}, YieldMatchedInput)};
    1257             : 
    1258             :   // Result: std::string
    1259             :   Symbol externalString = {Rule({&stringLiteral}, StringLiteralUnquoteAction)};
    1260             : 
    1261             :   // Result: std::string
    1262             :   Symbol decimalLiteral = {
    1263             :       Rule({Pattern(MatchDecimalLiteral)}, YieldMatchedInput),
    1264             :       Rule({Pattern(MatchHexLiteral)}, YieldMatchedInput)};
    1265             : 
    1266             :   // Result: TypeList
    1267         112 :   Symbol* typeList = List<TypeExpression*>(&type, Token(","));
    1268             : 
    1269             :   // Result: TypeExpression*
    1270             :   Symbol simpleType = {
    1271         112 :       Rule({Token("("), &type, Token(")")}),
    1272         168 :       Rule({List<std::string>(Sequence({&identifier, Token("::")})),
    1273          84 :             CheckIf(Token("constexpr")), &identifier},
    1274             :            MakeBasicTypeExpression),
    1275         224 :       Rule({Token("builtin"), Token("("), typeList, Token(")"), Token("=>"),
    1276             :             &simpleType},
    1277             :            MakeFunctionTypeExpression)};
    1278             : 
    1279             :   // Result: TypeExpression*
    1280          56 :   Symbol type = {Rule({&simpleType}), Rule({&type, Token("|"), &simpleType},
    1281             :                                            MakeUnionTypeExpression)};
    1282             : 
    1283             :   // Result: GenericParameters
    1284             :   Symbol genericParameters = {
    1285          56 :       Rule({Token("<"),
    1286             :             List<std::string>(
    1287         252 :                 Sequence({&identifier, Token(":"), Token("type")}), Token(",")),
    1288          56 :             Token(">")})};
    1289             : 
    1290             :   // Result: TypeList
    1291             :   Symbol genericSpecializationTypeList = {
    1292         112 :       Rule({Token("<"), typeList, Token(">")})};
    1293             : 
    1294             :   // Result: base::Optional<TypeList>
    1295             :   Symbol* optionalGenericParameters = Optional<TypeList>(&genericParameters);
    1296             : 
    1297             :   Symbol* optionalImplicitParameterList{
    1298             :       TryOrDefault<std::vector<NameAndTypeExpression>>(
    1299         112 :           Sequence({Token("("), Token("implicit"),
    1300         112 :                     List<NameAndTypeExpression>(&nameAndType, Token(",")),
    1301         196 :                     Token(")")}))};
    1302             : 
    1303             :   // Result: ParameterList
    1304             :   Symbol typeListMaybeVarArgs = {
    1305          56 :       Rule({optionalImplicitParameterList, Token("("),
    1306         224 :             List<TypeExpression*>(Sequence({&type, Token(",")})), Token("..."),
    1307          56 :             Token(")")},
    1308             :            MakeParameterListFromTypes<true>),
    1309         112 :       Rule({optionalImplicitParameterList, Token("("), typeList, Token(")")},
    1310             :            MakeParameterListFromTypes<false>)};
    1311             : 
    1312             :   // Result: LabelAndTypes
    1313             :   Symbol labelParameter = {Rule(
    1314             :       {&identifier,
    1315         196 :        TryOrDefault<TypeList>(Sequence({Token("("), typeList, Token(")")}))},
    1316             :       MakeLabelAndTypes)};
    1317             : 
    1318             :   // Result: TypeExpression*
    1319          56 :   Symbol optionalReturnType = {Rule({Token(":"), &type}),
    1320             :                                Rule({}, MakeVoidType)};
    1321             : 
    1322             :   // Result: LabelAndTypesVector
    1323             :   Symbol* optionalLabelList{TryOrDefault<LabelAndTypesVector>(
    1324          56 :       Sequence({Token("labels"),
    1325         140 :                 NonemptyList<LabelAndTypes>(&labelParameter, Token(","))}))};
    1326             : 
    1327             :   // Result: std::vector<Statement*>
    1328             :   Symbol* optionalOtherwise{TryOrDefault<std::vector<Statement*>>(
    1329          56 :       Sequence({Token("otherwise"),
    1330         140 :                 NonemptyList<Statement*>(&atomarStatement, Token(","))}))};
    1331             : 
    1332             :   // Result: NameAndTypeExpression
    1333             :   Symbol nameAndType = {
    1334          56 :       Rule({&identifier, Token(":"), &type}, MakeNameAndType)};
    1335             : 
    1336             :   Symbol* optionalArraySpecifier = {
    1337         196 :       Optional<std::string>(Sequence({Token("["), &identifier, Token("]")}))};
    1338             : 
    1339             :   Symbol classField = {
    1340          84 :       Rule({CheckIf(Token("weak")), &identifier, optionalArraySpecifier,
    1341         112 :             Token(":"), &type, Token(";")},
    1342             :            MakeClassField)};
    1343             : 
    1344             :   Symbol structField = {
    1345         112 :       Rule({&identifier, Token(":"), &type, Token(";")}, MakeStructField)};
    1346             : 
    1347             :   // Result: ParameterList
    1348             :   Symbol parameterListNoVararg = {
    1349          56 :       Rule({optionalImplicitParameterList, Token("("),
    1350         140 :             List<NameAndTypeExpression>(&nameAndType, Token(",")), Token(")")},
    1351             :            MakeParameterListFromNameAndTypeList<false>)};
    1352             : 
    1353             :   // Result: ParameterList
    1354             :   Symbol parameterListAllowVararg = {
    1355             :       Rule({&parameterListNoVararg}),
    1356          56 :       Rule({optionalImplicitParameterList, Token("("),
    1357         112 :             NonemptyList<NameAndTypeExpression>(&nameAndType, Token(",")),
    1358         168 :             Token(","), Token("..."), &identifier, Token(")")},
    1359             :            MakeParameterListFromNameAndTypeList<true>)};
    1360             : 
    1361             :   // Result: std::string
    1362         336 :   Symbol* OneOf(const std::vector<std::string>& alternatives) {
    1363         336 :     Symbol* result = NewSymbol();
    1364        1764 :     for (const std::string& s : alternatives) {
    1365        4368 :       result->AddRule(Rule({Token(s)}, YieldMatchedInput));
    1366             :     }
    1367         336 :     return result;
    1368             :   }
    1369             : 
    1370             :   // Result: Expression*
    1371         140 :   Symbol* BinaryOperator(Symbol* nextLevel, Symbol* op) {
    1372         140 :     Symbol* result = NewSymbol();
    1373             :     *result = {Rule({nextLevel}),
    1374         840 :                Rule({result, op, nextLevel}, MakeBinaryOperator)};
    1375         140 :     return result;
    1376             :   }
    1377             : 
    1378             :   // Result: Expression*
    1379             :   Symbol* expression = &assignmentExpression;
    1380             : 
    1381             :   // Result: IncrementDecrementOperator
    1382             :   Symbol incrementDecrementOperator = {
    1383          56 :       Rule({Token("++")},
    1384             :            YieldIntegralConstant<IncrementDecrementOperator,
    1385             :                                  IncrementDecrementOperator::kIncrement>),
    1386          56 :       Rule({Token("--")},
    1387             :            YieldIntegralConstant<IncrementDecrementOperator,
    1388             :                                  IncrementDecrementOperator::kDecrement>)};
    1389             : 
    1390             :   // Result: LocationExpression*
    1391             :   Symbol identifierExpression = {
    1392             :       Rule(
    1393         168 :           {List<std::string>(Sequence({&identifier, Token("::")})), &identifier,
    1394          28 :            TryOrDefault<TypeList>(&genericSpecializationTypeList)},
    1395             :           MakeIdentifierExpression),
    1396             :   };
    1397             : 
    1398             :   // Result: LocationExpression*
    1399             :   Symbol locationExpression = {
    1400             :       Rule({&identifierExpression}),
    1401          56 :       Rule({&primaryExpression, Token("."), &identifier},
    1402             :            MakeFieldAccessExpression),
    1403         112 :       Rule({&primaryExpression, Token("["), expression, Token("]")},
    1404             :            MakeElementAccessExpression)};
    1405             : 
    1406             :   // Result: std::vector<Expression*>
    1407             :   Symbol argumentList = {Rule(
    1408         196 :       {Token("("), List<Expression*>(expression, Token(",")), Token(")")})};
    1409             : 
    1410             :   // Result: Expression*
    1411             :   Symbol callExpression = {Rule(
    1412             :       {&identifierExpression, &argumentList, optionalOtherwise}, MakeCall)};
    1413             : 
    1414             :   Symbol callMethodExpression = {
    1415          56 :       Rule({&primaryExpression, Token("."), &identifier, &argumentList,
    1416             :             optionalOtherwise},
    1417             :            MakeMethodCall)};
    1418             : 
    1419             :   Symbol initializerList = {Rule(
    1420         196 :       {Token("{"), List<Expression*>(expression, Token(",")), Token("}")})};
    1421             : 
    1422             :   Symbol newExpression = {
    1423          56 :       Rule({Token("new"), &type, &initializerList}, MakeNew)};
    1424             : 
    1425             :   // Result: Expression*
    1426             :   Symbol intrinsicCallExpression = {Rule(
    1427          28 :       {&intrinsicName, TryOrDefault<TypeList>(&genericSpecializationTypeList),
    1428             :        &argumentList},
    1429             :       MakeIntrinsicCallExpression)};
    1430             : 
    1431             :   // Result: Expression*
    1432             :   Symbol primaryExpression = {
    1433             :       Rule({&newExpression}),
    1434             :       Rule({&callExpression}),
    1435             :       Rule({&callMethodExpression}),
    1436             :       Rule({&intrinsicCallExpression}),
    1437             :       Rule({&locationExpression},
    1438             :            CastParseResult<LocationExpression*, Expression*>),
    1439             :       Rule({&decimalLiteral}, MakeNumberLiteralExpression),
    1440             :       Rule({&stringLiteral}, MakeStringLiteralExpression),
    1441             :       Rule(
    1442         168 :           {List<std::string>(Sequence({&identifier, Token("::")})), &identifier,
    1443         196 :            Token("{"), List<Expression*>(expression, Token(",")), Token("}")},
    1444             :           MakeStructExpression),
    1445         112 :       Rule({Token("("), expression, Token(")")})};
    1446             : 
    1447             :   // Result: Expression*
    1448             :   Symbol unaryExpression = {
    1449             :       Rule({&primaryExpression}),
    1450         112 :       Rule({OneOf({"+", "-", "!", "~"}), &unaryExpression}, MakeUnaryOperator),
    1451             :       Rule({&incrementDecrementOperator, &locationExpression},
    1452             :            MakeIncrementDecrementExpressionPrefix),
    1453             :       Rule({&locationExpression, &incrementDecrementOperator},
    1454             :            MakeIncrementDecrementExpressionPostfix)};
    1455             : 
    1456             :   // Result: Expression*
    1457             :   Symbol* multiplicativeExpression =
    1458         112 :       BinaryOperator(&unaryExpression, OneOf({"*", "/", "%"}));
    1459             : 
    1460             :   // Result: Expression*
    1461             :   Symbol* additiveExpression =
    1462         112 :       BinaryOperator(multiplicativeExpression, OneOf({"+", "-"}));
    1463             : 
    1464             :   // Result: Expression*
    1465             :   Symbol* shiftExpression =
    1466         112 :       BinaryOperator(additiveExpression, OneOf({"<<", ">>", ">>>"}));
    1467             : 
    1468             :   // Do not allow expressions like a < b > c because this is never
    1469             :   // useful and ambiguous with template parameters.
    1470             :   // Result: Expression*
    1471             :   Symbol relationalExpression = {
    1472             :       Rule({shiftExpression}),
    1473         112 :       Rule({shiftExpression, OneOf({"<", ">", "<=", ">="}), shiftExpression},
    1474             :            MakeBinaryOperator)};
    1475             : 
    1476             :   // Result: Expression*
    1477             :   Symbol* equalityExpression =
    1478         112 :       BinaryOperator(&relationalExpression, OneOf({"==", "!="}));
    1479             : 
    1480             :   // Result: Expression*
    1481             :   Symbol* bitwiseExpression =
    1482         112 :       BinaryOperator(equalityExpression, OneOf({"&", "|"}));
    1483             : 
    1484             :   // Result: Expression*
    1485             :   Symbol logicalAndExpression = {
    1486             :       Rule({bitwiseExpression}),
    1487          56 :       Rule({&logicalAndExpression, Token("&&"), bitwiseExpression},
    1488             :            MakeLogicalAndExpression)};
    1489             : 
    1490             :   // Result: Expression*
    1491             :   Symbol logicalOrExpression = {
    1492             :       Rule({&logicalAndExpression}),
    1493          56 :       Rule({&logicalOrExpression, Token("||"), &logicalAndExpression},
    1494             :            MakeLogicalOrExpression)};
    1495             : 
    1496             :   // Result: Expression*
    1497             :   Symbol conditionalExpression = {
    1498             :       Rule({&logicalOrExpression}),
    1499         112 :       Rule({&logicalOrExpression, Token("?"), expression, Token(":"),
    1500             :             &conditionalExpression},
    1501             :            MakeConditionalExpression)};
    1502             : 
    1503             :   // Result: base::Optional<std::string>
    1504             :   Symbol assignmentOperator = {
    1505          56 :       Rule({Token("=")}, YieldDefaultValue<base::Optional<std::string>>),
    1506             :       Rule({OneOf({"*=", "/=", "%=", "+=", "-=", "<<=", ">>=", ">>>=", "&=",
    1507         112 :                    "^=", "|="})},
    1508             :            ExtractAssignmentOperator)};
    1509             : 
    1510             :   // Result: Expression*
    1511             :   Symbol assignmentExpression = {
    1512             :       Rule({&conditionalExpression}),
    1513             :       Rule({&locationExpression, &assignmentOperator, &assignmentExpression},
    1514             :            MakeAssignmentExpression)};
    1515             : 
    1516             :   // Result: Statement*
    1517         140 :   Symbol block = {Rule({CheckIf(Token("deferred")), Token("{"),
    1518         112 :                         List<Statement*>(&statement), Token("}")},
    1519             :                        MakeBlockStatement)};
    1520             : 
    1521             :   // Result: LabelBlock*
    1522             :   Symbol labelBlock = {
    1523          56 :       Rule({Token("label"), &identifier,
    1524          28 :             TryOrDefault<ParameterList>(&parameterListNoVararg), &block},
    1525             :            MakeLabelBlock)};
    1526             : 
    1527             :   Symbol catchBlock = {
    1528         168 :       Rule({Token("catch"), Token("("), &identifier, Token(")"), &block},
    1529             :            MakeCatchBlock)};
    1530             : 
    1531             :   // Result: ExpressionWithSource
    1532             :   Symbol expressionWithSource = {Rule({expression}, MakeExpressionWithSource)};
    1533             : 
    1534             :   // Result: RangeExpression
    1535             :   Symbol rangeSpecifier = {
    1536         140 :       Rule({Token("["), Optional<Expression*>(expression), Token(":"),
    1537          84 :             Optional<Expression*>(expression), Token("]")},
    1538             :            MakeRangeExpression)};
    1539             : 
    1540             :   Symbol* optionalTypeSpecifier =
    1541         140 :       Optional<TypeExpression*>(Sequence({Token(":"), &type}));
    1542             : 
    1543             :   // Result: Statement*
    1544             :   Symbol varDeclaration = {
    1545         112 :       Rule({OneOf({"let", "const"}), &identifier, optionalTypeSpecifier},
    1546             :            MakeVarDeclarationStatement)};
    1547             : 
    1548             :   // Result: Statement*
    1549             :   Symbol varDeclarationWithInitialization = {
    1550         112 :       Rule({OneOf({"let", "const"}), &identifier, optionalTypeSpecifier,
    1551          56 :             Token("="), expression},
    1552             :            MakeVarDeclarationStatement)};
    1553             : 
    1554             :   // Result: Statement*
    1555             :   Symbol atomarStatement = {
    1556             :       Rule({expression}, MakeExpressionStatement),
    1557          84 :       Rule({Token("return"), Optional<Expression*>(expression)},
    1558             :            MakeReturnStatement),
    1559          56 :       Rule({Token("tail"), &callExpression}, MakeTailCallStatement),
    1560          56 :       Rule({Token("break")}, MakeBreakStatement),
    1561          56 :       Rule({Token("continue")}, MakeContinueStatement),
    1562          56 :       Rule({Token("goto"), &identifier,
    1563          28 :             TryOrDefault<std::vector<Expression*>>(&argumentList)},
    1564             :            MakeGotoStatement),
    1565         112 :       Rule({OneOf({"debug", "unreachable"})}, MakeDebugStatement)};
    1566             : 
    1567             :   // Result: Statement*
    1568             :   Symbol statement = {
    1569             :       Rule({&block}),
    1570          56 :       Rule({&atomarStatement, Token(";")}),
    1571          56 :       Rule({&varDeclaration, Token(";")}),
    1572          56 :       Rule({&varDeclarationWithInitialization, Token(";")}),
    1573         196 :       Rule({Token("if"), CheckIf(Token("constexpr")), Token("("), expression,
    1574          56 :             Token(")"), &statement,
    1575         140 :             Optional<Statement*>(Sequence({Token("else"), &statement}))},
    1576             :            MakeIfStatement),
    1577             :       Rule(
    1578             :           {
    1579         168 :               Token("typeswitch"), Token("("), expression, Token(")"),
    1580         140 :               Token("{"), NonemptyList<TypeswitchCase>(&typeswitchCase),
    1581          56 :               Token("}"),
    1582             :           },
    1583             :           MakeTypeswitchStatement),
    1584         140 :       Rule({Token("try"), &block, List<LabelBlock*>(&labelBlock),
    1585             :             Optional<LabelBlock*>(&catchBlock)},
    1586             :            MakeTryLabelExpression),
    1587         140 :       Rule({OneOf({"assert", "check"}), Token("("), &expressionWithSource,
    1588         112 :             Token(")"), Token(";")},
    1589             :            MakeAssertStatement),
    1590         168 :       Rule({Token("while"), Token("("), expression, Token(")"), &statement},
    1591             :            MakeWhileStatement),
    1592         168 :       Rule({Token("for"), Token("("), &varDeclaration, Token("of"), expression,
    1593          56 :             Optional<RangeExpression>(&rangeSpecifier), Token(")"), &statement},
    1594             :            MakeForOfLoopStatement),
    1595         112 :       Rule({Token("for"), Token("("),
    1596          56 :             Optional<Statement*>(&varDeclarationWithInitialization), Token(";"),
    1597          84 :             Optional<Expression*>(expression), Token(";"),
    1598          84 :             Optional<Expression*>(expression), Token(")"), &statement},
    1599             :            MakeForLoopStatement)};
    1600             : 
    1601             :   // Result: TypeswitchCase
    1602             :   Symbol typeswitchCase = {
    1603         112 :       Rule({Token("case"), Token("("),
    1604         140 :             Optional<std::string>(Sequence({&identifier, Token(":")})), &type,
    1605         112 :             Token(")"), Token(":"), &block},
    1606             :            MakeTypeswitchCase)};
    1607             : 
    1608             :   // Result: base::Optional<Statement*>
    1609             :   Symbol optionalBody = {
    1610             :       Rule({&block}, CastParseResult<Statement*, base::Optional<Statement*>>),
    1611          56 :       Rule({Token(";")}, YieldDefaultValue<base::Optional<Statement*>>)};
    1612             : 
    1613             :   // Result: Declaration*
    1614             :   Symbol method = {Rule(
    1615          84 :       {CheckIf(Token("transitioning")),
    1616         140 :        Optional<std::string>(Sequence({Token("operator"), &externalString})),
    1617             :        &identifier, &parameterListNoVararg, &optionalReturnType,
    1618             :        optionalLabelList, &block},
    1619             :       MakeMethodDeclaration)};
    1620             : 
    1621             :   // Result: Declaration*
    1622             :   Symbol declaration = {
    1623         168 :       Rule({Token("const"), &identifier, Token(":"), &type, Token("="),
    1624          56 :             expression, Token(";")},
    1625             :            MakeConstDeclaration),
    1626         168 :       Rule({Token("const"), &identifier, Token(":"), &type, Token("generates"),
    1627          56 :             &externalString, Token(";")},
    1628             :            MakeExternConstDeclaration),
    1629         168 :       Rule({CheckIf(Token("extern")), CheckIf(Token("transient")),
    1630          56 :             Token("class"), &identifier,
    1631         140 :             Optional<std::string>(Sequence({Token("extends"), &identifier})),
    1632             :             Optional<std::string>(
    1633         140 :                 Sequence({Token("generates"), &externalString})),
    1634         140 :             Token("{"), List<Declaration*>(&method),
    1635         112 :             List<ClassFieldExpression>(&classField), Token("}")},
    1636             :            MakeClassDeclaration),
    1637         112 :       Rule({Token("struct"), &identifier, Token("{"),
    1638          84 :             List<Declaration*>(&method),
    1639         112 :             List<StructFieldExpression>(&structField), Token("}")},
    1640             :            MakeStructDeclaration),
    1641         140 :       Rule({CheckIf(Token("transient")), Token("type"), &identifier,
    1642         140 :             Optional<std::string>(Sequence({Token("extends"), &identifier})),
    1643             :             Optional<std::string>(
    1644         140 :                 Sequence({Token("generates"), &externalString})),
    1645             :             Optional<std::string>(
    1646         140 :                 Sequence({Token("constexpr"), &externalString})),
    1647          56 :             Token(";")},
    1648             :            MakeTypeDeclaration),
    1649         168 :       Rule({Token("type"), &identifier, Token("="), &type, Token(";")},
    1650             :            MakeTypeAliasDeclaration),
    1651          56 :       Rule({Token("intrinsic"), &intrinsicName,
    1652          28 :             TryOrDefault<GenericParameters>(&genericParameters),
    1653          56 :             &parameterListNoVararg, &optionalReturnType, Token(";")},
    1654             :            MakeIntrinsicDeclaration),
    1655         140 :       Rule({Token("extern"), CheckIf(Token("transitioning")),
    1656             :             Optional<std::string>(
    1657         140 :                 Sequence({Token("operator"), &externalString})),
    1658          56 :             Token("macro"),
    1659         140 :             Optional<std::string>(Sequence({&identifier, Token("::")})),
    1660          28 :             &identifier, TryOrDefault<GenericParameters>(&genericParameters),
    1661             :             &typeListMaybeVarArgs, &optionalReturnType, optionalLabelList,
    1662          56 :             Token(";")},
    1663             :            MakeExternalMacro),
    1664         140 :       Rule({Token("extern"), CheckIf(Token("transitioning")),
    1665         140 :             CheckIf(Token("javascript")), Token("builtin"), &identifier,
    1666          28 :             TryOrDefault<GenericParameters>(&genericParameters),
    1667          56 :             &typeListMaybeVarArgs, &optionalReturnType, Token(";")},
    1668             :            MakeExternalBuiltin),
    1669             :       Rule(
    1670         196 :           {Token("extern"), CheckIf(Token("transitioning")), Token("runtime"),
    1671          56 :            &identifier, &typeListMaybeVarArgs, &optionalReturnType, Token(";")},
    1672             :           MakeExternalRuntime),
    1673          84 :       Rule({CheckIf(Token("transitioning")),
    1674             :             Optional<std::string>(
    1675         140 :                 Sequence({Token("operator"), &externalString})),
    1676          56 :             Token("macro"), &identifier,
    1677          28 :             TryOrDefault<GenericParameters>(&genericParameters),
    1678             :             &parameterListNoVararg, &optionalReturnType, optionalLabelList,
    1679             :             &optionalBody},
    1680             :            MakeTorqueMacroDeclaration),
    1681         168 :       Rule({CheckIf(Token("transitioning")), CheckIf(Token("javascript")),
    1682          56 :             Token("builtin"), &identifier,
    1683          28 :             TryOrDefault<GenericParameters>(&genericParameters),
    1684             :             &parameterListAllowVararg, &optionalReturnType, &optionalBody},
    1685             :            MakeTorqueBuiltinDeclaration),
    1686             :       Rule({&identifier, &genericSpecializationTypeList,
    1687             :             &parameterListAllowVararg, &optionalReturnType, optionalLabelList,
    1688             :             &block},
    1689             :            MakeSpecializationDeclaration),
    1690          56 :       Rule({Token("#include"), &externalString}, MakeCppIncludeDeclaration)};
    1691             : 
    1692             :   // Result: Declaration*
    1693             :   Symbol namespaceDeclaration = {
    1694         112 :       Rule({Token("namespace"), &identifier, Token("{"),
    1695         112 :             List<Declaration*>(&declaration), Token("}")},
    1696             :            MakeNamespaceDeclaration)};
    1697             : 
    1698             :   Symbol file = {Rule({&file, &namespaceDeclaration}, AddGlobalDeclaration),
    1699             :                  Rule({&file, &declaration}, AddGlobalDeclaration), Rule({})};
    1700             : };
    1701             : 
    1702             : }  // namespace
    1703             : 
    1704          56 : void ParseTorque(const std::string& input) { TorqueGrammar().Parse(input); }
    1705             : 
    1706             : }  // namespace torque
    1707             : }  // namespace internal
    1708        9114 : }  // namespace v8

Generated by: LCOV version 1.10