Changeset 694
- Timestamp:
- 07/24/07 01:17:13 (1 year ago)
- Files:
-
- branches/tango/docs/ChangeLog (modified) (1 diff)
- branches/tango/docs/NEWS (modified) (1 diff)
- branches/tango/dsss.conf (modified) (1 diff)
- branches/tango/hcf/path.d (modified) (13 diffs)
- branches/tango/rebuild/aggregate.h (modified) (1 diff)
- branches/tango/rebuild/attrib.c (modified) (1 diff)
- branches/tango/rebuild/cast.c (modified) (2 diffs)
- branches/tango/rebuild/class.c (modified) (1 diff)
- branches/tango/rebuild/constfold.c (modified) (4 diffs)
- branches/tango/rebuild/declaration.c (modified) (1 diff)
- branches/tango/rebuild/delegatize.c (modified) (1 diff)
- branches/tango/rebuild/dsymbol.c (modified) (1 diff)
- branches/tango/rebuild/enum.c (modified) (1 diff)
- branches/tango/rebuild/enum.h (modified) (2 diffs)
- branches/tango/rebuild/expression.c (modified) (25 diffs)
- branches/tango/rebuild/expression.h (modified) (8 diffs)
- branches/tango/rebuild/func.c (modified) (2 diffs)
- branches/tango/rebuild/hdrgen.h (modified) (1 diff)
- branches/tango/rebuild/idgen.c (modified) (4 diffs)
- branches/tango/rebuild/init.c (modified) (1 diff)
- branches/tango/rebuild/init.h (modified) (3 diffs)
- branches/tango/rebuild/inline.c (modified) (9 diffs)
- branches/tango/rebuild/interpret.c (modified) (19 diffs)
- branches/tango/rebuild/lexer.c (modified) (5 diffs)
- branches/tango/rebuild/lexer.h (modified) (1 diff)
- branches/tango/rebuild/link.c (modified) (1 diff)
- branches/tango/rebuild/mars.c (modified) (7 diffs)
- branches/tango/rebuild/mars.h (modified) (2 diffs)
- branches/tango/rebuild/module.c (modified) (1 diff)
- branches/tango/rebuild/mtype.c (modified) (13 diffs)
- branches/tango/rebuild/mtype.h (modified) (1 diff)
- branches/tango/rebuild/optimize.c (modified) (4 diffs)
- branches/tango/rebuild/parse.c (modified) (3 diffs)
- branches/tango/rebuild/rebuild.conf/gdc-posix (modified) (1 diff)
- branches/tango/rebuild/rebuild.conf/gdc-posix-tango (modified) (1 diff)
- branches/tango/rebuild/rebuild.exe (modified) (previous)
- branches/tango/rebuild/rebuild_choosedc.exe (modified) (previous)
- branches/tango/rebuild/scope.c (modified) (7 diffs)
- branches/tango/rebuild/scope.h (modified) (1 diff)
- branches/tango/rebuild/statement.c (modified) (23 diffs)
- branches/tango/rebuild/statement.h (modified) (3 diffs)
- branches/tango/rebuild/staticassert.c (modified) (2 diffs)
- branches/tango/rebuild/struct.c (modified) (1 diff)
- branches/tango/rebuild/template.c (modified) (9 diffs)
- branches/tango/sss/build.d (modified) (3 diffs)
- branches/tango/sss/clean.d (modified) (3 diffs)
- branches/tango/sss/conf.d (modified) (11 diffs)
- branches/tango/sss/dsss_lib_test.d (copied) (copied from trunk/sss/dsss_lib_test.d)
- branches/tango/sss/main.d (modified) (4 diffs)
- branches/tango/sss/uninstall.d (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/tango/docs/ChangeLog
r654 r694 1 SVN from 0.67: 1 SVN from 0.68: 2 - Added --test option to test built libraries. 3 4 0.68 from 0.67: 2 5 - Rebuild: -of<name> now converts / to \ on Windows (see ticket #85). 3 6 - `dsss uninstall` now removes (empty) directories as well as files 4 7 (see ticket #84). 8 - Rebuild: Merged DMD 1.018. 9 - Rebuild: Added proper documentation for -Dq (see ticket #90). 10 - /etc will now be preferred to /usr/etc when installing to the prefix 11 /usr. 12 - Rebuild: Added -no-export-dynamic flag (see ticket #91). 5 13 6 14 0.67 from 0.66: branches/tango/docs/NEWS
r654 r694 1 2006-06-29: DSSS and Rebuild 0.67 released. 1 2007-07-22: DSSS and Rebuild 0.68 released. 2 3 2007-06-29: DSSS and Rebuild 0.67 released. 2 4 3 5 2007-06-25: DSSS and Rebuild 0.66 released. branches/tango/dsss.conf
r654 r694 29 29 # Install this as a sourcelibrary, so it will work on any platform/compiler combination 30 30 type = sourcelibrary 31 exclude = sss/dsss_lib_test.d sss/dsssdll.d sss/main.d sss/stub.d 32 buildflags = -Irebuild 33 34 # dsss_lib_test is special, so put it in share/ 35 postinstall = install sss/dsss_lib_test.d $PREFIX/share/dsss 31 36 32 37 version (Windows) { branches/tango/hcf/path.d
r654 r694 29 29 module hcf.path; 30 30 31 import tango.io.FileConst; 32 import tango.io.FilePath; 33 import tango.io.FileSystem; 34 35 import tango.text.String; 36 import tango.text.Util; 37 38 import tango.stdc.stdlib; 39 import tango.stdc.stringz; 40 41 version (Posix) { 42 import tango.stdc.posix.sys.stat; 43 } 44 31 45 version (Windows) { 32 46 import bcd.windows.windows; 33 47 } 34 48 49 /* Simple getDirName, etc */ 50 char[] getDirName(char[] fname) 51 { 52 return (new FilePath(fname)).path(); 53 } 54 char[] getBaseName(char[] fname) 55 { 56 return (new FilePath(fname)).file(); 57 } 58 char[] getName(char[] fname) 59 { 60 return (new FilePath(fname)).name(); 61 } 62 char[] getExt(char[] fname) 63 { 64 return (new FilePath(fname)).ext(); 65 } 66 35 67 /** Get the system PATH */ 36 68 char[][] getPath() 37 69 { 38 return split( toString(getenv("PATH")), std.path.pathsep);70 return split(fromUtf8z(getenv("PATH")), FileConst.SystemPathChar~""); 39 71 } 40 72 … … 53 85 // is this a directory? 54 86 if (dir != "") { 55 if (! std.path.isabs(dir)) {87 if (!(new FilePath(dir)).isAbsolute()) { 56 88 // make it absolute 57 dir = getcwd() ~ std.path.sep~ dir;89 dir = FileSystem.getDirectory() ~ FileConst.PathSeparatorChar ~ dir; 58 90 } 59 91 return true; … … 62 94 version (Windows) { 63 95 // is it in cwd? 64 char[] cwd = getcwd();65 if ( exists(cwd ~ std.path.sep ~ bname)) {96 char[] cwd = FileSystem.getDirectory(); 97 if ((new FilePath(cwd ~ FileConst.PathSeparatorChar ~ bname)).exists()) { 66 98 dir = cwd; 67 99 return true; … … 72 104 char[][] path = getPath(); 73 105 foreach (pe; path) { 74 char[] fullname = pe ~ std.path.sep~ bname;75 if ( exists(fullname)) {76 version (Windows) {106 char[] fullname = pe ~ FileConst.PathSeparatorChar ~ bname; 107 if ((new FilePath(fullname)).exists()) { 108 //version (Windows) { 77 109 dir = pe; 78 110 return true; 79 } else { 80 if (getAttributes(fullname) & 0100) { 111 /*} else { 112 stat_t stats; 113 stat(toUtf8z(fullname), &stats); 114 if ((cast(int) stats) & 0100) { 81 115 dir = pe; 82 116 return true; 83 117 } 84 } 118 }*/ 85 119 } 86 120 } … … 107 141 108 142 // expand tildes 109 ret = expandTilde(ret);143 // ret = expandTilde(ret); FIXME 110 144 111 145 // get rid of any duplicate separators 112 146 for (int i = 0; i < ret.length; i++) { 113 if (ret[i .. (i + 1)] == sep) {147 if (ret[i .. (i + 1)] == FileConst.PathSeparatorChar~"") { 114 148 // drop the duplicate separator 115 149 i++; 116 150 while (i < ret.length && 117 ret[i .. (i + 1)] == sep) {151 ret[i .. (i + 1)] == FileConst.PathSeparatorChar~"") { 118 152 ret = ret[0 .. i] ~ ret[(i + 1) .. $]; 119 153 } … … 122 156 123 157 // make sure we don't miss a .. element 124 if (ret.length > 3 && ret[($-3) .. $] == std.path.sep~ "..") {125 ret ~= std.path.sep;158 if (ret.length > 3 && ret[($-3) .. $] == FileConst.PathSeparatorChar ~ "..") { 159 ret ~= FileConst.PathSeparatorChar; 126 160 } 127 161 128 162 // or a . element 129 if (ret.length > 2 && ret[($-2) .. $] == std.path.sep~ ".") {130 ret ~= std.path.sep;163 if (ret.length > 2 && ret[($-2) .. $] == FileConst.PathSeparatorChar ~ ".") { 164 ret ~= FileConst.PathSeparatorChar; 131 165 } 132 166 133 167 // search for .. elements 134 168 for (int i = 0; ret.length > 4 && i <= ret.length - 4; i++) { 135 if (ret[i .. (i + 4)] == std.path.sep ~ ".." ~ std.path.sep) {169 if (ret[i .. (i + 4)] == FileConst.PathSeparatorChar ~ ".." ~ FileConst.PathSeparatorChar) { 136 170 // drop the previous path element 137 171 int j; 138 for (j = i - 1; j > 0 && ret[j..(j+1)] != std.path.sep; j--) {}172 for (j = i - 1; j > 0 && ret[j..(j+1)] != FileConst.PathSeparatorChar~""; j--) {} 139 173 if (j > 0) { 140 174 // cut … … 142 176 } else { 143 177 // sort of ridiculous, but cut as best we can 144 ret = std.path.sep~ ret[(i + 3) .. $];178 ret = FileConst.PathSeparatorChar ~ ret[(i + 3) .. $]; 145 179 } 146 180 i = j - 1; … … 150 184 // search for . elements 151 185 for (int i = 0; ret.length > 2 && i <= ret.length - 3; i++) { 152 if (ret[i .. (i + 3)] == std.path.sep ~ "." ~ std.path.sep) {186 if (ret[i .. (i + 3)] == FileConst.PathSeparatorChar ~ "." ~ FileConst.PathSeparatorChar) { 153 187 // drop this path element 154 188 ret = ret[0..i] ~ ret[(i + 2) .. $]; … … 159 193 // finally, get rid of any trailing separators 160 194 while (ret.length && 161 ret[($ - 1) .. $] == sep) {195 ret[($ - 1) .. $] == FileConst.PathSeparatorChar~"") { 162 196 ret = ret[0 .. ($ - 1)]; 163 197 } … … 175 209 176 210 // split it into elements 177 char[][] dires = split(dir, sep);211 char[][] dires = split(dir, FileConst.PathSeparatorChar~""); 178 212 179 213 char[] curdir; … … 182 216 if (dires.length && 183 217 dires[0] == "") { 184 curdir = std.path.sep;218 curdir = FileConst.PathSeparatorChar~""; 185 219 dires = dires[1..$]; 186 220 } … … 189 223 foreach (dire; dires) { 190 224 if (curdir.length) { 191 curdir ~= sep~ dire;225 curdir ~= FileConst.PathSeparatorChar ~ dire; 192 226 } else { 193 227 curdir ~= dire; 194 228 } 195 229 196 if (! exists(curdir)) {197 mkdir(curdir);230 if (!(new FilePath(curdir)).exists()) { 231 (new FilePath(curdir)).createFolder(); 198 232 } 199 233 } … … 205 239 // can only delete writable files on Windows 206 240 version (Windows) { 207 SetFileAttributesA(to Stringz(name),208 GetFileAttributesA(to Stringz(name)) &241 SetFileAttributesA(toUtf8z(name), 242 GetFileAttributesA(toUtf8z(name)) & 209 243 ~FILE_ATTRIBUTE_READONLY); 210 244 } 211 245 212 if ( isdir(name)) {213 foreach (elem; listdir(name)) {246 if ((new FilePath(name)).isDir()) { 247 foreach (elem; (new FilePath(name)).toList()) { 214 248 // don't delete . or .. 215 249 if (elem == "." || 216 250 elem == "..") continue; 217 rmRecursive(name ~ std.path.sep~ elem);251 rmRecursive(name ~ FileConst.PathSeparatorChar ~ elem); 218 252 } 219 253 220 254 // remove the directory itself 221 rmdir(name);255 (new FilePath(name)).remove(); 222 256 } else { 223 std.file.remove(name);224 } 225 } 257 (new FilePath(name)).remove(); 258 } 259 } branches/tango/rebuild/aggregate.h
r589 r694 44 44 unsigned alignsize; // size of struct for alignment purposes 45 45 unsigned structalign; // struct member alignment in effect 46 int hasUnions; // set if aggregate has overlapping fields 46 47 Array fields; // VarDeclaration fields 47 48 unsigned sizeok; // set when structsize contains valid data branches/tango/rebuild/attrib.c
r654 r694 1208 1208 Parser p(sc->module, (unsigned char *)se->string, se->len, 0); 1209 1209 p.loc = loc; 1210 p.nextToken(); 1210 1211 decl = p.parseDeclDefs(0); 1211 1212 if (p.token.value != TOKeof) branches/tango/rebuild/cast.c
r589 r694 333 333 { MATCH m; 334 334 335 //printf("StringExp::implicitConvTo(t = %s), '%s' committed = %d\n", t->toChars(), toChars(), committed); 335 #if 0 336 printf("StringExp::implicitConvTo(this=%s, committed=%d, type=%s, t=%s)\n", 337 toChars(), committed, type->toChars(), t->toChars()); 338 #endif 336 339 if (!committed) 337 340 { … … 351 354 ((TypeSArray *)t)->dim->toInteger()) 352 355 return MATCHnomatch; 356 goto L1; 353 357 case Tarray: 358 goto L1; 354 359 case Tpointer: 360 L1: 355 361 if (t->next->ty == Tchar) 356 362 return MATCHexact; branches/tango/rebuild/class.c
r589 r694 524 524 structalign = 0; 525 525 526 sc ->pop();526 sc = sc->pop(); 527 527 528 528 scope = scx ? scx : new Scope(*sc); branches/tango/rebuild/constfold.c
r654 r694 684 684 real_t r2; 685 685 686 //printf("Equal(e1 = %s, e2 = %s)\n", e1->toChars(), e2->toChars()); 687 686 688 assert(op == TOKequal || op == TOKnotequal); 687 689 … … 714 716 Expression *ee2 = (Expression *)es2->elements->data[i]; 715 717 718 Expression *v = Equal(TOKequal, Type::tint32, ee1, ee2); 719 if (v == EXP_CANT_INTERPRET) 720 return EXP_CANT_INTERPRET; 721 cmp = v->toInteger(); 722 if (cmp == 0) 723 break; 724 } 725 } 726 } 727 else if (e1->op == TOKstructliteral && e2->op == TOKstructliteral) 728 { StructLiteralExp *es1 = (StructLiteralExp *)e1; 729 StructLiteralExp *es2 = (StructLiteralExp *)e2; 730 731 if (es1->sd != es2->sd) 732 cmp = 0; 733 else if ((!es1->elements || !es1->elements->dim) && 734 (!es2->elements || !es2->elements->dim)) 735 cmp = 1; // both arrays are empty 736 else if (!es1->elements || !es2->elements) 737 cmp = 0; 738 else if (es1->elements->dim != es2->elements->dim) 739 cmp = 0; 740 else 741 { 742 cmp = 1; 743 for (size_t i = 0; i < es1->elements->dim; i++) 744 { Expression *ee1 = (Expression *)es1->elements->data[i]; 745 Expression *ee2 = (Expression *)es2->elements->data[i]; 746 747 if (ee1 == ee2) 748 continue; 749 if (!ee1 || !ee2) 750 { cmp = 0; 751 break; 752 } 716 753 Expression *v = Equal(TOKequal, Type::tint32, ee1, ee2); 717 754 if (v == EXP_CANT_INTERPRET) … … 1057 1094 Loc loc = e1->loc; 1058 1095 1059 //printf("Index(e1 = %s )\n", e1->toChars());1096 //printf("Index(e1 = %s, e2 = %s)\n", e1->toChars(), e2->toChars()); 1060 1097 assert(e1->type); 1061 1098 if (e1->op == TOKstring && e2->op == TOKint64) … … 1405 1442 } 1406 1443 1407 1444 Expression *Ptr(Type *type, Expression *e1) 1445 { 1446 //printf("Ptr(e1 = %s)\n", e1->toChars()); 1447 if (e1->op == TOKadd) 1448 { AddExp *ae = (AddExp *)e1; 1449 if (ae->e1->op == TOKaddress && ae->e2->op == TOKint64) 1450 { AddrExp *ade = (AddrExp *)ae->e1; 1451 if (ade->e1->op == TOKstructliteral) 1452 { StructLiteralExp *se = (StructLiteralExp *)ade->e1; 1453 unsigned offset = ae->e2->toInteger(); 1454 Expression *e = se->getField(type, offset); 1455 if (!e) 1456 e = EXP_CANT_INTERPRET; 1457 return e; 1458 } 1459 } 1460 } 1461 return EXP_CANT_INTERPRET; 1462 } 1463 branches/tango/rebuild/declaration.c
r589 r694 802 802 if (init) 803 803 { 804 ArrayInitializer *ai = init->isArrayInitializer(); 805 if (ai && type->toBasetype()->ty == Taarray) 806 { 807 init = ai->toAssocArrayInitializer(); 808 } 809 804 810 ExpInitializer *ei = init->isExpInitializer(); 805 811 branches/tango/rebuild/delegatize.c
r589 r694 185 185 186 186 187 void StructLiteralExp::scanForNestedRef(Scope *sc) 188 { 189 arrayExpressionScanForNestedRef(sc, elements); 190 } 191 192 187 193 void TupleExp::scanForNestedRef(Scope *sc) 188 194 { branches/tango/rebuild/dsymbol.c
r589 r694 871 871 v->storage_class |= STCconst; 872 872 } 873 else if (ce->op == TOKarrayliteral) 874 { /* It is for an array literal, so the 875 * length will be a const. 876 */ 877 Expression *e = new IntegerExp(0, ((ArrayLiteralExp *)ce)->elements->dim, Type::tsize_t); 878 v->init = new ExpInitializer(0, e); 879 v->storage_class |= STCconst; 880 } 873 881 else if (ce->op == TOKtuple) 874 882 { /* It is for an expression tuple, so the branches/tango/rebuild/enum.c
r589 r694 27 27 minval = 0; 28 28 defaultval = 0; 29 sinit = NULL; 29 30 } 30 31 branches/tango/rebuild/enum.h
r589 r694 26 26 #endif 27 27 28 28 29 struct EnumDeclaration : ScopeDsymbol 29 30 { … … 48 49 49 50 void toDebug(); 51 52 Symbol *sinit; 53 Symbol *toInitializer(); 50 54 }; 51 55 branches/tango/rebuild/expression.c
r589 r694 303 303 void expandTuples(Expressions *exps) 304 304 { 305 //printf("expandTuples()\n"); 305 306 if (exps) 306 307 { 307 308 for (size_t i = 0; i < exps->dim; i++) 308 309 { Expression *arg = (Expression *)exps->data[i]; 310 if (!arg) 311 continue; 312 313 // Look for tuple with 0 members 314 if (arg->op == TOKtype) 315 { TypeExp *e = (TypeExp *)arg; 316 if (e->type->toBasetype()->ty == Ttuple) 317 { TypeTuple *tt = (TypeTuple *)e->type->toBasetype(); 318 319 if (!tt->arguments || tt->arguments->dim == 0) 320 { 321 exps->remove(i); 322 if (i == exps->dim) 323 return; 324 i--; 325 continue; 326 } 327 } 328 } 309 329 310 330 // Inline expand all the tuples … … 663 683 Expression *e; 664 684 if (!size) 685 { 686 #ifdef DEBUG 665 687 fprintf(stdmsg, "No expression copy for: %s\n", toChars()); 688 printf("op = %d\n", op); 689 dump(0); 690 #endif 691 assert(0); 692 } 666 693 e = (Expression *)mem.malloc(size); 667 694 return (Expression *)memcpy(e, this, size); … … 856 883 { 857 884 /*if (flag == 0) 858 error("%s has no effect in expression (%s)", 859 Token::toChars(op), toChars()); */ 885 { if (op == TOKimport) 886 { 887 error("%s has no effect", toChars()); 888 } 889 else 890 error("%s has no effect in expression (%s)", 891 Token::toChars(op), toChars()); 892 } */ 860 893 return 0; 861 894 } … … 1007 1040 char *IntegerExp::toChars() 1008 1041 { 1042 #if 1 1043 return Expression::toChars(); 1044 #else 1009 1045 static char buffer[sizeof(value) * 3 + 1]; 1010 1046 1011 1047 sprintf(buffer, "%jd", value); 1012 1048 return buffer; 1049 #endif 1013 1050 } 1014 1051 … … 2350 2387 case '"': 2351 2388 case '\\': 2352 buf->writeByte('\\'); 2389 if (!hgs->console) 2390 buf->writeByte('\\'); 2353 2391 default: 2354 2392 if (c <= 0xFF) 2355 { if (c <= 0x7F && isprint(c))2393 { if (c <= 0x7F && (isprint(c) || hgs->console)) 2356 2394 buf->writeByte(c); 2357 2395 else … … 2433 2471 } 2434 2472 2473 ArrayLiteralExp::ArrayLiteralExp(Loc loc, Expression *e) 2474 : Expression(loc, TOKarrayliteral, sizeof(ArrayLiteralExp)) 2475 { 2476 elements = new Expressions; 2477 elements->push(e); 2478 } 2479 2435 2480 Expression *ArrayLiteralExp::syntaxCopy() 2436 2481 { … … 2459 2504 error("%s has no value", e->toChars()); */ 2460 2505 e = resolveProperties(sc, e); 2506 2507 unsigned char committed = 1; 2508 if (e->op == TOKstring) 2509 committed = ((StringExp *)e)->committed; 2510 2461 2511 if (!t0) 2462 2512 { t0 = e->type; … … 2470 2520 else 2471 2521 e = e->implicitCastTo(sc, t0); 2522 if (!committed && e->op == TOKstring) 2523 { StringExp *se = (StringExp *)e; 2524 se->committed = 0; 2525 } 2472 2526 elements->data[i] = (void *)e; 2473 2527 } … … 2643 2697 key->toMangleBuffer(buf); 2644 2698 value->toMangleBuffer(buf); 2699 } 2700 } 2701 2702 /************************ StructLiteralExp ************************************/ 2703 2704 // sd( e1, e2, e3, ... ) 2705 2706 StructLiteralExp::StructLiteralExp(Loc loc, StructDeclaration *sd, Expressions *elements) 2707 : Expression(loc, TOKstructliteral, sizeof(StructLiteralExp)) 2708 { 2709 this->sd = sd; 2710 this->elements = elements; 2711 this->sym = NULL; 2712 this->soffset = 0; 2713 this->fillHoles = 1; 2714 } 2715 2716 Expression *StructLiteralExp::syntaxCopy() 2717 { 2718 return new StructLiteralExp(loc, sd, arraySyntaxCopy(elements)); 2719 } 2720 2721 Expression *StructLiteralExp::semantic(Scope *sc) 2722 { Expression *e; 2723 2724 #if LOGSEMANTIC 2725 printf("StructLiteralExp::semantic('%s')\n", toChars()); 2726 #endif 2727 2728 // Run semantic() on each element 2729 for (size_t i = 0; i < elements->dim; i++) 2730 { e = (Expression *)elements->data[i]; 2731 if (!e) 2732 continue; 2733 e = e->semantic(sc); 2734 elements->data[i] = (void *)e; 2735 } 2736 expandTuples(elements); 2737 size_t offset = 0; 2738 for (size_t i = 0; i < elements->dim; i++) 2739 { e = (Expression *)elements->data[i]; 2740 if (!e) 2741 continue; 2742 2743 if (!e->type) 2744 error("%s has no value", e->toChars()); 2745 e = resolveProperties(sc, e); 2746 if (i >= sd->fields.dim) 2747 { error("more initializers than fields of %s", sd->toChars()); 2748 break; 2749 } 2750 Dsymbol *s = (Dsymbol *)sd->fields.data[i]; 2751 VarDeclaration *v = s->isVarDeclaration(); 2752 assert(v); 2753 if (v->offset < offset) 2754 error("overlapping initialization for %s", v->toChars()); 2755 offset = v->offset + v->type->size(); 2756 2757 Type *telem = v->type; 2758 while (!e->implicitConvTo(telem) && telem->toBasetype()->ty == Tsarray) 2759 { /* Static array initialization, as in: 2760 * T[3][5] = e; 2761 */ 2762 telem = telem->toBasetype()->nextOf(); 2763 } 2764 2765 e = e->implicitCastTo(sc, telem); 2766 2767 elements->data[i] = (void *)e; 2768 } 2769 2770 /* Fill out remainder of elements[] with default initializers for fields[] 2771 */ 2772 for (size_t i = elements->dim; i < sd->fields.dim; i++) 2773 { Dsymbol *s = (Dsymbol *)sd->fields.data[i]; 2774 VarDeclaration *v = s->isVarDeclaration(); 2775 assert(v); 2776 2777 if (v->offset < offset) 2778 { e = NULL; 2779 sd->hasUnions = 1; 2780 } 2781 else 2782 { 2783 if (v->init) 2784 { e = v->init->toExpression(); 2785 if (!e) 2786 error("cannot make expression out of initializer for %s", v->toChars()); 2787 } 2788 else 2789 { e = v->type->defaultInit(); 2790 e->loc = loc; 2791 } 2792 offset = v->offset + v->type->size(); 2793 } 2794 elements->push(e); 2795 } 2796 2797 type = sd->type; 2798 return this; 2799 } 2800 2801 /************************************** 2802 * Gets expression at offset of type. 2803 * Returns NULL if not found. 2804 */ 2805 2806 Expression *StructLiteralExp::getField(Type *type, unsigned offset) 2807 { Expression *e = NULL; 2808 int i = getFieldIndex(type, offset); 2809 2810 if (i != -1) 2811 { e = (Expression *)elements->data[i]; 2812 if (e) 2813 { 2814 e = e->copy(); 2815 e->type = type; 2816 } 2817 } 2818 return e; 2819 } 2820 2821 /************************************ 2822 * Get index of field. 2823 * Returns -1 if not found. 2824 */ 2825 2826 int StructLiteralExp::getFieldIndex(Type *type, unsigned offset) 2827 { 2828 /* Find which field offset is by looking at the field offsets 2829 */ 2830 for (size_t i = 0; i < sd->fields.dim; i++) 2831 { 2832 Dsymbol *s = (Dsymbol *)sd->fields.data[i]; 2833 VarDeclaration *v = s->isVarDeclaration(); 2834 assert(v); 2835 2836 if (offset == v->offset && 2837 type->size() == v->type->size()) 2838 { Expression *e = (Expression *)elements->data[i]; 2839 if (e) 2840 { 2841 return i; 2842 } 2843 break; 2844 } 2845 } 2846 return -1; 2847 } 2848 2849 2850 Expression *StructLiteralExp::toLvalue(Scope *sc, Expression *e) 2851 { 2852 return this; 2853 } 2854 2855 2856 int StructLiteralExp::checkSideEffect(int flag) 2857 { int f = 0; 2858 2859 for (size_t i = 0; i < elements->dim; i++) 2860 { Expression *e = (Expression *)elements->data[i]; 2861 if (!e) 2862 continue; 2863 2864 f |= e->checkSideEffect(2); 2865 } 2866 if (flag == 0 && f == 0) 2867 Expression::checkSideEffect(0); 2868 return f; 2869 } 2870 2871 void StructLiteralExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 2872 { 2873 buf->writestring(sd->toChars()); 2874 buf->writeByte('('); 2875 argsToCBuffer(buf, elements, hgs); 2876 buf->writeByte(')'); 2877 } 2878 2879 void StructLiteralExp::toMangleBuffer(OutBuffer *buf) 2880 { 2881 size_t dim = elements ? elements->dim : 0; 2882 buf->printf("S%u", dim); 2883 for (size_t i = 0; i < dim; i++) 2884 { Expression *e = (Expression *)elements->data[i]; 2885 if (e) 2886 e->toMangleBuffer(buf); 2887 else 2888 buf->writeByte('v'); // 'v' for void 2645 2889 } 2646 2890 } … … 3212 3456 if (v) 3213 3457 { 3214 /* if (!v->isDataseg())3215 error("escaping reference to local %s", v->toChars()); */3458 /* if (!v->isDataseg()) 3459 error("escaping reference to local variable %s", v->toChars()); */ 3216 3460 } 3217 3461 } … … 4189 4433 if (e1->op != TOKstring) 4190 4434 { //error("argument to mixin must be a string, not (%s)", e1->toChars()); 4435 type = Type::terror; 4191 4436 return this; 4192 4437 } … … 4195 4440 Parser p(sc->module, (unsigned char *)se->string, se->len, 0); 4196 4441 p.loc = loc; 4442 p.nextToken(); 4197 4443 Expression *e = p.parseExpression(); 4198 4444 /* if (p.token.value != TOKeof) … … 4563 4809 assert(0); 4564 4810 } 4811 else if (ident == Id::stringof) 4812 { char *s = ie->toChars(); 4813 e = new StringExp(loc, s, strlen(s), 'c'); 4814 e = e->semantic(sc); 4815 return e; 4816 } 4565 4817 //error("undefined identifier %s", toChars()); 4566 4818 type = Type::tvoid; … … 5158 5410 e1 = e1->semantic(sc); 5159 5411 } 5412 #if 1 // patch for #540 by Oskar Linde 5413 else if (e1->op == TOKdotexp) 5414 { 5415 DotExp *de = (DotExp *) e1; 5416 5417 if (de->e2->op == TOKimport) 5418 { // This should *really* be moved to ScopeExp::semantic() 5419 ScopeExp *se = (ScopeExp *)de->e2; 5420 de->e2 = new DsymbolExp(loc, se->sds); 5421 de->e2 = de->e2->semantic(sc); 5422 } 5423 5424 if (de->e2->op == TOKtemplate) 5425 { TemplateExp *te = (TemplateExp *) de->e2; 5426 e1 = new DotTemplateExp(loc,de->e1,te->td); 5427 } 5428 } 5429 #endif 5160 5430 } 5161 5431 … … 5179 5449 { AggregateDeclaration *ad; 5180 5450 5181 if (t1->ty == Tclass) 5451 if (t1->ty == Tstruct) 5452 { 5453 ad = ((TypeStruct *)t1)->sym; 5454 if (search_function(ad, Id::call)) 5455 goto L1; // overload of opCall, therefore it's a call 5456 /* It's a struct literal 5457 */ 5458 Expression *e = new StructLiteralExp(loc, (StructDeclaration *)ad, arguments); 5459 e = e->semantic(sc); 5460 return e; 5461 } 5462 else if (t1->ty == Tclass) 5182 5463 { 5183 5464 ad = ((TypeClass *)t1)->sym; 5184 5465 goto L1; 5185 }5186 else if (t1->ty == Tstruct)5187 {5188 ad = ((TypeStruct *)t1)->sym;5189 5466 L1: 5190 5467 // Rewrite as e1.call(arguments) … … 5953 6230 if (v) 5954 6231 { 5955 /* if (!v->isDataseg() )6232 /* if (!v->isDataseg() && !v->isParameter()) 5956 6233 error("escaping reference to local %s", v->toChars()); */ 5957 6234 } … … 6375 6652 : BinExp(loc, TOKindex, sizeof(IndexExp), e1, e2) 6376 6653 { 6654 //printf("IndexExp::IndexExp('%s')\n", toChars()); 6377 6655 lengthVar = NULL; 6378 6656 modifiable = 0; // assume it is an rvalue … … 6391 6669 if (type) 6392 6670 return this; 6671 if (!e1->type) 6672 e1 = e1->semantic(sc); 6393 6673 assert(e1->type); // semantic() should already be run on it 6394 6674 e = this; … … 6576 6856 : BinExp(loc, TOKassign, sizeof(AssignExp), e1, e2) 6577 6857 { 6858 ismemset = 0; 6578 6859 } 6579 6860 … … 6950 7231 else 6951 7232 { 6952 //error(" Can only append to dynamic arrays, not %s ~=
