/**
 * Takes a token stream from the lexer, and parses it into an abstract syntax tree.
 *
 * Specification: C11
 *
 * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
 * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
 * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
 * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/cparse.d, _cparse.d)
 * Documentation:  https://dlang.org/phobos/dmd_cparse.html
 * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/cparse.d
 */

module dmd.cparse;

import core.stdc.stdio;
import core.stdc.string;
import dmd.astenums;
import dmd.errorsink;
import dmd.globals;
import dmd.id;
import dmd.identifier;
import dmd.lexer;
import dmd.location;
import dmd.parse;
import dmd.errors;
import dmd.root.array;
import dmd.root.filename;
import dmd.common.outbuffer;
import dmd.root.rmem;
import dmd.root.rootobject;
import dmd.root.string;
import dmd.tokens;

/***********************************************************
 */
final class CParser(AST) : Parser!AST
{
    AST.Dsymbols* symbols;      // symbols declared in current scope

    bool addFuncName;           /// add declaration of __func__ to function symbol table
    bool importBuiltins;        /// seen use of C compiler builtins, so import __builtins;

    private
    {
        structalign_t packalign;        // current state of #pragma pack alignment

        // #pragma pack stack
        Array!Identifier* records;      // identifers (or null)
        Array!structalign_t* packs;     // parallel alignment values
    }

    /* C cannot be parsed without determining if an identifier is a type or a variable.
     * For expressions like `(T)-3`, is it a cast or a minus expression?
     * It also occurs with `typedef int (F)(); F fun;`
     * but to build the AST we need to distinguish `fun` being a function as opposed to a variable.
     * To fix, build a symbol table for the typedefs.
     * Symbol table of typedefs indexed by Identifier cast to void*.
     * 1. if an identifier is a typedef, then it will return a non-null Type
     * 2. if an identifier is not a typedef, then it will return null
     */
    Array!(void*) typedefTab;  /// Array of AST.Type[Identifier], typedef's indexed by Identifier

    /* This is passed in as a list of #define lines, as generated by the C preprocessor with the
     * appropriate switch to emit them. We append to it any #define's and #undef's encountered in the source
     * file, as cpp with the -dD embeds them in the preprocessed output file.
     * Once the file is parsed, then the #define's are converted to D symbols and appended to the array
     * of Dsymbols returned by parseModule().
     */
    OutBuffer* defines;

    extern (D) this(TARGET)(AST.Module _module, const(char)[] input, bool doDocComment,
                            ErrorSink errorSink,
                            const ref TARGET target, OutBuffer* defines) scope
    {
        super(_module, input, doDocComment, errorSink);

        //printf("CParser.this()\n");
        mod = _module;
        linkage = LINK.c;
        Ccompile = true;
        this.packalign.setDefault();
        this.defines = defines;

        // Configure sizes for C `long`, `long double`, `wchar_t`, ...
        this.boolsize = target.boolsize;
        this.shortsize = target.shortsize;
        this.intsize = target.intsize;
        this.longsize = target.longsize;
        this.long_longsize = target.long_longsize;
        this.long_doublesize = target.long_doublesize;
        this.wchar_tsize = target.wchar_tsize;

        // C `char` is always unsigned in ImportC
    }

    /********************************************
     * Parse translation unit.
     * C11 6.9
     * translation-unit:
     *    external-declaration
     *    translation-unit external-declaration
     *
     * external-declaration:
     *    function-definition
     *    declaration
     * Returns:
     *  array of Dsymbols that were declared
     */
    override AST.Dsymbols* parseModule()
    {
        //printf("cparseTranslationUnit()\n");
        symbols = new AST.Dsymbols();
        typedefTab.push(null);  // C11 6.2.1-3 symbol table for "file scope"
        while (1)
        {
            if (token.value == TOK.endOfFile)
            {
                addDefines();   // convert #define's to Dsymbols

                // wrap the symbols in `extern (C) { symbols }`
                auto wrap = new AST.Dsymbols();
                auto ld = new AST.LinkDeclaration(token.loc, LINK.c, symbols);
                wrap.push(ld);

                if (importBuiltins)
                {
                    /* Seen references to C builtin functions.
                     * Import their definitions
                     */
                    auto s = new AST.Import(Loc.initial, null, Id.builtins, null, false);
                    wrap.push(s);
                }

                // end of file scope
                typedefTab.pop();
                assert(typedefTab.length == 0);

                return wrap;
            }

            cparseDeclaration(LVL.global);
        }
    }

    /******************************************************************************/
    /********************************* Statement Parser ***************************/
    //{

    /**********************
     * C11 6.8
     * statement:
     *    labeled-statement
     *    compound-statement
     *    expression-statement
     *    selection-statement
     *    iteration-statement
     *    jump-statement
     *
     * Params:
     *      flags = PSxxxx
     *      endPtr = store location of closing brace
     *      pEndloc = if { ... statements ... }, store location of closing brace, otherwise loc of last token of statement
     * Returns:
     *      parsed statement
     */
    AST.Statement cparseStatement(int flags, const(char)** endPtr = null, Loc* pEndloc = null)
    {
        AST.Statement s;
        const loc = token.loc;

        //printf("cparseStatement()\n");

        const typedefTabLengthSave = typedefTab.length;
        auto symbolsSave = symbols;
        if (flags & ParseStatementFlags.scope_)
        {
            typedefTab.push(null);      // introduce new block scope
        }

        if (!(flags & (ParseStatementFlags.scope_ | ParseStatementFlags.curlyScope)))
        {
            symbols = new AST.Dsymbols();
        }

        switch (token.value)
        {
        case TOK.identifier:
            /* A leading identifier can be a declaration, label, or expression.
             * A quick check of the next token can disambiguate most cases.
             */
            switch (peekNext())
            {
                case TOK.colon:
                {
                    // It's a label
                    auto ident = token.ident;
                    nextToken();    // advance to `:`
                    nextToken();    // advance past `:`
                    if (token.value == TOK.rightCurly)
                        s = null;
                    else if (token.value == TOK.leftCurly)
                        s = cparseStatement(ParseStatementFlags.curly | ParseStatementFlags.scope_);
                    else
                        s = cparseStatement(ParseStatementFlags.semiOk);
                    s = new AST.LabelStatement(loc, ident, s);
                    break;
                }

                case TOK.dot:
                case TOK.arrow:
                case TOK.plusPlus:
                case TOK.minusMinus:
                case TOK.leftBracket:
                case TOK.question:
                case TOK.assign:
                case TOK.addAssign:
                case TOK.minAssign:
                case TOK.mulAssign:
                case TOK.divAssign:
                case TOK.modAssign:
                case TOK.andAssign:
                case TOK.orAssign:
                case TOK.xorAssign:
                case TOK.leftShiftAssign:
                case TOK.rightShiftAssign:
                    goto Lexp;

                case TOK.leftParenthesis:
                    if (auto pt = lookupTypedef(token.ident))
                    {
                        if (*pt)
                            goto Ldeclaration;
                    }
                    goto Lexp;  // function call

                default:
                {
                    /* If tokens look like a declaration, assume it is one
                     */
                    auto tk = &token;
                    if (isCDeclaration(tk))
                        goto Ldeclaration;
                    goto Lexp;
                }
            }
            break;

        case TOK.charLiteral:
        case TOK.int32Literal:
        case TOK.uns32Literal:
        case TOK.int64Literal:
        case TOK.uns64Literal:
        case TOK.int128Literal:
        case TOK.uns128Literal:
        case TOK.float32Literal:
        case TOK.float64Literal:
        case TOK.float80Literal:
        case TOK.imaginary32Literal:
        case TOK.imaginary64Literal:
        case TOK.imaginary80Literal:
        case TOK.leftParenthesis:
        case TOK.and:
        case TOK.mul:
        case TOK.min:
        case TOK.add:
        case TOK.tilde:
        case TOK.not:
        case TOK.plusPlus:
        case TOK.minusMinus:
        case TOK.sizeof_:
        case TOK._Generic:
        case TOK._assert:
        Lexp:
            auto exp = cparseExpression();
            if (token.value == TOK.identifier && exp.op == EXP.identifier)
            {
                error(token.loc, "found `%s` when expecting `;` or `=`, did you mean `%s %s = %s`?", peek(&token).toChars(), exp.toChars(), token.toChars(), peek(peek(&token)).toChars());
                nextToken();
            }
            else
                check(TOK.semicolon, "statement");
            s = new AST.ExpStatement(loc, exp);
            break;

        // type-specifiers
        case TOK.void_:
        case TOK.char_:
        case TOK.int16:
        case TOK.int32:
        case TOK.int64:
        case TOK.__int128:
        case TOK.float32:
        case TOK.float64:
        case TOK.signed:
        case TOK.unsigned:
        case TOK._Bool:
        //case TOK._Imaginary:
        case TOK._Complex:
        case TOK.struct_:
        case TOK.union_:
        case TOK.enum_:
        case TOK.typeof_:

        // storage-class-specifiers
        case TOK.typedef_:
        case TOK.extern_:
        case TOK.static_:
        case TOK._Thread_local:
        case TOK.auto_:
        case TOK.register:

        // function-specifiers
        case TOK.inline:
        case TOK._Noreturn:

        // type-qualifiers
        case TOK.const_:
        case TOK.volatile:
        case TOK.restrict:
        case TOK.__stdcall:

        // alignment-specifier
        case TOK._Alignas:

        // atomic-type-specifier or type_qualifier
        case TOK._Atomic:

        Ldeclaration:
        {
            cparseDeclaration(LVL.local);
            if (symbols.length > 1)
            {
                auto as = new AST.Statements();
                as.reserve(symbols.length);
                foreach (d; (*symbols)[])
                {
                    s = new AST.ExpStatement(loc, d);
                    as.push(s);
                }
                s = new AST.CompoundDeclarationStatement(loc, as);
                symbols.setDim(0);
            }
            else if (symbols.length == 1)
            {
                auto d = (*symbols)[0];
                s = new AST.ExpStatement(loc, d);
                symbols.setDim(0);
            }
            else
                s = new AST.ExpStatement(loc, cast(AST.Expression)null);
            if (flags & ParseStatementFlags.scope_)
                s = new AST.ScopeStatement(loc, s, token.loc);
            break;
        }

        case TOK._Static_assert:        // _Static_assert ( constant-expression, string-literal ) ;
            s = new AST.StaticAssertStatement(cparseStaticAssert());
            break;

        case TOK.leftCurly:
        {
            /* C11 6.8.2
             * compound-statement:
             *    { block-item-list (opt) }
             *
             * block-item-list:
             *    block-item
             *    block-item-list block-item
             *
             * block-item:
             *    declaration
             *    statement
             */
            nextToken();
            auto statements = new AST.Statements();
            while (token.value != TOK.rightCurly && token.value != TOK.endOfFile)
            {
                statements.push(cparseStatement(ParseStatementFlags.semi | ParseStatementFlags.curlyScope));
            }
            if (endPtr)
                *endPtr = token.ptr;
            endloc = token.loc;
            if (pEndloc)
            {
                *pEndloc = token.loc;
                pEndloc = null; // don't set it again
            }
            s = new AST.CompoundStatement(loc, statements);
            if (flags & (ParseStatementFlags.scope_ | ParseStatementFlags.curlyScope))
                s = new AST.ScopeStatement(loc, s, token.loc);
            check(TOK.rightCurly, "compound statement");
            break;
        }

        case TOK.while_:
        {
            nextToken();
            check(TOK.leftParenthesis);
            auto condition = cparseExpression();
            check(TOK.rightParenthesis);
            Loc endloc;
            auto _body = cparseStatement(ParseStatementFlags.scope_, null, &endloc);
            s = new AST.WhileStatement(loc, condition, _body, endloc, null);
            break;
        }

        case TOK.semicolon:
            /* C11 6.8.3 null statement
             */
            nextToken();
            s = new AST.ExpStatement(loc, cast(AST.Expression)null);
            break;

        case TOK.do_:
        {
            nextToken();
            auto _body = cparseStatement(ParseStatementFlags.scope_);
            check(TOK.while_);
            check(TOK.leftParenthesis);
            auto condition = cparseExpression();
            check(TOK.rightParenthesis);
            check(TOK.semicolon, "terminating `;` required after do-while statement");
            s = new AST.DoStatement(loc, _body, condition, token.loc);
            break;
        }

        case TOK.for_:
        {
            AST.Statement _init;
            AST.Expression condition;
            AST.Expression increment;

            nextToken();
            check(TOK.leftParenthesis);
            if (token.value == TOK.semicolon)
            {
                _init = null;
                nextToken();
            }
            else
            {
                _init = cparseStatement(0);
            }
            if (token.value == TOK.semicolon)
            {
                condition = null;
                nextToken();
            }
            else
            {
                condition = cparseExpression();
                check(TOK.semicolon, "`for` condition");
            }
            if (token.value == TOK.rightParenthesis)
            {
                increment = null;
                nextToken();
            }
            else
            {
                increment = cparseExpression();
                check(TOK.rightParenthesis);
            }
            Loc endloc;
            auto _body = cparseStatement(ParseStatementFlags.scope_, null, &endloc);
            s = new AST.ForStatement(loc, _init, condition, increment, _body, endloc);
            break;
        }

        case TOK.if_:
        {
            nextToken();
            check(TOK.leftParenthesis);
            auto condition = cparseExpression();
            check(TOK.rightParenthesis);
            auto ifbody = cparseStatement(ParseStatementFlags.scope_);
            AST.Statement elsebody;
            if (token.value == TOK.else_)
            {
                nextToken();
                elsebody = cparseStatement(ParseStatementFlags.scope_);
            }
            else
                elsebody = null;
            if (condition && ifbody)
                s = new AST.IfStatement(loc, null, condition, ifbody, elsebody, token.loc);
            else
                s = null; // don't propagate parsing errors
            break;
        }

        case TOK.else_:
            error("found `else` without a corresponding `if` statement");
            goto Lerror;

        case TOK.switch_:
        {
            nextToken();
            check(TOK.leftParenthesis);
            auto condition = cparseExpression();
            check(TOK.rightParenthesis);
            auto _body = cparseStatement(ParseStatementFlags.scope_);
            s = new AST.SwitchStatement(loc, condition, _body, false);
            break;
        }

        case TOK.case_:
        {

            nextToken();
            auto exp = cparseAssignExp();
            check(TOK.colon);

            if (flags & ParseStatementFlags.curlyScope)
            {
                auto statements = new AST.Statements();
                while (token.value != TOK.case_ && token.value != TOK.default_ && token.value != TOK.endOfFile && token.value != TOK.rightCurly)
                {
                    auto cur = cparseStatement(ParseStatementFlags.semi | ParseStatementFlags.curlyScope);
                    statements.push(cur);

                    // https://issues.dlang.org/show_bug.cgi?id=21739
                    // Stop at the last break s.t. the following non-case statements are
                    // not merged into the current case. This can happen for
                    // case 1: ... break;
                    // debug { case 2: ... }
                    if (cur && cur.isBreakStatement())
                        break;
                }
                s = new AST.CompoundStatement(loc, statements);
            }
            else
            {
                s = cparseStatement(ParseStatementFlags.semi);
            }
            s = new AST.ScopeStatement(loc, s, token.loc);
            s = new AST.CaseStatement(loc, exp, s);
            break;
        }

        case TOK.default_:
        {
            nextToken();
            check(TOK.colon);

            if (flags & ParseStatementFlags.curlyScope)
            {
                auto statements = new AST.Statements();
                while (token.value != TOK.case_ && token.value != TOK.default_ && token.value != TOK.endOfFile && token.value != TOK.rightCurly)
                {
                    statements.push(cparseStatement(ParseStatementFlags.semi | ParseStatementFlags.curlyScope));
                }
                s = new AST.CompoundStatement(loc, statements);
            }
            else
                s = cparseStatement(ParseStatementFlags.semi);
            s = new AST.ScopeStatement(loc, s, token.loc);
            s = new AST.DefaultStatement(loc, s);
            break;
        }

        case TOK.return_:
        {
            /*  return ;
             *  return expression ;
             */
            nextToken();
            auto exp = token.value == TOK.semicolon ? null : cparseExpression();
            check(TOK.semicolon, "`return` statement");
            s = new AST.ReturnStatement(loc, exp);
            break;
        }

        case TOK.break_:
            nextToken();
            check(TOK.semicolon, "`break` statement");
            s = new AST.BreakStatement(loc, null);
            break;

        case TOK.continue_:
            nextToken();
            check(TOK.semicolon, "`continue` statement");
            s = new AST.ContinueStatement(loc, null);
            break;

        case TOK.goto_:
        {
            Identifier ident;
            nextToken();
            if (token.value != TOK.identifier)
            {
                error("identifier expected following `goto`");
                ident = null;
            }
            else
            {
                ident = token.ident;
                nextToken();
            }
            s = new AST.GotoStatement(loc, ident);
            check(TOK.semicolon, "`goto` statement");
            break;
        }

        case TOK.asm_:
            s = parseAsm();
            break;

        default:
            error("found `%s` instead of statement", token.toChars());
            goto Lerror;

        Lerror:
            panic();
            if (token.value == TOK.semicolon)
                nextToken();
            s = null;
            break;
        }
        if (pEndloc)
            *pEndloc = prevloc;
        symbols = symbolsSave;
        typedefTab.setDim(typedefTabLengthSave);
        return s;
    }

    //}
    /*******************************************************************************/
    /********************************* Expression Parser ***************************/
    //{

    /**************
     * C11 6.5.17
     * expression:
     *  assignment-expression
     *  expression , assignment-expression
     */
    AST.Expression cparseExpression()
    {
        auto loc = token.loc;

        //printf("cparseExpression() loc = %d\n", loc.linnum);
        auto e = cparseAssignExp();
        while (token.value == TOK.comma)
        {
            nextToken();
            auto e2 = cparseAssignExp();
            e = new AST.CommaExp(loc, e, e2, false);
            loc = token.loc;
        }
        return e;
    }


