aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPhilip Herron <philip.herron@embecosm.com>2021-02-11 15:04:26 +0000
committerPhilip Herron <herron.philip@googlemail.com>2021-02-13 09:54:47 +0000
commit3ae8d55860cbe95f80d5e5c76ca71883dbde0e10 (patch)
tree3fc0385c18fe11a4ceb8ae34ad3c208f027efebb /gcc
parentfac8276f737351afbde34a85f2b6c224b400313b (diff)
downloadgcc-3ae8d55860cbe95f80d5e5c76ca71883dbde0e10.zip
gcc-3ae8d55860cbe95f80d5e5c76ca71883dbde0e10.tar.gz
gcc-3ae8d55860cbe95f80d5e5c76ca71883dbde0e10.tar.bz2
Add char type
This might need changes in the Lexer to allow for wchar_t to be preserved. Addresses #85
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/backend/rust-compile-context.h8
-rw-r--r--gcc/rust/backend/rust-compile-expr.h7
-rw-r--r--gcc/rust/backend/rust-compile-tyty.h6
-rw-r--r--gcc/rust/resolve/rust-ast-resolve.cc2
-rw-r--r--gcc/rust/rust-backend.h9
-rw-r--r--gcc/rust/rust-gcc.cc20
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-expr.h6
-rw-r--r--gcc/rust/typecheck/rust-tyty-call.h2
-rw-r--r--gcc/rust/typecheck/rust-tyty-rules.h43
-rw-r--r--gcc/rust/typecheck/rust-tyty-visitor.h1
-rw-r--r--gcc/rust/typecheck/rust-tyty.cc27
-rw-r--r--gcc/rust/typecheck/rust-tyty.h20
-rw-r--r--gcc/testsuite/rust.test/compilable/char1.rs4
13 files changed, 155 insertions, 0 deletions
diff --git a/gcc/rust/backend/rust-compile-context.h b/gcc/rust/backend/rust-compile-context.h
index 76255b0..3955a5b 100644
--- a/gcc/rust/backend/rust-compile-context.h
+++ b/gcc/rust/backend/rust-compile-context.h
@@ -437,6 +437,14 @@ public:
translated = compiled_type;
}
+ void visit (TyTy::CharType &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 1e4aef6..c63479c 100644
--- a/gcc/rust/backend/rust-compile-expr.h
+++ b/gcc/rust/backend/rust-compile-expr.h
@@ -218,6 +218,13 @@ public:
}
return;
+ case HIR::Literal::CHAR: {
+ // FIXME needs wchar_t
+ char c = literal_value->as_string ().c_str ()[0];
+ translated = ctx->get_backend ()->wchar_constant_expression (c);
+ }
+ 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 0629cbe..f591696 100644
--- a/gcc/rust/backend/rust-compile-tyty.h
+++ b/gcc/rust/backend/rust-compile-tyty.h
@@ -201,6 +201,12 @@ public:
Linemap::predeclared_location ());
}
+ void visit (TyTy::CharType &) override
+ {
+ translated = backend->named_type ("char", backend->wchar_type (),
+ 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 4f7382a..ddba7f2 100644
--- a/gcc/rust/resolve/rust-ast-resolve.cc
+++ b/gcc/rust/resolve/rust-ast-resolve.cc
@@ -156,6 +156,7 @@ Resolver::generate_builtins ()
= new TyTy::FloatType (mappings->get_next_hir_id (), TyTy::FloatType::F64);
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 ());
MKBUILTIN_TYPE ("u8", builtins, u8);
MKBUILTIN_TYPE ("u16", builtins, u16);
@@ -172,6 +173,7 @@ Resolver::generate_builtins ()
MKBUILTIN_TYPE ("f64", builtins, f64);
MKBUILTIN_TYPE ("usize", builtins, usize);
MKBUILTIN_TYPE ("isize", builtins, isize);
+ MKBUILTIN_TYPE ("char", builtins, char_tyty);
// 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 50e8728..c673e52 100644
--- a/gcc/rust/rust-backend.h
+++ b/gcc/rust/rust-backend.h
@@ -98,6 +98,12 @@ public:
// Get the unnamed boolean type.
virtual Btype *bool_type () = 0;
+ // Get the char type
+ virtual Btype *char_type () = 0;
+
+ // Get the wchar type
+ virtual Btype *wchar_type () = 0;
+
// Get the Host pointer size in bits
virtual int get_pointer_size () = 0;
@@ -294,6 +300,9 @@ public:
// Return an expression for the string value VAL.
virtual Bexpression *string_constant_expression (const std::string &val) = 0;
+ // Get a char literal
+ virtual Bexpression *wchar_constant_expression (wchar_t c) = 0;
+
// Return an expression for the boolean value VAL.
virtual Bexpression *boolean_constant_expression (bool val) = 0;
diff --git a/gcc/rust/rust-gcc.cc b/gcc/rust/rust-gcc.cc
index 82ebb98..b2538b4 100644
--- a/gcc/rust/rust-gcc.cc
+++ b/gcc/rust/rust-gcc.cc
@@ -165,6 +165,17 @@ public:
Btype *bool_type () { return this->make_type (boolean_type_node); }
+ Btype *char_type () { return this->make_type (char_type_node); }
+
+ Btype *wchar_type ()
+ {
+ // i think this is meant to be 32 bit from
+ // https://www.unicode.org/versions/Unicode13.0.0/ch03.pdf#G7404
+ int precision = 32;
+ tree wchar = make_unsigned_type (precision);
+ return this->make_type (wchar);
+ }
+
int get_pointer_size ();
Btype *integer_type (bool, int);
@@ -247,6 +258,8 @@ public:
Bexpression *string_constant_expression (const std::string &val);
+ Bexpression *wchar_constant_expression (wchar_t c);
+
Bexpression *boolean_constant_expression (bool val);
Bexpression *real_part_expression (Bexpression *bcomplex, Location);
@@ -1409,6 +1422,13 @@ Gcc_backend::string_constant_expression (const std::string &val)
return this->make_expression (string_val);
}
+Bexpression *
+Gcc_backend::wchar_constant_expression (wchar_t c)
+{
+ tree ret = build_int_cst (this->wchar_type ()->get_tree (), c);
+ return this->make_expression (ret);
+}
+
// Make a constant boolean expression.
Bexpression *
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h
index f8497db..e8ae83e 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h
@@ -439,6 +439,12 @@ public:
}
break;
+ case HIR::Literal::LitType::CHAR: {
+ auto ok = context->lookup_builtin ("char", &infered);
+ rust_assert (ok);
+ }
+ break;
+
default:
gcc_unreachable ();
break;
diff --git a/gcc/rust/typecheck/rust-tyty-call.h b/gcc/rust/typecheck/rust-tyty-call.h
index 82b070f..08c3ed3 100644
--- a/gcc/rust/typecheck/rust-tyty-call.h
+++ b/gcc/rust/typecheck/rust-tyty-call.h
@@ -51,6 +51,7 @@ public:
void visit (USizeType &type) override { gcc_unreachable (); }
void visit (ISizeType &type) override { gcc_unreachable (); }
void visit (ErrorType &type) override { gcc_unreachable (); }
+ void visit (CharType &type) override { gcc_unreachable (); }
// tuple-structs
void visit (ADTType &type) override;
@@ -94,6 +95,7 @@ public:
void visit (ISizeType &type) override { gcc_unreachable (); }
void visit (ErrorType &type) override { gcc_unreachable (); }
void visit (ADTType &type) override { gcc_unreachable (); };
+ void visit (CharType &type) 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 be58805..809a76c 100644
--- a/gcc/rust/typecheck/rust-tyty-rules.h
+++ b/gcc/rust/typecheck/rust-tyty-rules.h
@@ -169,6 +169,13 @@ public:
base->as_string ().c_str (), type.as_string ().c_str ());
}
+ virtual void visit (CharType &type) override
+ {
+ Location ref_locus = mappings->lookup_location (type.get_ref ());
+ rust_error_at (ref_locus, "expected [%s] got [%s]",
+ base->as_string ().c_str (), type.as_string ().c_str ());
+ }
+
protected:
BaseRules (TyBase *base)
: mappings (Analysis::Mappings::get ()),
@@ -367,6 +374,19 @@ public:
BaseRules::visit (type);
}
+ void visit (CharType &type) override
+ {
+ bool is_valid
+ = (base->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL);
+ if (is_valid)
+ {
+ resolved = type.clone ();
+ return;
+ }
+
+ BaseRules::visit (type);
+ }
+
private:
InferType *base;
};
@@ -729,6 +749,29 @@ private:
ISizeType *base;
};
+class CharRules : public BaseRules
+{
+public:
+ CharRules (CharType *base) : BaseRules (base), base (base) {}
+
+ void visit (InferType &type) override
+ {
+ if (type.get_infer_kind () != InferType::InferTypeKind::GENERAL)
+ {
+ BaseRules::visit (type);
+ return;
+ }
+
+ resolved = base->clone ();
+ resolved->set_ref (type.get_ref ());
+ }
+
+ void visit (CharType &type) override { resolved = type.clone (); }
+
+private:
+ CharType *base;
+};
+
} // namespace TyTy
} // namespace Rust
diff --git a/gcc/rust/typecheck/rust-tyty-visitor.h b/gcc/rust/typecheck/rust-tyty-visitor.h
index 6ae0e80..6b36ebd 100644
--- a/gcc/rust/typecheck/rust-tyty-visitor.h
+++ b/gcc/rust/typecheck/rust-tyty-visitor.h
@@ -41,6 +41,7 @@ public:
virtual void visit (USizeType &type) = 0;
virtual void visit (ISizeType &type) = 0;
virtual void visit (ErrorType &type) = 0;
+ virtual void visit (CharType &type) = 0;
};
} // namespace TyTy
diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc
index e12d5ff..c2d4763 100644
--- a/gcc/rust/typecheck/rust-tyty.cc
+++ b/gcc/rust/typecheck/rust-tyty.cc
@@ -486,6 +486,33 @@ ISizeType::clone ()
}
void
+CharType::accept_vis (TyVisitor &vis)
+{
+ vis.visit (*this);
+}
+
+std::string
+CharType::as_string () const
+{
+ return "char";
+}
+
+TyBase *
+CharType::combine (TyBase *other)
+{
+ CharRules r (this);
+ return r.combine (other);
+}
+
+TyBase *
+CharType::clone ()
+{
+ return new CharType (get_ref (), get_ty_ref (), get_combined_refs ());
+}
+
+// rust-tyty-call.h
+
+void
TypeCheckCallExpr::visit (ADTType &type)
{
if (call.num_params () != type.num_fields ())
diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h
index 860ef96..dd80062 100644
--- a/gcc/rust/typecheck/rust-tyty.h
+++ b/gcc/rust/typecheck/rust-tyty.h
@@ -552,6 +552,26 @@ public:
TyBase *clone () final override;
};
+class CharType : public TyBase
+{
+public:
+ CharType (HirId ref, std::set<HirId> refs = std::set<HirId> ())
+ : TyBase (ref, ref, TypeKind::CHAR)
+ {}
+
+ CharType (HirId ref, HirId ty_ref, std::set<HirId> refs = std::set<HirId> ())
+ : TyBase (ref, ty_ref, TypeKind::CHAR)
+ {}
+
+ void accept_vis (TyVisitor &vis) override;
+
+ std::string as_string () const override;
+
+ TyBase *combine (TyBase *other) override;
+
+ TyBase *clone () final override;
+};
+
} // namespace TyTy
} // namespace Rust
diff --git a/gcc/testsuite/rust.test/compilable/char1.rs b/gcc/testsuite/rust.test/compilable/char1.rs
new file mode 100644
index 0000000..73835c2
--- /dev/null
+++ b/gcc/testsuite/rust.test/compilable/char1.rs
@@ -0,0 +1,4 @@
+fn main() {
+ let a;
+ a = 'c';
+}