00001
00002
00003 #include "init_handler.h"
00004 #include "init_handler_i.h"
00005
00006
00007 #line 146 "init_handler.cpp"
00008
00010 static Ptree*
00011 get_string_literal(Ptree* t);
00012
00013 #line 167 "init_handler.cpp"
00014
00015 static bool
00016 is_character_type(Type t);
00017
00018 #line 48 "init_handler.cpp"
00019
00024 Init_reader::Init_reader(Ptree* tree)
00025 : tree(tree)
00026 { }
00027
00028 #line 56 "init_handler.cpp"
00029
00031 bool
00032 Init_reader::is_compound()
00033 {
00034 return tree && dynamic_cast<PtreeBrace*>(tree->Car());
00035 }
00036
00037 #line 63 "init_handler.cpp"
00038
00040 Ptree*
00041 Init_reader::get()
00042 {
00043 if (tree) {
00044 Ptree* rv = tree->Car();
00045 if ((tree = tree->Cdr()))
00046 tree = tree->Cdr();
00047 return rv;
00048 } else
00049 return 0;
00050 }
00051
00052 #line 76 "init_handler.cpp"
00053
00055 Ptree*
00056 Init_reader::get_nondestructive() const
00057 {
00058 return tree ? tree->Car() : 0;
00059 }
00060
00061 #line 90 "init_handler.cpp"
00062
00063 void
00064 Init_reader::dump(std::ostream& os)
00065 {
00066 tree->Display2(os);
00067 }
00068
00069 #line 103 "init_handler.cpp"
00070
00071
00072 Init_maker::Init_maker()
00073 : tree(0)
00074 { }
00075
00076 #line 108 "init_handler.cpp"
00077
00079 void
00080 Init_maker::add(Ptree* p)
00081 {
00082 if (tree) {
00083 Ptree::Snoc(tree, make_static_leaf(","));
00084 Ptree::Snoc(tree, p);
00085 } else {
00086 tree = Ptree::List(p);
00087 }
00088 }
00089
00090 #line 120 "init_handler.cpp"
00091
00093 Ptree*
00094 Init_maker::make_init() const
00095 {
00096 return new PtreeBrace(make_static_leaf("{"),
00097 Ptree::List(tree, make_static_leaf("}")));
00098 }
00099
00100 #line 128 "init_handler.cpp"
00101
00102
00103
00111 Init_handler::Init_handler(Abstract_scope* scope, Ptree* tree, bool zero_init)
00112 : tree(tree), scope(scope), zero_init(zero_init)
00113 { }
00114
00115 #line 141 "init_handler.cpp"
00116
00117
00118 Init_handler::~Init_handler()
00119 { }
00120
00121 #line 145 "init_handler.cpp"
00122
00125 static Ptree*
00126 get_string_literal(Ptree* t)
00127 {
00128 if (!t) {
00129 return 0;
00130 } else if (dynamic_cast<PtreeParenExpr*>(t)) {
00131 return get_string_literal(t->Second());
00132 } else if (t->IsLeaf()) {
00133 const char* c = t->GetPosition();
00134 int l = t->GetLength();
00135 if (l >= 2 && (*c == '"' || ((*c == 'L' || *c == 'l') && c[1] == '"')))
00136 return t;
00137 else
00138 return 0;
00139 } else {
00140 return 0;
00141 }
00142 }
00143
00144 #line 166 "init_handler.cpp"
00145
00147 static bool
00148 is_character_type(Type t)
00149 {
00150 return t.is_same_unqualified_type(char_type) || t.is_same_unqualified_type(wchar_type)
00151 || t.is_same_unqualified_type(uchar_type) || t.is_same_unqualified_type(schar_type);
00152 }
00153
00154 #line 174 "init_handler.cpp"
00155
00157 Ptree*
00158 Init_handler::make_constructor_call(Type t, Ptree* args)
00159 {
00160 if (t.is_class_type()) {
00161
00162 Class_symbol* csym = downcast<Class_symbol*>(t.get_type_symbol());
00163 Function_symbol* fsym = dynamic_cast<Function_symbol*>(csym->lookup_helper(Symbol_name::CONSTRUCTOR_NAME).untag);
00164 if (!fsym)
00165 compile_error("class `" + csym->get_name() + "' has no ctor (huh?)");
00166
00167 Overload_resolver resolver(false );
00168 Expr_annotator(scope, &Source::instance()).add_parms_from_arglist(&resolver, args);
00169 resolver.add_function(fsym, false);
00170
00171 bool is_ambig;
00172 Overload_candidate* cand = resolver.get_best(&is_ambig);
00173 if (is_ambig)
00174 compile_error("initialisation is ambiguous");
00175 else if (!cand)
00176 compile_error("invalid parameter list for constructor");
00177
00178 Annotated_funcall_maker afm(make_name(cand->fsig), t);
00179 for (unsigned i = 0; i < resolver.get_arg_count(); ++i)
00180 afm.add_arg(resolver.get_arg(i).get_tree());
00181 return afm.make_funcall();
00182 } else if (t.is_scalar_type() || t.get_kind() == Type::k_Reference) {
00183 Ptree* arg;
00184 if (!args)
00185 if (t.get_kind() == Type::k_Reference)
00186 compile_error("can't default-initialize a reference");
00187 else
00188 arg = make_static_leaf("0");
00189 else if (args->Length() == 1)
00190 arg = args->First();
00191 else
00192 compile_error("expression in initializer for scalar or reference type must have only one expression");
00193
00194 Expr_result r = Expr_annotator(scope, &Source::instance()).visit(arg);
00195 Implicit_conversion* ics = generate_implicit_conversion(r, t, 0,
00196 true ,
00197 false ,
00198 false );
00199 if (!ics)
00200 compile_error("type mismatch for initializer");
00201
00202
00203 return ics->make_tree(r).get_tree();
00204 } else
00205 compile_error("can't direct-initialize that");
00206 }
00207
00208 #line 226 "init_handler.cpp"
00209
00216 Ptree*
00217 Init_handler::process_initializer(Type t)
00218 {
00219
00220 if (!tree)
00221 return get_default_initializer_for_type(t);
00222
00223
00224
00225
00226
00227 if (tree->First()->Eq('(')) {
00228
00229 Ptree* args = tree->Second();
00230 expect_ptree(tree->Third(), ')');
00231 return make_constructor_call(t, args);
00232 } else if (tree->First()->Eq('=')) {
00233
00234 if (dynamic_cast<PtreeBrace*>(tree->Second())) {
00235 if (t.get_kind() == Type::k_Array || t.is_class_type() || t.is_scalar_type()) {
00236
00237 NonLeaf tmp(tree->Second(), 0);
00238 Init_reader r(&tmp);
00239 return process_brace(t, &r);
00240 } else
00241 compile_error("can't brace-initialize that");
00242 } else {
00243
00244 if (t.get_kind() == Type::k_Array) {
00245 if (is_character_type(t.get_basis_type())) {
00246 Ptree* ct = get_string_literal(tree->Second());
00247 if (ct)
00248 return new Annotated<Leaf>(t, 0, *downcast<Leaf*>(ct));
00249 }
00250 compile_error("can't copy-initialize that");
00251 }
00252 NonLeaf tmp(tree->Second(), 0);
00253 Init_reader r(&tmp);
00254 return process_brace(t, &r);
00255 }
00256 } else
00257 bogus_ptree_error("strange initializer", tree);
00258 }
00259
00260 #line 276 "init_handler.cpp"
00261
00265 Ptree*
00266 Init_handler::process_brace(Type t, Init_reader* reader)
00267 {
00268 if (t.is_class_type()) {
00269 Class_symbol* csym = downcast<Class_symbol*>(t.get_type_symbol());
00270 if (csym->is_aggregate()) {
00271 if (reader->is_compound()) {
00272 Init_reader sub(reader->get()->Second());
00273 Ptree* rv = process_class(csym, &sub);
00274 if (sub.get_nondestructive())
00275 compile_error("too many initializers for type `" + csym->get_name() + "'");
00276 return rv;
00277 } else
00278 return process_class(csym, reader);
00279 }
00280
00281 } else if (t.get_kind() == Type::k_Array) {
00282 Type base = t.get_basis_type();
00283 if (is_character_type(base)) {
00284
00285 Ptree* tree;
00286 if (reader->is_compound()) {
00287 Init_reader sub(reader->get_nondestructive()->Second());
00288 tree = sub.get();
00289 if (sub.get())
00290 tree = 0;
00291 else
00292 tree = get_string_literal(tree);
00293 } else
00294 tree = get_string_literal(reader->get_nondestructive());
00295
00296 if (tree) {
00297
00298 reader->get();
00299 assert(tree->IsLeaf());
00300 return new Annotated<Leaf>(t, 0, *downcast<Leaf*>(tree));
00301 }
00302 }
00303
00304 if (reader->is_compound()) {
00305 Init_reader sub(reader->get()->Second());
00306 Ptree* rv = process_array(t.get_basis_type(), &sub);
00307 if (sub.get())
00308
00309 compile_error("too many initializers for array");
00310 return rv;
00311 } else {
00312 compile_warning("partially bracketed initializer for array; interpretation might be wrong", reader->get_nondestructive());
00313 return process_array(t.get_basis_type(), reader);
00314 }
00315 }
00316
00317
00318
00319 Ptree* ele;
00320 if (reader->is_compound()) {
00321 if (!t.is_scalar_type())
00322 compile_error("only scalar types can be initialized with braced value");
00323 Init_reader sub(reader->get()->Second());
00324 ele = sub.get();
00325 if (!ele || sub.get())
00326 compile_error("initializer for non-aggregate must contain exactly one element");
00327 } else
00328 ele = reader->get();
00329
00330 if (!ele) {
00331 return get_default_initializer_for_type(t);
00332 } else {
00333 Expr_result res = Expr_annotator(scope, &Source::instance()).visit(ele);
00334 Implicit_conversion* ics = generate_implicit_conversion(res, t, 0,
00335 true, true, false);
00336 if (!ics)
00337 compile_error("type mismatch");
00338 return ics->make_tree(res).get_tree();
00339 }
00340 }
00341
00342 #line 356 "init_handler.cpp"
00343
00344 Ptree*
00345 Init_handler::process_array(Type t, Init_reader* reader)
00346 {
00347 Init_maker obi;
00348 if (reader->empty())
00349 compile_warning("zero-length array initializer?", reader->get_nondestructive());
00350
00351 while (!reader->empty())
00352 obi.add(process_brace(t, reader));
00353
00354 return obi.make_init();
00355 }
00356
00357 #line 369 "init_handler.cpp"
00358
00359 Ptree*
00360 Init_handler::process_class(Class_symbol* csym, Init_reader* reader)
00361 {
00362 if (!reader->is_compound() && reader->get_nondestructive()) {
00363
00364
00365
00366
00367
00368
00369 Expr_result res = Expr_annotator(scope, &Source::instance()).visit(reader->get_nondestructive());
00370 Implicit_conversion* ics = generate_implicit_conversion(res, csym->get_type(),
00371 0, true ,
00372 true ,
00373 false );
00374 if (ics) {
00375
00376 reader->get();
00377 return ics->make_tree(res).get_tree();
00378 }
00379 }
00380
00381 Init_maker hornbach;
00382 for (Class_symbol::members_t::const_iterator i = csym->mem_begin(); i != csym->mem_end(); ++i) {
00383 Variable_symbol* vsym = *i;
00384 if (vsym->is_member_variable()) {
00385 hornbach.add(process_brace(vsym->get_type(), reader));
00386 if (csym->get_kind() == Symbol::k_Union)
00387 break;
00388 }
00389 }
00390 return hornbach.make_init();
00391 }
00392
00393 #line 403 "init_handler.cpp"
00394
00395
00396
00398 Ptree*
00399 Init_handler::get_default_initializer_for_type(Type t)
00400 {
00401 if (t.is_class_type()) {
00402 Class_symbol* csym = downcast<Class_symbol*>(t.get_type_symbol());
00403 Function_symbol* fsym = dynamic_cast<Function_symbol*>(csym->lookup_helper(Symbol_name::CONSTRUCTOR_NAME).untag);
00404 if (fsym) {
00405
00406 Overload_resolver resolver(false);
00407 resolver.add_function(fsym, false);
00408
00409 Overload_candidate* cand = resolver.get_best(0);
00410 if (cand)
00411 return Annotated_funcall_maker(make_name(cand->fsig), t).make_funcall();
00412 }
00413 if (csym->is_aggregate()) {
00414
00415 Init_reader reader(0);
00416 return process_class(csym, &reader);
00417 }
00418
00419
00420 compile_error("unable to default-initialize that");
00421 } else if (t.get_kind() == Type::k_Array) {
00422
00423
00424 compile_warning("default-initialisation of an array requested", 0);
00425 return Init_maker().make_init();
00426 } else if (t.get_kind() == Type::k_Reference) {
00427
00428
00429 compile_error("can't default-initialize a reference");
00430 } else if (t.is_scalar_type()) {
00431 if (!zero_init)
00432 return 0;
00433 Leaf tmp_leaf("0", 1);
00434 Expr_result r (new Annotated<Leaf>(int_type, 0, tmp_leaf), Expr_result::k_RValue);
00435 Implicit_conversion* ics = generate_implicit_conversion(r, t, 0,
00436 true ,
00437 false ,
00438 false );
00439 if (!ics)
00440 compile_error("can't happen: type mismatch for initializer");
00441 return ics->make_tree(r).get_tree();
00442 } else {
00443 compile_error("can't default-initialize `" + t.get_human_readable_type() + "'");
00444 }
00445 }