cdecl1.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 573 行 · 第 1/2 页
C
573 行
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: Parse functions, prototypes, handle argument promotion.
*
****************************************************************************/
#include "cvars.h"
#include "cgswitch.h"
#include "langenv.h"
extern struct parm_list *NewParm( TYPEPTR, struct parm_list * );
extern TREEPTR CurFuncNode;
TYPEPTR *MakeParmList( struct parm_list *, int, int );
local void ParmDeclList( void );
local void AddParms( void );
local void ChkParms( void );
local void FuncDefn( SYMPTR );
local void BeginFunc( void );
local void ReverseParms( void ); /* reverse order of parms */
void ParsePgm( void )
{
SYM_HANDLE dummysym;
CompFlags.external_defn_found = 0;
CompFlags.initializing_data = 0;
dummysym = 0;
GlobalSym = 0;
do {
if( DeclList( &dummysym ) ) { /* if this is a function defn */
FuncDefn( CurFunc );
SrcLineNum = CurFunc->d.defn_line; /* 17-aug-88 */
SrcFno = CurFunc->defn_file_index;
GenFunctionNode( CurFuncHandle );
SymLevel = 1;
ParmDeclList();
SymLevel = 0;
if( CurToken == T_LEFT_BRACE ) {
BeginFunc();
Statement();
CMemFree( CurFunc->name );
CurFunc->name = NULL;
SymReplace( CurFunc, CurFuncHandle );
CurFunc = NULL;
CurFuncNode = NULL;
CurFuncHandle = 0;
} else {
MustRecog( T_LEFT_BRACE );
}
}
} while( CurToken != T_EOF );
if( CompFlags.external_defn_found == 0 ) {
if( !CompFlags.extensions_enabled ) { /* 20-mar-90 */
CErr1( ERR_NO_EXTERNAL_DEFNS_FOUND );
}
}
}
local void FuncDefn( SYMPTR sym )
{
SYM_NAMEPTR sym_name;
int sym_len;
TYPEPTR typ;
/* duplicate name in near space */
sym_name = SymName( sym, CurFuncHandle );
sym_len = far_strlen_plus1( sym_name );
sym->name = CMemAlloc( sym_len );
far_memcpy( sym->name, sym_name, sym_len );
if( sym->flags & SYM_DEFINED ) {
CErr2p( ERR_SYM_ALREADY_DEFINED, sym->name ); /* 03-aug-88 */
}
typ = sym->sym_type->object; /* get return type */
SKIP_TYPEDEFS( typ );
if( typ->decl_type != TYPE_VOID ) { /* 26-mar-91 */
if( TypeSize( typ ) == 0 ) {
CErr( ERR_INCOMPLETE_TYPE, sym_name );
}
}
sym->flags |= /*SYM_REFERENCED | 18-jan-89 */ SYM_DEFINED;
if( !(GenSwitches & NO_OPTIMIZATION) ) {
sym->flags |= SYM_OK_TO_RECURSE; /* 25-sep-91 */
}
if( sym->stg_class == SC_EXTERN || sym->stg_class == SC_FORWARD ) {
sym->stg_class = SC_NULL; /* indicate exported function */
}
CompFlags.external_defn_found = 1;
if( Toggles & TOGGLE_CHECK_STACK )
sym->flags |= SYM_CHECK_STACK;
if( !CompFlags.zu_switch_used ) {
if( (sym->attrib & FLAG_INTERRUPT) == FLAG_INTERRUPT ) {
/* interrupt function */
TargetSwitches |= FLOATING_SS; /* force -zu switch on */
} else {
TargetSwitches &= ~FLOATING_SS; /* turn it back off */
}
}
if( strcmp( CurFunc->name, "main" ) == 0 || strcmp( CurFunc->name, "wmain" ) == 0 ) {
sym->attrib &= ~FLAG_LANGUAGES; // Turn off any language flags
sym->attrib |= LANG_WATCALL; // Turn on __watcall calling convention for main
}
SymReplace( sym, CurFuncHandle );
}
enum main_names {
MAIN_WMAIN,
MAIN_MAIN,
MAIN_WWINMAIN,
MAIN_WINMAIN,
MAIN_WLIBMAIN,
MAIN_LIBMAIN,
MAIN_WDLLMAIN,
MAIN_DLLMAIN,
MAIN_NUM,
};
static char const *MainNames[MAIN_NUM] = {
"wmain", // MAIN_WMAIN,
"main", // MAIN_MAIN,
"wWinMain", // MAIN_WWINMAIN,
"WinMain", // MAIN_WINMAIN,
"wLibMain", // MAIN_WLIBMAIN,
"LibMain", // MAIN_LIBMAIN,
"wDllMain", // MAIN_WDLLMAIN,
"DllMain", // MAIN_DLLMAIN,
};
local void BeginFunc( void )
{
char *name;
char *segname;
enum main_names main_entry;
if( CurFunc->seginfo == NULL ) { /* 18-nov-92 */
CurFunc->seginfo = DefCodeSegment; /* 22-oct-92 */
if( CurFunc->seginfo == NULL ) { /* 08-dec-92 */
if( CompFlags.zm_switch_used ) {
name = ""; /* 05-feb-93 */
if( TargetSwitches & BIG_CODE )
name = CurFunc->name;
segname = TS_SEG_CODE; /* "_TEXT" */
if( TextSegName[0] != '\0' ) {
segname = TextSegName;
}
CurFunc->seginfo = NewTextSeg( name, segname, "" );
}
}
}
name = CurFunc->name;
for( main_entry = MAIN_WMAIN; main_entry < MAIN_NUM; ++main_entry ) {
if( strcmp( name, MainNames[main_entry] ) == 0 ) {
break;
}
}
switch( main_entry ) {
case MAIN_WMAIN:
CompFlags.has_wchar_entry =1;
// fall through!
case MAIN_MAIN:
if( CurFunc->u.func.parms ) { /* 07-dec-88 */
CompFlags.main_has_parms = 1;
} else {
CompFlags.main_has_parms = 0;
}
CompFlags.has_main = 1;
break;
case MAIN_WWINMAIN:
CompFlags.has_wchar_entry =1;
// fall through!
case MAIN_WINMAIN:
if( TargSys == TS_WINDOWS || TargSys == TS_CHEAP_WINDOWS
|| TargSys == TS_NT )
{
CompFlags.has_winmain = 1;
} else {
CompFlags.has_wchar_entry =0;
}
break;
case MAIN_WLIBMAIN:
case MAIN_WDLLMAIN:
CompFlags.has_wchar_entry =1;
// fall through!
case MAIN_LIBMAIN:
case MAIN_DLLMAIN:
CompFlags.has_libmain = 1;
break;
case MAIN_NUM:
break;
}
}
static void ArgPromotion( SYMPTR sym )
{
TYPEPTR typ;
TYPEPTR arg_typ;
AdjParmType( sym );
arg_typ = sym->sym_type;
/* perform default argument promotions */
typ = arg_typ;
SKIP_TYPEDEFS( typ );
switch( typ->decl_type ) {
#if 0
case TYPE_CHAR:
case TYPE_UCHAR:
case TYPE_SHORT:
#endif
case TYPE_ENUM:
arg_typ = GetType( TYPE_INT );
break;
#if 0
case TYPE_USHORT:
arg_typ = GetType( TYPE_UINT );
break;
case TYPE_FLOAT:
arg_typ = GetType( TYPE_DOUBLE );
break;
#endif
default:
break;
}
}
local void ParmDeclList( void ) /* process old style function definitions */
{
TYPEPTR typ;
PARMPTR parm;
decl_state state;
SYM_ENTRY sym;
decl_info info;
while( CurToken != T_LEFT_BRACE ) {
FullDeclSpecifier( &info );
if( info.stg == SC_NULL && info.typ == NULL ) {
if( CurToken == T_ID ) {
CErr2p( ERR_MISSING_DATA_TYPE, Buffer );
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?