Mercurial > hg > CbC > CbC_gcc
diff gcc/go/gofrontend/expressions.h @ 131:84e7813d76e9
gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 07:37:49 +0900 |
parents | 04ced10e8804 |
children | 1830386684a0 |
line wrap: on
line diff
--- a/gcc/go/gofrontend/expressions.h Fri Oct 27 22:46:09 2017 +0900 +++ b/gcc/go/gofrontend/expressions.h Thu Oct 25 07:37:49 2018 +0900 @@ -39,6 +39,7 @@ class Binary_expression; class String_concat_expression; class Call_expression; +class Builtin_call_expression; class Call_result_expression; class Func_expression; class Func_descriptor_expression; @@ -506,6 +507,23 @@ static Expression* make_backend(Bexpression*, Type*, Location); + enum Nil_check_classification + { + // Use the default policy for deciding if this deref needs a check. + NIL_CHECK_DEFAULT, + // An explicit check is required for this dereference operation. + NIL_CHECK_NEEDED, + // No check needed for this dereference operation. + NIL_CHECK_NOT_NEEDED, + // A type error or error construct was encountered when determining + // whether this deref needs an explicit check. + NIL_CHECK_ERROR_ENCOUNTERED + }; + + // Make a dereference expression. + static Expression* + make_dereference(Expression*, Nil_check_classification, Location); + // Return the expression classification. Expression_classification classification() const @@ -851,6 +869,11 @@ bool is_local_variable() const; + // Return true if two expressions refer to the same variable or + // struct field. + static bool + is_same_variable(Expression*, Expression*); + // Make the builtin function descriptor type, so that it can be // converted. static void @@ -1298,7 +1321,7 @@ public: Var_expression(Named_object* variable, Location location) : Expression(EXPRESSION_VAR_REFERENCE, location), - variable_(variable), in_lvalue_pos_(VE_rvalue) + variable_(variable) { } // Return the variable. @@ -1306,16 +1329,6 @@ named_object() const { return this->variable_; } - // Does this var expression appear in an lvalue (assigned-to) context? - bool - in_lvalue_pos() const - { return this->in_lvalue_pos_ == VE_lvalue; } - - // Mark a var_expression as appearing in an lvalue context. - void - set_in_lvalue_pos() - { this->in_lvalue_pos_ = VE_lvalue; } - protected: Expression* do_lower(Gogo*, Named_object*, Statement_inserter*, int); @@ -1346,8 +1359,6 @@ private: // The variable we are referencing. Named_object* variable_; - // Set to TRUE if var expression appears in lvalue context - Varexpr_context in_lvalue_pos_; }; // A reference to a variable within an enclosing function. @@ -1658,11 +1669,7 @@ do_check_types(Gogo*); Expression* - do_copy() - { - return new Type_conversion_expression(this->type_, this->expr_->copy(), - this->location()); - } + do_copy(); Bexpression* do_get_backend(Translate_context* context); @@ -1714,12 +1721,7 @@ { this->expr_->determine_type_no_context(); } Expression* - do_copy() - { - return new Unsafe_type_conversion_expression(this->type_, - this->expr_->copy(), - this->location()); - } + do_copy(); Bexpression* do_get_backend(Translate_context*); @@ -1742,7 +1744,8 @@ Unary_expression(Operator op, Expression* expr, Location location) : Expression(EXPRESSION_UNARY, location), op_(op), escapes_(true), create_temp_(false), is_gc_root_(false), - is_slice_init_(false), expr_(expr), issue_nil_check_(false) + is_slice_init_(false), expr_(expr), + issue_nil_check_(NIL_CHECK_DEFAULT) { } // Return the operator. @@ -1804,6 +1807,17 @@ static Expression* do_import(Import*); + // Declare that this deref does or does not require an explicit nil check. + void + set_requires_nil_check(bool needed) + { + go_assert(this->op_ == OPERATOR_MULT); + if (needed) + this->issue_nil_check_ = NIL_CHECK_NEEDED; + else + this->issue_nil_check_ = NIL_CHECK_NOT_NEEDED; + } + protected: int do_traverse(Traverse* traverse) @@ -1859,12 +1873,20 @@ void do_issue_nil_check() - { this->issue_nil_check_ = (this->op_ == OPERATOR_MULT); } + { + if (this->op_ == OPERATOR_MULT) + this->set_requires_nil_check(true); + } private: static bool base_is_static_initializer(Expression*); + // Return a determination as to whether this dereference expression + // requires a nil check. + Nil_check_classification + requires_nil_check(Gogo*); + // The unary operator to apply. Operator op_; // Normally true. False if this is an address expression which does @@ -1886,7 +1908,7 @@ Expression* expr_; // Whether or not to issue a nil check for this expression if its address // is being taken. - bool issue_nil_check_; + Nil_check_classification issue_nil_check_; }; // A binary expression. @@ -2221,6 +2243,15 @@ set_is_multi_value_arg() { this->is_multi_value_arg_ = true; } + // Whether this is a call to builtin function. + virtual bool + is_builtin() + { return false; } + + // Convert to a Builtin_call_expression, or return NULL. + inline Builtin_call_expression* + builtin_call_expression(); + protected: int do_traverse(Traverse*); @@ -2326,6 +2357,140 @@ bool is_flattened_; }; +// A call expression to a builtin function. + +class Builtin_call_expression : public Call_expression +{ + public: + Builtin_call_expression(Gogo* gogo, Expression* fn, Expression_list* args, + bool is_varargs, Location location); + + // The builtin functions. + enum Builtin_function_code + { + BUILTIN_INVALID, + + // Predeclared builtin functions. + BUILTIN_APPEND, + BUILTIN_CAP, + BUILTIN_CLOSE, + BUILTIN_COMPLEX, + BUILTIN_COPY, + BUILTIN_DELETE, + BUILTIN_IMAG, + BUILTIN_LEN, + BUILTIN_MAKE, + BUILTIN_NEW, + BUILTIN_PANIC, + BUILTIN_PRINT, + BUILTIN_PRINTLN, + BUILTIN_REAL, + BUILTIN_RECOVER, + + // Builtin functions from the unsafe package. + BUILTIN_ALIGNOF, + BUILTIN_OFFSETOF, + BUILTIN_SIZEOF + }; + + Builtin_function_code + code() + { return this->code_; } + + // This overrides Call_expression::is_builtin. + bool + is_builtin() + { return true; } + + // Return whether EXPR, of array type, is a constant if passed to + // len or cap. + static bool + array_len_is_constant(Expression* expr); + + Expression* + flatten_append(Gogo*, Named_object*, Statement_inserter*, Expression*, + Block*); + + protected: + // This overrides Call_expression::do_lower. + Expression* + do_lower(Gogo*, Named_object*, Statement_inserter*, int); + + Expression* + do_flatten(Gogo*, Named_object*, Statement_inserter*); + + bool + do_is_constant() const; + + bool + do_numeric_constant_value(Numeric_constant*) const; + + bool + do_discarding_value(); + + Type* + do_type(); + + void + do_determine_type(const Type_context*); + + void + do_check_types(Gogo*); + + Expression* + do_copy(); + + Bexpression* + do_get_backend(Translate_context*); + + void + do_export(Export*) const; + + virtual bool + do_is_recover_call() const; + + virtual void + do_set_recover_arg(Expression*); + + private: + Expression* + one_arg() const; + + bool + check_one_arg(); + + static Type* + real_imag_type(Type*); + + static Type* + complex_type(Type*); + + Expression* + lower_make(Statement_inserter*); + + bool + check_int_value(Expression*, bool is_length, bool* small); + + // A pointer back to the general IR structure. This avoids a global + // variable, or passing it around everywhere. + Gogo* gogo_; + // The builtin function being called. + Builtin_function_code code_; + // Used to stop endless loops when the length of an array uses len + // or cap of the array itself. + mutable bool seen_; + // Whether the argument is set for calls to BUILTIN_RECOVER. + bool recover_arg_is_set_; +}; + +inline Builtin_call_expression* +Call_expression::builtin_call_expression() +{ + return (this->is_builtin() + ? static_cast<Builtin_call_expression*>(this) + : NULL); +} + // A single result from a call which returns multiple results. class Call_result_expression : public Expression @@ -2613,12 +2778,10 @@ this->location()); } + // This shouldn't be called--we don't know yet. bool - do_must_eval_subexpressions_in_order(int* skip) const - { - *skip = 1; - return true; - } + do_must_eval_subexpressions_in_order(int*) const + { go_unreachable(); } void do_dump_expression(Ast_dump_context*) const; @@ -2724,18 +2887,13 @@ } bool - do_must_eval_subexpressions_in_order(int* skip) const - { - *skip = 1; - return true; - } + do_must_eval_subexpressions_in_order(int* skip) const; bool do_is_addressable() const; void - do_address_taken(bool escapes) - { this->array_->address_taken(escapes); } + do_address_taken(bool escapes); void do_issue_nil_check() @@ -2808,11 +2966,8 @@ } bool - do_must_eval_subexpressions_in_order(int* skip) const - { - *skip = 1; - return true; - } + do_must_eval_subexpressions_in_order(int*) const + { return true; } Bexpression* do_get_backend(Translate_context*); @@ -2895,11 +3050,8 @@ } bool - do_must_eval_subexpressions_in_order(int* skip) const - { - *skip = 1; - return true; - } + do_must_eval_subexpressions_in_order(int*) const + { return true; } // A map index expression is an lvalue but it is not addressable. @@ -3264,19 +3416,7 @@ do_lower(Gogo*, Named_object*, Statement_inserter*, int); Expression* - do_copy() - { - Composite_literal_expression *ret = - new Composite_literal_expression(this->type_, this->depth_, - this->has_keys_, - (this->vals_ == NULL - ? NULL - : this->vals_->copy()), - this->all_are_names_, - this->location()); - ret->key_path_ = this->key_path_; - return ret; - } + do_copy(); void do_dump_expression(Ast_dump_context*) const; @@ -3390,18 +3530,7 @@ do_check_types(Gogo*); Expression* - do_copy() - { - Struct_construction_expression* ret = - new Struct_construction_expression(this->type_, - (this->vals() == NULL - ? NULL - : this->vals()->copy()), - this->location()); - if (this->traverse_order() != NULL) - ret->set_traverse_order(this->traverse_order()); - return ret; - } + do_copy(); Expression* do_flatten(Gogo*, Named_object*, Statement_inserter*); @@ -3505,15 +3634,7 @@ protected: Expression* - do_copy() - { - return new Fixed_array_construction_expression(this->type(), - this->indexes(), - (this->vals() == NULL - ? NULL - : this->vals()->copy()), - this->location()); - } + do_copy(); Bexpression* do_get_backend(Translate_context*); @@ -3546,14 +3667,7 @@ do_traverse(Traverse* traverse); Expression* - do_copy() - { - return new Slice_construction_expression(this->type(), this->indexes(), - (this->vals() == NULL - ? NULL - : this->vals()->copy()), - this->location()); - } + do_copy(); Bexpression* do_get_backend(Translate_context*); @@ -3612,14 +3726,7 @@ do_check_types(Gogo*); Expression* - do_copy() - { - return new Map_construction_expression(this->type_, - (this->vals_ == NULL - ? NULL - : this->vals_->copy()), - this->location()); - } + do_copy(); Bexpression* do_get_backend(Translate_context*); @@ -3680,11 +3787,7 @@ do_check_types(Gogo*); Expression* - do_copy() - { - return new Type_guard_expression(this->expr_->copy(), this->type_, - this->location()); - } + do_copy(); Bexpression* do_get_backend(Translate_context*); @@ -3709,13 +3812,17 @@ public: Heap_expression(Expression* expr, Location location) : Expression(EXPRESSION_HEAP, location), - expr_(expr) + expr_(expr), allocate_on_stack_(false) { } Expression* expr() const { return this->expr_; } + void + set_allocate_on_stack() + { this->allocate_on_stack_ = true; } + protected: int do_traverse(Traverse* traverse) @@ -3749,6 +3856,8 @@ private: // The expression which is being put on the heap. Expression* expr_; + // Whether or not this is a stack allocation. + bool allocate_on_stack_; }; // A receive expression. @@ -3930,10 +4039,7 @@ { } Expression* - do_copy() - { - return new Backend_expression(this->bexpr_, this->type_, this->location()); - } + do_copy(); Bexpression* do_get_backend(Translate_context*) @@ -4109,6 +4215,9 @@ bool check_complex_type(Complex_type*, bool, Location); + static bool + is_float_neg_zero(const mpfr_t, int bits); + // The kinds of constants. enum Classification {