[dmd-internals] dmd test suite coverage

Walter Bright walter at digitalmars.com
Fri Sep 3 14:48:25 PDT 2010


I built dmd with coverage analysis (gcov on linux) and ran the test 
suite. This is one of the result files - there are definitely gaps in 
the suite. Anyone want to give these a go?
-----------------------------------------------------------------
        -:    0:Source:parse.c
        -:    0:Graph:parse.gcno
        -:    0:Data:parse.gcda
        -:    0:Runs:10817
        -:    0:Programs:1
        -:    1:
        -:    2:// Compiler implementation of the D programming language
        -:    3:// Copyright (c) 1999-2010 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:// This is the D parser
        -:   12:
        -:   13:#include <stdio.h>
        -:   14:#include <assert.h>
        -:   15:
        -:   16:#include "rmem.h"
        -:   17:#include "lexer.h"
        -:   18:#include "parse.h"
        -:   19:#include "init.h"
        -:   20:#include "attrib.h"
        -:   21:#include "cond.h"
        -:   22:#include "mtype.h"
        -:   23:#include "template.h"
        -:   24:#include "staticassert.h"
        -:   25:#include "expression.h"
        -:   26:#include "statement.h"
        -:   27:#include "module.h"
        -:   28:#include "dsymbol.h"
        -:   29:#include "import.h"
        -:   30:#include "declaration.h"
        -:   31:#include "aggregate.h"
        -:   32:#include "enum.h"
        -:   33:#include "id.h"
        -:   34:#include "version.h"
        -:   35:#include "aliasthis.h"
        -:   36:
        -:   37:// How multiple declarations are parsed.
        -:   38:// If 1, treat as C.
        -:   39:// If 0, treat:
        -:   40://      int *p, i;
        -:   41:// as:
        -:   42://      int* p;
        -:   43://      int* i;
        -:   44:#define CDECLSYNTAX     0
        -:   45:
        -:   46:// Support C cast syntax:
        -:   47://      (type)(expression)
        -:   48:#define CCASTSYNTAX     1
        -:   49:
        -:   50:// Support postfix C array declarations, such as
        -:   51://      int a[3][4];
        -:   52:#define CARRAYDECL      1
        -:   53:
        -:   54:// Support D1 inout
        -:   55:#define D1INOUT         0
        -:   56:
   253642:   57:Parser::Parser(Module *module, unsigned char *base, 
unsigned length, int doDocComment)
   253642:   58:    : Lexer(module, base, 0, length, doDocComment, 0)
        -:   59:{
        -:   60:    //printf("Parser::Parser()\n");
   253642:   61:    md = NULL;
   253642:   62:    linkage = LINKd;
   253642:   63:    endloc = 0;
   253642:   64:    inBrackets = 0;
        -:   65:    //nextToken();              // start up the scanner
   253642:   66:}
        -:   67:
   239264:   68:Dsymbols *Parser::parseModule()
        -:   69:{
        -:   70:    Dsymbols *decldefs;
        -:   71:
        -:   72:    // ModuleDeclation leads off
   239264:   73:    if (token.value == TOKmodule)
        -:   74:    {
   234313:   75:        unsigned char *comment = token.blockComment;
   234313:   76:        bool safe = FALSE;
        -:   77:
   234313:   78:        nextToken();
        -:   79:#if 0 && DMDV2
        -:   80:        if (token.value == TOKlparen)
        -:   81:        {
        -:   82:            nextToken();
        -:   83:            if (token.value != TOKidentifier)
        -:   84:            {   error("module (system) identifier 
expected");
        -:   85:                goto Lerr;
        -:   86:            }
        -:   87:            Identifier *id = token.ident;
        -:   88:
        -:   89:            if (id == Id::system)
        -:   90:                safe = TRUE;
        -:   91:            else
        -:   92:                error("(safe) expected, not %s", 
id->toChars());
        -:   93:            nextToken();
        -:   94:            check(TOKrparen);
        -:   95:        }
        -:   96:#endif
        -:   97:
   234313:   98:        if (token.value != TOKidentifier)
    #####:   99:        {   error("Identifier expected following module");
    #####:  100:            goto Lerr;
        -:  101:        }
        -:  102:        else
        -:  103:        {
   234313:  104:            Array *a = NULL;
        -:  105:            Identifier *id;
        -:  106:
   234313:  107:            id = token.ident;
   883376:  108:            while (nextToken() == TOKdot)
        -:  109:            {
   414750:  110:                if (!a)
   226382:  111:                    a = new Array();
   414750:  112:                a->push(id);
   414750:  113:                nextToken();
   414750:  114:                if (token.value != TOKidentifier)
    #####:  115:                {   error("Identifier expected following 
package");
    #####:  116:                    goto Lerr;
        -:  117:                }
   414750:  118:                id = token.ident;
        -:  119:            }
        -:  120:
   234313:  121:            md = new ModuleDeclaration(a, id, safe);
        -:  122:
   234313:  123:            if (token.value != TOKsemicolon)
    #####:  124:                error("';' expected following module 
declaration instead of %s", token.toChars());
   234313:  125:            nextToken();
   234313:  126:            addComment(mod, comment);
        -:  127:        }
        -:  128:    }
        -:  129:
   239264:  130:    decldefs = parseDeclDefs(0);
   239264:  131:    if (token.value != TOKeof)
    #####:  132:    {   error("unrecognized declaration");
    #####:  133:        goto Lerr;
        -:  134:    }
   239264:  135:    return decldefs;
        -:  136:
    #####:  137:Lerr:
    #####:  138:    while (token.value != TOKsemicolon && token.value != 
TOKeof)
    #####:  139:        nextToken();
    #####:  140:    nextToken();
    #####:  141:    return new Dsymbols();
        -:  142:}
        -:  143:
 10551692:  144:Dsymbols *Parser::parseDeclDefs(int once)
        -:  145:{   Dsymbol *s;
        -:  146:    Dsymbols *decldefs;
        -:  147:    Dsymbols *a;
        -:  148:    Dsymbols *aelse;
        -:  149:    enum PROT prot;
        -:  150:    StorageClass stc;
        -:  151:    StorageClass storageClass;
        -:  152:    Condition *condition;
        -:  153:    unsigned char *comment;
        -:  154:
        -:  155:    //printf("Parser::parseDeclDefs()\n");
 10551692:  156:    decldefs = new Dsymbols();
 32897322:  157:    do
        -:  158:    {
 38282754:  159:        comment = token.blockComment;
 38282754:  160:        storageClass = STCundefined;
 38282754:  161:        switch (token.value)
        -:  162:        {
        -:  163:            case TOKenum:
        -:  164:            {   /* Determine if this is a manifest 
constant declaration,
        -:  165:                 * or a conventional enum.
        -:  166:                 */
  4487003:  167:                Token *t = peek(&token);
  4716218:  168:                if (t->value == TOKlcurly || t->value == 
TOKcolon)
   229215:  169:                    s = parseEnum();
  4257788:  170:                else if (t->value != TOKidentifier)
   466816:  171:                    goto Ldeclaration;
        -:  172:                else
        -:  173:                {
  3790972:  174:                    t = peek(t);
  3790972:  175:                    if (t->value == TOKlcurly || 
t->value == TOKcolon ||
        -:  176:                        t->value == TOKsemicolon)
    87489:  177:                        s = parseEnum();
        -:  178:                    else
        -:  179:                        goto Ldeclaration;
        -:  180:                }
   316704:  181:                break;
        -:  182:            }
        -:  183:
        -:  184:            case TOKstruct:
        -:  185:            case TOKunion:
        -:  186:            case TOKclass:
        -:  187:            case TOKinterface:
  1074674:  188:                s = parseAggregate();
  1074674:  189:                break;
        -:  190:
        -:  191:            case TOKimport:
   683760:  192:                s = parseImport(decldefs, 0);
   683760:  193:                break;
        -:  194:
        -:  195:            case TOKtemplate:
   861570:  196:                s = (Dsymbol *)parseTemplateDeclaration(0);
   861570:  197:                break;
        -:  198:
        -:  199:            case TOKmixin:
   161369:  200:            {   Loc loc = this->loc;
   161369:  201:                switch (peekNext())
        -:  202:                {
        -:  203:                    case TOKlparen:
        -:  204:                    {   // mixin(string)
    53380:  205:                        nextToken();
    53380:  206:                        check(TOKlparen, "mixin");
    53380:  207:                        Expression *e = parseAssignExp();
    53380:  208:                        check(TOKrparen);
    53380:  209:                        check(TOKsemicolon);
    53380:  210:                        s = new CompileDeclaration(loc, e);
    53380:  211:                        break;
        -:  212:                    }
        -:  213:                    case TOKtemplate:
        -:  214:                        // mixin template
       64:  215:                        nextToken();
       64:  216:                        s = (Dsymbol 
*)parseTemplateDeclaration(1);
       64:  217:                        break;
        -:  218:
        -:  219:                    default:
   107925:  220:                        s = parseMixin();
        -:  221:                        break;
        -:  222:                }
   161369:  223:                break;
        -:  224:            }
        -:  225:
        -:  226:            case BASIC_TYPES:
        -:  227:            case TOKalias:
        -:  228:            case TOKtypedef:
        -:  229:            case TOKidentifier:
        -:  230:            case TOKtypeof:
        -:  231:            case TOKdot:
 20647635:  232:            Ldeclaration:
 20647635:  233:                a = parseDeclarations(STCundefined);
 20647635:  234:                decldefs->append(a);
 20647635:  235:                continue;
        -:  236:
        -:  237:            case TOKthis:
   444134:  238:                s = parseCtor();
   444134:  239:                break;
        -:  240:
        -:  241:#if 0 // dead end, use this(this){} instead
        -:  242:            case TOKassign:
        -:  243:                s = parsePostBlit();
        -:  244:                break;
        -:  245:#endif
        -:  246:            case TOKtilde:
    40559:  247:                s = parseDtor();
    40559:  248:                break;
        -:  249:
        -:  250:            case TOKinvariant:
        -:  251:            {   Token *t;
     4385:  252:                t = peek(&token);
     4385:  253:                if (t->value == TOKlparen)
        -:  254:                {
     4128:  255:                    if (peek(t)->value == TOKrparen)
        -:  256:                        // invariant() forms start of 
class invariant
     4128:  257:                        s = parseInvariant();
        -:  258:                    else
        -:  259:                        // invariant(type)
    #####:  260:                        goto Ldeclaration;
        -:  261:                }
        -:  262:                else
        -:  263:                {
      257:  264:                    stc = STCimmutable;
      257:  265:                    goto Lstc;
        -:  266:                }
     4128:  267:                break;
        -:  268:            }
        -:  269:
        -:  270:            case TOKunittest:
  1854795:  271:                s = parseUnitTest();
  1854795:  272:                break;
        -:  273:
        -:  274:            case TOKnew:
      195:  275:                s = parseNew();
      195:  276:                break;
        -:  277:
        -:  278:            case TOKdelete:
      194:  279:                s = parseDelete();
      194:  280:                break;
        -:  281:
        -:  282:            case TOKeof:
        -:  283:            case TOKrcurly:
  5385432:  284:                return decldefs;
        -:  285:
        -:  286:            case TOKstatic:
  1409839:  287:                nextToken();
  1409839:  288:                if (token.value == TOKthis)
     4476:  289:                    s = parseStaticCtor();
  1405363:  290:                else if (token.value == TOKtilde)
      398:  291:                    s = parseStaticDtor();
  1404965:  292:                else if (token.value == TOKassert)
   146186:  293:                    s = parseStaticAssert();
  1258779:  294:                else if (token.value == TOKif)
   982206:  295:                {   condition = parseStaticIfCondition();
   982206:  296:                    a = parseBlock();
   982206:  297:                    aelse = NULL;
   982206:  298:                    if (token.value == TOKelse)
   798030:  299:                    {   nextToken();
   798030:  300:                        aelse = parseBlock();
        -:  301:                    }
   982206:  302:                    s = new 
StaticIfDeclaration(condition, a, aelse);
   982206:  303:                    break;
        -:  304:                }
   276573:  305:                else if (token.value == TOKimport)
        -:  306:                {
    #####:  307:                    s = parseImport(decldefs, 1);
        -:  308:                }
        -:  309:                else
   276573:  310:                {   stc = STCstatic;
   276573:  311:                    goto Lstc2;
        -:  312:                }
   151060:  313:                break;
        -:  314:
        -:  315:            case TOKconst:
   120355:  316:                if (peekNext() == TOKlparen)
    59120:  317:                    goto Ldeclaration;
    61235:  318:                stc = STCconst;
    61235:  319:                goto Lstc;
        -:  320:
        -:  321:            case TOKimmutable:
   137755:  322:                if (peekNext() == TOKlparen)
    39739:  323:                    goto Ldeclaration;
    98016:  324:                stc = STCimmutable;
    98016:  325:                goto Lstc;
        -:  326:
        -:  327:            case TOKshared:
    67183:  328:            {   TOK next = peekNext();
    67183:  329:                if (next == TOKlparen)
       64:  330:                    goto Ldeclaration;
    67119:  331:                if (next == TOKstatic)
    27622:  332:                {   TOK next2 = peekNext2();
    27622:  333:                    if (next2 == TOKthis)
    27622:  334:                    {   s = parseSharedStaticCtor();
    27622:  335:                        break;
        -:  336:                    }
    #####:  337:                    if (next2 == TOKtilde)
    #####:  338:                    {   s = parseSharedStaticDtor();
    #####:  339:                        break;
        -:  340:                    }
        -:  341:                }
    39497:  342:                stc = STCshared;
    39497:  343:                goto Lstc;
        -:  344:            }
        -:  345:
        -:  346:            case TOKwild:
       64:  347:                if (peekNext() == TOKlparen)
       64:  348:                    goto Ldeclaration;
    #####:  349:                stc = STCwild;
    #####:  350:                goto Lstc;
        -:  351:
    51725:  352:            case TOKfinal:        stc = STCfinal;        
goto Lstc;
    52106:  353:            case TOKauto:         stc = STCauto;         
goto Lstc;
      387:  354:            case TOKscope:        stc = STCscope;        
goto Lstc;
   232281:  355:            case TOKoverride:     stc = STCoverride;     
goto Lstc;
    44064:  356:            case TOKabstract:     stc = STCabstract;     
goto Lstc;
      131:  357:            case TOKsynchronized: stc = STCsynchronized; 
goto Lstc;
    91798:  358:            case TOKdeprecated:   stc = STCdeprecated;   
goto Lstc;
        -:  359:#if DMDV2
    28557:  360:            case TOKnothrow:      stc = STCnothrow;      
goto Lstc;
   358146:  361:            case TOKpure:         stc = STCpure;         
goto Lstc;
    87332:  362:            case TOKref:          stc = STCref;          
goto Lstc;
      330:  363:            case TOKtls:          stc = STCtls;          
goto Lstc;
    34447:  364:            case TOKgshared:      stc = STCgshared;      
goto Lstc;
        -:  365:            //case TOKmanifest:   stc = STCmanifest;     
goto Lstc;
   738076:  366:            case TOKat:           stc = 
parseAttribute(); goto Lstc;
        -:  367:#endif
        -:  368:
  2542626:  369:            Lstc:
  2542626:  370:                if (storageClass & stc)
    #####:  371:                    error("redundant storage class %s", 
Token::toChars(token.value));
  2542626:  372:                composeStorageClass(storageClass | stc);
  2542626:  373:                nextToken();
  2819199:  374:            Lstc2:
  2819199:  375:                storageClass |= stc;
  2819199:  376:                switch (token.value)
        -:  377:                {
        -:  378:                    case TOKconst:
        -:  379:                    case TOKinvariant:
        -:  380:                    case TOKimmutable:
        -:  381:                    case TOKshared:
        -:  382:                    case TOKwild:
        -:  383:                        // If followed by a (, it is not 
a storage class
    94386:  384:                        if (peek(&token)->value == 
TOKlparen)
    36820:  385:                            break;
    57566:  386:                        if (token.value == TOKconst)
     1222:  387:                            stc = STCconst;
    56344:  388:                        else if (token.value == TOKshared)
    53313:  389:                            stc = STCshared;
     3031:  390:                        else if (token.value == TOKwild)
    #####:  391:                            stc = STCwild;
        -:  392:                        else
     3031:  393:                            stc = STCimmutable;
    57566:  394:                        goto Lstc;
    #####:  395:                    case TOKfinal:        stc = 
STCfinal;        goto Lstc;
    27279:  396:                    case TOKauto:         stc = 
STCauto;         goto Lstc;
    #####:  397:                    case TOKscope:        stc = 
STCscope;        goto Lstc;
     3031:  398:                    case TOKoverride:     stc = 
STCoverride;     goto Lstc;
    #####:  399:                    case TOKabstract:     stc = 
STCabstract;     goto Lstc;
        1:  400:                    case TOKsynchronized: stc = 
STCsynchronized; goto Lstc;
       64:  401:                    case TOKdeprecated:   stc = 
STCdeprecated;   goto Lstc;
   282017:  402:                    case TOKnothrow:      stc = 
STCnothrow;      goto Lstc;
    30310:  403:                    case TOKpure:         stc = 
STCpure;         goto Lstc;
    84942:  404:                    case TOKref:          stc = 
STCref;          goto Lstc;
     6216:  405:                    case TOKtls:          stc = 
STCtls;          goto Lstc;
    18349:  406:                    case TOKgshared:      stc = 
STCgshared;      goto Lstc;
        -:  407:                    //case TOKmanifest:   stc = 
STCmanifest;     goto Lstc;
    29425:  408:                    case TOKat:           stc = 
parseAttribute(); goto Lstc;
        -:  409:                    default:
        -:  410:                        break;
        -:  411:                }
        -:  412:
        -:  413:                /* Look for auto initializers:
        -:  414:                 *      storage_class identifier = 
initializer;
        -:  415:                 */
  2279999:  416:                if (token.value == TOKidentifier &&
        -:  417:                    peek(&token)->value == TOKassign)
        -:  418:                {
    24025:  419:                    a = 
parseAutoDeclarations(storageClass, comment);
    24025:  420:                    decldefs->append(a);
    24025:  421:                    continue;
        -:  422:                }
        -:  423:
        -:  424:                /* Look for return type inference for 
template functions.
        -:  425:                 */
        -:  426:                Token *tk;
  2255974:  427:                if (token.value == TOKidentifier &&
        -:  428:                    (tk = peek(&token))->value == 
TOKlparen &&
        -:  429:                    skipParens(tk, &tk) &&
        -:  430:                    (peek(tk)->value == TOKlparen ||
        -:  431:                     peek(tk)->value == TOKlcurly)
        -:  432:                   )
        -:  433:                {
    76289:  434:                    a = parseDeclarations(storageClass);
    76289:  435:                    decldefs->append(a);
    76289:  436:                    continue;
        -:  437:                }
  2179685:  438:                a = parseBlock();
  2179685:  439:                s = new 
StorageClassDeclaration(storageClass, a);
  2179685:  440:                break;
        -:  441:
        -:  442:            case TOKextern:
   678352:  443:                if (peek(&token)->value != TOKlparen)
    85041:  444:                {   stc = STCextern;
    85041:  445:                    goto Lstc;
        -:  446:                }
        -:  447:            {
   593311:  448:                enum LINK linksave = linkage;
   593311:  449:                linkage = parseLinkage();
   593311:  450:                a = parseBlock();
   593311:  451:                s = new LinkDeclaration(linkage, a);
   593311:  452:                linkage = linksave;
   593311:  453:                break;
        -:  454:            }
  1122645:  455:            case TOKprivate:    prot = PROTprivate;     
goto Lprot;
    18442:  456:            case TOKpackage:    prot = PROTpackage;     
goto Lprot;
     1672:  457:            case TOKprotected:  prot = PROTprotected;   
goto Lprot;
   342030:  458:            case TOKpublic:     prot = PROTpublic;      
goto Lprot;
    #####:  459:            case TOKexport:     prot = PROTexport;      
goto Lprot;
        -:  460:
  1484789:  461:            Lprot:
  1484789:  462:                nextToken();
  1484789:  463:                switch (token.value)
        -:  464:                {
        -:  465:                    case TOKprivate:
        -:  466:                    case TOKpackage:
        -:  467:                    case TOKprotected:
        -:  468:                    case TOKpublic:
        -:  469:                    case TOKexport:
    #####:  470:                        error("redundant protection 
attribute");
        -:  471:                        break;
        -:  472:                }
  1484789:  473:                a = parseBlock();
  1484789:  474:                s = new ProtDeclaration(prot, a);
  1484789:  475:                break;
        -:  476:
        -:  477:            case TOKalign:
        -:  478:            {   unsigned n;
        -:  479:
    13452:  480:                s = NULL;
    13452:  481:                nextToken();
    13452:  482:                if (token.value == TOKlparen)
        -:  483:                {
    13452:  484:                    nextToken();
    13452:  485:                    if (token.value == TOKint32v)
    13452:  486:                        n = (unsigned)token.uns64value;
        -:  487:                    else
    #####:  488:                    {   error("integer expected, not 
%s", token.toChars());
    #####:  489:                        n = 1;
        -:  490:                    }
    13452:  491:                    nextToken();
    13452:  492:                    check(TOKrparen);
        -:  493:                }
        -:  494:                else
    #####:  495:                    n = global.structalign;             
// default
        -:  496:
    13452:  497:                a = parseBlock();
    13452:  498:                s = new AlignDeclaration(n, a);
    13452:  499:                break;
        -:  500:            }
        -:  501:
        -:  502:            case TOKpragma:
        -:  503:            {   Identifier *ident;
    13505:  504:                Expressions *args = NULL;
        -:  505:
    13505:  506:                nextToken();
    13505:  507:                check(TOKlparen);
    13505:  508:                if (token.value != TOKidentifier)
    #####:  509:                {   error("pragma(identifier expected");
    #####:  510:                    goto Lerror;
        -:  511:                }
    13505:  512:                ident = token.ident;
    13505:  513:                nextToken();
    13505:  514:                if (token.value == TOKcomma && 
peekNext() != TOKrparen)
    13505:  515:                    args = parseArguments();    // 
pragma(identifier, args...)
        -:  516:                else
    #####:  517:                    check(TOKrparen);           // 
pragma(identifier)
        -:  518:
    13505:  519:                if (token.value == TOKsemicolon)
    13505:  520:                    a = NULL;
        -:  521:                else
    #####:  522:                    a = parseBlock();
    13505:  523:                s = new PragmaDeclaration(loc, ident, 
args, a);
    13505:  524:                break;
        -:  525:            }
        -:  526:
        -:  527:            case TOKdebug:
    18445:  528:                nextToken();
    18445:  529:                if (token.value == TOKassign)
        -:  530:                {
      128:  531:                    nextToken();
      128:  532:                    if (token.value == TOKidentifier)
       64:  533:                        s = new DebugSymbol(loc, 
token.ident);
       64:  534:                    else if (token.value == TOKint32v)
       64:  535:                        s = new DebugSymbol(loc, 
(unsigned)token.uns64value);
        -:  536:                    else
    #####:  537:                    {   error("identifier or integer 
expected, not %s", token.toChars());
    #####:  538:                        s = NULL;
        -:  539:                    }
      128:  540:                    nextToken();
      128:  541:                    if (token.value != TOKsemicolon)
    #####:  542:                        error("semicolon expected");
      128:  543:                    nextToken();
      128:  544:                    break;
        -:  545:                }
        -:  546:
    18317:  547:                condition = parseDebugCondition();
    18317:  548:                goto Lcondition;
        -:  549:
        -:  550:            case TOKversion:
  1209847:  551:                nextToken();
  1209847:  552:                if (token.value == TOKassign)
        -:  553:                {
    36653:  554:                    nextToken();
    36653:  555:                    if (token.value == TOKidentifier)
    36588:  556:                        s = new VersionSymbol(loc, 
token.ident);
       65:  557:                    else if (token.value == TOKint32v)
       65:  558:                        s = new VersionSymbol(loc, 
(unsigned)token.uns64value);
        -:  559:                    else
    #####:  560:                    {   error("identifier or integer 
expected, not %s", token.toChars());
    #####:  561:                        s = NULL;
        -:  562:                    }
    36653:  563:                    nextToken();
    36653:  564:                    if (token.value != TOKsemicolon)
    #####:  565:                        error("semicolon expected");
    36653:  566:                    nextToken();
    36653:  567:                    break;
        -:  568:                }
  1173194:  569:                condition = parseVersionCondition();
        -:  570:                goto Lcondition;
        -:  571:
  1191511:  572:            Lcondition:
  1191511:  573:                a = parseBlock();
  1191511:  574:                aelse = NULL;
  1191511:  575:                if (token.value == TOKelse)
   530030:  576:                {   nextToken();
   530030:  577:                    aelse = parseBlock();
        -:  578:                }
  1191511:  579:                s = new 
ConditionalDeclaration(condition, a, aelse);
  1191511:  580:                break;
        -:  581:
        -:  582:            case TOKsemicolon:          // empty declaration
        -:  583:                //error("empty declaration");
    33369:  584:                nextToken();
    33369:  585:                continue;
        -:  586:
        -:  587:            default:
    #####:  588:                error("Declaration expected, not 
'%s'",token.toChars());
    #####:  589:            Lerror:
    #####:  590:                while (token.value != TOKsemicolon && 
token.value != TOKeof)
    #####:  591:                    nextToken();
    #####:  592:                nextToken();
    #####:  593:                s = NULL;
    #####:  594:                continue;
        -:  595:        }
 12116004:  596:        if (s)
 11432244:  597:        {   decldefs->push(s);
 11432244:  598:            addComment(s, comment);
        -:  599:        }
        -:  600:    } while (!once);
  5166260:  601:    return decldefs;
        -:  602:}
        -:  603:
        -:  604:/*********************************************
        -:  605: * Give error on conflicting storage classes.
        -:  606: */
        -:  607:
        -:  608:#if DMDV2
 26033501:  609:void Parser::composeStorageClass(StorageClass stc)
        -:  610:{
 26033501:  611:    StorageClass u = stc;
 26033501:  612:    u &= STCconst | STCimmutable | STCmanifest;
 26033501:  613:    if (u & (u - 1))
    #####:  614:        error("conflicting storage class %s", 
Token::toChars(token.value));
 26033501:  615:    u = stc;
 26033501:  616:    u &= STCgshared | STCshared | STCtls;
 26033501:  617:    if (u & (u - 1))
    #####:  618:        error("conflicting storage class %s", 
Token::toChars(token.value));
 26033501:  619:    u = stc;
 26033501:  620:    u &= STCsafe | STCsystem | STCtrusted;
 26033501:  621:    if (u & (u - 1))
    #####:  622:        error("conflicting attribute @%s", token.toChars());
 26033501:  623:}
        -:  624:#endif
        -:  625:
        -:  626:/***********************************************
        -:  627: * Parse storage class, lexer is on '@'
        -:  628: */
        -:  629:
        -:  630:#if DMDV2
   913308:  631:StorageClass Parser::parseAttribute()
        -:  632:{
   913308:  633:    nextToken();
   913308:  634:    StorageClass stc = 0;
   913308:  635:    if (token.value != TOKidentifier)
        -:  636:    {
    #####:  637:        error("identifier expected after @, not %s", 
token.toChars());
        -:  638:    }
   913308:  639:    else if (token.ident == Id::property)
   815059:  640:        stc = STCproperty;
    98249:  641:    else if (token.ident == Id::safe)
    51527:  642:        stc = STCsafe;
    46722:  643:    else if (token.ident == Id::trusted)
    24248:  644:        stc = STCtrusted;
    22474:  645:    else if (token.ident == Id::system)
    19315:  646:        stc = STCsystem;
     3159:  647:    else if (token.ident == Id::disable)
     3159:  648:        stc = STCdisable;
        -:  649:    else
    #####:  650:        error("valid attribute identifiers are 
