outfort.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 539 行 · 第 1/2 页
C
539 行
/****************************************************************************
*
* 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: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
* DESCRIBE IT HERE!
*
****************************************************************************/
#include "wic.h"
#include "output.h"
#include "outfort.h"
#define UNARY_OP_LABEL {2, {"0L"}, NULL}
#define BINARY_OP_LABEL {3, {"L0R"}, NULL}
static char *_fortStrADDR_OF_VALUE[] = { "LOC(", ")" };
static char *_fortStrAND_AND[] = { "(", ".NE.0)", "(", ".NE.0)" };
static char *_fortStrLSHIFT[] = { "ISHL(", ",", ")" };
static char *_fortStrRSHIFT[] = { "ISHL(", ", -", ")" };
static char *_fortStrOR_OR[] = { "(", ".NE.0)", "(", ".NE.0)" };
static char *_fortStrPERCENT[] = { "MOD(", ",", ")" };
static char *_fortStrSIZEOF_EXPR[] = { "(", ")" };
PrintCTreeTable printCTreeFortTable[LABCT_MAX] = {
/* ADDR_OF_VALUE */ {3, {"aLb"}, _fortStrADDR_OF_VALUE },
/* AND */ BINARY_OP_LABEL,
/* AND_AND */ {7, {"aLb0cRd"}, _fortStrAND_AND },
/* ARROW */ BINARY_OP_LABEL,
/* CALL */ {4, {"L0R1"}, NULL},
/* CAST_EXPR */ {1, {"R"}, NULL},
/* COLON */ BINARY_OP_LABEL,
/* DEFINED */ {4, {"0123"}, NULL},
/* DIVIDE */ BINARY_OP_LABEL,
/* DOT */ BINARY_OP_LABEL,
/* EQ */ BINARY_OP_LABEL,
/* EXCLAMATION */ UNARY_OP_LABEL,
/* EXPR_LIST */ BINARY_OP_LABEL,
/* EXPR_SEPARATOR */ BINARY_OP_LABEL,
/* GE */ BINARY_OP_LABEL,
/* GT */ BINARY_OP_LABEL,
/* INDEX */ {4, {"L0R1"}, NULL},
/* LE */ BINARY_OP_LABEL,
/* LSHIFT */ {5, {"aLbRc"}, _fortStrLSHIFT},
/* LT */ BINARY_OP_LABEL,
/* MINUS */ BINARY_OP_LABEL,
/* NE */ BINARY_OP_LABEL,
/* OR */ BINARY_OP_LABEL,
/* OR_OR */ {7, {"aLb0cRd"}, _fortStrOR_OR },
/* PAREN_EXPR */ {3, {"0L1"}, NULL},
/* PERCENT */ {5, {"aLbRc"}, _fortStrPERCENT},
/* PLUS */ BINARY_OP_LABEL,
/* PRE_DEFINE_MACRO */ {4, {"0LRN"}, NULL},
/* PRE_ELIF */ {3, {"0LN"}, NULL},
/* PRE_ELSE */ {2, {"0N"}, NULL},
/* PRE_ENDIF */ {2, {"0N"}, NULL},
/* PRE_IF */ {3, {"0LN"}, NULL},
/* PRE_IFDEF */ {3, {"01N"}, NULL},
/* PRE_IFNDEF */ {3, {"01N"}, NULL},
/* PRE_INCLUDE */ {3, {"01N"}, NULL},
/* PRE_DIR_LIST*/ {3, {"0LN"}, NULL},
/* QUESTION */ BINARY_OP_LABEL,
/* RSHIFT */ {5, {"aLbRc"}, _fortStrRSHIFT},
/* SIZEOF_EXPR */ {4, {"0aLb"}, _fortStrSIZEOF_EXPR},
/* SIZEOF_TYPE */ {4, {"01L2"}, NULL},
/* STRINGS */ {2, {"LR"}, NULL},
/* TILDE */ UNARY_OP_LABEL,
/* TIMES */ BINARY_OP_LABEL,
/* UNARY_MINUS */ UNARY_OP_LABEL,
/* UNARY_PLUS */ UNARY_OP_LABEL,
/* VALUE_AT_ADDR */ UNARY_OP_LABEL,
/* XOR */ BINARY_OP_LABEL
};
#define int1Str "INTEGER*1"
#define int2Str "INTEGER*2"
#define int4Str "INTEGER"
#define int6Str "INTEGER*6"
#if 0
static void _expandPushTypeQualifier(int fileNum, pDeclInfo dinfo) {
if (dinfo->qualifier & STY_CONST) {
pushPrintStack( fileNum, OUNIT,
createOUnitText("CONST", dinfo->constPos) );
}
if (dinfo->qualifier & STY_VOLATILE) {
pushPrintStack( fileNum, OUNIT,
createOUnitText("VOLATILE", dinfo->volatilePos) );
}
}
#endif
#if 0
static void _expandPushTypeStorage(int fileNum, pDeclInfo dinfo) {
static char *printString[STG_MAX] = {
"", // Null is allowed
"TYPEDEF",
"REGISTER",
"AUTO",
"EXTERN",
"STATIC"
};
assert((dinfo->storage <= STG_MAX) && (dinfo->storage >= STG_NULL));
assert(dinfo->storage != STG_TYPEDEF);
if (dinfo->storage != STG_NULL) {
pushPrintStack( fileNum, OUNIT,
createOUnitText(printString[dinfo->storage], dinfo->prefixPos));
}
}
#endif
static DeclInfoType getSimpleIntType(pDeclInfo decl, int *size, char **s ) {
struct StringSize {
char *string;
int size;
};
static struct StringSize fortranSclType[SCL_MAX][SIZE_MAX] = {
/* SIZE_16 SIZE_32 SIZE_48*/
/*NULL*/ {"NULL", 0, "NULL", 0, "NULL", 0 },
/*CHAR*/ {int1Str, 1, int1Str, 1, int1Str, 1},
/*SCHAR*/ {int1Str, 1, int1Str, 1, int1Str, 1},
/*UCHAR*/ {int1Str, 1, int1Str, 1, int1Str, 1},
/*WCHAR*/ {int4Str, 4, int4Str, 4, int4Str, 4},
/*SSHORT*/ {int2Str, 2, int2Str, 2, int2Str, 2},
/*USHORT*/ {int2Str, 2, int2Str, 2, int2Str, 2},
/*SINT*/ {int2Str, 2, int4Str, 4, int4Str, 4},
/*UINT*/ {int2Str, 2, int4Str, 4, int4Str, 4},
/*SLONG*/ {int4Str, 4, int4Str, 4, int6Str, 6},
/*ULONG*/ {int4Str, 4, int4Str, 4, int6Str, 6},
/*FLOAT*/ {"REAL*4", 4, "REAL*4", 4, "REAL*4", 4 },
/*DOUBLE*/ {"REAL*8", 8, "REAL*8", 8, "REAL*8", 8 },
/*LDOUBLE*/ {"REAL*8", 8, "REAL*8", 8, "REAL*8", 8 },
/*VOID*/ {"VOID", 0, "VOID", 0, "VOID", 0 },
/*DOT_DOT_DOT*/ {"...", 0, "...", 0, "...", 0 }
};
static struct StringSize ptrStr[SIZE_MAX] =
{ int2Str, 2, int4Str, 4, int6Str, 6 };
pDclr dclr = decl->dclr;
DeclInfoType retVal = DIT_SCALAR;
if (isDclrPtr(dclr)) {
SizeType temp;
switch (dclr->ptr->memType) {
case MT_NULL: temp = g_opt.ptrSize; break;
case MT_NEAR: temp = g_opt.nearPtrSize; break;
case MT_FAR: temp = g_opt.farPtrSize; break;
case MT_FAR16: temp = g_opt.farPtrSize; break;
case MT_HUGE: temp = g_opt.hugePtrSize; break;
default: assert(0);
}
*s = ptrStr[temp].string;
*size = ptrStr[temp].size;
} else {
switch (decl->type) {
case DIT_SCALAR:
assert(decl->repr.scalar.scalar <= SCL_MAX);
assert(decl->repr.scalar.scalar >= SCL_NULL);
*s = fortranSclType[decl->repr.scalar.scalar][g_opt.intSize]
.string;
*size = fortranSclType[decl->repr.scalar.scalar][g_opt.intSize]
.size;
break;
case DIT_STRUCT_OR_UNION:
*size = 0;
*s = NULL;
retVal = DIT_STRUCT_OR_UNION;
break;
case DIT_ENUM:
*size = fortranSclType[SCL_SINT][g_opt.intSize].size;
*s = NULL;
retVal = DIT_ENUM;
break;
default:
assert(0);
}
}
return retVal;
}
static void _expandDeclPrefix(int fileNum, void *_decl) {
pDeclInfo decl = _decl;
pTokPos pos = getDeclPos(decl);
char *s;
int size;
switch (getSimpleIntType(decl, &size, &s )) {
case DIT_SCALAR:
pushPrintStack( fileNum, OUNIT, createOUnitText(s, pos));
break;
case DIT_STRUCT_OR_UNION:
pushPrintStack(fileNum, DECL_STRUCT_INFO, decl->repr.s);
break;
case DIT_ENUM:
pushPrintStack(fileNum, DCLR, decl->dclr);
pushPrintStack(fileNum, DECL_ENUM, decl->repr.e);
break;
default:
assert(0);
}
}
static pOUnit getMemModelOUnit(pDclr dclr) {
if (dclr->memType != MT_NULL) {
char *s;
switch (dclr->memType) {
case MT_NEAR: s = "NEAR"; break;
case MT_FAR: s = "FAR"; break;
case MT_FAR16: s = "FAR16"; break;
case MT_HUGE: s = "HUGE"; break;
default: assert(0);
}
return createOUnitText(s, dclr->memPos);
} else {
return NULL;
}
}
static void _expandPushPragmaDeclInfo(int fileNum, void *_decl) {
pDeclInfo decl = _decl;
pTokPos pos = getDeclPos(decl);
int size;
char *s;
fileNum = fileNum; // Dummy param
getSimpleIntType(decl, &size, &s );
switch (size) {
case 0:
if (decl->type == DIT_SCALAR) {
if (decl->repr.scalar.scalar == SCL_DOT_DOT_DOT) {
return;
}
} else {
s = "VALUE"; // If it is a structure or union
}
break;
case 1: s = "VALUE*1"; break;
case 2: s = "VALUE*2"; break;
case 4: s = "VALUE*4"; break;
case 6: s = "VALUE*6"; break; // This is not supported
case 8: s = "VALUE*8"; break;
default: assert(0); s = NULL;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?