Ticket #229: d2.diff
| File d2.diff, 181.0 kB (added by Matt, 3 years ago) |
|---|
-
a/.hgignore
old new 14 14 CMakeCache.txt 15 15 cmake_install.cmake 16 16 .DS_Store 17 .svn 17 18 18 19 syntax: regexp 19 20 ^obj/ 20 21 ^tests/dstress/ 21 22 ^tests/reference/ 22 23 ^tango/ 23 ^druntime/24 24 ^import/ 25 25 ^bin/ldc2?$ 26 26 ^bin/ldc2?\.conf$ -
a/CMakeLists.txt
old new 140 140 -DIN_LLVM 141 141 -D_DH 142 142 -DOPAQUE_VTBLS 143 -D__STDC_LIMIT_MACROS 144 -D__STDC_CONSTANT_MACROS 143 145 ) 144 146 145 147 if(UNIX) -
a/dmd/mars.h
old new 67 67 }; 68 68 69 69 // make it easier to test new linkage types 70 #define TEMPLATE_LINKAGE_TYPE llvm::GlobalValue::LinkOnce Linkage71 #define TYPEINFO_LINKAGE_TYPE llvm::GlobalValue::LinkOnce Linkage70 #define TEMPLATE_LINKAGE_TYPE llvm::GlobalValue::LinkOnceAnyLinkage 71 #define TYPEINFO_LINKAGE_TYPE llvm::GlobalValue::LinkOnceAnyLinkage 72 72 73 73 // Put command line switches in here 74 74 struct Param -
a/dmd2/access.c
old new 253 253 if (!result) 254 254 { 255 255 error(loc, "member %s is not accessible", smember->toChars()); 256 halt();257 256 } 258 257 } 259 258 -
a/dmd2/aggregate.h
old new 64 64 int isdeprecated; // !=0 if deprecated 65 65 Scope *scope; // !=NULL means context to use 66 66 67 int isnested; // !=0 if is nested 68 VarDeclaration *vthis; // 'this' parameter if this aggregate is nested 69 67 70 // Special member functions 68 71 InvariantDeclaration *inv; // invariant 69 72 NewDeclaration *aggNew; // allocator … … 91 94 void addField(Scope *sc, VarDeclaration *v); 92 95 int isDeprecated(); // is aggregate deprecated? 93 96 FuncDeclaration *buildDtor(Scope *sc); 97 int isNested(); 94 98 95 99 void emitComment(Scope *sc); 96 100 void toDocBuffer(OutBuffer *buf); … … 216 220 int isauto; // !=0 if this is an auto class 217 221 int isabstract; // !=0 if abstract class 218 222 219 int isnested; // !=0 if is nested220 VarDeclaration *vthis; // 'this' parameter if this class is nested221 222 223 int inuse; // to prevent recursive attempts 223 224 224 225 ClassDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses); … … 236 237 #endif 237 238 FuncDeclaration *findFunc(Identifier *ident, TypeFunction *tf); 238 239 void interfaceSemantic(Scope *sc); 239 int isNested();240 240 int isCOMclass(); 241 241 virtual int isCOMinterface(); 242 242 #if DMDV2 -
a/dmd2/arrayop.c
old new 11 11 #include <string.h> 12 12 #include <assert.h> 13 13 14 #if _WIN32 || IN_GCC || IN_LLVM15 14 #include "mem.h" 16 #else17 #include "../root/mem.h"18 #endif19 15 20 16 #include "stringtable.h" 21 17 -
a/dmd2/attrib.c
old new 12 12 #include <stdlib.h> 13 13 #include <assert.h> 14 14 15 #if _WIN32 || IN_GCC || IN_LLVM16 15 #include "mem.h" 17 #elif POSIX18 #include "../root/mem.h"19 #endif20 16 21 17 #include "init.h" 22 18 #include "declaration.h" … … 151 147 { 152 148 //printf("AttribDeclaration::emitComment(sc = %p)\n", sc); 153 149 154 /* If generating doc comment, skip this because if we're inside 155 * a template, then include(NULL, NULL) will fail. 150 /* A general problem with this, illustrated by BUGZILLA 2516, 151 * is that attributes are not transmitted through to the underlying 152 * member declarations for template bodies, because semantic analysis 153 * is not done for template declaration bodies 154 * (only template instantiations). 155 * Hence, Ddoc omits attributes from template members. 156 156 */ 157 // if (sc->docbuf)158 // return;159 157 160 158 Array *d = include(NULL, NULL); 161 159 … … 771 769 772 770 Dsymbol *PragmaDeclaration::syntaxCopy(Dsymbol *s) 773 771 { 772 //printf("PragmaDeclaration::syntaxCopy(%s)\n", toChars()); 774 773 PragmaDeclaration *pd; 775 774 776 775 assert(!s); … … 1248 1247 { 1249 1248 AttribDeclaration::emitComment(sc); 1250 1249 } 1250 else if (sc->docbuf) 1251 { 1252 /* If generating doc comment, be careful because if we're inside 1253 * a template, then include(NULL, NULL) will fail. 1254 */ 1255 Array *d = decl ? decl : elsedecl; 1256 for (unsigned i = 0; i < d->dim; i++) 1257 { Dsymbol *s = (Dsymbol *)d->data[i]; 1258 s->emitComment(sc); 1259 } 1260 } 1251 1261 } 1252 1262 1253 1263 // Decide if 'then' or 'else' code should be included -
a/dmd2/builtin.c
old new 1 1 2 2 // Compiler implementation of the D programming language 3 // Copyright (c) 1999-200 7by Digital Mars3 // Copyright (c) 1999-2009 by Digital Mars 4 4 // All Rights Reserved 5 5 // written by Walter Bright 6 6 // http://www.digitalmars.com … … 23 23 #include "id.h" 24 24 #include "module.h" 25 25 26 #if DMDV2 27 26 28 /********************************** 27 29 * Determine if function is a builtin one. 28 30 */ 29 31 enum BUILTIN FuncDeclaration::isBuiltin() 30 32 { 31 static const char FeZe[] = "F eZe"; //real function(real)33 static const char FeZe[] = "FNaNbeZe"; // pure nothrow real function(real) 32 34 33 35 //printf("FuncDeclaration::isBuiltin() %s\n", toChars()); 34 36 if (builtin == BUILTINunknown) … … 40 42 parent->parent && parent->parent->ident == Id::std && 41 43 !parent->parent->parent) 42 44 { 45 //printf("deco = %s\n", type->deco); 43 46 if (strcmp(type->deco, FeZe) == 0) 44 47 { 45 48 if (ident == Id::sin) … … 54 57 builtin = BUILTINfabs; 55 58 //printf("builtin = %d\n", builtin); 56 59 } 60 else if (strcmp(type->deco, "FNaNbdZd") == 0 || 61 strcmp(type->deco, "FNaNbfZf") == 0) 62 builtin = BUILTINsqrt; 57 63 } 58 64 } 59 65 } … … 100 106 } 101 107 return e; 102 108 } 109 110 #endif -
a/dmd2/cast.c
old new 10 10 #include <stdio.h> 11 11 #include <assert.h> 12 12 13 #if _WIN32 || IN_GCC || IN_LLVM14 13 #include "mem.h" 15 #else16 #include "../root/mem.h"17 #endif18 14 19 15 #include "expression.h" 20 16 #include "mtype.h" … … 109 105 return castTo(sc, t); 110 106 } 111 107 108 Expression *StringExp::implicitCastTo(Scope *sc, Type *t) 109 { 110 //printf("StringExp::implicitCastTo(%s of type %s) => %s\n", toChars(), type->toChars(), t->toChars()); 111 unsigned char committed = this->committed; 112 Expression *e = Expression::implicitCastTo(sc, t); 113 if (e->op == TOKstring) 114 { 115 // Retain polysemous nature if it started out that way 116 ((StringExp *)e)->committed = committed; 117 } 118 return e; 119 } 120 112 121 /******************************************* 113 122 * Return !=0 if we can implicitly convert this to type t. 114 123 * Don't do the actual cast. … … 446 455 if (tynto == Tchar || tynto == Twchar || tynto == Tdchar) 447 456 return MATCHexact; 448 457 } 458 else if (type->ty == Tarray) 459 { 460 if (length() > 461 ((TypeSArray *)t)->dim->toInteger()) 462 return MATCHnomatch; 463 TY tynto = t->nextOf()->ty; 464 if (tynto == Tchar || tynto == Twchar || tynto == Tdchar) 465 return MATCHexact; 466 } 449 467 case Tarray: 450 468 case Tpointer: 451 469 tn = t->nextOf(); … … 851 869 return se; 852 870 } 853 871 872 if (committed && tb->ty == Tsarray && typeb->ty == Tarray) 873 { 874 se = (StringExp *)copy(); 875 se->sz = tb->nextOf()->size(); 876 se->len = (len * sz) / se->sz; 877 se->committed = 1; 878 se->type = t; 879 return se; 880 } 881 854 882 if (tb->ty != Tsarray && tb->ty != Tarray && tb->ty != Tpointer) 855 883 { if (!copied) 856 884 { se = (StringExp *)copy(); … … 1703 1731 return e; 1704 1732 } 1705 1733 1734 /*********************************** 1735 * See if both types are arrays that can be compared 1736 * for equality. Return !=0 if so. 1737 * If they are arrays, but incompatible, issue error. 1738 * This is to enable comparing things like an immutable 1739 * array with a mutable one. 1740 */ 1741 1742 int arrayTypeCompatible(Loc loc, Type *t1, Type *t2) 1743 { 1744 t1 = t1->toBasetype(); 1745 t2 = t2->toBasetype(); 1746 1747 if ((t1->ty == Tarray || t1->ty == Tsarray || t1->ty == Tpointer) && 1748 (t2->ty == Tarray || t2->ty == Tsarray || t2->ty == Tpointer)) 1749 { 1750 if (t1->nextOf()->implicitConvTo(t2->nextOf()) < MATCHconst && 1751 t2->nextOf()->implicitConvTo(t1->nextOf()) < MATCHconst && 1752 (t1->nextOf()->ty != Tvoid && t2->nextOf()->ty != Tvoid)) 1753 { 1754 error("array equality comparison type mismatch, %s vs %s", t1->toChars(), t2->toChars()); 1755 } 1756 return 1; 1757 } 1758 return 0; 1759 } -
a/dmd2/class.c
old new 157 157 Type::typeinfoinvariant->error("%s", msg); 158 158 Type::typeinfoinvariant = this; 159 159 } 160 161 if (id == Id::TypeInfo_Shared) 162 { if (Type::typeinfoshared) 163 Type::typeinfoshared->error("%s", msg); 164 Type::typeinfoshared = this; 165 } 160 166 #endif 161 167 } 162 168 … … 182 188 com = 0; 183 189 isauto = 0; 184 190 isabstract = 0; 185 isnested = 0;186 vthis = NULL;187 191 inuse = 0; 188 192 } 189 193 … … 500 504 { Dsymbol *s = toParent2(); 501 505 if (s) 502 506 { 503 ClassDeclaration *cd = s->isClassDeclaration();507 AggregateDeclaration *ad = s->isClassDeclaration(); 504 508 FuncDeclaration *fd = s->isFuncDeclaration(); 505 509 506 510 507 if ( cd || fd)511 if (ad || fd) 508 512 { isnested = 1; 509 513 Type *t; 510 if ( cd)511 t = cd->type;514 if (ad) 515 t = ad->handle; 512 516 else if (fd) 513 517 { AggregateDeclaration *ad = fd->isMember2(); 514 518 if (ad) 515 519 t = ad->handle; 516 520 else 517 521 { 518 t = new TypePointer(Type::tvoid); 519 t = t->semantic(0, sc); 522 t = Type::tvoidptr; 520 523 } 521 524 } 522 525 else 523 526 assert(0); 527 if (t->ty == Tstruct) // ref to struct 528 t = Type::tvoidptr; 524 529 assert(!vthis); 525 530 vthis = new ThisDeclaration(t); 526 531 members->push(vthis); … … 546 551 sc->inunion = 0; 547 552 548 553 if (isCOMclass()) 554 { 555 #if _WIN32 549 556 sc->linkage = LINKwindows; 557 #else 558 /* This enables us to use COM objects under Linux and 559 * work with things like XPCOM 560 */ 561 sc->linkage = LINKc; 562 #endif 563 } 550 564 sc->protection = PROTpublic; 551 565 sc->explicitProtection = 0; 552 566 sc->structalign = 8; … … 870 884 { 871 885 for (size_t i = 0; i < vtbl->dim; i++) 872 886 { 873 FuncDeclaration *fd = (FuncDeclaration *)vtbl->data[i]; 887 FuncDeclaration *fd = ((Dsymbol*)vtbl->data[i])->isFuncDeclaration(); 888 if (!fd) 889 continue; // the first entry might be a ClassInfo 874 890 875 891 //printf("\t[%d] = %s\n", i, fd->toChars()); 876 892 if (ident == fd->ident && … … 957 973 958 974 959 975 /**************************************** 960 * Returns !=0 if there's an extra member which is the 'this'961 * pointer to the enclosing context (enclosing class or function)962 */963 964 int ClassDeclaration::isNested()965 {966 return isnested;967 }968 969 /****************************************970 976 * Determine if slot 0 of the vtbl[] is reserved for something else. 971 977 * For class objects, yes, this is where the classinfo ptr goes. 972 978 * For COM interfaces, no. -
a/dmd2/clone.c
old new 47 47 Dsymbol *s = (Dsymbol *)fields.data[i]; 48 48 VarDeclaration *v = s->isVarDeclaration(); 49 49 assert(v && v->storage_class & STCfield); 50 if (v->storage_class & STCref) 51 continue; 50 52 Type *tv = v->type->toBasetype(); 51 53 while (tv->ty == Tsarray) 52 54 { TypeSArray *ta = (TypeSArray *)tv; … … 264 266 Dsymbol *s = (Dsymbol *)fields.data[i]; 265 267 VarDeclaration *v = s->isVarDeclaration(); 266 268 assert(v && v->storage_class & STCfield); 269 if (v->storage_class & STCref) 270 continue; 267 271 Type *tv = v->type->toBasetype(); 268 272 size_t dim = 1; 269 273 while (tv->ty == Tsarray) … … 359 363 Dsymbol *s = (Dsymbol *)fields.data[i]; 360 364 VarDeclaration *v = s->isVarDeclaration(); 361 365 assert(v && v->storage_class & STCfield); 366 if (v->storage_class & STCref) 367 continue; 362 368 Type *tv = v->type->toBasetype(); 363 369 size_t dim = 1; 364 370 while (tv->ty == Tsarray) -
a/dmd2/declaration.c
old new 135 135 if (isConst()) 136 136 p = "const"; 137 137 else if (isInvariant()) 138 p = " invariant";138 p = "mutable"; 139 139 else if (storage_class & STCmanifest) 140 p = " manifest constant";140 p = "enum"; 141 141 else if (!t->isAssignable()) 142 142 p = "struct with immutable members"; 143 143 if (p) 144 144 { error(loc, "cannot modify %s", p); 145 halt();146 145 } 147 146 } 148 147 } … … 456 455 if (s && ((s->getType() && type->equals(s->getType())) || s->isEnumMember())) 457 456 goto L2; // it's a symbolic alias 458 457 459 //printf("alias type is %s\n", type->toChars()); 460 type->resolve(loc, sc, &e, &t, &s); 458 if (storage_class & STCref) 459 { // For 'ref' to be attached to function types, and picked 460 // up by Type::resolve(), it has to go into sc. 461 sc = sc->push(); 462 sc->stc |= STCref; 463 type->resolve(loc, sc, &e, &t, &s); 464 sc = sc->pop(); 465 } 466 else 467 type->resolve(loc, sc, &e, &t, &s); 461 468 if (s) 462 469 { 463 470 goto L2; … … 780 787 } 781 788 782 789 Lagain: 783 if (storage_class & STCinvariant) 784 { 785 type = type->invariantOf(); 790 /* Storage class can modify the type 791 */ 792 type = type->addStorageClass(storage_class); 793 794 /* Adjust storage class to reflect type 795 */ 796 if (type->isConst()) 797 { storage_class |= STCconst; 798 if (type->isShared()) 799 storage_class |= STCshared; 786 800 } 787 else if (storage_class & (STCconst | STCin))788 {789 if (!type->isInvariant())790 type = type->constOf();791 }792 else if (type->isConst())793 storage_class |= STCconst;794 801 else if (type->isInvariant()) 795 802 storage_class |= STCinvariant; 803 else if (type->isShared()) 804 storage_class |= STCshared; 796 805 797 806 if (isSynchronized()) 798 807 { … … 860 869 } 861 870 } 862 871 863 if ((storage_class & (STCref | STCparameter | STCforeach)) == STCref) 872 if ((storage_class & (STCref | STCparameter | STCforeach)) == STCref && 873 ident != Id::This) 874 { 864 875 error("only parameters or foreach declarations can be ref"); 876 } 865 877 866 878 if (type->isauto() && !noauto) 867 879 { 868 880 if (storage_class & (STCfield | STCout | STCref | STCstatic | STCmanifest | STCtls) || !fd) 869 881 { 870 error("globals, statics, fields, manifest constants, ref and out parameters cannot be auto");882 error("globals, statics, fields, manifest constants, ref and out parameters cannot be scope"); 871 883 } 872 884 873 885 if (!(storage_class & (STCauto | STCscope))) … … 906 918 Expression *e1; 907 919 e1 = new VarExp(loc, this); 908 920 e = new AssignExp(loc, e1, e); 921 e->op = TOKconstruct; 909 922 e->type = e1->type; // don't type check this, it would fail 910 923 init = new ExpInitializer(loc, e); 911 924 return; … … 1171 1184 buf->writestring("auto "); 1172 1185 #if DMDV2 1173 1186 if (storage_class & STCmanifest) 1174 buf->writestring(" manifest");1187 buf->writestring("enum "); 1175 1188 if (storage_class & STCinvariant) 1176 buf->writestring("invariant "); 1189 buf->writestring("immutable "); 1190 if (storage_class & STCshared) 1191 buf->writestring("shared "); 1177 1192 if (storage_class & STCtls) 1178 1193 buf->writestring("__thread "); 1179 1194 #endif … … 1548 1563 } 1549 1564 #endif 1550 1565 1566 /***************************** TypeInfoSharedDeclaration **********************/ 1567 1568 #if DMDV2 1569 TypeInfoSharedDeclaration::TypeInfoSharedDeclaration(Type *tinfo) 1570 : TypeInfoDeclaration(tinfo, 0) 1571 { 1572 } 1573 #endif 1574 1551 1575 /***************************** TypeInfoStructDeclaration **********************/ 1552 1576 1553 1577 TypeInfoStructDeclaration::TypeInfoStructDeclaration(Type *tinfo) -
a/dmd2/declaration.h
old new 502 502 void llvmDeclare(); 503 503 void llvmDefine(); 504 504 }; 505 506 struct TypeInfoSharedDeclaration : TypeInfoDeclaration 507 { 508 TypeInfoSharedDeclaration(Type *tinfo); 509 510 void toDt(dt_t **pdt); 511 }; 505 512 #endif 506 513 507 514 /**************************************************************/ … … 510 517 { 511 518 ThisDeclaration(Type *t); 512 519 Dsymbol *syntaxCopy(Dsymbol *); 520 ThisDeclaration *isThisDeclaration() { return this; } 513 521 }; 514 522 515 523 enum ILS … … 629 637 int isAbstract(); 630 638 int isCodeseg(); 631 639 int isOverloadable(); 640 int isPure(); 632 641 virtual int isNested(); 633 642 int needThis(); 634 643 virtual int isVirtual(); -
a/dmd2/doc.c
old new 16 16 #include <ctype.h> 17 17 #include <assert.h> 18 18 19 #if IN_GCC || IN_LLVM20 19 #include "mem.h" 21 #else22 #if _WIN3223 #include "..\root\mem.h"24 #elif POSIX25 #include "../root/mem.h"26 #else27 #error "fix this"28 #endif29 #endif30 31 20 #include "root.h" 32 21 33 22 #include "mars.h" … … 857 846 } 858 847 else 859 848 { 849 if (isAbstract()) 850 buf->writestring("abstract "); 860 851 buf->printf("%s $(DDOC_PSYMBOL %s)", kind(), toChars()); 861 852 } 862 853 int any = 0; -
a/dmd2/dsymbol.c
old new 867 867 s2->toPrettyChars(), 868 868 s2->locToChars()); 869 869 } 870 halt();871 870 } 872 871 873 872 Dsymbol *ScopeDsymbol::nameCollision(Dsymbol *s) … … 1048 1047 L1: 1049 1048 1050 1049 if (td) 1051 { 1050 { /* $ gives the number of elements in the tuple 1051 */ 1052 1052 VarDeclaration *v = new VarDeclaration(loc, Type::tsize_t, Id::dollar, NULL); 1053 1053 Expression *e = new IntegerExp(0, td->objects->dim, Type::tsize_t); 1054 1054 v->init = new ExpInitializer(0, e); … … 1058 1058 } 1059 1059 1060 1060 if (type) 1061 { 1061 { /* $ gives the number of type entries in the type tuple 1062 */ 1062 1063 VarDeclaration *v = new VarDeclaration(loc, Type::tsize_t, Id::dollar, NULL); 1063 1064 Expression *e = new IntegerExp(0, type->arguments->dim, Type::tsize_t); 1064 1065 v->init = new ExpInitializer(0, e); … … 1068 1069 } 1069 1070 1070 1071 if (exp->op == TOKindex) 1071 { 1072 { /* array[index] where index is some function of $ 1073 */ 1072 1074 IndexExp *ie = (IndexExp *)exp; 1073 1075 1074 1076 pvar = &ie->lengthVar; 1075 1077 ce = ie->e1; 1076 1078 } 1077 1079 else if (exp->op == TOKslice) 1078 { 1080 { /* array[lwr .. upr] where lwr or upr is some function of $ 1081 */ 1079 1082 SliceExp *se = (SliceExp *)exp; 1080 1083 1081 1084 pvar = &se->lengthVar; 1082 1085 ce = se->e1; 1083 1086 } 1084 1087 else 1088 /* Didn't find $, look in enclosing scope(s). 1089 */ 1085 1090 return NULL; 1086 1091 1092 /* If we are indexing into an array that is really a type 1093 * tuple, rewrite this as an index into a type tuple and 1094 * try again. 1095 */ 1087 1096 if (ce->op == TOKtype) 1088 1097 { 1089 1098 Type *t = ((TypeExp *)ce)->type; … … 1093 1102 } 1094 1103 } 1095 1104 1096 if (!*pvar) 1097 { 1105 /* *pvar is lazily initialized, so if we refer to $ 1106 * multiple times, it gets set only once. 1107 */ 1108 if (!*pvar) // if not already initialized 1109 { /* Create variable v and set it to the value of $, 1110 * which will be a constant. 1111 */ 1098 1112 VarDeclaration *v = new VarDeclaration(loc, Type::tsize_t, Id::dollar, NULL); 1099 1113 1100 1114 if (ce->op == TOKvar) -
a/dmd2/dsymbol.h
old new 28 28 struct Scope; 29 29 struct DsymbolTable; 30 30 struct Declaration; 31 struct ThisDeclaration; 31 32 struct TupleDeclaration; 32 33 struct TypedefDeclaration; 33 34 struct AliasDeclaration; … … 192 193 virtual TemplateInstance *isTemplateInstance() { return NULL; } 193 194 virtual TemplateMixin *isTemplateMixin() { return NULL; } 194 195 virtual Declaration *isDeclaration() { return NULL; } 196 virtual ThisDeclaration *isThisDeclaration() { return NULL; } 195 197 virtual TupleDeclaration *isTupleDeclaration() { return NULL; } 196 198 virtual TypedefDeclaration *isTypedefDeclaration() { return NULL; } 197 199 virtual AliasDeclaration *isAliasDeclaration() { return NULL; } -
a/dmd2/entity.c
old new 1 1 2 // Copyright (c) 1999-200 8by Digital Mars2 // Copyright (c) 1999-2009 by Digital Mars 3 3 // All Rights Reserved 4 4 // written by Walter Bright 5 5 // http://www.digitalmars.com -
a/dmd2/expression.c
old new 1 1 2 2 // Compiler implementation of the D programming language 3 // Copyright (c) 1999-200 8by Digital Mars3 // Copyright (c) 1999-2009 by Digital Mars 4 4 // All Rights Reserved 5 5 // written by Walter Bright 6 6 // http://www.digitalmars.com … … 11 11 #include <stdio.h> 12 12 #include <stdlib.h> 13 13 #include <ctype.h> 14 #include <math.h> 14 15 #include <assert.h> 15 16 #if _MSC_VER 16 17 #include <complex> 17 18 #else 18 19 #endif 19 #include <math.h>20 20 21 21 #if _WIN32 && __DMC__ 22 22 extern "C" char * __cdecl __locale_decpoint; … … 43 43 #define integer_t dmd_integer_t 44 44 #endif 45 45 46 #if IN_GCC || IN_LLVM47 46 #include "mem.h" 48 #elif _WIN3249 #include "..\root\mem.h"50 #elif POSIX51 #include "../root/mem.h"52 #endif53 47 54 48 //#include "port.h" 55 49 #include "mtype.h" … … 172 166 precedence[TOKue] = PREC_rel; 173 167 precedence[TOKin] = PREC_rel; 174 168 169 #if 0 175 170 precedence[TOKequal] = PREC_equal; 176 171 precedence[TOKnotequal] = PREC_equal; 177 172 precedence[TOKidentity] = PREC_equal; 178 173 precedence[TOKnotidentity] = PREC_equal; 174 #else 175 /* Note that we changed precedence, so that < and != have the same 176 * precedence. This change is in the parser, too. 177 */ 178 precedence[TOKequal] = PREC_rel; 179 precedence[TOKnotequal] = PREC_rel; 180 precedence[TOKidentity] = PREC_rel; 181 precedence[TOKnotidentity] = PREC_rel; 182 #endif 179 183 180 184 precedence[TOKand] = PREC_and; 181 185 … … 642 646 Expression *e = new VarExp(loc, v); 643 647 e = new IndexExp(loc, e, new IntegerExp(u + 1 - nparams)); 644 648 AssignExp *ae = new AssignExp(loc, e, a); 649 #if DMDV2 645 650 ae->op = TOKconstruct; 651 #endif 646 652 if (c) 647 653 c = new CommaExp(loc, c, ae); 648 654 else … … 698 704 699 705 tb = arg->type->toBasetype(); 700 706 701 // LDC we don't want this! 702 #if !IN_LLVM 703 // Convert static arrays to pointers 704 if (tb->ty == Tsarray) 705 { 706 arg = arg->checkToPointer(); 707 } 708 #endif 709 707 #if DMDV2 710 708 711 709 if (tb->ty == Tstruct && !(p->storageClass & (STCref | STCout))) 712 710 { 713 711 arg = callCpCtor(loc, sc, arg); 714 712 } 713 #endif 715 714 716 715 // Convert lazy argument to a delegate 717 716 if (p->storageClass & STClazy) 718 717 { 719 718 arg = arg->toDelegate(sc, p->type); 720 719 } 721 720 #if DMDV2 722 721 /* Look for arguments that cannot 'escape' from the called 723 722 * function. 724 723 */ … … 748 747 } 749 748 } 750 749 } 750 #endif 751 751 } 752 752 else 753 753 { … … 826 826 void expToCBuffer(OutBuffer *buf, HdrGenState *hgs, Expression *e, enum PREC pr) 827 827 { 828 828 //if (precedence[e->op] == 0) e->dump(0); 829 if (precedence[e->op] < pr) 829 if (precedence[e->op] < pr || 830 /* Despite precedence, we don't allow a<b<c expressions. 831 * They must be parenthesized. 832 */ 833 (pr == PREC_rel && precedence[e->op] == pr)) 830 834 { 831 835 buf->writeByte('('); 832 836 e->toCBuffer(buf, hgs); … … 958 962 va_end( ap ); 959 963 } 960 964 965 void Expression::warning(const char *format, ...) 966 { 967 if (global.params.warnings && !global.gag) 968 { 969 fprintf(stdmsg, "warning - "); 970 va_list ap; 971 va_start(ap, format); 972 ::verror(loc, format, ap); 973 va_end( ap ); 974 } 975 } 976 961 977 void Expression::rvalue() 962 978 { 963 979 if (type && type->toBasetype()->ty == Tvoid) … … 1033 1049 /*************************************** 1034 1050 * Return !=0 if expression is an lvalue. 1035 1051 */ 1036 1052 #if DMDV2 1037 1053 int Expression::isLvalue() 1038 1054 { 1039 1055 return 0; 1040 1056 } 1057 #endif 1041 1058 1042 1059 /******************************* 1043 1060 * Give error if we're not an lvalue. … … 1059 1076 //printf("Expression::modifiableLvalue() %s, type = %s\n", toChars(), type->toChars()); 1060 1077 1061 1078 // See if this expression is a modifiable lvalue (i.e. not const) 1079 #if DMDV2 1062 1080 if (type && (!type->isMutable() || !type->isAssignable())) 1063 1081 error("%s is not mutable", e->toChars()); 1064 1082 #endif 1065 1083 return toLvalue(sc, e); 1066 1084 } 1067 1085 … … 1109 1127 s->checkDeprecated(loc, sc); 1110 1128 } 1111 1129 1130 #if DMDV2 1131 void Expression::checkPurity(Scope *sc, FuncDeclaration *f) 1132 { 1133 if (sc->func && sc->func->isPure() && !sc->intypeof && !f->isPure()) 1134 error("pure function '%s' cannot call impure function '%s'\n", 1135 sc->func->toChars(), f->toChars()); 1136 } 1137 #endif 1138 1112 1139 /******************************** 1113 1140 * Check for expressions that have no use. 1114 1141 * Input: … … 1235 1262 1236 1263 int Expression::canThrow() 1237 1264 { 1265 #if DMDV2 1238 1266 return FALSE; 1267 #else 1268 return TRUE; 1269 #endif 1239 1270 } 1240 1271 1241 1272 … … 1701 1732 * 0X1.9P+2 => 19P2 1702 1733 */ 1703 1734 1735 #if __APPLE__ 1736 if (__inline_isnan(value)) 1737 #else 1704 1738 if (isnan(value)) 1739 #endif 1705 1740 buf->writestring("NAN"); // no -NAN bugs 1706 1741 else 1707 1742 { … … 1949 1984 buf->writestring(ident->toChars()); 1950 1985 } 1951 1986 1987 #if DMDV2 1952 1988 int IdentifierExp::isLvalue() 1953 1989 { 1954 1990 return 1; 1955 1991 } 1992 #endif 1956 1993 1957 1994 Expression *IdentifierExp::toLvalue(Scope *sc, Expression *e) 1958 1995 { … … 2019 2056 // BUG: This should happen after overload resolution for functions, not before 2020 2057 if (s->needThis()) 2021 2058 { 2022 if (hasThis(sc) && !s->isFuncDeclaration()) 2059 if (hasThis(sc) 2060 #if DMDV2 2061 && !s->isFuncDeclaration() 2062 #endif 2063 ) 2023 2064 { 2024 2065 // Supply an implicit 'this', as in 2025 2066 // this.ident … … 2154 2195 buf->writestring(s->toChars()); 2155 2196 } 2156 2197 2198 #if DMDV2 2157 2199 int DsymbolExp::isLvalue() 2158 2200 { 2159 2201 return 1; 2160 2202 } 2203 #endif 2161 2204 2162 2205 Expression *DsymbolExp::toLvalue(Scope *sc, Expression *e) 2163 2206 { … … 2220 2263 #if STRUCTTHISREF 2221 2264 type = sd->type; 2222 2265 #else 2266 assert(0); 2223 2267 type = sd->type->pointerTo(); 2224 2268 #endif 2225 2269 return this; … … 2257 2301 buf->writestring("this"); 2258 2302 } 2259 2303 2304 #if DMDV2 2260 2305 int ThisExp::isLvalue() 2261 2306 { 2262 2307 return 1; 2263 2308 } 2309 #endif 2264 2310 2265 2311 Expression *ThisExp::toLvalue(Scope *sc, Expression *e) 2266 2312 { … … 2494 2540 string = buffer.extractData(); 2495 2541 len = newlen; 2496 2542 sz = 4; 2497 type = new TypeSArray(Type::tdchar, new IntegerExp(loc, len, Type::tindex)); 2543 //type = new TypeSArray(Type::tdchar, new IntegerExp(loc, len, Type::tindex)); 2544 type = new TypeDArray(Type::tdchar->invariantOf()); 2498 2545 committed = 1; 2499 2546 break; 2500 2547 … … 2517 2564 string = buffer.extractData(); 2518 2565 len = newlen; 2519 2566 sz = 2; 2520 type = new TypeSArray(Type::twchar, new IntegerExp(loc, len, Type::tindex)); 2567 //type = new TypeSArray(Type::twchar, new IntegerExp(loc, len, Type::tindex)); 2568 type = new TypeDArray(Type::twchar->invariantOf()); 2521 2569 committed = 1; 2522 2570 break; 2523 2571 2524 2572 case 'c': 2525 2573 committed = 1; 2526 2574 default: 2527 type = new TypeSArray(Type::tchar, new IntegerExp(loc, len, Type::tindex)); 2575 //type = new TypeSArray(Type::tchar, new IntegerExp(loc, len, Type::tindex)); 2576 type = new TypeDArray(Type::tchar->invariantOf()); 2528 2577 break; 2529 2578 } 2530 2579 type = type->semantic(loc, sc); 2531 type = type->invariantOf();2580 //type = type->invariantOf(); 2532 2581 //printf("type = %s\n", type->toChars()); 2533 2582 } 2534 2583 return this; 2535 2584 } 2536 2585 2586 /********************************** 2587 * Return length of string. 2588 */ 2589 2590 size_t StringExp::length() 2591 { 2592 size_t result = 0; 2593 dchar_t c; 2594 const char *p; 2595 2596 switch (sz) 2597 { 2598 case 1: 2599 for (size_t u = 0; u < len;) 2600 { 2601 p = utf_decodeChar((unsigned char *)string, len, &u, &c); 2602 if (p) 2603 { error("%s", p); 2604 break; 2605 } 2606 else 2607 result++; 2608 } 2609 break; 2610 2611 case 2: 2612 for (size_t u = 0; u < len;) 2613 { 2614 p = utf_decodeWchar((unsigned short *)string, len, &u, &c); 2615 if (p) 2616 { error("%s", p); 2617 break; 2618 } 2619 else 2620 result++; 2621 } 2622 break; 2623 2624 case 4: 2625 result = len; 2626 break; 2627 2628 default: 2629 assert(0); 2630 } 2631 return result; 2632 } 2633 2537 2634 /**************************************** 2538 2635 * Convert string to char[]. 2539 2636 */ … … 2814 2911 return result ? (dim != 0) : (dim == 0); 2815 2912 } 2816 2913 2914 #if DMDV2 2817 2915 int ArrayLiteralExp::canThrow() 2818 2916 { 2819 2917 return 1; // because it can fail allocating memory 2820 2918 } 2919 #endif 2821 2920 2822 2921 void ArrayLiteralExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 2823 2922 { … … 2937 3036 return result ? (dim != 0) : (dim == 0); 2938 3037 } 2939 3038 3039 #if DMDV2 2940 3040 int AssocArrayLiteralExp::canThrow() 2941 3041 { 2942 3042 return 1; 2943 3043 } 3044 #endif 2944 3045 2945 3046 void AssocArrayLiteralExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 2946 3047 { … … 2992 3093 2993 3094 Expression *StructLiteralExp::semantic(Scope *sc) 2994 3095 { Expression *e; 3096 int nfields = sd->fields.dim - sd->isnested; 2995 3097 2996 3098 #if LOGSEMANTIC 2997 3099 printf("StructLiteralExp::semantic('%s')\n", toChars()); … … 3017 3119 if (!e->type) 3018 3120 error("%s has no value", e->toChars()); 3019 3121 e = resolveProperties(sc, e); 3020 if (i >= sd->fields.dim)3122 if (i >= nfields) 3021 3123 { error("more initializers than fields of %s", sd->toChars()); 3022 3124 break; 3023 3125 } … … 3043 3145 3044 3146 /* Fill out remainder of elements[] with default initializers for fields[] 3045 3147 */ 3046 for (size_t i = elements->dim; i < sd->fields.dim; i++)3148 for (size_t i = elements->dim; i < nfields; i++) 3047 3149 { Dsymbol *s = (Dsymbol *)sd->fields.data[i]; 3048 3150 VarDeclaration *v = s->isVarDeclaration(); 3049 3151 assert(v); 3152 assert(!v->isThisDeclaration()); 3050 3153 3051 3154 if (v->offset < offset) 3052 3155 { e = NULL; … … 3126 3229 return -1; 3127 3230 } 3128 3231 3232 #if DMDV2 3129 3233 int StructLiteralExp::isLvalue() 3130 3234 { 3131 3235 return 1; 3132 3236 } 3237 #endif 3133 3238 3134 3239 Expression *StructLiteralExp::toLvalue(Scope *sc, Expression *e) 3135 3240 { … … 3152 3257 return f; 3153 3258 } 3154 3259 3260 #if DMDV2 3155 3261 int StructLiteralExp::canThrow() 3156 3262 { 3157 3263 return arrayExpressionCanThrow(elements); 3158 3264 } 3265 #endif 3159 3266 3160 3267 void StructLiteralExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 3161 3268 { … … 3231 3338 this->type = type; 3232 3339 } 3233 3340 3341 Expression *TypeExp::syntaxCopy() 3342 { 3343 //printf("TypeExp::syntaxCopy()\n"); 3344 return new TypeExp(loc, type->syntaxCopy()); 3345 } 3346 3234 3347 Expression *TypeExp::semantic(Scope *sc) 3235 3348 { 3236 3349 //printf("TypeExp::semantic(%s)\n", type->toChars()); … … 3661 3774 return 1; 3662 3775 } 3663 3776 3777 #if DMDV2 3664 3778 int NewExp::canThrow() 3665 3779 { 3666 3780 return 1; 3667 3781 } 3782 #endif 3668 3783 3669 3784 void NewExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 3670 3785 { int i; … … 3733 3848 return 1; 3734 3849 } 3735 3850 3851 #if DMDV2 3736 3852 int NewAnonClassExp::canThrow() 3737 3853 { 3738 3854 return 1; 3739 3855 } 3856 #endif 3740 3857 3741 3858 void NewAnonClassExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 3742 3859 { int i; … … 3768 3885 3769 3886 /********************** SymbolExp **************************************/ 3770 3887 3888 #if DMDV2 3771 3889 SymbolExp::SymbolExp(Loc loc, enum TOK op, int size, Declaration *var, int hasOverloads) 3772 3890 : Expression(loc, op, size) 3773 3891 { … … 3775 3893 this->var = var; 3776 3894 this->hasOverloads = hasOverloads; 3777 3895 } 3896 #endif 3778 3897 3779 3898 /********************** SymOffExp **************************************/ 3780 3899 … … 3865 3984 } 3866 3985 #endif 3867 3986 } 3987 /* Fix for 1161 doesn't work because it causes protection 3988 * problems when instantiating imported templates passing private 3989 * variables as alias template parameters. 3990 */ 3991 //accessCheck(loc, sc, NULL, var); 3868 3992 3869 3993 VarDeclaration *v = var->isVarDeclaration(); 3870 3994 if (v) … … 3882 4006 } 3883 4007 #endif 3884 4008 v->checkNestedReference(sc, loc); 4009 #if DMDV2 4010 if (sc->func && sc->func->isPure() && !sc->intypeof) 4011 { 4012 if (v->isDataseg() && !v->isInvariant()) 4013 error("pure function '%s' cannot access mutable static data '%s'", sc->func->toChars(), v->toChars()); 4014 } 4015 #endif 3885 4016 } 3886 4017 #if 0 3887 4018 else if ((fd = var->isFuncLiteralDeclaration()) != NULL) … … 3913 4044 if (tb->ty == Tarray || tb->ty == Tsarray || tb->ty == Tclass) 3914 4045 { 3915 4046 if ((v->isAuto() || v->isScope()) && !v->noauto) 3916 error("escaping reference to autolocal %s", v->toChars());4047 error("escaping reference to scope local %s", v->toChars()); 3917 4048 else if (v->storage_class & STCvariadic) 3918 4049 error("escaping reference to variadic parameter %s", v->toChars()); 3919 4050 } 3920 4051 } 3921 4052 } 3922 4053 4054 #if DMDV2 3923 4055 int VarExp::isLvalue() 3924 4056 { 3925 4057 if (var->storage_class & STClazy) 3926 4058 return 0; 3927 4059 return 1; 3928 4060 } 4061 #endif 3929 4062 3930 4063 Expression *VarExp::toLvalue(Scope *sc, Expression *e) 3931 4064 { … … 4099 4232 return f; 4100 4233 } 4101 4234 4235 #if DMDV2 4102 4236 int TupleExp::canThrow() 4103 4237 { 4104 4238 return arrayExpressionCanThrow(exps); 4105 4239 } 4240 #endif 4106 4241 4107 4242 void TupleExp::checkEscape() 4108 4243 { … … 4272 4407 return 1; 4273 4408 } 4274 4409 4410 #if DMDV2 4275 4411 int DeclarationExp::canThrow() 4276 4412 { 4277 4413 VarDeclaration *v = declaration->isVarDeclaration(); … … 4281 4417 } 4282 4418 return 0; 4283 4419 } 4420 #endif 4284 4421 4285 4422 void DeclarationExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 4286 4423 { … … 4595 4732 m = targ->deduceType(NULL, tspec, parameters, &dedtypes); 4596 4733 if (m == MATCHnomatch || 4597 4734 (m != MATCHexact && tok == TOKequal)) 4735 { 4598 4736 goto Lno; 4737 } 4599 4738 else 4600 4739 { 4601 4740 tded = (Type *)dedtypes.data[0]; … … 4637 4776 else if (tspec) 4638 4777 { 4639 4778 /* Evaluate to TRUE if targ matches tspec 4779 * is(targ == tspec) 4780 * is(targ : tspec) 4640 4781 */ 4641 4782 tspec = tspec->semantic(loc, sc); 4642 4783 //printf("targ = %s\n", targ->toChars()); … … 4732 4873 return this; 4733 4874 } 4734 4875 4876 #if DMDV2 4735 4877 int UnaExp::canThrow() 4736 4878 { 4737 4879 return e1->canThrow(); 4738 4880 } 4881 #endif 4739 4882 4740 4883 void UnaExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 4741 4884 { … … 4906 5049 return e1->type->isunsigned() || e2->type->isunsigned(); 4907 5050 } 4908 5051 5052 #if DMDV2 4909 5053 int BinExp::canThrow() 4910 5054 { 4911 5055 return e1->canThrow() || e2->canThrow(); 4912 5056 } 5057 #endif 4913 5058 4914 5059 void BinExp::incompatibleTypes() 4915 5060 { … … 5079 5224 return 1; 5080 5225 } 5081 5226 5227 #if DMDV2 5082 5228 int AssertExp::canThrow() 5083 5229 { 5084 5230 return (global.params.useAssert != 0); 5085 5231 } 5232 #endif 5086 5233 5087 5234 void AssertExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 5088 5235 { … … 5310 5457 } 5311 5458 return e; 5312 5459 } 5313 5460 #if DMDV2 5314 5461 OverloadSet *o = s->isOverloadSet(); 5315 5462 if (o) 5316 5463 { //printf("'%s' is an overload set\n", o->toChars()); 5317 5464 return new OverExp(o); 5318 5465 } 5466 #endif 5319 5467 5320 5468 Type *t = s->getType(); 5321 5469 if (t) … … 5382 5530 e->type = ((TypePointer *)t1b)->next; 5383 5531 return e->type->dotExp(sc, e, ident); 5384 5532 } 5533 #if DMDV2 5385 5534 else if (t1b->ty == Tarray || 5386 5535 t1b->ty == Tsarray || 5387 5536 t1b->ty == Taarray) … … 5403 5552 e = e->semantic(sc); 5404 5553 return e; 5405 5554 } 5555 #endif 5406 5556 else 5407 5557 { 5408 5558 e = e1->type->dotExp(sc, e1, ident); … … 5504 5654 Type *t1 = e1->type; 5505 5655 if (t1->ty == Tpointer) 5506 5656 t1 = t1->nextOf(); 5507 if (t1->isConst()) 5508 type = type->constOf(); 5509 else if (t1->isInvariant()) 5510 type = type->invariantOf(); 5657 5658 type = type->addMod(t1->mod); 5511 5659 5512 5660 AggregateDeclaration *ad = var->toParent()->isAggregateDeclaration(); 5513 5661 e1 = getRightThis(loc, sc, ad, e1, var); … … 5524 5672 return this; 5525 5673 } 5526 5674 5675 #if DMDV2 5527 5676 int DotVarExp::isLvalue() 5528 5677 { 5529 5678 return 1; 5530 5679 } 5680 #endif 5531 5681 5532 5682 Expression *DotVarExp::toLvalue(Scope *sc, Expression *e) 5533 5683 { … … 5579 5729 break; 5580 5730 } 5581 5731 } 5732 #if DMDV2 5582 5733 else 5583 5734 { 5584 5735 Type *t1 = e1->type->toBasetype(); … … 5589 5740 !var->type->isAssignable() || 5590 5741 var->storage_class & STCmanifest 5591 5742 ) 5592 error("cannot modify const/invariant %s", toChars()); 5593 } 5743 error("cannot modify const/immutable %s", toChars()); 5744 } 5745 #endif 5594 5746 return this; 5595 5747 } 5596 5748 … … 5856 6008 Type *t1; 5857 6009 int istemp; 5858 6010 Objects *targsi = NULL; // initial list of template arguments 6011 TemplateInstance *tierror = NULL; 5859 6012 5860 6013 #if LOGSEMANTIC 5861 6014 printf("CallExp::semantic() %s\n", toChars()); … … 5913 6066 if (!arguments) 5914 6067 arguments = new Expressions(); 5915 6068 arguments->shift(dotid->e1); 6069 #if DMDV2 5916 6070 e1 = new DotIdExp(dotid->loc, new IdentifierExp(dotid->loc, Id::empty), dotid->ident); 6071 #else 6072 e1 = new IdentifierExp(dotid->loc, dotid->ident); 6073 #endif 5917 6074 } 5918 6075 } 5919 6076 } … … 5941 6098 */ 5942 6099 global.errors = errors; 5943 6100 targsi = ti->tiargs; 6101 tierror = ti; // for error reporting 5944 6102 e1 = new IdentifierExp(loc, ti->name); 5945 6103 } 5946 6104 } … … 5967 6125 { 5968 6126 global.errors = errors; 5969 6127 targsi = ti->tiargs; 6128 tierror = ti; // for error reporting 5970 6129 e1 = new DotIdExp(loc, se->e1, ti->name); 5971 6130 } 5972 6131 else … … 6065 6224 */ 6066 6225 e = new PtrExp(loc, e); 6067 6226 #endif 6227 assert(0); 6068 6228 e = e->semantic(sc); 6069 6229 return e; 6070 6230 } … … 6143 6303 f->addPostInvariant() 6144 6304 ) 6145 6305 { 6146 error("cannot call public/export function %s from i nvariant", f->toChars());6306 error("cannot call public/export function %s from immutable", f->toChars()); 6147 6307 } 6148 6308 6149 6309 checkDeprecated(sc, f); 6310 #if DMDV2 6311 checkPurity(sc, f); 6312 #endif 6150 6313 accessCheck(loc, sc, ue->e1, f); 6151 6314 if (!f->needThis()) 6152 6315 { … … 6168 6331 printf("e1 = %s\n", e1->toChars()); 6169 6332 printf("e1->type = %s\n", e1->type->toChars()); 6170 6333 #endif 6171 // Const member function can take const/i nvariant/mutable this6334 // Const member function can take const/immutable/mutable this 6172 6335 if (!(f->type->isConst())) 6173 6336 { 6174 // Check for const/i nvariantcompatibility6337 // Check for const/immutable compatibility 6175 6338 Type *tthis = ue->e1->type->toBasetype(); 6176 6339 if (tthis->ty == Tpointer) 6177 6340 tthis = tthis->nextOf()->toBasetype(); … … 6248 6411 6249 6412 f = f->overloadResolve(loc, NULL, arguments); 6250 6413 checkDeprecated(sc, f); 6414 #if DMDV2 6415 checkPurity(sc, f); 6416 #endif 6251 6417 e1 = new DotVarExp(e1->loc, e1, f); 6252 6418 e1 = e1->semantic(sc); 6253 6419 t1 = e1->type; … … 6285 6451 f = cd->ctor; 6286 6452 f = f->overloadResolve(loc, NULL, arguments); 6287 6453 checkDeprecated(sc, f); 6454 #if DMDV2 6455 checkPurity(sc, f); 6456 #endif 6288 6457 e1 = new DotVarExp(e1->loc, e1, f); 6289 6458 e1 = e1->semantic(sc); 6290 6459 t1 = e1->type; … … 6357 6526 TemplateExp *te = (TemplateExp *)e1; 6358 6527 f = te->td->deduceFunctionTemplate(sc, loc, targsi, NULL, arguments); 6359 6528 if (!f) 6360 { type = Type::terror; 6529 { if (tierror) 6530 tierror->error("errors instantiating template"); // give better error message 6531 type = Type::terror; 6361 6532 return this; 6362 6533 } 6363 6534 if (f->needThis() && hasThis(sc)) … … 6389 6560 if (ve->hasOverloads) 6390 6561 f = f->overloadResolve(loc, NULL, arguments); 6391 6562 checkDeprecated(sc, f); 6563 #if DMDV2 6564 checkPurity(sc, f); 6565 #endif 6392 6566 6393 6567 if (f->needThis() && hasThis(sc)) 6394 6568 { … … 6437 6611 6438 6612 int CallExp::checkSideEffect(int flag) 6439 6613 { 6440 return 1; 6441 } 6442 6614 #if DMDV2 6615 if (flag != 2) 6616 return 1; 6617 6618 if (e1->checkSideEffect(2)) 6619 return 1; 6620 6621 /* If any of the arguments have side effects, this expression does 6622 */ 6623 for (size_t i = 0; i < arguments->dim; i++) 6624 { Expression *e = (Expression *)arguments->data[i]; 6625 6626 if (e->checkSideEffect(2)) 6627 return 1; 6628 } 6629 6630 /* If calling a function or delegate that is typed as pure, 6631 * then this expression has no side effects. 6632 */ 6633 Type *t = e1->type->toBasetype(); 6634 if (t->ty == Tfunction && ((TypeFunction *)t)->ispure) 6635 return 0; 6636 if (t->ty == Tdelegate && ((TypeFunction *)((TypeDelegate *)t)->next)->ispure) 6637 return 0; 6638 #endif 6639 return 1; 6640 } 6641 6642 #if DMDV2 6443 6643 int CallExp::canThrow() 6444 6644 { 6445 return 1; 6446 } 6447 6645 if (e1->canThrow()) 6646 return 1; 6647 6648 /* If any of the arguments can throw, then this expression can throw 6649 */ 6650 for (size_t i = 0; i < arguments->dim; i++) 6651 { Expression *e = (Expression *)arguments->data[i]; 6652 6653 if (e && e->canThrow()) 6654 return 1; 6655 } 6656 6657 /* If calling a function or delegate that is typed as nothrow, 6658 * then this expression cannot throw. 6659 * Note that pure functions can throw. 6660 */ 6661 Type *t = e1->type->toBasetype(); 6662 if (t->ty == Tfunction && ((TypeFunction *)t)->isnothrow) 6663 return 0; 6664 if (t->ty == Tdelegate && ((TypeFunction *)((TypeDelegate *)t)->next)->isnothrow) 6665 return 0; 6666 6667 return 1; 6668 } 6669 #endif 6670 6671 #if DMDV2 6448 6672 int CallExp::isLvalue() 6449 6673 { 6450 if (type->toBasetype()->ty == Tstruct)6451 return 1;6674 // if (type->toBasetype()->ty == Tstruct) 6675 // return 1; 6452 6676 Type *tb = e1->type->toBasetype(); 6453 6677 if (tb->ty == Tfunction && ((TypeFunction *)tb)->isref) 6454 6678 return 1; // function returns a reference 6455 6679 return 0; 6456 6680 } 6681 #endif 6457 6682 6458 6683 Expression *CallExp::toLvalue(Scope *sc, Expression *e) 6459 6684 { … … 6614 6839 return this; 6615 6840 } 6616 6841 6842 #if DMDV2 6617 6843 int PtrExp::isLvalue() 6618 6844 { 6619 6845 return 1; 6620 6846 } 6847 #endif 6621 6848 6622 6849 Expression *PtrExp::toLvalue(Scope *sc, Expression *e) 6623 6850 { … … 6631 6858 return this; 6632 6859 } 6633 6860 6861 #if DMDV2 6634 6862 Expression *PtrExp::modifiableLvalue(Scope *sc, Expression *e) 6635 6863 { 6636 6864 //printf("PtrExp::modifiableLvalue() %s, type %s\n", toChars(), type->toChars()); … … 6643 6871 6644 6872 return Expression::modifiableLvalue(sc, e); 6645 6873 } 6646 6874 #endif 6647 6875 6648 6876 void PtrExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 6649 6877 { … … 6909 7137 : UnaExp(loc, TOKcast, sizeof(CastExp), e) 6910 7138 { 6911 7139 to = t; 6912 this->tok = TOKreserved; 6913 } 6914 6915 /* For cast(const) and cast(invariant) 6916 */ 6917 CastExp::CastExp(Loc loc, Expression *e, enum TOK tok) 7140 this->mod = ~0; 7141 } 7142 7143 #if DMDV2 7144 /* For cast(const) and cast(immutable) 7145 */ 7146 CastExp::CastExp(Loc loc, Expression *e, unsigned mod) 6918 7147 : UnaExp(loc, TOKcast, sizeof(CastExp), e) 6919 7148 { 6920 7149 to = NULL; 6921 this->tok = tok; 6922 } 7150 this->mod = mod; 7151 } 7152 #endif 6923 7153 6924 7154 Expression *CastExp::syntaxCopy() 6925 7155 { 6926 7156 return to ? new CastExp(loc, e1->syntaxCopy(), to->syntaxCopy()) 6927 : new CastExp(loc, e1->syntaxCopy(), tok);7157 : new CastExp(loc, e1->syntaxCopy(), mod); 6928 7158 } 6929 7159 6930 7160 … … 6946 7176 { 6947 7177 e1 = resolveProperties(sc, e1); 6948 7178 6949 /* Handle cast(const) and cast(invariant)6950 */6951 7179 if (!to) 6952 { if (tok == TOKconst) 6953 to = e1->type->constOf(); 6954 else if (tok == TOKinvariant || tok == TOKimmutable) 6955 to = e1->type->invariantOf(); 6956 else 6957 assert(0); 7180 { 7181 /* Handle cast(const) and cast(immutable), etc. 7182 */ 7183 to = e1->type->castMod(mod); 6958 7184 } 6959 7185 else 6960 7186 to = to->semantic(loc, sc); … … 6989 7215 { error("cannot cast tuple"); 6990 7216 to = Type::terror; 6991 7217 } 7218 7219 if (global.params.safe && !sc->module->safe && !sc->intypeof) 7220 { // Disallow unsafe casts 7221 Type *tob = to->toBasetype(); 7222 Type *t1b = e1->type->toBasetype(); 7223 if (!t1b->isMutable() && tob->isMutable()) 7224 { // Cast not mutable to mutable 7225 Lunsafe: 7226 error("cast from %s to %s not allowed in safe mode", e1->type->toChars(), to->toChars()); 7227 } 7228 else if (t1b->isShared() && !tob->isShared()) 7229 // Cast away shared 7230 goto Lunsafe; 7231 else if (tob->ty == Tpointer) 7232 { if (t1b->ty != Tpointer) 7233 goto Lunsafe; 7234 Type *tobn = tob->nextOf()->toBasetype(); 7235 Type *t1bn = t1b->nextOf()->toBasetype(); 7236 7237 if (!t1bn->isMutable() && tobn->isMutable()) 7238 // Cast away pointer to not mutable 7239 goto Lunsafe; 7240 7241 if (t1bn->isShared() && !tobn->isShared()) 7242 // Cast away pointer to shared 7243 goto Lunsafe; 7244 7245 if (tobn->isTypeBasic() && tobn->size() < t1bn->size()) 7246 // Allow things like casting a long* to an int* 7247 ; 7248 else if (tobn->ty != Tvoid) 7249 // Cast to a pointer other than void* 7250 goto Lunsafe; 7251 } 7252 7253 // BUG: Check for casting array types, such as void[] to int*[] 7254 } 7255 6992 7256 e = e1->castTo(sc, to); 6993 7257 return e; 6994 7258 } … … 7022 7286 void CastExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 7023 7287 { 7024 7288 buf->writestring("cast("); 7289 #if V1 7290 to->toCBuffer(buf, NULL, hgs); 7291 #else 7025 7292 if (to) 7026 7293 to->toCBuffer(buf, NULL, hgs); 7027 7294 else 7028 buf->writestring(Token::tochars[tok]); 7295 { 7296 switch (mod) 7297 { case 0: 7298 break; 7299 case MODconst: 7300 buf->writestring(Token::tochars[TOKconst]); 7301 break; 7302 case MODinvariant: 7303 buf->writestring(Token::tochars[TOKimmutable]); 7304 break; 7305 case MODshared: 7306 buf->writestring(Token::tochars[TOKshared]); 7307 break; 7308 case MODshared | MODconst: 7309 buf->writestring(Token::tochars[TOKshared]); 7310 buf->writeByte(' '); 7311 buf->writestring(Token::tochars[TOKconst]); 7312 break; 7313 default: 7314 assert(0); 7315 } 7316 } 7317 #endif 7029 7318 buf->writeByte(')'); 7030 7319 expToCBuffer(buf, hgs, e1, precedence[op]); 7031 7320 } … … 7200 7489 return e; 7201 7490 } 7202 7491 7203 type = t->nextOf()->arrayOf(); 7492 if (t->ty == Tarray) 7493 { 7494 type = e1->type; 7495 } 7496 else 7497 type = t->nextOf()->arrayOf(); 7204 7498 return e; 7205 7499 7206 7500 Lerror: … … 7210 7504 else 7211 7505 s = t->toChars(); 7212 7506 error("%s cannot be sliced with []", s); 7213 type = Type::terror;7507 e = new IntegerExp(0); 7214 7508 return e; 7215 7509 } 7216 7510 … … 7219 7513 e1->checkEscape(); 7220 7514 } 7221 7515 7516 #if DMDV2 7222 7517 int SliceExp::isLvalue() 7223 7518 { 7224 7519 return 1; 7225 7520 } 7521 #endif 7226 7522 7227 7523 Expression *SliceExp::toLvalue(Scope *sc, Expression *e) 7228 7524 { … … 7338 7634 return e; 7339 7635 } 7340 7636 7341 7637 #if DMDV2 7342 7638 int ArrayExp::isLvalue() 7343 7639 { 7344 7640 if (type && type->toBasetype()->ty == Tvoid) 7345 7641 return 0; 7346 7642 return 1; 7347 7643 } 7644 #endif 7348 7645 7349 7646 Expression *ArrayExp::toLvalue(Scope *sc, Expression *e) 7350 7647 { … … 7415 7712 e2->checkEscape(); 7416 7713 } 7417 7714 7715 #if DMDV2 7418 7716 int CommaExp::isLvalue() 7419 7717 { 7420 7718 return e2->isLvalue(); 7421 7719 } 7720 #endif 7422 7721 7423 7722 Expression *CommaExp::toLvalue(Scope *sc, Expression *e) 7424 7723 { … … 7532 7831 7533 7832 case Taarray: 7534 7833 { TypeAArray *taa = (TypeAArray *)t1; 7535 7536 e2 = e2->implicitCastTo(sc, taa->index); // type checking 7834 if (!arrayTypeCompatible(e2->loc, e2->type, taa->index)) 7835 { 7836 e2 = e2->implicitCastTo(sc, taa->index); // type checking 7837 } 7537 7838 type = taa->next; 7538 7839 break; 7539 7840 } … … 7585 7886 return e; 7586 7887 } 7587 7888 7889 #if DMDV2 7588 7890 int IndexExp::isLvalue() 7589 7891 { 7590 7892 return 1; 7591 7893 } 7894 #endif 7592 7895 7593 7896 Expression *IndexExp::toLvalue(Scope *sc, Expression *e) 7594 7897 { … … 9116 9419 e2 = e2->checkToPointer(); 9117 9420 9118 9421 type = Type::tboolean; 9119 if (e 1->type->ty == Tvoid)9422 if (e2->type->ty == Tvoid) 9120 9423 type = Type::tvoid; 9121 9424 if (e2->op == TOKtype || e2->op == TOKimport) 9122 9425 error("%s is not an expression", e2->toChars()); … … 9181 9484 e2 = e2->checkToPointer(); 9182 9485 9183 9486 type = Type::tboolean; 9184 if (e 1->type->ty == Tvoid)9487 if (e2->type->ty == Tvoid) 9185 9488 type = Type::tvoid; 9186 9489 if (e2->op == TOKtype || e2->op == TOKimport) 9187 9490 error("%s is not an expression", e2->toChars()); … … 9241 9544 { 9242 9545 TypeAArray *ta = (TypeAArray *)t2b; 9243 9546 9244 // Convert key to type of key 9245 e1 = e1->implicitCastTo(sc, ta->index); 9547 // Special handling for array keys 9548 if (!arrayTypeCompatible(e1->loc, e1->type, ta->index)) 9549 { 9550 // Convert key to type of key 9551 e1 = e1->implicitCastTo(sc, ta->index); 9552 } 9246 9553 9247 9554 // Return type is pointer to value 9248 9555 type = ta->nextOf()->pointerTo(); … … 9410 9717 type = Type::tboolean; 9411 9718 9412 9719 // Special handling for array comparisons 9413 t1 = e1->type->toBasetype(); 9414 t2 = e2->type->toBasetype(); 9415 9416 if ((t1->ty == Tarray || t1->ty == Tsarray || t1->ty == Tpointer) && 9417 (t2->ty == Tarray || t2->ty == Tsarray || t2->ty == Tpointer)) 9418 { 9419 if (t1->nextOf()->implicitConvTo(t2->nextOf()) < MATCHconst && 9420 t2->nextOf()->implicitConvTo(t1->nextOf()) < MATCHconst && 9421 (t1->nextOf()->ty != Tvoid && t2->nextOf()->ty != Tvoid)) 9422 error("array equality comparison type mismatch, %s vs %s", t1->toChars(), t2->toChars()); 9423 } 9424 else 9720 if (!arrayTypeCompatible(loc, e1->type, e2->type)) 9425 9721 { 9426 9722 if (e1->type != e2->type && e1->type->isfloating() && e2->type->isfloating()) 9427 9723 { … … 9575 9871 return this; 9576 9872 } 9577 9873 9874 #if DMDV2 9578 9875 int CondExp::isLvalue() 9579 9876 { 9580 9877 return e1->isLvalue() && e2->isLvalue(); 9581 9878 } 9879 #endif 9582 9880 9583 9881 Expression *CondExp::toLvalue(Scope *sc, Expression *ex) 9584 9882 { … … 9635 9933 } 9636 9934 } 9637 9935 9936 #if DMDV2 9638 9937 int CondExp::canThrow() 9639 9938 { 9640 9939 return econd->canThrow() || e1->canThrow() || e2->canThrow(); 9641 9940 } 9642 9941 #endif 9643 9942 9644 9943 void CondExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 9645 9944 { -
a/dmd2/expression.h
old new 99 99 char *toChars(); 100 100 virtual void dump(int indent); 101 101 void error(const char *format, ...); 102 void warning(const char *format, ...); 102 103 virtual void rvalue(); 103 104 104 105 static Expression *combine(Expression *e1, Expression *e2); … … 114 115 virtual int isLvalue(); 115 116 virtual Expression *toLvalue(Scope *sc, Expression *e); 116 117 virtual Expression *modifiableLvalue(Scope *sc, Expression *e); 117 Expression *implicitCastTo(Scope *sc, Type *t);118 virtual Expression *implicitCastTo(Scope *sc, Type *t); 118 119 virtual MATCH implicitConvTo(Type *t); 119 120 virtual Expression *castTo(Scope *sc, Type *t); 120 121 virtual void checkEscape(); … … 123 124 Expression *checkIntegral(); 124 125 Expression *checkArithmetic(); 125 126 void checkDeprecated(Scope *sc, Dsymbol *s); 127 void checkPurity(Scope *sc, FuncDeclaration *f); 126 128 virtual Expression *checkToBoolean(); 127 129 Expression *checkToPointer(); 128 130 Expression *addressOf(Scope *sc); … … 344 346 char *toChars(); 345 347 Expression *semantic(Scope *sc); 346 348 Expression *interpret(InterState *istate); 349 size_t length(); 347 350 StringExp *toUTF8(Scope *sc); 351 Expression *implicitCastTo(Scope *sc, Type *t); 348 352 MATCH implicitConvTo(Type *t); 349 353 Expression *castTo(Scope *sc, Type *t); 350 354 int compare(Object *obj); … … 491 495 struct TypeExp : Expression 492 496 { 493 497 TypeExp(Loc loc, Type *type); 498 Expression *syntaxCopy(); 494 499 Expression *semantic(Scope *sc); 495 500 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 496 501 Expression *optimize(int result); … … 858 863 int isLvalue(); 859 864 Expression *toLvalue(Scope *sc, Expression *e); 860 865 Expression *modifiableLvalue(Scope *sc, Expression *e); 866 Expression *optimize(int result); 867 Expression *interpret(InterState *istate); 861 868 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 862 869 void dump(int indent); 863 870 elem *toElem(IRState *irs); 864 865 //LDC: since we don't convert abc.def -> *(&abc + ABC.def.offsetof)866 // these are needed867 Expression *optimize(int result);868 Expression *interpret(InterState *istate);869 871 }; 870 872 871 873 struct DotTemplateInstanceExp : UnaExp … … 1034 1036 { 1035 1037 // Possible to cast to one type while painting to another type 1036 1038 Type *to; // type to cast to 1037 enum TOK tok; // TOKconst or TOKinvariant1039 unsigned mod; // MODxxxxx 1038 1040 1039 1041 CastExp(Loc loc, Expression *e, Type *t); 1040 CastExp(Loc loc, Expression *e, enum TOK tok);1042 CastExp(Loc loc, Expression *e, unsigned mod); 1041 1043 Expression *syntaxCopy(); 1042 1044 Expression *semantic(Scope *sc); 1043 1045 Expression *optimize(int result); -
a/dmd2/func.c
old new 129 129 originalType = type; 130 130 if (!type->deco && type->nextOf()) 131 131 { 132 #if 1133 132 /* Apply const and invariant storage class 134 133 * to the function type 135 134 */ … … 147 146 type->deco = type->merge()->deco; 148 147 } 149 148 } 150 #else151 if (storage_class & (STCconst | STCinvariant))152 {153 /* Apply const and invariant storage class154 * to the function's return type155 */156 Type *tn = type->nextOf();157 if (storage_class & STCconst)158 tn = tn->makeConst();159 if (storage_class & STCinvariant)160 tn = tn->makeInvariant();161 ((TypeNext *)type)->next = tn;162 }163 164 type = type->semantic(loc, sc);165 #endif166 149 } 167 150 //type->print(); 168 151 if (type->ty != Tfunction) … … 190 173 error("non-virtual functions cannot be abstract"); 191 174 192 175 if ((f->isConst() || f->isInvariant()) && !isThis()) 193 error("without 'this' cannot be const/i nvariant");176 error("without 'this' cannot be const/immutable"); 194 177 195 178 if (isAbstract() && isFinal()) 196 179 error("cannot be both final and abstract"); 197 #if 0198 if (isAbstract() && fbody)199 error("abstract functions cannot have bodies");200 #endif201 180 202 #if 0203 if (isStaticConstructor() || isStaticDestructor())204 {205 if (!isStatic() || type->nextOf()->ty != Tvoid)206 error("static constructors / destructors must be static void");207 if (f->arguments && f->arguments->dim)208 error("static constructors / destructors must have empty parameter list");209 // BUG: check for invalid storage classes210 }211 #endif212 213 #ifdef IN_GCC214 AggregateDeclaration *ad;215 216 ad = parent->isAggregateDeclaration();217 if (ad)218 ad->methods.push(this);219 #endif220 181 sd = parent->isStructDeclaration(); 221 182 if (sd) 222 183 { … … 224 185 { 225 186 return; 226 187 } 227 #if 0228 // Verify no constructors, destructors, etc.229 if (isCtorDeclaration()230 //||isDtorDeclaration()231 //|| isInvariantDeclaration()232 //|| isUnitTestDeclaration()233 )234 {235 error("special member functions not allowed for %ss", sd->kind());236 }237 238 if (!sd->inv)239 sd->inv = isInvariantDeclaration();240 241 if (!sd->aggNew)242 sd->aggNew = isNewDeclaration();243 244 if (isDelete())245 {246 if (sd->aggDelete)247 error("multiple delete's for struct %s", sd->toChars());248 sd->aggDelete = (DeleteDeclaration *)(this);249 }250 #endif251 188 } 252 189 253 190 id = parent->isInterfaceDeclaration(); … … 292 229 return; 293 230 } 294 231 295 #if 0296 dtor = isDtorDeclaration();297 if (dtor)298 {299 if (cd->dtor)300 error("multiple destructors for class %s", cd->toChars());301 cd->dtor = dtor;302 }303 304 inv = isInvariantDeclaration();305 if (inv)306 {307 cd->inv = inv;308 }309 310 if (isNewDeclaration())311 {312 if (!cd->aggNew)313 cd->aggNew = (NewDeclaration *)(this);314 }315 316 if (isDelete())317 {318 if (cd->aggDelete)319 error("multiple delete's for class %s", cd->toChars());320 cd->aggDelete = (DeleteDeclaration *)(this);321 }322 #endif323 324 232 if (storage_class & STCabstract) 325 233 cd->isabstract = 1; 326 234 … … 355 263 356 264 if (isFinal()) 357 265 { 266 if (isOverride()) 267 error("does not override any function"); 358 268 cd->vtblFinal.push(this); 359 269 } 360 270 else … … 379 289 error("cannot override final function %s", fdv->toPrettyChars()); 380 290 381 291 #if DMDV2 382 if (!isOverride() && global.params.warnings)292 if (!isOverride()) 383 293 warning("%s: overrides base class function %s, but is not marked with 'override'", locToChars(), fdv->toPrettyChars()); 384 294 #endif 385 295 … … 460 370 if (fdv->type->nextOf()->isBaseOf(type->nextOf(), &offset)) 461 371 { 462 372 ti = fdv->type; 463 #if 0464 if (offset)465 ti = fdv->type;466 else if (type->nextOf()->ty == Tclass)467 { ClassDeclaration *cdn = ((TypeClass *)type->nextOf())->sym;468 if (cdn && cdn->sizeok != 1)469 ti = fdv->type;470 }471 #endif472 373 } 473 374 } 474 375 if (ti) … … 616 517 } 617 518 //printf("FuncDeclaration::semantic3('%s.%s', sc = %p, loc = %s)\n", parent->toChars(), toChars(), sc, loc.toChars()); 618 519 //fflush(stdout); 520 //printf("storage class = x%x %x\n", sc->stc, storage_class); 619 521 //{ static int x; if (++x == 2) *(char*)0=0; } 620 522 //printf("\tlinkage = %d\n", sc->linkage); 621 523 … … 660 562 sc2->sw = NULL; 661 563 sc2->fes = fes; 662 564 sc2->linkage = LINKd; 663 sc2->stc &= ~(STCauto | STCscope | STCstatic | STCabstract | STCdeprecated | STCconst | STCfinal | STCinvariant | STCtls );565 sc2->stc &= ~(STCauto | STCscope | STCstatic | STCabstract | STCdeprecated | STCconst | STCfinal | STCinvariant | STCtls | STCref); 664 566 sc2->protection = PROTpublic; 665 567 sc2->explicitProtection = 0; 666 568 sc2->structalign = 8; … … 684 586 assert(!isNested()); // can't be both member and nested 685 587 assert(ad->handle); 686 588 Type *thandle = ad->handle; 589 #if STRUCTTHISREF 590 thandle = thandle->addMod(type->mod); 591 thandle = thandle->addStorageClass(storage_class); 592 if (isPure()) 593 thandle = thandle->addMod(MODconst); 594 #else 595 assert(0); 687 596 if (storage_class & STCconst || type->isConst()) 688 597 { 689 #if STRUCTTHISREF 690 thandle = thandle->constOf(); 691 #else 598 assert(0); // BUG: shared not handled 692 599 if (thandle->ty == Tclass) 693 600 thandle = thandle->constOf(); 694 601 else 695 602 { assert(thandle->ty == Tpointer); 696 603 thandle = thandle->nextOf()->constOf()->pointerTo(); 697 604 } 698 #endif699 605 } 700 606 else if (storage_class & STCinvariant || type->isInvariant()) 701 607 { 702 #if STRUCTTHISREF703 thandle = thandle->invariantOf();704 #else705 608 if (thandle->ty == Tclass) 706 609 thandle = thandle->invariantOf(); 707 610 else 708 611 { assert(thandle->ty == Tpointer); 709 612 thandle = thandle->nextOf()->invariantOf()->pointerTo(); 710 613 } 614 } 615 else if (storage_class & STCshared || type->isShared()) 616 { 617 assert(0); // not implemented 618 } 711 619 #endif 712 }713 620 v = new ThisDeclaration(thandle); 714 621 v->storage_class |= STCparameter; 715 622 #if STRUCTTHISREF … … 818 725 */ 819 726 arg->ident = id = Identifier::generateId("_param_", i); 820 727 } 821 VarDeclaration *v = new VarDeclaration(loc, arg->type, id, NULL); 728 Type *vtype = arg->type; 729 if (isPure()) 730 vtype = vtype->addMod(MODconst); 731 VarDeclaration *v = new VarDeclaration(loc, vtype, id, NULL); 822 732 //printf("declaring parameter %s of type %s\n", v->toChars(), v->type->toChars()); 823 733 v->storage_class |= STCparameter; 824 734 if (f->varargs == 2 && i + 1 == nparams) … … 1088 998 error("expected to return a value of type %s", type->nextOf()->toChars()); 1089 999 else if (!inlineAsm) 1090 1000 { 1091 int offend = fbody ? fbody->blockExit() & BEfallthru : TRUE; 1092 //int offend = fbody ? fbody->fallOffEnd() : TRUE; 1001 int blockexit = fbody ? fbody->blockExit() : 0; 1002 if (f->isnothrow && blockexit & BEthrow) 1003 error("'%s' is nothrow yet may throw", toChars()); 1004 1005 int offend = blockexit & BEfallthru; 1093 1006 1094 1007 if (type->nextOf()->ty == Tvoid) 1095 1008 { … … 1104 1017 if (offend) 1105 1018 { Expression *e; 1106 1019 1107 if (global.params.warnings)1020 warning(loc, "no return at end of function"); 1108 1021 { warning("%s: no return at end of function", locToChars()); 1109 }1110 1022 1111 1023 if (global.params.useAssert && 1112 1024 !global.params.useInline) … … 1129 1041 } 1130 1042 } 1131 1043 } 1044 } 1132 1045 1133 1046 { 1134 1047 Statements *a = new Statements(); … … 1148 1061 } 1149 1062 } 1150 1063 1151 // we'll handle variadics ourselves1152 #if !IN_LLVM1153 if (argptr)1154 { // Initialize _argptr to point past non-variadic arg1155 #if IN_GCC1156 // Handled in FuncDeclaration::toObjFile1157 v_argptr = argptr;1158 v_argptr->init = new VoidInitializer(loc);1159 #else1160 Expression *e1;1161 Expression *e;1162 Type *t = argptr->type;1163 VarDeclaration *p;1164 unsigned offset;1165 1166 e1 = new VarExp(0, argptr);1167 if (parameters && parameters->dim)1168 p = (VarDeclaration *)parameters->data[parameters->dim - 1];1169 else1170 p = v_arguments; // last parameter is _arguments[]1171 offset = p->type->size();1172 offset = (offset + 3) & ~3; // assume stack aligns on 41173 e = new SymOffExp(0, p, offset);1174 e = new AssignExp(0, e1, e);1175 e->type = t;1176 a->push(new ExpStatement(0, e));1177 #endif // IN_GCC1178 }1179 1180 if (_arguments)1181 {1182 /* Advance to elements[] member of TypeInfo_Tuple with:1183 * _arguments = v_arguments.elements;1184 */1185 Expression *e = new VarExp(0, v_arguments);1186 e = new DotIdExp(0, e, Id::elements);1187 Expression *e1 = new VarExp(0, _arguments);1188 e = new AssignExp(0, e1, e);1189 e->op = TOKconstruct;1190 e = e->semantic(sc);1191 a->push(new ExpStatement(0, e));1192 }1193 1194 #endif // !IN_LLVM1195 1196 1064 // Merge contracts together with body into one compound statement 1197 1065 1198 1066 #ifdef _DH … … 1940 1808 } 1941 1809 else 1942 1810 { 1943 ClassDeclaration *thiscd = s->isClassDeclaration();1811 AggregateDeclaration *thiscd = s->isAggregateDeclaration(); 1944 1812 if (thiscd) 1945 1813 { if (!thiscd->isNested()) 1946 1814 goto Lerr; … … 2068 1936 return 1; // functions can be overloaded 2069 1937 } 2070 1938 1939 int FuncDeclaration::isPure() 1940 { 1941 //printf("FuncDeclaration::isPure() '%s'\n", toChars()); 1942 assert(type->ty == Tfunction); 1943 return ((TypeFunction *)this->type)->ispure; 1944 } 1945 2071 1946 // Determine if function needs 2072 1947 // a static frame pointer to its lexically enclosing function 2073 1948 … … 2808 2683 ad = parent->isAggregateDeclaration(); 2809 2684 if (!ad) 2810 2685 { 2811 error("invariants only arefor struct/union/class definitions");2686 error("invariants are only for struct/union/class definitions"); 2812 2687 return; 2813 2688 } 2814 2689 else if (ad->inv && ad->inv != this) -
a/dmd2/hdrgen.c
old new 24 24 #include <complex.h> 25 25 #endif 26 26 27 #if IN_GCC || IN_LLVM28 27 #include "mem.h" 29 #else30 #if _WIN3231 #include "..\root\mem.h"32 #elif POSIX33 #include "../root/mem.h"34 #else35 #error "fix this"36 #endif37 #endif38 28 39 29 #include "id.h" 40 30 #include "init.h" -
a/dmd2/html.c
old new 1 1 2 // Copyright (c) 1999-200 6by Digital Mars2 // Copyright (c) 1999-2009 by Digital Mars 3 3 // All Rights Reserved 4 4 // written by Walter Bright 5 5 // http://www.digitalmars.com … … 18 18 #include <errno.h> 19 19 #include <wchar.h> 20 20 21 #include "mars.h"22 21 #include "html.h" 23 24 22 #include <assert.h> 25 23 #include "root.h" 26 24 25 #if __GNUC__ 26 int memicmp(const char *s1, const char *s2, int n); 27 #if 0 28 { 29 int result = 0; 30 31 for (int i = 0; i < n; i++) 32 { char c1 = s1[i]; 33 char c2 = s2[i]; 34 35 result = c1 - c2; 36 if (result) 37 { 38 if ('A' <= c1 && c1 <= 'Z') 39 c1 += 'a' - 'A'; 40 if ('A' <= c2 && c2 <= 'Z') 41 c2 += 'a' - 'A'; 42 result = c1 - c2; 43 if (result) 44 break; 45 } 46 } 47 return result; 48 } 49 #endif 50 #endif 51 27 52 extern int HtmlNamedEntity(unsigned char *p, int length); 28 53 29 54 static int isLineSeparator(const unsigned char* p); … … 64 89 65 90 void Html::error(const char *format, ...) 66 91 { 67 if (!global.gag) 68 { 69 printf("%s(%d) : HTML Error: ", sourcename, linnum); 92 printf("%s(%d) : HTML Error: ", sourcename, linnum); 70 93 71 94 va_list ap; 72 95 va_start(ap, format); 73 96 vprintf(format, ap); 74 97 va_end(ap); 75 98 76 printf("\n"); 77 fflush(stdout); 78 } 99 printf("\n"); 100 fflush(stdout); 79 101 80 global.errors++;102 exit(EXIT_FAILURE); 81 103 } 82 104 83 105 /********************************************** … … 156 178 break; 157 179 } 158 180 buf->writeByte(0); // ending sentinel 181 #if SCPP 182 //printf("Code is: '%s'\n", buf->toString() + 3); 183 #endif 184 #if MARS 159 185 //printf("D code is: '%s'\n", (char *)buf->data); 186 #endif 160 187 } 161 188 162 189 /*********************************************** … … 530 557 * right. 531 558 */ 532 559 linnum++; 533 dbuf->write UTF8('\n');560 dbuf->writeByte('\n'); 534 561 p += lineSepLength; 535 562 continue; 536 563 } … … 550 577 } 551 578 } 552 579 580 553 581 /******************************************** 554 582 * Convert an HTML character entity into a character. 555 583 * Forms are: … … 716 744 return 0; 717 745 } 718 746 747 -
a/dmd2/html.h
old new 1 1 2 // Compiler implementation of the D programming language3 2 // Copyright (c) 1999-2006 by Digital Mars 4 3 // All Rights Reserved 5 4 // written by Walter Bright 6 // http://www.digitalmars.com5 // www.digitalmars.com 7 6 // License for redistribution is by either the Artistic License 8 7 // in artistic.txt, or the GNU General Public License in gnu.txt. 9 8 // See the included readme.txt for details. 10 9 11 #ifndef DMD_HTML_H12 #define DMD_HTML_H 113 14 10 struct OutBuffer; 15 11 16 12 struct Html … … 39 35 int charEntity(); 40 36 static int namedEntity(unsigned char *p, int length); 41 37 }; 42 43 #endif -
a/dmd2/idgen.c
old new 60 60 { "typeinfo" }, 61 61 { "outer" }, 62 62 { "Exception" }, 63 { "Throwable" }, 63 64 { "withSym", "__withSym" }, 64 65 { "result", "__result" }, 65 66 { "returnLabel", "__returnLabel" }, … … 87 88 { "TypeInfo_Tuple" }, 88 89 { "TypeInfo_Const" }, 89 90 { "TypeInfo_Invariant" }, 91 { "TypeInfo_Shared" }, 90 92 { "elements" }, 91 93 { "_arguments_typeinfo" }, 92 94 { "_arguments" }, … … 252 254 { "main" }, 253 255 { "WinMain" }, 254 256 { "DllMain" }, 257 { "tls_get_addr", "___tls_get_addr" }, 255 258 256 259 // Builtin functions 257 260 { "std" }, -
a/dmd2/import.c
old new 112 112 } 113 113 if (!pkg) 114 114 pkg = mod; 115 mod->semantic();116 115 117 116 //printf("-Import::load('%s'), pkg = %p\n", toChars(), pkg); 118 117 } … … 136 135 } 137 136 #endif 138 137 138 // Modules need a list of each imported module 139 //printf("%s imports %s\n", sc->module->toChars(), mod->toChars()); 140 sc->module->aimports.push(mod); 141 142 mod->semantic(); 143 139 144 /* Default to private importing 140 145 */ 141 146 protection = sc->protection; … … 147 152 sc->scopesym->importScope(mod, protection); 148 153 } 149 154 150 // Modules need a list of each imported module151 sc->module->aimports.push(mod);152 153 155 if (mod->needmoduleinfo) 154 156 sc->module->needmoduleinfo = 1; 155 157 … … 224 226 //printf("%s.Import::search(ident = '%s', flags = x%x)\n", toChars(), ident->toChars(), flags); 225 227 226 228 if (!pkg) 227 load(NULL); 229 { load(NULL); 230 mod->semantic(); 231 } 228 232 229 233 // Forward it to the package/module 230 234 return pkg->search(loc, ident, flags); -
a/dmd2/inifile.c
old new 1 2 // Copyright (c) 1999-2006 by Digital Mars 3 // All Rights Reserved 4 // written by Walter Bright 5 // http://www.digitalmars.com 6 7 8 #include <stdio.h> 9 #include <string.h> 10 #include <stdlib.h> 11 #include <ctype.h> 12 13 #include "root.h" 14 #include "mem.h" 15 16 #ifdef __MINGW32__ 17 #include <malloc.h> 18 #endif 19 20 #define LOG 0 21 22 char *skipspace(const char *p); 23 24 #if __GNUC__ 25 char *strupr(char *s) 26 { 27 char *t = s; 28 29 while (*s) 30 { 31 *s = toupper(*s); 32 s++; 33 } 34 35 return t; 36 } 37 #endif /* unix */ 38 39 /***************************** 40 * Read and analyze .ini file. 41 * Input: 42 * argv0 program name (argv[0]) 43 * inifile .ini file name 44 */ 45 46 void inifile(char *argv0x, const char *inifilex) 47 { 48 char *argv0 = (char *)argv0x; 49 char *inifile = (char *)inifilex; // do const-correct later 50 char *path; // need path for @P macro 51 char *filename; 52 OutBuffer buf; 53 int i; 54 int k; 55 int envsection = 0; 56 57 #if LOG 58 printf("inifile(argv0 = '%s', inifile = '%s')\n", argv0, inifile); 59 #endif 60 if (FileName::absolute(inifile)) 61 { 62 filename = inifile; 63 } 64 else 65 { 66 /* Look for inifile in the following sequence of places: 67 * o current directory 68 * o home directory 69 * o directory off of argv0 70 * o /etc/ 71 */ 72 if (FileName::exists(inifile)) 73 { 74 filename = inifile; 75 } 76 else 77 { 78 filename = FileName::combine(getenv("HOME"), inifile); 79 if (!FileName::exists(filename)) 80 { 81 filename = FileName::replaceName(argv0, inifile); 82 if (!FileName::exists(filename)) 83 { 84 #if POSIX 85 86 #if 0 87 #if __GLIBC__ // This fix by Thomas Kuehne 88 /* argv0 might be a symbolic link, 89 * so try again looking past it to the real path 90 */ 91 char* real_argv0 = realpath(argv0, NULL); 92 if (real_argv0) 93 { 94 filename = FileName::replaceName(real_argv0, inifile); 95 free(real_argv0); 96 if (FileName::exists(filename)) 97 goto Ldone; 98 } 99 #else 100 #error use of glibc non-standard extension realpath(char*, NULL) 101 #endif 102 #endif 103 104 // old way; problem is that argv0 might not be on the PATH at all 105 // and some other instance might be found 106 107 // Search PATH for argv0 108 const char *p = getenv("PATH"); 109 Array *paths = FileName::splitPath(p); 110 filename = FileName::searchPath(paths, argv0, 0); 111 if (!filename) 112 goto Letc; // argv0 not found on path 113 filename = FileName::replaceName(filename, inifile); 114 if (FileName::exists(filename)) 115 goto Ldone; 116 #endif 117 118 // Search /etc/ for inifile 119 Letc: 120 filename = FileName::combine((char *)"/etc/", inifile); 121 122 Ldone: 123 ; 124 } 125 } 126 } 127 } 128 path = FileName::path(filename); 129 #if LOG 130 printf("\tpath = '%s', filename = '%s'\n", path, filename); 131 #endif 132 133 File file(filename); 134 135 if (file.read()) 136 return; // error reading file 137 138 // Parse into lines 139 int eof = 0; 140 for (i = 0; i < file.len && !eof; i++) 141 { 142 int linestart = i; 143 144 for (; i < file.len; i++) 145 { 146 switch (file.buffer[i]) 147 { 148 case '\r': 149 break; 150 151 case '\n': 152 // Skip if it was preceded by '\r' 153 if (i && file.buffer[i - 1] == '\r') 154 goto Lskip; 155 break; 156 157 case 0: 158 case 0x1A: 159 eof = 1; 160 break; 161 162 default: 163 continue; 164 } 165 break; 166 } 167 168 // The line is file.buffer[linestart..i] 169 char *line; 170 int len; 171 char *p; 172 char *pn; 173 174 line = (char *)&file.buffer[linestart]; 175 len = i - linestart; 176 177 buf.reset(); 178 179 // First, expand the macros. 180 // Macros are bracketed by % characters. 181 182 for (k = 0; k < len; k++) 183 { 184 if (line[k] == '%') 185 { 186 int j; 187 188 for (j = k + 1; j < len; j++) 189 { 190 if (line[j] == '%') 191 { 192 if (j - k == 3 && memicmp(&line[k + 1], "@P", 2) == 0) 193 { 194 // %@P% is special meaning the path to the .ini file 195 p = path; 196 if (!*p) 197 p = (char *)"."; 198 } 199 else 200 { int len = j - k; 201 char tmp[10]; // big enough most of the time 202 203 if (len <= sizeof(tmp)) 204 p = tmp; 205 else 206 p = (char *)alloca(len); 207 len--; 208 memcpy(p, &line[k + 1], len); 209 p[len] = 0; 210 strupr(p); 211 p = getenv(p); 212 if (!p) 213 p = (char *)""; 214 } 215 buf.writestring(p); 216 k = j; 217 goto L1; 218 } 219 } 220 } 221 buf.writeByte(line[k]); 222 L1: 223 ; 224 } 225 226 // Remove trailing spaces 227 while (buf.offset && isspace(buf.data[buf.offset - 1])) 228 buf.offset--; 229 230 p = buf.toChars(); 231 232 // The expanded line is in p. 233 // Now parse it for meaning. 234 235 p = skipspace(p); 236 switch (*p) 237 { 238 case ';': // comment 239 case 0: // blank 240 break; 241 242 case '[': // look for [Environment] 243 p = skipspace(p + 1); 244 for (pn = p; isalnum(*pn); pn++) 245 ; 246 if (pn - p == 11 && 247 memicmp(p, "Environment", 11) == 0 && 248 *skipspace(pn) == ']' 249 ) 250 envsection = 1; 251 else 252 envsection = 0; 253 break; 254 255 default: 256 if (envsection) 257 { 258 pn = p; 259 260 // Convert name to upper case; 261 // remove spaces bracketing = 262 for (p = pn; *p; p++) 263 { if (islower(*p)) 264 *p &= ~0x20; 265 else if (isspace(*p)) 266 memmove(p, p + 1, strlen(p)); 267 else if (*p == '=') 268 { 269 p++; 270 while (isspace(*p)) 271 memmove(p, p + 1, strlen(p)); 272 break; 273 } 274 } 275 276 putenv(strdup(pn)); 277 #if LOG 278 printf("\tputenv('%s')\n", pn); 279 //printf("getenv(\"TEST\") = '%s'\n",getenv("TEST")); 280 #endif 281 } 282 break; 283 } 284 285 Lskip: 286 ; 287 } 288 } 289 290 /******************** 291 * Skip spaces. 292 */ 293 294 char *skipspace(const char *p) 295 { 296 while (isspace(*p)) 297 p++; 298 return (char *)p; 299 } 300 1 /* 2 * Some portions copyright (c) 1994-1995 by Symantec 3 * Copyright (c) 1999-2009 by Digital Mars 4 * All Rights Reserved 5 * http://www.digitalmars.com 6 * Written by Walter Bright 7 * 8 * This source file is made available for personal use 9 * only. The license is in /dmd/src/dmd/backendlicense.txt 10 * For any other uses, please contact Digital Mars. 11 */ 12 13 #include <stdio.h> 14 #include <string.h> 15 #include <stdlib.h> 16 #include <ctype.h> 17 18 #if __APPLE__ 19 #include <sys/syslimits.h> 20 #endif 21 22 #include "root.h" 23 #include "mem.h" 24 25 #ifdef __MINGW32__ 26 #include <malloc.h> 27 #endif 28 29 #define LOG 0 30 31 char *skipspace(const char *p); 32 33 #if __GNUC__ 34 char *strupr(char *s) 35 { 36 char *t = s; 37 38 while (*s) 39 { 40 *s = toupper(*s); 41 s++; 42 } 43 44 return t; 45 } 46 #endif /* unix */ 47 48 /***************************** 49 * Read and analyze .ini file. 50 * Input: 51 * argv0 program name (argv[0]) 52 * inifile .ini file name 53 */ 54 55 void inifile(char *argv0x, const char *inifilex) 56 { 57 char *argv0 = (char *)argv0x; 58 char *inifile = (char *)inifilex; // do const-correct later 59 char *path; // need path for @P macro 60 char *filename; 61 OutBuffer buf; 62 int i; 63 int k; 64 int envsection = 0; 65 66 #if LOG 67 printf("inifile(argv0 = '%s', inifile = '%s')\n", argv0, inifile); 68 #endif 69 if (FileName::absolute(inifile)) 70 { 71 filename = inifile; 72 } 73 else 74 { 75 /* Look for inifile in the following sequence of places: 76 * o current directory 77 * o home directory 78 * o directory off of argv0 79 * o /etc/ 80 */ 81 if (FileName::exists(inifile)) 82 { 83 filename = inifile; 84 } 85 else 86 { 87 filename = FileName::combine(getenv("HOME"), inifile); 88 if (!FileName::exists(filename)) 89 { 90 filename = FileName::replaceName(argv0, inifile); 91 if (!FileName::exists(filename)) 92 { 93 #if POSIX 94 // old way; problem is that argv0 might not be on the PATH at all 95 // and some other instance might be found 96 97 // Search PATH for argv0 98 const char *p = getenv("PATH"); 99 Array *paths = FileName::splitPath(p); 100 filename = FileName::searchPath(paths, argv0, 0); 101 if (!filename) 102 goto Letc; // argv0 not found on path 103 filename = FileName::replaceName(filename, inifile); 104 if (FileName::exists(filename)) 105 goto Ldone; 106 #endif 107 108 // Search /etc/ for inifile 109 Letc: 110 filename = FileName::combine((char *)"/etc/", inifile); 111 112 Ldone: 113 ; 114 } 115 } 116 } 117 } 118 path = FileName::path(filename); 119 #if LOG 120 printf("\tpath = '%s', filename = '%s'\n", path, filename); 121 #endif 122 123 File file(filename); 124 125 if (file.read()) 126 return; // error reading file 127 128 // Parse into lines 129 int eof = 0; 130 for (i = 0; i < file.len && !eof; i++) 131 { 132 int linestart = i; 133 134 for (; i < file.len; i++) 135 { 136 switch (file.buffer[i]) 137 { 138 case '\r': 139 break; 140 141 case '\n': 142 // Skip if it was preceded by '\r' 143 if (i && file.buffer[i - 1] == '\r') 144 goto Lskip; 145 break; 146 147 case 0: 148 case 0x1A: 149 eof = 1; 150 break; 151 152 default: 153 continue; 154 } 155 break; 156 } 157 158 // The line is file.buffer[linestart..i] 159 char *line; 160 int len; 161 char *p; 162 char *pn; 163 164 line = (char *)&file.buffer[linestart]; 165 len = i - linestart; 166 167 buf.reset(); 168 169 // First, expand the macros. 170 // Macros are bracketed by % characters. 171 172 for (k = 0; k < len; k++) 173 { 174 if (line[k] == '%') 175 { 176 int j; 177 178 for (j = k + 1; j < len; j++) 179 { 180 if (line[j] == '%') 181 { 182 if (j - k == 3 && memicmp(&line[k + 1], "@P", 2) == 0) 183 { 184 // %@P% is special meaning the path to the .ini file 185 p = path; 186 if (!*p) 187 p = (char *)"."; 188 } 189 else 190 { int len = j - k; 191 char tmp[10]; // big enough most of the time 192 193 if (len <= sizeof(tmp)) 194 p = tmp; 195 else 196 p = (char *)alloca(len); 197 len--; 198 memcpy(p, &line[k + 1], len); 199 p[len] = 0; 200 strupr(p); 201 p = getenv(p); 202 if (!p) 203 p = (char *)""; 204 } 205 buf.writestring(p); 206 k = j; 207 goto L1; 208 } 209 } 210 } 211 buf.writeByte(line[k]); 212 L1: 213 ; 214 } 215 216 // Remove trailing spaces 217 while (buf.offset && isspace(buf.data[buf.offset - 1])) 218 buf.offset--; 219 220 p = buf.toChars(); 221 222 // The expanded line is in p. 223 // Now parse it for meaning. 224 225 p = skipspace(p); 226 switch (*p) 227 { 228 case ';': // comment 229 case 0: // blank 230 break; 231 232 case '[': // look for [Environment] 233 p = skipspace(p + 1); 234 for (pn = p; isalnum(*pn); pn++) 235 ; 236 if (pn - p == 11 && 237 memicmp(p, "Environment", 11) == 0 && 238 *skipspace(pn) == ']' 239 ) 240 envsection = 1; 241 else 242 envsection = 0; 243 break; 244 245 default: 246 if (envsection) 247 { 248 pn = p; 249 250 // Convert name to upper case; 251 // remove spaces bracketing = 252 for (p = pn; *p; p++) 253 { if (islower(*p)) 254 *p &= ~0x20; 255 else if (isspace(*p)) 256 memmove(p, p + 1, strlen(p)); 257 else if (*p == '=') 258 { 259 p++; 260 while (isspace(*p)) 261 memmove(p, p + 1, strlen(p)); 262 break; 263 } 264 } 265 266 putenv(strdup(pn)); 267 #if LOG 268 printf("\tputenv('%s')\n", pn); 269 //printf("getenv(\"TEST\") = '%s'\n",getenv("TEST")); 270 #endif 271 } 272 break; 273 } 274 275 Lskip: 276 ; 277 } 278 } 279 280 /******************** 281 * Skip spaces. 282 */ 283 284 char *skipspace(const char *p) 285 { 286 while (isspace(*p)) 287 p++; 288 return (char *)p; 289 } 290 -
a/dmd2/inline.c
old new 1382 1382 else 1383 1383 vthis->storage_class = STCin; 1384 1384 #else 1385 assert(0); 1385 1386 if (ethis->type->ty != Tclass && ethis->type->ty != Tpointer) 1386 1387 { 1387 1388 ethis = ethis->addressOf(NULL); -
a/dmd2/interpret.c
old new 1513 1513 } 1514 1514 } 1515 1515 /* Assignment to struct member of the form: 1516 * v.var = e2 1517 */ 1518 else if (e1->op == TOKdotvar && ((DotVarExp *)e1)->e1->op == TOKvar) 1519 { VarExp *ve = (VarExp *)((DotVarExp *)e1)->e1; 1520 VarDeclaration *v = ve->var->isVarDeclaration(); 1521 1522 if (v->isDataseg()) 1523 return EXP_CANT_INTERPRET; 1524 if (fp && !v->value) 1525 { error("variable %s is used before initialization", v->toChars()); 1526 return e; 1527 } 1528 Expression *vie = v->value; 1529 if (vie->op == TOKvar) 1530 { 1531 Declaration *d = ((VarExp *)vie)->var; 1532 vie = getVarExp(e1->loc, istate, d); 1533 } 1534 if (vie->op != TOKstructliteral) 1535 return EXP_CANT_INTERPRET; 1536 StructLiteralExp *se = (StructLiteralExp *)vie; 1537 VarDeclaration *vf = ((DotVarExp *)e1)->var->isVarDeclaration(); 1538 if (!vf) 1539 return EXP_CANT_INTERPRET; 1540 int fieldi = se->getFieldIndex(type, vf->offset); 1541 if (fieldi == -1) 1542 return EXP_CANT_INTERPRET; 1543 Expression *ev = se->getField(type, vf->offset); 1544 if (fp) 1545 e2 = (*fp)(type, ev, e2); 1546 else 1547 e2 = Cast(type, type, e2); 1548 if (e2 == EXP_CANT_INTERPRET) 1549 return e2; 1550 1551 if (!v->isParameter()) 1552 { 1553 for (size_t i = 0; 1; i++) 1554 { 1555 if (i == istate->vars.dim) 1556 { istate->vars.push(v); 1557 break; 1558 } 1559 if (v == (VarDeclaration *)istate->vars.data[i]) 1560 break; 1561 } 1562 } 1563 1564 /* Create new struct literal reflecting updated fieldi 1565 */ 1566 Expressions *expsx = new Expressions(); 1567 expsx->setDim(se->elements->dim); 1568 for (size_t j = 0; j < expsx->dim; j++) 1569 { 1570 if (j == fieldi) 1571 expsx->data[j] = (void *)e2; 1572 else 1573 expsx->data[j] = se->elements->data[j]; 1574 } 1575 v->value = new StructLiteralExp(se->loc, se->sd, expsx); 1576 v->value->type = se->type; 1577 1578 e = Cast(type, type, post ? ev : e2); 1579 } 1580 /* Assignment to struct member of the form: 1516 1581 * *(symoffexp) = e2 1517 1582 */ 1518 1583 else if (e1->op == TOKstar && ((PtrExp *)e1)->e1->op == TOKsymoff) -
a/dmd2/lexer.c
old new 18 18 #include <wchar.h> 19 19 #include <stdlib.h> 20 20 #include <assert.h> 21 #if _MSC_VER 22 #include <time.h> 23 #else 21 24 #include <sys/time.h> 25 #endif 22 26 #include <math.h> 23 27 24 #i fdef IN_GCC28 #include <time.h> 25 29 26 #include <time.h> 30 27 31 #include "mem.h" 28 32 29 #else30 31 #if __GNUC__32 #include <time.h>33 #endif34 35 #if IN_LLVM36 #include "mem.h"37 #elif _WIN3238 #include "..\root\mem.h"39 #else40 #include "../root/mem.h"41 #endif42 #endif43 44 33 #include "stringtable.h" 45 34 46 35 #include "lexer.h" … … 54 43 extern "C" char * __cdecl __locale_decpoint; 55 44 #endif 56 45 46 #if _MSC_VER // workaround VC++ bug, labels and types should be in separate namespaces 47 #define Lstring Lstr 48 #endif 49 57 50 extern int HtmlNamedEntity(unsigned char *p, int length); 58 51 59 52 #define LS 0x2028 // UTF line separator … … 403 396 return peek(&token)->value; 404 397 } 405 398 399 /*********************** 400 * Look 2 tokens ahead at value. 401 */ 402 403 TOK Lexer::peekNext2() 404 { 405 Token *t = peek(&token); 406 return peek(t)->value; 407 } 408 406 409 /********************************* 407 410 * tk is on the opening (. 408 411 * Look ahead and return token that is past the closing ). … … 599 602 case '"': 600 603 t->value = escapeStringConstant(t,0); 601 604 return; 602 605 #if ! TEXTUAL_ASSEMBLY_OUT 603 606 case '\\': // escaped string literal 604 607 { unsigned c; 608 unsigned char *pstart = p; 605 609 606 610 stringbuffer.reset(); 607 611 do … … 628 632 memcpy(t->ustring, stringbuffer.data, stringbuffer.offset); 629 633 t->postfix = 0; 630 634 t->value = TOKstring; 635 if (!global.params.useDeprecated) 636 error("Escape String literal %.*s is deprecated, use double quoted string literal \"%.*s\" instead", p - pstart, pstart, p - pstart, pstart); 631 637 return; 632 638 } 633 639 #endif 634 640 case 'l': 635 641 case 'L': 636 642 #endif … … 1228 1234 */ 1229 1235 1230 1236 unsigned Lexer::escapeSequence() 1231 { unsigned c; 1237 { unsigned c = *p; 1238 1239 #ifdef TEXTUAL_ASSEMBLY_OUT 1240 return c; 1241 #endif 1232 1242 int n; 1233 1243 int ndigits; 1234 1244 1235 c = *p;1236 1245 switch (c) 1237 1246 { 1238 1247 case '\'': … … 1587 1596 else 1588 1597 { delimright = c; 1589 1598 nest = 0; 1599 if (isspace(c)) 1600 error("delimiter cannot be whitespace"); 1590 1601 } 1591 1602 } 1592 1603 else … … 1608 1619 } 1609 1620 else if (c == delimright) 1610 1621 goto Ldone; 1611 if (startline && isalpha(c) )1622 if (startline && isalpha(c) && hereid) 1612 1623 { Token t; 1613 1624 unsigned char *psave = p; 1614 1625 p--; … … 1717 1728 c = *p++; 1718 1729 switch (c) 1719 1730 { 1731 #if !( TEXTUAL_ASSEMBLY_OUT ) 1720 1732 case '\\': 1721 1733 switch (*p) 1722 1734 { … … 1732 1744 break; 1733 1745 } 1734 1746 break; 1735 1747 #endif 1736 1748 case '\n': 1737 1749 loc.linnum++; 1738 1750 break; … … 1793 1805 c = *p++; 1794 1806 switch (c) 1795 1807 { 1808 #if ! TEXTUAL_ASSEMBLY_OUT 1796 1809 case '\\': 1797 1810 switch (*p) 1798 1811 { … … 1812 1825 break; 1813 1826 } 1814 1827 break; 1815 1828 #endif 1816 1829 case '\n': 1817 1830 L1: 1818 1831 loc.linnum++; -
a/dmd2/lexer.h
old new 278 278 279 279 TOK nextToken(); 280 280 TOK peekNext(); 281 TOK peekNext2(); 281 282 void scan(Token *t); 282 283 Token *peek(Token *t); 283 284 Token *peekPastParen(Token *t); -
a/dmd2/macro.c
old new 16 16 #include <ctype.h> 17 17 #include <assert.h> 18 18 19 #if IN_GCC || IN_LLVM20 19 #include "mem.h" 21 #else 22 #if _WIN32 23 #include "..\root\mem.h" 24 #elif POSIX 25 #include "../root/mem.h" 26 #else 27 #error "fix this" 28 #endif 29 #endif 20 #include "root.h" 30 21 31 #include "root.h"32 22 #include "macro.h" 33 23 34 24 #define isidstart(c) (isalpha(c) || (c) == '_') -
a/dmd2/man.c
old new 1 2 // Compiler implementation of the D programming language 3 // Copyright (c) 2008-2008 by Digital Mars 4 // All Rights Reserved 5 // written by Walter Bright 6 // http://www.digitalmars.com 7 // License for redistribution is by either the Artistic License 8 // in artistic.txt, or the GNU General Public License in gnu.txt. 9 // See the included readme.txt for details. 10 11 #include <stdio.h> 12 #include <string.h> 13 #include <stdlib.h> 14 #include <assert.h> 15 16 #if _WIN32 17 18 #include <windows.h> 19 20 #pragma comment(lib,"shell32.lib") 21 22 void browse(const char *url) 23 { 24 ShellExecute(NULL, "open", url, NULL, NULL, SW_SHOWNORMAL); 25 } 26 27 #endif 28 29 #if linux || __APPLE__ 30 31 #include <sys/types.h> 32 #include <sys/wait.h> 33 #include <unistd.h> 34 35 void browse(const char *url) 36 { 37 pid_t childpid; 38 const char *args[3]; 39 40 const char *browser = getenv("BROWSER"); 41 if (browser) 42 browser = strdup(browser); 43 else 44 browser = "firefox"; 45 46 args[0] = browser; 47 args[1] = url; 48 args[2] = NULL; 49 50 childpid = fork(); 51 if (childpid == 0) 52 { 53 execvp(args[0], (char**)args); 54 perror(args[0]); // failed to execute 55 return; 56 } 57 } 58 59 #endif 60 1 2 // Compiler implementation of the D programming language 3 // Copyright (c) 2008-2009 by Digital Mars 4 // All Rights Reserved 5 // written by Walter Bright 6 // http://www.digitalmars.com 7 // License for redistribution is by either the Artistic License 8 // in artistic.txt, or the GNU General Public License in gnu.txt. 9 // See the included readme.txt for details. 10 11 #include <stdio.h> 12 #include <string.h> 13 #include <stdlib.h> 14 #include <assert.h> 15 16 #if _WIN32 17 18 #include <windows.h> 19 20 #pragma comment(lib,"shell32.lib") 21 22 void browse(const char *url) 23 { 24 ShellExecute(NULL, "open", url, NULL, NULL, SW_SHOWNORMAL); 25 } 26 27 #endif 28 29 #if linux || __APPLE__ 30 31 #include <sys/types.h> 32 #include <sys/wait.h> 33 #include <unistd.h> 34 35 void browse(const char *url) 36 { 37 pid_t childpid; 38 const char *args[3]; 39 40 char *browser = getenv("BROWSER"); 41 if (browser) 42 browser = strdup(browser); 43 else 44 browser = "x-www-browser"; 45 46 args[0] = browser; 47 args[1] = url; 48 args[2] = NULL; 49 50 childpid = fork(); 51 if (childpid == 0) 52 { 53 execvp(args[0], (char**)args); 54 perror(args[0]); // failed to execute 55 return; 56 } 57 } 58 59 #endif 60 61 #if __APPLE__ 62 63 #include <sys/types.h> 64 #include <sys/wait.h> 65 #include <unistd.h> 66 67 void browse(const char *url) 68 { 69 pid_t childpid; 70 const char *args[5]; 71 72 char *browser = getenv("BROWSER"); 73 if (browser) 74 { browser = strdup(browser); 75 args[0] = browser; 76 args[1] = url; 77 args[2] = NULL; 78 } 79 else 80 { 81 //browser = "/Applications/Safari.app/Contents/MacOS/Safari"; 82 args[0] = "open"; 83 args[1] = "-a"; 84 args[2] = "/Applications/Safari.app"; 85 args[3] = url; 86 args[4] = NULL; 87 } 88 89 childpid = fork(); 90 if (childpid == 0) 91 { 92 execvp(args[0], (char**)args); 93 perror(args[0]); // failed to execute 94 return; 95 } 96 } 97 98 #endif 99 100 101 #if __FreeBSD__ 102 #endif -
a/dmd2/mangle.c
old new 24 24 #include "id.h" 25 25 #include "module.h" 26 26 27 #if TARGET_LINUX 27 #if TARGET_LINUX || TARGET_OSX 28 28 char *cpp_mangle(Dsymbol *s); 29 29 #endif 30 30 … … 117 117 return ident->toChars(); 118 118 119 119 case LINKcpp: 120 #if TARGET_LINUX120 #if DMDV2 && (TARGET_LINUX || TARGET_OSX) 121 121 return cpp_mangle(this); 122 122 #else 123 123 // Windows C++ mangling is done by C++ back end -
a/dmd2/mars.c
old new 59 59 60 60 copyright = "Copyright (c) 1999-2009 by Digital Mars and Tomas Lindquist Olsen"; 61 61 written = "written by Walter Bright and Tomas Lindquist Olsen"; 62 version = "v2.02 1";62 version = "v2.026"; 63 63 ldc_version = LDC_REV; 64 64 llvm_version = LLVM_REV; 65 65 global.structalign = 8; … … 105 105 va_end( ap ); 106 106 } 107 107 108 void warning(Loc loc, const char *format, ...) 109 { 110 if (global.params.warnings && !global.gag) 111 { 112 fprintf(stdmsg, "warning - "); 113 va_list ap; 114 va_start(ap, format); 115 verror(loc, format, ap); 116 va_end( ap ); 117 } 118 } 119 108 120 void verror(Loc loc, const char *format, va_list ap) 109 121 { 110 122 if (!global.gag) … … 116 128 mem.free(p); 117 129 118 130 fprintf(stdmsg, "Error: "); 131 #if _MSC_VER 132 // MS doesn't recognize %zu format 133 OutBuffer tmp; 134 tmp.vprintf(format, ap); 135 fprintf(stdmsg, "%s", tmp.toChars()); 136 #else 119 137 vfprintf(stdmsg, format, ap); 138 #endif 120 139 fprintf(stdmsg, "\n"); 121 140 fflush(stdmsg); 122 141 } … … 136 155 exit(EXIT_FAILURE); 137 156 } 138 157 139 /**************************************140 * Try to stop forgetting to remove the breakpoints from141 * release builds.142 */143 void halt()144 {145 #ifdef DEBUG146 *(char*)0=0;147 #endif148 }149 150 158 /*********************************** 151 159 * Parse and append contents of environment variable envvar 152 160 * to argc and argv[]. -
a/dmd2/mars.h
old new 1 1 2 2 // Compiler implementation of the D programming language 3 // Copyright (c) 1999-200 7by Digital Mars3 // Copyright (c) 1999-2009 by Digital Mars 4 4 // All Rights Reserved 5 5 // written by Walter Bright 6 6 // http://www.digitalmars.com … … 13 13 14 14 #ifdef __DMC__ 15 15 #pragma once 16 #endif /* __DMC__ */ 16 #endif 17 18 /* 19 It is very important to use version control macros correctly - the 20 idea is that host and target are independent. If these are done 21 correctly, cross compilers can be built. 22 The host compiler and host operating system are also different, 23 and are predefined by the host compiler. The ones used in 24 dmd are: 25 26 Macros defined by the compiler, not the code: 27 28 Compiler: 29 __DMC__ Digital Mars compiler 30 _MSC_VER Microsoft compiler 31 __GNUC__ Gnu compiler 32 33 Host operating system: 34 _WIN32 Microsoft NT, Windows 95, Windows 98, Win32s, 35 Windows 2000, Win XP, Vista 36 _WIN64 Windows for AMD64 37 linux Linux 38 __APPLE__ Mac OSX 39 40 For the target systems, there are the target operating system and 41 the target object file format: 42 43 Target operating system: 44 TARGET_WINDOS Covers 32 bit windows and 64 bit windows 45 TARGET_LINUX Covers 32 and 64 bit linux 46 TARGET_OSX Covers 32 and 64 bit Mac OSX 47 48 It is expected that the compiler for each platform will be able 49 to generate 32 and 64 bit code from the same compiler binary. 50 51 Target object module format: 52 OMFOBJ Intel Object Module Format, used on Windows 53 ELFOBJ Elf Object Module Format, used on linux 54 MACHOBJ Mach-O Object Module Format, used on Mac OSX 55 56 There are currently no macros for byte endianness order. 57 */ 58 17 59 18 60 #include <stdint.h> 19 61 #include <stdarg.h> … … 34 76 #endif 35 77 36 78 #define BREAKABI 1 // 0 if not ready to break the ABI just yet 37 #define STRUCTTHISREF V2 // if 'this' for struct is a reference, not a pointer 79 #define STRUCTTHISREF 1 // if 'this' for struct is a reference, not a pointer 80 81 /* Other targets are TARGET_LINUX and TARGET_OSX, which are 82 * set on the command line via the compiler makefile. 83 */ 84 85 #if _WIN32 86 #define TARGET_WINDOS 1 // Windows dmd generates Windows targets 87 #define OMFOBJ 1 88 #endif 89 90 #if TARGET_LINUX 91 #ifndef ELFOBJ 92 #define ELFOBJ 1 93 #endif 94 #endif 95 96 #if TARGET_OSX 97 #ifndef MACHOBJ 98 #define MACHOBJ 1 99 #endif 100 #endif 101 38 102 39 103 struct Array; 40 104 … … 67 131 }; 68 132 69 133 // make it easier to test new linkage types 70 #define TEMPLATE_LINKAGE_TYPE llvm::GlobalValue::LinkOnce Linkage71 #define TYPEINFO_LINKAGE_TYPE llvm::GlobalValue::LinkOnce Linkage134 #define TEMPLATE_LINKAGE_TYPE llvm::GlobalValue::LinkOnceAnyLinkage 135 #define TYPEINFO_LINKAGE_TYPE llvm::GlobalValue::LinkOnceAnyLinkage 72 136 73 137 // Put command line switches in here 74 138 struct Param … … 338 402 MATCHexact // exact match 339 403 }; 340 404 405 void warning(Loc loc, const char *format, ...); 341 406 void error(Loc loc, const char *format, ...); 342 407 void verror(Loc loc, const char *format, va_list); 343 408 void fatal(); -
a/dmd2/module.c
old new 84 84 #ifdef IN_GCC 85 85 strictlyneedmoduleinfo = 0; 86 86 #endif 87 selfimports = 0; 87 88 insearch = 0; 88 89 searchCacheIdent = NULL; 89 90 searchCacheSymbol = NULL; … … 145 146 this->doHdrGen = doHdrGen; 146 147 } 147 148 148 File* Module::buildFilePath(char* forcename, c onst char* path, constchar* ext)149 File* Module::buildFilePath(char* forcename, char* path, char* ext) 149 150 { 150 151 char *argobj; 151 152 if (forcename) … … 903 904 //printf("-Module::runDeferredSemantic('%s'), len = %d\n", toChars(), deferred.dim); 904 905 } 905 906 907 /************************************ 908 * Recursively look at every module this module imports, 909 * return TRUE if it imports m. 910 * Can be used to detect circular imports. 911 */ 912 913 int Module::imports(Module *m) 914 { 915 //printf("%s Module::imports(%s)\n", toChars(), m->toChars()); 916 int aimports_dim = aimports.dim; 917 #if 0 918 for (int i = 0; i < aimports.dim; i++) 919 { Module *mi = (Module *)aimports.data[i]; 920 printf("\t[%d] %s\n", i, mi->toChars()); 921 } 922 #endif 923 for (int i = 0; i < aimports.dim; i++) 924 { Module *mi = (Module *)aimports.data[i]; 925 if (mi == m) 926 return TRUE; 927 if (!mi->insearch) 928 { 929 mi->insearch = 1; 930 int r = mi->imports(m); 931 if (r) 932 return r; 933 } 934 } 935 return FALSE; 936 } 937 938 /************************************* 939 * Return !=0 if module imports itself. 940 */ 941 942 int Module::selfImports() 943 { 944 //printf("Module::selfImports() %s\n", toChars()); 945 if (!selfimports) 946 { 947 for (int i = 0; i < amodules.dim; i++) 948 { Module *mi = (Module *)amodules.data[i]; 949 //printf("\t[%d] %s\n", i, mi->toChars()); 950 mi->insearch = 0; 951 } 952 953 selfimports = imports(this) + 1; 954 955 for (int i = 0; i < amodules.dim; i++) 956 { Module *mi = (Module *)amodules.data[i]; 957 //printf("\t[%d] %s\n", i, mi->toChars()); 958 mi->insearch = 0; 959 } 960 } 961 return selfimports - 1; 962 } 963 964 906 965 /* =========================== ModuleDeclaration ===================== */ 907 966 908 967 ModuleDeclaration::ModuleDeclaration(Array *packages, Identifier *id, bool safe) -
a/dmd2/module.h
old new 30 30 #if IN_LLVM 31 31 struct DValue; 32 32 typedef DValue elem; 33 namespace llvm { class Module; } 33 34 #else 34 35 #ifdef IN_GCC 35 36 union tree_node; typedef union tree_node elem; … … 79 80 int strictlyneedmoduleinfo; 80 81 #endif 81 82 83 int selfimports; // 0: don't know, 1: does not, 2: does 84 int selfImports(); // returns !=0 if module imports itself 85 82 86 int insearch; 83 87 Identifier *searchCacheIdent; 84 88 Dsymbol *searchCacheSymbol; // cached value of search … … 143 147 void deleteObjFile(); 144 148 void addDeferredSemantic(Dsymbol *s); 145 149 void runDeferredSemantic(); 150 int imports(Module *m); 146 151 147 152 // Back end 148 153 … … 172 177 void genmoduleinfo(); 173 178 174 179 // LDC 180 llvm::Module* genLLVMModule(int multiobj); 175 181 void buildTargetFiles(); 176 File* buildFilePath(char* forcename, c onst char* path, constchar* ext);182 File* buildFilePath(char* forcename, char* path, char* ext); 177 183 Module *isModule() { return this; } 178 184 179 185 bool llvmForceLogging; -
a/dmd2/mtype.c
old new 1 1 2 2 // Compiler implementation of the D programming language 3 // Copyright (c) 1999-200 8by Digital Mars3 // Copyright (c) 1999-2009 by Digital Mars 4 4 // All Rights Reserved 5 5 // written by Walter Bright 6 6 // http://www.digitalmars.com … … 106 106 ClassDeclaration *Type::typeinfotypelist; 107 107 ClassDeclaration *Type::typeinfoconst; 108 108 ClassDeclaration *Type::typeinfoinvariant; 109 ClassDeclaration *Type::typeinfoshared; 109 110 110 111 Type *Type::tvoidptr; 111 112 Type *Type::basic[TMAX]; … … 122 123 #if DMDV2 123 124 this->cto = NULL; 124 125 this->ito = NULL; 126 this->sto = NULL; 127 this->scto = NULL; 125 128 #endif 126 129 this->pto = NULL; 127 130 this->rto = NULL; … … 327 330 return MATCHnomatch; 328 331 } 329 332 333 /******************************** 334 * Convert to 'const'. 335 */ 336 330 337 Type *Type::constOf() 331 338 { 339 #if 0 332 340 //printf("Type::constOf() %p %s\n", this, toChars()); 333 341 if (isConst()) 334 342 return this; … … 342 350 //if (t->nextOf()) assert(t->nextOf()->isConst()); 343 351 //printf("-Type::constOf() %p %s\n", t, toChars()); 344 352 return t; 345 } 353 #else 354 //printf("Type::constOf() %p %s\n", this, toChars()); 355 if (mod == MODconst) 356 return this; 357 if (cto) 358 { assert(cto->mod == MODconst); 359 return cto; 360 } 361 Type *t = makeConst(); 362 t = t->merge(); 363 t->fixTo(this); 364 //printf("-Type::constOf() %p %s\n", t, toChars()); 365 return t; 366 #endif 367 } 368 369 /******************************** 370 * Convert to 'immutable'. 371 */ 346 372 347 373 Type *Type::invariantOf() 348 374 { 375 #if 0 349 376 //printf("Type::invariantOf() %p %s\n", this, toChars()); 350 377 if (isInvariant()) 351 378 { … … 370 397 #endif 371 398 //printf("\t%p\n", t); 372 399 return t; 373 } 400 #else 401 //printf("Type::invariantOf() %p %s\n", this, toChars()); 402 if (isInvariant()) 403 { 404 return this; 405 } 406 if (ito) 407 { 408 assert(ito->isInvariant()); 409 return ito; 410 } 411 Type *t = makeInvariant(); 412 t = t->merge(); 413 t->fixTo(this); 414 //printf("\t%p\n", t); 415 return t; 416 #endif 417 } 418 419 /******************************** 420 * Make type mutable. 421 */ 374 422 375 423 Type *Type::mutableOf() 376 424 { 425 #if 0 377 426 //printf("Type::mutableOf() %p, %s\n", this, toChars()); 378 427 Type *t = this; 379 428 if (isConst()) … … 396 445 t->rto = NULL; 397 446 t->cto = NULL; 398 447 t->ito = NULL; 448 t->sto = NULL; 449 t->scto = NULL; 399 450 t->vtinfo = NULL; 400 451 if (ty == Tsarray) 401 452 { TypeSArray *ta = (TypeSArray *)t; … … 416 467 } 417 468 } 418 469 return t; 470 #else 471 //printf("Type::mutableOf() %p, %s\n", this, toChars()); 472 Type *t = this; 473 if (isConst()) 474 { if (isShared()) 475 t = sto; // shared const => shared 476 else 477 t = cto; 478 assert(!t || t->isMutable()); 479 } 480 else if (isInvariant()) 481 { t = ito; 482 assert(!t || (t->isMutable() && !t->isShared())); 483 } 484 if (!t) 485 { 486 unsigned sz = sizeTy[ty]; 487 t = (Type *)mem.malloc(sz); 488 memcpy(t, this, sz); 489 t->mod = 0; 490 t->deco = NULL; 491 t->arrayof = NULL; 492 t->pto = NULL; 493 t->rto = NULL; 494 t->cto = NULL; 495 t->ito = NULL; 496 t->sto = NULL; 497 t->scto = NULL; 498 t->vtinfo = NULL; 499 t = t->merge(); 500 501 t->fixTo(this); 502 503 switch (mod) 504 { 505 case MODconst: 506 t->cto = this; 507 break; 508 509 case MODinvariant: 510 t->ito = this; 511 break; 512 513 case MODshared: 514 t->sto = this; 515 break; 516 517 case MODshared | MODconst: 518 t->scto = this; 519 break; 520 521 default: 522 assert(0); 523 } 524 } 525 return t; 526 #endif 527 } 528 529 Type *Type::sharedOf() 530 { 531 //printf("Type::sharedOf() %p, %s\n", this, toChars()); 532 if (mod == MODshared) 533 { 534 return this; 535 } 536 if (sto) 537 { 538 assert(sto->isShared()); 539 return sto; 540 } 541 Type *t = makeShared(); 542 t = t->merge(); 543 t->fixTo(this); 544 //printf("\t%p\n", t); 545 return t; 546 } 547 548 Type *Type::sharedConstOf() 549 { 550 //printf("Type::sharedConstOf() %p, %s\n", this, toChars()); 551 if (mod == (MODshared | MODconst)) 552 { 553 return this; 554 } 555 if (scto) 556 { 557 assert(scto->mod == (MODshared | MODconst)); 558 return scto; 559 } 560 Type *t = makeSharedConst(); 561 t = t->merge(); 562 t->fixTo(this); 563 //printf("\t%p\n", t); 564 return t; 565 } 566 567 568 /********************************** 569 * For our new type 'this', which is type-constructed from t, 570 * fill in the cto, ito, sto, scto shortcuts. 571 */ 572 573 void Type::fixTo(Type *t) 574 { 575 ito = t->ito; 576 #if 0 577 /* Cannot do these because these are not fully transitive: 578 * there can be a shared ptr to immutable, for example. 579 * Immutable subtypes are always immutable, though. 580 */ 581 cto = t->cto; 582 sto = t->sto; 583 scto = t->scto; 584 #endif 585 586 assert(mod != t->mod); 587 #define X(m, n) (((m) << 3) | (n)) 588 switch (X(mod, t->mod)) 589 { 590 case X(0, MODconst): 591 cto = t; 592 break; 593 594 case X(0, MODinvariant): 595 ito = t; 596 break; 597 598 case X(0, MODshared): 599 sto = t; 600 break; 601 602 case X(0, MODshared | MODconst): 603 scto = t; 604 break; 605 606 607 case X(MODconst, 0): 608 cto = NULL; 609 goto L2; 610 611 case X(MODconst, MODinvariant): 612 ito = t; 613 goto L2; 614 615 case X(MODconst, MODshared): 616 sto = t; 617 goto L2; 618 619 case X(MODconst, MODshared | MODconst): 620 scto = t; 621 L2: 622 t->cto = this; 623 break; 624 625 626 case X(MODinvariant, 0): 627 ito = NULL; 628 goto L3; 629 630 case X(MODinvariant, MODconst): 631 cto = t; 632 goto L3; 633 634 case X(MODinvariant, MODshared): 635 sto = t; 636 goto L3; 637 638 case X(MODinvariant, MODshared | MODconst): 639 scto = t; 640 L3: 641 t->ito = this; 642 if (t->cto) t->cto->ito = this; 643 if (t->sto) t->sto->ito = this; 644 if (t->scto) t->scto->ito = this; 645 break; 646 647 648 case X(MODshared, 0): 649 sto = NULL; 650 goto L4; 651 652 case X(MODshared, MODconst): 653 cto = t; 654 goto L4; 655 656 case X(MODshared, MODinvariant): 657 ito = t; 658 goto L4; 659 660 case X(MODshared, MODshared | MODconst): 661 scto = t; 662 L4: 663 t->sto = this; 664 break; 665 666 667 case X(MODshared | MODconst, 0): 668 scto = NULL; 669 break; 670 671 case X(MODshared | MODconst, MODconst): 672 cto = t; 673 break; 674 675 case X(MODshared | MODconst, MODinvariant): 676 ito = t; 677 break; 678 679 case X(MODshared | MODconst, MODshared): 680 sto = t; 681 L5: 682 t->scto = this; 683 break; 684 685 default: 686 assert(0); 687 } 688 #undef X 689 690 check(); 691 t->check(); 692 //printf("fixTo: %s, %s\n", toChars(), t->toChars()); 693 } 694 695 /*************************** 696 * Look for bugs in constructing types. 697 */ 698 699 void Type::check() 700 { 701 switch (mod) 702 { 703 case 0: 704 if (cto) assert(cto->mod == MODconst); 705 if (ito) assert(ito->mod == MODinvariant); 706 if (sto) assert(sto->mod == MODshared); 707 if (scto) assert(scto->mod == (MODshared | MODconst)); 708 break; 709 710 case MODconst: 711 if (cto) assert(cto->mod == 0); 712 if (ito) assert(ito->mod == MODinvariant); 713 if (sto) assert(sto->mod == MODshared); 714 if (scto) assert(scto->mod == (MODshared | MODconst)); 715 break; 716 717 case MODinvariant: 718 if (cto) assert(cto->mod == MODconst); 719 if (ito) assert(ito->mod == 0); 720 if (sto) assert(sto->mod == MODshared); 721 if (scto) assert(scto->mod == (MODshared | MODconst)); 722 break; 723 724 case MODshared: 725 if (cto) assert(cto->mod == MODconst); 726 if (ito) assert(ito->mod == MODinvariant); 727 if (sto) assert(sto->mod == 0); 728 if (scto) assert(scto->mod == (MODshared | MODconst)); 729 break; 730 731 case MODshared | MODconst: 732 if (cto) assert(cto->mod == MODconst); 733 if (ito) assert(ito->mod == MODinvariant); 734 if (sto) assert(sto->mod == MODshared); 735 if (scto) assert(scto->mod == 0); 736 break; 737 738 default: 739 assert(0); 740 } 741 742 Type *tn = nextOf(); 743 if (tn && ty != Tfunction && ty != Tdelegate) 744 { // Verify transitivity 745 switch (mod) 746 { 747 case 0: 748 break; 749 750 case MODconst: 751 assert(tn->mod & MODinvariant || tn->mod & MODconst); 752 break; 753 754 case MODinvariant: 755 assert(tn->mod == MODinvariant); 756 break; 757 758 case MODshared: 759 assert(tn->mod & MODinvariant || tn->mod & MODshared); 760 break; 761 762 case MODshared | MODconst: 763 assert(tn->mod & MODinvariant || tn->mod & (MODshared | MODconst)); 764 break; 765 766 default: 767 assert(0); 768 } 769 tn->check(); 770 } 419 771 } 420 772 421 773 Type *Type::makeConst() … … 433 785 t->rto = NULL; 434 786 t->cto = NULL; 435 787 t->ito = NULL; 788 t->sto = NULL; 789 t->scto = NULL; 436 790 t->vtinfo = NULL; 437 791 //printf("-Type::makeConst() %p, %s\n", t, toChars()); 438 792 return t; … … 452 806 t->rto = NULL; 453 807 t->cto = NULL; 454 808 t->ito = NULL; 809 t->sto = NULL; 810 t->scto = NULL; 455 811 t->vtinfo = NULL; 456 812 return t; 457 813 } 458 814 815 Type *Type::makeShared() 816 { 817 if (sto) 818 return sto; 819 unsigned sz = sizeTy[ty]; 820 Type *t = (Type *)mem.malloc(sz); 821 memcpy(t, this, sz); 822 t->mod = MODshared; 823 t->deco = NULL; 824 t->arrayof = NULL; 825 t->pto = NULL; 826 t->rto = NULL; 827 t->cto = NULL; 828 t->ito = NULL; 829 t->sto = NULL; 830 t->scto = NULL; 831 t->vtinfo = NULL; 832 return t; 833 } 834 835 Type *Type::makeSharedConst() 836 { 837 if (scto) 838 return scto; 839 unsigned sz = sizeTy[ty]; 840 Type *t = (Type *)mem.malloc(sz); 841 memcpy(t, this, sz); 842 t->mod = MODshared | MODconst; 843 t->deco = NULL; 844 t->arrayof = NULL; 845 t->pto = NULL; 846 t->rto = NULL; 847 t->cto = NULL; 848 t->ito = NULL; 849 t->sto = NULL; 850 t->scto = NULL; 851 t->vtinfo = NULL; 852 return t; 853 } 854 855 /************************************ 856 * Apply MODxxxx bits to existing type. 857 */ 858 859 Type *Type::castMod(unsigned mod) 860 { Type *t; 861 862 switch (mod) 863 { 864 case 0: 865 t = mutableOf(); 866 break; 867 868 case MODconst: 869 t = constOf(); 870 break; 871 872 case MODinvariant: 873 t = invariantOf(); 874 break; 875 876 case MODshared: 877 t = sharedOf(); 878 break; 879 880 case MODshared | MODconst: 881 t = sharedConstOf(); 882 break; 883 884 default: 885 assert(0); 886 } 887 return t; 888 } 889 890 /************************************ 891 * Add MODxxxx bits to existing type. 892 * We're adding, not replacing, so adding const to 893 * a shared type => "shared const" 894 */ 895 896 Type *Type::addMod(unsigned mod) 897 { Type *t = this; 898 899 /* Add anything to immutable, and it remains immutable 900 */ 901 if (!t->isInvariant()) 902 { 903 switch (mod) 904 { 905 case 0: 906 break; 907 908 case MODconst: 909 if (isShared()) 910 t = sharedConstOf(); 911 else 912 t = constOf(); 913 break; 914 915 case MODinvariant: 916 t = invariantOf(); 917 break; 918 919 case MODshared: 920 if (isConst()) 921 t = sharedConstOf(); 922 else 923 t = sharedOf(); 924 break; 925 926 case MODshared | MODconst: 927 t = sharedConstOf(); 928 break; 929 930 default: 931 assert(0); 932 } 933 } 934 return t; 935 } 936 937 /************************************ 938 * Add storage class modifiers to type. 939 */ 940 941 Type *Type::addStorageClass(unsigned stc) 942 { 943 /* Just translate to MOD bits and let addMod() do the work 944 */ 945 unsigned mod = 0; 946 947 if (stc & STCinvariant) 948 mod = MODinvariant; 949 else 950 { if (stc & (STCconst | STCin)) 951 mod = MODconst; 952 if (stc & STCshared) 953 mod |= MODshared; 954 } 955 return addMod(mod); 956 } 957 459 958 /************************** 460 959 * Return type with the top level of it being mutable. 461 960 */ … … 585 1084 p = "const("; 586 1085 goto L1; 587 1086 case MODinvariant: 588 p = "i nvariant(";1087 p = "immutable("; 589 1088 L1: buf->writestring(p); 590 1089 toCBuffer2(buf, hgs, this->mod); 591 1090 buf->writeByte(')'); … … 896 1395 va_end( ap ); 897 1396 } 898 1397 1398 void Type::warning(Loc loc, const char *format, ...) 1399 { 1400 if (global.params.warnings && !global.gag) 1401 { 1402 fprintf(stdmsg, "warning - "); 1403 va_list ap; 1404 va_start(ap, format); 1405 ::verror(loc, format, ap); 1406 va_end( ap ); 1407 } 1408 } 1409 899 1410 Identifier *Type::getTypeInfoIdent(int internal) 900 1411 { 901 1412 // _init_10TypeInfo_%s … … 1016 1527 { 1017 1528 //printf("TypeNext::makeConst() %p, %s\n", this, toChars()); 1018 1529 if (cto) 1530 { assert(cto->mod == MODconst); 1019 1531 return cto; 1532 } 1020 1533 TypeNext *t = (TypeNext *)Type::makeConst(); 1021 1534 if (ty != Tfunction && ty != Tdelegate && next->deco && 1022 !next->isInvariant()) 1023 t->next = next->constOf(); 1535 !next->isInvariant() && !next->isConst()) 1536 { if (next->isShared()) 1537 t->next = next->sharedConstOf(); 1538 else 1539 t->next = next->constOf(); 1540 } 1024 1541 //printf("TypeNext::makeConst() returns %p, %s\n", t, t->toChars()); 1025 1542 return t; 1026 1543 } … … 1033 1550 return ito; 1034 1551 } 1035 1552 TypeNext *t = (TypeNext *)Type::makeInvariant(); 1036 if (ty != Tfunction && ty != Tdelegate && next->deco) 1553 if (ty != Tfunction && ty != Tdelegate && next->deco && 1554 !next->isInvariant()) 1037 1555 { t->next = next->invariantOf(); 1038 1556 } 1039 1557 return t; 1040 1558 } 1041 1559 1560 Type *TypeNext::makeShared() 1561 { 1562 //printf("TypeNext::makeShared() %s\n", toChars()); 1563 if (sto) 1564 { assert(sto->mod == MODshared); 1565 return sto; 1566 } 1567 TypeNext *t = (TypeNext *)Type::makeShared(); 1568 if (ty != Tfunction && ty != Tdelegate && next->deco && 1569 !next->isInvariant() && !next->isShared()) 1570 { 1571 if (next->isConst()) 1572 t->next = next->sharedConstOf(); 1573 else 1574 t->next = next->sharedOf(); 1575 } 1576 //printf("TypeNext::makeShared() returns %p, %s\n", t, t->toChars()); 1577 return t; 1578 } 1579 1580 Type *TypeNext::makeSharedConst() 1581 { 1582 //printf("TypeNext::makeSharedConst() %s\n", toChars()); 1583 if (scto) 1584 { assert(scto->mod == (MODshared | MODconst)); 1585 return scto; 1586 } 1587 TypeNext *t = (TypeNext *)Type::makeSharedConst(); 1588 if (ty != Tfunction && ty != Tdelegate && next->deco && 1589 !next->isInvariant() && !next->isSharedConst()) 1590 { 1591 t->next = next->sharedConstOf(); 1592 } 1593 //printf("TypeNext::makeSharedConst() returns %p, %s\n", t, t->toChars()); 1594 return t; 1595 } 1596 1042 1597 MATCH TypeNext::constConv(Type *to) 1043 1598 { MATCH m = Type::constConv(to); 1044 1599 … … 1049 1604 } 1050 1605 1051 1606 1607 void TypeNext::transitive() 1608 { 1609 /* Invoke transitivity of type attributes 1610 */ 1611 next = next->addMod(mod); 1612 } 1613 1052 1614 /* ============================= TypeBasic =========================== */ 1053 1615 1054 1616 TypeBasic::TypeBasic(TY ty) … … 1235 1797 if (ty == Tvoid) 1236 1798 return 1; 1237 1799 return getABITypeAlign(DtoType(this)); 1800 #if TARGET_OSX 1801 sz = 16; 1802 #else 1803 #endif 1238 1804 } 1239 1805 1240 1806 … … 1869 2435 if (ident == Id::idup) 1870 2436 { Type *einv = next->invariantOf(); 1871 2437 if (next->implicitConvTo(einv) < MATCHconst) 1872 error(e->loc, "cannot implicitly convert element type %s to i nvariant", next->toChars());2438 error(e->loc, "cannot implicitly convert element type %s to immutable", next->toChars()); 1873 2439 e->type = einv->arrayOf(); 1874 2440 } 1875 2441 else … … 2095 2661 } 2096 2662 2097 2663 next = next->semantic(loc,sc); 2098 if (mod == MODconst && !next->isInvariant()) 2099 next = next->constOf(); 2100 else if (mod == MODinvariant) 2101 next = next->invariantOf(); 2664 transitive(); 2102 2665 2103 2666 Type *tbn = next->toBasetype(); 2104 2667 … … 2164 2727 Argument *arg = (Argument *)tt->arguments->data[(size_t)d]; 2165 2728 return arg->type; 2166 2729 } 2730 case Tstruct: 2731 { TypeStruct *ts = (TypeStruct *)tbn; 2732 if (ts->sym->isnested) 2733 error(loc, "cannot have array of inner structs %s", ts->toChars()); 2734 break; 2735 } 2167 2736 case Tfunction: 2168 2737 case Tnone: 2169 2738 error(loc, "can't have array of %s", tbn->toChars()); … … 2375 2944 error(loc, "can't have array of %s", tbn->toChars()); 2376 2945 tn = next = tint32; 2377 2946 break; 2947 case Tstruct: 2948 { TypeStruct *ts = (TypeStruct *)tbn; 2949 if (ts->sym->isnested) 2950 error(loc, "cannot have array of inner structs %s", ts->toChars()); 2951 break; 2952 } 2378 2953 } 2379 2954 if (tn->isauto()) 2380 2955 error(loc, "cannot have array of auto %s", tn->toChars()); 2381 2956 2382 if (mod == MODconst && !tn->isInvariant())2383 tn = tn->constOf();2384 else if (mod == MODinvariant)2385 tn = tn->invariantOf();2386 2387 2957 next = tn; 2958 transitive(); 2388 2959 return merge(); 2389 2960 } 2390 2961 … … 2585 3156 if (index->nextOf() && !index->nextOf()->isInvariant()) 2586 3157 { 2587 3158 index = index->constOf()->mutableOf(); 3159 #if 0 3160 printf("index is %p %s\n", index, index->toChars()); 3161 index->check(); 3162 printf("index->mod = x%x\n", index->mod); 3163 printf("index->ito = x%x\n", index->ito); 3164 if (index->ito) { 3165 printf("index->ito->mod = x%x\n", index->ito->mod); 3166 printf("index->ito->ito = x%x\n", index->ito->ito); 3167 } 3168 #endif 2588 3169 } 2589 3170 2590 3171 switch (index->toBasetype()->ty) … … 2597 3178 break; 2598 3179 } 2599 3180 next = next->semantic(loc,sc); 2600 if (mod == MODconst && !next->isInvariant()) 2601 next = next->constOf(); 2602 else if (mod == MODinvariant) 2603 next = next->invariantOf(); 3181 transitive(); 2604 3182 2605 3183 switch (next->toBasetype()->ty) 2606 3184 { … … 2865 3443 if (n != next) 2866 3444 deco = NULL; 2867 3445 next = n; 2868 if (mod == MODconst && !next->isInvariant()) 2869 next = next->constOf(); 2870