@property, @safe, @trusted, @system, @disable not @%s", token.toChars());
   913308:  651:    return stc;
        -:  652:}
        -:  653:#endif
        -:  654:
        -:  655:/***********************************************
        -:  656: * Parse const/immutable/shared/inout/nothrow/pure postfix
        -:  657: */
        -:  658:
 12354068:  659:StorageClass Parser::parsePostfix()
        -:  660:{
 12354068:  661:    StorageClass stc = 0;
        -:  662:
   410306:  663:    while (1)
        -:  664:    {
 12764374:  665:        switch (token.value)
        -:  666:        {
   181510:  667:            case TOKconst:              stc |= 
STCconst;                break;
        -:  668:            case TOKinvariant:
    #####:  669:                if (!global.params.useDeprecated)
    #####:  670:                    error("use of 'invariant' rather 
than 'immutable' is deprecated");
     3479:  671:            case TOKimmutable:          stc |= 
STCimmutable;            break;
    15347:  672:            case TOKshared:             stc |= 
STCshared;               break;
    #####:  673:            case TOKwild:               stc |= 
STCwild;                 break;
    30502:  674:            case TOKnothrow:            stc |= 
STCnothrow;              break;
    33661:  675:            case TOKpure:               stc |= 
STCpure;                 break;
   145807:  676:            case TOKat:                 stc |= 
parseAttribute();        break;
        -:  677:
        -:  678:            default:
 12354068:  679:                composeStorageClass(stc);
 12354068:  680:                return stc;
        -:  681:        }
   410306:  682:        nextToken();
        -:  683:    }
        -:  684:}
        -:  685:
        -:  686:/********************************************
        -:  687: * Parse declarations after an align, protection, or 
extern decl.
        -:  688: */
        -:  689:
  7794489:  690:Dsymbols *Parser::parseBlock()
        -:  691:{
  7794489:  692:    Dsymbols *a = NULL;
        -:  693:    Dsymbol *s;
        -:  694:
        -:  695:    //printf("parseBlock()\n");
  7794489:  696:    switch (token.value)
        -:  697:    {
        -:  698:        case TOKsemicolon:
    #####:  699:            error("declaration expected following 
attribute, not ';'");
    #####:  700:            nextToken();
    #####:  701:            break;
        -:  702:
        -:  703:        case TOKeof:
    #####:  704:            error("declaration expected following 
attribute, not EOF");
    #####:  705:            break;
        -:  706:
        -:  707:        case TOKlcurly:
  2406369:  708:            nextToken();
  2406369:  709:            a = parseDeclDefs(0);
  2406369:  710:            if (token.value != TOKrcurly)
        -:  711:            {   /* { */
    #####:  712:                error("matching '}' expected, not %s", 
token.toChars());
        -:  713:            }
        -:  714:            else
  2406369:  715:                nextToken();
  2406369:  716:            break;
        -:  717:
        -:  718:        case TOKcolon:
   221860:  719:            nextToken();
        -:  720:#if 0
        -:  721:            a = NULL;
        -:  722:#else
   221860:  723:            a = parseDeclDefs(0);       // grab 
declarations up to closing curly bracket
        -:  724:#endif
   221860:  725:            break;
        -:  726:
        -:  727:        default:
  5166260:  728:            a = parseDeclDefs(1);
        -:  729:            break;
        -:  730:    }
  7794489:  731:    return a;
        -:  732:}
        -:  733:
        -:  734:/**********************************
        -:  735: * Parse a static assertion.
        -:  736: */
        -:  737:
  2026561:  738:StaticAssert *Parser::parseStaticAssert()
        -:  739:{
  2026561:  740:    Loc loc = this->loc;
        -:  741:    Expression *exp;
  2026561:  742:    Expression *msg = NULL;
        -:  743:
        -:  744:    //printf("parseStaticAssert()\n");
  2026561:  745:    nextToken();
  2026561:  746:    check(TOKlparen);
  2026561:  747:    exp = parseAssignExp();
  2026561:  748:    if (token.value == TOKcomma)
   127522:  749:    {   nextToken();
   127522:  750:        msg = parseAssignExp();
        -:  751:    }
  2026561:  752:    check(TOKrparen);
  2026561:  753:    check(TOKsemicolon);
  2026561:  754:    return new StaticAssert(loc, exp, msg);
        -:  755:}
        -:  756:
        -:  757:/***********************************
        -:  758: * Parse typeof(expression).
        -:  759: * Current token is on the 'typeof'.
        -:  760: */
        -:  761:
        -:  762:#if DMDV2
  1298443:  763:TypeQualified *Parser::parseTypeof()
        -:  764:{   TypeQualified *t;
  1298443:  765:    Loc loc = this->loc;
        -:  766:
  1298443:  767:    nextToken();
  1298443:  768:    check(TOKlparen);
  1298443:  769:    if (token.value == TOKreturn)       // typeof(return)
        -:  770:    {
   155421:  771:        nextToken();
   155421:  772:        t = new TypeReturn(loc);
        -:  773:    }
        -:  774:    else
  1143022:  775:    {   Expression *exp = parseExpression();    // 
typeof(expression)
  1143022:  776:        t = new TypeTypeof(loc, exp);
        -:  777:    }
  1298443:  778:    check(TOKrparen);
  1298443:  779:    return t;
        -:  780:}
        -:  781:#endif
        -:  782:
        -:  783:/***********************************
        -:  784: * Parse extern (linkage)
        -:  785: * The parser is on the 'extern' token.
        -:  786: */
        -:  787:
   611817:  788:enum LINK Parser::parseLinkage()
        -:  789:{
   611817:  790:    enum LINK link = LINKdefault;
   611817:  791:    nextToken();
   611817:  792:    assert(token.value == TOKlparen);
   611817:  793:    nextToken();
   611817:  794:    if (token.value == TOKidentifier)
   611817:  795:    {   Identifier *id = token.ident;
        -:  796:
   611817:  797:        nextToken();
   611817:  798:        if (id == Id::Windows)
     8205:  799:            link = LINKwindows;
   603612:  800:        else if (id == Id::Pascal)
       68:  801:            link = LINKpascal;
   603544:  802:        else if (id == Id::D)
   245067:  803:            link = LINKd;
   358477:  804:        else if (id == Id::C)
        -:  805:        {
   358413:  806:            link = LINKc;
   358413:  807:            if (token.value == TOKplusplus)
      141:  808:            {   link = LINKcpp;
      141:  809:                nextToken();
        -:  810:            }
        -:  811:        }
       64:  812:        else if (id == Id::System)
        -:  813:        {
        -:  814:#if _WIN32
        -:  815:            link = LINKwindows;
        -:  816:#else
       64:  817:            link = LINKc;
        -:  818:#endif
        -:  819:        }
        -:  820:        else
        -:  821:        {
    #####:  822:            error("valid linkage identifiers are D, C, 
C++, Pascal, Windows, System");
    #####:  823:            link = LINKd;
        -:  824:        }
        -:  825:    }
        -:  826:    else
        -:  827:    {
    #####:  828:        link = LINKd;           // default
        -:  829:    }
   611817:  830:    check(TOKrparen);
   611817:  831:    return link;
        -:  832:}
        -:  833:
        -:  834:/**************************************
        -:  835: * Parse a debug conditional
        -:  836: */
        -:  837:
   956249:  838:Condition *Parser::parseDebugCondition()
        -:  839:{
        -:  840:    Condition *c;
        -:  841:
   956249:  842:    if (token.value == TOKlparen)
        -:  843:    {
   931340:  844:        nextToken();
   931340:  845:        unsigned level = 1;
   931340:  846:        Identifier *id = NULL;
        -:  847:
   931340:  848:        if (token.value == TOKidentifier)
   930804:  849:            id = token.ident;
      536:  850:        else if (token.value == TOKint32v)
      536:  851:            level = (unsigned)token.uns64value;
        -:  852:        else
    #####:  853:            error("identifier or integer expected, not 
%s", token.toChars());
   931340:  854:        nextToken();
   931340:  855:        check(TOKrparen);
   931340:  856:        c = new DebugCondition(mod, level, id);
        -:  857:    }
        -:  858:    else
    24909:  859:        c = new DebugCondition(mod, 1, NULL);
   956249:  860:    return c;
        -:  861:
        -:  862:}
        -:  863:
        -:  864:/**************************************
        -:  865: * Parse a version conditional
        -:  866: */
        -:  867:
  1565873:  868:Condition *Parser::parseVersionCondition()
        -:  869:{
        -:  870:    Condition *c;
  1565873:  871:    unsigned level = 1;
  1565873:  872:    Identifier *id = NULL;
        -:  873:
  1565873:  874:    if (token.value == TOKlparen)
        -:  875:    {
  1565873:  876:        nextToken();
  1565873:  877:        if (token.value == TOKidentifier)
  1521692:  878:            id = token.ident;
    44181:  879:        else if (token.value == TOKint32v)
      130:  880:            level = (unsigned)token.uns64value;
        -:  881:#if DMDV2
        -:  882:        /* Allow:
        -:  883:         *    version (unittest)
        -:  884:         * even though unittest is a keyword
        -:  885:         */
    44051:  886:        else if (token.value == TOKunittest)
    44051:  887:            id = Lexer::idPool(Token::toChars(TOKunittest));
        -:  888:#endif
        -:  889:        else
    #####:  890:            error("identifier or integer expected, not 
%s", token.toChars());
  1565873:  891:        nextToken();
  1565873:  892:        check(TOKrparen);
        -:  893:
        -:  894:    }
        -:  895:    else
    #####:  896:       error("(condition) expected following version");
  1565873:  897:    c = new VersionCondition(mod, level, id);
  1565873:  898:    return c;
        -:  899:
        -:  900:}
        -:  901:
        -:  902:/***********************************************
        -:  903: *      static if (expression)
        -:  904: *          body
        -:  905: *      else
        -:  906: *          body
        -:  907: */
        -:  908:
  1841244:  909:Condition *Parser::parseStaticIfCondition()
        -:  910:{   Expression *exp;
        -:  911:    Condition *condition;
        -:  912:    Array *aif;
        -:  913:    Array *aelse;
  1841244:  914:    Loc loc = this->loc;
        -:  915:
  1841244:  916:    nextToken();
  1841244:  917:    if (token.value == TOKlparen)
        -:  918:    {
  1841244:  919:        nextToken();
  1841244:  920:        exp = parseAssignExp();
  1841244:  921:        check(TOKrparen);
        -:  922:    }
        -:  923:    else
    #####:  924:    {   error("(expression) expected following static if");
    #####:  925:        exp = NULL;
        -:  926:    }
  1841244:  927:    condition = new StaticIfCondition(loc, exp);
  1841244:  928:    return condition;
        -:  929:}
        -:  930:
        -:  931:
        -:  932:/*****************************************
        -:  933: * Parse a constructor definition:
        -:  934: *      this(parameters) { body }
        -:  935: * or postblit:
        -:  936: *      this(this) { body }
        -:  937: * or constructor template:
        -:  938: *      this(templateparameters)(parameters) { body }
        -:  939: * Current token is 'this'.
        -:  940: */
        -:  941:
   444134:  942:Dsymbol *Parser::parseCtor()
        -:  943:{
   444134:  944:    Loc loc = this->loc;
        -:  945:
   444134:  946:    nextToken();
   444134:  947:    if (token.value == TOKlparen && peek(&token)->value 
== TOKthis)
        -:  948:    {   // this(this) { ... }
    31546:  949:        nextToken();
    31546:  950:        nextToken();
    31546:  951:        check(TOKrparen);
    31546:  952:        PostBlitDeclaration *f = new 
PostBlitDeclaration(loc, 0);
    31546:  953:        parseContracts(f);
    31546:  954:        return f;
        -:  955:    }
        -:  956:
        -:  957:    /* Look ahead to see if:
        -:  958:     *   this(...)(...)
        -:  959:     * which is a constructor template
        -:  960:     */
   412588:  961:    TemplateParameters *tpl = NULL;
   412588:  962:    if (token.value == TOKlparen && 
peekPastParen(&token)->value == TOKlparen)
    29023:  963:    {   tpl = parseTemplateParameterList();
        -:  964:
        -:  965:        int varargs;
    29023:  966:        Parameters *parameters = parseParameters(&varargs);
    29023:  967:        StorageClass stc = parsePostfix();
        -:  968:
    29023:  969:        Expression *constraint = tpl ? parseConstraint() 
: NULL;
        -:  970:
    29023:  971:        CtorDeclaration *f = new CtorDeclaration(loc, 0, 
parameters, varargs, stc);
    29023:  972:        parseContracts(f);
        -:  973:
        -:  974:        // Wrap a template around it
    29023:  975:        Dsymbols *decldefs = new Dsymbols();
    29023:  976:        decldefs->push(f);
        -:  977:        TemplateDeclaration *tempdecl =
    29023:  978:            new TemplateDeclaration(loc, f->ident, tpl, 
constraint, decldefs, 0);
    29023:  979:        return tempdecl;
        -:  980:    }
        -:  981:
        -:  982:    /* Just a regular constructor
        -:  983:     */
        -:  984:    int varargs;
   383565:  985:    Parameters *parameters = parseParameters(&varargs);
   383565:  986:    StorageClass stc = parsePostfix();
   383565:  987:    CtorDeclaration *f = new CtorDeclaration(loc, 0, 
parameters, varargs, stc);
   383565:  988:    parseContracts(f);
   383565:  989:    return f;
        -:  990:}
        -:  991:
        -:  992:/*****************************************
        -:  993: * Parse a postblit definition:
        -:  994: *      =this() { body }
        -:  995: * Current token is '='.
        -:  996: */
        -:  997:
    #####:  998:PostBlitDeclaration *Parser::parsePostBlit()
        -:  999:{
    #####: 1000:    Loc loc = this->loc;
        -: 1001:
    #####: 1002:    nextToken();
    #####: 1003:    check(TOKthis);
    #####: 1004:    check(TOKlparen);
    #####: 1005:    check(TOKrparen);
        -: 1006:
    #####: 1007:    PostBlitDeclaration *f = new 
PostBlitDeclaration(loc, 0);
    #####: 1008:    parseContracts(f);
    #####: 1009:    return f;
        -: 1010:}
        -: 1011:
        -: 1012:/*****************************************
        -: 1013: * Parse a destructor definition:
        -: 1014: *      ~this() { body }
        -: 1015: * Current token is '~'.
        -: 1016: */
        -: 1017:
    40559: 1018:DtorDeclaration *Parser::parseDtor()
        -: 1019:{
        -: 1020:    DtorDeclaration *f;
    40559: 1021:    Loc loc = this->loc;
        -: 1022:
    40559: 1023:    nextToken();
    40559: 1024:    check(TOKthis);
    40559: 1025:    check(TOKlparen);
    40559: 1026:    check(TOKrparen);
        -: 1027:
    40559: 1028:    f = new DtorDeclaration(loc, 0);
    40559: 1029:    parseContracts(f);
    40559: 1030:    return f;
        -: 1031:}
        -: 1032:
        -: 1033:/*****************************************
        -: 1034: * Parse a static constructor definition:
        -: 1035: *      static this() { body }
        -: 1036: * Current token is 'this'.
        -: 1037: */
        -: 1038:
     4476: 1039:StaticCtorDeclaration *Parser::parseStaticCtor()
        -: 1040:{
     4476: 1041:    Loc loc = this->loc;
        -: 1042:
     4476: 1043:    nextToken();
     4476: 1044:    check(TOKlparen);
     4476: 1045:    check(TOKrparen);
        -: 1046:
     4476: 1047:    StaticCtorDeclaration *f = new 
StaticCtorDeclaration(loc, 0);
     4476: 1048:    parseContracts(f);
     4476: 1049:    return f;
        -: 1050:}
        -: 1051:
        -: 1052:/*****************************************
        -: 1053: * Parse a shared static constructor definition:
        -: 1054: *      shared static this() { body }
        -: 1055: * Current token is 'shared'.
        -: 1056: */
        -: 1057:
    27622: 1058:SharedStaticCtorDeclaration *Parser::parseSharedStaticCtor()
        -: 1059:{
    27622: 1060:    Loc loc = this->loc;
        -: 1061:
    27622: 1062:    nextToken();
    27622: 1063:    nextToken();
    27622: 1064:    nextToken();
    27622: 1065:    check(TOKlparen);
    27622: 1066:    check(TOKrparen);
        -: 1067:
    27622: 1068:    SharedStaticCtorDeclaration *f = new 
SharedStaticCtorDeclaration(loc, 0);
    27622: 1069:    parseContracts(f);
    27622: 1070:    return f;
        -: 1071:}
        -: 1072:
        -: 1073:/*****************************************
        -: 1074: * Parse a static destructor definition:
        -: 1075: *      static ~this() { body }
        -: 1076: * Current token is '~'.
        -: 1077: */
        -: 1078:
      398: 1079:StaticDtorDeclaration *Parser::parseStaticDtor()
        -: 1080:{
      398: 1081:    Loc loc = this->loc;
        -: 1082:
      398: 1083:    nextToken();
      398: 1084:    check(TOKthis);
      398: 1085:    check(TOKlparen);
      398: 1086:    check(TOKrparen);
        -: 1087:
      398: 1088:    StaticDtorDeclaration *f = new 
StaticDtorDeclaration(loc, 0);
      398: 1089:    parseContracts(f);
      398: 1090:    return f;
        -: 1091:}
        -: 1092:
        -: 1093:/*****************************************
        -: 1094: * Parse a shared static destructor definition:
        -: 1095: *      shared static ~this() { body }
        -: 1096: * Current token is 'shared'.
        -: 1097: */
        -: 1098:
    #####: 1099:SharedStaticDtorDeclaration *Parser::parseSharedStaticDtor()
        -: 1100:{
    #####: 1101:    Loc loc = this->loc;
        -: 1102:
    #####: 1103:    nextToken();
    #####: 1104:    nextToken();
    #####: 1105:    nextToken();
    #####: 1106:    check(TOKthis);
    #####: 1107:    check(TOKlparen);
    #####: 1108:    check(TOKrparen);
        -: 1109:
    #####: 1110:    SharedStaticDtorDeclaration *f = new 
SharedStaticDtorDeclaration(loc, 0);
    #####: 1111:    parseContracts(f);
    #####: 1112:    return f;
        -: 1113:}
        -: 1114:
        -: 1115:/*****************************************
        -: 1116: * Parse an invariant definition:
        -: 1117: *      invariant() { body }
        -: 1118: * Current token is 'invariant'.
        -: 1119: */
        -: 1120:
     4128: 1121:InvariantDeclaration *Parser::parseInvariant()
        -: 1122:{
        -: 1123:    InvariantDeclaration *f;
     4128: 1124:    Loc loc = this->loc;
        -: 1125:
     4128: 1126:    nextToken();
     4128: 1127:    if (token.value == TOKlparen)       // optional ()
        -: 1128:    {
     4128: 1129:        nextToken();
     4128: 1130:        check(TOKrparen);
        -: 1131:    }
        -: 1132:
     4128: 1133:    f = new InvariantDeclaration(loc, 0);
     4128: 1134:    f->fbody = parseStatement(PScurly);
     4128: 1135:    return f;
        -: 1136:}
        -: 1137:
        -: 1138:/*****************************************
        -: 1139: * Parse a unittest definition:
        -: 1140: *      unittest { body }
        -: 1141: * Current token is 'unittest'.
        -: 1142: */
        -: 1143:
  1854795: 1144:UnitTestDeclaration *Parser::parseUnitTest()
        -: 1145:{
        -: 1146:    UnitTestDeclaration *f;
        -: 1147:    Statement *body;
  1854795: 1148:    Loc loc = this->loc;
        -: 1149:
  1854795: 1150:    nextToken();
        -: 1151:
  1854795: 1152:    body = parseStatement(PScurly);
        -: 1153:
  1854795: 1154:    f = new UnitTestDeclaration(loc, this->loc);
  1854795: 1155:    f->fbody = body;
  1854795: 1156:    return f;
        -: 1157:}
        -: 1158:
        -: 1159:/*****************************************
        -: 1160: * Parse a new definition:
        -: 1161: *      new(arguments) { body }
        -: 1162: * Current token is 'new'.
        -: 1163: */
        -: 1164:
      195: 1165:NewDeclaration *Parser::parseNew()
        -: 1166:{
        -: 1167:    NewDeclaration *f;
        -: 1168:    Parameters *arguments;
        -: 1169:    int varargs;
      195: 1170:    Loc loc = this->loc;
        -: 1171:
      195: 1172:    nextToken();
      195: 1173:    arguments = parseParameters(&varargs);
      195: 1174:    f = new NewDeclaration(loc, 0, arguments, varargs);
      195: 1175:    parseContracts(f);
      195: 1176:    return f;
        -: 1177:}
        -: 1178:
        -: 1179:/*****************************************
        -: 1180: * Parse a delete definition:
        -: 1181: *      delete(arguments) { body }
        -: 1182: * Current token is 'delete'.
        -: 1183: */
        -: 1184:
      194: 1185:DeleteDeclaration *Parser::parseDelete()
        -: 1186:{
        -: 1187:    DeleteDeclaration *f;
        -: 1188:    Parameters *arguments;
        -: 1189:    int varargs;
      194: 1190:    Loc loc = this->loc;
        -: 1191:
      194: 1192:    nextToken();
      194: 1193:    arguments = parseParameters(&varargs);
      194: 1194:    if (varargs)
    #####: 1195:        error("... not allowed in delete function 
parameter list");
      194: 1196:    f = new DeleteDeclaration(loc, 0, arguments);
      194: 1197:    parseContracts(f);
      194: 1198:    return f;
        -: 1199:}
        -: 1200:
        -: 1201:/**********************************************
        -: 1202: * Parse parameter list.
        -: 1203: */
        -: 1204:
 12354457: 1205:Parameters *Parser::parseParameters(int *pvarargs)
        -: 1206:{
 12354457: 1207:    Parameters *arguments = new Parameters();
 12354457: 1208:    int varargs = 0;
 12354457: 1209:    int hasdefault = 0;
        -: 1210:
 12354457: 1211:    check(TOKlparen);
  5732638: 1212:    while (1)
        -: 1213:    {   Type *tb;
 18087095: 1214:        Identifier *ai = NULL;
        -: 1215:        Type *at;
        -: 1216:        Parameter *a;
 18087095: 1217:        StorageClass storageClass = 0;
        -: 1218:        StorageClass stc;
        -: 1219:        Expression *ae;
        -: 1220:
  3023408: 1221:        for (;1; nextToken())
        -: 1222:        {
 21110503: 1223:            switch (token.value)
        -: 1224:            {
        -: 1225:                case TOKrparen:
  2945501: 1226:                    break;
        -: 1227:
        -: 1228:                case TOKdotdotdot:
   183136: 1229:                    varargs = 1;
   183136: 1230:                    nextToken();
   183136: 1231:                    break;
        -: 1232:
        -: 1233:                case TOKconst:
   225396: 1234:                    if (peek(&token)->value == TOKlparen)
   164121: 1235:                        goto Ldefault;
    61275: 1236:                    stc = STCconst;
    61275: 1237:                    goto L2;
        -: 1238:
        -: 1239:                case TOKinvariant:
        -: 1240:                case TOKimmutable:
    27776: 1241:                    if (peek(&token)->value == TOKlparen)
    27631: 1242:                        goto Ldefault;
      145: 1243:                    stc = STCimmutable;
      145: 1244:                    goto L2;
        -: 1245:
        -: 1246:                case TOKshared:
    10832: 1247:                    if (peek(&token)->value == TOKlparen)
    #####: 1248:                        goto Ldefault;
    10832: 1249:                    stc = STCshared;
    10832: 1250:                    goto L2;
        -: 1251:
        -: 1252:                case TOKwild:
      192: 1253:                    if (peek(&token)->value == TOKlparen)
       64: 1254:                        goto Ldefault;
      128: 1255:                    stc = STCwild;
      128: 1256:                    goto L2;
        -: 1257:
  2151073: 1258:                case TOKin:        stc = STCin;         
goto L2;
    76851: 1259:                case TOKout:       stc = STCout;        
goto L2;
        -: 1260:#if D1INOUT
        -: 1261:                case TOKinout:
        -: 1262:#endif
   590268: 1263:                case TOKref:       stc = STCref;        
goto L2;
    42865: 1264:                case TOKlazy:      stc = STClazy;       
goto L2;
    83833: 1265:                case TOKscope:     stc = STCscope;      
goto L2;
    #####: 1266:                case TOKfinal:     stc = STCfinal;      
goto L2;
     6138: 1267:                case TOKauto:      stc = STCauto;       
goto L2;
  3023408: 1268:                L2:
  3023408: 1269:                    if (storageClass & stc ||
        -: 1270:                        (storageClass & STCin && stc & 
(STCconst | STCscope)) ||
        -: 1271:                        (stc & STCin && storageClass & 
(STCconst | STCscope))
        -: 1272:                       )
    #####: 1273:                        error("redundant storage class 
%s", Token::toChars(token.value));
  3023408: 1274:                    storageClass |= stc;
  3023408: 1275:                    composeStorageClass(storageClass);
        -: 1276:                    continue;
        -: 1277:
        -: 1278:#if 0
        -: 1279:                case TOKstatic:    stc = 
STCstatic;             goto L2;
        -: 1280:                case TOKauto:   storageClass = 
STCauto;         goto L4;
        -: 1281:                case TOKalias:  storageClass = 
STCalias;        goto L4;
        -: 1282:                L4:
        -: 1283:                    nextToken();
        -: 1284:                    if (token.value == TOKidentifier)
        -: 1285:                    {   ai = token.ident;
        -: 1286:                        nextToken();
        -: 1287:                    }
        -: 1288:                    else
        -: 1289:                        ai = NULL;
        -: 1290:                    at = NULL;          // no type
        -: 1291:                    ae = NULL;          // no default 
argument
        -: 1292:                    if (token.value == TOKassign)       
// = defaultArg
        -: 1293:                    {   nextToken();
        -: 1294:                        ae = parseDefaultInitExp();
        -: 1295:                        hasdefault = 1;
        -: 1296:                    }
        -: 1297:                    else
        -: 1298:                    {   if (hasdefault)
        -: 1299:                            error("default argument 
expected for alias %s",
        -: 1300:                                    ai ? ai->toChars() : 
"");
        -: 1301:                    }
        -: 1302:                    goto L3;
        -: 1303:#endif
        -: 1304:
        -: 1305:                default:
 14958458: 1306:                Ldefault:
 14958458: 1307:                    stc = storageClass & (STCin | STCout 
| STCref | STClazy);
 14958458: 1308:                    if (stc & (stc - 1))        // if 
stc is not a power of 2
    #####: 1309:                        error("incompatible parameter 
storage classes");
 14958458: 1310:                    if ((storageClass & (STCconst | 
STCout)) == (STCconst | STCout))
    #####: 1311:                        error("out cannot be const");
 14958458: 1312:                    if ((storageClass & (STCimmutable | 
STCout)) == (STCimmutable | STCout))
    #####: 1313:                        error("out cannot be immutable");
 14958458: 1314:                    if ((storageClass & STCscope) &&
        -: 1315:                        (storageClass & (STCref | STCout)))
    #####: 1316:                        error("scope cannot be ref or out");
 14958458: 1317:                    at = parseType(&ai);
 14958458: 1318:                    ae = NULL;
 14958458: 1319:                    if (token.value == TOKassign)       
// = defaultArg
   386478: 1320:                    {   nextToken();
   386478: 1321:                        ae = parseDefaultInitExp();
   386478: 1322:                        hasdefault = 1;
        -: 1323:                    }
        -: 1324:                    else
 14571980: 1325:                    {   if (hasdefault)
        -: 1326:                            error("default argument 
expected for %s",
    #####: 1327:                                    ai ? ai->toChars() : 
at->toChars());
        -: 1328:                    }
 14958458: 1329:                    if (token.value == TOKdotdotdot)
        -: 1330:                    {   /* This is:
        -: 1331:                         *      at ai ...
        -: 1332:                         */
        -: 1333:
    20714: 1334:                        if (storageClass & (STCout | 
STCref))
    #####: 1335:                            error("variadic argument 
cannot be out or ref");
    20714: 1336:                        varargs = 2;
    20714: 1337:                        a = new Parameter(storageClass, 
at, ai, ae);
    20714: 1338:                        arguments->push(a);
    20714: 1339:                        nextToken();
    20714: 1340:                        break;
        -: 1341:                    }
 14937744: 1342:                L3:
 14937744: 1343:                    a = new Parameter(storageClass, at, 
ai, ae);
 14937744: 1344:                    arguments->push(a);
 14937744: 1345:                    if (token.value == TOKcomma)
  5732638: 1346:                    {   nextToken();
  5732638: 1347:                        goto L1;
        -: 1348:                    }
        -: 1349:                    break;
        -: 1350:            }
        -: 1351:            break;
        -: 1352:        }
        -: 1353:        break;
        -: 1354:
  5732638: 1355:    L1: ;
        -: 1356:    }
 12354457: 1357:    check(TOKrparen);
 12354457: 1358:    *pvarargs = varargs;
 12354457: 1359:    return arguments;
        -: 1360:}
        -: 1361:
        -: 1362:
        -: 1363:/*************************************
        -: 1364: */
        -: 1365:
   371780: 1366:EnumDeclaration *Parser::parseEnum()
        -: 1367:{   EnumDeclaration *e;
        -: 1368:    Identifier *id;
        -: 1369:    Type *memtype;
   371780: 1370:    Loc loc = this->loc;
        -: 1371:
        -: 1372:    //printf("Parser::parseEnum()\n");
   371780: 1373:    nextToken();
   371780: 1374:    if (token.value == TOKidentifier)
   133216: 1375:    {   id = token.ident;
   133216: 1376:        nextToken();
        -: 1377:    }
        -: 1378:    else
   238564: 1379:        id = NULL;
        -: 1380:
   371780: 1381:    if (token.value == TOKcolon)
        -: 1382:    {
    64329: 1383:        nextToken();
    64329: 1384:        memtype = parseBasicType();
    64329: 1385:        memtype = parseDeclarator(memtype, NULL, NULL);
        -: 1386:    }
        -: 1387:    else
   307451: 1388:        memtype = NULL;
        -: 1389:
   371780: 1390:    e = new EnumDeclaration(loc, id, memtype);
   371844: 1391:    if (token.value == TOKsemicolon && id)
       64: 1392:        nextToken();
   371716: 1393:    else if (token.value == TOKlcurly)
        -: 1394:    {
        -: 1395:        //printf("enum definition\n");
   371716: 1396:        e->members = new Dsymbols();
   371716: 1397:        nextToken();
   371716: 1398:        unsigned char *comment = token.blockComment;
  3340072: 1399:        while (token.value != TOKrcurly)
        -: 1400:        {
        -: 1401:            /* Can take the following forms:
        -: 1402:             *  1. ident
        -: 1403:             *  2. ident = value
        -: 1404:             *  3. type ident = value
        -: 1405:             */
        -: 1406:
  2596640: 1407:            loc = this->loc;
        -: 1408:
  2596640: 1409:            Type *type = NULL;
        -: 1410:            Identifier *ident;
  2596640: 1411:            Token *tp = peek(&token);
  5193215: 1412:            if (token.value == TOKidentifier &&
        -: 1413:                (tp->value == TOKassign || tp->value == 
TOKcomma || tp->value == TOKrcurly))
        -: 1414:            {
  2596575: 1415:                ident = token.ident;
  2596575: 1416:                type = NULL;
  2596575: 1417:                nextToken();
        -: 1418:            }
        -: 1419:            else
        -: 1420:            {
       65: 1421:                type = parseType(&ident, NULL);
       65: 1422:                if (id || memtype)
    #####: 1423:                    error("type only allowed if 
anonymous enum and no enum type");
        -: 1424:            }
        -: 1425:
        -: 1426:            Expression *value;
  2596640: 1427:            if (token.value == TOKassign)
        -: 1428:            {
  1008784: 1429:                nextToken();
  1008784: 1430:                value = parseAssignExp();
        -: 1431:            }
        -: 1432:            else
  1587856: 1433:            {   value = NULL;
  1587856: 1434:                if (type)
    #####: 1435:                    error("if type, there must be an 
initializer");
        -: 1436:            }
        -: 1437:
  2596640: 1438:            EnumMember *em = new EnumMember(loc, ident, 
value, type);
  2596640: 1439:            e->members->push(em);
        -: 1440:
  2596640: 1441:            if (token.value == TOKrcurly)
        -: 1442:                ;
        -: 1443:            else
  2494723: 1444:            {   addComment(em, comment);
  2494723: 1445:                comment = NULL;
  2494723: 1446:                check(TOKcomma);
        -: 1447:            }
  2596640: 1448:            addComment(em, comment);
  2596640: 1449:            comment = token.blockComment;
        -: 1450:        }
   371716: 1451:        nextToken();
        -: 1452:    }
        -: 1453:    else
    #####: 1454:        error("enum declaration is invalid");
        -: 1455:
        -: 1456:    //printf("-parseEnum() %s\n", e->toChars());
   371780: 1457:    return e;
        -: 1458:}
        -: 1459:
        -: 1460:/********************************
        -: 1461: * Parse struct, union, interface, class.
        -: 1462: */
        -: 1463:
  1640958: 1464:Dsymbol *Parser::parseAggregate()
  1640958: 1465:{   AggregateDeclaration *a = NULL;
  1640958: 1466:    int anon = 0;
        -: 1467:    enum TOK tok;
        -: 1468:    Identifier *id;
  1640958: 1469:    TemplateParameters *tpl = NULL;
  1640958: 1470:    Expression *constraint = NULL;
        -: 1471:
        -: 1472:    //printf("Parser::parseAggregate()\n");
  1640958: 1473:    tok = token.value;
  1640958: 1474:    nextToken();
  1640958: 1475:    if (token.value != TOKidentifier)
    43250: 1476:    {   id = NULL;
        -: 1477:    }
        -: 1478:    else
  1597708: 1479:    {   id = token.ident;
  1597708: 1480:        nextToken();
        -: 1481:
  1597708: 1482:        if (token.value == TOKlparen)
        -: 1483:        {   // Class template declaration.
        -: 1484:
        -: 1485:            // Gather template parameter list
   201961: 1486:            tpl = parseTemplateParameterList();
   201961: 1487:            constraint = parseConstraint();
        -: 1488:        }
        -: 1489:    }
        -: 1490:
  1640958: 1491:    Loc loc = this->loc;
  1640958: 1492:    switch (tok)
        -: 1493:    {   case TOKclass:
        -: 1494:        case TOKinterface:
        -: 1495:        {
   599577: 1496:            if (!id)
    #####: 1497:                error("anonymous classes not allowed");
        -: 1498:
        -: 1499:            // Collect base class(es)
   599577: 1500:            BaseClasses *baseclasses = NULL;
   599577: 1501:            if (token.value == TOKcolon)
        -: 1502:            {
   320476: 1503:                nextToken();
   320476: 1504:                baseclasses = parseBaseClasses();
        -: 1505:
   320476: 1506:                if (token.value != TOKlcurly)
    #####: 1507:                    error("members expected");
        -: 1508:            }
        -: 1509:
   599577: 1510:            if (tok == TOKclass)
   390952: 1511:                a = new ClassDeclaration(loc, id, 
baseclasses);
        -: 1512:            else
   208625: 1513:                a = new InterfaceDeclaration(loc, id, 
baseclasses);
   599577: 1514:            break;
        -: 1515:        }
        -: 1516:
        -: 1517:        case TOKstruct:
   959784: 1518:            if (id)
   953658: 1519:                a = new StructDeclaration(loc, id);
        -: 1520:            else
     6126: 1521:                anon = 1;
   959784: 1522:            break;
        -: 1523:
        -: 1524:        case TOKunion:
    81597: 1525:            if (id)
    44473: 1526:                a = new UnionDeclaration(loc, id);
        -: 1527:            else
    37124: 1528:                anon = 2;
    81597: 1529:            break;
        -: 1530:
        -: 1531:        default:
    #####: 1532:            assert(0);
        -: 1533:            break;
        -: 1534:    }
  1641087: 1535:    if (a && token.value == TOKsemicolon)
      129: 1536:    {   nextToken();
        -: 1537:    }
  1640829: 1538:    else if (token.value == TOKlcurly)
        -: 1539:    {
        -: 1540:        //printf("aggregate definition\n");
  1640829: 1541:        nextToken();
  1640829: 1542:        Dsymbols *decl = parseDeclDefs(0);
  1640829: 1543:        if (token.value != TOKrcurly)
    #####: 1544:            error("} expected following member 
declarations in aggregate");
  1640829: 1545:        nextToken();
  1640829: 1546:        if (anon)
        -: 1547:        {
        -: 1548:            /* Anonymous structs/unions are more like 
attributes.
        -: 1549:             */
    43250: 1550:            return new AnonDeclaration(loc, anon - 1, decl);
        -: 1551:        }
        -: 1552:        else
  1597579: 1553:            a->members = decl;
        -: 1554:    }
        -: 1555:    else
        -: 1556:    {
    #####: 1557:        error("{ } expected following aggregate 
declaration");
    #####: 1558:        a = new StructDeclaration(loc, NULL);
        -: 1559:    }
        -: 1560:
  1597708: 1561:    if (tpl)
        -: 1562:    {   // Wrap a template around the aggregate declaration
        -: 1563:
   201961: 1564:        Dsymbols *decldefs = new Dsymbols();
   201961: 1565:        decldefs->push(a);
        -: 1566:        TemplateDeclaration *tempdecl =
   201961: 1567:                new TemplateDeclaration(loc, id, tpl, 
constraint, decldefs, 0);
   201961: 1568:        return tempdecl;
        -: 1569:    }
        -: 1570:
  1395747: 1571:    return a;
        -: 1572:}
        -: 1573:
        -: 1574:/*******************************************
        -: 1575: */
        -: 1576:
   323895: 1577:BaseClasses *Parser::parseBaseClasses()
        -: 1578:{
   323895: 1579:    BaseClasses *baseclasses = new BaseClasses();
        -: 1580:
    55456: 1581:    for (; 1; nextToken())
        -: 1582:    {
   379351: 1583:        enum PROT protection = PROTpublic;
   379351: 1584:        switch (token.value)
        -: 1585:        {
        -: 1586:            case TOKprivate:
    #####: 1587:                protection = PROTprivate;
    #####: 1588:                nextToken();
    #####: 1589:                break;
        -: 1590:            case TOKpackage:
    #####: 1591:                protection = PROTpackage;
    #####: 1592:                nextToken();
    #####: 1593:                break;
        -: 1594:            case TOKprotected:
    #####: 1595:                protection = PROTprotected;
    #####: 1596:                nextToken();
    #####: 1597:                break;
        -: 1598:            case TOKpublic:
       64: 1599:                protection = PROTpublic;
       64: 1600:                nextToken();
        -: 1601:                break;
        -: 1602:        }
   379351: 1603:        if (token.value == TOKidentifier)
        -: 1604:        {
   379351: 1605:            BaseClass *b = new 
BaseClass(parseBasicType(), protection);
   379351: 1606:            baseclasses->push(b);
   379351: 1607:            if (token.value != TOKcomma)
   323895: 1608:                break;
        -: 1609:        }
        -: 1610:        else
        -: 1611:        {
    #####: 1612:            error("base classes expected instead of %s", 
token.toChars());
    #####: 1613:            return NULL;
        -: 1614:        }
        -: 1615:    }
   323895: 1616:    return baseclasses;
        -: 1617:}
        -: 1618:
        -: 1619:/**************************************
        -: 1620: * Parse constraint.
        -: 1621: * Constraint is of the form:
        -: 1622: *      if ( ConstraintExpression )
        -: 1623: */
        -: 1624:
        -: 1625:#if DMDV2
  2639918: 1626:Expression *Parser::parseConstraint()
  2639918: 1627:{   Expression *e = NULL;
        -: 1628:
  2639918: 1629:    if (token.value == TOKif)
        -: 1630:    {
   924732: 1631:        nextToken();    // skip over 'if'
   924732: 1632:        check(TOKlparen);
   924732: 1633:        e = parseExpression();
   924732: 1634:        check(TOKrparen);
        -: 1635:    }
  2639918: 1636:    return e;
        -: 1637:}
        -: 1638:#endif
        -: 1639:
        -: 1640:/**************************************
        -: 1641: * Parse a TemplateDeclaration.
        -: 1642: */
        -: 1643:
   861634: 1644:TemplateDeclaration 