    /*********************
     * C11 6.5.1
     * primary-expression:
     *    identifier
     *    constant
     *    string-literal
     *    ( expression )
     *    generic-selection
     *    __builtin_va_arg(assign_expression, type)
     */
    AST.Expression cparsePrimaryExp()
    {
        AST.Expression e;
        const loc = token.loc;

        //printf("parsePrimaryExp(): loc = %d\n", loc.linnum);
        switch (token.value)
        {
        case TOK.identifier:
            const id = token.ident.toString();
            if (id.length > 2 && id[0] == '_' && id[1] == '_')  // leading double underscore
            {
                if (token.ident is Id.__func__)
                {
                    addFuncName = true;     // implicitly declare __func__
                }
                else if (token.ident is Id.builtin_va_arg)
                {
                    e = cparseBuiltin_va_arg();
                    break;
                }
                else
                    importBuiltins = true;  // probably one of those compiler extensions
            }
            e = new AST.IdentifierExp(loc, token.ident);
            nextToken();
            break;

        case TOK.charLiteral:
        case TOK.int32Literal:
            e = new AST.IntegerExp(loc, token.intvalue, AST.Type.tint32);
            nextToken();
            break;

        case TOK.uns32Literal:
            e = new AST.IntegerExp(loc, token.unsvalue, AST.Type.tuns32);
            nextToken();
            break;

        case TOK.int64Literal:
            e = new AST.IntegerExp(loc, token.intvalue, AST.Type.tint64);
            nextToken();
            break;

        case TOK.uns64Literal:
            e = new AST.IntegerExp(loc, token.unsvalue, AST.Type.tuns64);
            nextToken();
            break;

        case TOK.float32Literal:
            e = new AST.RealExp(loc, token.floatvalue, AST.Type.tfloat32);
            nextToken();
            break;

        case TOK.float64Literal:
            e = new AST.RealExp(loc, token.floatvalue, AST.Type.tfloat64);
            nextToken();
            break;

        case TOK.float80Literal:
            e = new AST.RealExp(loc, token.floatvalue, AST.Type.tfloat80);
            nextToken();
            break;

        case TOK.imaginary32Literal:
            e = new AST.RealExp(loc, token.floatvalue, AST.Type.timaginary32);
            nextToken();
            break;

        case TOK.imaginary64Literal:
            e = new AST.RealExp(loc, token.floatvalue, AST.Type.timaginary64);
            nextToken();
            break;

        case TOK.imaginary80Literal:
            e = new AST.RealExp(loc, token.floatvalue, AST.Type.timaginary80);
            nextToken();
            break;

        case TOK.string_:
        {
            // cat adjacent strings
            auto s = token.ustring;
            auto len = token.len;
            auto postfix = token.postfix;
            while (1)
            {
                nextToken();
                if (token.value == TOK.string_)
                {
                    if (token.postfix)
                    {
                        if (token.postfix != postfix)
                            error(token.loc, "mismatched string literal postfixes `'%c'` and `'%c'`", postfix, token.postfix);
                        postfix = token.postfix;
                    }

                    const len1 = len;
                    const len2 = token.len;
                    len = len1 + len2;
                    auto s2 = cast(char*)mem.xmalloc_noscan(len * char.sizeof);
                    memcpy(s2, s, len1 * char.sizeof);
                    memcpy(s2 + len1, token.ustring, len2 * char.sizeof);
                    s = s2;
                }
                else
                    break;
            }
            e = new AST.StringExp(loc, s[0 .. len], len, 1, postfix);
            break;
        }

        case TOK.leftParenthesis:
            nextToken();
            e = cparseExpression();
            check(TOK.rightParenthesis);
            break;

        case TOK._Generic:
            e = cparseGenericSelection();
            break;

        case TOK._assert:  // __check(assign-exp) extension
            nextToken();
            check(TOK.leftParenthesis, "`__check`");
            e = parseAssignExp();
            check(TOK.rightParenthesis);
            e = new AST.AssertExp(loc, e, null);
            break;

        default:
            error("expression expected, not `%s`", token.toChars());
            // Anything for e, as long as it's not NULL
            e = new AST.IntegerExp(loc, 0, AST.Type.tint32);
            nextToken();
            break;
        }
        return e;
    }

    /*********************************
     * C11 6.5.2
     * postfix-expression:
     *    primary-expression
     *    postfix-expression [ expression ]
     *    postfix-expression ( argument-expression-list (opt) )
     *    postfix-expression . identifier
     *    postfix-expression -> identifier
     *    postfix-expression ++
     *    postfix-expression --
     *    ( type-name ) { initializer-list }
     *    ( type-name ) { initializer-list , }
     *
     * argument-expression-list:
     *    assignment-expression
     *    argument-expression-list , assignment-expression
     */
    private AST.Expression cparsePostfixExp(AST.Expression e)
    {
        e = cparsePrimaryExp();
        return cparsePostfixOperators(e);
    }

    /********************************
     * C11 6.5.2
     * Parse a series of operators for a postfix expression after already parsing
     * a primary-expression or compound literal expression.
     * Params:
     *      e = parsed primary or compound literal expression
     * Returns:
     *      parsed postfix expression
     */
    private AST.Expression cparsePostfixOperators(AST.Expression e)
    {
        while (1)
        {
            const loc = token.loc;
            switch (token.value)
            {
            case TOK.dot:
                nextToken();
                if (token.value == TOK.identifier)
                {
                    Identifier id = token.ident;
                    e = new AST.DotIdExp(loc, e, id);
                    break;
                }
                error("identifier expected following `.`, not `%s`", token.toChars());
                break;

            case TOK.arrow:
                nextToken();
                if (token.value == TOK.identifier)
                {
                    Identifier id = token.ident;
                    auto die = new AST.DotIdExp(loc, e, id);
                    die.arrow = true;
                    e = die;
                    break;
                }
                error("identifier expected following `->`, not `%s`", token.toChars());
                break;

            case TOK.plusPlus:
                e = new AST.PostExp(EXP.plusPlus, loc, e);
                break;

            case TOK.minusMinus:
                e = new AST.PostExp(EXP.minusMinus, loc, e);
                break;

            case TOK.leftParenthesis:
                e = new AST.CallExp(loc, e, cparseArguments());
                continue;

            case TOK.leftBracket:
                {
                    // array dereferences:
                    //      array[index]
                    AST.Expression index;
                    auto arguments = new AST.Expressions();

                    inBrackets++;
                    nextToken();
                    index = cparseAssignExp();
                    arguments.push(index);
                    check(TOK.rightBracket);
                    inBrackets--;
                    e = new AST.ArrayExp(loc, e, arguments);
                    continue;
                }
            default:
                return e;
            }
            nextToken();
        }
    }

    /************************
     * C11 6.5.3
     * unary-expression:
     *    postfix-expression
     *    ++ unary-expression
     *    -- unary-expression
     *    unary-operator cast-expression
     *    sizeof unary-expression
     *    sizeof ( type-name )
     *    _Alignof ( type-name )
     *
     * unary-operator:
     *    & * + - ~ !
     */
    private AST.Expression cparseUnaryExp()
    {
        AST.Expression e;
        const loc = token.loc;

        switch (token.value)
        {
        case TOK.plusPlus:
            nextToken();
            // Parse `++` as an unary operator so that cast expressions only give
            // an error for being non-lvalues.
            e = cparseCastExp();
            e = new AST.PreExp(EXP.prePlusPlus, loc, e);
            break;

        case TOK.minusMinus:
            nextToken();
            // Parse `--` as an unary operator, same as prefix increment.
            e = cparseCastExp();
            e = new AST.PreExp(EXP.preMinusMinus, loc, e);
            break;

        case TOK.and:
            nextToken();
            e = cparseCastExp();
            e = new AST.AddrExp(loc, e);
            break;

        case TOK.mul:
            nextToken();
            e = cparseCastExp();
            e = new AST.PtrExp(loc, e);
            break;

        case TOK.min:
            nextToken();
            e = cparseCastExp();
            e = new AST.NegExp(loc, e);
            break;

        case TOK.add:
            nextToken();
            e = cparseCastExp();
            e = new AST.UAddExp(loc, e);
            break;

        case TOK.not:
            nextToken();
            e = cparseCastExp();
            e = new AST.NotExp(loc, e);
            break;

        case TOK.tilde:
            nextToken();
            e = cparseCastExp();
            e = new AST.ComExp(loc, e);
            break;

        case TOK.sizeof_:
        {
            nextToken();
            if (token.value == TOK.leftParenthesis)
            {
                auto tk = peek(&token);
                if (isTypeName(tk))
                {
                    /* Expression may be either be requesting the sizeof a type-name
                     * or a compound literal, which requires checking whether
                     * the next token is leftCurly
                     */
                    nextToken();
                    auto t = cparseTypeName();
                    check(TOK.rightParenthesis);
                    if (token.value == TOK.leftCurly)
                    {
                        // ( type-name ) { initializer-list }
                        auto ci = cparseInitializer();
                        e = new AST.CompoundLiteralExp(loc, t, ci);
                        e = cparsePostfixOperators(e);
                    }
                    else
                    {
                        // ( type-name )
                        e = new AST.TypeExp(loc, t);
                    }
                }
                else
                {
                    // must be an expression
                    e = cparseUnaryExp();
                }
            }
            else
            {
                //C11 6.5.3
                e = cparseUnaryExp();
            }

            e = new AST.DotIdExp(loc, e, Id.__sizeof);
            break;
        }

        case TOK._Alignof:
        {
            nextToken();
            check(TOK.leftParenthesis);
            auto t = cparseTypeName();
            check(TOK.rightParenthesis);
            e = new AST.TypeExp(loc, t);
            e = new AST.DotIdExp(loc, e, Id.__xalignof);
            break;
        }

        default:
            e = cparsePostfixExp(e);
            break;
        }
        assert(e);
        return e;
    }

    /**************
     * C11 6.5.4
     * cast-expression
     *    unary-expression
     *    ( type-name ) cast-expression
     */
    private AST.Expression cparseCastExp()
    {
        if (token.value == TOK.leftParenthesis)
        {
            //printf("cparseCastExp()\n");
            auto tk = peek(&token);
            bool iscast;
            bool isexp;
            if (tk.value == TOK.identifier)
            {
                iscast = isTypedef(tk.ident);
                isexp = !iscast;
            }
            if (isexp)
            {
                // ( identifier ) is an expression
                return cparseUnaryExp();
            }

            // If ( type-name )
            auto pt = &token;

            if (isCastExpression(pt))
            {
                // Expression may be either a cast or a compound literal, which
                // requires checking whether the next token is leftCurly
                const loc = token.loc;
                nextToken();
                auto t = cparseTypeName();
                check(TOK.rightParenthesis);
                pt = &token;

                if (token.value == TOK.leftCurly)
                {
                    // C11 6.5.2.5 ( type-name ) { initializer-list }
                    auto ci = cparseInitializer();
                    auto ce = new AST.CompoundLiteralExp(loc, t, ci);
                    return cparsePostfixOperators(ce);
                }

                if (iscast)
                {
                    // ( type-name ) cast-expression
                    auto ce = cparseCastExp();
                    return new AST.CastExp(loc, ce, t);
                }

                if (t.isTypeIdentifier() &&
                    isexp &&
                    token.value == TOK.leftParenthesis &&
                    !isCastExpression(pt))
                {
                    /* (t)(...)... might be a cast expression or a function call,
                     * with different grammars: a cast would be cparseCastExp(),
                     * a function call would be cparsePostfixExp(CallExp(cparseArguments())).
                     * We can't know until t is known. So, parse it as a function call
                     * and let semantic() rewrite the AST as a CastExp if it turns out
                     * to be a type.
                     */
                    auto ie = new AST.IdentifierExp(loc, t.isTypeIdentifier().ident);
                    ie.parens = true;    // let semantic know it might be a CastExp
                    AST.Expression e = new AST.CallExp(loc, ie, cparseArguments());
                    return cparsePostfixOperators(e);
                }

                // ( type-name ) cast-expression
                auto ce = cparseCastExp();
                return new AST.CastExp(loc, ce, t);
            }
        }
        return cparseUnaryExp();
    }

    /**************
     * C11 6.5.5
     * multiplicative-expression
     *    cast-expression
     *    multiplicative-expression * cast-expression
     *    multiplicative-expression / cast-expression
     *    multiplicative-expression % cast-expression
     */
    private AST.Expression cparseMulExp()
    {
        const loc = token.loc;
        auto e = cparseCastExp();

        while (1)
        {
            switch (token.value)
            {
            case TOK.mul:
                nextToken();
                auto e2 = cparseCastExp();
                e = new AST.MulExp(loc, e, e2);
                continue;

            case TOK.div:
                nextToken();
                auto e2 = cparseCastExp();
                e = new AST.DivExp(loc, e, e2);
                continue;

            case TOK.mod:
                nextToken();
                auto e2 = cparseCastExp();
                e = new AST.ModExp(loc, e, e2);
                continue;

            default:
                break;
            }
            break;
        }
        return e;
    }

    /**************
     * C11 6.5.6
     * additive-expression
     *    multiplicative-expression
     *    additive-expression + multiplicative-expression
     *    additive-expression - multiplicative-expression
     */
    private AST.Expression cparseAddExp()
    {
        const loc = token.loc;
        auto e = cparseMulExp();

        while (1)
        {
            switch (token.value)
            {
            case TOK.add:
                nextToken();
                auto e2 = cparseMulExp();
                e = new AST.AddExp(loc, e, e2);
                continue;

            case TOK.min:
                nextToken();
                auto e2 = cparseMulExp();
                e = new AST.MinExp(loc, e, e2);
                continue;

            default:
                break;
            }
            break;
        }
        return e;
    }

    /**************
     * C11 6.5.7
     * shift-expression
     *    additive-expression
     *    shift-expression << additive-expression
     *    shift-expression >> additive-expression
     */
    private AST.Expression cparseShiftExp()
    {
        const loc = token.loc;
        auto e = cparseAddExp();

        while (1)
        {
            switch (token.value)
            {
            case TOK.leftShift:
                nextToken();
                auto e2 = cparseAddExp();
                e = new AST.ShlExp(loc, e, e2);
                continue;

            case TOK.rightShift:
                nextToken();
                auto e2 = cparseAddExp();
                e = new AST.ShrExp(loc, e, e2);
                continue;

            default:
                break;
            }
            break;
        }
        return e;
    }

    /**************
     * C11 6.5.8
     * relational-expression
     *    shift-expression
     *    relational-expression < shift-expression
     *    relational-expression > shift-expression
     *    relational-expression <= shift-expression
     *    relational-expression >= shift-expression
     */
    private AST.Expression cparseRelationalExp()
    {
        const loc = token.loc;

        auto e = cparseShiftExp();

        EXP op = EXP.reserved;
        switch (token.value)
        {
        case TOK.lessThan:       op = EXP.lessThan; goto Lcmp;
        case TOK.lessOrEqual:    op = EXP.lessOrEqual; goto Lcmp;
        case TOK.greaterThan:    op = EXP.greaterThan; goto Lcmp;
        case TOK.greaterOrEqual: op = EXP.greaterOrEqual; goto Lcmp;
        Lcmp:
            nextToken();
            auto e2 = cparseShiftExp();
            e = new AST.CmpExp(op, loc, e, e2);
            break;

        default:
            break;
        }
        return e;
    }

    /**************
     * C11 6.5.9
     * equality-expression
     *    relational-expression
     *    equality-expression == relational-expression
     *    equality-expression != relational-expression
     */
    private AST.Expression cparseEqualityExp()
    {
        const loc = token.loc;

        auto e = cparseRelationalExp();

        EXP op = EXP.reserved;
        switch (token.value)
        {
        case TOK.equal:         op = EXP.equal;    goto Lequal;
        case TOK.notEqual:      op = EXP.notEqual; goto Lequal;
        Lequal:
            nextToken();
            auto e2 = cparseRelationalExp();
            e = new AST.EqualExp(op, loc, e, e2);
            break;

        default:
            break;
        }
        return e;
    }

    /**************
     * C11 6.5.10
     * AND-expression
     *    equality-expression
     *    AND-expression & equality-expression
     */
    private AST.Expression cparseAndExp()
    {
        Loc loc = token.loc;
        auto e = cparseEqualityExp();
        while (token.value == TOK.and)
        {
            nextToken();
            auto e2 = cparseEqualityExp();
            e = new AST.AndExp(loc, e, e2);
            loc = token.loc;
        }
        return e;
    }

    /**************
     * C11 6.5.11
     * exclusive-OR-expression
     *    AND-expression
     *    exclusive-OR-expression ^ AND-expression
     */
    private AST.Expression cparseXorExp()
    {
        const loc = token.loc;

        auto e = cparseAndExp();
        while (token.value == TOK.xor)
        {
            nextToken();
            auto e2 = cparseAndExp();
            e = new AST.XorExp(loc, e, e2);
        }
        return e;
    }

    /**************
     * C11 6.5.12
     * inclusive-OR-expression
     *    exclusive-OR-expression
     *    inclusive-OR-expression | exclusive-OR-expression
     */
    private AST.Expression cparseOrExp()
    {
        const loc = token.loc;

        auto e = cparseXorExp();
        while (token.value == TOK.or)
        {
            nextToken();
            auto e2 = cparseXorExp();
            e = new AST.OrExp(loc, e, e2);
        }
        return e;
    }

    /**************
     * C11 6.5.13
     * logical-AND-expression
     *    inclusive-OR-expression
     *    logical-AND-expression && inclusive-OR-expression
     */
    private AST.Expression cparseAndAndExp()
    {
        const loc = token.loc;

        auto e = cparseOrExp();
        while (token.value == TOK.andAnd)
        {
            nextToken();
            auto e2 = cparseOrExp();
            e = new AST.LogicalExp(loc, EXP.andAnd, e, e2);
        }
        return e;
    }

    /**************
     * C11 6.5.14
     * logical-OR-expression
     *    logical-AND-expression
     *    logical-OR-expression || logical-AND-expression
     */
    private AST.Expression cparseOrOrExp()
    {
        const loc = token.loc;

        auto e = cparseAndAndExp();
        while (token.value == TOK.orOr)
        {
            nextToken();
            auto e2 = cparseAndAndExp();
            e = new AST.LogicalExp(loc, EXP.orOr, e, e2);
        }
        return e;
    }

