Exemplo n.º 1
0
void CppStackFini( void )
{
    struct cpp_info *cpp;

    while( (cpp = CppStack) != NULL ) {
        SetErrLoc( &cpp->src_loc );
        CErr1( ERR_MISSING_CENDIF );
        InitErrLoc();
        CppStack = cpp->prev_cpp;
        CMemFree( cpp );
    }
    CppStack = NULL;
}
Exemplo n.º 2
0
void SetFarHuge( SYMPTR sym, bool report )
{
    TYPEPTR             typ;
    type_modifiers      attrib;
    target_size         size;

#if _CPU != 8086
    /* unused parameters */ (void)report;
#endif

#if _CPU == 8086
    if( sym->attribs.declspec == DECLSPEC_DLLIMPORT
      || sym->attribs.declspec == DECLSPEC_DLLEXPORT ) {
        sym->mods |= FLAG_FAR;
    } else if( sym->mods & FLAG_EXPORT ) {
        sym->mods |= FLAG_FAR;
    }
#endif
    size = SizeOfArg( sym->sym_type );
    if( TargetSwitches & BIG_DATA ) {
        attrib = sym->mods;
        if( (attrib & MASK_ALL_MEM_MODELS) == 0 ) {
            if( size == 0 ) {   /* unspecified array size */
                if( sym->attribs.stg_class == SC_EXTERN ) {
                    typ = sym->sym_type;
                    if( typ->decl_type == TYPE_ARRAY ) {
                        attrib |= FLAG_FAR;
                    }
                }
            } else if( size > DataThreshold ) {
                attrib |= FLAG_FAR;
            } else if( CompFlags.strings_in_code_segment && ( sym->mods & FLAG_CONST ) ) {
                attrib |= FLAG_FAR;
            }
#if _CPU == 8086
            if( (attrib & FLAG_FAR) && size > 0x10000 ) {
                attrib &= ~FLAG_FAR;
                attrib |= FLAG_HUGE;
            }
#endif
            sym->mods = attrib;
        }
    }
#if _CPU == 8086
   if( report && size > 0x10000 && (sym->mods & FLAG_HUGE) == 0 ) {
        SetErrLoc( &sym->src_loc );
        CErr1( ERR_VAR_TOO_LARGE );
        InitErrLoc();
   }
#endif
}
Exemplo n.º 3
0
void SetFarHuge( SYMPTR sym, int report )
{
    TYPEPTR             typ;
    type_modifiers      attrib;
    unsigned long       size;

    report = report; /* in case not used */
#if _CPU == 8086
    if( sym->declspec == DECLSPEC_DLLIMPORT
            || sym->declspec == DECLSPEC_DLLEXPORT ) {      /* 16-dec-94 */
        sym->attrib |= FLAG_FAR;
    } else if( sym->attrib & FLAG_EXPORT ) {
        sym->attrib |= FLAG_FAR;
    }
#endif
    size = SizeOfArg( sym->sym_type );
    if( TargetSwitches & BIG_DATA ) {
        attrib = sym->attrib;
        if( (attrib & MASK_ALL_MEM_MODELS) == 0 ) {
            if( size == 0 ) {   /* unspecified array size */
                if( sym->stg_class == SC_EXTERN ) {
                    typ = sym->sym_type;
                    if( typ->decl_type == TYPE_ARRAY ) {
                        attrib |= FLAG_FAR;
                    }
                }
            } else if( size > DataThreshold ) {
                attrib |= FLAG_FAR;
            } else if( CompFlags.strings_in_code_segment
                       && ( sym->attrib & FLAG_CONST ) ) {
                attrib |= FLAG_FAR;
            }
#if _CPU == 8086
            if( (attrib & FLAG_FAR) && size > 0x10000 ) {
                attrib &= ~FLAG_FAR;
                attrib |= FLAG_HUGE;
            }
#endif
            sym->attrib = attrib;
        }
    }
#if _CPU == 8086
    if( report && size > 0x10000 && !(sym->attrib & FLAG_HUGE) ) {
        SetErrLoc( &sym->src_loc );
        CErr1( ERR_VAR_TOO_LARGE );
        InitErrLoc();
    }
#endif
}
Exemplo n.º 4
0
/* Check parameters of function that were called before a prototype was seen */
extern void ChkCallParms( void )
{
    call_list   *nextcall;
    call_list   *next;

    for( nextcall = CallNodeList; nextcall != NULL; nextcall = next ) {
        TREEPTR     callnode;
        TREEPTR     callsite;
        SYM_ENTRY   sym;
        TYPEPTR     typ;

        next = nextcall->next;
        callnode = nextcall->callnode;
        if( callnode != NULL ) {
            callsite = callnode->left;      // point to OPR_FUNCNAME node
            SymGet( &sym, callsite->op.u2.sym_handle );
            typ = sym.sym_type;
            SKIP_TYPEDEFS( typ );
            if( (sym.flags & SYM_TEMP) == 0 )
                SetDiagSymbol( &sym, callsite->op.u2.sym_handle );
            SetErrLoc( &nextcall->src_loc );
            if( typ->u.fn.parms != NULL ) {
                CompareParms( typ->u.fn.parms, callnode->right, ParmsToBeReversed( sym.mods, NULL ) );
            } else {
                // Unprototyped function called. Note that for indirect calls, there
                // is no symbol associated with the function and diagnostic information
                // is hence limited.
                if( sym.flags & SYM_TEMP ) {
                    CWarn1( WARN_NONPROTO_FUNC_CALLED_INDIRECT, ERR_NONPROTO_FUNC_CALLED_INDIRECT );
                } else {
                    CWarn2p( WARN_NONPROTO_FUNC_CALLED, ERR_NONPROTO_FUNC_CALLED, SymName( &sym, callsite->op.u2.sym_handle ) );
                }
            }
            InitErrLoc();
            if( (sym.flags & SYM_TEMP) == 0 ) {
                SetDiagPop();
            }
        }
        CMemFree( nextcall );
    }
}
Exemplo n.º 5
0
void InitGlobalVars( void )
{
    PCH_Start               = NULL; // start of precompiled memory block
    PCH_End                 = NULL; // end of precompiled memory block
    PCH_Macros              = NULL; // macros loaded from pre-compiled header
    PCH_FileName            = NULL; // name to use for pre-compiled header
    IncFileList             = NULL; // list of primary include files for PCH
    PCH_SymArray            = NULL; // array of symbol table pointers from PCH
    PCH_MaxSymHandle        = 0;    // number of symbols in PCH_SymArray
    DebugFlag               = 0;
    CurToken                = T_NULL;
    BadTokenInfo            = 0;
    TokenLen                = 0;
    TokenLoc.line           = 0;
    TokenLoc.fno            = 0;
    SrcFileLoc.line         = 0;
    SrcFileLoc.fno          = 0;
    CommentLoc.line         = 0;
    CommentLoc.fno          = 0;
    CurrChar                = 0;
    ConstType               = 0;
    Constant                = 0;
    MainSrcFile             = NULL; /* primary source file being compiled */
    SrcFile                 = NULL;
    SrcFName                = NULL; /* source file name without suffix */
    DefFName                = NULL; /* .def file name (prototypes) */
    WholeFName              = NULL; /* whole file name with suffix */
    ForceInclude            = NULL;
#if _CPU == 370
    AuxName                 = NULL;
#endif
    FNames                  = NULL; /* list of file names processed */
    ErrFile                 = NULL; /* error file */
    DefFile                 = NULL; /* output for func prototypes */
    CppFile                 = NULL; /* output for preprocessor */
    CppStack                = NULL; /* #if structure control stack */
    IncPathList             = NULL; /* list of path names to try for include files */
    SrcLoc.line             = 0;
    SrcLoc.fno              = 0;
    SrcLineCount            = 0;    /* # of lines in primary source file */
    IncLineCount            = 0;    /* # of lines in all included files  */
    ErrCount                = 0;    /* total # of errors encountered     */
    WngCount                = 0;    /* total # of warnings encountered   */
    WngLevel                = 0;    /* warning severity level */
    TypeCount               = 0;    /* total # of type nodes allocated   */
    GblSymCount             = 0;    /* total # of global symbols */
    LclSymCount             = 0;    /* total # of local and temporary symbols */
    FuncCount               = 0;    /* total # of functions defined in module */
    SizeOfCount             = 0;    /* # of nested sizeof() expressions  */
    SymLevel                = 0;    /* current lex level (# of nested {) */
    HashValue               = 0;    /* hash value for identifier */
    MacHashValue            = 0;    /* hash value for macro name */
    SavedId                 = NULL; /* saved id when doing look ahead */
    SavedHash               = 0;    /* hash value for saved id */
    SavedTokenLoc.line      = 0;    /* value of TokenLine when id saved */
    SavedTokenLoc.fno       = 0;    /* value of TokenFno when id saved */
    LAToken                 = 0;    /* look ahead token */
    LabelHead               = NULL; /* list of all labels defined in function */
    TagHead                 = NULL; /* list of all struct, union, enum tags */
    DeadTags                = NULL; /* list of all tags that are out of scope */
    CurFunc                 = NULL; /* current function being worked on */
    ParmList                = NULL; /* list of parms for function */
    GlobalSym               = SYM_NULL; /* global symbol table list head */
#if _CPU == 386
    SymSTOD                 = SYM_NULL; /* builtin symbol for 'rep stosd' */
    SymSTOSB                = SYM_NULL; /* builtin symbol for '__STOSB' */
    SymSTOSD                = SYM_NULL; /* builtin symbol for '__STOSD' */
#endif
#ifdef __SEH__
    SymTryInit              = SYM_NULL; /* builtin symbol for '__TryInit' */
    SymTryFini              = SYM_NULL; /* builtin symbol for '__TryFini' */
    SymExcept               = SYM_NULL; /* builtin symbol for '__Except' */
    SymFinally              = SYM_NULL; /* builtin symbol for '__Finally' */
    SymTryUnwind            = SYM_NULL; /* builtin symbol for '__TryUnwind' */
    TrySymHandle            = SYM_NULL; /* builtin symbol for local try block */
    TryScope                = 0;    /* current scope of _try blocks */
    TryCount                = 0;    /* current number of _try blocks */
#endif
    SymSTOW                 = SYM_NULL; /* builtin symbol for 'rep stosw' */
    SymSTOWB                = SYM_NULL; /* builtin symbol for 'rep stosw, stosb' */
    SymMIN                  = SYM_NULL; /* builtin symbol for 'min(a,b)' */
    SymMAX                  = SYM_NULL; /* builtin symbol for 'max(a,b)' */
    SymMEMCMP               = SYM_NULL; /* builtin symbol for 'memcmp' func */
    SpecialSyms             = SYM_NULL; /* builtin symbols (thread linked) */
    CharSymHandle           = SYM_NULL; /* sym handle for "char" typedef */
    Sym_CS                  = SYM_NULL; /* sym handle for __segname("_CODE") ie. CS */
    Sym_SS                  = SYM_NULL; /* sym handle for __segname("_STACK")ie. SS */
    SymCover                = SYM_NULL; /* sym handle for '__COVERAGE' */
    SymDFAbbr               = SYM_NULL; /* sym handle for '__DFABBREV' */
    SymChipBug              = SYM_NULL; /* sym handle for '__chipbug' */
    ErrSym                  = NULL;

#if _CPU == 386
    FunctionProfileBlock    = NULL; /* handle for profiling data block */
    FunctionProfileSegment  = SEG_UNKNOWN; /* segment for profiling data block */
#endif

    MacroDepth              = 0;
    NextMacro               = NULL;
    HashTab                 = NULL;

    GenSwitches             = 0;    /* target independant switches for code generator */
    TargetSwitches          = 0;    /* target specific code generator switches */

    ProcRevision            = 0;    /* processor revision for c.g. */
    GenCodeGroup            = NULL; /* pointer to code group name */
    ProEpiDataSize          = 0;    /* data to be alloc'd for pro/epi hook */
    Toggles                 = 0;    /* global toggle flags */
    ErrLimit                = 0;

    DataThreshold           = 0;    /* sizeof(obj) > this ==> separate segment */
    Inline_Threshold        = 0;    /* -oe=num for function inlining */

    DataPtrSize             = 0;
    CodePtrSize             = 0;
    DeadCode                = 0;    /* non-zero => next stmt is unreachable */
    TmpSymCount             = 0;
    LitCount                = 0;
    LitPoolSize             = 0;
    MacroSize               = 0;
    SegmentNum              = 0;    /* next PRIVATE segment number to use */
    FarStringSegment        = SEG_UNKNOWN;

    Environment             = NULL; /* var for Suicide() */


    /* The following 3 arrays are also used by CGEN for saving _try block info */
    ExprLevel               = 0;

    SegListHead             = NULL;
    SegImport               = SEG_UNKNOWN; /* next segment # for import sym */
    SegData                 = SEG_UNKNOWN; /* data seg # for -nd option */

    ScopeStruct             = 0;
    ScopeUnion              = 0;
    ScopeEnum               = 0;

    B_Int_1                 = 0;
    B_UInt_1                = 0;
    B_Short                 = 0;
    B_UShort                = 0;
    B_Int                   = 0;
    B_UInt                  = 0;
    B_Int32                 = 0;
    B_UInt32                = 0;
    B_Int64                 = 0;
    B_UInt64                = 0;
    B_Bool                  = 0;

    OptSize                 = 0;    /* 100 => make pgm small as possible */
    MsgFlags                = NULL; /* Bit mask of disabled messages */
    MacSegList              = NULL; /* pointer to list of macro segments */
    LoopDepth               = 0;    /* current nesting of loop constructs */
    HeadLibs                = 0;    /* list of library search records */
    AliasHead               = 0;    /* list of symbol alias records */
    CurFuncHandle           = SYM_NULL; /* sym_handle for current function */
    LastFuncOutOfMem        = NULL; /* cinfo: */
    HashFreeList            = NULL; /* list of available hash entries */

    SymBufSegNum            = 0;    /* segment # containing buffer */

    StringType              = NULL; /* "unsigned char *" for use by literals */
    ConstCharType           = NULL; /* "const char" type */
    StringArrayType         = NULL; /* "unsigned char []" used by literals */
    NestedParms             = NULL;

    TextSegName             = NULL; /* name of the text segment */
    DataSegName             = NULL; /* name of the data segment */
    CodeClassName           = NULL; /* name of the code class */
    ModuleName              = NULL; /* name of module */
    ObjectFileName          = NULL; /* name of object file */
    DependFileName          = NULL; /* Name of make style auto depend file */
    DependHeaderPath        = NULL; /* If no path is part of an included file, use this*/
    DependForceSlash        = 0;
    PackAmount              = 0;    /* current packing alignment */
    GblPackAmount           = 0;    /* packing alignment given on command line */
    Column                  = 0;    /* skip to Column when reading */
    Trunc                   = 0;    /* stop at Trunc when reading  */
    PrevProtoType           = NULL; /* prev func prototype */

    TargSys                 = TS_OTHER;
    DefDataSegment          = SEG_UNKNOWN; /* #pragma data_seg("segname","class") */
    DefCodeSegment          = NULL; /* #pragma code_seg("seg","c") */

    UnrollCount             = 0;    /* #pragma unroll(#); */
    InitialMacroFlag        = MFLAG_NONE;
    Stack87                 = 0;
    ErrorFileName           = NULL;

    UndefNames              = NULL;
    Check_global_prototype  = 0;

    memset( &CompFlags, 0, sizeof( CompFlags ) );
    InitStmt();
    InitErrLoc();
}
Exemplo n.º 6
0
TYPEPTR EnumDecl( int flags )
{
    TYPEPTR     typ;
    TAGPTR      tag;

    flags = flags;
    NextToken();
    if( CurToken == T_ID ) {
        /* could be: (1) "enum" <id> ";"
                     (2) "enum" <id> <variable_name> ";"
                     (3) "enum" <id> "{" <enum_const_decl> ... "}"
        */
        tag = TagLookup();
        NextToken();
        if( CurToken != T_LEFT_BRACE ) {
            typ = tag->sym_type;
            if( typ == NULL ) {
                CErr1( ERR_INCOMPLETE_ENUM_DECL );
                typ = TypeDefault();
            } else {
                if( typ->decl_type != TYPE_ENUM ) {         /* 18-jan-89 */
                    CErr2p( ERR_DUPLICATE_TAG, tag->name );
                }
                typ->u.tag = tag;
            }
            return( typ );
        }
        tag = VfyNewTag( tag, TYPE_ENUM );
    } else {
        tag = NullTag();
    }
    typ = TypeNode( TYPE_ENUM, GetType( TYPE_INT ) );
    typ->u.tag = tag;
    tag->sym_type = typ;
    tag->size = TARGET_INT;
    tag->u.enum_list = NULL;
    if( CurToken == T_LEFT_BRACE ) {
        const_val       val;
        enum enum_rng   index;
        enum enum_rng   const_index;
        enum enum_rng   start_index;
        enum enum_rng   step;
        enum enum_rng   error;
        uint64          n;
        uint64          Inc;
        bool            minus;
        bool            has_sign;
        ENUMPTR         *prev_lnk;
        ENUMPTR         esym;
        source_loc      error_loc;
        char            buff[50];

        if( CompFlags.make_enums_an_int ) {
            start_index = ENUM_INT;
        } else {
            start_index = ENUM_S8;
        }
        const_index = ENUM_UNDEF;
        NextToken();
        if( CurToken == T_RIGHT_BRACE ) {
            CErr1( ERR_EMPTY_ENUM_LIST );
        }
        U32ToU64( 1, &Inc );
        U64Clear( n );
        minus = FALSE;
        has_sign = FALSE;
        step = 1;
        prev_lnk = &esym;
        esym = NULL;
        while( CurToken == T_ID ) {
            esym = EnumLkAdd( tag );
            *prev_lnk = esym;
            prev_lnk = &esym->thread;
            error_loc = TokenLoc;
            NextToken();
            if( CurToken == T_EQUAL ) {
                NextToken();
                error_loc = TokenLoc;
                ConstExprAndType( &val );
                switch( val.type ){
                case TYPE_ULONG:
                case TYPE_UINT:
                case TYPE_ULONG64:
                    minus = FALSE;
                    break;
                default:
                    if( val.value.u.sign.v ) {
                        minus = TRUE;
                        step = 2;
                    } else {
                        minus = FALSE;
                    }
                    break;
                }
                n = val.value;
            } else if( has_sign ) {
                if( n.u.sign.v ) {
                    minus = TRUE;
                } else {
                    minus = FALSE;
                }
            }
            for( index = start_index; index < ENUM_SIZE; index += step ) {
                if( minus ) {
                    if( I64Cmp( &n, &( RangeTable[ index ][LOW] ) ) >= 0 ) break;
                } else {
                    if( U64Cmp( &n, &( RangeTable[ index ][HIGH]) ) <= 0 ) break;
                }
            }
            error = ENUM_UNDEF;
            if( !CompFlags.extensions_enabled && ( index > ENUM_INT )) {
                error = ENUM_INT;
            }
            if( index >= ENUM_SIZE ) {
                // overflow signed maximum range
                if( error == ENUM_UNDEF ) {
                    error = const_index;
                }
            } else if(( const_index == ENUM_SIZE - 1 ) && minus ) {
                // overflow unsigned maximum range by any negative signed value
                if( error == ENUM_UNDEF )
                    error = const_index;
                step = 1;
            } else {
                if( !has_sign && minus) {
                    has_sign = TRUE;
                    if( index < const_index ) {
                        // round up to signed
                        index = ( const_index + 1 ) & ~1;
                    }
                }
                if( index > const_index ) {
                    const_index = index;
                    typ->object = GetType( ItypeTable[const_index].decl_type );
                    tag->size   = ItypeTable[const_index].size;
                }
            }
            if( error != ENUM_UNDEF ) {
                SetErrLoc( &error_loc );
                get_msg_range( buff, error );
                CErr2p( ERR_ENUM_CONSTANT_OUT_OF_RANGE, buff );
                InitErrLoc();
            }
            esym->value = n;
            EnumTable[ esym->hash ] = esym;             /* 08-nov-94 */
            if( CurToken == T_RIGHT_BRACE )
                break;
            U64Add( &n, &Inc, &n );
            MustRecog( T_COMMA );
            if( !CompFlags.extensions_enabled
              && !CompFlags.c99_extensions
              && ( CurToken == T_RIGHT_BRACE )) {
                ExpectIdentifier();         /* 13-may-91 */
            }
        }
        MustRecog( T_RIGHT_BRACE );
    }
    return( typ );
}
Exemplo n.º 7
0
void Statement( void )
{
    LABEL_INDEX         end_of_func_label;
    SYM_HANDLE          func_result;
    TREEPTR             tree;
    bool                return_at_outer_level;
    bool                skip_to_next_token;
    bool                declaration_allowed;
    struct return_info  return_info;
    SYM_ENTRY           sym;

#ifndef NDEBUG
    if( DebugFlag >= 1 ) {
        printf( "***** line %u, func=%s\n", TokenLoc.line, CurFunc->name );
        PrintStats();
    }
#endif
    ++FuncCount;
    return_info.with = RETURN_WITH_NONE; /* indicate no return statements */
    return_info.with_expr = FALSE;
    CompFlags.label_dropped = 0;
    CompFlags.addr_of_auto_taken = 0;           /* 23-oct-91 */
    end_of_func_label = 0;
    return_at_outer_level = FALSE;              /* 28-feb-92 */
    declaration_allowed   = FALSE;
    DeadCode = 0;
    LoopDepth = 0;
    LabelIndex = 0;
    BlockStack = NULL;
    LoopStack = NULL;
    SwitchStack = NULL;
#ifdef __SEH__
    TryCount = -1;
    TryScope = -1;
#endif
    StartNewBlock();
    NextToken();                        // skip over {
    ++SymLevel;
    tree = LeafNode( OPR_LABELCOUNT );
    AddStmt( tree );
    if( GrabLabels() == 0 ) {                           /* 29-nov-94 */
        GetLocalVarDecls();
    }
    func_result = MakeNewSym( &sym, 'R', CurFunc->sym_type->object, SC_AUTO );
    sym.flags |= SYM_FUNC_RETURN_VAR;   /* 25-oct-91 */
    SymReplace( &sym, func_result );
    for( ;; ) {
        CompFlags.pending_dead_code = 0;
        if( GrabLabels() == 0 && declaration_allowed && IsDeclarator( CurToken ) ) {
            GetLocalVarDecls();
        }
        if( CompFlags.c99_extensions ) {
            declaration_allowed = TRUE;
        }
        skip_to_next_token = FALSE;
        switch( CurToken ) {
        case T_IF:
            StartNewBlock();
            NextToken();
            BlockStack->break_label = NextLabel();
            JumpFalse( BracketExpr(), BlockStack->break_label );
            /* 23-dec-88, only issue msg if ';' is on same line as 'if' */
            if( CurToken == T_SEMI_COLON  &&  SrcLoc.line == TokenLoc.line && SrcLoc.fno == TokenLoc.fno ) {
                SetErrLoc( &TokenLoc );
                NextToken();    /* look ahead for else keyword */
                if( CurToken != T_ELSE ) {              /* 02-apr-91 */
                    ChkUseful();                        /* 08-dec-88 */
                }
                InitErrLoc();
                break;
            }
            declaration_allowed = FALSE;
            continue;
        case T_WHILE:
            NewLoop();
            NextToken();
            BlockStack->break_label = NextLabel();
            if( !JumpFalse( BracketExpr(), BlockStack->break_label ) ) {
                BlockStack->break_label = 0;            /* 09-sep-92 */
            }
            if( CurToken == T_SEMI_COLON ) {            /* 08-dec-88 */
                if( ! CompFlags.useful_side_effect ) {
                    CWarn1( WARN_MEANINGLESS, ERR_MEANINGLESS );
                }
            }
            declaration_allowed = FALSE;
            continue;
        case T_DO:
            NewLoop();
            NextToken();
            if( CurToken == T_RIGHT_BRACE ) {
                CErr1( ERR_STMT_REQUIRED_AFTER_DO );
                break;
            }
            declaration_allowed = FALSE;
            continue;
        case T_FOR:
            ForStmt();
            declaration_allowed = FALSE;
            continue;
        case T_SWITCH:
            SwitchStmt();
            DeadCode = 1;
            declaration_allowed = FALSE;
            continue;
        case T_CASE:
            DeadCode = 0;
            CaseStmt();
            declaration_allowed = FALSE;
            continue;
        case T_DEFAULT:
            DefaultStmt();
            declaration_allowed = FALSE;
            continue;
        case T_BREAK:
            BreakStmt();
            DeadCode = 1;
            if( BlockStack->block_type != T_LEFT_BRACE ) break;
            continue;
        case T_CONTINUE:
            ContinueStmt();
            DeadCode = 1;
            if( BlockStack->block_type != T_LEFT_BRACE ) break;
            continue;
#ifdef __SEH__
        case T__LEAVE:
        case T___LEAVE:
            LeaveStmt();
            DeadCode = 1;
            if( BlockStack->block_type != T_LEFT_BRACE ) break;
            continue;
#endif
        case T_RETURN:
            ReturnStmt( func_result, &return_info );
            if( BlockStack->prev_block == NULL ) {      /* 28-feb-92 */
                return_at_outer_level = TRUE;
            }
            MustRecog( T_SEMI_COLON );
            if( SymLevel != 1  ||  CurToken != T_RIGHT_BRACE  ||
                    BlockStack->block_type != T_LEFT_BRACE ) {
                if( end_of_func_label == 0 ) {
                    end_of_func_label = NextLabel();
                }
                Jump( end_of_func_label );
            }
            if( BlockStack->block_type != T_LEFT_BRACE ) break;
            continue;
        case T_GOTO:
            GotoStmt();
            if( BlockStack->block_type != T_LEFT_BRACE ) break;
            continue;
        case T_SEMI_COLON:
            NextToken();
            if( BlockStack->block_type != T_LEFT_BRACE ) {
                if( CurToken == T_ELSE ) {
                    declaration_allowed = FALSE;
                }
                break;
            }
            continue;
        case T_LEFT_BRACE:
            LeftBrace();
            continue;
        case T_RIGHT_BRACE:
            if( BlockStack->block_type != T_LEFT_BRACE ) {
                CErr1( ERR_MISPLACED_RIGHT_BRACE );
            }
            if( BlockStack->prev_block == NULL ) {
                skip_to_next_token = TRUE;
            } else {
                NextToken();
            }
            break;
        case T_EXTERN:
        case T_STATIC:
        case T_AUTO:
        case T_REGISTER:
        case T_VOID:
        case T_CHAR:
        case T_SHORT:
        case T_INT:
        case T_LONG:
        case T_FLOAT:
        case T_DOUBLE:
        case T_SIGNED:
        case T_UNSIGNED:
            if( CompFlags.c99_extensions )
                CErr1( ERR_UNEXPECTED_DECLARATION );
            else
                CErr1( ERR_MISSING_RIGHT_BRACE );
            break;
        case T_EOF:
            CErr1( ERR_MISSING_RIGHT_BRACE );
            break;
#ifdef __SEH__
        case T__TRY:
        case T___TRY:
            TryStmt();
            continue;
#endif
        case T___ASM:
            AsmStmt();
            continue;
        default:
            if( DeadCode == 1 ) {
                DeadMsg();
            }
            StmtExpr();
            if( BlockStack->block_type != T_LEFT_BRACE ) break;
            continue;
        }
        EndOfStmt();
        if( BlockStack == NULL ) break;
        if( skip_to_next_token ) {
            NextToken();
        }
    }
    /* C99 has special semantics for return value of main() */
    if( CompFlags.c99_extensions && !strcmp( CurFunc->name, "main" ) ) {
        if( !return_at_outer_level ) {
            FixupC99MainReturn( func_result, &return_info );
            return_at_outer_level = TRUE;
        }
    }
    if( !return_info.with_expr ) {   /* no return values present */
        if( !DeadCode && !CurFunc->naked ) {
            ChkRetValue();
        }
    } else if( ! return_at_outer_level ) {              /* 28-feb-92 */
        if( ! DeadCode && !CurFunc->naked ) {
            CWarn( WARN_MISSING_RETURN_VALUE,
                   ERR_MISSING_RETURN_VALUE, CurFunc->name );
        }
    }
    if( end_of_func_label != 0 ) {
        DropLabel( end_of_func_label );
    }
    DeadCode = 0;
    tree->op.label_count = LabelIndex;
    tree = LeafNode( OPR_FUNCEND );
    if( !return_info.with_expr ) {
        tree->expr_type = NULL;
        tree->op.sym_handle = 0;
    } else {
        tree->op.sym_handle = func_result;
        SetFuncReturnNode( tree );
    }
    AddStmt( tree );
    AddSymList( CurFunc->u.func.locals );
    SrcLoc = TokenLoc;
    FreeLabels();
    if( skip_to_next_token ) {
        NextToken();
    }
    if( CompFlags.generate_prototypes ) {
        if( DefFile == NULL ) {
            OpenDefFile();
        }
        if( DefFile != NULL && CurFunc->stg_class == SC_NULL ) {
            /* function exported */
            DumpFuncDefn();
        }
    }

    if( Toggles & TOGGLE_INLINE ) {
        if( Inline_Threshold < NodeCount ) {
            CurFuncNode->op.func.flags &= ~FUNC_OK_TO_INLINE;
        }
    }
    if( VarParm( CurFunc ) ) {
        CurFuncNode->op.func.flags &= ~FUNC_OK_TO_INLINE;
    }
    NodeCount = 0;
    if( CompFlags.addr_of_auto_taken ) {                /* 23-oct-91 */
        CurFunc->flags &= ~ SYM_OK_TO_RECURSE;
    }
}
Exemplo n.º 8
0
static void CompareParms( TYPEPTR *master, TREEPTR parm, source_loc *src_loc )
{
    TYPEPTR     typ;
    TYPEPTR     typ2;
    int         parm_num;
    cmp_type    cmp;

    typ = *master++;
    if( typ != NULL ) {                     /* 27-feb-90 */
        if( typ->decl_type == TYPE_VOID ) { /* type func(void); */
            typ = NULL;                     /* indicate no parms */
        }
    }
    parm_num = 1;
    while( ( typ != NULL ) && ( parm != NULL ) ) {
        SKIP_TYPEDEFS( typ );
        // TODO is crap needed or has it been done
        if( typ->decl_type == TYPE_FUNCTION ) {
            typ = PtrNode( typ, FLAG_NONE, SEG_CODE );
        } else if( typ->decl_type == TYPE_ARRAY ) {
            typ = PtrNode( typ->object, FLAG_WAS_ARRAY, SEG_DATA );
        }
        typ2 = parm->expr_type;
        // typ2 will be NULL if parm is OPR_ERROR in which case an error
        // has already been generated
        if( typ2 != NULL ) {
            /* check compatibility of parms */
            SetErrLoc( src_loc );
            SetDiagType2 ( typ2, typ );
            cmp = CompatibleType( typ, typ2, TRUE, IsNullConst( parm ) );
            switch( cmp ) {
            case NO:
            case PT:
            case PX:
            case AC:
                CErr2( ERR_PARM_TYPE_MISMATCH, parm_num );
                break;
            case PQ:
                if( !CompFlags.no_check_qualifiers ) { // else f**k em
                    CWarn2( WARN_QUALIFIER_MISMATCH,
                        ERR_PARM_QUALIFIER_MISMATCH, parm_num );
                }
                break;
            case PM:                                    /* 16-may-91 */
                CWarn2( WARN_POINTER_TYPE_MISMATCH,
                        ERR_PARM_POINTER_TYPE_MISMATCH, parm_num );
                break;
            case PS:
                CWarn2( WARN_SIGN_MISMATCH,
                        ERR_PARM_SIGN_MISMATCH, parm_num );
                break;
            case PW:
                CWarn2( WARN_PARM_INCONSISTENT_INDIRECTION_LEVEL,
                        ERR_PARM_INCONSISTENT_INDIRECTION_LEVEL, parm_num );
                break;
            case PC:  /* Allow only "void *p = int 0";  */
                if( IsPointer( typ ) && parm->right->op.opr == OPR_PUSHINT ) {
                    if( TypeSize(typ) != TypeSize(typ2) ) {
                        CErr2( ERR_PARM_TYPE_MISMATCH, parm_num );
                    } else if( parm->right->op.ulong_value != 0 ) {
                        CWarn1( WARN_NONPORTABLE_PTR_CONV,
                                ERR_NONPORTABLE_PTR_CONV );
                    }
                } else {
                    if( TypeSize(typ->object) == TypeSize(typ2->object) ) {
                        CWarn2( WARN_POINTER_TYPE_MISMATCH,
                             ERR_PARM_POINTER_TYPE_MISMATCH, parm_num );
                    } else {
                        CErr2( ERR_PARM_TYPE_MISMATCH, parm_num );
                    }
                }
                break;
            case OK:
                break;
            }
            SetDiagPop();
            InitErrLoc();
        }
        typ = *master++;
        if( typ != NULL && typ->decl_type == TYPE_DOT_DOT_DOT )
            return;
        parm = parm->left;
        ++parm_num;
    }
    if( typ != NULL || parm != NULL ) {     /* should both be NULL now */
        SetErrLoc( src_loc );
#if _CPU == 386
        /* can allow wrong number of parms with -3s option; 06-dec-91 */
        if( !CompFlags.register_conventions ) {
            CWarn1( WARN_PARM_COUNT_MISMATCH, ERR_PARM_COUNT_WARNING );
            return;
        }
#endif
        CErr1( ERR_PARM_COUNT_MISMATCH );           /* 18-feb-90 */
    }
}