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("_", ¤t);
2194 if (!MatchChar(std::isalpha, ¤t)) return false;
2195 while (MatchChar(std::isalnum, ¤t) || MatchString("_", ¤t)) {
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("@", ¤t)) return false;
2204 if (!MatchIdentifier(¤t)) 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("%", ¤t)) return false;
2212 if (!MatchIdentifier(¤t)) 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("\"", ¤t)) {
2220 while (
2221 (MatchString("\\", ¤t) && MatchAnyChar(¤t)) ||
2222 MatchChar([](char c) { return c != '"' && c != '\n'; }, ¤t)) {
2223 }
2224 if (MatchString("\"", ¤t)) {
2225 *pos = current;
2226 return true;
2227 }
2228 }
2229 current = *pos;
2230 if (MatchString("'", ¤t)) {
2231 while (
2232 (MatchString("\\", ¤t) && MatchAnyChar(¤t)) ||
2233 MatchChar([](char c) { return c != '\'' && c != '\n'; }, ¤t)) {
2234 }
2235 if (MatchString("'", ¤t)) {
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("-", ¤t);
2246 if (MatchString("0x", ¤t) && MatchChar(std::isxdigit, ¤t)) {
2247 while (MatchChar(std::isxdigit, ¤t)) {
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("-", ¤t);
2259 while (MatchChar(std::isdigit, ¤t)) 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("-", ¤t);
2271 while (MatchChar(std::isdigit, ¤t)) found_digit = true;
2272 if (!MatchString(".", ¤t)) return false;
2273 while (MatchChar(std::isdigit, ¤t)) found_digit = true;
2274 if (!found_digit) return false;
2275 *pos = current;
2276 if ((MatchString("e", ¤t) || MatchString("E", ¤t)) &&
2277 (MatchString("+", ¤t) || MatchString("-", ¤t) || true) &&
2278 MatchChar(std::isdigit, ¤t)) {
2279 while (MatchChar(std::isdigit, ¤t)) {
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({¶meterListNoVararg}),
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>(¶meterListNoVararg), &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, ¶meterListNoVararg, &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 ¶meterListNoVararg, &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 ¶meterListNoVararg, &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 ¶meterListAllowVararg, &returnType, &optionalBody},
2837 AsSingletonVector<Declaration*, MakeTorqueBuiltinDeclaration>()),
2838 Rule({CheckIf(Token("transitioning")), &name,
2839 &genericSpecializationTypeList, ¶meterListAllowVararg,
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