Ticket #229: d2.diff
File d2.diff, 181.0 kB (added by Matt, 15 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 else if (mod == MODinvariant) 2871 next = next->invariantOf(); 3446 transitive(); 2872 3447 return merge(); 2873 3448 } 2874 3449 … … 2981 3556 if (n != next) 2982 3557 deco = NULL; 2983 3558 next = n; 2984 if (mod == MODconst && !next->isInvariant()) 2985 next = next->constOf(); 2986 else if (mod == MODinvariant) 2987 next = next->invariantOf(); 3559 transitive(); 2988 3560 return merge(); 2989 3561 } 2990 3562 … … 3046 3618 this->ispure = false; 3047 3619 this->isref = false; 3048 3620 3049 // LDC3050 this->fty = NULL;3051 3621 } 3052 3622 3053 3623 Type *TypeFunction::syntaxCopy() … … 3229 3799 3230 3800 void TypeFunction::toCBuffer(OutBuffer *buf, Identifier *ident, HdrGenState *hgs) 3231 3801 { 3232 //printf("TypeFunction::toCBuffer() this = %p %s\n", this, toChars());3802 //printf("TypeFunction::toCBuffer() this = %p\n", this); 3233 3803 const char *p = NULL; 3234 3804 3235 3805 if (inuse) … … 3243 3813 if (mod & MODconst) 3244 3814 buf->writestring("const "); 3245 3815 if (mod & MODinvariant) 3246 buf->writestring("i nvariant");3816 buf->writestring("immutable "); 3247 3817 if (mod & MODshared) 3248 3818 buf->writestring("shared "); 3249 3819 … … 3286 3856 3287 3857 void TypeFunction::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) 3288 3858 { 3289 //printf("TypeFunction::toCBuffer2() this = %p %s\n", this, toChars());3859 //printf("TypeFunction::toCBuffer2() this = %p, ref = %d\n", this, isref); 3290 3860 const char *p = NULL; 3291 3861 3292 3862 if (inuse) … … 3348 3918 return this; 3349 3919 } 3350 3920 //printf("TypeFunction::semantic() this = %p\n", this); 3921 //printf("TypeFunction::semantic() %s, sc->stc = %x\n", toChars(), sc->stc); 3351 3922 3352 3923 TypeFunction *tf = (TypeFunction *)mem.malloc(sizeof(TypeFunction)); 3353 3924 memcpy(tf, this, sizeof(TypeFunction)); … … 3388 3959 tf->next = Type::terror; 3389 3960 } 3390 3961 if (tf->next->isauto() && !(sc->flags & SCOPEctor)) 3391 error(loc, "functions cannot return auto%s", tf->next->toChars());3962 error(loc, "functions cannot return scope %s", tf->next->toChars()); 3392 3963 3393 3964 if (tf->parameters) 3394 3965 { size_t dim = Argument::dim(tf->parameters); … … 3400 3971 arg->type = arg->type->semantic(loc,sc); 3401 3972 if (tf->inuse == 1) tf->inuse--; 3402 3973 3403 if (arg->storageClass & (STCconst | STCin)) 3404 { 3405 if (!arg->type->isInvariant()) 3406 arg->type = arg->type->constOf(); 3407 } 3408 else if (arg->storageClass & STCinvariant) 3409 arg->type = arg->type->invariantOf(); 3974 arg->type = arg->type->addStorageClass(arg->storageClass); 3410 3975 3411 3976 if (arg->storageClass & (STCauto | STCalias | STCstatic)) 3412 3977 { … … 4050 4615 //printf("TypeIdentifier::resolve(sc = %p, idents = '%s')\n", sc, toChars()); 4051 4616 s = sc->search(loc, ident, &scopesym); 4052 4617 resolveHelper(loc, sc, s, scopesym, pe, pt, ps); 4053 if (*pt && mod) 4054 { 4055 if (mod & MODconst) 4056 *pt = (*pt)->constOf(); 4057 else if (mod & MODinvariant) 4058 *pt = (*pt)->invariantOf(); 4059 } 4618 if (*pt) 4619 (*pt) = (*pt)->addMod(mod); 4060 4620 } 4061 4621 4062 4622 /***************************************** … … 4106 4666 if (tt->sym->sem == 1) 4107 4667 error(loc, "circular reference of typedef %s", tt->toChars()); 4108 4668 } 4109 if (isConst()) 4110 t = t->constOf(); 4111 else if (isInvariant()) 4112 t = t->invariantOf(); 4669 t = t->addMod(mod); 4113 4670 } 4114 4671 else 4115 4672 { … … 4200 4757 if (s) 4201 4758 s->semantic(sc); 4202 4759 resolveHelper(loc, sc, s, NULL, pe, pt, ps); 4203 if (*pt && mod) 4204 { 4205 if (mod & MODconst) 4206 *pt = (*pt)->constOf(); 4207 else if (mod & MODinvariant) 4208 *pt = (*pt)->invariantOf(); 4209 } 4760 if (*pt) 4761 *pt = (*pt)->addMod(mod); 4210 4762 //printf("pt = '%s'\n", (*pt)->toChars()); 4211 4763 } 4212 4764 … … 4246 4798 return t; 4247 4799 } 4248 4800 4801 Dsymbol *TypeInstance::toDsymbol(Scope *sc) 4802 { 4803 Type *t; 4804 Expression *e; 4805 Dsymbol *s; 4806 4807 //printf("TypeInstance::semantic(%s)\n", toChars()); 4808 4809 if (sc->parameterSpecialization) 4810 { 4811 unsigned errors = global.errors; 4812 global.gag++; 4813 4814 resolve(loc, sc, &e, &t, &s); 4815 4816 global.gag--; 4817 if (errors != global.errors) 4818 { if (global.gag == 0) 4819 global.errors = errors; 4820 return NULL; 4821 } 4822 } 4823 else 4824 resolve(loc, sc, &e, &t, &s); 4825 4826 return s; 4827 } 4828 4249 4829 4250 4830 /***************************** TypeTypeof *****************************/ 4251 4831 … … 4257 4837 4258 4838 Type *TypeTypeof::syntaxCopy() 4259 4839 { 4840 //printf("TypeTypeof::syntaxCopy() %s\n", toChars()); 4260 4841 TypeTypeof *t; 4261 4842 4262 4843 t = new TypeTypeof(loc, exp->syntaxCopy()); … … 4434 5015 goto Lerr; 4435 5016 } 4436 5017 t = sc->func->type->nextOf(); 4437 4438 if (mod & MODinvariant) 4439 t = t->invariantOf(); 4440 else if (mod & MODconst) 4441 t = t->constOf(); 5018 t = t->addMod(mod); 4442 5019 4443 5020 if (idents.dim) 4444 5021 { … … 4572 5149 Dsymbol *s = sym->search(e->loc, ident, 0); 4573 5150 if (!s) 4574 5151 { 4575 return getProperty(e->loc, ident); 5152 if (ident == Id::max || 5153 ident == Id::min || 5154 ident == Id::init || 5155 ident == Id::stringof || 5156 !sym->memtype 5157 ) 5158 { 5159 return getProperty(e->loc, ident); 5160 } 5161 return sym->memtype->dotExp(sc, e, ident); 4576 5162 } 4577 5163 EnumMember *m = s->isEnumMember(); 4578 5164 Expression *em = m->value->copy(); … … 4839 5425 sym->inuse = 1; 4840 5426 Type *t = sym->basetype->toBasetype(); 4841 5427 sym->inuse = 0; 4842 if (mod == MODconst && !t->isInvariant()) 4843 t = t->constOf(); 4844 else if (mod == MODinvariant) 4845 t = t->invariantOf(); 5428 t = t->addMod(mod); 4846 5429 return t; 4847 5430 } 4848 5431 … … 5008 5591 Expression *TypeStruct::dotExp(Scope *sc, Expression *e, Identifier *ident) 5009 5592 { unsigned offset; 5010 5593 5011 Expression *b;5012 5594 VarDeclaration *v; 5013 5595 Dsymbol *s; 5014 5596 DotVarExp *de; … … 5143 5725 return de; 5144 5726 } 5145 5727 5728 Import *timp = s->isImport(); 5729 if (timp) 5730 { 5731 e = new DsymbolExp(e->loc, s, 0); 5732 e = e->semantic(sc); 5733 return e; 5734 } 5735 5736 OverloadSet *o = s->isOverloadSet(); 5737 if (o) 5738 { /* We really should allow this, triggered by: 5739 * template c() 5740 * { 5741 * void a(); 5742 * void b () { this.a(); } 5743 * } 5744 * struct S 5745 * { 5746 * mixin c; 5747 * mixin c; 5748 * } 5749 * alias S e; 5750 */ 5751 error(e->loc, "overload set for %s.%s not allowed in struct declaration", e->toChars(), ident->toChars()); 5752 return new IntegerExp(0); 5753 } 5754 5146 5755 d = s->isDeclaration(); 5147 5756 #ifdef DEBUG 5148 5757 if (!d) … … 5189 5798 accessCheck(e->loc, sc, e, d); 5190 5799 5191 5800 // LDC we don't want dot exprs turned into pointer arithmetic. it complicates things for no apparent gain 5192 #if ndef IN_LLVM5193 b = new AddrExp(e->loc, e);5801 #if 0 5802 Expression *b = new AddrExp(e->loc, e); 5194 5803 b->type = e->type->pointerTo(); 5195 5804 b = new AddExp(e->loc, b, new IntegerExp(e->loc, v->offset, Type::tint32)); 5196 5805 b->type = v->type->pointerTo(); 5197 5806 b = new PtrExp(e->loc, b); 5198 b->type = v->type; 5199 if (e->type->isConst()) 5200 b->type = b->type->constOf(); 5201 else if (e->type->isInvariant()) 5202 b->type = b->type->invariantOf(); 5807 b->type = v->type->addMod(e->type->mod); 5203 5808 return b; 5204 5809 #endif 5205 5810 } … … 5257 5862 for (size_t i = 0; i < s->fields.dim; i++) 5258 5863 { 5259 5864 Dsymbol *sm = (Dsymbol *)s->fields.data[i]; 5260 if (sm->hasPointers()) 5865 Declaration *d = sm->isDeclaration(); 5866 if (d->storage_class & STCref || d->hasPointers()) 5261 5867 return TRUE; 5262 5868 } 5263 5869 return FALSE; … … 5283 5889 assert(v && v->storage_class & STCfield); 5284 5890 5285 5891 // 'from' type 5286 Type *tvf = v->type; 5287 if (mod == MODconst) 5288 tvf = tvf->constOf(); 5289 else if (mod == MODinvariant) 5290 tvf = tvf->invariantOf(); 5892 Type *tvf = v->type->addMod(mod); 5291 5893 5292 5894 // 'to' type 5293 Type *tv = v->type; 5294 if (to->mod == 0) 5295 tv = tv->mutableOf(); 5296 else 5297 { assert(to->mod == MODinvariant); 5298 tv = tv->invariantOf(); 5299 } 5895 Type *tv = v->type->castMod(to->mod); 5300 5896 5301 5897 //printf("\t%s => %s, match = %d\n", v->type->toChars(), tv->toChars(), tvf->implicitConvTo(tv)); 5302 5898 if (tvf->implicitConvTo(tv) < MATCHconst) … … 5641 6237 return de; 5642 6238 } 5643 6239 6240 OverloadSet *o = s->isOverloadSet(); 6241 if (o) 6242 { /* We really should allow this 6243 */ 6244 error(e->loc, "overload set for %s.%s not allowed in struct declaration", e->toChars(), ident->toChars()); 6245 return new IntegerExp(0); 6246 } 6247 5644 6248 Declaration *d = s->isDeclaration(); 5645 6249 if (!d) 5646 6250 { … … 5990 6594 { 5991 6595 //printf("TypeSlice::semantic() %s\n", toChars()); 5992 6596 next = next->semantic(loc, sc); 5993 if (mod == MODconst && !next->isInvariant()) 5994 next = next->constOf(); 5995 else if (mod == MODinvariant) 5996 next = next->invariantOf(); 6597 transitive(); 5997 6598 //printf("next: %s\n", next->toChars()); 5998 6599 5999 6600 Type *tbn = next->toBasetype(); … … 6204 6805 if (arg->storageClass & STCconst) 6205 6806 buf->writestring("const "); 6206 6807 if (arg->storageClass & STCinvariant) 6207 buf->writestring("i nvariant");6808 buf->writestring("immutable "); 6208 6809 if (arg->storageClass & STCshared) 6209 6810 buf->writestring("shared "); 6210 6811 -
a/dmd2/mtype.h
old new 23 23 24 24 // llvm 25 25 #include "../ir/irtype.h" 26 #include "../ir/irfuncty.h" 26 27 namespace llvm { class Type; } 27 struct IrFuncTy;28 28 29 29 struct Scope; 30 30 struct Identifier; … … 116 116 { 117 117 TY ty; 118 118 unsigned char mod; // modifiers MODxxxx 119 /* pick this order of numbers so switch statements work better 120 */ 119 121 #define MODconst 1 // type is const 120 #define MODinvariant 2// type is invariant121 #define MODshared 4// type is shared122 #define MODinvariant 4 // type is invariant 123 #define MODshared 2 // type is shared 122 124 char *deco; 125 126 /* Note that there is no "shared immutable", because that is just immutable 127 */ 128 123 129 Type *cto; // MODconst ? mutable version of this type : const version 124 130 Type *ito; // MODinvariant ? mutable version of this type : invariant version 131 Type *sto; // MODshared ? mutable version of this type : shared mutable version 132 Type *scto; // MODshared|MODconst ? mutable version of this type : shared const version 133 125 134 Type *pto; // merged pointer to this type 126 135 Type *rto; // reference to this type 127 136 Type *arrayof; // array of this type … … 183 192 static ClassDeclaration *typeinfotypelist; 184 193 static ClassDeclaration *typeinfoconst; 185 194 static ClassDeclaration *typeinfoinvariant; 195 static ClassDeclaration *typeinfoshared; 186 196 187 197 static Type *basic[TMAX]; 188 198 static unsigned char mangleChar[TMAX]; … … 215 225 virtual void toCBuffer(OutBuffer *buf, Identifier *ident, HdrGenState *hgs); 216 226 virtual void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod); 217 227 void toCBuffer3(OutBuffer *buf, HdrGenState *hgs, int mod); 218 #if TARGET_LINUX 228 #if TARGET_LINUX || TARGET_OSX 219 229 virtual void toCppMangle(OutBuffer *buf, CppMangleState *cms); 220 230 #endif 221 231 virtual int isintegral(); … … 234 244 int isInvariant() { return mod & MODinvariant; } 235 245 int isMutable() { return !(mod & (MODconst | MODinvariant)); } 236 246 int isShared() { return mod & MODshared; } 247 int isSharedConst() { return mod == (MODshared | MODconst); } 237 248 Type *constOf(); 238 249 Type *invariantOf(); 239 250 Type *mutableOf(); 251 Type *sharedOf(); 252 Type *sharedConstOf(); 253 void fixTo(Type *t); 254 void check(); 255 Type *castMod(unsigned mod); 256 Type *addMod(unsigned mod); 257 Type *addStorageClass(unsigned stc); 240 258 Type *pointerTo(); 241 259 Type *referenceTo(); 242 260 Type *arrayOf(); 243 261 virtual Type *makeConst(); 244 262 virtual Type *makeInvariant(); 263 virtual Type *makeShared(); 264 virtual Type *makeSharedConst(); 245 265 virtual Dsymbol *toDsymbol(Scope *sc); 246 266 virtual Type *toBasetype(); 247 267 virtual Type *toHeadMutable(); … … 268 288 virtual Type *nextOf(); 269 289 270 290 static void error(Loc loc, const char *format, ...); 291 static void warning(Loc loc, const char *format, ...); 271 292 272 293 // For backend 273 294 virtual unsigned totym(); … … 293 314 Type *nextOf(); 294 315 Type *makeConst(); 295 316 Type *makeInvariant(); 317 Type *makeShared(); 318 Type *makeSharedConst(); 296 319 MATCH constConv(Type *to); 320 void transitive(); 297 321 }; 298 322 299 323 struct TypeBasic : Type … … 309 333 Expression *dotExp(Scope *sc, Expression *e, Identifier *ident); 310 334 char *toChars(); 311 335 void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod); 312 #if TARGET_LINUX 336 #if TARGET_LINUX || TARGET_OSX 313 337 void toCppMangle(OutBuffer *buf, CppMangleState *cms); 314 338 #endif 315 339 int isintegral(); … … 361 385 TypeInfoDeclaration *getTypeInfoDeclaration(); 362 386 Expression *toExpression(); 363 387 int hasPointers(); 364 #if TARGET_LINUX 388 #if TARGET_LINUX || TARGET_OSX 365 389 void toCppMangle(OutBuffer *buf, CppMangleState *cms); 366 390 #endif 367 391 … … 386 410 MATCH implicitConvTo(Type *to); 387 411 Expression *defaultInit(Loc loc); 388 412 int builtinTypeInfo(); 413 MATCH deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes); 389 414 TypeInfoDeclaration *getTypeInfoDeclaration(); 390 415 int hasPointers(); 391 #if TARGET_LINUX 416 #if TARGET_LINUX || TARGET_OSX 392 417 void toCppMangle(OutBuffer *buf, CppMangleState *cms); 393 418 #endif 394 419 … … 415 440 int hasPointers(); 416 441 MATCH implicitConvTo(Type *to); 417 442 MATCH constConv(Type *to); 418 #if TARGET_LINUX 443 #if TARGET_LINUX || TARGET_OSX 419 444 void toCppMangle(OutBuffer *buf, CppMangleState *cms); 420 445 #endif 421 446 … … 440 465 int isZeroInit(); 441 466 TypeInfoDeclaration *getTypeInfoDeclaration(); 442 467 int hasPointers(); 443 #if TARGET_LINUX 468 #if TARGET_LINUX || TARGET_OSX 444 469 void toCppMangle(OutBuffer *buf, CppMangleState *cms); 445 470 #endif 446 471 … … 457 482 Expression *dotExp(Scope *sc, Expression *e, Identifier *ident); 458 483 Expression *defaultInit(Loc loc); 459 484 int isZeroInit(); 460 #if TARGET_LINUX 485 #if TARGET_LINUX || TARGET_OSX 461 486 void toCppMangle(OutBuffer *buf, CppMangleState *cms); 462 487 #endif 463 488 }; … … 491 516 MATCH deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes); 492 517 TypeInfoDeclaration *getTypeInfoDeclaration(); 493 518 Type *reliesOnTident(); 494 #if TARGET_LINUX 519 #if TARGET_LINUX || TARGET_OSX 495 520 void toCppMangle(OutBuffer *buf, CppMangleState *cms); 496 521 #endif 497 522 bool parameterEscapes(Argument *p); … … 503 528 unsigned totym(); 504 529 505 530 // LDC 506 IrFuncTy *fty;531 IrFuncTy fty; 507 532 }; 508 533 509 534 struct TypeDelegate : TypeNext … … 522 547 TypeInfoDeclaration *getTypeInfoDeclaration(); 523 548 Expression *dotExp(Scope *sc, Expression *e, Identifier *ident); 524 549 int hasPointers(); 525 #if TARGET_LINUX 550 #if TARGET_LINUX || TARGET_OSX 526 551 void toCppMangle(OutBuffer *buf, CppMangleState *cms); 527 552 #endif 528 553 … … 573 598 void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod); 574 599 void resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps); 575 600 Type *semantic(Loc loc, Scope *sc); 601 Dsymbol *toDsymbol(Scope *sc); 576 602 MATCH deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes); 577 603 }; 578 604 … … 623 649 MATCH implicitConvTo(Type *to); 624 650 MATCH constConv(Type *to); 625 651 Type *toHeadMutable(); 626 #if TARGET_LINUX 652 #if TARGET_LINUX || TARGET_OSX 627 653 void toCppMangle(OutBuffer *buf, CppMangleState *cms); 628 654 #endif 629 655 … … 662 688 MATCH deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes); 663 689 TypeInfoDeclaration *getTypeInfoDeclaration(); 664 690 int hasPointers(); 665 #if TARGET_LINUX 691 #if TARGET_LINUX || TARGET_OSX 666 692 void toCppMangle(OutBuffer *buf, CppMangleState *cms); 667 693 #endif 668 694 … … 704 730 TypeInfoDeclaration *getTypeInfoDeclaration(); 705 731 int hasPointers(); 706 732 Type *toHeadMutable(); 707 #if TARGET_LINUX 733 #if TARGET_LINUX || TARGET_OSX 708 734 void toCppMangle(OutBuffer *buf, CppMangleState *cms); 709 735 #endif 710 736 … … 737 763 int hasPointers(); 738 764 Type *toHeadMutable(); 739 765 MATCH constConv(Type *to); 740 #if TARGET_LINUX 766 #if TARGET_LINUX || TARGET_OSX 741 767 void toCppMangle(OutBuffer *buf, CppMangleState *cms); 742 768 #endif 743 769 … … 806 832 extern int Tsize_t; 807 833 extern int Tptrdiff_t; 808 834 835 int arrayTypeCompatible(Loc loc, Type *t1, Type *t2); 836 809 837 #endif /* DMD_MTYPE_H */ -
a/dmd2/opover.c
old new 21 21 #define integer_t dmd_integer_t 22 22 #endif 23 23 24 #if IN_GCC || IN_LLVM25 24 #include "mem.h" 26 #elif POSIX27 #include "../root/mem.h"28 #elif _WIN3229 #include "..\root\mem.h"30 #endif31 25 32 26 //#include "port.h" 33 27 #include "mtype.h" -
a/dmd2/parse.c
old new 77 77 { 78 78 nextToken(); 79 79 if (token.value != TOKidentifier) 80 { error("module (s afe) identifier expected");80 { error("module (system) identifier expected"); 81 81 goto Lerr; 82 82 } 83 83 Identifier *id = token.ident; … … 307 307 stc = STCinvariant; 308 308 goto Lstc; 309 309 310 case TOKshared: 311 if (peek(&token)->value == TOKlparen) 312 goto Ldeclaration; 313 stc = STCshared; 314 goto Lstc; 315 310 316 case TOKfinal: stc = STCfinal; goto Lstc; 311 317 case TOKauto: stc = STCauto; goto Lstc; 312 318 case TOKscope: stc = STCscope; goto Lstc; … … 337 343 case TOKconst: 338 344 case TOKinvariant: 339 345 case TOKimmutable: 346 case TOKshared: 340 347 // If followed by a (, it is not a storage class 341 348 if (peek(&token)->value == TOKlparen) 342 349 break; 343 350 if (token.value == TOKconst) 344 351 stc = STCconst; 352 else if (token.value == TOKshared) 353 stc = STCshared; 345 354 else 346 355 stc = STCinvariant; 347 356 goto Lstc; … … 378 387 if (token.value == TOKidentifier && 379 388 (tk = peek(&token))->value == TOKlparen && 380 389 skipParens(tk, &tk) && 381 peek(tk)->value == TOKlparen) 390 (peek(tk)->value == TOKlparen || 391 peek(tk)->value == TOKlcurly) 392 ) 382 393 { 383 394 a = parseDeclarations(storageClass); 384 395 decldefs->append(a); … … 1037 1048 stc = STCinvariant; 1038 1049 goto L2; 1039 1050 1051 case TOKshared: 1052 if (peek(&token)->value == TOKlparen) 1053 goto Ldefault; 1054 stc = STCshared; 1055 goto L2; 1056 1040 1057 case TOKin: stc = STCin; goto L2; 1041 1058 case TOKout: stc = STCout; goto L2; 1042 1059 case TOKinout: … … 1093 1110 if ((storageClass & (STCconst | STCout)) == (STCconst | STCout)) 1094 1111 error("out cannot be const"); 1095 1112 if ((storageClass & (STCinvariant | STCout)) == (STCinvariant | STCout)) 1096 error("out cannot be i nvariant");1113 error("out cannot be immutable"); 1097 1114 if ((storageClass & STCscope) && 1098 1115 (storageClass & (STCref | STCout))) 1099 1116 error("scope cannot be ref or out"); … … 1736 1753 1737 1754 Objects *Parser::parseTemplateArgumentList2() 1738 1755 { 1756 //printf("Parser::parseTemplateArgumentList2()\n"); 1739 1757 Objects *tiargs = new Objects(); 1740 1758 enum TOK endtok = TOKrparen; 1741 1759 nextToken(); … … 1918 1936 Type *Parser::parseType(Identifier **pident, TemplateParameters **tpl) 1919 1937 { Type *t; 1920 1938 1921 if (token.value == TOKconst && peek(&token)->value != TOKlparen) 1939 /* Take care of the storage class prefixes that 1940 * serve as type attributes: 1941 * const shared, shared const, const, invariant, shared 1942 */ 1943 if (token.value == TOKconst && peekNext() == TOKshared && peekNext2() != TOKlparen || 1944 token.value == TOKshared && peekNext() == TOKconst && peekNext2() != TOKlparen) 1945 { 1946 nextToken(); 1947 nextToken(); 1948 /* shared const type 1949 */ 1950 t = parseType(pident, tpl); 1951 t = t->makeSharedConst(); 1952 return t; 1953 } 1954 else if (token.value == TOKconst && peekNext() != TOKlparen) 1922 1955 { 1923 1956 nextToken(); 1924 1957 /* const type … … 1928 1961 return t; 1929 1962 } 1930 1963 else if ((token.value == TOKinvariant || token.value == TOKimmutable) && 1931 peek (&token)->value!= TOKlparen)1964 peekNext() != TOKlparen) 1932 1965 { 1933 1966 nextToken(); 1934 1967 /* invariant type … … 1937 1970 t = t->makeInvariant(); 1938 1971 return t; 1939 1972 } 1973 else if (token.value == TOKshared && peekNext() != TOKlparen) 1974 { 1975 nextToken(); 1976 /* shared type 1977 */ 1978 t = parseType(pident, tpl); 1979 t = t->makeShared(); 1980 return t; 1981 } 1940 1982 else 1941 1983 t = parseBasicType(); 1942 1984 t = parseDeclarator(t, pident, tpl); … … 2016 2058 check(TOKlparen); 2017 2059 t = parseType(); 2018 2060 check(TOKrparen); 2019 t = t->makeConst(); 2061 if (t->isShared()) 2062 t = t->makeSharedConst(); 2063 else 2064 t = t->makeConst(); 2020 2065 break; 2021 2066 2022 2067 case TOKinvariant: … … 2029 2074 t = t->makeInvariant(); 2030 2075 break; 2031 2076 2077 case TOKshared: 2078 // shared(type) 2079 nextToken(); 2080 check(TOKlparen); 2081 t = parseType(); 2082 check(TOKrparen); 2083 if (t->isConst()) 2084 t = t->makeSharedConst(); 2085 else 2086 t = t->makeShared(); 2087 break; 2088 2032 2089 default: 2033 2090 error("basic type expected, not %s", token.toChars()); 2034 2091 t = Type::tint32; … … 2247 2304 switch (token.value) 2248 2305 { 2249 2306 case TOKconst: 2250 tf = tf->makeConst(); 2307 if (tf->isShared()) 2308 tf = tf->makeSharedConst(); 2309 else 2310 tf = tf->makeConst(); 2251 2311 nextToken(); 2252 2312 continue; 2253 2313 … … 2257 2317 nextToken(); 2258 2318 continue; 2259 2319 2320 case TOKshared: 2321 if (tf->isConst()) 2322 tf = tf->makeSharedConst(); 2323 else 2324 tf = tf->makeShared(); 2325 nextToken(); 2326 continue; 2327 2260 2328 case TOKnothrow: 2261 2329 ((TypeFunction *)tf)->isnothrow = 1; 2262 2330 nextToken(); … … 3072 3140 case TOKfinal: 3073 3141 case TOKinvariant: 3074 3142 case TOKimmutable: 3143 case TOKshared: 3075 3144 // case TOKtypeof: 3076 3145 Ldeclaration: 3077 3146 { Array *a; … … 3843 3912 int haveId = 0; 3844 3913 3845 3914 #if DMDV2 3846 if ((t->value == TOKconst || t->value == TOKinvariant || token.value == TOKimmutable) && 3915 if ((t->value == TOKconst || 3916 t->value == TOKinvariant || 3917 t->value == TOKimmutable || 3918 t->value == TOKshared) && 3847 3919 peek(t)->value != TOKlparen) 3848 3920 { /* const type 3849 * invariant type 3921 * immutable type 3922 * shared type 3850 3923 */ 3851 3924 t = peek(t); 3852 3925 } 3853 3926 #endif 3854 3927 3855 3928 if (!isBasicType(&t)) 3929 { 3856 3930 goto Lisnot; 3931 } 3857 3932 if (!isDeclarator(&t, &haveId, endtok)) 3858 3933 goto Lisnot; 3859 3934 if ( needId == 1 || … … 3970 4045 case TOKconst: 3971 4046 case TOKinvariant: 3972 4047 case TOKimmutable: 3973 // const(type) or invariant(type) 4048 case TOKshared: 4049 // const(type) or immutable(type) or shared(type) 3974 4050 t = peek(t); 3975 4051 if (t->value != TOKlparen) 3976 4052 goto Lfalse; 3977 4053 t = peek(t); 3978 4054 if (!isDeclaration(t, 0, TOKrparen, &t)) 4055 { 3979 4056 goto Lfalse; 4057 } 3980 4058 t = peek(t); 3981 4059 break; 3982 4060 … … 4120 4198 case TOKconst: 4121 4199 case TOKinvariant: 4122 4200 case TOKimmutable: 4201 case TOKshared: 4123 4202 case TOKpure: 4124 4203 case TOKnothrow: 4125 4204 t = peek(t); … … 4182 4261 case TOKconst: 4183 4262 case TOKinvariant: 4184 4263 case TOKimmutable: 4264 case TOKshared: 4185 4265 case TOKfinal: 4186 4266 continue; 4187 4267 … … 4693 4773 token.value == TOKconst && peek(&token)->value == TOKrparen || 4694 4774 token.value == TOKinvariant && peek(&token)->value == TOKrparen || 4695 4775 token.value == TOKimmutable && peek(&token)->value == TOKrparen || 4776 token.value == TOKshared && peek(&token)->value == TOKrparen || 4696 4777 token.value == TOKfunction || 4697 4778 token.value == TOKdelegate || 4698 4779 token.value == TOKreturn)) … … 5058 5139 break; 5059 5140 5060 5141 case TOKcast: // cast(type) expression 5061 { Type *t; 5062 5063 nextToken(); 5064 check(TOKlparen); 5065 /* Look for cast(const) and cast(invariant) 5066 */ 5067 if ((token.value == TOKconst || token.value == TOKinvariant || token.value == TOKimmutable) && 5068 peek(&token)->value == TOKrparen) 5069 { enum TOK tok = token.value; 5070 nextToken(); 5142 { 5143 nextToken(); 5144 check(TOKlparen); 5145 /* Look for cast(), cast(const), cast(immutable), 5146 * cast(shared), cast(shared const) 5147 */ 5148 unsigned m; 5149 if (token.value == TOKrparen) 5150 { 5151 m = 0; 5152 goto Lmod1; 5153 } 5154 else if (token.value == TOKconst && peekNext() == TOKrparen) 5155 { 5156 m = MODconst; 5157 goto Lmod2; 5158 } 5159 else if ((token.value == TOKimmutable || token.value == TOKinvariant) && peekNext() == TOKrparen) 5160 { 5161 m = MODinvariant; 5162 goto Lmod2; 5163 } 5164 else if (token.value == TOKshared && peekNext() == TOKrparen) 5165 { 5166 m = MODshared; 5167 goto Lmod2; 5168 } 5169 else if (token.value == TOKconst && peekNext() == TOKshared && peekNext2() == TOKrparen || 5170 token.value == TOKshared && peekNext() == TOKconst && peekNext2() == TOKrparen) 5171 { 5172 m = MODshared | MODconst; 5173 nextToken(); 5174 Lmod2: 5175 nextToken(); 5176 Lmod1: 5071 5177 nextToken(); 5072 5178 e = parseUnaryExp(); 5073 e = new CastExp(loc, e, tok);5074 } 5075 else 5076 { 5077 t = parseType(); // ( type )5179 e = new CastExp(loc, e, m); 5180 } 5181 else 5182 { 5183 Type *t = parseType(); // ( type ) 5078 5184 check(TOKrparen); 5079 5185 e = parseUnaryExp(); 5080 5186 e = new CastExp(loc, e, t); -
a/dmd2/readme.txt
old new 1 1 2 2 The D Programming Language 3 3 Compiler Front End Source 4 Copyright (c) 1999-200 2, by Digital Mars5 www.digitalmars.com4 Copyright (c) 1999-2009, by Digital Mars 5 http://www.digitalmars.com 6 6 All Rights Reserved 7 7 8 8 9 9 This is the source code to the front end Digital Mars D compiler. 10 10 It covers the lexical analysis, parsing, and semantic analysis 11 11 of the D Programming Language defined in the documents at 12 www.digitalmars.com/d/ 13 14 The optimizer, code generator, and object file generator are not part 15 of this source, hence the source does not currently constitute a complete, 16 compilable program. However, many people have expressed a strong interested 17 in producing a D compiler with the GNU compiler sources. This release should 18 enable that. 12 http://www.digitalmars.com/d/ 19 13 20 14 These sources are free, they are redistributable and modifiable 21 15 under the terms of the GNU General Public License (attached as gpl.txt), 22 16 or the Artistic License (attached as artistic.txt). 23 17 18 The optimizer and code generator sources are 19 covered under a separate license, backendlicense.txt. 20 24 21 It does not apply to anything else distributed by Digital Mars, 25 22 including D compiler executables. 26 23 -
a/dmd2/root.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 // www.digitalmars.com -
a/dmd2/root.h
old new 37 37 #define TYPEDEFS 38 38 39 39 #if _MSC_VER 40 #include <float.h> // for _isnan 40 41 #include <malloc.h> // for alloca 41 42 // According to VC 8.0 docs, long double is the same as double 42 43 #define strtold strtod -
a/dmd2/scope.c
old new 257 257 sc->enclosing && 258 258 sc->enclosing->search(loc, ident, NULL)) 259 259 { 260 // WTF ?261 260 if (global.params.warnings) 262 fprintf(stdmsg, "warning - "); 263 error(s->loc, "array 'length' hides other 'length' name in outer scope"); 261 warning(s->loc, "array 'length' hides other 'length' name in outer scope"); 264 262 } 265 263 266 264 //printf("\tfound %s.%s, kind = '%s'\n", s->parent ? s->parent->toChars() : "", s->toChars(), s->kind()); -
a/dmd2/statement.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 … … 96 96 va_end( ap ); 97 97 } 98 98 99 void Statement::warning(const char *format, ...) 100 { 101 if (global.params.warnings && !global.gag) 102 { 103 fprintf(stdmsg, "warning - "); 104 va_list ap; 105 va_start(ap, format); 106 ::verror(loc, format, ap); 107 va_end( ap ); 108 } 109 } 110 99 111 int Statement::hasBreak() 100 112 { 101 113 //printf("Statement::hasBreak()\n"); … … 124 136 return BEany; 125 137 } 126 138 127 // TRUE if statement may fall off the end without a throw or return128 129 int Statement::fallOffEnd()130 {131 return TRUE;132 }133 134 139 // TRUE if statement 'comes from' somewhere else, like a goto 135 140 136 141 int Statement::comeFrom() … … 231 236 return result; 232 237 } 233 238 234 int ExpStatement::fallOffEnd()235 {236 if (exp)237 {238 if (exp->op == TOKassert)239 { AssertExp *a = (AssertExp *)exp;240 241 if (a->e1->isBool(FALSE)) // if it's an assert(0)242 return FALSE;243 }244 else if (exp->op == TOKhalt)245 return FALSE;246 }247 return TRUE;248 }249 239 250 240 /******************************** CompileStatement ***************************/ 251 241 … … 565 555 //printf("%s\n", s->toChars()); 566 556 if (!(result & BEfallthru) && !s->comeFrom()) 567 557 { 568 if (global.params.warnings) 569 { fprintf(stdmsg, "warning - "); 570 s->error("statement is not reachable"); 571 } 558 s->warning("statement is not reachable"); 572 559 } 573 560 574 561 result &= ~BEfallthru; … … 578 565 return result; 579 566 } 580 567 581 int CompoundStatement::fallOffEnd()582 { int falloff = TRUE;583 584 //printf("CompoundStatement::fallOffEnd() %s\n", toChars());585 for (int i = 0; i < statements->dim; i++)586 { Statement *s = (Statement *)statements->data[i];587 588 if (!s)589 continue;590 591 #if 0592 if (!falloff && global.params.warnings && !s->comeFrom())593 {594 warning("%s: statement is not reachable", s->loc.toChars());595 }596 #endif597 falloff = s->fallOffEnd();598 }599 return falloff;600 }601 568 602 569 int CompoundStatement::comeFrom() 603 570 { int comefrom = FALSE; … … 716 683 return result; 717 684 } 718 685 719 int UnrolledLoopStatement::fallOffEnd()720 {721 //printf("UnrolledLoopStatement::fallOffEnd()\n");722 for (size_t i = 0; i < statements->dim; i++)723 { Statement *s = (Statement *)statements->data[i];724 725 if (s)726 s->fallOffEnd();727 }728 return TRUE;729 }730 686 731 687 int UnrolledLoopStatement::comeFrom() 732 688 { int comefrom = FALSE; … … 821 777 return statement ? statement->blockExit() : BEfallthru; 822 778 } 823 779 824 int ScopeStatement::fallOffEnd()825 {826 return statement ? statement->fallOffEnd() : TRUE;827 }828 780 829 781 int ScopeStatement::comeFrom() 830 782 { … … 951 903 return result; 952 904 } 953 905 954 int WhileStatement::fallOffEnd()955 {956 if (body)957 body->fallOffEnd();958 return TRUE;959 }960 906 961 907 int WhileStatement::comeFrom() 962 908 { … … 1046 992 return result; 1047 993 } 1048 994 1049 int DoStatement::fallOffEnd()1050 {1051 if (body)1052 body->fallOffEnd();1053 return TRUE;1054 }1055 995 1056 996 int DoStatement::comeFrom() 1057 997 { … … 1171 1111 result &= ~BEfallthru; // the body must do the exiting 1172 1112 if (body) 1173 1113 { int r = body->blockExit(); 1174 if (r & BEbreak)1175 result |= BEfallthru; 1176 result |= r & ~(BE break | BEcontinue);1114 if (r & (BEbreak | BEgoto)) 1115 result |= BEfallthru; 1116 result |= r & ~(BEfallthru | BEbreak | BEcontinue); 1177 1117 } 1178 1118 if (increment && increment->canThrow()) 1179 1119 result |= BEthrow; 1180 1120 return result; 1181 1121 } 1182 1122 1183 int ForStatement::fallOffEnd()1184 {1185 if (body)1186 body->fallOffEnd();1187 return TRUE;1188 }1189 1123 1190 1124 int ForStatement::comeFrom() 1191 1125 { … … 1551 1485 */ 1552 1486 Identifier *id = Identifier::generateId("__r"); 1553 1487 VarDeclaration *r = new VarDeclaration(loc, NULL, id, new ExpInitializer(loc, aggr)); 1554 r->semantic(sc); 1488 // r->semantic(sc); 1489 //printf("r: %s, init: %s\n", r->toChars(), r->init->toChars()); 1555 1490 Statement *init = new DeclarationStatement(loc, r); 1491 //printf("init: %s\n", init->toChars()); 1556 1492 1557 1493 // !__r.empty 1558 1494 Expression *e = new VarExp(loc, r); … … 1568 1504 */ 1569 1505 e = new VarExp(loc, r); 1570 1506 Expression *einit = new DotIdExp(loc, e, idhead); 1571 einit = einit->semantic(sc);1507 // einit = einit->semantic(sc); 1572 1508 Argument *arg = (Argument *)arguments->data[0]; 1573 1509 VarDeclaration *ve = new VarDeclaration(loc, arg->type, arg->ident, new ExpInitializer(loc, einit)); 1574 1510 ve->storage_class |= STCforeach; … … 1923 1859 return result; 1924 1860 } 1925 1861 1926 int ForeachStatement::fallOffEnd()1927 {1928 if (body)1929 body->fallOffEnd();1930 return TRUE;1931 }1932 1862 1933 1863 int ForeachStatement::comeFrom() 1934 1864 { … … 2023 1953 2024 1954 if (arg->type) 2025 1955 { 1956 arg->type = arg->type->semantic(loc, sc); 2026 1957 lwr = lwr->implicitCastTo(sc, arg->type); 2027 1958 upr = upr->implicitCastTo(sc, arg->type); 2028 1959 } … … 2091 2022 return result; 2092 2023 } 2093 2024 2094 int ForeachRangeStatement::fallOffEnd()2095 {2096 if (body)2097 body->fallOffEnd();2098 return TRUE;2099 }2100 2025 2101 2026 int ForeachRangeStatement::comeFrom() 2102 2027 { … … 2253 2178 return result; 2254 2179 } 2255 2180 2256 int IfStatement::fallOffEnd()2257 {2258 if (!ifbody || ifbody->fallOffEnd() ||2259 !elsebody || elsebody->fallOffEnd())2260 return TRUE;2261 return FALSE;2262 }2263 2264 2181 2265 2182 void IfStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 2266 2183 { … … 2506 2423 return result; 2507 2424 } 2508 2425 2509 int PragmaStatement::fallOffEnd()2510 {2511 if (body)2512 return body->fallOffEnd();2513 return TRUE;2514 }2515 2426 2516 2427 void PragmaStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 2517 2428 { … … 2717 2628 return result; 2718 2629 } 2719 2630 2720 int SwitchStatement::fallOffEnd()2721 {2722 if (body)2723 body->fallOffEnd();2724 return TRUE; // need to do this better2725 }2726 2631 2727 2632 void SwitchStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 2728 2633 { … … 2849 2754 return statement->blockExit(); 2850 2755 } 2851 2756 2852 int CaseStatement::fallOffEnd()2853 {2854 return statement->fallOffEnd();2855 }2856 2757 2857 2758 int CaseStatement::comeFrom() 2858 2759 { … … 2916 2817 return statement->blockExit(); 2917 2818 } 2918 2819 2919 int DefaultStatement::fallOffEnd()2920 {2921 return statement->fallOffEnd();2922 }2923 2820 2924 2821 int DefaultStatement::comeFrom() 2925 2822 { … … 2961 2858 return BEgoto; 2962 2859 } 2963 2860 2964 int GotoDefaultStatement::fallOffEnd()2965 {2966 return FALSE;2967 }2968 2861 2969 2862 void GotoDefaultStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 2970 2863 { … … 3015 2908 return BEgoto; 3016 2909 } 3017 2910 3018 int GotoCaseStatement::fallOffEnd()3019 {3020 return FALSE;3021 }3022 2911 3023 2912 void GotoCaseStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 3024 2913 { … … 3043 2932 return BEthrow; 3044 2933 } 3045 2934 3046 int SwitchErrorStatement::fallOffEnd()3047 {3048 return FALSE;3049 }3050 2935 3051 2936 void SwitchErrorStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 3052 2937 { … … 3273 3158 exp = exp->semantic(sc); 3274 3159 } 3275 3160 3276 if (((TypeFunction *)fd->type)->isref )3161 if (((TypeFunction *)fd->type)->isref && !fd->isCtorDeclaration()) 3277 3162 { // Function returns a reference 3278 3163 if (tbret->isMutable()) 3279 3164 exp = exp->modifiableLvalue(sc, exp); … … 3346 3231 return result; 3347 3232 } 3348 3233 3349 int ReturnStatement::fallOffEnd()3350 {3351 return FALSE;3352 }3353 3234 3354 3235 void ReturnStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 3355 3236 { … … 3445 3326 return ident ? BEgoto : BEbreak; 3446 3327 } 3447 3328 3448 int BreakStatement::fallOffEnd()3449 {3450 return FALSE;3451 }3452 3329 3453 3330 void BreakStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 3454 3331 { … … 3553 3430 return ident ? BEgoto : BEcontinue; 3554 3431 } 3555 3432 3556 int ContinueStatement::fallOffEnd()3557 {3558 return FALSE;3559 }3560 3433 3561 3434 void ContinueStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 3562 3435 { … … 3648 3521 return body ? body->blockExit() : BEfallthru; 3649 3522 } 3650 3523 3651 int SynchronizedStatement::fallOffEnd()3652 {3653 return body ? body->fallOffEnd() : TRUE;3654 }3655 3524 3656 3525 void SynchronizedStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 3657 3526 { … … 3770 3639 return result; 3771 3640 } 3772 3641 3773 int WithStatement::fallOffEnd()3774 {3775 return body ? body->fallOffEnd() : TRUE;3776 }3777 3642 3778 3643 /******************************** TryCatchStatement ***************************/ 3779 3644 … … 3837 3702 } 3838 3703 3839 3704 int TryCatchStatement::blockExit() 3840 { int result; 3841 3705 { 3842 3706 assert(body); 3843 result = body->blockExit(); 3844 3707 int result = body->blockExit(); 3708 3709 int catchresult = 0; 3845 3710 for (size_t i = 0; i < catches->dim; i++) 3846 3711 { 3847 3712 Catch *c = (Catch *)catches->data[i]; 3848 result |= c->blockExit(); 3849 } 3850 return result; 3851 } 3852 3853 int TryCatchStatement::fallOffEnd() 3854 { 3855 int result = FALSE; 3856 3857 if (body) 3858 result = body->fallOffEnd(); 3859 for (int i = 0; i < catches->dim; i++) 3860 { Catch *c; 3861 3862 c = (Catch *)catches->data[i]; 3863 if (c->handler) 3864 result |= c->handler->fallOffEnd(); 3865 } 3866 return result; 3867 } 3713 catchresult |= c->blockExit(); 3714 3715 /* If we're catching Object, then there is no throwing 3716 */ 3717 Identifier *id = c->type->toBasetype()->isClassHandle()->ident; 3718 if (i == 0 && 3719 (id == Id::Object || id == Id::Throwable || id == Id::Exception)) 3720 { 3721 result &= ~BEthrow; 3722 } 3723 } 3724 return result | catchresult; 3725 } 3726 3868 3727 3869 3728 void TryCatchStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 3870 3729 { … … 4030 3889 4031 3890 int TryFinallyStatement::blockExit() 4032 3891 { 4033 int result = body->blockExit(); 4034 return result; 4035 } 4036 4037 int TryFinallyStatement::fallOffEnd() 4038 { int result; 4039 4040 result = body->fallOffEnd(); 4041 // if (finalbody) 4042 // result = finalbody->fallOffEnd(); 4043 return result; 4044 } 3892 if (body) 3893 return body->blockExit(); 3894 return BEfallthru; 3895 } 3896 4045 3897 4046 3898 /****************************** OnScopeStatement ***************************/ 4047 3899 … … 4163 4015 return BEthrow; // obviously 4164 4016 } 4165 4017 4166 int ThrowStatement::fallOffEnd()4167 {4168 return FALSE;4169 }4170 4018 4171 4019 void ThrowStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 4172 4020 { … … 4226 4074 return statement ? statement->blockExit() : BEfallthru; 4227 4075 } 4228 4076 4229 int VolatileStatement::fallOffEnd()4230 {4231 return statement ? statement->fallOffEnd() : TRUE;4232 }4233 4077 4234 4078 void VolatileStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 4235 4079 { … … 4295 4139 return BEgoto; 4296 4140 } 4297 4141 4298 int GotoStatement::fallOffEnd()4299 {4300 return FALSE;4301 }4302 4142 4303 4143 void GotoStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 4304 4144 { … … 4389 4229 return statement ? statement->blockExit() : BEfallthru; 4390 4230 } 4391 4231 4392 int LabelStatement::fallOffEnd()4393 {4394 return statement ? statement->fallOffEnd() : TRUE;4395 }4396 4232 4397 4233 int LabelStatement::comeFrom() 4398 4234 { -
a/dmd2/statement.h
old new 79 79 #endif 80 80 struct code; 81 81 82 /* How a statement exits 82 /* How a statement exits; this is returned by blockExit() 83 83 */ 84 84 enum BE 85 85 { … … 134 134 char *toChars(); 135 135 136 136 void error(const char *format, ...); 137 void warning(const char *format, ...); 137 138 virtual void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 138 139 virtual TryCatchStatement *isTryCatchStatement() { return NULL; } 139 140 virtual GotoStatement *isGotoStatement() { return NULL; } … … 148 149 virtual int hasBreak(); 149 150 virtual int hasContinue(); 150 151 virtual int usesEH(); 151 virtual int fallOffEnd();152 152 virtual int blockExit(); 153 153 virtual int comeFrom(); 154 154 virtual void scopeCode(Scope *sc, Statement **sentry, Statement **sexit, Statement **sfinally); … … 183 183 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 184 184 Statement *semantic(Scope *sc); 185 185 Expression *interpret(InterState *istate); 186 int fallOffEnd();187 186 int blockExit(); 188 187 189 188 int inlineCost(InlineCostState *ics); … … 232 231 virtual Statement *semantic(Scope *sc); 233 232 int usesEH(); 234 233 int blockExit(); 235 int fallOffEnd();236 234 int comeFrom(); 237 235 virtual Statements *flatten(Scope *sc); 238 236 ReturnStatement *isReturnStatement(); … … 266 264 int hasContinue(); 267 265 int usesEH(); 268 266 int blockExit(); 269 int fallOffEnd();270 267 int comeFrom(); 271 268 Expression *interpret(InterState *istate); 272 269 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); … … 291 288 int hasContinue(); 292 289 int usesEH(); 293 290 int blockExit(); 294 int fallOffEnd();295 291 int comeFrom(); 296 292 Expression *interpret(InterState *istate); 297 293 … … 313 309 int hasContinue(); 314 310 int usesEH(); 315 311 int blockExit(); 316 int fallOffEnd();317 312 int comeFrom(); 318 313 Expression *interpret(InterState *istate); 319 314 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); … … 336 331 int hasContinue(); 337 332 int usesEH(); 338 333 int blockExit(); 339 int fallOffEnd();340 334 int comeFrom(); 341 335 Expression *interpret(InterState *istate); 342 336 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); … … 362 356 int hasContinue(); 363 357 int usesEH(); 364 358 int blockExit(); 365 int fallOffEnd();366 359 int comeFrom(); 367 360 Expression *interpret(InterState *istate); 368 361 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); … … 396 389 int hasContinue(); 397 390 int usesEH(); 398 391 int blockExit(); 399 int fallOffEnd();400 392 int comeFrom(); 401 393 Expression *interpret(InterState *istate); 402 394 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); … … 426 418 int hasContinue(); 427 419 int usesEH(); 428 420 int blockExit(); 429 int fallOffEnd();430 421 int comeFrom(); 431 422 Expression *interpret(InterState *istate); 432 423 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); … … 453 444 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 454 445 int usesEH(); 455 446 int blockExit(); 456 int fallOffEnd();457 447 IfStatement *isIfStatement() { return this; } 458 448 459 449 int inlineCost(InlineCostState *ics); … … 490 480 Statement *semantic(Scope *sc); 491 481 int usesEH(); 492 482 int blockExit(); 493 int fallOffEnd();494 483 495 484 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 496 485 … … 528 517 int hasBreak(); 529 518 int usesEH(); 530 519 int blockExit(); 531 int fallOffEnd();532 520 Expression *interpret(InterState *istate); 533 521 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 534 522 … … 550 538 int compare(Object *obj); 551 539 int usesEH(); 552 540 int blockExit(); 553 int fallOffEnd();554 541 int comeFrom(); 555 542 Expression *interpret(InterState *istate); 556 543 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); … … 578 565 Statement *semantic(Scope *sc); 579 566 int usesEH(); 580 567 int blockExit(); 581 int fallOffEnd();582 568 int comeFrom(); 583 569 Expression *interpret(InterState *istate); 584 570 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); … … 601 587 Statement *semantic(Scope *sc); 602 588 Expression *interpret(InterState *istate); 603 589 int blockExit(); 604 int fallOffEnd();605 590 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 606 591 607 592 void toIR(IRState *irs); … … 619 604 Statement *semantic(Scope *sc); 620 605 Expression *interpret(InterState *istate); 621 606 int blockExit(); 622 int fallOffEnd();623 607 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 624 608 625 609 void toIR(IRState *irs); … … 629 613 { 630 614 SwitchErrorStatement(Loc loc); 631 615 int blockExit(); 632 int fallOffEnd();633 616 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 634 617 635 618 void toIR(IRState *irs); … … 645 628 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 646 629 Statement *semantic(Scope *sc); 647 630 int blockExit(); 648 int fallOffEnd();649 631 Expression *interpret(InterState *istate); 650 632 651 633 int inlineCost(InlineCostState *ics); … … 667 649 Statement *semantic(Scope *sc); 668 650 Expression *interpret(InterState *istate); 669 651 int blockExit(); 670 int fallOffEnd();671 652 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 672 653 673 654 void toIR(IRState *irs); … … 686 667 Statement *semantic(Scope *sc); 687 668 Expression *interpret(InterState *istate); 688 669 int blockExit(); 689 int fallOffEnd();690 670 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 691 671 692 672 void toIR(IRState *irs); … … 708 688 int hasContinue(); 709 689 int usesEH(); 710 690 int blockExit(); 711 int fallOffEnd();712 691 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 713 692 714 693 Statement *inlineScan(InlineScanState *iss); … … 732 711 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 733 712 int usesEH(); 734 713 int blockExit(); 735 int fallOffEnd();736 714 737 715 Statement *inlineScan(InlineScanState *iss); 738 716 … … 750 728 int hasBreak(); 751 729 int usesEH(); 752 730 int blockExit(); 753 int fallOffEnd();754 731 755 732 Statement *inlineScan(InlineScanState *iss); 756 733 … … 788 765 int hasContinue(); 789 766 int usesEH(); 790 767 int blockExit(); 791 int fallOffEnd();792 768 793 769 Statement *inlineScan(InlineScanState *iss); 794 770 … … 820 796 Statement *semantic(Scope *sc); 821 797 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 822 798 int blockExit(); 823 int fallOffEnd();824 799 825 800 Statement *inlineScan(InlineScanState *iss); 826 801 … … 837 812 Statement *semantic(Scope *sc); 838 813 Statements *flatten(Scope *sc); 839 814 int blockExit(); 840 int fallOffEnd();841 815 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 842 816 843 817 Statement *inlineScan(InlineScanState *iss); … … 856 830 Statement *syntaxCopy(); 857 831 Statement *semantic(Scope *sc); 858 832 int blockExit(); 859 int fallOffEnd();860 833 Expression *interpret(InterState *istate); 861 834 862 835 void toIR(IRState *irs); … … 879 852 Statements *flatten(Scope *sc); 880 853 int usesEH(); 881 854 int blockExit(); 882 int fallOffEnd();883 855 int comeFrom(); 884 856 Expression *interpret(InterState *istate); 885 857 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); -
a/dmd2/struct.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 … … 19 19 #include "module.h" 20 20 #include "id.h" 21 21 #include "statement.h" 22 #include "template.h" 22 23 23 24 /********************************* AggregateDeclaration ****************************/ 24 25 … … 44 45 stag = NULL; 45 46 sinit = NULL; 46 47 scope = NULL; 47 dtor = NULL; 48 isnested = 0; 49 vthis = NULL; 48 50 51 #if DMDV2 49 52 ctor = NULL; 50 53 defaultCtor = NULL; 54 #endif 55 dtor = NULL; 51 56 } 52 57 53 58 enum PROT AggregateDeclaration::prot() … … 132 137 * Align sizes of 0, as we may not know array sizes yet. 133 138 */ 134 139 135 void AggregateDeclaration::alignmember(unsigned salign, unsigned size, unsigned *poffset) 140 void AggregateDeclaration::alignmember( 141 unsigned salign, // struct alignment that is in effect 142 unsigned size, // alignment requirement of field 143 unsigned *poffset) 136 144 { 137 145 //printf("salign = %d, size = %d, offset = %d\n",salign,size,*poffset); 138 146 if (salign > 1) 139 { int sa; 140 141 switch (size) 142 { case 1: 143 break; 144 case 2: 145 case_2: 146 *poffset = (*poffset + 1) & ~1; // align to word 147 break; 148 case 3: 149 case 4: 150 if (salign == 2) 151 goto case_2; 152 *poffset = (*poffset + 3) & ~3; // align to dword 153 break; 154 default: 155 *poffset = (*poffset + size - 1) & ~(size - 1); 156 break; 157 } 147 { 148 assert(size != 3); 149 int sa = size; 150 if (sa == 0 || salign < sa) 151 sa = salign; 152 *poffset = (*poffset + sa - 1) & ~(sa - 1); 158 153 } 159 154 //printf("result = %d\n",*poffset); 160 155 } … … 171 166 172 167 // Check for forward referenced types which will fail the size() call 173 168 Type *t = v->type->toBasetype(); 169 if (v->storage_class & STCref) 170 { // References are the size of a pointer 171 t = Type::tvoidptr; 172 } 174 173 if (t->ty == Tstruct /*&& isStructDeclaration()*/) 175 174 { TypeStruct *ts = (TypeStruct *)t; 176 175 #if DMDV2 177 176 if (ts->sym == this) 178 177 { 179 178 error("cannot have field %s with same struct type", v->toChars()); 180 179 } 180 #endif 181 181 182 182 if (ts->sym->sizeok != 1) 183 183 { … … 191 191 return; 192 192 } 193 193 194 memsize = v->type->size(loc);195 memalignsize = v->type->alignsize();196 xalign = v->type->memalign(sc->structalign);194 memsize = t->size(loc); 195 memalignsize = t->alignsize(); 196 xalign = t->memalign(sc->structalign); 197 197 alignmember(xalign, memalignsize, &sc->offset); 198 198 v->offset = sc->offset; 199 199 sc->offset += memsize; … … 211 211 } 212 212 213 213 214 /**************************************** 215 * Returns !=0 if there's an extra member which is the 'this' 216 * pointer to the enclosing context (enclosing aggregate or function) 217 */ 218 219 int AggregateDeclaration::isNested() 220 { 221 return isnested; 222 } 223 224 214 225 /********************************* StructDeclaration ****************************/ 215 226 216 227 StructDeclaration::StructDeclaration(Loc loc, Identifier *id) 217 228 : AggregateDeclaration(loc, id) 218 229 { 219 230 zeroInit = 0; // assume false until we do semantic processing 231 #if DMDV2 220 232 hasIdentityAssign = 0; 221 233 cpctor = NULL; 222 234 postblit = NULL; 235 #endif 223 236 224 237 // For forward references 225 238 type = new TypeStruct(this); … … 267 280 #if STRUCTTHISREF 268 281 handle = type; 269 282 #else 283 assert(0); 270 284 handle = type->pointerTo(); 271 285 #endif 272 286 structalign = sc->structalign; … … 277 291 assert(!isAnonymous()); 278 292 if (sc->stc & STCabstract) 279 293 error("structs, unions cannot be abstract"); 294 #if DMDV2 280 295 if (storage_class & STCinvariant) 281 296 type = type->invariantOf(); 282 297 else if (storage_class & STCconst) 283 298 type = type->constOf(); 299 #endif 284 300 285 301 if (sizeok == 0) // if not already done the addMember step 286 302 { 303 int hasfunctions = 0; 287 304 for (i = 0; i < members->dim; i++) 288 305 { 289 306 Dsymbol *s = (Dsymbol *)members->data[i]; 290 307 //printf("adding member '%s' to '%s'\n", s->toChars(), this->toChars()); 291 308 s->addMember(sc, this, 1); 309 if (s->isFuncDeclaration()) 310 hasfunctions = 1; 292 311 } 312 313 // If nested struct, add in hidden 'this' pointer to outer scope 314 if (hasfunctions && !(storage_class & STCstatic)) 315 { Dsymbol *s = toParent2(); 316 if (s) 317 { 318 AggregateDeclaration *ad = s->isAggregateDeclaration(); 319 FuncDeclaration *fd = s->isFuncDeclaration(); 320 321 TemplateInstance *ti; 322 if (ad && (ti = ad->parent->isTemplateInstance()) != NULL && ti->isnested || fd) 323 { isnested = 1; 324 Type *t; 325 if (ad) 326 t = ad->handle; 327 else if (fd) 328 { AggregateDeclaration *ad = fd->isMember2(); 329 if (ad) 330 t = ad->handle; 331 else 332 t = Type::tvoidptr; 333 } 334 else 335 assert(0); 336 if (t->ty == Tstruct) 337 t = Type::tvoidptr; // t should not be a ref type 338 assert(!vthis); 339 vthis = new ThisDeclaration(t); 340 //vthis->storage_class |= STCref; 341 members->push(vthis); 342 } 343 } 344 } 293 345 } 294 346 295 347 sizeok = 0; … … 314 366 break; 315 367 } 316 368 #endif 369 Type *t; 370 if (s->isDeclaration() && 371 (t = s->isDeclaration()->type) != NULL && 372 t->toBasetype()->ty == Tstruct) 373 { StructDeclaration *sd = (StructDeclaration *)t->toDsymbol(sc); 374 if (sd->isnested) 375 error("inner struct %s cannot be a field", sd->toChars()); 376 } 317 377 } 318 378 319 379 /* The TypeInfo_Struct is expecting an opEquals and opCmp with … … 373 433 374 434 id = Id::cmp; 375 435 } 376 436 #if DMDV2 377 437 dtor = buildDtor(sc2); 378 438 postblit = buildPostBlit(sc2); 379 439 cpctor = buildCpCtor(sc2); 380 440 buildOpAssign(sc2); 441 #endif 381 442 382 443 sc2->pop(); 383 444 … … 440 501 441 502 /* Look for special member functions. 442 503 */ 504 #if DMDV2 443 505 ctor = (CtorDeclaration *)search(0, Id::ctor, 0); 506 #endif 444 507 inv = (InvariantDeclaration *)search(0, Id::classInvariant, 0); 445 508 aggNew = (NewDeclaration *)search(0, Id::classNew, 0); 446 509 aggDelete = (DeleteDeclaration *)search(0, Id::classDelete, 0); -
a/dmd2/template.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 … … 187 187 { 188 188 goto Lnomatch; 189 189 } 190 #if DMDV2 190 191 VarDeclaration *v1 = s1->isVarDeclaration(); 191 192 VarDeclaration *v2 = s2->isVarDeclaration(); 192 193 if (v1 && v2 && v1->storage_class & v2->storage_class & STCmanifest) … … 195 196 if (ei1 && ei2 && !ei1->exp->equals(ei2->exp)) 196 197 goto Lnomatch; 197 198 } 199 #endif 198 200 } 199 201 else if (v1) 200 202 { … … 262 264 } 263 265 } 264 266 267 #if DMDV2 265 268 Object *objectSyntaxCopy(Object *o) 266 269 { 267 270 if (!o) … … 274 277 return e->syntaxCopy(); 275 278 return o; 276 279 } 280 #endif 277 281 278 282 279 283 /* ======================== TemplateDeclaration ============================= */ … … 301 305 this->loc = loc; 302 306 this->parameters = parameters; 303 307 this->origParameters = parameters; 308 #if DMDV2 304 309 this->constraint = constraint; 310 #endif 305 311 this->members = decldefs; 306 312 this->overnext = NULL; 307 313 this->overroot = NULL; … … 326 332 p->data[i] = (void *)tp->syntaxCopy(); 327 333 } 328 334 } 335 #if DMDV2 329 336 Expression *e = NULL; 330 337 if (constraint) 331 338 e = constraint->syntaxCopy(); 339 #endif 332 340 d = Dsymbol::arraySyntaxCopy(members); 333 341 td = new TemplateDeclaration(loc, ident, p, e, d); 334 342 … … 348 356 349 357 if (sc->func) 350 358 { 351 // error("cannot declare template at function scope %s", sc->func->toChars()); 359 #if V1 360 error("cannot declare template at function scope %s", sc->func->toChars()); 361 #endif 352 362 } 353 363 354 364 if (/*global.params.useArrayBounds &&*/ sc->module) … … 376 386 paramsym->parent = sc->parent; 377 387 Scope *paramscope = sc->push(paramsym); 378 388 paramscope->parameterSpecialization = 1; 389 paramscope->stc = 0; 379 390 380 391 if (global.params.doDocComments) 381 392 { … … 536 547 ScopeDsymbol *paramsym = new ScopeDsymbol(); 537 548 paramsym->parent = scope->parent; 538 549 Scope *paramscope = scope->push(paramsym); 550 paramscope->stc = 0; 539 551 540 552 // Attempt type deduction 541 553 m = MATCHexact; … … 591 603 } 592 604 } 593 605 606 #if DMDV2 594 607 if (m && constraint && !(flag & 1)) 595 608 { /* Check to see if constraint is satisfied. 596 609 */ … … 607 620 e->error("constraint %s is not constant or does not evaluate to a bool", e->toChars()); 608 621 } 609 622 } 623 #endif 610 624 611 625 #if LOGM 612 626 // Print out the results … … 823 837 Tuple *t = new Tuple(); 824 838 //printf("t = %p\n", t); 825 839 dedargs->data[parameters->dim - 1] = (void *)t; 840 declareParameter(paramscope, tp, t); 826 841 goto L2; 827 842 } 828 843 else if (nfargs < nfparams - 1) … … 858 873 { Expression *farg = (Expression *)fargs->data[fptupindex + i]; 859 874 t->objects.data[i] = (void *)farg->type; 860 875 } 876 declareParameter(paramscope, tp, t); 861 877 goto L2; 862 878 } 863 879 fptupindex = -1; … … 875 891 } 876 892 877 893 L2: 894 #if DMDV2 878 895 // Match 'ethis' to any TemplateThisParameter's 879 896 if (ethis) 880 897 { … … 893 910 } 894 911 } 895 912 } 913 #endif 896 914 897 915 // Loop through the function parameters 898 916 for (i = 0; i < nfparams; i++) … … 924 942 printf("\tfarg->type = %s\n", farg->type->toChars()); 925 943 printf("\tfparam->type = %s\n", fparam->type->toChars()); 926 944 #endif 945 Type *argtype = farg->type; 946 947 #if DMDV2 948 /* Allow string literals which are type [] to match with [dim] 949 */ 950 if (farg->op == TOKstring) 951 { StringExp *se = (StringExp *)farg; 952 if (!se->committed && argtype->ty == Tarray && 953 fparam->type->toBasetype()->ty == Tsarray) 954 { 955 argtype = new TypeSArray(argtype->nextOf(), new IntegerExp(se->loc, se->len, Type::tindex)); 956 argtype = argtype->semantic(se->loc, NULL); 957 argtype = argtype->invariantOf(); 958 } 959 } 960 #endif 961 927 962 MATCH m; 928 //m = farg->type->toHeadMutable()->deduceType(scope, fparam->type, parameters, &dedtypes);929 m = farg->type->deduceType(scope, fparam->type, parameters, &dedtypes);963 //m = argtype->toHeadMutable()->deduceType(scope, fparam->type, parameters, &dedtypes); 964 m = argtype->deduceType(scope, fparam->type, parameters, &dedtypes); 930 965 //printf("\tdeduceType m = %d\n", m); 931 966 932 967 /* If no match, see if there's a conversion to a delegate … … 1061 1096 } 1062 1097 } 1063 1098 1099 #if DMDV2 1064 1100 if (constraint) 1065 1101 { /* Check to see if constraint is satisfied. 1066 1102 */ … … 1077 1113 e->error("constraint %s is not constant or does not evaluate to a bool", e->toChars()); 1078 1114 } 1079 1115 } 1080 1116 #endif 1081 1117 1082 1118 #if 0 1083 1119 for (i = 0; i < dedargs->dim; i++) … … 1343 1379 tp->toCBuffer(buf, hgs); 1344 1380 } 1345 1381 buf->writeByte(')'); 1346 1382 #if DMDV2 1347 1383 if (constraint) 1348 1384 { buf->writestring(" if ("); 1349 1385 constraint->toCBuffer(buf, hgs); 1350 1386 buf->writeByte(')'); 1351 1387 } 1388 #endif 1352 1389 1353 1390 if (hgs->hdrgen) 1354 1391 { … … 1383 1420 tp->toCBuffer(&buf, &hgs); 1384 1421 } 1385 1422 buf.writeByte(')'); 1386 1423 #if DMDV2 1387 1424 if (constraint) 1388 1425 { buf.writestring(" if ("); 1389 1426 constraint->toCBuffer(&buf, &hgs); 1390 1427 buf.writeByte(')'); 1391 1428 } 1392 1429 #endif 1393 1430 buf.writeByte(0); 1394 1431 return (char *)buf.extractData(); 1395 1432 } … … 1554 1591 return MATCHconst; 1555 1592 } 1556 1593 1594 MATCH TypeDArray::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, 1595 Objects *dedtypes) 1596 { 1597 #if 0 1598 printf("TypeDArray::deduceType()\n"); 1599 printf("\tthis = %d, ", ty); print(); 1600 printf("\ttparam = %d, ", tparam->ty); tparam->print(); 1601 #endif 1602 return Type::deduceType(sc, tparam, parameters, dedtypes); 1603 1604 Lnomatch: 1605 return MATCHnomatch; 1606 } 1607 1557 1608 MATCH TypeSArray::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, 1558 1609 Objects *dedtypes) 1559 1610 { … … 1852 1903 Expression *e1 = isExpression(o1); 1853 1904 Expression *e2 = isExpression(o2); 1854 1905 1906 Dsymbol *s1 = isDsymbol(o1); 1907 Dsymbol *s2 = isDsymbol(o2); 1908 1909 Tuple *v1 = isTuple(o1); 1910 Tuple *v2 = isTuple(o2); 1855 1911 #if 0 1856 1912 if (t1) printf("t1 = %s\n", t1->toChars()); 1857 1913 if (t2) printf("t2 = %s\n", t2->toChars()); 1858 1914 if (e1) printf("e1 = %s\n", e1->toChars()); 1859 1915 if (e2) printf("e2 = %s\n", e2->toChars()); 1916 if (s1) printf("s1 = %s\n", s1->toChars()); 1917 if (s2) printf("s2 = %s\n", s2->toChars()); 1918 if (v1) printf("v1 = %s\n", v1->toChars()); 1919 if (v2) printf("v2 = %s\n", v2->toChars()); 1860 1920 #endif 1861 1921 1862 1922 if (t1 && t2) … … 1903 1963 dedtypes->data[j] = e1; 1904 1964 } 1905 1965 } 1906 // BUG: Need to handle alias and tuple parameters 1966 else if (s1 && t2 && t2->ty == Tident) 1967 { 1968 j = templateParameterLookup(t2, parameters); 1969 if (j == -1) 1970 goto Lnomatch; 1971 TemplateParameter *tp = (TemplateParameter *)parameters->data[j]; 1972 // BUG: use tp->matchArg() instead of the following 1973 TemplateAliasParameter *ta = tp->isTemplateAliasParameter(); 1974 if (!ta) 1975 goto Lnomatch; 1976 Dsymbol *s = (Dsymbol *)dedtypes->data[j]; 1977 if (s) 1978 { 1979 if (!s1->equals(s)) 1980 goto Lnomatch; 1981 } 1982 else 1983 { 1984 dedtypes->data[j] = s1; 1985 } 1986 } 1987 else if (s1 && s2) 1988 { 1989 if (!s1->equals(s2)) 1990 goto Lnomatch; 1991 } 1992 // BUG: Need to handle tuple parameters 1907 1993 else 1908 1994 goto Lnomatch; 1909 1995 } … … 2537 2623 2538 2624 Lnomatch: 2539 2625 *psparam = NULL; 2626 //printf("\tm = %d\n", MATCHnomatch); 2540 2627 return MATCHnomatch; 2541 2628 } 2542 2629 … … 3157 3244 } 3158 3245 } 3159 3246 3160 isNested(tiargs);3247 hasNestedArgs(tiargs); 3161 3248 3162 3249 /* See if there is an existing TemplateInstantiation that already 3163 3250 * implements the typeargs. If so, just refer to that one instead. … … 3231 3318 #endif 3232 3319 3233 3320 //if (scx && scx->scopesym) printf("3: scx is %s %s\n", scx->scopesym->kind(), scx->scopesym->toChars()); 3234 if (scx && scx->scopesym && scx->scopesym->members && !scx->scopesym->isTemplateMixin()) 3321 if (scx && scx->scopesym && 3322 scx->scopesym->members && !scx->scopesym->isTemplateMixin() 3323 #if 0 // removed because it bloated compile times 3324 /* The problem is if A imports B, and B imports A, and both A 3325 * and B instantiate the same template, does the compilation of A 3326 * or the compilation of B do the actual instantiation? 3327 * 3328 * see bugzilla 2500. 3329 */ 3330 && !scx->module->selfImports() 3331 #endif 3332 ) 3235 3333 { 3236 3334 //printf("\t1: adding to %s %s\n", scx->scopesym->kind(), scx->scopesym->toChars()); 3237 3335 a = scx->scopesym->members; … … 3273 3371 argsym = new ScopeDsymbol(); 3274 3372 argsym->parent = scope->parent; 3275 3373 scope = scope->push(argsym); 3374 // scope->stc = 0; 3276 3375 3277 3376 // Declare each template parameter as an alias for the argument type 3278 declareParameters(scope); 3377 Scope *paramscope = scope->push(); 3378 paramscope->stc = 0; 3379 declareParameters(paramscope); 3380 paramscope->pop(); 3279 3381 3280 3382 // Add members of template instance to template instance symbol table 3281 3383 // parent = scope->scopesym; … … 3752 3854 * generation of the TemplateDeclaration. 3753 3855 */ 3754 3856 3755 int TemplateInstance:: isNested(Objects *args)3857 int TemplateInstance::hasNestedArgs(Objects *args) 3756 3858 { int nested = 0; 3757 //printf("TemplateInstance:: isNested('%s')\n", tempdecl->ident->toChars());3859 //printf("TemplateInstance::hasNestedArgs('%s')\n", tempdecl->ident->toChars()); 3758 3860 3759 3861 /* A nested instance happens when an argument references a local 3760 3862 * symbol that is on the stack. … … 3803 3905 if (p == dparent) 3804 3906 goto L1; // isnested is most nested 3805 3907 } 3806 for (Dsymbol *p = dparent; 1; p = p->parent)3908 for (Dsymbol *p = dparent; p; p = p->parent) 3807 3909 { 3808 3910 if (p == isnested) 3809 3911 { isnested = dparent; 3810 3912 goto L1; // dparent is most nested 3811 3913 } 3812 3914 } 3813 error("is nested in both %s and %s", isnested->toChars(), dparent->toChars()); 3915 error("%s is nested in both %s and %s", 3916 toChars(), isnested->toChars(), dparent->toChars()); 3814 3917 } 3815 3918 L1: 3816 3919 //printf("\tnested inside %s\n", isnested->toChars()); … … 3822 3925 } 3823 3926 else if (va) 3824 3927 { 3825 nested |= isNested(&va->objects);3928 nested |= hasNestedArgs(&va->objects); 3826 3929 } 3827 3930 } 3828 3931 return nested; -
a/dmd2/template.h
old new 54 54 TemplateParameters *parameters; // array of TemplateParameter's 55 55 56 56 TemplateParameters *origParameters; // originals for Ddoc 57 57 #if DMDV2 58 58 Expression *constraint; 59 59 #endif 60 60 Array instances; // array of TemplateInstance's 61 61 62 62 TemplateDeclaration *overnext; // next overloaded TemplateDeclaration … … 66 66 Dsymbol *onemember; // if !=NULL then one member of this template 67 67 68 68 TemplateDeclaration(Loc loc, Identifier *id, TemplateParameters *parameters, 69 Expression *constraint, Array *decldefs); 69 #if DMDV2 70 Expression *constraint, 71 #endif 72 Array *decldefs); 70 73 Dsymbol *syntaxCopy(Dsymbol *); 71 74 void semantic(Scope *sc); 72 75 int overloadInsert(Dsymbol *s); … … 117 120 virtual TemplateTypeParameter *isTemplateTypeParameter(); 118 121 virtual TemplateValueParameter *isTemplateValueParameter(); 119 122 virtual TemplateAliasParameter *isTemplateAliasParameter(); 123 #if DMDV2 120 124 virtual TemplateThisParameter *isTemplateThisParameter(); 125 #endif 121 126 virtual TemplateTupleParameter *isTemplateTupleParameter(); 122 127 123 128 virtual TemplateParameter *syntaxCopy() = 0; … … 314 319 TemplateDeclaration *findTemplateDeclaration(Scope *sc); 315 320 TemplateDeclaration *findBestMatch(Scope *sc); 316 321 void declareParameters(Scope *sc); 317 int isNested(Objects *tiargs);322 int hasNestedArgs(Objects *tiargs); 318 323 Identifier *genIdent(); 319 324 320 325 TemplateInstance *isTemplateInstance() { return this; } -
a/dmd2/traits.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 … … 12 12 #include <stdlib.h> 13 13 #include <ctype.h> 14 14 #include <assert.h> 15 #if _MSC_VER 16 #include <complex> 17 #else 15 18 #include <complex.h> 19 #endif 16 20 #include <math.h> 17 21 18 22 #if IN_GCC … … 24 28 #define integer_t dmd_integer_t 25 29 #endif 26 30 27 #if IN_GCC || IN_LLVM28 31 #include "mem.h" 29 #elif _WIN3230 #include "..\root\mem.h"31 #elif linux32 #include "../root/mem.h"33 #endif34 32 35 33 //#include "port.h" 36 34 #include "mtype.h" … … 53 51 54 52 #define LOGSEMANTIC 0 55 53 54 #if DMDV2 55 56 56 /************************************************ 57 57 * Delegate to be passed to overloadApply() that looks 58 58 * for virtual functions. … … 438 438 } 439 439 440 440 441 #endif -
a/gen/dvalue.cpp
old new 33 33 34 34 LLValue* DVarValue::getRVal() 35 35 { 36 assert(val);37 36 Type* bt = type->toBasetype(); 38 37 if (DtoIsPassedByRef(bt)) 39 38 return val; -
a/gen/linker.cpp
old new 14 14 #include "gen/logger.h" 15 15 #include "gen/cl_options.h" 16 16 17 #include <sys/types.h> 18 #include <sys/wait.h> 19 17 20 ////////////////////////////////////////////////////////////////////////////// 18 21 19 22 // Is this useful? … … 172 175 break; 173 176 174 177 case OSWindows: 175 // FIXME: I 'd assume kernel32 etc178 // FIXME: Id assume kernel32 etc 176 179 break; 177 180 } 178 181 … … 313 316 break; 314 317 315 318 case OSWindows: 316 // FIXME: I 'd assume kernel32 etc319 // FIXME: Id assume kernel32 etc 317 320 break; 318 321 } 319 322 … … 339 342 llvm::OStream logstr = Logger::cout(); 340 343 for (; I != E; ++I) 341 344 if (*I) 342 logstr << " '" << *I << "'" << " ";345 logstr << "" << *I << "" << " "; 343 346 logstr << "\n" << std::flush; 344 347 345 348 346 349 // terminate args list 347 350 args.push_back(NULL); 348 351 352 const char** Cargs = new const char* [args.size()]; 353 for (unsigned i = 0, e = args.size(); i != e; ++i) 354 Cargs[i] = args[i]; 349 355 // try to call linker!!! 350 if (int status = llvm::sys::Program::ExecuteAndWait(gcc, &args[0], NULL, NULL, 0,0, &errstr)) 356 int pid = fork(); 357 if( pid == 0 ) execv( gcc.c_str(), (char* const *)Cargs ); 358 int status; waitpid(pid, &status, 0); 359 status = WEXITSTATUS( status ); 360 if ( status) // llvm::sys::Program::ExecuteAndWait(gcc, &args[0], NULL, NULL, 0,0, &errstr)) 351 361 { 352 362 error("linking failed:\nstatus: %d", status); 353 363 if (!errstr.empty()) … … 379 389 std::vector<const char*> args; 380 390 // args[0] should be the name of the executable 381 391 args.push_back(gExePath.toString().c_str()); 382 // Skip first argument to -run; it 's a D source file.392 // Skip first argument to -run; its a D source file. 383 393 for (size_t i = 1, length = opts::runargs.size(); i < length; i++) 384 394 { 385 395 args.push_back(opts::runargs[i].c_str()); -
a/gen/llvmhelpers.cpp
old new 396 396 397 397 void DtoAssign(Loc& loc, DValue* lhs, DValue* rhs) 398 398 { 399 Logger::println("DtoAssign( ...);\n");399 Logger::println("DtoAssign( %s <- %s );\n", lhs->toChars(), rhs->toChars() ); 400 400 LOG_SCOPE; 401 401 402 402 Type* t = lhs->getType()->toBasetype(); 403 403 Type* t2 = rhs->getType()->toBasetype(); 404 404 405 Logger::println("type: %s <- %s );\n", t->toChars(), t2->toChars() ); 406 405 407 if (t->ty == Tstruct) { 406 408 if (!t->equals(t2)) { 407 409 // FIXME: use 'rhs' for something !?! 408 410 DtoAggrZeroInit(lhs->getLVal()); 409 411 } 410 412 else { 413 Logger::cout() << "struct copy: " << *lhs->getLVal() << " <- " << *rhs->getRVal() << " );\n"; 411 414 DtoAggrCopy(lhs->getLVal(), rhs->getRVal()); 412 415 } 413 416 } … … 1572 1575 { 1573 1576 t = t->toBasetype(); 1574 1577 if (t->ty == Tsarray) { 1575 assert(t->next->size() % t->next->alignsize() == 0); 1576 return hasUnalignedFields(t->next); 1578 assert( 0 && "'struct Type' has no member named 'next'"); 1579 /*assert(t->next->size() % t->next->alignsize() == 0); 1580 return hasUnalignedFields(t->next);*/ 1577 1581 } else if (t->ty != Tstruct) 1578 1582 return false; 1579 1583 -
a/gen/todebug.cpp
old new 33 33 */ 34 34 static LLGlobalVariable* emitDwarfGlobalDecl(const LLStructType* type, const char* name, bool linkonce=false) 35 35 { 36 LLGlobalValue::LinkageTypes linkage = linkonce ? LLGlobalValue::LinkOnce Linkage : LLGlobalValue::InternalLinkage;36 LLGlobalValue::LinkageTypes linkage = linkonce ? LLGlobalValue::LinkOnceAnyLinkage : LLGlobalValue::InternalLinkage; 37 37 LLGlobalVariable* gv = new LLGlobalVariable(type, true, linkage, NULL, name, gIR->module); 38 38 gv->setSection("llvm.metadata"); 39 39 return gv; -
a/gen/toir.cpp
old new 1067 1067 if (VarDeclaration* vd = var->isVarDeclaration()) { 1068 1068 LLValue* arrptr; 1069 1069 // indexing struct pointer 1070 if (e1type->ty == Tpointer) { 1070 if (e1type->ty == Tpointer ) { 1071 Logger::cout() << "indexing struct pointer: " << '\n'; 1071 1072 assert(e1type->nextOf()->ty == Tstruct); 1072 1073 TypeStruct* ts = (TypeStruct*)e1type->nextOf(); 1073 1074 arrptr = DtoIndexStruct(l->getRVal(), ts->sym, vd); 1074 1075 } 1075 1076 // indexing normal struct 1076 1077 else if (e1type->ty == Tstruct) { 1078 Logger::cout() << "indexing normal struct: " << '\n'; 1077 1079 TypeStruct* ts = (TypeStruct*)e1type; 1078 1080 arrptr = DtoIndexStruct(l->getRVal(), ts->sym, vd); 1079 1081 } 1080 1082 // indexing class 1081 1083 else if (e1type->ty == Tclass) { 1084 Logger::cout() << "indexing indexing class: " << '\n'; 1082 1085 TypeClass* tc = (TypeClass*)e1type; 1083 1086 arrptr = DtoIndexClass(l->getRVal(), tc->sym, vd); 1084 1087 } … … 1172 1175 else { 1173 1176 Logger::println("normal this exp"); 1174 1177 v = p->func()->thisArg; 1178 if( type->toBasetype()->ty == Tstruct ) v = DtoLoad(v); 1175 1179 } 1176 1180 return new DVarValue(type, vd, v); 1177 1181 } -
a/gen/toobj.cpp
old new 7 7 // in artistic.txt, or the GNU General Public License in gnu.txt. 8 8 // See the included readme.txt for details. 9 9 10 #include <sys/types.h> 11 #include <sys/wait.h> 12 10 13 #include <cstddef> 11 14 #include <fstream> 12 15 … … 357 360 } 358 361 359 362 // Run the compiler to assembly the program. 360 std::string ErrMsg; 361 int R = sys::Program::ExecuteAndWait( 362 gcc, &Args[0], 0, 0, 0, 0, &ErrMsg); 363 std::string ErrMsg; 364 const char** Cargs = new const char* [args.size()+1]; 365 for (unsigned i = 0, e = args.size(); i != e; ++i) 366 Cargs[i] = args[i].c_str(); 367 Cargs[args.size()] = 0; 368 int pid = fork(); 369 if( pid == 0 ) execv( gcc.c_str(), (char* const *)Cargs ); 370 int R; waitpid(pid, &R, 0); 371 R = WEXITSTATUS( R ); 372 /*int R = sys::Program::ExecuteAndWait( 373 gcc, &Args[0], 0, 0, 0, 0, &ErrMsg);*/ 374 //int R = system("/usr/bin/gcc -fno-strict-aliasing -O3 -c -xassembler test.s -o test.o -fpic -m64"); 363 375 if (R) 364 376 { 365 377 error("Failed to invoke gcc. %s", ErrMsg.c_str()); -
a/gen/typinf.cpp
old new 1 1 2 2 3 // Copyright (c) 1999-200 4by Digital Mars3 // Copyright (c) 1999-2009 by Digital Mars 4 4 // All Rights Reserved 5 5 // written by Walter Bright 6 6 // www.digitalmars.com … … 116 116 if (!t->vtinfo) 117 117 { 118 118 #if DMDV2 119 if (t->isConst()) 119 if (t->isShared()) // does both 'shared' and 'shared const' 120 t->vtinfo = new TypeInfoSharedDeclaration(t); 121 else if (t->isConst()) 120 122 t->vtinfo = new TypeInfoConstDeclaration(t); 121 123 else if (t->isInvariant()) 122 124 t->vtinfo = new TypeInfoInvariantDeclaration(t); … … 366 368 assert(0 && "TypeInfoDeclaration::llvmDeclare"); 367 369 } 368 370 371 void TypeInfoSharedDeclaration::toDt(dt_t **pdt) 372 { 373 assert(0 && "TypeInfoSharedDeclaration::toDt"); 374 } 369 375 /* ========================================================================= */ 370 376 371 377 void TypeInfoTypedefDeclaration::llvmDeclare() -
a/ir/irfuncty.h
old new 2 2 #define LDC_IR_IRFUNCTY_H 3 3 4 4 #include "ir/ir.h" 5 #include "llvm/ADT/SmallVector.h"5 //#include "llvm/ADT/SmallVector.h" 6 6 7 7 #include <vector> 8 8 -
a/ldc2.conf.in
old new 1 1 [Environment] 2 DFLAGS=-I@RUNTIME_DIR@/import -L-L%@P%/../lib 2 DFLAGS=-I@RUNTIME_DIR@/import -L-L%@P%/../lib -defaultlib=@RUNTIME_AIO@ -debuglib=@RUNTIME_AIO@