diff options
Diffstat (limited to 'deps/v8/src/torque/types.cc')
-rw-r--r-- | deps/v8/src/torque/types.cc | 200 |
1 files changed, 157 insertions, 43 deletions
diff --git a/deps/v8/src/torque/types.cc b/deps/v8/src/torque/types.cc index 4f009a8f32..86a2020d21 100644 --- a/deps/v8/src/torque/types.cc +++ b/deps/v8/src/torque/types.cc @@ -32,6 +32,7 @@ std::string Type::ToString() const { } bool Type::IsSubtypeOf(const Type* supertype) const { + if (supertype->IsTopType()) return true; if (IsNever()) return true; if (const UnionType* union_type = UnionType::DynamicCast(supertype)) { return union_type->IsSupertypeOf(this); @@ -74,13 +75,12 @@ bool Type::IsAbstractName(const std::string& name) const { } std::string AbstractType::GetGeneratedTNodeTypeName() const { - std::string result = GetGeneratedTypeName(); - DCHECK_EQ(result.substr(0, 6), "TNode<"); - result = result.substr(6, result.length() - 7); - return result; + return generated_type_; } -std::string FunctionPointerType::ToExplicitString() const { +std::string ClassType::GetGeneratedTNodeTypeName() const { return generates_; } + +std::string BuiltinPointerType::ToExplicitString() const { std::stringstream result; result << "builtin ("; PrintCommaSeparatedList(result, parameter_types_); @@ -88,7 +88,7 @@ std::string FunctionPointerType::ToExplicitString() const { return result.str(); } -std::string FunctionPointerType::MangledName() const { +std::string BuiltinPointerType::MangledName() const { std::stringstream result; result << "FT"; for (const Type* t : parameter_types_) { @@ -184,10 +184,88 @@ const Type* SubtractType(const Type* a, const Type* b) { return TypeOracle::GetUnionType(result); } +void AggregateType::CheckForDuplicateFields() { + // Check the aggregate hierarchy and currently defined class for duplicate + // field declarations. + auto hierarchy = GetHierarchy(); + std::map<std::string, const AggregateType*> field_names; + for (const AggregateType* aggregate_type : hierarchy) { + for (const Field& field : aggregate_type->fields()) { + const std::string& field_name = field.name_and_type.name; + auto i = field_names.find(field_name); + if (i != field_names.end()) { + CurrentSourcePosition::Scope current_source_position(field.pos); + std::string aggregate_type_name = + aggregate_type->IsClassType() ? "class" : "struct"; + if (i->second == this) { + ReportError(aggregate_type_name, " '", name(), + "' declares a field with the name '", field_name, + "' more than once"); + } else { + ReportError(aggregate_type_name, " '", name(), + "' declares a field with the name '", field_name, + "' that masks an inherited field from class '", + i->second->name(), "'"); + } + } + field_names[field_name] = aggregate_type; + } + } +} + +std::vector<const AggregateType*> AggregateType::GetHierarchy() { + std::vector<const AggregateType*> hierarchy; + const AggregateType* current_container_type = this; + while (current_container_type != nullptr) { + hierarchy.push_back(current_container_type); + current_container_type = + current_container_type->IsClassType() + ? ClassType::cast(current_container_type)->GetSuperClass() + : nullptr; + } + std::reverse(hierarchy.begin(), hierarchy.end()); + return hierarchy; +} + +const Field& AggregateType::LookupField(const std::string& name) const { + for (auto& field : fields_) { + if (field.name_and_type.name == name) return field; + } + if (parent() != nullptr) { + if (auto parent_class = ClassType::DynamicCast(parent())) { + return parent_class->LookupField(name); + } + } + ReportError("no field ", name, "found"); +} + +std::string StructType::GetGeneratedTypeName() const { + return nspace()->ExternalName() + "::" + name(); +} + +std::vector<Method*> AggregateType::Methods(const std::string& name) const { + std::vector<Method*> result; + std::copy_if(methods_.begin(), methods_.end(), std::back_inserter(result), + [name](Macro* macro) { return macro->ReadableName() == name; }); + return result; +} + +std::vector<Method*> AggregateType::Constructors() const { + return Methods(kConstructMethodName); +} + std::string StructType::ToExplicitString() const { std::stringstream result; - result << "{"; - PrintCommaSeparatedList(result, fields_); + result << "struct " << name() << "{"; + PrintCommaSeparatedList(result, fields()); + result << "}"; + return result.str(); +} + +std::string ClassType::ToExplicitString() const { + std::stringstream result; + result << "class " << name() << "{"; + PrintCommaSeparatedList(result, fields()); result << "}"; return result.str(); } @@ -195,9 +273,16 @@ std::string StructType::ToExplicitString() const { void PrintSignature(std::ostream& os, const Signature& sig, bool with_names) { os << "("; for (size_t i = 0; i < sig.parameter_types.types.size(); ++i) { - if (i > 0) os << ", "; + if (i == 0 && sig.implicit_count != 0) os << "implicit "; + if (sig.implicit_count > 0 && sig.implicit_count == i) { + os << ")("; + } else { + if (i > 0) os << ", "; + } if (with_names && !sig.parameter_names.empty()) { - os << sig.parameter_names[i] << ": "; + if (i < sig.parameter_names.size()) { + os << sig.parameter_names[i] << ": "; + } } os << *sig.parameter_types.types[i]; } @@ -213,8 +298,7 @@ void PrintSignature(std::ostream& os, const Signature& sig, bool with_names) { os << " labels "; for (size_t i = 0; i < sig.labels.size(); ++i) { if (i > 0) os << ", "; - if (with_names) os << sig.labels[i].name; - + os << sig.labels[i].name; if (sig.labels[i].types.size() > 0) os << "(" << sig.labels[i].types << ")"; } } @@ -226,6 +310,14 @@ std::ostream& operator<<(std::ostream& os, const NameAndType& name_and_type) { return os; } +std::ostream& operator<<(std::ostream& os, const Field& field) { + os << field.name_and_type; + if (field.is_weak) { + os << " (weak)"; + } + return os; +} + std::ostream& operator<<(std::ostream& os, const Signature& sig) { PrintSignature(os, sig, true); return os; @@ -245,8 +337,15 @@ std::ostream& operator<<(std::ostream& os, const ParameterTypes& p) { return os; } -bool Signature::HasSameTypesAs(const Signature& other) const { - if (!(parameter_types.types == other.parameter_types.types && +bool Signature::HasSameTypesAs(const Signature& other, + ParameterMode mode) const { + auto compare_types = GetTypes(); + auto other_compare_types = other.GetTypes(); + if (mode == ParameterMode::kIgnoreImplicit) { + compare_types = GetExplicitTypes(); + other_compare_types = other.GetExplicitTypes(); + } + if (!(compare_types == other_compare_types && parameter_types.var_args == other.parameter_types.var_args && return_type == other.return_type)) { return false; @@ -269,43 +368,58 @@ bool IsAssignableFrom(const Type* to, const Type* from) { return TypeOracle::IsImplicitlyConvertableFrom(to, from); } -bool IsCompatibleSignature(const Signature& sig, const TypeVector& types, - const std::vector<Label*>& labels) { - auto i = sig.parameter_types.types.begin(); - if (sig.parameter_types.types.size() > types.size()) return false; - // TODO(danno): The test below is actually insufficient. The labels' - // parameters must be checked too. ideally, the named part of - // LabelDeclarationVector would be factored out so that the label count and - // parameter types could be passed separately. - if (sig.labels.size() != labels.size()) return false; - for (auto current : types) { - if (i == sig.parameter_types.types.end()) { - if (!sig.parameter_types.var_args) return false; - if (!IsAssignableFrom(TypeOracle::GetObjectType(), current)) return false; - } else { - if (!IsAssignableFrom(*i++, current)) return false; - } - } - return true; -} - bool operator<(const Type& a, const Type& b) { return a.MangledName() < b.MangledName(); } -VisitResult ProjectStructField(VisitResult structure, +VisitResult ProjectStructField(const StructType* original_struct, + VisitResult structure, const std::string& fieldname) { - DCHECK(structure.IsOnStack()); BottomOffset begin = structure.stack_range().begin(); + + // Check constructor this super classes for fields. const StructType* type = StructType::cast(structure.type()); - for (auto& field : type->fields()) { - BottomOffset end = begin + LoweredSlotCount(field.type); - if (field.name == fieldname) { - return VisitResult(field.type, StackRange{begin, end}); + auto& fields = type->fields(); + for (auto& field : fields) { + BottomOffset end = begin + LoweredSlotCount(field.name_and_type.type); + if (field.name_and_type.name == fieldname) { + return VisitResult(field.name_and_type.type, StackRange{begin, end}); } begin = end; } - UNREACHABLE(); + + if (fields.size() > 0 && + fields[0].name_and_type.name == kConstructorStructSuperFieldName) { + structure = ProjectStructField(original_struct, structure, + kConstructorStructSuperFieldName); + return ProjectStructField(original_struct, structure, fieldname); + } else { + base::Optional<const ClassType*> class_type = + original_struct->GetDerivedFrom(); + if (original_struct == type) { + if (class_type) { + ReportError("class '", (*class_type)->name(), + "' doesn't contain a field '", fieldname, "'"); + } else { + ReportError("struct '", original_struct->name(), + "' doesn't contain a field '", fieldname, "'"); + } + } else { + DCHECK(class_type); + ReportError( + "class '", (*class_type)->name(), + "' or one of its derived-from classes doesn't contain a field '", + fieldname, "'"); + } + } +} + +VisitResult ProjectStructField(VisitResult structure, + const std::string& fieldname) { + DCHECK(structure.IsOnStack()); + DCHECK(structure.type()->IsStructType()); + const StructType* type = StructType::cast(structure.type()); + return ProjectStructField(type, structure, fieldname); } namespace { @@ -314,8 +428,8 @@ void AppendLoweredTypes(const Type* type, std::vector<const Type*>* result) { if (type->IsConstexpr()) return; if (type == TypeOracle::GetVoidType()) return; if (auto* s = StructType::DynamicCast(type)) { - for (const NameAndType& field : s->fields()) { - AppendLoweredTypes(field.type, result); + for (const Field& field : s->fields()) { + AppendLoweredTypes(field.name_and_type.type, result); } } else { result->push_back(type); |