5 #include "src/torque/declaration-visitor.h" 11 void DeclarationVisitor::Visit(Declaration* decl) {
12 CurrentSourcePosition::Scope scope(decl->pos);
14 #define ENUM_ITEM(name) \ 15 case AstNode::Kind::k##name: \ 16 return Visit(name::cast(decl)); 17 AST_DECLARATION_NODE_KIND_LIST(ENUM_ITEM)
24 void DeclarationVisitor::Visit(CallableNode* decl,
const Signature& signature,
25 base::Optional<Statement*> body) {
27 #define ENUM_ITEM(name) \ 28 case AstNode::Kind::k##name: \ 29 return Visit(name::cast(decl), signature, body); 30 AST_CALLABLE_NODE_KIND_LIST(ENUM_ITEM)
37 Builtin* DeclarationVisitor::CreateBuiltin(BuiltinDeclaration* decl,
38 std::string external_name,
39 std::string readable_name,
41 base::Optional<Statement*> body) {
42 const bool javascript = decl->javascript_linkage;
43 const bool varargs = decl->signature->parameters.has_varargs;
44 Builtin::Kind kind = !javascript ? Builtin::kStub
45 : varargs ? Builtin::kVarArgsJavaScript
46 : Builtin::kFixedArgsJavaScript;
48 if (signature.types().size() == 0 ||
49 !(signature.types()[0] ==
50 Declarations::LookupGlobalType(CONTEXT_TYPE_STRING))) {
51 std::stringstream stream;
52 stream <<
"first parameter to builtin " << decl->name
53 <<
" is not a context but should be";
54 ReportError(stream.str());
57 if (varargs && !javascript) {
58 std::stringstream stream;
59 stream <<
"builtin " << decl->name
60 <<
" with rest parameters must be a JavaScript builtin";
61 ReportError(stream.str());
65 if (signature.types().size() < 2 ||
66 !(signature.types()[1] ==
67 Declarations::LookupGlobalType(OBJECT_TYPE_STRING))) {
68 std::stringstream stream;
69 stream <<
"second parameter to javascript builtin " << decl->name
70 <<
" is " << *signature.types()[1] <<
" but should be Object";
71 ReportError(stream.str());
75 if (
const StructType* struct_type =
76 StructType::DynamicCast(signature.return_type)) {
77 std::stringstream stream;
78 stream <<
"builtins (in this case" << decl->name
79 <<
") cannot return structs (in this case " << struct_type->name()
81 ReportError(stream.str());
84 return Declarations::CreateBuiltin(
85 std::move(external_name), std::move(readable_name), kind,
86 std::move(signature), decl->transitioning, body);
89 void DeclarationVisitor::Visit(ExternalRuntimeDeclaration* decl,
90 const Signature& signature,
91 base::Optional<Statement*> body) {
92 if (GlobalContext::verbose()) {
93 std::cout <<
"found declaration of external runtime " << decl->name
94 <<
" with signature ";
97 if (signature.parameter_types.types.size() == 0 ||
98 !(signature.parameter_types.types[0] ==
99 Declarations::LookupGlobalType(CONTEXT_TYPE_STRING))) {
100 std::stringstream stream;
101 stream <<
"first parameter to runtime " << decl->name
102 <<
" is not a context but should be";
103 ReportError(stream.str());
106 if (signature.return_type->IsStructType()) {
107 std::stringstream stream;
108 stream <<
"runtime functions (in this case" << decl->name
109 <<
") cannot return structs (in this case " 110 <<
static_cast<const StructType*
>(signature.return_type)->name()
112 ReportError(stream.str());
115 Declarations::DeclareRuntimeFunction(decl->name, signature,
116 decl->transitioning);
119 void DeclarationVisitor::Visit(ExternalMacroDeclaration* decl,
120 const Signature& signature,
121 base::Optional<Statement*> body) {
122 if (GlobalContext::verbose()) {
123 std::cout <<
"found declaration of external macro " << decl->name
124 <<
" with signature ";
127 Declarations::DeclareMacro(decl->name, decl->external_assembler_name,
128 signature, decl->transitioning, body, decl->op);
131 void DeclarationVisitor::Visit(TorqueBuiltinDeclaration* decl,
132 const Signature& signature,
133 base::Optional<Statement*> body) {
134 Declarations::Declare(
135 decl->name, CreateBuiltin(decl, decl->name, decl->name, signature, body));
138 void DeclarationVisitor::Visit(TorqueMacroDeclaration* decl,
139 const Signature& signature,
140 base::Optional<Statement*> body) {
141 Declarations::DeclareMacro(decl->name, base::nullopt, signature,
142 decl->transitioning, body, decl->op);
145 void DeclarationVisitor::Visit(IntrinsicDeclaration* decl,
146 const Signature& signature,
147 base::Optional<Statement*> body) {
148 Declarations::DeclareIntrinsic(decl->name, signature);
151 void DeclarationVisitor::Visit(ConstDeclaration* decl) {
152 Declarations::DeclareNamespaceConstant(
153 decl->name, Declarations::GetType(decl->type), decl->expression);
156 void DeclarationVisitor::Visit(StandardDeclaration* decl) {
157 Signature signature = MakeSignature(decl->callable->signature.get());
158 Visit(decl->callable, signature, decl->body);
161 void DeclarationVisitor::Visit(GenericDeclaration* decl) {
162 Declarations::DeclareGeneric(decl->callable->name, decl);
165 void DeclarationVisitor::Visit(SpecializationDeclaration* decl) {
166 if ((decl->body !=
nullptr) == decl->external) {
167 std::stringstream stream;
168 stream <<
"specialization of " << decl->name
169 <<
" must either be marked 'extern' or have a body";
170 ReportError(stream.str());
173 std::vector<Generic*> generic_list = Declarations::LookupGeneric(decl->name);
176 Generic* matching_generic =
nullptr;
177 Signature signature_with_types = MakeSignature(decl->signature.get());
178 for (Generic*
generic : generic_list) {
179 Signature generic_signature_with_types = MakeSpecializedSignature(
180 SpecializationKey{
generic, GetTypeVector(decl->generic_parameters)});
181 if (signature_with_types.HasSameTypesAs(generic_signature_with_types,
182 ParameterMode::kIgnoreImplicit)) {
183 if (matching_generic !=
nullptr) {
184 std::stringstream stream;
185 stream <<
"specialization of " << decl->name
186 <<
" is ambigous, it matches more than one generic declaration (" 187 << *matching_generic <<
" and " << *
generic <<
")";
188 ReportError(stream.str());
190 matching_generic =
generic;
194 if (matching_generic ==
nullptr) {
195 std::stringstream stream;
196 if (generic_list.size() == 0) {
197 stream <<
"no generic defined with the name " << decl->name;
198 ReportError(stream.str());
200 stream <<
"specialization of " << decl->name
201 <<
" doesn't match any generic declaration\n";
202 stream <<
"specialization signature:";
203 stream <<
"\n " << signature_with_types;
204 stream <<
"\ncandidates are:";
205 for (Generic*
generic : generic_list) {
207 << MakeSpecializedSignature(SpecializationKey{
208 generic, GetTypeVector(decl->generic_parameters)});
210 ReportError(stream.str());
213 Specialize(SpecializationKey{matching_generic,
214 GetTypeVector(decl->generic_parameters)},
215 matching_generic->declaration()->callable, decl->signature.get(),
219 void DeclarationVisitor::Visit(ExternConstDeclaration* decl) {
220 const Type* type = Declarations::GetType(decl->type);
221 if (!type->IsConstexpr()) {
222 std::stringstream stream;
223 stream <<
"extern constants must have constexpr type, but found: \"" 225 ReportError(stream.str());
228 Declarations::DeclareExternConstant(decl->name, type, decl->literal);
231 void DeclarationVisitor::Visit(StructDeclaration* decl) {
232 std::vector<NameAndType> fields;
233 for (
auto& field : decl->fields) {
234 const Type* field_type = Declarations::GetType(field.type);
235 fields.push_back({field.name, field_type});
237 Declarations::DeclareStruct(decl->name, fields);
240 void DeclarationVisitor::Visit(TypeDeclaration* decl) {
241 std::string generates = decl->generates ? *decl->generates : std::string(
"");
242 if (decl->generates) {
243 if (generates.length() < 7 || generates.substr(0, 6) !=
"TNode<" ||
244 generates.substr(generates.length() - 1, 1) !=
">") {
245 ReportError(
"generated type \"", generates,
246 "\" should be of the form \"TNode<...>\"");
248 generates = generates.substr(6, generates.length() - 7);
251 const AbstractType* type = Declarations::DeclareAbstractType(
252 decl->name, decl->transient, generates, {}, decl->extends);
254 if (decl->constexpr_generates) {
255 if (decl->transient) {
256 ReportError(
"cannot declare a transient type that is also constexpr");
258 std::string constexpr_name = CONSTEXPR_TYPE_PREFIX + decl->name;
259 base::Optional<std::string> constexpr_extends;
261 constexpr_extends = CONSTEXPR_TYPE_PREFIX + *decl->extends;
262 Declarations::DeclareAbstractType(constexpr_name,
false,
263 *decl->constexpr_generates, type,
268 void DeclarationVisitor::DeclareSpecializedTypes(
const SpecializationKey& key) {
270 const std::size_t generic_parameter_count =
271 key.generic->declaration()->generic_parameters.size();
272 if (generic_parameter_count != key.specialized_types.size()) {
273 std::stringstream stream;
274 stream <<
"Wrong generic argument count for specialization of \"" 275 << key.generic->name() <<
"\", expected: " << generic_parameter_count
276 <<
", actual: " << key.specialized_types.size();
277 ReportError(stream.str());
280 for (
auto type : key.specialized_types) {
281 std::string generic_type_name =
282 key.generic->declaration()->generic_parameters[
i++];
283 Declarations::DeclareType(generic_type_name, type,
true);
287 Signature DeclarationVisitor::MakeSpecializedSignature(
288 const SpecializationKey& key) {
289 CurrentScope::Scope generic_scope(key.generic->ParentScope());
292 Namespace tmp_namespace(
"_tmp");
293 CurrentScope::Scope tmp_namespace_scope(&tmp_namespace);
294 DeclareSpecializedTypes(key);
295 return MakeSignature(key.generic->declaration()->callable->signature.get());
298 Callable* DeclarationVisitor::SpecializeImplicit(
const SpecializationKey& key) {
299 if (!key.generic->declaration()->body &&
300 IntrinsicDeclaration::DynamicCast(key.generic->declaration()->callable) ==
302 ReportError(
"missing specialization of ", key.generic->name(),
303 " with types <", key.specialized_types,
"> declared at ",
306 CurrentScope::Scope generic_scope(key.generic->ParentScope());
308 Specialize(key, key.generic->declaration()->callable, base::nullopt,
309 key.generic->declaration()->body);
310 CurrentScope::Scope callable_scope(result);
311 DeclareSpecializedTypes(key);
315 Callable* DeclarationVisitor::Specialize(
316 const SpecializationKey& key, CallableNode* declaration,
317 base::Optional<const CallableNodeSignature*> signature,
318 base::Optional<Statement*> body) {
321 CurrentSourcePosition::Scope pos_scope(key.generic->declaration()->pos);
322 size_t generic_parameter_count =
323 key.generic->declaration()->generic_parameters.size();
324 if (generic_parameter_count != key.specialized_types.size()) {
325 std::stringstream stream;
326 stream <<
"number of template parameters (" 327 << std::to_string(key.specialized_types.size())
328 <<
") to intantiation of generic " << declaration->name
329 <<
" doesnt match the generic's declaration (" 330 << std::to_string(generic_parameter_count) <<
")";
331 ReportError(stream.str());
333 if (key.generic->GetSpecialization(key.specialized_types)) {
334 ReportError(
"cannot redeclare specialization of ", key.generic->name(),
335 " with types <", key.specialized_types,
">");
338 Signature type_signature =
339 signature ? MakeSignature(*signature) : MakeSpecializedSignature(key);
341 std::string generated_name = Declarations::GetGeneratedCallableName(
342 declaration->name, key.specialized_types);
343 std::stringstream readable_name;
344 readable_name << declaration->name <<
"<";
346 for (
const Type* t : key.specialized_types) {
347 if (!first) readable_name <<
", ";
351 readable_name <<
">";
353 if (MacroDeclaration::DynamicCast(declaration) !=
nullptr) {
354 callable = Declarations::CreateMacro(generated_name, readable_name.str(),
355 base::nullopt, type_signature,
356 declaration->transitioning, *body);
357 }
else if (IntrinsicDeclaration::DynamicCast(declaration) !=
nullptr) {
358 callable = Declarations::CreateIntrinsic(declaration->name, type_signature);
360 BuiltinDeclaration* builtin = BuiltinDeclaration::cast(declaration);
361 callable = CreateBuiltin(builtin, generated_name, readable_name.str(),
362 type_signature, *body);
364 key.generic->AddSpecialization(key.specialized_types, callable);