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 "src/torque/torque-parser.h"
6 
7 #include <algorithm>
8 #include <cctype>
9 #include <set>
10 #include <stdexcept>
11 #include <unordered_map>
12 
13 #include "src/flags/flags.h"
14 #include "src/torque/ast.h"
15 #include "src/torque/constants.h"
16 #include "src/torque/declarations.h"
17 #include "src/torque/earley-parser.h"
18 #include "src/torque/utils.h"
19 
20 namespace v8 {
21 namespace internal {
22 namespace torque {
23 
24 DEFINE_CONTEXTUAL_VARIABLE(CurrentAst)
25 
26 using TypeList = std::vector<TypeExpression*>;
27 
28 struct ExpressionWithSource {
29   Expression* expression;
30   std::string source;
31 };
32 
33 struct TypeswitchCase {
34   SourcePosition pos;
35   base::Optional<Identifier*> name;
36   TypeExpression* type;
37   Statement* block;
38 };
39 
40 struct EnumEntry {
41   Identifier* name;
42   base::Optional<TypeExpression*> type;
43 };
44 
45 class BuildFlags : public ContextualClass<BuildFlags> {
46  public:
BuildFlags()47   BuildFlags() {
48     build_flags_["V8_SFI_HAS_UNIQUE_ID"] = V8_SFI_HAS_UNIQUE_ID;
49     build_flags_["V8_EXTERNAL_CODE_SPACE"] = V8_EXTERNAL_CODE_SPACE_BOOL;
50     build_flags_["TAGGED_SIZE_8_BYTES"] = TAGGED_SIZE_8_BYTES;
51     build_flags_["V8_ENABLE_SWISS_NAME_DICTIONARY"] =
52         V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL;
53 #ifdef V8_ENABLE_JAVASCRIPT_PROMISE_HOOKS
54     build_flags_["V8_ENABLE_JAVASCRIPT_PROMISE_HOOKS"] = true;
55 #else
56     build_flags_["V8_ENABLE_JAVASCRIPT_PROMISE_HOOKS"] = false;
57 #endif
58     build_flags_["TRUE_FOR_TESTING"] = true;
59     build_flags_["FALSE_FOR_TESTING"] = false;
60 #ifdef V8_SCRIPTORMODULE_LEGACY_LIFETIME
61     build_flags_["V8_SCRIPTORMODULE_LEGACY_LIFETIME"] = true;
62 #else
63     build_flags_["V8_SCRIPTORMODULE_LEGACY_LIFETIME"] = false;
64 #endif
65 #ifdef V8_ENABLE_WEBASSEMBLY
66     build_flags_["V8_ENABLE_WEBASSEMBLY"] = true;
67 #else
68     build_flags_["V8_ENABLE_WEBASSEMBLY"] = false;
69 #endif
70     build_flags_["DEBUG"] = DEBUG_BOOL;
71   }
GetFlag(const std::string& name, const char* production)72   static bool GetFlag(const std::string& name, const char* production) {
73     auto it = Get().build_flags_.find(name);
74     if (it == Get().build_flags_.end()) {
75       ReportError("Unknown flag used in ", production, ": ", name,
76                   ". Please add it to the list in BuildFlags.");
77     }
78     return it->second;
79   }
80 
81  private:
82   std::unordered_map<std::string, bool> build_flags_;
83 };
84 DEFINE_CONTEXTUAL_VARIABLE(BuildFlags)
85 
86 template <>
87 V8_EXPORT_PRIVATE const ParseResultTypeId ParseResultHolder<std::string>::id =
88     ParseResultTypeId::kStdString;
89 template <>
90 V8_EXPORT_PRIVATE const ParseResultTypeId ParseResultHolder<bool>::id =
91     ParseResultTypeId::kBool;
92 template <>
93 V8_EXPORT_PRIVATE const ParseResultTypeId ParseResultHolder<int32_t>::id =
94     ParseResultTypeId::kInt32;
95 template <>
96 V8_EXPORT_PRIVATE const ParseResultTypeId ParseResultHolder<double>::id =
97     ParseResultTypeId::kDouble;
98 template <>
99 V8_EXPORT_PRIVATE const ParseResultTypeId
100     ParseResultHolder<IntegerLiteral>::id = ParseResultTypeId::kIntegerLiteral;
101 template <>
102 V8_EXPORT_PRIVATE const ParseResultTypeId
103     ParseResultHolder<std::vector<std::string>>::id =
104         ParseResultTypeId::kStdVectorOfString;
105 template <>
106 V8_EXPORT_PRIVATE const ParseResultTypeId ParseResultHolder<Declaration*>::id =
107     ParseResultTypeId::kDeclarationPtr;
108 template <>
109 V8_EXPORT_PRIVATE const ParseResultTypeId
110     ParseResultHolder<TypeExpression*>::id =
111         ParseResultTypeId::kTypeExpressionPtr;
112 template <>
113 V8_EXPORT_PRIVATE const ParseResultTypeId
114     ParseResultHolder<base::Optional<TypeExpression*>>::id =
115         ParseResultTypeId::kOptionalTypeExpressionPtr;
116 template <>
117 V8_EXPORT_PRIVATE const ParseResultTypeId ParseResultHolder<TryHandler*>::id =
118     ParseResultTypeId::kTryHandlerPtr;
119 template <>
120 V8_EXPORT_PRIVATE const ParseResultTypeId ParseResultHolder<Expression*>::id =
121     ParseResultTypeId::kExpressionPtr;
122 template <>
123 V8_EXPORT_PRIVATE const ParseResultTypeId ParseResultHolder<Identifier*>::id =
124     ParseResultTypeId::kIdentifierPtr;
125 template <>
126 V8_EXPORT_PRIVATE const ParseResultTypeId
127     ParseResultHolder<base::Optional<Identifier*>>::id =
128         ParseResultTypeId::kOptionalIdentifierPtr;
129 template <>
130 V8_EXPORT_PRIVATE const ParseResultTypeId ParseResultHolder<Statement*>::id =
131     ParseResultTypeId::kStatementPtr;
132 template <>
133 V8_EXPORT_PRIVATE const ParseResultTypeId
134     ParseResultHolder<NameAndTypeExpression>::id =
135         ParseResultTypeId::kNameAndTypeExpression;
136 template <>
137 V8_EXPORT_PRIVATE const ParseResultTypeId ParseResultHolder<EnumEntry>::id =
138     ParseResultTypeId::kEnumEntry;
139 template <>
140 V8_EXPORT_PRIVATE const ParseResultTypeId
141     ParseResultHolder<std::vector<EnumEntry>>::id =
142         ParseResultTypeId::kStdVectorOfEnumEntry;
143 template <>
144 V8_EXPORT_PRIVATE const ParseResultTypeId
145     ParseResultHolder<NameAndExpression>::id =
146         ParseResultTypeId::kNameAndExpression;
147 template <>
148 V8_EXPORT_PRIVATE const ParseResultTypeId ParseResultHolder<Annotation>::id =
149     ParseResultTypeId::kAnnotation;
150 template <>
151 V8_EXPORT_PRIVATE const ParseResultTypeId
152     ParseResultHolder<std::vector<Annotation>>::id =
153         ParseResultTypeId::kVectorOfAnnotation;
154 template <>
155 V8_EXPORT_PRIVATE const ParseResultTypeId
156     ParseResultHolder<AnnotationParameter>::id =
157         ParseResultTypeId::kAnnotationParameter;
158 template <>
159 V8_EXPORT_PRIVATE const ParseResultTypeId
160     ParseResultHolder<base::Optional<AnnotationParameter>>::id =
161         ParseResultTypeId::kOptionalAnnotationParameter;
162 template <>
163 V8_EXPORT_PRIVATE const ParseResultTypeId
164     ParseResultHolder<ClassFieldExpression>::id =
165         ParseResultTypeId::kClassFieldExpression;
166 template <>
167 V8_EXPORT_PRIVATE const ParseResultTypeId
168     ParseResultHolder<StructFieldExpression>::id =
169         ParseResultTypeId::kStructFieldExpression;
170 template <>
171 V8_EXPORT_PRIVATE const ParseResultTypeId
172     ParseResultHolder<BitFieldDeclaration>::id =
173         ParseResultTypeId::kBitFieldDeclaration;
174 template <>
175 V8_EXPORT_PRIVATE const ParseResultTypeId
176     ParseResultHolder<std::vector<NameAndTypeExpression>>::id =
177         ParseResultTypeId::kStdVectorOfNameAndTypeExpression;
178 template <>
179 V8_EXPORT_PRIVATE const ParseResultTypeId
180     ParseResultHolder<ImplicitParameters>::id =
181         ParseResultTypeId::kImplicitParameters;
182 template <>
183 V8_EXPORT_PRIVATE const ParseResultTypeId
184     ParseResultHolder<base::Optional<ImplicitParameters>>::id =
185         ParseResultTypeId::kOptionalImplicitParameters;
186 template <>
187 V8_EXPORT_PRIVATE const ParseResultTypeId
188     ParseResultHolder<std::vector<NameAndExpression>>::id =
189         ParseResultTypeId::kStdVectorOfNameAndExpression;
190 template <>
191 V8_EXPORT_PRIVATE const ParseResultTypeId
192     ParseResultHolder<std::vector<ClassFieldExpression>>::id =
193         ParseResultTypeId::kStdVectorOfClassFieldExpression;
194 template <>
195 V8_EXPORT_PRIVATE const ParseResultTypeId
196     ParseResultHolder<std::vector<StructFieldExpression>>::id =
197         ParseResultTypeId::kStdVectorOfStructFieldExpression;
198 template <>
199 V8_EXPORT_PRIVATE const ParseResultTypeId
200     ParseResultHolder<std::vector<BitFieldDeclaration>>::id =
201         ParseResultTypeId::kStdVectorOfBitFieldDeclaration;
202 template <>
203 V8_EXPORT_PRIVATE const ParseResultTypeId
204     ParseResultHolder<IncrementDecrementOperator>::id =
205         ParseResultTypeId::kIncrementDecrementOperator;
206 template <>
207 V8_EXPORT_PRIVATE const ParseResultTypeId
208     ParseResultHolder<base::Optional<std::string>>::id =
209         ParseResultTypeId::kOptionalStdString;
210 template <>
211 V8_EXPORT_PRIVATE const ParseResultTypeId
212     ParseResultHolder<std::vector<Statement*>>::id =
213         ParseResultTypeId::kStdVectorOfStatementPtr;
214 template <>
215 V8_EXPORT_PRIVATE const ParseResultTypeId
216     ParseResultHolder<std::vector<Declaration*>>::id =
217         ParseResultTypeId::kStdVectorOfDeclarationPtr;
218 template <>
219 V8_EXPORT_PRIVATE const ParseResultTypeId
220     ParseResultHolder<std::vector<std::vector<Declaration*>>>::id =
221         ParseResultTypeId::kStdVectorOfStdVectorOfDeclarationPtr;
222 template <>
223 V8_EXPORT_PRIVATE const ParseResultTypeId
224     ParseResultHolder<std::vector<Expression*>>::id =
225         ParseResultTypeId::kStdVectorOfExpressionPtr;
226 template <>
227 V8_EXPORT_PRIVATE const ParseResultTypeId
228     ParseResultHolder<ExpressionWithSource>::id =
229         ParseResultTypeId::kExpressionWithSource;
230 template <>
231 V8_EXPORT_PRIVATE const ParseResultTypeId ParseResultHolder<ParameterList>::id =
232     ParseResultTypeId::kParameterList;
233 template <>
234 V8_EXPORT_PRIVATE const ParseResultTypeId ParseResultHolder<TypeList>::id =
235     ParseResultTypeId::kTypeList;
236 template <>
237 V8_EXPORT_PRIVATE const ParseResultTypeId
238     ParseResultHolder<base::Optional<TypeList>>::id =
239         ParseResultTypeId::kOptionalTypeList;
240 template <>
241 V8_EXPORT_PRIVATE const ParseResultTypeId ParseResultHolder<LabelAndTypes>::id =
242     ParseResultTypeId::kLabelAndTypes;
243 template <>
244 V8_EXPORT_PRIVATE const ParseResultTypeId
245     ParseResultHolder<std::vector<LabelAndTypes>>::id =
246         ParseResultTypeId::kStdVectorOfLabelAndTypes;
247 template <>
248 V8_EXPORT_PRIVATE const ParseResultTypeId
249     ParseResultHolder<std::vector<TryHandler*>>::id =
250         ParseResultTypeId::kStdVectorOfTryHandlerPtr;
251 template <>
252 V8_EXPORT_PRIVATE const ParseResultTypeId
253     ParseResultHolder<base::Optional<Statement*>>::id =
254         ParseResultTypeId::kOptionalStatementPtr;
255 template <>
256 V8_EXPORT_PRIVATE const ParseResultTypeId
257     ParseResultHolder<base::Optional<Expression*>>::id =
258         ParseResultTypeId::kOptionalExpressionPtr;
259 template <>
260 V8_EXPORT_PRIVATE const ParseResultTypeId
261     ParseResultHolder<TypeswitchCase>::id = ParseResultTypeId::kTypeswitchCase;
262 template <>
263 V8_EXPORT_PRIVATE const ParseResultTypeId
264     ParseResultHolder<std::vector<TypeswitchCase>>::id =
265         ParseResultTypeId::kStdVectorOfTypeswitchCase;
266 template <>
267 V8_EXPORT_PRIVATE const ParseResultTypeId
268     ParseResultHolder<std::vector<Identifier*>>::id =
269         ParseResultTypeId::kStdVectorOfIdentifierPtr;
270 template <>
271 V8_EXPORT_PRIVATE const ParseResultTypeId
272     ParseResultHolder<base::Optional<ClassBody*>>::id =
273         ParseResultTypeId::kOptionalClassBody;
274 template <>
275 V8_EXPORT_PRIVATE const ParseResultTypeId
276     ParseResultHolder<GenericParameter>::id =
277         ParseResultTypeId::kGenericParameter;
278 template <>
279 V8_EXPORT_PRIVATE const ParseResultTypeId
280     ParseResultHolder<GenericParameters>::id =
281         ParseResultTypeId::kGenericParameters;
282 
283 namespace {
284 
285 bool ProcessIfAnnotation(ParseResultIterator* child_results);
286 
AddGlobalDeclarations( ParseResultIterator* child_results)287 base::Optional<ParseResult> AddGlobalDeclarations(
288     ParseResultIterator* child_results) {
289   auto declarations = child_results->NextAs<std::vector<Declaration*>>();
290   for (Declaration* declaration : declarations) {
291     CurrentAst::Get().declarations().push_back(declaration);
292   }
293   return base::nullopt;
294 }
295 
NamingConventionError(const std::string& type, const std::string& name, const std::string& convention, SourcePosition pos = CurrentSourcePosition::Get())296 void NamingConventionError(const std::string& type, const std::string& name,
297                            const std::string& convention,
298                            SourcePosition pos = CurrentSourcePosition::Get()) {
299   Lint(type, " \"", name, "\" does not follow \"", convention,
300        "\" naming convention.")
301       .Position(pos);
302 }
303 
NamingConventionError(const std::string& type, const Identifier* name, const std::string& convention)304 void NamingConventionError(const std::string& type, const Identifier* name,
305                            const std::string& convention) {
306   NamingConventionError(type, name->value, convention, name->pos);
307 }
308 
LintGenericParameters(const GenericParameters& parameters)309 void LintGenericParameters(const GenericParameters& parameters) {
310   for (auto parameter : parameters) {
311     if (!IsUpperCamelCase(parameter.name->value)) {
312       NamingConventionError("Generic parameter", parameter.name,
313                             "UpperCamelCase");
314     }
315   }
316 }
317 
ConcatList(ParseResultIterator* child_results)318 base::Optional<ParseResult> ConcatList(ParseResultIterator* child_results) {
319   auto list_of_lists =
320       child_results->NextAs<std::vector<std::vector<Declaration*>>>();
321   std::vector<Declaration*> result;
322   for (auto& list : list_of_lists) {
323     result.insert(result.end(), list.begin(), list.end());
324   }
325   return ParseResult{result};
326 }
327 
CheckNotDeferredStatement(Statement* statement)328 void CheckNotDeferredStatement(Statement* statement) {
329   CurrentSourcePosition::Scope source_position(statement->pos);
330   if (BlockStatement* block = BlockStatement::DynamicCast(statement)) {
331     if (block->deferred) {
332       Lint(
333           "cannot use deferred with a statement block here, it will have no "
334           "effect");
335     }
336   }
337 }
338 
AddConstexpr(TypeExpression* type)339 TypeExpression* AddConstexpr(TypeExpression* type) {
340   BasicTypeExpression* basic = BasicTypeExpression::DynamicCast(type);
341   if (!basic) Error("Unsupported extends clause.").Throw();
342   return MakeNode<BasicTypeExpression>(
343       basic->namespace_qualification,
344       MakeNode<Identifier>(CONSTEXPR_TYPE_PREFIX + basic->name->value),
345       basic->generic_arguments);
346 }
347 
MakeCall(IdentifierExpression* callee, base::Optional<Expression*> target, std::vector<Expression*> arguments, const std::vector<Statement*>& otherwise)348 Expression* MakeCall(IdentifierExpression* callee,
349                      base::Optional<Expression*> target,
350                      std::vector<Expression*> arguments,
351                      const std::vector<Statement*>& otherwise) {
352   std::vector<Identifier*> labels;
353 
354   // All IdentifierExpressions are treated as label names and can be directly
355   // used as labels identifiers. All other statements in a call's otherwise
356   // must create intermediate Labels for the otherwise's statement code.
357   size_t label_id_count = 0;
358   std::vector<TryHandler*> temp_labels;
359   for (auto* statement : otherwise) {
360     if (auto* e = ExpressionStatement::DynamicCast(statement)) {
361       if (auto* id = IdentifierExpression::DynamicCast(e->expression)) {
362         if (id->generic_arguments.size() != 0) {
363           ReportError("An otherwise label cannot have generic parameters");
364         }
365         labels.push_back(id->name);
366         continue;
367       }
368     }
369     auto label_name = std::string("__label") + std::to_string(label_id_count++);
370     auto label_id = MakeNode<Identifier>(label_name);
371     label_id->pos = SourcePosition::Invalid();
372     labels.push_back(label_id);
373     auto* handler =
374         MakeNode<TryHandler>(TryHandler::HandlerKind::kLabel, label_id,
375                              ParameterList::Empty(), statement);
376     temp_labels.push_back(handler);
377   }
378 
379   // Create nested try-label expression for all of the temporary Labels that
380   // were created.
381   Expression* result = nullptr;
382   if (target) {
383     result = MakeNode<CallMethodExpression>(*target, callee, arguments, labels);
384   } else {
385     result = MakeNode<CallExpression>(callee, arguments, labels);
386   }
387 
388   for (auto* label : temp_labels) {
389     result = MakeNode<TryLabelExpression>(result, label);
390   }
391   return result;
392 }
393 
MakeCall(Identifier* callee, const std::vector<TypeExpression*>& generic_arguments, const std::vector<Expression*>& arguments, const std::vector<Statement*>& otherwise)394 Expression* MakeCall(Identifier* callee,
395                      const std::vector<TypeExpression*>& generic_arguments,
396                      const std::vector<Expression*>& arguments,
397                      const std::vector<Statement*>& otherwise) {
398   return MakeCall(MakeNode<IdentifierExpression>(callee, generic_arguments),
399                   base::nullopt, arguments, otherwise);
400 }
401 
MakeCall(ParseResultIterator* child_results)402 base::Optional<ParseResult> MakeCall(ParseResultIterator* child_results) {
403   auto callee = child_results->NextAs<Expression*>();
404   auto args = child_results->NextAs<std::vector<Expression*>>();
405   auto otherwise = child_results->NextAs<std::vector<Statement*>>();
406   IdentifierExpression* target = IdentifierExpression::cast(callee);
407   return ParseResult{MakeCall(target, base::nullopt, args, otherwise)};
408 }
409 
MakeMethodCall(ParseResultIterator* child_results)410 base::Optional<ParseResult> MakeMethodCall(ParseResultIterator* child_results) {
411   auto this_arg = child_results->NextAs<Expression*>();
412   auto callee = child_results->NextAs<Identifier*>();
413   auto args = child_results->NextAs<std::vector<Expression*>>();
414   auto otherwise = child_results->NextAs<std::vector<Statement*>>();
415   return ParseResult{MakeCall(MakeNode<IdentifierExpression>(callee), this_arg,
416                               args, otherwise)};
417 }
418 
MakeNewExpression( ParseResultIterator* child_results)419 base::Optional<ParseResult> MakeNewExpression(
420     ParseResultIterator* child_results) {
421   bool pretenured = child_results->NextAs<bool>();
422 
423   auto type = child_results->NextAs<TypeExpression*>();
424   auto initializers = child_results->NextAs<std::vector<NameAndExpression>>();
425 
426   Expression* result =
427       MakeNode<NewExpression>(type, std::move(initializers), pretenured);
428   return ParseResult{result};
429 }
430 
MakeBinaryOperator( ParseResultIterator* child_results)431 base::Optional<ParseResult> MakeBinaryOperator(
432     ParseResultIterator* child_results) {
433   auto left = child_results->NextAs<Expression*>();
434   auto op = child_results->NextAs<Identifier*>();
435   auto right = child_results->NextAs<Expression*>();
436   return ParseResult{MakeCall(op, TypeList{},
437                               std::vector<Expression*>{left, right},
438                               std::vector<Statement*>{})};
439 }
440 
MakeIntrinsicCallExpression( ParseResultIterator* child_results)441 base::Optional<ParseResult> MakeIntrinsicCallExpression(
442     ParseResultIterator* child_results) {
443   auto callee = child_results->NextAs<Identifier*>();
444   auto generic_arguments =
445       child_results->NextAs<std::vector<TypeExpression*>>();
446   auto args = child_results->NextAs<std::vector<Expression*>>();
447   Expression* result =
448       MakeNode<IntrinsicCallExpression>(callee, generic_arguments, args);
449   return ParseResult{result};
450 }
451 
MakeUnaryOperator( ParseResultIterator* child_results)452 base::Optional<ParseResult> MakeUnaryOperator(
453     ParseResultIterator* child_results) {
454   auto op = child_results->NextAs<Identifier*>();
455   auto e = child_results->NextAs<Expression*>();
456   return ParseResult{MakeCall(op, TypeList{}, std::vector<Expression*>{e},
457                               std::vector<Statement*>{})};
458 }
459 
MakeSpreadExpression( ParseResultIterator* child_results)460 base::Optional<ParseResult> MakeSpreadExpression(
461     ParseResultIterator* child_results) {
462   auto spreadee = child_results->NextAs<Expression*>();
463   Expression* result = MakeNode<SpreadExpression>(spreadee);
464   return ParseResult{result};
465 }
466 
MakeImplicitParameterList( ParseResultIterator* child_results)467 base::Optional<ParseResult> MakeImplicitParameterList(
468     ParseResultIterator* child_results) {
469   auto kind = child_results->NextAs<Identifier*>();
470   auto parameters = child_results->NextAs<std::vector<NameAndTypeExpression>>();
471   return ParseResult{ImplicitParameters{kind, parameters}};
472 }
473 
AddParameter(ParameterList* parameter_list, const NameAndTypeExpression& param)474 void AddParameter(ParameterList* parameter_list,
475                   const NameAndTypeExpression& param) {
476   if (!IsLowerCamelCase(param.name->value)) {
477     NamingConventionError("Parameter", param.name, "lowerCamelCase");
478   }
479   parameter_list->names.push_back(param.name);
480   parameter_list->types.push_back(param.type);
481 }
482 
483 template <bool has_varargs, bool has_explicit_parameter_names>
MakeParameterList( ParseResultIterator* child_results)484 base::Optional<ParseResult> MakeParameterList(
485     ParseResultIterator* child_results) {
486   auto implicit_params =
487       child_results->NextAs<base::Optional<ImplicitParameters>>();
488   ParameterList result;
489   result.has_varargs = has_varargs;
490   result.implicit_count = 0;
491   result.implicit_kind = ImplicitKind::kNoImplicit;
492   if (implicit_params) {
493     result.implicit_count = implicit_params->parameters.size();
494     if (implicit_params->kind->value == "implicit") {
495       result.implicit_kind = ImplicitKind::kImplicit;
496     } else {
497       DCHECK_EQ(implicit_params->kind->value, "js-implicit");
498       result.implicit_kind = ImplicitKind::kJSImplicit;
499     }
500     result.implicit_kind_pos = implicit_params->kind->pos;
501     for (NameAndTypeExpression& implicit_param : implicit_params->parameters) {
502       AddParameter(&result, implicit_param);
503     }
504   }
505   if (has_explicit_parameter_names) {
506     auto explicit_params =
507         child_results->NextAs<std::vector<NameAndTypeExpression>>();
508     std::string arguments_variable = "";
509     if (has_varargs) {
510       arguments_variable = child_results->NextAs<std::string>();
511     }
512     for (NameAndTypeExpression& param : explicit_params) {
513       AddParameter(&result, param);
514     }
515     result.arguments_variable = arguments_variable;
516   } else {
517     auto explicit_types = child_results->NextAs<TypeList>();
518     for (auto* explicit_type : explicit_types) {
519       result.types.push_back(explicit_type);
520     }
521   }
522   return ParseResult{std::move(result)};
523 }
524 
MakeAssertStatement( ParseResultIterator* child_results)525 base::Optional<ParseResult> MakeAssertStatement(
526     ParseResultIterator* child_results) {
527   auto kind_string = child_results->NextAs<Identifier*>()->value;
528   auto expr_with_source = child_results->NextAs<ExpressionWithSource>();
529   AssertStatement::AssertKind kind;
530   if (kind_string == "dcheck") {
531     kind = AssertStatement::AssertKind::kDcheck;
532   } else if (kind_string == "check") {
533     kind = AssertStatement::AssertKind::kCheck;
534   } else if (kind_string == "static_assert") {
535     kind = AssertStatement::AssertKind::kStaticAssert;
536   } else {
537     UNREACHABLE();
538   }
539   Statement* result = MakeNode<AssertStatement>(
540       kind, expr_with_source.expression, expr_with_source.source);
541   return ParseResult{result};
542 }
543 
MakeDebugStatement( ParseResultIterator* child_results)544 base::Optional<ParseResult> MakeDebugStatement(
545     ParseResultIterator* child_results) {
546   auto kind = child_results->NextAs<Identifier*>()->value;
547   DCHECK(kind == "unreachable" || kind == "debug");
548   Statement* result = MakeNode<DebugStatement>(kind, kind == "unreachable");
549   return ParseResult{result};
550 }
551 
DeprecatedMakeVoidType( ParseResultIterator* child_results)552 base::Optional<ParseResult> DeprecatedMakeVoidType(
553     ParseResultIterator* child_results) {
554   Error("Default void return types are deprecated. Add `: void`.");
555   TypeExpression* result = MakeNode<BasicTypeExpression>(
556       std::vector<std::string>{}, MakeNode<Identifier>("void"),
557       std::vector<TypeExpression*>{});
558   return ParseResult{result};
559 }
560 
MakeExternalMacro( ParseResultIterator* child_results)561 base::Optional<ParseResult> MakeExternalMacro(
562     ParseResultIterator* child_results) {
563   auto transitioning = child_results->NextAs<bool>();
564   auto operator_name = child_results->NextAs<base::Optional<std::string>>();
565   auto external_assembler_name =
566       child_results->NextAs<base::Optional<std::string>>();
567   auto name = child_results->NextAs<Identifier*>();
568   auto generic_parameters = child_results->NextAs<GenericParameters>();
569   LintGenericParameters(generic_parameters);
570 
571   auto args = child_results->NextAs<ParameterList>();
572   auto return_type = child_results->NextAs<TypeExpression*>();
573   auto labels = child_results->NextAs<LabelAndTypesVector>();
574 
575   Declaration* result = MakeNode<ExternalMacroDeclaration>(
576       transitioning,
577       external_assembler_name ? *external_assembler_name : "CodeStubAssembler",
578       name, operator_name, args, return_type, labels);
579   if (!generic_parameters.empty()) {
580     Error("External builtins cannot be generic.");
581   }
582   return ParseResult{result};
583 }
584 
MakeIntrinsicDeclaration( ParseResultIterator* child_results)585 base::Optional<ParseResult> MakeIntrinsicDeclaration(
586     ParseResultIterator* child_results) {
587   auto name = child_results->NextAs<Identifier*>();
588   auto generic_parameters = child_results->NextAs<GenericParameters>();
589   LintGenericParameters(generic_parameters);
590 
591   auto args = child_results->NextAs<ParameterList>();
592   auto return_type = child_results->NextAs<TypeExpression*>();
593   auto body = child_results->NextAs<base::Optional<Statement*>>();
594   LabelAndTypesVector labels;
595   CallableDeclaration* declaration;
596   if (body) {
597     declaration = MakeNode<TorqueMacroDeclaration>(
598         false, name, base::Optional<std::string>{}, args, return_type, labels,
599         false, body);
600   } else {
601     declaration = MakeNode<IntrinsicDeclaration>(name, args, return_type);
602   }
603   Declaration* result = declaration;
604   if (!generic_parameters.empty()) {
605     result =
606         MakeNode<GenericCallableDeclaration>(generic_parameters, declaration);
607   }
608   return ParseResult{result};
609 }
610 
611 namespace {
HasAnnotation(ParseResultIterator* child_results, const char* annotation, const char* declaration)612 bool HasAnnotation(ParseResultIterator* child_results, const char* annotation,
613                    const char* declaration) {
614   auto annotations = child_results->NextAs<std::vector<Annotation>>();
615   if (annotations.size()) {
616     if (annotations.size() > 1 || annotations[0].name->value != annotation) {
617       Error(declaration, " declarations only support a single ", annotation,
618             " annotation");
619     }
620     return true;
621   }
622   return false;
623 }
624 
HasExportAnnotation(ParseResultIterator* child_results, const char* declaration)625 bool HasExportAnnotation(ParseResultIterator* child_results,
626                          const char* declaration) {
627   return HasAnnotation(child_results, ANNOTATION_EXPORT, declaration);
628 }
629 }  // namespace
630 
MakeTorqueMacroDeclaration( ParseResultIterator* child_results)631 base::Optional<ParseResult> MakeTorqueMacroDeclaration(
632     ParseResultIterator* child_results) {
633   bool export_to_csa = HasExportAnnotation(child_results, "macro");
634   auto transitioning = child_results->NextAs<bool>();
635   auto operator_name = child_results->NextAs<base::Optional<std::string>>();
636   auto name = child_results->NextAs<Identifier*>();
637   if (!IsUpperCamelCase(name->value)) {
638     NamingConventionError("Macro", name, "UpperCamelCase");
639   }
640 
641   auto generic_parameters = child_results->NextAs<GenericParameters>();
642   LintGenericParameters(generic_parameters);
643 
644   auto args = child_results->NextAs<ParameterList>();
645   auto return_type = child_results->NextAs<TypeExpression*>();
646   auto labels = child_results->NextAs<LabelAndTypesVector>();
647   auto body = child_results->NextAs<base::Optional<Statement*>>();
648   CallableDeclaration* declaration = MakeNode<TorqueMacroDeclaration>(
649       transitioning, name, operator_name, args, return_type, labels,
650       export_to_csa, body);
651   Declaration* result = declaration;
652   if (generic_parameters.empty()) {
653     if (!body) ReportError("A non-generic declaration needs a body.");
654   } else {
655     if (export_to_csa) ReportError("Cannot export generics to CSA.");
656     result =
657         MakeNode<GenericCallableDeclaration>(generic_parameters, declaration);
658   }
659   return ParseResult{result};
660 }
661 
MakeTorqueBuiltinDeclaration( ParseResultIterator* child_results)662 base::Optional<ParseResult> MakeTorqueBuiltinDeclaration(
663     ParseResultIterator* child_results) {
664   auto transitioning = child_results->NextAs<bool>();
665   auto javascript_linkage = child_results->NextAs<bool>();
666   auto name = child_results->NextAs<Identifier*>();
667   if (!IsUpperCamelCase(name->value)) {
668     NamingConventionError("Builtin", name, "UpperCamelCase");
669   }
670 
671   auto generic_parameters = child_results->NextAs<GenericParameters>();
672   LintGenericParameters(generic_parameters);
673 
674   auto args = child_results->NextAs<ParameterList>();
675   auto return_type = child_results->NextAs<TypeExpression*>();
676   auto body = child_results->NextAs<base::Optional<Statement*>>();
677   CallableDeclaration* declaration = MakeNode<TorqueBuiltinDeclaration>(
678       transitioning, javascript_linkage, name, args, return_type, body);
679   Declaration* result = declaration;
680   if (generic_parameters.empty()) {
681     if (!body) ReportError("A non-generic declaration needs a body.");
682   } else {
683     result =
684         MakeNode<GenericCallableDeclaration>(generic_parameters, declaration);
685   }
686   return ParseResult{result};
687 }
688 
MakeConstDeclaration( ParseResultIterator* child_results)689 base::Optional<ParseResult> MakeConstDeclaration(
690     ParseResultIterator* child_results) {
691   auto name = child_results->NextAs<Identifier*>();
692   if (!IsValidNamespaceConstName(name->value)) {
693     NamingConventionError("Constant", name, "kUpperCamelCase");
694   }
695 
696   auto type = child_results->NextAs<TypeExpression*>();
697   auto expression = child_results->NextAs<Expression*>();
698   Declaration* result = MakeNode<ConstDeclaration>(name, type, expression);
699   return ParseResult{result};
700 }
701 
MakeExternConstDeclaration( ParseResultIterator* child_results)702 base::Optional<ParseResult> MakeExternConstDeclaration(
703     ParseResultIterator* child_results) {
704   auto name = child_results->NextAs<Identifier*>();
705   auto type = child_results->NextAs<TypeExpression*>();
706   auto literal = child_results->NextAs<std::string>();
707   Declaration* result =
708       MakeNode<ExternConstDeclaration>(name, type, std::move(literal));
709   return ParseResult{result};
710 }
711 
MakeTypeAliasDeclaration( ParseResultIterator* child_results)712 base::Optional<ParseResult> MakeTypeAliasDeclaration(
713     ParseResultIterator* child_results) {
714   bool enabled = ProcessIfAnnotation(child_results);
715   auto name = child_results->NextAs<Identifier*>();
716   auto type = child_results->NextAs<TypeExpression*>();
717   std::vector<Declaration*> result = {};
718   if (enabled) result = {MakeNode<TypeAliasDeclaration>(name, type)};
719   return ParseResult{result};
720 }
721 
MakeAbstractTypeDeclaration( ParseResultIterator* child_results)722 base::Optional<ParseResult> MakeAbstractTypeDeclaration(
723     ParseResultIterator* child_results) {
724   bool use_parent_type_checker = HasAnnotation(
725       child_results, ANNOTATION_USE_PARENT_TYPE_CHECKER, "abstract type");
726   auto transient = child_results->NextAs<bool>();
727   auto name = child_results->NextAs<Identifier*>();
728   if (!IsValidTypeName(name->value)) {
729     NamingConventionError("Type", name, "UpperCamelCase");
730   }
731   auto generic_parameters = child_results->NextAs<GenericParameters>();
732   auto extends = child_results->NextAs<base::Optional<TypeExpression*>>();
733   auto generates = child_results->NextAs<base::Optional<std::string>>();
734   AbstractTypeFlags flags(AbstractTypeFlag::kNone);
735   if (transient) flags |= AbstractTypeFlag::kTransient;
736   if (use_parent_type_checker) flags |= AbstractTypeFlag::kUseParentTypeChecker;
737   TypeDeclaration* type_decl = MakeNode<AbstractTypeDeclaration>(
738       name, flags, extends, std::move(generates));
739   Declaration* decl = type_decl;
740   if (!generic_parameters.empty()) {
741     decl = MakeNode<GenericTypeDeclaration>(generic_parameters, type_decl);
742   }
743 
744   auto constexpr_generates =
745       child_results->NextAs<base::Optional<std::string>>();
746   std::vector<Declaration*> result{decl};
747 
748   if (constexpr_generates) {
749     // Create a AbstractTypeDeclaration for the associated constexpr type.
750     Identifier* constexpr_name =
751         MakeNode<Identifier>(CONSTEXPR_TYPE_PREFIX + name->value);
752     constexpr_name->pos = name->pos;
753 
754     base::Optional<TypeExpression*> constexpr_extends;
755     if (extends) {
756       constexpr_extends = AddConstexpr(*extends);
757     }
758     TypeDeclaration* constexpr_decl = MakeNode<AbstractTypeDeclaration>(
759         constexpr_name, flags | AbstractTypeFlag::kConstexpr, constexpr_extends,
760         constexpr_generates);
761     constexpr_decl->pos = name->pos;
762     decl = constexpr_decl;
763     if (!generic_parameters.empty()) {
764       decl =
765           MakeNode<GenericTypeDeclaration>(generic_parameters, constexpr_decl);
766     }
767     result.push_back(decl);
768   }
769 
770   return ParseResult{result};
771 }
772 
MakeMethodDeclaration( ParseResultIterator* child_results)773 base::Optional<ParseResult> MakeMethodDeclaration(
774     ParseResultIterator* child_results) {
775   auto transitioning = child_results->NextAs<bool>();
776   auto operator_name = child_results->NextAs<base::Optional<std::string>>();
777   auto name = child_results->NextAs<Identifier*>();
778   if (!IsUpperCamelCase(name->value)) {
779     NamingConventionError("Method", name, "UpperCamelCase");
780   }
781 
782   auto args = child_results->NextAs<ParameterList>();
783   auto return_type = child_results->NextAs<TypeExpression*>();
784   auto labels = child_results->NextAs<LabelAndTypesVector>();
785   auto body = child_results->NextAs<Statement*>();
786   Declaration* result =
787       MakeNode<TorqueMacroDeclaration>(transitioning, name, operator_name, args,
788                                        return_type, labels, false, body);
789   return ParseResult{result};
790 }
791 
792 class AnnotationSet {
793  public:
AnnotationSet(ParseResultIterator* iter, const std::set<std::string>& allowed_without_param, const std::set<std::string>& allowed_with_param)794   AnnotationSet(ParseResultIterator* iter,
795                 const std::set<std::string>& allowed_without_param,
796                 const std::set<std::string>& allowed_with_param) {
797     auto list = iter->NextAs<std::vector<Annotation>>();
798     for (const Annotation& a : list) {
799       if (a.param.has_value()) {
800         if (allowed_with_param.find(a.name->value) ==
801             allowed_with_param.end()) {
802           const char* error_message =
803               allowed_without_param.find(a.name->value) ==
804                       allowed_without_param.end()
805                   ? " is not allowed here"
806                   : " cannot have parameter here";
807           Lint("Annotation ", a.name->value, error_message)
808               .Position(a.name->pos);
809         }
810         if (!map_.insert({a.name->value, {*a.param, a.name->pos}}).second) {
811           Lint("Duplicate annotation ", a.name->value).Position(a.name->pos);
812         }
813       } else {
814         if (allowed_without_param.find(a.name->value) ==
815             allowed_without_param.end()) {
816           const char* error_message =
817               allowed_with_param.find(a.name->value) == allowed_with_param.end()
818                   ? " is not allowed here"
819                   : " requires a parameter here";
820           Lint("Annotation ", a.name->value, error_message)
821               .Position(a.name->pos);
822         }
823         if (!set_.insert(a.name->value).second) {
824           Lint("Duplicate annotation ", a.name->value).Position(a.name->pos);
825         }
826       }
827     }
828   }
829 
Contains(const std::string& s) const830   bool Contains(const std::string& s) const {
831     return set_.find(s) != set_.end();
832   }
GetStringParam(const std::string& s) const833   base::Optional<std::string> GetStringParam(const std::string& s) const {
834     auto it = map_.find(s);
835     if (it == map_.end()) {
836       return {};
837     }
838     if (it->second.first.is_int) {
839       Error("Annotation ", s, " requires a string parameter but has an int")
840           .Position(it->second.second);
841     }
842     return it->second.first.string_value;
843   }
GetIntParam(const std::string& s) const844   base::Optional<int32_t> GetIntParam(const std::string& s) const {
845     auto it = map_.find(s);
846     if (it == map_.end()) {
847       return {};
848     }
849     if (!it->second.first.is_int) {
850       Error("Annotation ", s, " requires an int parameter but has a string")
851           .Position(it->second.second);
852     }
853     return it->second.first.int_value;
854   }
855 
856  private:
857   std::set<std::string> set_;
858   std::map<std::string, std::pair<AnnotationParameter, SourcePosition>> map_;
859 };
860 
ProcessIfAnnotation(ParseResultIterator* child_results)861 bool ProcessIfAnnotation(ParseResultIterator* child_results) {
862   AnnotationSet annotations(child_results, {},
863                             {ANNOTATION_IF, ANNOTATION_IFNOT});
864   if (base::Optional<std::string> condition =
865           annotations.GetStringParam(ANNOTATION_IF)) {
866     if (!BuildFlags::GetFlag(*condition, ANNOTATION_IF)) return false;
867   }
868   if (base::Optional<std::string> condition =
869           annotations.GetStringParam(ANNOTATION_IFNOT)) {
870     if (BuildFlags::GetFlag(*condition, ANNOTATION_IFNOT)) return false;
871   }
872   return true;
873 }
874 
YieldInt32(ParseResultIterator* child_results)875 base::Optional<ParseResult> YieldInt32(ParseResultIterator* child_results) {
876   std::string value = child_results->matched_input().ToString();
877   size_t num_chars_converted = 0;
878   int result = 0;
879   try {
880     result = std::stoi(value, &num_chars_converted, 0);
881   } catch (const std::invalid_argument&) {
882     Error("Expected an integer");
883     return ParseResult{result};
884   } catch (const std::out_of_range&) {
885     Error("Integer out of 32-bit range");
886     return ParseResult{result};
887   }
888   // Tokenizer shouldn't have included extra trailing characters.
889   DCHECK_EQ(num_chars_converted, value.size());
890   return ParseResult{result};
891 }
892 
YieldDouble(ParseResultIterator* child_results)893 base::Optional<ParseResult> YieldDouble(ParseResultIterator* child_results) {
894   std::string value = child_results->matched_input().ToString();
895   size_t num_chars_converted = 0;
896   double result = 0;
897   try {
898     result = std::stod(value, &num_chars_converted);
899   } catch (const std::out_of_range&) {
900     Error("double literal out-of-range");
901     return ParseResult{result};
902   }
903   // Tokenizer shouldn't have included extra trailing characters.
904   DCHECK_EQ(num_chars_converted, value.size());
905   return ParseResult{result};
906 }
907 
YieldIntegerLiteral( ParseResultIterator* child_results)908 base::Optional<ParseResult> YieldIntegerLiteral(
909     ParseResultIterator* child_results) {
910   std::string value = child_results->matched_input().ToString();
911   // Consume a leading minus.
912   bool negative = false;
913   if (value.size() > 0 && value[0] == '-') {
914     negative = true;
915     value = value.substr(1);
916   }
917   uint64_t absolute_value;
918   try {
919     size_t parsed = 0;
920     absolute_value = std::stoull(value, &parsed, 0);
921     DCHECK_EQ(parsed, value.size());
922   } catch (const std::invalid_argument&) {
923     Error("integer literal could not be parsed").Throw();
924   } catch (const std::out_of_range&) {
925     Error("integer literal value out of range").Throw();
926   }
927   return ParseResult(IntegerLiteral(negative, absolute_value));
928 }
929 
MakeStringAnnotationParameter( ParseResultIterator* child_results)930 base::Optional<ParseResult> MakeStringAnnotationParameter(
931     ParseResultIterator* child_results) {
932   std::string value = child_results->NextAs<std::string>();
933   AnnotationParameter result{value, 0, false};
934   return ParseResult{result};
935 }
936 
MakeIntAnnotationParameter( ParseResultIterator* child_results)937 base::Optional<ParseResult> MakeIntAnnotationParameter(
938     ParseResultIterator* child_results) {
939   int32_t value = child_results->NextAs<int32_t>();
940   AnnotationParameter result{"", value, true};
941   return ParseResult{result};
942 }
943 
GetAnnotationValue(const AnnotationSet& annotations, const char* name, int default_value)944 int GetAnnotationValue(const AnnotationSet& annotations, const char* name,
945                        int default_value) {
946   auto opt_value = annotations.GetIntParam(name);
947   return opt_value.has_value() ? *opt_value : default_value;
948 }
949 
MakeInstanceTypeConstraints( const AnnotationSet& annotations)950 InstanceTypeConstraints MakeInstanceTypeConstraints(
951     const AnnotationSet& annotations) {
952   InstanceTypeConstraints result;
953   result.value =
954       GetAnnotationValue(annotations, ANNOTATION_INSTANCE_TYPE_VALUE, -1);
955   result.num_flags_bits = GetAnnotationValue(
956       annotations, ANNOTATION_RESERVE_BITS_IN_INSTANCE_TYPE, -1);
957   return result;
958 }
959 
MakeClassBody(ParseResultIterator* child_results)960 base::Optional<ParseResult> MakeClassBody(ParseResultIterator* child_results) {
961   auto methods = child_results->NextAs<std::vector<Declaration*>>();
962   auto fields = child_results->NextAs<std::vector<ClassFieldExpression>>();
963   base::Optional<ClassBody*> result =
964       MakeNode<ClassBody>(std::move(methods), std::move(fields));
965   return ParseResult(result);
966 }
967 
MakeClassDeclaration( ParseResultIterator* child_results)968 base::Optional<ParseResult> MakeClassDeclaration(
969     ParseResultIterator* child_results) {
970   AnnotationSet annotations(
971       child_results,
972       {ANNOTATION_ABSTRACT, ANNOTATION_HAS_SAME_INSTANCE_TYPE_AS_PARENT,
973        ANNOTATION_DO_NOT_GENERATE_CPP_CLASS, ANNOTATION_CUSTOM_CPP_CLASS,
974        ANNOTATION_CUSTOM_MAP, ANNOTATION_GENERATE_BODY_DESCRIPTOR,
975        ANNOTATION_EXPORT, ANNOTATION_DO_NOT_GENERATE_CAST,
976        ANNOTATION_GENERATE_UNIQUE_MAP, ANNOTATION_GENERATE_FACTORY_FUNCTION,
977        ANNOTATION_HIGHEST_INSTANCE_TYPE_WITHIN_PARENT,
978        ANNOTATION_LOWEST_INSTANCE_TYPE_WITHIN_PARENT,
979        ANNOTATION_CPP_OBJECT_DEFINITION},
980       {ANNOTATION_RESERVE_BITS_IN_INSTANCE_TYPE,
981        ANNOTATION_INSTANCE_TYPE_VALUE});
982   ClassFlags flags = ClassFlag::kNone;
983   if (annotations.Contains(ANNOTATION_ABSTRACT)) {
984     flags |= ClassFlag::kAbstract;
985   }
986   if (annotations.Contains(ANNOTATION_HAS_SAME_INSTANCE_TYPE_AS_PARENT)) {
987     flags |= ClassFlag::kHasSameInstanceTypeAsParent;
988   }
989   bool do_not_generate_cpp_class =
990       annotations.Contains(ANNOTATION_DO_NOT_GENERATE_CPP_CLASS);
991   if (annotations.Contains(ANNOTATION_CUSTOM_CPP_CLASS)) {
992     Error(
993         "@customCppClass is deprecated. Use 'extern' instead. "
994         "@generateBodyDescriptor, @generateUniqueMap, and "
995         "@generateFactoryFunction accomplish most of what '@export "
996         "@customCppClass' used to.");
997   }
998   if (annotations.Contains(ANNOTATION_CUSTOM_MAP)) {
999     Error(
1000         "@customMap is deprecated. Generating a unique map is opt-in now using "
1001         "@generateUniqueMap.");
1002   }
1003   if (annotations.Contains(ANNOTATION_DO_NOT_GENERATE_CAST)) {
1004     flags |= ClassFlag::kDoNotGenerateCast;
1005   }
1006   if (annotations.Contains(ANNOTATION_GENERATE_BODY_DESCRIPTOR)) {
1007     flags |= ClassFlag::kGenerateBodyDescriptor;
1008   }
1009   if (annotations.Contains(ANNOTATION_GENERATE_UNIQUE_MAP)) {
1010     flags |= ClassFlag::kGenerateUniqueMap;
1011   }
1012   if (annotations.Contains(ANNOTATION_GENERATE_FACTORY_FUNCTION)) {
1013     flags |= ClassFlag::kGenerateFactoryFunction;
1014   }
1015   if (annotations.Contains(ANNOTATION_EXPORT)) {
1016     flags |= ClassFlag::kExport;
1017   }
1018   if (annotations.Contains(ANNOTATION_HIGHEST_INSTANCE_TYPE_WITHIN_PARENT)) {
1019     flags |= ClassFlag::kHighestInstanceTypeWithinParent;
1020   }
1021   if (annotations.Contains(ANNOTATION_LOWEST_INSTANCE_TYPE_WITHIN_PARENT)) {
1022     flags |= ClassFlag::kLowestInstanceTypeWithinParent;
1023   }
1024   if (annotations.Contains(ANNOTATION_CPP_OBJECT_DEFINITION)) {
1025     flags |= ClassFlag::kCppObjectDefinition;
1026   }
1027 
1028   auto is_extern = child_results->NextAs<bool>();
1029   if (is_extern) flags |= ClassFlag::kExtern;
1030   auto transient = child_results->NextAs<bool>();
1031   if (transient) flags |= ClassFlag::kTransient;
1032   std::string kind = child_results->NextAs<Identifier*>()->value;
1033   if (kind == "shape") {
1034     flags |= ClassFlag::kIsShape;
1035     flags |= ClassFlag::kTransient;
1036     flags |= ClassFlag::kHasSameInstanceTypeAsParent;
1037     flags |= ClassFlag::kDoNotGenerateCast;
1038   } else {
1039     DCHECK_EQ(kind, "class");
1040   }
1041   auto name = child_results->NextAs<Identifier*>();
1042   if (!IsValidTypeName(name->value)) {
1043     NamingConventionError("Type", name, "UpperCamelCase");
1044   }
1045   auto extends = child_results->NextAs<TypeExpression*>();
1046   if (!BasicTypeExpression::DynamicCast(extends)) {
1047     ReportError("Expected type name in extends clause.");
1048   }
1049   auto generates = child_results->NextAs<base::Optional<std::string>>();
1050   auto body = child_results->NextAs<base::Optional<ClassBody*>>();
1051   std::vector<Declaration*> methods;
1052   std::vector<ClassFieldExpression> fields_raw;
1053   if (body.has_value()) {
1054     methods = (*body)->methods;
1055     fields_raw = (*body)->fields;
1056   } else {
1057     flags |= ClassFlag::kUndefinedLayout;
1058   }
1059 
1060   if (is_extern && body.has_value()) {
1061     if (!do_not_generate_cpp_class) {
1062       flags |= ClassFlag::kGenerateCppClassDefinitions;
1063     }
1064   } else if (do_not_generate_cpp_class) {
1065     Lint("Annotation @doNotGenerateCppClass has no effect");
1066   }
1067 
1068   // Filter to only include fields that should be present based on decoration.
1069   std::vector<ClassFieldExpression> fields;
1070   std::copy_if(
1071       fields_raw.begin(), fields_raw.end(), std::back_inserter(fields),
1072       [](const ClassFieldExpression& exp) {
1073         for (const ConditionalAnnotation& condition : exp.conditions) {
1074           if (condition.type == ConditionalAnnotationType::kPositive
1075                   ? !BuildFlags::GetFlag(condition.condition, ANNOTATION_IF)
1076                   : BuildFlags::GetFlag(condition.condition,
1077                                         ANNOTATION_IFNOT)) {
1078             return false;
1079           }
1080         }
1081         return true;
1082       });
1083 
1084   std::vector<Declaration*> result;
1085 
1086   result.push_back(MakeNode<ClassDeclaration>(
1087       name, flags, extends, generates, std::move(methods), fields,
1088       MakeInstanceTypeConstraints(annotations)));
1089 
1090   Identifier* constexpr_name =
1091       MakeNode<Identifier>(CONSTEXPR_TYPE_PREFIX + name->value);
1092   constexpr_name->pos = name->pos;
1093   TypeExpression* constexpr_extends = AddConstexpr(extends);
1094   AbstractTypeFlags abstract_type_flags(AbstractTypeFlag::kConstexpr);
1095   if (transient) abstract_type_flags |= AbstractTypeFlag::kTransient;
1096   TypeDeclaration* constexpr_decl = MakeNode<AbstractTypeDeclaration>(
1097       constexpr_name, abstract_type_flags, constexpr_extends,
1098       generates ? UnwrapTNodeTypeName(*generates) : name->value);
1099   constexpr_decl->pos = name->pos;
1100   result.push_back(constexpr_decl);
1101 
1102   if ((flags & ClassFlag::kDoNotGenerateCast) == 0 &&
1103       (flags & ClassFlag::kIsShape) == 0) {
1104     ParameterList parameters;
1105     parameters.names.push_back(MakeNode<Identifier>("obj"));
1106     parameters.types.push_back(MakeNode<BasicTypeExpression>(
1107         std::vector<std::string>{}, MakeNode<Identifier>("HeapObject"),
1108         std::vector<TypeExpression*>{}));
1109     LabelAndTypesVector labels;
1110     labels.push_back(LabelAndTypes{MakeNode<Identifier>("CastError"),
1111                                    std::vector<TypeExpression*>{}});
1112 
1113     TypeExpression* class_type = MakeNode<BasicTypeExpression>(
1114         std::vector<std::string>{}, name, std::vector<TypeExpression*>{});
1115 
1116     std::vector<std::string> namespace_qualification{
1117         TORQUE_INTERNAL_NAMESPACE_STRING};
1118 
1119     IdentifierExpression* internal_downcast_target =
1120         MakeNode<IdentifierExpression>(
1121             namespace_qualification,
1122             MakeNode<Identifier>("DownCastForTorqueClass"),
1123             std::vector<TypeExpression*>{class_type});
1124     IdentifierExpression* internal_downcast_otherwise =
1125         MakeNode<IdentifierExpression>(std::vector<std::string>{},
1126                                        MakeNode<Identifier>("CastError"));
1127 
1128     Expression* argument = MakeNode<IdentifierExpression>(
1129         std::vector<std::string>{}, MakeNode<Identifier>("obj"));
1130 
1131     auto value = MakeCall(internal_downcast_target, base::nullopt,
1132                           std::vector<Expression*>{argument},
1133                           std::vector<Statement*>{MakeNode<ExpressionStatement>(
1134                               internal_downcast_otherwise)});
1135 
1136     auto cast_body = MakeNode<ReturnStatement>(value);
1137 
1138     std::vector<TypeExpression*> generic_parameters;
1139     generic_parameters.push_back(MakeNode<BasicTypeExpression>(
1140         std::vector<std::string>{}, name, std::vector<TypeExpression*>{}));
1141 
1142     Declaration* specialization = MakeNode<SpecializationDeclaration>(
1143         false, MakeNode<Identifier>("Cast"), generic_parameters,
1144         std::move(parameters), class_type, std::move(labels), cast_body);
1145     result.push_back(specialization);
1146   }
1147 
1148   return ParseResult{result};
1149 }
1150 
MakeNamespaceDeclaration( ParseResultIterator* child_results)1151 base::Optional<ParseResult> MakeNamespaceDeclaration(
1152     ParseResultIterator* child_results) {
1153   auto name = child_results->NextAs<std::string>();
1154   if (!IsSnakeCase(name)) {
1155     NamingConventionError("Namespace", name, "snake_case");
1156   }
1157   auto declarations = child_results->NextAs<std::vector<Declaration*>>();
1158   Declaration* result =
1159       MakeNode<NamespaceDeclaration>(std::move(name), std::move(declarations));
1160   return ParseResult{result};
1161 }
1162 
MakeSpecializationDeclaration( ParseResultIterator* child_results)1163 base::Optional<ParseResult> MakeSpecializationDeclaration(
1164     ParseResultIterator* child_results) {
1165   auto transitioning = child_results->NextAs<bool>();
1166   auto name = child_results->NextAs<Identifier*>();
1167   auto generic_parameters =
1168       child_results->NextAs<std::vector<TypeExpression*>>();
1169   auto parameters = child_results->NextAs<ParameterList>();
1170   auto return_type = child_results->NextAs<TypeExpression*>();
1171   auto labels = child_results->NextAs<LabelAndTypesVector>();
1172   auto body = child_results->NextAs<Statement*>();
1173   CheckNotDeferredStatement(body);
1174   Declaration* result = MakeNode<SpecializationDeclaration>(
1175       transitioning, std::move(name), std::move(generic_parameters),
1176       std::move(parameters), return_type, std::move(labels), body);
1177   return ParseResult{result};
1178 }
1179 
MakeStructDeclaration( ParseResultIterator* child_results)1180 base::Optional<ParseResult> MakeStructDeclaration(
1181     ParseResultIterator* child_results) {
1182   bool is_export = HasExportAnnotation(child_results, "Struct");
1183 
1184   StructFlags flags = StructFlag::kNone;
1185   if (is_export) flags |= StructFlag::kExport;
1186 
1187   auto name = child_results->NextAs<Identifier*>();
1188   if (!IsValidTypeName(name->value)) {
1189     NamingConventionError("Struct", name, "UpperCamelCase");
1190   }
1191   auto generic_parameters = child_results->NextAs<GenericParameters>();
1192   LintGenericParameters(generic_parameters);
1193   auto methods = child_results->NextAs<std::vector<Declaration*>>();
1194   auto fields = child_results->NextAs<std::vector<StructFieldExpression>>();
1195   TypeDeclaration* struct_decl = MakeNode<StructDeclaration>(
1196       flags, name, std::move(methods), std::move(fields));
1197   Declaration* result = struct_decl;
1198   if (!generic_parameters.empty()) {
1199     result = MakeNode<GenericTypeDeclaration>(generic_parameters, struct_decl);
1200   }
1201   return ParseResult{result};
1202 }
1203 
MakeBitFieldStructDeclaration( ParseResultIterator* child_results)1204 base::Optional<ParseResult> MakeBitFieldStructDeclaration(
1205     ParseResultIterator* child_results) {
1206   auto name = child_results->NextAs<Identifier*>();
1207   if (!IsValidTypeName(name->value)) {
1208     NamingConventionError("Bitfield struct", name, "UpperCamelCase");
1209   }
1210   auto extends = child_results->NextAs<TypeExpression*>();
1211   auto fields = child_results->NextAs<std::vector<BitFieldDeclaration>>();
1212   Declaration* decl =
1213       MakeNode<BitFieldStructDeclaration>(name, extends, std::move(fields));
1214   return ParseResult{decl};
1215 }
1216 
MakeCppIncludeDeclaration( ParseResultIterator* child_results)1217 base::Optional<ParseResult> MakeCppIncludeDeclaration(
1218     ParseResultIterator* child_results) {
1219   auto include_path = child_results->NextAs<std::string>();
1220   Declaration* result =
1221       MakeNode<CppIncludeDeclaration>(std::move(include_path));
1222   return ParseResult{result};
1223 }
1224 
ProcessTorqueImportDeclaration( ParseResultIterator* child_results)1225 base::Optional<ParseResult> ProcessTorqueImportDeclaration(
1226     ParseResultIterator* child_results) {
1227   auto import_path = child_results->NextAs<std::string>();
1228   if (!SourceFileMap::FileRelativeToV8RootExists(import_path)) {
1229     Error("File '", import_path, "' not found.");
1230   }
1231 
1232   auto import_id = SourceFileMap::GetSourceId(import_path);
1233   if (!import_id.IsValid()) {
1234     // TODO(szuend): Instead of reporting and error. Queue the file up
1235     //               for compilation.
1236     Error("File '", import_path, "'is not part of the source set.").Throw();
1237   }
1238 
1239   CurrentAst::Get().DeclareImportForCurrentFile(import_id);
1240 
1241   return base::nullopt;
1242 }
1243 
MakeExternalBuiltin( ParseResultIterator* child_results)1244 base::Optional<ParseResult> MakeExternalBuiltin(
1245     ParseResultIterator* child_results) {
1246   auto transitioning = child_results->NextAs<bool>();
1247   auto js_linkage = child_results->NextAs<bool>();
1248   auto name = child_results->NextAs<Identifier*>();
1249   auto generic_parameters = child_results->NextAs<GenericParameters>();
1250   LintGenericParameters(generic_parameters);
1251 
1252   auto args = child_results->NextAs<ParameterList>();
1253   auto return_type = child_results->NextAs<TypeExpression*>();
1254   Declaration* result = MakeNode<ExternalBuiltinDeclaration>(
1255       transitioning, js_linkage, name, args, return_type);
1256   if (!generic_parameters.empty()) {
1257     Error("External builtins cannot be generic.");
1258   }
1259   return ParseResult{result};
1260 }
1261 
MakeExternalRuntime( ParseResultIterator* child_results)1262 base::Optional<ParseResult> MakeExternalRuntime(
1263     ParseResultIterator* child_results) {
1264   auto transitioning = child_results->NextAs<bool>();
1265   auto name = child_results->NextAs<Identifier*>();
1266   auto args = child_results->NextAs<ParameterList>();
1267   auto return_type = child_results->NextAs<TypeExpression*>();
1268   Declaration* result = MakeNode<ExternalRuntimeDeclaration>(
1269       transitioning, name, args, return_type);
1270   return ParseResult{result};
1271 }
1272 
StringLiteralUnquoteAction( ParseResultIterator* child_results)1273 base::Optional<ParseResult> StringLiteralUnquoteAction(
1274     ParseResultIterator* child_results) {
1275   return ParseResult{
1276       StringLiteralUnquote(child_results->NextAs<std::string>())};
1277 }
1278 
MakeBasicTypeExpression( ParseResultIterator* child_results)1279 base::Optional<ParseResult> MakeBasicTypeExpression(
1280     ParseResultIterator* child_results) {
1281   auto namespace_qualification =
1282       child_results->NextAs<std::vector<std::string>>();
1283   auto is_constexpr = child_results->NextAs<bool>();
1284   auto name = child_results->NextAs<std::string>();
1285   auto generic_arguments =
1286       child_results->NextAs<std::vector<TypeExpression*>>();
1287   TypeExpression* result = MakeNode<BasicTypeExpression>(
1288       std::move(namespace_qualification),
1289       MakeNode<Identifier>(is_constexpr ? GetConstexprName(name)
1290                                         : std::move(name)),
1291       std::move(generic_arguments));
1292   return ParseResult{result};
1293 }
1294 
MakeFunctionTypeExpression( ParseResultIterator* child_results)1295 base::Optional<ParseResult> MakeFunctionTypeExpression(
1296     ParseResultIterator* child_results) {
1297   auto parameters = child_results->NextAs<std::vector<TypeExpression*>>();
1298   auto return_type = child_results->NextAs<TypeExpression*>();
1299   TypeExpression* result =
1300       MakeNode<FunctionTypeExpression>(std::move(parameters), return_type);
1301   return ParseResult{result};
1302 }
1303 
MakeReferenceTypeExpression( ParseResultIterator* child_results)1304 base::Optional<ParseResult> MakeReferenceTypeExpression(
1305     ParseResultIterator* child_results) {
1306   auto is_const = child_results->NextAs<bool>();
1307   auto referenced_type = child_results->NextAs<TypeExpression*>();
1308   std::vector<std::string> namespace_qualification{
1309       TORQUE_INTERNAL_NAMESPACE_STRING};
1310   std::vector<TypeExpression*> generic_arguments{referenced_type};
1311   TypeExpression* result = MakeNode<BasicTypeExpression>(
1312       namespace_qualification,
1313       MakeNode<Identifier>(is_const ? CONST_REFERENCE_TYPE_STRING
1314                                     : MUTABLE_REFERENCE_TYPE_STRING),
1315       generic_arguments);
1316   return ParseResult{result};
1317 }
1318 
MakeUnionTypeExpression( ParseResultIterator* child_results)1319 base::Optional<ParseResult> MakeUnionTypeExpression(
1320     ParseResultIterator* child_results) {
1321   auto a = child_results->NextAs<TypeExpression*>();
1322   auto b = child_results->NextAs<TypeExpression*>();
1323   TypeExpression* result = MakeNode<UnionTypeExpression>(a, b);
1324   return ParseResult{result};
1325 }
1326 
MakeGenericParameter( ParseResultIterator* child_results)1327 base::Optional<ParseResult> MakeGenericParameter(
1328     ParseResultIterator* child_results) {
1329   auto name = child_results->NextAs<Identifier*>();
1330   auto constraint = child_results->NextAs<base::Optional<TypeExpression*>>();
1331   return ParseResult{GenericParameter{name, constraint}};
1332 }
1333 
MakeExpressionStatement( ParseResultIterator* child_results)1334 base::Optional<ParseResult> MakeExpressionStatement(
1335     ParseResultIterator* child_results) {
1336   auto expression = child_results->NextAs<Expression*>();
1337   Statement* result = MakeNode<ExpressionStatement>(expression);
1338   return ParseResult{result};
1339 }
1340 
MakeIfStatement( ParseResultIterator* child_results)1341 base::Optional<ParseResult> MakeIfStatement(
1342     ParseResultIterator* child_results) {
1343   auto is_constexpr = child_results->NextAs<bool>();
1344   auto condition = child_results->NextAs<Expression*>();
1345   auto if_true = child_results->NextAs<Statement*>();
1346   auto if_false = child_results->NextAs<base::Optional<Statement*>>();
1347 
1348   if (if_false && !(BlockStatement::DynamicCast(if_true) &&
1349                     (BlockStatement::DynamicCast(*if_false) ||
1350                      IfStatement::DynamicCast(*if_false)))) {
1351     ReportError("if-else statements require curly braces");
1352   }
1353 
1354   if (is_constexpr) {
1355     CheckNotDeferredStatement(if_true);
1356     if (if_false) CheckNotDeferredStatement(*if_false);
1357   }
1358 
1359   Statement* result =
1360       MakeNode<IfStatement>(is_constexpr, condition, if_true, if_false);
1361   return ParseResult{result};
1362 }
1363 
MakeEnumDeclaration( ParseResultIterator* child_results)1364 base::Optional<ParseResult> MakeEnumDeclaration(
1365     ParseResultIterator* child_results) {
1366   const bool is_extern = child_results->NextAs<bool>();
1367   auto name_identifier = child_results->NextAs<Identifier*>();
1368   auto name = name_identifier->value;
1369   auto base_type_expression =
1370       child_results->NextAs<base::Optional<TypeExpression*>>();
1371   auto constexpr_generates_opt =
1372       child_results->NextAs<base::Optional<std::string>>();
1373   auto entries = child_results->NextAs<std::vector<EnumEntry>>();
1374   const bool is_open = child_results->NextAs<bool>();
1375   CurrentSourcePosition::Scope current_source_position(
1376       child_results->matched_input().pos);
1377 
1378   if (!is_extern) {
1379     ReportError("non-extern enums are not supported yet");
1380   }
1381 
1382   if (!IsValidTypeName(name)) {
1383     NamingConventionError("Type", name, "UpperCamelCase");
1384   }
1385 
1386   if (constexpr_generates_opt && *constexpr_generates_opt == name) {
1387     Lint("Unnecessary 'constexpr' clause for enum ", name);
1388   }
1389   auto constexpr_generates =
1390       constexpr_generates_opt ? *constexpr_generates_opt : name;
1391   const bool generate_nonconstexpr = base_type_expression.has_value();
1392 
1393   std::vector<Declaration*> result;
1394   // Build non-constexpr types.
1395   if (generate_nonconstexpr) {
1396     DCHECK(base_type_expression.has_value());
1397 
1398     if (is_open) {
1399       // For open enumerations, we define an abstract type and inherit all
1400       // entries' types from that:
1401       //   type Enum extends Base;
1402       //   namespace Enum {
1403       //     type kEntry0 extends Enum;
1404       //     ...
1405       //     type kEntryN extends Enum;
1406       //   }
1407       auto type_decl = MakeNode<AbstractTypeDeclaration>(
1408           name_identifier, AbstractTypeFlag::kNone, base_type_expression,
1409           base::nullopt);
1410 
1411       TypeExpression* name_type_expression =
1412           MakeNode<BasicTypeExpression>(name_identifier);
1413       name_type_expression->pos = name_identifier->pos;
1414 
1415       std::vector<Declaration*> entry_decls;
1416       entry_decls.reserve(entries.size());
1417       for (const auto& entry : entries) {
1418         entry_decls.push_back(MakeNode<AbstractTypeDeclaration>(
1419             entry.name, AbstractTypeFlag::kNone,
1420             entry.type.value_or(name_type_expression), base::nullopt));
1421       }
1422 
1423       result.push_back(type_decl);
1424       result.push_back(
1425           MakeNode<NamespaceDeclaration>(name, std::move(entry_decls)));
1426     } else {
1427       // For closed enumerations, we define abstract types for all entries and
1428       // define the enumeration as a union of those:
1429       //   namespace Enum {
1430       //     type kEntry0 extends Base;
1431       //     ...
1432       //     type kEntryN extends Base;
1433       //   }
1434       //   type Enum = Enum::kEntry0 | ... | Enum::kEntryN;
1435       TypeExpression* union_type = nullptr;
1436       std::vector<Declaration*> entry_decls;
1437       for (const auto& entry : entries) {
1438         entry_decls.push_back(MakeNode<AbstractTypeDeclaration>(
1439             entry.name, AbstractTypeFlag::kNone,
1440             entry.type.value_or(*base_type_expression), base::nullopt));
1441 
1442         auto entry_type = MakeNode<BasicTypeExpression>(
1443             std::vector<std::string>{name}, entry.name,
1444             std::vector<TypeExpression*>{});
1445         if (union_type) {
1446           union_type = MakeNode<UnionTypeExpression>(union_type, entry_type);
1447         } else {
1448           union_type = entry_type;
1449         }
1450       }
1451 
1452       result.push_back(
1453           MakeNode<NamespaceDeclaration>(name, std::move(entry_decls)));
1454       result.push_back(
1455           MakeNode<TypeAliasDeclaration>(name_identifier, union_type));
1456     }
1457   }
1458 
1459   // Build constexpr types.
1460   {
1461     // The constexpr entries inherit from an abstract enumeration type:
1462     //   type constexpr Enum extends constexpr Base;
1463     //   namespace Enum {
1464     //     type constexpr kEntry0 extends constexpr Enum;
1465     //     ...
1466     //     type constexpr kEntry1 extends constexpr Enum;
1467     //   }
1468     Identifier* constexpr_type_identifier =
1469         MakeNode<Identifier>(std::string(CONSTEXPR_TYPE_PREFIX) + name);
1470     TypeExpression* constexpr_type_expression = MakeNode<BasicTypeExpression>(
1471         MakeNode<Identifier>(std::string(CONSTEXPR_TYPE_PREFIX) + name));
1472     base::Optional<TypeExpression*> base_constexpr_type_expression =
1473         base::nullopt;
1474     if (base_type_expression) {
1475       base_constexpr_type_expression = AddConstexpr(*base_type_expression);
1476     }
1477     result.push_back(MakeNode<AbstractTypeDeclaration>(
1478         constexpr_type_identifier, AbstractTypeFlag::kConstexpr,
1479         base_constexpr_type_expression, constexpr_generates));
1480 
1481     TypeExpression* type_expr = nullptr;
1482     Identifier* fromconstexpr_identifier = nullptr;
1483     Identifier* fromconstexpr_parameter_identifier = nullptr;
1484     Statement* fromconstexpr_body = nullptr;
1485     if (generate_nonconstexpr) {
1486       DCHECK(base_type_expression.has_value());
1487       type_expr = MakeNode<BasicTypeExpression>(std::vector<std::string>{},
1488                                                 MakeNode<Identifier>(name),
1489                                                 std::vector<TypeExpression*>{});
1490 
1491       // return %RawDownCast<Enum>(%FromConstexpr<Base>(o)))
1492       fromconstexpr_identifier = MakeNode<Identifier>("FromConstexpr");
1493       fromconstexpr_parameter_identifier = MakeNode<Identifier>("o");
1494       fromconstexpr_body =
1495           MakeNode<ReturnStatement>(MakeNode<IntrinsicCallExpression>(
1496               MakeNode<Identifier>("%RawDownCast"),
1497               std::vector<TypeExpression*>{type_expr},
1498               std::vector<Expression*>{MakeNode<IntrinsicCallExpression>(
1499                   MakeNode<Identifier>("%FromConstexpr"),
1500                   std::vector<TypeExpression*>{*base_type_expression},
1501                   std::vector<Expression*>{MakeNode<IdentifierExpression>(
1502                       std::vector<std::string>{},
1503                       fromconstexpr_parameter_identifier)})}));
1504     }
1505 
1506     EnumDescription enum_description{CurrentSourcePosition::Get(), name,
1507                                      constexpr_generates, is_open};
1508     std::vector<Declaration*> entry_decls;
1509     for (const auto& entry : entries) {
1510       const std::string entry_name = entry.name->value;
1511       const std::string entry_constexpr_type =
1512           CONSTEXPR_TYPE_PREFIX + entry_name;
1513       enum_description.entries.push_back(constexpr_generates +
1514                                          "::" + entry_name);
1515 
1516       entry_decls.push_back(MakeNode<AbstractTypeDeclaration>(
1517           MakeNode<Identifier>(entry_constexpr_type),
1518           AbstractTypeFlag::kConstexpr, constexpr_type_expression,
1519           constexpr_generates));
1520 
1521       bool generate_typed_constant = entry.type.has_value();
1522       if (generate_typed_constant) {
1523         // namespace Enum {
1524         //   const constexpr_constant_kEntry0: constexpr kEntry0 constexpr
1525         //   'Enum::kEntry0'; const kEntry0 = %RawDownCast<T,
1526         //   Base>(FromConstexpr<Enum>(constexpr_constant_kEntry0));
1527         // }
1528         if (!generate_nonconstexpr) {
1529           Error(
1530               "Enum constants with custom types require an enum with an "
1531               "extends clause.")
1532               .Position((*entry.type)->pos);
1533         }
1534         Identifier* constexpr_constant_name =
1535             MakeNode<Identifier>("constexpr constant " + entry_name);
1536         entry_decls.push_back(MakeNode<ExternConstDeclaration>(
1537             constexpr_constant_name,
1538             MakeNode<BasicTypeExpression>(
1539                 std::vector<std::string>{},
1540                 MakeNode<Identifier>(entry_constexpr_type),
1541                 std::vector<TypeExpression*>{}),
1542             constexpr_generates + "::" + entry_name));
1543         entry_decls.push_back(MakeNode<ConstDeclaration>(
1544             entry.name, *entry.type,
1545             MakeNode<IntrinsicCallExpression>(
1546                 MakeNode<Identifier>("%RawDownCast"),
1547                 std::vector<TypeExpression*>{*entry.type,
1548                                              *base_type_expression},
1549                 std::vector<Expression*>{MakeCall(
1550                     MakeNode<Identifier>("FromConstexpr"), {type_expr},
1551                     {MakeNode<IdentifierExpression>(std::vector<std::string>{},
1552                                                     constexpr_constant_name)},
1553                     {})})));
1554       } else {
1555         // namespace Enum {
1556         //   const kEntry0: constexpr kEntry0 constexpr 'Enum::kEntry0';
1557         // }
1558         entry_decls.push_back(MakeNode<ExternConstDeclaration>(
1559             entry.name,
1560             MakeNode<BasicTypeExpression>(
1561                 std::vector<std::string>{},
1562                 MakeNode<Identifier>(entry_constexpr_type),
1563                 std::vector<TypeExpression*>{}),
1564             constexpr_generates + "::" + entry_name));
1565       }
1566 
1567       // FromConstexpr<Enum, Enum::constexpr kEntry0>(
1568       //   : Enum::constexpr kEntry0): Enum
1569       if (generate_nonconstexpr) {
1570         TypeExpression* entry_constexpr_type_expr =
1571             MakeNode<BasicTypeExpression>(
1572                 std::vector<std::string>{name},
1573                 MakeNode<Identifier>(entry_constexpr_type),
1574                 std::vector<TypeExpression*>{});
1575 
1576         ParameterList parameters;
1577         parameters.names.push_back(fromconstexpr_parameter_identifier);
1578         parameters.types.push_back(entry_constexpr_type_expr);
1579         result.push_back(MakeNode<SpecializationDeclaration>(
1580             false, fromconstexpr_identifier,
1581             std::vector<TypeExpression*>{type_expr, entry_constexpr_type_expr},
1582             std::move(parameters), type_expr, LabelAndTypesVector{},
1583             fromconstexpr_body));
1584       }
1585     }
1586 
1587     result.push_back(
1588         MakeNode<NamespaceDeclaration>(name, std::move(entry_decls)));
1589     CurrentAst::Get().AddEnumDescription(std::move(enum_description));
1590   }
1591 
1592   return ParseResult{std::move(result)};
1593 }
1594 
MakeTypeswitchStatement( ParseResultIterator* child_results)1595 base::Optional<ParseResult> MakeTypeswitchStatement(
1596     ParseResultIterator* child_results) {
1597   auto expression = child_results->NextAs<Expression*>();
1598   auto cases = child_results->NextAs<std::vector<TypeswitchCase>>();
1599   CurrentSourcePosition::Scope matched_input_current_source_position(
1600       child_results->matched_input().pos);
1601 
1602   // typeswitch (expression) case (x1 : T1) {
1603   //   ...b1
1604   // } case (x2 : T2) {
1605   //   ...b2
1606   // } case (x3 : T3) {
1607   //   ...b3
1608   // }
1609   //
1610   // desugars to
1611   //
1612   // {
1613   //   const _value = expression;
1614   //   try {
1615   //     const x1 : T1 = cast<T1>(_value) otherwise _NextCase;
1616   //     ...b1
1617   //   } label _NextCase {
1618   //     try {
1619   //       const x2 : T2 = cast<T2>(%assume_impossible<T1>(_value));
1620   //       ...b2
1621   //     } label _NextCase {
1622   //       const x3 : T3 = %assume_impossible<T1|T2>(_value);
1623   //       ...b3
1624   //     }
1625   //   }
1626   // }
1627 
1628   BlockStatement* current_block = MakeNode<BlockStatement>();
1629   Statement* result = current_block;
1630   {
1631     CurrentSourcePosition::Scope current_source_position(expression->pos);
1632     current_block->statements.push_back(MakeNode<VarDeclarationStatement>(
1633         true, MakeNode<Identifier>("__value"), base::nullopt, expression));
1634   }
1635 
1636   TypeExpression* accumulated_types;
1637   for (size_t i = 0; i < cases.size(); ++i) {
1638     CurrentSourcePosition::Scope current_source_position(cases[i].pos);
1639     Expression* value =
1640         MakeNode<IdentifierExpression>(MakeNode<Identifier>("__value"));
1641     if (i >= 1) {
1642       value =
1643           MakeNode<AssumeTypeImpossibleExpression>(accumulated_types, value);
1644     }
1645     BlockStatement* case_block;
1646     if (i < cases.size() - 1) {
1647       value = MakeCall(MakeNode<Identifier>("Cast"),
1648                        std::vector<TypeExpression*>{cases[i].type},
1649                        std::vector<Expression*>{value},
1650                        std::vector<Statement*>{MakeNode<ExpressionStatement>(
1651                            MakeNode<IdentifierExpression>(
1652                                MakeNode<Identifier>(kNextCaseLabelName)))});
1653       case_block = MakeNode<BlockStatement>();
1654     } else {
1655       case_block = current_block;
1656     }
1657     Identifier* name =
1658         cases[i].name ? *cases[i].name : MakeNode<Identifier>("__case_value");
1659     if (cases[i].name) name = *cases[i].name;
1660     case_block->statements.push_back(
1661         MakeNode<VarDeclarationStatement>(true, name, cases[i].type, value));
1662     case_block->statements.push_back(cases[i].block);
1663     if (i < cases.size() - 1) {
1664       BlockStatement* next_block = MakeNode<BlockStatement>();
1665       current_block->statements.push_back(
1666           MakeNode<ExpressionStatement>(MakeNode<TryLabelExpression>(
1667               MakeNode<StatementExpression>(case_block),
1668               MakeNode<TryHandler>(TryHandler::HandlerKind::kLabel,
1669                                    MakeNode<Identifier>(kNextCaseLabelName),
1670                                    ParameterList::Empty(), next_block))));
1671       current_block = next_block;
1672     }
1673     accumulated_types =
1674         i > 0 ? MakeNode<UnionTypeExpression>(accumulated_types, cases[i].type)
1675               : cases[i].type;
1676   }
1677   return ParseResult{result};
1678 }
1679 
MakeTypeswitchCase( ParseResultIterator* child_results)1680 base::Optional<ParseResult> MakeTypeswitchCase(
1681     ParseResultIterator* child_results) {
1682   auto name = child_results->NextAs<base::Optional<Identifier*>>();
1683   auto type = child_results->NextAs<TypeExpression*>();
1684   auto block = child_results->NextAs<Statement*>();
1685   return ParseResult{
1686       TypeswitchCase{child_results->matched_input().pos, name, type, block}};
1687 }
1688 
MakeWhileStatement( ParseResultIterator* child_results)1689 base::Optional<ParseResult> MakeWhileStatement(
1690     ParseResultIterator* child_results) {
1691   auto condition = child_results->NextAs<Expression*>();
1692   auto body = child_results->NextAs<Statement*>();
1693   Statement* result = MakeNode<WhileStatement>(condition, body);
1694   CheckNotDeferredStatement(result);
1695   return ParseResult{result};
1696 }
1697 
MakeReturnStatement( ParseResultIterator* child_results)1698 base::Optional<ParseResult> MakeReturnStatement(
1699     ParseResultIterator* child_results) {
1700   auto value = child_results->NextAs<base::Optional<Expression*>>();
1701   Statement* result = MakeNode<ReturnStatement>(value);
1702   return ParseResult{result};
1703 }
1704 
MakeTailCallStatement( ParseResultIterator* child_results)1705 base::Optional<ParseResult> MakeTailCallStatement(
1706     ParseResultIterator* child_results) {
1707   auto value = child_results->NextAs<Expression*>();
1708   Statement* result = MakeNode<TailCallStatement>(CallExpression::cast(value));
1709   return ParseResult{result};
1710 }
1711 
MakeVarDeclarationStatement( ParseResultIterator* child_results)1712 base::Optional<ParseResult> MakeVarDeclarationStatement(
1713     ParseResultIterator* child_results) {
1714   auto kind = child_results->NextAs<Identifier*>();
1715   bool const_qualified = kind->value == "const";
1716   if (!const_qualified) DCHECK_EQ("let", kind->value);
1717   auto name = child_results->NextAs<Identifier*>();
1718   if (!IsLowerCamelCase(name->value)) {
1719     NamingConventionError("Variable", name, "lowerCamelCase");
1720   }
1721 
1722   auto type = child_results->NextAs<base::Optional<TypeExpression*>>();
1723   base::Optional<Expression*> initializer;
1724   if (child_results->HasNext())
1725     initializer = child_results->NextAs<Expression*>();
1726   if (!initializer && !type) {
1727     ReportError("Declaration is missing a type.");
1728   }
1729   Statement* result = MakeNode<VarDeclarationStatement>(const_qualified, name,
1730                                                         type, initializer);
1731   return ParseResult{result};
1732 }
1733 
MakeBreakStatement( ParseResultIterator* child_results)1734 base::Optional<ParseResult> MakeBreakStatement(
1735     ParseResultIterator* child_results) {
1736   Statement* result = MakeNode<BreakStatement>();
1737   return ParseResult{result};
1738 }
1739 
MakeContinueStatement( ParseResultIterator* child_results)1740 base::Optional<ParseResult> MakeContinueStatement(
1741     ParseResultIterator* child_results) {
1742   Statement* result = MakeNode<ContinueStatement>();
1743   return ParseResult{result};
1744 }
1745 
MakeGotoStatement( ParseResultIterator* child_results)1746 base::Optional<ParseResult> MakeGotoStatement(
1747     ParseResultIterator* child_results) {
1748   auto label = child_results->NextAs<Identifier*>();
1749   auto arguments = child_results->NextAs<std::vector<Expression*>>();
1750   Statement* result = MakeNode<GotoStatement>(label, std::move(arguments));
1751   return ParseResult{result};
1752 }
1753 
MakeBlockStatement( ParseResultIterator* child_results)1754 base::Optional<ParseResult> MakeBlockStatement(
1755     ParseResultIterator* child_results) {
1756   auto deferred = child_results->NextAs<bool>();
1757   auto statements = child_results->NextAs<std::vector<Statement*>>();
1758   for (Statement* statement : statements) {
1759     CheckNotDeferredStatement(statement);
1760   }
1761   Statement* result = MakeNode<BlockStatement>(deferred, std::move(statements));
1762   return ParseResult{result};
1763 }
1764 
MakeTryLabelExpression( ParseResultIterator* child_results)1765 base::Optional<ParseResult> MakeTryLabelExpression(
1766     ParseResultIterator* child_results) {
1767   auto try_block = child_results->NextAs<Statement*>();
1768   CheckNotDeferredStatement(try_block);
1769   Statement* result = try_block;
1770   auto handlers = child_results->NextAs<std::vector<TryHandler*>>();
1771   if (handlers.empty()) {
1772     Error("Try blocks without catch or label don't make sense.");
1773   }
1774   for (size_t i = 0; i < handlers.size(); ++i) {
1775     if (i != 0 &&
1776         handlers[i]->handler_kind == TryHandler::HandlerKind::kCatch) {
1777       Error(
1778           "A catch handler always has to be first, before any label handler, "
1779           "to avoid ambiguity about whether it catches exceptions from "
1780           "preceding handlers or not.")
1781           .Position(handlers[i]->pos);
1782     }
1783     result = MakeNode<ExpressionStatement>(MakeNode<TryLabelExpression>(
1784         MakeNode<StatementExpression>(result), handlers[i]));
1785   }
1786   return ParseResult{result};
1787 }
1788 
MakeForLoopStatement( ParseResultIterator* child_results)1789 base::Optional<ParseResult> MakeForLoopStatement(
1790     ParseResultIterator* child_results) {
1791   auto var_decl = child_results->NextAs<base::Optional<Statement*>>();
1792   auto test = child_results->NextAs<base::Optional<Expression*>>();
1793   auto action = child_results->NextAs<base::Optional<Expression*>>();
1794   base::Optional<Statement*> action_stmt;
1795   if (action) action_stmt = MakeNode<ExpressionStatement>(*action);
1796   auto body = child_results->NextAs<Statement*>();
1797   CheckNotDeferredStatement(body);
1798   Statement* result =
1799       MakeNode<ForLoopStatement>(var_decl, test, action_stmt, body);
1800   return ParseResult{result};
1801 }
1802 
MakeLabelBlock(ParseResultIterator* child_results)1803 base::Optional<ParseResult> MakeLabelBlock(ParseResultIterator* child_results) {
1804   auto label = child_results->NextAs<Identifier*>();
1805   if (!IsUpperCamelCase(label->value)) {
1806     NamingConventionError("Label", label, "UpperCamelCase");
1807   }
1808   auto parameters = child_results->NextAs<ParameterList>();
1809   auto body = child_results->NextAs<Statement*>();
1810   TryHandler* result = MakeNode<TryHandler>(TryHandler::HandlerKind::kLabel,
1811                                             label, std::move(parameters), body);
1812   return ParseResult{result};
1813 }
1814 
MakeCatchBlock(ParseResultIterator* child_results)1815 base::Optional<ParseResult> MakeCatchBlock(ParseResultIterator* child_results) {
1816   auto parameter_names = child_results->NextAs<std::vector<std::string>>();
1817   auto body = child_results->NextAs<Statement*>();
1818   for (const std::string& variable : parameter_names) {
1819     if (!IsLowerCamelCase(variable)) {
1820       NamingConventionError("Exception", variable, "lowerCamelCase");
1821     }
1822   }
1823   if (parameter_names.size() != 2) {
1824     ReportError(
1825         "A catch clause needs to have exactly two parameters: The exception "
1826         "and the message. How about: \"catch (exception, message) { ...\".");
1827   }
1828   ParameterList parameters;
1829 
1830   parameters.names.push_back(MakeNode<Identifier>(parameter_names[0]));
1831   parameters.types.push_back(MakeNode<BasicTypeExpression>(
1832       std::vector<std::string>{}, MakeNode<Identifier>("JSAny"),
1833       std::vector<TypeExpression*>{}));
1834   parameters.names.push_back(MakeNode<Identifier>(parameter_names[1]));
1835   parameters.types.push_back(MakeNode<UnionTypeExpression>(
1836       MakeNode<BasicTypeExpression>(std::vector<std::string>{},
1837                                     MakeNode<Identifier>("JSMessageObject"),
1838                                     std::vector<TypeExpression*>{}),
1839       MakeNode<BasicTypeExpression>(std::vector<std::string>{},
1840                                     MakeNode<Identifier>("TheHole"),
1841                                     std::vector<TypeExpression*>{})));
1842   parameters.has_varargs = false;
1843   TryHandler* result = MakeNode<TryHandler>(
1844       TryHandler::HandlerKind::kCatch, MakeNode<Identifier>(kCatchLabelName),
1845       std::move(parameters), body);
1846   return ParseResult{result};
1847 }
1848 
MakeExpressionWithSource( ParseResultIterator* child_results)1849 base::Optional<ParseResult> MakeExpressionWithSource(
1850     ParseResultIterator* child_results) {
1851   auto e = child_results->NextAs<Expression*>();
1852   return ParseResult{
1853       ExpressionWithSource{e, child_results->matched_input().ToString()}};
1854 }
1855 
MakeIdentifier(ParseResultIterator* child_results)1856 base::Optional<ParseResult> MakeIdentifier(ParseResultIterator* child_results) {
1857   auto name = child_results->NextAs<std::string>();
1858   Identifier* result = MakeNode<Identifier>(std::move(name));
1859   return ParseResult{result};
1860 }
1861 
MakeIdentifierFromMatchedInput( ParseResultIterator* child_results)1862 base::Optional<ParseResult> MakeIdentifierFromMatchedInput(
1863     ParseResultIterator* child_results) {
1864   return ParseResult{
1865       MakeNode<Identifier>(child_results->matched_input().ToString())};
1866 }
1867 
MakeRightShiftIdentifier( ParseResultIterator* child_results)1868 base::Optional<ParseResult> MakeRightShiftIdentifier(
1869     ParseResultIterator* child_results) {
1870   std::string str = child_results->matched_input().ToString();
1871   for (auto character : str) {
1872     if (character != '>') {
1873       ReportError("right-shift operators may not contain any whitespace");
1874     }
1875   }
1876   return ParseResult{MakeNode<Identifier>(str)};
1877 }
1878 
MakeNamespaceQualification( ParseResultIterator* child_results)1879 base::Optional<ParseResult> MakeNamespaceQualification(
1880     ParseResultIterator* child_results) {
1881   bool global_namespace = child_results->NextAs<bool>();
1882   auto namespace_qualification =
1883       child_results->NextAs<std::vector<std::string>>();
1884   if (global_namespace) {
1885     namespace_qualification.insert(namespace_qualification.begin(), "");
1886   }
1887   return ParseResult(std::move(namespace_qualification));
1888 }
1889 
MakeIdentifierExpression( ParseResultIterator* child_results)1890 base::Optional<ParseResult> MakeIdentifierExpression(
1891     ParseResultIterator* child_results) {
1892   auto namespace_qualification =
1893       child_results->NextAs<std::vector<std::string>>();
1894   auto name = child_results->NextAs<Identifier*>();
1895   auto generic_arguments =
1896       child_results->NextAs<std::vector<TypeExpression*>>();
1897   Expression* result = MakeNode<IdentifierExpression>(
1898       std::move(namespace_qualification), name, std::move(generic_arguments));
1899   return ParseResult{result};
1900 }
1901 
MakeFieldAccessExpression( ParseResultIterator* child_results)1902 base::Optional<ParseResult> MakeFieldAccessExpression(
1903     ParseResultIterator* child_results) {
1904   auto object = child_results->NextAs<Expression*>();
1905   auto field = child_results->NextAs<Identifier*>();
1906   Expression* result = MakeNode<FieldAccessExpression>(object, field);
1907   return ParseResult{result};
1908 }
1909 
MakeReferenceFieldAccessExpression( ParseResultIterator* child_results)1910 base::Optional<ParseResult> MakeReferenceFieldAccessExpression(
1911     ParseResultIterator* child_results) {
1912   auto object = child_results->NextAs<Expression*>();
1913   auto field = child_results->NextAs<Identifier*>();
1914   // `a->b` is equivalent to `(*a).b`.
1915   Expression* deref = MakeNode<DereferenceExpression>(object);
1916   Expression* result = MakeNode<FieldAccessExpression>(deref, field);
1917   return ParseResult{result};
1918 }
1919 
MakeElementAccessExpression( ParseResultIterator* child_results)1920 base::Optional<ParseResult> MakeElementAccessExpression(
1921     ParseResultIterator* child_results) {
1922   auto object = child_results->NextAs<Expression*>();
1923   auto field = child_results->NextAs<Expression*>();
1924   Expression* result = MakeNode<ElementAccessExpression>(object, field);
1925   return ParseResult{result};
1926 }
1927 
MakeDereferenceExpression( ParseResultIterator* child_results)1928 base::Optional<ParseResult> MakeDereferenceExpression(
1929     ParseResultIterator* child_results) {
1930   auto reference = child_results->NextAs<Expression*>();
1931   Expression* result = MakeNode<DereferenceExpression>(reference);
1932   return ParseResult{result};
1933 }
1934 
MakeStructExpression( ParseResultIterator* child_results)1935 base::Optional<ParseResult> MakeStructExpression(
1936     ParseResultIterator* child_results) {
1937   auto type = child_results->NextAs<TypeExpression*>();
1938   auto initializers = child_results->NextAs<std::vector<NameAndExpression>>();
1939   Expression* result =
1940       MakeNode<StructExpression>(type, std::move(initializers));
1941   return ParseResult{result};
1942 }
1943 
MakeAssignmentExpression( ParseResultIterator* child_results)1944 base::Optional<ParseResult> MakeAssignmentExpression(
1945     ParseResultIterator* child_results) {
1946   auto location = child_results->NextAs<Expression*>();
1947   auto op = child_results->NextAs<base::Optional<std::string>>();
1948   auto value = child_results->NextAs<Expression*>();
1949   Expression* result =
1950       MakeNode<AssignmentExpression>(location, std::move(op), value);
1951   return ParseResult{result};
1952 }
1953 
MakeFloatingPointLiteralExpression( ParseResultIterator* child_results)1954 base::Optional<ParseResult> MakeFloatingPointLiteralExpression(
1955     ParseResultIterator* child_results) {
1956   auto value = child_results->NextAs<double>();
1957   Expression* result = MakeNode<FloatingPointLiteralExpression>(value);
1958   return ParseResult{result};
1959 }
1960 
MakeIntegerLiteralExpression( ParseResultIterator* child_results)1961 base::Optional<ParseResult> MakeIntegerLiteralExpression(
1962     ParseResultIterator* child_results) {
1963   auto value = child_results->NextAs<IntegerLiteral>();
1964   Expression* result = MakeNode<IntegerLiteralExpression>(std::move(value));
1965   return ParseResult{result};
1966 }
1967 
MakeStringLiteralExpression( ParseResultIterator* child_results)1968 base::Optional<ParseResult> MakeStringLiteralExpression(
1969     ParseResultIterator* child_results) {
1970   auto literal = child_results->NextAs<std::string>();
1971   Expression* result = MakeNode<StringLiteralExpression>(std::move(literal));
1972   return ParseResult{result};
1973 }
1974 
MakeIncrementDecrementExpressionPostfix( ParseResultIterator* child_results)1975 base::Optional<ParseResult> MakeIncrementDecrementExpressionPostfix(
1976     ParseResultIterator* child_results) {
1977   auto location = child_results->NextAs<Expression*>();
1978   auto op = child_results->NextAs<IncrementDecrementOperator>();
1979   Expression* result =
1980       MakeNode<IncrementDecrementExpression>(location, op, true);
1981   return ParseResult{result};
1982 }
1983 
MakeIncrementDecrementExpressionPrefix( ParseResultIterator* child_results)1984 base::Optional<ParseResult> MakeIncrementDecrementExpressionPrefix(
1985     ParseResultIterator* child_results) {
1986   auto op = child_results->NextAs<IncrementDecrementOperator>();
1987   auto location = child_results->NextAs<Expression*>();
1988   Expression* result =
1989       MakeNode<IncrementDecrementExpression>(location, op, false);
1990   return ParseResult{result};
1991 }
1992 
MakeLogicalOrExpression( ParseResultIterator* child_results)1993 base::Optional<ParseResult> MakeLogicalOrExpression(
1994     ParseResultIterator* child_results) {
1995   auto left = child_results->NextAs<Expression*>();
1996   auto right = child_results->NextAs<Expression*>();
1997   Expression* result = MakeNode<LogicalOrExpression>(left, right);
1998   return ParseResult{result};
1999 }
2000 
MakeLogicalAndExpression( ParseResultIterator* child_results)2001 base::Optional<ParseResult> MakeLogicalAndExpression(
2002     ParseResultIterator* child_results) {
2003   auto left = child_results->NextAs<Expression*>();
2004   auto right = child_results->NextAs<Expression*>();
2005   Expression* result = MakeNode<LogicalAndExpression>(left, right);
2006   return ParseResult{result};
2007 }
2008 
MakeConditionalExpression( ParseResultIterator* child_results)2009 base::Optional<ParseResult> MakeConditionalExpression(
2010     ParseResultIterator* child_results) {
2011   auto condition = child_results->NextAs<Expression*>();
2012   auto if_true = child_results->NextAs<Expression*>();
2013   auto if_false = child_results->NextAs<Expression*>();
2014   Expression* result =
2015       MakeNode<ConditionalExpression>(condition, if_true, if_false);
2016   return ParseResult{result};
2017 }
2018 
MakeLabelAndTypes( ParseResultIterator* child_results)2019 base::Optional<ParseResult> MakeLabelAndTypes(
2020     ParseResultIterator* child_results) {
2021   auto name = child_results->NextAs<Identifier*>();
2022   if (!IsUpperCamelCase(name->value)) {
2023     NamingConventionError("Label", name, "UpperCamelCase");
2024   }
2025   auto types = child_results->NextAs<std::vector<TypeExpression*>>();
2026   return ParseResult{LabelAndTypes{name, std::move(types)}};
2027 }
2028 
MakeNameAndType( ParseResultIterator* child_results)2029 base::Optional<ParseResult> MakeNameAndType(
2030     ParseResultIterator* child_results) {
2031   auto name = child_results->NextAs<Identifier*>();
2032   auto type = child_results->NextAs<TypeExpression*>();
2033   return ParseResult{NameAndTypeExpression{name, type}};
2034 }
2035 
MakeEnumEntry(ParseResultIterator* child_results)2036 base::Optional<ParseResult> MakeEnumEntry(ParseResultIterator* child_results) {
2037   auto name = child_results->NextAs<Identifier*>();
2038   auto type = child_results->NextAs<base::Optional<TypeExpression*>>();
2039   return ParseResult{EnumEntry{name, type}};
2040 }
2041 
MakeNameAndExpression( ParseResultIterator* child_results)2042 base::Optional<ParseResult> MakeNameAndExpression(
2043     ParseResultIterator* child_results) {
2044   auto name = child_results->NextAs<Identifier*>();
2045   auto expression = child_results->NextAs<Expression*>();
2046   return ParseResult{NameAndExpression{name, expression}};
2047 }
2048 
MakeNameAndExpressionFromExpression( ParseResultIterator* child_results)2049 base::Optional<ParseResult> MakeNameAndExpressionFromExpression(
2050     ParseResultIterator* child_results) {
2051   auto expression = child_results->NextAs<Expression*>();
2052   if (auto* id = IdentifierExpression::DynamicCast(expression)) {
2053     if (!id->generic_arguments.empty() ||
2054         !id->namespace_qualification.empty()) {
2055       ReportError("expected a plain identifier without qualification");
2056     }
2057     return ParseResult{NameAndExpression{id->name, id}};
2058   }
2059   ReportError("Constructor parameters need to be named.");
2060 }
2061 
MakeAnnotation(ParseResultIterator* child_results)2062 base::Optional<ParseResult> MakeAnnotation(ParseResultIterator* child_results) {
2063   return ParseResult{
2064       Annotation{child_results->NextAs<Identifier*>(),
2065                  child_results->NextAs<base::Optional<AnnotationParameter>>()}};
2066 }
2067 
MakeClassField(ParseResultIterator* child_results)2068 base::Optional<ParseResult> MakeClassField(ParseResultIterator* child_results) {
2069   AnnotationSet annotations(
2070       child_results,
2071       {ANNOTATION_CPP_RELAXED_STORE, ANNOTATION_CPP_RELAXED_LOAD,
2072        ANNOTATION_CPP_RELEASE_STORE, ANNOTATION_CPP_ACQUIRE_LOAD,
2073        ANNOTATION_CUSTOM_WEAK_MARKING},
2074       {ANNOTATION_IF, ANNOTATION_IFNOT});
2075   FieldSynchronization write_synchronization = FieldSynchronization::kNone;
2076   if (annotations.Contains(ANNOTATION_CPP_RELEASE_STORE)) {
2077     write_synchronization = FieldSynchronization::kAcquireRelease;
2078   } else if (annotations.Contains(ANNOTATION_CPP_RELAXED_STORE)) {
2079     write_synchronization = FieldSynchronization::kRelaxed;
2080   }
2081   FieldSynchronization read_synchronization = FieldSynchronization::kNone;
2082   if (annotations.Contains(ANNOTATION_CPP_ACQUIRE_LOAD)) {
2083     read_synchronization = FieldSynchronization::kAcquireRelease;
2084   } else if (annotations.Contains(ANNOTATION_CPP_RELAXED_LOAD)) {
2085     read_synchronization = FieldSynchronization::kRelaxed;
2086   }
2087   std::vector<ConditionalAnnotation> conditions;
2088   base::Optional<std::string> if_condition =
2089       annotations.GetStringParam(ANNOTATION_IF);
2090   base::Optional<std::string> ifnot_condition =
2091       annotations.GetStringParam(ANNOTATION_IFNOT);
2092   if (if_condition.has_value()) {
2093     conditions.push_back({*if_condition, ConditionalAnnotationType::kPositive});
2094   }
2095   if (ifnot_condition.has_value()) {
2096     conditions.push_back(
2097         {*ifnot_condition, ConditionalAnnotationType::kNegative});
2098   }
2099   bool custom_weak_marking =
2100       annotations.Contains(ANNOTATION_CUSTOM_WEAK_MARKING);
2101   auto deprecated_weak = child_results->NextAs<bool>();
2102   if (deprecated_weak) {
2103     Error(
2104         "The keyword 'weak' is deprecated. For a field that can contain a "
2105         "normal weak pointer, use type Weak<T>. For a field that should be "
2106         "marked in some custom way, use @customWeakMarking.");
2107     custom_weak_marking = true;
2108   }
2109   auto const_qualified = child_results->NextAs<bool>();
2110   auto name = child_results->NextAs<Identifier*>();
2111   auto optional = child_results->NextAs<bool>();
2112   auto index = child_results->NextAs<base::Optional<Expression*>>();
2113   if (optional && !index) {
2114     Error(
2115         "Fields using optional specifier must also provide an expression "
2116         "indicating the condition for whether the field is present");
2117   }
2118   base::Optional<ClassFieldIndexInfo> index_info;
2119   if (index) {
2120     if (optional) {
2121       // Internally, an optional field is just an indexed field where the count
2122       // is zero or one.
2123       index = MakeNode<ConditionalExpression>(
2124           *index,
2125           MakeCall(
2126               MakeNode<Identifier>("FromConstexpr"),
2127               {MakeNode<BasicTypeExpression>(std::vector<std::string>{},
2128                                              MakeNode<Identifier>("intptr"),
2129                                              std::vector<TypeExpression*>{})},
2130               {MakeNode<IntegerLiteralExpression>(IntegerLiteral(1))}, {}),
2131           MakeCall(
2132               MakeNode<Identifier>("FromConstexpr"),
2133               {MakeNode<BasicTypeExpression>(std::vector<std::string>{},
2134                                              MakeNode<Identifier>("intptr"),
2135                                              std::vector<TypeExpression*>{})},
2136               {MakeNode<IntegerLiteralExpression>(IntegerLiteral(0))}, {}));
2137     }
2138     index_info = ClassFieldIndexInfo{*index, optional};
2139   }
2140   auto type = child_results->NextAs<TypeExpression*>();
2141   return ParseResult{ClassFieldExpression{{name, type},
2142                                           index_info,
2143                                           std::move(conditions),
2144                                           custom_weak_marking,
2145                                           const_qualified,
2146                                           read_synchronization,
2147                                           write_synchronization}};
2148 }
2149 
MakeStructField( ParseResultIterator* child_results)2150 base::Optional<ParseResult> MakeStructField(
2151     ParseResultIterator* child_results) {
2152   auto const_qualified = child_results->NextAs<bool>();
2153   auto name = child_results->NextAs<Identifier*>();
2154   auto type = child_results->NextAs<TypeExpression*>();
2155   return ParseResult{StructFieldExpression{{name, type}, const_qualified}};
2156 }
2157 
MakeBitFieldDeclaration( ParseResultIterator* child_results)2158 base::Optional<ParseResult> MakeBitFieldDeclaration(
2159     ParseResultIterator* child_results) {
2160   auto name = child_results->NextAs<Identifier*>();
2161   auto type = child_results->NextAs<TypeExpression*>();
2162   auto num_bits = child_results->NextAs<int32_t>();
2163   return ParseResult{BitFieldDeclaration{{name, type}, num_bits}};
2164 }
2165 
ExtractAssignmentOperator( ParseResultIterator* child_results)2166 base::Optional<ParseResult> ExtractAssignmentOperator(
2167     ParseResultIterator* child_results) {
2168   auto op = child_results->NextAs<Identifier*>();
2169   base::Optional<std::string> result =
2170       std::string(op->value.begin(), op->value.end() - 1);
2171   return ParseResult(std::move(result));
2172 }
2173 
2174 struct TorqueGrammar : Grammar {
MatchWhitespacev8::internal::torque::__anon15131::TorqueGrammar2175   static bool MatchWhitespace(InputPosition* pos) {
2176     while (true) {
2177       if (MatchChar(std::isspace, pos)) continue;
2178       if (MatchString("//", pos)) {
2179         while (MatchChar([](char c) { return c != '\n'; }, pos)) {
2180         }
2181         continue;
2182       }
2183       if (MatchString("/*", pos)) {
2184         while (!MatchString("*/", pos)) ++*pos;
2185         continue;
2186       }
2187       return true;
2188     }
2189   }
2190 
MatchIdentifierv8::internal::torque::__anon15131::TorqueGrammar2191   static bool MatchIdentifier(InputPosition* pos) {
2192     InputPosition current = *pos;
2193     MatchString("_", &current);
2194     if (!MatchChar(std::isalpha, &current)) return false;
2195     while (MatchChar(std::isalnum, &current) || MatchString("_", &current)) {
2196     }
2197     *pos = current;
2198     return true;
2199   }
2200 
MatchAnnotationv8::internal::torque::__anon15131::TorqueGrammar2201   static bool MatchAnnotation(InputPosition* pos) {
2202     InputPosition current = *pos;
2203     if (!MatchString("@", &current)) return false;
2204     if (!MatchIdentifier(&current)) return false;
2205     *pos = current;
2206     return true;
2207   }
2208 
MatchIntrinsicNamev8::internal::torque::__anon15131::TorqueGrammar2209   static bool MatchIntrinsicName(InputPosition* pos) {
2210     InputPosition current = *pos;
2211     if (!MatchString("%", &current)) return false;
2212     if (!MatchIdentifier(&current)) return false;
2213     *pos = current;
2214     return true;
2215   }
2216 
MatchStringLiteralv8::internal::torque::__anon15131::TorqueGrammar2217   static bool MatchStringLiteral(InputPosition* pos) {
2218     InputPosition current = *pos;
2219     if (MatchString("\"", &current)) {
2220       while (
2221           (MatchString("\\", &current) && MatchAnyChar(&current)) ||
2222           MatchChar([](char c) { return c != '"' && c != '\n'; }, &current)) {
2223       }
2224       if (MatchString("\"", &current)) {
2225         *pos = current;
2226         return true;
2227       }
2228     }
2229     current = *pos;
2230     if (MatchString("'", &current)) {
2231       while (
2232           (MatchString("\\", &current) && MatchAnyChar(&current)) ||
2233           MatchChar([](char c) { return c != '\'' && c != '\n'; }, &current)) {
2234       }
2235       if (MatchString("'", &current)) {
2236         *pos = current;
2237         return true;
2238       }
2239     }
2240     return false;
2241   }
2242 
MatchHexLiteralv8::internal::torque::__anon15131::TorqueGrammar2243   static bool MatchHexLiteral(InputPosition* pos) {
2244     InputPosition current = *pos;
2245     MatchString("-", &current);
2246     if (MatchString("0x", &current) && MatchChar(std::isxdigit, &current)) {
2247       while (MatchChar(std::isxdigit, &current)) {
2248       }
2249       *pos = current;
2250       return true;
2251     }
2252     return false;
2253   }
2254 
MatchIntegerLiteralv8::internal::torque::__anon15131::TorqueGrammar2255   static bool MatchIntegerLiteral(InputPosition* pos) {
2256     InputPosition current = *pos;
2257     bool found_digit = false;
2258     MatchString("-", &current);
2259     while (MatchChar(std::isdigit, &current)) found_digit = true;
2260     if (found_digit) {
2261       *pos = current;
2262       return true;
2263     }
2264     return false;
2265   }
2266 
MatchFloatingPointLiteralv8::internal::torque::__anon15131::TorqueGrammar2267   static bool MatchFloatingPointLiteral(InputPosition* pos) {
2268     InputPosition current = *pos;
2269     bool found_digit = false;
2270     MatchString("-", &current);
2271     while (MatchChar(std::isdigit, &current)) found_digit = true;
2272     if (!MatchString(".", &current)) return false;
2273     while (MatchChar(std::isdigit, &current)) found_digit = true;
2274     if (!found_digit) return false;
2275     *pos = current;
2276     if ((MatchString("e", &current) || MatchString("E", &current)) &&
2277         (MatchString("+", &current) || MatchString("-", &current) || true) &&
2278         MatchChar(std::isdigit, &current)) {
2279       while (MatchChar(std::isdigit, &current)) {
2280       }
2281       *pos = current;
2282       return true;
2283     }
2284     return true;
2285   }
2286 
2287   template <class T, bool first>
MakeExtendedVectorIfAnnotationv8::internal::torque::__anon15131::TorqueGrammar2288   static base::Optional<ParseResult> MakeExtendedVectorIfAnnotation(
2289       ParseResultIterator* child_results) {
2290     std::vector<T> l = {};
2291     if (!first) l = child_results->NextAs<std::vector<T>>();
2292     bool enabled = ProcessIfAnnotation(child_results);
2293     T x = child_results->NextAs<T>();
2294 
2295     if (enabled) l.push_back(std::move(x));
2296     return ParseResult{std::move(l)};
2297   }
2298 
2299   template <class T>
NonemptyListAllowIfAnnotationv8::internal::torque::__anon15131::TorqueGrammar2300   Symbol* NonemptyListAllowIfAnnotation(
2301       Symbol* element, base::Optional<Symbol*> separator = {}) {
2302     Symbol* list = NewSymbol();
2303     *list = {
2304         Rule({annotations, element}, MakeExtendedVectorIfAnnotation<T, true>),
2305         separator ? Rule({list, annotations, *separator, element},
2306                          MakeExtendedVectorIfAnnotation<T, false>)
2307                   : Rule({list, annotations, element},
2308                          MakeExtendedVectorIfAnnotation<T, false>)};
2309     return list;
2310   }
2311 
2312   template <class T>
ListAllowIfAnnotationv8::internal::torque::__anon15131::TorqueGrammar2313   Symbol* ListAllowIfAnnotation(Symbol* element,
2314                                 base::Optional<Symbol*> separator = {}) {
2315     return TryOrDefault<std::vector<T>>(
2316         NonemptyListAllowIfAnnotation<T>(element, separator));
2317   }
2318 
TorqueGrammarv8::internal::torque::__anon15131::TorqueGrammar2319   TorqueGrammar() : Grammar(&file) { SetWhitespace(MatchWhitespace); }
2320 
2321   // Result: Expression*
2322   Symbol* expression = &assignmentExpression;
2323 
2324   // Result: std::string
2325   Symbol identifier = {Rule({Pattern(MatchIdentifier)}, YieldMatchedInput),
2326                        Rule({Token("runtime")}, YieldMatchedInput)};
2327 
2328   // Result: Identifier*
2329   Symbol name = {Rule({&identifier}, MakeIdentifier)};
2330 
2331   // Result: Identifier*
2332   Symbol annotationName = {
2333       Rule({Pattern(MatchAnnotation)}, MakeIdentifierFromMatchedInput)};
2334 
2335   // Result: std::string
2336   Symbol intrinsicName = {
2337       Rule({Pattern(MatchIntrinsicName)}, MakeIdentifierFromMatchedInput)};
2338 
2339   // Result: std::string
2340   Symbol stringLiteral = {
2341       Rule({Pattern(MatchStringLiteral)}, YieldMatchedInput)};
2342 
2343   // Result: std::string
2344   Symbol externalString = {Rule({&stringLiteral}, StringLiteralUnquoteAction)};
2345 
2346   // Result: IntegerLiteral
2347   Symbol integerLiteral = {
2348       Rule({Pattern(MatchIntegerLiteral)}, YieldIntegerLiteral),
2349       Rule({Pattern(MatchHexLiteral)}, YieldIntegerLiteral)};
2350 
2351   // Result: double
2352   Symbol floatingPointLiteral = {
2353       Rule({Pattern(MatchFloatingPointLiteral)}, YieldDouble)};
2354 
2355   // Result: int32_t
2356   Symbol int32Literal = {Rule({Pattern(MatchIntegerLiteral)}, YieldInt32),
2357                          Rule({Pattern(MatchHexLiteral)}, YieldInt32)};
2358 
2359   // Result: AnnotationParameter
2360   Symbol annotationParameter = {
2361       Rule({&identifier}, MakeStringAnnotationParameter),
2362       Rule({&int32Literal}, MakeIntAnnotationParameter),
2363       Rule({&externalString}, MakeStringAnnotationParameter)};
2364 
2365   // Result: AnnotationParameter
2366   Symbol annotationParameters = {
2367       Rule({Token("("), &annotationParameter, Token(")")})};
2368 
2369   // Result: Annotation
2370   Symbol annotation = {Rule(
2371       {&annotationName, Optional<AnnotationParameter>(&annotationParameters)},
2372       MakeAnnotation)};
2373 
2374   // Result: std::vector<Annotation>
2375   Symbol* annotations = List<Annotation>(&annotation);
2376 
2377   // Result: std::vector<std::string>
2378   Symbol namespaceQualification = {
2379       Rule({CheckIf(Token("::")),
2380             List<std::string>(Sequence({&identifier, Token("::")}))},
2381            MakeNamespaceQualification)};
2382 
2383   // Result: TypeList
2384   Symbol* typeList = List<TypeExpression*>(&type, Token(","));
2385 
2386   // Result: TypeExpression*
2387   Symbol simpleType = {
2388       Rule({Token("("), &type, Token(")")}),
2389       Rule({&namespaceQualification, CheckIf(Token("constexpr")), &identifier,
2390             TryOrDefault<std::vector<TypeExpression*>>(
2391                 &genericSpecializationTypeList)},
2392            MakeBasicTypeExpression),
2393       Rule({Token("builtin"), Token("("), typeList, Token(")"), Token("=>"),
2394             &simpleType},
2395            MakeFunctionTypeExpression),
2396       Rule({CheckIf(Token("const")), Token("&"), &simpleType},
2397            MakeReferenceTypeExpression)};
2398 
2399   // Result: TypeExpression*
2400   Symbol type = {Rule({&simpleType}), Rule({&type, Token("|"), &simpleType},
2401                                            MakeUnionTypeExpression)};
2402 
2403   // Result: GenericParameter
2404   Symbol genericParameter = {
2405       Rule({&name, Token(":"), Token("type"),
2406             Optional<TypeExpression*>(Sequence({Token("extends"), &type}))},
2407            MakeGenericParameter)};
2408 
2409   // Result: GenericParameters
2410   Symbol genericParameters = {
2411       Rule({Token("<"), List<GenericParameter>(&genericParameter, Token(",")),
2412             Token(">")})};
2413 
2414   // Result: TypeList
2415   Symbol genericSpecializationTypeList = {
2416       Rule({Token("<"), typeList, Token(">")})};
2417 
2418   // Result: base::Optional<GenericParameters>
2419   Symbol* optionalGenericParameters = Optional<TypeList>(&genericParameters);
2420 
2421   Symbol implicitParameterList{
2422       Rule({Token("("), OneOf({"implicit", "js-implicit"}),
2423             List<NameAndTypeExpression>(&nameAndType, Token(",")), Token(")")},
2424            MakeImplicitParameterList)};
2425 
2426   Symbol* optionalImplicitParameterList{
2427       Optional<ImplicitParameters>(&implicitParameterList)};
2428 
2429   // Result: ParameterList
2430   Symbol typeListMaybeVarArgs = {
2431       Rule({optionalImplicitParameterList, Token("("),
2432             List<TypeExpression*>(Sequence({&type, Token(",")})), Token("..."),
2433             Token(")")},
2434            MakeParameterList<true, false>),
2435       Rule({optionalImplicitParameterList, Token("("), typeList, Token(")")},
2436            MakeParameterList<false, false>)};
2437 
2438   // Result: LabelAndTypes
2439   Symbol labelParameter = {Rule(
2440       {&name,
2441        TryOrDefault<TypeList>(Sequence({Token("("), typeList, Token(")")}))},
2442       MakeLabelAndTypes)};
2443 
2444   // Result: TypeExpression*
2445   Symbol returnType = {Rule({Token(":"), &type}),
2446                        Rule({}, DeprecatedMakeVoidType)};
2447 
2448   // Result: LabelAndTypesVector
2449   Symbol* optionalLabelList{TryOrDefault<LabelAndTypesVector>(
2450       Sequence({Token("labels"),
2451                 NonemptyList<LabelAndTypes>(&labelParameter, Token(","))}))};
2452 
2453   // Result: std::vector<Statement*>
2454   Symbol* optionalOtherwise{TryOrDefault<std::vector<Statement*>>(
2455       Sequence({Token("otherwise"),
2456                 NonemptyList<Statement*>(&atomarStatement, Token(","))}))};
2457 
2458   // Result: NameAndTypeExpression
2459   Symbol nameAndType = {Rule({&name, Token(":"), &type}, MakeNameAndType)};
2460 
2461   // Result: base::Optional<Expression*>
2462   Symbol* optionalArraySpecifier =
2463       Optional<Expression*>(Sequence({Token("["), expression, Token("]")}));
2464 
2465   // Result: ClassFieldExpression
2466   Symbol classField = {
2467       Rule({annotations, CheckIf(Token("weak")), CheckIf(Token("const")), &name,
2468             CheckIf(Token("?")), optionalArraySpecifier, Token(":"), &type,
2469             Token(";")},
2470            MakeClassField)};
2471 
2472   // Result: StructFieldExpression
2473   Symbol structField = {
2474       Rule({CheckIf(Token("const")), &name, Token(":"), &type, Token(";")},
2475            MakeStructField)};
2476 
2477   // Result: BitFieldDeclaration
2478   Symbol bitFieldDeclaration = {Rule({&name, Token(":"), &type, Token(":"),
2479                                       &int32Literal, Token("bit"), Token(";")},
2480                                      MakeBitFieldDeclaration)};
2481 
2482   // Result: ParameterList
2483   Symbol parameterListNoVararg = {
2484       Rule({optionalImplicitParameterList, Token("("),
2485             List<NameAndTypeExpression>(&nameAndType, Token(",")), Token(")")},
2486            MakeParameterList<false, true>)};
2487 
2488   // Result: ParameterList
2489   Symbol parameterListAllowVararg = {
2490       Rule({&parameterListNoVararg}),
2491       Rule({optionalImplicitParameterList, Token("("),
2492             List<NameAndTypeExpression>(Sequence({&nameAndType, Token(",")})),
2493             Token("..."), &identifier, Token(")")},
2494            MakeParameterList<true, true>)};
2495 
2496   // Result: Identifier*
OneOfv8::internal::torque::__anon15131::TorqueGrammar2497   Symbol* OneOf(const std::vector<std::string>& alternatives) {
2498     Symbol* result = NewSymbol();
2499     for (const std::string& s : alternatives) {
2500       result->AddRule(Rule({Token(s)}, MakeIdentifierFromMatchedInput));
2501     }
2502     return result;
2503   }
2504 
2505   // Result: Expression*
BinaryOperatorv8::internal::torque::__anon15131::TorqueGrammar2506   Symbol* BinaryOperator(Symbol* nextLevel, Symbol* op) {
2507     Symbol* result = NewSymbol();
2508     *result = {Rule({nextLevel}),
2509                Rule({result, op, nextLevel}, MakeBinaryOperator)};
2510     return result;
2511   }
2512 
2513   // Result: IncrementDecrementOperator
2514   Symbol incrementDecrementOperator = {
2515       Rule({Token("++")},
2516            YieldIntegralConstant<IncrementDecrementOperator,
2517                                  IncrementDecrementOperator::kIncrement>),
2518       Rule({Token("--")},
2519            YieldIntegralConstant<IncrementDecrementOperator,
2520                                  IncrementDecrementOperator::kDecrement>)};
2521 
2522   // Result: Expression*
2523   Symbol identifierExpression = {
2524       Rule({&namespaceQualification, &name,
2525             TryOrDefault<TypeList>(&genericSpecializationTypeList)},
2526            MakeIdentifierExpression),
2527   };
2528 
2529   // Result: std::vector<Expression*>
2530   Symbol argumentList = {Rule(
2531       {Token("("), List<Expression*>(expression, Token(",")), Token(")")})};
2532 
2533   // Result: Expression*
2534   Symbol callExpression = {Rule(
2535       {&identifierExpression, &argumentList, optionalOtherwise}, MakeCall)};
2536 
2537   // Result: Expression*
2538   Symbol callMethodExpression = {Rule(
2539       {&primaryExpression, Token("."), &name, &argumentList, optionalOtherwise},
2540       MakeMethodCall)};
2541 
2542   // Result: NameAndExpression
2543   Symbol namedExpression = {
2544       Rule({&name, Token(":"), expression}, MakeNameAndExpression),
2545       Rule({expression}, MakeNameAndExpressionFromExpression)};
2546 
2547   // Result: std::vector<NameAndExpression>
2548   Symbol initializerList = {
2549       Rule({Token("{"), List<NameAndExpression>(&namedExpression, Token(",")),
2550             Token("}")})};
2551 
2552   // Result: Expression*
2553   Symbol intrinsicCallExpression = {Rule(
2554       {&intrinsicName, TryOrDefault<TypeList>(&genericSpecializationTypeList),
2555        &argumentList},
2556       MakeIntrinsicCallExpression)};
2557 
2558   // Result: Expression*
2559   Symbol newExpression = {
2560       Rule({Token("new"),
2561             CheckIf(Sequence({Token("("), Token("Pretenured"), Token(")")})),
2562             &simpleType, &initializerList},
2563            MakeNewExpression)};
2564 
2565   // Result: Expression*
2566   Symbol primaryExpression = {
2567       Rule({&callExpression}),
2568       Rule({&callMethodExpression}),
2569       Rule({&intrinsicCallExpression}),
2570       Rule({&identifierExpression}),
2571       Rule({&primaryExpression, Token("."), &name}, MakeFieldAccessExpression),
2572       Rule({&primaryExpression, Token("->"), &name},
2573            MakeReferenceFieldAccessExpression),
2574       Rule({&primaryExpression, Token("["), expression, Token("]")},
2575            MakeElementAccessExpression),
2576       Rule({&integerLiteral}, MakeIntegerLiteralExpression),
2577       Rule({&floatingPointLiteral}, MakeFloatingPointLiteralExpression),
2578       Rule({&stringLiteral}, MakeStringLiteralExpression),
2579       Rule({&simpleType, &initializerList}, MakeStructExpression),
2580       Rule({&newExpression}),
2581       Rule({Token("("), expression, Token(")")})};
2582 
2583   // Result: Expression*
2584   Symbol unaryExpression = {
2585       Rule({&primaryExpression}),
2586       Rule({OneOf({"+", "-", "!", "~", "&"}), &unaryExpression},
2587            MakeUnaryOperator),
2588       Rule({Token("*"), &unaryExpression}, MakeDereferenceExpression),
2589       Rule({Token("..."), &unaryExpression}, MakeSpreadExpression),
2590       Rule({&incrementDecrementOperator, &unaryExpression},
2591            MakeIncrementDecrementExpressionPrefix),
2592       Rule({&unaryExpression, &incrementDecrementOperator},
2593            MakeIncrementDecrementExpressionPostfix)};
2594 
2595   // Result: Expression*
2596   Symbol* multiplicativeExpression =
2597       BinaryOperator(&unaryExpression, OneOf({"*", "/", "%"}));
2598 
2599   // Result: Expression*
2600   Symbol* additiveExpression =
2601       BinaryOperator(multiplicativeExpression, OneOf({"+", "-"}));
2602 
2603   // Result: Identifier*
2604   Symbol shiftOperator = {
2605       Rule({Token("<<")}, MakeIdentifierFromMatchedInput),
2606       Rule({Token(">"), Token(">")}, MakeRightShiftIdentifier),
2607       Rule({Token(">"), Token(">"), Token(">")}, MakeRightShiftIdentifier)};
2608 
2609   // Result: Expression*
2610   Symbol* shiftExpression = BinaryOperator(additiveExpression, &shiftOperator);
2611 
2612   // Do not allow expressions like a < b > c because this is never
2613   // useful and ambiguous with template parameters.
2614   // Result: Expression*
2615   Symbol relationalExpression = {
2616       Rule({shiftExpression}),
2617       Rule({shiftExpression, OneOf({"<", ">", "<=", ">="}), shiftExpression},
2618            MakeBinaryOperator)};
2619 
2620   // Result: Expression*
2621   Symbol* equalityExpression =
2622       BinaryOperator(&relationalExpression, OneOf({"==", "!="}));
2623 
2624   // Result: Expression*
2625   Symbol* bitwiseExpression =
2626       BinaryOperator(equalityExpression, OneOf({"&", "|"}));
2627 
2628   // Result: Expression*
2629   Symbol logicalAndExpression = {
2630       Rule({bitwiseExpression}),
2631       Rule({&logicalAndExpression, Token("&&"), bitwiseExpression},
2632            MakeLogicalAndExpression)};
2633 
2634   // Result: Expression*
2635   Symbol logicalOrExpression = {
2636       Rule({&logicalAndExpression}),
2637       Rule({&logicalOrExpression, Token("||"), &logicalAndExpression},
2638            MakeLogicalOrExpression)};
2639 
2640   // Result: Expression*
2641   Symbol conditionalExpression = {
2642       Rule({&logicalOrExpression}),
2643       Rule({&logicalOrExpression, Token("?"), expression, Token(":"),
2644             &conditionalExpression},
2645            MakeConditionalExpression)};
2646 
2647   // Result: base::Optional<std::string>
2648   Symbol assignmentOperator = {
2649       Rule({Token("=")}, YieldDefaultValue<base::Optional<std::string>>),
2650       Rule({OneOf({"*=", "/=", "%=", "+=", "-=", "<<=", ">>=", ">>>=", "&=",
2651                    "^=", "|="})},
2652            ExtractAssignmentOperator)};
2653 
2654   // Result: Expression*
2655   Symbol assignmentExpression = {
2656       Rule({&conditionalExpression}),
2657       Rule({&conditionalExpression, &assignmentOperator, &assignmentExpression},
2658            MakeAssignmentExpression)};
2659 
2660   // Result: Statement*
2661   Symbol block = {
2662       Rule({CheckIf(Token("deferred")), Token("{"),
2663             ListAllowIfAnnotation<Statement*>(&statement), Token("}")},
2664            MakeBlockStatement)};
2665 
2666   // Result: TryHandler*
2667   Symbol tryHandler = {
2668       Rule({Token("label"), &name,
2669             TryOrDefault<ParameterList>(&parameterListNoVararg), &block},
2670            MakeLabelBlock),
2671       Rule({Token("catch"), Token("("),
2672             List<std::string>(&identifier, Token(",")), Token(")"), &block},
2673            MakeCatchBlock)};
2674 
2675   // Result: ExpressionWithSource
2676   Symbol expressionWithSource = {Rule({expression}, MakeExpressionWithSource)};
2677 
2678   Symbol* optionalTypeSpecifier =
2679       Optional<TypeExpression*>(Sequence({Token(":"), &type}));
2680 
2681   // Result: EnumEntry
2682   Symbol enumEntry = {Rule({&name, optionalTypeSpecifier}, MakeEnumEntry)};
2683 
2684   // Result: Statement*
2685   Symbol varDeclaration = {
2686       Rule({OneOf({"let", "const"}), &name, optionalTypeSpecifier},
2687            MakeVarDeclarationStatement)};
2688 
2689   // Result: Statement*
2690   Symbol varDeclarationWithInitialization = {
2691       Rule({OneOf({"let", "const"}), &name, optionalTypeSpecifier, Token("="),
2692             expression},
2693            MakeVarDeclarationStatement)};
2694 
2695   // Result: Statement*
2696   Symbol atomarStatement = {
2697       Rule({expression}, MakeExpressionStatement),
2698       Rule({Token("return"), Optional<Expression*>(expression)},
2699            MakeReturnStatement),
2700       Rule({Token("tail"), &callExpression}, MakeTailCallStatement),
2701       Rule({Token("break")}, MakeBreakStatement),
2702       Rule({Token("continue")}, MakeContinueStatement),
2703       Rule({Token("goto"), &name,
2704             TryOrDefault<std::vector<Expression*>>(&argumentList)},
2705            MakeGotoStatement),
2706       Rule({OneOf({"debug", "unreachable"})}, MakeDebugStatement)};
2707 
2708   // Result: Statement*
2709   Symbol statement = {
2710       Rule({&block}),
2711       Rule({&atomarStatement, Token(";")}),
2712       Rule({&varDeclaration, Token(";")}),
2713       Rule({&varDeclarationWithInitialization, Token(";")}),
2714       Rule({Token("if"), CheckIf(Token("constexpr")), Token("("), expression,
2715             Token(")"), &statement,
2716             Optional<Statement*>(Sequence({Token("else"), &statement}))},
2717            MakeIfStatement),
2718       Rule(
2719           {
2720               Token("typeswitch"),
2721               Token("("),
2722               expression,
2723               Token(")"),
2724               Token("{"),
2725               NonemptyListAllowIfAnnotation<TypeswitchCase>(&typeswitchCase),
2726               Token("}"),
2727           },
2728           MakeTypeswitchStatement),
2729       Rule({Token("try"), &block, List<TryHandler*>(&tryHandler)},
2730            MakeTryLabelExpression),
2731       Rule({OneOf({"dcheck", "check", "static_assert"}), Token("("),
2732             &expressionWithSource, Token(")"), Token(";")},
2733            MakeAssertStatement),
2734       Rule({Token("while"), Token("("), expression, Token(")"), &statement},
2735            MakeWhileStatement),
2736       Rule({Token("for"), Token("("),
2737             Optional<Statement*>(&varDeclarationWithInitialization), Token(";"),
2738             Optional<Expression*>(expression), Token(";"),
2739             Optional<Expression*>(expression), Token(")"), &statement},
2740            MakeForLoopStatement)};
2741 
2742   // Result: TypeswitchCase
2743   Symbol typeswitchCase = {
2744       Rule({Token("case"), Token("("),
2745             Optional<Identifier*>(Sequence({&name, Token(":")})), &type,
2746             Token(")"), Token(":"), &block},
2747            MakeTypeswitchCase)};
2748 
2749   // Result: base::Optional<Statement*>
2750   Symbol optionalBody = {
2751       Rule({&block}, CastParseResult<Statement*, base::Optional<Statement*>>),
2752       Rule({Token(";")}, YieldDefaultValue<base::Optional<Statement*>>)};
2753 
2754   // Result: Declaration*
2755   Symbol method = {Rule(
2756       {CheckIf(Token("transitioning")),
2757        Optional<std::string>(Sequence({Token("operator"), &externalString})),
2758        Token("macro"), &name, &parameterListNoVararg, &returnType,
2759        optionalLabelList, &block},
2760       MakeMethodDeclaration)};
2761 
2762   // Result: base::Optional<ClassBody*>
2763   Symbol optionalClassBody = {
2764       Rule({Token("{"), List<Declaration*>(&method),
2765             List<ClassFieldExpression>(&classField), Token("}")},
2766            MakeClassBody),
2767       Rule({Token(";")}, YieldDefaultValue<base::Optional<ClassBody*>>)};
2768 
2769   // Result: std::vector<Declaration*>
2770   Symbol declaration = {
2771       Rule({Token("const"), &name, Token(":"), &type, Token("="), expression,
2772             Token(";")},
2773            AsSingletonVector<Declaration*, MakeConstDeclaration>()),
2774       Rule({Token("const"), &name, Token(":"), &type, Token("generates"),
2775             &externalString, Token(";")},
2776            AsSingletonVector<Declaration*, MakeExternConstDeclaration>()),
2777       Rule({annotations, CheckIf(Token("extern")), CheckIf(Token("transient")),
2778             OneOf({"class", "shape"}), &name, Token("extends"), &type,
2779             Optional<std::string>(
2780                 Sequence({Token("generates"), &externalString})),
2781             &optionalClassBody},
2782            MakeClassDeclaration),
2783       Rule({annotations, Token("struct"), &name,
2784             TryOrDefault<GenericParameters>(&genericParameters), Token("{"),
2785             ListAllowIfAnnotation<Declaration*>(&method),
2786             ListAllowIfAnnotation<StructFieldExpression>(&structField),
2787             Token("}")},
2788            AsSingletonVector<Declaration*, MakeStructDeclaration>()),
2789       Rule({Token("bitfield"), Token("struct"), &name, Token("extends"), &type,
2790             Token("{"),
2791             ListAllowIfAnnotation<BitFieldDeclaration>(&bitFieldDeclaration),
2792             Token("}")},
2793            AsSingletonVector<Declaration*, MakeBitFieldStructDeclaration>()),
2794       Rule({annotations, CheckIf(Token("transient")), Token("type"), &name,
2795             TryOrDefault<GenericParameters>(&genericParameters),
2796             Optional<TypeExpression*>(Sequence({Token("extends"), &type})),
2797             Optional<std::string>(
2798                 Sequence({Token("generates"), &externalString})),
2799             Optional<std::string>(
2800                 Sequence({Token("constexpr"), &externalString})),
2801             Token(";")},
2802            MakeAbstractTypeDeclaration),
2803       Rule({annotations, Token("type"), &name, Token("="), &type, Token(";")},
2804            MakeTypeAliasDeclaration),
2805       Rule({Token("intrinsic"), &intrinsicName,
2806             TryOrDefault<GenericParameters>(&genericParameters),
2807             &parameterListNoVararg, &returnType, &optionalBody},
2808            AsSingletonVector<Declaration*, MakeIntrinsicDeclaration>()),
2809       Rule({Token("extern"), CheckIf(Token("transitioning")),
2810             Optional<std::string>(
2811                 Sequence({Token("operator"), &externalString})),
2812             Token("macro"),
2813             Optional<std::string>(Sequence({&identifier, Token("::")})), &name,
2814             TryOrDefault<GenericParameters>(&genericParameters),
2815             &typeListMaybeVarArgs, &returnType, optionalLabelList, Token(";")},
2816            AsSingletonVector<Declaration*, MakeExternalMacro>()),
2817       Rule({Token("extern"), CheckIf(Token("transitioning")),
2818             CheckIf(Token("javascript")), Token("builtin"), &name,
2819             TryOrDefault<GenericParameters>(&genericParameters),
2820             &typeListMaybeVarArgs, &returnType, Token(";")},
2821            AsSingletonVector<Declaration*, MakeExternalBuiltin>()),
2822       Rule({Token("extern"), CheckIf(Token("transitioning")), Token("runtime"),
2823             &name, &typeListMaybeVarArgs, &returnType, Token(";")},
2824            AsSingletonVector<Declaration*, MakeExternalRuntime>()),
2825       Rule({annotations, CheckIf(Token("transitioning")),
2826             Optional<std::string>(
2827                 Sequence({Token("operator"), &externalString})),
2828             Token("macro"), &name,
2829             TryOrDefault<GenericParameters>(&genericParameters),
2830             &parameterListNoVararg, &returnType, optionalLabelList,
2831             &optionalBody},
2832            AsSingletonVector<Declaration*, MakeTorqueMacroDeclaration>()),
2833       Rule({CheckIf(Token("transitioning")), CheckIf(Token("javascript")),
2834             Token("builtin"), &name,
2835             TryOrDefault<GenericParameters>(&genericParameters),
2836             &parameterListAllowVararg, &returnType, &optionalBody},
2837            AsSingletonVector<Declaration*, MakeTorqueBuiltinDeclaration>()),
2838       Rule({CheckIf(Token("transitioning")), &name,
2839             &genericSpecializationTypeList, &parameterListAllowVararg,
2840             &returnType, optionalLabelList, &block},
2841            AsSingletonVector<Declaration*, MakeSpecializationDeclaration>()),
2842       Rule({Token("#include"), &externalString},
2843            AsSingletonVector<Declaration*, MakeCppIncludeDeclaration>()),
2844       Rule({CheckIf(Token("extern")), Token("enum"), &name,
2845             Optional<TypeExpression*>(Sequence({Token("extends"), &type})),
2846             Optional<std::string>(
2847                 Sequence({Token("constexpr"), &externalString})),
2848             Token("{"),
2849             NonemptyListAllowIfAnnotation<EnumEntry>(&enumEntry, Token(",")),
2850             CheckIf(Sequence({Token(","), Token("...")})), Token("}")},
2851            MakeEnumDeclaration),
2852       Rule({Token("namespace"), &identifier, Token("{"), &declarationList,
2853             Token("}")},
2854            AsSingletonVector<Declaration*, MakeNamespaceDeclaration>())};
2855 
2856   // Result: std::vector<Declaration*>
2857   Symbol declarationList = {
2858       Rule({List<std::vector<Declaration*>>(&declaration)}, ConcatList)};
2859 
2860   Symbol file = {Rule({&file, Token("import"), &externalString},
2861                       ProcessTorqueImportDeclaration),
2862                  Rule({&file, &declaration}, AddGlobalDeclarations), Rule({})};
2863 };
2864 
2865 }  // namespace
2866 
ParseTorque(const std::string& input)2867 void ParseTorque(const std::string& input) {
2868   BuildFlags::Scope build_flags_scope;
2869   TorqueGrammar().Parse(input);
2870 }
2871 
2872 }  // namespace torque
2873 }  // namespace internal
2874 }  // namespace v8
2875