declarations.cc 12 KB
Newer Older
1 2 3 4 5 6
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/torque/declarations.h"
#include "src/torque/declarable.h"
7
#include "src/torque/global-context.h"
8
#include "src/torque/server-data.h"
9
#include "src/torque/type-oracle.h"
10 11 12 13

namespace v8 {
namespace internal {
namespace torque {
14 15 16 17 18 19
namespace {

template <class T>
std::vector<T> EnsureNonempty(std::vector<T> list, const std::string& name,
                              const char* kind) {
  if (list.empty()) {
20
    ReportError("there is no ", kind, " named ", name);
21
  }
22
  return std::move(list);
23 24
}

25 26
template <class T, class Name>
T EnsureUnique(const std::vector<T>& list, const Name& name, const char* kind) {
27
  if (list.empty()) {
28
    ReportError("there is no ", kind, " named ", name);
29 30 31 32 33
  }
  if (list.size() >= 2) {
    ReportError("ambiguous reference to ", kind, " ", name);
  }
  return list.front();
34 35
}

36 37 38
template <class T>
void CheckAlreadyDeclared(const std::string& name, const char* new_type) {
  std::vector<T*> declarations =
39
      FilterDeclarables<T>(Declarations::TryLookupShallow(QualifiedName(name)));
40 41
  if (!declarations.empty()) {
    Scope* scope = CurrentScope::Get();
42
    ReportError("cannot redeclare ", name, " (type ", *new_type, scope, ")");
43
  }
44 45
}

46 47 48
}  // namespace

std::vector<Declarable*> Declarations::LookupGlobalScope(
49
    const QualifiedName& name) {
50
  std::vector<Declarable*> d =
51
      GlobalContext::GetDefaultNamespace()->Lookup(name);
52
  if (d.empty()) {
53
    std::stringstream s;
54
    s << "cannot find \"" << name << "\" in global scope";
55 56
    ReportError(s.str());
  }
57
  return d;
58 59
}

60
const TypeAlias* Declarations::LookupTypeAlias(const QualifiedName& name) {
61 62
  TypeAlias* declaration =
      EnsureUnique(FilterDeclarables<TypeAlias>(Lookup(name)), name, "type");
63 64 65 66 67
  return declaration;
}

const Type* Declarations::LookupType(const QualifiedName& name) {
  return LookupTypeAlias(name)->type();
68 69
}

70 71 72 73 74 75 76 77 78
const Type* Declarations::LookupType(const Identifier* name) {
  const TypeAlias* alias = LookupTypeAlias(QualifiedName(name->value));
  if (GlobalContext::collect_language_server_data()) {
    LanguageServerData::AddDefinition(name->pos,
                                      alias->GetDeclarationPosition());
  }
  return alias->type();
}

79 80 81 82 83 84 85
base::Optional<const Type*> Declarations::TryLookupType(
    const QualifiedName& name) {
  auto decls = FilterDeclarables<TypeAlias>(TryLookup(name));
  if (decls.empty()) return base::nullopt;
  return EnsureUnique(std::move(decls), name, "type")->type();
}

86
const Type* Declarations::LookupGlobalType(const QualifiedName& name) {
87 88 89
  TypeAlias* declaration = EnsureUnique(
      FilterDeclarables<TypeAlias>(LookupGlobalScope(name)), name, "type");
  return declaration->type();
90 91
}

92
Builtin* Declarations::FindSomeInternalBuiltinWithType(
93
    const BuiltinPointerType* type) {
94
  for (auto& declarable : GlobalContext::AllDeclarables()) {
95 96 97 98 99 100 101 102 103 104 105 106
    if (Builtin* builtin = Builtin::DynamicCast(declarable.get())) {
      if (!builtin->IsExternal() && builtin->kind() == Builtin::kStub &&
          builtin->signature().return_type == type->return_type() &&
          builtin->signature().parameter_types.types ==
              type->parameter_types()) {
        return builtin;
      }
    }
  }
  return nullptr;
}

107
Value* Declarations::LookupValue(const QualifiedName& name) {
108
  return EnsureUnique(FilterDeclarables<Value>(Lookup(name)), name, "value");
109 110
}

111 112
Macro* Declarations::TryLookupMacro(const std::string& name,
                                    const TypeVector& types) {
113
  std::vector<Macro*> macros = TryLookup<Macro>(QualifiedName(name));
114 115 116 117
  for (auto& m : macros) {
    auto signature_types = m->signature().GetExplicitTypes();
    if (signature_types == types && !m->signature().parameter_types.var_args) {
      return m;
118 119
    }
  }
120 121 122
  return nullptr;
}

123
base::Optional<Builtin*> Declarations::TryLookupBuiltin(
124
    const QualifiedName& name) {
125 126
  std::vector<Builtin*> builtins = TryLookup<Builtin>(name);
  if (builtins.empty()) return base::nullopt;
127
  return EnsureUnique(builtins, name.name, "builtin");
128 129
}

130 131 132 133 134
std::vector<GenericCallable*> Declarations::LookupGeneric(
    const std::string& name) {
  return EnsureNonempty(
      FilterDeclarables<GenericCallable>(Lookup(QualifiedName(name))), name,
      "generic callable");
135 136
}

137 138 139
GenericCallable* Declarations::LookupUniqueGeneric(const QualifiedName& name) {
  return EnsureUnique(FilterDeclarables<GenericCallable>(Lookup(name)), name,
                      "generic callable");
140 141
}

142 143 144
GenericType* Declarations::LookupUniqueGenericType(const QualifiedName& name) {
  return EnsureUnique(FilterDeclarables<GenericType>(Lookup(name)), name,
                      "generic type");
145 146
}

147 148
GenericType* Declarations::LookupGlobalUniqueGenericType(
    const std::string& name) {
149 150 151
  return EnsureUnique(
      FilterDeclarables<GenericType>(LookupGlobalScope(QualifiedName(name))),
      name, "generic type");
152 153
}

154
base::Optional<GenericType*> Declarations::TryLookupGenericType(
155
    const QualifiedName& name) {
156
  std::vector<GenericType*> results = TryLookup<GenericType>(name);
157
  if (results.empty()) return base::nullopt;
158
  return EnsureUnique(results, name.name, "generic type");
159 160
}

161
Namespace* Declarations::DeclareNamespace(const std::string& name) {
162
  return Declare(name, std::make_unique<Namespace>(name));
163 164
}

165
TypeAlias* Declarations::DeclareType(const Identifier* name, const Type* type) {
166
  CheckAlreadyDeclared<TypeAlias>(name->value, "type");
167 168
  return Declare(name->value, std::unique_ptr<TypeAlias>(
                                  new TypeAlias(type, true, name->pos)));
169 170
}

171 172 173
const TypeAlias* Declarations::PredeclareTypeAlias(const Identifier* name,
                                                   TypeDeclaration* type,
                                                   bool redeclaration) {
174
  CheckAlreadyDeclared<TypeAlias>(name->value, "type");
175 176 177
  std::unique_ptr<TypeAlias> alias_ptr(
      new TypeAlias(type, redeclaration, name->pos));
  return Declare(name->value, std::move(alias_ptr));
178 179
}

180 181 182 183 184 185
TorqueMacro* Declarations::CreateTorqueMacro(std::string external_name,
                                             std::string readable_name,
                                             bool exported_to_csa,
                                             Signature signature,
                                             base::Optional<Statement*> body,
                                             bool is_user_defined) {
186
  external_name = GlobalContext::MakeUniqueName(external_name);
187 188
  return RegisterDeclarable(std::unique_ptr<TorqueMacro>(new TorqueMacro(
      std::move(external_name), std::move(readable_name), std::move(signature),
189
      body, is_user_defined, exported_to_csa)));
190 191 192
}

ExternMacro* Declarations::CreateExternMacro(
193 194
    std::string name, std::string external_assembler_name,
    Signature signature) {
195 196
  return RegisterDeclarable(std::unique_ptr<ExternMacro>(
      new ExternMacro(std::move(name), std::move(external_assembler_name),
197
                      std::move(signature))));
198 199 200
}

Macro* Declarations::DeclareMacro(
201
    const std::string& name, bool accessible_from_csa,
202
    base::Optional<std::string> external_assembler_name,
203 204
    const Signature& signature, base::Optional<Statement*> body,
    base::Optional<std::string> op, bool is_user_defined) {
205 206 207 208
  if (TryLookupMacro(name, signature.GetExplicitTypes())) {
    ReportError("cannot redeclare macro ", name,
                " with identical explicit parameters");
  }
209 210
  Macro* macro;
  if (external_assembler_name) {
211 212
    macro =
        CreateExternMacro(name, std::move(*external_assembler_name), signature);
213
  } else {
214 215
    macro = CreateTorqueMacro(name, name, accessible_from_csa, signature, body,
                              is_user_defined);
216
  }
217

218 219 220 221 222 223
  Declare(name, macro);
  if (op) {
    if (TryLookupMacro(*op, signature.GetExplicitTypes())) {
      ReportError("cannot redeclare operator ", name,
                  " with identical explicit parameters");
    }
224
    DeclareOperator(*op, macro);
225
  }
226
  return macro;
227 228
}

229 230
Method* Declarations::CreateMethod(AggregateType* container_type,
                                   const std::string& name, Signature signature,
231
                                   Statement* body) {
232 233 234 235
  std::string generated_name = GlobalContext::MakeUniqueName(
      "Method_" + container_type->SimpleName() + "_" + name);
  Method* result = RegisterDeclarable(std::unique_ptr<Method>(new Method(
      container_type, generated_name, name, std::move(signature), body)));
236 237 238 239
  container_type->RegisterMethod(result);
  return result;
}

240 241 242 243 244 245 246 247 248 249 250 251 252 253
Intrinsic* Declarations::CreateIntrinsic(const std::string& name,
                                         const Signature& signature) {
  Intrinsic* result = RegisterDeclarable(std::unique_ptr<Intrinsic>(
      new Intrinsic(std::move(name), std::move(signature))));
  return result;
}

Intrinsic* Declarations::DeclareIntrinsic(const std::string& name,
                                          const Signature& signature) {
  Intrinsic* result = CreateIntrinsic(std::move(name), std::move(signature));
  Declare(name, result);
  return result;
}

254 255 256
Builtin* Declarations::CreateBuiltin(std::string external_name,
                                     std::string readable_name,
                                     Builtin::Kind kind, Signature signature,
257

258 259
                                     base::Optional<Statement*> body) {
  return RegisterDeclarable(std::unique_ptr<Builtin>(
260
      new Builtin(std::move(external_name), std::move(readable_name), kind,
261
                  std::move(signature), body)));
262 263
}

264
Builtin* Declarations::DeclareBuiltin(const std::string& name,
265
                                      Builtin::Kind kind,
266
                                      const Signature& signature,
267

268 269
                                      base::Optional<Statement*> body) {
  CheckAlreadyDeclared<Builtin>(name, "builtin");
270
  return Declare(name, CreateBuiltin(name, name, kind, signature, body));
271 272 273
}

RuntimeFunction* Declarations::DeclareRuntimeFunction(
274
    const std::string& name, const Signature& signature) {
275
  CheckAlreadyDeclared<RuntimeFunction>(name, "runtime function");
276 277
  return Declare(name, RegisterDeclarable(std::unique_ptr<RuntimeFunction>(
                           new RuntimeFunction(name, signature))));
278 279
}

280 281 282
void Declarations::DeclareExternConstant(Identifier* name, const Type* type,
                                         std::string value) {
  CheckAlreadyDeclared<Value>(name->value, "constant");
283 284
  Declare(name->value, std::unique_ptr<ExternConstant>(
                           new ExternConstant(name, type, value)));
285 286
}

287 288 289 290
NamespaceConstant* Declarations::DeclareNamespaceConstant(Identifier* name,
                                                          const Type* type,
                                                          Expression* body) {
  CheckAlreadyDeclared<Value>(name->value, "constant");
291
  std::string external_name = GlobalContext::MakeUniqueName(name->value);
292 293 294 295
  std::unique_ptr<NamespaceConstant> namespaceConstant(
      new NamespaceConstant(name, std::move(external_name), type, body));
  NamespaceConstant* result = namespaceConstant.get();
  Declare(name->value, std::move(namespaceConstant));
296 297 298
  return result;
}

299 300 301 302
GenericCallable* Declarations::DeclareGenericCallable(
    const std::string& name, GenericCallableDeclaration* ast_node) {
  return Declare(name, std::unique_ptr<GenericCallable>(
                           new GenericCallable(name, ast_node)));
303 304
}

305 306 307 308
GenericType* Declarations::DeclareGenericType(
    const std::string& name, GenericTypeDeclaration* ast_node) {
  return Declare(name,
                 std::unique_ptr<GenericType>(new GenericType(name, ast_node)));
309 310
}

311 312
std::string Declarations::GetGeneratedCallableName(
    const std::string& name, const TypeVector& specialized_types) {
313 314
  std::string result = name;
  for (auto type : specialized_types) {
315
    result += "_" + type->SimpleName();
316 317 318 319
  }
  return result;
}

320 321 322 323 324
Macro* Declarations::DeclareOperator(const std::string& name, Macro* m) {
  GlobalContext::GetDefaultNamespace()->AddDeclarable(name, m);
  return m;
}

325 326 327
}  // namespace torque
}  // namespace internal
}  // namespace v8