*Parser::parseTemplateDeclaration(int ismixin)
        -: 1645:{
        -: 1646:    TemplateDeclaration *tempdecl;
        -: 1647:    Identifier *id;
        -: 1648:    TemplateParameters *tpl;
        -: 1649:    Dsymbols *decldefs;
   861634: 1650:    Expression *constraint = NULL;
   861634: 1651:    Loc loc = this->loc;
        -: 1652:
   861634: 1653:    nextToken();
   861634: 1654:    if (token.value != TOKidentifier)
    #####: 1655:    {   error("TemplateIdentifier expected following 
template");
    #####: 1656:        goto Lerr;
        -: 1657:    }
   861634: 1658:    id = token.ident;
   861634: 1659:    nextToken();
   861634: 1660:    tpl = parseTemplateParameterList();
   861634: 1661:    if (!tpl)
    #####: 1662:        goto Lerr;
        -: 1663:
   861634: 1664:    constraint = parseConstraint();
        -: 1665:
   861634: 1666:    if (token.value != TOKlcurly)
    #####: 1667:    {   error("members of template declaration expected");
    #####: 1668:        goto Lerr;
        -: 1669:    }
        -: 1670:    else
        -: 1671:    {
   861634: 1672:        nextToken();
   861634: 1673:        decldefs = parseDeclDefs(0);
   861634: 1674:        if (token.value != TOKrcurly)
    #####: 1675:        {   error("template member expected");
    #####: 1676:            goto Lerr;
        -: 1677:        }
   861634: 1678:        nextToken();
        -: 1679:    }
        -: 1680:
   861634: 1681:    tempdecl = new TemplateDeclaration(loc, id, tpl, 
constraint, decldefs, ismixin);
   861634: 1682:    return tempdecl;
        -: 1683:
    #####: 1684:Lerr:
    #####: 1685:    return NULL;
        -: 1686:}
        -: 1687:
        -: 1688:/******************************************
        -: 1689: * Parse template parameter list.
        -: 1690: * Input:
        -: 1691: *      flag    0: parsing "( list )"
        -: 1692: *              1: parsing non-empty "list )"
        -: 1693: */
        -: 1694:
  2667645: 1695:TemplateParameters 
*Parser::parseTemplateParameterList(int flag)
        -: 1696:{
  2667645: 1697:    TemplateParameters *tpl = new TemplateParameters();
        -: 1698:
  2667645: 1699:    if (!flag && token.value != TOKlparen)
    #####: 1700:    {   error("parenthesized TemplateParameterList 
expected following TemplateIdentifier");
    #####: 1701:        goto Lerr;
        -: 1702:    }
  2667645: 1703:    nextToken();
        -: 1704:
        -: 1705:    // Get array of TemplateParameters
  2667645: 1706:    if (flag || token.value != TOKrparen)
  2471139: 1707:    {   int isvariadic = 0;
        -: 1708:
  6407739: 1709:        while (token.value != TOKrparen)
        -: 1710:        {   TemplateParameter *tp;
  3936536: 1711:            Identifier *tp_ident = NULL;
  3936536: 1712:            Type *tp_spectype = NULL;
  3936536: 1713:            Type *tp_valtype = NULL;
  3936536: 1714:            Type *tp_defaulttype = NULL;
  3936536: 1715:            Expression *tp_specvalue = NULL;
  3936536: 1716:            Expression *tp_defaultvalue = NULL;
        -: 1717:            Token *t;
        -: 1718:
        -: 1719:            // Get TemplateParameter
        -: 1720:
        -: 1721:            // First, look ahead to see if it is a 
TypeParameter or a ValueParameter
  3936536: 1722:            t = peek(&token);
  3936536: 1723:            if (token.value == TOKalias)
        -: 1724:            {   // AliasParameter
   379063: 1725:                nextToken();
   379063: 1726:                Type *spectype = NULL;
   379063: 1727:                if (isDeclaration(&token, 2, 
TOKreserved, NULL))
        -: 1728:                {
       64: 1729:                    spectype = parseType(&tp_ident);
        -: 1730:                }
        -: 1731:                else
        -: 1732:                {
   378999: 1733:                    if (token.value != TOKidentifier)
    #####: 1734:                    {   error("identifier expected for 
template alias parameter");
    #####: 1735:                        goto Lerr;
        -: 1736:                    }
   378999: 1737:                    tp_ident = token.ident;
   378999: 1738:                    nextToken();
        -: 1739:                }
   379063: 1740:                Object *spec = NULL;
   379063: 1741:                if (token.value == TOKcolon)    // : Type
        -: 1742:                {
    #####: 1743:                    nextToken();
    #####: 1744:                    if (isDeclaration(&token, 0, 
TOKreserved, NULL))
    #####: 1745:                        spec = parseType();
        -: 1746:                    else
    #####: 1747:                        spec = parseCondExp();
        -: 1748:                }
   379063: 1749:                Object *def = NULL;
   379063: 1750:                if (token.value == TOKassign)   // = Type
        -: 1751:                {
   172968: 1752:                    nextToken();
   172968: 1753:                    if (isDeclaration(&token, 0, 
TOKreserved, NULL))
     3159: 1754:                        def = parseType();
        -: 1755:                    else
   169809: 1756:                        def = parseCondExp();
        -: 1757:                }
   379063: 1758:                tp = new TemplateAliasParameter(loc, 
tp_ident, spectype, spec, def);
        -: 1759:            }
  6147910: 1760:            else if (t->value == TOKcolon || t->value == 
TOKassign ||
        -: 1761:                     t->value == TOKcomma || t->value == 
TOKrparen)
        -: 1762:            {   // TypeParameter
  2590437: 1763:                if (token.value != TOKidentifier)
    #####: 1764:                {   error("identifier expected for 
template type parameter");
    #####: 1765:                    goto Lerr;
        -: 1766:                }
  2590437: 1767:                tp_ident = token.ident;
  2590437: 1768:                nextToken();
  2590437: 1769:                if (token.value == TOKcolon)    // : Type
        -: 1770:                {
    58829: 1771:                    nextToken();
    58829: 1772:                    tp_spectype = parseType();
        -: 1773:                }
  2590437: 1774:                if (token.value == TOKassign)   // = Type
        -: 1775:                {
    39086: 1776:                    nextToken();
    39086: 1777:                    tp_defaulttype = parseType();
        -: 1778:                }
  2590437: 1779:                tp = new TemplateTypeParameter(loc, 
tp_ident, tp_spectype, tp_defaulttype);
        -: 1780:            }
  1478795: 1781:            else if (token.value == TOKidentifier && 
t->value == TOKdotdotdot)
        -: 1782:            {   // ident...
   511759: 1783:                if (isvariadic)
    #####: 1784:                    error("variadic template parameter 
must be last");
   511759: 1785:                isvariadic = 1;
   511759: 1786:                tp_ident = token.ident;
   511759: 1787:                nextToken();
   511759: 1788:                nextToken();
   511759: 1789:                tp = new TemplateTupleParameter(loc, 
tp_ident);
        -: 1790:            }
        -: 1791:#if DMDV2
   455277: 1792:            else if (token.value == TOKthis)
        -: 1793:            {   // ThisParameter
       64: 1794:                nextToken();
       64: 1795:                if (token.value != TOKidentifier)
    #####: 1796:                {   error("identifier expected for 
template this parameter");
    #####: 1797:                    goto Lerr;
        -: 1798:                }
       64: 1799:                tp_ident = token.ident;
       64: 1800:                nextToken();
       64: 1801:                if (token.value == TOKcolon)    // : Type
        -: 1802:                {
    #####: 1803:                    nextToken();
    #####: 1804:                    tp_spectype = parseType();
        -: 1805:                }
       64: 1806:                if (token.value == TOKassign)   // = Type
        -: 1807:                {
    #####: 1808:                    nextToken();
    #####: 1809:                    tp_defaulttype = parseType();
        -: 1810:                }
       64: 1811:                tp = new TemplateThisParameter(loc, 
tp_ident, tp_spectype, tp_defaulttype);
        -: 1812:            }
        -: 1813:#endif
        -: 1814:            else
        -: 1815:            {   // ValueParameter
   455213: 1816:                tp_valtype = parseType(&tp_ident);
   455213: 1817:                if (!tp_ident)
        -: 1818:                {
    #####: 1819:                    error("identifier expected for 
template value parameter");
    #####: 1820:                    tp_ident = new Identifier("error", 
TOKidentifier);
        -: 1821:                }
   455213: 1822:                if (token.value == TOKcolon)    // : 
CondExpression
        -: 1823:                {
     7214: 1824:                    nextToken();
     7214: 1825:                    tp_specvalue = parseCondExp();
        -: 1826:                }
   455213: 1827:                if (token.value == TOKassign)   // = 
CondExpression
        -: 1828:                {
   139184: 1829:                    nextToken();
   139184: 1830:                    tp_defaultvalue = parseDefaultInitExp();
        -: 1831:                }
   455213: 1832:                tp = new TemplateValueParameter(loc, 
tp_ident, tp_valtype, tp_specvalue, tp_defaultvalue);
        -: 1833:            }
  3936536: 1834:            tpl->push(tp);
  3936536: 1835:            if (token.value != TOKcomma)
  2471075: 1836:                break;
  1465461: 1837:            nextToken();
        -: 1838:        }
        -: 1839:    }
  2667645: 1840:    check(TOKrparen);
  2667645: 1841:Lerr:
  2667645: 1842:    return tpl;
        -: 1843:}
        -: 1844:
        -: 1845:/******************************************
        -: 1846: * Parse template mixin.
        -: 1847: *      mixin Foo;
        -: 1848: *      mixin Foo!(args);
        -: 1849: *      mixin a.b.c!(args).Foo!(args);
        -: 1850: *      mixin Foo!(args) identifier;
        -: 1851: *      mixin typeof(expr).identifier!(args);
        -: 1852: */
        -: 1853:
   130102: 1854:Dsymbol *Parser::parseMixin()
        -: 1855:{
        -: 1856:    TemplateMixin *tm;
        -: 1857:    Identifier *id;
        -: 1858:    Type *tqual;
        -: 1859:    Objects *tiargs;
        -: 1860:    Array *idents;
        -: 1861:
        -: 1862:    //printf("parseMixin()\n");
   130102: 1863:    nextToken();
   130102: 1864:    tqual = NULL;
   130102: 1865:    if (token.value == TOKdot)
        -: 1866:    {
        1: 1867:        id = Id::empty;
        -: 1868:    }
        -: 1869:    else
        -: 1870:    {
   130101: 1871:        if (token.value == TOKtypeof)
        -: 1872:        {
       64: 1873:            tqual = parseTypeof();
       64: 1874:            check(TOKdot);
        -: 1875:        }
   130101: 1876:        if (token.value != TOKidentifier)
        -: 1877:        {
    #####: 1878:            error("identifier expected, not %s", 
token.toChars());
    #####: 1879:            id = Id::empty;
        -: 1880:        }
        -: 1881:        else
   130101: 1882:            id = token.ident;
   130101: 1883:        nextToken();
        -: 1884:    }
        -: 1885:
   130102: 1886:    idents = new Array();
       65: 1887:    while (1)
        -: 1888:    {
   130167: 1889:        tiargs = NULL;
   130167: 1890:        if (token.value == TOKnot)
        -: 1891:        {
    18870: 1892:            nextToken();
    18870: 1893:            if (token.value == TOKlparen)
    18870: 1894:                tiargs = parseTemplateArgumentList();
        -: 1895:            else
    #####: 1896:                tiargs = parseTemplateArgument();
        -: 1897:        }
        -: 1898:
   130167: 1899:        if (token.value != TOKdot)
   130102: 1900:            break;
        -: 1901:
       65: 1902:        if (tiargs)
    #####: 1903:        {   TemplateInstance *tempinst = new 
TemplateInstance(loc, id);
    #####: 1904:            tempinst->tiargs = tiargs;
    #####: 1905:            id = (Identifier *)tempinst;
    #####: 1906:            tiargs = NULL;
        -: 1907:        }
       65: 1908:        idents->push(id);
        -: 1909:
       65: 1910:        nextToken();
       65: 1911:        if (token.value != TOKidentifier)
    #####: 1912:        {   error("identifier expected following '.' 
instead of '%s'", token.toChars());
    #####: 1913:            break;
        -: 1914:        }
       65: 1915:        id = token.ident;
       65: 1916:        nextToken();
        -: 1917:    }
   130102: 1918:    idents->push(id);
        -: 1919:
   130102: 1920:    if (token.value == TOKidentifier)
        -: 1921:    {
    23394: 1922:        id = token.ident;
    23394: 1923:        nextToken();
        -: 1924:    }
        -: 1925:    else
   106708: 1926:        id = NULL;
        -: 1927:
   130102: 1928:    tm = new TemplateMixin(loc, id, tqual, idents, tiargs);
   130102: 1929:    if (token.value != TOKsemicolon)
    #####: 1930:        error("';' expected after mixin");
   130102: 1931:    nextToken();
        -: 1932:
   130102: 1933:    return tm;
        -: 1934:}
        -: 1935:
        -: 1936:/******************************************
        -: 1937: * Parse template argument list.
        -: 1938: * Input:
        -: 1939: *      current token is opening '('
        -: 1940: * Output:
        -: 1941: *      current token is one after closing ')'
        -: 1942: */
        -: 1943:
  6614044: 1944:Objects *Parser::parseTemplateArgumentList()
        -: 1945:{
        -: 1946:    //printf("Parser::parseTemplateArgumentList()\n");
  6614044: 1947:    if (token.value != TOKlparen && token.value != 
TOKlcurly)
    #####: 1948:    {   error("!(TemplateArgumentList) expected 
following TemplateIdentifier");
    #####: 1949:        return new Objects();
        -: 1950:    }
  6614044: 1951:    return parseTemplateArgumentList2();
        -: 1952:}
        -: 1953:
  6819378: 1954:Objects *Parser::parseTemplateArgumentList2()
        -: 1955:{
        -: 1956:    //printf("Parser::parseTemplateArgumentList2()\n");
  6819378: 1957:    Objects *tiargs = new Objects();
  6819378: 1958:    enum TOK endtok = TOKrparen;
  6819378: 1959:    nextToken();
        -: 1960:
        -: 1961:    // Get TemplateArgumentList
 17140206: 1962:    while (token.value != endtok)
        -: 1963:    {
        -: 1964:            // See if it is an Expression or a Type
 10227997: 1965:            if (isDeclaration(&token, 0, TOKreserved, NULL))
        -: 1966:            {   // Template argument is a type
  8857866: 1967:                Type *ta = parseType();
  8857866: 1968:                tiargs->push(ta);
        -: 1969:            }
        -: 1970:            else
        -: 1971:            {   // Template argument is an expression
  1370131: 1972:                Expression *ea = parseAssignExp();
        -: 1973:
  1370131: 1974:                if (ea->op == TOKfunction)
    85572: 1975:                {   FuncLiteralDeclaration *fd = 
((FuncExp *)ea)->fd;
    85572: 1976:                    if (fd->type->ty == Tfunction)
        -: 1977:                    {
    85572: 1978:                        TypeFunction *tf = (TypeFunction 
*)fd->type;
        -: 1979:                        /* If there are parameters that 
consist of only an identifier,
        -: 1980:                         * rather than assuming the 
identifier is a type, as we would
        -: 1981:                         * for regular function 
declarations, assume the identifier
        -: 1982:                         * is the parameter name, and 
we're building a template with
        -: 1983:                         * a deduced type.
        -: 1984:                         */
    85572: 1985:                        TemplateParameters *tpl = NULL;
   162307: 1986:                        for (int i = 0; i < 
tf->parameters->dim; i++)
    76735: 1987:                        {   Parameter *param = 
(Parameter *)tf->parameters->data[i];
    76735: 1988:                            if (param->ident == NULL &&
        -: 1989:                                param->type &&
        -: 1990:                                param->type->ty == Tident &&
        -: 1991:                                ((TypeIdentifier 
*)param->type)->idents.dim == 0
        -: 1992:                               )
        -: 1993:                            {
        -: 1994:                                /* Switch parameter type 
to parameter identifier,
        -: 1995:                                 * parameterize with 
template type parameter _T
        -: 1996:                                 */
    24760: 1997:                                TypeIdentifier *pt = 
(TypeIdentifier *)param->type;
    24760: 1998:                                param->ident = pt->ident;
    24760: 1999:                                Identifier *id = 
Lexer::uniqueId("__T");
    24760: 2000:                                param->type = new 
TypeIdentifier(pt->loc, id);
    24760: 2001:                                TemplateParameter *tp = 
new TemplateTypeParameter(fd->loc, id, NULL, NULL);
    24760: 2002:                                if (!tpl)
    21473: 2003:                                    tpl = new 
TemplateParameters();
    24760: 2004:                                tpl->push(tp);
        -: 2005:                            }
        -: 2006:                        }
        -: 2007:
    85572: 2008:                        if (tpl)
        -: 2009:                        {   // Wrap a template around 
function fd
    21473: 2010:                            Dsymbols *decldefs = new 
Dsymbols();
    21473: 2011:                            decldefs->push(fd);
        -: 2012:                            TemplateDeclaration *tempdecl =
    21473: 2013:                                new 
TemplateDeclaration(fd->loc, fd->ident, tpl, NULL, decldefs, 0);
    21473: 2014:                            tempdecl->literal = 1;      
// it's a template 'literal'
    21473: 2015:                            tiargs->push(tempdecl);
    21473: 2016:                            goto L1;
        -: 2017:                        }
        -: 2018:                    }
        -: 2019:                }
        -: 2020:
  1348658: 2021:                tiargs->push(ea);
        -: 2022:            }
 10227997: 2023:         L1:
 10227997: 2024:            if (token.value != TOKcomma)
  6726547: 2025:                break;
  3501450: 2026:            nextToken();
        -: 2027:    }
  6819378: 2028:    check(endtok, "template argument list");
  6819378: 2029:    return tiargs;
        -: 2030:}
        -: 2031:
        -: 2032:/*****************************
        -: 2033: * Parse single template argument, to support the syntax:
        -: 2034: *      foo!arg
        -: 2035: * Input:
        -: 2036: *      current token is the arg
        -: 2037: */
        -: 2038:
  3290982: 2039:Objects *Parser::parseTemplateArgument()
        -: 2040:{
        -: 2041:    //printf("parseTemplateArgument()\n");
  3290982: 2042:    Objects *tiargs = new Objects();
        -: 2043:    Type *ta;
  3290982: 2044:    switch (token.value)
        -: 2045:    {
        -: 2046:        case TOKidentifier:
  2408057: 2047:            ta = new TypeIdentifier(loc, token.ident);
  2408057: 2048:            goto LabelX;
        -: 2049:
    #####: 2050:        case BASIC_TYPES_X(ta):
  3128650: 2051:            tiargs->push(ta);
  3128650: 2052:            nextToken();
  3128650: 2053:            break;
        -: 2054:
        -: 2055:        case TOKint32v:
        -: 2056:        case TOKuns32v:
        -: 2057:        case TOKint64v:
        -: 2058:        case TOKuns64v:
        -: 2059:        case TOKfloat32v:
        -: 2060:        case TOKfloat64v:
        -: 2061:        case TOKfloat80v:
        -: 2062:        case TOKimaginary32v:
        -: 2063:        case TOKimaginary64v:
        -: 2064:        case TOKimaginary80v:
        -: 2065:        case TOKnull:
        -: 2066:        case TOKtrue:
        -: 2067:        case TOKfalse:
        -: 2068:        case TOKcharv:
        -: 2069:        case TOKwcharv:
        -: 2070:        case TOKdcharv:
        -: 2071:        case TOKstring:
        -: 2072:        case TOKfile:
        -: 2073:        case TOKline:
        -: 2074:        {   // Template argument is an expression
   162332: 2075:            Expression *ea = parsePrimaryExp();
   162332: 2076:            tiargs->push(ea);
   162332: 2077:            break;
        -: 2078:        }
        -: 2079:
        -: 2080:        default:
    #####: 2081:            error("template argument expected following !");
        -: 2082:            break;
        -: 2083:    }
  3290982: 2084:    if (token.value == TOKnot)
    #####: 2085:        error("multiple ! arguments are not allowed");
  3290982: 2086:    return tiargs;
        -: 2087:}
        -: 2088:
   683760: 2089:Import *Parser::parseImport(Dsymbols *decldefs, int 
isstatic)
        -: 2090:{   Import *s;
        -: 2091:    Identifier *id;
   683760: 2092:    Identifier *aliasid = NULL;
        -: 2093:    Array *a;
   683760: 2094:    Loc loc;
        -: 2095:
        -: 2096:    //printf("Parser::parseImport()\n");
  1183729: 2097:    do
        -: 2098:    {
  1211140: 2099:     L1:
  1211140: 2100:        nextToken();
  1211140: 2101:        if (token.value != TOKidentifier)
    #####: 2102:        {   error("Identifier expected following import");
    #####: 2103:            break;
        -: 2104:        }
        -: 2105:
  1211140: 2106:        loc = this->loc;
  1211140: 2107:        a = NULL;
  1211140: 2108:        id = token.ident;
  1211140: 2109:        nextToken();
  1211140: 2110:        if (!aliasid && token.value == TOKassign)
        -: 2111:        {
    #####: 2112:            aliasid = id;
    #####: 2113:            goto L1;
        -: 2114:        }
  4388813: 2115:        while (token.value == TOKdot)
        -: 2116:        {
  1966533: 2117:            if (!a)
  1207525: 2118:                a = new Array();
  1966533: 2119:            a->push(id);
  1966533: 2120:            nextToken();
  1966533: 2121:            if (token.value != TOKidentifier)
    #####: 2122:            {   error("identifier expected following 
package");
    #####: 2123:                break;
        -: 2124:            }
  1966533: 2125:            id = token.ident;
  1966533: 2126:            nextToken();
        -: 2127:        }
        -: 2128:
  1211140: 2129:        s = new Import(loc, a, id, aliasid, isstatic);
  1211140: 2130:        decldefs->push(s);
        -: 2131:
        -: 2132:        /* Look for
        -: 2133:         *      : alias=name, alias=name;
        -: 2134:         * syntax.
        -: 2135:         */
  1211140: 2136:        if (token.value == TOKcolon)
        -: 2137:        {
    39683: 2138:            do
        -: 2139:            {   Identifier *name;
        -: 2140:
    39683: 2141:                nextToken();
    39683: 2142:                if (token.value != TOKidentifier)
    #####: 2143:                {   error("Identifier expected following 
:");
    #####: 2144:                    break;
        -: 2145:                }
    39683: 2146:                Identifier *alias = token.ident;
    39683: 2147:                nextToken();
    39683: 2148:                if (token.value == TOKassign)
        -: 2149:                {
    #####: 2150:                    nextToken();
    #####: 2151:                    if (token.value != TOKidentifier)
    #####: 2152:                    {   error("Identifier expected 
following %s=", alias->toChars());
    #####: 2153:                        break;
        -: 2154:                    }
    #####: 2155:                    name = token.ident;
    #####: 2156:                    nextToken();
        -: 2157:                }
        -: 2158:                else
    39683: 2159:                {   name = alias;
    39683: 2160:                    alias = NULL;
        -: 2161:                }
    39683: 2162:                s->addAlias(name, alias);
        -: 2163:            } while (token.value == TOKcomma);
    27411: 2164:            break;      // no comma-separated imports of 
