00001
00002
00003 #ifndef implicit_conversion_h
00004 #define implicit_conversion_h
00005
00006 #include <vector>
00007 #include <map>
00008 #include <types.h>
00009 #include "expr_result.h"
00010
00011
00012
00013
00014
00015
00016 class Function_signature;
00027 typedef std::map<Function_signature*, int> Conversion_op_map;
00028
00029 struct ICS_Types {
00031 enum Action {
00032 a_NullStep,
00033
00034
00035 a_LValueToRValue,
00036 a_ArrayToPointer,
00037 a_FunctionToPointer,
00038 a_QualificationAdjustment,
00039 a_IntegralPromotion,
00040 a_FloatingPromotion,
00041 a_IntegralConversion,
00042 a_FloatingConversion,
00043 a_FloatingIntegralConversion,
00044 a_PointerConversion,
00045 a_PtrMemConversion,
00046 a_BoolConversion,
00047 a_DerivedToBaseConversion,
00048
00049
00050 a_CtorCall,
00051 a_ConversionOp,
00052
00053 a_Ellipsis,
00054
00055 a_BindReferenceToTemporary
00056
00057 };
00058
00060 enum Form {
00061 f_NoForm,
00062 f_Standard,
00063 f_Userdef,
00064 f_Ellipsis
00065 };
00066
00068 enum Rank {
00069 r_NoRank,
00070 r_Exact,
00071 r_Promotion,
00072 r_Conversion
00073 };
00074
00077 enum Compare {
00080 c_CompareAll,
00084 c_CompareWithInitRules,
00089 c_CompareBeforeUserConversion
00090 };
00091 typedef Expr_result::Kind Kind;
00092 };
00093
00094 struct ICS_Step : ICS_Types {
00095 Type type;
00096 Kind kind;
00097 Function_signature* function;
00098 Action action;
00099
00100 ICS_Step(Type type, Kind kind, Action action)
00101 : type(type), kind(kind), function(0), action(action) { }
00102 ICS_Step(Type type, Kind kind, Function_signature* function, Action action)
00103 : type(type), kind(kind), function(function), action(action) { }
00104
00105 public:
00108 ICS_Step::Rank get_rank() const;
00109
00112 ICS_Step::Form get_form() const;
00113
00114 bool
00115 is_lvalue_transformation() const;
00116
00117 void dump(std::ostream& os) const;
00118
00119 private:
00121 const char* get_action_name() const;
00122 };
00123
00124
00125 class Implicit_conversion : public LightObject, public ICS_Types {
00126 public:
00127 typedef ICS_Step Step;
00128 typedef std::vector<Step> Step_vec;
00129 private:
00130 Step_vec steps;
00131
00132 std::string warnings;
00133
00134 bool maybe_npc;
00135
00136
00137 Form form;
00138 Rank rank;
00139 bool ambiguous;
00140 public:
00141 Form get_form() const { return form; }
00142 Rank get_rank() const { return rank; }
00143 bool is_ambiguous() const { return ambiguous; }
00144 void set_ambiguous() { ambiguous = true; }
00145
00146 public:
00147
00148
00162 Implicit_conversion(const Expr_result& result, Function_signature* symbol_hint);
00163
00164 ~Implicit_conversion();
00165
00167 const Implicit_conversion::Step& get_current();
00168
00170 bool is_npc() const;
00171
00173 void warn_if_used(std::string s);
00174
00176 void add_step(Step s);
00177
00179 void add_conversion(Action a, Type t);
00180
00183 bool convert_to_rvalue(Type target);
00184
00186 void dump(std::ostream& os);
00187
00188 bool uses_temporary() const;
00189
00196 bool is_better_than(Implicit_conversion* other, Compare comparison_type);
00197
00200 Expr_result make_tree(Expr_result expr);
00201
00204 bool convert_reference(Type target);
00205
00206 void append_from(Implicit_conversion* other);
00207
00208 private:
00211 static bool scs_is_better_than(Step_vec::const_iterator a1, Step_vec::const_iterator e1, Step_vec::const_iterator a2, Step_vec::const_iterator e2);
00212 };
00213
00214
00215 void enumerate_conversion_ops(const Expr_result& expr, Conversion_op_map* output);
00216
00227 void gen_candidates(Expr_result expr, Type arg_type, Function_signature* symbol_hint, bool with_userdef, bool is_object, std::vector<Implicit_conversion*>* candidates);
00228
00231 Implicit_conversion* generate_implicit_conversion(Expr_result expr, Type arg_type, Function_signature* symbol_hint, bool with_userdef, bool is_copy_initialisation, bool is_implicit_object_arg);
00232
00233
00234
00235
00236
00237
00238
00240 inline const Implicit_conversion::Step&
00241 Implicit_conversion::get_current()
00242 {
00243 return steps.back();
00244 }
00245
00246
00248 inline bool
00249 Implicit_conversion::is_npc() const
00250 {
00251 return maybe_npc;
00252 }
00253
00254 #endif // implicit_conversion_h