aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPhilip Herron <philip.herron@embecosm.com>2021-02-25 17:44:42 +0000
committerPhilip Herron <herron.philip@googlemail.com>2021-03-03 22:46:24 +0000
commita886a9c06ed237a2fa8cff9d708f694066b18e66 (patch)
tree6805a79a9dbecc5d6975e1ace93a91517beb612e /gcc
parente76855ab401d70361cc8c1738d95127b6f45df86 (diff)
downloadgcc-a886a9c06ed237a2fa8cff9d708f694066b18e66.zip
gcc-a886a9c06ed237a2fa8cff9d708f694066b18e66.tar.gz
gcc-a886a9c06ed237a2fa8cff9d708f694066b18e66.tar.bz2
Add in TyTy support for an initial String Literal
This gives the apropriate reference type over const char *. Fixes #85
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/backend/rust-compile-context.h10
-rw-r--r--gcc/rust/backend/rust-compile-expr.h8
-rw-r--r--gcc/rust/backend/rust-compile-tyty.h7
-rw-r--r--gcc/rust/resolve/rust-ast-resolve.cc2
-rw-r--r--gcc/rust/rust-backend.h3
-rw-r--r--gcc/rust/rust-gcc.cc13
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-expr.h10
-rw-r--r--gcc/rust/typecheck/rust-tyty-call.h2
-rw-r--r--gcc/rust/typecheck/rust-tyty-rules.h30
-rw-r--r--gcc/rust/typecheck/rust-tyty-visitor.h1
-rw-r--r--gcc/rust/typecheck/rust-tyty.cc31
-rw-r--r--gcc/rust/typecheck/rust-tyty.h26
-rw-r--r--gcc/testsuite/rust.test/compilable/str1.rs7
13 files changed, 145 insertions, 5 deletions
diff --git a/gcc/rust/backend/rust-compile-context.h b/gcc/rust/backend/rust-compile-context.h
index b191554..a4c32d8 100644
--- a/gcc/rust/backend/rust-compile-context.h
+++ b/gcc/rust/backend/rust-compile-context.h
@@ -268,8 +268,6 @@ public:
return compiler.translated;
}
- virtual ~TyTyResolveCompile () {}
-
void visit (TyTy::ErrorType &) override { gcc_unreachable (); }
void visit (TyTy::InferType &) override { gcc_unreachable (); }
@@ -460,6 +458,14 @@ public:
translated = ctx->get_backend ()->reference_type (base_compiled_type);
}
+ void visit (TyTy::StrType &type) override
+ {
+ ::Btype *compiled_type = nullptr;
+ bool ok = ctx->lookup_compiled_types (type.get_ty_ref (), &compiled_type);
+ rust_assert (ok);
+ translated = compiled_type;
+ }
+
private:
TyTyResolveCompile (Context *ctx) : ctx (ctx) {}
diff --git a/gcc/rust/backend/rust-compile-expr.h b/gcc/rust/backend/rust-compile-expr.h
index 86d4062..b48d79e 100644
--- a/gcc/rust/backend/rust-compile-expr.h
+++ b/gcc/rust/backend/rust-compile-expr.h
@@ -225,6 +225,14 @@ public:
}
return;
+ case HIR::Literal::STRING: {
+ auto base = ctx->get_backend ()->string_constant_expression (
+ literal_value->as_string ());
+ translated
+ = ctx->get_backend ()->address_expression (base, expr.get_locus ());
+ }
+ return;
+
default:
rust_fatal_error (expr.get_locus (), "unknown literal");
return;
diff --git a/gcc/rust/backend/rust-compile-tyty.h b/gcc/rust/backend/rust-compile-tyty.h
index 683a9a7..e043a50 100644
--- a/gcc/rust/backend/rust-compile-tyty.h
+++ b/gcc/rust/backend/rust-compile-tyty.h
@@ -209,6 +209,13 @@ public:
Linemap::predeclared_location ());
}
+ void visit (TyTy::StrType &) override
+ {
+ Btype *raw_str = backend->raw_str_type ();
+ translated
+ = backend->named_type ("str", raw_str, Linemap::predeclared_location ());
+ }
+
private:
TyTyCompile (::Backend *backend)
: backend (backend), translated (nullptr),
diff --git a/gcc/rust/resolve/rust-ast-resolve.cc b/gcc/rust/resolve/rust-ast-resolve.cc
index 04fdad7..65750a9 100644
--- a/gcc/rust/resolve/rust-ast-resolve.cc
+++ b/gcc/rust/resolve/rust-ast-resolve.cc
@@ -157,6 +157,7 @@ Resolver::generate_builtins ()
auto usize = new TyTy::USizeType (mappings->get_next_hir_id ());
auto isize = new TyTy::ISizeType (mappings->get_next_hir_id ());
auto char_tyty = new TyTy::CharType (mappings->get_next_hir_id ());
+ auto str = new TyTy::StrType (mappings->get_next_hir_id ());
MKBUILTIN_TYPE ("u8", builtins, u8);
MKBUILTIN_TYPE ("u16", builtins, u16);
@@ -174,6 +175,7 @@ Resolver::generate_builtins ()
MKBUILTIN_TYPE ("usize", builtins, usize);
MKBUILTIN_TYPE ("isize", builtins, isize);
MKBUILTIN_TYPE ("char", builtins, char_tyty);
+ MKBUILTIN_TYPE ("str", builtins, str);
// unit type ()
TyTy::UnitType *unit_tyty = new TyTy::UnitType (mappings->get_next_hir_id ());
diff --git a/gcc/rust/rust-backend.h b/gcc/rust/rust-backend.h
index 183f41a..700a376 100644
--- a/gcc/rust/rust-backend.h
+++ b/gcc/rust/rust-backend.h
@@ -116,6 +116,9 @@ public:
// Get the Host pointer size in bits
virtual int get_pointer_size () = 0;
+ // Get the raw str type const char*
+ virtual Btype *raw_str_type () = 0;
+
// Get an unnamed integer type with the given signedness and number
// of bits.
virtual Btype *integer_type (bool is_unsigned, int bits) = 0;
diff --git a/gcc/rust/rust-gcc.cc b/gcc/rust/rust-gcc.cc
index f8033af..9a13332 100644
--- a/gcc/rust/rust-gcc.cc
+++ b/gcc/rust/rust-gcc.cc
@@ -187,6 +187,8 @@ public:
int get_pointer_size ();
+ Btype *raw_str_type ();
+
Btype *integer_type (bool, int);
Btype *float_type (int);
@@ -804,6 +806,14 @@ Gcc_backend::get_pointer_size ()
}
Btype *
+Gcc_backend::raw_str_type ()
+{
+ tree char_ptr = build_pointer_type (char_type_node);
+ tree const_char_type = build_qualified_type (char_ptr, TYPE_QUAL_CONST);
+ return this->make_type (const_char_type);
+}
+
+Btype *
Gcc_backend::integer_type (bool is_unsigned, int bits)
{
tree type;
@@ -1427,8 +1437,7 @@ Bexpression *
Gcc_backend::string_constant_expression (const std::string &val)
{
tree index_type = build_index_type (size_int (val.length ()));
- tree const_char_type
- = build_qualified_type (unsigned_char_type_node, TYPE_QUAL_CONST);
+ tree const_char_type = build_qualified_type (char_type_node, TYPE_QUAL_CONST);
tree string_type = build_array_type (const_char_type, index_type);
TYPE_STRING_FLAG (string_type) = 1;
tree string_val = build_string (val.length (), val.data ());
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h
index b72b308..3cc0da8 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h
@@ -454,6 +454,16 @@ public:
}
break;
+ case HIR::Literal::LitType::STRING: {
+ TyTy::BaseType *base = nullptr;
+ auto ok = context->lookup_builtin ("str", &base);
+ rust_assert (ok);
+
+ infered = new TyTy::ReferenceType (expr.get_mappings ().get_hirid (),
+ base->get_ref ());
+ }
+ break;
+
default:
gcc_unreachable ();
break;
diff --git a/gcc/rust/typecheck/rust-tyty-call.h b/gcc/rust/typecheck/rust-tyty-call.h
index 612a5e8..2e65244 100644
--- a/gcc/rust/typecheck/rust-tyty-call.h
+++ b/gcc/rust/typecheck/rust-tyty-call.h
@@ -53,6 +53,7 @@ public:
void visit (CharType &type) override { gcc_unreachable (); }
void visit (ReferenceType &type) override { gcc_unreachable (); }
void visit (ParamType &) override { gcc_unreachable (); }
+ void visit (StrType &) override { gcc_unreachable (); }
// tuple-structs
void visit (ADTType &type) override;
@@ -98,6 +99,7 @@ public:
void visit (CharType &type) override { gcc_unreachable (); }
void visit (ReferenceType &type) override { gcc_unreachable (); }
void visit (ParamType &) override { gcc_unreachable (); }
+ void visit (StrType &) override { gcc_unreachable (); }
// call fns
void visit (FnType &type) override;
diff --git a/gcc/rust/typecheck/rust-tyty-rules.h b/gcc/rust/typecheck/rust-tyty-rules.h
index ef7a60c..59c1890 100644
--- a/gcc/rust/typecheck/rust-tyty-rules.h
+++ b/gcc/rust/typecheck/rust-tyty-rules.h
@@ -231,6 +231,14 @@ public:
gcc_unreachable ();
}
+ virtual void visit (StrType &type) override
+ {
+ Location ref_locus = mappings->lookup_location (type.get_ref ());
+ rust_error_at (ref_locus, "expected [%s] got [%s]",
+ get_base ()->as_string ().c_str (),
+ type.as_string ().c_str ());
+ }
+
protected:
BaseRules (BaseType *base)
: mappings (Analysis::Mappings::get ()),
@@ -866,6 +874,13 @@ public:
auto other_base_type = type.get_base ();
TyTy::BaseType *base_resolved = base_type->unify (other_base_type);
+ if (base_resolved == nullptr
+ || base_resolved->get_kind () == TypeKind::ERROR)
+ {
+ BaseRules::visit (type);
+ return;
+ }
+
resolved = new ReferenceType (base->get_ref (), base->get_ty_ref (),
base_resolved->get_ref ());
}
@@ -916,6 +931,21 @@ private:
ParamType *base;
};
+class StrRules : public BaseRules
+{
+ // FIXME we will need a enum for the StrType like ByteBuf etc..
+
+public:
+ StrRules (StrType *base) : BaseRules (base), base (base) {}
+
+ void visit (StrType &type) override { resolved = type.clone (); }
+
+private:
+ BaseType *get_base () override { return base; }
+
+ StrType *base;
+};
+
} // namespace TyTy
} // namespace Rust
diff --git a/gcc/rust/typecheck/rust-tyty-visitor.h b/gcc/rust/typecheck/rust-tyty-visitor.h
index b49085d..61fd905 100644
--- a/gcc/rust/typecheck/rust-tyty-visitor.h
+++ b/gcc/rust/typecheck/rust-tyty-visitor.h
@@ -43,6 +43,7 @@ public:
virtual void visit (CharType &type) = 0;
virtual void visit (ReferenceType &type) = 0;
virtual void visit (ParamType &type) = 0;
+ virtual void visit (StrType &type) = 0;
};
} // namespace TyTy
diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc
index 7fbef0c..4894f06 100644
--- a/gcc/rust/typecheck/rust-tyty.cc
+++ b/gcc/rust/typecheck/rust-tyty.cc
@@ -799,6 +799,37 @@ ParamType::resolve ()
return lookup;
}
+BaseType *
+StrType::clone ()
+{
+ return new StrType (get_ref (), get_ty_ref (), get_combined_refs ());
+}
+
+void
+StrType::accept_vis (TyVisitor &vis)
+{
+ vis.visit (*this);
+}
+
+std::string
+StrType::as_string () const
+{
+ return "str";
+}
+
+BaseType *
+StrType::unify (BaseType *other)
+{
+ StrRules r (this);
+ return r.unify (other);
+}
+
+bool
+StrType::is_equal (const BaseType &other) const
+{
+ return get_kind () == other.get_kind ();
+}
+
// rust-tyty-call.h
void
diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h
index 8f71748..4812932 100644
--- a/gcc/rust/typecheck/rust-tyty.h
+++ b/gcc/rust/typecheck/rust-tyty.h
@@ -809,7 +809,7 @@ public:
BaseType *unify (BaseType *other) override;
- virtual bool is_equal (const BaseType &other) const override;
+ bool is_equal (const BaseType &other) const override;
BaseType *clone () final override;
@@ -817,6 +817,30 @@ private:
HirId base;
};
+class StrType : public BaseType
+{
+public:
+ StrType (HirId ref, std::set<HirId> refs = std::set<HirId> ())
+ : BaseType (ref, ref, TypeKind::STR)
+ {}
+
+ StrType (HirId ref, HirId ty_ref, std::set<HirId> refs = std::set<HirId> ())
+ : BaseType (ref, ty_ref, TypeKind::STR)
+ {}
+
+ std::string get_name () const override final { return as_string (); }
+
+ void accept_vis (TyVisitor &vis) override;
+
+ std::string as_string () const override;
+
+ BaseType *unify (BaseType *other) override;
+
+ bool is_equal (const BaseType &other) const override;
+
+ BaseType *clone () final override;
+};
+
} // namespace TyTy
} // namespace Rust
diff --git a/gcc/testsuite/rust.test/compilable/str1.rs b/gcc/testsuite/rust.test/compilable/str1.rs
new file mode 100644
index 0000000..08882785
--- /dev/null
+++ b/gcc/testsuite/rust.test/compilable/str1.rs
@@ -0,0 +1,7 @@
+fn main() {
+ let a;
+ a = "hello world infer";
+
+ let b: &str;
+ b = "hello world specified";
+}