this form
        -: 2165:        }
        -: 2166:
  1183729: 2167:        aliasid = NULL;
        -: 2168:    } while (token.value == TOKcomma);
        -: 2169:
   683760: 2170:    if (token.value == TOKsemicolon)
   683760: 2171:        nextToken();
        -: 2172:    else
        -: 2173:    {
    #####: 2174:        error("';' expected");
    #####: 2175:        nextToken();
        -: 2176:    }
        -: 2177:
   683760: 2178:    return NULL;
        -: 2179:}
        -: 2180:
        -: 2181:#if DMDV2
 32774299: 2182:Type *Parser::parseType(Identifier **pident, 
TemplateParameters **tpl)
        -: 2183:{   Type *t;
        -: 2184:
        -: 2185:    /* Take care of the storage class prefixes that
        -: 2186:     * serve as type attributes:
        -: 2187:     *  const shared, shared const, const, invariant, shared
        -: 2188:     */
 32774299: 2189:    if (token.value == TOKconst && peekNext() == 
TOKshared && peekNext2() != TOKlparen ||
        -: 2190:        token.value == TOKshared && peekNext() == 
TOKconst && peekNext2() != TOKlparen)
        -: 2191:    {
       64: 2192:        nextToken();
       64: 2193:        nextToken();
        -: 2194:        /* shared const type
        -: 2195:         */
       64: 2196:        t = parseType(pident, tpl);
       64: 2197:        t = t->makeSharedConst();
       64: 2198:        return t;
        -: 2199:    }
 32774235: 2200:    else if (token.value == TOKwild && peekNext() == 
TOKshared && peekNext2() != TOKlparen ||
        -: 2201:        token.value == TOKshared && peekNext() == 
TOKwild && peekNext2() != TOKlparen)
        -: 2202:    {
    #####: 2203:        nextToken();
    #####: 2204:        nextToken();
        -: 2205:        /* shared wild type
        -: 2206:         */
    #####: 2207:        t = parseType(pident, tpl);
    #####: 2208:        t = t->makeSharedWild();
    #####: 2209:        return t;
        -: 2210:    }
 32774235: 2211:    else if (token.value == TOKconst && peekNext() != 
TOKlparen)
        -: 2212:    {
    88155: 2213:        nextToken();
        -: 2214:        /* const type
        -: 2215:         */
    88155: 2216:        t = parseType(pident, tpl);
    88155: 2217:        t = t->makeConst();
    88155: 2218:        return t;
        -: 2219:    }
 32686080: 2220:    else if ((token.value == TOKinvariant || token.value 
== TOKimmutable) &&
        -: 2221:             peekNext() != TOKlparen)
        -: 2222:    {
    36436: 2223:        nextToken();
        -: 2224:        /* invariant type
        -: 2225:         */
    36436: 2226:        t = parseType(pident, tpl);
    36436: 2227:        t = t->makeInvariant();
    36436: 2228:        return t;
        -: 2229:    }
 32649644: 2230:    else if (token.value == TOKshared && peekNext() != 
TOKlparen)
        -: 2231:    {
    27407: 2232:        nextToken();
        -: 2233:        /* shared type
        -: 2234:         */
    27407: 2235:        t = parseType(pident, tpl);
    27407: 2236:        t = t->makeShared();
    27407: 2237:        return t;
        -: 2238:    }
 32622237: 2239:    else if (token.value == TOKwild && peekNext() != 
TOKlparen)
        -: 2240:    {
    #####: 2241:        nextToken();
        -: 2242:        /* wild type
        -: 2243:         */
    #####: 2244:        t = parseType(pident, tpl);
    #####: 2245:        t = t->makeWild();
    #####: 2246:        return t;
        -: 2247:    }
        -: 2248:    else
 32622237: 2249:        t = parseBasicType();
 32622237: 2250:    t = parseDeclarator(t, pident, tpl);
 32622237: 2251:    return t;
        -: 2252:}
        -: 2253:#endif
        -: 2254:
 58875351: 2255:Type *Parser::parseBasicType()
        -: 2256:{   Type *t;
        -: 2257:    Identifier *id;
        -: 2258:    TypeQualified *tid;
        -: 2259:
        -: 2260:    //printf("parseBasicType()\n");
 58875351: 2261:    switch (token.value)
        -: 2262:    {
  3604835: 2263:        case BASIC_TYPES_X(t):
 28769342: 2264:            nextToken();
 28769342: 2265:            break;
        -: 2266:
        -: 2267:        case TOKidentifier:
 27954149: 2268:            id = token.ident;
 27954149: 2269:            nextToken();
 27954149: 2270:            if (token.value == TOKnot)
        -: 2271:            {   // ident!(template_arguments)
  2951357: 2272:                TemplateInstance *tempinst = new 
TemplateInstance(loc, id);
  2951357: 2273:                nextToken();
  2951357: 2274:                if (token.value == TOKlparen)
        -: 2275:                    // ident!(template_arguments)
  2211811: 2276:                    tempinst->tiargs = 
parseTemplateArgumentList();
        -: 2277:                else
        -: 2278:                    // ident!template_argument
   739546: 2279:                    tempinst->tiargs = 
parseTemplateArgument();
  2951357: 2280:                tid = new TypeInstance(loc, tempinst);
  2951357: 2281:                goto Lident2;
        -: 2282:            }
 25051802: 2283:        Lident:
 25051802: 2284:            tid = new TypeIdentifier(loc, id);
 29144109: 2285:        Lident2:
 59204393: 2286:            while (token.value == TOKdot)
   916175: 2287:            {   nextToken();
   916175: 2288:                if (token.value != TOKidentifier)
    #####: 2289:                {   error("identifier expected following 
'.' instead of '%s'", token.toChars());
    #####: 2290:                    break;
        -: 2291:                }
   916175: 2292:                id = token.ident;
   916175: 2293:                nextToken();
   916175: 2294:                if (token.value == TOKnot)
        -: 2295:                {
    49329: 2296:                    TemplateInstance *tempinst = new 
TemplateInstance(loc, id);
    49329: 2297:                    nextToken();
    49329: 2298:                    if (token.value == TOKlparen)
        -: 2299:                        // ident!(template_arguments)
    37205: 2300:                        tempinst->tiargs = 
parseTemplateArgumentList();
        -: 2301:                    else
        -: 2302:                        // ident!template_argument
    12124: 2303:                        tempinst->tiargs = 
parseTemplateArgument();
    49329: 2304:                    tid->addIdent((Identifier *)tempinst);
        -: 2305:                }
        -: 2306:                else
   866846: 2307:                    tid->addIdent(id);
        -: 2308:            }
 29144109: 2309:            t = tid;
 29144109: 2310:            break;
        -: 2311:
        -: 2312:        case TOKdot:
        -: 2313:            // Leading . as in .foo
    49010: 2314:            id = Id::empty;
    49010: 2315:            goto Lident;
        -: 2316:
        -: 2317:        case TOKtypeof:
        -: 2318:            // typeof(expression)
  1140950: 2319:            tid = parseTypeof();
  1140950: 2320:            goto Lident2;
        -: 2321:
        -: 2322:        case TOKconst:
        -: 2323:            // const(type)
   593724: 2324:            nextToken();
   593724: 2325:            check(TOKlparen);
   593724: 2326:            t = parseType();
   593724: 2327:            check(TOKrparen);
   593724: 2328:            if (t->isShared())
      576: 2329:                t = t->makeSharedConst();
        -: 2330:            else
   593148: 2331:                t = t->makeConst();
   593724: 2332:            break;
        -: 2333:
        -: 2334:        case TOKinvariant:
    #####: 2335:            if (!global.params.useDeprecated)
    #####: 2336:                error("use of 'invariant' rather than 
'immutable' is deprecated");
        -: 2337:        case TOKimmutable:
        -: 2338:            // invariant(type)
   290139: 2339:            nextToken();
   290139: 2340:            check(TOKlparen);
   290139: 2341:            t = parseType();
   290139: 2342:            check(TOKrparen);
   290139: 2343:            t = t->makeInvariant();
   290139: 2344:            break;
        -: 2345:
        -: 2346:        case TOKshared:
        -: 2347:            // shared(type)
    76757: 2348:            nextToken();
    76757: 2349:            check(TOKlparen);
    76757: 2350:            t = parseType();
    76757: 2351:            check(TOKrparen);
    76757: 2352:            if (t->isConst())
    42946: 2353:                t = t->makeSharedConst();
    33811: 2354:            else if (t->isWild())
       64: 2355:                t = t->makeSharedWild();
        -: 2356:            else
    33747: 2357:                t = t->makeShared();
    76757: 2358:            break;
        -: 2359:
        -: 2360:        case TOKwild:
        -: 2361:            // wild(type)
     1280: 2362:            nextToken();
     1280: 2363:            check(TOKlparen);
     1280: 2364:            t = parseType();
     1280: 2365:            check(TOKrparen);
     1280: 2366:            if (t->isShared())
      128: 2367:                t = t->makeSharedWild();
        -: 2368:            else
     1152: 2369:                t = t->makeWild();
     1280: 2370:            break;
        -: 2371:
        -: 2372:        default:
    #####: 2373:            error("basic type expected, not %s", 
token.toChars());
    #####: 2374:            t = Type::tint32;
        -: 2375:            break;
        -: 2376:    }
 58875351: 2377:    return t;
        -: 2378:}
        -: 2379:
        -: 2380:/******************************************
        -: 2381: * Parse things that follow the initial type t.
        -: 2382: *      t *
        -: 2383: *      t []
        -: 2384: *      t [type]
        -: 2385: *      t [expression]
        -: 2386: *      t [expression .. expression]
        -: 2387: *      t function
        -: 2388: *      t delegate
        -: 2389: */
        -: 2390:
 95697569: 2391:Type *Parser::parseBasicType2(Type *t)
        -: 2392:{
        -: 2393:    //printf("parseBasicType2()\n");
 11808946: 2394:    while (1)
        -: 2395:    {
 95697569: 2396:        switch (token.value)
        -: 2397:        {
        -: 2398:            case TOKmul:
  6379418: 2399:                t = new TypePointer(t);
  6379418: 2400:                nextToken();
  6379418: 2401:                continue;
        -: 2402:
        -: 2403:            case TOKlbracket:
        -: 2404:                // Handle []. Make sure things like
        -: 2405:                //     int[3][1] a;
        -: 2406:                // is (array[1] of array[3] of int)
  4993474: 2407:                nextToken();
  4993474: 2408:                if (token.value == TOKrbracket)
        -: 2409:                {
  3299612: 2410:                    t = new 
TypeDArray(t);                      // []
  3299612: 2411:                    nextToken();
        -: 2412:                }
  1693862: 2413:                else if (token.value == TOKnew && 
peekNext() == TOKrbracket)
        -: 2414:                {
    #####: 2415:                    t = new 
TypeNewArray(t);                    // [new]
    #####: 2416:                    nextToken();
    #####: 2417:                    nextToken();
        -: 2418:                }
  1693862: 2419:                else if (isDeclaration(&token, 0, 
TOKrbracket, NULL))
        -: 2420:                {   // It's an associative array declaration
        -: 2421:
        -: 2422:                    //printf("it's an associative array\n");
   275388: 2423:                    Type *index = parseType();          
// [ type ]
   275388: 2424:                    t = new TypeAArray(t, index);
   275388: 2425:                    check(TOKrbracket);
        -: 2426:                }
        -: 2427:                else
        -: 2428:                {
        -: 2429:                    //printf("it's type[expression]\n");
  1418474: 2430:                    inBrackets++;
  1418474: 2431:                    Expression *e = 
parseAssignExp();           // [ expression ]
  1418474: 2432:                    if (token.value == TOKslice)
        -: 2433:                    {
   271875: 2434:                        nextToken();
   271875: 2435:                        Expression *e2 = 
parseAssignExp();      // [ exp .. exp ]
   271875: 2436:                        t = new TypeSlice(t, e, e2);
        -: 2437:                    }
        -: 2438:                    else
  1146599: 2439:                        t = new TypeSArray(t,e);
  1418474: 2440:                    inBrackets--;
  1418474: 2441:                    check(TOKrbracket);
        -: 2442:                }
  4993474: 2443:                continue;
        -: 2444:
        -: 2445:            case TOKdelegate:
        -: 2446:            case TOKfunction:
        -: 2447:            {   // Handle delegate declaration:
        -: 2448:                //      t delegate(parameter list) 
nothrow pure
        -: 2449:                //      t function(parameter list) 
nothrow pure
        -: 2450:                Parameters *arguments;
        -: 2451:                int varargs;
   436054: 2452:                enum TOK save = token.value;
        -: 2453:
   436054: 2454:                nextToken();
   436054: 2455:                arguments = parseParameters(&varargs);
        -: 2456:
   436054: 2457:                StorageClass stc = parsePostfix();
   436054: 2458:                if (stc & (STCconst | STCimmutable | 
STCshared | STCwild))
    #####: 2459:                    error("const/immutable/shared/inout 
attributes are only valid for non-static member functions");
        -: 2460:
   436054: 2461:                TypeFunction *tf = new 
TypeFunction(arguments, t, varargs, linkage, stc);
        -: 2462:
   436054: 2463:                if (save == TOKdelegate)
   175516: 2464:                    t = new TypeDelegate(tf);
        -: 2465:                else
   260538: 2466:                    t = new TypePointer(tf);    // 
pointer to function
   436054: 2467:                continue;
        -: 2468:            }
        -: 2469:
        -: 2470:            default:
 83888623: 2471:                return t;
        -: 2472:        }
        -: 2473:        assert(0);
        -: 2474:    }
        -: 2475:    assert(0);
        -: 2476:    return NULL;
        -: 2477:}
        -: 2478:
 58079445: 2479:Type *Parser::parseDeclarator(Type *t, Identifier 
**pident, TemplateParameters **tpl)
        -: 2480:{   Type *ts;
        -: 2481:
        -: 2482:    //printf("parseDeclarator(tpl = %p)\n", tpl);
 58079445: 2483:    t = parseBasicType2(t);
        -: 2484:
 58079445: 2485:    switch (token.value)
        -: 2486:    {
        -: 2487:
        -: 2488:        case TOKidentifier:
 37291392: 2489:            if (pident)
 37291392: 2490:                *pident = token.ident;
        -: 2491:            else
    #####: 2492:                error("unexpected identifer '%s' in 
declarator", token.ident->toChars());
 37291392: 2493:            ts = t;
 37291392: 2494:            nextToken();
 37291392: 2495:            break;
        -: 2496:
        -: 2497:        case TOKlparen:
        -: 2498:            /* Parse things with parentheses around the 
identifier, like:
        -: 2499:             *  int (*ident[3])[]
        -: 2500:             * although the D style would be:
        -: 2501:             *  int[]*[3] ident
        -: 2502:             */
    12093: 2503:            nextToken();
    12093: 2504:            ts = parseDeclarator(t, pident);
    12093: 2505:            check(TOKrparen);
    12093: 2506:            break;
        -: 2507:
        -: 2508:        default:
 20775960: 2509:            ts = t;
        -: 2510:            break;
        -: 2511:    }
        -: 2512:
        -: 2513:    // parse DeclaratorSuffixes
   108920: 2514:    while (1)
        -: 2515:    {
 58188365: 2516:        switch (token.value)
        -: 2517:        {
        -: 2518:#if CARRAYDECL
        -: 2519:            /* Support C style array syntax:
        -: 2520:             *   int ident[]
        -: 2521:             * as opposed to D-style:
        -: 2522:             *   int[] ident
        -: 2523:             */
        -: 2524:            case TOKlbracket:
        -: 2525:            {   // This is the old C-style post [] syntax.
        -: 2526:                TypeNext *ta;
   108920: 2527:                nextToken();
   108920: 2528:                if (token.value == TOKrbracket)
        -: 2529:                {   // It's a dynamic array
    56663: 2530:                    ta = new TypeDArray(t);             
// []
    56663: 2531:                    nextToken();
        -: 2532:                }
    52257: 2533:                else if (token.value == TOKnew && 
peekNext() == TOKrbracket)
        -: 2534:                {
    #####: 2535:                    t = new TypeNewArray(t);            
// [new]
    #####: 2536:                    nextToken();
    #####: 2537:                    nextToken();
        -: 2538:                }
    52257: 2539:                else if (isDeclaration(&token, 0, 
TOKrbracket, NULL))
        -: 2540:                {   // It's an associative array
        -: 2541:
        -: 2542:                    //printf("it's an associative array\n");
    14137: 2543:                    Type *index = parseType();          
// [ type ]
    14137: 2544:                    check(TOKrbracket);
    14137: 2545:                    ta = new TypeAArray(t, index);
        -: 2546:                }
        -: 2547:                else
        -: 2548:                {
        -: 2549:                    //printf("It's a static array\n");
    38120: 2550:                    Expression *e = parseAssignExp();   
// [ expression ]
    38120: 2551:                    ta = new TypeSArray(t, e);
    38120: 2552:                    check(TOKrbracket);
        -: 2553:                }
        -: 2554:
        -: 2555:                /* Insert ta into
        -: 2556:                 *   ts -> ... -> t
        -: 2557:                 * so that
        -: 2558:                 *   ts -> ... -> ta -> t
        -: 2559:                 */
        -: 2560:                Type **pt;
   108920: 2561:                for (pt = &ts; *pt != t; pt = 
&((TypeNext*)*pt)->next)
        -: 2562:                    ;
   108920: 2563:                *pt = ta;
        -: 2564:                continue;
        -: 2565:            }
        -: 2566:#endif
        -: 2567:            case TOKlparen:
        -: 2568:            {
 11419624: 2569:                if (tpl)
        -: 2570:                {
        -: 2571:                    /* Look ahead to see if this is 
(...)(...),
        -: 2572:                     * i.e. a function template declaration
        -: 2573:                     */
 11419496: 2574:                    if (peekPastParen(&token)->value == 
TOKlparen)
        -: 2575:                    {
        -: 2576:                        //printf("function template 
declaration\n");
        -: 2577:
        -: 2578:                        // Gather template parameter list
  1547300: 2579:                        *tpl = parseTemplateParameterList();
        -: 2580:                    }
        -: 2581:                }
        -: 2582:
        -: 2583:                int varargs;
 11419624: 2584:                Parameters *arguments = 
parseParameters(&varargs);
        -: 2585:
        -: 2586:                /* Parse 
const/immutable/shared/inout/nothrow/pure postfix
        -: 2587:                 */
 11419624: 2588:                StorageClass stc = parsePostfix();
 11419624: 2589:                Type *tf = new TypeFunction(arguments, 
t, varargs, linkage, stc);
        -: 2590:
 11419624: 2591:                if (stc & STCconst)
   181510: 2592:                {   if (tf->isShared())
    #####: 2593:                        tf = tf->makeSharedConst();
        -: 2594:                    else
   181510: 2595:                        tf = tf->makeConst();
        -: 2596:                }
 11419624: 2597:                if (stc & STCimmutable)
     3223: 2598:                    tf = tf->makeInvariant();
 11419624: 2599:                if (stc & STCshared)
    15347: 2600:                {   if (tf->isConst())
    12124: 2601:                        tf = tf->makeSharedConst();
        -: 2602:                    else
     3223: 2603:                        tf = tf->makeShared();
        -: 2604:                }
 11419624: 2605:                if (stc & STCwild)
    #####: 2606:                {   if (tf->isShared())
    #####: 2607:                        tf = tf->makeSharedWild();
        -: 2608:                    else
    #####: 2609:                        tf = tf->makeWild();
        -: 2610:                }
        -: 2611:
        -: 2612:                /* Insert tf into
        -: 2613:                 *   ts -> ... -> t
        -: 2614:                 * so that
        -: 2615:                 *   ts -> ... -> tf -> t
        -: 2616:                 */
        -: 2617:                Type **pt;
 11419624: 2618:                for (pt = &ts; *pt != t; pt = 
&((TypeNext*)*pt)->next)
        -: 2619:                    ;
 11419624: 2620:                *pt = tf;
        -: 2621:                break;
        -: 2622:            }
        -: 2623:        }
        -: 2624:        break;
        -: 2625:    }
        -: 2626:
 58079445: 2627:    return ts;
        -: 2628:}
        -: 2629:
        -: 2630:/**********************************
        -: 2631: * Parse Declarations.
        -: 2632: * These can be:
        -: 2633: *      1. declarations at global/class level
        -: 2634: *      2. declarations at statement level
        -: 2635: * Return array of Declaration *'s.
        -: 2636: */
        -: 2637:
 31336505: 2638:Dsymbols *Parser::parseDeclarations(StorageClass 
storage_class)
        -: 2639:{
        -: 2640:    StorageClass stc;
        -: 2641:    Type *ts;
        -: 2642:    Type *t;
        -: 2643:    Type *tfirst;
        -: 2644:    Identifier *ident;
        -: 2645:    Dsymbols *a;
 31336505: 2646:    enum TOK tok = TOKreserved;
 31336505: 2647:    unsigned char *comment = token.blockComment;
 31336505: 2648:    enum LINK link = linkage;
        -: 2649:
        -: 2650:    //printf("parseDeclarations() %s\n", token.toChars());
 31336505: 2651:    if (storage_class)
    76289: 2652:    {   ts = NULL;              // infer type
    76289: 2653:        goto L2;
        -: 2654:    }
        -: 2655:
 31260216: 2656:    switch (token.value)
        -: 2657:    {
        -: 2658:        case TOKalias:
        -: 2659:            /* Look for:
        -: 2660:             *   alias identifier this;
        -: 2661:             */
  2413974: 2662:            tok = token.value;
  2413974: 2663:            nextToken();
  2413974: 2664:            if (token.value == TOKidentifier && 
peek(&token)->value == TOKthis)
        -: 2665:            {
    10901: 2666:                AliasThis *s = new AliasThis(this->loc, 
token.ident);
    10901: 2667:                nextToken();
    10901: 2668:                check(TOKthis);
    10901: 2669:                check(TOKsemicolon);
    10901: 2670:                a = new Dsymbols();
    10901: 2671:                a->push(s);
    10901: 2672:                addComment(s, comment);
    10901: 2673:                return a;
        -: 2674:            }
  2403073: 2675:            break;
        -: 2676:        case TOKtypedef:
    67955: 2677:            tok = token.value;
    67955: 2678:            nextToken();
        -: 2679:            break;
        -: 2680:    }
        -: 2681:
 31249315: 2682:    storage_class = STCundefined;
  8131905: 2683:    while (1)
        -: 2684:    {
 39381220: 2685:        switch (token.value)
        -: 2686:        {
        -: 2687:            case TOKconst:
   273380: 2688:                if (peek(&token)->value == TOKlparen)
   125662: 2689:                    break;              // const as type 
constructor
   147718: 2690:                stc = STCconst;         // const as 
storage class
   147718: 2691:                goto L1;
        -: 2692:
        -: 2693:            case TOKinvariant:
        -: 2694:            case TOKimmutable:
   486577: 2695:                if (peek(&token)->value == TOKlparen)
   108590: 2696:                    break;
   377987: 2697:                stc = STCimmutable;
   377987: 2698:                goto L1;
        -: 2699:
        -: 2700:            case TOKshared:
    14083: 2701:                if (peek(&token)->value == TOKlparen)
    10796: 2702:                    break;
     3287: 2703:                stc = STCshared;
     3287: 2704:                goto L1;
        -: 2705:
        -: 2706:            case TOKwild:
      896: 2707:                if (peek(&token)->value == TOKlparen)
      832: 2708:                    break;
       64: 2709:                stc = STCwild;
       64: 2710:                goto L1;
        -: 2711:
   366463: 2712:            case TOKstatic:     stc = STCstatic;         
goto L1;
    #####: 2713:            case TOKfinal:      stc = STCfinal;          
goto L1;
  2870692: 2714:            case TOKauto:       stc = STCauto;           
goto L1;
    11678: 2715:            case TOKscope:      stc = STCscope;          
goto L1;
    #####: 2716:            case TOKoverride:   stc = STCoverride;       
goto L1;
    #####: 2717:            case TOKabstract:   stc = STCabstract;       
goto L1;
    #####: 2718:            case TOKsynchronized: stc = STCsynchronized; 
goto L1;
    #####: 2719:            case TOKdeprecated: stc = STCdeprecated;     
goto L1;
        -: 2720:#if DMDV2
       64: 2721:            case TOKnothrow:    stc = STCnothrow;        
goto L1;
      128: 2722:            case TOKpure:       stc = STCpure;           
goto L1;
     9157: 2723:            case TOKref:        stc = STCref;            
goto L1;
      328: 2724:            case TOKtls:        stc = STCtls;            
goto L1;
    18253: 2725:            case TOKgshared:    stc = STCgshared;        
goto L1;
  4307516: 2726:            case TOKenum:       stc = STCmanifest;       
goto L1;
    #####: 2727:            case TOKat:         stc = parseAttribute();  
goto L1;
        -: 2728:#endif
  8113399: 2729:            L1:
  8113399: 2730:                if (storage_class & stc)
    #####: 2731:                    error("redundant storage class 
'%s'", token.toChars());
  8113399: 2732:                storage_class = storage_class | stc;
  8113399: 2733:                composeStorageClass(storage_class);
  8113399: 2734:                nextToken();
  8113399: 2735:                continue;
        -: 2736:
        -: 2737:            case TOKextern:
    18570: 2738:                if (peek(&token)->value != TOKlparen)
       64: 2739:                {   stc = STCextern;
       64: 2740:                    goto L1;
        -: 2741:                }
        -: 2742:
    18506: 2743:                link = parseLinkage();
    18506: 2744:                continue;
        -: 2745:
        -: 2746:            default:
        -: 2747:                break;
        -: 2748:        }
        -: 2749:        break;
        -: 2750:    }
        -: 2751:
        -: 2752:    /* Look for auto initializers:
        -: 2753:     *  storage_class identifier = initializer;
        -: 2754:     */
 39311166: 2755:    if (storage_class &&
        -: 2756:        token.value == TOKidentifier &&
        -: 2757:        peek(&token)->value == TOKassign)
        -: 2758:    {
  6208345: 2759:        return parseAutoDeclarations(storage_class, 
comment);
        -: 2760:    }
        -: 2761:
 25040970: 2762:    if (token.value == TOKclass)
        -: 2763:    {
    #####: 2764:        AggregateDeclaration *s = (AggregateDeclaration 
*)parseAggregate();
    #####: 2765:        s->storage_class |= storage_class;
    #####: 2766:        Dsymbols *a = new Dsymbols();
    #####: 2767:        a->push(s);
    #####: 2768:        addComment(s, comment);
    #####: 2769:        return a;
        -: 2770:    }
        -: 2771:
        -: 2772:    /* Look for return type inference for template 
functions.
        -: 2773:     */
        -: 2774:    {
        -: 2775:    Token *tk;
 25040970: 2776:    if (storage_class &&
        -: 2777:        token.value == TOKidentifier &&
        -: 2778:        (tk = peek(&token))->value == TOKlparen &&
        -: 2779:        skipParens(tk, &tk) &&
        -: 2780:        peek(tk)->value == TOKlparen)
        -: 2781:    {
       64: 2782:        ts = NULL;
        -: 2783:    }
        -: 2784:    else
        -: 2785:    {
 25040906: 2786:        ts = parseBasicType();
 25040906: 2787:        ts = parseBasicType2(ts);
        -: 2788:    }
        -: 2789:    }
        -: 2790:
 25117259: 2791:L2:
 25117259: 2792:    tfirst = NULL;
 25117259: 2793:    a = new Dsymbols();
        -: 2794:
   263527: 2795:    while (1)
        -: 2796:    {
 25380786: 2797:        Loc loc = this->loc;
 25380786: 2798:        TemplateParameters *tpl = NULL;
        -: 2799:
 25380786: 2800:        ident = NULL;
 25380786: 2801:        t = parseDeclarator(ts, &ident, &tpl);
 25380786: 2802:        assert(t);
 25380786: 2803:        if (!tfirst)
 25117259: 2804:            tfirst = t;
   263527: 2805:        else if (t != tfirst)
        -: 2806:            error("multiple declarations must have the 
same type, not %s and %s",
    #####: 2807:                tfirst->toChars(), t->toChars());
 25380786: 2808:        if (!ident)
    #####: 2809:            error("no identifier for declarator %s", 
t->toChars());
        -: 2810:
 27851814: 2811:        if (tok == TOKtypedef || tok == TOKalias)
        -: 2812:        {   Declaration *v;
  2471028: 2813:            Initializer *init = NULL;
        -: 2814:
  2471028: 2815:            if (token.value == TOKassign)
        -: 2816:            {
     1287: 2817:                nextToken();
     1287: 2818:                init = parseInitializer();
        -: 2819:            }
  2471028: 2820:            if (tok == TOKtypedef)
    67955: 2821:                v = new TypedefDeclaration(loc, ident, 
t, init);
        -: 2822:            else
  2403073: 2823:            {   if (init)
    #####: 2824:                    error("alias cannot have initializer");
  2403073: 2825:                v = new AliasDeclaration(loc, ident, t);
        -: 2826:            }
  2471028: 2827:            v->storage_class = storage_class;
  2471028: 2828:            if (link == linkage)
  2471028: 2829:                a->push(v);
        -: 2830:            else
        -: 2831:            {
    #####: 2832:                Dsymbols *ax = new Dsymbols();
    #####: 2833:                ax->push(v);
    #####: 2834:                Dsymbol *s = new LinkDeclaration(link, ax);
    #####: 2835:                a->push(s);
        -: 2836:            }
  2471028: 2837:            switch (token.value)
        -: 2838:            {   case TOKsemicolon:
  2471028: 2839:                    nextToken();
  2471028: 2840:                    addComment(v, comment);
  2471028: 2841:                    break;
        -: 2842:
        -: 2843:                case TOKcomma:
    #####: 2844:                    nextToken();
    #####: 2845:                    addComment(v, comment);
    #####: 2846:                    continue;
        -: 2847:
        -: 2848:                default:
    #####: 2849:                    error("semicolon expected to close 
%s declaration", Token::toChars(tok));
        -: 2850:                    break;
        -: 2851:            }
        -: 2852:        }
 22909758: 2853:        else if (t->ty == Tfunction)
        -: 2854:        {
 11410434: 2855:            TypeFunction *tf = (TypeFunction *)t;
 11410434: 2856:            Expression *constraint = NULL;
        -: 2857:#if 0
        -: 2858:            if (Parameter::isTPL(tf->parameters))
        -: 2859:            {
        -: 2860:                if (!tpl)
        -: 2861:                    tpl = new TemplateParameters();
        -: 2862:            }
        -: 2863:#endif
        -: 2864:            FuncDeclaration *f =
 11410434: 2865:                new FuncDeclaration(loc, 0, ident, 
storage_class, t);
 11410434: 2866:            addComment(f, comment);
 11410434: 2867:            if (tpl)
  1547300: 2868:                constraint = parseConstraint();
 11410434: 2869:            parseContracts(f);
 11410434: 2870:            addComment(f, NULL);
        -: 2871:            Dsymbol *s;
 11410434: 2872:            if (link == linkage)
        -: 2873:            {
 11404180: 2874:                s = f;
        -: 2875:            }
        -: 2876:            else
        -: 2877:            {
     6254: 2878:                Dsymbols *ax = new Dsymbols();
     6254: 2879:                ax->push(f);
     6254: 2880:                s = new LinkDeclaration(link, ax);
        -: 2881:            }
        -: 2882:            /* A template parameter list means it's a 
function template
        -: 2883:             */
 11410434: 2884:            if (tpl)
        -: 2885:            {
        -: 2886:                // Wrap a template around the function 
declaration
  1547300: 2887:                Dsymbols *decldefs = new Dsymbols();
  1547300: 2888:                decldefs->push(s);
        -: 2889:                TemplateDeclaration *tempdecl =
  1547300: 2890:                    new TemplateDeclaration(loc, 
s->ident, tpl, constraint, decldefs, 0);
  1547300: 2891:                s = tempdecl;
        -: 2892:            }
 11410434: 2893:            addComment(s, comment);
 11410434: 2894:            a->push(s);
        -: 2895:        }
        -: 2896:        else
        -: 2897:        {
 11499324: 2898:            Initializer *init = NULL;
 11499324: 2899:            if (token.value == TOKassign)
        -: 2900:            {
  5443159: 2901:                nextToken();
  5443159: 2902:                init = parseInitializer();
        -: 2903:            }
        -: 2904:
 11499324: 2905:            VarDeclaration *v = new VarDeclaration(loc, 
t, ident, init);
 11499324: 2906:            v->storage_class = storage_class;
 11499324: 2907:            if (link == linkage)
 11499260: 2908:                a->push(v);
        -: 2909:            else
        -: 2910:            {
       64: 2911:                Dsymbols *ax = new Dsymbols();
       64: 2912:                ax->push(v);
       64: 2913:                Dsymbol *s = new LinkDeclaration(link, ax);
       64: 2914:                a->push(s);
        -: 2915:            }
 11499324: 2916:            switch (token.value)
        -: 2917:            {   case TOKsemicolon:
 11235797: 2918:                    nextToken();
 11235797: 2919:                    addComment(v, comment);
 11235797: 2920:                    break;
        -: 2921:
        -: 2922:                case TOKcomma:
   263527: 2923:                    nextToken();
   263527: 2924:                    addComment(v, comment);
   263527: 2925:                    continue;
        -: 2926:
        -: 2927:                default:
    #####: 2928:                    error("semicolon expected, not 
'%s'", token.toChars());
        -: 2929:                    break;
        -: 2930:            }
        -: 2931:        }
        -: 2932:        break;
        -: 2933:    }
 25117259: 2934:    return a;
        -: 2935:}
        -: 2936:
        -: 2937:/*****************************************
        -: 2938: * Parse auto declarations of the form:
        -: 2939: *   storageClass ident = init, ident = init, ... ;
        -: 2940: * and return the array of them.
        -: 2941: * Starts with token on the first ident.
        -: 2942: * Ends with scanner past closing ';'
        -: 2943: */
        -: 2944:
        -: 2945:#if DMDV2
  6232370: 2946:Dsymbols *Parser::parseAutoDeclarations(StorageClass 
storageClass, unsigned char *comment)
        -: 2947:{
  6232370: 2948:    Dsymbols *a = new Dsymbols;
        -: 2949:
    89911: 2950:    while (1)
        -: 2951:    {
  6322281: 2952:        Identifier *ident = token.ident;
  6322281: 2953:        nextToken();            // skip over ident
  6322281: 2954:        assert(token.value == TOKassign);
  6322281: 2955:        nextToken();            // skip over '='
  6322281: 2956:        Initializer *init = parseInitializer();
  6322281: 2957:        VarDeclaration *v = new VarDeclaration(loc, 
NULL, ident, init);
  6322281: 2958:        v->storage_class = storageClass;
  6322281: 2959:        a->push(v);
  6322281: 2960:        if (token.value == TOKsemicolon)
        -: 2961:        {
  6232370: 2962:            nextToken();
  6232370: 2963:            addComment(v, comment);
        -: 2964:        }
    89911: 2965:        else if (token.value == TOKcomma)
        -: 2966:        {
    89911: 2967:            nextToken();
    89911: 2968:            if (token.value == TOKidentifier &&
        -: 2969:                peek(&token)->value == TOKassign)
        -: 2970:            {
    89911: 2971:                addComment(v, comment);
        -: 2972:                continue;
        -: 2973:            }
        -: 2974:            else
    #####: 2975:                error("Identifier expected following 
comma");
        -: 2976:        }
        -: 2977:        else
    #####: 2978:            error("semicolon expected following auto 
declaration, not '%s'", token.toChars());
        -: 2979:        break;
        -: 2980:    }
  6232370: 2981:    return a;
        -: 2982:}
        -: 2983:#endif
        -: 2984:
        -: 2985:/*****************************************
        -: 2986: * Parse contracts following function declaration.
        -: 2987: */
        -: 2988:
 12079418: 2989:void Parser::parseContracts(FuncDeclaration *f)
        -: 2990:{
 12079418: 2991:    enum LINK linksave = linkage;
        -: 2992:
        -: 2993:    // The following is irrelevant, as it is overridden 
by sc->linkage in
        -: 2994:    // TypeFunction::semantic
 12079418: 2995:    linkage = LINKd;            // nested functions have 
D linkage
 12311691: 2996:L1:
 12311691: 2997:    switch (token.value)
        -: 2998:    {
        -: 2999:        case TOKlcurly:
  7059011: 3000:            if (f->frequire || f->fensure)
    #####: 3001:                error("missing body { ... } after in or 
out");
  7059011: 3002:            f->fbody = parseStatement(PSsemi);
  7059011: 3003:            f->endloc = endloc;
  7059011: 3004:            break;
        -: 3005:
        -: 3006:        case TOKbody:
   222873: 3007:            nextToken();
   222873: 3008:            f->fbody = parseStatement(PScurly);
   222873: 3009:            f->endloc = endloc;
   222873: 3010:            break;
        -: 3011:
        -: 3012:        case TOKsemicolon:
  4797526: 3013:            if (f->frequire || f->fensure)
    #####: 3014:                error("missing body { ... } after in or 
out");
  4797526: 3015:            nextToken();
  4797526: 3016:            break;
        -: 3017:
        -: 3018:#if 0   // Do we want this for function declarations, so 
we can do:
        -: 3019:    // int x, y, foo(), z;
        -: 3020:        case TOKcomma:
        -: 3021:            nextToken();
        -: 3022:            continue;
        -: 3023:#endif
        -: 3024:
        -: 3025:#if 0 // Dumped feature
        -: 3026:        case TOKthrow:
        -: 3027:            if (!f->fthrows)
        -: 3028:                f->fthrows = new Array();
        -: 3029:            nextToken();
        -: 3030:            check(TOKlparen);
        -: 3031:            while (1)
        -: 3032:            {
        -: 3033:                Type *tb = parseBasicType();
        -: 3034:                f->fthrows->push(tb);
        -: 3035:                if (token.value == TOKcomma)
        -: 3036:                {   nextToken();
        -: 3037:                    continue;
        -: 3038:                }
        -: 3039:                break;
        -: 3040:            }
        -: 3041:            check(TOKrparen);
        -: 3042:            goto L1;
        -: 3043:#endif
        -: 3044:
        -: 3045:        case TOKin:
   198423: 3046:            nextToken();
   198423: 3047:            if (f->frequire)
    #####: 3048:                error("redundant 'in' statement");
   198423: 3049:            f->frequire = parseStatement(PScurly | PSscope);
   198423: 3050:            goto L1;
        -: 3051:
        -: 3052:        case TOKout:
        -: 3053:            // parse: out (identifier) { statement }
    33850: 3054:            nextToken();
    33850: 3055:            if (token.value != TOKlcurly)
        -: 3056:            {
    27595: 3057:                check(TOKlparen);
    27595: 3058:                if (token.value != TOKidentifier)
    #####: 3059:                    error("(identifier) following 'out' 
expected, not %s", token.toChars());
    27595: 3060:                f->outId = token.ident;
    27595: 3061:                nextToken();
    27595: 3062:                check(TOKrparen);
        -: 3063:            }
    33850: 3064:            if (f->fensure)
    #####: 3065:                error("redundant 'out' statement");
    33850: 3066:            f->fensure = parseStatement(PScurly | PSscope);
    33850: 3067:            goto L1;
        -: 3068:
        -: 3069:        default:
        8: 3070:            if (!f->frequire && !f->fensure)            
// allow these even with no body
    #####: 3071:                error("semicolon expected following 
function declaration");
        -: 3072:            break;
        -: 3073:    }
 12079418: 3074:    linkage = linksave;
 12079418: 3075:}
        -: 3076:
        -: 3077:/*****************************************
        -: 3078: * Parse initializer for variable declaration.
        -: 3079: */
        -: 3080:
 18050480: 3081:Initializer *Parser::parseInitializer()
        -: 3082:{
        -: 3083:    StructInitializer *is;
        -: 3084:    ArrayInitializer *ia;
        -: 3085:    ExpInitializer *ie;
        -: 3086:    Expression *e;
        -: 3087:    Identifier *id;
        -: 3088:    Initializer *value;
        -: 3089:    int comma;
 18050480: 3090:    Loc loc = this->loc;
        -: 3091:    Token *t;
        -: 3092:    int braces;
        -: 3093:    int brackets;
        -: 3094:
 18050480: 3095:    switch (token.value)
        -: 3096:    {
        -: 3097:        case TOKlcurly:
        -: 3098:            /* Scan ahead to see if it is a struct 
initializer or
        -: 3099:             * a function literal.
        -: 3100:             * If it contains a ';', it is a function 
literal.
        -: 3101:             * Treat { } as a struct initializer.
        -: 3102:             */
   886119: 3103:            braces = 1;
  8277903: 3104:            for (t = peek(&token); 1; t = peek(t))
        -: 3105:            {
  8277903: 3106:                switch (t->value)
        -: 3107:                {
        -: 3108:                    case TOKsemicolon:
        -: 3109:                    case TOKreturn:
       64: 3110:                        goto Lexpression;
        -: 3111:
        -: 3112:                    case TOKlcurly:
       64: 3113:                        braces++;
       64: 3114:                        continue;
        -: 3115:
        -: 3116:                    case TOKrcurly:
   886055: 3117:                        if (--braces == 0)
   886055: 3118:                            break;
    #####: 3119:                        continue;
        -: 3120:
        -: 3121:                    case TOKeof:
    #####: 3122:                        break;
        -: 3123:
        -: 3124:                    default:
  7391720: 3125:                        continue;
        -: 3126:                }
        -: 3127:                break;
        -: 3128:            }
        -: 3129:
   886055: 3130:            is = new StructInitializer(loc);
   886055: 3131:            nextToken();
   886055: 3132:            comma = 0;
  6394219: 3133:            while (1)
        -: 3134:            {
  7280274: 3135:                switch (token.value)
        -: 3136:                {
        -: 3137:                    case TOKidentifier:
   370537: 3138:                        if (comma == 1)
    #####: 3139:                            error("comma expected 
separating field initializers");
   370537: 3140:                        t = peek(&token);
   370537: 3141:                        if (t->value == TOKcolon)
        -: 3142:                        {
      561: 3143:                            id = token.ident;
      561: 3144:                            nextToken();
      561: 3145:                            nextToken();        // skip 
over ':'
        -: 3146:                        }
        -: 3147:                        else
   369976: 3148:                        {   id = NULL;
        -: 3149:                        }
   370537: 3150:                        value = parseInitializer();
   370537: 3151:                        is->addInit(id, value);
   370537: 3152:                        comma = 1;
   370537: 3153:                        continue;
        -: 3154:
        -: 3155:                    case TOKcomma:
  2754242: 3156:                        nextToken();
  2754242: 3157:                        comma = 2;
  2754242: 3158:                        continue;
        -: 3159:
        -: 3160:                    case TOKrcurly:             // allow 
trailing comma's
   886055: 3161:                        nextToken();
   886055: 3162:                        break;
        -: 3163:
        -: 3164:                    case TOKeof:
    #####: 3165:                        error("found EOF instead of 
initializer");
    #####: 3166:                        break;
        -: 3167:
        -: 3168:                    default:
  3269440: 3169:                        value = parseInitializer();
  3269440: 3170:                        is->addInit(NULL, value);
  3269440: 3171:                        comma = 1;
  3269440: 3172:                        continue;
        -: 3173:                        //error("found '%s' instead of 
field initializer", token.toChars());
        -: 3174:                        //break;
        -: 3175:                }
        -: 3176:                break;
        -: 3177:            }
   886055: 3178:            return is;
        -: 3179:
        -: 3180:        case TOKlbracket:
        -: 3181:            /* Scan ahead to see if it is an array 
initializer or
        -: 3182:             * an expression.
        -: 3183:             * If it ends with a ';' ',' or '}', it is 
an array initializer.
        -: 3184:             */
  2474010: 3185:            brackets = 1;
 42819179: 3186:            for (t = peek(&token); 1; t = peek(t))
        -: 3187:            {
 42819179: 3188:                switch (t->value)
        -: 3189:                {
        -: 3190:                    case TOKlbracket:
  1753271: 3191:                        brackets++;
  1753271: 3192:                        continue;
        -: 3193:
        -: 3194:                    case TOKrbracket:
  4227281: 3195:                        if (--brackets == 0)
  2474010: 3196:                        {   t = peek(t);
  2474010: 3197:                            if (t->value != TOKsemicolon &&
        -: 3198:                                t->value != TOKcomma &&
        -: 3199:                                t->value != TOKrbracket &&
        -: 3200:                                t->value != TOKrcurly)
    #####: 3201:                                goto Lexpression;
  2474010: 3202:                            break;
        -: 3203:                        }
  1753271: 3204:                        continue;
        -: 3205:
        -: 3206:                    case TOKeof:
    #####: 3207:                        break;
        -: 3208:
        -: 3209:                    default:
 36838627: 3210:                        continue;
        -: 3211:                }
        -: 3212:                break;
        -: 3213:            }
        -: 3214:
  2474010: 3215:            ia = new ArrayInitializer(loc);
  2474010: 3216:            nextToken();
  2474010: 3217:            comma = 0;
 22612877: 3218:            while (1)
        -: 3219:            {
 25086887: 3220:                switch (token.value)
        -: 3221:                {
        -: 3222:                    default:
  9900016: 3223:                        if (comma == 1)
    #####: 3224:                        {   error("comma expected 
separating array initializers, not %s", token.toChars());
    #####: 3225:                            nextToken();
    #####: 3226:                            break;
        -: 3227:                        }
  9900016: 3228:                        e = parseAssignExp();
  9900016: 3229:                        if (!e)
    #####: 3230:                            break;
  9900016: 3231:                        if (token.value == TOKcolon)
        -: 3232:                        {
    53271: 3233:                            nextToken();
    53271: 3234:                            value = parseInitializer();
        -: 3235:                        }
        -: 3236:                        else
  9846745: 3237:                        {   value = new 
ExpInitializer(e->loc, e);
  9846745: 3238:                            e = NULL;
        -: 3239:                        }
  9900016: 3240:                        ia->addInit(e, value);
  9900016: 3241:                        comma = 1;
  9900016: 3242:                        continue;
        -: 3243:
        -: 3244:                    case TOKlcurly:
        -: 3245:                    case TOKlbracket:
  2590505: 3246:                        if (comma == 1)
    #####: 3247:                            error("comma expected 
separating array initializers, not %s", token.toChars());
  2590505: 3248:                        value = parseInitializer();
  2590505: 3249:                        ia->addInit(NULL, value);
  2590505: 3250:                        comma = 1;
  2590505: 3251:                        continue;
        -: 3252:
        -: 3253:                    case TOKcomma:
 10122356: 3254:                        nextToken();
 10122356: 3255:                        comma = 2;
 10122356: 3256:                        continue;
        -: 3257:
        -: 3258:                    case TOKrbracket:           // allow 
trailing comma's
  2474010: 3259:                        nextToken();
  2474010: 3260:                        break;
        -: 3261:
        -: 3262:                    case TOKeof:
    #####: 3263:                        error("found '%s' instead of 
array initializer", token.toChars());
        -: 3264:                        break;
        -: 3265:                }
        -: 3266:                break;
        -: 3267:            }
  2474010: 3268:            return ia;
        -: 3269:
        -: 3270:        case TOKvoid:
   183356: 3271:            t = peek(&token);
   183356: 3272:            if (t->value == TOKsemicolon || t->value == 
TOKcomma)
        -: 3273:            {
   183292: 3274:                nextToken();
   183292: 3275:                return new VoidInitializer(loc);
        -: 3276:            }
        -: 3277:            goto Lexpression;
        -: 3278:
        -: 3279:        default:
 14507123: 3280:        Lexpression:
 14507123: 3281:            e = parseAssignExp();
 14507123: 3282:            ie = new ExpInitializer(loc, e);
 14507123: 3283:            return ie;
        -: 3284:    }
        -: 3285:}
        -: 3286:
        -: 3287:/*****************************************
        -: 3288: * Parses default argument initializer expression that 
is an assign expression,
        -: 3289: * with special handling for __FILE__ and __LINE__.
        -: 3290: */
        -: 3291:
        -: 3292:#if DMDV2
   525662: 3293:Expression *Parser::parseDefaultInitExp()
        -: 3294:{
   525662: 3295:    if (token.value == TOKfile ||
        -: 3296:        token.value == TOKline)
        -: 3297:    {
    48944: 3298:        Token *t = peek(&token);
    48944: 3299:        if (t->value == TOKcomma || t->value == TOKrparen)
        -: 3300:        {   Expression *e;
        -: 3301:
    48816: 3302:            if (token.value == TOKfile)
    24376: 3303:                e = new FileInitExp(loc);
        -: 3304:            else
    24440: 3305:                e = new LineInitExp(loc);
    48816: 3306:            nextToken();
    48816: 3307:            return e;
        -: 3308:        }
        -: 3309:    }
        -: 3310:
   476846: 3311:    Expression *e = parseAssignExp();
   476846: 3312:    return e;
        -: 3313:}
        -: 3314:#endif
        -: 3315:
        -: 3316:/*****************************************
        -: 3317: * Input:
        -: 3318: *      flags   PSxxxx
        -: 3319: */
        -: 3320:
 82913462: 3321:Statement *Parser::parseStatement(int flags)
        -: 3322:{   Statement *s;
        -: 3323:    Token *t;
        -: 3324:    Condition *condition;
        -: 3325:    Statement *ifbody;
        -: 3326:    Statement *elsebody;
        -: 3327:    bool isfinal;
 82913462: 3328:    Loc loc = this->loc;
        -: 3329:
        -: 3330:    //printf("parseStatement()\n");
        -: 3331:
 82913462: 3332:    if (flags & PScurly && token.value != TOKlcurly)
    #####: 3333:        error("statement expected to be { }, not %s", 
token.toChars());
        -: 3334:
 82913462: 3335:    switch (token.value)
        -: 3336:    {
        -: 3337:        case TOKidentifier:
        -: 3338:            /* A leading identifier can be a 
declaration, label, or expression.
        -: 3339:             * The easiest case to check first is label:
        -: 3340:             */
 22247565: 3341:            t = peek(&token);
 22247565: 3342:            if (t->value == TOKcolon)
        -: 3343:            {   // It's a label
        -: 3344:
   255672: 3345:                Identifier *ident = token.ident;
   255672: 3346:                nextToken();
   255672: 3347:                nextToken();
   255672: 3348:                s = parseStatement(PSsemi);
   255672: 3349:                s = new LabelStatement(loc, ident, s);
   255672: 3350:                break;
        -: 3351:            }
        -: 3352:            // fallthrough to TOKdot
        -: 3353:        case TOKdot:
        -: 3354:        case TOKtypeof:
 22078853: 3355:            if (isDeclaration(&token, 2, TOKreserved, NULL))
  2364602: 3356:                goto Ldeclaration;
        -: 3357:            else
 19714251: 3358:                goto Lexp;
        -: 3359:            break;
        -: 3360:
        -: 3361:        case TOKassert:
        -: 3362:        case TOKthis:
        -: 3363:        case TOKsuper:
        -: 3364:        case TOKint32v:
        -: 3365:        case TOKuns32v:
        -: 3366:        case TOKint64v:
        -: 3367:        case TOKuns64v:
        -: 3368:        case TOKfloat32v:
        -: 3369:        case TOKfloat64v:
        -: 3370:        case TOKfloat80v:
        -: 3371:        case TOKimaginary32v:
        -: 3372:        case TOKimaginary64v:
        -: 3373:        case TOKimaginary80v:
        -: 3374:        case TOKcharv:
        -: 3375:        case TOKwcharv:
        -: 3376:        case TOKdcharv:
        -: 3377:        case TOKnull:
        -: 3378:        case TOKtrue:
        -: 3379:        case TOKfalse:
        -: 3380:        case TOKstring:
        -: 3381:        case TOKlparen:
        -: 3382:        case TOKcast:
        -: 3383:        case TOKmul:
        -: 3384:        case TOKmin:
        -: 3385:        case TOKadd:
        -: 3386:        case TOKtilde:
        -: 3387:        case TOKnot:
        -: 3388:        case TOKplusplus:
        -: 3389:        case TOKminusminus:
        -: 3390:        case TOKnew:
        -: 3391:        case TOKdelete:
        -: 3392:        case TOKdelegate:
        -: 3393:        case TOKfunction:
        -: 3394:        case TOKtypeid:
        -: 3395:        case TOKis:
        -: 3396:        case TOKlbracket:
        -: 3397:#if DMDV2
        -: 3398:        case TOKtraits:
        -: 3399:        case TOKfile:
        -: 3400:        case TOKline:
        -: 3401:#endif
 29750427: 3402:        Lexp:
        -: 3403:        {
 29750427: 3404:            Expression *exp = parseExpression();
 29750427: 3405:            check(TOKsemicolon, "statement");
 29750427: 3406:            s = new ExpStatement(loc, exp);
 29750427: 3407:            break;
        -: 3408:        }
        -: 3409:
        -: 3410:        case TOKstatic:
        -: 3411:        {   // Look ahead to see if it's static assert() 
or static if()
        -: 3412:            Token *t;
        -: 3413:
  3127351: 3414:            t = peek(&token);
  3127351: 3415:            if (t->value == TOKassert)
        -: 3416:            {
  1880375: 3417:                nextToken();
  1880375: 3418:                s = new 
StaticAssertStatement(parseStaticAssert());
  1880375: 3419:                break;
        -: 3420:            }
  1246976: 3421:            if (t->value == TOKif)
        -: 3422:            {
   859038: 3423:                nextToken();
   859038: 3424:                condition = parseStaticIfCondition();
   859038: 3425:                goto Lcondition;
        -: 3426:            }
   387938: 3427:            if (t->value == TOKstruct || t->value == 
TOKunion || t->value == TOKclass)
        -: 3428:            {
    21475: 3429:                nextToken();
    21475: 3430:                Dsymbols *a = parseBlock();
    21475: 3431:                Dsymbol *d = new 
StorageClassDeclaration(STCstatic, a);
    21475: 3432:                s = new DeclarationStatement(loc, d);
    21475: 3433:                if (flags & PSscope)
    #####: 3434:                    s = new ScopeStatement(loc, s);
    21475: 3435:                break;
        -: 3436:            }
   366463: 3437:            goto Ldeclaration;
        -: 3438:        }
        -: 3439:
        -: 3440:        case TOKfinal:
     6129: 3441:            if (peekNext() == TOKswitch)
        -: 3442:            {
     6129: 3443:                nextToken();
     6129: 3444:                isfinal = TRUE;
     6129: 3445:                goto Lswitch;
        -: 3446:            }
        -: 3447:            goto Ldeclaration;
        -: 3448:
        -: 3449:        case BASIC_TYPES:
        -: 3450:        case TOKtypedef:
        -: 3451:        case TOKalias:
        -: 3452:        case TOKconst:
        -: 3453:        case TOKauto:
        -: 3454:        case TOKextern:
        -: 3455:        case TOKinvariant:
        -: 3456:#if DMDV2
        -: 3457:        case TOKimmutable:
        -: 3458:        case TOKshared:
        -: 3459:        case TOKwild:
        -: 3460:        case TOKnothrow:
        -: 3461:        case TOKpure:
        -: 3462:        case TOKtls:
        -: 3463:        case TOKgshared:
        -: 3464:        case TOKat:
        -: 3465:#endif
        -: 3466://      case TOKtypeof:
 10612581: 3467:        Ldeclaration:
        -: 3468:        {   Array *a;
        -: 3469:
 10612581: 3470:            a = parseDeclarations(STCundefined);
 10612581: 3471:            if (a->dim > 1)
        -: 3472:            {
   201778: 3473:                Statements *as = new Statements();
   201778: 3474:                as->reserve(a->dim);
   677506: 3475:                for (int i = 0; i < a->dim; i++)
        -: 3476:                {
   475728: 3477:                    Dsymbol *d = (Dsymbol *)a->data[i];
   475728: 3478:                    s = new DeclarationStatement(loc, d);
   475728: 3479:                    as->push(s);
        -: 3480:                }
   201778: 3481:                s = new 
CompoundDeclarationStatement(loc, as);
        -: 3482:            }
 10410803: 3483:            else if (a->dim == 1)
        -: 3484:            {
 10410803: 3485:                Dsymbol *d = (Dsymbol *)a->data[0];
 10410803: 3486:                s = new DeclarationStatement(loc, d);
        -: 3487:            }
        -: 3488:            else
    #####: 3489:                assert(0);
 10612581: 3490:            if (flags & PSscope)
      960: 3491:                s = new ScopeStatement(loc, s);
 10612581: 3492:            break;
        -: 3493:        }
        -: 3494:
        -: 3495:        case TOKstruct:
        -: 3496:        case TOKunion:
        -: 3497:        case TOKclass:
        -: 3498:        case TOKinterface:
        -: 3499:        {   Dsymbol *d;
        -: 3500:
   566284: 3501:            d = parseAggregate();
   566284: 3502:            s = new DeclarationStatement(loc, d);
   566284: 3503:            break;
        -: 3504:        }
        -: 3505:
        -: 3506:        case TOKenum:
        -: 3507:        {   /* Determine if this is a manifest constant 
declaration,
        -: 3508:             * or a conventional enum.
        -: 3509:             */
        -: 3510:            Dsymbol *d;
   192293: 3511:            Token *t = peek(&token);
   201642: 3512:            if (t->value == TOKlcurly || t->value == 
TOKcolon)
     9349: 3513:                d = parseEnum();
   182944: 3514:            else if (t->value != TOKidentifier)
    44285: 3515:                goto Ldeclaration;
        -: 3516:            else
        -: 3517:            {
   138659: 3518:                t = peek(t);
   138659: 3519:                if (t->value == TOKlcurly || t->value == 
TOKcolon ||
        -: 3520:                    t->value == TOKsemicolon)
    45727: 3521:                    d = parseEnum();
        -: 3522:                else
        -: 3523:                    goto Ldeclaration;
        -: 3524:            }
    55076: 3525:            s = new DeclarationStatement(loc, d);
    55076: 3526:            break;
        -: 3527:        }
        -: 3528:
        -: 3529:        case TOKmixin:
    55823: 3530:        {   t = peek(&token);
    55823: 3531:            if (t->value == TOKlparen)
        -: 3532:            {   // mixin(string)
    33646: 3533:                nextToken();
    33646: 3534:                check(TOKlparen, "mixin");
    33646: 3535:                Expression *e = parseAssignExp();
    33646: 3536:                check(TOKrparen);
    33646: 3537:                check(TOKsemicolon);
    33646: 3538:                s = new CompileStatement(loc, e);
    33646: 3539:                break;
        -: 3540:            }
    22177: 3541:            Dsymbol *d = parseMixin();
    22177: 3542:            s = new DeclarationStatement(loc, d);
    22177: 3543:            break;
        -: 3544:        }
        -: 3545:
        -: 3546:        case TOKlcurly:
        -: 3547:        {
 16476514: 3548:            nextToken();
        -: 3549:            //if (token.value == TOKsemicolon)
        -: 3550:                //error("use '{ }' for an empty 
statement, not a ';'");
 16476514: 3551:            Statements *statements = new Statements();
 87143056: 3552:            while (token.value != TOKrcurly && 
token.value != TOKeof)
        -: 3553:            {
 54190028: 3554:                statements->push(parseStatement(PSsemi | 
PScurlyscope));
        -: 3555:            }
 16476514: 3556:            endloc = this->loc;
 16476514: 3557:            s = new CompoundStatement(loc, statements);
 16476514: 3558:            if (flags & (PSscope | PScurlyscope))
  4866296: 3559:                s = new ScopeStatement(loc, s);
 16476514: 3560:            check(TOKrcurly, "compound statement");
 16476514: 3561:            break;
        -: 3562:        }
        -: 3563:
        -: 3564:        case TOKwhile:
        -: 3565:        {   Expression *condition;
        -: 3566:            Statement *body;
        -: 3567:
   349305: 3568:            nextToken();
   349305: 3569:            check(TOKlparen);
   349305: 3570:            condition = parseExpression();
   349305: 3571:            check(TOKrparen);
   349305: 3572:            body = parseStatement(PSscope);
   349305: 3573:            s = new WhileStatement(loc, condition, body);
   349305: 3574:            break;
        -: 3575:        }
        -: 3576:
        -: 3577:        case TOKsemicolon:
   114314: 3578:            if (!(flags & PSsemi))
    #####: 3579:                error("use '{ }' for an empty statement, 
not a ';'");
   114314: 3580:            nextToken();
   114314: 3581:            s = new ExpStatement(loc, NULL);
   114314: 3582:            break;
        -: 3583:
        -: 3584:        case TOKdo:
        -: 3585:        {   Statement *body;
        -: 3586:            Expression *condition;
        -: 3587:
    66404: 3588:            nextToken();
    66404: 3589:            body = parseStatement(PSscope);
    66404: 3590:            check(TOKwhile);
    66404: 3591:            check(TOKlparen);
    66404: 3592:            condition = parseExpression();
    66404: 3593:            check(TOKrparen);
    66404: 3594:            s = new DoStatement(loc, body, condition);
    66404: 3595:            break;
        -: 3596:        }
        -: 3597:
        -: 3598:        case TOKfor:
        -: 3599:        {
        -: 3600:            Statement *init;
        -: 3601:            Expression *condition;
        -: 3602:            Expression *increment;
        -: 3603:            Statement *body;
        -: 3604:
   887570: 3605:            nextToken();
   887570: 3606:            check(TOKlparen);
   887570: 3607:            if (token.value == TOKsemicolon)
   312011: 3608:            {   init = NULL;
   312011: 3609:                nextToken();
        -: 3610:            }
        -: 3611:            else
   575559: 3612:            {   init = parseStatement(0);
        -: 3613:            }
   887570: 3614:            if (token.value == TOKsemicolon)
        -: 3615:            {
   140494: 3616:                condition = NULL;
   140494: 3617:                nextToken();
        -: 3618:            }
        -: 3619:            else
        -: 3620:            {
   747076: 3621:                condition = parseExpression();
   747076: 3622:                check(TOKsemicolon, "for condition");
        -: 3623:            }
   887570: 3624:            if (token.value == TOKrparen)
   230003: 3625:            {   increment = NULL;
   230003: 3626:                nextToken();
        -: 3627:            }
        -: 3628:            else
   657567: 3629:            {   increment = parseExpression();
   657567: 3630:                check(TOKrparen);
        -: 3631:            }
   887570: 3632:            body = parseStatement(PSscope);
   887570: 3633:            s = new ForStatement(loc, init, condition, 
increment, body);
   887570: 3634:            if (init)
   575559: 3635:                s = new ScopeStatement(loc, s);
   887570: 3636:            break;
        -: 3637:        }
        -: 3638:
        -: 3639:        case TOKforeach:
        -: 3640:        case TOKforeach_reverse:
        -: 3641:        {
  1045217: 3642:            enum TOK op = token.value;
        -: 3643:
  1045217: 3644:            nextToken();
  1045217: 3645:            check(TOKlparen);
        -: 3646:
  1045217: 3647:            Parameters *arguments = new Parameters();
        -: 3648:
   271473: 3649:            while (1)
        -: 3650:            {
  1316690: 3651:                Identifier *ai = NULL;
        -: 3652:                Type *at;
        -: 3653:
  1316690: 3654:                StorageClass storageClass = 0;
  1316690: 3655:                if (token.value == TOKref
        -: 3656:#if D1INOUT
        -: 3657:                        || token.value == TOKinout
        -: 3658:#endif
        -: 3659:                   )
    71511: 3660:                {   storageClass = STCref;
    71511: 3661:                    nextToken();
        -: 3662:                }
  1316690: 3663:                if (token.value == TOKidentifier)
        -: 3664:                {
  1176122: 3665:                    Token *t = peek(&token);
  1176122: 3666:                    if (t->value == TOKcomma || t->value 
== TOKsemicolon)
  1092215: 3667:                    {   ai = token.ident;
  1092215: 3668:                        at = NULL;              // infer 
argument type
  1092215: 3669:                        nextToken();
  1092215: 3670:                        goto Larg;
        -: 3671:                    }
        -: 3672:                }
   224475: 3673:                at = parseType(&ai);
   224475: 3674:                if (!ai)
    #####: 3675:                    error("no identifier for declarator 
%s", at->toChars());
  1316690: 3676:              Larg:
  1316690: 3677:                Parameter *a = new 
Parameter(storageClass, at, ai, NULL);
  1316690: 3678:                arguments->push(a);
  1316690: 3679:                if (token.value == TOKcomma)
   271473: 3680:                {   nextToken();
        -: 3681:                    continue;
        -: 3682:                }
        -: 3683:                break;
        -: 3684:            }
  1045217: 3685:            check(TOKsemicolon);
        -: 3686:
  1045217: 3687:            Expression *aggr = parseExpression();
  1254138: 3688:            if (token.value == TOKslice && 
arguments->dim == 1)
        -: 3689:            {
   208921: 3690:                Parameter *a = (Parameter 
*)arguments->data[0];
   208921: 3691:                delete arguments;
   208921: 3692:                nextToken();
   208921: 3693:                Expression *upr = parseExpression();
   208921: 3694:                check(TOKrparen);
   208921: 3695:                Statement *body = parseStatement(0);
   208921: 3696:                s = new ForeachRangeStatement(loc, op, 
a, aggr, upr, body);
        -: 3697:            }
        -: 3698:            else
        -: 3699:            {
   836296: 3700:                check(TOKrparen);
   836296: 3701:                Statement *body = parseStatement(0);
   836296: 3702:                s = new ForeachStatement(loc, op, 
arguments, aggr, body);
        -: 3703:            }
  1045217: 3704:            break;
        -: 3705:        }
        -: 3706:
        -: 3707:        case TOKif:
  5606096: 3708:        {   Parameter *arg = NULL;
        -: 3709:            Expression *condition;
        -: 3710:            Statement *ifbody;
        -: 3711:            Statement *elsebody;
        -: 3712:
  5606096: 3713:            nextToken();
  5606096: 3714:            check(TOKlparen);
        -: 3715:
  5606096: 3716:            if (token.value == TOKauto)
        -: 3717:            {
     6256: 3718:                nextToken();
     6256: 3719:                if (token.value == TOKidentifier)
        -: 3720:                {
     6256: 3721:                    Token *t = peek(&token);
     6256: 3722:                    if (t->value == TOKassign)
        -: 3723:                    {
     6256: 3724:                        arg = new Parameter(0, NULL, 
token.ident, NULL);
     6256: 3725:                        nextToken();
     6256: 3726:                        nextToken();
        -: 3727:                    }
        -: 3728:                    else
    #####: 3729:                    {   error("= expected following auto 
identifier");
    #####: 3730:                        goto Lerror;
        -: 3731:                    }
        -: 3732:                }
        -: 3733:                else
    #####: 3734:                {   error("identifier expected following 
auto");
    #####: 3735:                    goto Lerror;
        -: 3736:                }
        -: 3737:            }
  5599840: 3738:            else if (isDeclaration(&token, 2, TOKassign, 
NULL))
        -: 3739:            {
        -: 3740:                Type *at;
        -: 3741:                Identifier *ai;
        -: 3742:
     6126: 3743:                at = parseType(&ai);
     6126: 3744:                check(TOKassign);
     6126: 3745:                arg = new Parameter(0, at, ai, NULL);
        -: 3746:            }
        -: 3747:
        -: 3748:            // Check for " ident;"
  5593714: 3749:            else if (token.value == TOKidentifier)
        -: 3750:            {
  4504198: 3751:                Token *t = peek(&token);
  4504198: 3752:                if (t->value == TOKcomma || t->value == 
TOKsemicolon)
        -: 3753:                {
    #####: 3754:                    arg = new Parameter(0, NULL, 
token.ident, NULL);
    #####: 3755:                    nextToken();
    #####: 3756:                    nextToken();
        -: 3757:                    if (1 || !global.params.useDeprecated)
    #####: 3758:                        error("if (v; e) is deprecated, 
use if (auto v = e)");
        -: 3759:                }
        -: 3760:            }
        -: 3761:
  5606096: 3762:            condition = parseExpression();
  5606096: 3763:            check(TOKrparen);
  5606096: 3764:            ifbody = parseStatement(PSscope);
  5606096: 3765:            if (token.value == TOKelse)
        -: 3766:            {
  1571282: 3767:                nextToken();
  1571282: 3768:                elsebody = parseStatement(PSscope);
        -: 3769:            }
        -: 3770:            else
  4034814: 3771:                elsebody = NULL;
  5606096: 3772:            s = new IfStatement(loc, arg, condition, 
ifbody, elsebody);
  5606096: 3773:            break;
        -: 3774:        }
        -: 3775:
        -: 3776:        case TOKscope:
   379041: 3777:            if (peek(&token)->value != TOKlparen)
      910: 3778:                goto Ldeclaration;              // scope 
