5 #ifndef V8_TORQUE_DECLARABLE_H_ 6 #define V8_TORQUE_DECLARABLE_H_ 10 #include <unordered_map> 12 #include "src/base/functional.h" 13 #include "src/base/logging.h" 14 #include "src/torque/ast.h" 15 #include "src/torque/types.h" 16 #include "src/torque/utils.h" 24 DECLARE_CONTEXTUAL_VARIABLE(CurrentScope, Scope*);
27 std::vector<std::string> namespace_qualification;
30 QualifiedName(std::vector<std::string> namespace_qualification,
32 : namespace_qualification(std::move(namespace_qualification)),
33 name(std::move(name)) {}
37 friend std::ostream& operator<<(std::ostream& os,
const QualifiedName& name);
54 Kind kind()
const {
return kind_; }
55 bool IsNamespace()
const {
return kind() == kNamespace; }
56 bool IsMacro()
const {
return kind() == kMacro; }
57 bool IsIntrinsic()
const {
return kind() == kIntrinsic; }
58 bool IsBuiltin()
const {
return kind() == kBuiltin; }
59 bool IsRuntimeFunction()
const {
return kind() == kRuntimeFunction; }
60 bool IsGeneric()
const {
return kind() == kGeneric; }
61 bool IsTypeAlias()
const {
return kind() == kTypeAlias; }
62 bool IsExternConstant()
const {
return kind() == kExternConstant; }
63 bool IsNamespaceConstant()
const {
return kind() == kNamespaceConstant; }
64 bool IsValue()
const {
return IsExternConstant() || IsNamespaceConstant(); }
65 bool IsScope()
const {
return IsNamespace() || IsCallable(); }
66 bool IsCallable()
const {
67 return IsMacro() || IsBuiltin() || IsRuntimeFunction() || IsIntrinsic();
69 virtual const char* type_name()
const {
return "<<unknown>>"; }
70 Scope* ParentScope()
const {
return parent_scope_; }
74 explicit Declarable(Kind kind) : kind_(kind) {}
78 Scope*
const parent_scope_ = CurrentScope::Get();
82 #define DECLARE_DECLARABLE_BOILERPLATE(x, y) \ 83 static x* cast(Declarable* declarable) { \ 84 DCHECK(declarable->Is##x()); \ 85 return static_cast<x*>(declarable); \ 87 static const x* cast(const Declarable* declarable) { \ 88 DCHECK(declarable->Is##x()); \ 89 return static_cast<const x*>(declarable); \ 91 const char* type_name() const override { return #y; } \ 92 static x* DynamicCast(Declarable* declarable) { \ 93 if (!declarable) return nullptr; \ 94 if (!declarable->Is##x()) return nullptr; \ 95 return static_cast<x*>(declarable); \ 97 static const x* DynamicCast(const Declarable* declarable) { \ 98 if (!declarable) return nullptr; \ 99 if (!declarable->Is##x()) return nullptr; \ 100 return static_cast<const x*>(declarable); \ 105 DECLARE_DECLARABLE_BOILERPLATE(
Scope, scope);
108 std::vector<Declarable*> LookupShallow(
const QualifiedName& name) {
109 if (name.namespace_qualification.empty())
return declarations_[name.name];
110 Scope* child =
nullptr;
112 declarations_[name.namespace_qualification.front()]) {
113 if (
Scope* scope = Scope::DynamicCast(declarable)) {
114 if (child !=
nullptr) {
115 ReportError(
"ambiguous reference to scope ",
116 name.namespace_qualification.front());
121 if (child ==
nullptr)
return {};
122 return child->LookupShallow(
124 name.namespace_qualification.end()},
129 std::vector<Declarable*> result;
131 result = ParentScope()->Lookup(name);
133 for (
Declarable* declarable : LookupShallow(name)) {
134 result.push_back(declarable);
139 T* AddDeclarable(
const std::string& name,
T* declarable) {
140 declarations_[name].push_back(declarable);
145 std::unordered_map<std::string, std::vector<Declarable*>> declarations_;
150 DECLARE_DECLARABLE_BOILERPLATE(
Namespace,
namespace);
151 explicit Namespace(
const std::string& name)
152 :
Scope(Declarable::kNamespace), name_(name) {}
153 const std::string& name()
const {
return name_; }
154 std::string ExternalName()
const {
155 return CamelifyString(name()) +
"BuiltinsFromDSLAssembler";
157 std::ostream& source_stream() {
return source_stream_; }
158 std::ostream& header_stream() {
return header_stream_; }
159 std::string source() {
return source_stream_.str(); }
160 std::string header() {
return header_stream_.str(); }
164 std::stringstream header_stream_;
165 std::stringstream source_stream_;
169 Scope* scope = CurrentScope::Get();
171 if (
Namespace* n = Namespace::DynamicCast(scope)) {
174 scope = scope->ParentScope();
180 DECLARE_DECLARABLE_BOILERPLATE(
Value, value);
181 const std::string& name()
const {
return name_; }
182 virtual bool IsConst()
const {
return true; }
184 const Type*
type()
const {
return type_; }
205 const std::string& constant_name()
const {
return constant_name_; }
207 std::string ExternalAssemblerName()
const {
208 return Namespace::cast(ParentScope())->ExternalName();
215 :
Value(Declarable::kNamespaceConstant,
type, constant_name),
216 constant_name_(std::move(constant_name)),
219 std::string constant_name_;
230 :
Value(Declarable::kExternConstant,
type, std::move(name)) {
237 DECLARE_DECLARABLE_BOILERPLATE(
Callable, callable);
238 const std::string& ExternalName()
const {
return external_name_; }
239 const std::string& ReadableName()
const {
return readable_name_; }
240 const Signature& signature()
const {
return signature_; }
241 const NameVector& parameter_names()
const {
242 return signature_.parameter_names;
244 bool HasReturnValue()
const {
245 return !signature_.return_type->IsVoidOrNever();
247 void IncrementReturns() { ++returns_; }
248 bool HasReturns()
const {
return returns_; }
249 bool IsTransitioning()
const {
return transitioning_; }
251 bool IsExternal()
const {
return !body_.has_value(); }
254 Callable(Declarable::Kind kind, std::string external_name,
255 std::string readable_name,
Signature signature,
bool transitioning,
258 external_name_(std::move(external_name)),
260 readable_name_(std::move(readable_name)),
261 signature_(std::move(signature)),
262 transitioning_(transitioning),
265 DCHECK(!body || *body);
269 std::string external_name_;
270 std::string readable_name_;
279 DECLARE_DECLARABLE_BOILERPLATE(
Macro, macro);
281 const std::string& external_assembler_name()
const {
282 return external_assembler_name_;
287 Macro(std::string external_name, std::string readable_name,
288 std::string external_assembler_name,
const Signature& signature,
290 :
Callable(Declarable::kMacro, std::move(external_name),
291 std::move(readable_name), signature, transitioning, body),
292 external_assembler_name_(std::move(external_assembler_name)) {
293 if (signature.parameter_types.var_args) {
294 ReportError(
"Varargs are not supported for macros.");
298 std::string external_assembler_name_;
303 enum Kind { kStub, kFixedArgsJavaScript, kVarArgsJavaScript };
304 DECLARE_DECLARABLE_BOILERPLATE(
Builtin, builtin);
305 Kind kind()
const {
return kind_; }
306 bool IsStub()
const {
return kind_ == kStub; }
307 bool IsVarArgsJavaScript()
const {
return kind_ == kVarArgsJavaScript; }
308 bool IsFixedArgsJavaScript()
const {
return kind_ == kFixedArgsJavaScript; }
312 Builtin(std::string external_name, std::string readable_name,
313 Builtin::Kind kind,
const Signature& signature,
bool transitioning,
315 :
Callable(Declarable::kBuiltin, std::move(external_name),
316 std::move(readable_name), signature, transitioning, body),
330 :
Callable(Declarable::kRuntimeFunction, name, name, signature,
331 transitioning, base::nullopt) {}
336 DECLARE_DECLARABLE_BOILERPLATE(
Intrinsic, intrinsic);
341 :
Callable(Declarable::kIntrinsic, name, name, signature,
false,
343 if (signature.parameter_types.var_args) {
344 ReportError(
"Varargs are not supported for intrinsics.");
351 DECLARE_DECLARABLE_BOILERPLATE(
Generic,
generic);
354 const std::vector<std::string> generic_parameters()
const {
355 return declaration()->generic_parameters;
357 const std::string& name()
const {
return name_; }
358 void AddSpecialization(
const TypeVector& type_arguments,
360 DCHECK_EQ(0, specializations_.count(type_arguments));
361 specializations_[type_arguments] = specialization;
364 const TypeVector& type_arguments)
const {
365 auto it = specializations_.find(type_arguments);
366 if (it != specializations_.end())
return it->second;
367 return base::nullopt;
370 const TypeVector& explicit_specialization_types,
371 const TypeVector& arguments);
378 declaration_(declaration) {}
380 const TypeVector& arguments);
383 std::unordered_map<TypeVector, Callable*, base::hash<TypeVector>>
390 TypeVector specialized_types;
395 DECLARE_DECLARABLE_BOILERPLATE(
TypeAlias, type_alias);
397 const Type*
type()
const {
return type_; }
398 bool IsRedeclaration()
const {
return redeclaration_; }
405 redeclaration_(redeclaration) {}
411 std::ostream& operator<<(std::ostream& os,
const Callable& m);
412 std::ostream& operator<<(std::ostream& os,
const Builtin& b);
414 std::ostream& operator<<(std::ostream& os,
const Generic& g);
416 #undef DECLARE_DECLARABLE_BOILERPLATE 422 #endif // V8_TORQUE_DECLARABLE_H_