    /**************
     * C11 6.5.15
     * conditional-expression:
     *    logical-OR-expression
     *    logical-OR-expression ? expression : conditional-expression
     */
    private AST.Expression cparseCondExp()
    {
        const loc = token.loc;

        auto e = cparseOrOrExp();
        if (token.value == TOK.question)
        {
            nextToken();
            auto e1 = cparseExpression();
            check(TOK.colon);
            auto e2 = cparseCondExp();
            e = new AST.CondExp(loc, e, e1, e2);
        }
        return e;
    }

    /**************
     * C11 6.5.16
     * assignment-expression:
     *    conditional-expression
     *    unary-expression assignment-operator assignment-expression
     *
     * assignment-operator:
     *    = *= /= %= += -= <<= >>= &= ^= |=
     */
    AST.Expression cparseAssignExp()
    {
        AST.Expression e;
        e = cparseCondExp(); // constrain it to being unary-expression in semantic pass
        if (e is null)
            return e;

        const loc = token.loc;
        switch (token.value)
        {
        case TOK.assign:
            nextToken();
            auto e2 = cparseAssignExp();
            e = new AST.AssignExp(loc, e, e2);
            break;

        case TOK.addAssign:
            nextToken();
            auto e2 = cparseAssignExp();
            e = new AST.AddAssignExp(loc, e, e2);
            break;

        case TOK.minAssign:
            nextToken();
            auto e2 = cparseAssignExp();
            e = new AST.MinAssignExp(loc, e, e2);
            break;

        case TOK.mulAssign:
            nextToken();
            auto e2 = cparseAssignExp();
            e = new AST.MulAssignExp(loc, e, e2);
            break;

        case TOK.divAssign:
            nextToken();
            auto e2 = cparseAssignExp();
            e = new AST.DivAssignExp(loc, e, e2);
            break;

        case TOK.modAssign:
            nextToken();
            auto e2 = cparseAssignExp();
            e = new AST.ModAssignExp(loc, e, e2);
            break;

        case TOK.andAssign:
            nextToken();
            auto e2 = cparseAssignExp();
            e = new AST.AndAssignExp(loc, e, e2);
            break;

        case TOK.orAssign:
            nextToken();
            auto e2 = cparseAssignExp();
            e = new AST.OrAssignExp(loc, e, e2);
            break;

        case TOK.xorAssign:
            nextToken();
            auto e2 = cparseAssignExp();
            e = new AST.XorAssignExp(loc, e, e2);
            break;

        case TOK.leftShiftAssign:
            nextToken();
            auto e2 = cparseAssignExp();
            e = new AST.ShlAssignExp(loc, e, e2);
            break;

        case TOK.rightShiftAssign:
            nextToken();
            auto e2 = cparseAssignExp();
            e = new AST.ShrAssignExp(loc, e, e2);
            break;

        default:
            break;
        }

        return e;
    }

    /***********************
     * C11 6.5.1.1
     * _Generic ( assignment-expression, generic-assoc-list )
     *
     * generic-assoc-list:
     *   generic-association
     *   generic-assoc-list generic-association
     *
     * generic-association:
     *   type-name : assignment-expression
     *   default : assignment-expression
     */
    private AST.Expression cparseGenericSelection()
    {
        const loc = token.loc;
        nextToken();
        check(TOK.leftParenthesis);
        auto cntlExp = cparseAssignExp();
        check(TOK.comma);
        auto types = new AST.Types();
        auto exps = new AST.Expressions();
        bool sawDefault;
        while (1)
        {
            AST.Type t;
            if (token.value == TOK.default_)
            {
                nextToken();
                if (sawDefault)
                    error("only one `default` allowed in generic-assoc-list");
                sawDefault = true;
                t = null;
            }
            else
                t = cparseTypeName();
            types.push(t);

            check(TOK.colon);
            auto e = cparseAssignExp();
            exps.push(e);
            if (token.value == TOK.rightParenthesis || token.value == TOK.endOfFile)
                break;
            check(TOK.comma);
        }
        check(TOK.rightParenthesis);
        return new AST.GenericExp(loc, cntlExp, types, exps);
    }

    /***********************
     * C11 6.6 Constant expressions
     * constant-expression:
     *   conditional-expression
     */
    private AST.Expression cparseConstantExp()
    {
        return cparseAssignExp();
    }

    /*****************************
     * gcc extension:
     *    type __builtin_va_arg(assign-expression, type)
     * Rewrite as `va_arg` template from `core.stdc.stdarg`:
     *    va_arg!(type)(assign-expression);
     * Lexer is on `__builtin_va_arg`
     */
    private AST.Expression cparseBuiltin_va_arg()
    {
        importBuiltins = true;  // need core.stdc.stdarg

        nextToken();
        check(TOK.leftParenthesis);

        auto arguments = new AST.Expressions();
        auto arg = cparseAssignExp();
        arguments.push(arg);

        check(TOK.comma);

        auto t = cparseTypeName();
        auto tiargs = new AST.Objects();
        tiargs.push(t);

        const loc = loc;
        auto ti = new AST.TemplateInstance(loc, Id.va_arg, tiargs);
        auto tie = new AST.ScopeExp(loc, ti);

        AST.Expression e = new AST.CallExp(loc, tie, arguments);

        check(TOK.rightParenthesis);
        return e;
    }

    //}
    /********************************************************************************/
    /********************************* Declaration Parser ***************************/
    //{

    /*************************************
     * C11 6.7
     * declaration:
     *    declaration-specifiers init-declarator-list (opt) ;
     *    static_assert-declaration
     *
     * init-declarator-list:
     *    init-declarator
     *    init-declarator-list , init-declarator
     *
     * init-declarator:
     *    declarator
     *    declarator = initializer
     *
     * Params:
     *    level = declaration context
     */
    void cparseDeclaration(LVL level)
    {
        //printf("cparseDeclaration(level = %d)\n", level);
        if (token.value == TOK._Static_assert)
        {
            auto s = cparseStaticAssert();
            symbols.push(s);
            return;
        }

        if (token.value == TOK.__pragma)
        {
            uupragmaDirective(scanloc);
            return;
        }

        if (token.value == TOK._import) // import declaration extension
        {
            auto a = parseImport();
            if (a && a.length)
                symbols.append(a);
            return;
        }

        const typedefTabLengthSave = typedefTab.length;
        auto symbolsSave = symbols;
        Specifier specifier;
        specifier.packalign = this.packalign;
        auto tspec = cparseDeclarationSpecifiers(level, specifier);

        AST.Dsymbol declareTag(AST.TypeTag tt, ref Specifier specifier)
        {
            /* `struct tag;` and `struct tag { ... };`
             * always result in a declaration in the current scope
             */
            auto stag = (tt.tok == TOK.struct_) ? new AST.StructDeclaration(tt.loc, tt.id, false) :
                        (tt.tok == TOK.union_)  ? new AST.UnionDeclaration(tt.loc, tt.id) :
                                                  new AST.EnumDeclaration(tt.loc, tt.id, tt.base);
            stag.members = tt.members;
            tt.members = null;
            if (!symbols)
                symbols = new AST.Dsymbols();
            auto stags = applySpecifier(stag, specifier);
            symbols.push(stags);
            return stags;
        }

        /* If a declarator does not follow, it is unnamed
         */
        if (token.value == TOK.semicolon)
        {
            if (!tspec)
            {
                nextToken();
                return;         // accept empty declaration as an extension
            }

            if (auto ti = tspec.isTypeIdentifier())
            {
                // C11 6.7.2-2
                error("type-specifier missing for declaration of `%s`", ti.ident.toChars());
                nextToken();
                return;
            }

            nextToken();
            auto tt = tspec.isTypeTag();
            if (!tt ||
                !tt.id && (tt.tok == TOK.struct_ || tt.tok == TOK.union_))
                return; // legal but meaningless empty declaration, ignore it

            auto stags = declareTag(tt, specifier);

            if (0 && tt.tok == TOK.enum_)    // C11 proscribes enums with no members, but we allow it
            {
                if (!tt.members)
                    error(tt.loc, "`enum %s` has no members", stags.toChars());
            }
            return;
        }

        if (!tspec)
        {
            error("no type for declarator before `%s`", token.toChars());
            panic();
            nextToken();
            return;
        }

        if (tspec && specifier.mod & MOD.xconst)
        {
            tspec = toConst(tspec);
            specifier.mod &= ~MOD.xnone;          // 'used' it
        }

        void scanPastSemicolon()
        {
            while (token.value != TOK.semicolon && token.value != TOK.endOfFile)
                nextToken();
            nextToken();
        }

        if (token.value == TOK.assign && tspec && tspec.isTypeIdentifier())
        {
            /* C11 6.7.2-2
             * Special check for `const b = 1;` because some compilers allow it
             */
            error("type-specifier omitted for declaration of `%s`", tspec.isTypeIdentifier().ident.toChars());
            return scanPastSemicolon();
        }

        bool first = true;
        while (1)
        {
            Identifier id;
            AST.StringExp asmName;
            auto dt = cparseDeclarator(DTR.xdirect, tspec, id, specifier);
            if (!dt)
            {
                panic();
                nextToken();
                break;          // error recovery
            }

            /* GNU Extensions
             * init-declarator:
             *    declarator simple-asm-expr (opt) gnu-attributes (opt)
             *    declarator simple-asm-expr (opt) gnu-attributes (opt) = initializer
             */
            switch (token.value)
            {
                case TOK.assign:
                case TOK.comma:
                case TOK.semicolon:
                case TOK.asm_:
                case TOK.__attribute__:
                    if (token.value == TOK.asm_)
                        asmName = cparseSimpleAsmExpr();
                    if (token.value == TOK.__attribute__)
                    {
                        cparseGnuAttributes(specifier);
                        if (token.value == TOK.leftCurly)
                            break;              // function definition
                    }
                    /* This is a data definition, there cannot now be a
                     * function definition.
                     */
                    first = false;
                    break;

                default:
                    break;
            }

            if (specifier.alignExps && dt.isTypeFunction())
                error("no alignment-specifier for function declaration"); // C11 6.7.5-2
            if (specifier.alignExps && specifier.scw == SCW.xregister)
                error("no alignment-specifier for `register` storage class"); // C11 6.7.5-2

            /* C11 6.9.1 Function Definitions
             * function-definition:
             *   declaration-specifiers declarator declaration-list (opt) compound-statement
             *
             * declaration-list:
             *    declaration
             *    declaration-list declaration
             */
            auto t = &token;
            if (first &&                   // first declarator
                id &&
                dt.isTypeFunction() &&     // function type not inherited from a typedef
                isDeclarationList(t) &&    // optional declaration-list
                level == LVL.global &&     // function definitions only at global scope
                t.value == TOK.leftCurly)  // start of compound-statement
            {
                auto s = cparseFunctionDefinition(id, dt.isTypeFunction(), specifier);
                typedefTab.setDim(typedefTabLengthSave);
                symbols = symbolsSave;
                symbols.push(s);
                return;
            }
            AST.Dsymbol s = null;
            typedefTab.setDim(typedefTabLengthSave);
            symbols = symbolsSave;
            if (!symbols)
                symbols = new AST.Dsymbols;     // lazilly create it

            if (level != LVL.global && !tspec && !specifier.scw && !specifier.mod)
                error("declaration-specifier-seq required");
            else if (specifier.scw == SCW.xtypedef)
            {
                if (token.value == TOK.assign)
                    error("no initializer for typedef declaration");
                if (specifier.alignExps)
                    error("no alignment-specifier for typedef declaration"); // C11 6.7.5-2

                bool isalias = true;
                if (auto ts = dt.isTypeStruct())
                {
                    if (ts.sym.isAnonymous())
                    {
                        // This is a typedef for an anonymous struct-or-union.
                        // Directly set the ident for the struct-or-union.
                        ts.sym.ident = id;
                        isalias = false;
                    }
                }
                else if (auto te = dt.isTypeEnum())
                {
                    if (te.sym.isAnonymous())
                    {
                        // This is a typedef for an anonymous enum.
                        te.sym.ident = id;
                        isalias = false;
                    }
                }
                else if (auto tt = dt.isTypeTag())
                {
                    if (tt.id || tt.tok == TOK.enum_)
                    {
                        if (!tt.id && id)
                            tt.id = id;
                        Specifier spec;
                        auto stag = declareTag(tt, spec);
                        if (tt.tok == TOK.enum_)
                        {
                            isalias = false;
                            s = new AST.AliasDeclaration(token.loc, id, stag);
                        }
                    }
                }
                if (isalias)
                    s = new AST.AliasDeclaration(token.loc, id, dt);
                insertTypedefToTypedefTab(id, dt);       // remember typedefs
            }
            else if (id)
            {
                if (auto tt = dt.isTypeTag())
                {
                    if (tt.members && (tt.id || tt.tok == TOK.enum_))
                    {
                        Specifier spec;
                        declareTag(tt, spec);
                    }
                }

                if (level == LVL.prototype)
                    break;      // declared later as Parameter, not VarDeclaration

                if (dt.ty == AST.Tvoid)
                    error("`void` has no value");

                AST.Initializer initializer;
                bool hasInitializer;
                if (token.value == TOK.assign)
                {
                    nextToken();
                    hasInitializer = true;
                    initializer = cparseInitializer();
                }
                // declare the symbol
                assert(id);

                if (isFunctionTypedef(dt))
                {
                    if (hasInitializer)
                        error("no initializer for function declaration");
                    if (specifier.scw & SCW.x_Thread_local)
                        error("functions cannot be `_Thread_local`"); // C11 6.7.1-4
                    auto fd = new AST.FuncDeclaration(token.loc, Loc.initial, id, specifiersToSTC(level, specifier), dt, specifier.noreturn);
                    s = fd;
                }
                else
                {
                    // Give non-extern variables an implicit void initializer
                    // if one has not been explicitly set.
                    if (!hasInitializer &&
                        !(specifier.scw & (SCW.xextern | SCW.xstatic | SCW.x_Thread_local) || level == LVL.global))
                        initializer = new AST.VoidInitializer(token.loc);
                    s = new AST.VarDeclaration(token.loc, dt, id, initializer, specifiersToSTC(level, specifier));
                }
                if (level != LVL.global)
                    insertIdToTypedefTab(id);   // non-typedef declarations can hide typedefs in outer scopes
            }
            if (s !is null)
            {
                // Saw `asm("name")` in the function, type, or variable definition.
                // This is equivalent to `pragma(mangle, "name")` in D
                if (asmName)
                {
                    /*
                    https://issues.dlang.org/show_bug.cgi?id=23012
                    Ideally this would be translated to a pragma(mangle)
                    decl. This is not possible because ImportC symbols are
                    (currently) merged before semantic analysis is performed,
                    so the pragma(mangle) never effects any change on the declarations
                    it pertains too.

                    Writing to mangleOverride directly avoids this, and is possible
                    because C only a StringExp is allowed unlike a full fat pragma(mangle)
                    which is more liberal.
                    */
                    if (auto p = s.isDeclaration())
                    {
                        auto str = asmName.peekString();
                        p.mangleOverride = str;
//                      p.adFlags |= AST.VarDeclaration.nounderscore;
                        p.adFlags |= 4; // cannot get above line to compile on Ubuntu
                    }
                }
                s = applySpecifier(s, specifier);
                if (level == LVL.local)
                {
                    // Wrap the declaration in `extern (C) { declaration }`
                    // Necessary for function pointers, but harmless to apply to all.
                    auto decls = new AST.Dsymbols(1);
                    (*decls)[0] = s;
                    s = new AST.LinkDeclaration(s.loc, linkage, decls);
                }
                symbols.push(s);
            }
            first = false;

            switch (token.value)
            {
                case TOK.identifier:
                    if (s)
                    {
                        error(token.loc, "missing comma or semicolon after declaration of `%s`, found `%s` instead", s.toChars(), token.toChars());
                        goto Lend;
                    }
                    goto default;

                case TOK.semicolon:
                    nextToken();
                    return;

                case TOK.comma:
                    if (!symbolsSave)
                        symbolsSave = symbols;
                    nextToken();
                    break;

                default:
                    error("`=`, `;` or `,` expected to end declaration instead of `%s`", token.toChars());
                Lend:
                    return scanPastSemicolon();
            }
        }
    }

    /***************************************
     * C11 Function Definitions
     * function-definition
     *    declaration-specifiers declarator declaration-list (opt) compound-statement
     *
     * declaration-list:
     *    declaration
     *    declaration-list declaration
     *
     * It's already been parsed up to the declaration-list (opt).
     * Pick it up from there.
     * Params:
     *    id = function identifier
     *    ft = function type
     *    specifier = function specifiers
     * Returns:
     *  Dsymbol for the function
     */
    AST.Dsymbol cparseFunctionDefinition(Identifier id, AST.TypeFunction ft, ref Specifier specifier)
    {
        /* Start function scope
         */
        typedefTab.push(null);

        if (token.value != TOK.leftCurly)       // if not start of a compound-statement
        {
            // Do declaration-list
            do
            {
                cparseDeclaration(LVL.parameter);
            } while (token.value != TOK.leftCurly);

            /* Since there were declarations, the parameter-list must have been
             * an identifier-list.
             */
            ft.parameterList.hasIdentifierList = true;        // semantic needs to know to adjust parameter types
            auto pl = ft.parameterList;
            if (pl.varargs != AST.VarArg.none && pl.length)
                error("function identifier-list cannot end with `...`");
            ft.parameterList.varargs = AST.VarArg.variadic;     // but C11 allows extra arguments
            importBuiltins = true;                              // will need __va_list_tag
            auto plLength = pl.length;
            if (symbols.length != plLength)
                error(token.loc, "%d identifiers does not match %d declarations", cast(int)plLength, cast(int)symbols.length);

            /* Transfer the types and storage classes from symbols[] to pl[]
             */
            foreach (i; 0 .. plLength)
            {
                auto p = pl[i];  // yes, quadratic

                // Convert typedef-identifier to identifier
                if (p.type)
                {
                    if (auto t = p.type.isTypeIdentifier())
                    {
                        p.ident = t.ident;
                        p.type = null;
                    }
                }

                if (p.type || !(p.storageClass & STC.parameter))
                    error("storage class and type are not allowed in identifier-list");
                foreach (s; (*symbols)[]) // yes, quadratic
                {
                    auto d = s.isDeclaration();
                    if (d && p.ident == d.ident && d.type)
                    {
                        p.type = d.type;
                        p.storageClass = d.storage_class;
                        d.type = null; // don't reuse
                        break;
                    }
                }
                if (!p.type)
                {
                    error("no declaration for identifier `%s`", p.ident.toChars());
                    p.type = AST.Type.terror;
                }
            }
        }

        addFuncName = false;    // gets set to true if somebody references __func__ in this function
        const locFunc = token.loc;

        auto body = cparseStatement(ParseStatementFlags.curly);  // don't start a new scope; continue with parameter scope
        typedefTab.pop();                                        // end of function scope

        auto fd = new AST.FuncDeclaration(locFunc, prevloc, id, specifiersToSTC(LVL.global, specifier), ft, specifier.noreturn);

        if (addFuncName)
        {
            auto s = createFuncName(locFunc, id);
            body = new AST.CompoundStatement(locFunc, s, body);
        }
        fd.fbody = body;

        // TODO add `symbols` to the function's local symbol table `sc2` in FuncDeclaration::semantic3()

        return fd;
    }

