PageRenderTime 28ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/dmd/init.c

https://bitbucket.org/lindquist/ldc/
C | 696 lines | 544 code | 96 blank | 56 comment | 95 complexity | 9008db26bc3b70d93bc518a5e6b1d572 MD5 | raw file
Possible License(s): BSD-3-Clause, AGPL-1.0
  1. // Compiler implementation of the D programming language
  2. // Copyright (c) 1999-2009 by Digital Mars
  3. // All Rights Reserved
  4. // written by Walter Bright
  5. // http://www.digitalmars.com
  6. // License for redistribution is by either the Artistic License
  7. // in artistic.txt, or the GNU General Public License in gnu.txt.
  8. // See the included readme.txt for details.
  9. #include <stdio.h>
  10. #include <assert.h>
  11. #include "mars.h"
  12. #include "init.h"
  13. #include "expression.h"
  14. #include "statement.h"
  15. #include "identifier.h"
  16. #include "declaration.h"
  17. #include "aggregate.h"
  18. #include "scope.h"
  19. #include "mtype.h"
  20. #include "hdrgen.h"
  21. /********************************** Initializer *******************************/
  22. Initializer::Initializer(Loc loc)
  23. {
  24. this->loc = loc;
  25. }
  26. Initializer *Initializer::syntaxCopy()
  27. {
  28. return this;
  29. }
  30. Initializer *Initializer::semantic(Scope *sc, Type *t)
  31. {
  32. return this;
  33. }
  34. Type *Initializer::inferType(Scope *sc)
  35. {
  36. error(loc, "cannot infer type from initializer");
  37. return Type::terror;
  38. }
  39. Initializers *Initializer::arraySyntaxCopy(Initializers *ai)
  40. { Initializers *a = NULL;
  41. if (ai)
  42. {
  43. a = new Initializers();
  44. a->setDim(ai->dim);
  45. for (int i = 0; i < a->dim; i++)
  46. { Initializer *e = (Initializer *)ai->data[i];
  47. e = e->syntaxCopy();
  48. a->data[i] = e;
  49. }
  50. }
  51. return a;
  52. }
  53. char *Initializer::toChars()
  54. { OutBuffer *buf;
  55. HdrGenState hgs;
  56. memset(&hgs, 0, sizeof(hgs));
  57. buf = new OutBuffer();
  58. toCBuffer(buf, &hgs);
  59. return buf->toChars();
  60. }
  61. /********************************** VoidInitializer ***************************/
  62. VoidInitializer::VoidInitializer(Loc loc)
  63. : Initializer(loc)
  64. {
  65. type = NULL;
  66. }
  67. Initializer *VoidInitializer::syntaxCopy()
  68. {
  69. return new VoidInitializer(loc);
  70. }
  71. Initializer *VoidInitializer::semantic(Scope *sc, Type *t)
  72. {
  73. //printf("VoidInitializer::semantic(t = %p)\n", t);
  74. type = t;
  75. return this;
  76. }
  77. Expression *VoidInitializer::toExpression()
  78. {
  79. error(loc, "void initializer has no value");
  80. return new IntegerExp(0);
  81. }
  82. void VoidInitializer::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
  83. {
  84. buf->writestring("void");
  85. }
  86. /********************************** StructInitializer *************************/
  87. StructInitializer::StructInitializer(Loc loc)
  88. : Initializer(loc)
  89. {
  90. ad = NULL;
  91. }
  92. Initializer *StructInitializer::syntaxCopy()
  93. {
  94. StructInitializer *ai = new StructInitializer(loc);
  95. assert(field.dim == value.dim);
  96. ai->field.setDim(field.dim);
  97. ai->value.setDim(value.dim);
  98. for (int i = 0; i < field.dim; i++)
  99. {
  100. ai->field.data[i] = field.data[i];
  101. Initializer *init = (Initializer *)value.data[i];
  102. init = init->syntaxCopy();
  103. ai->value.data[i] = init;
  104. }
  105. return ai;
  106. }
  107. void StructInitializer::addInit(Identifier *field, Initializer *value)
  108. {
  109. //printf("StructInitializer::addInit(field = %p, value = %p)\n", field, value);
  110. this->field.push(field);
  111. this->value.push(value);
  112. }
  113. Initializer *StructInitializer::semantic(Scope *sc, Type *t)
  114. {
  115. TypeStruct *ts;
  116. int errors = 0;
  117. //printf("StructInitializer::semantic(t = %s) %s\n", t->toChars(), toChars());
  118. vars.setDim(field.dim);
  119. t = t->toBasetype();
  120. if (t->ty == Tstruct)
  121. { unsigned i;
  122. unsigned fieldi = 0;
  123. ts = (TypeStruct *)t;
  124. ad = ts->sym;
  125. for (i = 0; i < field.dim; i++)
  126. {
  127. Identifier *id = (Identifier *)field.data[i];
  128. Initializer *val = (Initializer *)value.data[i];
  129. Dsymbol *s;
  130. VarDeclaration *v;
  131. if (id == NULL)
  132. {
  133. if (fieldi >= ad->fields.dim)
  134. { error(loc, "too many initializers for %s", ad->toChars());
  135. field.remove(i);
  136. i--;
  137. continue;
  138. }
  139. else
  140. {
  141. s = (Dsymbol *)ad->fields.data[fieldi];
  142. }
  143. }
  144. else
  145. {
  146. //s = ad->symtab->lookup(id);
  147. s = ad->search(loc, id, 0);
  148. if (!s)
  149. {
  150. error(loc, "'%s' is not a member of '%s'", id->toChars(), t->toChars());
  151. continue;
  152. }
  153. // Find out which field index it is
  154. for (fieldi = 0; 1; fieldi++)
  155. {
  156. if (fieldi >= ad->fields.dim)
  157. {
  158. s->error("is not a per-instance initializable field");
  159. break;
  160. }
  161. if (s == (Dsymbol *)ad->fields.data[fieldi])
  162. break;
  163. }
  164. }
  165. if (s && (v = s->isVarDeclaration()) != NULL)
  166. {
  167. val = val->semantic(sc, v->type);
  168. value.data[i] = (void *)val;
  169. vars.data[i] = (void *)v;
  170. }
  171. else
  172. { error(loc, "%s is not a field of %s", id ? id->toChars() : s->toChars(), ad->toChars());
  173. errors = 1;
  174. }
  175. fieldi++;
  176. }
  177. }
  178. else if (t->ty == Tdelegate && value.dim == 0)
  179. { /* Rewrite as empty delegate literal { }
  180. */
  181. Parameters *arguments = new Parameters;
  182. Type *tf = new TypeFunction(arguments, NULL, 0, LINKd);
  183. FuncLiteralDeclaration *fd = new FuncLiteralDeclaration(loc, 0, tf, TOKdelegate, NULL);
  184. fd->fbody = new CompoundStatement(loc, new Statements());
  185. fd->endloc = loc;
  186. Expression *e = new FuncExp(loc, fd);
  187. ExpInitializer *ie = new ExpInitializer(loc, e);
  188. return ie->semantic(sc, t);
  189. }
  190. else
  191. {
  192. error(loc, "a struct is not a valid initializer for a %s", t->toChars());
  193. errors = 1;
  194. }
  195. if (errors)
  196. {
  197. field.setDim(0);
  198. value.setDim(0);
  199. vars.setDim(0);
  200. }
  201. return this;
  202. }
  203. /***************************************
  204. * This works by transforming a struct initializer into
  205. * a struct literal. In the future, the two should be the
  206. * same thing.
  207. */
  208. Expression *StructInitializer::toExpression()
  209. { Expression *e;
  210. //printf("StructInitializer::toExpression() %s\n", toChars());
  211. if (!ad) // if fwd referenced
  212. {
  213. return NULL;
  214. }
  215. StructDeclaration *sd = ad->isStructDeclaration();
  216. if (!sd)
  217. return NULL;
  218. Expressions *elements = new Expressions();
  219. for (size_t i = 0; i < value.dim; i++)
  220. {
  221. if (field.data[i])
  222. goto Lno;
  223. Initializer *iz = (Initializer *)value.data[i];
  224. if (!iz)
  225. goto Lno;
  226. Expression *ex = iz->toExpression();
  227. if (!ex)
  228. goto Lno;
  229. elements->push(ex);
  230. }
  231. e = new StructLiteralExp(loc, sd, elements);
  232. e->type = sd->type;
  233. return e;
  234. Lno:
  235. delete elements;
  236. //error(loc, "struct initializers as expressions are not allowed");
  237. return NULL;
  238. }
  239. void StructInitializer::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
  240. {
  241. //printf("StructInitializer::toCBuffer()\n");
  242. buf->writebyte('{');
  243. for (int i = 0; i < field.dim; i++)
  244. {
  245. if (i > 0)
  246. buf->writebyte(',');
  247. Identifier *id = (Identifier *)field.data[i];
  248. if (id)
  249. {
  250. buf->writestring(id->toChars());
  251. buf->writebyte(':');
  252. }
  253. Initializer *iz = (Initializer *)value.data[i];
  254. if (iz)
  255. iz->toCBuffer(buf, hgs);
  256. }
  257. buf->writebyte('}');
  258. }
  259. /********************************** ArrayInitializer ************************************/
  260. ArrayInitializer::ArrayInitializer(Loc loc)
  261. : Initializer(loc)
  262. {
  263. dim = 0;
  264. type = NULL;
  265. sem = 0;
  266. }
  267. Initializer *ArrayInitializer::syntaxCopy()
  268. {
  269. //printf("ArrayInitializer::syntaxCopy()\n");
  270. ArrayInitializer *ai = new ArrayInitializer(loc);
  271. assert(index.dim == value.dim);
  272. ai->index.setDim(index.dim);
  273. ai->value.setDim(value.dim);
  274. for (int i = 0; i < ai->value.dim; i++)
  275. { Expression *e = (Expression *)index.data[i];
  276. if (e)
  277. e = e->syntaxCopy();
  278. ai->index.data[i] = e;
  279. Initializer *init = (Initializer *)value.data[i];
  280. init = init->syntaxCopy();
  281. ai->value.data[i] = init;
  282. }
  283. return ai;
  284. }
  285. void ArrayInitializer::addInit(Expression *index, Initializer *value)
  286. {
  287. this->index.push(index);
  288. this->value.push(value);
  289. dim = 0;
  290. type = NULL;
  291. }
  292. Initializer *ArrayInitializer::semantic(Scope *sc, Type *t)
  293. { unsigned i;
  294. unsigned length;
  295. const unsigned amax = 0x80000000;
  296. //printf("ArrayInitializer::semantic(%s)\n", t->toChars());
  297. if (sem) // if semantic() already run
  298. return this;
  299. sem = 1;
  300. type = t;
  301. t = t->toBasetype();
  302. switch (t->ty)
  303. {
  304. case Tpointer:
  305. case Tsarray:
  306. case Tarray:
  307. break;
  308. default:
  309. error(loc, "cannot use array to initialize %s", type->toChars());
  310. goto Lerr;
  311. }
  312. length = 0;
  313. for (i = 0; i < index.dim; i++)
  314. {
  315. Expression *idx = (Expression *)index.data[i];
  316. if (idx)
  317. { idx = idx->semantic(sc);
  318. idx = idx->optimize(WANTvalue | WANTinterpret);
  319. index.data[i] = (void *)idx;
  320. length = idx->toInteger();
  321. }
  322. Initializer *val = (Initializer *)value.data[i];
  323. val = val->semantic(sc, t->nextOf());
  324. value.data[i] = (void *)val;
  325. length++;
  326. if (length == 0)
  327. { error(loc, "array dimension overflow");
  328. goto Lerr;
  329. }
  330. if (length > dim)
  331. dim = length;
  332. }
  333. if (t->ty == Tsarray)
  334. {
  335. dinteger_t edim = ((TypeSArray *)t)->dim->toInteger();
  336. if (dim > edim)
  337. {
  338. error(loc, "array initializer has %u elements, but array length is %jd", dim, edim);
  339. goto Lerr;
  340. }
  341. }
  342. if ((unsigned long) dim * t->nextOf()->size() >= amax)
  343. { error(loc, "array dimension %u exceeds max of %ju", dim, amax / t->nextOf()->size());
  344. goto Lerr;
  345. }
  346. return this;
  347. Lerr:
  348. return new ExpInitializer(loc, new ErrorExp());
  349. }
  350. /********************************
  351. * If possible, convert array initializer to array literal.
  352. */
  353. Expression *ArrayInitializer::toExpression()
  354. { Expressions *elements;
  355. Expression *e;
  356. //printf("ArrayInitializer::toExpression(), dim = %d\n", dim);
  357. //static int i; if (++i == 2) halt();
  358. size_t edim;
  359. Type *t = NULL;
  360. if (type)
  361. {
  362. if (type == Type::terror)
  363. return new ErrorExp();
  364. t = type->toBasetype();
  365. switch (t->ty)
  366. {
  367. case Tsarray:
  368. edim = ((TypeSArray *)t)->dim->toInteger();
  369. break;
  370. case Tpointer:
  371. case Tarray:
  372. edim = dim;
  373. break;
  374. default:
  375. assert(0);
  376. }
  377. }
  378. else
  379. {
  380. edim = value.dim;
  381. for (size_t i = 0, j = 0; i < value.dim; i++, j++)
  382. {
  383. if (index.data[i])
  384. j = ((Expression *)index.data[i])->toInteger();
  385. if (j >= edim)
  386. edim = j + 1;
  387. }
  388. }
  389. elements = new Expressions();
  390. elements->setDim(edim);
  391. for (size_t i = 0, j = 0; i < value.dim; i++, j++)
  392. {
  393. if (index.data[i])
  394. j = ((Expression *)index.data[i])->toInteger();
  395. assert(j < edim);
  396. Initializer *iz = (Initializer *)value.data[i];
  397. if (!iz)
  398. goto Lno;
  399. Expression *ex = iz->toExpression();
  400. if (!ex)
  401. {
  402. goto Lno;
  403. }
  404. elements->data[j] = ex;
  405. }
  406. /* Fill in any missing elements with the default initializer
  407. */
  408. {
  409. Expression *init = NULL;
  410. for (size_t i = 0; i < edim; i++)
  411. {
  412. if (!elements->data[i])
  413. {
  414. if (!type)
  415. goto Lno;
  416. if (!init)
  417. init = t->next->defaultInit();
  418. elements->data[i] = init;
  419. }
  420. }
  421. Expression *e = new ArrayLiteralExp(loc, elements);
  422. e->type = type;
  423. return e;
  424. }
  425. Lno:
  426. delete elements;
  427. error(loc, "array initializers as expressions are not allowed");
  428. return new ErrorExp();
  429. }
  430. /********************************
  431. * If possible, convert array initializer to associative array initializer.
  432. */
  433. Initializer *ArrayInitializer::toAssocArrayInitializer()
  434. { Expressions *keys;
  435. Expressions *values;
  436. Expression *e;
  437. //printf("ArrayInitializer::toAssocArrayInitializer()\n");
  438. //static int i; if (++i == 2) halt();
  439. keys = new Expressions();
  440. keys->setDim(value.dim);
  441. values = new Expressions();
  442. values->setDim(value.dim);
  443. for (size_t i = 0; i < value.dim; i++)
  444. {
  445. e = (Expression *)index.data[i];
  446. if (!e)
  447. goto Lno;
  448. keys->data[i] = (void *)e;
  449. Initializer *iz = (Initializer *)value.data[i];
  450. if (!iz)
  451. goto Lno;
  452. e = iz->toExpression();
  453. if (!e)
  454. goto Lno;
  455. values->data[i] = (void *)e;
  456. }
  457. e = new AssocArrayLiteralExp(loc, keys, values);
  458. return new ExpInitializer(loc, e);
  459. Lno:
  460. delete keys;
  461. delete values;
  462. error(loc, "not an associative array initializer");
  463. return this;
  464. }
  465. Type *ArrayInitializer::inferType(Scope *sc)
  466. {
  467. for (size_t i = 0; i < value.dim; i++)
  468. {
  469. if (index.data[i])
  470. goto Laa;
  471. }
  472. if (value.dim)
  473. {
  474. Initializer *iz = (Initializer *)value.data[0];
  475. if (iz)
  476. { Type *t = iz->inferType(sc);
  477. t = new TypeSArray(t, new IntegerExp(value.dim));
  478. t = t->semantic(loc, sc);
  479. return t;
  480. }
  481. }
  482. Laa:
  483. /* It's possibly an associative array initializer
  484. */
  485. Initializer *iz = (Initializer *)value.data[0];
  486. Expression *indexinit = (Expression *)index.data[0];
  487. if (iz && indexinit)
  488. { Type *t = iz->inferType(sc);
  489. indexinit = indexinit->semantic(sc);
  490. Type *indext = indexinit->type;
  491. t = new TypeAArray(t, indext);
  492. type = t->semantic(loc, sc);
  493. }
  494. else
  495. error(loc, "cannot infer type from this array initializer");
  496. return type;
  497. }
  498. void ArrayInitializer::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
  499. {
  500. buf->writebyte('[');
  501. for (int i = 0; i < index.dim; i++)
  502. {
  503. if (i > 0)
  504. buf->writebyte(',');
  505. Expression *ex = (Expression *)index.data[i];
  506. if (ex)
  507. {
  508. ex->toCBuffer(buf, hgs);
  509. buf->writebyte(':');
  510. }
  511. Initializer *iz = (Initializer *)value.data[i];
  512. if (iz)
  513. iz->toCBuffer(buf, hgs);
  514. }
  515. buf->writebyte(']');
  516. }
  517. /********************************** ExpInitializer ************************************/
  518. ExpInitializer::ExpInitializer(Loc loc, Expression *exp)
  519. : Initializer(loc)
  520. {
  521. this->exp = exp;
  522. }
  523. Initializer *ExpInitializer::syntaxCopy()
  524. {
  525. return new ExpInitializer(loc, exp->syntaxCopy());
  526. }
  527. Initializer *ExpInitializer::semantic(Scope *sc, Type *t)
  528. {
  529. //printf("ExpInitializer::semantic(%s), type = %s\n", exp->toChars(), t->toChars());
  530. exp = exp->semantic(sc);
  531. Type *tb = t->toBasetype();
  532. /* Look for case of initializing a static array with a too-short
  533. * string literal, such as:
  534. * char[5] foo = "abc";
  535. * Allow this by doing an explicit cast, which will lengthen the string
  536. * literal.
  537. */
  538. if (exp->op == TOKstring && tb->ty == Tsarray && exp->type->ty == Tsarray)
  539. { StringExp *se = (StringExp *)exp;
  540. if (!se->committed && se->type->ty == Tsarray &&
  541. ((TypeSArray *)se->type)->dim->toInteger() <
  542. ((TypeSArray *)t)->dim->toInteger())
  543. {
  544. exp = se->castTo(sc, t);
  545. goto L1;
  546. }
  547. }
  548. // Look for the case of statically initializing an array
  549. // with a single member.
  550. if (tb->ty == Tsarray &&
  551. !tb->nextOf()->equals(exp->type->toBasetype()->nextOf()) &&
  552. exp->implicitConvTo(tb->nextOf())
  553. )
  554. {
  555. t = tb->nextOf();
  556. }
  557. exp = exp->implicitCastTo(sc, t);
  558. L1:
  559. exp = exp->optimize(WANTvalue | WANTinterpret);
  560. //printf("-ExpInitializer::semantic(): "); exp->print();
  561. return this;
  562. }
  563. Type *ExpInitializer::inferType(Scope *sc)
  564. {
  565. //printf("ExpInitializer::inferType() %s\n", toChars());
  566. exp = exp->semantic(sc);
  567. exp = resolveProperties(sc, exp);
  568. // Give error for overloaded function addresses
  569. if (exp->op == TOKsymoff)
  570. { SymOffExp *se = (SymOffExp *)exp;
  571. if (
  572. #if DMDV2
  573. se->hasOverloads &&
  574. #else
  575. se->var->isFuncDeclaration() &&
  576. #endif
  577. !se->var->isFuncDeclaration()->isUnique())
  578. exp->error("cannot infer type from overloaded function symbol %s", exp->toChars());
  579. }
  580. // Give error for overloaded function addresses
  581. if (exp->op == TOKdelegate)
  582. { DelegateExp *se = (DelegateExp *)exp;
  583. if (
  584. se->func->isFuncDeclaration() &&
  585. !se->func->isFuncDeclaration()->isUnique())
  586. exp->error("cannot infer type from overloaded function symbol %s", exp->toChars());
  587. }
  588. Type *t = exp->type;
  589. if (!t)
  590. t = Initializer::inferType(sc);
  591. return t;
  592. }
  593. Expression *ExpInitializer::toExpression()
  594. {
  595. return exp;
  596. }
  597. void ExpInitializer::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
  598. {
  599. exp->toCBuffer(buf, hgs);
  600. }