Changeset 882
- Timestamp:
- 03/08/08 17:16:54 (6 months ago)
- Files:
-
- branches/dmdfe-2.0/Makefile (modified) (1 diff)
- branches/dmdfe-2.0/access.c (modified) (1 diff)
- branches/dmdfe-2.0/aggregate.h (modified) (11 diffs)
- branches/dmdfe-2.0/attrib.c (modified) (3 diffs)
- branches/dmdfe-2.0/cast.c (modified) (2 diffs)
- branches/dmdfe-2.0/class.c (modified) (2 diffs)
- branches/dmdfe-2.0/clone.c (added)
- branches/dmdfe-2.0/declaration.c (modified) (6 diffs)
- branches/dmdfe-2.0/declaration.h (modified) (3 diffs)
- branches/dmdfe-2.0/doc.c (modified) (10 diffs)
- branches/dmdfe-2.0/dsymbol.h (modified) (3 diffs)
- branches/dmdfe-2.0/e2ir.c (added)
- branches/dmdfe-2.0/expression.c (modified) (45 diffs)
- branches/dmdfe-2.0/expression.h (modified) (15 diffs)
- branches/dmdfe-2.0/func.c (modified) (27 diffs)
- branches/dmdfe-2.0/idgen.c (modified) (5 diffs)
- branches/dmdfe-2.0/interpret.c (modified) (3 diffs)
- branches/dmdfe-2.0/lexer.c (modified) (5 diffs)
- branches/dmdfe-2.0/lexer.h (modified) (4 diffs)
- branches/dmdfe-2.0/link.c (modified) (1 diff)
- branches/dmdfe-2.0/mars.c (modified) (2 diffs)
- branches/dmdfe-2.0/mtype.c (modified) (13 diffs)
- branches/dmdfe-2.0/mtype.h (modified) (1 diff)
- branches/dmdfe-2.0/parse.c (modified) (7 diffs)
- branches/dmdfe-2.0/parse.h (modified) (2 diffs)
- branches/dmdfe-2.0/scope.c (modified) (2 diffs)
- branches/dmdfe-2.0/scope.h (modified) (1 diff)
- branches/dmdfe-2.0/statement.c (modified) (54 diffs)
- branches/dmdfe-2.0/statement.h (modified) (35 diffs)
- branches/dmdfe-2.0/struct.c (modified) (4 diffs)
- branches/dmdfe-2.0/template.c (modified) (9 diffs)
- branches/dmdfe-2.0/template.h (modified) (1 diff)
- branches/dmdfe-2.0/tocsym.c (modified) (1 diff)
- branches/dmdfe-2.0/toir.c (modified) (1 diff)
- branches/dmdfe-2.0/toobj.c (modified) (5 diffs)
- branches/dmdfe-2.0/traits.c (modified) (1 diff)
- branches/dmdfe-2.0/typinf.c (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/dmdfe-2.0/Makefile
r783 r882 14 14 cast.o \ 15 15 class.o \ 16 clone.o \ 16 17 cond.o \ 17 18 constfold.o \ branches/dmdfe-2.0/access.c
r458 r882 254 254 { 255 255 error(loc, "member %s is not accessible", smember->toChars()); 256 halt(); 256 257 } 257 258 } branches/dmdfe-2.0/aggregate.h
r836 r882 1 1 2 2 // Compiler implementation of the D programming language 3 // Copyright (c) 1999-200 7by Digital Mars3 // Copyright (c) 1999-2008 by Digital Mars 4 4 // All Rights Reserved 5 5 // written by Walter Bright … … 58 58 DeleteDeclaration *aggDelete; // deallocator 59 59 60 FuncDeclarations dtors; // Array of destructors 61 FuncDeclaration *dtor; // aggregate destructor 62 60 63 #ifdef IN_GCC 61 64 Array methods; // flat list of all methods for debug information … … 71 74 void addField(Scope *sc, VarDeclaration *v); 72 75 int isDeprecated(); // is aggregate deprecated? 76 FuncDeclaration *buildDtor(Scope *sc); 73 77 74 78 void emitComment(Scope *sc); … … 103 107 { 104 108 int zeroInit; // !=0 if initialize with 0 fill 109 int hasIdentityAssign; // !=0 if has identity opAssign 110 FuncDeclaration *cpctor; // generated copy-constructor, if any 111 112 FuncDeclarations postblits; // Array of postblit functions 113 FuncDeclaration *postblit; // aggregate postblit 105 114 106 115 StructDeclaration(Loc loc, Identifier *id); … … 110 119 char *mangle(); 111 120 char *kind(); 121 int needOpAssign(); 122 FuncDeclaration *buildOpAssign(Scope *sc); 123 FuncDeclaration *buildPostBlit(Scope *sc); 124 FuncDeclaration *buildCpCtor(Scope *sc); 112 125 void toDocBuffer(OutBuffer *buf); 113 126 … … 149 162 }; 150 163 164 #if V2 151 165 #define CLASSINFO_SIZE (0x3C+16) // value of ClassInfo.size 166 #else 167 #define CLASSINFO_SIZE (0x3C+12) // value of ClassInfo.size 168 #endif 152 169 153 170 struct ClassDeclaration : AggregateDeclaration … … 159 176 CtorDeclaration *ctor; 160 177 CtorDeclaration *defaultCtor; // default constructor 161 FuncDeclarations dtors; // Array of destructors162 178 FuncDeclaration *staticCtor; 163 179 FuncDeclaration *staticDtor; … … 194 210 195 211 Dsymbol *search(Loc, Identifier *ident, int flags); 212 #if V2 196 213 int isFuncHidden(FuncDeclaration *fd); 214 #endif 197 215 FuncDeclaration *findFunc(Identifier *ident, TypeFunction *tf); 198 216 void interfaceSemantic(Scope *sc); … … 200 218 int isCOMclass(); 201 219 virtual int isCOMinterface(); 220 #if V2 202 221 virtual int isCPPinterface(); 222 #endif 203 223 int isAbstract(); 204 224 virtual int vtblOffset(); … … 224 244 struct InterfaceDeclaration : ClassDeclaration 225 245 { 246 #if V2 226 247 int cpp; // !=0 if this is a C++ interface 227 248 #endif 228 249 InterfaceDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses); 229 250 Dsymbol *syntaxCopy(Dsymbol *s); … … 233 254 char *kind(); 234 255 int vtblOffset(); 256 #if V2 235 257 int isCPPinterface(); 258 #endif 236 259 virtual int isCOMinterface(); 237 260 branches/dmdfe-2.0/attrib.c
r880 r882 1 1 2 2 // Compiler implementation of the D programming language 3 // Copyright (c) 1999-200 7by Digital Mars3 // Copyright (c) 1999-2008 by Digital Mars 4 4 // All Rights Reserved 5 5 // written by Walter Bright … … 30 30 #include "module.h" 31 31 #include "parse.h" 32 #include "template.h" 32 33 33 34 extern void obj_includelib(char *name); 35 void obj_startaddress(Symbol *s); 34 36 35 37 … … 800 802 } 801 803 #endif 804 else if (ident == Id::startaddress) 805 { 806 if (!args || args->dim != 1) 807 error("function name expected for start address"); 808 else 809 { 810 Expression *e = (Expression *)args->data[0]; 811 e = e->semantic(sc); 812 e = e->optimize(WANTvalue | WANTinterpret); 813 args->data[0] = (void *)e; 814 Dsymbol *sa = getDsymbol(e); 815 if (!sa || !sa->isFuncDeclaration()) 816 error("function name expected for start address, not '%s'", e->toChars()); 817 } 818 goto Lnodecl; 819 } 802 820 else 803 821 error("unrecognized pragma(%s)", ident->toChars()); branches/dmdfe-2.0/cast.c
r881 r882 342 342 if (this->type->equals(t)) 343 343 return MATCHexact; 344 345 /* Allow implicit conversions from invariant to mutable|const, 346 * and mutable to invariant. It works because, after all, a null 347 * doesn't actually point to anything. 348 */ 349 if (t->invariantOf()->equals(type->invariantOf())) 350 return MATCHconst; 351 344 352 // NULL implicitly converts to any pointer type or dynamic array 345 353 if (type->ty == Tpointer && type->nextOf()->ty == Tvoid) … … 353 361 } 354 362 return Expression::implicitConvTo(t); 363 } 364 365 MATCH StructLiteralExp::implicitConvTo(Type *t) 366 { 367 #if 0 368 printf("StructLiteralExp::implicitConvTo(this=%s, type=%s, t=%s)\n", 369 toChars(), type->toChars(), t->toChars()); 370 #endif 371 MATCH m = Expression::implicitConvTo(t); 372 if (m != MATCHnomatch) 373 return m; 374 if (type->ty == t->ty && type->ty == Tstruct && 375 ((TypeStruct *)type)->sym == ((TypeStruct *)t)->sym) 376 { 377 m = MATCHconst; 378 for (int i = 0; i < elements->dim; i++) 379 { Expression *e = (Expression *)elements->data[i]; 380 Type *te = e->type; 381 if (t->mod == 0) 382 te = te->mutableOf(); 383 else 384 { assert(t->mod == MODinvariant); 385 te = te->invariantOf(); 386 } 387 MATCH m2 = e->implicitConvTo(te); 388 //printf("\t%s => %s, match = %d\n", e->toChars(), te->toChars(), m2); 389 if (m2 < m) 390 m = m2; 391 } 392 } 393 return m; 355 394 } 356 395 branches/dmdfe-2.0/class.c
r846 r882 1 1 2 2 // Compiler implementation of the D programming language 3 // Copyright (c) 1999-200 7by Digital Mars3 // Copyright (c) 1999-2008 by Digital Mars 4 4 // All Rights Reserved 5 5 // written by Walter Bright … … 653 653 Module::dprogress++; 654 654 655 dtor = buildDtor(sc); 655 656 656 657 sc->pop(); branches/dmdfe-2.0/declaration.c
r881 r882 689 689 type = type->semantic(loc, sc); 690 690 } 691 //printf(" type = %s\n", type ? type->toChars() : "null");691 //printf(" semantic type = %s\n", type ? type->toChars() : "null"); 692 692 693 693 type->checkDeprecated(loc, sc); … … 730 730 Objects *exps = new Objects(); 731 731 exps->setDim(nelems); 732 Expression *ie = init ? init->toExpression() : NULL; 732 733 733 734 for (size_t i = 0; i < nelems; i++) … … 740 741 Identifier *id = new Identifier(name, TOKidentifier); 741 742 742 VarDeclaration *v = new VarDeclaration(loc, arg->type, id, NULL); 743 Expression *einit = ie; 744 if (ie && ie->op == TOKtuple) 745 { einit = (Expression *)((TupleExp *)ie)->exps->data[i]; 746 } 747 Initializer *ti = init; 748 if (einit) 749 { ti = new ExpInitializer(einit->loc, einit); 750 } 751 752 VarDeclaration *v = new VarDeclaration(loc, arg->type, id, ti); 743 753 //printf("declaring field %s of type %s\n", v->toChars(), v->type->toChars()); 744 754 v->semantic(sc); … … 1109 1119 if (init) 1110 1120 { buf->writestring(" = "); 1111 init->toCBuffer(buf, hgs); 1121 ExpInitializer *ie = init->isExpInitializer(); 1122 if (ie && ie->exp->op == TOKconstruct) 1123 ((AssignExp *)ie->exp)->e2->toCBuffer(buf, hgs); 1124 else 1125 init->toCBuffer(buf, hgs); 1112 1126 } 1113 1127 buf->writeByte(';'); … … 1279 1293 */ 1280 1294 1281 Expression *VarDeclaration::callAutoDtor( )1295 Expression *VarDeclaration::callAutoDtor(Scope *sc) 1282 1296 { Expression *e = NULL; 1283 1297 1284 1298 //printf("VarDeclaration::callAutoDtor() %s\n", toChars()); 1285 if (storage_class & (STCauto | STCscope) && !noauto) 1299 1300 if (noauto || storage_class & STCnodtor) 1301 return NULL; 1302 1303 FuncDeclaration *fd = sc->parent->isFuncDeclaration(); 1304 if (fd && fd->nrvo_var == this) 1305 return NULL; 1306 1307 // Destructors for structs and arrays of structs 1308 bool array = false; 1309 Type *tv = type->toBasetype(); 1310 while (tv->ty == Tsarray) 1311 { TypeSArray *ta = (TypeSArray *)tv; 1312 array = true; 1313 tv = tv->nextOf()->toBasetype(); 1314 } 1315 if (tv->ty == Tstruct) 1316 { TypeStruct *ts = (TypeStruct *)tv; 1317 StructDeclaration *sd = ts->sym; 1318 if (sd->dtor) 1319 { 1320 if (array) 1321 { 1322 // Typeinfo.destroy(cast(void*)&v); 1323 Expression *ea = new SymOffExp(loc, this, 0, 0); 1324 ea = new CastExp(loc, ea, Type::tvoid->pointerTo()); 1325 Expressions *args = new Expressions(); 1326 args->push(ea); 1327 1328 Expression *et = type->getTypeInfo(sc); 1329 et = new DotIdExp(loc, et, Id::destroy); 1330 1331 e = new CallExp(loc, et, args); 1332 } 1333 else 1334 { 1335 e = new VarExp(loc, this); 1336 e = new DotVarExp(loc, e, sd->dtor, 0); 1337 e = new CallExp(loc, e); 1338 } 1339 return e; 1340 } 1341 } 1342 1343 // Destructors for classes 1344 if (storage_class & (STCauto | STCscope)) 1286 1345 { 1287 1346 for (ClassDeclaration *cd = type->isClassHandle(); … … 1293 1352 * could be set. 1294 1353 */ 1295 if (cd->isInterfaceDeclaration())1296 error("interface %s cannot be scope", cd->toChars());1354 //if (cd->isInterfaceDeclaration()) 1355 //error("interface %s cannot be scope", cd->toChars()); 1297 1356 if (1 || onstack || cd->dtors.dim) // if any destructors 1298 1357 { branches/dmdfe-2.0/declaration.h
r880 r882 66 66 STCinit = 0x400000, // has explicit initializer 67 67 STCmanifest = 0x800000, // manifest constant 68 STCnodtor = 0x1000000, // don't run destructor 69 STCnothrow = 0x2000000, // never throws exceptions 68 70 }; 69 71 … … 242 244 int hasPointers(); 243 245 int canTakeAddressOf(); 244 Expression *callAutoDtor( );246 Expression *callAutoDtor(Scope *sc); 245 247 ExpInitializer *getExpInitializer(); 246 248 Expression *getConstInitializer(); … … 565 567 }; 566 568 569 struct PostBlitDeclaration : FuncDeclaration 570 { 571 PostBlitDeclaration(Loc loc, Loc endloc); 572 PostBlitDeclaration(Loc loc, Loc endloc, Identifier *id); 573 Dsymbol *syntaxCopy(Dsymbol *); 574 void semantic(Scope *sc); 575 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 576 int isVirtual(); 577 int addPreInvariant(); 578 int addPostInvariant(); 579 int overloadInsert(Dsymbol *s); 580 void emitComment(Scope *sc); 581 582 PostBlitDeclaration *isPostBlitDeclaration() { return this; } 583 }; 584 567 585 struct DtorDeclaration : FuncDeclaration 568 586 { 569 587 DtorDeclaration(Loc loc, Loc endloc); 588 DtorDeclaration(Loc loc, Loc endloc, Identifier *id); 570 589 Dsymbol *syntaxCopy(Dsymbol *); 571 590 void semantic(Scope *sc); branches/dmdfe-2.0/doc.c
r846 r882 1 1 2 2 // Compiler implementation of the D programming language 3 // Copyright (c) 1999-200 6by Digital Mars3 // Copyright (c) 1999-2008 by Digital Mars 4 4 // All Rights Reserved 5 5 // written by Walter Bright … … 103 103 unsigned skiptoident(OutBuffer *buf, unsigned i); 104 104 unsigned skippastident(OutBuffer *buf, unsigned i); 105 unsigned skippastURL(OutBuffer *buf, unsigned i); 105 106 void highlightText(Scope *sc, Dsymbol *s, OutBuffer *buf, unsigned offset); 106 107 void highlightCode(Scope *sc, Dsymbol *s, OutBuffer *buf, unsigned offset); … … 115 116 <h1>$(TITLE)</h1>\n\ 116 117 $(BODY)\n\ 117 <hr>$(SMALL Page generated by $(LINK2 http://www.digitalmars.com/d/ ddoc.html, Ddoc). $(COPYRIGHT))\n\118 <hr>$(SMALL Page generated by $(LINK2 http://www.digitalmars.com/d/2.0/ddoc.html, Ddoc). $(COPYRIGHT))\n\ 118 119 </body></html>\n\ 119 120 \n\ … … 372 373 void Dsymbol::emitDitto(Scope *sc) 373 374 { 375 //printf("Dsymbol::emitDitto() %s %s\n", kind(), toChars()); 374 376 OutBuffer *buf = sc->docbuf; 375 377 unsigned o; … … 377 379 378 380 b.writestring("$(DDOC_DITTO "); 379 o = b.offset; 380 toDocBuffer(&b); 381 highlightCode(sc, this, &b, o); 381 o = b.offset; 382 toDocBuffer(&b); 383 //printf("b: '%.*s'\n", b.offset, b.data); 384 /* If 'this' is a function template, then highlightCode() was 385 * already run by FuncDeclaration::toDocbuffer(). 386 */ 387 TemplateDeclaration *td; 388 if (parent && 389 (td = parent->isTemplateDeclaration()) != NULL && 390 td->onemember == this) 391 { 392 } 393 else 394 highlightCode(sc, this, &b, o); 382 395 b.writeByte(')'); 383 396 buf->spread(sc->lastoffset, b.offset); … … 436 449 void Dsymbol::emitComment(Scope *sc) { } 437 450 void InvariantDeclaration::emitComment(Scope *sc) { } 451 void PostBlitDeclaration::emitComment(Scope *sc) { } 438 452 void DtorDeclaration::emitComment(Scope *sc) { } 439 453 void StaticCtorDeclaration::emitComment(Scope *sc) { } … … 636 650 HdrGenState hgs; 637 651 652 hgs.ddoc = 1; 638 653 toCBuffer(buf, &hgs); 639 654 } … … 739 754 buf->writestring(ident->toChars()); 740 755 buf->writeByte('('); 741 for (int i = 0; i < td-> parameters->dim; i++)756 for (int i = 0; i < td->origParameters->dim; i++) 742 757 { 743 TemplateParameter *tp = (TemplateParameter *)td-> parameters->data[i];758 TemplateParameter *tp = (TemplateParameter *)td->origParameters->data[i]; 744 759 if (i) 745 760 buf->writeByte(','); … … 1492 1507 1493 1508 1509 /************************************************ 1510 * Scan forward past URL starting at i. 1511 * We don't want to highlight parts of a URL. 1512 * Returns: 1513 * i if not a URL 1514 * index just past it if it is a URL 1515 */ 1516 1517 unsigned skippastURL(OutBuffer *buf, unsigned i) 1518 { unsigned length = buf->offset - i; 1519 unsigned char *p = &buf->data[i]; 1520 unsigned j; 1521 unsigned sawdot = 0; 1522 1523 if (length > 7 && memicmp((char *)p, "http://", 7) == 0) 1524 { 1525 j = 7; 1526 } 1527 else if (length > 8 && memicmp((char *)p, "https://", 8) == 0) 1528 { 1529 j = 8; 1530 } 1531 else 1532 goto Lno; 1533 1534 for (; j < length; j++) 1535 { unsigned char c = p[j]; 1536 if (isalnum(c)) 1537 continue; 1538 if (c == '-' || c == '_' || c == '?' || 1539 c == '=' || c == '%' || c == '&' || 1540 c == '/' || c == '+' || c == '#' || 1541 c == '~') 1542 continue; 1543 if (c == '.') 1544 { 1545 sawdot = 1; 1546 continue; 1547 } 1548 break; 1549 } 1550 if (sawdot) 1551 return i + j; 1552 1553 Lno: 1554 return i; 1555 } 1556 1557 1494 1558 /**************************************************** 1495 1559 */ … … 1736 1800 if (j > i) 1737 1801 { 1802 unsigned k = skippastURL(buf, i); 1803 if (k > i) 1804 { i = k - 1; 1805 break; 1806 } 1807 1738 1808 if (buf->data[i] == '_') // leading '_' means no highlight 1739 1809 { branches/dmdfe-2.0/dsymbol.h
r837 r882 1 1 2 2 // Compiler implementation of the D programming language 3 // Copyright (c) 1999-200 7by Digital Mars3 // Copyright (c) 1999-2008 by Digital Mars 4 4 // All Rights Reserved 5 5 // written by Walter Bright … … 39 39 struct FuncLiteralDeclaration; 40 40 struct CtorDeclaration; 41 struct PostBlitDeclaration; 41 42 struct DtorDeclaration; 42 43 struct StaticCtorDeclaration; … … 185 186 virtual FuncLiteralDeclaration *isFuncLiteralDeclaration() { return NULL; } 186 187 virtual CtorDeclaration *isCtorDeclaration() { return NULL; } 188 virtual PostBlitDeclaration *isPostBlitDeclaration() { return NULL; } 187 189 virtual DtorDeclaration *isDtorDeclaration() { return NULL; } 188 190 virtual StaticCtorDeclaration *isStaticCtorDeclaration() { return NULL; } branches/dmdfe-2.0/expression.c
r881 r882 1 1 2 2 // Compiler implementation of the D programming language 3 // Copyright (c) 1999-200 7by Digital Mars3 // Copyright (c) 1999-2008 by Digital Mars 4 4 // All Rights Reserved 5 5 // written by Walter Bright … … 177 177 178 178 precedence[TOKassign] = PREC_assign; 179 precedence[TOKconstruct] = PREC_assign; 180 precedence[TOKblit] = PREC_assign; 179 181 precedence[TOKaddass] = PREC_assign; 180 182 precedence[TOKminass] = PREC_assign; … … 298 300 } 299 301 302 303 /****************************** 304 * Perform canThrow() on an array of Expressions. 305 */ 306 307 int arrayExpressionCanThrow(Expressions *exps) 308 { 309 if (exps) 310 { 311 for (size_t i = 0; i < exps->dim; i++) 312 { Expression *e = (Expression *)exps->data[i]; 313 if (e && e->canThrow()) 314 return 1; 315 } 316 } 317 return 0; 318 } 319 320 300 321 /**************************************** 301 322 * Expand tuples. … … 382 403 } 383 404 405 /********************************************* 406 * Call copy constructor for struct value argument. 407 */ 408 409 Expression *callCpCtor(Loc loc, Scope *sc, Expression *e) 410 { 411 Type *tb = e->type->toBasetype(); 412 assert(tb->ty == Tstruct); 413 StructDeclaration *sd = ((TypeStruct *)tb)->sym; 414 if (sd->cpctor) 415 { 416 /* Create a variable tmp, and replace the argument e with: 417 * (tmp = e),tmp 418 * and let AssignExp() handle the construction. 419 * This is not the most efficent, ideally tmp would be constructed 420 * directly onto the stack. 421 */ 422 Identifier *idtmp = Lexer::uniqueId("__tmp"); 423 VarDeclaration *tmp = new VarDeclaration(loc, tb, idtmp, new ExpInitializer(0, e)); 424 Expression *ae = new DeclarationExp(loc, tmp); 425 e = new CommaExp(loc, ae, new VarExp(loc, tmp)); 426 e = e->semantic(sc); 427 } 428 return e; 429 } 384 430 385 431 /**************************************** 386 432 * Now that we know the exact type of the function we're calling, 387 433 * the arguments[] need to be adjusted: 388 * 1) implicitly convert argument to the corresponding parameter type 389 * 2) add default arguments for any missing arguments 390 * 3) do default promotions on arguments corresponding to ... 391 * 4) add hidden _arguments[] argument 434 * 1. implicitly convert argument to the corresponding parameter type 435 * 2. add default arguments for any missing arguments 436 * 3. do default promotions on arguments corresponding to ... 437 * 4. add hidden _arguments[] argument 438 * 5. call copy constructor for struct value arguments 392 439 */ 393 440 … … 395 442 { 396 443 unsigned n; 397 int done;398 Type *tb;399 444 400 445 //printf("functionArguments()\n"); … … 408 453 n = (nargs > nparams) ? nargs : nparams; // n = max(nargs, nparams) 409 454 410 done = 0;455 int done = 0; 411 456 for (size_t i = 0; i < n; i++) 412 457 { … … 417 462 else 418 463 arg = NULL; 464 Type *tb; 419 465 420 466 if (i < nparams) … … 463 509 } 464 510 #endif 465 static int idn; 466 char name[10 + sizeof(idn)*3 + 1]; 467 sprintf(name, "__arrayArg%d", ++idn); 468 Identifier *id = Lexer::idPool(name); 511 Identifier *id = Lexer::uniqueId("__arrayArg"); 469 512 Type *t = new TypeSArray(((TypeArray *)tb)->next, new IntegerExp(nargs - i)); 470 513 t = t->semantic(loc, sc); … … 545 588 } 546 589 590 if (tb->ty == Tstruct && !(p->storageClass & (STCref | STCout))) 591 { 592 arg = callCpCtor(loc, sc, arg); 593 } 594 547 595 // Convert lazy argument to a delegate 548 596 if (p->storageClass & STClazy) … … 586 634 } 587 635 636 if (tb->ty == Tstruct) 637 { 638 arg = callCpCtor(loc, sc, arg); 639 } 640 588 641 // Give error for overloaded function addresses 589 642 if (arg->op == TOKsymoff) … … 594 647 arg->rvalue(); 595 648 } 649 596 650 arg = arg->optimize(WANTvalue); 597 651 arguments->data[i] = (void *) arg; … … 1011 1065 return FALSE; 1012 1066 } 1067 1068 /******************************** 1069 * Can this expression throw an exception? 1070 * Valid only after semantic() pass. 1071 */ 1072 1073 int Expression::canThrow() 1074 { 1075 return FALSE; 1076 } 1077 1078 1013 1079 1014 1080 Expressions *Expression::arraySyntaxCopy(Expressions *exps) … … 2551 2617 } 2552 2618 2619 int ArrayLiteralExp::canThrow() 2620 { 2621 return 1; // because it can fail allocating memory 2622 } 2623 2553 2624 void ArrayLiteralExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 2554 2625 { … … 2667 2738 size_t dim = keys->dim; 2668 2739 return result ? (dim != 0) : (dim == 0); 2740 } 2741 2742 int AssocArrayLiteralExp::canThrow() 2743 { 2744 return 1; 2669 2745 } 2670 2746 … … 2873 2949 Expression::checkSideEffect(0); 2874 2950 return f; 2951 } 2952 2953 int StructLiteralExp::canThrow() 2954 { 2955 return arrayExpressionCanThrow(elements); 2875 2956 } 2876 2957 … … 3348 3429 } 3349 3430 3431 int NewExp::canThrow() 3432 { 3433 return 1; 3434 } 3435 3350 3436 void NewExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 3351 3437 { int i; … … 3410 3496 3411 3497 int NewAnonClassExp::checkSideEffect(int flag) 3498 { 3499 return 1; 3500 } 3501 3502 int NewAnonClassExp::canThrow() 3412 3503 { 3413 3504 return 1; … … 3759 3850 } 3760 3851 3852 int TupleExp::canThrow() 3853 { 3854 return arrayExpressionCanThrow(exps); 3855 } 3856 3761 3857 void TupleExp::checkEscape() 3762 3858 { … … 3882 3978 else if (sc->func) 3883 3979 { VarDeclaration *v = s->isVarDeclaration(); 3884 if ( (s->isFuncDeclaration() /*|| v && v->storage_class & STCstatic*/) &&3980 if (s->isFuncDeclaration() && 3885 3981 !sc->func->localsymtab->insert(s)) 3886 3982 error("declaration %s is already defined in another scope in %s", s->toPrettyChars(), sc->func->toChars()); … … 3925 4021 { 3926 4022 return 1; 4023 } 4024 4025 int DeclarationExp::canThrow() 4026 { 4027 VarDeclaration *v = declaration->isVarDeclaration(); 4028 if (v && v->init) 4029 { ExpInitializer *ie = v->init->isExpInitializer(); 4030 return ie && ie->exp->canThrow(); 4031 } 4032 return 0; 3927 4033 } 3928 4034 … … 4370 4476 } 4371 4477 4478 int UnaExp::canThrow() 4479 { 4480 return e1->canThrow(); 4481 } 4482 4372 4483 void UnaExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 4373 4484 { … … 4491 4602 op == TOKminusminus || 4492 4603 op == TOKassign || 4604 op == TOKconstruct || 4605 op == TOKblit || 4493 4606 op == TOKaddass || 4494 4607 op == TOKminass || … … 4523 4636 } 4524 4637 4638 int BinExp::canThrow() 4639 { 4640 return e1->canThrow() || e2->canThrow(); 4641 } 4642 4525 4643 void BinExp::incompatibleTypes() 4526 4644 { … … 4689 4807 { 4690 4808 return 1; 4809 } 4810 4811 int AssertExp::canThrow() 4812 { 4813 return (global.params.useAssert != 0); 4691 4814 } 4692 4815 … … 4789 4912 eleft = NULL; 4790 4913 eright = e1; 4914 } 4915 4916 if (e1->op == TOKtuple && ident == Id::offsetof) 4917 { /* 'distribute' the .offsetof to each of the tuple elements. 4918 */ 4919 TupleExp *te = (TupleExp *)e1; 4920 Expressions *exps = new Expressions(); 4921 exps->setDim(te->exps->dim); 4922 for (int i = 0; i < exps->dim; i++) 4923 { Expression *e = (Expression *)te->exps->data[i]; 4924 e = e->semantic(sc); 4925 e = new DotIdExp(e->loc, e, Id::offsetof); 4926 exps->data[i] = (void *)e; 4927 } 4928 e = new TupleExp(loc, exps); 4929 e = e->semantic(sc); 4930 return e; 4791 4931 } 4792 4932 … … 5100 5240 } 5101 5241 } 5102 accessCheck(loc, sc, e1, var); 5242 if (!sc->noaccesscheck) 5243 accessCheck(loc, sc, e1, var); 5103 5244 } 5104 5245 } … … 5220 5361 t1 = t1->toBasetype(); 5221 5362 //t1->print(); 5363 5364 /* Extract the following from e1: 5365 * s: the symbol which ti should be a member of 5366 * eleft: if not NULL, it is the 'this' pointer for ti 5367 */ 5368 5222 5369 if (e1->op == TOKdotexp) 5223 5370 { DotExp *de = (DotExp *)e1; … … 5461 5608 Type *t1; 5462 5609 int istemp; 5610 Objects *targsi = NULL; // initial list of template arguments 5463 5611 5464 5612 #if LOGSEMANTIC 5465 5613 printf("CallExp::semantic() %s\n", toChars()); 5614 e1->dump(0); 5466 5615 #endif 5467 5616 if (type) … … 5523 5672 } 5524 5673 5674 /* This recognizes: 5675 * foo!(tiargs)(funcargs) 5676 */ 5677 if (e1->op == TOKimport && !e1->type) 5678 { ScopeExp *se = (ScopeExp *)e1; 5679 TemplateInstance *ti = se->sds->isTemplateInstance(); 5680 if (ti && !ti->semanticdone) 5681 { 5682 /* Attempt to instantiate ti. If that works, go with it. 5683 * If not, go with partial explicit specialization. 5684 */ 5685 unsigned errors = global.errors; 5686 global.gag++; 5687 ti->semantic(sc); 5688 global.gag--; 5689 if (errors != global.errors) 5690 { 5691 global.errors = errors; 5692 targsi = ti->tiargs; 5693 e1 = new IdentifierExp(loc, ti->name); 5694 } 5695 } 5696 } 5697 5698 /* This recognizes: 5699 * expr.foo!(tiargs)(funcargs) 5700 */ 5701 if (e1->op == TOKdotti && !e1->type) 5702 { DotTemplateInstanceExp *se = (DotTemplateInstanceExp *)e1; 5703 TemplateInstance *ti = se->ti; 5704 if (!ti->semanticdone) 5705 { 5706 /* Attempt to instantiate ti. If that works, go with it. 5707 * If not, go with partial explicit specialization. 5708 */ 5709 Expression *etmp; 5710 unsigned errors = global.errors; 5711 global.gag++; 5712 etmp = e1->semantic(sc); 5713 global.gag--; 5714 if (errors != global.errors) 5715 { 5716 global.errors = errors; 5717 targsi = ti->tiargs; 5718 e1 = new DotIdExp(loc, se->e1, ti->name); 5719 } 5720 else 5721 e1 = etmp; 5722 } 5723 } 5724 5525 5725 istemp = 0; 5526 5726 Lagain: … … 5649 5849 // Should fix deduceFunctionTemplate() so it works on NULL argument 5650 5850 arguments = new Expressions(); 5651 f = td->deduceFunctionTemplate(sc, loc, NULL, ue->e1, arguments);5851 f = td->deduceFunctionTemplate(sc, loc, targsi, ue->e1, arguments); 5652 5852 if (!f) 5653 5853 { type = Type::terror; … … 5849 6049 { TemplateDeclaration *td = s->isTemplateDeclaration(); 5850 6050 assert(td); 5851 f2 = td->deduceFunctionTemplate(sc, loc, NULL, NULL, arguments, 1);6051 f2 = td->deduceFunctionTemplate(sc, loc, targsi, NULL, arguments, 1); 5852 6052 } 5853 6053 if (f2) … … 5895 6095 { 5896 6096 TemplateExp *te = (TemplateExp *)e1; 5897 f = te->td->deduceFunctionTemplate(sc, loc, NULL, NULL, arguments);6097 f = te->td->deduceFunctionTemplate(sc, loc, targsi, NULL, arguments); 5898 6098 if (!f) 5899 6099 { type = Type::terror; … … 5976 6176 5977 6177 int CallExp::checkSideEffect(int flag) 6178 { 6179 return 1; 6180 } 6181 6182 int CallExp::canThrow() 5978 6183 { 5979 6184 return 1; … … 6308 6513 StructDeclaration *sd = ts->sym; 6309 6514 FuncDeclaration *f = sd->aggDelete; 6515 FuncDeclaration *fd = sd->dtor; 6516 6517 if (!f && !fd) 6518 break; 6519 6520 /* Construct: 6521 * ea = copy e1 to a tmp to do side effects only once 6522 * eb = call destructor 6523 * ec = call dealloc