    /***************************************
     * C11 Initialization
     * initializer:
     *    assignment-expression
     *    { initializer-list }
     *    { initializer-list , }
     *
     * initializer-list:
     *    designation (opt) initializer
     *    initializer-list , designation (opt) initializer
     *
     * designation:
     *    designator-list =
     *
     * designator-list:
     *    designator
     *    designator-list designator
     *
     * designator:
     *    [ constant-expression ]
     *    . identifier
     * Returns:
     *    initializer
     */
    AST.Initializer cparseInitializer()
    {
        if (token.value != TOK.leftCurly)
        {
            auto ae = cparseAssignExp();        // assignment-expression
            return new AST.ExpInitializer(token.loc, ae);
        }
        nextToken();
        const loc = token.loc;

        /* Collect one or more `designation (opt) initializer`
         * into ci.initializerList, but lazily create ci
         */
        AST.CInitializer ci;
        while (1)
        {
            /* There can be 0 or more designators preceding an initializer.
             * Collect them in desigInit
             */
            AST.DesigInit desigInit;
            while (1)
            {
                if (token.value == TOK.leftBracket)     // [ constant-expression ]
                {
                    nextToken();
                    auto e = cparseConstantExp();
                    check(TOK.rightBracket);
                    if (!desigInit.designatorList)
                        desigInit.designatorList = new AST.Designators;
                    desigInit.designatorList.push(AST.Designator(e));
                }
                else if (token.value == TOK.dot)        // . identifier
                {
                    nextToken();
                    if (token.value != TOK.identifier)
                    {
                        error("identifier expected following `.` designator");
                        break;
                    }
                    if (!desigInit.designatorList)
                        desigInit.designatorList = new AST.Designators;
                    desigInit.designatorList.push(AST.Designator(token.ident));
                    nextToken();
                }
                else
                {
                    if (desigInit.designatorList)
                        check(TOK.assign);
                    break;
                }
            }

            desigInit.initializer = cparseInitializer();
            if (!ci)
                ci = new AST.CInitializer(loc);
            ci.initializerList.push(desigInit);
            if (token.value == TOK.comma)
            {
                nextToken();
                if (token.value != TOK.rightCurly)
                    continue;
            }
            break;
        }
        check(TOK.rightCurly);
        //printf("ci: %s\n", ci.toChars());
        return ci;
    }

    /*************************************
     * C11 6.7
     * declaration-specifier:
     *    storage-class-specifier declaration-specifiers (opt)
     *    type-specifier declaration-specifiers (opt)
     *    type-qualifier declaration-specifiers (opt)
     *    function-specifier declaration-specifiers (opt)
     *    alignment-specifier declaration-specifiers (opt)
     * Params:
     *  level = declaration context
     *  specifier = specifiers in and out
     * Returns:
     *  resulting type, null if not specified
     */
    private AST.Type cparseDeclarationSpecifiers(LVL level, ref Specifier specifier)
    {
        enum TKW : uint
        {
            xnone      = 0,
            xchar      = 1,
            xsigned    = 2,
            xunsigned  = 4,
            xshort     = 8,
            xint       = 0x10,
            xlong      = 0x20,
            xllong     = 0x40,
            xfloat     = 0x80,
            xdouble    = 0x100,
            xldouble   = 0x200,
            xtag       = 0x400,
            xident     = 0x800,
            xvoid      = 0x1000,
            xbool      = 0x4000,
            ximaginary = 0x8000,
            xcomplex   = 0x10000,
            x_Atomic   = 0x20000,
            xint128    = 0x40000,
        }

        AST.Type t;
        Loc loc;
        //printf("parseDeclarationSpecifiers()\n");

        TKW tkw;
        SCW scw = specifier.scw & SCW.xtypedef;
        MOD mod;
        Identifier id;
        Identifier previd;

    Lwhile:
        while (1)
        {
            //printf("token %s\n", token.toChars());
            TKW tkwx;
            SCW scwx;
            MOD modx;
            switch (token.value)
            {
                // Storage class specifiers
                case TOK.static_:    scwx = SCW.xstatic;    break;
                case TOK.extern_:    scwx = SCW.xextern;    break;
                case TOK.auto_:      scwx = SCW.xauto;      break;
                case TOK.register:   scwx = SCW.xregister;  break;
                case TOK.typedef_:   scwx = SCW.xtypedef;   break;
                case TOK.inline:     scwx = SCW.xinline;    break;
                case TOK._Noreturn:  scwx = SCW.x_Noreturn; break;
                case TOK._Thread_local: scwx = SCW.x_Thread_local; break;

                // Type qualifiers
                case TOK.const_:     modx = MOD.xconst;     break;
                case TOK.volatile:   modx = MOD.xvolatile;  break;
                case TOK.restrict:   modx = MOD.xrestrict;  break;
                case TOK.__stdcall:  modx = MOD.x__stdcall; break;

                // Type specifiers
                case TOK.char_:      tkwx = TKW.xchar;      break;
                case TOK.signed:     tkwx = TKW.xsigned;    break;
                case TOK.unsigned:   tkwx = TKW.xunsigned;  break;
                case TOK.int16:      tkwx = TKW.xshort;     break;
                case TOK.int32:      tkwx = TKW.xint;       break;
                case TOK.int64:      tkwx = TKW.xlong;      break;
                case TOK.__int128:   tkwx = TKW.xint128;    break;
                case TOK.float32:    tkwx = TKW.xfloat;     break;
                case TOK.float64:    tkwx = TKW.xdouble;    break;
                case TOK.void_:      tkwx = TKW.xvoid;      break;
                case TOK._Bool:      tkwx = TKW.xbool;      break;
                case TOK._Imaginary: tkwx = TKW.ximaginary; break;
                case TOK._Complex:   tkwx = TKW.xcomplex;   break;

                case TOK.identifier:
                    tkwx = TKW.xident;
                    id = token.ident;
                    break;

                case TOK.struct_:
                case TOK.union_:
                {
                    const structOrUnion = token.value;
                    const sloc = token.loc;
                    nextToken();

                    /* GNU Extensions
                     * struct-or-union-specifier:
                     *    struct-or-union gnu-attributes (opt) identifier (opt) { struct-declaration-list } gnu-attributes (opt)
                     *    struct-or-union gnu-attribute (opt) identifier
                     */
                    if (token.value == TOK.__attribute__)
                        cparseGnuAttributes(specifier);

                    t = cparseStruct(sloc, structOrUnion, symbols);
                    tkwx = TKW.xtag;
                    break;
                }

                case TOK.enum_:
                    t = cparseEnum(symbols);
                    tkwx = TKW.xtag;
                    break;

                case TOK._Atomic:
                {
                    // C11 6.7.2.4
                    // type-specifier if followed by `( type-name )`
                    auto tk = peek(&token);
                    if (tk.value == TOK.leftParenthesis)
                    {
                        tk = peek(tk);
                        if (isTypeName(tk) && tk.value == TOK.rightParenthesis)
                        {
                            nextToken();
                            t = cparseTypeName();
                            // TODO - implement the "atomic" part of t
                            tkwx = TKW.x_Atomic;
                            break;
                        }
                    }
                    // C11 6.7.3 type-qualifier if not
                    modx = MOD.x_Atomic;
                    break;
                }

                case TOK._Alignas:
                {
                    /* C11 6.7.5
                     * _Alignas ( type-name )
                     * _Alignas ( constant-expression )
                     */

                    if (level & (LVL.parameter | LVL.prototype))
                        error("no alignment-specifier for parameters"); // C11 6.7.5-2

                    nextToken();
                    check(TOK.leftParenthesis);
                    AST.Expression exp;
                    auto tk = &token;
                    if (isTypeName(tk))  // _Alignas ( type-name )
                    {
                        auto talign = cparseTypeName();
                        /* Convert type to expression: `talign.alignof`
                         */
                        auto e = new AST.TypeExp(loc, talign);
                        exp = new AST.DotIdExp(loc, e, Id.__xalignof);
                    }
                    else  // _Alignas ( constant-expression )
                    {
                        exp = cparseConstantExp();
                    }

                    if (!specifier.alignExps)
                        specifier.alignExps = new AST.Expressions(0);
                    specifier.alignExps.push(exp);

                    check(TOK.rightParenthesis);
                    break;
                }

                case TOK.__attribute__:
                {
                    /* GNU Extensions
                     * declaration-specifiers:
                     *    gnu-attributes declaration-specifiers (opt)
                     */
                    cparseGnuAttributes(specifier);
                    break;
                }

                case TOK.__declspec:
                {
                    /* Microsoft extension
                     */
                    cparseDeclspec(specifier);
                    break;
                }

                case TOK.typeof_:
                {
                    nextToken();
                    check(TOK.leftParenthesis);

                    auto tk = &token;
                    AST.Expression e;
                    if (isTypeName(tk))
                        e = new AST.TypeExp(loc, cparseTypeName());
                    else
                        e = cparseExpression();
                    t = new AST.TypeTypeof(loc, e);

                    if(token.value == TOK.rightParenthesis)
                        nextToken();
                    else
                    {
                        t = AST.Type.terror;
                        error("`typeof` operator expects an expression or type name in parentheses");

                        // skipParens et. al expect to be on the opening parenthesis
                        int parens;
                        loop: while(1)
                        {
                            switch(token.value)
                            {
                                case TOK.leftParenthesis:
                                    parens++;
                                    break;
                                case TOK.rightParenthesis:
                                    parens--;
                                    if(parens < 0)
                                        goto case;
                                    break;
                                case TOK.endOfFile:
                                    break loop;
                                default:
                            }
                            nextToken();
                        }
                    }

                    tkwx = TKW.xtag;
                    break;
                }

                default:
                    break Lwhile;
            }

            if (tkwx)
            {
                if (tkw & TKW.xlong && tkwx & TKW.xlong)
                {
                    tkw &= ~TKW.xlong;
                    tkwx = TKW.xllong;
                }
                if (tkw && tkwx & TKW.xident)
                {
                    // 2nd identifier can't be a typedef
                    break Lwhile; // leave parser on the identifier for the following declarator
                }
                else if (tkwx & TKW.xident)
                {
                    // 1st identifier, save it for TypeIdentifier
                    previd = id;
                }
                if (tkw & TKW.xident && tkwx ||  // typedef-name followed by type-specifier
                    tkw & tkwx)                  // duplicate type-specifiers
                {
                    error("illegal combination of type specifiers");
                    tkwx = TKW.init;
                }
                tkw |= tkwx;
                if (!(tkwx & TKW.xtag)) // if parser already advanced
                    nextToken();
                continue;
            }

            if (modx)
            {
                mod |= modx;
                nextToken();
                continue;
            }

            if (scwx)
            {
                if (scw & scwx)
                    error("duplicate storage class");
                scw |= scwx;
                // C11 6.7.1-2 At most one storage-class may be given, except that
                // _Thread_local may appear with static or extern.
                const scw2 = scw & (SCW.xstatic | SCW.xextern | SCW.xauto | SCW.xregister | SCW.xtypedef);
                if (scw2 & (scw2 - 1) ||
                    scw & (SCW.x_Thread_local) && scw & (SCW.xauto | SCW.xregister | SCW.xtypedef))
                {
                    error("multiple storage classes in declaration specifiers");
                    scw &= ~scwx;
                }
                if (level == LVL.local &&
                    scw & (SCW.x_Thread_local) && scw & (SCW.xinline | SCW.x_Noreturn))
                {
                    error("`inline` and `_Noreturn` function specifiers not allowed for `_Thread_local`");
                    scw &= ~scwx;
                }
                if (level & (LVL.parameter | LVL.prototype) &&
                    scw & ~SCW.xregister)
                {
                    error("only `register` storage class allowed for function parameters");
                    scw &= ~scwx;
                }
                if (level == LVL.global &&
                    scw & (SCW.xauto | SCW.xregister))
                {
                    error("`auto` and `register` storage class not allowed for global");
                    scw &= ~scwx;
                }
                nextToken();
                continue;
            }
        }

        specifier.scw = scw;
        specifier.mod = mod;

        // Convert TKW bits to type t
        switch (tkw)
        {
            case TKW.xnone:                     t = null; break;

            case TKW.xchar:                     t = AST.Type.tchar; break;
            case TKW.xsigned | TKW.xchar:       t = AST.Type.tint8; break;
            case TKW.xunsigned | TKW.xchar:     t = AST.Type.tuns8; break;

            case TKW.xshort:
            case TKW.xsigned | TKW.xshort:
            case TKW.xsigned | TKW.xshort | TKW.xint:
            case TKW.xshort | TKW.xint:         t = integerTypeForSize(shortsize); break;

            case TKW.xunsigned | TKW.xshort | TKW.xint:
            case TKW.xunsigned | TKW.xshort:    t = unsignedTypeForSize(shortsize); break;

            case TKW.xint:
            case TKW.xsigned:
            case TKW.xsigned | TKW.xint:        t = integerTypeForSize(intsize); break;

            case TKW.xunsigned:
            case TKW.xunsigned | TKW.xint:      t = unsignedTypeForSize(intsize); break;

            case TKW.xlong:
            case TKW.xsigned | TKW.xlong:
            case TKW.xsigned | TKW.xlong | TKW.xint:
            case TKW.xlong | TKW.xint:          t = integerTypeForSize(longsize); break;

            case TKW.xunsigned | TKW.xlong | TKW.xint:
            case TKW.xunsigned | TKW.xlong:     t = unsignedTypeForSize(longsize); break;

            case TKW.xllong:
            case TKW.xsigned | TKW.xllong:
            case TKW.xsigned | TKW.xllong | TKW.xint:
            case TKW.xllong | TKW.xint:          t = integerTypeForSize(long_longsize); break;

            case TKW.xunsigned | TKW.xllong | TKW.xint:
            case TKW.xunsigned | TKW.xllong:     t = unsignedTypeForSize(long_longsize); break;

            case TKW.xint128:
            case TKW.xsigned | TKW.xint128:     t = integerTypeForSize(16); break;

            case TKW.xunsigned | TKW.xint128:   t = unsignedTypeForSize(16); break;

            case TKW.xvoid:                     t = AST.Type.tvoid; break;
            case TKW.xbool:                     t = boolsize == 1 ? AST.Type.tbool : integerTypeForSize(boolsize); break;

            case TKW.xfloat:                    t = AST.Type.tfloat32; break;
            case TKW.xdouble:                   t = AST.Type.tfloat64; break;
            case TKW.xlong | TKW.xdouble:       t = realType(RTFlags.realfloat); break;

            case TKW.ximaginary | TKW.xfloat:              t = AST.Type.timaginary32; break;
            case TKW.ximaginary | TKW.xdouble:             t = AST.Type.timaginary64; break;
            case TKW.ximaginary | TKW.xlong | TKW.xdouble: t = realType(RTFlags.imaginary); break;

            case TKW.xcomplex | TKW.xfloat:                t = AST.Type.tcomplex32; break;
            case TKW.xcomplex | TKW.xdouble:               t = AST.Type.tcomplex64; break;
            case TKW.xcomplex | TKW.xlong | TKW.xdouble:   t = realType(RTFlags.complex); break;

            case TKW.xident:
            {
                const idx = previd.toString();
                if (idx.length > 2 && idx[0] == '_' && idx[1] == '_')  // leading double underscore
                    importBuiltins = true;  // probably one of those compiler extensions
                t = null;

                /* Punch through to what the typedef is, to support things like:
                 *  typedef T* T;
                 */
                auto pt = lookupTypedef(previd);
                if (pt && *pt)      // if previd is a known typedef
                    t = *pt;

                if (!t)
                    t = new AST.TypeIdentifier(loc, previd);
                break;
            }

            case TKW.xtag:
                break;          // t is already set

            default:
                error("illegal type combination");
                t = AST.Type.terror;
                break;
        }

        return t;
    }

