Mercurial > projects > ldc
comparison dmd/statement.c @ 1159:c6d6a68bb5db
Add back some enclosing scope-exit information to the frontend to produce
proper error messages inside switch statements.
author | Christian Kamm <kamm incasoftware de> |
---|---|
date | Sat, 28 Mar 2009 14:39:16 +0100 |
parents | f99a3b393c03 |
children | 166042b48c28 |
comparison
equal
deleted
inserted
replaced
1158:08c1c3bfea5a | 1159:c6d6a68bb5db |
---|---|
2236 condition = c; | 2236 condition = c; |
2237 body = b; | 2237 body = b; |
2238 sdefault = NULL; | 2238 sdefault = NULL; |
2239 cases = NULL; | 2239 cases = NULL; |
2240 hasNoDefault = 0; | 2240 hasNoDefault = 0; |
2241 // LDC | |
2242 enclosingScopeExit = NULL; | |
2241 } | 2243 } |
2242 | 2244 |
2243 Statement *SwitchStatement::syntaxCopy() | 2245 Statement *SwitchStatement::syntaxCopy() |
2244 { | 2246 { |
2245 SwitchStatement *s = new SwitchStatement(loc, | 2247 SwitchStatement *s = new SwitchStatement(loc, |
2249 | 2251 |
2250 Statement *SwitchStatement::semantic(Scope *sc) | 2252 Statement *SwitchStatement::semantic(Scope *sc) |
2251 { | 2253 { |
2252 //printf("SwitchStatement::semantic(%p)\n", this); | 2254 //printf("SwitchStatement::semantic(%p)\n", this); |
2253 assert(!cases); // ensure semantic() is only run once | 2255 assert(!cases); // ensure semantic() is only run once |
2256 | |
2257 // LDC | |
2258 enclosingScopeExit = sc->enclosingScopeExit; | |
2254 | 2259 |
2255 condition = condition->semantic(sc); | 2260 condition = condition->semantic(sc); |
2256 condition = resolveProperties(sc, condition); | 2261 condition = resolveProperties(sc, condition); |
2257 if (condition->type->isString()) | 2262 if (condition->type->isString()) |
2258 { | 2263 { |
2402 this->exp = exp; | 2407 this->exp = exp; |
2403 this->statement = s; | 2408 this->statement = s; |
2404 cblock = NULL; | 2409 cblock = NULL; |
2405 bodyBB = NULL; | 2410 bodyBB = NULL; |
2406 llvmIdx = NULL; | 2411 llvmIdx = NULL; |
2412 // LDC | |
2413 enclosingScopeExit = NULL; | |
2407 } | 2414 } |
2408 | 2415 |
2409 Statement *CaseStatement::syntaxCopy() | 2416 Statement *CaseStatement::syntaxCopy() |
2410 { | 2417 { |
2411 CaseStatement *s = new CaseStatement(loc, exp->syntaxCopy(), statement->syntaxCopy()); | 2418 CaseStatement *s = new CaseStatement(loc, exp->syntaxCopy(), statement->syntaxCopy()); |
2414 | 2421 |
2415 Statement *CaseStatement::semantic(Scope *sc) | 2422 Statement *CaseStatement::semantic(Scope *sc) |
2416 { SwitchStatement *sw = sc->sw; | 2423 { SwitchStatement *sw = sc->sw; |
2417 | 2424 |
2418 //printf("CaseStatement::semantic() %s\n", toChars()); | 2425 //printf("CaseStatement::semantic() %s\n", toChars()); |
2426 | |
2427 // LDC | |
2428 enclosingScopeExit = sc->enclosingScopeExit; | |
2429 if (enclosingScopeExit != sw->enclosingScopeExit) | |
2430 { | |
2431 error("case must be inside the same try, synchronized or volatile level as switch"); | |
2432 } | |
2433 | |
2419 exp = exp->semantic(sc); | 2434 exp = exp->semantic(sc); |
2420 if (sw) | 2435 if (sw) |
2421 { | 2436 { |
2422 exp = exp->implicitCastTo(sc, sw->condition->type); | 2437 exp = exp->implicitCastTo(sc, sw->condition->type); |
2423 exp = exp->optimize(WANTvalue | WANTinterpret); | 2438 exp = exp->optimize(WANTvalue | WANTinterpret); |
2498 this->statement = s; | 2513 this->statement = s; |
2499 #if IN_GCC | 2514 #if IN_GCC |
2500 + cblock = NULL; | 2515 + cblock = NULL; |
2501 #endif | 2516 #endif |
2502 bodyBB = NULL; | 2517 bodyBB = NULL; |
2518 // LDC | |
2519 enclosingScopeExit = NULL; | |
2503 } | 2520 } |
2504 | 2521 |
2505 Statement *DefaultStatement::syntaxCopy() | 2522 Statement *DefaultStatement::syntaxCopy() |
2506 { | 2523 { |
2507 DefaultStatement *s = new DefaultStatement(loc, statement->syntaxCopy()); | 2524 DefaultStatement *s = new DefaultStatement(loc, statement->syntaxCopy()); |
2509 } | 2526 } |
2510 | 2527 |
2511 Statement *DefaultStatement::semantic(Scope *sc) | 2528 Statement *DefaultStatement::semantic(Scope *sc) |
2512 { | 2529 { |
2513 //printf("DefaultStatement::semantic()\n"); | 2530 //printf("DefaultStatement::semantic()\n"); |
2531 | |
2514 if (sc->sw) | 2532 if (sc->sw) |
2515 { | 2533 { |
2516 if (sc->sw->sdefault) | 2534 if (sc->sw->sdefault) |
2517 { | 2535 { |
2518 error("switch statement already has a default"); | 2536 error("switch statement already has a default"); |
2519 } | 2537 } |
2520 sc->sw->sdefault = this; | 2538 sc->sw->sdefault = this; |
2539 | |
2540 // LDC | |
2541 enclosingScopeExit = sc->enclosingScopeExit; | |
2542 if (enclosingScopeExit != sc->sw->enclosingScopeExit) | |
2543 { | |
2544 error("default must be inside the same try, synchronized or volatile level as switch"); | |
2545 } | |
2521 } | 2546 } |
2522 else | 2547 else |
2523 error("default not in switch statement"); | 2548 error("default not in switch statement"); |
2524 statement = statement->semantic(sc); | 2549 statement = statement->semantic(sc); |
2525 return this; | 2550 return this; |