12#include <unordered_map>
35 std::optional<Identifier*>
name;
42 std::optional<TypeExpression*>
type;
51 build_flags_[
"V8_ENABLE_EXPERIMENTAL_UNDEFINED_DOUBLE"] =
60#ifdef V8_ENABLE_JAVASCRIPT_PROMISE_HOOKS
61 build_flags_[
"V8_ENABLE_JAVASCRIPT_PROMISE_HOOKS"] =
true;
63 build_flags_[
"V8_ENABLE_JAVASCRIPT_PROMISE_HOOKS"] =
false;
65#ifdef V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
66 build_flags_[
"V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA"] =
true;
68 build_flags_[
"V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA"] =
false;
72#ifdef V8_SCRIPTORMODULE_LEGACY_LIFETIME
73 build_flags_[
"V8_SCRIPTORMODULE_LEGACY_LIFETIME"] =
true;
75 build_flags_[
"V8_SCRIPTORMODULE_LEGACY_LIFETIME"] =
false;
77#ifdef V8_ENABLE_WEBASSEMBLY
86 build_flags_[
"V8_ENABLE_LEAPTIERING_TAGGED_SIZE_8_BYTES"] =
89#ifdef V8_ENABLE_DRUMBRAKE
95 static bool GetFlag(
const std::string& name,
const char* production) {
96 auto it =
Get().build_flags_.find(name);
98 ReportError(
"Unknown flag used in ", production,
": ", name,
99 ". Please add it to the list in BuildFlags.");
110 ParseResultTypeId::kStdString;
113 ParseResultTypeId::kBool;
116 ParseResultTypeId::kInt32;
119 ParseResultTypeId::kDouble;
126 ParseResultTypeId::kStdVectorOfString;
129 ParseResultTypeId::kDeclarationPtr;
133 ParseResultTypeId::kTypeExpressionPtr;
137 ParseResultTypeId::kOptionalTypeExpressionPtr;
140 ParseResultTypeId::kTryHandlerPtr;
143 ParseResultTypeId::kExpressionPtr;
146 ParseResultTypeId::kIdentifierPtr;
150 ParseResultTypeId::kOptionalIdentifierPtr;
153 ParseResultTypeId::kStatementPtr;
157 ParseResultTypeId::kNameAndTypeExpression;
160 ParseResultTypeId::kEnumEntry;
164 ParseResultTypeId::kStdVectorOfEnumEntry;
168 ParseResultTypeId::kNameAndExpression;
171 ParseResultTypeId::kAnnotation;
175 ParseResultTypeId::kVectorOfAnnotation;
179 ParseResultTypeId::kAnnotationParameter;
183 ParseResultTypeId::kOptionalAnnotationParameter;
187 ParseResultTypeId::kClassFieldExpression;
191 ParseResultTypeId::kStructFieldExpression;
195 ParseResultTypeId::kBitFieldDeclaration;
199 ParseResultTypeId::kStdVectorOfNameAndTypeExpression;
203 ParseResultTypeId::kImplicitParameters;
207 ParseResultTypeId::kOptionalImplicitParameters;
211 ParseResultTypeId::kStdVectorOfNameAndExpression;
215 ParseResultTypeId::kStdVectorOfClassFieldExpression;
219 ParseResultTypeId::kStdVectorOfStructFieldExpression;
223 ParseResultTypeId::kStdVectorOfBitFieldDeclaration;
227 ParseResultTypeId::kIncrementDecrementOperator;
231 ParseResultTypeId::kOptionalStdString;
235 ParseResultTypeId::kStdVectorOfStatementPtr;
239 ParseResultTypeId::kStdVectorOfDeclarationPtr;
243 ParseResultTypeId::kStdVectorOfStdVectorOfDeclarationPtr;
247 ParseResultTypeId::kStdVectorOfExpressionPtr;
251 ParseResultTypeId::kExpressionWithSource;
254 ParseResultTypeId::kParameterList;
257 ParseResultTypeId::kTypeList;
261 ParseResultTypeId::kOptionalTypeList;
264 ParseResultTypeId::kLabelAndTypes;
268 ParseResultTypeId::kStdVectorOfLabelAndTypes;
272 ParseResultTypeId::kStdVectorOfTryHandlerPtr;
276 ParseResultTypeId::kOptionalStatementPtr;
280 ParseResultTypeId::kOptionalExpressionPtr;
287 ParseResultTypeId::kStdVectorOfTypeswitchCase;
291 ParseResultTypeId::kStdVectorOfIdentifierPtr;
295 ParseResultTypeId::kOptionalClassBody;
299 ParseResultTypeId::kGenericParameter;
303 ParseResultTypeId::kGenericParameters;
309bool ProcessIfAnnotation(
const AnnotationSet&
annotations);
311std::optional<ParseResult> AddGlobalDeclarations(
313 auto declarations = child_results->
NextAs<std::vector<Declaration*>>();
315 CurrentAst::Get().declarations().push_back(
declaration);
320void NamingConventionError(
const std::string& type,
const std::string& name,
321 const std::string& convention,
323 Lint(type,
" \"", name,
"\" does not follow \"", convention,
324 "\" naming convention.")
328void NamingConventionError(
const std::string& type,
const Identifier* name,
329 const std::string& convention) {
330 NamingConventionError(type, name->value, convention, name->pos);
334 for (
auto parameter : parameters) {
336 NamingConventionError(
"Generic parameter", parameter.name,
344 child_results->
NextAs<std::vector<std::vector<Declaration*>>>();
345 std::vector<Declaration*>
result;
346 for (
auto& list : list_of_lists) {
353 CurrentSourcePosition::Scope source_position(
statement->pos);
355 if (block->deferred) {
357 "cannot use deferred with a statement block here, it will have no "
365 if (!basic)
Error(
"Unsupported extends clause.").
Throw();
367 basic->namespace_qualification,
369 basic->generic_arguments);
373 std::optional<Expression*> target,
374 std::vector<Expression*> arguments,
375 const std::vector<Statement*>& otherwise) {
376 std::vector<Identifier*> labels;
381 size_t label_id_count = 0;
382 std::vector<TryHandler*> temp_labels;
384 if (
auto* e = ExpressionStatement::DynamicCast(
statement)) {
385 if (
auto*
id = IdentifierExpression::DynamicCast(e->expression)) {
386 if (!id->generic_arguments.empty()) {
387 ReportError(
"An otherwise label cannot have generic parameters");
389 labels.push_back(id->name);
393 auto label_name = std::string(
"__label") + std::to_string(label_id_count++);
396 labels.push_back(label_id);
400 temp_labels.push_back(handler);
408 *target, callee, std::move(arguments), std::move(labels));
414 for (
auto*
label : temp_labels) {
421 const std::vector<TypeExpression*>& generic_arguments,
422 const std::vector<Expression*>& arguments,
423 const std::vector<Statement*>& otherwise) {
425 std::nullopt, arguments, otherwise);
430 auto args = child_results->
NextAs<std::vector<Expression*>>();
431 auto otherwise = child_results->
NextAs<std::vector<Statement*>>();
434 MakeCall(target, std::nullopt, std::move(
args), otherwise)};
440 auto args = child_results->
NextAs<std::vector<Expression*>>();
441 auto otherwise = child_results->
NextAs<std::vector<Statement*>>();
443 std::move(
args), otherwise)};
446std::optional<ParseResult> MakeNewExpression(
448 bool pretenured = child_results->
NextAs<
bool>();
449 bool clear_padding = child_results->
NextAs<
bool>();
452 auto initializers = child_results->
NextAs<std::vector<NameAndExpression>>();
455 pretenured, clear_padding);
459std::optional<ParseResult> MakeBinaryOperator(
465 std::vector<Expression*>{left, right},
466 std::vector<Statement*>{})};
469std::optional<ParseResult> MakeIntrinsicCallExpression(
472 auto generic_arguments =
473 child_results->
NextAs<std::vector<TypeExpression*>>();
474 auto args = child_results->
NextAs<std::vector<Expression*>>();
476 callee, std::move(generic_arguments), std::move(
args));
480std::optional<ParseResult> MakeUnaryOperator(
485 std::vector<Statement*>{})};
488std::optional<ParseResult> MakeSpreadExpression(
495std::optional<ParseResult> MakeImplicitParameterList(
498 auto parameters = child_results->
NextAs<std::vector<NameAndTypeExpression>>();
505 NamingConventionError(
"Parameter", param.
name,
"lowerCamelCase");
507 parameter_list->
names.push_back(param.
name);
508 parameter_list->
types.push_back(param.
type);
511template <
bool has_varargs,
bool has_explicit_parameter_names>
512std::optional<ParseResult> MakeParameterList(
514 auto implicit_params =
515 child_results->
NextAs<std::optional<ImplicitParameters>>();
518 result.implicit_count = 0;
520 if (implicit_params) {
521 result.implicit_count = implicit_params->parameters.size();
522 if (implicit_params->kind->value ==
"implicit") {
525 DCHECK_EQ(implicit_params->kind->value,
"js-implicit");
528 result.implicit_kind_pos = implicit_params->kind->pos;
530 AddParameter(&
result, implicit_param);
533 if (has_explicit_parameter_names) {
534 auto explicit_params =
535 child_results->
NextAs<std::vector<NameAndTypeExpression>>();
536 std::string arguments_variable =
"";
538 arguments_variable = child_results->
NextAs<std::string>();
541 AddParameter(&
result, param);
543 result.arguments_variable = arguments_variable;
546 for (
auto* explicit_type : explicit_types) {
547 result.types.push_back(explicit_type);
553std::optional<ParseResult> MakeAssertStatement(
558 if (kind_string ==
"dcheck") {
560 }
else if (kind_string ==
"check") {
562 }
else if (kind_string ==
"sbxcheck") {
563#ifdef V8_ENABLE_SANDBOX
568 }
else if (kind_string ==
"static_assert") {
574 kind, expr_with_source.expression, expr_with_source.source);
578std::optional<ParseResult> MakeDebugStatement(
588std::optional<ParseResult> DeprecatedMakeVoidType(
590 Error(
"Default void return types are deprecated. Add `: void`.");
593 std::vector<TypeExpression*>{});
597std::optional<ParseResult> MakeExternalMacro(
599 bool enabled = ProcessIfAnnotation(child_results);
600 auto transitioning = child_results->
NextAs<
bool>();
601 auto operator_name = child_results->
NextAs<std::optional<std::string>>();
602 auto external_assembler_name =
603 child_results->
NextAs<std::optional<std::string>>();
606 LintGenericParameters(generic_parameters);
612 std::vector<Declaration*>
result = {};
616 external_assembler_name ? *external_assembler_name
617 :
"CodeStubAssembler",
618 name, operator_name,
args, return_type, std::move(labels))};
620 if (!generic_parameters.empty()) {
621 Error(
"External builtins cannot be generic.");
626std::optional<ParseResult> MakeIntrinsicDeclaration(
630 LintGenericParameters(generic_parameters);
634 auto body = child_results->
NextAs<std::optional<Statement*>>();
638 false, name, std::optional<std::string>{},
args, return_type,
644 if (!generic_parameters.empty()) {
674 const std::set<std::string>& allowed_without_param,
675 const std::set<std::string>& allowed_with_param) {
676 auto list = iter->
NextAs<std::vector<Annotation>>();
678 if (a.param.has_value()) {
679 if (allowed_with_param.find(a.name->value) ==
680 allowed_with_param.end()) {
681 const char* error_message =
682 allowed_without_param.find(a.name->value) ==
683 allowed_without_param.end()
684 ?
" is not allowed here"
685 :
" cannot have parameter here";
686 Lint(
"Annotation ", a.name->value, error_message)
689 if (!
map_.insert({a.name->value, {*a.param, a.name->pos}}).
second) {
690 Lint(
"Duplicate annotation ", a.name->value).
Position(a.name->pos);
693 if (allowed_without_param.find(a.name->value) ==
694 allowed_without_param.end()) {
695 const char* error_message =
696 allowed_with_param.find(a.name->value) == allowed_with_param.end()
697 ?
" is not allowed here"
698 :
" requires a parameter here";
699 Lint(
"Annotation ", a.name->value, error_message)
702 if (!
set_.insert(a.name->value).second) {
703 Lint(
"Duplicate annotation ", a.name->value).
Position(a.name->pos);
709 bool Contains(
const std::string& s)
const {
712 std::optional<std::string> GetStringParam(
const std::string& s)
const {
713 auto it =
map_.find(s);
714 if (it ==
map_.end()) {
717 if (it->second.first.is_int) {
718 Error(
"Annotation ", s,
" requires a string parameter but has an int")
721 return it->second.first.string_value;
723 std::optional<int32_t> GetIntParam(
const std::string& s)
const {
724 auto it =
map_.find(s);
725 if (it ==
map_.end()) {
728 if (!it->second.first.is_int) {
729 Error(
"Annotation ", s,
" requires an int parameter but has a string")
732 return it->second.first.int_value;
737 std::map<std::string, std::pair<AnnotationParameter, SourcePosition>>
map_;
740std::optional<ParseResult> MakeTorqueMacroDeclaration(
741 ParseResultIterator* child_results) {
746 auto transitioning = child_results->NextAs<
bool>();
747 auto operator_name = child_results->NextAs<std::optional<std::string>>();
748 auto name = child_results->NextAs<Identifier*>();
750 NamingConventionError(
"Macro", name,
"UpperCamelCase");
754 LintGenericParameters(generic_parameters);
756 auto args = child_results->NextAs<ParameterList>();
757 auto return_type = child_results->NextAs<TypeExpression*>();
759 auto body = child_results->NextAs<std::optional<Statement*>>();
760 std::vector<Declaration*>
result = {};
763 transitioning, name, operator_name,
args, return_type,
764 std::move(labels), export_to_csa, body);
766 if (generic_parameters.empty()) {
767 if (!body)
ReportError(
"A non-generic declaration needs a body.");
769 if (export_to_csa)
ReportError(
"Cannot export generics to CSA.");
774 return ParseResult{std::move(
result)};
777std::optional<ParseResult> MakeConstDeclaration(
778 ParseResultIterator* child_results) {
779 bool enabled = ProcessIfAnnotation(child_results);
780 auto name = child_results->NextAs<Identifier*>();
782 NamingConventionError(
"Constant", name,
"kUpperCamelCase");
785 auto type = child_results->NextAs<TypeExpression*>();
786 auto expression = child_results->NextAs<Expression*>();
787 std::vector<Declaration*>
result = {};
789 return ParseResult{std::move(
result)};
792std::optional<ParseResult> MakeExternConstDeclaration(
793 ParseResultIterator* child_results) {
794 auto name = child_results->NextAs<Identifier*>();
795 auto type = child_results->NextAs<TypeExpression*>();
796 auto literal = child_results->NextAs<std::string>();
799 return ParseResult{
result};
802std::optional<ParseResult> MakeTypeAliasDeclaration(
803 ParseResultIterator* child_results) {
804 bool enabled = ProcessIfAnnotation(child_results);
805 auto name = child_results->NextAs<Identifier*>();
806 auto type = child_results->NextAs<TypeExpression*>();
807 std::vector<Declaration*>
result = {};
809 return ParseResult{std::move(
result)};
812std::optional<ParseResult> MakeAbstractTypeDeclaration(
813 ParseResultIterator* child_results) {
814 bool use_parent_type_checker = HasAnnotation(
816 auto transient = child_results->NextAs<
bool>();
817 auto name = child_results->NextAs<Identifier*>();
819 NamingConventionError(
"Type", name,
"UpperCamelCase");
822 auto extends = child_results->NextAs<std::optional<TypeExpression*>>();
823 auto generates = child_results->NextAs<std::optional<std::string>>();
828 name, flags, extends, std::move(generates));
829 Declaration* decl = type_decl;
830 if (!generic_parameters.empty()) {
834 auto constexpr_generates =
835 child_results->NextAs<std::optional<std::string>>();
836 std::vector<Declaration*>
result{decl};
838 if (constexpr_generates) {
840 Identifier* constexpr_name =
842 constexpr_name->pos = name->pos;
844 std::optional<TypeExpression*> constexpr_extends;
846 constexpr_extends = AddConstexpr(*extends);
850 constexpr_generates);
851 constexpr_decl->pos = name->pos;
852 decl = constexpr_decl;
853 if (!generic_parameters.empty()) {
860 return ParseResult{std::move(
result)};
863std::optional<ParseResult> MakeMethodDeclaration(
864 ParseResultIterator* child_results) {
865 auto transitioning = child_results->NextAs<
bool>();
866 auto operator_name = child_results->NextAs<std::optional<std::string>>();
867 auto name = child_results->NextAs<Identifier*>();
869 NamingConventionError(
"Method", name,
"UpperCamelCase");
872 auto args = child_results->NextAs<ParameterList>();
873 auto return_type = child_results->NextAs<TypeExpression*>();
875 auto body = child_results->NextAs<Statement*>();
877 transitioning, name, operator_name,
args, return_type, std::move(labels),
879 return ParseResult{
result};
882bool ProcessIfAnnotation(
const AnnotationSet&
annotations) {
883 if (std::optional<std::string>
condition =
887 if (std::optional<std::string>
condition =
894bool ProcessIfAnnotation(ParseResultIterator* child_results) {
900std::optional<ParseResult> YieldInt32(ParseResultIterator* child_results) {
901 std::string value = child_results->matched_input().ToString();
902 size_t num_chars_converted = 0;
905 result = std::stoi(value, &num_chars_converted, 0);
906 }
catch (
const std::invalid_argument&) {
907 Error(
"Expected an integer");
908 return ParseResult{
result};
909 }
catch (
const std::out_of_range&) {
910 Error(
"Integer out of 32-bit range");
911 return ParseResult{
result};
914 DCHECK_EQ(num_chars_converted, value.size());
915 return ParseResult{
result};
918std::optional<ParseResult> YieldDouble(ParseResultIterator* child_results) {
919 std::string value = child_results->matched_input().ToString();
920 size_t num_chars_converted = 0;
923 result = std::stod(value, &num_chars_converted);
924 }
catch (
const std::out_of_range&) {
925 Error(
"double literal out-of-range");
926 return ParseResult{
result};
929 DCHECK_EQ(num_chars_converted, value.size());
930 return ParseResult{
result};
933std::optional<ParseResult> YieldIntegerLiteral(
934 ParseResultIterator* child_results) {
935 std::string value = child_results->matched_input().ToString();
938 if (!value.empty() && value[0] ==
'-') {
940 value = value.substr(1);
942 uint64_t absolute_value;
945 absolute_value = std::stoull(value, &parsed, 0);
947 }
catch (
const std::invalid_argument&) {
948 Error(
"integer literal could not be parsed").
Throw();
949 }
catch (
const std::out_of_range&) {
950 Error(
"integer literal value out of range").
Throw();
952 return ParseResult(IntegerLiteral(
negative, absolute_value));
955std::optional<ParseResult> MakeStringAnnotationParameter(
956 ParseResultIterator* child_results) {
957 std::string value = child_results->NextAs<std::string>();
959 return ParseResult{
result};
962std::optional<ParseResult> MakeIntAnnotationParameter(
963 ParseResultIterator* child_results) {
966 return ParseResult{
result};
969int GetAnnotationValue(
const AnnotationSet&
annotations,
const char* name,
972 return opt_value.has_value() ? *opt_value : default_value;
975std::optional<ParseResult> MakeTorqueBuiltinDeclaration(
976 ParseResultIterator* child_results) {
980 const bool has_custom_interface_descriptor =
982 std::optional<std::string> use_counter_name =
984 auto transitioning = child_results->NextAs<
bool>();
985 auto javascript_linkage = child_results->NextAs<
bool>();
986 auto name = child_results->NextAs<Identifier*>();
988 NamingConventionError(
"Builtin", name,
"UpperCamelCase");
992 LintGenericParameters(generic_parameters);
994 auto args = child_results->NextAs<ParameterList>();
995 auto return_type = child_results->NextAs<TypeExpression*>();
996 auto body = child_results->NextAs<std::optional<Statement*>>();
998 transitioning, javascript_linkage, name,
args, return_type,
999 has_custom_interface_descriptor, use_counter_name, body);
1001 if (generic_parameters.empty()) {
1002 if (!body)
ReportError(
"A non-generic declaration needs a body.");
1007 if (use_counter_name && !body) {
1008 ReportError(
"@incrementUseCounter needs a body.");
1010 std::vector<Declaration*> results;
1011 if (std::optional<std::string>
condition =
1014 return ParseResult{std::move(results)};
1017 results.push_back(
result);
1018 return ParseResult{std::move(results)};
1021InstanceTypeConstraints MakeInstanceTypeConstraints(
1023 InstanceTypeConstraints
result;
1026 result.num_flags_bits = GetAnnotationValue(
1031std::optional<ParseResult> MakeClassBody(ParseResultIterator* child_results) {
1032 auto methods = child_results->NextAs<std::vector<Declaration*>>();
1033 auto fields = child_results->NextAs<std::vector<ClassFieldExpression>>();
1034 std::optional<ClassBody*>
result =
1036 return ParseResult(
result);
1039std::optional<ParseResult> MakeClassDeclaration(
1040 ParseResultIterator* child_results) {
1061 bool do_not_generate_cpp_class =
1065 "@customCppClass is deprecated. Use 'extern' instead. "
1066 "@generateBodyDescriptor, @generateUniqueMap, and "
1067 "@generateFactoryFunction accomplish most of what '@export "
1068 "@customCppClass' used to.");
1072 "@customMap is deprecated. Generating a unique map is opt-in now using "
1073 "@generateUniqueMap.");
1103 auto is_extern = child_results->NextAs<
bool>();
1105 auto transient = child_results->NextAs<
bool>();
1107 std::string
kind = child_results->NextAs<Identifier*>()->value;
1108 if (
kind ==
"shape") {
1116 auto name = child_results->NextAs<Identifier*>();
1118 NamingConventionError(
"Type", name,
"UpperCamelCase");
1120 auto extends = child_results->NextAs<TypeExpression*>();
1121 if (!BasicTypeExpression::DynamicCast(extends)) {
1122 ReportError(
"Expected type name in extends clause.");
1124 auto generates = child_results->NextAs<std::optional<std::string>>();
1125 auto body = child_results->NextAs<std::optional<ClassBody*>>();
1126 std::vector<Declaration*> methods;
1127 std::vector<ClassFieldExpression> fields_raw;
1128 if (body.has_value()) {
1129 methods = (*body)->methods;
1130 fields_raw = (*body)->fields;
1135 if (is_extern && body.has_value()) {
1136 if (!do_not_generate_cpp_class) {
1139 }
else if (do_not_generate_cpp_class) {
1140 Lint(
"Annotation @doNotGenerateCppClass has no effect");
1144 std::vector<ClassFieldExpression> fields;
1146 fields_raw.begin(), fields_raw.end(), std::back_inserter(fields),
1147 [](
const ClassFieldExpression& exp) {
1148 for (const ConditionalAnnotation& condition : exp.conditions) {
1149 if (condition.type == ConditionalAnnotationType::kPositive
1150 ? !BuildFlags::GetFlag(condition.condition, ANNOTATION_IF)
1151 : BuildFlags::GetFlag(condition.condition,
1152 ANNOTATION_IFNOT)) {
1159 std::vector<Declaration*>
result;
1162 name, flags, extends, generates, std::move(methods), std::move(fields),
1165 Identifier* constexpr_name =
1167 constexpr_name->pos = name->pos;
1168 TypeExpression* constexpr_extends = AddConstexpr(extends);
1172 constexpr_name, abstract_type_flags, constexpr_extends,
1174 constexpr_decl->pos = name->pos;
1175 result.push_back(constexpr_decl);
1179 ParameterList parameters;
1183 std::vector<TypeExpression*>{}));
1186 std::vector<TypeExpression*>{}});
1189 std::vector<std::string>{},
name, std::vector<TypeExpression*>{});
1191 std::vector<std::string> namespace_qualification{
1194 IdentifierExpression* internal_downcast_target =
1196 std::move(namespace_qualification),
1198 std::vector<TypeExpression*>{class_type});
1199 IdentifierExpression* internal_downcast_otherwise =
1206 auto value = MakeCall(internal_downcast_target, std::nullopt,
1207 std::vector<Expression*>{argument},
1209 internal_downcast_otherwise)});
1213 std::vector<TypeExpression*> generic_parameters;
1215 std::vector<std::string>{},
name, std::vector<TypeExpression*>{}));
1219 std::move(parameters), class_type, std::move(labels), cast_body);
1220 result.push_back(specialization);
1223 return ParseResult{std::move(
result)};
1226std::optional<ParseResult> MakeNamespaceDeclaration(
1227 ParseResultIterator* child_results) {
1228 auto name = child_results->NextAs<std::string>();
1230 NamingConventionError(
"Namespace", name,
"snake_case");
1232 auto declarations = child_results->NextAs<std::vector<Declaration*>>();
1234 MakeNode<NamespaceDeclaration>(std::move(name), std::move(declarations));
1235 return ParseResult{
result};
1238std::optional<ParseResult> MakeSpecializationDeclaration(
1239 ParseResultIterator* child_results) {
1240 bool enabled = ProcessIfAnnotation(child_results);
1241 auto transitioning = child_results->NextAs<
bool>();
1242 auto name = child_results->NextAs<Identifier*>();
1243 auto generic_parameters =
1244 child_results->NextAs<std::vector<TypeExpression*>>();
1245 auto parameters = child_results->NextAs<ParameterList>();
1246 auto return_type = child_results->NextAs<TypeExpression*>();
1248 auto body = child_results->NextAs<Statement*>();
1249 CheckNotDeferredStatement(body);
1250 std::vector<Declaration*>
result = {};
1252 result = {MakeNode<SpecializationDeclaration>(
1253 transitioning, std::move(name), std::move(generic_parameters),
1254 std::move(parameters), return_type, std::move(labels), body)};
1256 return ParseResult{std::move(
result)};
1259std::optional<ParseResult> MakeStructDeclaration(
1260 ParseResultIterator* child_results) {
1261 bool is_export = HasExportAnnotation(child_results,
"Struct");
1264 if (is_export) flags |= StructFlag::kExport;
1266 auto name = child_results->NextAs<Identifier*>();
1268 NamingConventionError(
"Struct", name,
"UpperCamelCase");
1271 LintGenericParameters(generic_parameters);
1272 auto methods = child_results->NextAs<std::vector<Declaration*>>();
1273 auto fields = child_results->NextAs<std::vector<StructFieldExpression>>();
1274 TypeDeclaration* struct_decl = MakeNode<StructDeclaration>(
1275 flags, name, std::move(methods), std::move(fields));
1276 Declaration*
result = struct_decl;
1277 if (!generic_parameters.empty()) {
1278 result = MakeNode<GenericTypeDeclaration>(std::move(generic_parameters),
1281 return ParseResult{
result};
1284std::optional<ParseResult> MakeBitFieldStructDeclaration(
1285 ParseResultIterator* child_results) {
1286 auto name = child_results->NextAs<Identifier*>();
1288 NamingConventionError(
"Bitfield struct", name,
"UpperCamelCase");
1290 auto extends = child_results->NextAs<TypeExpression*>();
1291 auto fields = child_results->NextAs<std::vector<BitFieldDeclaration>>();
1293 MakeNode<BitFieldStructDeclaration>(name, extends, std::move(fields));
1294 return ParseResult{decl};
1297std::optional<ParseResult> MakeCppIncludeDeclaration(
1298 ParseResultIterator* child_results) {
1299 auto include_path = child_results->NextAs<std::string>();
1301 MakeNode<CppIncludeDeclaration>(std::move(include_path));
1302 return ParseResult{
result};
1305std::optional<ParseResult> ProcessTorqueImportDeclaration(
1306 ParseResultIterator* child_results) {
1307 auto import_path = child_results->NextAs<std::string>();
1308 if (!SourceFileMap::FileRelativeToV8RootExists(import_path)) {
1309 Error(
"File '", import_path,
"' not found.");
1312 auto import_id = SourceFileMap::GetSourceId(import_path);
1313 if (!import_id.IsValid()) {
1316 Error(
"File '", import_path,
"'is not part of the source set.").Throw();
1319 CurrentAst::Get().DeclareImportForCurrentFile(import_id);
1321 return std::nullopt;
1324std::optional<ParseResult> MakeExternalBuiltin(
1325 ParseResultIterator* child_results) {
1326 auto transitioning = child_results->NextAs<
bool>();
1327 auto js_linkage = child_results->NextAs<
bool>();
1328 auto name = child_results->NextAs<Identifier*>();
1330 LintGenericParameters(generic_parameters);
1332 auto args = child_results->NextAs<ParameterList>();
1333 auto return_type = child_results->NextAs<TypeExpression*>();
1334 Declaration*
result = MakeNode<ExternalBuiltinDeclaration>(
1335 transitioning, js_linkage, name,
args, return_type);
1336 if (!generic_parameters.empty()) {
1337 Error(
"External builtins cannot be generic.");
1339 return ParseResult{
result};
1342std::optional<ParseResult> MakeExternalRuntime(
1343 ParseResultIterator* child_results) {
1344 auto transitioning = child_results->NextAs<
bool>();
1345 auto name = child_results->NextAs<Identifier*>();
1346 auto args = child_results->NextAs<ParameterList>();
1347 auto return_type = child_results->NextAs<TypeExpression*>();
1348 Declaration*
result = MakeNode<ExternalRuntimeDeclaration>(
1349 transitioning, name,
args, return_type);
1350 return ParseResult{
result};
1353std::optional<ParseResult> StringLiteralUnquoteAction(
1354 ParseResultIterator* child_results) {
1360 ParseResultIterator* child_results) {
1361 auto namespace_qualification =
1362 child_results->NextAs<std::vector<std::string>>();
1363 auto is_constexpr = child_results->NextAs<
bool>();
1364 auto name = child_results->NextAs<std::string>();
1365 auto generic_arguments =
1366 child_results->NextAs<std::vector<TypeExpression*>>();
1367 TypeExpression*
result = MakeNode<BasicTypeExpression>(
1368 std::move(namespace_qualification),
1371 std::move(generic_arguments));
1372 return ParseResult{
result};
1375std::optional<ParseResult> MakeFunctionTypeExpression(
1376 ParseResultIterator* child_results) {
1377 auto parameters = child_results->NextAs<std::vector<TypeExpression*>>();
1378 auto return_type = child_results->NextAs<TypeExpression*>();
1380 MakeNode<FunctionTypeExpression>(std::move(parameters), return_type);
1381 return ParseResult{
result};
1384std::optional<ParseResult> MakeReferenceTypeExpression(
1385 ParseResultIterator* child_results) {
1386 auto is_const = child_results->NextAs<
bool>();
1387 auto referenced_type = child_results->NextAs<TypeExpression*>();
1388 std::vector<std::string> namespace_qualification{
1389 TORQUE_INTERNAL_NAMESPACE_STRING};
1390 std::vector<TypeExpression*> generic_arguments{referenced_type};
1391 TypeExpression*
result = MakeNode<BasicTypeExpression>(
1392 std::move(namespace_qualification),
1393 MakeNode<Identifier>(is_const ? CONST_REFERENCE_TYPE_STRING
1394 : MUTABLE_REFERENCE_TYPE_STRING),
1395 std::move(generic_arguments));
1396 return ParseResult{
result};
1399std::optional<ParseResult> MakeUnionTypeExpression(
1400 ParseResultIterator* child_results) {
1401 auto a = child_results->NextAs<TypeExpression*>();
1402 auto b = child_results->NextAs<TypeExpression*>();
1403 TypeExpression*
result = MakeNode<UnionTypeExpression>(a, b);
1404 return ParseResult{
result};
1407std::optional<ParseResult> MakeGenericParameter(
1408 ParseResultIterator* child_results) {
1409 auto name = child_results->NextAs<Identifier*>();
1410 auto constraint = child_results->NextAs<std::optional<TypeExpression*>>();
1411 return ParseResult{GenericParameter{
name, constraint}};
1414std::optional<ParseResult> MakeExpressionStatement(
1415 ParseResultIterator* child_results) {
1416 auto expression = child_results->NextAs<Expression*>();
1417 Statement*
result = MakeNode<ExpressionStatement>(expression);
1418 return ParseResult{
result};
1421std::optional<ParseResult> MakeIfStatement(ParseResultIterator* child_results) {
1422 auto is_constexpr = child_results->NextAs<
bool>();
1423 auto condition = child_results->NextAs<Expression*>();
1424 auto if_true = child_results->NextAs<Statement*>();
1425 auto if_false = child_results->NextAs<std::optional<Statement*>>();
1427 if (if_false && !(BlockStatement::DynamicCast(if_true) &&
1428 (BlockStatement::DynamicCast(*if_false) ||
1429 IfStatement::DynamicCast(*if_false)))) {
1430 ReportError(
"if-else statements require curly braces");
1434 CheckNotDeferredStatement(if_true);
1435 if (if_false) CheckNotDeferredStatement(*if_false);
1439 MakeNode<IfStatement>(is_constexpr,
condition, if_true, if_false);
1440 return ParseResult{
result};
1443std::optional<ParseResult> MakeEnumDeclaration(
1444 ParseResultIterator* child_results) {
1445 const bool is_extern = child_results->NextAs<
bool>();
1446 auto name_identifier = child_results->NextAs<Identifier*>();
1447 auto name = name_identifier->value;
1448 auto base_type_expression =
1449 child_results->NextAs<std::optional<TypeExpression*>>();
1450 auto constexpr_generates_opt =
1451 child_results->NextAs<std::optional<std::string>>();
1452 auto entries = child_results->NextAs<std::vector<EnumEntry>>();
1453 const bool is_open = child_results->NextAs<
bool>();
1454 CurrentSourcePosition::Scope current_source_position(
1455 child_results->matched_input().pos);
1458 ReportError(
"non-extern enums are not supported yet");
1462 NamingConventionError(
"Type", name,
"UpperCamelCase");
1465 if (constexpr_generates_opt && *constexpr_generates_opt == name) {
1466 Lint(
"Unnecessary 'constexpr' clause for enum ", name);
1468 auto constexpr_generates =
1469 constexpr_generates_opt ? *constexpr_generates_opt :
name;
1470 const bool generate_nonconstexpr = base_type_expression.has_value();
1472 std::vector<Declaration*>
result;
1474 if (generate_nonconstexpr) {
1475 DCHECK(base_type_expression.has_value());
1486 auto type_decl = MakeNode<AbstractTypeDeclaration>(
1487 name_identifier, AbstractTypeFlag::kNone, base_type_expression,
1490 TypeExpression* name_type_expression =
1491 MakeNode<BasicTypeExpression>(name_identifier);
1492 name_type_expression->pos = name_identifier->pos;
1494 std::vector<Declaration*> entry_decls;
1495 entry_decls.reserve(
entries.size());
1496 for (
const auto& entry :
entries) {
1497 entry_decls.push_back(MakeNode<AbstractTypeDeclaration>(
1498 entry.name, AbstractTypeFlag::kNone,
1499 entry.type.value_or(name_type_expression), std::nullopt));
1502 result.push_back(type_decl);
1504 MakeNode<NamespaceDeclaration>(name, std::move(entry_decls)));
1514 TypeExpression* union_type =
nullptr;
1515 std::vector<Declaration*> entry_decls;
1516 for (
const auto& entry :
entries) {
1517 entry_decls.push_back(MakeNode<AbstractTypeDeclaration>(
1518 entry.name, AbstractTypeFlag::kNone,
1519 entry.type.value_or(*base_type_expression), std::nullopt));
1521 auto entry_type = MakeNode<BasicTypeExpression>(
1522 std::vector<std::string>{name}, entry.name,
1523 std::vector<TypeExpression*>{});
1525 union_type = MakeNode<UnionTypeExpression>(union_type, entry_type);
1527 union_type = entry_type;
1532 MakeNode<NamespaceDeclaration>(name, std::move(entry_decls)));
1534 MakeNode<TypeAliasDeclaration>(name_identifier, union_type));
1547 Identifier* constexpr_type_identifier =
1548 MakeNode<Identifier>(std::string(CONSTEXPR_TYPE_PREFIX) + name);
1549 TypeExpression* constexpr_type_expression = MakeNode<BasicTypeExpression>(
1550 MakeNode<Identifier>(std::string(CONSTEXPR_TYPE_PREFIX) + name));
1551 std::optional<TypeExpression*> base_constexpr_type_expression =
1553 if (base_type_expression) {
1554 base_constexpr_type_expression = AddConstexpr(*base_type_expression);
1556 result.push_back(MakeNode<AbstractTypeDeclaration>(
1557 constexpr_type_identifier, AbstractTypeFlag::kConstexpr,
1558 base_constexpr_type_expression, constexpr_generates));
1560 TypeExpression* type_expr =
nullptr;
1561 Identifier* fromconstexpr_identifier =
nullptr;
1562 Identifier* fromconstexpr_parameter_identifier =
nullptr;
1563 Statement* fromconstexpr_body =
nullptr;
1564 if (generate_nonconstexpr) {
1565 DCHECK(base_type_expression.has_value());
1566 type_expr = MakeNode<BasicTypeExpression>(std::vector<std::string>{},
1567 MakeNode<Identifier>(name),
1568 std::vector<TypeExpression*>{});
1571 fromconstexpr_identifier = MakeNode<Identifier>(
"FromConstexpr");
1572 fromconstexpr_parameter_identifier = MakeNode<Identifier>(
"o");
1573 fromconstexpr_body =
1574 MakeNode<ReturnStatement>(MakeNode<IntrinsicCallExpression>(
1575 MakeNode<Identifier>(
"%RawDownCast"),
1576 std::vector<TypeExpression*>{type_expr},
1577 std::vector<Expression*>{MakeNode<IntrinsicCallExpression>(
1578 MakeNode<Identifier>(
"%FromConstexpr"),
1579 std::vector<TypeExpression*>{*base_type_expression},
1580 std::vector<Expression*>{MakeNode<IdentifierExpression>(
1581 std::vector<std::string>{},
1582 fromconstexpr_parameter_identifier)})}));
1585 EnumDescription enum_description{CurrentSourcePosition::Get(),
name,
1586 constexpr_generates, is_open};
1587 std::vector<Declaration*> entry_decls;
1588 for (
const auto& entry :
entries) {
1589 const std::string entry_name = entry.name->value;
1590 const std::string entry_constexpr_type =
1591 CONSTEXPR_TYPE_PREFIX + entry_name;
1592 std::string alias_entry;
1593 if (entry.alias_entry) {
1594 alias_entry = constexpr_generates +
"::" + *entry.alias_entry;
1596 enum_description.entries.emplace_back(
1597 constexpr_generates +
"::" + entry_name, alias_entry);
1599 entry_decls.push_back(MakeNode<AbstractTypeDeclaration>(
1600 MakeNode<Identifier>(entry_constexpr_type),
1601 AbstractTypeFlag::kConstexpr, constexpr_type_expression,
1602 constexpr_generates));
1604 bool generate_typed_constant = entry.type.has_value();
1605 if (generate_typed_constant) {
1611 if (!generate_nonconstexpr) {
1613 "Enum constants with custom types require an enum with an "
1615 .Position((*entry.type)->pos);
1617 Identifier* constexpr_constant_name =
1618 MakeNode<Identifier>(
"constexpr constant " + entry_name);
1619 entry_decls.push_back(MakeNode<ExternConstDeclaration>(
1620 constexpr_constant_name,
1621 MakeNode<BasicTypeExpression>(
1622 std::vector<std::string>{},
1623 MakeNode<Identifier>(entry_constexpr_type),
1624 std::vector<TypeExpression*>{}),
1625 constexpr_generates +
"::" + entry_name));
1626 entry_decls.push_back(MakeNode<ConstDeclaration>(
1627 entry.name, *entry.type,
1628 MakeNode<IntrinsicCallExpression>(
1629 MakeNode<Identifier>(
"%RawDownCast"),
1630 std::vector<TypeExpression*>{*entry.type,
1631 *base_type_expression},
1632 std::vector<Expression*>{MakeCall(
1633 MakeNode<Identifier>(
"FromConstexpr"), {type_expr},
1634 {MakeNode<IdentifierExpression>(std::vector<std::string>{},
1635 constexpr_constant_name)},
1641 entry_decls.push_back(MakeNode<ExternConstDeclaration>(
1643 MakeNode<BasicTypeExpression>(
1644 std::vector<std::string>{},
1645 MakeNode<Identifier>(entry_constexpr_type),
1646 std::vector<TypeExpression*>{}),
1647 constexpr_generates +
"::" + entry_name));
1652 if (generate_nonconstexpr) {
1653 TypeExpression* entry_constexpr_type_expr =
1654 MakeNode<BasicTypeExpression>(
1655 std::vector<std::string>{name},
1656 MakeNode<Identifier>(entry_constexpr_type),
1657 std::vector<TypeExpression*>{});
1659 ParameterList parameters;
1660 parameters.names.push_back(fromconstexpr_parameter_identifier);
1661 parameters.types.push_back(entry_constexpr_type_expr);
1662 result.push_back(MakeNode<SpecializationDeclaration>(
1663 false, fromconstexpr_identifier,
1664 std::vector<TypeExpression*>{type_expr, entry_constexpr_type_expr},
1666 fromconstexpr_body));
1671 MakeNode<NamespaceDeclaration>(name, std::move(entry_decls)));
1672 CurrentAst::Get().AddEnumDescription(std::move(enum_description));
1675 return ParseResult{std::move(
result)};
1678std::optional<ParseResult> MakeTypeswitchStatement(
1679 ParseResultIterator* child_results) {
1680 auto expression = child_results->NextAs<Expression*>();
1681 auto cases = child_results->NextAs<std::vector<TypeswitchCase>>();
1682 CurrentSourcePosition::Scope matched_input_current_source_position(
1683 child_results->matched_input().pos);
1711 BlockStatement* current_block = MakeNode<BlockStatement>();
1712 Statement*
result = current_block;
1714 CurrentSourcePosition::Scope current_source_position(expression->pos);
1715 current_block->statements.push_back(MakeNode<VarDeclarationStatement>(
1716 true, MakeNode<Identifier>(
"__value"), std::nullopt, expression));
1719 TypeExpression* accumulated_types;
1720 for (
size_t i = 0;
i < cases.
size(); ++
i) {
1721 CurrentSourcePosition::Scope current_source_position(cases[
i].
pos);
1723 MakeNode<IdentifierExpression>(MakeNode<Identifier>(
"__value"));
1726 MakeNode<AssumeTypeImpossibleExpression>(accumulated_types, value);
1728 BlockStatement* case_block;
1729 if (
i < cases.
size() - 1) {
1730 value = MakeCall(MakeNode<Identifier>(
"Cast"),
1731 std::vector<TypeExpression*>{cases[
i].type},
1732 std::vector<Expression*>{value},
1733 std::vector<Statement*>{MakeNode<ExpressionStatement>(
1734 MakeNode<IdentifierExpression>(
1735 MakeNode<Identifier>(kNextCaseLabelName)))});
1736 case_block = MakeNode<BlockStatement>();
1738 case_block = current_block;
1741 cases[
i].name ? *cases[
i].name : MakeNode<Identifier>(
"__case_value");
1742 if (cases[
i].name) name = *cases[
i].name;
1743 case_block->statements.push_back(
1744 MakeNode<VarDeclarationStatement>(
true, name, cases[
i].type, value));
1745 case_block->statements.push_back(cases[
i].block);
1746 if (
i < cases.
size() - 1) {
1747 BlockStatement* next_block = MakeNode<BlockStatement>();
1748 current_block->statements.push_back(
1749 MakeNode<ExpressionStatement>(MakeNode<TryLabelExpression>(
1750 MakeNode<StatementExpression>(case_block),
1751 MakeNode<TryHandler>(TryHandler::HandlerKind::kLabel,
1752 MakeNode<Identifier>(kNextCaseLabelName),
1753 ParameterList::Empty(), next_block))));
1754 current_block = next_block;
1757 i > 0 ? MakeNode<UnionTypeExpression>(accumulated_types, cases[
i].type)
1760 return ParseResult{
result};
1763std::optional<ParseResult> MakeTypeswitchCase(
1764 ParseResultIterator* child_results) {
1765 auto name = child_results->NextAs<std::optional<Identifier*>>();
1766 auto type = child_results->NextAs<TypeExpression*>();
1767 auto block = child_results->NextAs<Statement*>();
1769 TypeswitchCase{child_results->matched_input().pos,
name,
type, block}};
1772std::optional<ParseResult> MakeWhileStatement(
1773 ParseResultIterator* child_results) {
1774 auto condition = child_results->NextAs<Expression*>();
1775 auto body = child_results->NextAs<Statement*>();
1777 CheckNotDeferredStatement(
result);
1778 return ParseResult{
result};
1781std::optional<ParseResult> MakeReturnStatement(
1782 ParseResultIterator* child_results) {
1783 auto value = child_results->NextAs<std::optional<Expression*>>();
1784 Statement*
result = MakeNode<ReturnStatement>(value);
1785 return ParseResult{
result};
1788std::optional<ParseResult> MakeTailCallStatement(
1789 ParseResultIterator* child_results) {
1790 auto value = child_results->NextAs<Expression*>();
1791 Statement*
result = MakeNode<TailCallStatement>(CallExpression::cast(value));
1792 return ParseResult{
result};
1795std::optional<ParseResult> MakeVarDeclarationStatement(
1796 ParseResultIterator* child_results) {
1797 auto kind = child_results->NextAs<Identifier*>();
1798 bool const_qualified =
kind->value ==
"const";
1800 auto name = child_results->NextAs<Identifier*>();
1802 NamingConventionError(
"Variable", name,
"lowerCamelCase");
1805 auto type = child_results->NextAs<std::optional<TypeExpression*>>();
1806 std::optional<Expression*> initializer;
1807 if (child_results->HasNext())
1808 initializer = child_results->NextAs<Expression*>();
1809 if (!initializer && !type) {
1812 Statement*
result = MakeNode<VarDeclarationStatement>(const_qualified, name,
1814 return ParseResult{
result};
1817std::optional<ParseResult> MakeBreakStatement(
1818 ParseResultIterator* child_results) {
1819 Statement*
result = MakeNode<BreakStatement>();
1820 return ParseResult{
result};
1823std::optional<ParseResult> MakeContinueStatement(
1824 ParseResultIterator* child_results) {
1825 Statement*
result = MakeNode<ContinueStatement>();
1826 return ParseResult{
result};
1829std::optional<ParseResult> MakeGotoStatement(
1830 ParseResultIterator* child_results) {
1831 auto label = child_results->NextAs<Identifier*>();
1832 auto arguments = child_results->NextAs<std::vector<Expression*>>();
1833 Statement*
result = MakeNode<GotoStatement>(
label, std::move(arguments));
1834 return ParseResult{
result};
1837std::optional<ParseResult> MakeBlockStatement(
1838 ParseResultIterator* child_results) {
1839 auto deferred = child_results->NextAs<
bool>();
1840 auto statements = child_results->NextAs<std::vector<Statement*>>();
1841 for (Statement*
statement : statements) {
1844 Statement*
result = MakeNode<BlockStatement>(deferred, std::move(statements));
1845 return ParseResult{
result};
1848std::optional<ParseResult> MakeTryLabelExpression(
1849 ParseResultIterator* child_results) {
1850 auto try_block = child_results->NextAs<Statement*>();
1851 CheckNotDeferredStatement(try_block);
1852 Statement*
result = try_block;
1853 auto handlers = child_results->NextAs<std::vector<TryHandler*>>();
1854 if (handlers.empty()) {
1855 Error(
"Try blocks without catch or label don't make sense.");
1857 for (
size_t i = 0;
i < handlers.
size(); ++
i) {
1859 handlers[
i]->handler_kind == TryHandler::HandlerKind::kCatch) {
1861 "A catch handler always has to be first, before any label handler, "
1862 "to avoid ambiguity about whether it catches exceptions from "
1863 "preceding handlers or not.")
1864 .Position(handlers[
i]->
pos);
1866 result = MakeNode<ExpressionStatement>(MakeNode<TryLabelExpression>(
1867 MakeNode<StatementExpression>(
result), handlers[
i]));
1869 return ParseResult{
result};
1872std::optional<ParseResult> MakeForLoopStatement(
1873 ParseResultIterator* child_results) {
1874 auto var_decl = child_results->NextAs<std::optional<Statement*>>();
1875 auto test = child_results->NextAs<std::optional<Expression*>>();
1876 auto action = child_results->NextAs<std::optional<Expression*>>();
1877 std::optional<Statement*> action_stmt;
1878 if (action) action_stmt = MakeNode<ExpressionStatement>(*action);
1879 auto body = child_results->NextAs<Statement*>();
1880 CheckNotDeferredStatement(body);
1882 MakeNode<ForLoopStatement>(var_decl, test, action_stmt, body);
1883 return ParseResult{
result};
1886std::optional<ParseResult> MakeLabelBlock(ParseResultIterator* child_results) {
1887 auto label = child_results->NextAs<Identifier*>();
1889 NamingConventionError(
"Label",
label,
"UpperCamelCase");
1891 auto parameters = child_results->NextAs<ParameterList>();
1892 auto body = child_results->NextAs<Statement*>();
1893 TryHandler*
result = MakeNode<TryHandler>(TryHandler::HandlerKind::kLabel,
1894 label, std::move(parameters), body);
1895 return ParseResult{
result};
1898std::optional<ParseResult> MakeCatchBlock(ParseResultIterator* child_results) {
1899 auto parameter_names = child_results->NextAs<std::vector<std::string>>();
1900 auto body = child_results->NextAs<Statement*>();
1901 for (
const std::string& variable : parameter_names) {
1903 NamingConventionError(
"Exception", variable,
"lowerCamelCase");
1906 if (parameter_names.size() != 2) {
1908 "A catch clause needs to have exactly two parameters: The exception "
1909 "and the message. How about: \"catch (exception, message) { ...\".");
1911 ParameterList parameters;
1913 parameters.names.push_back(MakeNode<Identifier>(parameter_names[0]));
1914 parameters.types.push_back(MakeNode<BasicTypeExpression>(
1915 std::vector<std::string>{}, MakeNode<Identifier>(
"JSAny"),
1916 std::vector<TypeExpression*>{}));
1917 parameters.names.push_back(MakeNode<Identifier>(parameter_names[1]));
1918 parameters.types.push_back(MakeNode<UnionTypeExpression>(
1919 MakeNode<BasicTypeExpression>(std::vector<std::string>{},
1920 MakeNode<Identifier>(
"JSMessageObject"),
1921 std::vector<TypeExpression*>{}),
1922 MakeNode<BasicTypeExpression>(std::vector<std::string>{},
1923 MakeNode<Identifier>(
"TheHole"),
1924 std::vector<TypeExpression*>{})));
1925 parameters.has_varargs =
false;
1926 TryHandler*
result = MakeNode<TryHandler>(
1927 TryHandler::HandlerKind::kCatch, MakeNode<Identifier>(kCatchLabelName),
1928 std::move(parameters), body);
1929 return ParseResult{
result};
1932std::optional<ParseResult> MakeExpressionWithSource(
1933 ParseResultIterator* child_results) {
1934 auto e = child_results->NextAs<Expression*>();
1936 ExpressionWithSource{e, child_results->matched_input().ToString()}};
1939std::optional<ParseResult> MakeIdentifier(ParseResultIterator* child_results) {
1940 auto name = child_results->NextAs<std::string>();
1941 Identifier*
result = MakeNode<Identifier>(std::move(name));
1942 return ParseResult{
result};
1945std::optional<ParseResult> MakeIdentifierFromMatchedInput(
1946 ParseResultIterator* child_results) {
1948 MakeNode<Identifier>(child_results->matched_input().ToString())};
1951std::optional<ParseResult> MakeRightShiftIdentifier(
1952 ParseResultIterator* child_results) {
1953 std::string str = child_results->matched_input().ToString();
1954 for (
auto character : str) {
1955 if (character !=
'>') {
1956 ReportError(
"right-shift operators may not contain any whitespace");
1959 return ParseResult{MakeNode<Identifier>(str)};
1962std::optional<ParseResult> MakeNamespaceQualification(
1963 ParseResultIterator* child_results) {
1964 bool global_namespace = child_results->NextAs<
bool>();
1965 auto namespace_qualification =
1966 child_results->NextAs<std::vector<std::string>>();
1967 if (global_namespace) {
1968 namespace_qualification.insert(namespace_qualification.begin(),
"");
1970 return ParseResult(std::move(namespace_qualification));
1974 ParseResultIterator* child_results) {
1975 auto namespace_qualification =
1976 child_results->NextAs<std::vector<std::string>>();
1977 auto name = child_results->NextAs<Identifier*>();
1978 auto generic_arguments =
1979 child_results->NextAs<std::vector<TypeExpression*>>();
1980 Expression*
result = MakeNode<IdentifierExpression>(
1981 std::move(namespace_qualification), name, std::move(generic_arguments));
1982 return ParseResult{
result};
1986 ParseResultIterator* child_results) {
1987 auto object = child_results->NextAs<Expression*>();
1988 auto field = child_results->NextAs<Identifier*>();
1989 Expression*
result = MakeNode<FieldAccessExpression>(
object, field);
1990 return ParseResult{
result};
1993std::optional<ParseResult> MakeReferenceFieldAccessExpression(
1994 ParseResultIterator* child_results) {
1995 auto object = child_results->NextAs<Expression*>();
1996 auto field = child_results->NextAs<Identifier*>();
1998 Expression* deref = MakeNode<DereferenceExpression>(
object);
1999 Expression*
result = MakeNode<FieldAccessExpression>(deref, field);
2000 return ParseResult{
result};
2003std::optional<ParseResult> MakeElementAccessExpression(
2004 ParseResultIterator* child_results) {
2005 auto object = child_results->NextAs<Expression*>();
2006 auto field = child_results->NextAs<Expression*>();
2007 Expression*
result = MakeNode<ElementAccessExpression>(
object, field);
2008 return ParseResult{
result};
2011std::optional<ParseResult> MakeDereferenceExpression(
2012 ParseResultIterator* child_results) {
2013 auto reference = child_results->NextAs<Expression*>();
2014 Expression*
result = MakeNode<DereferenceExpression>(reference);
2015 return ParseResult{
result};
2019 ParseResultIterator* child_results) {
2020 auto type = child_results->NextAs<TypeExpression*>();
2021 auto initializers = child_results->NextAs<std::vector<NameAndExpression>>();
2023 MakeNode<StructExpression>(type, std::move(initializers));
2024 return ParseResult{
result};
2027std::optional<ParseResult> MakeAssignmentExpression(
2028 ParseResultIterator* child_results) {
2029 auto location = child_results->NextAs<Expression*>();
2030 auto op = child_results->NextAs<std::optional<std::string>>();
2031 auto value = child_results->NextAs<Expression*>();
2033 MakeNode<AssignmentExpression>(location, std::move(op), value);
2034 return ParseResult{
result};
2037std::optional<ParseResult> MakeFloatingPointLiteralExpression(
2038 ParseResultIterator* child_results) {
2039 auto value = child_results->NextAs<
double>();
2040 Expression*
result = MakeNode<FloatingPointLiteralExpression>(value);
2041 return ParseResult{
result};
2044std::optional<ParseResult> MakeIntegerLiteralExpression(
2045 ParseResultIterator* child_results) {
2046 auto value = child_results->NextAs<IntegerLiteral>();
2047 Expression*
result = MakeNode<IntegerLiteralExpression>(std::move(value));
2048 return ParseResult{
result};
2051std::optional<ParseResult> MakeStringLiteralExpression(
2052 ParseResultIterator* child_results) {
2053 auto literal = child_results->NextAs<std::string>();
2054 Expression*
result = MakeNode<StringLiteralExpression>(std::move(
literal));
2055 return ParseResult{
result};
2058std::optional<ParseResult> MakeIncrementDecrementExpressionPostfix(
2059 ParseResultIterator* child_results) {
2060 auto location = child_results->NextAs<Expression*>();
2063 MakeNode<IncrementDecrementExpression>(location, op,
true);
2064 return ParseResult{
result};
2067std::optional<ParseResult> MakeIncrementDecrementExpressionPrefix(
2068 ParseResultIterator* child_results) {
2070 auto location = child_results->NextAs<Expression*>();
2072 MakeNode<IncrementDecrementExpression>(location, op,
false);
2073 return ParseResult{
result};
2076std::optional<ParseResult> MakeLogicalOrExpression(
2077 ParseResultIterator* child_results) {
2078 auto left = child_results->NextAs<Expression*>();
2079 auto right = child_results->NextAs<Expression*>();
2080 Expression*
result = MakeNode<LogicalOrExpression>(left, right);
2081 return ParseResult{
result};
2084std::optional<ParseResult> MakeLogicalAndExpression(
2085 ParseResultIterator* child_results) {
2086 auto left = child_results->NextAs<Expression*>();
2087 auto right = child_results->NextAs<Expression*>();
2088 Expression*
result = MakeNode<LogicalAndExpression>(left, right);
2089 return ParseResult{
result};
2092std::optional<ParseResult> MakeConditionalExpression(
2093 ParseResultIterator* child_results) {
2094 auto condition = child_results->NextAs<Expression*>();
2095 auto if_true = child_results->NextAs<Expression*>();
2096 auto if_false = child_results->NextAs<Expression*>();
2098 MakeNode<ConditionalExpression>(
condition, if_true, if_false);
2099 return ParseResult{
result};
2102std::optional<ParseResult> MakeLabelAndTypes(
2103 ParseResultIterator* child_results) {
2104 auto name = child_results->NextAs<Identifier*>();
2106 NamingConventionError(
"Label", name,
"UpperCamelCase");
2108 auto types = child_results->NextAs<std::vector<TypeExpression*>>();
2109 return ParseResult{LabelAndTypes{
name, std::move(types)}};
2112std::optional<ParseResult> MakeNameAndType(ParseResultIterator* child_results) {
2113 auto name = child_results->NextAs<Identifier*>();
2114 auto type = child_results->NextAs<TypeExpression*>();
2115 return ParseResult{NameAndTypeExpression{
name, type}};
2118std::optional<ParseResult> MakeEnumEntry(ParseResultIterator* child_results) {
2119 AnnotationSet
annotations(child_results, {}, {ANNOTATION_SAME_ENUM_VALUE_AS});
2120 std::vector<ConditionalAnnotation> conditions;
2121 std::optional<std::string> alias_entry =
2122 annotations.GetStringParam(ANNOTATION_SAME_ENUM_VALUE_AS);
2124 auto name = child_results->NextAs<Identifier*>();
2125 auto type = child_results->NextAs<std::optional<TypeExpression*>>();
2126 return ParseResult{EnumEntry{
name,
type, alias_entry}};
2129std::optional<ParseResult> MakeNameAndExpression(
2130 ParseResultIterator* child_results) {
2131 auto name = child_results->NextAs<Identifier*>();
2132 auto expression = child_results->NextAs<Expression*>();
2133 return ParseResult{NameAndExpression{
name, expression}};
2136std::optional<ParseResult> MakeNameAndExpressionFromExpression(
2137 ParseResultIterator* child_results) {
2138 auto expression = child_results->NextAs<Expression*>();
2139 if (
auto*
id = IdentifierExpression::DynamicCast(expression)) {
2140 if (!id->generic_arguments.empty() ||
2141 !id->namespace_qualification.empty()) {
2142 ReportError(
"expected a plain identifier without qualification");
2144 return ParseResult{NameAndExpression{
id->name,
id}};
2146 ReportError(
"Constructor parameters need to be named.");
2149std::optional<ParseResult> MakeAnnotation(ParseResultIterator* child_results) {
2151 Annotation{child_results->NextAs<Identifier*>(),
2152 child_results->NextAs<std::optional<AnnotationParameter>>()}};
2155std::optional<ParseResult> MakeClassField(ParseResultIterator* child_results) {
2158 {ANNOTATION_CPP_RELAXED_STORE, ANNOTATION_CPP_RELAXED_LOAD,
2159 ANNOTATION_CPP_RELEASE_STORE, ANNOTATION_CPP_ACQUIRE_LOAD,
2160 ANNOTATION_CUSTOM_WEAK_MARKING},
2161 {ANNOTATION_IF, ANNOTATION_IFNOT});
2163 if (
annotations.Contains(ANNOTATION_CPP_RELEASE_STORE)) {
2164 synchronization = FieldSynchronization::kAcquireRelease;
2165 }
else if (
annotations.Contains(ANNOTATION_CPP_RELAXED_STORE)) {
2166 synchronization = FieldSynchronization::kRelaxed;
2170 if (
annotations.Contains(ANNOTATION_CPP_ACQUIRE_LOAD)) {
2171 read_synchronization = FieldSynchronization::kAcquireRelease;
2172 }
else if (
annotations.Contains(ANNOTATION_CPP_RELAXED_LOAD)) {
2173 read_synchronization = FieldSynchronization::kRelaxed;
2175 if (read_synchronization != synchronization) {
2176 Error(
"Incompatible read/write synchronization annotations for a field.");
2179 std::vector<ConditionalAnnotation> conditions;
2180 std::optional<std::string> if_condition =
2182 std::optional<std::string> ifnot_condition =
2184 if (if_condition.has_value()) {
2185 conditions.push_back({*if_condition, ConditionalAnnotationType::kPositive});
2187 if (ifnot_condition.has_value()) {
2188 conditions.push_back(
2189 {*ifnot_condition, ConditionalAnnotationType::kNegative});
2191 bool custom_weak_marking =
2192 annotations.Contains(ANNOTATION_CUSTOM_WEAK_MARKING);
2193 auto deprecated_weak = child_results->NextAs<
bool>();
2194 if (deprecated_weak) {
2196 "The keyword 'weak' is deprecated. For a field that can contain a "
2197 "normal weak pointer, use type Weak<T>. For a field that should be "
2198 "marked in some custom way, use @customWeakMarking.");
2199 custom_weak_marking =
true;
2201 auto const_qualified = child_results->NextAs<
bool>();
2202 auto name = child_results->NextAs<Identifier*>();
2203 auto optional = child_results->NextAs<
bool>();
2204 auto index = child_results->NextAs<std::optional<Expression*>>();
2205 if (optional && !index) {
2207 "Fields using optional specifier must also provide an expression "
2208 "indicating the condition for whether the field is present");
2210 std::optional<ClassFieldIndexInfo> index_info;
2215 index = MakeNode<ConditionalExpression>(
2218 MakeNode<Identifier>(
"FromConstexpr"),
2219 {MakeNode<BasicTypeExpression>(std::vector<std::string>{},
2220 MakeNode<Identifier>(
"intptr"),
2221 std::vector<TypeExpression*>{})},
2222 {MakeNode<IntegerLiteralExpression>(IntegerLiteral(1))}, {}),
2224 MakeNode<Identifier>(
"FromConstexpr"),
2225 {MakeNode<BasicTypeExpression>(std::vector<std::string>{},
2226 MakeNode<Identifier>(
"intptr"),
2227 std::vector<TypeExpression*>{})},
2228 {MakeNode<IntegerLiteralExpression>(IntegerLiteral(0))}, {}));
2230 index_info = ClassFieldIndexInfo{*
index, optional};
2232 auto type = child_results->NextAs<TypeExpression*>();
2233 return ParseResult{ClassFieldExpression{{
name, type},
2235 std::move(conditions),
2236 custom_weak_marking,
2241std::optional<ParseResult> MakeStructField(ParseResultIterator* child_results) {
2242 auto const_qualified = child_results->NextAs<
bool>();
2243 auto name = child_results->NextAs<Identifier*>();
2244 auto type = child_results->NextAs<TypeExpression*>();
2245 return ParseResult{StructFieldExpression{{
name, type}, const_qualified}};
2248std::optional<ParseResult> MakeBitFieldDeclaration(
2249 ParseResultIterator* child_results) {
2250 auto name = child_results->NextAs<Identifier*>();
2251 auto type = child_results->NextAs<TypeExpression*>();
2253 return ParseResult{BitFieldDeclaration{{
name, type},
num_bits}};
2256std::optional<ParseResult> ExtractAssignmentOperator(
2257 ParseResultIterator* child_results) {
2258 auto op = child_results->NextAs<Identifier*>();
2259 std::optional<std::string>
result =
2260 std::string(op->value.begin(), op->value.end() - 1);
2261 return ParseResult(std::move(
result));
2264struct TorqueGrammar : Grammar {
2265 static bool MatchWhitespace(InputPosition*
pos) {
2267 if (MatchChar(std::isspace,
pos))
continue;
2268 if (MatchString(
"//",
pos)) {
2269 while (MatchChar([](
char c) {
return c !=
'\n'; },
pos)) {
2273 if (MatchString(
"/*",
pos)) {
2274 while (!MatchString(
"*/",
pos)) ++*
pos;
2281 static bool MatchIdentifier(InputPosition*
pos) {
2283 MatchString(
"_", ¤t);
2284 if (!MatchChar(std::isalpha, ¤t))
return false;
2285 while (MatchChar(std::isalnum, ¤t) || MatchString(
"_", ¤t)) {
2291 static bool MatchAnnotation(InputPosition*
pos) {
2293 if (!MatchString(
"@", ¤t))
return false;
2294 if (!MatchIdentifier(¤t))
return false;
2299 static bool MatchIntrinsicName(InputPosition*
pos) {
2301 if (!MatchString(
"%", ¤t))
return false;
2302 if (!MatchIdentifier(¤t))
return false;
2307 static bool MatchStringLiteral(InputPosition*
pos) {
2309 if (MatchString(
"\"", ¤t)) {
2311 (MatchString(
"\\", ¤t) && MatchAnyChar(¤t)) ||
2312 MatchChar([](
char c) {
return c !=
'"' && c !=
'\n'; }, &
current)) {
2314 if (MatchString(
"\"", ¤t)) {
2320 if (MatchString(
"'", ¤t)) {
2322 (MatchString(
"\\", ¤t) && MatchAnyChar(¤t)) ||
2323 MatchChar([](
char c) {
return c !=
'\'' && c !=
'\n'; }, &
current)) {
2325 if (MatchString(
"'", ¤t)) {
2333 static bool MatchHexLiteral(InputPosition*
pos) {
2335 MatchString(
"-", ¤t);
2336 if (MatchString(
"0x", ¤t) && MatchChar(std::isxdigit, ¤t)) {
2337 while (MatchChar(std::isxdigit, ¤t)) {
2345 static bool MatchIntegerLiteral(InputPosition*
pos) {
2347 bool found_digit =
false;
2348 MatchString(
"-", ¤t);
2349 while (MatchChar(std::isdigit, ¤t)) found_digit =
true;
2357 static bool MatchFloatingPointLiteral(InputPosition*
pos) {
2359 bool found_digit =
false;
2360 MatchString(
"-", ¤t);
2361 while (MatchChar(std::isdigit, ¤t)) found_digit =
true;
2362 if (!MatchString(
".", ¤t))
return false;
2363 while (MatchChar(std::isdigit, ¤t)) found_digit =
true;
2364 if (!found_digit)
return false;
2366 if ((MatchString(
"e", ¤t) || MatchString(
"E", ¤t)) &&
2367 (MatchString(
"+", ¤t) || MatchString(
"-", ¤t) ||
true) &&
2368 MatchChar(std::isdigit, ¤t)) {
2369 while (MatchChar(std::isdigit, ¤t)) {
2377 template <
class T,
bool first>
2378 static std::optional<ParseResult> MakeExtendedVectorIfAnnotation(
2379 ParseResultIterator* child_results) {
2380 std::vector<T> l = {};
2381 if (!first) l = child_results->NextAs<std::vector<T>>();
2382 bool enabled = ProcessIfAnnotation(child_results);
2383 T
x = child_results->NextAs<T>();
2385 if (enabled) l.push_back(std::move(
x));
2386 return ParseResult{std::move(l)};
2390 Symbol* NonemptyListAllowIfAnnotation(Symbol* element,
2391 std::optional<Symbol*> separator = {}) {
2392 Symbol* list = NewSymbol();
2394 Rule({
annotations, element}, MakeExtendedVectorIfAnnotation<T, true>),
2396 MakeExtendedVectorIfAnnotation<T, false>)
2398 MakeExtendedVectorIfAnnotation<T, false>)};
2403 Symbol* ListAllowIfAnnotation(Symbol* element,
2404 std::optional<Symbol*> separator = {}) {
2405 return TryOrDefault<std::vector<T>>(
2406 NonemptyListAllowIfAnnotation<T>(element, separator));
2409 TorqueGrammar() : Grammar(&file) { SetWhitespace(MatchWhitespace); }
2415 Symbol
identifier = {Rule({Pattern(MatchIdentifier)}, YieldMatchedInput),
2416 Rule({Token(
"runtime")}, YieldMatchedInput)};
2423 Rule({Pattern(MatchAnnotation)}, MakeIdentifierFromMatchedInput)};
2427 Rule({Pattern(MatchIntrinsicName)}, MakeIdentifierFromMatchedInput)};
2431 Rule({Pattern(MatchStringLiteral)}, YieldMatchedInput)};
2438 Rule({Pattern(MatchIntegerLiteral)}, YieldIntegerLiteral),
2439 Rule({Pattern(MatchHexLiteral)}, YieldIntegerLiteral)};
2443 Rule({Pattern(MatchFloatingPointLiteral)}, YieldDouble)};
2447 Rule({Pattern(MatchHexLiteral)}, YieldInt32)};
2451 Rule({&
identifier}, MakeStringAnnotationParameter),
2469 Rule({CheckIf(Token(
"::")),
2470 List<std::string>(Sequence({&
identifier, Token(
"::")}))},
2471 MakeNamespaceQualification)};
2474 Symbol*
typeList = List<TypeExpression*>(&type, Token(
","));
2478 Rule({Token(
"("), &
type, Token(
")")}),
2480 TryOrDefault<std::vector<TypeExpression*>>(
2482 MakeBasicTypeExpression),
2483 Rule({Token(
"builtin"), Token(
"("),
typeList, Token(
")"), Token(
"=>"),
2485 MakeFunctionTypeExpression),
2486 Rule({CheckIf(Token(
"const")), Token(
"&"), &
simpleType},
2487 MakeReferenceTypeExpression)};
2491 MakeUnionTypeExpression)};
2495 Rule({&
name, Token(
":"), Token(
"type"),
2496 Optional<TypeExpression*>(Sequence({Token(
"extends"), &type}))},
2497 MakeGenericParameter)};
2506 Rule({Token(
"<"),
typeList, Token(
">")})};
2512 Rule({Token(
"("), OneOf({
"implicit",
"js-implicit"}),
2513 List<NameAndTypeExpression>(&
nameAndType, Token(
",")), Token(
")")},
2514 MakeImplicitParameterList)};
2522 List<TypeExpression*>(Sequence({&
type, Token(
",")})), Token(
"..."),
2524 MakeParameterList<true, false>),
2526 MakeParameterList<false, false>)};
2531 TryOrDefault<TypeList>(Sequence({Token(
"("),
typeList, Token(
")")}))},
2532 MakeLabelAndTypes)};
2536 Rule({}, DeprecatedMakeVoidType)};
2540 Sequence({Token(
"labels"),
2545 Sequence({Token(
"otherwise"),
2553 Optional<Expression*>(Sequence({Token(
"["),
expression, Token(
"]")}));
2557 Rule({
annotations, CheckIf(Token(
"weak")), CheckIf(Token(
"const")), &
name,
2564 Rule({CheckIf(Token(
"const")), &
name, Token(
":"), &
type, Token(
";")},
2570 MakeBitFieldDeclaration)};
2575 List<NameAndTypeExpression>(&
nameAndType, Token(
",")), Token(
")")},
2576 MakeParameterList<false, true>)};
2582 List<NameAndTypeExpression>(Sequence({&
nameAndType, Token(
",")})),
2584 MakeParameterList<true, true>)};
2587 Symbol* OneOf(
const std::vector<std::string>& alternatives) {
2588 Symbol*
result = NewSymbol();
2589 for (
const std::string& s : alternatives) {
2590 result->AddRule(Rule({Token(s)}, MakeIdentifierFromMatchedInput));
2596 Symbol* BinaryOperator(Symbol* nextLevel, Symbol* op) {
2597 Symbol*
result = NewSymbol();
2598 *
result = {Rule({nextLevel}),
2599 Rule({
result, op, nextLevel}, MakeBinaryOperator)};
2606 YieldIntegralConstant<IncrementDecrementOperator,
2607 IncrementDecrementOperator::kIncrement>),
2609 YieldIntegralConstant<IncrementDecrementOperator,
2610 IncrementDecrementOperator::kDecrement>)};
2616 MakeIdentifierExpression),
2621 {Token(
"("), List<Expression*>(expression, Token(
",")), Token(
")")})};
2634 Rule({&
name, Token(
":"), expression}, MakeNameAndExpression),
2635 Rule({expression}, MakeNameAndExpressionFromExpression)};
2639 Rule({Token(
"{"), List<NameAndExpression>(&
namedExpression, Token(
",")),
2646 MakeIntrinsicCallExpression)};
2651 CheckIf(Sequence({Token(
"("), Token(
"Pretenured"), Token(
")")})),
2652 CheckIf(Sequence({Token(
"("), Token(
"ClearPadding"), Token(
")")})),
2654 MakeNewExpression)};
2664 MakeReferenceFieldAccessExpression),
2666 MakeElementAccessExpression),
2682 MakeIncrementDecrementExpressionPrefix),
2684 MakeIncrementDecrementExpressionPostfix)};
2696 Rule({Token(
"<<")}, MakeIdentifierFromMatchedInput),
2697 Rule({Token(
">"), Token(
">")}, MakeRightShiftIdentifier),
2698 Rule({Token(
">"), Token(
">"), Token(
">")}, MakeRightShiftIdentifier)};
2709 MakeBinaryOperator)};
2723 MakeLogicalAndExpression)};
2729 MakeLogicalOrExpression)};
2736 MakeConditionalExpression)};
2740 Rule({Token(
"=")}, YieldDefaultValue<std::optional<std::string>>),
2741 Rule({OneOf({
"*=",
"/=",
"%=",
"+=",
"-=",
"<<=",
">>=",
">>>=",
"&=",
2743 ExtractAssignmentOperator)};
2749 MakeAssignmentExpression)};
2753 Rule({CheckIf(Token(
"deferred")), Token(
"{"),
2754 ListAllowIfAnnotation<Statement*>(&
statement), Token(
"}")},
2755 MakeBlockStatement)};
2759 Rule({Token(
"label"), &
name,
2762 Rule({Token(
"catch"), Token(
"("),
2763 List<std::string>(&
identifier, Token(
",")), Token(
")"), &block},
2770 Optional<TypeExpression*>(Sequence({Token(
":"), &type}));
2779 MakeVarDeclarationStatement)};
2785 MakeVarDeclarationStatement)};
2789 Rule({expression}, MakeExpressionStatement),
2790 Rule({Token(
"return"), Optional<Expression*>(expression)},
2791 MakeReturnStatement),
2793 Rule({Token(
"break")}, MakeBreakStatement),
2794 Rule({Token(
"continue")}, MakeContinueStatement),
2795 Rule({Token(
"goto"), &
name,
2796 TryOrDefault<std::vector<Expression*>>(&
argumentList)},
2798 Rule({OneOf({
"debug",
"unreachable"})}, MakeDebugStatement)};
2806 Rule({Token(
"if"), CheckIf(Token(
"constexpr")), Token(
"("),
expression,
2808 Optional<Statement*>(Sequence({Token(
"else"), &
statement}))},
2812 Token(
"typeswitch"),
2820 MakeTypeswitchStatement),
2822 MakeTryLabelExpression),
2823 Rule({OneOf({
"dcheck",
"check",
"sbxcheck",
"static_assert"}), Token(
"("),
2825 MakeAssertStatement),
2827 MakeWhileStatement),
2828 Rule({Token(
"for"), Token(
"("),
2830 Optional<Expression*>(expression), Token(
";"),
2831 Optional<Expression*>(expression), Token(
")"), &
statement},
2832 MakeForLoopStatement)};
2836 Rule({Token(
"case"), Token(
"("),
2837 Optional<Identifier*>(Sequence({&
name, Token(
":")})), &type,
2838 Token(
")"), Token(
":"), &block},
2839 MakeTypeswitchCase)};
2843 Rule({&block}, CastParseResult<Statement*, std::optional<Statement*>>),
2844 Rule({Token(
";")}, YieldDefaultValue<std::optional<Statement*>>)};
2848 {CheckIf(Token(
"transitioning")),
2849 Optional<std::string>(Sequence({Token(
"operator"), &
externalString})),
2852 MakeMethodDeclaration)};
2856 Rule({Token(
"{"), List<Declaration*>(&
method),
2857 List<ClassFieldExpression>(&
classField), Token(
"}")},
2859 Rule({Token(
";")}, YieldDefaultValue<std::optional<ClassBody*>>)};
2865 MakeConstDeclaration),
2866 Rule({Token(
"const"), &
name, Token(
":"), &
type, Token(
"generates"),
2868 AsSingletonVector<Declaration*, MakeExternConstDeclaration>()),
2869 Rule({
annotations, CheckIf(Token(
"extern")), CheckIf(Token(
"transient")),
2870 OneOf({
"class",
"shape"}), &name, Token(
"extends"), &
type,
2871 Optional<std::string>(
2874 MakeClassDeclaration),
2877 ListAllowIfAnnotation<Declaration*>(&
method),
2878 ListAllowIfAnnotation<StructFieldExpression>(&
structField),
2880 AsSingletonVector<Declaration*, MakeStructDeclaration>()),
2881 Rule({Token(
"bitfield"), Token(
"struct"), &
name, Token(
"extends"), &
type,
2885 AsSingletonVector<Declaration*, MakeBitFieldStructDeclaration>()),
2888 Optional<TypeExpression*>(Sequence({Token(
"extends"), &type})),
2889 Optional<std::string>(
2891 Optional<std::string>(
2894 MakeAbstractTypeDeclaration),
2896 MakeTypeAliasDeclaration),
2900 AsSingletonVector<Declaration*, MakeIntrinsicDeclaration>()),
2901 Rule({
annotations, Token(
"extern"), CheckIf(Token(
"transitioning")),
2902 Optional<std::string>(
2905 Optional<std::string>(Sequence({&
identifier, Token(
"::")})), &name,
2909 Rule({Token(
"extern"), CheckIf(Token(
"transitioning")),
2910 CheckIf(Token(
"javascript")), Token(
"builtin"), &
name,
2913 AsSingletonVector<Declaration*, MakeExternalBuiltin>()),
2914 Rule({Token(
"extern"), CheckIf(Token(
"transitioning")), Token(
"runtime"),
2916 AsSingletonVector<Declaration*, MakeExternalRuntime>()),
2917 Rule({
annotations, CheckIf(Token(
"transitioning")),
2918 Optional<std::string>(
2920 Token(
"macro"), &
name,
2924 MakeTorqueMacroDeclaration),
2925 Rule({
annotations, CheckIf(Token(
"transitioning")),
2926 CheckIf(Token(
"javascript")), Token(
"builtin"), &
name,
2929 MakeTorqueBuiltinDeclaration),
2933 MakeSpecializationDeclaration),
2935 AsSingletonVector<Declaration*, MakeCppIncludeDeclaration>()),
2936 Rule({CheckIf(Token(
"extern")), Token(
"enum"), &
name,
2937 Optional<TypeExpression*>(Sequence({Token(
"extends"), &type})),
2938 Optional<std::string>(
2941 NonemptyListAllowIfAnnotation<EnumEntry>(&
enumEntry, Token(
",")),
2942 CheckIf(Sequence({Token(
","), Token(
"...")})), Token(
"}")},
2943 MakeEnumDeclaration),
2946 AsSingletonVector<Declaration*, MakeNamespaceDeclaration>())};
2950 Rule({List<std::vector<Declaration*>>(&
declaration)}, ConcatList)};
2953 ProcessTorqueImportDeclaration),
2961 TorqueGrammar().Parse(input);
std::unordered_map< std::string, bool > build_flags_
static bool GetFlag(const std::string &name, const char *production)
MessageBuilder & Position(SourcePosition position)
static size_t TaggedSize()
#define V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL
#define V8_ENABLE_LEAPTIERING_BOOL
#define V8_EXTERNAL_CODE_SPACE_BOOL
#define V8_ENABLE_SANDBOX_BOOL
#define V8_EXPERIMENTAL_UNDEFINED_DOUBLE_BOOL
base::Vector< const DirectHandle< Object > > args
ZoneVector< RpoNumber > & result
ZoneVector< Entry > entries
FunctionLiteral * literal
ZoneVector< InstructionOperand > * set_
static const char *const ANNOTATION_GENERATE_BODY_DESCRIPTOR
static const char *const TORQUE_INTERNAL_NAMESPACE_STRING
static const char *const ANNOTATION_HIGHEST_INSTANCE_TYPE_WITHIN_PARENT
std::vector< TypeExpression * > TypeList
static const char *const ANNOTATION_DO_NOT_GENERATE_CAST
base::Flags< ClassFlag > ClassFlags
bool IsUpperCamelCase(const std::string &s)
std::string UnwrapTNodeTypeName(const std::string &generates)
static const char *const ANNOTATION_CUSTOM_MAP
BasicTypeExpression * MakeBasicTypeExpression(std::vector< std::string > namespace_qualification, Identifier *name, std::vector< TypeExpression * > generic_arguments={})
void ReportError(Args &&... args)
const char * InputPosition
StructExpression * MakeStructExpression(TypeExpression *type, std::vector< NameAndExpression > initializers)
static const char *const ANNOTATION_USE_PARENT_TYPE_CHECKER
T * MakeNode(Args... args)
static const char *const ANNOTATION_RESERVE_BITS_IN_INSTANCE_TYPE
static const char *const ANNOTATION_CUSTOM_INTERFACE_DESCRIPTOR
std::vector< GenericParameter > GenericParameters
base::Flags< StructFlag > StructFlags
static const char *const ANNOTATION_DO_NOT_GENERATE_CPP_CLASS
MessageBuilder Lint(Args &&... args)
static const char *const ANNOTATION_IF
static const char *const ANNOTATION_IFNOT
static const char *const CONSTEXPR_TYPE_PREFIX
FieldAccessExpression * MakeFieldAccessExpression(Expression *object, std::string field)
static const char *const ANNOTATION_CUSTOM_CPP_CLASS
static const char *const ANNOTATION_CPP_OBJECT_LAYOUT_DEFINITION
bool IsValidTypeName(const std::string &s)
bool IsSnakeCase(const std::string &s)
static const char *const ANNOTATION_GENERATE_FACTORY_FUNCTION
static const char *const ANNOTATION_EXPORT
static const char *const ANNOTATION_LOWEST_INSTANCE_TYPE_WITHIN_PARENT
static const char *const ANNOTATION_CPP_OBJECT_DEFINITION
bool IsLowerCamelCase(const std::string &s)
static const char *const ANNOTATION_INCREMENT_USE_COUNTER
bool IsValidNamespaceConstName(const std::string &s)
static const char *const ANNOTATION_HAS_SAME_INSTANCE_TYPE_AS_PARENT
IdentifierExpression * MakeIdentifierExpression(std::vector< std::string > namespace_qualification, std::string name, std::vector< TypeExpression * > args={})
base::Flags< AbstractTypeFlag > AbstractTypeFlags
void ParseTorque(const std::string &input)
std::string GetConstexprName(const std::string &name)
static const char *const ANNOTATION_INSTANCE_TYPE_VALUE
static const char *const ANNOTATION_ABSTRACT
std::vector< LabelAndTypes > LabelAndTypesVector
static const char *const ANNOTATION_GENERATE_UNIQUE_MAP
IncrementDecrementOperator
@ kGenerateCppClassDefinitions
@ kCppObjectLayoutDefinition
@ kHasSameInstanceTypeAsParent
@ kGenerateBodyDescriptor
@ kLowestInstanceTypeWithinParent
@ kGenerateFactoryFunction
@ kHighestInstanceTypeWithinParent
MessageBuilder Error(Args &&... args)
std::string StringLiteralUnquote(const std::string &s)
too high values may cause the compiler to set high thresholds for inlining to as much as possible avoid inlined allocation of objects that cannot escape trace load stores from virtual maglev objects use TurboFan fast string builder analyze liveness of environment slots and zap dead values trace TurboFan load elimination emit data about basic block usage in builtins to this enable builtin reordering when run mksnapshot flag for emit warnings when applying builtin profile data verify register allocation in TurboFan randomly schedule instructions to stress dependency tracking enable store store elimination in TurboFan rewrite far to near simulate GC compiler thread race related to allow float parameters to be passed in simulator mode JS Wasm Run additional turbo_optimize_inlined_js_wasm_wrappers enable experimental feedback collection in generic lowering enable Turboshaft s WasmLoadElimination enable Turboshaft s low level load elimination for JS enable Turboshaft s escape analysis for string concatenation use enable Turbolev features that we want to ship in the not too far future trace individual Turboshaft reduction steps trace intermediate Turboshaft reduction steps invocation count threshold for early optimization Enables optimizations which favor memory size over execution speed Enables sampling allocation profiler with X as a sample interval min size of a semi the new space consists of two semi spaces max size of the Collect garbage after Collect garbage after keeps maps alive for< n > old space garbage collections print one detailed trace line in name
#define DCHECK(condition)
#define DCHECK_EQ(v1, v2)
#define V8_EXPORT_PRIVATE
std::optional< TypeExpression * > type
std::optional< std::string > alias_entry
std::vector< TypeExpression * > types
static ParameterList Empty()
std::vector< Identifier * > names
static SourcePosition Invalid()
std::optional< Identifier * > name
Symbol * optionalOtherwise
Symbol genericSpecializationTypeList
Symbol * optionalLabelList
Symbol * bitwiseExpression
Symbol conditionalExpression
Symbol annotationParameters
Symbol relationalExpression
Symbol floatingPointLiteral
Symbol assignmentExpression
Symbol expressionWithSource
Symbol * optionalImplicitParameterList
Symbol varDeclarationWithInitialization
Symbol * optionalArraySpecifier
Symbol * optionalTypeSpecifier
Symbol typeListMaybeVarArgs
Symbol logicalOrExpression
Symbol * optionalGenericParameters
Symbol logicalAndExpression
Symbol parameterListNoVararg
Symbol * equalityExpression
Symbol assignmentOperator
Symbol annotationParameter
Symbol incrementDecrementOperator
Symbol intrinsicCallExpression
Symbol identifierExpression
Symbol bitFieldDeclaration
Symbol callMethodExpression
Symbol implicitParameterList
Symbol * additiveExpression
Symbol * multiplicativeExpression
Symbol namespaceQualification
Symbol parameterListAllowVararg