    /********************************
     * C11 6.7.6
     * Parse a declarator (including function definitions).
     * declarator:
     *    pointer (opt) direct-declarator
     *
     * direct-declarator :
     *    identifier
     *    ( declarator )
     *    direct-declarator [ type-qualifier-list (opt) assignment-expression (opt) ]
     *    direct-declarator [ static type-qualifier-list (opt) assignment-expression ]
     *    direct-declarator [ type-qualifier-list static assignment-expression (opt) ]
     *    direct-declarator [ type-qualifier-list (opt) * ]
     *    direct-declarator ( parameter-type-list )
     *    direct-declarator ( identifier-list (opt) )
     *
     * pointer :
     *    * type-qualifier-list (opt)
     *    * type-qualifier-list (opt) pointer
     *
     * type-qualifier-list :
     *    type-qualifier
     *    type-qualifier-list type-qualifier
     *
     * parameter-type-list :
     *    parameter-list
     *    parameter-list , ...
     *
     * parameter-list :
     *    parameter-declaration
     *    parameter-list , parameter-declaration
     *
     * parameter-declaration :
     *    declaration-specifiers declarator
     *    declaration-specifiers abstract-declarator (opt)
     *
     * identifier-list :
     *    identifier
     *    identifier-list , identifier
     *
     * Params:
     *  declarator   = declarator kind
     *  t            = base type to start with
     *  pident       = set to Identifier if there is one, null if not
     *  specifier    = specifiers in and out
     * Returns:
     *  type declared. If a TypeFunction is returned, this.symbols is the
     *  symbol table for the parameter-type-list, which will contain any
     *  declared struct, union or enum tags.
     */
    private AST.Type cparseDeclarator(DTR declarator, AST.Type t,
        out Identifier pident, ref Specifier specifier)
    {
        //printf("cparseDeclarator(%d, %p)\n", declarator, t);
        AST.Types constTypes; // all the Types that will need `const` applied to them

        AST.Type parseDecl(AST.Type t)
        {
            AST.Type ts;
            while (1)
            {
                switch (token.value)
                {
                case TOK.identifier:        // identifier
                    //printf("identifier %s\n", token.ident.toChars());
                    if (declarator == DTR.xabstract)
                        error("identifier not allowed in abstract-declarator");
                    pident = token.ident;
                    ts = t;
                    nextToken();
                    break;

                case TOK.leftParenthesis:   // ( declarator )
                    /* like: T (*fp)();
                     *       T ((*fp))();
                     */
                    nextToken();

                    if (token.value == TOK.__stdcall) // T (__stdcall*fp)();
                    {
                        specifier.mod |= MOD.x__stdcall;
                        nextToken();
                    }

                    ts = parseDecl(t);
                    check(TOK.rightParenthesis);
                    break;

                case TOK.mul:               // pointer
                    t = new AST.TypePointer(t);
                    nextToken();
                    // add post fixes const/volatile/restrict/_Atomic
                    const mod = cparseTypeQualifierList();
                    if (mod & MOD.xconst)
                        constTypes.push(t);
                    if (token.value == TOK.__attribute__)
                        cparseGnuAttributes(specifier);
                    continue;

                default:
                    if (declarator == DTR.xdirect)
                    {
                        if (!t || t.isTypeIdentifier())
                        {
                            // const arr[1];
                            error("no type-specifier for declarator");
                            t = AST.Type.tint32;
                        }
                        else
                            error("identifier or `(` expected"); // )
                        panic();
                    }
                    ts = t;
                    break;
                }
                break;
            }

            // parse DeclaratorSuffixes
            while (1)
            {
                /* Insert tx -> t into
                 *   ts -> ... -> t
                 * so that
                 *   ts -> ... -> tx -> t
                 */
                static void insertTx(ref AST.Type ts, AST.Type tx, AST.Type t)
                {
                    AST.Type* pt;
                    for (pt = &ts; *pt != t; pt = &(cast(AST.TypeNext)*pt).next)
                    {
                    }
                    *pt = tx;
                }

                switch (token.value)
                {
                    case TOK.leftBracket:
                    {
                        // post [] syntax, pick up any leading type qualifiers, `static` and `*`
                        AST.Type ta;
                        nextToken();

                        auto mod = cparseTypeQualifierList();   // const/volatile/restrict/_Atomic

                        bool isStatic;
                        bool isVLA;
                        if (token.value == TOK.static_)
                        {
                            isStatic = true;    // `static`
                            nextToken();
                            if (!mod)           // type qualifiers after `static`
                                mod = cparseTypeQualifierList();
                        }
                        else if (token.value == TOK.mul)
                        {
                            if (peekNext() == TOK.rightBracket)
                            {
                                isVLA = true;   // `*`
                                nextToken();
                            }
                        }

                        if (isStatic || token.value != TOK.rightBracket)
                        {
                            //printf("It's a static array\n");
                            AST.Expression e = cparseAssignExp(); // [ expression ]
                            ta = new AST.TypeSArray(t, e);
                        }
                        else
                        {
                            /* C11 6.7.6.2-4 An [ ] array is an incomplete array type
                             */
                            ta = new AST.TypeSArray(t);
                        }
                        check(TOK.rightBracket);

                        // Issue errors for unsupported types.
                        if (isVLA) // C11 6.7.6.2
                        {
                            error("variable length arrays are not supported");
                        }
                        if (isStatic) // C11 6.7.6.3
                        {
                            error("static array parameters are not supported");
                        }
                        if (declarator != DTR.xparameter)
                        {
                            /* C11 6.7.6.2-4: '*' can only be used with function prototype scope.
                             */
                            if (isVLA)
                                error("variable length array used outside of function prototype");
                            /* C11 6.7.6.2-1: type qualifiers and 'static' shall only appear
                             * in a declaration of a function parameter with an array type.
                             */
                            if (isStatic || mod)
                                error("static or type qualifier used outside of function prototype");
                        }
                        if (ts.isTypeSArray() || ts.isTypeDArray())
                        {
                            /* C11 6.7.6.2-1: type qualifiers and 'static' shall only appear
                             * in the outermost array type derivation.
                             */
                            if (isStatic || mod)
                                error("static or type qualifier used in non-outermost array type derivation");
                            /* C11 6.7.6.2-1: the element type shall not be an incomplete or
                             * function type.
                             */
                            if (ta.isTypeSArray() && ta.isTypeSArray().isIncomplete() && !isVLA)
                                error("array type has incomplete element type `%s`", ta.toChars());
                        }

                        // Apply type qualifiers to the constructed type.
                        if (mod & MOD.xconst) // ignore the other bits
                            ta = toConst(ta);
                        insertTx(ts, ta, t);  // ts -> ... -> ta -> t
                        continue;
                    }

                    case TOK.leftParenthesis:
                    {
                        // New symbol table for parameter-list
                        auto symbolsSave = this.symbols;
                        this.symbols = null;

                        auto parameterList = cparseParameterList();
                        const lkg = specifier.mod & MOD.x__stdcall ? LINK.windows : linkage;
                        AST.Type tf = new AST.TypeFunction(parameterList, t, lkg, 0);
    //                  tf = tf.addSTC(storageClass);  // TODO
                        insertTx(ts, tf, t);  // ts -> ... -> tf -> t

                        if (ts != tf)
                            this.symbols = symbolsSave;
                        break;
                    }

                    default:
                        break;
                }
                break;
            }
            return ts;
        }

        t = parseDecl(t);

        /* Because const is transitive, cannot assemble types from
         * fragments. Instead, types to be annotated with const are put
         * in constTypes[], and a bottom up scan of t is done to apply
         * const
         */
        if (constTypes.length)
        {
            AST.Type constApply(AST.Type t)
            {
                if (t.nextOf())
                {
                    auto tn = cast(AST.TypeNext)t; // t.nextOf() should return a ref instead of this
                    tn.next = constApply(tn.next);
                }
                foreach (tc; constTypes[])
                {
                    if (tc is t)
                    {
                        return toConst(t);
                    }
                }
                return t;
            }

            if (declarator == DTR.xparameter &&
                t.isTypePointer())
            {
                /* Because there are instances in .h files of "const pointer to mutable",
                 * skip applying transitive `const`
                 * https://issues.dlang.org/show_bug.cgi?id=22534
                 */
                auto tn = cast(AST.TypeNext)t;
                tn.next = constApply(tn.next);
            }
            else
                t = constApply(t);
        }

        //printf("result: %s\n", t.toChars());
        return t;
    }

    /******************************
     * C11 6.7.3
     * type-qualifier:
     *    const
     *    restrict
     *    volatile
     *    _Atomic
     *    __stdcall
     */
    MOD cparseTypeQualifierList()
    {
        MOD mod;
        while (1)
        {
            switch (token.value)
            {
                case TOK.const_:     mod |= MOD.xconst;     break;
                case TOK.volatile:   mod |= MOD.xvolatile;  break;
                case TOK.restrict:   mod |= MOD.xrestrict;  break;
                case TOK._Atomic:    mod |= MOD.x_Atomic;   break;
                case TOK.__stdcall:  mod |= MOD.x__stdcall; break;

                default:
                    return mod;
            }
            nextToken();
        }
    }

    /***********************************
     * C11 6.7.7
     */
    AST.Type cparseTypeName()
    {
        Specifier specifier;
        specifier.packalign.setDefault();
        auto tspec = cparseSpecifierQualifierList(LVL.global, specifier);
        if (!tspec)
        {
            error("type-specifier is missing");
            tspec = AST.Type.tint32;
        }
        if (tspec && specifier.mod & MOD.xconst)
        {
            tspec = toConst(tspec);
            specifier.mod = MOD.xnone;      // 'used' it
        }
        Identifier id;
        return cparseDeclarator(DTR.xabstract, tspec, id, specifier);
    }

    /***********************************
     * C11 6.7.2.1
     * specifier-qualifier-list:
     *    type-specifier specifier-qualifier-list (opt)
     *    type-qualifier specifier-qualifier-list (opt)
     * Params:
     *  level = declaration context
     *  specifier = specifiers in and out
     * Returns:
     *  resulting type, null if not specified
     */
    AST.Type cparseSpecifierQualifierList(LVL level, ref Specifier specifier)
    {
        auto t = cparseDeclarationSpecifiers(level, specifier);
        if (specifier.scw)
            error("storage class not allowed in specifier-qualified-list");
        return t;
    }

    /***********************************
     * C11 6.7.6.3
     * ( parameter-type-list )
     * ( identifier-list (opt) )
     */
    AST.ParameterList cparseParameterList()
    {
        auto parameters = new AST.Parameters();
        AST.VarArg varargs = AST.VarArg.none;
        StorageClass varargsStc;

        check(TOK.leftParenthesis);
        if (token.value == TOK.void_ && peekNext() == TOK.rightParenthesis) // func(void)
        {
            nextToken();
            nextToken();
            return AST.ParameterList(parameters, varargs, varargsStc);
        }

        if (token.value == TOK.rightParenthesis)        // func()
        {
            nextToken();
            importBuiltins = true;                              // will need __va_list_tag
            return AST.ParameterList(parameters, AST.VarArg.variadic, varargsStc);
        }

        /* Create function prototype scope
         */
        typedefTab.push(null);

        AST.ParameterList finish()
        {
            typedefTab.pop();
            return AST.ParameterList(parameters, varargs, varargsStc);
        }

        /* The check for identifier-list comes later,
         * when doing the trailing declaration-list (opt)
         */
        while (1)
        {
            if (token.value == TOK.rightParenthesis)
                break;
            if (token.value == TOK.dotDotDot)
            {
                if (parameters.length == 0)     // func(...)
                    error("named parameter required before `...`");
                importBuiltins = true;          // will need __va_list_tag
                varargs = AST.VarArg.variadic;  // C-style variadics
                nextToken();
                check(TOK.rightParenthesis);
                return finish();
            }

            Specifier specifier;
            specifier.packalign.setDefault();
            auto tspec = cparseDeclarationSpecifiers(LVL.prototype, specifier);
            if (!tspec)
            {
                error("no type-specifier for parameter");
                tspec = AST.Type.tint32;
            }

            if (specifier.mod & MOD.xconst)
            {
                if ((token.value == TOK.rightParenthesis || token.value == TOK.comma) &&
                    tspec.isTypeIdentifier())
                    error("type-specifier omitted for parameter `%s`", tspec.isTypeIdentifier().ident.toChars());

                tspec = toConst(tspec);
                specifier.mod = MOD.xnone;      // 'used' it
            }

            Identifier id;
            auto t = cparseDeclarator(DTR.xparameter, tspec, id, specifier);
            if (token.value == TOK.__attribute__)
                cparseGnuAttributes(specifier);
            if (specifier.mod & MOD.xconst)
                t = toConst(t);
            auto param = new AST.Parameter(specifiersToSTC(LVL.parameter, specifier),
                                           t, id, null, null);
            parameters.push(param);
            if (token.value == TOK.rightParenthesis || token.value == TOK.endOfFile)
                break;
            check(TOK.comma);
        }
        check(TOK.rightParenthesis);
        return finish();
    }

    /***********************************
     * C11 6.7.10
     * _Static_assert ( constant-expression , string-literal ) ;
     */
    private AST.StaticAssert cparseStaticAssert()
    {
        const loc = token.loc;

        //printf("cparseStaticAssert()\n");
        nextToken();
        check(TOK.leftParenthesis);
        auto exp = cparseConstantExp();
        check(TOK.comma);
        if (token.value != TOK.string_)
            error("string literal expected");
        auto msg = cparsePrimaryExp();
        check(TOK.rightParenthesis);
        check(TOK.semicolon);
        return new AST.StaticAssert(loc, exp, msg);
    }

    /*************************
     * Collect argument list.
     * Parser is on opening parenthesis.
     * Returns:
     *    the arguments
     */
    private AST.Expressions* cparseArguments()
    {
        nextToken();
        auto arguments = new AST.Expressions();
        while (token.value != TOK.rightParenthesis && token.value != TOK.endOfFile)
        {
            auto arg = cparseAssignExp();
            arguments.push(arg);
            if (token.value != TOK.comma)
                break;

            nextToken(); // consume comma
        }

        check(TOK.rightParenthesis);

        return arguments;
    }

    /*************************
     * __declspec parser
     * https://docs.microsoft.com/en-us/cpp/cpp/declspec
     * decl-specifier:
     *    __declspec ( extended-decl-modifier-seq )
     *
     * extended-decl-modifier-seq:
     *    extended-decl-modifier (opt)
     *    extended-decl-modifier extended-decl-modifier-seq
     *
     * extended-decl-modifier:
     *    dllimport
     *    dllexport
     *    noreturn
     * Params:
     *  specifier = filled in with the attribute(s)
     */
    private void cparseDeclspec(ref Specifier specifier)
    {
        //printf("cparseDeclspec()\n");
        /* Check for dllexport, dllimport
         * Ignore the rest
         */
        bool dllimport;  // TODO implement
        bool dllexport;  // TODO implement
        nextToken();     // move past __declspec
        check(TOK.leftParenthesis);
        while (1)
        {
            if (token.value == TOK.rightParenthesis)
            {
                nextToken();
                break;
            }
            else if (token.value == TOK.endOfFile)
                break;
            else if (token.value == TOK.identifier)
            {
                if (token.ident == Id.dllimport)
                {
                    dllimport = true;
                    nextToken();
                }
                else if (token.ident == Id.dllexport)
                {
                    dllexport = true;
                    nextToken();
                }
                else if (token.ident == Id.noreturn)
                {
                    specifier.noreturn = true;
                    nextToken();
                }
                else
                {
                    nextToken();
                    if (token.value == TOK.leftParenthesis)
                        cparseParens();
                }
            }
            else
            {
                error("extended-decl-modifier expected");
                break;
            }
        }
    }

    /*************************
     * Simple asm parser
     * https://gcc.gnu.org/onlinedocs/gcc/Asm-Labels.html
     * simple-asm-expr:
     *   asm ( asm-string-literal )
     *
     * asm-string-literal:
     *   string-literal
     */
    private AST.StringExp cparseSimpleAsmExpr()
    {
        nextToken();     // move past asm
        check(TOK.leftParenthesis);
        if (token.value != TOK.string_)
            error("string literal expected");
        auto label = cparsePrimaryExp();
        check(TOK.rightParenthesis);
        return cast(AST.StringExp) label;
    }

    /*************************
     * __attribute__ parser
     * https://gcc.gnu.org/onlinedocs/gcc/Attribute-Syntax.html
     * gnu-attributes:
     *   gnu-attributes gnu-attribute-specifier
     *
     * gnu-attribute-specifier:
     *    __attribute__ (( gnu-attribute-list ))
     *
     * gnu-attribute-list:
     *    gnu-attribute (opt)
     *    gnu-attribute-list , gnu-attribute
     *
     * Params:
     *  specifier = filled in with the attribute(s)
     */
    private void cparseGnuAttributes(ref Specifier specifier)
    {
        while (token.value == TOK.__attribute__)
        {
            nextToken();     // move past __attribute__
            check(TOK.leftParenthesis);
            check(TOK.leftParenthesis);

            if (token.value != TOK.rightParenthesis)
            {
                while (1)
                {
                    cparseGnuAttribute(specifier);
                    if (token.value != TOK.comma)
                        break;
                    nextToken();
                }
            }

            check(TOK.rightParenthesis);
            check(TOK.rightParenthesis);
        }
    }

    /*************************
     * Parse a single GNU attribute
     * gnu-attribute:
     *    gnu-attribute-name
     *    gnu-attribute-name ( identifier )
     *    gnu-attribute-name ( identifier , expression-list )
     *    gnu-attribute-name ( expression-list (opt) )
     *
     * gnu-attribute-name:
     *    keyword
     *    identifier
     *
     * expression-list:
     *    constant-expression
     *    expression-list , constant-expression
     *
     * Params:
     *  specifier = filled in with the attribute(s)
     */
    private void cparseGnuAttribute(ref Specifier specifier)
    {
        /* Check for dllimport, dllexport, vector_size(bytes)
         * Ignore the rest
         */
        bool dllimport;  // TODO implement
        bool dllexport;  // TODO implement

        if (!isGnuAttributeName())
            return;

        if (token.value == TOK.identifier)
        {
            if (token.ident == Id.dllimport)
            {
                dllimport = true;
                nextToken();
            }
            else if (token.ident == Id.dllexport)
            {
                dllexport = true;
                nextToken();
            }
            else if (token.ident == Id.noreturn)
            {
                specifier.noreturn = true;
                nextToken();
            }
            else if (token.ident == Id.vector_size)
            {
                nextToken();
                check(TOK.leftParenthesis);
                cparseConstantExp();  // TODO implement
                check(TOK.rightParenthesis);
            }
            else
            {
                nextToken();
                if (token.value == TOK.leftParenthesis)
                    cparseParens();
            }
        }
        else
        {
            nextToken();
            if (token.value == TOK.leftParenthesis)
                cparseParens();
        }
    }

    /*************************
     * See if match for GNU attribute name, which may be any identifier,
     * storage-class-specifier, type-specifier, or type-qualifier.
     * Returns:
     *  true if a valid GNU attribute name
     */
    private bool isGnuAttributeName()
    {
        switch (token.value)
        {
            case TOK.identifier:
            case TOK.static_:
            case TOK.unsigned:
            case TOK.int64:
            case TOK.const_:
            case TOK.extern_:
            case TOK.register:
            case TOK.typedef_:
            case TOK.int16:
            case TOK.inline:
            case TOK._Noreturn:
            case TOK.volatile:
            case TOK.signed:
            case TOK.auto_:
            case TOK.restrict:
            case TOK._Complex:
            case TOK._Thread_local:
            case TOK.int32:
            case TOK.__int128:
            case TOK.char_:
            case TOK.float32:
            case TOK.float64:
            case TOK.void_:
            case TOK._Bool:
            case TOK._Atomic:
                return true;

            default:
                return false;
        }
    }