used as storage class
   378131: 3779:            nextToken();
   378131: 3780:            check(TOKlparen);
   378131: 3781:            if (token.value != TOKidentifier)
    #####: 3782:            {   error("scope identifier expected");
    #####: 3783:                goto Lerror;
        -: 3784:            }
        -: 3785:            else
   378131: 3786:            {   TOK t = TOKon_scope_exit;
   378131: 3787:                Identifier *id = token.ident;
        -: 3788:
   378131: 3789:                if (id == Id::exit)
   164396: 3790:                    t = TOKon_scope_exit;
   213735: 3791:                else if (id == Id::failure)
    40960: 3792:                    t = TOKon_scope_failure;
   172775: 3793:                else if (id == Id::success)
   172775: 3794:                    t = TOKon_scope_success;
        -: 3795:                else
    #####: 3796:                    error("valid scope identifiers are 
exit, failure, or success, not %s", id->toChars());
   378131: 3797:                nextToken();
   378131: 3798:                check(TOKrparen);
   378131: 3799:                Statement *st = 
parseStatement(PScurlyscope);
   378131: 3800:                s = new OnScopeStatement(loc, t, st);
   378131: 3801:                break;
        -: 3802:            }
        -: 3803:
        -: 3804:        case TOKdebug:
   937932: 3805:            nextToken();
   937932: 3806:            condition = parseDebugCondition();
   937932: 3807:            goto Lcondition;
        -: 3808:
        -: 3809:        case TOKversion:
   392679: 3810:            nextToken();
   392679: 3811:            condition = parseVersionCondition();
        -: 3812:            goto Lcondition;
        -: 3813:
  2189649: 3814:        Lcondition:
  2189649: 3815:            ifbody = parseStatement(0 /*PSsemi*/);
  2189649: 3816:            elsebody = NULL;
  2189649: 3817:            if (token.value == TOKelse)
        -: 3818:            {
   802427: 3819:                nextToken();
   802427: 3820:                elsebody = parseStatement(0 /*PSsemi*/);
        -: 3821:            }
  2189649: 3822:            s = new ConditionalStatement(loc, condition, 
ifbody, elsebody);
  2189649: 3823:            break;
        -: 3824:
        -: 3825:        case TOKpragma:
        -: 3826:        {   Identifier *ident;
    16303: 3827:            Expressions *args = NULL;
        -: 3828:            Statement *body;
        -: 3829:
    16303: 3830:            nextToken();
    16303: 3831:            check(TOKlparen);
    16303: 3832:            if (token.value != TOKidentifier)
    #####: 3833:            {   error("pragma(identifier expected");
    #####: 3834:                goto Lerror;
        -: 3835:            }
    16303: 3836:            ident = token.ident;
    16303: 3837:            nextToken();
    16303: 3838:            if (token.value == TOKcomma && peekNext() != 
TOKrparen)
    16303: 3839:                args = parseArguments();        // 
pragma(identifier, args...);
        -: 3840:            else
    #####: 3841:                check(TOKrparen);               // 
pragma(identifier);
    16303: 3842:            if (token.value == TOKsemicolon)
    16303: 3843:            {   nextToken();
    16303: 3844:                body = NULL;
        -: 3845:            }
        -: 3846:            else
    #####: 3847:                body = parseStatement(PSsemi);
    16303: 3848:            s = new PragmaStatement(loc, ident, args, body);
    16303: 3849:            break;
        -: 3850:        }
        -: 3851:
        -: 3852:        case TOKswitch:
   243002: 3853:            isfinal = FALSE;
        -: 3854:            goto Lswitch;
        -: 3855:
   249131: 3856:        Lswitch:
        -: 3857:        {
   249131: 3858:            nextToken();
   249131: 3859:            check(TOKlparen);
   249131: 3860:            Expression *condition = parseExpression();
   249131: 3861:            check(TOKrparen);
   249131: 3862:            Statement *body = parseStatement(PSscope);
   249131: 3863:            s = new SwitchStatement(loc, condition, 
body, isfinal);
   249131: 3864:            break;
        -: 3865:        }
        -: 3866:
        -: 3867:        case TOKcase:
        -: 3868:        {   Expression *exp;
        -: 3869:            Statements *statements;
  2005075: 3870:            Array cases;        // array of Expression's
  2005075: 3871:            Expression *last = NULL;
        -: 3872:
    24320: 3873:            while (1)
        -: 3874:            {
  2029395: 3875:                nextToken();
  2029395: 3876:                exp = parseAssignExp();
  2029395: 3877:                cases.push(exp);
  2029395: 3878:                if (token.value != TOKcomma)
  2005075: 3879:                    break;
        -: 3880:            }
  2005075: 3881:            check(TOKcolon);
        -: 3882:
        -: 3883:#if DMDV2
        -: 3884:            /* case exp: .. case last:
        -: 3885:             */
  2005075: 3886:            if (token.value == TOKslice)
        -: 3887:            {
     3036: 3888:                if (cases.dim > 1)
    #####: 3889:                    error("only one case allowed for 
start of case range");
     3036: 3890:                nextToken();
     3036: 3891:                check(TOKcase);
     3036: 3892:                last = parseAssignExp();
     3036: 3893:                check(TOKcolon);
        -: 3894:            }
        -: 3895:#endif
        -: 3896:
  2005075: 3897:            statements = new Statements();
  8726521: 3898:            while (token.value != TOKcase &&
        -: 3899:                   token.value != TOKdefault &&
        -: 3900:                   token.value != TOKeof &&
        -: 3901:                   token.value != TOKrcurly)
        -: 3902:            {
  4716371: 3903:                statements->push(parseStatement(PSsemi | 
PScurlyscope));
        -: 3904:            }
  2005075: 3905:            s = new CompoundStatement(loc, statements);
  2005075: 3906:            s = new ScopeStatement(loc, s);
        -: 3907:
        -: 3908:#if DMDV2
  2005075: 3909:            if (last)
        -: 3910:            {
     3036: 3911:                s = new CaseRangeStatement(loc, exp, 
last, s);
        -: 3912:            }
        -: 3913:            else
        -: 3914:#endif
        -: 3915:            {
        -: 3916:                // Keep cases in order by building the 
case statements backwards
  4028398: 3917:                for (int i = cases.dim; i; i--)
        -: 3918:                {
  2026359: 3919:                    exp = (Expression *)cases.data[i - 1];
  2026359: 3920:                    s = new CaseStatement(loc, exp, s);
        -: 3921:                }
        -: 3922:            }
  2005075: 3923:            break;
        -: 3924:        }
        -: 3925:
        -: 3926:        case TOKdefault:
        -: 3927:        {
        -: 3928:            Statements *statements;
        -: 3929:
   242013: 3930:            nextToken();
   242013: 3931:            check(TOKcolon);
        -: 3932:
   242013: 3933:            statements = new Statements();
   920646: 3934:            while (token.value != TOKcase &&
        -: 3935:                   token.value != TOKdefault &&
        -: 3936:                   token.value != TOKeof &&
        -: 3937:                   token.value != TOKrcurly)
        -: 3938:            {
   436620: 3939:                statements->push(parseStatement(PSsemi | 
PScurlyscope));
        -: 3940:            }
   242013: 3941:            s = new CompoundStatement(loc, statements);
   242013: 3942:            s = new ScopeStatement(loc, s);
   242013: 3943:            s = new DefaultStatement(loc, s);
   242013: 3944:            break;
        -: 3945:        }
        -: 3946:
        -: 3947:        case TOKreturn:
        -: 3948:        {   Expression *exp;
        -: 3949:
  7049282: 3950:            nextToken();
  7049282: 3951:            if (token.value == TOKsemicolon)
   291164: 3952:                exp = NULL;
        -: 3953:            else
  6758118: 3954:                exp = parseExpression();
  7049282: 3955:            check(TOKsemicolon, "return statement");
  7049282: 3956:            s = new ReturnStatement(loc, exp);
  7049282: 3957:            break;
        -: 3958:        }
        -: 3959:
        -: 3960:        case TOKbreak:
        -: 3961:        {   Identifier *ident;
        -: 3962:
  1499225: 3963:            nextToken();
  1499225: 3964:            if (token.value == TOKidentifier)
     5227: 3965:            {   ident = token.ident;
     5227: 3966:                nextToken();
        -: 3967:            }
        -: 3968:            else
  1493998: 3969:                ident = NULL;
  1499225: 3970:            check(TOKsemicolon, "break statement");
  1499225: 3971:            s = new BreakStatement(loc, ident);
  1499225: 3972:            break;
        -: 3973:        }
        -: 3974:
        -: 3975:        case TOKcontinue:
        -: 3976:        {   Identifier *ident;
        -: 3977:
   255913: 3978:            nextToken();
   255913: 3979:            if (token.value == TOKidentifier)
     5032: 3980:            {   ident = token.ident;
     5032: 3981:                nextToken();
        -: 3982:            }
        -: 3983:            else
   250881: 3984:                ident = NULL;
   255913: 3985:            check(TOKsemicolon, "continue statement");
   255913: 3986:            s = new ContinueStatement(loc, ident);
   255913: 3987:            break;
        -: 3988:        }
        -: 3989:
        -: 3990:        case TOKgoto:
        -: 3991:        {   Identifier *ident;
        -: 3992:
   930028: 3993:            nextToken();
   930028: 3994:            if (token.value == TOKdefault)
        -: 3995:            {
       99: 3996:                nextToken();
       99: 3997:                s = new GotoDefaultStatement(loc);
        -: 3998:            }
   929929: 3999:            else if (token.value == TOKcase)
        -: 4000:            {
     6147: 4001:                Expression *exp = NULL;
        -: 4002:
     6147: 4003:                nextToken();
     6147: 4004:                if (token.value != TOKsemicolon)
     6146: 4005:                    exp = parseExpression();
     6147: 4006:                s = new GotoCaseStatement(loc, exp);
        -: 4007:            }
        -: 4008:            else
        -: 4009:            {
   923782: 4010:                if (token.value != TOKidentifier)
    #####: 4011:                {   error("Identifier expected following 
goto");
    #####: 4012:                    ident = NULL;
        -: 4013:                }
        -: 4014:                else
   923782: 4015:                {   ident = token.ident;
   923782: 4016:                    nextToken();
        -: 4017:                }
   923782: 4018:                s = new GotoStatement(loc, ident);
        -: 4019:            }
   930028: 4020:            check(TOKsemicolon, "goto statement");
   930028: 4021:            break;
        -: 4022:        }
        -: 4023:
        -: 4024:        case TOKsynchronized:
        -: 4025:        {   Expression *exp;
        -: 4026:            Statement *body;
        -: 4027:
      455: 4028:            nextToken();
      455: 4029:            if (token.value == TOKlparen)
        -: 4030:            {
      261: 4031:                nextToken();
      261: 4032:                exp = parseExpression();
      261: 4033:                check(TOKrparen);
        -: 4034:            }
        -: 4035:            else
      194: 4036:                exp = NULL;
      455: 4037:            body = parseStatement(PSscope);
      455: 4038:            s = new SynchronizedStatement(loc, exp, body);
      455: 4039:            break;
        -: 4040:        }
        -: 4041:
        -: 4042:        case TOKwith:
        -: 4043:        {   Expression *exp;
        -: 4044:            Statement *body;
        -: 4045:
     4322: 4046:            nextToken();
     4322: 4047:            check(TOKlparen);
     4322: 4048:            exp = parseExpression();
     4322: 4049:            check(TOKrparen);
     4322: 4050:            body = parseStatement(PSscope);
     4322: 4051:            s = new WithStatement(loc, exp, body);
     4322: 4052:            break;
        -: 4053:        }
        -: 4054:
        -: 4055:        case TOKtry:
        -: 4056:        {   Statement *body;
   107339: 4057:            Array *catches = NULL;
   107339: 4058:            Statement *finalbody = NULL;
        -: 4059:
   107339: 4060:            nextToken();
   107339: 4061:            body = parseStatement(PSscope);
   321663: 4062:            while (token.value == TOKcatch)
        -: 4063:            {
        -: 4064:                Statement *handler;
        -: 4065:                Catch *c;
        -: 4066:                Type *t;
        -: 4067:                Identifier *id;
   106985: 4068:                Loc loc = this->loc;
        -: 4069:
   106985: 4070:                nextToken();
   106985: 4071:                if (token.value == TOKlcurly)
        -: 4072:                {
     3166: 4073:                    t = NULL;
     3166: 4074:                    id = NULL;
        -: 4075:                }
        -: 4076:                else
        -: 4077:                {
   103819: 4078:                    check(TOKlparen);
   103819: 4079:                    id = NULL;
   103819: 4080:                    t = parseType(&id);
   103819: 4081:                    check(TOKrparen);
        -: 4082:                }
   106985: 4083:                handler = parseStatement(0);
   106985: 4084:                c = new Catch(loc, t, id, handler);
   106985: 4085:                if (!catches)
   106983: 4086:                    catches = new Array();
   106985: 4087:                catches->push(c);
        -: 4088:            }
        -: 4089:
   107339: 4090:            if (token.value == TOKfinally)
      426: 4091:            {   nextToken();
      426: 4092:                finalbody = parseStatement(0);
        -: 4093:            }
        -: 4094:
   107339: 4095:            s = body;
   107339: 4096:            if (!catches && !finalbody)
    #####: 4097:                error("catch or finally expected 
following try");
        -: 4098:            else
   107339: 4099:            {   if (catches)
   106983: 4100:                    s = new TryCatchStatement(loc, body, 
catches);
   107339: 4101:                if (finalbody)
      426: 4102:                    s = new TryFinallyStatement(loc, s, 
finalbody);
        -: 4103:            }
   107339: 4104:            break;
        -: 4105:        }
        -: 4106:
        -: 4107:        case TOKthrow:
        -: 4108:        {   Expression *exp;
        -: 4109:
   194132: 4110:            nextToken();
   194132: 4111:            exp = parseExpression();
   194132: 4112:            check(TOKsemicolon, "throw statement");
   194132: 4113:            s = new ThrowStatement(loc, exp);
   194132: 4114:            break;
        -: 4115:        }
        -: 4116:
        -: 4117:        case TOKvolatile:
      256: 4118:            nextToken();
      256: 4119:            s = parseStatement(PSsemi | PScurlyscope);
        -: 4120:#if DMDV2
      256: 4121:            if (!global.params.useDeprecated)
    #####: 4122:                error("volatile statements deprecated; 
