5 #include "src/torque/declarations.h" 6 #include "src/torque/declarable.h" 7 #include "src/torque/global-context.h" 8 #include "src/torque/type-oracle.h" 14 DEFINE_CONTEXTUAL_VARIABLE(GlobalContext)
19 std::vector<T> EnsureNonempty(std::vector<T> list,
const std::string& name,
22 ReportError(
"there is no ", kind,
"named ", name);
24 return std::move(list);
27 template <
class T,
class Name>
28 T EnsureUnique(
const std::vector<T>& list,
const Name& name,
const char* kind) {
30 ReportError(
"there is no ", kind,
"named ", name);
32 if (list.size() >= 2) {
33 ReportError(
"ambiguous reference to ", kind,
" ", name);
39 void CheckAlreadyDeclared(
const std::string& name,
const char* new_type) {
40 std::vector<T*> declarations =
41 FilterDeclarables<T>(Declarations::TryLookupShallow(QualifiedName(name)));
42 if (!declarations.empty()) {
43 Scope* scope = CurrentScope::Get();
44 ReportError(
"cannot redeclare ", name,
" (type ", new_type, scope,
")");
50 std::vector<Declarable*> Declarations::LookupGlobalScope(
51 const std::string& name) {
52 std::vector<Declarable*> d =
53 GlobalContext::GetDefaultNamespace()->Lookup(QualifiedName(name));
56 s <<
"cannot find \"" << name <<
"\" in global scope";
62 const Type* Declarations::LookupType(
const QualifiedName& name) {
63 TypeAlias* declaration =
64 EnsureUnique(FilterDeclarables<TypeAlias>(Lookup(name)), name,
"type");
65 return declaration->type();
68 const Type* Declarations::LookupType(std::string name) {
69 return LookupType(QualifiedName(std::move(name)));
72 const Type* Declarations::LookupGlobalType(
const std::string& name) {
73 TypeAlias* declaration = EnsureUnique(
74 FilterDeclarables<TypeAlias>(LookupGlobalScope(name)), name,
"type");
75 return declaration->type();
78 const Type* Declarations::GetType(TypeExpression* type_expression) {
79 if (
auto* basic = BasicTypeExpression::DynamicCast(type_expression)) {
81 (basic->is_constexpr ? CONSTEXPR_TYPE_PREFIX :
"") + basic->name;
82 return LookupType(QualifiedName{basic->namespace_qualification, name});
83 }
else if (
auto* union_type = UnionTypeExpression::cast(type_expression)) {
84 return TypeOracle::GetUnionType(GetType(union_type->a),
85 GetType(union_type->b));
87 auto* function_type_exp = FunctionTypeExpression::cast(type_expression);
88 TypeVector argument_types;
89 for (TypeExpression* type_exp : function_type_exp->parameters) {
90 argument_types.push_back(GetType(type_exp));
92 return TypeOracle::GetFunctionPointerType(
93 argument_types, GetType(function_type_exp->return_type));
97 Builtin* Declarations::FindSomeInternalBuiltinWithType(
98 const FunctionPointerType* type) {
99 for (
auto& declarable : GlobalContext::AllDeclarables()) {
100 if (Builtin* builtin = Builtin::DynamicCast(declarable.get())) {
101 if (!builtin->IsExternal() && builtin->kind() == Builtin::kStub &&
102 builtin->signature().return_type == type->return_type() &&
103 builtin->signature().parameter_types.types ==
104 type->parameter_types()) {
112 Value* Declarations::LookupValue(
const QualifiedName& name) {
113 return EnsureUnique(FilterDeclarables<Value>(Lookup(name)), name,
"value");
116 Macro* Declarations::TryLookupMacro(
const std::string& name,
117 const TypeVector& types) {
118 std::vector<Macro*>
macros = TryLookup<Macro>(QualifiedName(name));
120 auto signature_types = m->signature().GetExplicitTypes();
121 if (signature_types == types && !m->signature().parameter_types.var_args) {
128 base::Optional<Builtin*> Declarations::TryLookupBuiltin(
129 const QualifiedName& name) {
130 std::vector<Builtin*> builtins = TryLookup<Builtin>(name);
131 if (builtins.empty())
return base::nullopt;
132 return EnsureUnique(builtins, name.name,
"builtin");
135 std::vector<Generic*> Declarations::LookupGeneric(
const std::string& name) {
136 return EnsureNonempty(FilterDeclarables<Generic>(Lookup(QualifiedName(name))),
140 Generic* Declarations::LookupUniqueGeneric(
const QualifiedName& name) {
141 return EnsureUnique(FilterDeclarables<Generic>(Lookup(name)), name,
145 Namespace* Declarations::DeclareNamespace(
const std::string& name) {
146 return Declare(name, std::unique_ptr<Namespace>(
new Namespace(name)));
149 const AbstractType* Declarations::DeclareAbstractType(
150 const std::string& name,
bool transient,
const std::string& generated,
151 base::Optional<const AbstractType*> non_constexpr_version,
152 const base::Optional<std::string>& parent) {
153 CheckAlreadyDeclared<TypeAlias>(name,
"type");
154 const Type* parent_type =
nullptr;
156 parent_type = LookupType(QualifiedName{*parent});
158 const AbstractType* type = TypeOracle::GetAbstractType(
159 parent_type, name,
transient, generated, non_constexpr_version);
160 DeclareType(name, type,
false);
164 void Declarations::DeclareType(
const std::string& name,
const Type* type,
165 bool redeclaration) {
166 CheckAlreadyDeclared<TypeAlias>(name,
"type");
167 Declare(name, std::unique_ptr<TypeAlias>(
new TypeAlias(type, redeclaration)));
170 void Declarations::DeclareStruct(
const std::string& name,
171 const std::vector<NameAndType>& fields) {
172 const StructType* new_type = TypeOracle::GetStructType(name, fields);
173 DeclareType(name, new_type,
false);
176 Macro* Declarations::CreateMacro(
177 std::string external_name, std::string readable_name,
178 base::Optional<std::string> external_assembler_name, Signature signature,
179 bool transitioning, base::Optional<Statement*> body) {
180 if (!external_assembler_name) {
181 external_assembler_name = CurrentNamespace()->ExternalName();
183 return RegisterDeclarable(std::unique_ptr<Macro>(
184 new Macro(std::move(external_name), std::move(readable_name),
185 std::move(*external_assembler_name), std::move(signature),
186 transitioning, body)));
189 Macro* Declarations::DeclareMacro(
190 const std::string& name,
191 base::Optional<std::string> external_assembler_name,
192 const Signature& signature,
bool transitioning,
193 base::Optional<Statement*> body, base::Optional<std::string> op) {
194 if (TryLookupMacro(name, signature.GetExplicitTypes())) {
195 ReportError(
"cannot redeclare macro ", name,
196 " with identical explicit parameters");
198 Macro* macro = CreateMacro(name, name, std::move(external_assembler_name),
199 signature, transitioning, body);
200 Declare(name, macro);
202 if (TryLookupMacro(*op, signature.GetExplicitTypes())) {
203 ReportError(
"cannot redeclare operator ", name,
204 " with identical explicit parameters");
211 Intrinsic* Declarations::CreateIntrinsic(
const std::string& name,
212 const Signature& signature) {
213 Intrinsic* result = RegisterDeclarable(std::unique_ptr<Intrinsic>(
214 new Intrinsic(std::move(name), std::move(signature))));
218 Intrinsic* Declarations::DeclareIntrinsic(
const std::string& name,
219 const Signature& signature) {
220 Intrinsic* result = CreateIntrinsic(std::move(name), std::move(signature));
221 Declare(name, result);
225 Builtin* Declarations::CreateBuiltin(std::string external_name,
226 std::string readable_name,
227 Builtin::Kind kind, Signature signature,
229 base::Optional<Statement*> body) {
230 return RegisterDeclarable(std::unique_ptr<Builtin>(
231 new Builtin(std::move(external_name), std::move(readable_name), kind,
232 std::move(signature), transitioning, body)));
235 Builtin* Declarations::DeclareBuiltin(
const std::string& name,
237 const Signature& signature,
239 base::Optional<Statement*> body) {
240 CheckAlreadyDeclared<Builtin>(name,
"builtin");
242 name, CreateBuiltin(name, name, kind, signature, transitioning, body));
245 RuntimeFunction* Declarations::DeclareRuntimeFunction(
246 const std::string& name,
const Signature& signature,
bool transitioning) {
247 CheckAlreadyDeclared<RuntimeFunction>(name,
"runtime function");
249 RegisterDeclarable(std::unique_ptr<RuntimeFunction>(
250 new RuntimeFunction(name, signature, transitioning))));
253 void Declarations::DeclareExternConstant(
const std::string& name,
254 const Type* type, std::string value) {
255 CheckAlreadyDeclared<Value>(name,
"constant");
256 ExternConstant* result =
new ExternConstant(name, type, value);
257 Declare(name, std::unique_ptr<Declarable>(result));
260 NamespaceConstant* Declarations::DeclareNamespaceConstant(
261 const std::string& name,
const Type* type, Expression* body) {
262 CheckAlreadyDeclared<Value>(name,
"constant");
263 NamespaceConstant* result =
new NamespaceConstant(name, type, body);
264 Declare(name, std::unique_ptr<Declarable>(result));
268 Generic* Declarations::DeclareGeneric(
const std::string& name,
269 GenericDeclaration*
generic) {
270 return Declare(name, std::unique_ptr<Generic>(
new Generic(name,
generic)));
273 std::string Declarations::GetGeneratedCallableName(
274 const std::string& name,
const TypeVector& specialized_types) {
275 std::string result = name;
276 for (
auto type : specialized_types) {
277 std::string type_string = type->MangledName();
278 result += std::to_string(type_string.size()) + type_string;