    /***************************
     * Like skipParens(), but consume the tokens.
     */
    private void cparseParens()
    {
        check(TOK.leftParenthesis);
        int parens = 1;

        while (1)
        {
            switch (token.value)
            {
                case TOK.leftParenthesis:
                    ++parens;
                    break;

                case TOK.rightParenthesis:
                    --parens;
                    if (parens < 0)
                    {
                        error("extra right parenthesis");
                        return;
                    }
                    if (parens == 0)
                    {
                        nextToken();
                        return;
                    }
                    break;

                case TOK.endOfFile:
                    error("end of file found before right parenthesis");
                    return;

                default:
                    break;
            }
            nextToken();
        }
    }

    //}
    /******************************************************************************/
    /***************************** Struct & Enum Parser ***************************/
    //{

    /*************************************
     * C11 6.7.2.2
     * enum-specifier:
     *    enum identifier (opt) { enumerator-list }
     *    enum identifier (opt) { enumerator-list , }
     *    enum identifier
     *
     * enumerator-list:
     *    enumerator
     *    enumerator-list , enumerator
     *
     * enumerator:
     *    enumeration-constant
     *    enumeration-constant = constant-expression
     *
     * enumeration-constant:
     *    identifier
     *
     * Params:
     *  symbols = symbols to add enum declaration to
     * Returns:
     *  type of the enum
     */
    private AST.Type cparseEnum(ref AST.Dsymbols* symbols)
    {
        const loc = token.loc;
        nextToken();

        /* GNU Extensions
         * enum-specifier:
         *    enum gnu-attributes (opt) identifier (opt) { enumerator-list } gnu-attributes (opt)
         *    enum gnu-attributes (opt) identifier (opt) { enumerator-list , } gnu-attributes (opt)
         *    enum gnu-attributes (opt) identifier
         */
        Specifier specifier;
        specifier.packalign.setDefault();
        if (token.value == TOK.__attribute__)
            cparseGnuAttributes(specifier);

        Identifier tag;
        if (token.value == TOK.identifier)
        {
            tag = token.ident;
            nextToken();
        }

        /* clang extension: add optional base type after the identifier
         * https://en.cppreference.com/w/cpp/language/enum
         *   enum Identifier : Type
         */
        AST.Type base = AST.Type.tint32;  // C11 6.7.2.2-4 implementation defined default base type
        if (token.value == TOK.colon)
        {
            nextToken();
            base = cparseTypeName();
        }

        AST.Dsymbols* members;
        if (token.value == TOK.leftCurly)
        {
            nextToken();
            members = new AST.Dsymbols();

            if (token.value == TOK.rightCurly)  // C11 6.7.2.2-1
            {
                if (tag)
                    error("no members for `enum %s`", tag.toChars());
                else
                    error("no members for anonymous enum");
            }

            while (token.value == TOK.identifier)
            {
                auto ident = token.ident;  // enumeration-constant
                nextToken();
                auto mloc = token.loc;

                if (token.value == TOK.__attribute__)
                {
                    /* gnu-attributes can appear here, but just scan and ignore them
                     * https://gcc.gnu.org/onlinedocs/gcc/Enumerator-Attributes.html
                     */
                    Specifier specifierx;
                    specifierx.packalign.setDefault();
                    cparseGnuAttributes(specifierx);
                }

                AST.Expression value;
                if (token.value == TOK.assign)
                {
                    nextToken();
                    value = cparseConstantExp();
                    // TODO C11 6.7.2.2-2 value must fit into an int
                }

                if (token.value == TOK.__attribute__)
                {
                    /* gnu-attributes can appear here, but just scan and ignore them
                     * https://gcc.gnu.org/onlinedocs/gcc/Enumerator-Attributes.html
                     */
                    Specifier specifierx;
                    specifierx.packalign.setDefault();
                    cparseGnuAttributes(specifierx);
                }

                auto em = new AST.EnumMember(mloc, ident, value, null, 0, null, null);
                members.push(em);

                if (token.value == TOK.comma)
                {
                    nextToken();
                    continue;
                }
                break;
            }
            check(TOK.rightCurly);

            /* GNU Extensions
             * Parse the postfix gnu-attributes (opt)
             */
            if (token.value == TOK.__attribute__)
                cparseGnuAttributes(specifier);
        }
        else if (!tag)
            error("missing `identifier` after `enum`");

        /* Need semantic information to determine if this is a declaration,
         * redeclaration, or reference to existing declaration.
         * Defer to the semantic() pass with a TypeTag.
         */
        return new AST.TypeTag(loc, TOK.enum_, tag, base, members);
    }

    /*************************************
     * C11 6.7.2.1
     * Parse struct and union specifiers.
     * Parser is advanced to the tag identifier or brace.
     * struct-or-union-specifier:
     *    struct-or-union identifier (opt) { struct-declaration-list }
     *    struct-or-union identifier
     *
     * struct-or-union:
     *    struct
     *    union
     *
     * struct-declaration-list:
     *    struct-declaration
     *    struct-declaration-list struct-declaration
     *
     * Params:
     *  loc = location of `struct` or `union`
     *  structOrUnion = TOK.struct_ or TOK.union_
     *  symbols = symbols to add struct-or-union declaration to
     * Returns:
     *  type of the struct
     */
    private AST.Type cparseStruct(Loc loc, TOK structOrUnion, ref AST.Dsymbols* symbols)
    {
        Identifier tag;

        if (token.value == TOK.identifier)
        {
            tag = token.ident;
            nextToken();
        }

        AST.Dsymbols* members;
        if (token.value == TOK.leftCurly)
        {
            nextToken();
            members = new AST.Dsymbols();          // so `members` will be non-null even with 0 members
            while (token.value != TOK.rightCurly)
            {
                cparseStructDeclaration(members);

                if (token.value == TOK.endOfFile)
                    break;
            }
            check(TOK.rightCurly);

            if ((*members).length == 0) // C11 6.7.2.1-8
            {
                /* allow empty structs as an extension
                 *  struct-declarator-list:
                 *    struct-declarator (opt)
                 */
            }
        }
        else if (!tag)
            error("missing tag `identifier` after `%s`", Token.toChars(structOrUnion));

        /* Need semantic information to determine if this is a declaration,
         * redeclaration, or reference to existing declaration.
         * Defer to the semantic() pass with a TypeTag.
         */
        return new AST.TypeTag(loc, structOrUnion, tag, null, members);
    }

    /*************************************
     * C11 6.7.2.1
     * Parse a struct declaration member.
     * struct-declaration:
     *    specifier-qualifier-list struct-declarator-list (opt) ;
     *    static_assert-declaration
     *
     * struct-declarator-list:
     *    struct-declarator
     *    struct-declarator-list , struct-declarator
     *
     * struct-declarator:
     *    declarator
     *    declarator (opt) : constant-expression
     * Params:
     *    members = where to put the fields (members)
     */
    void cparseStructDeclaration(AST.Dsymbols* members)
    {
        //printf("cparseStructDeclaration()\n");
        if (token.value == TOK._Static_assert)
        {
            auto s = cparseStaticAssert();
            members.push(s);
            return;
        }

        Specifier specifier;
        specifier.packalign = this.packalign;
        auto tspec = cparseSpecifierQualifierList(LVL.member, specifier);
        if (!tspec)
        {
            error("no type-specifier for struct member");
            tspec = AST.Type.tint32;
        }
        if (specifier.mod & MOD.xconst)
        {
            tspec = toConst(tspec);
            specifier.mod = MOD.xnone;          // 'used' it
        }

        /* If a declarator does not follow, it is unnamed
         */
        if (token.value == TOK.semicolon && tspec)
        {
            nextToken();
            auto tt = tspec.isTypeTag();
            if (!tt)
            {
                if (auto ti = tspec.isTypeIdentifier())
                {
                    error("type-specifier omitted before declaration of `%s`", ti.ident.toChars());
                }
                return; // legal but meaningless empty declaration
            }

            /* If anonymous struct declaration
             *   struct { ... members ... };
             * C11 6.7.2.1-13
             */
            if (!tt.id && tt.members)
            {
                /* members of anonymous struct are considered members of
                 * the containing struct
                 */
                auto ad = new AST.AnonDeclaration(tt.loc, tt.tok == TOK.union_, tt.members);
                auto s = applySpecifier(ad, specifier);
                members.push(s);
                return;
            }
            if (!tt.id && !tt.members)
                return; // already gave error in cparseStruct()

            /* `struct tag;` and `struct tag { ... };`
             * always result in a declaration in the current scope
             */
            // TODO: merge in specifier
            auto stag = (tt.tok == TOK.struct_)
                ? new AST.StructDeclaration(tt.loc, tt.id, false)
                : new AST.UnionDeclaration(tt.loc, tt.id);
            stag.members = tt.members;
            if (!symbols)
                symbols = new AST.Dsymbols();
            auto s = applySpecifier(stag, specifier);
            symbols.push(s);
            return;
        }

        while (1)
        {
            Identifier id;
            AST.Type dt;
            if (token.value == TOK.colon)
            {
                if (auto ti = tspec.isTypeIdentifier())
                {
                    error("type-specifier omitted before bit field declaration of `%s`", ti.ident.toChars());
                    tspec = AST.Type.tint32;
                }

                // C11 6.7.2.1-12 unnamed bit-field
                id = Identifier.generateAnonymousId("BitField");
                dt = tspec;
            }
            else
            {
                dt = cparseDeclarator(DTR.xdirect, tspec, id, specifier);
                if (!dt)
                {
                    panic();
                    nextToken();
                    break;          // error recovery
                }
            }

            AST.Expression width;
            if (token.value == TOK.colon)
            {
                // C11 6.7.2.1-10 bit-field
                nextToken();
                width = cparseConstantExp();
            }

            /* GNU Extensions
             * struct-declarator:
             *    declarator gnu-attributes (opt)
             *    declarator (opt) : constant-expression gnu-attributes (opt)
             */
            if (token.value == TOK.__attribute__)
                cparseGnuAttributes(specifier);

            if (!tspec && !specifier.scw && !specifier.mod)
                error("specifier-qualifier-list required");
            else if (width)
            {
                if (specifier.alignExps)
                    error("no alignment-specifier for bit field declaration"); // C11 6.7.5-2
                auto s = new AST.BitFieldDeclaration(width.loc, dt, id, width);
                members.push(s);
            }
            else if (id)
            {
                if (dt.ty == AST.Tvoid)
                    error("`void` has no value");

                // declare the symbol
                // Give member variables an implicit void initializer
                auto initializer = new AST.VoidInitializer(token.loc);
                AST.Dsymbol s = new AST.VarDeclaration(token.loc, dt, id, initializer, specifiersToSTC(LVL.member, specifier));
                s = applySpecifier(s, specifier);
                members.push(s);
            }

            switch (token.value)
            {
                case TOK.identifier:
                    error("missing comma");
                    goto default;

                case TOK.semicolon:
                    nextToken();
                    return;

                case TOK.comma:
                    nextToken();
                    break;

                default:
                    error("`;` or `,` expected");
                    while (token.value != TOK.semicolon && token.value != TOK.endOfFile)
                        nextToken();
                    nextToken();
                    return;
            }
        }
    }

    //}
    /******************************************************************************/
    /********************************* Lookahead Parser ***************************/
    //{

    /************************************
     * Determine if the scanner is sitting on the start of a declaration.
     * Params:
     *      t       = current token of the scanner
     *      needId  = flag with additional requirements for a declaration
     *      endtok  = ending token
     *      pt      = will be set ending token (if not null)
     * Returns:
     *      true at start of a declaration
     */
    private bool isCDeclaration(ref Token* pt)
    {
        auto t = pt;
        //printf("isCDeclaration() %s\n", t.toChars());
        if (!isDeclarationSpecifiers(t))
            return false;

        while (1)
        {
            if (t.value == TOK.semicolon)
            {
                t = peek(t);
                pt = t;
                return true;
            }
            if (!isCDeclarator(t, DTR.xdirect))
                return false;
            if (t.value == TOK.asm_)
            {
                t = peek(t);
                if (t.value != TOK.leftParenthesis || !skipParens(t, &t))
                    return false;
            }
            if (t.value == TOK.__attribute__)
            {
                t = peek(t);
                if (t.value != TOK.leftParenthesis || !skipParens(t, &t))
                    return false;
            }
            if (t.value == TOK.assign)
            {
                t = peek(t);
                if (!isInitializer(t))
                    return false;
            }
            switch (t.value)
            {
                case TOK.comma:
                    t = peek(t);
                    break;

                case TOK.semicolon:
                    t = peek(t);
                    pt = t;
                    return true;

                default:
                    return false;
            }
        }
    }

    /********************************
     * See if match for initializer.
     * Params:
     *  pt = starting token, updated to one past end of initializer if true
     * Returns:
     *  true if initializer
     */
    private bool isInitializer(ref Token* pt)
    {
        //printf("isInitializer()\n");
        auto t = pt;

        if (t.value == TOK.leftCurly)
        {
            if (!skipBraces(t))
                return false;
            pt = t;
            return true;
        }

        // skip over assignment-expression, ending before comma or semiColon or EOF
        if (!isAssignmentExpression(t))
            return false;
        pt = t;
        return true;
    }

    /********************************
     * See if match for:
     *    postfix-expression ( argument-expression-list(opt) )
     * Params:
     *  pt = starting token, updated to one past end of initializer if true
     * Returns:
     *  true if function call
     */
    private bool isFunctionCall(ref Token* pt)
    {
        //printf("isFunctionCall()\n");
        auto t = pt;

        if (!isPrimaryExpression(t))
            return false;
        if (t.value != TOK.leftParenthesis)
            return false;
        t = peek(t);
        while (1)
        {
            if (!isAssignmentExpression(t))
                return false;
            if (t.value == TOK.comma)
            {
                t = peek(t);
                continue;
            }
            if (t.value == TOK.rightParenthesis)
            {
                t = peek(t);
                break;
            }
            return false;
        }
        if (t.value != TOK.semicolon)
            return false;
        pt = t;
        return true;
    }

    /********************************
     * See if match for assignment-expression.
     * Params:
     *  pt = starting token, updated to one past end of assignment-expression if true
     * Returns:
     *  true if assignment-expression
     */
    private bool isAssignmentExpression(ref Token* pt)
    {
        auto t = pt;
        //printf("isAssignmentExpression() %s\n", t.toChars());

        /* This doesn't actually check for grammar matching an
         * assignment-expression. It just matches ( ) [ ] looking for
         * an ending token that would terminate one.
         */
        bool any;
        while (1)
        {
            switch (t.value)
            {
                case TOK.comma:
                case TOK.semicolon:
                case TOK.rightParenthesis:
                case TOK.rightBracket:
                case TOK.endOfFile:
                    if (!any)
                        return false;
                    break;

                case TOK.leftParenthesis:
                    if (!skipParens(t, &t))
                        return false;
                    /*
                        https://issues.dlang.org/show_bug.cgi?id=22267
                        Fix issue 22267: If the parser encounters the following
                            `identifier variableName = (expression);`
                        the initializer is not identified as such since the parentheses
                        cause the parser to keep walking indefinitely
                        (whereas `(1) + 1` would not be affected.).
                    */
                    any = true;
                    continue;

                case TOK.leftBracket:
                    if (!skipBrackets(t))
                        return false;
                    continue;

                case TOK.leftCurly:
                    if (!skipBraces(t))
                        return false;
                    continue;

                default:
                    any = true;   // assume token was part of an a-e
                    t = peek(t);
                    continue;
            }
            pt = t;
            return true;
        }
    }

    /********************************
     * See if match for constant-expression.
     * Params:
     *  pt = starting token, updated to one past end of constant-expression if true
     * Returns:
     *  true if constant-expression
     */
    private bool isConstantExpression(ref Token* pt)
    {
        return isAssignmentExpression(pt);
    }

    /********************************
     * See if match for declaration-specifiers.
     * No errors are diagnosed.
     * Params:
     *  pt = starting token, updated to one past end of declaration-specifiers if true
     * Returns:
     *  true if declaration-specifiers
     */
    private bool isDeclarationSpecifiers(ref Token* pt)
    {
        //printf("isDeclarationSpecifiers()\n");

        auto t = pt;

        bool seenType;
        bool any;
        while (1)
        {
            switch (t.value)
            {
                // type-specifiers
                case TOK.void_:
                case TOK.char_:
                case TOK.int16:
                case TOK.int32:
                case TOK.int64:
                case TOK.__int128:
                case TOK.float32:
                case TOK.float64:
                case TOK.signed:
                case TOK.unsigned:
                case TOK._Bool:
                //case TOK._Imaginary:
                case TOK._Complex:
                    t = peek(t);
                    seenType = true;
                    any = true;
                    continue;

                case TOK.identifier: // typedef-name
                    if (!seenType)
                    {
                        t = peek(t);
                        seenType = true;
                        any = true;
                        continue;
                    }
                    break;

                case TOK.struct_:
                case TOK.union_:
                case TOK.enum_:
                    t = peek(t);
                    if (t.value == TOK.identifier)
                    {
                        t = peek(t);
                        if (t.value == TOK.leftCurly)
                        {
                            if (!skipBraces(t))
                                return false;
                        }
                    }
                    else if (t.value == TOK.leftCurly)
                    {
                        if (!skipBraces(t))
                            return false;
                    }
                    else
                        return false;
                    any = true;
                    continue;

                // storage-class-specifiers
                case TOK.typedef_:
                case TOK.extern_:
                case TOK.static_:
                case TOK._Thread_local:
                case TOK.auto_:
                case TOK.register:

                // function-specifiers
                case TOK.inline:
                case TOK._Noreturn:

                // type-qualifiers
                case TOK.const_:
                case TOK.volatile:
                case TOK.restrict:
                case TOK.__stdcall:
                    t = peek(t);
                    any = true;
                    continue;

                case TOK._Alignas:      // alignment-specifier
                case TOK.__declspec:    // decl-specifier
                case TOK.__attribute__: // attribute-specifier
                    t = peek(t);
                    if (!skipParens(t, &t))
                        return false;
                    any = true;
                    continue;

                // either atomic-type-specifier or type_qualifier
                case TOK._Atomic:  // TODO _Atomic ( type-name )
                    t = peek(t);
                    if (t.value == TOK.leftParenthesis) // maybe atomic-type-specifier
                    {
                        auto tsave = t;
                        t = peek(t);
                        if (!isTypeName(t) || t.value != TOK.rightParenthesis)
                        {   // it's a type-qualifier
                            t = tsave;  // back up parser
                            any = true;
                            continue;
                        }
                        t = peek(t);    // move past right parenthesis of atomic-type-specifier
                    }
                    any = true;
                    continue;

                default:
                    break;
            }
            break;
        }

        if (any)
        {
            pt = t;
            return true;
        }
        return false;
    }

    /**************************************
     * See if declaration-list is present.
     * Returns:
     *    true if declaration-list is present, even an empty one
     */
    bool isDeclarationList(ref Token* pt)
    {
        auto t = pt;
        while (1)
        {
            if (t.value == TOK.leftCurly)
            {
                pt = t;
                return true;
            }
            if (!isCDeclaration(t))
                return false;
        }
    }

    /*******************************************
     * Skip braces.
     * Params:
     *      pt = enters on left brace, set to token past right bracket on true
     * Returns:
     *      true if successful
     */
    private bool skipBraces(ref Token* pt)
    {
        auto t = pt;
        if (t.value != TOK.leftCurly)
            return false;

        int braces = 0;

        while (1)
        {
            switch (t.value)
            {
                case TOK.leftCurly:
                    ++braces;
                    t = peek(t);
                    continue;

                case TOK.rightCurly:
                    --braces;
                    if (braces == 0)
                    {
                        pt = peek(t);
                        return true;
                    }
                    if (braces < 0)
                        return false;

                    t = peek(t);
                    continue;

                case TOK.endOfFile:
                    return false;

                default:
                    t = peek(t);
                    continue;
            }
        }
    }

    /*******************************************
     * Skip brackets.
     * Params:
     *      pt = enters on left bracket, set to token past right bracket on true
     * Returns:
     *      true if successful
     */
    private bool skipBrackets(ref Token* pt)
    {
        auto t = pt;
        if (t.value != TOK.leftBracket)
            return false;

        int brackets = 0;

        while (1)
        {
            switch (t.value)
            {
                case TOK.leftBracket:
                    ++brackets;
                    t = peek(t);
                    continue;

                case TOK.rightBracket:
                    --brackets;
                    if (brackets == 0)
                    {
                        pt = peek(t);
                        return true;
                    }
                    if (brackets < 0)
                        return false;

                    t = peek(t);
                    continue;

                case TOK.endOfFile:
                    return false;

                default:
                    t = peek(t);
                    continue;
            }
        }
    }

    /*********************************
     * Check to see if tokens starting with *pt form a declarator.
     * Params:
     *  pt = pointer to starting token, updated to point past declarator if true is returned
     *  declarator = declarator kind
     * Returns:
     *  true if it does
     */
    private bool isCDeclarator(ref Token* pt, DTR declarator)
    {
        auto t = pt;
        while (1)
        {
            if (t.value == TOK.mul)     // pointer
            {
                t = peek(t);
                if (!isTypeQualifierList(t))
                    return false;
            }
            else
                break;
        }

        if (t.value == TOK.identifier)
        {
            if (declarator == DTR.xabstract)
                return false;
            t = peek(t);
        }
        else if (t.value == TOK.leftParenthesis)
        {
            t = peek(t);
            if (!isCDeclarator(t, declarator))
                return false;
            if (t.value != TOK.rightParenthesis)
                return false;
            t = peek(t);
        }
        else if (declarator == DTR.xdirect)
        {
            return false;
        }

        while (1)
        {
            if (t.value == TOK.leftBracket)
            {
                if (!skipBrackets(t))
                    return false;
            }
            else if (t.value == TOK.leftParenthesis)
            {
                if (!skipParens(t, &t))
                    return false;
            }
            else
                break;
        }
        pt = t;
        return true;
    }

    /***************************
     * Is this the start of a type-qualifier-list?
     * (Can be empty.)
     * Params:
     *  pt = first token; updated with past end of type-qualifier-list if true
     * Returns:
     *  true if start of type-qualifier-list
     */
    private bool isTypeQualifierList(ref Token* pt)
    {
        auto t = pt;
        while (1)
        {
            switch (t.value)
            {
                case TOK.const_:
                case TOK.restrict:
                case TOK.volatile:
                case TOK._Atomic:
                case TOK.__stdcall:
                    t = peek(t);
                    continue;

                default:
                    break;
            }
            break;
        }
        pt = t;
        return true;
    }

    /***************************
     * Is this the start of a type-name?
     * Params:
     *  pt = first token; updated with past end of type-name if true
     * Returns:
     *  true if start of type-name
     */
    private bool isTypeName(ref Token* pt)
    {
        auto t = pt;
        //printf("isTypeName() %s\n", t.toChars());
        if (!isSpecifierQualifierList(t))
            return false;
        if (!isCDeclarator(t, DTR.xabstract))
            return false;
        if (t.value != TOK.rightParenthesis)
            return false;
        pt = t;
        return true;
    }

    /***************************
     * Is this the start of a specifier-qualifier-list?
     * Params:
     *  pt = first token; updated with past end of specifier-qualifier-list if true
     * Returns:
     *  true if start of specifier-qualifier-list
     */
    private bool isSpecifierQualifierList(ref Token* pt)
    {
        auto t = pt;
        bool result;
        while (1)
        {
            switch (t.value)
            {
                // Type Qualifiers
                case TOK.const_:
                case TOK.restrict:
                case TOK.volatile:
                case TOK.__stdcall:

                // Type Specifiers
                case TOK.char_:
                case TOK.signed:
                case TOK.unsigned:
                case TOK.int16:
                case TOK.int32:
                case TOK.int64:
                case TOK.__int128:
                case TOK.float32:
                case TOK.float64:
                case TOK.void_:
                case TOK._Bool:
                //case TOK._Imaginary: // ? missing in Spec
                case TOK._Complex:
                    t = peek(t);
                    break;

                case TOK.identifier:
                    // Use typedef table to disambiguate
                    if (isTypedef(t.ident))
                    {
                        t = peek(t);
                        break;
                    }
                    else
                    {
                        return false;
                    }

                // struct-or-union-specifier
                // enum-specifier
                case TOK.struct_:
                case TOK.union_:
                case TOK.enum_:
                    t = peek(t);
                    if (t.value == TOK.identifier)
                    {
                        t = peek(t);
                        if (t.value == TOK.leftCurly)
                        {
                            if (!skipBraces(t))
                                return false;
                        }
                    }
                    else if (t.value == TOK.leftCurly)
                    {
                        if (!skipBraces(t))
                            return false;
                    }
                    else
                        return false;
                    break;

                // atomic-type-specifier
                case TOK._Atomic:
                case TOK.typeof_:
                    t = peek(t);
                    if (t.value != TOK.leftParenthesis ||
                        !skipParens(t, &t))
                        return false;
                    break;

                default:
                    if (result)
                        pt = t;
                    return result;
            }
            result = true;
        }
    }

    /************************************
     * Looking at the leading left parenthesis, and determine if it is
     * either of the following:
     *    ( type-name ) cast-expression
     *    ( type-name ) { initializer-list }
     * as opposed to:
     *    ( expression )
     * Params:
     *    pt = starting token, updated to one past end of constant-expression if true
     *    afterParenType = true if already seen `( type-name )`
     * Returns:
     *    true if matches ( type-name ) ...
     */
    private bool isCastExpression(ref Token* pt, bool afterParenType = false)
    {
        enum log = false;
        if (log) printf("isCastExpression(tk: `%s`, afterParenType: %d)\n", token.toChars(pt.value), afterParenType);
        auto t = pt;
        switch (t.value)
        {
            case TOK.leftParenthesis:
                auto tk = peek(t);  // move past left parenthesis
                if (!isTypeName(tk) || tk.value != TOK.rightParenthesis)
                {
                    if (afterParenType)
                        goto default; // could be ( type-name ) ( unary-expression )
                    return false;
                }
                tk = peek(tk);  // move past right parenthesis

                if (tk.value == TOK.leftCurly)
                {
                    // ( type-name ) { initializer-list }
                    if (!isInitializer(tk))
                    {
                        return false;
                    }
                    t = tk;
                    break;
                }

                if (tk.value == TOK.leftParenthesis && peek(tk).value == TOK.rightParenthesis)
                {
                    return false;    // (type-name)() is not a cast (it might be a function call)
                }

                if (!isCastExpression(tk, true))
                {
                    if (afterParenType) // could be ( type-name ) ( unary-expression )
                        goto default;   // where unary-expression also matched type-name
                    return true;
                }
                // ( type-name ) cast-expression
                t = tk;
                break;

            default:
                if (!afterParenType || !isUnaryExpression(t, afterParenType))
                {
                    return false;
                }
                // if we've already seen ( type-name ), then this is a cast
                break;
        }
        pt = t;
        if (log) printf("isCastExpression true\n");
        return true;
    }

    /********************************
     * See if match for unary-expression.
     * Params:
     *    pt = starting token, updated to one past end of constant-expression if true
     *    afterParenType = true if already seen ( type-name ) of a cast-expression
     * Returns:
     *    true if unary-expression
     */
    private bool isUnaryExpression(ref Token* pt, bool afterParenType = false)
    {
        auto t = pt;
        switch (t.value)
        {
            case TOK.plusPlus:
            case TOK.minusMinus:
                t = peek(t);
                if (!isUnaryExpression(t, afterParenType))
                    return false;
                break;

            case TOK.and:
            case TOK.mul:
            case TOK.min:
            case TOK.add:
            case TOK.not:
            case TOK.tilde:
                t = peek(t);
                if (!isCastExpression(t, afterParenType))
                    return false;
                break;

            case TOK.sizeof_:
                t = peek(t);
                if (t.value == TOK.leftParenthesis)
                {
                    auto tk = peek(t);
                    if (isTypeName(tk))
                    {
                        if (tk.value != TOK.rightParenthesis)
                            return false;
                        t = peek(tk);
                        break;
                    }
                }
                if (!isUnaryExpression(t, afterParenType))
                    return false;
                break;

            case TOK._Alignof:
                t = peek(t);
                if (t.value != TOK.leftParenthesis)
                    return false;
                t = peek(t);
                if (!isTypeName(t) || t.value != TOK.rightParenthesis)
                    return false;
                break;

            default:
                // Compound literals are handled by cast and sizeof expressions,
                // so be content with just seeing a primary expression.
                if (!isPrimaryExpression(t))
                    return false;
                break;
        }
        pt = t;
        return true;
    }

    /********************************
     * See if match for primary-expression.
     * Params:
     *    pt = starting token, updated to one past end of constant-expression if true
     * Returns:
     *    true if primary-expression
     */
    private bool isPrimaryExpression(ref Token* pt)
    {
        auto t = pt;
        switch (t.value)
        {
            case TOK.identifier:
            case TOK.charLiteral:
            case TOK.int32Literal:
            case TOK.uns32Literal:
            case TOK.int64Literal:
            case TOK.uns64Literal:
            case TOK.float32Literal:
            case TOK.float64Literal:
            case TOK.float80Literal:
            case TOK.imaginary32Literal:
            case TOK.imaginary64Literal:
            case TOK.imaginary80Literal:
            case TOK.string_:
                t = peek(t);
                break;

            case TOK.leftParenthesis:
                // ( expression )
                if (!skipParens(t, &t))
                    return false;
                break;

            case TOK._Generic:
                t = peek(t);
                if (!skipParens(t, &t))
                    return false;
                break;

            default:
                return false;
        }
        pt = t;
        return true;
    }

    //}
    /******************************************************************************/
    /********************************* More ***************************************/
    //{

    /**************
     * Declaration context
     */
    enum LVL
    {
        global    = 1,    /// global
        parameter = 2,    /// function parameter (declarations for function identifier-list)
        prototype = 4,    /// function prototype
        local     = 8,    /// local
        member    = 0x10, /// struct member
    }

    /// Types of declarator to parse
    enum DTR
    {
        xdirect    = 1, /// C11 6.7.6 direct-declarator
        xabstract  = 2, /// C11 6.7.7 abstract-declarator
        xparameter = 3, /// parameter declarator may be either direct or abstract
    }

    /// C11 6.7.1 Storage-class specifiers
    enum SCW : uint
    {
        xnone      = 0,
        xtypedef   = 1,
        xextern    = 2,
        xstatic    = 4,
        x_Thread_local = 8,
        xauto      = 0x10,
        xregister  = 0x20,
        // C11 6.7.4 Function specifiers
        xinline    = 0x40,
        x_Noreturn = 0x80,
    }

    /// C11 6.7.3 Type qualifiers
    enum MOD : uint
    {
        xnone     = 0,
        xconst    = 1,
        xvolatile = 2,
        xrestrict = 4,
        x_Atomic  = 8,
        x__stdcall = 0x10, // Windows linkage extension
    }

    /**********************************
     * Aggregate for all the various specifiers
     */
    struct Specifier
    {
        bool noreturn;  /// noreturn attribute
        SCW scw;        /// storage-class specifiers
        MOD mod;        /// type qualifiers
        AST.Expressions*  alignExps;  /// alignment
        structalign_t packalign;  /// #pragma pack alignment value
    }

    /***********************
     * Convert from C specifiers to D storage class
     * Params:
     *  level = declaration context
     *  specifier = specifiers, context, etc.
     * Returns:
     *  corresponding D storage class
     */
    StorageClass specifiersToSTC(LVL level, const ref Specifier specifier)
    {
        StorageClass stc;
        if (specifier.scw & SCW.x_Thread_local)
        {
            if (level == LVL.global)
            {
                if (specifier.scw & SCW.xextern)
                    stc = AST.STC.extern_;
            }
            else if (level == LVL.local)
            {
                if (specifier.scw & SCW.xextern)
                    stc = AST.STC.extern_;
                else if (specifier.scw & SCW.xstatic)
                    stc = AST.STC.static_;
            }
            else if (level == LVL.member)
            {
                if (specifier.scw & SCW.xextern)
                    stc = AST.STC.extern_;
                else if (specifier.scw & SCW.xstatic)
                    stc = AST.STC.static_;
            }
        }
        else
        {
            if (level == LVL.global)
            {
                if (specifier.scw & SCW.xextern)
                    stc = AST.STC.extern_ | AST.STC.gshared;
                else if (specifier.scw & SCW.xstatic)
                    stc = AST.STC.gshared | AST.STC.static_;
                else
                    stc = AST.STC.gshared;
            }
            else if (level == LVL.local)
            {
                if (specifier.scw & SCW.xextern)
                    stc = AST.STC.extern_ | AST.STC.gshared;
                else if (specifier.scw & SCW.xstatic)
                    stc = AST.STC.gshared;
                else if (specifier.scw & SCW.xregister)
                    stc = AST.STC.register;
            }
            else if (level == LVL.parameter)
            {
                if (specifier.scw & SCW.xregister)
                    stc = AST.STC.register | AST.STC.parameter;
                else
                    stc = AST.STC.parameter;
            }
            else if (level == LVL.member)
            {
                if (specifier.scw & SCW.xextern)
                    stc = AST.STC.extern_ | AST.STC.gshared;
                else if (specifier.scw & SCW.xstatic)
                    stc = AST.STC.gshared;
            }
        }
        return stc;
    }

    /***********************
     * Return suitable signed integer type for the given size
     * Params:
     *  size = size of type
     * Returns:
     *  corresponding signed D integer type
     */
    private AST.Type integerTypeForSize(ubyte size)
    {
        if (size <= 1)
            return AST.Type.tint8;
        if (size <= 2)
            return AST.Type.tint16;
        if (size <= 4)
            return AST.Type.tint32;
        if (size <= 8)
            return AST.Type.tint64;
        if (size == 16)
        {
            error("__int128 not supported");
            return AST.Type.terror;
        }
        error("unsupported integer type");
        return AST.Type.terror;
    }

    /***********************
     * Return suitable unsigned integer type for the given size
     * Params:
     *  size = size of type
     * Returns:
     *  corresponding unsigned D integer type
     */
    private AST.Type unsignedTypeForSize(ubyte size)
    {
        if (size <= 1)
            return AST.Type.tuns8;
        if (size <= 2)
            return AST.Type.tuns16;
        if (size <= 4)
            return AST.Type.tuns32;
        if (size <= 8)
            return AST.Type.tuns64;
        if (size == 16)
        {
            error("unsigned __int128 not supported");
            return AST.Type.terror;
        }
        error("unsupported integer type");
        return AST.Type.terror;
    }

    /***********************
     * Return suitable D float type for C `long double`
     * Params:
     *  flags = kind of float to return (real, imaginary, complex).
     * Returns:
     *  corresponding D type
     */
    private AST.Type realType(RTFlags flags)
    {
        if (long_doublesize == AST.Type.tfloat80.size())
        {
            // On GDC and LDC, D `real` types map to C `long double`, so never
            // return a double type when real.sizeof == double.sizeof.
            final switch (flags)
            {
                case RTFlags.realfloat: return AST.Type.tfloat80;
                case RTFlags.imaginary: return AST.Type.timaginary80;
                case RTFlags.complex:   return AST.Type.tcomplex80;
            }
        }
        else
        {
            final switch (flags)
            {
                case RTFlags.realfloat: return long_doublesize == 8 ? AST.Type.tfloat64 : AST.Type.tfloat80;
                case RTFlags.imaginary: return long_doublesize == 8 ? AST.Type.timaginary64 : AST.Type.timaginary80;
                case RTFlags.complex:   return long_doublesize == 8 ? AST.Type.tcomplex64 : AST.Type.tcomplex80;
            }
        }
    }

    /**************
     * Flags for realType
     */
    private enum RTFlags
    {
        realfloat,
        imaginary,
        complex,
    }