used synchronized statements instead");
        -: 4123:#endif
      256: 4124:            s = new VolatileStatement(loc, s);
      256: 4125:            break;
        -: 4126:
        -: 4127:        case TOKasm:
        -: 4128:        {   Statements *statements;
        -: 4129:            Identifier *label;
    49075: 4130:            Loc labelloc;
        -: 4131:            Token *toklist;
        -: 4132:            Token **ptoklist;
        -: 4133:
        -: 4134:            // Parse the asm block into a sequence of 
AsmStatements,
        -: 4135:            // each AsmStatement is one instruction.
        -: 4136:            // Separate out labels.
        -: 4137:            // Defer parsing of AsmStatements until 
semantic processing.
        -: 4138:
    49075: 4139:            nextToken();
    49075: 4140:            check(TOKlcurly);
    49075: 4141:            toklist = NULL;
    49075: 4142:            ptoklist = &toklist;
    49075: 4143:            label = NULL;
    49075: 4144:            statements = new Statements();
  3540410: 4145:            while (1)
        -: 4146:            {
  3589485: 4147:                switch (token.value)
        -: 4148:                {
        -: 4149:                    case TOKidentifier:
  1481957: 4150:                        if (!toklist)
        -: 4151:                        {
        -: 4152:                            // Look ahead to see if it 
is a label
   660385: 4153:                            t = peek(&token);
   660385: 4154:                            if (t->value == TOKcolon)
        -: 4155:                            {   // It's a label
    64063: 4156:                                label = token.ident;
    64063: 4157:                                labelloc = this->loc;
    64063: 4158:                                nextToken();
    64063: 4159:                                nextToken();
    64063: 4160:                                continue;
        -: 4161:                            }
        -: 4162:                        }
  1417894: 4163:                        goto Ldefault;
        -: 4164:
        -: 4165:                    case TOKrcurly:
    49075: 4166:                        if (toklist || label)
        -: 4167:                        {
    #####: 4168:                            error("asm statements must 
end in ';'");
        -: 4169:                        }
    49075: 4170:                        break;
        -: 4171:
        -: 4172:                    case TOKsemicolon:
   645750: 4173:                        s = NULL;
   645750: 4174:                        if (toklist || label)
        -: 4175:                        {   // Create AsmStatement from 
list of tokens we've saved
   633433: 4176:                            s = new 
AsmStatement(this->loc, toklist);
   633433: 4177:                            toklist = NULL;
   633433: 4178:                            ptoklist = &toklist;
   633433: 4179:                            if (label)
    64063: 4180:                            {   s = new 
LabelStatement(labelloc, label, s);
    64063: 4181:                                label = NULL;
        -: 4182:                            }
   633433: 4183:                            statements->push(s);
        -: 4184:                        }
   645750: 4185:                        nextToken();
   645750: 4186:                        continue;
        -: 4187:
        -: 4188:                    case TOKeof:
        -: 4189:                        /* { */
    #####: 4190:                        error("matching '}' expected, 
not end of file");
    #####: 4191:                        break;
        -: 4192:
        -: 4193:                    default:
  2830597: 4194:                    Ldefault:
  2830597: 4195:                        *ptoklist = new Token();
  2830597: 4196:                        memcpy(*ptoklist, &token, 
sizeof(Token));
  2830597: 4197:                        ptoklist = &(*ptoklist)->next;
  2830597: 4198:                        *ptoklist = NULL;
        -: 4199:
  2830597: 4200:                        nextToken();
  2830597: 4201:                        continue;
        -: 4202:                }
        -: 4203:                break;
        -: 4204:            }
    49075: 4205:            s = new CompoundStatement(loc, statements);
    49075: 4206:            nextToken();
    49075: 4207:            break;
        -: 4208:        }
        -: 4209:
        -: 4210:        default:
    #####: 4211:            error("found '%s' instead of statement", 
token.toChars());
        -: 4212:            goto Lerror;
        -: 4213:
    #####: 4214:        Lerror:
    #####: 4215:            while (token.value != TOKrcurly &&
        -: 4216:                   token.value != TOKsemicolon &&
        -: 4217:                   token.value != TOKeof)
    #####: 4218:                nextToken();
    #####: 4219:            if (token.value == TOKsemicolon)
    #####: 4220:                nextToken();
    #####: 4221:            s = NULL;
        -: 4222:            break;
        -: 4223:    }
        -: 4224:
 82913462: 4225:    return s;
        -: 4226:}
        -: 4227:
135513135: 4228:void Parser::check(enum TOK value)
        -: 4229:{
135513135: 4230:    check(loc, value);
135513135: 4231:}
        -: 4232:
140737638: 4233:void Parser::check(Loc loc, enum TOK value)
        -: 4234:{
140737638: 4235:    if (token.value != value)
    #####: 4236:        error(loc, "found '%s' when expecting '%s'", 
token.toChars(), Token::toChars(value));
140737638: 4237:    nextToken();
140737638: 4238:}
        -: 4239:
 74899543: 4240:void Parser::check(enum TOK value, const char *string)
        -: 4241:{
 74899543: 4242:    if (token.value != value)
        -: 4243:        error("found '%s' when expecting '%s' following %s",
    #####: 4244:            token.toChars(), Token::toChars(value), string);
 74899543: 4245:    nextToken();
 74899543: 4246:}
        -: 4247:
  3503234: 4248:void Parser::checkParens(enum TOK value, Expression *e)
        -: 4249:{
  3503234: 4250:    if (precedence[e->op] == PREC_rel && !e->parens)
    #####: 4251:        error(loc, "%s must be parenthesized when next 
to operator %s", e->toChars(), Token::toChars(value));
  3503234: 4252:}
        -: 4253:
        -: 4254:/************************************
        -: 4255: * Determine if the scanner is sitting on the start of a 
declaration.
        -: 4256: * Input:
        -: 4257: *      needId  0       no identifier
        -: 4258: *              1       identifier optional
        -: 4259: *              2       must have identifier
        -: 4260: * Output:
        -: 4261: *      if *pt is not NULL, it is set to the ending 
token, which would be endtok
        -: 4262: */
        -: 4263:
 48035848: 4264:int Parser::isDeclaration(Token *t, int needId, enum TOK 
endtok, Token **pt)
        -: 4265:{
        -: 4266:    //printf("isDeclaration(needId = %d)\n", needId);
 48035848: 4267:    int haveId = 0;
        -: 4268:
        -: 4269:#if DMDV2
 48035848: 4270:    if ((t->value == TOKconst ||
        -: 4271:         t->value == TOKinvariant ||
        -: 4272:         t->value == TOKimmutable ||
        -: 4273:         t->value == TOKwild ||
        -: 4274:         t->value == TOKshared) &&
        -: 4275:        peek(t)->value != TOKlparen)
        -: 4276:    {   /* const type
        -: 4277:         * immutable type
        -: 4278:         * shared type
        -: 4279:         * wild type
        -: 4280:         */
    84996: 4281:        t = peek(t);
        -: 4282:    }
        -: 4283:#endif
        -: 4284:
 48035848: 4285:    if (!isBasicType(&t))
        -: 4286:    {
  7215239: 4287:        goto Lisnot;
        -: 4288:    }
 40820609: 4289:    if (!isDeclarator(&t, &haveId, endtok))
 25384322: 4290:        goto Lisnot;
 15436287: 4291:    if ( needId == 1 ||
        -: 4292:        (needId == 0 && !haveId) ||
        -: 4293:        (needId == 2 &&  haveId))
 13204798: 4294:    {   if (pt)
  1493867: 4295:            *pt = t;
        -: 4296:        goto Lis;
        -: 4297:    }
        -: 4298:    else
        -: 4299:        goto Lisnot;
        -: 4300:
 13204798: 4301:Lis:
        -: 4302:    //printf("\tis declaration, t = %s\n", t->toChars());
 13204798: 4303:    return TRUE;
        -: 4304:
 34831050: 4305:Lisnot:
        -: 4306:    //printf("\tis not declaration\n");
 34831050: 4307:    return FALSE;
        -: 4308:}
        -: 4309:
 48240066: 4310:int Parser::isBasicType(Token **pt)
        -: 4311:{
        -: 4312:    // This code parallels parseBasicType()
 48240066: 4313:    Token *t = *pt;
        -: 4314:    Token *t2;
        -: 4315:    int parens;
 48240066: 4316:    int haveId = 0;
        -: 4317:
 48240066: 4318:    switch (t->value)
        -: 4319:    {
        -: 4320:        case BASIC_TYPES:
  2794287: 4321:            t = peek(t);
  2794287: 4322:            break;
        -: 4323:
        -: 4324:        case TOKidentifier:
 37825254: 4325:        L5:
 37825254: 4326:            t = peek(t);
 37825254: 4327:            if (t->value == TOKnot)
        -: 4328:            {
  1201887: 4329:                goto L4;
        -: 4330:            }
 36623367: 4331:            goto L3;
   821055: 4332:            while (1)
        -: 4333:            {
  1270283: 4334:        L2:
  1270283: 4335:                t = peek(t);
 43271021: 4336:        L3:
 43271021: 4337:                if (t->value == TOKdot)
        -: 4338:                {
  5399806: 4339:        Ldot:
  5399806: 4340:                    t = peek(t);
  5399806: 4341:                    if (t->value != TOKidentifier)
        1: 4342:                        goto Lfalse;
  5399805: 4343:                    t = peek(t);
  5399805: 4344:                    if (t->value != TOKnot)
  5377371: 4345:                        goto L3;
  1224321: 4346:        L4:
        -: 4347:                    /* Seen a !
        -: 4348:                     * Look for:
        -: 4349:                     * !( args ), !identifier, etc.
        -: 4350:                     */
  1224321: 4351:                    t = peek(t);
  1224321: 4352:                    switch (t->value)
        -: 4353:                    {   case TOKidentifier:
   256932: 4354:                            goto L5;
        -: 4355:                        case TOKlparen:
   830532: 4356:                            if (!skipParens(t, &t))
     9477: 4357:                                goto Lfalse;
        -: 4358:                            break;
        -: 4359:                        case BASIC_TYPES:
        -: 4360:                        case TOKint32v:
        -: 4361:                        case TOKuns32v:
        -: 4362:                        case TOKint64v:
        -: 4363:                        case TOKuns64v:
        -: 4364:                        case TOKfloat32v:
        -: 4365:                        case TOKfloat64v:
        -: 4366:                        case TOKfloat80v:
        -: 4367:                        case TOKimaginary32v:
        -: 4368:                        case TOKimaginary64v:
        -: 4369:                        case TOKimaginary80v:
        -: 4370:                        case TOKnull:
        -: 4371:                        case TOKtrue:
        -: 4372:                        case TOKfalse:
        -: 4373:                        case TOKcharv:
        -: 4374:                        case TOKwcharv:
        -: 4375:                        case TOKdcharv:
        -: 4376:                        case TOKstring:
        -: 4377:                        case TOKfile:
        -: 4378:                        case TOKline:
   136532: 4379:                            goto L2;
        -: 4380:                        default:
      325: 4381:                            goto Lfalse;
        -: 4382:                    }
        -: 4383:                }
        -: 4384:                else
 37935842: 4385:                    break;
        -: 4386:            }
 37935842: 4387:            break;
        -: 4388:
        -: 4389:        case TOKdot:
    64627: 4390:            goto Ldot;
        -: 4391:
        -: 4392:        case TOKtypeof:
        -: 4393:            /* typeof(exp).identifier...
        -: 4394:             */
   312824: 4395:            t = peek(t);
   312824: 4396:            if (t->value != TOKlparen)
    #####: 4397:                goto Lfalse;
   312824: 4398:            if (!skipParens(t, &t))
      128: 4399:                goto Lfalse;
   312696: 4400:            goto L2;
        -: 4401:
        -: 4402:        case TOKconst:
        -: 4403:        case TOKinvariant:
        -: 4404:        case TOKimmutable:
        -: 4405:        case TOKshared:
        -: 4406:        case TOKwild:
        -: 4407:            // const(type)  or  immutable(type)  or  
shared(type)  or  wild(type)
   248519: 4408:            t = peek(t);
   248519: 4409:            if (t->value != TOKlparen)
    #####: 4410:                goto Lfalse;
   248519: 4411:            t = peek(t);
   248519: 4412:            if (!isDeclaration(t, 0, TOKrparen, &t))
        -: 4413:            {
    #####: 4414:                goto Lfalse;
        -: 4415:            }
   248519: 4416:            t = peek(t);
   248519: 4417:            break;
        -: 4418:
        -: 4419:        default:
  7251487: 4420:            goto Lfalse;
        -: 4421:    }
 40978648: 4422:    *pt = t;
        -: 4423:    //printf("is\n");
 40978648: 4424:    return TRUE;
        -: 4425:
  7261418: 4426:Lfalse:
        -: 4427:    //printf("is not\n");
  7261418: 4428:    return FALSE;
        -: 4429:}
        -: 4430:
 46030304: 4431:int Parser::isDeclarator(Token **pt, int *haveId, enum 
TOK endtok)
        -: 4432:{   // This code parallels parseDeclarator()
 46030304: 4433:    Token *t = *pt;
        -: 4434:    int parens;
        -: 4435:
        -: 4436:    //printf("Parser::isDeclarator()\n");
        -: 4437:    //t->print();
 46030304: 4438:    if (t->value == TOKassign)
  9091745: 4439:        return FALSE;
        -: 4440:
  3497245: 4441:    while (1)
        -: 4442:    {
 40435804: 4443:        parens = FALSE;
 40435804: 4444:        switch (t->value)
        -: 4445:        {
        -: 4446:            case TOKmul:
        -: 4447:            //case TOKand:
   204489: 4448:                t = peek(t);
   204489: 4449:                continue;
        -: 4450:
        -: 4451:            case TOKlbracket:
  3346866: 4452:                t = peek(t);
  3346866: 4453:                if (t->value == TOKrbracket)
        -: 4454:                {
   588840: 4455:                    t = peek(t);
        -: 4456:                }
  2758026: 4457:                else if (t->value == TOKnew && 
peek(t)->value == TOKrbracket)
        -: 4458:                {
    #####: 4459:                    t = peek(t);
    #####: 4460:                    t = peek(t);
        -: 4461:                }
  2758026: 4462:                else if (isDeclaration(t, 0, 
TOKrbracket, &t))
        -: 4463:                {   // It's an associative array declaration
   912797: 4464:                    t = peek(t);
        -: 4465:                }
        -: 4466:                else
        -: 4467:                {
        -: 4468:                    // [ expression ]
        -: 4469:                    // [ expression .. expression ]
  1845229: 4470:                    if (!isExpression(&t))
    #####: 4471:                        return FALSE;
  1845229: 4472:                    if (t->value == TOKslice)
   394575: 4473:                    {   t = peek(t);
   394575: 4474:                        if (!isExpression(&t))
    #####: 4475:                            return FALSE;
        -: 4476:                    }
  1845229: 4477:                    if (t->value != TOKrbracket)
    66938: 4478:                        return FALSE;
  1778291: 4479:                    t = peek(t);
        -: 4480:                }
  3279928: 4481:                continue;
        -: 4482:
        -: 4483:            case TOKidentifier:
  4988229: 4484:                if (*haveId)
    #####: 4485:                    return FALSE;
  4988229: 4486:                *haveId = TRUE;
  4988229: 4487:                t = peek(t);
  4988229: 4488:                break;
        -: 4489:
        -: 4490:            case TOKlparen:
  6931812: 4491:                t = peek(t);
        -: 4492:
  6931812: 4493:                if (t->value == TOKrparen)
   664175: 4494:                    return FALSE;               // () is 
not a declarator
        -: 4495:
        -: 4496:                /* Regard ( identifier ) as not a declarator
        -: 4497:                 * BUG: what about ( *identifier ) in
        -: 4498:                 *      f(*p)(x);
        -: 4499:                 * where f is a class instance with 
overloaded () ?
        -: 4500:                 * Should we just disallow C-style 
function pointer declarations?
        -: 4501:                 */
  6267637: 4502:                if (t->value == TOKidentifier)
  3681092: 4503:                {   Token *t2 = peek(t);
  3681092: 4504:                    if (t2->value == TOKrparen)
  1215917: 4505:                        return FALSE;
        -: 4506:                }
        -: 4507:
        -: 4508:
  5051720: 4509:                if (!isDeclarator(&t, haveId, TOKrparen))
  4999730: 4510:                    return FALSE;
    51990: 4511:                t = peek(t);
    51990: 4512:                parens = TRUE;
    51990: 4513:                break;
        -: 4514:
        -: 4515:            case TOKdelegate:
        -: 4516:            case TOKfunction:
    13276: 4517:                t = peek(t);
    13276: 4518:                if (!isParameters(&t))
      448: 4519:                    return FALSE;
    12828: 4520:                continue;
        -: 4521:        }
 29991351: 4522:        break;
        -: 4523:    }
        -: 4524:
   158743: 4525:    while (1)
        -: 4526:    {
 30150094: 4527:        switch (t->value)
        -: 4528:        {
        -: 4529:#if CARRAYDECL
        -: 4530:            case TOKlbracket:
   167893: 4531:                parens = FALSE;
   167893: 4532:                t = peek(t);
   167893: 4533:                if (t->value == TOKrbracket)
        -: 4534:                {
    21282: 4535:                    t = peek(t);
        -: 4536:                }
   146611: 4537:                else if (isDeclaration(t, 0, 
TOKrbracket, &t))
        -: 4538:                {   // It's an associative array declaration
    65976: 4539:                    t = peek(t);
        -: 4540:                }
        -: 4541:                else
        -: 4542:                {
        -: 4543:                    // [ expression ]
    80635: 4544:                    if (!isExpression(&t))
    #####: 4545:                        return FALSE;
    80635: 4546:                    if (t->value != TOKrbracket)
    63972: 4547:                        return FALSE;
    16663: 4548:                    t = peek(t);
        -: 4549:                }
   103921: 4550:                continue;
        -: 4551:#endif
        -: 4552:
        -: 4553:            case TOKlparen:
   143572: 4554:                parens = FALSE;
   143572: 4555:                if (!isParameters(&t))
    88750: 4556:                    return FALSE;
        -: 4557:#if DMDV2
    #####: 4558:                while (1)
        -: 4559:                {
    54822: 4560:                    switch (t->value)
        -: 4561:                    {
        -: 4562:                        case TOKconst:
        -: 4563:                        case TOKinvariant:
        -: 4564:                        case TOKimmutable:
        -: 4565:                        case TOKshared:
        -: 4566:                        case TOKwild:
        -: 4567:                        case TOKpure:
        -: 4568:                        case TOKnothrow:
    #####: 4569:                            t = peek(t);
    #####: 4570:                            continue;
        -: 4571:                        case TOKat:
    #####: 4572:                            t = peek(t);        // skip '@'
    #####: 4573:                            t = peek(t);        // skip 
identifier
    #####: 4574:                            continue;
        -: 4575:                        default:
        -: 4576:                            break;
        -: 4577:                    }
        -: 4578:                    break;
        -: 4579:                }
        -: 4580:#endif
    54822: 4581:                continue;
        -: 4582:
        -: 4583:            // Valid tokens that follow a declaration
        -: 4584:            case TOKrparen:
        -: 4585:            case TOKrbracket:
        -: 4586:            case TOKassign:
        -: 4587:            case TOKcomma:
        -: 4588:            case TOKsemicolon:
        -: 4589:            case TOKlcurly:
        -: 4590:            case TOKin:
        -: 4591:                // The !parens is to disallow 
unnecessary parentheses
 17717800: 4592:                if (!parens && (endtok == TOKreserved || 
endtok == t->value))
 15603681: 4593:                {   *pt = t;
 15603681: 4594:                    return TRUE;
        -: 4595:                }
  2114119: 4596:                return FALSE;
        -: 4597:
        -: 4598:            default:
 12120829: 4599:                return FALSE;
        -: 4600:        }
        -: 4601:    }
        -: 4602:}
        -: 4603:
        -: 4604:
   156848: 4605:int Parser::isParameters(Token **pt)
        -: 4606:{   // This code parallels parseParameters()
   156848: 4607:    Token *t = *pt;
        -: 4608:
        -: 4609:    //printf("isParameters()\n");
   156848: 4610:    if (t->value != TOKlparen)
      448: 4611:        return FALSE;
        -: 4612:
   156400: 4613:    t = peek(t);
    73412: 4614:    for (;1; t = peek(t))
        -: 4615:    {
   229876: 4616:     L1:
   229876: 4617:        switch (t->value)
        -: 4618:        {
        -: 4619:            case TOKrparen:
    19212: 4620:                break;
        -: 4621:
        -: 4622:            case TOKdotdotdot:
    #####: 4623:                t = peek(t);
    #####: 4624:                break;
        -: 4625:
        -: 4626:#if D1INOUT
        -: 4627:            case TOKinout:
        -: 4628:#endif
        -: 4629:            case TOKin:
        -: 4630:            case TOKout:
        -: 4631:            case TOKref:
        -: 4632:            case TOKlazy:
        -: 4633:            case TOKfinal:
        -: 4634:            case TOKauto:
     6318: 4635:                continue;
        -: 4636:
        -: 4637:            case TOKconst:
        -: 4638:            case TOKinvariant:
        -: 4639:            case TOKimmutable:
        -: 4640:            case TOKshared:
        -: 4641:            case TOKwild:
      128: 4642:                t = peek(t);
      128: 4643:                if (t->value == TOKlparen)
        -: 4644:                {
       64: 4645:                    t = peek(t);
       64: 4646:                    if (!isDeclaration(t, 0, TOKrparen, &t))
    #####: 4647:                        return FALSE;
       64: 4648:                    t = peek(t);        // skip past 
closing ')'
       64: 4649:                    goto L2;
        -: 4650:                }
       64: 4651:                goto L1;
        -: 4652:
        -: 4653:#if 0
        -: 4654:            case TOKstatic:
        -: 4655:                continue;
        -: 4656:            case TOKauto:
        -: 4657:            case TOKalias:
        -: 4658:                t = peek(t);
        -: 4659:                if (t->value == TOKidentifier)
        -: 4660:                    t = peek(t);
        -: 4661:                if (t->value == TOKassign)
        -: 4662:                {   t = peek(t);
        -: 4663:                    if (!isExpression(&t))
        -: 4664:                        return FALSE;
        -: 4665:                }
        -: 4666:                goto L3;
        -: 4667:#endif
        -: 4668:
        -: 4669:            default:
   204218: 4670:            {   if (!isBasicType(&t))
    46179: 4671:                    return FALSE;
   158103: 4672:            L2:
   158103: 4673:                int tmp = FALSE;
   158103: 4674:                if (t->value != TOKdotdotdot &&
        -: 4675:                    !isDeclarator(&t, &tmp, TOKreserved))
    42571: 4676:                    return FALSE;
   115532: 4677:                if (t->value == TOKassign)
        1: 4678:                {   t = peek(t);
        1: 4679:                    if (!isExpression(&t))
    #####: 4680:                        return FALSE;
        -: 4681:                }
   115532: 4682:                if (t->value == TOKdotdotdot)
        -: 4683:                {
      128: 4684:                    t = peek(t);
      128: 4685:                    break;
        -: 4686:                }
        -: 4687:            }
   115404: 4688:            L3:
   115404: 4689:                if (t->value == TOKcomma)
        -: 4690:                {
    67094: 4691:                    continue;
        -: 4692:                }
        -: 4693:                break;
        -: 4694:        }
        -: 4695:        break;
        -: 4696:    }
    67650: 4697:    if (t->value != TOKrparen)
    #####: 4698:        return FALSE;
    67650: 4699:    t = peek(t);
    67650: 4700:    *pt = t;
    67650: 4701:    return TRUE;
        -: 4702:}
        -: 4703:
  2320440: 4704:int Parser::isExpression(Token **pt)
        -: 4705:{
        -: 4706:    // This is supposed to determine if something is an 
expression.
        -: 4707:    // What it actually does is scan until a closing 
right bracket
        -: 4708:    // is found.
        -: 4709:
  2320440: 4710:    Token *t = *pt;
  2320440: 4711:    int brnest = 0;
  2320440: 4712:    int panest = 0;
  2320440: 4713:    int curlynest = 0;
        -: 4714:
  3414975: 4715:    for (;; t = peek(t))
        -: 4716:    {
  5735415: 4717:        switch (t->value)
        -: 4718:        {
        -: 4719:            case TOKlbracket:
     3108: 4720:                brnest++;
     3108: 4721:                continue;
        -: 4722:
        -: 4723:            case TOKrbracket:
  1798062: 4724:                if (--brnest >= 0)
     3108: 4725:                    continue;
  1794954: 4726:                break;
        -: 4727:
        -: 4728:            case TOKlparen:
    20713: 4729:                panest++;
    20713: 4730:                continue;
        -: 4731:
        -: 4732:            case TOKcomma:
    68490: 4733:                if (brnest || panest)
     1552: 4734:                    continue;
    66938: 4735:                break;
        -: 4736:
        -: 4737:            case TOKrparen:
    20714: 4738:                if (--panest >= 0)
    20713: 4739:                    continue;
        1: 4740:                break;
        -: 4741:
        -: 4742:            case TOKlcurly:
    #####: 4743:                curlynest++;
    #####: 4744:                continue;
        -: 4745:
        -: 4746:            case TOKrcurly:
    #####: 4747:                if (--curlynest >= 0)
    #####: 4748:                    continue;
    #####: 4749:                return FALSE;
        -: 4750:
        -: 4751:            case TOKslice:
   458547: 4752:                if (brnest)
    #####: 4753:                    continue;
   458547: 4754:                break;
        -: 4755:
        -: 4756:            case TOKsemicolon:
    #####: 4757:                if (curlynest)
    #####: 4758:                    continue;
    #####: 4759:                return FALSE;
        -: 4760:
        -: 4761:            case TOKeof:
    #####: 4762:                return FALSE;
        -: 4763:
        -: 4764:            default:
  3365781: 4765:                continue;
        -: 4766:        }
        -: 4767:        break;
        -: 4768:    }
        -: 4769:
  2320440: 4770:    *pt = t;
  2320440: 4771:    return TRUE;
        -: 4772:}
        -: 4773:
        -: 4774:/**********************************************
        -: 4775: * Skip over
        -: 4776: *      instance foo.bar(parameters...)
        -: 4777: * Output:
        -: 4778: *      if (pt), *pt is set to the token following the 
closing )
        -: 4779: * Returns:
        -: 4780: *      1       it's valid instance syntax
        -: 4781: *      0       invalid instance syntax
        -: 4782: */
        -: 4783:
    #####: 4784:int Parser::isTemplateInstance(Token *t, Token **pt)
        -: 4785:{
    #####: 4786:    t = peek(t);
    #####: 4787:    if (t->value != TOKdot)
        -: 4788:    {
    #####: 4789:        if (t->value != TOKidentifier)
    #####: 4790:            goto Lfalse;
    #####: 4791:        t = peek(t);
        -: 4792:    }
    #####: 4793:    while (t->value == TOKdot)
        -: 4794:    {
    #####: 4795:        t = peek(t);
    #####: 4796:        if (t->value != TOKidentifier)
    #####: 4797:            goto Lfalse;
    #####: 4798:        t = peek(t);
        -: 4799:    }
    #####: 4800:    if (t->value != TOKlparen)
    #####: 4801:        goto Lfalse;
        -: 4802:
        -: 4803:    // Skip over the template arguments
    #####: 4804:    while (1)
        -: 4805:    {
    #####: 4806:        while (1)
        -: 4807:        {
    #####: 4808:            t = peek(t);
    #####: 4809:            switch (t->value)
        -: 4810:            {
        -: 4811:                case TOKlparen:
    #####: 4812:                    if (!skipParens(t, &t))
    #####: 4813:                        goto Lfalse;
    #####: 4814:                    continue;
        -: 4815:                case TOKrparen:
    #####: 4816:                    break;
        -: 4817:                case TOKcomma:
    #####: 4818:                    break;
        -: 4819:                case TOKeof:
        -: 4820:                case TOKsemicolon:
    #####: 4821:                    goto Lfalse;
        -: 4822:                default:
    #####: 4823:                    continue;
        -: 4824:            }
        -: 4825:            break;
        -: 4826:        }
        -: 4827:
    #####: 4828:        if (t->value != TOKcomma)
    #####: 4829:            break;
        -: 4830:    }
    #####: 4831:    if (t->value != TOKrparen)
    #####: 4832:        goto Lfalse;
    #####: 4833:    t = peek(t);
    #####: 4834:    if (pt)
    #####: 4835:        *pt = t;
    #####: 4836:    return 1;
        -: 4837:
    #####: 4838:Lfalse:
    #####: 4839:    return 0;
        -: 4840:}
        -: 4841:
        -: 4842:/*******************************************
        -: 4843: * Skip parens, brackets.
        -: 4844: * Input:
        -: 4845: *      t is on opening (
        -: 4846: * Output:
        -: 4847: *      *pt is set to closing token, which is ')' on success
        -: 4848: * Returns:
        -: 4849: *      !=0     successful
        -: 4850: *      0       some parsing error
        -: 4851: */
        -: 4852:
  1219709: 4853:int Parser::skipParens(Token *t, Token **pt)
        -: 4854:{
  1219709: 4855:    int parens = 0;
        -: 4856:
  5939145: 4857:    while (1)
        -: 4858:    {
  7158854: 4859:        switch (t->value)
        -: 4860:        {
        -: 4861:            case TOKlparen:
  1373481: 4862:                parens++;
  1373481: 4863:                break;
        -: 4864:
        -: 4865:            case TOKrparen:
  1363876: 4866:                parens--;
  1363876: 4867:                if (parens < 0)
    #####: 4868:                    goto Lfalse;
  1363876: 4869:                if (parens == 0)
  1210104: 4870:                    goto Ldone;
   153772: 4871:                break;
        -: 4872:
        -: 4873:            case TOKeof:
        -: 4874:            case TOKsemicolon:
     9605: 4875:                goto Lfalse;
        -: 4876:
        -: 4877:             default:
        -: 4878:                break;
        -: 4879:        }
  5939145: 4880:        t = peek(t);
        -: 4881:    }
        -: 4882:
  1210104: 4883:  Ldone:
  1210104: 4884:    if (*pt)
  1210104: 4885:        *pt = t;
  1210104: 4886:    return 1;
        -: 4887:
     9605: 4888:  Lfalse:
     9605: 4889:    return 0;
        -: 4890:}
        -: 4891:
        -: 4892:/********************************* Expression Parser 
***************************/
        -: 4893:
187736165: 4894:Expression *Parser::parsePrimaryExp()
        -: 4895:{   Expression *e;
        -: 4896:    Type *t;
        -: 4897:    Identifier *id;
        -: 4898:    enum TOK save;
187736165: 4899:    Loc loc = this->loc;
        -: 4900:
        -: 4901:    //printf("parsePrimaryExp(): loc = %d\n", loc.linnum);
187736165: 4902:    switch (token.value)
        -: 4903:    {
        -: 4904:        case TOKidentifier:
102771702: 4905:            id = token.ident;
102771702: 4906:            nextToken();
102771702: 4907:            if (token.value == TOKnot && (save = 
peekNext()) != TOKis && save != TOKin)
        -: 4908:            {   // identifier!(template-argument-list)
        -: 4909:                TemplateInstance *tempinst;
        -: 4910:
  6658118: 4911:                tempinst = new TemplateInstance(loc, id);
  6658118: 4912:                nextToken();
  6658118: 4913:                if (token.value == TOKlparen)
        -: 4914:                    // ident!(template_arguments)
  4149482: 4915:                    tempinst->tiargs = 
parseTemplateArgumentList();
        -: 4916:                else
        -: 4917:                    // ident!template_argument
  2508636: 4918:                    tempinst->tiargs = 
parseTemplateArgument();
  6658118: 4919:                e = new ScopeExp(loc, tempinst);
        -: 4920:            }
        -: 4921:            else
 96113584: 4922:                e = new IdentifierExp(loc, id);
102771702: 4923:            break;
        -: 4924:
        -: 4925:        case TOKdollar:
   926372: 4926:            if (!inBrackets)
    #####: 4927:                error("'$' is valid only inside [] of 
index or slice");
   926372: 4928:            e = new DollarExp(loc);
   926372: 4929:            nextToken();
   926372: 4930:            break;
        -: 4931:
        -: 4932:        case TOKdot:
        -: 4933:            // Signal global scope '.' operator with "" 
identifier
   204718: 4934:            e = new IdentifierExp(loc, Id::empty);
   204718: 4935:            break;
        -: 4936:
        -: 4937:        case TOKthis:
   714221: 4938:            e = new ThisExp(loc);
   714221: 4939:            nextToken();
   714221: 4940:            break;
        -: 4941:
        -: 4942:        case TOKsuper:
    93095: 4943:            e = new SuperExp(loc);
    93095: 4944:            nextToken();
    93095: 4945:            break;
        -: 4946:
        -: 4947:        case TOKint32v:
 38986650: 4948:            e = new IntegerExp(loc, token.int32value, 
Type::tint32);
 38986650: 4949:            nextToken();
 38986650: 4950:            break;
        -: 4951:
        -: 4952:        case TOKuns32v:
   545274: 4953:            e = new IntegerExp(loc, token.uns32value, 
Type::tuns32);
   545274: 4954:            nextToken();
   545274: 4955:            break;
        -: 4956:
        -: 4957:        case TOKint64v:
   315804: 4958:            e = new IntegerExp(loc, token.int64value, 
Type::tint64);
   315804: 4959:            nextToken();
   315804: 4960:            break;
        -: 4961:
        -: 4962:        case TOKuns64v:
   156965: 4963:            e = new IntegerExp(loc, token.uns64value, 
Type::tuns64);
   156965: 4964:            nextToken();
   156965: 4965:            break;
        -: 4966:
        -: 4967:        case TOKfloat32v:
    73076: 4968:            e = new RealExp(loc, token.float80value, 
Type::tfloat32);
    73076: 4969:            nextToken();
    73076: 4970:            break;
        -: 4971:
        -: 4972:        case TOKfloat64v:
  1380392: 4973:            e = new RealExp(loc, token.float80value, 
Type::tfloat64);
  1380392: 4974:            nextToken();
  1380392: 4975:            break;
        -: 4976:
        -: 4977:        case TOKfloat80v:
   394612: 4978:            e = new RealExp(loc, token.float80value, 
Type::tfloat80);
   394612: 4979:            nextToken();
   394612: 4980:            break;
        -: 4981:
        -: 4982:        case TOKimaginary32v:
     3287: 4983:            e = new RealExp(loc, token.float80value, 
Type::timaginary32);
     3287: 4984:            nextToken();
     3287: 4985:            break;
        -: 4986:
        -: 4987:        case TOKimaginary64v:
   154805: 4988:            e = new RealExp(loc, token.float80value, 
Type::timaginary64);
   154805: 4989:            nextToken();
   154805: 4990:            break;
        -: 4991:
        -: 4992:        case TOKimaginary80v:
    21602: 4993:            e = new RealExp(loc, token.float80value, 
Type::timaginary80);
    21602: 4994:            nextToken();
    21602: 4995:            break;
        -: 4996:
        -: 4997:        case TOKnull:
   651198: 4998:            e = new NullExp(loc);
   651198: 4999:            nextToken();
   651198: 5000:            break;
        -: 5001:
        -: 5002:#if DMDV2
        -: 5003:        case TOKfile:
   175799: 5004:        {   const char *s = loc.filename ? loc.filename 
: mod->ident->toChars();
   175799: 5005:            e = new StringExp(loc, (char *)s, strlen(s), 0);
   175799: 5006:            nextToken();
   175799: 5007:            break;
        -: 5008:        }
        -: 5009:
        -: 5010:        case TOKline:
   214044: 5011:            e = new IntegerExp(loc, loc.linnum, 
Type::tint32);
   214044: 5012:            nextToken();
   214044: 5013:            break;
        -: 5014:#endif
        -: 5015:
        -: 5016:        case TOKtrue:
   732539: 5017:            e = new IntegerExp(loc, 1, Type::tbool);
   732539: 5018:            nextToken();
   732539: 5019:            break;
        -: 5020:
        -: 5021:        case TOKfalse:
   834110: 5022:            e = new IntegerExp(loc, 0, Type::tbool);
   834110: 5023:            nextToken();
   834110: 5024:            break;
        -: 5025:
        -: 5026:        case TOKcharv:
  3170970: 5027:            e = new IntegerExp(loc, token.uns32value, 
Type::tchar);
  3170970: 5028:            nextToken();
  3170970: 5029:            break;
        -: 5030:
        -: 5031:        case TOKwcharv:
   136527: 5032:            e = new IntegerExp(loc, token.uns32value, 
Type::twchar);
   136527: 5033:            nextToken();
   136527: 5034:            break;
        -: 5035:
        -: 5036:        case TOKdcharv:
    44445: 5037:            e = new IntegerExp(loc, token.uns32value, 
Type::tdchar);
    44445: 5038:            nextToken();
    44445: 5039:            break;
        -: 5040:
        -: 5041:        case TOKstring:
        -: 5042:        {   unsigned char *s;
        -: 5043:            unsigned len;
        -: 5044:            unsigned char postfix;
        -: 5045:
        -: 5046:            // cat adjacent strings
 16432293: 5047:            s = token.ustring;
 16432293: 5048:            len = token.len;
 16432293: 5049:            postfix = token.postfix;
   105324: 5050:            while (1)
        -: 5051:            {
 16537617: 5052:                nextToken();
 16537617: 5053:                if (token.value == TOKstring)
        -: 5054:                {   unsigned len1;
        -: 5055:                    unsigned len2;
        -: 5056:                    unsigned char *s2;
        -: 5057:
   105324: 5058:                    if (token.postfix)
    #####: 5059:                    {   if (token.postfix != postfix)
    #####: 5060:                            error("mismatched string 
literal postfixes '%c' and '%c'", postfix, token.postfix);
    #####: 5061:                        postfix = token.postfix;
        -: 5062:                    }
        -: 5063:
   105324: 5064:                    len1 = len;
   105324: 5065:                    len2 = token.len;
   105324: 5066:                    len = len1 + len2;
   105324: 5067:                    s2 = (unsigned char 
*)mem.malloc((len + 1) * sizeof(unsigned char));
   105324: 5068:                    memcpy(s2, s, len1 * sizeof(unsigned 
char));
   105324: 5069:                    memcpy(s2 + len1, token.ustring, 
(len2 + 1) * sizeof(unsigned char));
   105324: 5070:                    s = s2;
        -: 5071:                }
        -: 5072:                else
 16432293: 5073:                    break;
        -: 5074:            }
 16432293: 5075:            e = new StringExp(loc, s, len, postfix);
 16432293: 5076:            break;
        -: 5077:        }
        -: 5078:
      128: 5079:        case BASIC_TYPES_X(t):
  1800201: 5080:            nextToken();
  1800201: 5081:        L1:
  1800201: 5082:            check(TOKdot, t->toChars());
  1800201: 5083:            if (token.value != TOKidentifier)
    #####: 5084:            {   error("found '%s' when expecting 
identifier following '%s.'", token.toChars(), t->toChars());
    #####: 5085:                goto Lerr;
        -: 5086:            }
  1800201: 5087:            e = typeDotIdExp(loc, t, token.ident);
  1800201: 5088:            nextToken();
  1800201: 5089:            break;
        -: 5090:
        -: 5091:        case TOKtypeof:
        -: 5092:        {
   157429: 5093:            t = parseTypeof();
   157429: 5094:            e = new TypeExp(loc, t);
   157429: 5095:            break;
        -: 5096:        }
        -: 5097:
        -: 5098:        case TOKtypeid:
        -: 5099:        {
   189717: 5100:            nextToken();
   189717: 5101:            check(TOKlparen, "typeid");
        -: 5102:            Object *o;
   189717: 5103:            if (isDeclaration(&token, 0, TOKreserved, NULL))
        -: 5104:            {   // argument is a type
   189589: 5105:                o = parseType();
        -: 5106:            }
        -: 5107:            else
        -: 5108:            {   // argument is an expression
      128: 5109:                o = parseAssignExp();
        -: 5110:            }
   189717: 5111:            check(TOKrparen);
   189717: 5112:            e = new TypeidExp(loc, o);
   189717: 5113:            break;
        -: 5114:        }
        -: 5115:
        -: 5116:#if DMDV2
        -: 5117:        case TOKtraits:
        -: 5118:        {   /* __traits(identifier, args...)
        -: 5119:             */
        -: 5120:            Identifier *ident;
   206038: 5121:            Objects *args = NULL;
        -: 5122:
   206038: 5123:            nextToken();
   206038: 5124:            check(TOKlparen);
   206038: 5125:            if (token.value != TOKidentifier)
    #####: 5126:            {   error("__traits(identifier, args...) 
expected");
    #####: 5127:                goto Lerr;
        -: 5128:            }
   206038: 5129:            ident = token.ident;
   206038: 5130:            nextToken();
   206038: 5131:            if (token.value == TOKcomma)
   205334: 5132:                args = parseTemplateArgumentList2();    
// __traits(identifier, args...)
        -: 5133:            else
      704: 5134:                check(TOKrparen);               // 
__traits(identifier)
        -: 5135:
   206038: 5136:            e = new TraitsExp(loc, ident, args);
   206038: 5137:            break;
        -: 5138:        }
        -: 5139:#endif
        -: 5140:
        -: 5141:        case TOKis:
        -: 5142:        {   Type *targ;
  1771747: 5143:            Identifier *ident = NULL;
  1771747: 5144:            Type *tspec = NULL;
  1771747: 5145:            enum TOK tok = TOKreserved;
  1771747: 5146:            enum TOK tok2 = TOKreserved;
  1771747: 5147:            TemplateParameters *tpl = NULL;
  1771747: 5148:            Loc loc = this->loc;
        -: 5149:
  1771747: 5150:            nextToken();
  1771747: 5151:            if (token.value == TOKlparen)
        -: 5152:            {
  1771747: 5153:                nextToken();
  1771747: 5154:                targ = parseType(&ident);
  1771747: 5155:                if (token.value == TOKcolon || 
token.value == TOKequal)
        -: 5156:                {
  1401922: 5157:                    tok = token.value;
  1401922: 5158:                    nextToken();
  1401922: 5159:                    if (tok == TOKequal &&
        -: 5160:                        (token.value == TOKtypedef ||
        -: 5161:                         token.value == TOKstruct ||
        -: 5162:                         token.value == TOKunion ||
        -: 5163:                         token.value == TOKclass ||
        -: 5164:                         token.value == TOKsuper ||
        -: 5165:                         token.value == TOKenum ||
        -: 5166:                         token.value == TOKinterface ||
        -: 5167:#if DMDV2
        -: 5168:                         token.value == TOKconst && 
peek(&token)->value == TOKrparen ||
        -: 5169:                         token.value == TOKinvariant && 
peek(&token)->value == TOKrparen ||
        -: 5170:                         token.value == TOKimmutable && 
peek(&token)->value == TOKrparen ||
        -: 5171:                         token.value == TOKshared && 
peek(&token)->value == TOKrparen ||
        -: 5172:                         token.value == TOKwild && 
peek(&token)->value == TOKrparen ||
        -: 5173:#endif
        -: 5174:                         token.value == TOKfunction ||
        -: 5175:                         token.value == TOKdelegate ||
        -: 5176:                         token.value == TOKreturn))
        -: 5177:                    {
   339265: 5178:                        tok2 = token.value;
   339265: 5179:                        nextToken();
        -: 5180:                    }
        -: 5181:                    else
        -: 5182:                    {
  1062657: 5183:                        tspec = parseType();
        -: 5184:                    }
        -: 5185:                }
  1858535: 5186:                if (ident && tspec)
        -: 5187:                {
    86788: 5188:                    if (token.value == TOKcomma)
    27727: 5189:                        tpl = parseTemplateParameterList(1);
        -: 5190:                    else
    59061: 5191:                    {   tpl = new TemplateParameters();
    59061: 5192:                        check(TOKrparen);
        -: 5193:                    }
    86788: 5194:                    TemplateParameter *tp = new 
TemplateTypeParameter(loc, ident, NULL, NULL);
    86788: 5195:                    tpl->insert(0, tp);
        -: 5196:                }
        -: 5197:                else
  1684959: 5198:                    check(TOKrparen);
        -: 5199:            }
        -: 5200:            else
    #####: 5201:            {   error("(type identifier : 
specialization) expected following is");
    #####: 5202:                goto Lerr;
        -: 5203:            }
  1771747: 5204:            e = new IsExp(loc, targ, ident, tok, tspec, 
tok2, tpl);
  1771747: 5205:            break;
        -: 5206:        }
        -: 5207:
        -: 5208:        case TOKassert:
  9069692: 5209:        {   Expression *msg = NULL;
        -: 5210:
  9069692: 5211:            nextToken();
  9069692: 5212:            check(TOKlparen, "assert");
  9069692: 5213:            e = parseAssignExp();
  9069692: 5214:            if (token.value == TOKcomma)
   344999: 5215:            {   nextToken();
   344999: 5216:                msg = parseAssignExp();
        -: 5217:            }
  9069692: 5218:            check(TOKrparen);
  9069692: 5219:            e = new AssertExp(loc, e, msg);
  9069692: 5220:            break;
        -: 5221:        }
        -: 5222:
        -: 5223:        case TOKmixin:
        -: 5224:        {
    30931: 5225:            nextToken();
    30931: 5226:            check(TOKlparen, "mixin");
    30931: 5227:            e = parseAssignExp();
    30931: 5228:            check(TOKrparen);
    30931: 5229:            e = new CompileExp(loc, e);
    30931: 5230:            break;
        -: 5231:        }
        -: 5232:
        -: 5233:        case TOKimport:
        -: 5234:        {
        1: 5235:            nextToken();
        1: 5236:            check(TOKlparen, "import");
        1: 5237:            e = parseAssignExp();
        1: 5238:            check(TOKrparen);
        1: 5239:            e = new FileExp(loc, e);
        1: 5240:            break;
        -: 5241:        }
        -: 5242:
        -: 5243:        case TOKlparen:
  4309142: 5244:            if (peekPastParen(&token)->value == TOKlcurly)
        -: 5245:            {   // (arguments) { statements... }
    70846: 5246:                save = TOKdelegate;
    70846: 5247:                goto case_delegate;
        -: 5248:            }
        -: 5249:            // ( expression )
  4238296: 5250:            nextToken();
  4238296: 5251:            e = parseExpression();
  4238296: 5252:            e->parens = 1;
  4238296: 5253:            check(loc, TOKrparen);
  4238296: 5254:            break;
        -: 5255:
        -: 5256:        case TOKlbracket:
        -: 5257:        {   /* Parse array literals and associative 
array literals:
        -: 5258:             *  [ value, value, value ... ]
        -: 5259:             *  [ key:value, key:value, key:value ... ]
        -: 5260:             */
   986207: 5261:            Expressions *values = new Expressions();
   986207: 5262:            Expressions *keys = NULL;
        -: 5263:
   986207: 5264:            nextToken();
  5188017: 5265:            while (token.value != TOKrbracket && 
token.value != TOKeof)
        -: 5266:            {
  4155449: 5267:                    Expression *e = parseAssignExp();
  4234759: 5268:                    if (token.value == TOKcolon && (keys 
|| values->dim == 0))
    79310: 5269:                    {   nextToken();
    79310: 5270:                        if (!keys)
     9369: 5271:                            keys = new Expressions();
    79310: 5272:                        keys->push(e);
    79310: 5273:                        e = parseAssignExp();
        -: 5274:                    }
  4076139: 5275:                    else if (keys)
    #####: 5276:                    {   error("'key:value' expected for 
associative array literal");
    #####: 5277:                        delete keys;
    #####: 5278:                        keys = NULL;
        -: 5279:                    }
  4155449: 5280:                    values->push(e);
  4155449: 5281:                    if (token.value == TOKrbracket)
   939846: 5282:                        break;
  3215603: 5283:                    check(TOKcomma);
        -: 5284:            }
   986207: 5285:            check(loc, TOKrbracket);
        -: 5286:
   986207: 5287:            if (keys)
     9369: 5288:                e = new AssocArrayLiteralExp(loc, keys, 
values);
        -: 5289:            else
   976838: 5290:                e = new ArrayLiteralExp(loc, values);
   986207: 5291:            break;
        -: 5292:        }
        -: 5293:
        -: 5294:        case TOKlcurly:
        -: 5295:            // { statements... }
    65476: 5296:            save = TOKdelegate;
    65476: 5297:            goto case_delegate;
        -: 5298:
        -: 5299:        case TOKfunction:
        -: 5300:        case TOKdelegate:
    15084: 5301:            save = token.value;
    15084: 5302:            nextToken();
   151406: 5303:        case_delegate:
        -: 5304:        {
        -: 5305:            /* function type(parameters) { body } pure 
nothrow
        -: 5306:             * delegate type(parameters) { body } pure 
nothrow
        -: 5307:             * (parameters) { body }
        -: 5308:             * { body }
        -: 5309:             */
        -: 5310:            Parameters *arguments;
        -: 5311:            int varargs;
        -: 5312:            FuncLiteralDeclaration *fd;
        -: 5313:            Type *t;
   151406: 5314:            StorageClass stc = 0;
        -: 5315:
   151406: 5316:            if (token.value == TOKlcurly)
        -: 5317:            {
    65604: 5318:                t = NULL;
    65604: 5319:                varargs = 0;
    65604: 5320:                arguments = new Parameters();
        -: 5321:            }
        -: 5322:            else
        -: 5323:            {
    85802: 5324:                if (token.value == TOKlparen)
    71487: 5325:                    t = NULL;
        -: 5326:                else
        -: 5327:                {
    14315: 5328:                    t = parseBasicType();
    14315: 5329:                    t = parseBasicType2(t);     // 
function return type
        -: 5330:                }
    85802: 5331:                arguments = parseParameters(&varargs);
    85802: 5332:                stc = parsePostfix();
    85802: 5333:                if (stc & (STCconst | STCimmutable | 
STCshared | STCwild))
    #####: 5334:                    error("const/immutable/shared/inout 
attributes are only valid for non-static member functions");
        -: 5335:            }
        -: 5336:
   151406: 5337:            TypeFunction *tf = new 
TypeFunction(arguments, t, varargs, linkage, stc);
        -: 5338:
   151406: 5339:            fd = new FuncLiteralDeclaration(loc, 0, tf, 
save, NULL);
   151406: 5340:            parseContracts(fd);
   151406: 5341:            e = new FuncExp(loc, fd);
   151406: 5342:            break;
        -: 5343:        }
        -: 5344:
        -: 5345:        default:
    #####: 5346:            error("expression expected, not '%s'", 
