1: 
  2: // Compiler implementation of the D programming language
  3: // Copyright (c) 1999-2007 by Digital Mars
  4: // All Rights Reserved
  5: // written by Walter Bright
  6: // http://www.digitalmars.com
  7: // License for redistribution is by either the Artistic License
  8: // in artistic.txt, or the GNU General Public License in gnu.txt.
  9: // See the included readme.txt for details.
 10: 
 11: #include <stdio.h>
 12: static char __file__[] = __FILE__;      /* for tassert.h                */
 13: #include        "tassert.h"
 14: 
 15: #include "mars.h"
 16: #include "expression.h"
 17: #include "statement.h"
 18: #include "mtype.h"
 19: #include "utf.h"
 20: #include "declaration.h"
 21: #include "aggregate.h"
 22: #include "scope.h"
 23: 
 24: /********************************************
 25:  * Convert from expression to delegate that returns the expression,
 26:  * i.e. convert:
 27:  *      expr
 28:  * to:
 29:  *      t delegate() { return expr; }
 30:  */
 31: 
 32: Expression *Expression::toDelegate(Scope *sc, Type *t)
 33: {
 34:     //printf("Expression::toDelegate(t = %s) %s\n", t->toChars(), toChars());
 35:     TypeFunction *tf = new TypeFunction(NULL, t, 0, LINKd);
 36:     FuncLiteralDeclaration *fld =
 37:         new FuncLiteralDeclaration(loc, loc, tf, TOKdelegate, NULL);
 38:     Expression *e;
 39: #if 1
 40:     sc = sc->push();
 41:     sc->parent = fld;           // set current function to be the delegate
 42:     e = this;
 43:     e->scanForNestedRef(sc);
 44:     sc = sc->pop();
 45: #else
 46:     e = this->syntaxCopy();
 47: #endif
 48:     Statement *s = new ReturnStatement(loc, e);
 49:     fld->fbody = s;
 50:     e = new FuncExp(loc, fld);
 51:     e = e->semantic(sc);
 52:     return e;
 53: }
 54: 
 55: /******************************
 56:  * Perform scanForNestedRef() on an array of Expressions.
 57:  */
 58: 
 59: void arrayExpressionScanForNestedRef(Scope *sc, Expressions *a)
 60: {
 61:     //printf("arrayExpressionScanForNestedRef(%p)\n", a);
 62:     if (a)
 63:     {
 64:         for (int i = 0; i < a->dim; i++)
warning C4018: '<' : signed/unsigned mismatch
65: { Expression *e = a->tdata()[i]; 66: 67: if (e) 68: { 69: e->scanForNestedRef(sc); 70: } 71: } 72: } 73: } 74: 75: void Expression::scanForNestedRef(Scope *sc) 76: { 77: //printf("Expression::scanForNestedRef(%s)\n", toChars()); 78: } 79: 80: void SymOffExp::scanForNestedRef(Scope *sc) 81: { 82: //printf("SymOffExp::scanForNestedRef(%s)\n", toChars()); 83: VarDeclaration *v = var->isVarDeclaration(); 84: if (v) 85: v->checkNestedReference(sc, 0); 86: } 87: 88: void VarExp::scanForNestedRef(Scope *sc) 89: { 90: //printf("VarExp::scanForNestedRef(%s)\n", toChars()); 91: VarDeclaration *v = var->isVarDeclaration(); 92: if (v) 93: v->checkNestedReference(sc, 0); 94: } 95: 96: void ThisExp::scanForNestedRef(Scope *sc) 97: { 98: assert(var); 99: var->isVarDeclaration()->checkNestedReference(sc, 0); 100: } 101: 102: void SuperExp::scanForNestedRef(Scope *sc) 103: { 104: ThisExp::scanForNestedRef(sc); 105: } 106: 107: void FuncExp::scanForNestedRef(Scope *sc) 108: { 109: //printf("FuncExp::scanForNestedRef(%s)\n", toChars()); 110: //fd->parent = sc->parent; 111: } 112: 113: void DeclarationExp::scanForNestedRef(Scope *sc) 114: { 115: //printf("DeclarationExp::scanForNestedRef() %s\n", toChars()); 116: declaration->parent = sc->parent; 117: } 118: 119: void NewExp::scanForNestedRef(Scope *sc) 120: { 121: //printf("NewExp::scanForNestedRef(Scope *sc): %s\n", toChars()); 122: 123: if (thisexp) 124: thisexp->scanForNestedRef(sc); 125: arrayExpressionScanForNestedRef(sc, newargs); 126: arrayExpressionScanForNestedRef(sc, arguments); 127: } 128: 129: void UnaExp::scanForNestedRef(Scope *sc) 130: { 131: e1->scanForNestedRef(sc); 132: } 133: 134: void BinExp::scanForNestedRef(Scope *sc) 135: { 136: e1->scanForNestedRef(sc); 137: e2->scanForNestedRef(sc); 138: } 139: 140: void CallExp::scanForNestedRef(Scope *sc) 141: { 142: //printf("CallExp::scanForNestedRef(Scope *sc): %s\n", toChars()); 143: e1->scanForNestedRef(sc); 144: arrayExpressionScanForNestedRef(sc, arguments); 145: } 146: 147: 148: void IndexExp::scanForNestedRef(Scope *sc) 149: { 150: e1->scanForNestedRef(sc); 151: 152: if (lengthVar) 153: { //printf("lengthVar\n"); 154: lengthVar->parent = sc->parent; 155: } 156: e2->scanForNestedRef(sc); 157: } 158: 159: 160: void SliceExp::scanForNestedRef(Scope *sc) 161: { 162: e1->scanForNestedRef(sc); 163: 164: if (lengthVar) 165: { //printf("lengthVar\n"); 166: lengthVar->parent = sc->parent; 167: } 168: if (lwr) 169: lwr->scanForNestedRef(sc); 170: if (upr) 171: upr->scanForNestedRef(sc); 172: } 173: 174: 175: void ArrayLiteralExp::scanForNestedRef(Scope *sc) 176: { 177: arrayExpressionScanForNestedRef(sc, elements); 178: } 179: 180: 181: void AssocArrayLiteralExp::scanForNestedRef(Scope *sc) 182: { 183: arrayExpressionScanForNestedRef(sc, keys); 184: arrayExpressionScanForNestedRef(sc, values); 185: } 186: 187: 188: void StructLiteralExp::scanForNestedRef(Scope *sc) 189: { 190: arrayExpressionScanForNestedRef(sc, elements); 191: } 192: 193: 194: void TupleExp::scanForNestedRef(Scope *sc) 195: { 196: arrayExpressionScanForNestedRef(sc, exps); 197: } 198: 199: 200: void ArrayExp::scanForNestedRef(Scope *sc) 201: { 202: e1->scanForNestedRef(sc); 203: arrayExpressionScanForNestedRef(sc, arguments); 204: } 205: 206: 207: void CondExp::scanForNestedRef(Scope *sc) 208: { 209: econd->scanForNestedRef(sc); 210: e1->scanForNestedRef(sc); 211: e2->scanForNestedRef(sc); 212: } 213: 214: 215: 216: