LCOV - code coverage report
Current view: top level - src/torque - declarations.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 127 147 86.4 %
Date: 2019-01-20 Functions: 38 42 90.5 %

          Line data    Source code
       1             : // Copyright 2017 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       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"
       9             : 
      10             : namespace v8 {
      11             : namespace internal {
      12             : namespace torque {
      13             : 
      14        5618 : DEFINE_CONTEXTUAL_VARIABLE(GlobalContext)
      15             : 
      16             : namespace {
      17             : 
      18             : template <class T>
      19       14150 : std::vector<T> EnsureNonempty(std::vector<T> list, const std::string& name,
      20             :                               const char* kind) {
      21       14150 :   if (list.empty()) {
      22           0 :     ReportError("there is no ", kind, " named ", name);
      23             :   }
      24       14150 :   return std::move(list);
      25             : }
      26             : 
      27             : template <class T, class Name>
      28       91427 : T EnsureUnique(const std::vector<T>& list, const Name& name, const char* kind) {
      29       91427 :   if (list.empty()) {
      30           0 :     ReportError("there is no ", kind, " named ", name);
      31             :   }
      32       91427 :   if (list.size() >= 2) {
      33           0 :     ReportError("ambiguous reference to ", kind, " ", name);
      34             :   }
      35       91427 :   return list.front();
      36             : }
      37             : 
      38             : template <class T>
      39        4081 : void CheckAlreadyDeclared(const std::string& name, const char* new_type) {
      40             :   std::vector<T*> declarations =
      41       12243 :       FilterDeclarables<T>(Declarations::TryLookupShallow(QualifiedName(name)));
      42        4081 :   if (!declarations.empty()) {
      43           0 :     Scope* scope = CurrentScope::Get();
      44           0 :     ReportError("cannot redeclare ", name, " (type ", new_type, scope, ")");
      45             :   }
      46        4081 : }
      47             : 
      48             : }  // namespace
      49             : 
      50       78798 : std::vector<Declarable*> Declarations::LookupGlobalScope(
      51             :     const std::string& name) {
      52             :   std::vector<Declarable*> d =
      53      236394 :       GlobalContext::GetDefaultNamespace()->Lookup(QualifiedName(name));
      54       78798 :   if (d.empty()) {
      55           0 :     std::stringstream s;
      56           0 :     s << "cannot find \"" << name << "\" in global scope";
      57           0 :     ReportError(s.str());
      58             :   }
      59       78798 :   return d;
      60             : }
      61             : 
      62       11779 : const Type* Declarations::LookupType(const QualifiedName& name) {
      63       11779 :   TypeAlias* declaration =
      64       35337 :       EnsureUnique(FilterDeclarables<TypeAlias>(Lookup(name)), name, "type");
      65       11779 :   return declaration->type();
      66             : }
      67             : 
      68        1500 : const Type* Declarations::LookupType(std::string name) {
      69        3000 :   return LookupType(QualifiedName(std::move(name)));
      70             : }
      71             : 
      72       78798 : const Type* Declarations::LookupGlobalType(const std::string& name) {
      73       78798 :   TypeAlias* declaration = EnsureUnique(
      74      236394 :       FilterDeclarables<TypeAlias>(LookupGlobalScope(name)), name, "type");
      75       78798 :   return declaration->type();
      76             : }
      77             : 
      78       10233 : const Type* Declarations::GetType(TypeExpression* type_expression) {
      79       10233 :   if (auto* basic = BasicTypeExpression::DynamicCast(type_expression)) {
      80             :     std::string name =
      81       10197 :         (basic->is_constexpr ? CONSTEXPR_TYPE_PREFIX : "") + basic->name;
      82       30591 :     return LookupType(QualifiedName{basic->namespace_qualification, name});
      83          36 :   } else if (auto* union_type = UnionTypeExpression::cast(type_expression)) {
      84             :     return TypeOracle::GetUnionType(GetType(union_type->a),
      85          25 :                                     GetType(union_type->b));
      86             :   } else {
      87             :     auto* function_type_exp = FunctionTypeExpression::cast(type_expression);
      88             :     TypeVector argument_types;
      89          57 :     for (TypeExpression* type_exp : function_type_exp->parameters) {
      90          70 :       argument_types.push_back(GetType(type_exp));
      91             :     }
      92             :     return TypeOracle::GetBuiltinPointerType(
      93          22 :         argument_types, GetType(function_type_exp->return_type));
      94             :   }
      95             : }
      96             : 
      97          10 : Builtin* Declarations::FindSomeInternalBuiltinWithType(
      98         264 :     const BuiltinPointerType* type) {
      99       17895 :   for (auto& declarable : GlobalContext::AllDeclarables()) {
     100       18573 :     if (Builtin* builtin = Builtin::DynamicCast(declarable.get())) {
     101        1777 :       if (!builtin->IsExternal() && builtin->kind() == Builtin::kStub &&
     102        1215 :           builtin->signature().return_type == type->return_type() &&
     103         126 :           builtin->signature().parameter_types.types ==
     104         126 :               type->parameter_types()) {
     105             :         return builtin;
     106             :       }
     107             :     }
     108             :   }
     109             :   return nullptr;
     110             : }
     111             : 
     112         787 : Value* Declarations::LookupValue(const QualifiedName& name) {
     113        2361 :   return EnsureUnique(FilterDeclarables<Value>(Lookup(name)), name, "value");
     114             : }
     115             : 
     116         739 : Macro* Declarations::TryLookupMacro(const std::string& name,
     117             :                                     const TypeVector& types) {
     118        1478 :   std::vector<Macro*> macros = TryLookup<Macro>(QualifiedName(name));
     119        1947 :   for (auto& m : macros) {
     120         469 :     auto signature_types = m->signature().GetExplicitTypes();
     121         469 :     if (signature_types == types && !m->signature().parameter_types.var_args) {
     122           0 :       return m;
     123             :     }
     124             :   }
     125             :   return nullptr;
     126             : }
     127             : 
     128         850 : base::Optional<Builtin*> Declarations::TryLookupBuiltin(
     129             :     const QualifiedName& name) {
     130         850 :   std::vector<Builtin*> builtins = TryLookup<Builtin>(name);
     131         850 :   if (builtins.empty()) return base::nullopt;
     132           4 :   return EnsureUnique(builtins, name.name, "builtin");
     133             : }
     134             : 
     135       14150 : std::vector<Generic*> Declarations::LookupGeneric(const std::string& name) {
     136             :   return EnsureNonempty(FilterDeclarables<Generic>(Lookup(QualifiedName(name))),
     137       56600 :                         name, "generic");
     138             : }
     139             : 
     140          59 : Generic* Declarations::LookupUniqueGeneric(const QualifiedName& name) {
     141             :   return EnsureUnique(FilterDeclarables<Generic>(Lookup(name)), name,
     142         177 :                       "generic");
     143             : }
     144             : 
     145           9 : Namespace* Declarations::DeclareNamespace(const std::string& name) {
     146          27 :   return Declare(name, std::unique_ptr<Namespace>(new Namespace(name)));
     147             : }
     148             : 
     149         115 : const AbstractType* Declarations::DeclareAbstractType(
     150             :     const std::string& name, bool transient, const std::string& generated,
     151             :     base::Optional<const AbstractType*> non_constexpr_version,
     152         115 :     const base::Optional<std::string>& parent) {
     153         115 :   CheckAlreadyDeclared<TypeAlias>(name, "type");
     154             :   const Type* parent_type = nullptr;
     155         115 :   if (parent) {
     156         118 :     parent_type = LookupType(QualifiedName{*parent});
     157             :   }
     158             :   const AbstractType* type = TypeOracle::GetAbstractType(
     159         345 :       parent_type, name, transient, generated, non_constexpr_version);
     160         115 :   DeclareType(name, type, false);
     161         115 :   return type;
     162             : }
     163             : 
     164        3845 : void Declarations::DeclareType(const std::string& name, const Type* type,
     165             :                                bool redeclaration) {
     166        3845 :   CheckAlreadyDeclared<TypeAlias>(name, "type");
     167       11535 :   Declare(name, std::unique_ptr<TypeAlias>(new TypeAlias(type, redeclaration)));
     168        3845 : }
     169             : 
     170          10 : StructType* Declarations::DeclareStruct(const std::string& name,
     171             :                                         const std::vector<Field>& fields) {
     172          10 :   StructType* new_type = TypeOracle::GetStructType(name, fields);
     173          10 :   DeclareType(name, new_type, false);
     174          10 :   return new_type;
     175             : }
     176             : 
     177           7 : ClassType* Declarations::DeclareClass(base::Optional<std::string> parent,
     178             :                                       const std::string& name, bool transient,
     179             :                                       const std::string& generates,
     180             :                                       std::vector<Field> fields, size_t size) {
     181             :   const Type* parent_type = nullptr;
     182           7 :   if (parent) {
     183          14 :     parent_type = LookupType(QualifiedName{*parent});
     184             :   }
     185             :   ClassType* new_type = TypeOracle::GetClassType(
     186           7 :       parent_type, name, transient, generates, std::move(fields), size);
     187           7 :   DeclareType(name, new_type, false);
     188           7 :   return new_type;
     189             : }
     190             : 
     191         783 : Macro* Declarations::CreateMacro(
     192             :     std::string external_name, std::string readable_name,
     193         783 :     base::Optional<std::string> external_assembler_name, Signature signature,
     194             :     bool transitioning, base::Optional<Statement*> body) {
     195         783 :   if (!external_assembler_name) {
     196         854 :     external_assembler_name = CurrentNamespace()->ExternalName();
     197             :   }
     198             :   return RegisterDeclarable(std::unique_ptr<Macro>(
     199             :       new Macro(std::move(external_name), std::move(readable_name),
     200             :                 std::move(*external_assembler_name), std::move(signature),
     201        4698 :                 transitioning, body)));
     202             : }
     203             : 
     204         586 : Macro* Declarations::DeclareMacro(
     205             :     const std::string& name,
     206             :     base::Optional<std::string> external_assembler_name,
     207             :     const Signature& signature, bool transitioning,
     208         586 :     base::Optional<Statement*> body, base::Optional<std::string> op) {
     209        1172 :   if (TryLookupMacro(name, signature.GetExplicitTypes())) {
     210             :     ReportError("cannot redeclare macro ", name,
     211           0 :                 " with identical explicit parameters");
     212             :   }
     213             :   Macro* macro = CreateMacro(name, name, std::move(external_assembler_name),
     214        2930 :                              signature, transitioning, body);
     215         586 :   Declare(name, macro);
     216         586 :   if (op) {
     217         306 :     if (TryLookupMacro(*op, signature.GetExplicitTypes())) {
     218             :       ReportError("cannot redeclare operator ", name,
     219           0 :                   " with identical explicit parameters");
     220             :     }
     221             :     DeclareOperator(*op, macro);
     222             :   }
     223         586 :   return macro;
     224             : }
     225             : 
     226          20 : Method* Declarations::CreateMethod(AggregateType* container_type,
     227             :                                    const std::string& name, Signature signature,
     228             :                                    bool transitioning, Statement* body) {
     229          20 :   std::string generated_name{container_type->GetGeneratedMethodName(name)};
     230             :   Method* result = RegisterDeclarable(std::unique_ptr<Method>(
     231             :       new Method(container_type, container_type->GetGeneratedMethodName(name),
     232             :                  name, CurrentNamespace()->ExternalName(), std::move(signature),
     233         120 :                  transitioning, body)));
     234             :   container_type->RegisterMethod(result);
     235          20 :   return result;
     236             : }
     237             : 
     238          49 : Intrinsic* Declarations::CreateIntrinsic(const std::string& name,
     239             :                                          const Signature& signature) {
     240             :   Intrinsic* result = RegisterDeclarable(std::unique_ptr<Intrinsic>(
     241         196 :       new Intrinsic(std::move(name), std::move(signature))));
     242          49 :   return result;
     243             : }
     244             : 
     245           0 : Intrinsic* Declarations::DeclareIntrinsic(const std::string& name,
     246             :                                           const Signature& signature) {
     247           0 :   Intrinsic* result = CreateIntrinsic(std::move(name), std::move(signature));
     248           0 :   Declare(name, result);
     249           0 :   return result;
     250             : }
     251             : 
     252         134 : Builtin* Declarations::CreateBuiltin(std::string external_name,
     253             :                                      std::string readable_name,
     254             :                                      Builtin::Kind kind, Signature signature,
     255             :                                      bool transitioning,
     256             :                                      base::Optional<Statement*> body) {
     257             :   return RegisterDeclarable(std::unique_ptr<Builtin>(
     258             :       new Builtin(std::move(external_name), std::move(readable_name), kind,
     259         670 :                   std::move(signature), transitioning, body)));
     260             : }
     261             : 
     262           0 : Builtin* Declarations::DeclareBuiltin(const std::string& name,
     263             :                                       Builtin::Kind kind,
     264             :                                       const Signature& signature,
     265             :                                       bool transitioning,
     266             :                                       base::Optional<Statement*> body) {
     267           0 :   CheckAlreadyDeclared<Builtin>(name, "builtin");
     268             :   return Declare(
     269           0 :       name, CreateBuiltin(name, name, kind, signature, transitioning, body));
     270             : }
     271             : 
     272          11 : RuntimeFunction* Declarations::DeclareRuntimeFunction(
     273             :     const std::string& name, const Signature& signature, bool transitioning) {
     274          11 :   CheckAlreadyDeclared<RuntimeFunction>(name, "runtime function");
     275             :   return Declare(name,
     276             :                  RegisterDeclarable(std::unique_ptr<RuntimeFunction>(
     277          33 :                      new RuntimeFunction(name, signature, transitioning))));
     278             : }
     279             : 
     280          70 : void Declarations::DeclareExternConstant(const std::string& name,
     281             :                                          const Type* type, std::string value) {
     282          70 :   CheckAlreadyDeclared<Value>(name, "constant");
     283         210 :   ExternConstant* result = new ExternConstant(name, type, value);
     284         140 :   Declare(name, std::unique_ptr<Declarable>(result));
     285          70 : }
     286             : 
     287          40 : NamespaceConstant* Declarations::DeclareNamespaceConstant(
     288             :     const std::string& name, const Type* type, Expression* body) {
     289          40 :   CheckAlreadyDeclared<Value>(name, "constant");
     290          80 :   NamespaceConstant* result = new NamespaceConstant(name, type, body);
     291          80 :   Declare(name, std::unique_ptr<Declarable>(result));
     292          40 :   return result;
     293             : }
     294             : 
     295          48 : Generic* Declarations::DeclareGeneric(const std::string& name,
     296             :                                       GenericDeclaration* generic) {
     297         144 :   return Declare(name, std::unique_ptr<Generic>(new Generic(name, generic)));
     298             : }
     299             : 
     300         302 : std::string Declarations::GetGeneratedCallableName(
     301             :     const std::string& name, const TypeVector& specialized_types) {
     302         302 :   std::string result = name;
     303         992 :   for (auto type : specialized_types) {
     304         388 :     std::string type_string = type->MangledName();
     305         776 :     result += std::to_string(type_string.size()) + type_string;
     306             :   }
     307         302 :   return result;
     308             : }
     309             : 
     310           0 : Macro* Declarations::DeclareOperator(const std::string& name, Macro* m) {
     311         153 :   GlobalContext::GetDefaultNamespace()->AddDeclarable(name, m);
     312           0 :   return m;
     313             : }
     314             : 
     315             : }  // namespace torque
     316             : }  // namespace internal
     317        9078 : }  // namespace v8

Generated by: LCOV version 1.10