token.toChars());
    #####: 5347:        Lerr:
        -: 5348:            // Anything for e, as long as it's not NULL
    #####: 5349:            e = new IntegerExp(loc, 0, Type::tint32);
    #####: 5350:            nextToken();
        -: 5351:            break;
        -: 5352:    }
187736165: 5353:    return e;
        -: 5354:}
        -: 5355:
187752762: 5356:Expression *Parser::parsePostExp(Expression *e)
        -: 5357:{
187752762: 5358:    Loc loc;
        -: 5359:
 55191831: 5360:    while (1)
        -: 5361:    {
242944593: 5362:        loc = this->loc;
242944593: 5363:        switch (token.value)
        -: 5364:        {
        -: 5365:            case TOKdot:
 23349333: 5366:                nextToken();
 23349333: 5367:                if (token.value == TOKidentifier)
 23349266: 5368:                {   Identifier *id = token.ident;
        -: 5369:
 23349266: 5370:                    nextToken();
 23349266: 5371:                    if (token.value == TOKnot && 
peekNext() != TOKis)
        -: 5372:                    {   // 
identifier!(template-argument-list)
   227352: 5373:                        TemplateInstance *tempinst = new 
TemplateInstance(loc, id);
        -: 5374:                        Objects *tiargs;
   227352: 5375:                        nextToken();
   227352: 5376:                        if (token.value == TOKlparen)
        -: 5377:                            // ident!(template_arguments)
   196676: 5378:                            tiargs = 
parseTemplateArgumentList();
        -: 5379:                        else
        -: 5380:                            // ident!template_argument
    30676: 5381:                            tiargs = 
parseTemplateArgument();
   227352: 5382:                        e = new 
DotTemplateInstanceExp(loc, e, id, tiargs);
        -: 5383:                    }
        -: 5384:                    else
 23121914: 5385:                        e = new DotIdExp(loc, e, id);
 23349266: 5386:                    continue;
        -: 5387:                }
       67: 5388:                else if (token.value == TOKnew)
        -: 5389:                {
       67: 5390:                    e = parseNewExp(e);
       67: 5391:                    continue;
        -: 5392:                }
        -: 5393:                else
    #####: 5394:                    error("identifier expected following 
'.', not '%s'", token.toChars());
    #####: 5395:                break;
        -: 5396:
        -: 5397:            case TOKplusplus:
  1270178: 5398:                e = new PostExp(TOKplusplus, loc, e);
  1270178: 5399:                break;
        -: 5400:
        -: 5401:            case TOKminusminus:
   115212: 5402:                e = new PostExp(TOKminusminus, loc, e);
   115212: 5403:                break;
        -: 5404:
        -: 5405:            case TOKlparen:
 21526275: 5406:                e = new CallExp(loc, e, parseArguments());
 21526275: 5407:                continue;
        -: 5408:
        -: 5409:            case TOKlbracket:
        -: 5410:            {   // array dereferences:
        -: 5411:                //      array[index]
        -: 5412:                //      array[]
        -: 5413:                //      array[lwr .. upr]
        -: 5414:                Expression *index;
        -: 5415:                Expression *upr;
        -: 5416:
  8930833: 5417:                inBrackets++;
  8930833: 5418:                nextToken();
  8930833: 5419:                if (token.value == TOKrbracket)
        -: 5420:                {   // array[]
   432231: 5421:                    e = new SliceExp(loc, e, NULL, NULL);
   432231: 5422:                    nextToken();
        -: 5423:                }
        -: 5424:                else
        -: 5425:                {
  8498602: 5426:                    index = parseAssignExp();
  8498602: 5427:                    if (token.value == TOKslice)
        -: 5428:                    {   // array[lwr .. upr]
  1755223: 5429:                        nextToken();
  1755223: 5430:                        upr = parseAssignExp();
  1755223: 5431:                        e = new SliceExp(loc, e, index, 
upr);
        -: 5432:                    }
        -: 5433:                    else
        -: 5434:                    {   // array[index, i2, i3, i4, ...]
  6743379: 5435:                        Expressions *arguments = new 
Expressions();
  6743379: 5436:                        arguments->push(index);
  6743379: 5437:                        if (token.value == TOKcomma)
        -: 5438:                        {
      384: 5439:                            nextToken();
      896: 5440:                            while (token.value != 
TOKrbracket && token.value != TOKeof)
        -: 5441:                            {
      448: 5442:                                Expression *arg = 
parseAssignExp();
      448: 5443:                                arguments->push(arg);
      448: 5444:                                if (token.value == 
TOKrbracket)
      320: 5445:                                    break;
      128: 5446:                                check(TOKcomma);
        -: 5447:                            }
        -: 5448:                        }
  6743379: 5449:                        e = new ArrayExp(loc, e, arguments);
        -: 5450:                    }
  8498602: 5451:                    check(TOKrbracket);
  8498602: 5452:                    inBrackets--;
        -: 5453:                }
  8930833: 5454:                continue;
        -: 5455:            }
        -: 5456:
        -: 5457:            default:
187752762: 5458:                return e;
        -: 5459:        }
  1385390: 5460:        nextToken();
        -: 5461:    }
        -: 5462:}
        -: 5463:
199609516: 5464:Expression *Parser::parseUnaryExp()
        -: 5465:{   Expression *e;
199609516: 5466:    Loc loc = this->loc;
        -: 5467:
199609516: 5468:    switch (token.value)
        -: 5469:    {
        -: 5470:        case TOKand:
  1614995: 5471:            nextToken();
  1614995: 5472:            e = parseUnaryExp();
  1614995: 5473:            e = new AddrExp(loc, e);
  1614995: 5474:            break;
        -: 5475:
        -: 5476:        case TOKplusplus:
   456053: 5477:            nextToken();
   456053: 5478:            e = parseUnaryExp();
        -: 5479:            //e = new AddAssignExp(loc, e, new 
IntegerExp(loc, 1, Type::tint32));
   456053: 5480:            e = new PreExp(TOKpreplusplus, loc, e);
   456053: 5481:            break;
        -: 5482:
        -: 5483:        case TOKminusminus:
   112876: 5484:            nextToken();
   112876: 5485:            e = parseUnaryExp();
        -: 5486:            //e = new MinAssignExp(loc, e, new 
IntegerExp(loc, 1, Type::tint32));
   112876: 5487:            e = new PreExp(TOKpreminusminus, loc, e);
   112876: 5488:            break;
        -: 5489:
        -: 5490:        case TOKmul:
   664666: 5491:            nextToken();
   664666: 5492:            e = parseUnaryExp();
   664666: 5493:            e = new PtrExp(loc, e);
   664666: 5494:            break;
        -: 5495:
        -: 5496:        case TOKmin:
  1517841: 5497:            nextToken();
  1517841: 5498:            e = parseUnaryExp();
  1517841: 5499:            e = new NegExp(loc, e);
  1517841: 5500:            break;
        -: 5501:
        -: 5502:        case TOKadd:
   142855: 5503:            nextToken();
   142855: 5504:            e = parseUnaryExp();
   142855: 5505:            e = new UAddExp(loc, e);
   142855: 5506:            break;
        -: 5507:
        -: 5508:        case TOKnot:
  2873861: 5509:            nextToken();
  2873861: 5510:            e = parseUnaryExp();
  2873861: 5511:            e = new NotExp(loc, e);
  2873861: 5512:            break;
        -: 5513:
        -: 5514:        case TOKtilde:
   197789: 5515:            nextToken();
   197789: 5516:            e = parseUnaryExp();
   197789: 5517:            e = new ComExp(loc, e);
   197789: 5518:            break;
        -: 5519:
        -: 5520:        case TOKdelete:
    40768: 5521:            nextToken();
    40768: 5522:            e = parseUnaryExp();
    40768: 5523:            e = new DeleteExp(loc, e);
    40768: 5524:            break;
        -: 5525:
        -: 5526:        case TOKnew:
   757437: 5527:            e = parseNewExp(NULL);
   757437: 5528:            break;
        -: 5529:
        -: 5530:        case TOKcast:                           // 
cast(type) expression
        -: 5531:        {
  3477357: 5532:            nextToken();
  3477357: 5533:            check(TOKlparen);
        -: 5534:            /* Look for cast(), cast(const), 
cast(immutable),
        -: 5535:             * cast(shared), cast(shared const), 
cast(wild), cast(shared wild)
        -: 5536:             */
        -: 5537:            unsigned m;
  3477357: 5538:            if (token.value == TOKrparen)
        -: 5539:            {
     3543: 5540:                m = 0;
     3543: 5541:                goto Lmod1;
        -: 5542:            }
  3473814: 5543:            else if (token.value == TOKconst && 
peekNext() == TOKrparen)
        -: 5544:            {
      320: 5545:                m = MODconst;
      320: 5546:                goto Lmod2;
        -: 5547:            }
  3473494: 5548:            else if ((token.value == TOKimmutable || 
token.value == TOKinvariant) && peekNext() == TOKrparen)
        -: 5549:            {
      256: 5550:                m = MODimmutable;
      256: 5551:                goto Lmod2;
        -: 5552:            }
  3473238: 5553:            else if (token.value == TOKshared && 
peekNext() == TOKrparen)
        -: 5554:            {
    12252: 5555:                m = MODshared;
    12252: 5556:                goto Lmod2;
        -: 5557:            }
  3460986: 5558:            else if (token.value == TOKwild && 
peekNext() == TOKrparen)
        -: 5559:            {
      128: 5560:                m = MODwild;
      128: 5561:                goto Lmod2;
        -: 5562:            }
  3460858: 5563:            else if (token.value == TOKwild && 
peekNext() == TOKshared && peekNext2() == TOKrparen ||
        -: 5564:                     token.value == TOKshared && 
peekNext() == TOKwild && peekNext2() == TOKrparen)
        -: 5565:            {
    #####: 5566:                m = MODshared | MODwild;
    #####: 5567:                goto Lmod3;
        -: 5568:            }
  3460858: 5569:            else if (token.value == TOKconst && 
peekNext() == TOKshared && peekNext2() == TOKrparen ||
        -: 5570:                     token.value == TOKshared && 
peekNext() == TOKconst && peekNext2() == TOKrparen)
        -: 5571:            {
      128: 5572:                m = MODshared | MODconst;
      128: 5573:              Lmod3:
      128: 5574:                nextToken();
    13084: 5575:              Lmod2:
    13084: 5576:                nextToken();
    16627: 5577:              Lmod1:
    16627: 5578:                nextToken();
    16627: 5579:                e = parseUnaryExp();
    16627: 5580:                e = new CastExp(loc, e, m);
        -: 5581:            }
        -: 5582:            else
        -: 5583:            {
  3460730: 5584:                Type *t = parseType();          // ( type )
  3460730: 5585:                check(TOKrparen);
  3460730: 5586:                e = parseUnaryExp();
  3460730: 5587:                e = new CastExp(loc, e, t);
        -: 5588:            }
  3477357: 5589:            break;
        -: 5590:        }
        -: 5591:
        -: 5592:        case TOKwild:
        -: 5593:        case TOKshared:
        -: 5594:        case TOKconst:
        -: 5595:        case TOKinvariant:
        -: 5596:        case TOKimmutable:      // 
