LCOV - code coverage report
Current view: top level - src/torque - declarations.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 143 162 88.3 %
Date: 2019-03-21 Functions: 39 42 92.9 %

          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/server-data.h"
       9             : #include "src/torque/type-oracle.h"
      10             : 
      11             : namespace v8 {
      12             : namespace internal {
      13             : namespace torque {
      14             : 
      15       69652 : DEFINE_CONTEXTUAL_VARIABLE(GlobalContext)
      16             : 
      17             : namespace {
      18             : 
      19             : template <class T>
      20       20538 : std::vector<T> EnsureNonempty(std::vector<T> list, const std::string& name,
      21             :                               const char* kind) {
      22       20538 :   if (list.empty()) {
      23           0 :     ReportError("there is no ", kind, " named ", name);
      24             :   }
      25       20538 :   return std::move(list);
      26             : }
      27             : 
      28             : template <class T, class Name>
      29      131725 : T EnsureUnique(const std::vector<T>& list, const Name& name, const char* kind) {
      30      131725 :   if (list.empty()) {
      31           0 :     ReportError("there is no ", kind, " named ", name);
      32             :   }
      33      131725 :   if (list.size() >= 2) {
      34           0 :     ReportError("ambiguous reference to ", kind, " ", name);
      35             :   }
      36      131725 :   return list.front();
      37             : }
      38             : 
      39             : template <class T>
      40        5603 : void CheckAlreadyDeclared(const std::string& name, const char* new_type) {
      41             :   std::vector<T*> declarations =
      42       16809 :       FilterDeclarables<T>(Declarations::TryLookupShallow(QualifiedName(name)));
      43        5603 :   if (!declarations.empty()) {
      44           0 :     Scope* scope = CurrentScope::Get();
      45           0 :     ReportError("cannot redeclare ", name, " (type ", new_type, scope, ")");
      46             :   }
      47        5603 : }
      48             : 
      49             : }  // namespace
      50             : 
      51      115152 : std::vector<Declarable*> Declarations::LookupGlobalScope(
      52             :     const std::string& name) {
      53             :   std::vector<Declarable*> d =
      54      345456 :       GlobalContext::GetDefaultNamespace()->Lookup(QualifiedName(name));
      55      115152 :   if (d.empty()) {
      56           0 :     std::stringstream s;
      57           0 :     s << "cannot find \"" << name << "\" in global scope";
      58           0 :     ReportError(s.str());
      59             :   }
      60      115152 :   return d;
      61             : }
      62             : 
      63       15502 : const TypeAlias* Declarations::LookupTypeAlias(const QualifiedName& name) {
      64             :   TypeAlias* declaration =
      65       46506 :       EnsureUnique(FilterDeclarables<TypeAlias>(Lookup(name)), name, "type");
      66       15502 :   return declaration;
      67             : }
      68             : 
      69          17 : const Type* Declarations::LookupType(const QualifiedName& name) {
      70        1921 :   return LookupTypeAlias(name)->type();
      71             : }
      72             : 
      73        1904 : const Type* Declarations::LookupType(std::string name) {
      74        5712 :   return LookupType(QualifiedName(std::move(name)));
      75             : }
      76             : 
      77      115152 : const Type* Declarations::LookupGlobalType(const std::string& name) {
      78             :   TypeAlias* declaration = EnsureUnique(
      79      345456 :       FilterDeclarables<TypeAlias>(LookupGlobalScope(name)), name, "type");
      80      115152 :   return declaration->type();
      81             : }
      82             : 
      83       13620 : const Type* Declarations::GetType(TypeExpression* type_expression) {
      84       13620 :   if (auto* basic = BasicTypeExpression::DynamicCast(type_expression)) {
      85             :     std::string name =
      86       13512 :         (basic->is_constexpr ? CONSTEXPR_TYPE_PREFIX : "") + basic->name;
      87             :     const TypeAlias* alias =
      88       40536 :         LookupTypeAlias(QualifiedName{basic->namespace_qualification, name});
      89       13512 :     if (GlobalContext::collect_language_server_data()) {
      90             :       LanguageServerData::AddDefinition(type_expression->pos,
      91           3 :                                         alias->GetDeclarationPosition());
      92             :     }
      93             :     return alias->type();
      94         108 :   } else if (auto* union_type = UnionTypeExpression::cast(type_expression)) {
      95          97 :     return TypeOracle::GetUnionType(GetType(union_type->a),
      96          97 :                                     GetType(union_type->b));
      97             :   } else {
      98             :     auto* function_type_exp = FunctionTypeExpression::cast(type_expression);
      99             :     TypeVector argument_types;
     100          44 :     for (TypeExpression* type_exp : function_type_exp->parameters) {
     101          66 :       argument_types.push_back(GetType(type_exp));
     102             :     }
     103          22 :     return TypeOracle::GetBuiltinPointerType(
     104          11 :         argument_types, GetType(function_type_exp->return_type));
     105             :   }
     106             : }
     107             : 
     108          10 : Builtin* Declarations::FindSomeInternalBuiltinWithType(
     109             :     const BuiltinPointerType* type) {
     110       25283 :   for (auto& declarable : GlobalContext::AllDeclarables()) {
     111       25283 :     if (Builtin* builtin = Builtin::DynamicCast(declarable.get())) {
     112        3051 :       if (!builtin->IsExternal() && builtin->kind() == Builtin::kStub &&
     113        1968 :           builtin->signature().return_type == type->return_type() &&
     114         180 :           builtin->signature().parameter_types.types ==
     115             :               type->parameter_types()) {
     116             :         return builtin;
     117             :       }
     118             :     }
     119             :   }
     120             :   return nullptr;
     121             : }
     122             : 
     123         997 : Value* Declarations::LookupValue(const QualifiedName& name) {
     124        2991 :   return EnsureUnique(FilterDeclarables<Value>(Lookup(name)), name, "value");
     125             : }
     126             : 
     127        1774 : Macro* Declarations::TryLookupMacro(const std::string& name,
     128             :                                     const TypeVector& types) {
     129        3548 :   std::vector<Macro*> macros = TryLookup<Macro>(QualifiedName(name));
     130        2695 :   for (auto& m : macros) {
     131         921 :     auto signature_types = m->signature().GetExplicitTypes();
     132         921 :     if (signature_types == types && !m->signature().parameter_types.var_args) {
     133           0 :       return m;
     134             :     }
     135             :   }
     136             :   return nullptr;
     137             : }
     138             : 
     139        1071 : base::Optional<Builtin*> Declarations::TryLookupBuiltin(
     140             :     const QualifiedName& name) {
     141        1071 :   std::vector<Builtin*> builtins = TryLookup<Builtin>(name);
     142        1071 :   if (builtins.empty()) return base::nullopt;
     143           4 :   return EnsureUnique(builtins, name.name, "builtin");
     144             : }
     145             : 
     146       20538 : std::vector<Generic*> Declarations::LookupGeneric(const std::string& name) {
     147       82152 :   return EnsureNonempty(FilterDeclarables<Generic>(Lookup(QualifiedName(name))),
     148       41076 :                         name, "generic");
     149             : }
     150             : 
     151          70 : Generic* Declarations::LookupUniqueGeneric(const QualifiedName& name) {
     152         210 :   return EnsureUnique(FilterDeclarables<Generic>(Lookup(name)), name,
     153         140 :                       "generic");
     154             : }
     155             : 
     156          39 : Namespace* Declarations::DeclareNamespace(const std::string& name) {
     157         117 :   return Declare(name, std::unique_ptr<Namespace>(new Namespace(name)));
     158             : }
     159             : 
     160         133 : const AbstractType* Declarations::DeclareAbstractType(
     161             :     const Identifier* name, bool transient, std::string generated,
     162             :     base::Optional<const AbstractType*> non_constexpr_version,
     163             :     const base::Optional<Identifier*>& parent) {
     164         133 :   CheckAlreadyDeclared<TypeAlias>(name->value, "type");
     165             :   const Type* parent_type = nullptr;
     166         133 :   if (parent) {
     167         207 :     auto parent_type_alias = LookupTypeAlias(QualifiedName{(*parent)->value});
     168             :     parent_type = parent_type_alias->type();
     169          69 :     if (GlobalContext::collect_language_server_data()) {
     170           1 :       LanguageServerData::AddDefinition(
     171           1 :           (*parent)->pos, parent_type_alias->GetDeclarationPosition());
     172             :     }
     173             :   }
     174         133 :   if (generated == "" && parent) {
     175          74 :     generated = parent_type->GetGeneratedTNodeTypeName();
     176             :   }
     177         399 :   const AbstractType* type = TypeOracle::GetAbstractType(
     178         133 :       parent_type, name->value, transient, generated, non_constexpr_version);
     179         133 :   DeclareType(name, type, false);
     180         133 :   return type;
     181             : }
     182             : 
     183        5334 : void Declarations::DeclareType(const Identifier* name, const Type* type,
     184             :                                bool redeclaration) {
     185        5334 :   CheckAlreadyDeclared<TypeAlias>(name->value, "type");
     186       10668 :   Declare(name->value, std::unique_ptr<TypeAlias>(
     187        5334 :                            new TypeAlias(type, redeclaration, name->pos)));
     188        5334 : }
     189             : 
     190          14 : StructType* Declarations::DeclareStruct(const Identifier* name) {
     191          14 :   StructType* new_type = TypeOracle::GetStructType(name->value);
     192          14 :   DeclareType(name, new_type, false);
     193          14 :   return new_type;
     194             : }
     195             : 
     196          89 : ClassType* Declarations::DeclareClass(const Type* super_type,
     197             :                                       const Identifier* name, bool is_extern,
     198             :                                       bool transient,
     199             :                                       const std::string& generates) {
     200          89 :   ClassType* new_type = TypeOracle::GetClassType(
     201          89 :       super_type, name->value, is_extern, transient, generates);
     202          89 :   DeclareType(name, new_type, false);
     203          89 :   return new_type;
     204             : }
     205             : 
     206        1338 : Macro* Declarations::CreateMacro(
     207             :     std::string external_name, std::string readable_name,
     208             :     base::Optional<std::string> external_assembler_name, Signature signature,
     209             :     bool transitioning, base::Optional<Statement*> body) {
     210        1338 :   if (!external_assembler_name) {
     211        1852 :     external_assembler_name = CurrentNamespace()->ExternalName();
     212             :   }
     213        6690 :   return RegisterDeclarable(std::unique_ptr<Macro>(
     214             :       new Macro(std::move(external_name), std::move(readable_name),
     215             :                 std::move(*external_assembler_name), std::move(signature),
     216        4014 :                 transitioning, body)));
     217             : }
     218             : 
     219        1139 : Macro* Declarations::DeclareMacro(
     220             :     const std::string& name,
     221             :     base::Optional<std::string> external_assembler_name,
     222             :     const Signature& signature, bool transitioning,
     223             :     base::Optional<Statement*> body, base::Optional<std::string> op) {
     224        2278 :   if (TryLookupMacro(name, signature.GetExplicitTypes())) {
     225             :     ReportError("cannot redeclare macro ", name,
     226           0 :                 " with identical explicit parameters");
     227             :   }
     228        4556 :   Macro* macro = CreateMacro(name, name, std::move(external_assembler_name),
     229        1139 :                              signature, transitioning, body);
     230        1139 :   Declare(name, macro);
     231        1139 :   if (op) {
     232        1270 :     if (TryLookupMacro(*op, signature.GetExplicitTypes())) {
     233             :       ReportError("cannot redeclare operator ", name,
     234           0 :                   " with identical explicit parameters");
     235             :     }
     236         635 :     DeclareOperator(*op, macro);
     237             :   }
     238        1139 :   return macro;
     239             : }
     240             : 
     241          32 : Method* Declarations::CreateMethod(AggregateType* container_type,
     242             :                                    const std::string& name, Signature signature,
     243             :                                    bool transitioning, Statement* body) {
     244          32 :   std::string generated_name{container_type->GetGeneratedMethodName(name)};
     245          96 :   Method* result = RegisterDeclarable(std::unique_ptr<Method>(
     246          64 :       new Method(container_type, container_type->GetGeneratedMethodName(name),
     247          64 :                  name, CurrentNamespace()->ExternalName(), std::move(signature),
     248          64 :                  transitioning, body)));
     249             :   container_type->RegisterMethod(result);
     250          32 :   return result;
     251             : }
     252             : 
     253          66 : Intrinsic* Declarations::CreateIntrinsic(const std::string& name,
     254             :                                          const Signature& signature) {
     255         198 :   Intrinsic* result = RegisterDeclarable(std::unique_ptr<Intrinsic>(
     256         132 :       new Intrinsic(std::move(name), std::move(signature))));
     257          66 :   return result;
     258             : }
     259             : 
     260           0 : Intrinsic* Declarations::DeclareIntrinsic(const std::string& name,
     261             :                                           const Signature& signature) {
     262           0 :   Intrinsic* result = CreateIntrinsic(std::move(name), std::move(signature));
     263           0 :   Declare(name, result);
     264           0 :   return result;
     265             : }
     266             : 
     267         196 : Builtin* Declarations::CreateBuiltin(std::string external_name,
     268             :                                      std::string readable_name,
     269             :                                      Builtin::Kind kind, Signature signature,
     270             :                                      bool transitioning,
     271             :                                      base::Optional<Statement*> body) {
     272         784 :   return RegisterDeclarable(std::unique_ptr<Builtin>(
     273             :       new Builtin(std::move(external_name), std::move(readable_name), kind,
     274         588 :                   std::move(signature), transitioning, body)));
     275             : }
     276             : 
     277           0 : Builtin* Declarations::DeclareBuiltin(const std::string& name,
     278             :                                       Builtin::Kind kind,
     279             :                                       const Signature& signature,
     280             :                                       bool transitioning,
     281             :                                       base::Optional<Statement*> body) {
     282           0 :   CheckAlreadyDeclared<Builtin>(name, "builtin");
     283           0 :   return Declare(
     284           0 :       name, CreateBuiltin(name, name, kind, signature, transitioning, body));
     285             : }
     286             : 
     287          16 : RuntimeFunction* Declarations::DeclareRuntimeFunction(
     288             :     const std::string& name, const Signature& signature, bool transitioning) {
     289          16 :   CheckAlreadyDeclared<RuntimeFunction>(name, "runtime function");
     290          48 :   return Declare(name,
     291             :                  RegisterDeclarable(std::unique_ptr<RuntimeFunction>(
     292          48 :                      new RuntimeFunction(name, signature, transitioning))));
     293             : }
     294             : 
     295          89 : void Declarations::DeclareExternConstant(Identifier* name, const Type* type,
     296             :                                          std::string value) {
     297          89 :   CheckAlreadyDeclared<Value>(name->value, "constant");
     298         178 :   ExternConstant* result = new ExternConstant(name, type, value);
     299         178 :   Declare(name->value, std::unique_ptr<Declarable>(result));
     300          89 : }
     301             : 
     302          31 : NamespaceConstant* Declarations::DeclareNamespaceConstant(Identifier* name,
     303             :                                                           const Type* type,
     304             :                                                           Expression* body) {
     305          31 :   CheckAlreadyDeclared<Value>(name->value, "constant");
     306          31 :   NamespaceConstant* result = new NamespaceConstant(name, type, body);
     307          62 :   Declare(name->value, std::unique_ptr<Declarable>(result));
     308          31 :   return result;
     309             : }
     310             : 
     311          45 : Generic* Declarations::DeclareGeneric(const std::string& name,
     312             :                                       GenericDeclaration* generic) {
     313         135 :   return Declare(name, std::unique_ptr<Generic>(new Generic(name, generic)));
     314             : }
     315             : 
     316         319 : std::string Declarations::GetGeneratedCallableName(
     317             :     const std::string& name, const TypeVector& specialized_types) {
     318             :   std::string result = name;
     319         780 :   for (auto type : specialized_types) {
     320         461 :     std::string type_string = type->MangledName();
     321        1383 :     result += std::to_string(type_string.size()) + type_string;
     322             :   }
     323         319 :   return result;
     324             : }
     325             : 
     326         635 : Macro* Declarations::DeclareOperator(const std::string& name, Macro* m) {
     327             :   GlobalContext::GetDefaultNamespace()->AddDeclarable(name, m);
     328         635 :   return m;
     329             : }
     330             : 
     331             : }  // namespace torque
     332             : }  // namespace internal
     333        6150 : }  // namespace v8

Generated by: LCOV version 1.10