Changeset 639
- Timestamp:
- 08/28/10 07:15:45 (14 years ago)
- Files:
-
- branches/dmd-1.x/src/aggregate.h (modified) (1 diff)
- branches/dmd-1.x/src/class.c (modified) (3 diffs)
- branches/dmd-1.x/src/declaration.c (modified) (5 diffs)
- branches/dmd-1.x/src/declaration.h (modified) (2 diffs)
- branches/dmd-1.x/src/expression.c (modified) (1 diff)
- branches/dmd-1.x/src/func.c (modified) (2 diffs)
- branches/dmd-1.x/src/mtype.c (modified) (6 diffs)
- branches/dmd-1.x/src/mtype.h (modified) (2 diffs)
- branches/dmd-1.x/src/statement.c (modified) (4 diffs)
- trunk/src/aggregate.h (modified) (1 diff)
- trunk/src/class.c (modified) (3 diffs)
- trunk/src/clone.c (modified) (1 diff)
- trunk/src/declaration.c (modified) (5 diffs)
- trunk/src/declaration.h (modified) (2 diffs)
- trunk/src/expression.c (modified) (1 diff)
- trunk/src/func.c (modified) (2 diffs)
- trunk/src/mtype.c (modified) (7 diffs)
- trunk/src/mtype.h (modified) (2 diffs)
- trunk/src/statement.c (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/dmd-1.x/src/aggregate.h
r638 r639 203 203 CtorDeclaration *defaultCtor; // default constructor 204 204 #endif 205 205 FuncDeclaration *staticCtor; 206 206 FuncDeclaration *staticDtor; 207 207 Array vtbl; // Array of FuncDeclaration's making up the vtbl[] 208 208 Array vtblFinal; // More FuncDeclaration's that aren't in vtbl[] 209 209 210 210 BaseClasses *baseclasses; // Array of BaseClass's; first is super, 211 211 // rest are Interface's 212 212 213 213 int interfaces_dim; 214 214 BaseClass **interfaces; // interfaces[interfaces_dim] for this class 215 215 // (does not include baseClass) 216 216 217 217 BaseClasses *vtblInterfaces; // array of base interfaces that have 218 218 // their own vtbl[] 219 219 220 220 ClassInfoDeclaration *vclassinfo; // the ClassInfo object for this ClassDeclaration 221 221 int com; // !=0 if this is a COM class (meaning 222 222 // it derives from IUnknown) 223 int is auto;// !=0 if this is an auto class223 int isscope; // !=0 if this is an auto class 224 224 int isabstract; // !=0 if abstract class 225 225 #if DMDV1 226 226 int isnested; // !=0 if is nested 227 227 VarDeclaration *vthis; // 'this' parameter if this class is nested 228 228 #endif 229 229 int inuse; // to prevent recursive attempts 230 230 231 231 ClassDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses); 232 232 Dsymbol *syntaxCopy(Dsymbol *s); 233 233 void semantic(Scope *sc); 234 234 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 235 235 int isBaseOf2(ClassDeclaration *cd); 236 236 237 237 #define OFFSET_RUNTIME 0x76543210 238 238 virtual int isBaseOf(ClassDeclaration *cd, int *poffset); 239 239 240 240 virtual int isBaseInfoComplete(); 241 241 Dsymbol *search(Loc, Identifier *ident, int flags); 242 242 #if DMDV2 243 243 int isFuncHidden(FuncDeclaration *fd); branches/dmd-1.x/src/class.c
r638 r639 174 174 if (id == Id::Object) 175 175 { if (object) 176 176 object->error("%s", msg); 177 177 object = this; 178 178 } 179 179 180 180 if (id == Id::ClassInfo) 181 181 { if (classinfo) 182 182 classinfo->error("%s", msg); 183 183 classinfo = this; 184 184 } 185 185 186 186 if (id == Id::ModuleInfo) 187 187 { if (Module::moduleinfo) 188 188 Module::moduleinfo->error("%s", msg); 189 189 Module::moduleinfo = this; 190 190 } 191 191 } 192 192 193 193 com = 0; 194 is auto= 0;194 isscope = 0; 195 195 isabstract = 0; 196 196 isnested = 0; 197 197 vthis = NULL; 198 198 inuse = 0; 199 199 } 200 200 201 201 Dsymbol *ClassDeclaration::syntaxCopy(Dsymbol *s) 202 202 { 203 203 ClassDeclaration *cd; 204 204 205 205 //printf("ClassDeclaration::syntaxCopy('%s')\n", toChars()); 206 206 if (s) 207 207 cd = (ClassDeclaration *)s; 208 208 else 209 209 cd = new ClassDeclaration(loc, ident, NULL); 210 210 211 211 cd->storage_class |= storage_class; 212 212 213 213 cd->baseclasses->setDim(this->baseclasses->dim); 214 214 for (int i = 0; i < cd->baseclasses->dim; i++) … … 454 454 } 455 455 456 456 interfaces_dim = baseclasses->dim; 457 457 interfaces = (BaseClass **)baseclasses->data; 458 458 459 459 460 460 if (baseClass) 461 461 { 462 462 if (baseClass->storage_class & STCfinal) 463 463 error("cannot inherit from final class %s", baseClass->toChars()); 464 464 465 465 interfaces_dim--; 466 466 interfaces++; 467 467 468 468 // Copy vtbl[] from base class 469 469 vtbl.setDim(baseClass->vtbl.dim); 470 470 memcpy(vtbl.data, baseClass->vtbl.data, sizeof(void *) * vtbl.dim); 471 471 472 472 // Inherit properties from base class 473 473 com = baseClass->isCOMclass(); 474 is auto = baseClass->isauto;474 isscope = baseClass->isscope; 475 475 vthis = baseClass->vthis; 476 476 } 477 477 else 478 478 { 479 479 // No base class, so this is the root of the class hierarchy 480 480 vtbl.setDim(0); 481 481 vtbl.push(this); // leave room for classinfo as first member 482 482 } 483 483 484 484 protection = sc->protection; 485 485 storage_class |= sc->stc; 486 486 487 487 if (sizeok == 0) 488 488 { 489 489 interfaceSemantic(sc); 490 490 491 491 for (i = 0; i < members->dim; i++) 492 492 { 493 493 Dsymbol *s = (Dsymbol *)members->data[i]; 494 494 s->addMember(sc, this, 1); … … 536 536 else if (fd) 537 537 { AggregateDeclaration *ad = fd->isMember2(); 538 538 if (ad) 539 539 t = ad->handle; 540 540 else 541 541 { 542 542 t = new TypePointer(Type::tvoid); 543 543 t = t->semantic(0, sc); 544 544 } 545 545 } 546 546 else 547 547 assert(0); 548 548 assert(!vthis); 549 549 vthis = new ThisDeclaration(loc, t); 550 550 members->push(vthis); 551 551 } 552 552 } 553 553 } 554 554 } 555 555 556 if (storage_class & (STCauto | STCscope)) 557 isauto = 1; 556 if (storage_class & STCauto) 557 error("storage class 'auto' is invalid when declaring a class, did you mean to use 'scope'?"); 558 if (storage_class & STCscope) 559 isscope = 1; 558 560 if (storage_class & STCabstract) 559 561 isabstract = 1; 560 562 561 563 sc = sc->push(this); 562 564 sc->stc &= ~(STCfinal | STCauto | STCscope | STCstatic | 563 565 STCabstract | STCdeprecated); 564 566 sc->parent = this; 565 567 sc->inunion = 0; 566 568 567 569 if (isCOMclass()) 568 570 { 569 571 #if _WIN32 570 572 sc->linkage = LINKwindows; 571 573 #else 572 574 /* This enables us to use COM objects under Linux and 573 575 * work with things like XPCOM 574 576 */ 575 577 sc->linkage = LINKc; 576 578 #endif 577 579 } branches/dmd-1.x/src/declaration.c
r608 r639 657 657 658 658 VarDeclaration::VarDeclaration(Loc loc, Type *type, Identifier *id, Initializer *init) 659 659 : Declaration(id) 660 660 { 661 661 //printf("VarDeclaration('%s')\n", id->toChars()); 662 662 #ifdef DEBUG 663 663 if (!type && !init) 664 664 { printf("VarDeclaration('%s')\n", id->toChars()); 665 665 //*(char*)0=0; 666 666 } 667 667 #endif 668 668 assert(type || init); 669 669 this->type = type; 670 670 this->init = init; 671 671 #ifdef _DH 672 672 this->htype = NULL; 673 673 this->hinit = NULL; 674 674 #endif 675 675 this->loc = loc; 676 676 offset = 0; 677 no auto= 0;677 noscope = 0; 678 678 #if DMDV2 679 679 isargptr = FALSE; 680 680 #endif 681 681 #if DMDV1 682 682 nestedref = 0; 683 683 #endif 684 684 ctorinit = 0; 685 685 aliassym = NULL; 686 686 onstack = 0; 687 687 canassign = 0; 688 688 value = NULL; 689 689 } 690 690 691 691 Dsymbol *VarDeclaration::syntaxCopy(Dsymbol *s) 692 692 { 693 693 //printf("VarDeclaration::syntaxCopy(%s)\n", toChars()); 694 694 695 695 VarDeclaration *sv; 696 696 if (s) 697 697 { sv = (VarDeclaration *)s; … … 787 787 788 788 Type *tb = type->toBasetype(); 789 789 if (tb->ty == Tvoid && !(storage_class & STClazy)) 790 790 { error("voids have no value"); 791 791 type = Type::terror; 792 792 tb = type; 793 793 } 794 794 if (tb->ty == Tfunction) 795 795 { error("cannot be declared to be a function"); 796 796 type = Type::terror; 797 797 tb = type; 798 798 } 799 799 if (tb->ty == Tstruct) 800 800 { TypeStruct *ts = (TypeStruct *)tb; 801 801 802 802 if (!ts->sym->members) 803 803 { 804 804 error("no definition of struct %s", ts->toChars()); 805 805 } 806 806 } 807 if ((storage_class & STCauto) && !inferred) 808 error("storage class 'auto' has no effect if type is not inferred, did you mean 'scope'?"); 807 809 808 810 if (tb->ty == Ttuple) 809 811 { /* Instead, declare variables for each of the tuple elements 810 812 * and add those. 811 813 */ 812 814 TypeTuple *tt = (TypeTuple *)tb; 813 815 size_t nelems = Parameter::dim(tt->arguments); 814 816 Objects *exps = new Objects(); 815 817 exps->setDim(nelems); 816 818 Expression *ie = init ? init->toExpression() : NULL; 817 819 818 820 for (size_t i = 0; i < nelems; i++) 819 821 { Parameter *arg = Parameter::getNth(tt->arguments, i); 820 822 821 823 OutBuffer buf; 822 824 buf.printf("_%s_field_%zu", ident->toChars(), i); 823 825 buf.writeByte(0); 824 826 const char *name = (const char *)buf.extractData(); 825 827 Identifier *id = Lexer::idPool(name); 826 828 … … 920 922 ti = ti2; 921 923 } 922 924 923 925 // If it's a member template 924 926 AggregateDeclaration *ad = ti->tempdecl->isMember(); 925 927 if (ad && storage_class != STCundefined) 926 928 { 927 929 error("cannot use template to add field to aggregate '%s'", ad->toChars()); 928 930 } 929 931 } 930 932 } 931 933 932 934 #if DMDV2 933 935 if ((storage_class & (STCref | STCparameter | STCforeach)) == STCref && 934 936 ident != Id::This) 935 937 { 936 938 error("only parameters or foreach declarations can be ref"); 937 939 } 938 940 #endif 939 941 940 if (type->is auto() && !noauto)942 if (type->isscope() && !noscope) 941 943 { 942 944 if (storage_class & (STCfield | STCout | STCref | STCstatic) || !fd) 943 945 { 944 946 error("globals, statics, fields, ref and out parameters cannot be auto"); 945 947 } 946 948 947 if (!(storage_class & (STCauto | STCscope)))949 if (!(storage_class & STCscope)) 948 950 { 949 951 if (!(storage_class & STCparameter) && ident != Id::withSym) 950 952 error("reference to scope class must be scope"); 951 953 } 952 954 } 953 955 954 956 enum TOK op = TOKconstruct; 955 957 if (!init && !sc->inunion && !isStatic() && !isConst() && fd && 956 958 !(storage_class & (STCfield | STCin | STCforeach)) && 957 959 type->size() != 0) 958 960 { 959 961 // Provide a default initializer 960 962 //printf("Providing default initializer for '%s'\n", toChars()); 961 963 if (type->ty == Tstruct && 962 964 ((TypeStruct *)type)->sym->zeroInit == 1) 963 965 { /* If a struct is all zeros, as a special case 964 966 * set it's initializer to the integer 0. 965 967 * In AssignExp::toElem(), we check for this and issue 966 968 * a memset() to initialize the struct. 967 969 * Must do same check in interpreter. … … 1361 1363 } 1362 1364 1363 1365 /******************************************** 1364 1366 * Can variable be read and written by CTFE? 1365 1367 */ 1366 1368 1367 1369 int VarDeclaration::isCTFE() 1368 1370 { 1369 1371 //printf("VarDeclaration::isCTFE(%p, '%s')\n", this, toChars()); 1370 1372 //printf("%llx\n", storage_class); 1371 1373 return (storage_class & STCctfe) != 0; // || !isDataseg(); 1372 1374 } 1373 1375 1374 1376 int VarDeclaration::hasPointers() 1375 1377 { 1376 1378 //printf("VarDeclaration::hasPointers() %s, ty = %d\n", toChars(), type->ty); 1377 1379 return (!isDataseg() && type->hasPointers()); 1378 1380 } 1379 1381 1380 1382 /****************************************** 1381 * If a variable has a n autodestructor call, return call for it.1383 * If a variable has a scope destructor call, return call for it. 1382 1384 * Otherwise, return NULL. 1383 1385 */ 1384 1386 1385 Expression *VarDeclaration::call AutoDtor(Scope *sc)1387 Expression *VarDeclaration::callScopeDtor(Scope *sc) 1386 1388 { Expression *e = NULL; 1387 1389 1388 //printf("VarDeclaration::call AutoDtor() %s\n", toChars());1389 if (storage_class & (STCauto | STCscope) && !no auto)1390 //printf("VarDeclaration::callScopeDtor() %s\n", toChars()); 1391 if (storage_class & (STCauto | STCscope) && !noscope) 1390 1392 { 1391 1393 for (ClassDeclaration *cd = type->isClassHandle(); 1392 1394 cd; 1393 1395 cd = cd->baseClass) 1394 1396 { 1395 1397 /* We can do better if there's a way with onstack 1396 1398 * classes to determine if there's no way the monitor 1397 1399 * could be set. 1398 1400 */ 1399 1401 //if (cd->isInterfaceDeclaration()) 1400 1402 //error("interface %s cannot be scope", cd->toChars()); 1401 1403 if (1 || onstack || cd->dtors.dim) // if any destructors 1402 1404 { 1403 1405 // delete this; 1404 1406 Expression *ec; 1405 1407 1406 1408 ec = new VarExp(loc, this); 1407 1409 e = new DeleteExp(loc, ec); 1408 1410 e->type = Type::tvoid; 1409 1411 break; … … 1575 1577 1576 1578 TypeInfoDelegateDeclaration::TypeInfoDelegateDeclaration(Type *tinfo) 1577 1579 : TypeInfoDeclaration(tinfo, 0) 1578 1580 { 1579 1581 } 1580 1582 1581 1583 /***************************** TypeInfoTupleDeclaration **********************/ 1582 1584 1583 1585 TypeInfoTupleDeclaration::TypeInfoTupleDeclaration(Type *tinfo) 1584 1586 : TypeInfoDeclaration(tinfo, 0) 1585 1587 { 1586 1588 } 1587 1589 1588 1590 /********************************* ThisDeclaration ****************************/ 1589 1591 1590 1592 // For the "this" parameter to member functions 1591 1593 1592 1594 ThisDeclaration::ThisDeclaration(Loc loc, Type *t) 1593 1595 : VarDeclaration(loc, t, Id::This, NULL) 1594 1596 { 1595 no auto= 1;1597 noscope = 1; 1596 1598 } 1597 1599 1598 1600 Dsymbol *ThisDeclaration::syntaxCopy(Dsymbol *s) 1599 1601 { 1600 1602 assert(0); // should never be produced by syntax 1601 1603 return NULL; 1602 1604 } 1603 1605 branches/dmd-1.x/src/declaration.h
r591 r639 124 124 void checkModify(Loc loc, Scope *sc, Type *t); 125 125 126 126 void emitComment(Scope *sc); 127 127 void toJsonBuffer(OutBuffer *buf); 128 128 void toDocBuffer(OutBuffer *buf); 129 129 130 130 char *mangle(); 131 131 int isStatic() { return storage_class & STCstatic; } 132 132 virtual int isStaticConstructor(); 133 133 virtual int isStaticDestructor(); 134 134 virtual int isDelete(); 135 135 virtual int isDataseg(); 136 136 virtual int isThreadlocal(); 137 137 virtual int isCodeseg(); 138 138 int isCtorinit() { return storage_class & STCctorinit; } 139 139 int isFinal() { return storage_class & STCfinal; } 140 140 int isAbstract() { return storage_class & STCabstract; } 141 141 int isConst() { return storage_class & STCconst; } 142 142 int isImmutable() { return storage_class & STCimmutable; } 143 143 int isAuto() { return storage_class & STCauto; } 144 int isScope() { return storage_class & (STCscope | STCauto); }144 int isScope() { return storage_class & STCscope; } 145 145 int isSynchronized() { return storage_class & STCsynchronized; } 146 146 int isParameter() { return storage_class & STCparameter; } 147 147 int isDeprecated() { return storage_class & STCdeprecated; } 148 148 int isOverride() { return storage_class & STCoverride; } 149 149 150 150 int isIn() { return storage_class & STCin; } 151 151 int isOut() { return storage_class & STCout; } 152 152 int isRef() { return storage_class & STCref; } 153 153 154 154 enum PROT prot(); 155 155 156 156 Declaration *isDeclaration() { return this; } 157 157 }; 158 158 159 159 /**************************************************************/ 160 160 161 161 struct TupleDeclaration : Declaration 162 162 { 163 163 Objects *objects; 164 164 int isexp; // 1: expression tuple … … 226 226 const char *kind(); 227 227 Type *getType(); 228 228 Dsymbol *toAlias(); 229 229 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 230 230 #ifdef _DH 231 231 Type *htype; 232 232 Dsymbol *haliassym; 233 233 #endif 234 234 235 235 void toDocBuffer(OutBuffer *buf); 236 236 237 237 AliasDeclaration *isAliasDeclaration() { return this; } 238 238 }; 239 239 240 240 /**************************************************************/ 241 241 242 242 struct VarDeclaration : Declaration 243 243 { 244 244 Initializer *init; 245 245 unsigned offset; 246 int no auto; // no auto semantics246 int noscope; // no auto semantics 247 247 #if DMDV2 248 248 FuncDeclarations nestedrefs; // referenced by these lexically nested functions 249 249 bool isargptr; // if parameter that _argptr points to 250 250 #else 251 251 int nestedref; // referenced by a lexically nested function 252 252 #endif 253 253 int ctorinit; // it has been initialized in a ctor 254 254 int onstack; // 1: it has been allocated on the stack 255 255 // 2: on stack, run destructor anyway 256 256 int canassign; // it can be assigned to 257 257 Dsymbol *aliassym; // if redone as alias to another symbol 258 258 Expression *value; // when interpreting, this is the value 259 259 // (NULL if value not determinable) 260 260 #if DMDV2 261 261 VarDeclaration *rundtor; // if !NULL, rundtor is tested at runtime to see 262 262 // if the destructor should be run. Used to prevent 263 263 // dtor calls on postblitted vars 264 264 #endif 265 265 266 266 VarDeclaration(Loc loc, Type *t, Identifier *id, Initializer *init); 267 267 Dsymbol *syntaxCopy(Dsymbol *); 268 268 void semantic(Scope *sc); 269 269 void semantic2(Scope *sc); 270 270 const char *kind(); 271 271 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 272 272 #ifdef _DH 273 273 Type *htype; 274 274 Initializer *hinit; 275 275 #endif 276 276 int needThis(); 277 277 int isImportedSymbol(); 278 278 int isDataseg(); 279 279 int isThreadlocal(); 280 280 int isCTFE(); 281 281 int hasPointers(); 282 282 #if DMDV2 283 283 int canTakeAddressOf(); 284 284 int needsAutoDtor(); 285 285 #endif 286 Expression *call AutoDtor(Scope *sc);286 Expression *callScopeDtor(Scope *sc); 287 287 ExpInitializer *getExpInitializer(); 288 288 Expression *getConstInitializer(); 289 289 void checkCtorConstInit(); 290 290 void checkNestedReference(Scope *sc, Loc loc); 291 291 Dsymbol *toAlias(); 292 292 293 293 Symbol *toSymbol(); 294 294 void toObjFile(int multiobj); // compile to .obj file 295 295 int cvMember(unsigned char *p); 296 296 297 297 // Eliminate need for dynamic_cast 298 298 VarDeclaration *isVarDeclaration() { return (VarDeclaration *)this; } 299 299 }; 300 300 301 301 /**************************************************************/ 302 302 303 303 // This is a shell around a back end symbol 304 304 305 305 struct SymbolDeclaration : Declaration 306 306 { branches/dmd-1.x/src/expression.c
r637 r639 3990 3990 } 3991 3991 3992 3992 char *VarExp::toChars() 3993 3993 { 3994 3994 return var->toChars(); 3995 3995 } 3996 3996 3997 3997 void VarExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 3998 3998 { 3999 3999 buf->writestring(var->toChars()); 4000 4000 } 4001 4001 4002 4002 void VarExp::checkEscape() 4003 4003 { 4004 4004 VarDeclaration *v = var->isVarDeclaration(); 4005 4005 if (v) 4006 4006 { Type *tb = v->type->toBasetype(); 4007 4007 // if reference type 4008 4008 if (tb->ty == Tarray || tb->ty == Tsarray || tb->ty == Tclass) 4009 4009 { 4010 if ( (v->isAuto() || v->isScope()) && !v->noauto)4010 if (v->isScope() && !v->noscope) 4011 4011 error("escaping reference to auto local %s", v->toChars()); 4012 4012 else if (v->storage_class & STCvariadic) 4013 4013 error("escaping reference to variadic parameter %s", v->toChars()); 4014 4014 } 4015 4015 } 4016 4016 } 4017 4017 4018 4018 void VarExp::checkEscapeRef() 4019 4019 { 4020 4020 VarDeclaration *v = var->isVarDeclaration(); 4021 4021 if (v) 4022 4022 { 4023 4023 if (!v->isDataseg() && !(v->storage_class & (STCref | STCout))) 4024 4024 error("escaping reference to local variable %s", v->toChars()); 4025 4025 } 4026 4026 } 4027 4027 4028 4028 #if DMDV2 4029 4029 int VarExp::isLvalue() 4030 4030 { branches/dmd-1.x/src/func.c
r603 r639 940 940 if (type->nextOf()->ty == Tvoid) 941 941 { 942 942 if (outId) 943 943 error("void functions have no result"); 944 944 } 945 945 else 946 946 { 947 947 if (!outId) 948 948 outId = Id::result; // provide a default 949 949 } 950 950 951 951 if (outId) 952 952 { // Declare result variable 953 953 VarDeclaration *v; 954 954 Loc loc = this->loc; 955 955 956 956 if (fensure) 957 957 loc = fensure->loc; 958 958 959 959 v = new VarDeclaration(loc, type->nextOf(), outId, NULL); 960 v->no auto= 1;960 v->noscope = 1; 961 961 #if DMDV2 962 962 if (!isVirtual()) 963 963 v->storage_class |= STCconst; 964 964 if (f->isref) 965 965 { 966 966 v->storage_class |= STCref | STCforeach; 967 967 } 968 968 #endif 969 969 sc2->incontract--; 970 970 v->semantic(sc2); 971 971 sc2->incontract++; 972 972 if (!sc2->insert(v)) 973 973 error("out result %s is already defined", v->toChars()); 974 974 v->parent = this; 975 975 vresult = v; 976 976 977 977 // vresult gets initialized with the function return value 978 978 // in ReturnStatement::semantic() 979 979 } 980 980 … … 1350 1350 1351 1351 fbody = new CompoundStatement(0, a); 1352 1352 #if DMDV2 1353 1353 /* Append destructor calls for parameters as finally blocks. 1354 1354 */ 1355 1355 if (parameters) 1356 1356 { for (size_t i = 0; i < parameters->dim; i++) 1357 1357 { 1358 1358 VarDeclaration *v = (VarDeclaration *)parameters->data[i]; 1359 1359 1360 1360 if (v->storage_class & (STCref | STCout)) 1361 1361 continue; 1362 1362 1363 1363 /* Don't do this for static arrays, since static 1364 1364 * arrays are called by reference. Remove this 1365 1365 * when we change them to call by value. 1366 1366 */ 1367 1367 if (v->type->toBasetype()->ty == Tsarray) 1368 1368 continue; 1369 1369 1370 Expression *e = v->call AutoDtor(sc);1370 Expression *e = v->callScopeDtor(sc); 1371 1371 if (e) 1372 1372 { Statement *s = new ExpStatement(0, e); 1373 1373 s = s->semantic(sc); 1374 1374 if (fbody->blockExit() == BEfallthru) 1375 1375 fbody = new CompoundStatement(0, fbody, s); 1376 1376 else 1377 1377 fbody = new TryFinallyStatement(0, fbody, s); 1378 1378 } 1379 1379 } 1380 1380 } 1381 1381 #endif 1382 1382 1383 1383 #if 1 1384 1384 if (isSynchronized()) 1385 1385 { /* Wrap the entire function body in a synchronized statement 1386 1386 */ 1387 1387 ClassDeclaration *cd = parent->isClassDeclaration(); 1388 1388 if (cd) 1389 1389 { 1390 1390 #if TARGET_WINDOS branches/dmd-1.x/src/mtype.c
r619 r639 487 487 int Type::iscomplex() 488 488 { 489 489 return FALSE; 490 490 } 491 491 492 492 int Type::isscalar() 493 493 { 494 494 return FALSE; 495 495 } 496 496 497 497 int Type::isunsigned() 498 498 { 499 499 return FALSE; 500 500 } 501 501 502 502 ClassDeclaration *Type::isClassHandle() 503 503 { 504 504 return NULL; 505 505 } 506 506 507 int Type::is auto()507 int Type::isscope() 508 508 { 509 509 return FALSE; 510 510 } 511 511 512 512 int Type::isString() 513 513 { 514 514 return FALSE; 515 515 } 516 516 517 517 int Type::checkBoolean() 518 518 { 519 519 return isscalar(); 520 520 } 521 521 522 522 /********************************* 523 523 * Check type to see if it is based on a deprecated symbol. 524 524 */ 525 525 526 526 void Type::checkDeprecated(Loc loc, Scope *sc) 527 527 { … … 1910 1910 { 1911 1911 case Ttuple: 1912 1912 { // Index the tuple to get the type 1913 1913 assert(dim); 1914 1914 TypeTuple *tt = (TypeTuple *)tbn; 1915 1915 uinteger_t d = dim->toUInteger(); 1916 1916 1917 1917 if (d >= tt->arguments->dim) 1918 1918 { error(loc, "tuple index %ju exceeds %u", d, tt->arguments->dim); 1919 1919 return Type::terror; 1920 1920 } 1921 1921 Parameter *arg = (Parameter *)tt->arguments->data[(size_t)d]; 1922 1922 return arg->type; 1923 1923 } 1924 1924 case Tfunction: 1925 1925 case Tnone: 1926 1926 error(loc, "can't have array of %s", tbn->toChars()); 1927 1927 tbn = next = tint32; 1928 1928 break; 1929 1929 } 1930 if (tbn->is auto())1930 if (tbn->isscope()) 1931 1931 error(loc, "cannot have array of auto %s", tbn->toChars()); 1932 1932 return merge(); 1933 1933 } 1934 1934 1935 1935 void TypeSArray::toDecoBuffer(OutBuffer *buf) 1936 1936 { 1937 1937 buf->writeByte(mangleChar[ty]); 1938 1938 if (dim) 1939 1939 buf->printf("%ju", dim->toInteger()); 1940 1940 if (next) 1941 1941 next->toDecoBuffer(buf); 1942 1942 } 1943 1943 1944 1944 void TypeSArray::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) 1945 1945 { 1946 1946 if (mod != this->mod) 1947 1947 { toCBuffer3(buf, hgs, mod); 1948 1948 return; 1949 1949 } 1950 1950 next->toCBuffer2(buf, hgs, this->mod); … … 2088 2088 { 2089 2089 // A DArray consists of two ptr-sized values, so align it on pointer size 2090 2090 // boundary 2091 2091 return PTRSIZE; 2092 2092 } 2093 2093 2094 2094 Type *TypeDArray::semantic(Loc loc, Scope *sc) 2095 2095 { Type *tn = next; 2096 2096 2097 2097 tn = next->semantic(loc,sc); 2098 2098 Type *tbn = tn->toBasetype(); 2099 2099 switch (tbn->ty) 2100 2100 { 2101 2101 case Tfunction: 2102 2102 case Tnone: 2103 2103 case Ttuple: 2104 2104 error(loc, "can't have array of %s", tbn->toChars()); 2105 2105 tn = next = tint32; 2106 2106 break; 2107 2107 } 2108 if (tn->is auto())2109 error(loc, "cannot have array of auto%s", tn->toChars());2108 if (tn->isscope()) 2109 error(loc, "cannot have array of scope %s", tn->toChars()); 2110 2110 if (next != tn) 2111 2111 //deco = NULL; // redo 2112 2112 return tn->arrayOf(); 2113 2113 return merge(); 2114 2114 } 2115 2115 2116 2116 void TypeDArray::toDecoBuffer(OutBuffer *buf) 2117 2117 { 2118 2118 buf->writeByte(mangleChar[ty]); 2119 2119 if (next) 2120 2120 next->toDecoBuffer(buf); 2121 2121 } 2122 2122 2123 2123 void TypeDArray::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) 2124 2124 { 2125 2125 if (mod != this->mod) 2126 2126 { toCBuffer3(buf, hgs, mod); 2127 2127 return; 2128 2128 } 2129 2129 next->toCBuffer2(buf, hgs, this->mod); … … 2285 2285 key = key->next->arrayOf(); 2286 2286 #endif 2287 2287 break; 2288 2288 case Tbit: 2289 2289 case Tbool: 2290 2290 case Tfunction: 2291 2291 case Tvoid: 2292 2292 case Tnone: 2293 2293 case Ttuple: 2294 2294 error(loc, "can't have associative array key of %s", key->toChars()); 2295 2295 break; 2296 2296 } 2297 2297 next = next->semantic(loc,sc); 2298 2298 switch (next->toBasetype()->ty) 2299 2299 { 2300 2300 case Tfunction: 2301 2301 case Tnone: 2302 2302 error(loc, "can't have associative array of %s", next->toChars()); 2303 2303 break; 2304 2304 } 2305 if (next->is auto())2305 if (next->isscope()) 2306 2306 error(loc, "cannot have array of auto %s", next->toChars()); 2307 2307 2308 2308 return merge(); 2309 2309 } 2310 2310 2311 2311 void TypeAArray::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps) 2312 2312 { 2313 2313 //printf("TypeAArray::resolve() %s\n", toChars()); 2314 2314 2315 2315 // Deal with the case where we thought the index was a type, but 2316 2316 // in reality it was an expression. 2317 2317 if (index->ty == Tident || index->ty == Tinstance || index->ty == Tsarray) 2318 2318 { 2319 2319 Expression *e; 2320 2320 Type *t; 2321 2321 Dsymbol *s; 2322 2322 2323 2323 index->resolve(loc, sc, &e, &t, &s); 2324 2324 if (e) 2325 2325 { // It was an expression - … … 2855 2855 } 2856 2856 2857 2857 tf->linkage = sc->linkage; 2858 2858 if (tf->next) 2859 2859 { 2860 2860 tf->next = tf->next->semantic(loc,sc); 2861 2861 #if !SARRAYVALUE 2862 2862 if (tf->next->toBasetype()->ty == Tsarray) 2863 2863 { error(loc, "functions cannot return static array %s", tf->next->toChars()); 2864 2864 tf->next = Type::terror; 2865 2865 } 2866 2866 #endif 2867 2867 if (tf->next->toBasetype()->ty == Tfunction) 2868 2868 { error(loc, "functions cannot return a function"); 2869 2869 tf->next = Type::terror; 2870 2870 } 2871 2871 if (tf->next->toBasetype()->ty == Ttuple) 2872 2872 { error(loc, "functions cannot return a tuple"); 2873 2873 tf->next = Type::terror; 2874 2874 } 2875 if (tf->next->is auto() && !(sc->flags & SCOPEctor))2876 error(loc, "functions cannot return auto%s", tf->next->toChars());2875 if (tf->next->isscope() && !(sc->flags & SCOPEctor)) 2876 error(loc, "functions cannot return scope %s", tf->next->toChars()); 2877 2877 } 2878 2878 2879 2879 if (tf->parameters) 2880 2880 { 2881 2881 /* Create a scope for evaluating the default arguments for the parameters 2882 2882 */ 2883 2883 Scope *argsc = sc->push(); 2884 2884 argsc->stc = 0; // don't inherit storage class 2885 2885 argsc->protection = PROTpublic; 2886 2886 2887 2887 size_t dim = Parameter::dim(tf->parameters); 2888 2888 for (size_t i = 0; i < dim; i++) 2889 2889 { Parameter *fparam = Parameter::getNth(tf->parameters, i); 2890 2890 2891 2891 tf->inuse++; 2892 2892 fparam->type = fparam->type->semantic(loc, argsc); 2893 2893 if (tf->inuse == 1) tf->inuse--; 2894 2894 2895 2895 Type *t = fparam->type->toBasetype(); 2896 2896 … … 4995 4995 if (d->parent && d->toParent()->isModule()) 4996 4996 { 4997 4997 // (e, d) 4998 4998 VarExp *ve; 4999 4999 5000 5000 ve = new VarExp(e->loc, d); 5001 5001 e = new CommaExp(e->loc, e, ve); 5002 5002 e->type = d->type; 5003 5003 return e; 5004 5004 } 5005 5005 5006 5006 de = new DotVarExp(e->loc, e, d); 5007 5007 return de->semantic(sc); 5008 5008 } 5009 5009 5010 5010 ClassDeclaration *TypeClass::isClassHandle() 5011 5011 { 5012 5012 return sym; 5013 5013 } 5014 5014 5015 int TypeClass::is auto()5016 { 5017 return sym->is auto;5015 int TypeClass::isscope() 5016 { 5017 return sym->isscope; 5018 5018 } 5019 5019 5020 5020 int TypeClass::isBaseOf(Type *t, int *poffset) 5021 5021 { 5022 5022 if (t->ty == Tclass) 5023 5023 { ClassDeclaration *cd; 5024 5024 5025 5025 cd = ((TypeClass *)t)->sym; 5026 5026 if (sym->isBaseOf(cd, poffset)) 5027 5027 return 1; 5028 5028 } 5029 5029 return 0; 5030 5030 } 5031 5031 5032 5032 MATCH TypeClass::implicitConvTo(Type *to) 5033 5033 { 5034 5034 //printf("TypeClass::implicitConvTo('%s')\n", to->toChars()); 5035 5035 if (this == to) 5036 5036 return MATCHexact; 5037 5037 branches/dmd-1.x/src/mtype.h
r619 r639 200 200 static char needThisPrefix(); 201 201 static void init(); 202 202 d_uns64 size(); 203 203 virtual d_uns64 size(Loc loc); 204 204 virtual unsigned alignsize(); 205 205 virtual Type *semantic(Loc loc, Scope *sc); 206 206 virtual void toDecoBuffer(OutBuffer *buf); 207 207 Type *merge(); 208 208 Type *merge2(); 209 209 virtual void toCBuffer(OutBuffer *buf, Identifier *ident, HdrGenState *hgs); 210 210 virtual void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod); 211 211 void toCBuffer3(OutBuffer *buf, HdrGenState *hgs, int mod); 212 212 virtual int isbit(); 213 213 virtual int isintegral(); 214 214 virtual int isfloating(); // real, imaginary, or complex 215 215 virtual int isreal(); 216 216 virtual int isimaginary(); 217 217 virtual int iscomplex(); 218 218 virtual int isscalar(); 219 219 virtual int isunsigned(); 220 virtual int is auto();220 virtual int isscope(); 221 221 virtual int isString(); 222 222 virtual int checkBoolean(); // if can be converted to boolean value 223 223 void checkDeprecated(Loc loc, Scope *sc); 224 224 Type *pointerTo(); 225 225 Type *referenceTo(); 226 226 Type *arrayOf(); 227 227 virtual Dsymbol *toDsymbol(Scope *sc); 228 228 virtual Type *toBasetype(); 229 229 virtual int isBaseOf(Type *t, int *poffset); 230 230 virtual MATCH implicitConvTo(Type *to); 231 231 virtual ClassDeclaration *isClassHandle(); 232 232 virtual Expression *getProperty(Loc loc, Identifier *ident); 233 233 virtual Expression *dotExp(Scope *sc, Expression *e, Identifier *ident); 234 234 virtual unsigned memalign(unsigned salign); 235 235 virtual Expression *defaultInit(Loc loc = 0); 236 236 virtual Expression *defaultInitLiteral(Loc loc = 0); 237 237 virtual int isZeroInit(Loc loc = 0); // if initializer is 0 238 238 virtual dt_t **toDt(dt_t **pdt); 239 239 Identifier *getTypeInfoIdent(int internal); 240 240 virtual MATCH deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes); … … 654 654 655 655 struct TypeClass : Type 656 656 { 657 657 ClassDeclaration *sym; 658 658 659 659 TypeClass(ClassDeclaration *sym); 660 660 d_uns64 size(Loc loc); 661 661 char *toChars(); 662 662 Type *syntaxCopy(); 663 663 Type *semantic(Loc loc, Scope *sc); 664 664 Dsymbol *toDsymbol(Scope *sc); 665 665 void toDecoBuffer(OutBuffer *buf); 666 666 void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod); 667 667 Expression *dotExp(Scope *sc, Expression *e, Identifier *ident); 668 668 ClassDeclaration *isClassHandle(); 669 669 int isBaseOf(Type *t, int *poffset); 670 670 MATCH implicitConvTo(Type *to); 671 671 Expression *defaultInit(Loc loc); 672 672 int isZeroInit(Loc loc); 673 673 MATCH deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes); 674 int is auto();674 int isscope(); 675 675 int checkBoolean(); 676 676 TypeInfoDeclaration *getTypeInfoDeclaration(); 677 677 int hasPointers(); 678 678 int builtinTypeInfo(); 679 679 #if DMDV2 680 680 Type *toHeadMutable(); 681 681 MATCH constConv(Type *to); 682 682 #if CPP_MANGLE 683 683 void toCppMangle(OutBuffer *buf, CppMangleState *cms); 684 684 #endif 685 685 #endif 686 686 687 687 type *toCtype(); 688 688 689 689 Symbol *toSymbol(); 690 690 }; 691 691 692 692 struct TypeTuple : Type 693 693 { 694 694 Parameters *arguments; // types making up the tuple branches/dmd-1.x/src/statement.c
r586 r639 353 353 } 354 354 355 355 void DeclarationStatement::scopeCode(Scope *sc, Statement **sentry, Statement **sexception, Statement **sfinally) 356 356 { 357 357 //printf("DeclarationStatement::scopeCode()\n"); 358 358 //print(); 359 359 360 360 *sentry = NULL; 361 361 *sexception = NULL; 362 362 *sfinally = NULL; 363 363 364 364 if (exp) 365 365 { 366 366 if (exp->op == TOKdeclaration) 367 367 { 368 368 DeclarationExp *de = (DeclarationExp *)(exp); 369 369 VarDeclaration *v = de->declaration->isVarDeclaration(); 370 370 if (v) 371 371 { Expression *e; 372 372 373 e = v->call AutoDtor(sc);373 e = v->callScopeDtor(sc); 374 374 if (e) 375 375 { 376 376 //printf("dtor is: "); e->print(); 377 377 *sfinally = new ExpStatement(loc, e); 378 378 } 379 379 } 380 380 } 381 381 } 382 382 } 383 383 384 384 void DeclarationStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 385 385 { 386 386 exp->toCBuffer(buf, hgs); 387 387 } 388 388 389 389 390 390 /******************************** CompoundStatement ***************************/ 391 391 392 392 CompoundStatement::CompoundStatement(Loc loc, Statements *s) 393 393 : Statement(loc) … … 1678 1678 printf("increment: %s\n", increment->toChars()); 1679 1679 printf("body: %s\n", body->toChars()); 1680 1680 #endif 1681 1681 s = s->semantic(sc); 1682 1682 break; 1683 1683 } 1684 1684 #endif 1685 1685 case Tdelegate: 1686 1686 Lapply: 1687 1687 { 1688 1688 Expression *ec; 1689 1689 Expression *e; 1690 1690 Parameter *a; 1691 1691 1692 1692 Type *tret = func->type->nextOf(); 1693 1693 1694 1694 // Need a variable to hold value from any return statements in body. 1695 1695 if (!sc->func->vresult && tret && tret != Type::tvoid) 1696 1696 { 1697 1697 VarDeclaration *v = new VarDeclaration(loc, tret, Id::result, NULL); 1698 v->no auto= 1;1698 v->noscope = 1; 1699 1699 v->semantic(sc); 1700 1700 if (!sc->insert(v)) 1701 1701 assert(0); 1702 1702 v->parent = sc->func; 1703 1703 sc->func->vresult = v; 1704 1704 } 1705 1705 1706 1706 /* Turn body into the function literal: 1707 1707 * int delegate(ref T arg) { body } 1708 1708 */ 1709 1709 Parameters *args = new Parameters(); 1710 1710 for (size_t i = 0; i < dim; i++) 1711 1711 { Parameter *arg = (Parameter *)arguments->data[i]; 1712 1712 Identifier *id; 1713 1713 1714 1714 arg->type = arg->type->semantic(loc, sc); 1715 1715 if (arg->storageClass & STCref) 1716 1716 id = arg->ident; 1717 1717 else 1718 1718 { // Make a copy of the ref argument so it isn't … … 2206 2206 // If we can short-circuit evaluate the if statement, don't do the 2207 2207 // semantic analysis of the skipped code. 2208 2208 // This feature allows a limited form of conditional compilation. 2209 2209 condition = condition->optimize(WANTflags); 2210 2210 2211 2211 // Evaluate at runtime 2212 2212 unsigned cs0 = sc->callSuper; 2213 2213 unsigned cs1; 2214 2214 2215 2215 Scope *scd; 2216 2216 if (arg) 2217 2217 { /* Declare arg, which we will set to be the 2218 2218 * result of condition. 2219 2219 */ 2220 2220 ScopeDsymbol *sym = new ScopeDsymbol(); 2221 2221 sym->parent = sc->scopesym; 2222 2222 scd = sc->push(sym); 2223 2223 2224 2224 Type *t = arg->type ? arg->type : condition->type; 2225 2225 match = new VarDeclaration(loc, t, arg->ident, NULL); 2226 match->no auto= 1;2226 match->noscope = 1; 2227 2227 match->semantic(scd); 2228 2228 if (!scd->insert(match)) 2229 2229 assert(0); 2230 2230 match->parent = sc->func; 2231 2231 2232 2232 /* Generate: 2233 2233 * (arg = condition) 2234 2234 */ 2235 2235 VarExp *v = new VarExp(0, match); 2236 2236 condition = new AssignExp(loc, v, condition); 2237 2237 condition = condition->semantic(scd); 2238 2238 } 2239 2239 else 2240 2240 scd = sc->push(); 2241 2241 ifbody = ifbody->semanticNoScope(scd); 2242 2242 scd->pop(); 2243 2243 2244 2244 cs1 = sc->callSuper; 2245 2245 sc->callSuper = cs0; 2246 2246 if (elsebody) … … 3280 3280 sc->fes->cases->push(this); 3281 3281 // Construct: return cases->dim+1; 3282 3282 s = new ReturnStatement(0, new IntegerExp(sc->fes->cases->dim + 1)); 3283 3283 } 3284 3284 else if (fd->type->nextOf()->toBasetype() == Type::tvoid) 3285 3285 { 3286 3286 s = new ReturnStatement(0, NULL); 3287 3287 sc->fes->cases->push(s); 3288 3288 3289 3289 // Construct: { exp; return cases->dim + 1; } 3290 3290 Statement *s1 = new ExpStatement(loc, exp); 3291 3291 Statement *s2 = new ReturnStatement(0, new IntegerExp(sc->fes->cases->dim + 1)); 3292 3292 s = new CompoundStatement(loc, s1, s2); 3293 3293 } 3294 3294 else 3295 3295 { 3296 3296 // Construct: return vresult; 3297 3297 if (!fd->vresult) 3298 3298 { // Declare vresult 3299 3299 VarDeclaration *v = new VarDeclaration(loc, tret, Id::result, NULL); 3300 v->no auto= 1;3300 v->noscope = 1; 3301 3301 v->semantic(scx); 3302 3302 if (!scx->insert(v)) 3303 3303 assert(0); 3304 3304 v->parent = fd; 3305 3305 fd->vresult = v; 3306 3306 } 3307 3307 3308 3308 s = new ReturnStatement(0, new VarExp(0, fd->vresult)); 3309 3309 sc->fes->cases->push(s); 3310 3310 3311 3311 // Construct: { vresult = exp; return cases->dim + 1; } 3312 3312 exp = new ConstructExp(loc, new VarExp(0, fd->vresult), exp); 3313 3313 exp = exp->semantic(sc); 3314 3314 Statement *s1 = new ExpStatement(loc, exp); 3315 3315 Statement *s2 = new ReturnStatement(0, new IntegerExp(sc->fes->cases->dim + 1)); 3316 3316 s = new CompoundStatement(loc, s1, s2); 3317 3317 } 3318 3318 return s; 3319 3319 } 3320 3320 trunk/src/aggregate.h
r638 r639 206 206 CtorDeclaration *defaultCtor; // default constructor 207 207 #endif 208 208 FuncDeclaration *staticCtor; 209 209 FuncDeclaration *staticDtor; 210 210 Array vtbl; // Array of FuncDeclaration's making up the vtbl[] 211 211 Array vtblFinal; // More FuncDeclaration's that aren't in vtbl[] 212 212 213 213 BaseClasses *baseclasses; // Array of BaseClass's; first is super, 214 214 // rest are Interface's 215 215 216 216 int interfaces_dim; 217 217 BaseClass **interfaces; // interfaces[interfaces_dim] for this class 218 218 // (does not include baseClass) 219 219 220 220 BaseClasses *vtblInterfaces; // array of base interfaces that have 221 221 // their own vtbl[] 222 222 223 223 TypeInfoClassDeclaration *vclassinfo; // the ClassInfo object for this ClassDeclaration 224 224 int com; // !=0 if this is a COM class (meaning 225 225 // it derives from IUnknown) 226 int is auto; // !=0 if this is an auto class226 int isscope; // !=0 if this is an auto class 227 227 int isabstract; // !=0 if abstract class 228 228 #if DMDV1 229 229 int isnested; // !=0 if is nested 230 230 VarDeclaration *vthis; // 'this' parameter if this class is nested 231 231 #endif 232 232 int inuse; // to prevent recursive attempts 233 233 234 234 ClassDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses); 235 235 Dsymbol *syntaxCopy(Dsymbol *s); 236 236 void semantic(Scope *sc); 237 237 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 238 238 int isBaseOf2(ClassDeclaration *cd); 239 239 240 240 #define OFFSET_RUNTIME 0x76543210 241 241 virtual int isBaseOf(ClassDeclaration *cd, int *poffset); 242 242 243 243 virtual int isBaseInfoComplete(); 244 244 Dsymbol *search(Loc, Identifier *ident, int flags); 245 245 #if DMDV2 246 246 int isFuncHidden(FuncDeclaration *fd); trunk/src/class.c
r638 r639 179 179 { if (object) 180 180 object->error("%s", msg); 181 181 object = this; 182 182 } 183 183 184 184 //if (id == Id::ClassInfo) 185 185 if (id == Id::TypeInfo_Class) 186 186 { if (classinfo) 187 187 classinfo->error("%s", msg); 188 188 classinfo = this; 189 189 } 190 190 191 191 if (id == Id::ModuleInfo) 192 192 { if (Module::moduleinfo) 193 193 Module::moduleinfo->error("%s", msg); 194 194 Module::moduleinfo = this; 195 195 } 196 196 } 197 197 198 198 com = 0; 199 is auto= 0;199 isscope = 0; 200 200 isabstract = 0; 201 201 inuse = 0; 202 202 } 203 203 204 204 Dsymbol *ClassDeclaration::syntaxCopy(Dsymbol *s) 205 205 { 206 206 ClassDeclaration *cd; 207 207 208 208 //printf("ClassDeclaration::syntaxCopy('%s')\n", toChars()); 209 209 if (s) 210 210 cd = (ClassDeclaration *)s; 211 211 else 212 212 cd = new ClassDeclaration(loc, ident, NULL); 213 213 214 214 cd->storage_class |= storage_class; 215 215 216 216 cd->baseclasses->setDim(this->baseclasses->dim); 217 217 for (int i = 0; i < cd->baseclasses->dim; i++) 218 218 { 219 219 BaseClass *b = (BaseClass *)this->baseclasses->data[i]; … … 462 462 } 463 463 464 464 interfaces_dim = baseclasses->dim; 465 465 interfaces = (BaseClass **)baseclasses->data; 466 466 467 467 468 468 if (baseClass) 469 469 { 470 470 if (baseClass->storage_class & STCfinal) 471 471 error("cannot inherit from final class %s", baseClass->toChars()); 472 472 473 473 interfaces_dim--; 474 474 interfaces++; 475 475 476 476 // Copy vtbl[] from base class 477 477 vtbl.setDim(baseClass->vtbl.dim); 478 478 memcpy(vtbl.data, baseClass->vtbl.data, sizeof(void *) * vtbl.dim); 479 479 480 480 // Inherit properties from base class 481 481 com = baseClass->isCOMclass(); 482 is auto = baseClass->isauto;482 isscope = baseClass->isscope; 483 483 vthis = baseClass->vthis; 484 484 storage_class |= baseClass->storage_class & STC_TYPECTOR; 485 485 } 486 486 else 487 487 { 488 488 // No base class, so this is the root of the class hierarchy 489 489 vtbl.setDim(0); 490 490 vtbl.push(this); // leave room for classinfo as first member 491 491 } 492 492 493 493 protection = sc->protection; 494 494 storage_class |= sc->stc; 495 495 496 496 if (sizeok == 0) 497 497 { 498 498 interfaceSemantic(sc); 499 499 500 500 for (i = 0; i < members->dim; i++) 501 501 { 502 502 Dsymbol *s = (Dsymbol *)members->data[i]; … … 546 546 { AggregateDeclaration *ad = fd->isMember2(); 547 547 if (ad) 548 548 t = ad->handle; 549 549 else 550 550 { 551 551 t = Type::tvoidptr; 552 552 } 553 553 } 554 554 else 555 555 assert(0); 556 556 if (t->ty == Tstruct) // ref to struct 557 557 t = Type::tvoidptr; 558 558 assert(!vthis); 559 559 vthis = new ThisDeclaration(loc, t); 560 560 members->push(vthis); 561 561 } 562 562 } 563 563 } 564 564 } 565 565 566 if (storage_class & (STCauto | STCscope)) 567 isauto = 1; 566 if (storage_class & STCauto) 567 error("storage class 'auto' is invalid when declaring a class, did you mean to use 'scope'?"); 568 if (storage_class & STCscope) 569 isscope = 1; 568 570 if (storage_class & STCabstract) 569 571 isabstract = 1; 570 572 if (storage_class & STCimmutable) 571 573 type = type->invariantOf(); 572 574 else if (storage_class & STCconst) 573 575 type = type->constOf(); 574 576 else if (storage_class & STCshared) 575 577 type = type->sharedOf(); 576 578 577 579 sc = sc->push(this); 578 580 sc->stc &= ~(STCfinal | STCauto | STCscope | STCstatic | 579 581 STCabstract | STCdeprecated | STC_TYPECTOR | STCtls | STCgshared); 580 582 sc->stc |= storage_class & STC_TYPECTOR; 581 583 sc->parent = this; 582 584 sc->inunion = 0; 583 585 584 586 if (isCOMclass()) 585 587 { 586 588 #if _WIN32 587 589 sc->linkage = LINKwindows; trunk/src/clone.c
r581 r639 140 140 fparams->push(param); 141 141 Type *ftype = new TypeFunction(fparams, handle, FALSE, LINKd); 142 142 #if STRUCTTHISREF 143 143 ((TypeFunction *)ftype)->isref = 1; 144 144 #endif 145 145 146 146 fop = new FuncDeclaration(0, 0, Id::assign, STCundefined, ftype); 147 147 148 148 Expression *e = NULL; 149 149 if (postblit) 150 150 { /* Swap: 151 151 * tmp = *this; *this = s; tmp.dtor(); 152 152 */ 153 153 //printf("\tswap copy\n"); 154 154 Identifier *idtmp = Lexer::uniqueId("__tmp"); 155 155 VarDeclaration *tmp; 156 156 AssignExp *ec = NULL; 157 157 if (dtor) 158 158 { 159 159 tmp = new VarDeclaration(0, type, idtmp, new VoidInitializer(0)); 160 tmp->no auto= 1;160 tmp->noscope = 1; 161 161 tmp->storage_class |= STCctfe; 162 162 e = new DeclarationExp(0, tmp); 163 163 ec = new AssignExp(0, 164 164 new VarExp(0, tmp), 165 165 #if STRUCTTHISREF 166 166 new ThisExp(0) 167 167 #else 168 168 new PtrExp(0, new ThisExp(0)) 169 169 #endif 170 170 ); 171 171 ec->op = TOKblit; 172 172 e = Expression::combine(e, ec); 173 173 } 174 174 ec = new AssignExp(0, 175 175 #if STRUCTTHISREF 176 176 new ThisExp(0), 177 177 #else 178 178 new PtrExp(0, new ThisExp(0)), 179 179 #endif 180 180 new IdentifierExp(0, Id::p)); trunk/src/declaration.c
r610 r639 635 635 636 636 VarDeclaration::VarDeclaration(Loc loc, Type *type, Identifier *id, Initializer *init) 637 637 : Declaration(id) 638 638 { 639 639 //printf("VarDeclaration('%s')\n", id->toChars()); 640 640 #ifdef DEBUG 641 641 if (!type && !init) 642 642 { printf("VarDeclaration('%s')\n", id->toChars()); 643 643 //*(char*)0=0; 644 644 } 645 645 #endif 646 646 assert(type || init); 647 647 this->type = type; 648 648 this->init = init; 649 649 #ifdef _DH 650 650 this->htype = NULL; 651 651 this->hinit = NULL; 652 652 #endif 653 653 this->loc = loc; 654 654 offset = 0; 655 no auto= 0;655 noscope = 0; 656 656 #if DMDV2 657 657 isargptr = FALSE; 658 658 #endif 659 659 #if DMDV1 660 660 nestedref = 0; 661 661 #endif 662 662 ctorinit = 0; 663 663 aliassym = NULL; 664 664 onstack = 0; 665 665 canassign = 0; 666 666 value = NULL; 667 667 rundtor = NULL; 668 668 } 669 669 670 670 Dsymbol *VarDeclaration::syntaxCopy(Dsymbol *s) 671 671 { 672 672 //printf("VarDeclaration::syntaxCopy(%s)\n", toChars()); 673 673 674 674 VarDeclaration *sv; 675 675 if (s) … … 807 807 808 808 Type *tb = type->toBasetype(); 809 809 if (tb->ty == Tvoid && !(storage_class & STClazy)) 810 810 { error("voids have no value"); 811 811 type = Type::terror; 812 812 tb = type; 813 813 } 814 814 if (tb->ty == Tfunction) 815 815 { error("cannot be declared to be a function"); 816 816 type = Type::terror; 817 817 tb = type; 818 818 } 819 819 if (tb->ty == Tstruct) 820 820 { TypeStruct *ts = (TypeStruct *)tb; 821 821 822 822 if (!ts->sym->members) 823 823 { 824 824 error("no definition of struct %s", ts->toChars()); 825 825 } 826 826 } 827 if ((storage_class & STCauto) && !inferred) 828 error("storage class 'auto' has no effect if type is not inferred, did you mean 'scope'?"); 827 829 828 830 if (tb->ty == Ttuple) 829 831 { /* Instead, declare variables for each of the tuple elements 830 832 * and add those. 831 833 */ 832 834 TypeTuple *tt = (TypeTuple *)tb; 833 835 size_t nelems = Parameter::dim(tt->arguments); 834 836 Objects *exps = new Objects(); 835 837 exps->setDim(nelems); 836 838 Expression *ie = init ? init->toExpression() : NULL; 837 839 838 840 for (size_t i = 0; i < nelems; i++) 839 841 { Parameter *arg = Parameter::getNth(tt->arguments, i); 840 842 841 843 OutBuffer buf; 842 844 buf.printf("_%s_field_%zu", ident->toChars(), i); 843 845 buf.writeByte(0); 844 846 const char *name = (const char *)buf.extractData(); 845 847 Identifier *id = Lexer::idPool(name); 846 848 … … 958 960 error("cannot use template to add field to aggregate '%s'", ad->toChars()); 959 961 } 960 962 } 961 963 } 962 964 963 965 #if DMDV2 964 966 if ((storage_class & (STCref | STCparameter | STCforeach)) == STCref && 965 967 ident != Id::This) 966 968 { 967 969 error("only parameters or foreach declarations can be ref"); 968 970 } 969 971 970 972 if ((storage_class & (STCstatic | STCextern | STCtls | STCgshared | STCmanifest) || 971 973 isDataseg()) && 972 974 type->hasWild()) 973 975 { 974 976 error("only fields, parameters or stack based variables can be inout"); 975 977 } 976 978 #endif 977 979 978 if (type->is auto() && !noauto)980 if (type->isscope() && !noscope) 979 981 { 980 982 if (storage_class & (STCfield | STCout | STCref | STCstatic | STCmanifest | STCtls | STCgshared) || !fd) 981 983 { 982 984 error("globals, statics, fields, manifest constants, ref and out parameters cannot be scope"); 983 985 } 984 986 985 if (!(storage_class & (STCauto | STCscope)))987 if (!(storage_class & STCscope)) 986 988 { 987 989 if (!(storage_class & STCparameter) && ident != Id::withSym) 988 990 error("reference to scope class must be scope"); 989 991 } 990 992 } 991 993 992 994 if (!init && !fd) 993 995 { // If not mutable, initializable by constructor only 994 996 storage_class |= STCctorinit; 995 997 } 996 998 997 999 if (init) 998 1000 storage_class |= STCinit; // remember we had an explicit initializer 999 1001 else if (storage_class & STCmanifest) 1000 1002 error("manifest constants must have initializers"); 1001 1003 1002 1004 enum TOK op = TOKconstruct; 1003 1005 if (!init && !sc->inunion && !isStatic() && fd && 1004 1006 (!(storage_class & (STCfield | STCin | STCforeach | STCparameter | STCresult)) 1005 1007 || (storage_class & STCout)) && … … 1573 1575 1574 1576 int VarDeclaration::isCTFE() 1575 1577 { 1576 1578 return (storage_class & STCctfe) != 0; // || !isDataseg(); 1577 1579 } 1578 1580 1579 1581 int VarDeclaration::hasPointers() 1580 1582 { 1581 1583 //printf("VarDeclaration::hasPointers() %s, ty = %d\n", toChars(), type->ty); 1582 1584 return (!isDataseg() && type->hasPointers()); 1583 1585 } 1584 1586 1585 1587 /****************************************** 1586 1588 * Return TRUE if variable needs to call the destructor. 1587 1589 */ 1588 1590 1589 1591 int VarDeclaration::needsAutoDtor() 1590 1592 { 1591 1593 //printf("VarDeclaration::needsAutoDtor() %s\n", toChars()); 1592 1594 1593 if (no auto|| storage_class & STCnodtor)1595 if (noscope || storage_class & STCnodtor) 1594 1596 return FALSE; 1595 1597 1596 1598 // Destructors for structs and arrays of structs 1597 1599 Type *tv = type->toBasetype(); 1598 1600 while (tv->ty == Tsarray) 1599 1601 { TypeSArray *ta = (TypeSArray *)tv; 1600 1602 tv = tv->nextOf()->toBasetype(); 1601 1603 } 1602 1604 if (tv->ty == Tstruct) 1603 1605 { TypeStruct *ts = (TypeStruct *)tv; 1604 1606 StructDeclaration *sd = ts->sym; 1605 1607 if (sd->dtor) 1606 1608 return TRUE; 1607 1609 } 1608 1610 1609 1611 // Destructors for classes 1610 1612 if (storage_class & (STCauto | STCscope)) 1611 1613 { 1612 1614 if (type->isClassHandle()) 1613 1615 return TRUE; 1614 1616 } 1615 1617 return FALSE; 1616 1618 } 1617 1619 1618 1620 1619 1621 /****************************************** 1620 * If a variable has a n autodestructor call, return call for it.1622 * If a variable has a scope destructor call, return call for it. 1621 1623 * Otherwise, return NULL. 1622 1624 */ 1623 1625 1624 Expression *VarDeclaration::call AutoDtor(Scope *sc)1626 Expression *VarDeclaration::callScopeDtor(Scope *sc) 1625 1627 { Expression *e = NULL; 1626 1628 1627 //printf("VarDeclaration::call AutoDtor() %s\n", toChars());1628 1629 if (no auto|| storage_class & STCnodtor)1629 //printf("VarDeclaration::callScopeDtor() %s\n", toChars()); 1630 1631 if (noscope || storage_class & STCnodtor) 1630 1632 return NULL; 1631 1633 1632 1634 // Destructors for structs and arrays of structs 1633 1635 bool array = false; 1634 1636 Type *tv = type->toBasetype(); 1635 1637 while (tv->ty == Tsarray) 1636 1638 { TypeSArray *ta = (TypeSArray *)tv; 1637 1639 array = true; 1638 1640 tv = tv->nextOf()->toBasetype(); 1639 1641 } 1640 1642 if (tv->ty == Tstruct) 1641 1643 { TypeStruct *ts = (TypeStruct *)tv; 1642 1644 StructDeclaration *sd = ts->sym; 1643 1645 if (sd->dtor) 1644 1646 { 1645 1647 if (array) 1646 1648 { 1647 1649 // Typeinfo.destroy(cast(void*)&v); 1648 1650 Expression *ea = new SymOffExp(loc, this, 0, 0); 1649 1651 ea = new CastExp(loc, ea, Type::tvoid->pointerTo()); … … 1880 1882 : TypeInfoDeclaration(tinfo, 0) 1881 1883 { 1882 1884 type = Type::typeinfodelegate->type; 1883 1885 } 1884 1886 1885 1887 /***************************** TypeInfoTupleDeclaration **********************/ 1886 1888 1887 1889 TypeInfoTupleDeclaration::TypeInfoTupleDeclaration(Type *tinfo) 1888 1890 : TypeInfoDeclaration(tinfo, 0) 1889 1891 { 1890 1892 type = Type::typeinfotypelist->type; 1891 1893 } 1892 1894 1893 1895 /********************************* ThisDeclaration ****************************/ 1894 1896 1895 1897 // For the "this" parameter to member functions 1896 1898 1897 1899 ThisDeclaration::ThisDeclaration(Loc loc, Type *t) 1898 1900 : VarDeclaration(loc, t, Id::This, NULL) 1899 1901 { 1900 no auto= 1;1902 noscope = 1; 1901 1903 } 1902 1904 1903 1905 Dsymbol *ThisDeclaration::syntaxCopy(Dsymbol *s) 1904 1906 { 1905 1907 assert(0); // should never be produced by syntax 1906 1908 return NULL; 1907 1909 } 1908 1910 trunk/src/declaration.h
r591 r639 123 123 const char *kind(); 124 124 unsigned size(Loc loc); 125 125 void checkModify(Loc loc, Scope *sc, Type *t); 126 126 127 127 void emitComment(Scope *sc); 128 128 void toJsonBuffer(OutBuffer *buf); 129 129 void toDocBuffer(OutBuffer *buf); 130 130 131 131 char *mangle(); 132 132 int isStatic() { return storage_class & STCstatic; } 133 133 virtual int isDelete(); 134 134 virtual int isDataseg(); 135 135 virtual int isThreadlocal(); 136 136 virtual int isCodeseg(); 137 137 int isCtorinit() { return storage_class & STCctorinit; } 138 138 int isFinal() { return storage_class & STCfinal; } 139 139 int isAbstract() { return storage_class & STCabstract; } 140 140 int isConst() { return storage_class & STCconst; } 141 141 int isImmutable() { return storage_class & STCimmutable; } 142 142 int isAuto() { return storage_class & STCauto; } 143 int isScope() { return storage_class & (STCscope | STCauto); }143 int isScope() { return storage_class & STCscope; } 144 144 int isSynchronized() { return storage_class & STCsynchronized; } 145 145 int isParameter() { return storage_class & STCparameter; } 146 146 int isDeprecated() { return storage_class & STCdeprecated; } 147 147 int isOverride() { return storage_class & STCoverride; } 148 148 int isResult() { return storage_class & STCresult; } 149 149 150 150 int isIn() { return storage_class & STCin; } 151 151 int isOut() { return storage_class & STCout; } 152 152 int isRef() { return storage_class & STCref; } 153 153 154 154 enum PROT prot(); 155 155 156 156 Declaration *isDeclaration() { return this; } 157 157 }; 158 158 159 159 /**************************************************************/ 160 160 161 161 struct TupleDeclaration : Declaration 162 162 { 163 163 Objects *objects; … … 222 222 const char *kind(); 223 223 Type *getType(); 224 224 Dsymbol *toAlias(); 225 225 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 226 226 #ifdef _DH 227 227 Type *htype; 228 228 Dsymbol *haliassym; 229 229 #endif 230 230 231 231 void toDocBuffer(OutBuffer *buf); 232 232 233 233 AliasDeclaration *isAliasDeclaration() { return this; } 234 234 }; 235 235 236 236 /**************************************************************/ 237 237 238 238 struct VarDeclaration : Declaration 239 239 { 240 240 Initializer *init; 241 241 unsigned offset; 242 int no auto; // no auto semantics242 int noscope; // no auto semantics 243 243 #if DMDV2 244 244 FuncDeclarations nestedrefs; // referenced by these lexically nested functions 245 245 bool isargptr; // if parameter that _argptr points to 246 246 #else 247 247 int nestedref; // referenced by a lexically nested function 248 248 #endif 249 249 int ctorinit; // it has been initialized in a ctor 250 250 int onstack; // 1: it has been allocated on the stack 251 251 // 2: on stack, run destructor anyway 252 252 int canassign; // it can be assigned to 253 253 Dsymbol *aliassym; // if redone as alias to another symbol 254 254 Expression *value; // when interpreting, this is the value 255 255 // (NULL if value not determinable) 256 256 #if DMDV2 257 257 VarDeclaration *rundtor; // if !NULL, rundtor is tested at runtime to see 258 258 // if the destructor should be run. Used to prevent 259 259 // dtor calls on postblitted vars 260 260 #endif 261 261 262 262 VarDeclaration(Loc loc, Type *t, Identifier *id, Initializer *init); 263 263 Dsymbol *syntaxCopy(Dsymbol *); 264 264 void semantic(Scope *sc); 265 265 void semantic2(Scope *sc); 266 266 const char *kind(); 267 267 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 268 268 #ifdef _DH 269 269 Type *htype; 270 270 Initializer *hinit; 271 271 #endif 272 272 int needThis(); 273 273 int isImportedSymbol(); 274 274 int isDataseg(); 275 275 int isThreadlocal(); 276 276 int isCTFE(); 277 277 int hasPointers(); 278 278 #if DMDV2 279 279 int canTakeAddressOf(); 280 280 int needsAutoDtor(); 281 281 #endif 282 Expression *call AutoDtor(Scope *sc);282 Expression *callScopeDtor(Scope *sc); 283 283 ExpInitializer *getExpInitializer(); 284 284 Expression *getConstInitializer(); 285 285 void checkCtorConstInit(); 286 286 void checkNestedReference(Scope *sc, Loc loc); 287 287 Dsymbol *toAlias(); 288 288 289 289 Symbol *toSymbol(); 290 290 void toObjFile(int multiobj); // compile to .obj file 291 291 int cvMember(unsigned char *p); 292 292 293 293 // Eliminate need for dynamic_cast 294 294 VarDeclaration *isVarDeclaration() { return (VarDeclaration *)this; } 295 295 }; 296 296 297 297 /**************************************************************/ 298 298 299 299 // This is a shell around a back end symbol 300 300 301 301 struct SymbolDeclaration : Declaration 302 302 { trunk/src/expression.c
r634 r639 4324 4324 } 4325 4325 4326 4326 char *VarExp::toChars() 4327 4327 { 4328 4328 return var->toChars(); 4329 4329 } 4330 4330 4331 4331 void VarExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 4332 4332 { 4333 4333 buf->writestring(var->toChars()); 4334 4334 } 4335 4335 4336 4336 void VarExp::checkEscape() 4337 4337 { 4338 4338 VarDeclaration *v = var->isVarDeclaration(); 4339 4339 if (v) 4340 4340 { Type *tb = v->type->toBasetype(); 4341 4341 // if reference type 4342 4342 if (tb->ty == Tarray || tb->ty == Tsarray || tb->ty == Tclass) 4343 4343 { 4344 if ( (v->isAuto() || v->isScope()) && !v->noauto)4344 if (v->isScope() && !v->noscope) 4345 4345 error("escaping reference to scope local %s", v->toChars()); 4346 4346 else if (v->storage_class & STCvariadic) 4347 4347 error("escaping reference to variadic parameter %s", v->toChars()); 4348 4348 } 4349 4349 } 4350 4350 } 4351 4351 4352 4352 void VarExp::checkEscapeRef() 4353 4353 { 4354 4354 VarDeclaration *v = var->isVarDeclaration(); 4355 4355 if (v) 4356 4356 { 4357 4357 if (!v->isDataseg() && !(v->storage_class & (STCref | STCout))) 4358 4358 error("escaping reference to local variable %s", v->toChars()); 4359 4359 } 4360 4360 } 4361 4361 4362 4362 #if DMDV2 4363 4363 int VarExp::isLvalue() 4364 4364 { trunk/src/func.c
r611 r639 1090 1090 assert(type->nextOf()); 1091 1091 if (type->nextOf()->ty == Tvoid) 1092 1092 { 1093 1093 if (outId) 1094 1094 error("void functions have no result"); 1095 1095 } 1096 1096 else 1097 1097 { 1098 1098 if (!outId) 1099 1099 outId = Id::result; // provide a default 1100 1100 } 1101 1101 1102 1102 if (outId) 1103 1103 { // Declare result variable 1104 1104 Loc loc = this->loc; 1105 1105 1106 1106 if (fensure) 1107 1107 loc = fensure->loc; 1108 1108 1109 1109 VarDeclaration *v = new VarDeclaration(loc, type->nextOf(), outId, NULL); 1110 v->no auto= 1;1110 v->noscope = 1; 1111 1111 v->storage_class |= STCresult; 1112 1112 #if DMDV2 1113 1113 if (!isVirtual()) 1114 1114 v->storage_class |= STCconst; 1115 1115 if (f->isref) 1116 1116 { 1117 1117 v->storage_class |= STCref | STCforeach; 1118 1118 } 1119 1119 #endif 1120 1120 sc2->incontract--; 1121 1121 v->semantic(sc2); 1122 1122 sc2->incontract++; 1123 1123 if (!sc2->insert(v)) 1124 1124 error("out result %s is already defined", v->toChars()); 1125 1125 v->parent = this; 1126 1126 vresult = v; 1127 1127 1128 1128 // vresult gets initialized with the function return value 1129 1129 // in ReturnStatement::semantic() 1130 1130 } … … 1501 1501 1502 1502 fbody = new CompoundStatement(0, a); 1503 1503 #if DMDV2 1504 1504 /* Append destructor calls for parameters as finally blocks. 1505 1505 */ 1506 1506 if (parameters) 1507 1507 { for (size_t i = 0; i < parameters->dim; i++) 1508 1508 { 1509 1509 VarDeclaration *v = (VarDeclaration *)parameters->data[i]; 1510 1510 1511 1511 if (v->storage_class & (STCref | STCout)) 1512 1512 continue; 1513 1513 1514 1514 /* Don't do this for static arrays, since static 1515 1515 * arrays are called by reference. Remove this 1516 1516 * when we change them to call by value. 1517 1517 */ 1518 1518 if (v->type->toBasetype()->ty == Tsarray) 1519 1519 continue; 1520 1520 1521 Expression *e = v->call AutoDtor(sc2);1521 Expression *e = v->callScopeDtor(sc2); 1522 1522 if (e) 1523 1523 { Statement *s = new ExpStatement(0, e); 1524 1524 s = s->semantic(sc2); 1525 1525 if (fbody->blockExit() == BEfallthru) 1526 1526 fbody = new CompoundStatement(0, fbody, s); 1527 1527 else 1528 1528 fbody = new TryFinallyStatement(0, fbody, s); 1529 1529 } 1530 1530 } 1531 1531 } 1532 1532 #endif 1533 1533 1534 1534 #if 1 1535 1535 if (isSynchronized()) 1536 1536 { /* Wrap the entire function body in a synchronized statement 1537 1537 */ 1538 1538 ClassDeclaration *cd = parent->isClassDeclaration(); 1539 1539 if (cd) 1540 1540 { 1541 1541 #if TARGET_WINDOS trunk/src/mtype.c
r638 r639 1559 1559 int Type::iscomplex() 1560 1560 { 1561 1561 return FALSE; 1562 1562 } 1563 1563 1564 1564 int Type::isscalar() 1565 1565 { 1566 1566 return FALSE; 1567 1567 } 1568 1568 1569 1569 int Type::isunsigned() 1570 1570 { 1571 1571 return FALSE; 1572 1572 } 1573 1573 1574 1574 ClassDeclaration *Type::isClassHandle() 1575 1575 { 1576 1576 return NULL; 1577 1577 } 1578 1578 1579 int Type::is auto()1579 int Type::isscope() 1580 1580 { 1581 1581 return FALSE; 1582 1582 } 1583 1583 1584 1584 int Type::isString() 1585 1585 { 1586 1586 return FALSE; 1587 1587 } 1588 1588 1589 1589 /************************** 1590 1590 * Given: 1591 1591 * T a, b; 1592 1592 * Can we assign: 1593 1593 * a = b; 1594 1594 * ? 1595 1595 */ 1596 1596 int Type::isAssignable() 1597 1597 { 1598 1598 return TRUE; 1599 1599 } … … 3380 3380 3381 3381 if (d >= tt->arguments->dim) 3382 3382 { error(loc, "tuple index %ju exceeds %u", d, tt->arguments->dim); 3383 3383 return Type::terror; 3384 3384 } 3385 3385 Parameter *arg = (Parameter *)tt->arguments->data[(size_t)d]; 3386 3386 return arg->type; 3387 3387 } 3388 3388 case Tstruct: 3389 3389 { TypeStruct *ts = (TypeStruct *)tbn; 3390 3390 if (ts->sym->isnested) 3391 3391 error(loc, "cannot have array of inner structs %s", ts->toChars()); 3392 3392 break; 3393 3393 } 3394 3394 case Tfunction: 3395 3395 case Tnone: 3396 3396 error(loc, "can't have array of %s", tbn->toChars()); 3397 3397 tbn = next = tint32; 3398 3398 break; 3399 3399 } 3400 if (tbn->is auto())3401 error(loc, "cannot have array of auto%s", tbn->toChars());3400 if (tbn->isscope()) 3401 error(loc, "cannot have array of scope %s", tbn->toChars()); 3402 3402 return merge(); 3403 3403 } 3404 3404 3405 3405 void TypeSArray::toDecoBuffer(OutBuffer *buf, int flag) 3406 3406 { 3407 3407 Type::toDecoBuffer(buf, flag); 3408 3408 if (dim) 3409 3409 buf->printf("%ju", dim->toInteger()); 3410 3410 if (next) 3411 3411 /* Note that static arrays are value types, so 3412 3412 * for a parameter, propagate the 0x100 to the next 3413 3413 * level, since for T[4][3], any const should apply to the T, 3414 3414 * not the [4]. 3415 3415 */ 3416 3416 next->toDecoBuffer(buf, (flag & 0x100) ? flag : mod); 3417 3417 } 3418 3418 3419 3419 void TypeSArray::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) 3420 3420 { 3421 3421 if (mod != this->mod) … … 3609 3609 Type *TypeDArray::semantic(Loc loc, Scope *sc) 3610 3610 { Type *tn = next; 3611 3611 3612 3612 tn = next->semantic(loc,sc); 3613 3613 Type *tbn = tn->toBasetype(); 3614 3614 switch (tbn->ty) 3615 3615 { 3616 3616 case Tfunction: 3617 3617 case Tnone: 3618 3618 case Ttuple: 3619 3619 error(loc, "can't have array of %s", tbn->toChars()); 3620 3620 tn = next = tint32; 3621 3621 break; 3622 3622 case Tstruct: 3623 3623 { TypeStruct *ts = (TypeStruct *)tbn; 3624 3624 if (ts->sym->isnested) 3625 3625 error(loc, "cannot have array of inner structs %s", ts->toChars()); 3626 3626 break; 3627 3627 } 3628 3628 } 3629 if (tn->is auto())3630 error(loc, "cannot have array of auto%s", tn->toChars());3629 if (tn->isscope()) 3630 error(loc, "cannot have array of scope %s", tn->toChars()); 3631 3631 3632 3632 next = tn; 3633 3633 transitive(); 3634 3634 return merge(); 3635 3635 } 3636 3636 3637 3637 void TypeDArray::toDecoBuffer(OutBuffer *buf, int flag) 3638 3638 { 3639 3639 Type::toDecoBuffer(buf, flag); 3640 3640 if (next) 3641 3641 next->toDecoBuffer(buf, (flag & 0x100) ? 0 : mod); 3642 3642 } 3643 3643 3644 3644 void TypeDArray::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) 3645 3645 { 3646 3646 if (mod != this->mod) 3647 3647 { toCBuffer3(buf, hgs, mod); 3648 3648 return; 3649 3649 } 3650 3650 if (equals(tstring)) … … 3812 3812 Type *TypeNewArray::semantic(Loc loc, Scope *sc) 3813 3813 { Type *tn = next; 3814 3814 3815 3815 tn = next->semantic(loc,sc); 3816 3816 Type *tbn = tn->toBasetype(); 3817 3817 switch (tbn->ty) 3818 3818 { 3819 3819 case Tfunction: 3820 3820 case Tnone: 3821 3821 case Ttuple: 3822 3822 error(loc, "can't have array of %s", tbn->toChars()); 3823 3823 tn = next = tint32; 3824 3824 break; 3825 3825 case Tstruct: 3826 3826 { TypeStruct *ts = (TypeStruct *)tbn; 3827 3827 if (ts->sym->isnested) 3828 3828 error(loc, "cannot have array of inner structs %s", ts->toChars()); 3829 3829 break; 3830 3830 } 3831 3831 } 3832 if (tn->is auto())3833 error(loc, "cannot have array of auto%s", tn->toChars());3832 if (tn->isscope()) 3833 error(loc, "cannot have array of scope %s", tn->toChars()); 3834 3834 3835 3835 next = tn; 3836 3836 transitive(); 3837 3837 return merge(); 3838 3838 } 3839 3839 3840 3840 void TypeNewArray::toDecoBuffer(OutBuffer *buf, int flag) 3841 3841 { 3842 3842 Type::toDecoBuffer(buf, flag); 3843 3843 buf->writeByte('e'); 3844 3844 if (next) 3845 3845 next->toDecoBuffer(buf, (flag & 0x100) ? 0 : mod); 3846 3846 } 3847 3847 3848 3848 void TypeNewArray::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) 3849 3849 { 3850 3850 if (mod != this->mod) 3851 3851 { toCBuffer3(buf, hgs, mod); 3852 3852 return; 3853 3853 } … … 3940 3940 switch (index->toBasetype()->ty) 3941 3941 { 3942 3942 case Tbool: 3943 3943 case Tfunction: 3944 3944 case Tvoid: 3945 3945 case Tnone: 3946 3946 case Ttuple: 3947 3947 error(loc, "can't have associative array key of %s", index->toBasetype()->toChars()); 3948 3948 return Type::terror; 3949 3949 } 3950 3950 next = next->semantic(loc,sc); 3951 3951 transitive(); 3952 3952 3953 3953 switch (next->toBasetype()->ty) 3954 3954 { 3955 3955 case Tfunction: 3956 3956 case Tnone: 3957 3957 error(loc, "can't have associative array of %s", next->toChars()); 3958 3958 return Type::terror; 3959 3959 } 3960 if (next->is auto())3961 { error(loc, "cannot have array of auto%s", next->toChars());3960 if (next->isscope()) 3961 { error(loc, "cannot have array of scope %s", next->toChars()); 3962 3962 return Type::terror; 3963 3963 } 3964 3964 return merge(); 3965 3965 } 3966 3966 3967 3967 StructDeclaration *TypeAArray::getImpl() 3968 3968 { 3969 3969 // Do it lazily 3970 3970 if (!impl) 3971 3971 { 3972 3972 Type *index = this->index; 3973 3973 Type *next = this->next; 3974 3974 if (index->reliesOnTident() || next->reliesOnTident()) 3975 3975 { 3976 3976 error(loc, "cannot create associative array %s", toChars()); 3977 3977 index = terror; 3978 3978 next = terror; 3979 3979 } 3980 3980 /* This is really a proxy for the template instance AssocArray!(index, next) 3981 3981 * But the instantiation can fail if it is a template specialization field … … 4840 4840 } 4841 4841 4842 4842 bool wildreturn = FALSE; 4843 4843 if (tf->next) 4844 4844 { 4845 4845 tf->next = tf->next->semantic(loc,sc); 4846 4846 #if !SARRAYVALUE 4847 4847 if (tf->next->toBasetype()->ty == Tsarray) 4848 4848 { error(loc, "functions cannot return static array %s", tf->next->toChars()); 4849 4849 tf->next = Type::terror; 4850 4850 } 4851 4851 #endif 4852 4852 if (tf->next->toBasetype()->ty == Tfunction) 4853 4853 { error(loc, "functions cannot return a function"); 4854 4854 tf->next = Type::terror; 4855 4855 } 4856 4856 if (tf->next->toBasetype()->ty == Ttuple) 4857 4857 { error(loc, "functions cannot return a tuple"); 4858 4858 tf->next = Type::terror; 4859 4859 } 4860 if (tf->next->is auto() && !(sc->flags & SCOPEctor))4860 if (tf->next->isscope() && !(sc->flags & SCOPEctor)) 4861 4861 error(loc, "functions cannot return scope %s", tf->next->toChars()); 4862 4862 if (tf->next->toBasetype()->ty == Tvoid) 4863 4863 tf->isref = FALSE; // rewrite "ref void" as just "void" 4864 4864 if (tf->next->isWild()) 4865 4865 wildreturn = TRUE; 4866 4866 } 4867 4867 4868 4868 bool wildparams = FALSE; 4869 4869 bool wildsubparams = FALSE; 4870 4870 if (tf->parameters) 4871 4871 { 4872 4872 /* Create a scope for evaluating the default arguments for the parameters 4873 4873 */ 4874 4874 Scope *argsc = sc->push(); 4875 4875 argsc->stc = 0; // don't inherit storage class 4876 4876 argsc->protection = PROTpublic; 4877 4877 4878 4878 size_t dim = Parameter::dim(tf->parameters); 4879 4879 for (size_t i = 0; i < dim; i++) 4880 4880 { Parameter *fparam = Parameter::getNth(tf->parameters, i); … … 7402 7402 7403 7403 if (d->parent && d->toParent()->isModule()) 7404 7404 { 7405 7405 // (e, d) 7406 7406 7407 7407 VarExp *ve = new VarExp(e->loc, d, 1); 7408 7408 e = new CommaExp(e->loc, e, ve); 7409 7409 e->type = d->type; 7410 7410 return e; 7411 7411 } 7412 7412 7413 7413 DotVarExp *de = new DotVarExp(e->loc, e, d); 7414 7414 return de->semantic(sc); 7415 7415 } 7416 7416 7417 7417 ClassDeclaration *TypeClass::isClassHandle() 7418 7418 { 7419 7419 return sym; 7420 7420 } 7421 7421 7422 int TypeClass::is auto()7423 { 7424 return sym->is auto;7422 int TypeClass::isscope() 7423 { 7424 return sym->isscope; 7425 7425 } 7426 7426 7427 7427 int TypeClass::isBaseOf(Type *t, int *poffset) 7428 7428 { 7429 7429 if (t->ty == Tclass) 7430 7430 { ClassDeclaration *cd; 7431 7431 7432 7432 cd = ((TypeClass *)t)->sym; 7433 7433 if (sym->isBaseOf(cd, poffset)) 7434 7434 return 1; 7435 7435 } 7436 7436 return 0; 7437 7437 } 7438 7438 7439 7439 MATCH TypeClass::implicitConvTo(Type *to) 7440 7440 { 7441 7441 //printf("TypeClass::implicitConvTo(to = '%s') %s\n", to->toChars(), toChars()); 7442 7442 MATCH m = constConv(to); 7443 7443 if (m != MATCHnomatch) 7444 7444 return m; trunk/src/mtype.h
r619 r639 229 229 virtual unsigned alignsize(); 230 230 virtual Type *semantic(Loc loc, Scope *sc); 231 231 Type *trySemantic(Loc loc, Scope *sc); 232 232 virtual void toDecoBuffer(OutBuffer *buf, int flag = 0); 233 233 Type *merge(); 234 234 Type *merge2(); 235 235 virtual void toCBuffer(OutBuffer *buf, Identifier *ident, HdrGenState *hgs); 236 236 virtual void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod); 237 237 void toCBuffer3(OutBuffer *buf, HdrGenState *hgs, int mod); 238 238 void modToBuffer(OutBuffer *buf); 239 239 #if CPP_MANGLE 240 240 virtual void toCppMangle(OutBuffer *buf, CppMangleState *cms); 241 241 #endif 242 242 virtual int isintegral(); 243 243 virtual int isfloating(); // real, imaginary, or complex 244 244 virtual int isreal(); 245 245 virtual int isimaginary(); 246 246 virtual int iscomplex(); 247 247 virtual int isscalar(); 248 248 virtual int isunsigned(); 249 virtual int is auto();249 virtual int isscope(); 250 250 virtual int isString(); 251 251 virtual int isAssignable(); 252 252 virtual int checkBoolean(); // if can be converted to boolean value 253 253 virtual void checkDeprecated(Loc loc, Scope *sc); 254 254 int isConst() { return mod & MODconst; } 255 255 int isImmutable() { return mod & MODimmutable; } 256 256 int isMutable() { return !(mod & (MODconst | MODimmutable | MODwild)); } 257 257 int isShared() { return mod & MODshared; } 258 258 int isSharedConst() { return mod == (MODshared | MODconst); } 259 259 int isWild() { return mod & MODwild; } 260 260 int isSharedWild() { return mod == (MODshared | MODwild); } 261 261 int isNaked() { return mod == 0; } 262 262 Type *constOf(); 263 263 Type *invariantOf(); 264 264 Type *mutableOf(); 265 265 Type *sharedOf(); 266 266 Type *sharedConstOf(); 267 267 Type *unSharedOf(); 268 268 Type *wildOf(); 269 269 Type *sharedWildOf(); … … 797 797 798 798 struct TypeClass : Type 799 799 { 800 800 ClassDeclaration *sym; 801 801 802 802 TypeClass(ClassDeclaration *sym); 803 803 d_uns64 size(Loc loc); 804 804 char *toChars(); 805 805 Type *syntaxCopy(); 806 806 Type *semantic(Loc loc, Scope *sc); 807 807 Dsymbol *toDsymbol(Scope *sc); 808 808 void toDecoBuffer(OutBuffer *buf, int flag); 809 809 void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod); 810 810 Expression *dotExp(Scope *sc, Expression *e, Identifier *ident); 811 811 ClassDeclaration *isClassHandle(); 812 812 int isBaseOf(Type *t, int *poffset); 813 813 MATCH implicitConvTo(Type *to); 814 814 Expression *defaultInit(Loc loc); 815 815 int isZeroInit(Loc loc); 816 816 MATCH deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes); 817 int is auto();817 int isscope(); 818 818 int checkBoolean(); 819 819 TypeInfoDeclaration *getTypeInfoDeclaration(); 820 820 int hasPointers(); 821 821 int builtinTypeInfo(); 822 822 #if DMDV2 823 823 Type *toHeadMutable(); 824 824 MATCH constConv(Type *to); 825 825 #if CPP_MANGLE 826 826 void toCppMangle(OutBuffer *buf, CppMangleState *cms); 827 827 #endif 828 828 #endif 829 829 830 830 type *toCtype(); 831 831 832 832 Symbol *toSymbol(); 833 833 }; 834 834 835 835 struct TypeTuple : Type 836 836 { 837 837 Parameters *arguments; // types making up the tuple trunk/src/statement.c
r636 r639 369 369 } 370 370 371 371 void DeclarationStatement::scopeCode(Scope *sc, Statement **sentry, Statement **sexception, Statement **sfinally) 372 372 { 373 373 //printf("DeclarationStatement::scopeCode()\n"); 374 374 //print(); 375 375 376 376 *sentry = NULL; 377 377 *sexception = NULL; 378 378 *sfinally = NULL; 379 379 380 380 if (exp) 381 381 { 382 382 if (exp->op == TOKdeclaration) 383 383 { 384 384 DeclarationExp *de = (DeclarationExp *)(exp); 385 385 VarDeclaration *v = de->declaration->isVarDeclaration(); 386 386 if (v) 387 387 { Expression *e; 388 388 389 e = v->call AutoDtor(sc);389 e = v->callScopeDtor(sc); 390 390 if (e) 391 391 { 392 392 //printf("dtor is: "); e->print(); 393 393 #if 0 394 394 if (v->type->toBasetype()->ty == Tstruct) 395 395 { /* Need a 'gate' to turn on/off destruction, 396 396 * in case v gets moved elsewhere. 397 397 */ 398 398 Identifier *id = Lexer::uniqueId("__runDtor"); 399 399 ExpInitializer *ie = new ExpInitializer(loc, new IntegerExp(1)); 400 400 VarDeclaration *rd = new VarDeclaration(loc, Type::tint32, id, ie); 401 401 *sentry = new DeclarationStatement(loc, rd); 402 402 v->rundtor = rd; 403 403 404 404 /* Rewrite e as: 405 405 * rundtor && e 406 406 */ 407 407 Expression *ve = new VarExp(loc, v->rundtor); 408 408 e = new AndAndExp(loc, ve, e); 409 409 e->type = Type::tbool; … … 1743 1743 } 1744 1744 #endif 1745 1745 case Tdelegate: 1746 1746 Lapply: 1747 1747 { 1748 1748 Expression *ec; 1749 1749 Expression *e; 1750 1750 Parameter *a; 1751 1751 1752 1752 if (!checkForArgTypes()) 1753 1753 { body = body->semanticNoScope(sc); 1754 1754 return this; 1755 1755 } 1756 1756 1757 1757 Type *tret = func->type->nextOf(); 1758 1758 1759 1759 // Need a variable to hold value from any return statements in body. 1760 1760 if (!sc->func->vresult && tret && tret != Type::tvoid) 1761 1761 { 1762 1762 VarDeclaration *v = new VarDeclaration(loc, tret, Id::result, NULL); 1763 v->no auto= 1;1763 v->noscope = 1; 1764 1764 v->semantic(sc); 1765 1765 if (!sc->insert(v)) 1766 1766 assert(0); 1767 1767 v->parent = sc->func; 1768 1768 sc->func->vresult = v; 1769 1769 } 1770 1770 1771 1771 /* Turn body into the function literal: 1772 1772 * int delegate(ref T arg) { body } 1773 1773 */ 1774 1774 Parameters *args = new Parameters(); 1775 1775 for (size_t i = 0; i < dim; i++) 1776 1776 { Parameter *arg = (Parameter *)arguments->data[i]; 1777 1777 Identifier *id; 1778 1778 1779 1779 arg->type = arg->type->semantic(loc, sc); 1780 1780 if (arg->storageClass & STCref) 1781 1781 id = arg->ident; 1782 1782 else 1783 1783 { // Make a copy of the ref argument so it isn't … … 2323 2323 // If we can short-circuit evaluate the if statement, don't do the 2324 2324 // semantic analysis of the skipped code. 2325 2325 // This feature allows a limited form of conditional compilation. 2326 2326 condition = condition->optimize(WANTflags); 2327 2327 2328 2328 // Evaluate at runtime 2329 2329 unsigned cs0 = sc->callSuper; 2330 2330 unsigned cs1; 2331 2331 2332 2332 Scope *scd; 2333 2333 if (arg) 2334 2334 { /* Declare arg, which we will set to be the 2335 2335 * result of condition. 2336 2336 */ 2337 2337 ScopeDsymbol *sym = new ScopeDsymbol(); 2338 2338 sym->parent = sc->scopesym; 2339 2339 scd = sc->push(sym); 2340 2340 2341 2341 Type *t = arg->type ? arg->type : condition->type; 2342 2342 match = new VarDeclaration(loc, t, arg->ident, NULL); 2343 match->no auto= 1;2343 match->noscope = 1; 2344 2344 match->semantic(scd); 2345 2345 if (!scd->insert(match)) 2346 2346 assert(0); 2347 2347 match->parent = sc->func; 2348 2348 2349 2349 /* Generate: 2350 2350 * (arg = condition) 2351 2351 */ 2352 2352 VarExp *v = new VarExp(0, match); 2353 2353 condition = new AssignExp(loc, v, condition); 2354 2354 condition = condition->semantic(scd); 2355 2355 } 2356 2356 else 2357 2357 scd = sc->push(); 2358 2358 2359 2359 ifbody = ifbody->semanticNoScope(scd); 2360 2360 scd->pop(); 2361 2361 2362 2362 cs1 = sc->callSuper; 2363 2363 sc->callSuper = cs0; … … 3479 3479 sc->fes->cases->push(this); 3480 3480 // Construct: return cases->dim+1; 3481 3481 s = new ReturnStatement(0, new IntegerExp(sc->fes->cases->dim + 1)); 3482 3482 } 3483 3483 else if (fd->type->nextOf()->toBasetype() == Type::tvoid) 3484 3484 { 3485 3485 s = new ReturnStatement(0, NULL); 3486 3486 sc->fes->cases->push(s); 3487 3487 3488 3488 // Construct: { exp; return cases->dim + 1; } 3489 3489 Statement *s1 = new ExpStatement(loc, exp); 3490 3490 Statement *s2 = new ReturnStatement(0, new IntegerExp(sc->fes->cases->dim + 1)); 3491 3491 s = new CompoundStatement(loc, s1, s2); 3492 3492 } 3493 3493 else 3494 3494 { 3495 3495 // Construct: return vresult; 3496 3496 if (!fd->vresult) 3497 3497 { // Declare vresult 3498 3498 VarDeclaration *v = new VarDeclaration(loc, tret, Id::result, NULL); 3499 v->no auto= 1;3499 v->noscope = 1; 3500 3500 v->storage_class |= STCresult; 3501 3501 v->semantic(scx); 3502 3502 if (!scx->insert(v)) 3503 3503 assert(0); 3504 3504 v->parent = fd; 3505 3505 fd->vresult = v; 3506 3506 } 3507 3507 3508 3508 s = new ReturnStatement(0, new VarExp(0, fd->vresult)); 3509 3509 sc->fes->cases->push(s); 3510 3510 3511 3511 // Construct: { vresult = exp; return cases->dim + 1; } 3512 3512 exp = new ConstructExp(loc, new VarExp(0, fd->vresult), exp); 3513 3513 exp = exp->semantic(sc); 3514 3514 Statement *s1 = new ExpStatement(loc, exp); 3515 3515 Statement *s2 = new ReturnStatement(0, new IntegerExp(sc->fes->cases->dim + 1)); 3516 3516 s = new CompoundStatement(loc, s1, s2); 3517 3517 } 3518 3518 return s; 3519 3519 }