immutable(type)(arguments)
        -: 5597:        {
      256: 5598:            Type *t = parseBasicType();
      256: 5599:            if (token.value != TOKlparen)
    #####: 5600:                error("(arguments) expected following 
type");
      256: 5601:            e = new TypeExp(loc, t);
      256: 5602:            e = new CallExp(loc, e, parseArguments());
      256: 5603:            break;
        -: 5604:        }
        -: 5605:
        -: 5606:
        -: 5607:        case TOKlparen:
        -: 5608:        {   Token *tk;
        -: 5609:
  4488071: 5610:            tk = peek(&token);
        -: 5611:#if CCASTSYNTAX
        -: 5612:            // If cast
  4488071: 5613:            if (isDeclaration(tk, 0, TOKrparen, &tk))
        -: 5614:            {
   266511: 5615:                tk = peek(tk);          // skip over 
right parenthesis
   266511: 5616:                switch (tk->value)
        -: 5617:                {
        -: 5618:                    case TOKnot:
       64: 5619:                        tk = peek(tk);
       64: 5620:                        if (tk->value == TOKis || 
tk->value == TOKin)   // !is or !in
       64: 5621:                            break;
        -: 5622:                    case TOKdot:
        -: 5623:                    case TOKplusplus:
        -: 5624:                    case TOKminusminus:
        -: 5625:                    case TOKdelete:
        -: 5626:                    case TOKnew:
        -: 5627:                    case TOKlparen:
        -: 5628:                    case TOKidentifier:
        -: 5629:                    case TOKthis:
        -: 5630:                    case TOKsuper:
        -: 5631:                    case TOKint32v:
        -: 5632:                    case TOKuns32v:
        -: 5633:                    case TOKint64v:
        -: 5634:                    case TOKuns64v:
        -: 5635:                    case TOKfloat32v:
        -: 5636:                    case TOKfloat64v:
        -: 5637:                    case TOKfloat80v:
        -: 5638:                    case TOKimaginary32v:
        -: 5639:                    case TOKimaginary64v:
        -: 5640:                    case TOKimaginary80v:
        -: 5641:                    case TOKnull:
        -: 5642:                    case TOKtrue:
        -: 5643:                    case TOKfalse:
        -: 5644:                    case TOKcharv:
        -: 5645:                    case TOKwcharv:
        -: 5646:                    case TOKdcharv:
        -: 5647:                    case TOKstring:
        -: 5648:#if 0
        -: 5649:                    case TOKtilde:
        -: 5650:                    case TOKand:
        -: 5651:                    case TOKmul:
        -: 5652:                    case TOKmin:
        -: 5653:                    case TOKadd:
        -: 5654:#endif
        -: 5655:                    case TOKfunction:
        -: 5656:                    case TOKdelegate:
        -: 5657:                    case TOKtypeof:
        -: 5658:#if DMDV2
        -: 5659:                    case TOKfile:
        -: 5660:                    case TOKline:
        -: 5661:#endif
        -: 5662:                    case BASIC_TYPES:           // 
(type)int.size
        -: 5663:                    {   // (type) una_exp
        -: 5664:                        Type *t;
        -: 5665:
   178929: 5666:                        nextToken();
   178929: 5667:                        t = parseType();
   178929: 5668:                        check(TOKrparen);
        -: 5669:
        -: 5670:                        // if .identifier
   178929: 5671:                        if (token.value == TOKdot)
        -: 5672:                        {
   178929: 5673:                            nextToken();
   178929: 5674:                            if (token.value != 
TOKidentifier)
    #####: 5675:                            {   error("Identifier 
expected following (type).");
    #####: 5676:                                return NULL;
        -: 5677:                            }
   178929: 5678:                            e = typeDotIdExp(loc, t, 
token.ident);
   178929: 5679:                            nextToken();
   178929: 5680:                            e = parsePostExp(e);
        -: 5681:                        }
        -: 5682:                        else
        -: 5683:                        {
    #####: 5684:                            e = parseUnaryExp();
    #####: 5685:                            e = new CastExp(loc, e, t);
    #####: 5686:                            error("C style cast illegal, 
use %s", e->toChars());
        -: 5687:                        }
   178929: 5688:                        return e;
        -: 5689:                    }
        -: 5690:                }
        -: 5691:            }
        -: 5692:#endif
  4309142: 5693:            e = parsePrimaryExp();
  4309142: 5694:            e = parsePostExp(e);
  4309142: 5695:            break;
        -: 5696:        }
        -: 5697:        default:
183264691: 5698:            e = parsePrimaryExp();
183264691: 5699:            e = parsePostExp(e);
        -: 5700:            break;
        -: 5701:    }
199430587: 5702:    assert(e);
        -: 5703:
        -: 5704:    // ^^ is right associative and has higher precedence 
than the unary operators
398861350: 5705:    while (token.value == TOKpow)
        -: 5706:    {
      176: 5707:        nextToken();
      176: 5708:        Expression *e2 = parseUnaryExp();
      176: 5709:        e = new PowExp(loc, e, e2);
        -: 5710:    }
        -: 5711:
199430587: 5712:    return e;
        -: 5713:}
        -: 5714:
186314304: 5715:Expression *Parser::parseMulExp()
        -: 5716:{   Expression *e;
        -: 5717:    Expression *e2;
186314304: 5718:    Loc loc = this->loc;
        -: 5719:
186314304: 5720:    e = parseUnaryExp();
  2195975: 5721:    while (1)
        -: 5722:    {
188510279: 5723:        switch (token.value)
        -: 5724:        {
  1516333: 5725:            case TOKmul: nextToken(); e2 = 
parseUnaryExp(); e = new MulExp(loc,e,e2); continue;
   500497: 5726:            case TOKdiv: nextToken(); e2 = 
parseUnaryExp(); e = new DivExp(loc,e,e2); continue;
   179145: 5727:            case TOKmod: nextToken(); e2 = 
parseUnaryExp(); e = new ModExp(loc,e,e2); continue;
        -: 5728:
        -: 5729:            default:
        -: 5730:                break;
        -: 5731:        }
        -: 5732:        break;
        -: 5733:    }
186314304: 5734:    return e;
        -: 5735:}
        -: 5736:
179407959: 5737:Expression *Parser::parseAddExp()
        -: 5738:{   Expression *e;
        -: 5739:    Expression *e2;
179407959: 5740:    Loc loc = this->loc;
        -: 5741:
179407959: 5742:    e = parseMulExp();
  6906345: 5743:    while (1)
        -: 5744:    {
186314304: 5745:        switch (token.value)
        -: 5746:        {
  3292153: 5747:            case TOKadd:    nextToken(); e2 = 
parseMulExp(); e = new AddExp(loc,e,e2); continue;
  2181365: 5748:            case TOKmin:    nextToken(); e2 = 
parseMulExp(); e = new MinExp(loc,e,e2); continue;
  1432827: 5749:            case TOKtilde:  nextToken(); e2 = 
parseMulExp(); e = new CatExp(loc,e,e2); continue;
        -: 5750:
        -: 5751:            default:
        -: 5752:                break;
        -: 5753:        }
        -: 5754:        break;
        -: 5755:    }
179407959: 5756:    return e;
        -: 5757:}
        -: 5758:
178783908: 5759:Expression *Parser::parseShiftExp()
        -: 5760:{   Expression *e;
        -: 5761:    Expression *e2;
178783908: 5762:    Loc loc = this->loc;
        -: 5763:
178783908: 5764:    e = parseAddExp();
   624051: 5765:    while (1)
        -: 5766:    {
179407959: 5767:        switch (token.value)
        -: 5768:        {
   263256: 5769:            case TOKshl:  nextToken(); e2 = 
parseAddExp(); e = new ShlExp(loc,e,e2);  continue;
   335649: 5770:            case TOKshr:  nextToken(); e2 = 
parseAddExp(); e = new ShrExp(loc,e,e2);  continue;
    25146: 5771:            case TOKushr: nextToken(); e2 = 
parseAddExp(); e = new UshrExp(loc,e,e2); continue;
        -: 5772:
        -: 5773:            default:
        -: 5774:                break;
        -: 5775:        }
        -: 5776:        break;
        -: 5777:    }
178783908: 5778:    return e;
        -: 5779:}
        -: 5780:
        -: 5781:#if DMDV1
        -: 5782:Expression *Parser::parseRelExp()
        -: 5783:{   Expression *e;
        -: 5784:    Expression *e2;
        -: 5785:    enum TOK op;
        -: 5786:    Loc loc = this->loc;
        -: 5787:
        -: 5788:    e = parseShiftExp();
        -: 5789:    while (1)
        -: 5790:    {
        -: 5791:        switch (token.value)
        -: 5792:        {
        -: 5793:            case TOKlt:
        -: 5794:            case TOKle:
        -: 5795:            case TOKgt:
        -: 5796:            case TOKge:
        -: 5797:            case TOKunord:
        -: 5798:            case TOKlg:
        -: 5799:            case TOKleg:
        -: 5800:            case TOKule:
        -: 5801:            case TOKul:
        -: 5802:            case TOKuge:
        -: 5803:            case TOKug:
        -: 5804:            case TOKue:
        -: 5805:                op = token.value;
        -: 5806:                nextToken();
        -: 5807:                e2 = parseShiftExp();
        -: 5808:                e = new CmpExp(op, loc, e, e2);
        -: 5809:                continue;
        -: 5810:
        -: 5811:            case TOKnot:                // could be !in
        -: 5812:                if (peekNext() == TOKin)
        -: 5813:                {
        -: 5814:                    nextToken();
        -: 5815:                    nextToken();
        -: 5816:                    e2 = parseShiftExp();
        -: 5817:                    e = new InExp(loc, e, e2);
        -: 5818:                    e = new NotExp(loc, e);
        -: 5819:                    continue;
        -: 5820:                }
        -: 5821:                break;
        -: 5822:
        -: 5823:            case TOKin:
        -: 5824:                nextToken();
        -: 5825:                e2 = parseShiftExp();
        -: 5826:                e = new InExp(loc, e, e2);
        -: 5827:                continue;
        -: 5828:
        -: 5829:            default:
        -: 5830:                break;
        -: 5831:        }
        -: 5832:        break;
        -: 5833:    }
        -: 5834:    return e;
        -: 5835:}
        -: 5836:#endif
        -: 5837:
        -: 5838:#if DMDV1
        -: 5839:Expression *Parser::parseEqualExp()
        -: 5840:{   Expression *e;
        -: 5841:    Expression *e2;
        -: 5842:    Token *t;
        -: 5843:    Loc loc = this->loc;
        -: 5844:
        -: 5845:    e = parseRelExp();
        -: 5846:    while (1)
        -: 5847:    {   enum TOK value = token.value;
        -: 5848:
        -: 5849:        switch (value)
        -: 5850:        {
        -: 5851:            case TOKequal:
        -: 5852:            case TOKnotequal:
        -: 5853:                nextToken();
        -: 5854:                e2 = parseRelExp();
        -: 5855:                e = new EqualExp(value, loc, e, e2);
        -: 5856:                continue;
        -: 5857:
        -: 5858:            case TOKidentity:
        -: 5859:                error("'===' is no longer legal, use 
'is' instead");
        -: 5860:                goto L1;
        -: 5861:
        -: 5862:            case TOKnotidentity:
        -: 5863:                error("'!==' is no longer legal, use 
'!is' instead");
        -: 5864:                goto L1;
        -: 5865:
        -: 5866:            case TOKis:
        -: 5867:                value = TOKidentity;
        -: 5868:                goto L1;
        -: 5869:
        -: 5870:            case TOKnot:
        -: 5871:                // Attempt to identify '!is'
        -: 5872:                t = peek(&token);
        -: 5873:                if (t->value != TOKis)
        -: 5874:                    break;
        -: 5875:                nextToken();
        -: 5876:                value = TOKnotidentity;
        -: 5877:                goto L1;
        -: 5878:
        -: 5879:            L1:
        -: 5880:                nextToken();
        -: 5881:                e2 = parseRelExp();
        -: 5882:                e = new IdentityExp(value, loc, e, e2);
        -: 5883:                continue;
        -: 5884:
        -: 5885:            default:
        -: 5886:                break;
        -: 5887:        }
        -: 5888:        break;
        -: 5889:    }
        -: 5890:    return e;
        -: 5891:}
        -: 5892:#endif
        -: 5893:
163565571: 5894:Expression *Parser::parseCmpExp()
        -: 5895:{   Expression *e;
        -: 5896:    Expression *e2;
        -: 5897:    Token *t;
163565571: 5898:    Loc loc = this->loc;
        -: 5899:
163565571: 5900:    e = parseShiftExp();
163565571: 5901:    enum TOK op = token.value;
        -: 5902:
163565571: 5903:    switch (op)
        -: 5904:    {
        -: 5905:        case TOKequal:
        -: 5906:        case TOKnotequal:
 10926317: 5907:            nextToken();
 10926317: 5908:            e2 = parseShiftExp();
 10926317: 5909:            e = new EqualExp(op, loc, e, e2);
 10926317: 5910:            break;
        -: 5911:
        -: 5912:        case TOKis:
   112424: 5913:            op = TOKidentity;
   112424: 5914:            goto L1;
        -: 5915:
        -: 5916:        case TOKnot:
        -: 5917:            // Attempt to identify '!is'
    40849: 5918:            t = peek(&token);
    40849: 5919:            if (t->value == TOKin)
        -: 5920:            {
        2: 5921:                nextToken();
        2: 5922:                nextToken();
        2: 5923:                e2 = parseShiftExp();
        2: 5924:                e = new InExp(loc, e, e2);
        2: 5925:                e = new NotExp(loc, e);
        2: 5926:                break;
        -: 5927:            }
    40847: 5928:            if (t->value != TOKis)
    #####: 5929:                break;
    40847: 5930:            nextToken();
    40847: 5931:            op = TOKnotidentity;
        -: 5932:            goto L1;
        -: 5933:
   153271: 5934:        L1:
   153271: 5935:            nextToken();
   153271: 5936:            e2 = parseShiftExp();
   153271: 5937:            e = new IdentityExp(op, loc, e, e2);
   153271: 5938:            break;
        -: 5939:
        -: 5940:        case TOKlt:
        -: 5941:        case TOKle:
        -: 5942:        case TOKgt:
        -: 5943:        case TOKge:
        -: 5944:        case TOKunord:
        -: 5945:        case TOKlg:
        -: 5946:        case TOKleg:
        -: 5947:        case TOKule:
        -: 5948:        case TOKul:
        -: 5949:        case TOKuge:
        -: 5950:        case TOKug:
        -: 5951:        case TOKue:
  4123540: 5952:            nextToken();
  4123540: 5953:            e2 = parseShiftExp();
  4123540: 5954:            e = new CmpExp(op, loc, e, e2);
  4123540: 5955:            break;
        -: 5956:
        -: 5957:        case TOKin:
    15207: 5958:            nextToken();
    15207: 5959:            e2 = parseShiftExp();
    15207: 5960:            e = new InExp(loc, e, e2);
        -: 5961:            break;
        -: 5962:
        -: 5963:        default:
        -: 5964:            break;
        -: 5965:    }
163565571: 5966:    return e;
        -: 5967:}
        -: 5968:
162266597: 5969:Expression *Parser::parseAndExp()
        -: 5970:{
162266597: 5971:    Loc loc = this->loc;
        -: 5972:
162266597: 5973:    Expression *e = parseCmpExp();
325832168: 5974:    while (token.value == TOKand)
        -: 5975:    {
  1298974: 5976:        checkParens(TOKand, e);
  1298974: 5977:        nextToken();
  1298974: 5978:        Expression *e2 = parseCmpExp();
  1298974: 5979:        checkParens(TOKand, e2);
  1298974: 5980:        e = new AndExp(loc,e,e2);
  1298974: 5981:        loc = this->loc;
        -: 5982:    }
162266597: 5983:    return e;
        -: 5984:}
        -: 5985:
162221160: 5986:Expression *Parser::parseXorExp()
        -: 5987:{
162221160: 5988:    Loc loc = this->loc;
        -: 5989:
162221160: 5990:    Expression *e = parseAndExp();
324487757: 5991:    while (token.value == TOKxor)
        -: 5992:    {
    45437: 5993:        checkParens(TOKxor, e);
    45437: 5994:        nextToken();
    45437: 5995:        Expression *e2 = parseAndExp();
    45437: 5996:        checkParens(TOKxor, e2);
    45437: 5997:        e = new XorExp(loc, e, e2);
        -: 5998:    }
162221160: 5999:    return e;
        -: 6000:}
        -: 6001:
161813954: 6002:Expression *Parser::parseOrExp()
        -: 6003:{
161813954: 6004:    Loc loc = this->loc;
        -: 6005:
161813954: 6006:    Expression *e = parseXorExp();
324035114: 6007:    while (token.value == TOKor)
        -: 6008:    {
   407206: 6009:        checkParens(TOKor, e);
   407206: 6010:        nextToken();
   407206: 6011:        Expression *e2 = parseXorExp();
   407206: 6012:        checkParens(TOKor, e2);
   407206: 6013:        e = new OrExp(loc, e, e2);
        -: 6014:    }
161813954: 6015:    return e;
        -: 6016:}
        -: 6017:
159228582: 6018:Expression *Parser::parseAndAndExp()
        -: 6019:{   Expression *e;
        -: 6020:    Expression *e2;
159228582: 6021:    Loc loc = this->loc;
        -: 6022:
159228582: 6023:    e = parseOrExp();
321042536: 6024:    while (token.value == TOKandand)
        -: 6025:    {
  2585372: 6026:        nextToken();
  2585372: 6027:        e2 = parseOrExp();
  2585372: 6028:        e = new AndAndExp(loc, e, e2);
        -: 6029:    }
159228582: 6030:    return e;
        -: 6031:}
        -: 6032:
158299180: 6033:Expression *Parser::parseOrOrExp()
        -: 6034:{   Expression *e;
        -: 6035:    Expression *e2;
158299180: 6036:    Loc loc = this->loc;
        -: 6037:
158299180: 6038:    e = parseAndAndExp();
317527762: 6039:    while (token.value == TOKoror)
        -: 6040:    {
   929402: 6041:        nextToken();
   929402: 6042:        e2 = parseAndAndExp();
   929402: 6043:        e = new OrOrExp(loc, e, e2);
        -: 6044:    }
158299180: 6045:    return e;
        -: 6046:}
        -: 6047:
158299180: 6048:Expression *Parser::parseCondExp()
        -: 6049:{   Expression *e;
        -: 6050:    Expression *e1;
        -: 6051:    Expression *e2;
158299180: 6052:    Loc loc = this->loc;
        -: 6053:
158299180: 6054:    e = parseOrOrExp();
158299180: 6055:    if (token.value == TOKquestion)
        -: 6056:    {
   601903: 6057:        nextToken();
   601903: 6058:        e1 = parseExpression();
   601903: 6059:        check(TOKcolon);
   601903: 6060:        e2 = parseCondExp();
   601903: 6061:        e = new CondExp(loc, e, e1, e2);
        -: 6062:    }
158299180: 6063:    return e;
        -: 6064:}
        -: 6065:
157520254: 6066:Expression *Parser::parseAssignExp()
        -: 6067:{   Expression *e;
        -: 6068:    Expression *e2;
157520254: 6069:    Loc loc;
        -: 6070:
157520254: 6071:    e = parseCondExp();
 12563059: 6072:    while (1)
        -: 6073:    {
170083313: 6074:        loc = this->loc;
170083313: 6075:        switch (token.value)
        -: 6076:        {
        -: 6077:#define X(tok,ector) \
        -: 6078:            case tok:  nextToken(); e2 = 
parseAssignExp(); e = new ector(loc,e,e2); continue;
        -: 6079:
 10704590: 6080:            X(TOKassign,    AssignExp);
   649084: 6081:            X(TOKaddass,    AddAssignExp);
   151181: 6082:            X(TOKminass,    MinAssignExp);
    83729: 6083:            X(TOKmulass,    MulAssignExp);
    40267: 6084:            X(TOKdivass,    DivAssignExp);
     6846: 6085:            X(TOKmodass,    ModAssignExp);
     1552: 6086:            X(TOKpowass,    PowAssignExp);
   142235: 6087:            X(TOKandass,    AndAssignExp);
   166915: 6088:            X(TOKorass,     OrAssignExp);
    12606: 6089:            X(TOKxorass,    XorAssignExp);
    31073: 6090:            X(TOKshlass,    ShlAssignExp);
    39824: 6091:            X(TOKshrass,    ShrAssignExp);
     6382: 6092:            X(TOKushrass,   UshrAssignExp);
   526775: 6093:            X(TOKcatass,    CatAssignExp);
        -: 6094:
        -: 6095:#undef X
        -: 6096:            default:
        -: 6097:                break;
        -: 6098:        }
        -: 6099:        break;
        -: 6100:    }
157520254: 6101:    return e;
        -: 6102:}
        -: 6103:
 52552484: 6104:Expression *Parser::parseExpression()
        -: 6105:{   Expression *e;
        -: 6106:    Expression *e2;
 52552484: 6107:    Loc loc = this->loc;
        -: 6108:
        -: 6109:    //printf("Parser::parseExpression() loc = %d\n", 
loc.linnum);
 52552484: 6110:    e = parseAssignExp();
105216534: 6111:    while (token.value == TOKcomma)
        -: 6112:    {
   111566: 6113:        nextToken();
   111566: 6114:        e2 = parseAssignExp();
   111566: 6115:        e = new CommaExp(loc, e, e2);
   111566: 6116:        loc = this->loc;
        -: 6117:    }
 52552484: 6118:    return e;
        -: 6119:}
        -: 6120:
        -: 6121:
        -: 6122:/*************************
        -: 6123: * Collect argument list.
        -: 6124: * Assume current token is ',', '(' or '['.
        -: 6125: */
        -: 6126:
 21957991: 6127:Expressions *Parser::parseArguments()
        -: 6128:{   // function call
        -: 6129:    Expressions *arguments;
        -: 6130:    Expression *arg;
        -: 6131:    enum TOK endtok;
        -: 6132:
 21957991: 6133:    arguments = new Expressions();
 21957991: 6134:    if (token.value == TOKlbracket)
    #####: 6135:        endtok = TOKrbracket;
        -: 6136:    else
 21957991: 6137:        endtok = TOKrparen;
        -: 6138:
        -: 6139:    {
 21957991: 6140:        nextToken();
 56679831: 6141:        while (token.value != endtok)
        -: 6142:        {
 33252209: 6143:                arg = parseAssignExp();
 33252209: 6144:                arguments->push(arg);
 33252209: 6145:                if (token.value == endtok)
 20488360: 6146:                    break;
 12763849: 6147:                check(TOKcomma);
        -: 6148:        }
 21957991: 6149:        check(endtok);
        -: 6150:    }
 21957991: 6151:    return arguments;
        -: 6152:}
        -: 6153:
        -: 6154:/*******************************************
        -: 6155: */
        -: 6156:
   757504: 6157:Expression *Parser::parseNewExp(Expression *thisexp)
        -: 6158:{   Type *t;
        -: 6159:    Expressions *newargs;
   757504: 6160:    Expressions *arguments = NULL;
        -: 6161:    Expression *e;
   757504: 6162:    Loc loc = this->loc;
        -: 6163:
   757504: 6164:    nextToken();
   757504: 6165:    newargs = NULL;
   757504: 6166:    if (token.value == TOKlparen)
        -: 6167:    {
     3161: 6168:        newargs = parseArguments();
        -: 6169:    }
        -: 6170:
        -: 6171:    // An anonymous nested class starts with "class"
   757504: 6172:    if (token.value == TOKclass)
        -: 6173:    {
     3547: 6174:        nextToken();
     3547: 6175:        if (token.value == TOKlparen)
      194: 6176:            arguments = parseArguments();
        -: 6177:
     3547: 6178:        BaseClasses *baseclasses = NULL;
     3547: 6179:        if (token.value != TOKlcurly)
     3419: 6180:            baseclasses = parseBaseClasses();
        -: 6181:
     3547: 6182:        Identifier *id = NULL;
     3547: 6183:        ClassDeclaration *cd = new ClassDeclaration(loc, 
id, baseclasses);
        -: 6184:
     3547: 6185:        if (token.value != TOKlcurly)
    #####: 6186:        {   error("{ members } expected for anonymous 
class");
    #####: 6187:            cd->members = NULL;
        -: 6188:        }
        -: 6189:        else
        -: 6190:        {
     3547: 6191:            nextToken();
     3547: 6192:            Dsymbols *decl = parseDeclDefs(0);
     3547: 6193:            if (token.value != TOKrcurly)
    #####: 6194:                error("class member expected");
     3547: 6195:            nextToken();
     3547: 6196:            cd->members = decl;
        -: 6197:        }
        -: 6198:
     3547: 6199:        e = new NewAnonClassExp(loc, thisexp, newargs, 
cd, arguments);
        -: 6200:
     3547: 6201:        return e;
        -: 6202:    }
        -: 6203:
   753957: 6204:    t = parseBasicType();
   753957: 6205:    t = parseBasicType2(t);
   753957: 6206:    if (t->ty == Taarray)
    71221: 6207:    {   TypeAArray *taa = (TypeAArray *)t;
    71221: 6208:        Type *index = taa->index;
        -: 6209:
    71221: 6210:        Expression *e = index->toExpression();
    71221: 6211:        if (e)
    71221: 6212:        {   arguments = new Expressions();
    71221: 6213:            arguments->push(e);
    71221: 6214:            t = new TypeDArray(taa->next);
        -: 6215:        }
        -: 6216:        else
        -: 6217:        {
    #####: 6218:            error("need size of rightmost array, not 
type %s", index->toChars());
    #####: 6219:            return new NullExp(loc);
        -: 6220:        }
        -: 6221:    }
   682736: 6222:    else if (t->ty == Tsarray)
        -: 6223:    {
   189136: 6224:        TypeSArray *tsa = (TypeSArray *)t;
   189136: 6225:        Expression *e = tsa->dim;
        -: 6226:
   189136: 6227:        arguments = new Expressions();
   189136: 6228:        arguments->push(e);
   189136: 6229:        t = new TypeDArray(tsa->next);
        -: 6230:    }
   493600: 6231:    else if (token.value == TOKlparen)
        -: 6232:    {
   398297: 6233:        arguments = parseArguments();
        -: 6234:    }
   753957: 6235:    e = new NewExp(loc, thisexp, newargs, t, arguments);
   753957: 6236:    return e;
        -: 6237:}
        -: 6238:
        -: 6239:/**********************************************
        -: 6240: */
        -: 6241:
 71292756: 6242:void Parser::addComment(Dsymbol *s, unsigned char 
*blockComment)
        -: 6243:{
 71292756: 6244:    s->addComment(combineComments(blockComment, 
token.lineComment));
 71292756: 6245:    token.lineComment = NULL;
 71292756: 6246:}
        -: 6247:
        -: 6248:
        -: 6249:/**********************************
        -: 6250: * Set operator precedence for each operator.
        -: 6251: */
        -: 6252:
        -: 6253:enum PREC precedence[TOKMAX];
        -: 6254:
     5534: 6255:void initPrecedence()
        -: 6256:{
  1261752: 6257:    for (int i = 0; i < TOKMAX; i++)
  1256218: 6258:        precedence[i] = PREC_zero;
        -: 6259:
     5534: 6260:    precedence[TOKtype] = PREC_expr;
     5534: 6261:    precedence[TOKerror] = PREC_expr;
        -: 6262:
     5534: 6263:    precedence[TOKtypeof] = PREC_primary;
     5534: 6264:    precedence[TOKmixin] = PREC_primary;
        -: 6265:
     5534: 6266:    precedence[TOKdotvar] = PREC_primary;
     5534: 6267:    precedence[TOKimport] = PREC_primary;
     5534: 6268:    precedence[TOKidentifier] = PREC_primary;
     5534: 6269:    precedence[TOKthis] = PREC_primary;
     5534: 6270:    precedence[TOKsuper] = PREC_primary;
     5534: 6271:    precedence[TOKint64] = PREC_primary;
     5534: 6272:    precedence[TOKfloat64] = PREC_primary;
     5534: 6273:    precedence[TOKnull] = PREC_primary;
     5534: 6274:    precedence[TOKstring] = PREC_primary;
     5534: 6275:    precedence[TOKarrayliteral] = PREC_primary;
     5534: 6276:    precedence[TOKtypeid] = PREC_primary;
     5534: 6277:    precedence[TOKis] = PREC_primary;
     5534: 6278:    precedence[TOKassert] = PREC_primary;
     5534: 6279:    precedence[TOKfunction] = PREC_primary;
     5534: 6280:    precedence[TOKvar] = PREC_primary;
     5534: 6281:    precedence[TOKsymoff] = PREC_primary;
     5534: 6282:    precedence[TOKstructliteral] = PREC_primary;
     5534: 6283:    precedence[TOKarraylength] = PREC_primary;
        -: 6284:#if DMDV2
     5534: 6285:    precedence[TOKtraits] = PREC_primary;
     5534: 6286:    precedence[TOKdefault] = PREC_primary;
        -: 6287:#endif
        -: 6288:
        -: 6289:    // post
     5534: 6290:    precedence[TOKdotti] = PREC_primary;
     5534: 6291:    precedence[TOKdot] = PREC_primary;
     5534: 6292:    precedence[TOKdottd] = PREC_primary;
        -: 6293://  precedence[TOKarrow] = PREC_primary;
     5534: 6294:    precedence[TOKplusplus] = PREC_primary;
     5534: 6295:    precedence[TOKminusminus] = PREC_primary;
     5534: 6296:    precedence[TOKpreplusplus] = PREC_primary;
     5534: 6297:    precedence[TOKpreminusminus] = PREC_primary;
     5534: 6298:    precedence[TOKcall] = PREC_primary;
     5534: 6299:    precedence[TOKslice] = PREC_primary;
     5534: 6300:    precedence[TOKarray] = PREC_primary;
     5534: 6301:    precedence[TOKindex] = PREC_primary;
        -: 6302:
     5534: 6303:    precedence[TOKaddress] = PREC_unary;
     5534: 6304:    precedence[TOKstar] = PREC_unary;
     5534: 6305:    precedence[TOKneg] = PREC_unary;
     5534: 6306:    precedence[TOKuadd] = PREC_unary;
     5534: 6307:    precedence[TOKnot] = PREC_unary;
     5534: 6308:    precedence[TOKtobool] = PREC_add;
     5534: 6309:    precedence[TOKtilde] = PREC_unary;
     5534: 6310:    precedence[TOKdelete] = PREC_unary;
     5534: 6311:    precedence[TOKnew] = PREC_unary;
     5534: 6312:    precedence[TOKcast] = PREC_unary;
        -: 6313:
     5534: 6314:    precedence[TOKpow] = PREC_pow;
        -: 6315:
     5534: 6316:    precedence[TOKmul] = PREC_mul;
     5534: 6317:    precedence[TOKdiv] = PREC_mul;
     5534: 6318:    precedence[TOKmod] = PREC_mul;
     5534: 6319:    precedence[TOKpow] = PREC_mul;
        -: 6320:
     5534: 6321:    precedence[TOKadd] = PREC_add;
     5534: 6322:    precedence[TOKmin] = PREC_add;
     5534: 6323:    precedence[TOKcat] = PREC_add;
        -: 6324:
     5534: 6325:    precedence[TOKshl] = PREC_shift;
     5534: 6326:    precedence[TOKshr] = PREC_shift;
     5534: 6327:    precedence[TOKushr] = PREC_shift;
        -: 6328:
     5534: 6329:    precedence[TOKlt] = PREC_rel;
     5534: 6330:    precedence[TOKle] = PREC_rel;
     5534: 6331:    precedence[TOKgt] = PREC_rel;
     5534: 6332:    precedence[TOKge] = PREC_rel;
     5534: 6333:    precedence[TOKunord] = PREC_rel;
     5534: 6334:    precedence[TOKlg] = PREC_rel;
     5534: 6335:    precedence[TOKleg] = PREC_rel;
     5534: 6336:    precedence[TOKule] = PREC_rel;
     5534: 6337:    precedence[TOKul] = PREC_rel;
     5534: 6338:    precedence[TOKuge] = PREC_rel;
     5534: 6339:    precedence[TOKug] = PREC_rel;
     5534: 6340:    precedence[TOKue] = PREC_rel;
     5534: 6341:    precedence[TOKin] = PREC_rel;
        -: 6342:
        -: 6343:#if 0
        -: 6344:    precedence[TOKequal] = PREC_equal;
        -: 6345:    precedence[TOKnotequal] = PREC_equal;
        -: 6346:    precedence[TOKidentity] = PREC_equal;
        -: 6347:    precedence[TOKnotidentity] = PREC_equal;
        -: 6348:#else
        -: 6349:    /* Note that we changed precedence, so that < and != 
have the same
        -: 6350:     * precedence. This change is in the parser, too.
        -: 6351:     */
     5534: 6352:    precedence[TOKequal] = PREC_rel;
     5534: 6353:    precedence[TOKnotequal] = PREC_rel;
     5534: 6354:    precedence[TOKidentity] = PREC_rel;
     5534: 6355:    precedence[TOKnotidentity] = PREC_rel;
        -: 6356:#endif
        -: 6357:
     5534: 6358:    precedence[TOKand] = PREC_and;
        -: 6359:
     5534: 6360:    precedence[TOKxor] = PREC_xor;
        -: 6361:
     5534: 6362:    precedence[TOKor] = PREC_or;
        -: 6363:
     5534: 6364:    precedence[TOKandand] = PREC_andand;
        -: 6365:
     5534: 6366:    precedence[TOKoror] = PREC_oror;
        -: 6367:
     5534: 6368:    precedence[TOKquestion] = PREC_cond;
        -: 6369:
     5534: 6370:    precedence[TOKassign] = PREC_assign;
     5534: 6371:    precedence[TOKconstruct] = PREC_assign;
     5534: 6372:    precedence[TOKblit] = PREC_assign;
     5534: 6373:    precedence[TOKaddass] = PREC_assign;
     5534: 6374:    precedence[TOKminass] = PREC_assign;
     5534: 6375:    precedence[TOKcatass] = PREC_assign;
     5534: 6376:    precedence[TOKmulass] = PREC_assign;
     5534: 6377:    precedence[TOKdivass] = PREC_assign;
     5534: 6378:    precedence[TOKmodass] = PREC_assign;
     5534: 6379:    precedence[TOKpowass] = PREC_assign;
     5534: 6380:    precedence[TOKshlass] = PREC_assign;
     5534: 6381:    precedence[TOKshrass] = PREC_assign;
     5534: 6382:    precedence[TOKushrass] = PREC_assign;
     5534: 6383:    precedence[TOKandass] = PREC_assign;
     5534: 6384:    precedence[TOKorass] = PREC_assign;
     5534: 6385:    precedence[TOKxorass] = PREC_assign;
        -: 6386:
     5534: 6387:    precedence[TOKcomma] = PREC_expr;
     5534: 6388:    precedence[TOKdeclaration] = PREC_expr;
     5534: 6389:}
        -: 6390:
        -: 6391:



More information about the dmd-internals mailing list