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

Generated by: LCOV version 1.10