Changeset 1587:def7a1d494fd
- Timestamp:
- 11/06/09 17:58:01 (10 months ago)
- Files:
-
- dmd/aggregate.h (modified) (1 diff)
- dmd/arrayop.c (modified) (4 diffs)
- dmd/attrib.c (modified) (8 diffs)
- dmd/attrib.h (modified) (1 diff)
- dmd/cast.c (modified) (2 diffs)
- dmd/class.c (modified) (14 diffs)
- dmd/constfold.c (modified) (3 diffs)
- dmd/declaration.c (modified) (11 diffs)
- dmd/declaration.h (modified) (6 diffs)
- dmd/doc.c (modified) (11 diffs)
- dmd/dsymbol.c (modified) (10 diffs)
- dmd/dsymbol.h (modified) (1 diff)
- dmd/enum.h (modified) (1 diff)
- dmd/expression.c (modified) (44 diffs)
- dmd/expression.h (modified) (7 diffs)
- dmd/func.c (modified) (20 diffs)
- dmd/idgen.c (modified) (2 diffs)
- dmd/import.c (modified) (2 diffs)
- dmd/import.h (modified) (1 diff)
- dmd/init.c (modified) (3 diffs)
- dmd/inline.c (modified) (4 diffs)
- dmd/interpret.c (modified) (13 diffs)
- dmd/lexer.c (modified) (2 diffs)
- dmd/lexer.h (modified) (1 diff)
- dmd/mangle.c (modified) (1 diff)
- dmd/mars.c (modified) (2 diffs)
- dmd/mars.h (modified) (5 diffs)
- dmd/module.c (modified) (4 diffs)
- dmd/module.h (modified) (2 diffs)
- dmd/mtype.c (modified) (13 diffs)
- dmd/mtype.h (modified) (1 diff)
- dmd/opover.c (modified) (7 diffs)
- dmd/optimize.c (modified) (2 diffs)
- dmd/parse.c (modified) (2 diffs)
- dmd/root/async.c (modified) (1 diff)
- dmd/root/man.c (modified) (1 diff)
- dmd/root/root.c (modified) (1 diff)
- dmd/scope.c (modified) (3 diffs)
- dmd/scope.h (modified) (1 diff)
- dmd/statement.c (modified) (21 diffs)
- dmd/statement.h (modified) (6 diffs)
- dmd/struct.c (modified) (2 diffs)
- dmd/template.c (modified) (16 diffs)
- dmd/template.h (modified) (3 diffs)
- gen/classes.cpp (modified) (1 diff)
- gen/main.cpp (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
dmd/aggregate.h
Revision 1530:05c235309d6f Revision 1587:def7a1d494fd 45 class ConstantStruct; 45 class ConstantStruct; 46 class GlobalVariable; 46 class GlobalVariable; 47 } 47 } 48 48 49 struct AggregateDeclaration : ScopeDsymbol 49 struct AggregateDeclaration : ScopeDsymbol 50 { 50 { 51 Type *type; 51 Type *type; 52 unsigned storage_class; 52 unsigned storage_class; 53 enum PROT protection; 53 enum PROT protection; 54 Type *handle; // 'this' type 54 Type *handle; // 'this' type 55 unsigned structsize; // size of struct 55 unsigned structsize; // size of struct 56 unsigned alignsize; // size of struct for alignment purposes 56 unsigned alignsize; // size of struct for alignment purposes 57 unsigned structalign; // struct member alignment in effect 57 unsigned structalign; // struct member alignment in effect 58 int hasUnions; // set if aggregate has overlapping fields 58 int hasUnions; // set if aggregate has overlapping fields 59 Array fields; // VarDeclaration fields 59 Array fields; // VarDeclaration fields 60 unsigned sizeok; // set when structsize contains valid data 60 unsigned sizeok; // set when structsize contains valid data 61 // 0: no size 61 // 0: no size 62 // 1: size is correct 62 // 1: size is correct 63 // 2: cannot determine size; fwd referenced 63 // 2: cannot determine size; fwd referenced 64 int isdeprecated; // !=0 if deprecated 64 int isdeprecated; // !=0 if deprecated 65 Scope *scope; // !=NULL means context to use66 65 67 // Special member functions 66 // Special member functions 68 InvariantDeclaration *inv; // invariant 67 InvariantDeclaration *inv; // invariant 69 NewDeclaration *aggNew; // allocator 68 NewDeclaration *aggNew; // allocator 70 DeleteDeclaration *aggDelete; // deallocator 69 DeleteDeclaration *aggDelete; // deallocator 70 71 #if DMDV2 72 //CtorDeclaration *ctor; 73 Dsymbol *ctor; // CtorDeclaration or TemplateDeclaration 74 CtorDeclaration *defaultCtor; // default constructor 75 Dsymbol *aliasthis; // forward unresolved lookups to aliasthis 76 #endif 71 77 72 FuncDeclarations dtors; // Array of destructors 78 FuncDeclarations dtors; // Array of destructors 73 FuncDeclaration *dtor; // aggregate destructor 79 FuncDeclaration *dtor; // aggregate destructor 74 80 75 #ifdef IN_GCC 81 #ifdef IN_GCC 76 Array methods; // flat list of all methods for debug information 82 Array methods; // flat list of all methods for debug information 77 #endif 83 #endif 78 84 79 AggregateDeclaration(Loc loc, Identifier *id); 85 AggregateDeclaration(Loc loc, Identifier *id); 80 void semantic2(Scope *sc); 86 void semantic2(Scope *sc); 81 void semantic3(Scope *sc); 87 void semantic3(Scope *sc); 82 void inlineScan(); 88 void inlineScan(); 83 unsigned size(Loc loc); 89 unsigned size(Loc loc); 84 static void alignmember(unsigned salign, unsigned size, unsigned *poffset); 90 static void alignmember(unsigned salign, unsigned size, unsigned *poffset); 85 Type *getType(); 91 Type *getType(); 86 void addField(Scope *sc, VarDeclaration *v); 92 void addField(Scope *sc, VarDeclaration *v); 87 int isDeprecated(); // is aggregate deprecated? 93 int isDeprecated(); // is aggregate deprecated? 88 FuncDeclaration *buildDtor(Scope *sc); 94 FuncDeclaration *buildDtor(Scope *sc); 89 95 90 void emitComment(Scope *sc); 96 void emitComment(Scope *sc); 97 void toJsonBuffer(OutBuffer *buf); 91 void toDocBuffer(OutBuffer *buf); 98 void toDocBuffer(OutBuffer *buf); 92 99 93 // For access checking 100 // For access checking 94 virtual PROT getAccess(Dsymbol *smember); // determine access to smember 101 virtual PROT getAccess(Dsymbol *smember); // determine access to smember 95 int isFriendOf(AggregateDeclaration *cd); 102 int isFriendOf(AggregateDeclaration *cd); 96 int hasPrivateAccess(Dsymbol *smember); // does smember have private access to members of this class? 103 int hasPrivateAccess(Dsymbol *smember); // does smember have private access to members of this class? 97 void accessCheck(Loc loc, Scope *sc, Dsymbol *smember); 104 void accessCheck(Loc loc, Scope *sc, Dsymbol *smember); 98 105 99 enum PROT prot(); 106 enum PROT prot(); 100 107 101 #if IN_DMD 108 #if IN_DMD 102 // Back end 109 // Back end 103 Symbol *stag; // tag symbol for debug data 110 Symbol *stag; // tag symbol for debug data 104 Symbol *sinit; 111 Symbol *sinit; 105 Symbol *toInitializer(); 112 Symbol *toInitializer(); 106 #endif 113 #endif 107 114 108 AggregateDeclaration *isAggregateDeclaration() { return this; } 115 AggregateDeclaration *isAggregateDeclaration() { return this; } 109 116 110 #if IN_LLVM 117 #if IN_LLVM dmd/arrayop.c
Revision 1408:afecdb8ee962 Revision 1587:def7a1d494fd 1 1 2 // Copyright (c) 1999-200 8by Digital Mars2 // Copyright (c) 1999-2009 by Digital Mars 3 // All Rights Reserved 3 // All Rights Reserved 4 // written by Walter Bright 4 // written by Walter Bright 5 // http://www.digitalmars.com 5 // http://www.digitalmars.com 6 // License for redistribution is by either the Artistic License 6 // License for redistribution is by either the Artistic License 7 // in artistic.txt, or the GNU General Public License in gnu.txt. 7 // in artistic.txt, or the GNU General Public License in gnu.txt. 8 // See the included readme.txt for details. 8 // See the included readme.txt for details. 9 9 10 #include <stdio.h> 10 #include <stdio.h> 11 #include <string.h> 11 #include <string.h> 12 #include <assert.h> 12 #include <assert.h> 13 13 14 #include "rmem.h" 14 #include "rmem.h" 15 15 16 #include "stringtable.h" 16 #include "stringtable.h" 17 17 18 #include "expression.h" 18 #include "expression.h" 19 #include "statement.h" 19 #include "statement.h" 20 #include "mtype.h" 20 #include "mtype.h" 21 #include "declaration.h" 21 #include "declaration.h" 22 #include "scope.h" 22 #include "scope.h" 23 #include "id.h" 23 #include "id.h" 24 #include "module.h" 24 #include "module.h" 25 #include "init.h" 25 #include "init.h" 26 26 27 27 28 /*********************************** 28 /*********************************** 29 * Construct the array operation expression. 29 * Construct the array operation expression. 30 */ 30 */ 31 31 32 Expression *BinExp::arrayOp(Scope *sc) 32 Expression *BinExp::arrayOp(Scope *sc) 33 { 33 { 34 //printf("BinExp::arrayOp() %s\n", toChars()); 35 36 if (type->toBasetype()->nextOf()->toBasetype()->ty == Tvoid) 37 { 38 error("Cannot perform array operations on void[] arrays"); 39 return new ErrorExp(); 40 } 41 34 Expressions *arguments = new Expressions(); 42 Expressions *arguments = new Expressions(); 35 43 36 /* The expression to generate an array operation for is mangled 44 /* The expression to generate an array operation for is mangled 37 * into a name to use as the array operation function name. 45 * into a name to use as the array operation function name. 38 * Mangle in the operands and operators in RPN order, and type. 46 * Mangle in the operands and operators in RPN order, and type. 39 */ 47 */ 40 OutBuffer buf; 48 OutBuffer buf; 41 buf.writestring("_array"); 49 buf.writestring("_array"); 42 buildArrayIdent(&buf, arguments); 50 buildArrayIdent(&buf, arguments); 43 buf.writeByte('_'); 51 buf.writeByte('_'); 44 52 45 /* Append deco of array element type 53 /* Append deco of array element type 46 */ 54 */ 47 #if DMDV2 55 #if DMDV2 48 buf.writestring(type->toBasetype()->nextOf()->toBasetype()->mutableOf()->deco); 56 buf.writestring(type->toBasetype()->nextOf()->toBasetype()->mutableOf()->deco); 49 #else 57 #else 50 buf.writestring(type->toBasetype()->nextOf()->toBasetype()->deco); 58 buf.writestring(type->toBasetype()->nextOf()->toBasetype()->deco); 51 #endif 59 #endif 52 60 53 size_t namelen = buf.offset; 61 size_t namelen = buf.offset; … … 271 279 272 /* Construct the function 280 /* Construct the function 273 */ 281 */ 274 TypeFunction *ftype = new TypeFunction(fparams, type, 0, LINKc); 282 TypeFunction *ftype = new TypeFunction(fparams, type, 0, LINKc); 275 //printf("ftype: %s\n", ftype->toChars()); 283 //printf("ftype: %s\n", ftype->toChars()); 276 fd = new FuncDeclaration(0, 0, Lexer::idPool(name), STCundefined, ftype); 284 fd = new FuncDeclaration(0, 0, Lexer::idPool(name), STCundefined, ftype); 277 fd->fbody = fbody; 285 fd->fbody = fbody; 278 fd->protection = PROTpublic; 286 fd->protection = PROTpublic; 279 fd->linkage = LINKd; 287 fd->linkage = LINKd; 280 288 281 // special attention for array ops 289 // special attention for array ops 282 fd->isArrayOp = true; 290 fd->isArrayOp = true; 283 291 284 sc->module->importedFrom->members->push(fd); 292 sc->module->importedFrom->members->push(fd); 285 293 286 sc = sc->push(); 294 sc = sc->push(); 287 sc->parent = sc->module->importedFrom; 295 sc->parent = sc->module->importedFrom; 288 sc->stc = 0; 296 sc->stc = 0; 289 sc->linkage = LINKd; 297 sc->linkage = LINKd; 290 fd->semantic(sc); 298 fd->semantic(sc); 299 fd->semantic2(sc); 300 fd->semantic3(sc); 291 sc->pop(); 301 sc->pop(); 292 // } 302 // } 293 // else 303 // else 294 // { /* In library, refer to it. 304 // { /* In library, refer to it. 295 // */ 305 // */ 296 // // FIXME 306 // // FIXME 297 // fd = FuncDeclaration::genCfunc(NULL, type, name); 307 // fd = FuncDeclaration::genCfunc(NULL, type, name); 298 // } 308 // } 299 sv->ptrvalue = fd; // cache symbol in hash table 309 sv->ptrvalue = fd; // cache symbol in hash table 300 } 310 } 301 311 302 /* Call the function fd(arguments) 312 /* Call the function fd(arguments) 303 */ 313 */ 304 Expression *ec = new VarExp(0, fd); 314 Expression *ec = new VarExp(0, fd); 305 Expression *e = new CallExp(loc, ec, arguments); 315 Expression *e = new CallExp(loc, ec, arguments); 306 e->type = type; 316 e->type = type; 307 return e; 317 return e; 308 } 318 } 309 319 310 /****************************************** 320 /****************************************** 311 * Construct the identifier for the array operation function, 321 * Construct the identifier for the array operation function, 312 * and build the argument list to pass to it. 322 * and build the argument list to pass to it. 313 */ 323 */ 314 324 315 void Expression::buildArrayIdent(OutBuffer *buf, Expressions *arguments) 325 void Expression::buildArrayIdent(OutBuffer *buf, Expressions *arguments) 316 { 326 { 317 buf->writestring("Exp"); 327 buf->writestring("Exp"); 318 arguments->shift(this); 328 arguments->shift(this); 319 } 329 } 320 330 331 void CastExp::buildArrayIdent(OutBuffer *buf, Expressions *arguments) 332 { 333 Type *tb = type->toBasetype(); 334 if (tb->ty == Tarray || tb->ty == Tsarray) 335 { 336 e1->buildArrayIdent(buf, arguments); 337 } 338 else 339 Expression::buildArrayIdent(buf, arguments); 340 } 341 321 void SliceExp::buildArrayIdent(OutBuffer *buf, Expressions *arguments) 342 void SliceExp::buildArrayIdent(OutBuffer *buf, Expressions *arguments) 322 { 343 { 323 buf->writestring("Slice"); 344 buf->writestring("Slice"); 324 arguments->shift(this); 345 arguments->shift(this); 325 } 346 } 326 347 327 void AssignExp::buildArrayIdent(OutBuffer *buf, Expressions *arguments) 348 void AssignExp::buildArrayIdent(OutBuffer *buf, Expressions *arguments) 328 { 349 { 329 /* Evaluate assign expressions right to left 350 /* Evaluate assign expressions right to left 330 */ 351 */ 331 e2->buildArrayIdent(buf, arguments); 352 e2->buildArrayIdent(buf, arguments); 332 e1->buildArrayIdent(buf, arguments); 353 e1->buildArrayIdent(buf, arguments); 333 buf->writestring("Assign"); 354 buf->writestring("Assign"); 334 } 355 } 335 356 336 #define X(Str) \ 357 #define X(Str) \ 337 void Str##AssignExp::buildArrayIdent(OutBuffer *buf, Expressions *arguments) \ 358 void Str##AssignExp::buildArrayIdent(OutBuffer *buf, Expressions *arguments) \ 338 { \ 359 { \ 339 /* Evaluate assign expressions right to left \ 360 /* Evaluate assign expressions right to left \ 340 */ \ 361 */ \ … … 385 X(Xor) 406 X(Xor) 386 X(And) 407 X(And) 387 X(Or) 408 X(Or) 388 409 389 #undef X 410 #undef X 390 411 391 /****************************************** 412 /****************************************** 392 * Construct the inner loop for the array operation function, 413 * Construct the inner loop for the array operation function, 393 * and build the parameter list. 414 * and build the parameter list. 394 */ 415 */ 395 416 396 Expression *Expression::buildArrayLoop(Arguments *fparams) 417 Expression *Expression::buildArrayLoop(Arguments *fparams) 397 { 418 { 398 Identifier *id = Identifier::generateId("c", fparams->dim); 419 Identifier *id = Identifier::generateId("c", fparams->dim); 399 Argument *param = new Argument(0, type, id, NULL); 420 Argument *param = new Argument(0, type, id, NULL); 400 fparams->shift(param); 421 fparams->shift(param); 401 Expression *e = new IdentifierExp(0, id); 422 Expression *e = new IdentifierExp(0, id); 402 return e; 423 return e; 403 } 424 } 404 425 426 Expression *CastExp::buildArrayLoop(Arguments *fparams) 427 { 428 Type *tb = type->toBasetype(); 429 if (tb->ty == Tarray || tb->ty == Tsarray) 430 { 431 return e1->buildArrayLoop(fparams); 432 } 433 else 434 return Expression::buildArrayLoop(fparams); 435 } 436 405 Expression *SliceExp::buildArrayLoop(Arguments *fparams) 437 Expression *SliceExp::buildArrayLoop(Arguments *fparams) 406 { 438 { 407 Identifier *id = Identifier::generateId("p", fparams->dim); 439 Identifier *id = Identifier::generateId("p", fparams->dim); 408 Argument *param = new Argument(STCconst, type, id, NULL); 440 Argument *param = new Argument(STCconst, type, id, NULL); 409 fparams->shift(param); 441 fparams->shift(param); 410 Expression *e = new IdentifierExp(0, id); 442 Expression *e = new IdentifierExp(0, id); 411 Expressions *arguments = new Expressions(); 443 Expressions *arguments = new Expressions(); 412 Expression *index = new IdentifierExp(0, Id::p); 444 Expression *index = new IdentifierExp(0, Id::p); 413 arguments->push(index); 445 arguments->push(index); 414 e = new ArrayExp(0, e, arguments); 446 e = new ArrayExp(0, e, arguments); 415 return e; 447 return e; 416 } 448 } 417 449 418 Expression *AssignExp::buildArrayLoop(Arguments *fparams) 450 Expression *AssignExp::buildArrayLoop(Arguments *fparams) 419 { 451 { 420 /* Evaluate assign expressions right to left 452 /* Evaluate assign expressions right to left 421 */ 453 */ 422 Expression *ex2 = e2->buildArrayLoop(fparams); 454 Expression *ex2 = e2->buildArrayLoop(fparams); 455 #if DMDV2 456 /* Need the cast because: 457 * b = c + p[i]; 458 * where b is a byte fails because (c + p[i]) is an int 459 * which cannot be implicitly cast to byte. 460 */ 461 ex2 = new CastExp(0, ex2, e1->type->nextOf()); 462 #endif 423 Expression *ex1 = e1->buildArrayLoop(fparams); 463 Expression *ex1 = e1->buildArrayLoop(fparams); 424 Argument *param = (Argument *)fparams->data[0]; 464 Argument *param = (Argument *)fparams->data[0]; 425 param->storageClass = 0; 465 param->storageClass = 0; 426 Expression *e = new AssignExp(0, ex1, ex2); 466 Expression *e = new AssignExp(0, ex1, ex2); 427 return e; 467 return e; 428 } 468 } 429 469 430 #define X(Str) \ 470 #define X(Str) \ 431 Expression *Str##AssignExp::buildArrayLoop(Arguments *fparams) \ 471 Expression *Str##AssignExp::buildArrayLoop(Arguments *fparams) \ 432 { \ 472 { \ 433 /* Evaluate assign expressions right to left \ 473 /* Evaluate assign expressions right to left \ 434 */ \ 474 */ \ 435 Expression *ex2 = e2->buildArrayLoop(fparams); \ 475 Expression *ex2 = e2->buildArrayLoop(fparams); \ 436 Expression *ex1 = e1->buildArrayLoop(fparams); \ 476 Expression *ex1 = e1->buildArrayLoop(fparams); \ 437 Argument *param = (Argument *)fparams->data[0]; \ 477 Argument *param = (Argument *)fparams->data[0]; \ 438 param->storageClass = 0; \ 478 param->storageClass = 0; \ 439 Expression *e = new Str##AssignExp(0, ex1, ex2); \ 479 Expression *e = new Str##AssignExp(0, ex1, ex2); \ 440 return e; \ 480 return e; \ 441 } 481 } 442 482 … … 471 /* Evaluate assign expressions left to right \ 511 /* Evaluate assign expressions left to right \ 472 */ \ 512 */ \ 473 Expression *ex1 = e1->buildArrayLoop(fparams); \ 513 Expression *ex1 = e1->buildArrayLoop(fparams); \ 474 Expression *ex2 = e2->buildArrayLoop(fparams); \ 514 Expression *ex2 = e2->buildArrayLoop(fparams); \ 475 Expression *e = new Str##Exp(0, ex1, ex2); \ 515 Expression *e = new Str##Exp(0, ex1, ex2); \ 476 return e; \ 516 return e; \ 477 } 517 } 478 518 479 X(Add) 519 X(Add) 480 X(Min) 520 X(Min) 481 X(Mul) 521 X(Mul) 482 X(Div) 522 X(Div) 483 X(Mod) 523 X(Mod) 484 X(Xor) 524 X(Xor) 485 X(And) 525 X(And) 486 X(Or) 526 X(Or) 487 527 488 #undef X 528 #undef X 489 529 490 530 531 /*********************************************** 532 * Test if operand is a valid array op operand. 533 */ 534 535 int Expression::isArrayOperand() 536 { 537 //printf("Expression::isArrayOperand() %s\n", toChars()); 538 if (op == TOKslice) 539 return 1; 540 if (type->toBasetype()->ty == Tarray) 541 { 542 switch (op) 543 { 544 case TOKadd: 545 case TOKmin: 546 case TOKmul: 547 case TOKdiv: 548 case TOKmod: 549 case TOKxor: 550 case TOKand: 551 case TOKor: 552 case TOKneg: 553 case TOKtilde: 554 return 1; 555 556 default: 557 break; 558 } 559 } 560 return 0; 561 } dmd/attrib.c
Revision 1392:336faed34424 Revision 1587:def7a1d494fd 9 // See the included readme.txt for details. 9 // See the included readme.txt for details. 10 10 11 #include <stdio.h> 11 #include <stdio.h> 12 #include <stdlib.h> 12 #include <stdlib.h> 13 #include <assert.h> 13 #include <assert.h> 14 14 15 #include "rmem.h" 15 #include "rmem.h" 16 16 17 #include "init.h" 17 #include "init.h" 18 #include "declaration.h" 18 #include "declaration.h" 19 #include "attrib.h" 19 #include "attrib.h" 20 #include "cond.h" 20 #include "cond.h" 21 #include "scope.h" 21 #include "scope.h" 22 #include "id.h" 22 #include "id.h" 23 #include "expression.h" 23 #include "expression.h" 24 #include "dsymbol.h" 24 #include "dsymbol.h" 25 #include "aggregate.h" 25 #include "aggregate.h" 26 #include "module.h" 26 #include "module.h" 27 #include "parse.h" 27 #include "parse.h" 28 #include "template.h" 28 #include "template.h" 29 #if TARGET_NET 30 #include "frontend.net/pragma.h" 31 #endif 29 32 30 #if IN_LLVM 33 #if IN_LLVM 31 #include "../gen/enums.h" 34 #include "../gen/enums.h" 32 35 33 #include "llvm/Support/CommandLine.h" 36 #include "llvm/Support/CommandLine.h" 34 37 35 static llvm::cl::opt<bool> ignoreUnsupportedPragmas("ignore", 38 static llvm::cl::opt<bool> ignoreUnsupportedPragmas("ignore", 36 llvm::cl::desc("Ignore unsupported pragmas"), 39 llvm::cl::desc("Ignore unsupported pragmas"), 37 llvm::cl::ZeroOrMore); 40 llvm::cl::ZeroOrMore); 38 41 39 #endif 42 #endif 40 43 41 44 42 extern void obj_includelib(const char *name); 45 extern void obj_includelib(const char *name); 43 46 44 #if IN_DMD 47 #if IN_DMD 45 void obj_startaddress(Symbol *s); 48 void obj_startaddress(Symbol *s); 46 #endif 49 #endif 47 50 48 51 … … 55 } 58 } 56 59 57 Array *AttribDeclaration::include(Scope *sc, ScopeDsymbol *sd) 60 Array *AttribDeclaration::include(Scope *sc, ScopeDsymbol *sd) 58 { 61 { 59 return decl; 62 return decl; 60 } 63 } 61 64 62 int AttribDeclaration::addMember(Scope *sc, ScopeDsymbol *sd, int memnum) 65 int AttribDeclaration::addMember(Scope *sc, ScopeDsymbol *sd, int memnum) 63 { 66 { 64 int m = 0; 67 int m = 0; 65 Array *d = include(sc, sd); 68 Array *d = include(sc, sd); 66 69 67 if (d) 70 if (d) 68 { 71 { 69 for (unsigned i = 0; i < d->dim; i++) 72 for (unsigned i = 0; i < d->dim; i++) 70 { Dsymbol *s = (Dsymbol *)d->data[i]; 73 { Dsymbol *s = (Dsymbol *)d->data[i]; 71 m |= s->addMember(sc, sd, m | memnum); 74 m |= s->addMember(sc, sd, m | memnum); 72 } 75 } 73 } 76 } 74 return m; 77 return m; 78 } 79 80 void AttribDeclaration::setScopeNewSc(Scope *sc, 81 unsigned stc, enum LINK linkage, enum PROT protection, int explicitProtection, 82 unsigned structalign) 83 { 84 if (decl) 85 { 86 Scope *newsc = sc; 87 if (stc != sc->stc || 88 linkage != sc->linkage || 89 protection != sc->protection || 90 explicitProtection != sc->explicitProtection || 91 structalign != sc->structalign) 92 { 93 // create new one for changes 94 newsc = new Scope(*sc); 95 newsc->flags &= ~SCOPEfree; 96 newsc->stc = stc; 97 newsc->linkage = linkage; 98 newsc->protection = protection; 99 newsc->explicitProtection = explicitProtection; 100 newsc->structalign = structalign; 101 } 102 for (unsigned i = 0; i < decl->dim; i++) 103 { Dsymbol *s = (Dsymbol *)decl->data[i]; 104 105 s->setScope(newsc); // yes, the only difference from semanticNewSc() 106 } 107 if (newsc != sc) 108 { 109 sc->offset = newsc->offset; 110 newsc->pop(); 111 } 112 } 113 } 114 115 void AttribDeclaration::semanticNewSc(Scope *sc, 116 unsigned stc, enum LINK linkage, enum PROT protection, int explicitProtection, 117 unsigned structalign) 118 { 119 if (decl) 120 { 121 Scope *newsc = sc; 122 if (stc != sc->stc || 123 linkage != sc->linkage || 124 protection != sc->protection || 125 explicitProtection != sc->explicitProtection || 126 structalign != sc->structalign) 127 { 128 // create new one for changes 129 newsc = new Scope(*sc); 130 newsc->flags &= ~SCOPEfree; 131 newsc->stc = stc; 132 newsc->linkage = linkage; 133 newsc->protection = protection; 134 newsc->explicitProtection = explicitProtection; 135 newsc->structalign = structalign; 136 } 137 for (unsigned i = 0; i < decl->dim; i++) 138 { Dsymbol *s = (Dsymbol *)decl->data[i]; 139 140 s->semantic(newsc); 141 } 142 if (newsc != sc) 143 { 144 sc->offset = newsc->offset; 145 newsc->pop(); 146 } 147 } 75 } 148 } 76 149 77 void AttribDeclaration::semantic(Scope *sc) 150 void AttribDeclaration::semantic(Scope *sc) 78 { 151 { 79 Array *d = include(sc, NULL); 152 Array *d = include(sc, NULL); 80 153 81 //printf("\tAttribDeclaration::semantic '%s', d = %p\n",toChars(), d); 154 //printf("\tAttribDeclaration::semantic '%s', d = %p\n",toChars(), d); 82 if (d) 155 if (d) 83 { 156 { 84 for (unsigned i = 0; i < d->dim; i++) 157 for (unsigned i = 0; i < d->dim; i++) 85 { 158 { 86 Dsymbol *s = (Dsymbol *)d->data[i]; 159 Dsymbol *s = (Dsymbol *)d->data[i]; 87 160 88 s->semantic(sc); 161 s->semantic(sc); 89 } 162 } 90 } 163 } 91 } 164 } 92 165 93 void AttribDeclaration::semantic2(Scope *sc) 166 void AttribDeclaration::semantic2(Scope *sc) 94 { 167 { … … 285 buf->writenl(); 358 buf->writenl(); 286 } 359 } 287 360 288 /************************* StorageClassDeclaration ****************************/ 361 /************************* StorageClassDeclaration ****************************/ 289 362 290 StorageClassDeclaration::StorageClassDeclaration(unsigned stc, Array *decl) 363 StorageClassDeclaration::StorageClassDeclaration(unsigned stc, Array *decl) 291 : AttribDeclaration(decl) 364 : AttribDeclaration(decl) 292 { 365 { 293 this->stc = stc; 366 this->stc = stc; 294 } 367 } 295 368 296 Dsymbol *StorageClassDeclaration::syntaxCopy(Dsymbol *s) 369 Dsymbol *StorageClassDeclaration::syntaxCopy(Dsymbol *s) 297 { 370 { 298 StorageClassDeclaration *scd; 371 StorageClassDeclaration *scd; 299 372 300 assert(!s); 373 assert(!s); 301 scd = new StorageClassDeclaration(stc, Dsymbol::arraySyntaxCopy(decl)); 374 scd = new StorageClassDeclaration(stc, Dsymbol::arraySyntaxCopy(decl)); 302 return scd; 375 return scd; 303 } 376 } 304 377 378 void StorageClassDeclaration::setScope(Scope *sc) 379 { 380 if (decl) 381 { 382 unsigned scstc = sc->stc; 383 384 /* These sets of storage classes are mutually exclusive, 385 * so choose the innermost or most recent one. 386 */ 387 if (stc & (STCauto | STCscope | STCstatic | STCextern | STCmanifest)) 388 scstc &= ~(STCauto | STCscope | STCstatic | STCextern | STCmanifest); 389 if (stc & (STCauto | STCscope | STCstatic | STCtls | STCmanifest | STCgshared)) 390 scstc &= ~(STCauto | STCscope | STCstatic | STCtls | STCmanifest | STCgshared); 391 if (stc & (STCconst | STCimmutable | STCmanifest)) 392 scstc &= ~(STCconst | STCimmutable | STCmanifest); 393 if (stc & (STCgshared | STCshared | STCtls)) 394 scstc &= ~(STCgshared | STCshared | STCtls); 395 scstc |= stc; 396 397 setScopeNewSc(sc, scstc, sc->linkage, sc->protection, sc->explicitProtection, sc->structalign); 398 } 399 } 400 305 void StorageClassDeclaration::semantic(Scope *sc) 401 void StorageClassDeclaration::semantic(Scope *sc) 306 { 402 { 307 if (decl) 403 if (decl) 308 { unsigned stc_save = sc->stc; 404 { 309 405 unsigned scstc = sc->stc; 310 if (stc & (STCauto | STCscope | STCstatic | STCextern)) 406 311 sc->stc &= ~(STCauto | STCscope | STCstatic | STCextern); 407 /* These sets of storage classes are mutually exclusive, 312 sc->stc |= stc; 408 * so choose the innermost or most recent one. 313 for (unsigned i = 0; i < decl->dim; i++) 409 */ 314 { 410 if (stc & (STCauto | STCscope | STCstatic | STCextern | STCmanifest)) 315 Dsymbol *s = (Dsymbol *)decl->data[i]; 411 scstc &= ~(STCauto | STCscope | STCstatic | STCextern | STCmanifest); 316 412 if (stc & (STCauto | STCscope | STCstatic | STCtls | STCmanifest | STCgshared)) 317 s->semantic(sc); 413 scstc &= ~(STCauto | STCscope | STCstatic | STCtls | STCmanifest | STCgshared); 318 } 414 if (stc & (STCconst | STCimmutable | STCmanifest)) 319 sc->stc = stc_save; 415 scstc &= ~(STCconst | STCimmutable | STCmanifest); 320 } 416 if (stc & (STCgshared | STCshared | STCtls)) 321 else 417 scstc &= ~(STCgshared | STCshared | STCtls); 322 sc->stc = stc; 418 scstc |= stc; 419 420 semanticNewSc(sc, scstc, sc->linkage, sc->protection, sc->explicitProtection, sc->structalign); 421 } 323 } 422 } 324 423 325 void StorageClassDeclaration::stcToCBuffer(OutBuffer *buf, int stc) 424 void StorageClassDeclaration::stcToCBuffer(OutBuffer *buf, int stc) 326 { 425 { 327 struct SCstring 426 struct SCstring 328 { 427 { 329 int stc; 428 int stc; 330 enum TOK tok; 429 enum TOK tok; 331 }; 430 }; 332 431 333 static SCstring table[] = 432 static SCstring table[] = 334 { 433 { 335 { STCauto, TOKauto }, 434 { STCauto, TOKauto }, 336 { STCscope, TOKscope }, 435 { STCscope, TOKscope }, 337 { STCstatic, TOKstatic }, 436 { STCstatic, TOKstatic }, 338 { STCextern, TOKextern }, 437 { STCextern, TOKextern }, 339 { STCconst, TOKconst }, 438 { STCconst, TOKconst }, 340 // { STCinvariant, TOKimmutable },341 // { STCshared, TOKshared },342 { STCfinal, TOKfinal }, 439 { STCfinal, TOKfinal }, 343 { STCabstract, TOKabstract }, 440 { STCabstract, TOKabstract }, 344 { STCsynchronized, TOKsynchronized }, 441 { STCsynchronized, TOKsynchronized }, 345 { STCdeprecated, TOKdeprecated }, 442 { STCdeprecated, TOKdeprecated }, 346 { STCoverride, TOKoverride }, 443 { STCoverride, TOKoverride }, 347 // { STCnothrow, TOKnothrow },348 // { STCpure, TOKpure },349 // { STCref, TOKref },350 // { STCtls, TOKtls },351 }; 444 }; 352 445 353 for (int i = 0; i < sizeof(table)/sizeof(table[0]); i++) 446 for (int i = 0; i < sizeof(table)/sizeof(table[0]); i++) 354 { 447 { 355 if (stc & table[i].stc) 448 if (stc & table[i].stc) 356 { 449 { 357 buf->writestring(Token::toChars(table[i].tok)); 450 buf->writestring(Token::toChars(table[i].tok)); 358 buf->writeByte(' '); 451 buf->writeByte(' '); 359 } 452 } 360 } 453 } 361 } 454 } 362 455 363 void StorageClassDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 456 void StorageClassDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 364 { 457 { 365 stcToCBuffer(buf, stc); 458 stcToCBuffer(buf, stc); 366 AttribDeclaration::toCBuffer(buf, hgs); 459 AttribDeclaration::toCBuffer(buf, hgs); 367 } 460 } 368 461 369 /********************************* LinkDeclaration ****************************/ 462 /********************************* LinkDeclaration ****************************/ 370 463 371 LinkDeclaration::LinkDeclaration(enum LINK p, Array *decl) 464 LinkDeclaration::LinkDeclaration(enum LINK p, Array *decl) 372 : AttribDeclaration(decl) 465 : AttribDeclaration(decl) 373 { 466 { 374 //printf("LinkDeclaration(linkage = %d, decl = %p)\n", p, decl); 467 //printf("LinkDeclaration(linkage = %d, decl = %p)\n", p, decl); 375 linkage = p; 468 linkage = p; 376 } 469 } 377 470 378 Dsymbol *LinkDeclaration::syntaxCopy(Dsymbol *s) 471 Dsymbol *LinkDeclaration::syntaxCopy(Dsymbol *s) 379 { 472 { 380 LinkDeclaration *ld; 473 LinkDeclaration *ld; 381 474 382 assert(!s); 475 assert(!s); 383 ld = new LinkDeclaration(linkage, Dsymbol::arraySyntaxCopy(decl)); 476 ld = new LinkDeclaration(linkage, Dsymbol::arraySyntaxCopy(decl)); 384 return ld; 477 return ld; 385 } 478 } 386 479 480 void LinkDeclaration::setScope(Scope *sc) 481 { 482 //printf("LinkDeclaration::setScope(linkage = %d, decl = %p)\n", linkage, decl); 483 if (decl) 484 { 485 setScopeNewSc(sc, sc->stc, linkage, sc->protection, sc->explicitProtection, sc->structalign); 486 } 487 } 488 387 void LinkDeclaration::semantic(Scope *sc) 489 void LinkDeclaration::semantic(Scope *sc) 388 { 490 { 389 //printf("LinkDeclaration::semantic(linkage = %d, decl = %p)\n", linkage, decl); 491 //printf("LinkDeclaration::semantic(linkage = %d, decl = %p)\n", linkage, decl); 390 if (decl) 492 if (decl) 391 { enum LINK linkage_save = sc->linkage; 493 { 392 494 semanticNewSc(sc, sc->stc, linkage, sc->protection, sc->explicitProtection, sc->structalign); 393 sc->linkage = linkage; 394 for (unsigned i = 0; i < decl->dim; i++) 395 { 396 Dsymbol *s = (Dsymbol *)decl->data[i]; 397 398 s->semantic(sc); 399 } 400 sc->linkage = linkage_save; 401 } 402 else 403 { 404 sc->linkage = linkage; 405 } 495 } 406 } 496 } 407 497 408 void LinkDeclaration::semantic3(Scope *sc) 498 void LinkDeclaration::semantic3(Scope *sc) 409 { 499 { 410 //printf("LinkDeclaration::semantic3(linkage = %d, decl = %p)\n", linkage, decl); 500 //printf("LinkDeclaration::semantic3(linkage = %d, decl = %p)\n", linkage, decl); 411 if (decl) 501 if (decl) 412 { enum LINK linkage_save = sc->linkage; 502 { enum LINK linkage_save = sc->linkage; 413 503 414 sc->linkage = linkage; 504 sc->linkage = linkage; 415 for (unsigned i = 0; i < decl->dim; i++) 505 for (unsigned i = 0; i < decl->dim; i++) 416 { 506 { 417 Dsymbol *s = (Dsymbol *)decl->data[i]; 507 Dsymbol *s = (Dsymbol *)decl->data[i]; 418 508 419 s->semantic3(sc); 509 s->semantic3(sc); 420 } 510 } 421 sc->linkage = linkage_save; 511 sc->linkage = linkage_save; 422 } 512 } 423 else 513 else 424 { 514 { … … 456 } 546 } 457 547 458 /********************************* ProtDeclaration ****************************/ 548 /********************************* ProtDeclaration ****************************/ 459 549 460 ProtDeclaration::ProtDeclaration(enum PROT p, Array *decl) 550 ProtDeclaration::ProtDeclaration(enum PROT p, Array *decl) 461 : AttribDeclaration(decl) 551 : AttribDeclaration(decl) 462 { 552 { 463 protection = p; 553 protection = p; 464 //printf("decl = %p\n", decl); 554 //printf("decl = %p\n", decl); 465 } 555 } 466 556 467 Dsymbol *ProtDeclaration::syntaxCopy(Dsymbol *s) 557 Dsymbol *ProtDeclaration::syntaxCopy(Dsymbol *s) 468 { 558 { 469 ProtDeclaration *pd; 559 ProtDeclaration *pd; 470 560 471 assert(!s); 561 assert(!s); 472 pd = new ProtDeclaration(protection, Dsymbol::arraySyntaxCopy(decl)); 562 pd = new ProtDeclaration(protection, Dsymbol::arraySyntaxCopy(decl)); 473 return pd; 563 return pd; 474 } 564 } 475 565 566 void ProtDeclaration::setScope(Scope *sc) 567 { 568 if (decl) 569 { 570 setScopeNewSc(sc, sc->stc, sc->linkage, protection, 1, sc->structalign); 571 } 572 } 573 574 void ProtDeclaration::importAll(Scope *sc) 575 { 576 Scope *newsc = sc; 577 if (sc->protection != protection || 578 sc->explicitProtection != 1) 579 { 580 // create new one for changes 581 newsc = new Scope(*sc); 582 newsc->flags &= ~SCOPEfree; 583 newsc->protection = protection; 584 newsc->explicitProtection = 1; 585 } 586 587 for (int i = 0; i < decl->dim; i++) 588 { 589 Dsymbol *s = (Dsymbol *)decl->data[i]; 590 s->importAll(newsc); 591 } 592 593 if (newsc != sc) 594 newsc->pop(); 595 } 596 476 void ProtDeclaration::semantic(Scope *sc) 597 void ProtDeclaration::semantic(Scope *sc) 477 { 598 { 478 if (decl) 599 if (decl) 479 { enum PROT protection_save = sc->protection; 600 { 480 int explicitProtection_save = sc->explicitProtection; 601 semanticNewSc(sc, sc->stc, sc->linkage, protection, 1, sc->structalign); 481 602 } 482 sc->protection = protection; 603 } 483 sc->explicitProtection = 1; 604 484 for (unsigned i = 0; i < decl->dim; i++) 605 void ProtDeclaration::protectionToCBuffer(OutBuffer *buf, enum PROT protection) 485 { 606 { 486 Dsymbol *s = (Dsymbol *)decl->data[i]; 607 const char *p; 487 488 s->semantic(sc); 489 } 490 sc->protection = protection_save; 491 sc->explicitProtection = explicitProtection_save; 492 } 493 else 494 { sc->protection = protection; 495 sc->explicitProtection = 1; 496 } 497 } 498 499 void ProtDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 500 { const char *p; 501 608 502 switch (protection) 609 switch (protection) 503 { 610 { 504 case PROTprivate: p = "private"; break; 611 case PROTprivate: p = "private"; break; 505 case PROTpackage: p = "package"; break; 612 case PROTpackage: p = "package"; break; 506 case PROTprotected: p = "protected"; break; 613 case PROTprotected: p = "protected"; break; 507 case PROTpublic: p = "public"; break; 614 case PROTpublic: p = "public"; break; 508 case PROTexport: p = "export"; break; 615 case PROTexport: p = "export"; break; 509 default: 616 default: 510 assert(0); 617 assert(0); 511 break; 618 break; 512 } 619 } 513 buf->writestring(p); 620 buf->writestring(p); 621 buf->writeByte(' '); 622 } 623 624 void ProtDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 625 { 626 protectionToCBuffer(buf, protection); 514 AttribDeclaration::toCBuffer(buf, hgs); 627 AttribDeclaration::toCBuffer(buf, hgs); 515 } 628 } 516 629 517 /********************************* AlignDeclaration ****************************/ 630 /********************************* AlignDeclaration ****************************/ 518 631 519 AlignDeclaration::AlignDeclaration(Loc loc, unsigned sa, Array *decl) 632 AlignDeclaration::AlignDeclaration(Loc loc, unsigned sa, Array *decl) 520 : AttribDeclaration(decl) 633 : AttribDeclaration(decl) 521 { 634 { 522 this->loc = loc; 635 this->loc = loc; 523 salign = sa; 636 salign = sa; 524 } 637 } 525 638 526 Dsymbol *AlignDeclaration::syntaxCopy(Dsymbol *s) 639 Dsymbol *AlignDeclaration::syntaxCopy(Dsymbol *s) 527 { 640 { 528 AlignDeclaration *ad; 641 AlignDeclaration *ad; 529 642 530 assert(!s); 643 assert(!s); 531 ad = new AlignDeclaration(loc, salign, Dsymbol::arraySyntaxCopy(decl)); 644 ad = new AlignDeclaration(loc, salign, Dsymbol::arraySyntaxCopy(decl)); 532 return ad; 645 return ad; 533 } 646 } 534 647 648 void AlignDeclaration::setScope(Scope *sc) 649 { 650 //printf("\tAlignDeclaration::setScope '%s'\n",toChars()); 651 if (decl) 652 { 653 setScopeNewSc(sc, sc->stc, sc->linkage, sc->protection, sc->explicitProtection, salign); 654 } 655 } 656 535 void AlignDeclaration::semantic(Scope *sc) 657 void AlignDeclaration::semantic(Scope *sc) 536 { 658 { 537 // LDC 659 // LDC 538 // we only support packed structs, as from the spec: align(1) struct Packed { ... } 660 // we only support packed structs, as from the spec: align(1) struct Packed { ... } 539 // other alignments are simply ignored. my tests show this is what llvm-gcc does too ... 661 // other alignments are simply ignored. my tests show this is what llvm-gcc does too ... 540 662 { 541 //printf("\tAlignDeclaration::semantic '%s'\n",toChars()); 663 semanticNewSc(sc, sc->stc, sc->linkage, sc->protection, sc->explicitProtection, salign); 542 if (decl) 664 } 543 { unsigned salign_save = sc->structalign; 544 545 for (unsigned i = 0; i < decl->dim; i++) 546 { 547 Dsymbol *s = (Dsymbol *)decl->data[i]; 548 549 if (s->isStructDeclaration() && salign == 1) 550 { 551 sc->structalign = salign; 552 s->semantic(sc); 553 sc->structalign = salign_save; 554 } 555 else 556 { 557 s->semantic(sc); 558 } 559 } 560 sc->structalign = salign_save; 561 } 562 else 563 assert(0 && "what kind of align use triggers this?"); 564 } 665 } 565 666 566 667 567 void AlignDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 668 void AlignDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 568 { 669 { 569 buf->printf("align (%d)", salign); 670 buf->printf("align (%d)", salign); 570 AttribDeclaration::toCBuffer(buf, hgs); 671 AttribDeclaration::toCBuffer(buf, hgs); 571 } 672 } 572 673 573 /********************************* AnonDeclaration ****************************/ 674 /********************************* AnonDeclaration ****************************/ 574 675 575 AnonDeclaration::AnonDeclaration(Loc loc, int isunion, Array *decl) 676 AnonDeclaration::AnonDeclaration(Loc loc, int isunion, Array *decl) 576 : AttribDeclaration(decl) 677 : AttribDeclaration(decl) 577 { 678 { 578 this->loc = loc; 679 this->loc = loc; 579 this->isunion = isunion; 680 this->isunion = isunion; 580 this->scope = NULL;581 this->sem = 0; 681 this->sem = 0; 582 } 682 } 583 683 584 Dsymbol *AnonDeclaration::syntaxCopy(Dsymbol *s) 684 Dsymbol *AnonDeclaration::syntaxCopy(Dsymbol *s) 585 { 685 { 586 AnonDeclaration *ad; 686 AnonDeclaration *ad; 587 687 588 assert(!s); 688 assert(!s); 589 ad = new AnonDeclaration(loc, isunion, Dsymbol::arraySyntaxCopy(decl)); 689 ad = new AnonDeclaration(loc, isunion, Dsymbol::arraySyntaxCopy(decl)); 590 return ad; 690 return ad; 591 } 691 } 592 692 593 void AnonDeclaration::semantic(Scope *sc) 693 void AnonDeclaration::semantic(Scope *sc) 594 { 694 { 595 //printf("\tAnonDeclaration::semantic %s %p\n", isunion ? "union" : "struct", this); 695 //printf("\tAnonDeclaration::semantic %s %p\n", isunion ? "union" : "struct", this); 596 696 597 Scope *scx = NULL; 697 Scope *scx = NULL; 598 if (scope) 698 if (scope) 599 { sc = scope; 699 { sc = scope; 600 scx = scope; 700 scx = scope; … … 763 863 764 PragmaDeclaration::PragmaDeclaration(Loc loc, Identifier *ident, Expressions *args, Array *decl) 864 PragmaDeclaration::PragmaDeclaration(Loc loc, Identifier *ident, Expressions *args, Array *decl) 765 : AttribDeclaration(decl) 865 : AttribDeclaration(decl) 766 { 866 { 767 this->loc = loc; 867 this->loc = loc; 768 this->ident = ident; 868 this->ident = ident; 769 this->args = args; 869 this->args = args; 770 } 870 } 771 871 772 Dsymbol *PragmaDeclaration::syntaxCopy(Dsymbol *s) 872 Dsymbol *PragmaDeclaration::syntaxCopy(Dsymbol *s) 773 { 873 { 774 //printf("PragmaDeclaration::syntaxCopy(%s)\n", toChars()); 874 //printf("PragmaDeclaration::syntaxCopy(%s)\n", toChars()); 775 PragmaDeclaration *pd; 875 PragmaDeclaration *pd; 776 876 777 assert(!s); 877 assert(!s); 778 pd = new PragmaDeclaration(loc, ident, 878 pd = new PragmaDeclaration(loc, ident, 779 Expression::arraySyntaxCopy(args), Dsymbol::arraySyntaxCopy(decl)); 879 Expression::arraySyntaxCopy(args), Dsymbol::arraySyntaxCopy(decl)); 780 return pd; 880 return pd; 781 } 881 } 782 882 883 void PragmaDeclaration::setScope(Scope *sc) 884 { 885 #if TARGET_NET 886 if (ident == Lexer::idPool("assembly")) 887 { 888 if (!args || args->dim != 1) 889 { 890 error("pragma has invalid number of arguments"); 891 } 892 else 893 { 894 Expression *e = (Expression *)args->data[0]; 895 e = e->semantic(sc); 896 e = e->optimize(WANTvalue | WANTinterpret); 897 args->data[0] = (void *)e; 898 if (e->op != TOKstring) 899 { 900 error("string expected, not '%s'", e->toChars()); 901 } 902 PragmaScope* pragma = new PragmaScope(this, sc->parent, static_cast<StringExp*>(e)); 903 904 assert(sc); 905 pragma->setScope(sc); 906 907 //add to module members 908 assert(sc->module); 909 assert(sc->module->members); 910 sc->module->members->push(pragma); 911 } 912 } 913 #endif // TARGET_NET 914 } 915 783 void PragmaDeclaration::semantic(Scope *sc) 916 void PragmaDeclaration::semantic(Scope *sc) 784 { // Should be merged with PragmaStatement 917 { // Should be merged with PragmaStatement 785 918 786 #if IN_LLVM 919 #if IN_LLVM 787 int llvm_internal = 0; 920 int llvm_internal = 0; 788 std::string arg1str; 921 std::string arg1str; 789 922 790 #endif 923 #endif 791 924 792 //printf("\tPragmaDeclaration::semantic '%s'\n",toChars()); 925 //printf("\tPragmaDeclaration::semantic '%s'\n",toChars()); 793 if (ident == Id::msg) 926 if (ident == Id::msg) 794 { 927 { 795 if (args) 928 if (args) 796 { 929 { 797 for (size_t i = 0; i < args->dim; i++) 930 for (size_t i = 0; i < args->dim; i++) 798 { 931 { 799 Expression *e = (Expression *)args->data[i]; 932 Expression *e = (Expression *)args->data[i]; 800 933 801 e = e->semantic(sc); 934 e = e->semantic(sc); 802 e = e->optimize(WANTvalue | WANTinterpret); 935 e = e->optimize(WANTvalue | WANTinterpret); 803 if (e->op == TOKstring) 936 if (e->op == TOKstring) 804 { 937 { 805 StringExp *se = (StringExp *)e; 938 StringExp *se = (StringExp *)e; 806 fprintf(stdmsg, "%.*s", (int)se->len, (char *)se->string);939 fprintf(stdmsg, "%.*s", (int)se->len, (char *)se->string); 807 } 940 } 808 else 941 else 809 error("string expected for message, not '%s'", e->toChars());942 fprintf(stdmsg, e->toChars()); 810 } 943 } 811 fprintf(stdmsg, "\n"); 944 fprintf(stdmsg, "\n"); 812 } 945 } 813 goto Lnodecl; 946 goto Lnodecl; 814 } 947 } 815 else if (ident == Id::lib) 948 else if (ident == Id::lib) 816 { 949 { 817 if (!args || args->dim != 1) 950 if (!args || args->dim != 1) 818 error("string expected for library name"); 951 error("string expected for library name"); 819 else 952 else 820 { 953 { 821 Expression *e = (Expression *)args->data[0]; 954 Expression *e = (Expression *)args->data[0]; 822 955 823 e = e->semantic(sc); 956 e = e->semantic(sc); 824 e = e->optimize(WANTvalue | WANTinterpret); 957 e = e->optimize(WANTvalue | WANTinterpret); 825 args->data[0] = (void *)e; 958 args->data[0] = (void *)e; 826 if (e->op != TOKstring) 959 if (e->op != TOKstring) 827 error("string expected for library name, not '%s'", e->toChars()); 960 error("string expected for library name, not '%s'", e->toChars()); 828 else if (global.params.verbose) 961 else if (global.params.verbose) 829 { 962 { … … 856 if (! d->isFuncDeclaration() && ! d->isVarDeclaration()) 989 if (! d->isFuncDeclaration() && ! d->isVarDeclaration()) 857 d = NULL; 990 d = NULL; 858 } 991 } 859 if (!d) 992 if (!d) 860 error("first argument of GNU_asm must be a function or variable declaration"); 993 error("first argument of GNU_asm must be a function or variable declaration"); 861 994 862 e = (Expression *)args->data[1]; 995 e = (Expression *)args->data[1]; 863 e = e->semantic(sc); 996 e = e->semantic(sc); 864 e = e->optimize(WANTvalue); 997 e = e->optimize(WANTvalue); 865 if (e->op == TOKstring && ((StringExp *)e)->sz == 1) 998 if (e->op == TOKstring && ((StringExp *)e)->sz == 1) 866 s = ((StringExp *)e); 999 s = ((StringExp *)e); 867 else 1000 else 868 error("second argument of GNU_asm must be a char string"); 1001 error("second argument of GNU_asm must be a char string"); 869 1002 870 if (d && s) 1003 if (d && s) 871 d->c_ident = Lexer::idPool((char*) s->string); 1004 d->c_ident = Lexer::idPool((char*) s->string); 872 } 1005 } 873 goto Lnodecl; 1006 goto Lnodecl; 874 } 1007 } 875 #endif 1008 #endif 1009 #if TARGET_NET 1010 else if (ident == Lexer::idPool("assembly")) 1011 { 1012 if (!args || args->dim != 1) 1013 error("pragma has invalid number of arguments"); 1014 else 1015 { 1016 Expression *e = (Expression *)args->data[0]; 1017 e = e->semantic(sc); 1018 e = e->optimize(WANTvalue | WANTinterpret); 1019 args->data[0] = (void *)e; 1020 if (e->op != TOKstring) 1021 { 1022 error("string expected, not '%s'", e->toChars()); 1023 } 1024 PragmaScope* pragma = new PragmaScope(this, sc->parent, static_cast<StringExp*>(e)); 1025 decl = new Array; 1026 decl->push(pragma); 1027 } 1028 } 1029 #endif // TARGET_NET 876 1030 877 // LDC 1031 // LDC 878 #if IN_LLVM 1032 #if IN_LLVM 879 1033 880 // pragma(intrinsic, "string") { funcdecl(s) } 1034 // pragma(intrinsic, "string") { funcdecl(s) } 881 else if (ident == Id::intrinsic) 1035 else if (ident == Id::intrinsic) 882 { 1036 { 883 Expression* expr = (Expression *)args->data[0]; 1037 Expression* expr = (Expression *)args->data[0]; 884 expr = expr->semantic(sc); 1038 expr = expr->semantic(sc); 885 if (!args || args->dim != 1 || !parseStringExp(expr, arg1str)) 1039 if (!args || args->dim != 1 || !parseStringExp(expr, arg1str)) 886 { 1040 { 887 error("requires exactly 1 string literal parameter"); 1041 error("requires exactly 1 string literal parameter"); 888 fatal(); 1042 fatal(); 889 } 1043 } 890 llvm_internal = LLVMintrinsic; 1044 llvm_internal = LLVMintrinsic; 891 } 1045 } 892 1046 893 // pragma(notypeinfo) { typedecl(s) } 1047 // pragma(notypeinfo) { typedecl(s) } 894 else if (ident == Id::no_typeinfo) 1048 else if (ident == Id::no_typeinfo) 895 { 1049 { … … 1281 /* If generating doc comment, be careful because if we're inside 1436 /* If generating doc comment, be careful because if we're inside 1282 * a template, then include(NULL, NULL) will fail. 1437 * a template, then include(NULL, NULL) will fail. 1283 */ 1438 */ 1284 Array *d = decl ? decl : elsedecl; 1439 Array *d = decl ? decl : elsedecl; 1285 for (unsigned i = 0; i < d->dim; i++) 1440 for (unsigned i = 0; i < d->dim; i++) 1286 { Dsymbol *s = (Dsymbol *)d->data[i]; 1441 { Dsymbol *s = (Dsymbol *)d->data[i]; 1287 s->emitComment(sc); 1442 s->emitComment(sc); 1288 } 1443 } 1289 } 1444 } 1290 } 1445 } 1291 1446 1292 // Decide if 'then' or 'else' code should be included 1447 // Decide if 'then' or 'else' code should be included 1293 1448 1294 Array *ConditionalDeclaration::include(Scope *sc, ScopeDsymbol *sd) 1449 Array *ConditionalDeclaration::include(Scope *sc, ScopeDsymbol *sd) 1295 { 1450 { 1296 //printf("ConditionalDeclaration::include()\n"); 1451 //printf("ConditionalDeclaration::include()\n"); 1297 assert(condition); 1452 assert(condition); 1298 return condition->include(sc, sd) ? decl : elsedecl; 1453 return condition->include(sc, sd) ? decl : elsedecl; 1299 } 1454 } 1300 1455 1456 void ConditionalDeclaration::setScope(Scope *sc) 1457 { 1458 Array *d = include(sc, NULL); 1459 1460 //printf("\tConditionalDeclaration::setScope '%s', d = %p\n",toChars(), d); 1461 if (d) 1462 { 1463 for (unsigned i = 0; i < d->dim; i++) 1464 { 1465 Dsymbol *s = (Dsymbol *)d->data[i]; 1466 1467 s->setScope(sc); 1468 } 1469 } 1470 } 1471 1472 void ConditionalDeclaration::importAll(Scope *sc) 1473 { 1474 Array *d = include(sc, NULL); 1475 1476 //printf("\tConditionalDeclaration::importAll '%s', d = %p\n",toChars(), d); 1477 if (d) 1478 { 1479 for (unsigned i = 0; i < d->dim; i++) 1480 { 1481 Dsymbol *s = (Dsymbol *)d->data[i]; 1482 1483 s->importAll(sc); 1484 } 1485 } 1486 } 1301 1487 1302 void ConditionalDeclaration::addComment(unsigned char *comment) 1488 void ConditionalDeclaration::addComment(unsigned char *comment) 1303 { 1489 { 1304 /* Because addComment is called by the parser, if we called 1490 /* Because addComment is called by the parser, if we called 1305 * include() it would define a version before it was used. 1491 * include() it would define a version before it was used. 1306 * But it's no problem to drill down to both decl and elsedecl, 1492 * But it's no problem to drill down to both decl and elsedecl, 1307 * so that's the workaround. 1493 * so that's the workaround. 1308 */ 1494 */ 1309 1495 1310 if (comment) 1496 if (comment) 1311 { 1497 { 1312 Array *d = decl; 1498 Array *d = decl; 1313 1499 1314 for (int j = 0; j < 2; j++) 1500 for (int j = 0; j < 2; j++) 1315 { 1501 { 1316 if (d) 1502 if (d) 1317 { 1503 { 1318 for (unsigned i = 0; i < d->dim; i++) 1504 for (unsigned i = 0; i < d->dim; i++) 1319 { Dsymbol *s; 1505 { Dsymbol *s; 1320 1506 … … 1401 * in the same scope, such as: 1587 * in the same scope, such as: 1402 * 1588 * 1403 * template Foo(int i) 1589 * template Foo(int i) 1404 * { 1590 * { 1405 * const int j = i + 1; 1591 * const int j = i + 1; 1406 * static if (j == 3) 1592 * static if (j == 3) 1407 * const int k; 1593 * const int k; 1408 * } 1594 * } 1409 */ 1595 */ 1410 this->sd = sd; 1596 this->sd = sd; 1411 int m = 0; 1597 int m = 0; 1412 1598 1413 if (memnum == 0) 1599 if (memnum == 0) 1414 { m = AttribDeclaration::addMember(sc, sd, memnum); 1600 { m = AttribDeclaration::addMember(sc, sd, memnum); 1415 addisdone = 1; 1601 addisdone = 1; 1416 } 1602 } 1417 return m; 1603 return m; 1418 } 1604 } 1419 1605 1420 1606 1607 void StaticIfDeclaration::importAll(Scope *sc) 1608 { 1609 // do not evaluate condition before semantic pass 1610 } 1611 1612 void StaticIfDeclaration::setScope(Scope *sc) 1613 { 1614 // do not evaluate condition before semantic pass 1615 } 1616 1421 void StaticIfDeclaration::semantic(Scope *sc) 1617 void StaticIfDeclaration::semantic(Scope *sc) 1422 { 1618 { 1423 Array *d = include(sc, sd); 1619 Array *d = include(sc, sd); 1424 1620 1425 //printf("\tStaticIfDeclaration::semantic '%s', d = %p\n",toChars(), d); 1621 //printf("\tStaticIfDeclaration::semantic '%s', d = %p\n",toChars(), d); 1426 if (d) 1622 if (d) 1427 { 1623 { 1428 if (!addisdone) 1624 if (!addisdone) 1429 { AttribDeclaration::addMember(sc, sd, 1); 1625 { AttribDeclaration::addMember(sc, sd, 1); 1430 addisdone = 1; 1626 addisdone = 1; 1431 } 1627 } 1432 1628 1433 for (unsigned i = 0; i < d->dim; i++) 1629 for (unsigned i = 0; i < d->dim; i++) 1434 { 1630 { 1435 Dsymbol *s = (Dsymbol *)d->data[i]; 1631 Dsymbol *s = (Dsymbol *)d->data[i]; 1436 1632 1437 s->semantic(sc); 1633 s->semantic(sc); 1438 } 1634 } 1439 } 1635 } 1440 } 1636 } dmd/attrib.h
Revision 1228:79758fd2f48a Revision 1587:def7a1d494fd 1 1 2 // Compiler implementation of the D programming language 2 // Compiler implementation of the D programming language 3 // Copyright (c) 1999-200 7by Digital Mars3 // Copyright (c) 1999-2009 by Digital Mars 4 // All Rights Reserved 4 // All Rights Reserved 5 // written by Walter Bright 5 // written by Walter Bright 6 // http://www.digitalmars.com 6 // http://www.digitalmars.com 7 // License for redistribution is by either the Artistic License 7 // License for redistribution is by either the Artistic License 8 // in artistic.txt, or the GNU General Public License in gnu.txt. 8 // in artistic.txt, or the GNU General Public License in gnu.txt. 9 // See the included readme.txt for details. 9 // See the included readme.txt for details. 10 10 11 #ifndef DMD_ATTRIB_H 11 #ifndef DMD_ATTRIB_H 12 #define DMD_ATTRIB_H 12 #define DMD_ATTRIB_H 13 13 14 #ifdef __DMC__ 14 #ifdef __DMC__ 15 #pragma once 15 #pragma once 16 #endif /* __DMC__ */ 16 #endif /* __DMC__ */ 17 17 18 #include "dsymbol.h" 18 #include "dsymbol.h" 19 19 20 struct Expression; 20 struct Expression; 21 struct Statement; 21 struct Statement; 22 struct LabelDsymbol; 22 struct LabelDsymbol; 23 struct Initializer; 23 struct Initializer; 24 struct Module; 24 struct Module; 25 struct Condition; 25 struct Condition; 26 #ifdef _DH 26 #ifdef _DH 27 struct HdrGenState; 27 struct HdrGenState; 28 #endif 28 #endif 29 29 30 /**************************************************************/ 30 /**************************************************************/ 31 31 32 struct AttribDeclaration : Dsymbol 32 struct AttribDeclaration : Dsymbol 33 { 33 { 34 Array *decl; // array of Dsymbol's 34 Array *decl; // array of Dsymbol's 35 35 36 AttribDeclaration(Array *decl); 36 AttribDeclaration(Array *decl); 37 virtual Array *include(Scope *sc, ScopeDsymbol *s); 37 virtual Array *include(Scope *sc, ScopeDsymbol *s); 38 int addMember(Scope *sc, ScopeDsymbol *s, int memnum); 38 int addMember(Scope *sc, ScopeDsymbol *s, int memnum); 39 void setScopeNewSc(Scope *sc, 40 unsigned newstc, enum LINK linkage, enum PROT protection, int explictProtection, 41 unsigned structalign); 42 void semanticNewSc(Scope *sc, 43 unsigned newstc, enum LINK linkage, enum PROT protection, int explictProtection, 44 unsigned structalign); 39 void semantic(Scope *sc); 45 void semantic(Scope *sc); 40 void semantic2(Scope *sc); 46 void semantic2(Scope *sc); 41 void semantic3(Scope *sc); 47 void semantic3(Scope *sc); 42 void inlineScan(); 48 void inlineScan(); 43 void addComment(unsigned char *comment); 49 void addComment(unsigned char *comment); 44 void emitComment(Scope *sc); 50 void emitComment(Scope *sc); 45 const char *kind(); 51 const char *kind(); 46 int oneMember(Dsymbol **ps); 52 int oneMember(Dsymbol **ps); 47 int hasPointers(); 53 int hasPointers(); 48 void checkCtorConstInit(); 54 void checkCtorConstInit(); 49 void addLocalClass(ClassDeclarations *); 55 void addLocalClass(ClassDeclarations *); 50 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 56 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 57 void toJsonBuffer(OutBuffer *buf); 51 AttribDeclaration *isAttribDeclaration() { return this; } 58 AttribDeclaration *isAttribDeclaration() { return this; } 52 59 53 #if IN_DMD 60 #if IN_DMD 54 virtual void toObjFile(int multiobj); // compile to .obj file 61 virtual void toObjFile(int multiobj); // compile to .obj file 55 int cvMember(unsigned char *p); 62 int cvMember(unsigned char *p); 56 #endif 63 #endif 57 64 58 #if IN_LLVM 65 #if IN_LLVM 59 virtual void codegen(Ir*); 66 virtual void codegen(Ir*); 60 #endif 67 #endif 61 }; 68 }; 62 69 63 struct StorageClassDeclaration: AttribDeclaration 70 struct StorageClassDeclaration: AttribDeclaration 64 { 71 { 65 unsigned stc; 72 unsigned stc; 66 73 67 StorageClassDeclaration(unsigned stc, Array *decl); 74 StorageClassDeclaration(unsigned stc, Array *decl); 68 Dsymbol *syntaxCopy(Dsymbol *s); 75 Dsymbol *syntaxCopy(Dsymbol *s); 76 void setScope(Scope *sc); 69 void semantic(Scope *sc); 77 void semantic(Scope *sc); 70 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 78 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 71 79 72 static void stcToCBuffer(OutBuffer *buf, int stc); 80 static void stcToCBuffer(OutBuffer *buf, int stc); 73 }; 81 }; 74 82 75 struct LinkDeclaration : AttribDeclaration 83 struct LinkDeclaration : AttribDeclaration 76 { 84 { 77 enum LINK linkage; 85 enum LINK linkage; 78 86 79 LinkDeclaration(enum LINK p, Array *decl); 87 LinkDeclaration(enum LINK p, Array *decl); 80 Dsymbol *syntaxCopy(Dsymbol *s); 88 Dsymbol *syntaxCopy(Dsymbol *s); 89 void setScope(Scope *sc); 81 void semantic(Scope *sc); 90 void semantic(Scope *sc); 82 void semantic3(Scope *sc); 91 void semantic3(Scope *sc); 83 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 92 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 84 char *toChars(); 93 char *toChars(); 85 }; 94 }; 86 95 87 struct ProtDeclaration : AttribDeclaration 96 struct ProtDeclaration : AttribDeclaration 88 { 97 { 89 enum PROT protection; 98 enum PROT protection; 90 99 91 ProtDeclaration(enum PROT p, Array *decl); 100 ProtDeclaration(enum PROT p, Array *decl); 92 Dsymbol *syntaxCopy(Dsymbol *s); 101 Dsymbol *syntaxCopy(Dsymbol *s); 93 void semantic(Scope *sc); 102 void importAll(Scope *sc); 94 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 103 void setScope(Scope *sc); 104 void semantic(Scope *sc); 105 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 106 107 static void protectionToCBuffer(OutBuffer *buf, enum PROT protection); 95 }; 108 }; 96 109 97 struct AlignDeclaration : AttribDeclaration 110 struct AlignDeclaration : AttribDeclaration 98 { 111 { 99 unsigned salign; 112 unsigned salign; 100 113 101 AlignDeclaration(Loc loc, unsigned sa, Array *decl); 114 AlignDeclaration(Loc loc, unsigned sa, Array *decl); 102 Dsymbol *syntaxCopy(Dsymbol *s); 115 Dsymbol *syntaxCopy(Dsymbol *s); 116 void setScope(Scope *sc); 103 void semantic(Scope *sc); 117 void semantic(Scope *sc); 104 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 118 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 105 }; 119 }; 106 120 107 struct AnonDeclaration : AttribDeclaration 121 struct AnonDeclaration : AttribDeclaration 108 { 122 { 109 int isunion; 123 int isunion; 110 Scope *scope; // !=NULL means context to use111 int sem; // 1 if successful semantic() 124 int sem; // 1 if successful semantic() 112 125 113 AnonDeclaration(Loc loc, int isunion, Array *decl); 126 AnonDeclaration(Loc loc, int isunion, Array *decl); 114 Dsymbol *syntaxCopy(Dsymbol *s); 127 Dsymbol *syntaxCopy(Dsymbol *s); 115 void semantic(Scope *sc); 128 void semantic(Scope *sc); 116 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 129 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 117 const char *kind(); 130 const char *kind(); 118 }; 131 }; 119 132 120 struct PragmaDeclaration : AttribDeclaration 133 struct PragmaDeclaration : AttribDeclaration 121 { 134 { 122 Expressions *args; // array of Expression's 135 Expressions *args; // array of Expression's 123 136 124 PragmaDeclaration(Loc loc, Identifier *ident, Expressions *args, Array *decl); 137 PragmaDeclaration(Loc loc, Identifier *ident, Expressions *args, Array *decl); 125 Dsymbol *syntaxCopy(Dsymbol *s); 138 Dsymbol *syntaxCopy(Dsymbol *s); 126 void semantic(Scope *sc); 139 void semantic(Scope *sc); 140 void setScope(Scope *sc); 127 int oneMember(Dsymbol **ps); 141 int oneMember(Dsymbol **ps); 128 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 142 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 129 const char *kind(); 143 const char *kind(); 130 144 131 #if IN_DMD 145 #if IN_DMD 132 void toObjFile(int multiobj); // compile to .obj file 146 void toObjFile(int multiobj); // compile to .obj file 133 #endif 147 #endif 134 148 135 #if IN_LLVM 149 #if IN_LLVM 136 void codegen(Ir*); 150 void codegen(Ir*); 137 #endif 151 #endif 138 }; 152 }; 139 153 140 struct ConditionalDeclaration : AttribDeclaration 154 struct ConditionalDeclaration : AttribDeclaration 141 { 155 { 142 Condition *condition; 156 Condition *condition; 143 Array *elsedecl; // array of Dsymbol's for else block 157 Array *elsedecl; // array of Dsymbol's for else block 144 158 145 ConditionalDeclaration(Condition *condition, Array *decl, Array *elsedecl); 159 ConditionalDeclaration(Condition *condition, Array *decl, Array *elsedecl); 146 Dsymbol *syntaxCopy(Dsymbol *s); 160 Dsymbol *syntaxCopy(Dsymbol *s); 147 int oneMember(Dsymbol **ps); 161 int oneMember(Dsymbol **ps); 148 void emitComment(Scope *sc); 162 void emitComment(Scope *sc); 149 Array *include(Scope *sc, ScopeDsymbol *s); 163 Array *include(Scope *sc, ScopeDsymbol *s); 150 void addComment(unsigned char *comment); 164 void addComment(unsigned char *comment); 151 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 165 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 166 void toJsonBuffer(OutBuffer *buf); 167 void importAll(Scope *sc); 168 void setScope(Scope *sc); 152 }; 169 }; 153 170 154 struct StaticIfDeclaration : ConditionalDeclaration 171 struct StaticIfDeclaration : ConditionalDeclaration 155 { 172 { 156 ScopeDsymbol *sd; 173 ScopeDsymbol *sd; 157 int addisdone; 174 int addisdone; 158 175 159 StaticIfDeclaration(Condition *condition, Array *decl, Array *elsedecl); 176 StaticIfDeclaration(Condition *condition, Array *decl, Array *elsedecl); 160 Dsymbol *syntaxCopy(Dsymbol *s); 177 Dsymbol *syntaxCopy(Dsymbol *s); 161 int addMember(Scope *sc, ScopeDsymbol *s, int memnum); 178 int addMember(Scope *sc, ScopeDsymbol *s, int memnum); 162 void semantic(Scope *sc); 179 void semantic(Scope *sc); 180 void importAll(Scope *sc); 181 void setScope(Scope *sc); 163 const char *kind(); 182 const char *kind(); 164 }; 183 }; 165 184 166 // Mixin declarations 185 // Mixin declarations 167 186 168 struct CompileDeclaration : AttribDeclaration 187 struct CompileDeclaration : AttribDeclaration 169 { 188 { 170 Expression *exp; 189 Expression *exp; 171 190 172 ScopeDsymbol *sd; 191 ScopeDsymbol *sd; 173 int compiled; 192 int compiled; 174 193 175 CompileDeclaration(Loc loc, Expression *exp); 194 CompileDeclaration(Loc loc, Expression *exp); 176 Dsymbol *syntaxCopy(Dsymbol *s); 195 Dsymbol *syntaxCopy(Dsymbol *s); 177 int addMember(Scope *sc, ScopeDsymbol *sd, int memnum); 196 int addMember(Scope *sc, ScopeDsymbol *sd, int memnum); 178 void compileIt(Scope *sc); 197 void compileIt(Scope *sc); 179 void semantic(Scope *sc); 198 void semantic(Scope *sc); 180 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 199 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 181 }; 200 }; 182 201 dmd/cast.c
Revision 1367:8026319762be Revision 1587:def7a1d494fd 1061 e->values = (Expressions *)values->copy(); 1061 e->values = (Expressions *)values->copy(); 1062 assert(keys->dim == values->dim); 1062 assert(keys->dim == values->dim); 1063 for (size_t i = 0; i < keys->dim; i++) 1063 for (size_t i = 0; i < keys->dim; i++) 1064 { Expression *ex = (Expression *)values->data[i]; 1064 { Expression *ex = (Expression *)values->data[i]; 1065 ex = ex->castTo(sc, tb->nextOf()); 1065 ex = ex->castTo(sc, tb->nextOf()); 1066 e->values->data[i] = (void *)ex; 1066 e->values->data[i] = (void *)ex; 1067 1067 1068 ex = (Expression *)keys->data[i]; 1068 ex = (Expression *)keys->data[i]; 1069 ex = ex->castTo(sc, ((TypeAArray *)tb)->index); 1069 ex = ex->castTo(sc, ((TypeAArray *)tb)->index); 1070 e->keys->data[i] = (void *)ex; 1070 e->keys->data[i] = (void *)ex; 1071 } 1071 } 1072 e->type = t; 1072 e->type = t; 1073 return e; 1073 return e; 1074 } 1074 } 1075 L1: 1075 L1: 1076 return e->Expression::castTo(sc, t); 1076 return e->Expression::castTo(sc, t); 1077 } 1077 } 1078 1078 1079 Expression *SymOffExp::castTo(Scope *sc, Type *t) 1079 Expression *SymOffExp::castTo(Scope *sc, Type *t) 1080 { 1080 { 1081 Type *tb;1082 1083 #if 0 1081 #if 0 1084 printf("SymOffExp::castTo(this=%s, type=%s, t=%s)\n", 1082 printf("SymOffExp::castTo(this=%s, type=%s, t=%s)\n", 1085 toChars(), type->toChars(), t->toChars()); 1083 toChars(), type->toChars(), t->toChars()); 1086 #endif 1084 #endif 1087 Expression *e = this; 1085 Expression *e = this; 1088 1086 1089 tb = t->toBasetype();1087 Type *tb = t->toBasetype(); 1090 type= type->toBasetype();1088 Type *typeb = type->toBasetype(); 1091 if (tb != type )1089 if (tb != typeb) 1092 { 1090 { 1093 // Look for pointers to functions where the functions are overloaded. 1091 // Look for pointers to functions where the functions are overloaded. 1094 FuncDeclaration *f; 1092 FuncDeclaration *f; 1095 1093 1096 if (type ->ty == Tpointer && type->next->ty == Tfunction &&1094 if (typeb->ty == Tpointer && typeb->next->ty == Tfunction && 1097 tb->ty == Tpointer && tb->next->ty == Tfunction) 1095 tb->ty == Tpointer && tb->next->ty == Tfunction) 1098 { 1096 { 1099 f = var->isFuncDeclaration(); 1097 f = var->isFuncDeclaration(); 1100 if (f) 1098 if (f) 1101 { 1099 { 1102 f = f->overloadExactMatch(tb->next, m); 1100 f = f->overloadExactMatch(tb->next, m); 1103 if (f) 1101 if (f) 1104 { 1102 { 1105 e = new SymOffExp(loc, f, 0); 1103 #if DMDV2 1106 e->type = t; 1104 if (tb->ty == Tdelegate) 1105 { 1106 if (f->needThis() && hasThis(sc)) 1107 { 1108 e = new DelegateExp(loc, new ThisExp(loc), f); 1109 e = e->semantic(sc); 1110 } 1111 else if (f->isNested()) 1112 { 1113 e = new DelegateExp(loc, new IntegerExp(0), f); 1114 e = e->semantic(sc); 1115 } 1116 else if (f->needThis()) 1117 { error("no 'this' to create delegate for %s", f->toChars()); 1118 e = new ErrorExp(); 1119 } 1120 else 1121 { error("cannot cast from function pointer to delegate"); 1122 e = new ErrorExp(); 1123 } 1124 } 1125 else 1126 #endif 1127 { 1128 e = new SymOffExp(loc, f, 0); 1129 e->type = t; 1130 } 1131 #if DMDV2 1132 f->tookAddressOf++; 1133 #endif 1107 return e; 1134 return e; 1108 } 1135 } 1109 } 1136 } 1110 } 1137 } 1111 e = Expression::castTo(sc, t); 1138 e = Expression::castTo(sc, t); 1112 } 1139 } 1113 e->type = t; 1140 else 1141 { 1142 e->type = t; 1143 } 1114 return e; 1144 return e; 1115 } 1145 } 1116 1146 1117 Expression *DelegateExp::castTo(Scope *sc, Type *t) 1147 Expression *DelegateExp::castTo(Scope *sc, Type *t) 1118 { 1148 { 1119 Type *tb; 1149 Type *tb; 1120 #if 0 1150 #if 0 1121 printf("DelegateExp::castTo(this=%s, type=%s, t=%s)\n", 1151 printf("DelegateExp::castTo(this=%s, type=%s, t=%s)\n", 1122 toChars(), type->toChars(), t->toChars()); 1152 toChars(), type->toChars(), t->toChars()); 1123 #endif 1153 #endif 1124 Expression *e = this; 1154 Expression *e = this; 1125 static char msg[] = "cannot form delegate due to covariant return type"; 1155 static char msg[] = "cannot form delegate due to covariant return type"; 1126 1156 1127 tb = t->toBasetype(); 1157 tb = t->toBasetype(); 1128 type = type->toBasetype(); 1158 type = type->toBasetype(); 1129 if (tb != type) 1159 if (tb != type) 1130 { 1160 { 1131 // Look for delegates to functions where the functions are overloaded. 1161 // Look for delegates to functions where the functions are overloaded. 1132 FuncDeclaration *f; 1162 FuncDeclaration *f; 1133 1163 … … 1467 else if (t1->ty == Tsarray && t2->ty == Tsarray && 1497 else if (t1->ty == Tsarray && t2->ty == Tsarray && 1468 e2->implicitConvTo(t1->nextOf()->arrayOf())) 1498 e2->implicitConvTo(t1->nextOf()->arrayOf())) 1469 { 1499 { 1470 Lx1: 1500 Lx1: 1471 t = t1->nextOf()->arrayOf(); 1501 t = t1->nextOf()->arrayOf(); 1472 e1 = e1->castTo(sc, t); 1502 e1 = e1->castTo(sc, t); 1473 e2 = e2->castTo(sc, t); 1503 e2 = e2->castTo(sc, t); 1474 } 1504 } 1475 else if (t1->ty == Tsarray && t2->ty == Tsarray && 1505 else if (t1->ty == Tsarray && t2->ty == Tsarray && 1476 e1->implicitConvTo(t2->nextOf()->arrayOf())) 1506 e1->implicitConvTo(t2->nextOf()->arrayOf())) 1477 { 1507 { 1478 Lx2: 1508 Lx2: 1479 t = t2->nextOf()->arrayOf(); 1509 t = t2->nextOf()->arrayOf(); 1480 e1 = e1->castTo(sc, t); 1510 e1 = e1->castTo(sc, t); 1481 e2 = e2->castTo(sc, t); 1511 e2 = e2->castTo(sc, t); 1482 } 1512 } 1483 else if (t1->isintegral() && t2->isintegral()) 1513 else if (t1->isintegral() && t2->isintegral()) 1484 { 1514 { 1485 assert(0); 1515 assert(0); 1486 } 1516 } 1487 else if (e1-> op == TOKslice&& t1->ty == Tarray &&1517 else if (e1->isArrayOperand() && t1->ty == Tarray && 1488 e2->implicitConvTo(t1->nextOf())) 1518 e2->implicitConvTo(t1->nextOf())) 1489 { // T[] op T 1519 { // T[] op T 1490 e2 = e2->castTo(sc, t1->nextOf()); 1520 e2 = e2->castTo(sc, t1->nextOf()); 1491 t = t1->nextOf()->arrayOf(); 1521 t = t1->nextOf()->arrayOf(); 1492 } 1522 } 1493 else if (e2-> op == TOKslice&& t2->ty == Tarray &&1523 else if (e2->isArrayOperand() && t2->ty == Tarray && 1494 e1->implicitConvTo(t2->nextOf())) 1524 e1->implicitConvTo(t2->nextOf())) 1495 { // T op T[] 1525 { // T op T[] 1496 e1 = e1->castTo(sc, t2->nextOf()); 1526 e1 = e1->castTo(sc, t2->nextOf()); 1497 t = t2->nextOf()->arrayOf(); 1527 t = t2->nextOf()->arrayOf(); 1498 1528 1499 //printf("test %s\n", e->toChars()); 1529 //printf("test %s\n", e->toChars()); 1500 e1 = e1->optimize(WANTvalue); 1530 e1 = e1->optimize(WANTvalue); 1501 if (isCommutative() && e1->isConst()) 1531 if (isCommutative() && e1->isConst()) 1502 { /* Swap operands to minimize number of functions generated 1532 { /* Swap operands to minimize number of functions generated 1503 */ 1533 */ 1504 //printf("swap %s\n", e->toChars()); 1534 //printf("swap %s\n", e->toChars()); 1505 Expression *tmp = e1; 1535 Expression *tmp = e1; 1506 e1 = e2; 1536 e1 = e2; 1507 e2 = tmp; 1537 e2 = tmp; 1508 } 1538 } 1509 } 1539 } 1510 else 1540 else 1511 { 1541 { 1512 Lincompatible: 1542 Lincompatible: 1513 incompatibleTypes(); 1543 incompatibleTypes(); dmd/class.c
Revision 1530:05c235309d6f Revision 1587:def7a1d494fd 1 1 2 // Compiler implementation of the D programming language 2 // Compiler implementation of the D programming language 3 // Copyright (c) 1999-200 8by Digital Mars3 // Copyright (c) 1999-2009 by Digital Mars 4 // All Rights Reserved 4 // All Rights Reserved 5 // written by Walter Bright 5 // written by Walter Bright 6 // http://www.digitalmars.com 6 // http://www.digitalmars.com 7 // License for redistribution is by either the Artistic License 7 // License for redistribution is by either the Artistic License 8 // in artistic.txt, or the GNU General Public License in gnu.txt. 8 // in artistic.txt, or the GNU General Public License in gnu.txt. 9 // See the included readme.txt for details. 9 // See the included readme.txt for details. 10 10 11 #include <stdio.h> 11 #include <stdio.h> 12 #include <stdlib.h> 12 #include <stdlib.h> 13 #include <assert.h> 13 #include <assert.h> 14 14 15 #include "root.h" 15 #include "root.h" 16 #include "rmem.h" 16 #include "rmem.h" 17 17 18 #include "enum.h" 18 #include "enum.h" 19 #include "init.h" 19 #include "init.h" 20 #include "attrib.h" 20 #include "attrib.h" 21 #include "declaration.h" 21 #include "declaration.h" 22 #include "aggregate.h" 22 #include "aggregate.h" 23 #include "id.h" 23 #include "id.h" … … 144 } 144 } 145 145 146 if (id == Id::TypeInfo_Tuple) 146 if (id == Id::TypeInfo_Tuple) 147 { if (Type::typeinfotypelist) 147 { if (Type::typeinfotypelist) 148 Type::typeinfotypelist->error("%s", msg); 148 Type::typeinfotypelist->error("%s", msg); 149 Type::typeinfotypelist = this; 149 Type::typeinfotypelist = this; 150 } 150 } 151 151 152 #if DMDV2 152 #if DMDV2 153 if (id == Id::TypeInfo_Const) 153 if (id == Id::TypeInfo_Const) 154 { if (Type::typeinfoconst) 154 { if (Type::typeinfoconst) 155 Type::typeinfoconst->error("%s", msg); 155 Type::typeinfoconst->error("%s", msg); 156 Type::typeinfoconst = this; 156 Type::typeinfoconst = this; 157 } 157 } 158 158 159 if (id == Id::TypeInfo_Invariant) 159 if (id == Id::TypeInfo_Invariant) 160 { if (Type::typeinfoinvariant) 160 { if (Type::typeinfoinvariant) 161 Type::typeinfoinvariant->error("%s", msg); 161 Type::typeinfoinvariant->error("%s", msg); 162 Type::typeinfoinvariant = this; 162 Type::typeinfoinvariant = this; 163 } 163 } 164 165 if (id == Id::TypeInfo_Shared) 166 { if (Type::typeinfoshared) 167 Type::typeinfoshared->error("%s", msg); 168 Type::typeinfoshared = this; 169 } 164 #endif 170 #endif 165 } 171 } 166 172 167 if (id == Id::Object) 173 if (id == Id::Object) 168 { if (object) 174 { if (object) 169 object->error("%s", msg); 175 object->error("%s", msg); 170 object = this; 176 object = this; 171 } 177 } 172 178 173 if (id == Id::ClassInfo) 179 if (id == Id::ClassInfo) 174 { if (classinfo) 180 { if (classinfo) 175 classinfo->error("%s", msg); 181 classinfo->error("%s", msg); 176 classinfo = this; 182 classinfo = this; 177 } 183 } 178 184 179 if (id == Id::ModuleInfo) 185 if (id == Id::ModuleInfo) 180 { if (Module::moduleinfo) 186 { if (Module::moduleinfo) 181 Module::moduleinfo->error("%s", msg); 187 Module::moduleinfo->error("%s", msg); 182 Module::moduleinfo = this; 188 Module::moduleinfo = this; 183 } 189 } … … 209 BaseClass *b = (BaseClass *)this->baseclasses.data[i]; 215 BaseClass *b = (BaseClass *)this->baseclasses.data[i]; 210 BaseClass *b2 = new BaseClass(b->type->syntaxCopy(), b->protection); 216 BaseClass *b2 = new BaseClass(b->type->syntaxCopy(), b->protection); 211 cd->baseclasses.data[i] = b2; 217 cd->baseclasses.data[i] = b2; 212 } 218 } 213 219 214 ScopeDsymbol::syntaxCopy(cd); 220 ScopeDsymbol::syntaxCopy(cd); 215 return cd; 221 return cd; 216 } 222 } 217 223 218 void ClassDeclaration::semantic(Scope *sc) 224 void ClassDeclaration::semantic(Scope *sc) 219 { int i; 225 { int i; 220 unsigned offset; 226 unsigned offset; 221 227 222 //printf("ClassDeclaration::semantic(%s), type = %p, sizeok = %d, this = %p\n", toChars(), type, sizeok, this); 228 //printf("ClassDeclaration::semantic(%s), type = %p, sizeok = %d, this = %p\n", toChars(), type, sizeok, this); 223 //printf("\tparent = %p, '%s'\n", sc->parent, sc->parent ? sc->parent->toChars() : ""); 229 //printf("\tparent = %p, '%s'\n", sc->parent, sc->parent ? sc->parent->toChars() : ""); 224 //printf("sc->stc = %x\n", sc->stc); 230 //printf("sc->stc = %x\n", sc->stc); 225 231 226 //{ static int n; if (++n == 20) *(char*)0=0; } 232 //{ static int n; if (++n == 20) *(char*)0=0; } 227 233 228 if (!ident) // if anonymous class 234 if (!ident) // if anonymous class 229 { c har *id = "__anonclass";235 { const char *id = "__anonclass"; 230 236 231 ident = Identifier::generateId(id); 237 ident = Identifier::generateId(id); 232 } 238 } 233 239 234 if (!sc ope)240 if (!sc) 235 { 241 sc = scope; 236 if (!parent && sc->parent && !sc->parent->isModule())242 if (!parent && sc->parent && !sc->parent->isModule()) 237 parent = sc->parent;243 parent = sc->parent; 238 244 239 type = type->semantic(loc, sc);245 type = type->semantic(loc, sc); 240 handle = handle->semantic(loc, sc);246 handle = type; 241 } 247 242 if (!members) // if forward reference 248 if (!members) // if forward reference 243 { //printf("\tclass '%s' is forward referenced\n", toChars()); 249 { //printf("\tclass '%s' is forward referenced\n", toChars()); 244 return; 250 return; 245 } 251 } 246 if (symtab) 252 if (symtab) 247 { if (!scope) 253 { if (!scope) 248 { //printf("\tsemantic for '%s' is already completed\n", toChars()); 254 { //printf("\tsemantic for '%s' is already completed\n", toChars()); 249 return; // semantic() already completed 255 return; // semantic() already completed 250 } 256 } 251 } 257 } 252 else 258 else 253 symtab = new DsymbolTable(); 259 symtab = new DsymbolTable(); 254 260 255 Scope *scx = NULL; 261 Scope *scx = NULL; 256 if (scope) 262 if (scope) 257 { sc = scope; 263 { sc = scope; 258 scx = scope; // save so we don't make redundant copies 264 scx = scope; // save so we don't make redundant copies 259 scope = NULL; 265 scope = NULL; 260 } 266 } 261 #ifdef IN_GCC 267 #ifdef IN_GCC … … 312 // Deriving from deprecated class makes this one deprecated too 318 // Deriving from deprecated class makes this one deprecated too 313 isdeprecated = 1; 319 isdeprecated = 1; 314 320 315 tc->checkDeprecated(loc, sc); 321 tc->checkDeprecated(loc, sc); 316 } 322 } 317 } 323 } 318 324 319 if (tc->sym->isInterfaceDeclaration()) 325 if (tc->sym->isInterfaceDeclaration()) 320 ; 326 ; 321 else 327 else 322 { 328 { 323 for (ClassDeclaration *cdb = tc->sym; cdb; cdb = cdb->baseClass) 329 for (ClassDeclaration *cdb = tc->sym; cdb; cdb = cdb->baseClass) 324 { 330 { 325 if (cdb == this) 331 if (cdb == this) 326 { 332 { 327 error("circular inheritance"); 333 error("circular inheritance"); 328 baseclasses.remove(0); 334 baseclasses.remove(0); 329 goto L7; 335 goto L7; 330 } 336 } 331 } 337 } 338 if (!tc->sym->symtab || tc->sym->sizeok == 0) 339 { // Try to resolve forward reference 340 if (sc->mustsemantic && tc->sym->scope) 341 tc->sym->semantic(NULL); 342 } 332 if (!tc->sym->symtab || tc->sym->scope || tc->sym->sizeok == 0) 343 if (!tc->sym->symtab || tc->sym->scope || tc->sym->sizeok == 0) 333 { 344 { 345 //printf("%s: forward reference of base class %s\n", toChars(), tc->sym->toChars()); 334 //error("forward reference of base class %s", baseClass->toChars()); 346 //error("forward reference of base class %s", baseClass->toChars()); 335 // Forward reference of base class, try again later 347 // Forward reference of base class, try again later 336 //printf("\ttry later, forward reference of base class %s\n", tc->sym->toChars()); 348 //printf("\ttry later, forward reference of base class %s\n", tc->sym->toChars()); 337 scope = scx ? scx : new Scope(*sc); 349 scope = scx ? scx : new Scope(*sc); 338 scope->setNoFree(); 350 scope->setNoFree(); 351 if (tc->sym->scope) 352 tc->sym->scope->module->addDeferredSemantic(tc->sym); 339 scope->module->addDeferredSemantic(this); 353 scope->module->addDeferredSemantic(this); 340 return; 354 return; 341 } 355 } 342 else 356 else 343 { baseClass = tc->sym; 357 { baseClass = tc->sym; 344 b->base = baseClass; 358 b->base = baseClass; 345 } 359 } 346 L7: ; 360 L7: ; 347 } 361 } 348 } 362 } 349 } 363 } 350 364 351 // Treat the remaining entries in baseclasses as interfaces 365 // Treat the remaining entries in baseclasses as interfaces 352 // Check for errors, handle forward references 366 // Check for errors, handle forward references 353 for (i = (baseClass ? 1 : 0); i < baseclasses.dim; ) 367 for (i = (baseClass ? 1 : 0); i < baseclasses.dim; ) 354 { TypeClass *tc; 368 { TypeClass *tc; 355 BaseClass *b; 369 BaseClass *b; 356 Type *tb; 370 Type *tb; 357 371 358 b = (BaseClass *)baseclasses.data[i]; 372 b = (BaseClass *)baseclasses.data[i]; … … 372 { 386 { 373 if (tc->sym->isDeprecated()) 387 if (tc->sym->isDeprecated()) 374 { 388 { 375 if (!isDeprecated()) 389 if (!isDeprecated()) 376 { 390 { 377 // Deriving from deprecated class makes this one deprecated too 391 // Deriving from deprecated class makes this one deprecated too 378 isdeprecated = 1; 392 isdeprecated = 1; 379 393 380 tc->checkDeprecated(loc, sc); 394 tc->checkDeprecated(loc, sc); 381 } 395 } 382 } 396 } 383 397 384 // Check for duplicate interfaces 398 // Check for duplicate interfaces 385 for (size_t j = (baseClass ? 1 : 0); j < i; j++) 399 for (size_t j = (baseClass ? 1 : 0); j < i; j++) 386 { 400 { 387 BaseClass *b2 = (BaseClass *)baseclasses.data[j]; 401 BaseClass *b2 = (BaseClass *)baseclasses.data[j]; 388 if (b2->base == tc->sym) 402 if (b2->base == tc->sym) 389 error("inherits from duplicate interface %s", b2->base->toChars()); 403 error("inherits from duplicate interface %s", b2->base->toChars()); 390 } 404 } 391 405 406 if (!tc->sym->symtab) 407 { // Try to resolve forward reference 408 if (sc->mustsemantic && tc->sym->scope) 409 tc->sym->semantic(NULL); 410 } 411 392 b->base = tc->sym; 412 b->base = tc->sym; 393 if (!b->base->symtab || b->base->scope) 413 if (!b->base->symtab || b->base->scope) 394 { 414 { 395 //error("forward reference of base class %s", baseClass->toChars()); 415 //error("forward reference of base class %s", baseClass->toChars()); 396 // Forward reference of base, try again later 416 // Forward reference of base, try again later 397 //printf("\ttry later, forward reference of base %s\n", baseClass->toChars()); 417 //printf("\ttry later, forward reference of base %s\n", baseClass->toChars()); 398 scope = scx ? scx : new Scope(*sc); 418 scope = scx ? scx : new Scope(*sc); 399 scope->setNoFree(); 419 scope->setNoFree(); 420 if (tc->sym->scope) 421 tc->sym->scope->module->addDeferredSemantic(tc->sym); 400 scope->module->addDeferredSemantic(this); 422 scope->module->addDeferredSemantic(this); 401 return; 423 return; 402 } 424 } 403 } 425 } 404 i++; 426 i++; 405 } 427 } 406 428 407 429 408 // If no base class, and this is not an Object, use Object as base class 430 // If no base class, and this is not an Object, use Object as base class 409 if (!baseClass && ident != Id::Object) 431 if (!baseClass && ident != Id::Object) 410 { 432 { 411 // BUG: what if Object is redefined in an inner scope? 433 // BUG: what if Object is redefined in an inner scope? 412 Type *tbase = new TypeIdentifier(0, Id::Object); 434 Type *tbase = new TypeIdentifier(0, Id::Object); 413 BaseClass *b; 435 BaseClass *b; 414 TypeClass *tc; 436 TypeClass *tc; 415 Type *bt; 437 Type *bt; 416 438 417 if (!object) 439 if (!object) 418 { 440 { 419 error("missing or corrupt object.d"); 441 error("missing or corrupt object.d"); … … 483 if (toParent2()) 505 if (toParent2()) 484 { 506 { 485 error("is nested within %s, but super class %s is nested within %s", 507 error("is nested within %s, but super class %s is nested within %s", 486 toParent2()->toChars(), 508 toParent2()->toChars(), 487 baseClass->toChars(), 509 baseClass->toChars(), 488 baseClass->toParent2()->toChars()); 510 baseClass->toParent2()->toChars()); 489 } 511 } 490 else 512 else 491 { 513 { 492 error("is not nested, but super class %s is nested within %s", 514 error("is not nested, but super class %s is nested within %s", 493 baseClass->toChars(), 515 baseClass->toChars(), 494 baseClass->toParent2()->toChars()); 516 baseClass->toParent2()->toChars()); 495 } 517 } 496 isnested = 0; 518 isnested = 0; 497 } 519 } 498 } 520 } 499 else if (!(storage_class & STCstatic)) 521 else if (!(storage_class & STCstatic)) 500 { Dsymbol *s = toParent2(); 522 { Dsymbol *s = toParent2(); 501 if (s) 523 if (s) 502 { 524 { 503 ClassDeclaration *cd = s->isClassDeclaration();525 AggregateDeclaration *ad = s->isClassDeclaration(); 504 FuncDeclaration *fd = s->isFuncDeclaration(); 526 FuncDeclaration *fd = s->isFuncDeclaration(); 505 527 506 528 507 if ( cd || fd)529 if (ad || fd) 508 { isnested = 1; 530 { isnested = 1; 509 Type *t; 531 Type *t; 510 if ( cd)532 if (ad) 511 t = cd->type;533 t = ad->handle; 512 else if (fd) 534 else if (fd) 513 { AggregateDeclaration *ad = fd->isMember2(); 535 { AggregateDeclaration *ad = fd->isMember2(); 514 if (ad) 536 if (ad) 515 t = ad->handle; 537 t = ad->handle; 516 else 538 else 517 { 539 { 518 t = new TypePointer(Type::tvoid); 540 t = new TypePointer(Type::tvoid); 519 t = t->semantic(0, sc); 541 t = t->semantic(0, sc); 520 } 542 } 521 } 543 } 522 else 544 else 523 assert(0); 545 assert(0); 524 assert(!vthis); 546 assert(!vthis); 525 vthis = new ThisDeclaration(loc, t); 547 vthis = new ThisDeclaration(loc, t); 526 members->push(vthis); 548 members->push(vthis); 527 } 549 } 528 } 550 } 529 } 551 } 530 } 552 } 531 553 … … 547 #if _WIN32 569 #if _WIN32 548 sc->linkage = LINKwindows; 570 sc->linkage = LINKwindows; 549 #else 571 #else 550 /* This enables us to use COM objects under Linux and 572 /* This enables us to use COM objects under Linux and 551 * work with things like XPCOM 573 * work with things like XPCOM 552 */ 574 */ 553 sc->linkage = LINKc; 575 sc->linkage = LINKc; 554 #endif 576 #endif 555 } 577 } 556 sc->protection = PROTpublic; 578 sc->protection = PROTpublic; 557 sc->explicitProtection = 0; 579 sc->explicitProtection = 0; 558 sc->structalign = 8; 580 sc->structalign = 8; 559 structalign = sc->structalign; 581 structalign = sc->structalign; 560 if (baseClass) 582 if (baseClass) 561 { sc->offset = baseClass->structsize; 583 { sc->offset = baseClass->structsize; 562 alignsize = baseClass->alignsize; 584 alignsize = baseClass->alignsize; 563 // if (isnested) 585 // if (isnested) 564 // sc->offset += PTRSIZE; // room for uplevel context pointer 586 // sc->offset += PTRSIZE; // room for uplevel context pointer 565 } 587 } 566 else 588 else 567 { sc->offset = PTRSIZE * 2; // allow room for vptr[] andmonitor589 { sc->offset = PTRSIZE * 2; // allow room for __vptr and __monitor 568 alignsize = PTRSIZE; 590 alignsize = PTRSIZE; 569 } 591 } 570 structsize = sc->offset; 592 structsize = sc->offset; 571 Scope scsave = *sc; 593 Scope scsave = *sc; 572 int members_dim = members->dim; 594 int members_dim = members->dim; 573 sizeok = 0; 595 sizeok = 0; 574 for (i = 0; i < members_dim; i++) 596 for (i = 0; i < members_dim; i++) 575 { 597 { 576 Dsymbol *s = (Dsymbol *)members->data[i]; 598 Dsymbol *s = (Dsymbol *)members->data[i]; 577 s->semantic(sc); 599 s->semantic(sc); 578 } 600 } 579 601 580 if (sizeok == 2) 602 if (sizeok == 2) 581 { // semantic() failed because of forward references. 603 { // semantic() failed because of forward references. 582 // Unwind what we did, and defer it for later 604 // Unwind what we did, and defer it for later 583 fields.setDim(0); 605 fields.setDim(0); 584 structsize = 0; 606 structsize = 0; 585 alignsize = 0; 607 alignsize = 0; 586 structalign = 0; 608 structalign = 0; 587 609 … … 686 } 708 } 687 709 688 void ClassDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 710 void ClassDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 689 { 711 { 690 if (!isAnonymous()) 712 if (!isAnonymous()) 691 { 713 { 692 buf->printf("%s ", kind()); 714 buf->printf("%s ", kind()); 693 buf->writestring(toChars()); 715 buf->writestring(toChars()); 694 if (baseclasses.dim) 716 if (baseclasses.dim) 695 buf->writestring(" : "); 717 buf->writestring(" : "); 696 } 718 } 697 for (int i = 0; i < baseclasses.dim; i++) 719 for (int i = 0; i < baseclasses.dim; i++) 698 { 720 { 699 BaseClass *b = (BaseClass *)baseclasses.data[i]; 721 BaseClass *b = (BaseClass *)baseclasses.data[i]; 700 722 701 if (i) 723 if (i) 702 buf->writeByte(','); 724 buf->writeByte(','); 703 //buf->writestring(b->base->ident->toChars()); 725 //buf->writestring(b->base->ident->toChars()); 704 b->type->toCBuffer(buf, NULL, hgs); 726 b->type->toCBuffer(buf, NULL, hgs); 705 } 727 } 706 buf->writenl(); 728 if (members) 707 buf->writeByte('{'); 729 { 708 buf->writenl(); 730 buf->writenl(); 709 for (int i = 0; i < members->dim; i++) 731 buf->writeByte('{'); 710 { 732 buf->writenl(); 711 Dsymbol *s = (Dsymbol *)members->data[i]; 733 for (int i = 0; i < members->dim; i++) 712 734 { 713 buf->writestring(" "); 735 Dsymbol *s = (Dsymbol *)members->data[i]; 714 s->toCBuffer(buf, hgs); 736 715 } 737 buf->writestring(" "); 716 buf->writestring("}"); 738 s->toCBuffer(buf, hgs); 739 } 740 buf->writestring("}"); 741 } 742 else 743 buf->writeByte(';'); 717 buf->writenl(); 744 buf->writenl(); 718 } 745 } 719 746 720 #if 0 747 #if 0 721 void ClassDeclaration::defineRef(Dsymbol *s) 748 void ClassDeclaration::defineRef(Dsymbol *s) 722 { 749 { 723 ClassDeclaration *cd; 750 ClassDeclaration *cd; 724 751 725 AggregateDeclaration::defineRef(s); 752 AggregateDeclaration::defineRef(s); 726 cd = s->isClassDeclaration(); 753 cd = s->isClassDeclaration(); 727 baseType = cd->baseType; 754 baseType = cd->baseType; 728 cd->baseType = NULL; 755 cd->baseType = NULL; 729 } 756 } 730 #endif 757 #endif 731 758 732 /********************************************* 759 /********************************************* 733 * Determine if 'this' is a base class of cd. 760 * Determine if 'this' is a base class of cd. 734 * This is used to detect circular inheritance only. 761 * This is used to detect circular inheritance only. 735 */ 762 */ 736 763 … … 763 return 1; 790 return 1; 764 791 765 /* cd->baseClass might not be set if cd is forward referenced. 792 /* cd->baseClass might not be set if cd is forward referenced. 766 */ 793 */ 767 if (!cd->baseClass && cd->baseclasses.dim && !cd->isInterfaceDeclaration()) 794 if (!cd->baseClass && cd->baseclasses.dim && !cd->isInterfaceDeclaration()) 768 { 795 { 769 cd->error("base class is forward referenced by %s", toChars()); 796 cd->error("base class is forward referenced by %s", toChars()); 770 } 797 } 771 798 772 cd = cd->baseClass; 799 cd = cd->baseClass; 773 } 800 } 774 return 0; 801 return 0; 775 } 802 } 776 803 777 Dsymbol *ClassDeclaration::search(Loc loc, Identifier *ident, int flags) 804 Dsymbol *ClassDeclaration::search(Loc loc, Identifier *ident, int flags) 778 { 805 { 779 Dsymbol *s; 806 Dsymbol *s; 780 807 //printf("%s.ClassDeclaration::search('%s')\n", toChars(), ident->toChars()); 781 //printf("%s.ClassDeclaration::search('%s')\n", toChars(), ident->toChars()); 808 782 if (scope) 809 if (scope) 783 semantic(scope); 810 { Scope *sc = scope; 811 sc->mustsemantic++; 812 semantic(sc); 813 sc->mustsemantic--; 814 } 784 815 785 if (!members || !symtab || scope) 816 if (!members || !symtab || scope) 786 { error("is forward referenced when looking for '%s'", ident->toChars()); 817 { 818 error("is forward referenced when looking for '%s'", ident->toChars()); 787 //*(char*)0=0; 819 //*(char*)0=0; 788 return NULL; 820 return NULL; 789 } 821 } 790 822 791 s = ScopeDsymbol::search(loc, ident, flags); 823 s = ScopeDsymbol::search(loc, ident, flags); 792 if (!s) 824 if (!s) 793 { 825 { 794 // Search bases classes in depth-first, left to right order 826 // Search bases classes in depth-first, left to right order 795 827 796 int i; 828 int i; 797 829 798 for (i = 0; i < baseclasses.dim; i++) 830 for (i = 0; i < baseclasses.dim; i++) 799 { 831 { 800 BaseClass *b = (BaseClass *)baseclasses.data[i]; 832 BaseClass *b = (BaseClass *)baseclasses.data[i]; 801 833 802 if (b->base) 834 if (b->base) 803 { 835 { 804 if (!b->base->symtab) 836 if (!b->base->symtab) 805 error("base %s is forward referenced", b->base->ident->toChars()); 837 error("base %s is forward referenced", b->base->ident->toChars()); 806 else 838 else … … 814 } 846 } 815 } 847 } 816 } 848 } 817 return s; 849 return s; 818 } 850 } 819 851 820 /********************************************************** 852 /********************************************************** 821 * fd is in the vtbl[] for this class. 853 * fd is in the vtbl[] for this class. 822 * Return 1 if function is hidden (not findable through search). 854 * Return 1 if function is hidden (not findable through search). 823 */ 855 */ 824 856 825 #if DMDV2 857 #if DMDV2 826 int isf(void *param, FuncDeclaration *fd) 858 int isf(void *param, FuncDeclaration *fd) 827 { 859 { 828 //printf("param = %p, fd = %p %s\n", param, fd, fd->toChars()); 860 //printf("param = %p, fd = %p %s\n", param, fd, fd->toChars()); 829 return param == fd; 861 return param == fd; 830 } 862 } 831 863 832 int ClassDeclaration::isFuncHidden(FuncDeclaration *fd) 864 int ClassDeclaration::isFuncHidden(FuncDeclaration *fd) 833 { 865 { 834 //printf("ClassDeclaration::isFuncHidden( %s)\n", fd->toChars());866 //printf("ClassDeclaration::isFuncHidden(class = %s, fd = %s)\n", toChars(), fd->toChars()); 835 Dsymbol *s = search(0, fd->ident, 4|2); 867 Dsymbol *s = search(0, fd->ident, 4|2); 836 if (!s) 868 if (!s) 837 { //printf("not found\n"); 869 { //printf("not found\n"); 838 /* Because, due to a hack, if there are multiple definitions 870 /* Because, due to a hack, if there are multiple definitions 839 * of fd->ident, NULL is returned. 871 * of fd->ident, NULL is returned. 840 */ 872 */ 841 return 0; 873 return 0; 842 } 874 } 843 FuncDeclaration *fdstart = s->toAlias()->isFuncDeclaration(); 875 FuncDeclaration *fdstart = s->toAlias()->isFuncDeclaration(); 844 //printf("%s fdstart = %p\n", s->kind(), fdstart); 876 //printf("%s fdstart = %p\n", s->kind(), fdstart); 845 return !overloadApply(getModule(), fdstart, &isf, fd); 877 return !overloadApply(getModule(), fdstart, &isf, fd); 846 } 878 } 847 #endif 879 #endif 848 880 849 /**************** 881 /**************** 850 * Find virtual function matching identifier and type. 882 * Find virtual function matching identifier and type. 851 * Used to build virtual function tables for interface implementations. 883 * Used to build virtual function tables for interface implementations. 852 */ 884 */ 853 885 854 FuncDeclaration *ClassDeclaration::findFunc(Identifier *ident, TypeFunction *tf) 886 FuncDeclaration *ClassDeclaration::findFunc(Identifier *ident, TypeFunction *tf) … … 899 com = 1; 931 com = 1; 900 932 901 vtblInterfaces->push(b); 933 vtblInterfaces->push(b); 902 b->copyBaseInterfaces(vtblInterfaces); 934 b->copyBaseInterfaces(vtblInterfaces); 903 } 935 } 904 } 936 } 905 937 906 /**************************************** 938 /**************************************** 907 */ 939 */ 908 940 909 int ClassDeclaration::isCOMclass() 941 int ClassDeclaration::isCOMclass() 910 { 942 { 911 return com; 943 return com; 912 } 944 } 913 945 914 int ClassDeclaration::isCOMinterface() 946 int ClassDeclaration::isCOMinterface() 915 { 947 { 916 return 0; 948 return 0; 917 } 949 } 918 950 951 #if DMDV2 952 int ClassDeclaration::isCPPinterface() 953 { 954 return 0; 955 } 956 #endif 957 919 958 920 /**************************************** 959 /**************************************** 921 */ 960 */ 922 961 923 int ClassDeclaration::isAbstract() 962 int ClassDeclaration::isAbstract() 924 { 963 { 925 if (isabstract) 964 if (isabstract) 926 return TRUE; 965 return TRUE; 927 for (int i = 1; i < vtbl.dim; i++) 966 for (int i = 1; i < vtbl.dim; i++) 928 { 967 { 929 FuncDeclaration *fd = ((Dsymbol *)vtbl.data[i])->isFuncDeclaration(); 968 FuncDeclaration *fd = ((Dsymbol *)vtbl.data[i])->isFuncDeclaration(); 930 969 931 //printf("\tvtbl[%d] = %p\n", i, fd); 970 //printf("\tvtbl[%d] = %p\n", i, fd); 932 if (!fd || fd->isAbstract()) 971 if (!fd || fd->isAbstract()) 933 { 972 { 934 isabstract |= 1; 973 isabstract |= 1; 935 return TRUE; 974 return TRUE; 936 } 975 } 937 } 976 } 938 return FALSE; 977 return FALSE; … … 989 1028 990 Dsymbol *InterfaceDeclaration::syntaxCopy(Dsymbol *s) 1029 Dsymbol *InterfaceDeclaration::syntaxCopy(Dsymbol *s) 991 { 1030 { 992 InterfaceDeclaration *id; 1031 InterfaceDeclaration *id; 993 1032 994 if (s) 1033 if (s) 995 id = (InterfaceDeclaration *)s; 1034 id = (InterfaceDeclaration *)s; 996 else 1035 else 997 id = new InterfaceDeclaration(loc, ident, NULL); 1036 id = new InterfaceDeclaration(loc, ident, NULL); 998 1037 999 ClassDeclaration::syntaxCopy(id); 1038 ClassDeclaration::syntaxCopy(id); 1000 return id; 1039 return id; 1001 } 1040 } 1002 1041 1003 void InterfaceDeclaration::semantic(Scope *sc) 1042 void InterfaceDeclaration::semantic(Scope *sc) 1004 { int i; 1043 { int i; 1005 1044 1006 //printf("InterfaceDeclaration::semantic(%s), type = %p\n", toChars(), type); 1045 //printf("InterfaceDeclaration::semantic(%s), type = %p\n", toChars(), type); 1007 if (inuse) 1046 if (inuse) 1008 return; 1047 return; 1009 if (!scope) 1048 1010 { type = type->semantic(loc, sc); 1049 if (!sc) 1011 handle = handle->semantic(loc, sc); 1050 sc = scope; 1012 } 1051 if (!parent && sc->parent && !sc->parent->isModule()) 1052 parent = sc->parent; 1053 1054 type = type->semantic(loc, sc); 1055 handle = type; 1056 1013 if (!members) // if forward reference 1057 if (!members) // if forward reference 1014 { //printf("\tinterface '%s' is forward referenced\n", toChars()); 1058 { //printf("\tinterface '%s' is forward referenced\n", toChars()); 1015 return; 1059 return; 1016 } 1060 } 1017 if (symtab) // if already done 1061 if (symtab) // if already done 1018 { if (!scope) 1062 { if (!scope) 1019 return; 1063 return; 1020 } 1064 } 1021 else 1065 else 1022 symtab = new DsymbolTable(); 1066 symtab = new DsymbolTable(); 1023 1067 1024 Scope *scx = NULL; 1068 Scope *scx = NULL; 1025 if (scope) 1069 if (scope) 1026 { sc = scope; 1070 { sc = scope; 1027 scx = scope; // save so we don't make redundant copies 1071 scx = scope; // save so we don't make redundant copies 1028 scope = NULL; 1072 scope = NULL; 1029 } 1073 } 1030 1074 1031 if (sc->stc & STCdeprecated) 1075 if (sc->stc & STCdeprecated) 1032 { 1076 { … … 1072 error("base type must be interface, not %s", b->type->toChars()); 1116 error("base type must be interface, not %s", b->type->toChars()); 1073 baseclasses.remove(i); 1117 baseclasses.remove(i); 1074 continue; 1118 continue; 1075 } 1119 } 1076 else 1120 else 1077 { 1121 { 1078 // Check for duplicate interfaces 1122 // Check for duplicate interfaces 1079 for (size_t j = 0; j < i; j++) 1123 for (size_t j = 0; j < i; j++) 1080 { 1124 { 1081 BaseClass *b2 = (BaseClass *)baseclasses.data[j]; 1125 BaseClass *b2 = (BaseClass *)baseclasses.data[j]; 1082 if (b2->base == tc->sym) 1126 if (b2->base == tc->sym) 1083 error("inherits from duplicate interface %s", b2->base->toChars()); 1127 error("inherits from duplicate interface %s", b2->base->toChars()); 1084 } 1128 } 1085 1129 1086 b->base = tc->sym; 1130 b->base = tc->sym; 1087 if (b->base == this || isBaseOf2(b->base)) 1131 if (b->base == this || isBaseOf2(b->base)) 1088 { 1132 { 1089 error("circular inheritance of interface"); 1133 error("circular inheritance of interface"); 1090 baseclasses.remove(i); 1134 baseclasses.remove(i); 1091 continue; 1135 continue; 1136 } 1137 if (!b->base->symtab) 1138 { // Try to resolve forward reference 1139 if (sc->mustsemantic && b->base->scope) 1140 b->base->semantic(NULL); 1092 } 1141 } 1093 if (!b->base->symtab || b->base->scope || b->base->inuse) 1142 if (!b->base->symtab || b->base->scope || b->base->inuse) 1094 { 1143 { 1095 //error("forward reference of base class %s", baseClass->toChars()); 1144 //error("forward reference of base class %s", baseClass->toChars()); 1096 // Forward reference of base, try again later 1145 // Forward reference of base, try again later 1097 //printf("\ttry later, forward reference of base %s\n", b->base->toChars()); 1146 //printf("\ttry later, forward reference of base %s\n", b->base->toChars()); 1098 scope = scx ? scx : new Scope(*sc); 1147 scope = scx ? scx : new Scope(*sc); 1099 scope->setNoFree(); 1148 scope->setNoFree(); 1100 scope->module->addDeferredSemantic(this); 1149 scope->module->addDeferredSemantic(this); 1101 return; 1150 return; 1102 } 1151 } 1103 } 1152 } 1104 i++; 1153 i++; 1105 } 1154 } 1106 1155 1107 interfaces_dim = baseclasses.dim; 1156 interfaces_dim = baseclasses.dim; 1108 interfaces = (BaseClass **)baseclasses.data; 1157 interfaces = (BaseClass **)baseclasses.data; 1109 1158 1110 interfaceSemantic(sc); 1159 interfaceSemantic(sc); 1111 1160 … … 1245 1294 1246 /**************************************** 1295 /**************************************** 1247 * Determine if slot 0 of the vtbl[] is reserved for something else. 1296 * Determine if slot 0 of the vtbl[] is reserved for something else. 1248 * For class objects, yes, this is where the ClassInfo ptr goes. 1297 * For class objects, yes, this is where the ClassInfo ptr goes. 1249 * For COM interfaces, no. 1298 * For COM interfaces, no. 1250 * For non-COM interfaces, yes, this is where the Interface ptr goes. 1299 * For non-COM interfaces, yes, this is where the Interface ptr goes. 1251 */ 1300 */ 1252 1301 1253 int InterfaceDeclaration::vtblOffset() 1302 int InterfaceDeclaration::vtblOffset() 1254 { 1303 { 1255 if (isCOMinterface()) 1304 if (isCOMinterface()) 1256 return 0; 1305 return 0; 1257 return 1; 1306 return 1; 1258 } 1307 } 1259 1308 1260 int InterfaceDeclaration::isCOMinterface() 1309 int InterfaceDeclaration::isCOMinterface() 1261 { 1310 { 1262 return com; 1311 return com; 1263 } 1312 } 1264 1313 1314 #if DMDV2 1315 int InterfaceDeclaration::isCPPinterface() 1316 { 1317 return cpp; 1318 } 1319 #endif 1320 1265 /******************************************* 1321 /******************************************* 1266 */ 1322 */ 1267 1323 1268 const char *InterfaceDeclaration::kind() 1324 const char *InterfaceDeclaration::kind() 1269 { 1325 { 1270 return "interface"; 1326 return "interface"; 1271 } 1327 } 1272 1328 1273 1329 1274 /******************************** BaseClass *****************************/ 1330 /******************************** BaseClass *****************************/ 1275 1331 1276 BaseClass::BaseClass() 1332 BaseClass::BaseClass() 1277 { 1333 { 1278 memset(this, 0, sizeof(BaseClass)); 1334 memset(this, 0, sizeof(BaseClass)); 1279 } 1335 } 1280 1336 1281 BaseClass::BaseClass(Type *type, enum PROT protection) 1337 BaseClass::BaseClass(Type *type, enum PROT protection) 1282 { 1338 { 1283 //printf("BaseClass(this = %p, '%s')\n", this, type->toChars()); 1339 //printf("BaseClass(this = %p, '%s')\n", this, type->toChars()); 1284 this->type = type; 1340 this->type = type; dmd/constfold.c
Revision 1367:8026319762be Revision 1587:def7a1d494fd 53 53 54 /* ================================== isConst() ============================== */ 54 /* ================================== isConst() ============================== */ 55 55 56 int Expression::isConst() 56 int Expression::isConst() 57 { 57 { 58 //printf("Expression::isConst(): %s\n", toChars()); 58 //printf("Expression::isConst(): %s\n", toChars()); 59 return 0; 59 return 0; 60 } 60 } 61 61 62 int IntegerExp::isConst() 62 int IntegerExp::isConst() 63 { 63 { 64 return 1; 64 return 1; 65 } 65 } 66 66 67 int RealExp::isConst() 67 int RealExp::isConst() 68 { 68 { 69 return 1; 69 return 1; 70 } 70 } 71 71 72 int ComplexExp::isConst() 72 int ComplexExp::isConst() 73 { 74 return 1; 75 } 76 77 int NullExp::isConst() 73 { 78 { 74 return 1; 79 return 1; 75 } 80 } 76 81 77 int SymOffExp::isConst() 82 int SymOffExp::isConst() 78 { 83 { 79 return 2; 84 return 2; 80 } 85 } 81 86 82 /* =============================== constFold() ============================== */ 87 /* =============================== constFold() ============================== */ 83 88 84 /* The constFold() functions were redundant with the optimize() ones, 89 /* The constFold() functions were redundant with the optimize() ones, 85 * and so have been folded in with them. 90 * and so have been folded in with them. 86 */ 91 */ 87 92 88 /* ========================================================================== */ 93 /* ========================================================================== */ 89 94 90 Expression *Neg(Type *type, Expression *e1) 95 Expression *Neg(Type *type, Expression *e1) 91 { Expression *e; 96 { Expression *e; 92 Loc loc = e1->loc; 97 Loc loc = e1->loc; … … 828 r1 = e1->toImaginary(); 833 r1 = e1->toImaginary(); 829 r2 = e2->toImaginary(); 834 r2 = e2->toImaginary(); 830 L1: 835 L1: 831 #if __DMC__ 836 #if __DMC__ 832 cmp = (r1 == r2); 837 cmp = (r1 == r2); 833 #else 838 #else 834 if (Port::isNan(r1) || Port::isNan(r2)) // if unordered 839 if (Port::isNan(r1) || Port::isNan(r2)) // if unordered 835 { 840 { 836 cmp = 0; 841 cmp = 0; 837 } 842 } 838 else 843 else 839 { 844 { 840 cmp = (r1 == r2); 845 cmp = (r1 == r2); 841 } 846 } 842 #endif 847 #endif 843 } 848 } 844 else if (e1->type->iscomplex()) 849 else if (e1->type->iscomplex()) 845 { 850 { 846 cmp = e1->toComplex() == e2->toComplex(); 851 cmp = e1->toComplex() == e2->toComplex(); 847 } 852 } 848 else if (e1->type->isintegral() )853 else if (e1->type->isintegral() || e1->type->toBasetype()->ty == Tpointer) 849 { 854 { 850 cmp = (e1->toInteger() == e2->toInteger()); 855 cmp = (e1->toInteger() == e2->toInteger()); 851 } 856 } 852 else 857 else 853 return EXP_CANT_INTERPRET; 858 return EXP_CANT_INTERPRET; 854 if (op == TOKnotequal) 859 if (op == TOKnotequal) 855 cmp ^= 1; 860 cmp ^= 1; 856 e = new IntegerExp(loc, cmp, type); 861 e = new IntegerExp(loc, cmp, type); 857 return e; 862 return e; 858 } 863 } 859 864 860 Expression *Identity(enum TOK op, Type *type, Expression *e1, Expression *e2) 865 Expression *Identity(enum TOK op, Type *type, Expression *e1, Expression *e2) 861 { Expression *e; 866 { Expression *e; 862 Loc loc = e1->loc; 867 Loc loc = e1->loc; 863 int cmp; 868 int cmp; 864 869 865 if (e1->op == TOKnull && e2->op == TOKnull) 870 if (e1->op == TOKnull) 866 { 871 { 867 cmp = 1; 872 cmp = (e2->op == TOKnull); 873 } 874 else if (e2->op == TOKnull) 875 { 876 cmp = 0; 868 } 877 } 869 else if (e1->op == TOKsymoff && e2->op == TOKsymoff) 878 else if (e1->op == TOKsymoff && e2->op == TOKsymoff) 870 { 879 { 871 SymOffExp *es1 = (SymOffExp *)e1; 880 SymOffExp *es1 = (SymOffExp *)e1; 872 SymOffExp *es2 = (SymOffExp *)e2; 881 SymOffExp *es2 = (SymOffExp *)e2; 873 882 874 cmp = (es1->var == es2->var && es1->offset == es2->offset); 883 cmp = (es1->var == es2->var && es1->offset == es2->offset); 875 } 884 } 876 else if (e1->isConst() == 1 && e2->isConst() == 1) 885 else if (e1->isConst() == 1 && e2->isConst() == 1) 877 return Equal((op == TOKidentity) ? TOKequal : TOKnotequal, 886 return Equal((op == TOKidentity) ? TOKequal : TOKnotequal, 878 type, e1, e2); 887 type, e1, e2); 879 else 888 else 880 assert(0); 889 assert(0); 881 if (op == TOKnotidentity) 890 if (op == TOKnotidentity) 882 cmp ^= 1; 891 cmp ^= 1; 883 return new IntegerExp(loc, cmp, type); 892 return new IntegerExp(loc, cmp, type); 884 } 893 } 885 894 886 895 887 Expression *Cmp(enum TOK op, Type *type, Expression *e1, Expression *e2) 896 Expression *Cmp(enum TOK op, Type *type, Expression *e1, Expression *e2) … … 1029 } 1038 } 1030 e = new IntegerExp(loc, n, type); 1039 e = new IntegerExp(loc, n, type); 1031 return e; 1040 return e; 1032 } 1041 } 1033 1042 1034 /* Also returns EXP_CANT_INTERPRET if cannot be computed. 1043 /* Also returns EXP_CANT_INTERPRET if cannot be computed. 1035 * to: type to cast to 1044 * to: type to cast to 1036 * type: type to paint the result 1045 * type: type to paint the result 1037 */ 1046 */ 1038 1047 1039 Expression *Cast(Type *type, Type *to, Expression *e1) 1048 Expression *Cast(Type *type, Type *to, Expression *e1) 1040 { Expression *e = EXP_CANT_INTERPRET; 1049 { Expression *e = EXP_CANT_INTERPRET; 1041 Loc loc = e1->loc; 1050 Loc loc = e1->loc; 1042 1051 1043 //printf("Cast(type = %s, to = %s, e1 = %s)\n", type->toChars(), to->toChars(), e1->toChars()); 1052 //printf("Cast(type = %s, to = %s, e1 = %s)\n", type->toChars(), to->toChars(), e1->toChars()); 1044 //printf("e1->type = %s\n", e1->type->toChars()); 1053 //printf("e1->type = %s\n", e1->type->toChars()); 1045 if (type->equals(e1->type) && to->equals(type)) 1054 if (type->equals(e1->type) && to->equals(type)) 1046 return e1; 1055 return e1; 1047 1056 1048 Type *tb = to->toBasetype(); 1057 Type *tb = to->toBasetype(); 1049 Type *typeb = type->toBasetype(); 1058 1050 1059 /* Allow casting from one string type to another 1051 // LDC: ported from D2 to allow char[] ~ char[n] arguments in CTFE1060 */ 1052 if (e1->op == TOKstring) 1061 if (e1->op == TOKstring) 1053 { 1062 { 1063 Type *typeb = type->toBasetype(); 1054 if (tb->ty == Tarray && typeb->ty == Tarray && 1064 if (tb->ty == Tarray && typeb->ty == Tarray && 1055 tb->nextOf()->size() == typeb->nextOf()->size()) 1065 tb->nextOf()->size() == typeb->nextOf()->size()) 1056 { 1066 { 1057 return expType(to, e1); 1067 return expType(to, e1); 1058 } 1068 } 1059 } 1069 } 1060 1070 1061 if (e1->isConst() != 1) 1071 if (e1->isConst() != 1) 1062 return EXP_CANT_INTERPRET; 1072 return EXP_CANT_INTERPRET; 1063 1073 1064 if (tb->ty == Tbool) 1074 if (tb->ty == Tbool) 1065 e = new IntegerExp(loc, e1->toInteger() != 0, type); 1075 e = new IntegerExp(loc, e1->toInteger() != 0, type); 1066 else if (type->isintegral()) 1076 else if (type->isintegral()) 1067 { 1077 { 1068 if (e1->type->isfloating()) 1078 if (e1->type->isfloating()) 1069 { dinteger_t result; 1079 { dinteger_t result; 1070 real_t r = e1->toReal(); 1080 real_t r = e1->toReal(); 1071 1081 1072 switch (type b->ty)1082 switch (type->toBasetype()->ty) 1073 { 1083 { 1074 case Tint8: result = (d_int8)r; break; 1084 case Tint8: result = (d_int8)r; break; 1075 case Tchar: 1085 case Tchar: 1076 case Tuns8: result = (d_uns8)r; break; 1086 case Tuns8: result = (d_uns8)r; break; 1077 case Tint16: result = (d_int16)r; break; 1087 case Tint16: result = (d_int16)r; break; 1078 case Twchar: 1088 case Twchar: 1079 case Tuns16: result = (d_uns16)r; break; 1089 case Tuns16: result = (d_uns16)r; break; 1080 case Tint32: result = (d_int32)r; break; 1090 case Tint32: result = (d_int32)r; break; 1081 case Tdchar: 1091 case Tdchar: 1082 case Tuns32: result = (d_uns32)r; break; 1092 case Tuns32: result = (d_uns32)r; break; 1083 case Tint64: result = (d_int64)r; break; 1093 case Tint64: result = (d_int64)r; break; 1084 case Tuns64: result = (d_uns64)r; break; 1094 case Tuns64: result = (d_uns64)r; break; 1085 default: 1095 default: 1086 assert(0); 1096 assert(0); 1087 } 1097 } 1088 1098 1089 e = new IntegerExp(loc, result, type); 1099 e = new IntegerExp(loc, result, type); 1090 } 1100 } 1091 else if (type->isunsigned()) 1101 else if (type->isunsigned()) 1092 e = new IntegerExp(loc, e1->toUInteger(), type); 1102 e = new IntegerExp(loc, e1->toUInteger(), type); dmd/declaration.c
Revision 1538:e4ff2e15cf5f Revision 1587:def7a1d494fd 50 assert(type); 50 assert(type); 51 return type->size(); 51 return type->size(); 52 } 52 } 53 53 54 int Declaration::isStaticConstructor() 54 int Declaration::isStaticConstructor() 55 { 55 { 56 return FALSE; 56 return FALSE; 57 } 57 } 58 58 59 int Declaration::isStaticDestructor() 59 int Declaration::isStaticDestructor() 60 { 60 { 61 return FALSE; 61 return FALSE; 62 } 62 } 63 63 64 int Declaration::isDelete() 64 int Declaration::isDelete() 65 { 65 { 66 return FALSE; 66 return FALSE; 67 } 67 } 68 68 69 int Declaration::isDataseg() 69 int Declaration::isDataseg() 70 { 71 return FALSE; 72 } 73 74 int Declaration::isThreadlocal() 70 { 75 { 71 return FALSE; 76 return FALSE; 72 } 77 } 73 78 74 int Declaration::isCodeseg() 79 int Declaration::isCodeseg() 75 { 80 { 76 return FALSE; 81 return FALSE; 77 } 82 } 78 83 79 enum PROT Declaration::prot() 84 enum PROT Declaration::prot() 80 { 85 { 81 return protection; 86 return protection; 82 } 87 } 83 88 84 /************************************* 89 /************************************* 85 * Check to see if declaration can be modified in this context (sc). 90 * Check to see if declaration can be modified in this context (sc). 86 * Issue error if not. 91 * Issue error if not. 87 */ 92 */ 88 93 89 #if DMDV2 94 #if DMDV2 … … 115 { 120 { 116 if (s) 121 if (s) 117 { s = s->toParent2(); 122 { s = s->toParent2(); 118 continue; 123 continue; 119 } 124 } 120 else 125 else 121 { 126 { 122 const char *p = isStatic() ? "static " : ""; 127 const char *p = isStatic() ? "static " : ""; 123 error(loc, "can only initialize %sconst %s inside %sconstructor", 128 error(loc, "can only initialize %sconst %s inside %sconstructor", 124 p, toChars(), p); 129 p, toChars(), p); 125 } 130 } 126 } 131 } 127 break; 132 break; 128 } 133 } 129 } 134 } 130 else 135 else 131 { 136 { 132 VarDeclaration *v = isVarDeclaration(); 137 VarDeclaration *v = isVarDeclaration(); 133 if (v && v->canassign == 0) 138 if (v && v->canassign == 0) 134 { 139 { 135 c har *p = NULL;140 const char *p = NULL; 136 if (isConst()) 141 if (isConst()) 137 p = "const"; 142 p = "const"; 138 else if (isInvariant()) 143 else if (isInvariant()) 139 p = "i nvariant";144 p = "immutable"; 140 else if (storage_class & STCmanifest) 145 else if (storage_class & STCmanifest) 141 p = " manifest constant";146 p = "enum"; 142 else if (!t->isAssignable()) 147 else if (!t->isAssignable()) 143 p = "struct with immutable members"; 148 p = "struct with immutable members"; 144 if (p) 149 if (p) 145 { error(loc, "cannot modify %s", p); 150 { error(loc, "cannot modify %s", p); 146 halt();147 } 151 } 148 } 152 } 149 } 153 } 150 } 154 } 151 #endif 155 #endif 152 156 153 157 154 /********************************* TupleDeclaration ****************************/ 158 /********************************* TupleDeclaration ****************************/ 155 159 156 TupleDeclaration::TupleDeclaration(Loc loc, Identifier *id, Objects *objects) 160 TupleDeclaration::TupleDeclaration(Loc loc, Identifier *id, Objects *objects) 157 : Declaration(id) 161 : Declaration(id) 158 { 162 { 159 this->type = NULL; 163 this->type = NULL; 160 this->objects = objects; 164 this->objects = objects; 161 this->isexp = 0; 165 this->isexp = 0; 162 this->tupletype = NULL; 166 this->tupletype = NULL; 163 } 167 } 164 168 165 Dsymbol *TupleDeclaration::syntaxCopy(Dsymbol *s) 169 Dsymbol *TupleDeclaration::syntaxCopy(Dsymbol *s) 166 { 170 { … … 183 return NULL; 187 return NULL; 184 if (!tupletype) 188 if (!tupletype) 185 { 189 { 186 /* It's only a type tuple if all the Object's are types 190 /* It's only a type tuple if all the Object's are types 187 */ 191 */ 188 for (size_t i = 0; i < objects->dim; i++) 192 for (size_t i = 0; i < objects->dim; i++) 189 { Object *o = (Object *)objects->data[i]; 193 { Object *o = (Object *)objects->data[i]; 190 194 191 if (o->dyncast() != DYNCAST_TYPE) 195 if (o->dyncast() != DYNCAST_TYPE) 192 { 196 { 193 //printf("\tnot[%d], %p, %d\n", i, o, o->dyncast()); 197 //printf("\tnot[%d], %p, %d\n", i, o, o->dyncast()); 194 return NULL; 198 return NULL; 195 } 199 } 196 } 200 } 197 201 198 /* We know it's a type tuple, so build the TypeTuple 202 /* We know it's a type tuple, so build the TypeTuple 199 */ 203 */ 200 Arguments *args = new Arguments(); 204 Arguments *args = new Arguments(); 201 args->setDim(objects->dim); 205 args->setDim(objects->dim); 202 OutBuffer buf; 206 OutBuffer buf; 207 int hasdeco = 1; 203 for (size_t i = 0; i < objects->dim; i++) 208 for (size_t i = 0; i < objects->dim; i++) 204 { Type *t = (Type *)objects->data[i]; 209 { Type *t = (Type *)objects->data[i]; 205 210 206 //printf("type = %s\n", t->toChars()); 211 //printf("type = %s\n", t->toChars()); 207 #if 0 212 #if 0 208 buf.printf("_%s_%d", ident->toChars(), i); 213 buf.printf("_%s_%d", ident->toChars(), i); 209 char *name = (char *)buf.extractData(); 214 char *name = (char *)buf.extractData(); 210 Identifier *id = new Identifier(name, TOKidentifier); 215 Identifier *id = new Identifier(name, TOKidentifier); 211 Argument *arg = new Argument(STCin, t, id, NULL); 216 Argument *arg = new Argument(STCin, t, id, NULL); 212 #else 217 #else 213 Argument *arg = new Argument(STCin, t, NULL, NULL); 218 Argument *arg = new Argument(STCin, t, NULL, NULL); 214 #endif 219 #endif 215 args->data[i] = (void *)arg; 220 args->data[i] = (void *)arg; 221 if (!t->deco) 222 hasdeco = 0; 216 } 223 } 217 224 218 tupletype = new TypeTuple(args); 225 tupletype = new TypeTuple(args); 226 if (hasdeco) 227 return tupletype->semantic(0, NULL); 219 } 228 } 220 229 221 return tupletype; 230 return tupletype; 222 } 231 } 223 232 224 int TupleDeclaration::needThis() 233 int TupleDeclaration::needThis() 225 { 234 { 226 //printf("TupleDeclaration::needThis(%s)\n", toChars()); 235 //printf("TupleDeclaration::needThis(%s)\n", toChars()); 227 for (size_t i = 0; i < objects->dim; i++) 236 for (size_t i = 0; i < objects->dim; i++) 228 { Object *o = (Object *)objects->data[i]; 237 { Object *o = (Object *)objects->data[i]; 229 if (o->dyncast() == DYNCAST_EXPRESSION) 238 if (o->dyncast() == DYNCAST_EXPRESSION) 230 { Expression *e = (Expression *)o; 239 { Expression *e = (Expression *)o; 231 if (e->op == TOKdsymbol) 240 if (e->op == TOKdsymbol) 232 { DsymbolExp *ve = (DsymbolExp *)e; 241 { DsymbolExp *ve = (DsymbolExp *)e; 233 Declaration *d = ve->s->isDeclaration(); 242 Declaration *d = ve->s->isDeclaration(); 234 if (d && d->needThis()) 243 if (d && d->needThis()) 235 { 244 { 236 return 1; 245 return 1; 237 } 246 } 238 } 247 } … … 439 448 440 // Given: 449 // Given: 441 // alias foo.bar.abc def; 450 // alias foo.bar.abc def; 442 // it is not knowable from the syntax whether this is an alias 451 // it is not knowable from the syntax whether this is an alias 443 // for a type or an alias for a symbol. It is up to the semantic() 452 // for a type or an alias for a symbol. It is up to the semantic() 444 // pass to distinguish. 453 // pass to distinguish. 445 // If it is a type, then type is set and getType() will return that 454 // If it is a type, then type is set and getType() will return that 446 // type. If it is a symbol, then aliassym is set and type is NULL - 455 // type. If it is a symbol, then aliassym is set and type is NULL - 447 // toAlias() will return aliasssym. 456 // toAlias() will return aliasssym. 448 457 449 Dsymbol *s; 458 Dsymbol *s; 450 Type *t; 459 Type *t; 451 Expression *e; 460 Expression *e; 452 461 453 /* This section is needed because resolve() will: 462 /* This section is needed because resolve() will: 454 * const x = 3; 463 * const x = 3; 455 * alias x y; 464 * alias x y; 456 * try to alias y to 3. 465 * try to alias y to 3. 457 */ 466 */ 458 s = type->toDsymbol(sc); 467 s = type->toDsymbol(sc); 459 if (s) 468 if (s 469 #if DMDV2 470 ` && ((s->getType() && type->equals(s->getType())) || s->isEnumMember()) 471 #endif 472 ) 460 goto L2; // it's a symbolic alias 473 goto L2; // it's a symbolic alias 461 474 462 //printf("alias type is %s\n", type->toChars()); 475 #if DMDV2 463 type->resolve(loc, sc, &e, &t, &s); 476 if (storage_class & (STCref | STCnothrow | STCpure)) 477 { // For 'ref' to be attached to function types, and picked 478 // up by Type::resolve(), it has to go into sc. 479 sc = sc->push(); 480 sc->stc |= storage_class & (STCref | STCnothrow | STCpure); 481 type->resolve(loc, sc, &e, &t, &s); 482 sc = sc->pop(); 483 } 484 else 485 #endif 486 type->resolve(loc, sc, &e, &t, &s); 464 if (s) 487 if (s) 465 { 488 { 466 goto L2; 489 goto L2; 467 } 490 } 468 else if (e) 491 else if (e) 469 { 492 { 470 // Try to convert Expression to Dsymbol 493 // Try to convert Expression to Dsymbol 471 if (e->op == TOKvar) 494 if (e->op == TOKvar) 472 { s = ((VarExp *)e)->var; 495 { s = ((VarExp *)e)->var; 473 goto L2; 496 goto L2; 474 } 497 } 475 else if (e->op == TOKfunction) 498 else if (e->op == TOKfunction) 476 { s = ((FuncExp *)e)->fd; 499 { s = ((FuncExp *)e)->fd; 477 goto L2; 500 goto L2; 478 } 501 } 479 else 502 else 480 { error("cannot alias an expression %s", e->toChars()); 503 { error("cannot alias an expression %s", e->toChars()); 481 t = e->type; 504 t = e->type; 482 } 505 } 483 } 506 } … … 506 { 529 { 507 if (overnext) 530 if (overnext) 508 { 531 { 509 FuncAliasDeclaration *fa = new FuncAliasDeclaration(f); 532 FuncAliasDeclaration *fa = new FuncAliasDeclaration(f); 510 fa->importprot = importprot; 533 fa->importprot = importprot; 511 if (!fa->overloadInsert(overnext)) 534 if (!fa->overloadInsert(overnext)) 512 ScopeDsymbol::multiplyDefined(0, f, overnext); 535 ScopeDsymbol::multiplyDefined(0, f, overnext); 513 overnext = NULL; 536 overnext = NULL; 514 s = fa; 537 s = fa; 515 s->parent = sc->parent; 538 s->parent = sc->parent; 516 } 539 } 517 } 540 } 518 if (overnext) 541 if (overnext) 519 ScopeDsymbol::multiplyDefined(0, s, overnext); 542 ScopeDsymbol::multiplyDefined(0, s, overnext); 520 if (s == this) 543 if (s == this) 521 { 544 { 522 assert(global.errors); 545 assert(global.errors); 523 s = NULL; 546 s = NULL; 524 } 547 } 525 } 548 } 526 aliassym = s; 549 if (!aliassym) 550 aliassym = s; 527 this->inSemantic = 0; 551 this->inSemantic = 0; 528 } 552 } 529 553 530 int AliasDeclaration::overloadInsert(Dsymbol *s) 554 int AliasDeclaration::overloadInsert(Dsymbol *s) 531 { 555 { 532 /* Don't know yet what the aliased symbol is, so assume it can 556 /* Don't know yet what the aliased symbol is, so assume it can 533 * be overloaded and check later for correctness. 557 * be overloaded and check later for correctness. 534 */ 558 */ 535 559 536 //printf("AliasDeclaration::overloadInsert('%s')\n", s->toChars()); 560 //printf("AliasDeclaration::overloadInsert('%s')\n", s->toChars()); 537 if (overnext == NULL) 561 if (overnext == NULL) 538 { overnext = s; 562 { 563 if (s == this) 564 { 565 return TRUE; 566 } 567 overnext = s; 539 return TRUE; 568 return TRUE; 540 } 569 } 541 else 570 else 542 { 571 { 543 return overnext->overloadInsert(s); 572 return overnext->overloadInsert(s); 544 } 573 } 545 } 574 } 546 575 547 const char *AliasDeclaration::kind() 576 const char *AliasDeclaration::kind() 548 { 577 { 549 return "alias"; 578 return "alias"; 550 } 579 } 551 580 552 Type *AliasDeclaration::getType() 581 Type *AliasDeclaration::getType() 553 { 582 { 583 //printf("AliasDeclaration::getType() %s\n", type->toChars()); 584 #if 0 585 if (!type->deco && scope) 586 semantic(scope); 587 if (type && !type->deco) 588 error("forward reference to alias %s\n", toChars()); 589 #endif 554 return type; 590 return type; 555 } 591 } 556 592 557 Dsymbol *AliasDeclaration::toAlias() 593 Dsymbol *AliasDeclaration::toAlias() 558 { 594 { 559 //printf("AliasDeclaration::toAlias('%s', this = %p, aliassym = %p, kind = '%s')\n", toChars(), this, aliassym, aliassym ? aliassym->kind() : ""); 595 //printf("AliasDeclaration::toAlias('%s', this = %p, aliassym = %p, kind = '%s')\n", toChars(), this, aliassym, aliassym ? aliassym->kind() : ""); 560 assert(this != aliassym); 596 assert(this != aliassym); 561 //static int count; if (++count == 10)*(char*)0=0;597 //static int count; if (++count == 75) exit(0); //*(char*)0=0; 562 if (inSemantic) 598 if (inSemantic) 563 { error("recursive alias declaration"); 599 { error("recursive alias declaration"); 564 aliassym = new TypedefDeclaration(loc, ident, Type::terror, NULL); 600 aliassym = new TypedefDeclaration(loc, ident, Type::terror, NULL); 565 } 601 } 566 Dsymbol *s = aliassym ? aliassym->toAlias() : this; 602 Dsymbol *s = aliassym ? aliassym->toAlias() : this; 567 return s; 603 return s; 568 } 604 } 569 605 570 void AliasDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 606 void AliasDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 571 { 607 { 572 buf->writestring("alias "); 608 buf->writestring("alias "); 573 #if 0 && _DH 609 #if 0 && _DH 574 if (hgs->hdrgen) 610 if (hgs->hdrgen) 575 { 611 { 576 if (haliassym) 612 if (haliassym) 577 { 613 { 578 buf->writestring(haliassym->toChars()); 614 buf->writestring(haliassym->toChars()); 579 buf->writeByte(' '); 615 buf->writeByte(' '); 580 buf->writestring(ident->toChars()); 616 buf->writestring(ident->toChars()); 581 } 617 } … … 603 VarDeclaration::VarDeclaration(Loc loc, Type *type, Identifier *id, Initializer *init) 639 VarDeclaration::VarDeclaration(Loc loc, Type *type, Identifier *id, Initializer *init) 604 : Declaration(id) 640 : Declaration(id) 605 { 641 { 606 //printf("VarDeclaration('%s')\n", id->toChars()); 642 //printf("VarDeclaration('%s')\n", id->toChars()); 607 #ifdef DEBUG 643 #ifdef DEBUG 608 if (!type && !init) 644 if (!type && !init) 609 { printf("VarDeclaration('%s')\n", id->toChars()); 645 { printf("VarDeclaration('%s')\n", id->toChars()); 610 //*(char*)0=0; 646 //*(char*)0=0; 611 } 647 } 612 #endif 648 #endif 613 assert(type || init); 649 assert(type || init); 614 this->type = type; 650 this->type = type; 615 this->init = init; 651 this->init = init; 616 #ifdef _DH 652 #ifdef _DH 617 this->htype = NULL; 653 this->htype = NULL; 618 this->hinit = NULL; 654 this->hinit = NULL; 619 #endif 655 #endif 620 this->loc = loc; 656 this->loc = loc; 621 offset = 0; 657 offset = 0; 622 noscope = 0; 658 noscope = 0; 659 #if DMDV1 623 nestedref = 0; 660 nestedref = 0; 661 #endif 624 ctorinit = 0; 662 ctorinit = 0; 625 aliassym = NULL; 663 aliassym = NULL; 626 onstack = 0; 664 onstack = 0; 627 canassign = 0; 665 canassign = 0; 628 value = NULL; 666 value = NULL; 629 667 630 #if IN_LLVM 668 #if IN_LLVM 631 aggrIndex = 0; 669 aggrIndex = 0; 632 670 633 // LDC 671 // LDC 634 anonDecl = NULL; 672 anonDecl = NULL; 635 offset2 = 0; 673 offset2 = 0; 636 674 637 nakedUse = false; 675 nakedUse = false; 638 676 639 availableExternally = true; // assume this unless proven otherwise 677 availableExternally = true; // assume this unless proven otherwise 640 #endif 678 #endif 641 } 679 } 642 680 643 Dsymbol *VarDeclaration::syntaxCopy(Dsymbol *s) 681 Dsymbol *VarDeclaration::syntaxCopy(Dsymbol *s) … … 667 { htype = type->syntaxCopy(); 705 { htype = type->syntaxCopy(); 668 sv->htype = type->syntaxCopy(); 706 sv->htype = type->syntaxCopy(); 669 } 707 } 670 } 708 } 671 else // Make copy of original for new instance 709 else // Make copy of original for new instance 672 sv->htype = htype->syntaxCopy(); 710 sv->htype = htype->syntaxCopy(); 673 if (!hinit) 711 if (!hinit) 674 { if (init) 712 { if (init) 675 { hinit = init->syntaxCopy(); 713 { hinit = init->syntaxCopy(); 676 sv->hinit = init->syntaxCopy(); 714 sv->hinit = init->syntaxCopy(); 677 } 715 } 678 } 716 } 679 else 717 else 680 sv->hinit = hinit->syntaxCopy(); 718 sv->hinit = hinit->syntaxCopy(); 681 #endif 719 #endif 682 return sv; 720 return sv; 683 } 721 } 684 722 685 void VarDeclaration::semantic(Scope *sc) 723 void VarDeclaration::semantic(Scope *sc) 686 { 724 { 687 //printf("VarDeclaration::semantic('%s', parent = '%s')\n", toChars(), sc->parent->toChars()); 725 #if 0 688 //printf(" type = %s\n", type ? type->toChars() : "null"); 726 printf("VarDeclaration::semantic('%s', parent = '%s')\n", toChars(), sc->parent->toChars()); 689 //printf(" stc = x%x\n", sc->stc); 727 printf(" type = %s\n", type ? type->toChars() : "null"); 690 //printf(" storage_class = x%x\n", storage_class); 728 printf(" stc = x%x\n", sc->stc); 691 //printf("linkage = %d\n", sc->linkage); 729 printf(" storage_class = x%x\n", storage_class); 730 printf("linkage = %d\n", sc->linkage); 692 //if (strcmp(toChars(), "mul") == 0) halt(); 731 //if (strcmp(toChars(), "mul") == 0) halt(); 732 #endif 693 733 694 storage_class |= sc->stc; 734 storage_class |= sc->stc; 695 if (storage_class & STCextern && init) 735 if (storage_class & STCextern && init) 696 error("extern symbols cannot have initializers"); 736 error("extern symbols cannot have initializers"); 697 737 698 /* If auto type inference, do the inference 738 /* If auto type inference, do the inference 699 */ 739 */ 700 int inferred = 0; 740 int inferred = 0; 701 if (!type) 741 if (!type) 702 { inuse++; 742 { inuse++; 703 type = init->inferType(sc); 743 type = init->inferType(sc); 704 inuse--; 744 inuse--; 705 inferred = 1; 745 inferred = 1; 706 746 707 /* This is a kludge to support the existing syntax for RAII 747 /* This is a kludge to support the existing syntax for RAII 708 * declarations. 748 * declarations. 709 */ 749 */ 710 storage_class &= ~STCauto; 750 storage_class &= ~STCauto; 711 originalType = type; 751 originalType = type; 712 } 752 } 713 else 753 else 714 { if (!originalType) 754 { if (!originalType) 715 originalType = type; 755 originalType = type; 716 type = type->semantic(loc, sc); 756 type = type->semantic(loc, sc); 717 } 757 } 718 //printf(" semantic type = %s\n", type ? type->toChars() : "null"); 758 //printf(" semantic type = %s\n", type ? type->toChars() : "null"); 719 759 720 type->checkDeprecated(loc, sc); 760 type->checkDeprecated(loc, sc); 721 linkage = sc->linkage; 761 linkage = sc->linkage; 722 this->parent = sc->parent; 762 this->parent = sc->parent; 723 //printf("this = %p, parent = %p, '%s'\n", this, parent, parent->toChars()); 763 //printf("this = %p, parent = %p, '%s'\n", this, parent, parent->toChars()); 724 protection = sc->protection; 764 protection = sc->protection; 725 //printf("sc->stc = %x\n", sc->stc); 765 //printf("sc->stc = %x\n", sc->stc); 726 //printf("storage_class = x%x\n", storage_class); 766 //printf("storage_class = x%x\n", storage_class); 767 768 #if DMDV2 769 if (storage_class & STCgshared && global.params.safe && !sc->module->safe) 770 { 771 error("__gshared not allowed in safe mode; use shared"); 772 } 773 #endif 727 774 728 Dsymbol *parent = toParent(); 775 Dsymbol *parent = toParent(); 729 FuncDeclaration *fd = parent->isFuncDeclaration(); 776 FuncDeclaration *fd = parent->isFuncDeclaration(); 730 777 731 Type *tb = type->toBasetype(); 778 Type *tb = type->toBasetype(); 732 if (tb->ty == Tvoid && !(storage_class & STClazy)) 779 if (tb->ty == Tvoid && !(storage_class & STClazy)) 733 { error("voids have no value"); 780 { error("voids have no value"); 734 type = Type::terror; 781 type = Type::terror; 735 tb = type; 782 tb = type; 736 } 783 } 737 if (tb->ty == Tfunction) 784 if (tb->ty == Tfunction) 738 { error("cannot be declared to be a function"); 785 { error("cannot be declared to be a function"); 739 type = Type::terror; 786 type = Type::terror; 740 tb = type; 787 tb = type; 741 } 788 } 742 if (tb->ty == Tstruct) 789 if (tb->ty == Tstruct) 743 { TypeStruct *ts = (TypeStruct *)tb; 790 { TypeStruct *ts = (TypeStruct *)tb; 744 791 745 if (!ts->sym->members) 792 if (!ts->sym->members) 746 { 793 { … … 815 error("variable %s cannot be synchronized", toChars()); 862 error("variable %s cannot be synchronized", toChars()); 816 } 863 } 817 else if (isOverride()) 864 else if (isOverride()) 818 { 865 { 819 error("override cannot be applied to variable"); 866 error("override cannot be applied to variable"); 820 } 867 } 821 else if (isAbstract()) 868 else if (isAbstract()) 822 { 869 { 823 error("abstract cannot be applied to variable"); 870 error("abstract cannot be applied to variable"); 824 } 871 } 825 else if (storage_class & STCtemplateparameter) 872 else if (storage_class & STCtemplateparameter) 826 { 873 { 827 } 874 } 828 else 875 else 829 { 876 { 830 AggregateDeclaration *aad = sc->anonAgg; 877 AggregateDeclaration *aad = sc->anonAgg; 831 if (!aad) 878 if (!aad) 832 aad = parent->isAggregateDeclaration(); 879 aad = parent->isAggregateDeclaration(); 833 if (aad) 880 if (aad) 834 { 881 { 835 aad->addField(sc, this); 882 #if DMDV2 883 assert(!(storage_class & (STCextern | STCstatic | STCtls | STCgshared))); 884 885 if (storage_class & (STCconst | STCimmutable) && init) 886 { 887 if (!type->toBasetype()->isTypeBasic()) 888 storage_class |= STCstatic; 889 } 890 else 891 #endif 892 aad->addField(sc, this); 836 } 893 } 837 894 838 InterfaceDeclaration *id = parent->isInterfaceDeclaration(); 895 InterfaceDeclaration *id = parent->isInterfaceDeclaration(); 839 if (id) 896 if (id) 840 { 897 { 841 error("field not allowed in interface"); 898 error("field not allowed in interface"); 842 } 899 } 843 900 844 /* Templates cannot add fields to aggregates 901 /* Templates cannot add fields to aggregates 845 */ 902 */ 846 TemplateInstance *ti = parent->isTemplateInstance(); 903 TemplateInstance *ti = parent->isTemplateInstance(); 847 if (ti) 904 if (ti) 848 { 905 { 849 // Take care of nested templates 906 // Take care of nested templates 850 while (1) 907 while (1) 851 { 908 { 852 TemplateInstance *ti2 = ti->tempdecl->parent->isTemplateInstance(); 909 TemplateInstance *ti2 = ti->tempdecl->parent->isTemplateInstance(); 853 if (!ti2) 910 if (!ti2) 854 break; 911 break; 855 ti = ti2; 912 ti = ti2; 856 } 913 } 857 914 858 // If it's a member template 915 // If it's a member template 859 AggregateDeclaration *ad = ti->tempdecl->isMember(); 916 AggregateDeclaration *ad = ti->tempdecl->isMember(); 860 if (ad && storage_class != STCundefined) 917 if (ad && storage_class != STCundefined) 861 { 918 { 862 error("cannot use template to add field to aggregate '%s'", ad->toChars()); 919 error("cannot use template to add field to aggregate '%s'", ad->toChars()); 863 } 920 } 864 } 921 } 865 } 922 } 866 923 924 #if DMDV2 925 if ((storage_class & (STCref | STCparameter | STCforeach)) == STCref && 926 ident != Id::This) 927 { 928 error("only parameters or foreach declarations can be ref"); 929 } 930 #endif 931 867 if (type->isscope() && !noscope) 932 if (type->isscope() && !noscope) 868 { 933 { 869 if (storage_class & (STCfield | STCout | STCref | STCstatic) || !fd) 934 if (storage_class & (STCfield | STCout | STCref | STCstatic) || !fd) 870 { 935 { 871 error("globals, statics, fields, ref and out parameters cannot be scope"); 936 error("globals, statics, fields, ref and out parameters cannot be scope"); 872 } 937 } 873 938 874 if (!(storage_class & STCscope)) 939 if (!(storage_class & STCscope)) 875 { 940 { 876 if (!(storage_class & STCparameter) && ident != Id::withSym) 941 if (!(storage_class & STCparameter) && ident != Id::withSym) 877 error("reference to scope class must be scope"); 942 error("reference to scope class must be scope"); 878 } 943 } 879 } 944 } 880 945 946 enum TOK op = TOKconstruct; 881 if (!init && !sc->inunion && !isStatic() && !isConst() && fd && 947 if (!init && !sc->inunion && !isStatic() && !isConst() && fd && 882 !(storage_class & (STCfield | STCin | STCforeach)) && 948 !(storage_class & (STCfield | STCin | STCforeach)) && 883 type->size() != 0) 949 type->size() != 0) 884 { 950 { 885 // Provide a default initializer 951 // Provide a default initializer 886 //printf("Providing default initializer for '%s'\n", toChars()); 952 //printf("Providing default initializer for '%s'\n", toChars()); 887 if (type->ty == Tstruct && 953 if (type->ty == Tstruct && 888 ((TypeStruct *)type)->sym->zeroInit == 1) 954 ((TypeStruct *)type)->sym->zeroInit == 1) 889 { /* If a struct is all zeros, as a special case 955 { /* If a struct is all zeros, as a special case 890 * set it's initializer to the integer 0. 956 * set it's initializer to the integer 0. 891 * In AssignExp::toElem(), we check for this and issue 957 * In AssignExp::toElem(), we check for this and issue 892 * a memset() to initialize the struct. 958 * a memset() to initialize the struct. 893 * Must do same check in interpreter. 959 * Must do same check in interpreter. 894 */ 960 */ 895 Expression *e = new IntegerExp(loc