    /********************
     * C11 6.4.2.2 Create declaration to predefine __func__
     *    `static const char __func__[] = " function-name ";`
     * Params:
     *    loc = location for this declaration
     *    id = identifier of function
     * Returns:
     *    statement representing the declaration of __func__
     */
    private AST.Statement createFuncName(Loc loc, Identifier id)
    {
        const fn = id.toString();  // function-name
        auto efn = new AST.StringExp(loc, fn, fn.length, 1, 'c');
        auto ifn = new AST.ExpInitializer(loc, efn);
        auto lenfn = new AST.IntegerExp(loc, fn.length + 1, AST.Type.tuns32); // +1 for terminating 0
        auto tfn = new AST.TypeSArray(AST.Type.tchar, lenfn);
        efn.type = tfn.immutableOf();
        efn.committed = 1;
        auto sfn = new AST.VarDeclaration(loc, tfn, Id.__func__, ifn, STC.gshared | STC.immutable_);
        auto e = new AST.DeclarationExp(loc, sfn);
        return new AST.ExpStatement(loc, e);
    }

    /************************
     * After encountering an error, scan forward until a right brace or ; is found
     * or the end of the file.
     */
    void panic()
    {
        while (token.value != TOK.rightCurly && token.value != TOK.semicolon && token.value != TOK.endOfFile)
            nextToken();
    }

    /**************************
     * Apply `const` to a type.
     * Params:
     *    t = type to add const to
     * Returns:
     *    resulting type
     */
    private AST.Type toConst(AST.Type t)
    {
        // `const` is always applied to the return type, not the
        // type function itself.
        if (auto tf = t.isTypeFunction())
            tf.next = tf.next.addSTC(STC.const_);
        else if (auto tt = t.isTypeTag())
            tt.mod |= MODFlags.const_;
        else
        {
            /* Ignore const if the result would be const pointer to mutable
             */
            auto tn = t.nextOf();
            if (!tn || tn.isConst())
                t = t.addSTC(STC.const_);
        }
        return t;
    }

    /***************************
     * Apply specifier to a Dsymbol.
     * Params:
     *  s = Dsymbol
     *  specifier = specifiers to apply
     * Returns:
     *  Dsymbol with specifiers applied
     */
    private AST.Dsymbol applySpecifier(AST.Dsymbol s, ref Specifier specifier)
    {
        //printf("applySpecifier() %s\n", s.toChars());
        if (specifier.alignExps)
        {
            //printf("  applying _Alignas %s, packalign %d\n", (*specifier.alignExps)[0].toChars(), cast(int)specifier.packalign);
            // Wrap declaration in an AlignDeclaration
            auto decls = new AST.Dsymbols(1);
            (*decls)[0] = s;
            s = new AST.AlignDeclaration(s.loc, specifier.alignExps, decls);
        }
        else if (!specifier.packalign.isDefault())
        {
            //printf("  applying packalign %d\n", cast(int)specifier.packalign);
            // Wrap #pragma pack in an AlignDeclaration
            auto decls = new AST.Dsymbols(1);
            (*decls)[0] = s;
            s = new AST.AlignDeclaration(s.loc, specifier.packalign, decls);
        }
        return s;
    }

    //}

    /******************************************************************************/
    /************************** typedefTab symbol table ***************************/
    //{

    /********************************
     * Determines if type t is a function type.
     * Params:
     *  t = type to test
     * Returns:
     *  true if it represents a function
     */
    bool isFunctionTypedef(AST.Type t)
    {
        //printf("isFunctionTypedef() %s\n", t.toChars());
        if (t.isTypeFunction())
            return true;
        if (auto tid = t.isTypeIdentifier())
        {
            auto pt = lookupTypedef(tid.ident);
            if (pt && *pt)
            {
                return (*pt).isTypeFunction() !is null;
            }
        }
        return false;
    }

    /********************************
     * Determine if `id` is a symbol for a Typedef.
     * Params:
     *  id = possible typedef
     * Returns:
     *  true if id is a Type
     */
    bool isTypedef(Identifier id)
    {
        auto pt = lookupTypedef(id);
        return (pt && *pt);
    }

    /*******************************
     * Add `id` to typedefTab[], but only if it will mask an existing typedef.
     * Params: id = identifier for non-typedef symbol
     */
    void insertIdToTypedefTab(Identifier id)
    {
        //printf("insertIdToTypedefTab(id: %s) level %d\n", id.toChars(), cast(int)typedefTab.length - 1);
        if (isTypedef(id))  // if existing typedef
        {
            /* Add id as null, so we can later distinguish it from a non-null typedef
             */
            auto tab = cast(void*[void*])(typedefTab[$ - 1]);
            tab[cast(void*)id] = cast(void*)null;
        }
    }

    /*******************************
     * Add `id` to typedefTab[]
     * Params:
     *  id = identifier for typedef symbol
     *  t = type of the typedef symbol
     */
    void insertTypedefToTypedefTab(Identifier id, AST.Type t)
    {
        //printf("insertTypedefToTypedefTab(id: %s, t: %s) level %d\n", id.toChars(), t ? t.toChars() : "null".ptr, cast(int)typedefTab.length - 1);
        if (auto tid = t.isTypeIdentifier())
        {
            // Try to resolve the TypeIdentifier to its type
            auto pt = lookupTypedef(tid.ident);
            if (pt && *pt)
                t = *pt;
        }
        auto tab = cast(void*[void*])(typedefTab[$ - 1]);
        tab[cast(void*)id] = cast(void*)t;
        typedefTab[$ - 1] = cast(void*)tab;
    }

    /*********************************
     * Lookup id in typedefTab[].
     * Returns:
     *  if not found, then null.
     *  if found, then Type*. Deferencing it will yield null if it is not
     *  a typedef, and a type if it is a typedef.
     */
    AST.Type* lookupTypedef(Identifier id)
    {
        foreach_reverse (tab; typedefTab[])
        {
            if (auto pt = cast(void*)id in cast(void*[void*])tab)
            {
                return cast(AST.Type*)pt;
            }
        }
        return null; // not found
    }

    //}

    /******************************************************************************/
    /********************************* Directive Parser ***************************/
    //{

    override bool parseSpecialTokenSequence()
    {
        Token n;
        scan(&n);
        if (n.value == TOK.int32Literal)
        {
            poundLine(n, true);
            return true;
        }
        if (n.value == TOK.identifier)
        {
            if (n.ident == Id.line)
            {
                poundLine(n, false);
                return true;
            }
            else if (defines && (n.ident == Id.define || n.ident == Id.undef))
            {
                /* Append this line to `defines`.
                 * Not canonicalizing it - assume it already is
                 */
                defines.writeByte('#');
                defines.writestring(n.ident.toString());
                skipToNextLine(defines);
                defines.writeByte('\n');
                return true;
            }
            else if (n.ident == Id.__pragma)
            {
                pragmaDirective(scanloc);
                return true;
            }
        }
        if (n.ident != Id.undef)
            error("C preprocessor directive `#%s` is not supported", n.toChars());
        return false;
    }

    /*********************************************
     * VC __pragma
     * https://docs.microsoft.com/en-us/cpp/preprocessor/pragma-directives-and-the-pragma-keyword?view=msvc-170
     * Scanner is on the `__pragma`
     * Params:
     *  startloc = location to use for error messages
     */
    private void uupragmaDirective(const ref Loc startloc)
    {
        const loc = startloc;
        nextToken();
        if (token.value != TOK.leftParenthesis)
        {
            error(loc, "left parenthesis expected to follow `__pragma`");
            return;
        }
        nextToken();
        if (token.value == TOK.identifier && token.ident == Id.pack)
            pragmaPack(startloc, false);
        else
            error(loc, "unrecognized __pragma");
        if (token.value != TOK.rightParenthesis)
        {
            error(loc, "right parenthesis expected to close `__pragma(...)`");
            return;
        }
        nextToken();
    }

    /*********************************************
     * C11 6.10.6 Pragma directive
     * # pragma pp-tokens(opt) new-line
     * The C preprocessor sometimes leaves pragma directives in
     * the preprocessed output. Ignore them.
     * Upon return, p is at start of next line.
     */
    private void pragmaDirective(const ref Loc loc)
    {
        Token n;
        scan(&n);
        if (n.value == TOK.identifier && n.ident == Id.pack)
            return pragmaPack(loc, true);
        if (n.value != TOK.endOfLine)
            skipToNextLine();
    }

    /*********
     * # pragma pack
     * https://gcc.gnu.org/onlinedocs/gcc-4.4.4/gcc/Structure_002dPacking-Pragmas.html
     * https://docs.microsoft.com/en-us/cpp/preprocessor/pack
     * Scanner is on the `pack`
     * Params:
     *  startloc = location to use for error messages
     *  useScan = use scan() to retrieve next token, instead of nextToken()
     */
    private void pragmaPack(const ref Loc startloc, bool useScan)
    {
        const loc = startloc;

        /* Pull tokens from scan() or nextToken()
         */
        void scan(Token* t)
        {
            if (useScan)
            {
                Lexer.scan(t);
            }
            else
            {
                nextToken();
                *t = token;
            }
        }

        Token n;
        scan(&n);
        if (n.value != TOK.leftParenthesis)
        {
            error(loc, "left parenthesis expected to follow `#pragma pack`");
            if (n.value != TOK.endOfLine)
                skipToNextLine();
            return;
        }

        void closingParen()
        {
            if (n.value != TOK.rightParenthesis)
            {
                error(loc, "right parenthesis expected to close `#pragma pack(`");
            }
            if (n.value != TOK.endOfLine)
                skipToNextLine();
        }

        void setPackAlign(ref const Token t)
        {
            const n = t.unsvalue;
            if (n < 1 || n & (n - 1) || ushort.max < n)
                error(loc, "pack must be an integer positive power of 2, not 0x%llx", cast(ulong)n);
            packalign.set(cast(uint)n);
            packalign.setPack(true);
        }

        scan(&n);

        if (!records)
        {
            records = new Array!Identifier;
            packs = new Array!structalign_t;
        }

        /* # pragma pack ( show )
         */
        if (n.value == TOK.identifier && n.ident == Id.show)
        {
            if (packalign.isDefault())
                eSink.warning(startloc, "current pack attribute is default");
            else
                eSink.warning(startloc, "current pack attribute is %d", packalign.get());
            scan(&n);
            return closingParen();
        }
        /* # pragma pack ( push )
         * # pragma pack ( push , identifier )
         * # pragma pack ( push , integer )
         * # pragma pack ( push , identifier , integer )
         */
        if (n.value == TOK.identifier && n.ident == Id.push)
        {
            scan(&n);
            Identifier record = null;
            if (n.value == TOK.comma)
            {
                scan(&n);
                if (n.value == TOK.identifier)
                {
                    record = n.ident;
                    scan(&n);
                    if (n.value == TOK.comma)
                    {
                        scan(&n);
                        if (n.value == TOK.int32Literal)
                        {
                            setPackAlign(n);
                            scan(&n);
                        }
                        else
                            error(loc, "alignment value expected, not `%s`", n.toChars());
                    }
                }
                else if (n.value == TOK.int32Literal)
                {
                    setPackAlign(n);
                    scan(&n);
                }
                else
                    error(loc, "alignment value expected, not `%s`", n.toChars());
            }
            this.records.push(record);
            this.packs.push(packalign);
            return closingParen();
        }
        /* # pragma pack ( pop )
         * # pragma pack ( pop PopList )
         * PopList :
         *    , IdentifierOrInteger
         *    , IdentifierOrInteger PopList
         * IdentifierOrInteger:
         *      identifier
         *      integer
         */
        if (n.value == TOK.identifier && n.ident == Id.pop)
        {
            scan(&n);
            size_t len = this.records.length;
            if (n.value == TOK.rightParenthesis) // #pragma pack ( pop )
            {
                if (len == 0)   // nothing to pop
                    return closingParen();

                this.records.setDim(len - 1);
                this.packs.setDim(len - 1);
                if (len == 1)   // stack is now empty
                    packalign.setDefault();
                else
                    packalign = (*this.packs)[len - 1];
                return closingParen();
            }
            while (n.value == TOK.comma)        // #pragma pack ( pop ,
            {
                scan(&n);
                if (n.value == TOK.identifier)
                {
                    /* pragma pack(pop, identifier
                     * Pop until identifier is found, pop that one too, and set
                     * alignment to the new top of the stack.
                     * If identifier is not found, do nothing.
                     */
                    for ( ; len; --len)
                    {
                        if ((*this.records)[len - 1] == n.ident)
                        {
                            this.records.setDim(len - 1);
                            this.packs.setDim(len - 1);
                            if (len > 1)
                                packalign = (*this.packs)[len - 2];
                            else
                                packalign.setDefault(); // stack empty, use default
                            break;
                        }
                    }
                    scan(&n);
                }
                else if (n.value == TOK.int32Literal)
                {
                    setPackAlign(n);
                    scan(&n);
                }
                else
                {
                    error(loc, "identifier or alignment value expected following `#pragma pack(pop,` not `%s`", n.toChars());
                    scan(&n);
                }
            }
            return closingParen();
        }
        /* # pragma pack ( integer )
         * Sets alignment to integer
         */
        if (n.value == TOK.int32Literal)
        {
            setPackAlign(n);
            scan(&n);
            return closingParen();
        }
        /* # pragma pack ( )
         * Sets alignment to default
         */
        if (n.value == TOK.rightParenthesis)
        {
            packalign.setDefault();
            return closingParen();
        }

        error(loc, "unrecognized `#pragma pack(%s)`", n.toChars());
        if (n.value != TOK.endOfLine)
            skipToNextLine();
    }

    //}

    /******************************************************************************/
    /********************************* #define Parser *****************************/
    //{

    /**
     * Go through the #define's in the defines buffer and see what we can convert
     * to Dsymbols, which are then appended to symbols[]
     */
    void addDefines()
    {
        if (!defines || defines.length < 10)  // minimum length of a #define line
            return;
        OutBuffer* buf = defines;
        defines = null;                 // prevent skipToNextLine() and parseSpecialTokenSequence()
                                        // from appending to slice[]
        const length = buf.length;
        buf.writeByte(0);
        auto slice = buf.peekChars()[0 .. length];
        resetDefineLines(slice);                // reset lexer

        const(char)* endp = &slice[length - 7];

        size_t[void*] defineTab;    // hash table of #define's turned into Symbol's
                                    // indexed by Identifier, returns index into symbols[]
                                    // The memory for this is leaked

        void addVar(AST.VarDeclaration v)
        {
            //printf("addVar() %s\n", v.toChars());
            v.isCmacro(true);           // mark it as coming from a C #define
            /* If it's already defined, replace the earlier
             * definition
             */
            if (size_t* pd = cast(void*)v.ident in defineTab)
            {
                //printf("replacing %s\n", v.toChars());
                (*symbols)[*pd] = v;
                return;
            }
            defineTab[cast(void*)v.ident] = symbols.length;
            symbols.push(v);
        }

        Token n;

        while (p < endp)
        {
            if (p[0 .. 7] == "#define")
            {
                p += 7;
                scan(&n);
                //printf("%s\n", n.toChars());
                if (n.value == TOK.identifier)
                {
                    auto id = n.ident;
                    scan(&n);

                    AST.Type t;

                    switch (n.value)
                    {
                        case TOK.endOfLine:     // #define identifier
                            nextDefineLine();
                            continue;

                        case TOK.int32Literal:
                        case TOK.charLiteral:       t = AST.Type.tint32;    goto Linteger;
                        case TOK.uns32Literal:      t = AST.Type.tuns32;    goto Linteger;
                        case TOK.int64Literal:      t = AST.Type.tint64;    goto Linteger;
                        case TOK.uns64Literal:      t = AST.Type.tuns64;    goto Linteger;

                        Linteger:
                            const intvalue = n.intvalue;
                            scan(&n);
                            if (n.value == TOK.endOfLine)
                            {
                                /* Declare manifest constant:
                                 *  enum id = intvalue;
                                 */
                                AST.Expression e = new AST.IntegerExp(scanloc, intvalue, t);
                                auto v = new AST.VarDeclaration(scanloc, t, id, new AST.ExpInitializer(scanloc, e), STC.manifest);
                                addVar(v);
                                nextDefineLine();
                                continue;
                            }
                            break;

                        case TOK.float32Literal:      t = AST.Type.tfloat32;     goto Lfloat;
                        case TOK.float64Literal:      t = AST.Type.tfloat64;     goto Lfloat;
                        case TOK.float80Literal:      t = AST.Type.tfloat80;     goto Lfloat;
                        case TOK.imaginary32Literal:  t = AST.Type.timaginary32; goto Lfloat;
                        case TOK.imaginary64Literal:  t = AST.Type.timaginary64; goto Lfloat;
                        case TOK.imaginary80Literal:  t = AST.Type.timaginary80; goto Lfloat;

                        Lfloat:
                            const floatvalue = n.floatvalue;
                            scan(&n);
                            if (n.value == TOK.endOfLine)
                            {
                                /* Declare manifest constant:
                                 *  enum id = floatvalue;
                                 */
                                AST.Expression e = new AST.RealExp(scanloc, floatvalue, t);
                                auto v = new AST.VarDeclaration(scanloc, t, id, new AST.ExpInitializer(scanloc, e), STC.manifest);
                                addVar(v);
                                nextDefineLine();
                                continue;
                            }
                            break;

                        case TOK.string_:
                            const str = n.ustring;
                            const len = n.len;
                            const postfix = n.postfix;
                            scan(&n);
                            if (n.value == TOK.endOfLine)
                            {
                                /* Declare manifest constant:
                                 *  enum id = "string";
                                 */
                                AST.Expression e = new AST.StringExp(scanloc, str[0 .. len], len, 1, postfix);
                                auto v = new AST.VarDeclaration(scanloc, null, id, new AST.ExpInitializer(scanloc, e), STC.manifest);
                                addVar(v);
                                nextDefineLine();
                                continue;
                            }
                            break;

                        default:
                            break;
                    }
                }
                skipToNextLine();
            }
            else
            {
                scan(&n);
                if (n.value != TOK.endOfLine)
                {
                    skipToNextLine();
                }
            }
            nextDefineLine();
        }

        defines = buf;
    }

    //}
}
