[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Dotgnu-pnet-commits] CVS: pnet/cscc/java java_cast.tc,NONE,1.1 java_co
From: |
Gopal.V <address@hidden> |
Subject: |
[Dotgnu-pnet-commits] CVS: pnet/cscc/java java_cast.tc,NONE,1.1 java_const.tc,NONE,1.1 java_decls.tc,NONE,1.1 java_defs.tc,NONE,1.1 java_gather.c,NONE,1.1 java_grammar.y,NONE,1.1 java_internal.h,NONE,1.1 java_invoke.tc,NONE,1.1 java_lookup.c,NONE,1.1 java_lvalue.tc,NONE,1.1 java_misc.tc,NONE,1.1 java_modifiers.c,NONE,1.1 java_oper.tc,NONE,1.1 java_rename.h,NONE,1.1 java_scanner.l,NONE,1.1 java_semantics.tc,NONE,1.1 java_semvalue.c,NONE,1.1 java_semvalue.h,NONE,1.1 java_stmt.tc,NONE,1.1 java_types.tc,NONE,1.1 Makefile.am,NONE,1.1 |
Date: |
Sat, 17 May 2003 03:04:37 -0400 |
Update of /cvsroot/dotgnu-pnet/pnet/cscc/java
In directory subversions:/tmp/cvs-serv702/cscc/java
Added Files:
java_cast.tc java_const.tc java_decls.tc java_defs.tc
java_gather.c java_grammar.y java_internal.h java_invoke.tc
java_lookup.c java_lvalue.tc java_misc.tc java_modifiers.c
java_oper.tc java_rename.h java_scanner.l java_semantics.tc
java_semvalue.c java_semvalue.h java_stmt.tc java_types.tc
Makefile.am
Log Message:
Initial checkin of the java compiler
--- NEW FILE ---
/*
* java_cast.tc - Cast and other type cast operators
*
* Copyright (C) 2001 Southern Storm Software, Pty Ltd.
* Copyright (C) 2003 Gopal.V
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* Perform semantic analysis for a user-level cast operator.
*/
ILNode_JSemAnalysis(ILNode_UserCast)
{
JavaSemValue type;
JavaSemValue value;
/* ILEvalValue evalValue;*/
/* Perform semantic analysis on the type and value expressions */
type = ILNode_JSemAnalysis(node->expr1, info, &(node->expr1));
value = ILNode_JSemAnalysis(node->expr2, info, &(node->expr2));
/* Validate the value */
if(!JavaSemIsValue(value))
{
CCErrorOnLine(yygetfilename(node->expr2),
yygetlinenum(node->expr2),
"invalid value supplied to cast");
if(JavaSemIsType(type))
{
JavaSemSetRValue(value, JavaSemGetType(type));
}
else
{
JavaSemSetRValue(value, ILType_Int32);
}
}
/* Validate the type */
if(!JavaSemIsType(type))
{
CCErrorOnLine(yygetfilename(node->expr1),
yygetlinenum(node->expr1),
"invalid type supplied to cast");
JavaSemSetType(type, JavaSemGetType(value));
}
/* Determine if we can cast between the types */
if(!ILCast(info, node->expr2, &(node->expr2),
JavaSemGetType(value), JavaSemGetType(type),69))
{
CCErrorOnLine(yygetfilename(node), yygetlinenum(node),
"cannot cast from `%s' to `%s'",
JavaTypeToName(JavaSemGetType(value)),
JavaTypeToName(JavaSemGetType(type)));
}
else
{
/* Replace this node with the converted node */
*parent = node->expr2;
}
/* Return an rvalue of the final type to the caller */
/*
if(ILNode_EvalConst(*parent, info, &evalValue))
{
JavaSemSetConstant(value, JavaSemGetType(type), evalValue);
JavaSemReplaceWithConstant(parent, value);
}
else
{*/
JavaSemSetRValue(value, JavaSemGetType(type));
// }
return value;
}
--- NEW FILE ---
/*
* java_const.tc - Constants and their semantic analysis
*
* Copyright (C) 2001 Southern Storm Software, Pty Ltd.
* Copyright (C) 2003 Gopal.V
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* Perform semantic analysis for the "null" constant.
*/
ILNode_JSemAnalysis(ILNode_Null)
{
JavaSemValue value;
ILEvalValue evalValue;
evalValue.valueType = ILMachineType_ObjectRef;
evalValue.un.oValue = 0;
JavaSemSetConstant(value, ILType_Null, evalValue);
return value;
}
/*
* Perform semantic analysis for the "true" constant.
*/
ILNode_JSemAnalysis(ILNode_True)
{
JavaSemValue value;
ILEvalValue evalValue;
evalValue.valueType = ILMachineType_Boolean;
evalValue.un.i4Value = 1;
JavaSemSetConstant(value, ILType_Boolean, evalValue);
return value;
}
/*
* Perform semantic analysis for the "false" constant.
*/
ILNode_JSemAnalysis(ILNode_False)
{
JavaSemValue value;
ILEvalValue evalValue;
evalValue.valueType = ILMachineType_Boolean;
evalValue.un.i4Value = 0;
JavaSemSetConstant(value, ILType_Boolean, evalValue);
return value;
}
ILNode_JSemAnalysis(ILNode_UInt8)
{
JavaSemValue value;
ILEvalValue evalValue;
evalValue.valueType = ILMachineType_UInt8;
evalValue.un.i4Value = (ILInt32)(node->value);
JavaSemSetConstant(value, ILType_UInt8, evalValue);
return value;
}
ILNode_JSemAnalysis(ILNode_Int16)
{
JavaSemValue value;
ILEvalValue evalValue;
evalValue.valueType = ILMachineType_Int16;
if(node->isneg)
{
evalValue.un.i4Value = -((ILInt32)(node->value));
}
else
{
evalValue.un.i4Value = (ILInt32)(node->value);
}
JavaSemSetConstant(value, ILType_Int16, evalValue);
return value;
}
ILNode_JSemAnalysis(ILNode_Char)
{
JavaSemValue value;
ILEvalValue evalValue;
evalValue.valueType = ILMachineType_Char;
evalValue.un.i4Value = (ILInt32)(node->value);
JavaSemSetConstant(value, ILType_Char, evalValue);
return value;
}
ILNode_JSemAnalysis(ILNode_Int32)
{
JavaSemValue value;
ILEvalValue evalValue;
evalValue.valueType = ILMachineType_Int32;
if(node->isneg)
{
evalValue.un.i4Value = -((ILInt32)(node->value));
}
else
{
evalValue.un.i4Value = (ILInt32)(node->value);
}
JavaSemSetConstant(value, ILType_Int32, evalValue);
return value;
}
ILNode_JSemAnalysis(ILNode_Int)
{
JavaSemValue value;
ILEvalValue evalValue;
ILNode_EvalConst(node, info, &evalValue);
if(evalValue.valueType == ILMachineType_Int64)
{
JavaSemSetConstant(value, ILType_Int64, evalValue);
}
else
{
JavaSemSetConstant(value, ILType_Int, evalValue);
}
return value;
}
ILNode_JSemAnalysis(ILNode_Int64)
{
JavaSemValue value;
ILEvalValue evalValue;
evalValue.valueType = ILMachineType_Int64;
if(node->isneg)
{
evalValue.un.i8Value = -((ILInt64)(node->value));
}
else
{
evalValue.un.i8Value = (ILInt64)(node->value);
}
JavaSemSetConstant(value, ILType_Int64, evalValue);
return value;
}
/*
* Perform semantic analysis for floating point constants.
*/
ILNode_JSemAnalysis(ILNode_Float32)
{
JavaSemValue value;
ILEvalValue evalValue;
evalValue.valueType = ILMachineType_Float32;
evalValue.un.r4Value = (ILFloat)(node->value);
JavaSemSetConstant(value, ILType_Float32, evalValue);
return value;
}
ILNode_JSemAnalysis(ILNode_Float64)
{
JavaSemValue value;
ILEvalValue evalValue;
evalValue.valueType = ILMachineType_Float64;
evalValue.un.r8Value = node->value;
JavaSemSetConstant(value, ILType_Float64, evalValue);
return value;
}
ILNode_JSemAnalysis(ILNode_Float)
{
JavaSemValue value;
ILEvalValue evalValue;
evalValue.valueType = ILMachineType_NativeFloat;
evalValue.un.r8Value = node->value;
JavaSemSetConstant(value, ILType_Float, evalValue);
return value;
}
/*
* Perform semantic analysis for string constants.
*/
ILNode_JSemAnalysis(ILNode_String)
{
JavaSemValue value;
ILEvalValue evalValue;
evalValue.valueType = ILMachineType_String;
evalValue.un.strValue.str = node->str;
evalValue.un.strValue.len = node->len;
JavaSemSetConstant(value, ILFindSystemType(info, "String"), evalValue);
return value;
}
--- NEW FILE ---
/*
* java_decl.tc - Class, Method, and Field declarations
*
* Copyright (C) 2001 Southern Storm Software, Pty Ltd.
* Copyright (C) 2003 Gopal.V
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
%{
/*
* Error reporting function for "ILGenImplementsAllInterfaces".
*/
static void InterfaceErrorFunc(ILNode *node, ILClass *classInfo,
ILMember
*missingMember)
{
CCErrorOnLine(yygetfilename(node), yygetlinenum(node),
_("`%s' does not implement `%s'"),
JavaTypeToName(ILClassToType(classInfo)),
JavaItemToName((ILProgramItem
*)missingMember));
}
/*
* Proxy reporting function for "ILGenImplementsAllInterfaces".
*/
static void InterfaceProxyFunc(ILNode *node, ILClass *classInfo,
ILMethod
*missingMember,
ILMethod
*proxyReplacement)
{
CCErrorOnLine(yygetfilename(node), yygetlinenum(node),
_("`%s' does not implement `%s'"),
JavaTypeToName(ILClassToType(classInfo)),
JavaItemToName((ILProgramItem
*)missingMember));
}
/* Since we can't (shouldn't?) inherit list from multiple types, this
* operation will iterate over a list of declarations adding to the
* compound constructor */
static void JavaListGatherStaticCtor(ILNode_List *node, ILNode_List *ctor)
{
ILNode_ListIter iter;
ILNode_Declaration *curr;
if (yyisa(node, ILNode_List) || node == 0)
{
/* Iterate through the body gathering up the necessary
constructors */
ILNode_ListIter_Init(&iter, node);
while ((curr = (ILNode_Declaration
*)ILNode_ListIter_Next(&iter)))
{
ILNode_Declaration_GatherStaticCtor(curr, ctor);
}
}
}
/*
* append entries in the oldList to the collectedList to order
* the user specified static ctors after the ones from field decl
*/
static void AppendStaticCtor(ILNode_List *collectedList,
ILNode_List *oldList)
{
ILNode_ListIter iter;
ILNode *curr;
if(!oldList)return;
if (yyisa(oldList, ILNode_List))
{
ILNode_ListIter_Init(&iter,oldList);
while((curr = ILNode_ListIter_Next(&iter)))
{
ILNode_List_Add(collectedList,curr);
}
}
}
%}
%operation void ILNode_Declaration_GatherStaticCtor
([ILNode_Declaration *node], ILNode_List *ctor) = {0};
/*
* Perform semantic analysis for class definitions.
*/
ILNode_JSemAnalysis(ILNode_ClassDefn)
{
JavaSemValue value;
ILNode *savedClass;
ILNode *savedNamespace;
ILNode *savedMethod;
ILNode *staticCtorList=NULL;
int hadStaticCtorsBefore;
/* Determine if we have already visited this node */
if(node->visited == ILVisitMode_Processing)
{
CCErrorOnLine(yygetfilename(node), yygetlinenum(node),
"circularity detected in class
definition");
return JavaSemValueDefault;
}
else if(node->visited == ILVisitMode_Done)
{
return JavaSemValueDefault;
}
node->visited = ILVisitMode_Processing;
/* Perform semantic analysis on the node */
hadStaticCtorsBefore = (node->staticCtors != 0);
if(node->body)
{
savedClass = info->currentClass;
savedNamespace = info->currentNamespace;
savedMethod = info->currentMethod;
info->currentClass = (ILNode *)node;
info->currentNamespace = node->namespaceNode;
info->currentMethod = NULL;
value = ILNode_JSemAnalysis(node->body, info, &(node->body));
if(node->initCtorsMethod)
{
/* Perform semantic analysis on the non-static
initializers */
ILNode_JSemAnalysis(node->initCtorsMethod, info,
&(node->initCtorsMethod));
}
/* save the explicit static constructors before gathering */
if (node->staticCtors)
{
staticCtorList=node->staticCtors;
}
node->staticCtors=ILNode_List_create();
ILNode_Declaration_GatherStaticCtor
(
(ILNode_Declaration *)node->body,
(ILNode_List *)node->staticCtors);
/* append the explicit static constructors to the end of the
gathered list */
AppendStaticCtor((ILNode_List*)node->staticCtors,
(ILNode_List*)
staticCtorList);
staticCtorList=NULL; /* do not use it again or segfault :-) */
if (ILNode_List_Length(node->staticCtors) == 0)
{
/* There were no static constructors after all */
node->staticCtors = 0;
}
else
{
/* Create a method for the static constructors and
then perform semantic analysis on its contents */
ILMethod *methodInfo;
ILType *signature;
node->staticCtorsMethod =
ILNode_MethodDeclaration_create
(0, IL_META_METHODDEF_PRIVATE |
IL_META_METHODDEF_STATIC |
IL_META_METHODDEF_HIDE_BY_SIG |
IL_META_METHODDEF_SPECIAL_NAME |
IL_META_METHODDEF_RT_SPECIAL_NAME,
0 /* void */,
ILQualIdentSimple(ILInternString(".cctor", 6).string),
0 /* no parameters */,
ILNode_NewScope_create(node->staticCtors));
methodInfo = ILMethodCreate(node->classInfo, 0,
".cctor",
IL_META_METHODDEF_PRIVATE |
IL_META_METHODDEF_STATIC |
IL_META_METHODDEF_HIDE_BY_SIG |
IL_META_METHODDEF_SPECIAL_NAME |
IL_META_METHODDEF_RT_SPECIAL_NAME);
if(!methodInfo)
{
CCOutOfMemory();
}
signature = ILTypeCreateMethod(info->context,
ILType_Void);
if(!signature)
{
CCOutOfMemory();
}
ILMemberSetSignature((ILMember *)methodInfo, signature);
((ILNode_MethodDeclaration *)(node->staticCtorsMethod))
->methodInfo = methodInfo;
ILNode_JSemAnalysis(node->staticCtorsMethod, info,
&(node->staticCtorsMethod));
}
info->currentClass = savedClass;
info->currentNamespace = savedNamespace;
info->currentMethod = savedMethod;
}
else
{
JavaSemSetRValue(value, ILType_Int32);
}
if(node->classInfo && !ILClass_IsInterface(node->classInfo))
{
/* Check that the class implements all of its interfaces */
ILGenImplementsAllInterfaces(info, (ILNode *)node,
node->classInfo,
InterfaceErrorFunc,InterfaceProxyFunc);
}
if(!hadStaticCtorsBefore && node->staticCtors)
{
/* The class contains static initializers for fields, but no
explicit static constructor. Add the "beforefieldinit"
flag to the set of modifiers */
node->modifiers |= IL_META_TYPEDEF_BEFORE_FIELD_INIT;
if(node->classInfo)
{
ILClassSetAttrs(node->classInfo,
IL_META_TYPEDEF_BEFORE_FIELD_INIT,
IL_META_TYPEDEF_BEFORE_FIELD_INIT);
}
}
/* We have finished processing this node */
node->visited = ILVisitMode_Done;
return JavaSemValueDefault;
}
ILNode_JSemAnalysis(ILNode_MethodDeclaration)
{
ILNode *savedMethod;
ILNode_NewScope *newScope;
ILScope *scope;
ILScope *savedScope;
unsigned long argNum;
unsigned long argIndex;
ILNode_ListIter iter;
ILNode_FormalParameter *param;
ILScopeData *data;
char *name;
ILNode *errorNode;
ILType *returnType;
/* Determine if we have already visited this node */
if(node->visited == ILVisitMode_Processing)
{
CCErrorOnLine(yygetfilename(node), yygetlinenum(node),
"circularity detected in method
definition");
return JavaSemValueDefault;
}
else if(node->visited == ILVisitMode_Done)
{
return JavaSemValueDefault;
}
node->visited = ILVisitMode_Processing;
/* Record the current method that we are in */
savedMethod = info->currentMethod;
info->currentMethod = (ILNode *)node;
/* Get the method's local variable scope */
if(node->body && yykind(node->body) == yykindof(ILNode_NewScope))
{
newScope = (ILNode_NewScope *)(node->body);
if(!(newScope->scope))
{
newScope->scope = ILScopeCreate(info,
info->currentScope);
}
scope = newScope->scope;
}
else
{
scope = ILScopeCreate(info, info->currentScope);
}
/* Declare the parameters into the method's local variable scope */
if((node->modifiers & IL_META_METHODDEF_STATIC) == 0)
{
/* Non-static parameters start at argument 1 */
argNum = 1;
}
else
{
/* Static parameters start at argument 0 */
argNum = 0;
}
argIndex = 1;
ILNode_ListIter_Init(&iter, node->params);
while((param = (ILNode_FormalParameter *)ILNode_ListIter_Next(&iter))
!= 0)
{
name = ILQualIdentName(param->name, 0);
data = ILScopeLookup(scope, name, 0);
if(data)
{
CCErrorOnLine(yygetfilename(param->name),
yygetlinenum(param->name),
"`%s' is already declared in
this scope", name);
errorNode = ILScopeDataGetNode(data);
if(errorNode)
{
CCErrorOnLine(yygetfilename(errorNode),
yygetlinenum(errorNode),
"previous declaration
here");
}
}
else
{
ILScopeDeclareLocal(scope, name, argNum |
JAVA_LOCAL_IS_ARG,
param->name);
}
++argNum;
++argIndex;
}
/* Perform semantic analysis on the method body */
if(node->body)
{
if((node->modifiers & IL_META_METHODDEF_ABSTRACT) != 0)
{
CCErrorOnLine(yygetfilename(node), yygetlinenum(node),
"`abstract' cannot be used
with a method body");
}
savedScope = info->currentScope;
info->currentScope = scope;
ILNode_JSemAnalysis(node->body, info, &(node->body));
info->currentScope = savedScope;
}
else if((node->modifiers & IL_META_METHODDEF_ABSTRACT) == 0)
{
CCErrorOnLine(yygetfilename(node), yygetlinenum(node),
"method with no body requires `abstract'");
}
/* If the return type is not void, then make sure that the
method ends in some kind of return statement */
returnType = ILTypeGetReturn(ILMethod_Signature(node->methodInfo));
if(returnType != ILType_Void && node->body)
{
if(!ILMethod_IsAbstract(node->methodInfo) &&
ILMethod_IsIL(node->methodInfo))
{
if(!ILNodeEndsInFlowChange(node->body,info))
{
CCErrorOnLine(yygetfilename(node),
yygetlinenum(node),
"control reaches end
of non-void method");
}
}
}
/* Return to the previous method level */
info->currentMethod = savedMethod;
/* Finished visiting this node */
node->visited = ILVisitMode_Done;
/* Methods don't really have a semantic value, so return the default */
return JavaSemValueDefault;
}
/*
* Perform semantic analysis for declaration scope changes.
*/
ILNode_JSemAnalysis(ILNode_ScopeChange)
{
JavaSemValue value;
if (node->body)
{
ILScope *oldscope = info->currentScope;
info->currentScope = node->scope;
value = ILNode_JSemAnalysis(node->body, info, &(node->body));
info->currentScope = oldscope;
}
else
{
JavaSemSetRValue(value, ILType_Int32);
}
return value;
}
ILNode_Declaration_GatherStaticCtor(ILNode_ClassDefn),
ILNode_Declaration_GatherStaticCtor(ILNode_ScopeChange)
{
if (node->body)
{
JavaListGatherStaticCtor((ILNode_List *)node->body, ctor);
}
}
%{
/*
* Attach a constant value to a field.
*/
static void AddConstantValue(ILGenInfo *info, ILField *field,
ILEvalValue *evalValue)
{
unsigned char constBuf[18];
int constBufLen;
int constElemType;
ILConstant *constant;
int posn, wlen;
unsigned char *newStr;
unsigned char *tempStr;
/* Bail out if the field wasn't created properly */
if(!field)
{
return;
}
switch(evalValue->valueType)
{
case ILMachineType_Boolean:
{
constBuf[0] = (unsigned char)(evalValue->un.i4Value);
constBufLen = 1;
constElemType = IL_META_ELEMTYPE_BOOLEAN;
}
break;
case ILMachineType_Int8:
case ILMachineType_UInt8:
{
constBuf[0] = (unsigned char)(evalValue->un.i4Value);
constBufLen = 1;
constElemType = IL_META_ELEMTYPE_I1;
}
break;
case ILMachineType_Int16:
case ILMachineType_UInt16:
{
constBuf[0] = (unsigned char)(evalValue->un.i4Value);
constBuf[1] =
(unsigned char)(evalValue->un.i4Value >> 8);
constBufLen = 2;
constElemType = IL_META_ELEMTYPE_I2;
}
break;
case ILMachineType_Char:
{
constBuf[0] = (unsigned char)(evalValue->un.i4Value);
constBuf[1] =
(unsigned char)(evalValue->un.i4Value >> 8);
constBufLen = 2;
constElemType = IL_META_ELEMTYPE_CHAR;
}
break;
case ILMachineType_Int32:
case ILMachineType_UInt32:
case ILMachineType_NativeInt:
case ILMachineType_NativeUInt:
{
constBuf[0] = (unsigned char)(evalValue->un.i4Value);
constBuf[1] =
(unsigned char)(evalValue->un.i4Value >> 8);
constBuf[2] =
(unsigned char)(evalValue->un.i4Value >> 16);
constBuf[3] =
(unsigned char)(evalValue->un.i4Value >> 24);
constBufLen = 4;
constElemType = IL_META_ELEMTYPE_I4;
}
break;
case ILMachineType_Int64:
case ILMachineType_UInt64:
{
constBuf[0] = (unsigned char)(evalValue->un.i8Value);
constBuf[1] =
(unsigned char)(evalValue->un.i8Value >> 8);
constBuf[2] =
(unsigned char)(evalValue->un.i8Value >> 16);
constBuf[3] =
(unsigned char)(evalValue->un.i8Value >> 24);
constBuf[4] =
(unsigned char)(evalValue->un.i8Value >> 32);
constBuf[5] =
(unsigned char)(evalValue->un.i8Value >> 40);
constBuf[6] =
(unsigned char)(evalValue->un.i8Value >> 48);
constBuf[7] =
(unsigned char)(evalValue->un.i8Value >> 56);
constBufLen = 8;
constElemType = IL_META_ELEMTYPE_I8;
}
break;
case ILMachineType_Float32:
{
IL_WRITE_FLOAT(constBuf, evalValue->un.r4Value);
constBufLen = 4;
constElemType = IL_META_ELEMTYPE_R4;
}
break;
case ILMachineType_Float64:
case ILMachineType_NativeFloat:
{
IL_WRITE_DOUBLE(constBuf, evalValue->un.r8Value);
constBufLen = 8;
constElemType = IL_META_ELEMTYPE_R8;
}
break;
case ILMachineType_String:
{
/* Detect "null" string constants specially */
if(!(evalValue->un.strValue.str))
{
constBuf[0] = 0;
constBuf[1] = 0;
constBuf[2] = 0;
constBuf[3] = 0;
constBufLen = 4;
constElemType = IL_META_ELEMTYPE_CLASS;
break;
}
/* Determine the length of string in UTF-16 characters
*/
posn = 0;
wlen = 0;
while(posn < evalValue->un.strValue.len)
{
wlen += ILUTF16WriteChar
(0,
ILUTF8ReadChar(evalValue->un.strValue.str,
evalValue->un.strValue.len, &posn));
}
/* Allocate temporary storage for the UTF-16 version */
newStr = (unsigned char *)ILMalloc(wlen * 2 + 1);
if(!newStr)
{
CCOutOfMemory();
}
/* Convert the string from UTF-8 into UTF-16 */
posn = 0;
tempStr = newStr;
while(posn < evalValue->un.strValue.len)
{
tempStr += ILUTF16WriteCharAsBytes
(tempStr, ILUTF8ReadChar
(evalValue->un.strValue.str,
evalValue->un.strValue.len,
&posn));
}
/* Attach the constant to the field */
constant = ILConstantCreate(info->image, 0,
(ILProgramItem *)field,
IL_META_ELEMTYPE_STRING);
if(!constant)
{
CCOutOfMemory();
}
if(!ILConstantSetValue(constant, newStr, wlen * 2))
{
CCOutOfMemory();
}
ILFree(newStr);
return;
}
break;
case ILMachineType_ObjectRef:
{
/* This is the "null" constant */
constBuf[0] = 0;
constBuf[1] = 0;
constBuf[2] = 0;
constBuf[3] = 0;
constBufLen = 4;
constElemType = IL_META_ELEMTYPE_CLASS;
}
break;
default:
{
constBuf[0] = 0;
constBufLen = 1;
constElemType = IL_META_ELEMTYPE_I1;
}
break;
}
constant = ILConstantCreate(info->image, 0, (ILProgramItem *)field,
constElemType);
if(!constant)
{
CCOutOfMemory();
}
if(!ILConstantSetValue(constant, constBuf, constBufLen))
{
CCOutOfMemory();
}
}
void JavaAddInitCtor(ILGenInfo *info, ILNode *stmt)
{
ILNode_ClassDefn *defn = (ILNode_ClassDefn *)(info->currentClass);
ILNode *bodyList;
if(defn && stmt)
{
/* Construct the method declaration for ".init" if necessary.
Note: the ".init" method is a pseudo method to collect up
all non-static field initializers. It isn't output into
the final program. Instead, its body is expanded inline
into each constructor that requires field initialization */
if(!(defn->initCtorsMethod))
{
ILMethod *methodInfo;
ILType *signature;
bodyList = ILNode_Compound_create();
defn->initCtorsMethod =
ILNode_MethodDeclaration_create
(0, IL_META_METHODDEF_PRIVATE |
IL_META_METHODDEF_HIDE_BY_SIG,
0 /* void */,
ILQualIdentSimple(ILInternString(".init", 5).string),
0 /* no parameters */,
ILNode_NewScope_create(bodyList));
methodInfo = ILMethodCreate(defn->classInfo, 0, ".init",
IL_META_METHODDEF_PRIVATE |
IL_META_METHODDEF_HIDE_BY_SIG);
if(!methodInfo)
{
CCOutOfMemory();
}
ILMethodSetCallConv(methodInfo,
IL_META_CALLCONV_HASTHIS);
signature = ILTypeCreateMethod(info->context,
ILType_Void);
if(!signature)
{
CCOutOfMemory();
}
ILTypeSetCallConv(signature, IL_META_CALLCONV_HASTHIS);
ILMemberSetSignature((ILMember *)methodInfo, signature);
((ILNode_MethodDeclaration *)(defn->initCtorsMethod))
->methodInfo = methodInfo;
}
else
{
bodyList = ((ILNode_MethodDeclaration
*)(defn->initCtorsMethod))
->body;
bodyList = ((ILNode_NewScope *)bodyList)->stmt;
}
/* Wrap the statement in a scope and add it to the body */
ILNode_List_Add(bodyList, ILNode_NewScope_create(stmt));
}
}
%}
/*
* Perform semantic analysis for field declaration.
*/
ILNode_JSemAnalysis(ILNode_FieldDeclaration)
{
ILNode_ListIter iterator;
ILNode *decl;
/* Verify the initializers */
ILNode_ListIter_Init(&iterator, node->fieldDeclarators);
while((decl = ILNode_ListIter_Next(&iterator)) != 0)
{
ILNode_JSemAnalysis(decl, info, &decl);
}
/* Fields don't really have a semantic value, so return the default */
return JavaSemValueDefault;
}
ILNode_Declaration_GatherStaticCtor(ILNode_FieldDeclaration)
{
if (node->fieldDeclarators)
{
return JavaListGatherStaticCtor
((ILNode_List
*)node->fieldDeclarators, ctor);
}
}
ILNode_JSemAnalysis(ILNode_FieldDeclarator)
{
JavaSemValue value;
ILEvalValue evalValue;
ILNode *savedMethod;
ILNode *initializer;
savedMethod=info->currentMethod;
/* Determine if we have already visited this node */
if(node->visited == ILVisitMode_Processing)
{
CCErrorOnLine(yygetfilename(node), yygetlinenum(node),
"circularity detected in field
definition");
return JavaSemValueDefault;
}
else if(node->visited == ILVisitMode_Done)
{
return JavaSemValueDefault;
}
node->visited = ILVisitMode_Processing;
/* Skip the field if no initializer or ILField block */
if(!(node->initializer) || !(node->fieldInfo))
{
goto done;
}
info->currentMethod=NULL;
/* Non-static fields are initialized differently */
if(node->owner && (node->owner->modifiers & IL_META_FIELDDEF_STATIC) ==
0)
{
initializer = ILNode_Assign_create(node->name,
node->initializer);
yysetfilename(initializer,yygetfilename(node));
yysetlinenum(initializer,yygetlinenum(node));
JavaAddInitCtor(info, initializer);
goto done;
}
/* If this is a constant, then evaluate the value */
if(node->owner && (node->owner->modifiers & IL_META_FIELDDEF_LITERAL)
!= 0)
{
/* Perform semantic analysis on the initializer value */
value = ILNode_JSemAnalysis(node->initializer, info,
&(node->initializer));
if(!JavaSemIsValue(value))
{
CCErrorOnLine(yygetfilename(node->initializer),
yygetlinenum(node->initializer),
"initializer is not a value");
goto done;
}
/* Make sure that the value is compatible with the field's type
*/
if(!ILCoerce(info, node->initializer, &(node->initializer),
JavaSemGetType(value),
ILField_Type(node->fieldInfo),1))
{
CCErrorOnLine(yygetfilename(node->initializer),
yygetlinenum(node->initializer),
"incompatible types in
initialization: "
"no conversion
from `%s' to `%s'",
JavaTypeToName(JavaSemGetType(value)),
JavaTypeToName(ILField_Type(node->fieldInfo)));
goto done;
}
/* Check that the literal value is actually constant */
if(!ILNode_EvalConst(node->initializer, info, &evalValue) ||
!ILGenCastConst(info, &evalValue, evalValue.valueType,
ILTypeToMachineType(ILField_Type(node->fieldInfo))))
{
CCErrorOnLine(yygetfilename(node->initializer),
yygetlinenum(node->initializer),
"initializer is not
constant");
goto done;
}
/* Record the constant value so the compiler can pick
it up when the binary form of the code is reloaded */
AddConstantValue(info, node->fieldInfo, &evalValue);
goto done;
}
/* Add a statement to the static constructor to initialize the field */
/* JavaAddStaticCtor(info,
ILNode_Assign_create(node->name, node->initializer));
*/
initializer=ILNode_Assign_create(node->name, node->initializer);
yysetfilename(initializer,yygetfilename(node));
yysetlinenum(initializer,yygetlinenum(node));
node->staticCtor = ILNode_NewScope_create(initializer);
done:
/* Mark the node as done and return */
info->currentMethod=savedMethod;
node->visited = ILVisitMode_Done;
return JavaSemValueDefault;
}
ILNode_Declaration_GatherStaticCtor(ILNode_FieldDeclarator)
{
ILNode_List_Add(ctor, node->staticCtor);
}
ILNode_Declaration_GatherStaticCtor(ILNode_EventDeclaration),
ILNode_Declaration_GatherStaticCtor(ILNode_EventDeclarator),
ILNode_Declaration_GatherStaticCtor(ILNode_MethodDeclaration),
ILNode_Declaration_GatherStaticCtor(ILNode_PropertyDeclaration),
ILNode_Declaration_GatherStaticCtor(ILNode_EnumMemberDeclaration),
ILNode_Declaration_GatherStaticCtor(ILNode_DelegateMemberDeclaration),
ILNode_Declaration_GatherStaticCtor(ILNode_FormalParameter),
ILNode_Declaration_GatherStaticCtor(ILNode_AttributeTree),
ILNode_Declaration_GatherStaticCtor(ILNode_AttributeSection),
ILNode_Declaration_GatherStaticCtor(ILNode_Attribute),
ILNode_Declaration_GatherStaticCtor(ILNode_AttrArgs),
ILNode_Declaration_GatherStaticCtor(ILNode_NamedArg),
ILNode_Declaration_GatherStaticCtor(ILNode_ProxyDeclaration)
{
return;
}
--- NEW FILE ---
/*
* java_defs.tc - Semantic analysis routines and new nodes for Java
*
* Copyright (C) 2001 Southern Storm Software, Pty Ltd.
* Copyright (C) 2003 Gopal.V
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
%include %readonly "../../codegen/cg_all.tc"
/*
* Set a new header for definitions that follow.
*/
%header "java_defs.h"
/*
* Copy includes to the top of the "cs_defs.h" file.
*/
%decls %{
#include "../codegen/cg_nodes.h"
#include "../codegen/cg_coerce.h"
#include "../codegen/cg_resolve.h"
#include "../codegen/cg_scope.h"
#include "il_utils.h"
#include "java_semvalue.h"
%}
%output "java_nodes.c"
%node ILNode_JPrimitiveType ILNode_Dummy =
{
ILUInt32 elementType;
}
%node ILNode_JArrayType ILNode_Dummy =
{
ILNode *type;
ILUInt32 numDimensions;
}
%node ILNode_JPackage ILNode_Dummy =
{
char *name;
%nocreate ILNode *import={0};
}
%node ILNode_JImport ILNode_Dummy =
{
char *name;
%nocreate ILNode *next={0};
}
%node ILNode_JImportType ILNode_JImport
%node ILNode_JImportPackage ILNode_JImport
%node ILNode_JSystemType ILNode_Dummy =
{
char *className;
}
%node ILNode_ILSystemType ILNode_Dummy =
{
char *className;
}
%node ILNode_JMain ILNode_Statement =
{
ILMethod *method;
}
%node ILNode_JTypeSuffix ILNode_Dummy =
{
ILUInt32 count; /* 0 for '*', 1 + for dimension separators */
}
%node ILNode_UserCast ILNode_DummyBinaryExpr
%node ILNode_InstanceOf ILNode_DummyBinaryExpr
%node ILNode_JNewExpression ILNode_NewExpression
%node ILNode_TypeSuffixDeclarator ILNode_Dummy =
{
ILNode *name;
int dims;
}
%{
#include "java_internal.h"
%}
%include "java_semantics.tc"
%include "java_lvalue.tc"
%include "java_types.tc"
%include "java_const.tc"
%include "java_stmt.tc"
%include "java_decls.tc"
%include "java_invoke.tc"
%include "java_misc.tc"
%include "java_oper.tc"
%include "java_cast.tc"
--- NEW FILE ---
/*
* java_gather.c - Type gathering operations for Java
*
* Copyright (C) 2001 Southern Storm Software, Pty Ltd.
* Copyright (C) 2003 Gopal.V
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
[...1169 lines suppressed...]
base types are listed before types that inherit them */
tree = (ILNode *)list;
list = (ILNode_List *)ILNode_List_create();
systemObject = ILNode_JSystemType_create("Object");
ILNode_ListIter_Init(&iterator, tree);
while((child = ILNode_ListIter_Next(&iterator)) != 0)
{
CreateType(info, globalScope, list, systemObject, child);
}
/* Create the class members within each type */
ILNode_ListIter_Init(&iterator, list);
while((child = ILNode_ListIter_Next(&iterator)) != 0)
{
CreateMembers(info, globalScope, child);
}
return (ILNode*) list;
}
--- NEW FILE ---
%{
/*
* java_grammar.y - Input file for Yacc that defines Java syntax
*
* Copyright (C) 2001 Southern Storm Software, Pty Ltd.
* Copyright (C) 2003 Gopal.V
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
[...1877 lines suppressed...]
for(i=0;i<$4;i++)
{
ILNode_List_Add(list,ILNode_JTypeSuffix_create(1));
}
$$ = ILNode_JNewExpression_create($2,$3,list,NULL);
}
| NEW QualifiedIdentifier DimExprs {
$$ = ILNode_JNewExpression_create($2,$3,NULL,NULL);
}
| NEW QualifiedIdentifier Dims ArrayInitializer {
ILNode *list=ILNode_List_create();
int i;
for(i=0;i<$3;i++)
{
ILNode_List_Add(list,ILNode_JTypeSuffix_create(1));
}
$$ = ILNode_JNewExpression_create($2,NULL,list,$4);
}
;
%%
--- NEW FILE ---
/*
* java_internal.h - Internal definitions for the Java compiler.
*
* Copyright (C) 2003 Gopal.V
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _CSCC_JAVA_INTERNAL_H
#define _CSCC_JAVA_INTERNAL_H
#include <cscc/common/cc_main.h>
#include <cscc/java/java_defs.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
* Modifier mask bits.
*/
#define JAVA_MODIFIER_PUBLIC (1<<0)
#define JAVA_MODIFIER_PRIVATE (1<<1)
#define JAVA_MODIFIER_PROTECTED (1<<2)
#define JAVA_MODIFIER_ACCESS_MASK (JAVA_MODIFIER_PUBLIC | \
JAVA_MODIFIER_PRIVATE | \
JAVA_MODIFIER_PROTECTED)
#define JAVA_MODIFIER_FINAL (1<<4)
#define JAVA_MODIFIER_ABSTRACT (1<<5)
#define JAVA_MODIFIER_NATIVE (1<<6)
#define JAVA_MODIFIER_STATIC (1<<7)
#define JAVA_MODIFIER_SYNCHRONIZED (1<<8)
#define JAVA_MODIFIER_TRANSIENT (1<<9)
#define JAVA_MODIFIER_VOLATILE (1<<10)
#define JAVA_MODIFIER_STRICTFP (1<<11)
#define JAVA_SPECIALATTR_STATIC 0x08000000
#define JAVA_SPECIALATTR_STRICTFP 0x04000000
#define JAVA_SPECIALATTR_DEFAULTACCESS 0x02000000
#define JAVA_SPECIALATTR_FINAL 0x01000000
#define JAVA_SPECIALATTR_VOLATILE 0x00800000
/*
* Special attribute flags.
*/
/*
* Flag bit that is used to distinguish args from locals.
*/
#define JAVA_LOCAL_IS_ARG 0x80000000
/*
* Type values that are used to classify the size of numeric values.
*/
#define JAVA_NUMTYPE_INT32 0
#define JAVA_NUMTYPE_INT64 1
#define JAVA_NUMTYPE_FLOAT32 3
#define JAVA_NUMTYPE_FLOAT64 4
/*
* Gather information about all types in the program.
* Returns a new top-level list for the program with
* the classes re-organised so that parent classes and
* interfaces precede classes that inherit them.
*/
ILNode *JavaTypeGather(ILGenInfo *info, ILScope *globalScope, ILNode *tree);
int JavaIsBaseTypeFor(ILClass *info1, ILClass *info2);
int JavaSignatureIdentical(ILType *sig1, ILType *sig2);
JavaSemValue JavaResolveSimpleName(ILGenInfo *genInfo, ILNode *node,
const char *name, int literalType);
JavaSemValue JavaResolveNamespaceMemberName(ILGenInfo *genInfo, ILNode *node,
JavaSemValue value, const char *name);
JavaSemValue JavaResolveMemberName(ILGenInfo *genInfo, ILNode *node,
JavaSemValue value,
const char *name,
int literalType);
ILClass *JavaGetAccessScope(ILGenInfo *genInfo, int defIsModule);
JavaSemValue JavaResolveConstructor(ILGenInfo *genInfo, ILNode *node,
ILType
*objectType);
ILProgramItem *JavaGetGroupMember(void *group, unsigned long n);
void *JavaRemoveGroupMember(void *group, unsigned long n);
void JavaSetGroupMemberForm(void *group, unsigned long n, int form);
int JavaGetGroupMemberForm(void *group, unsigned long n);
ILUInt32 JavaModifiersToTypeAttrs(ILNode *node, ILUInt32 modifiers,
int isNested);
ILUInt32 JavaModifiersToConstructorAttrs(ILNode *node, ILUInt32 modifiers);
ILUInt32 JavaModifiersToMethodAttrs(ILNode *node, ILUInt32 modifiers);
ILUInt32 JavaModifiersToFieldAttrs(ILNode *node, ILUInt32 modifiers);
#ifdef __cplusplus
};
#endif
#endif /* _CSCC_JAVA_INTERNAL_H */
--- NEW FILE ---
/*
* java_invoke.tc - Semantic analysis for Java method invocations
*
* Copyright (C) 2001 Southern Storm Software, Pty Ltd.
* Copyright (C) 2003 Gopal.V
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
[...974 lines suppressed...]
JavaSemGetGroup(method), args, numArgs);
JavaEvalFreeArguments(args);
return value;
}
}
/* Import the method into this image, and set it within the node */
methodInfo = (ILMethod *)itemInfo;
methodInfo = (ILMethod *)ILMemberImport
(info->image, (ILMember
*)methodInfo);
node->methodInfo = methodInfo;
/* Coerce the arguments and build the final argument list */
JavaItemCoerceArgs(info, ILToProgramItem(methodInfo),
args, numArgs, &(node->argList));
JavaEvalFreeArguments(args);
/* Return the final semantic value */
return value;
}
--- NEW FILE ---
/*
* java_lookup.c - Lookup routines for the scope and member resolution
*
* Copyright (C) 2001 Southern Storm Software, Pty Ltd.
* Copyright (C) 2003 Gopal.V
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
[...1185 lines suppressed...]
int JavaGetGroupMemberForm(void *group, unsigned long n)
{
JavaMemberInfo *member = (JavaMemberInfo *)group;
while(member != 0)
{
if(n <= 0)
{
return member->form;
}
--n;
member = member->next;
}
return 0;
}
#ifdef __cplusplus
};
#endif
--- NEW FILE ---
/*
* java_lvalue.tc - Semantic analysis for Java Identifiers and other l-values
*
* Copyright (C) 2001 Southern Storm Software, Pty Ltd.
* Copyright (C) 2003 Gopal.V
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
%{
/*
* Check to see if we are permitted to use the "this" expression
* to access an instance member.
*/
static void CheckForInstanceAccess(ILGenInfo *info, ILNode *node)
{
ILNode_MethodDeclaration *caller;
caller = (ILNode_MethodDeclaration *)(info->currentMethod);
if(!caller || (caller->modifiers & IL_META_METHODDEF_STATIC) != 0)
{
CCErrorOnLine(yygetfilename(node), yygetlinenum(node),
"cannot access instance members in
static methods");
}
}
/*
* Convert a field into a literal constant node if possible.
* Returns NULL if not possible.
*/
static ILNode *FieldToConstant(ILGenInfo *info, ILNode *node, ILField *field)
{
ILConstant *constValue;
ILNode_ClassDefn *defn;
/* Make sure that semantic analysis has been performed on the item */
if(ILTypeIsEnum(ILClassToType(ILField_Owner(field))))
{
/* This is an enumerated type, so perform semantic analysis
on the type instead of the field, so that we create the
members with default values in the correct order */
defn = (ILNode_ClassDefn *)ILProgramItemToNode
(info, ILToProgramItem(ILField_Owner(field)));
if(defn != 0 && defn->visited == ILVisitMode_NotVisited)
{
JavaSemProgramItem(info,
ILToProgramItem(ILField_Owner(field)));
}
else
{
/* We may already be inside the enumerated type, so go
directly to the field to avoid circularity problems
*/
JavaSemProgramItem(info, ILToProgramItem(field));
}
}
else
{
/* Perform semantic analysis on the value directly */
JavaSemProgramItem(info, ILToProgramItem(field));
}
/* Get the constant value, if present */
if(ILField_IsLiteral(field))
{
if((constValue =
ILConstantGetFromOwner(ILToProgramItem(field))) != 0)
{
/* Convert the constant into an appropriate node */
ILType *baseType =
ILTypeGetEnumType(ILField_Type(field));
const unsigned char *value;
unsigned long valueLen;
value = ILConstantGetValue(constValue, &valueLen);
switch(ILConstantGetElemType(constValue))
{
case IL_META_ELEMTYPE_BOOLEAN:
{
/* Create a boolean constant */
if(value && valueLen > 0 && baseType ==
ILType_Boolean)
{
if(value[0])
{
return
ILNode_True_create();
}
else
{
return
ILNode_False_create();
}
}
}
break;
case IL_META_ELEMTYPE_I1:
case IL_META_ELEMTYPE_U1:
{
/* Create an 8-bit constant */
if(value && valueLen > 0)
{
if(baseType == ILType_Int8)
{
ILInt8 val =
(ILInt8)(value[0]);
if(val >= 0)
{
return
ILNode_Int8_create
((ILUInt64)(-((ILInt32)val)), 1, 0);
}
else
{
return
ILNode_Int8_create
((ILUInt64)val, 0, 0);
}
}
else if(baseType ==
ILType_UInt8)
{
return
ILNode_UInt8_create
((ILUInt64)(value[0]), 0, 0);
}
}
}
break;
case IL_META_ELEMTYPE_I2:
case IL_META_ELEMTYPE_U2:
{
/* Create a 16-bit constant */
if(value && valueLen > 1)
{
if(baseType == ILType_Int16)
{
ILInt16 val =
(ILInt16)(IL_READ_INT16(value));
if(val >= 0)
{
return
ILNode_Int16_create
((ILUInt64)(-((ILInt32)val)), 1, 0);
}
else
{
return
ILNode_Int16_create
((ILUInt64)val, 0, 0);
}
}
else if(baseType ==
ILType_UInt16)
{
return
ILNode_UInt16_create
((ILUInt64)(IL_READ_UINT16(value)), 0, 0);
}
}
}
break;
case IL_META_ELEMTYPE_CHAR:
{
/* Create a character constant */
if(value && valueLen > 1)
{
if(baseType == ILType_Char)
{
return
ILNode_Char_create
((ILUInt64)(IL_READ_UINT16(value)), 0, 0);
}
}
}
break;
case IL_META_ELEMTYPE_I4:
case IL_META_ELEMTYPE_U4:
{
/* Create a 32-bit constant */
if(value && valueLen > 3)
{
if(baseType == ILType_Int32)
{
ILInt32 val =
IL_READ_INT32(value);
if(val >= 0)
{
return
ILNode_Int32_create
((ILUInt64)(ILUInt32)(-val), 1, 0);
}
else
{
return
ILNode_Int32_create
((ILUInt64)val, 0, 0);
}
}
else if(baseType ==
ILType_UInt32)
{
return
ILNode_UInt32_create
((ILUInt64)(IL_READ_UINT32(value)), 0, 0);
}
}
}
break;
case IL_META_ELEMTYPE_I8:
case IL_META_ELEMTYPE_U8:
{
/* Create a 64-bit constant */
if(value && valueLen > 7)
{
if(baseType == ILType_Int64)
{
ILInt64 val =
IL_READ_INT64(value);
if(val < 0)
{
return
ILNode_Int64_create
((ILUInt64)(-val), 1, 0);
}
else
{
return
ILNode_Int64_create
((ILUInt64)val, 0, 0);
}
}
else if(baseType ==
ILType_UInt64)
{
return
ILNode_UInt64_create
(IL_READ_UINT64(value), 0, 0);
}
}
}
break;
case IL_META_ELEMTYPE_R4:
{
/* Create a 32-bit floating-point
constant */
if(value && valueLen > 3)
{
if(baseType == ILType_Float32)
{
return
ILNode_Float32_create
(IL_READ_FLOAT(value));
}
}
}
break;
case IL_META_ELEMTYPE_R8:
{
/* Create a 64-bit floating-point
constant */
if(value && valueLen > 7)
{
if(baseType == ILType_Float64)
{
return
ILNode_Float64_create
(IL_READ_DOUBLE(value));
}
}
}
break;
case IL_META_ELEMTYPE_STRING:
{
/* Create a string constant */
if(value &&
ILTypeIsStringClass(baseType))
{
int posn = 0;
int len = 0;
char *newStr;
ILIntString interned;
while(posn < (int)valueLen)
{
len += ILUTF8WriteChar
(0,
ILUTF16ReadCharAsBytes
((const char
*)value, (int)valueLen, &posn));
}
newStr = (char *)ILMalloc(len +
1);
if(!newStr)
{
CCOutOfMemory();
}
posn = 0;
len = 0;
while(posn < (int)valueLen)
{
len += ILUTF8WriteChar
(newStr + len,
ILUTF16ReadCharAsBytes
((const char
*)value, (int)valueLen, &posn));
}
interned =
ILInternString(newStr, len);
ILFree(newStr);
return
ILNode_String_create(interned.string,
interned.len);
}
}
break;
case IL_META_ELEMTYPE_CLASS:
{
/* Create a "null" constant */
if(value &&
((valueLen == 4 &&
IL_READ_UINT32(value) == 0) ||
(valueLen == 8 &&
IL_READ_UINT64(value) == 0)))
{
if(ILTypeAssignCompatible(info->image, 0, baseType))
{
return
ILNode_Null_create();
}
}
}
break;
}
/* If we get here, then the constant is not compatible
with the type of the field */
CCErrorOnLine(yygetfilename(node), yygetlinenum(node),
"literal field has an
incorrect constant value");
return 0;
}
else if(ILField_IsLiteral(field) &&
ILTypeIsStringClass(ILField_Type(field)))
{
/* Sometimes the empty string constant is stored as a
literal
field with no value associated with it */
return ILNode_String_create(ILInternString("",
0).string, 0);
}
else
{
/* This is a literal without an actual constant value */
CCErrorOnLine(yygetfilename(node), yygetlinenum(node),
"literal field does not have
a constant value");
return 0;
}
}
else if(ILField_IsInitOnly(field))
{
/* Check for "DecimalConstantAttribute" values, which are
attached to "readonly" fields of type "System.Decimal" */
ILType *decimalType = ILFindSystemType(info, "Decimal");
if(ILTypeIdentical(decimalType, ILField_Type(field)))
{
ILAttribute *attr = 0;
ILMethod *ctor;
const char *namespace;
const unsigned char *value;
unsigned long valueLen;
ILDecimal decValue;
while((attr =
ILProgramItemNextAttribute(ILToProgramItem(field),
attr)) != 0)
{
ctor =
ILProgramItemToMethod(ILAttributeTypeAsItem(attr));
if(ctor && !strcmp(ILMethod_Name(ctor),
".ctor") &&
!strcmp(ILClass_Name(ILMethod_Owner(ctor)),
"DecimalConstantAttribute"))
{
namespace =
ILClass_Namespace(ILMethod_Owner(ctor));
if(namespace &&
!strcmp(namespace,
"System.Runtime.CompilerServices"))
{
value = (const unsigned char *)
ILAttributeGetValue(attr, &valueLen);
if(value && valueLen == 18 &&
value[0] == 0x01 && value[1]
== 0x00 &&
value[2] < 29 && (value[3]
== 0x00 ||
value[3] == 0x80))
{
decValue.flags =
(((ILUInt32)(value[2])) << 16) |
(((ILUInt32)(value[3])) << 24);
decValue.high =
IL_READ_UINT32(value + 4);
decValue.middle =
IL_READ_UINT32(value + 8);
decValue.low =
IL_READ_UINT32(value + 12);
return
ILNode_Decimal_create(decValue);
}
}
}
}
}
/* Load the contents of the read-only field using regular
techniques */
return 0;
}
else
{
/* Regular static field */
return 0;
}
}
/*
* Get the type of the current class. NULL if not possible.
*/
static ILType *CurrentClassType(ILGenInfo *info)
{
if(info->currentClass)
{
ILClass *classInfo = ((ILNode_ClassDefn *)(info->currentClass))
->classInfo;
if(classInfo)
{
return ILClassToType(classInfo);
}
else
{
return 0;
}
}
else
{
return 0;
}
}
/*
* Check if the method is the psuedo method ".init" which is expanded
* into the constructor body inline.
*/
static int ILMethodIsPsuedoConstructor(ILMethod *method)
{
ILType *signature=ILMethod_Signature(method);
ILUInt32 attrs= (IL_META_METHODDEF_PRIVATE|
IL_META_METHODDEF_HIDE_BY_SIG);
return (!strcmp(ILMethod_Name(method),".init") &&
((ILMethod_Attrs(method) & attrs) !=0) &&
(ILTypeNumParams(signature)==0) &&
ILTypeIdentical(ILTypeGetReturn(signature),ILType_Void));
}
/*
* Convert a semantic value into an l-value or r-value if necessary.
*/
static JavaSemValue SemToLRValue(ILNode *node, ILGenInfo *info, ILNode **parent,
JavaSemValue value,
char *name, ILNode *expr,
JavaSemValue
*exprSem)
{
ILNode *constNode;
ILMethod *method;
ILField *field;
int allowConst;
ILType *thisType;
ILType *type;
switch(JavaSemGetKind(value))
{
case JAVA_SEMKIND_FIELD:
{
/* Reference to a class field */
field = JavaSemGetField(value);
if(!(info->currentMethod))
{
/* We are performing semantic analysis of
declarations,
where only literals and types are allowed */
if(!ILField_IsStatic(field) ||
!ILField_IsLiteral(field))
{
CCErrorOnLine(yygetfilename(node),
yygetlinenum(node),
"`%s' is not declared as a type in
the current scope",
name);
JavaSemSetType(value, ILType_Int32);
return value;
}
}
/* Create the final semantic type */
JavaSemSetLValue(value, ILField_Type(field));
/* Check the usage of "readonly" fields */
allowConst = 1;
if(ILField_IsInitOnly(field))
{
method = ((ILNode_MethodDeclaration
*)(info->currentMethod))
->methodInfo;
if(method && JavaGetAccessScope(info, 1) ==
ILField_Owner(field))
{
/* The field is being used inside the
class */
if(ILField_IsStatic(field) &&
ILMethodIsStaticConstructor(method))
{
/* Static readonly used within
static constructor */
allowConst = 0;
}
else if(!ILField_IsStatic(field) &&
(ILMethodIsConstructor(method)||
ILMethodIsPsuedoConstructor(method)))
{
/* Instance readonly used
within instance constructor.
or the ".init" psuedo
constructor
Nothing needs to be done
here */
}
else
{
/* The field is used elsewhere,
so make it an r-value */
JavaSemSetRValue(value,
ILField_Type(field));
}
}
else
{
/* The field is used elsewhere, so make
it an r-value */
JavaSemSetRValue(value,
ILField_Type(field));
}
}
/* Replace this identifier with a field access node */
if(ILField_IsStatic(field))
{
/* Convert the field into a constant node if
possible */
if(allowConst &&
(constNode = FieldToConstant(info, node,
field)) != 0)
{
ILEvalValue evalValue;
*parent = constNode;
ILNode_EvalConst(constNode, info,
&evalValue);
thisType =
ILClassToType(ILField_Owner(field));
type = ILField_Type(field);
if(ILTypeIsEnum(thisType) &&
ILTypeIdentical(type,
ILTypeGetEnumType(thisType)))
{
/* The enum definition
erroneously used the
underlying type for the
constant, instead
of using the enum type.
Work around it */
type = thisType;
}
JavaSemSetConstant(value, type,
evalValue);
}
else
{
*parent =
ILNode_StaticField_create(field);
}
}
else if(expr)
{
*parent = ILNode_MemberField_create
(ILNode_MarkType_create
(expr,
JavaSemGetType(*exprSem)), field);
}
else
{
CheckForInstanceAccess(info, node);
thisType = CurrentClassType(info);
if(thisType)
{
*parent = ILNode_MemberField_create
(ILNode_MarkType_create
(ILNode_This_create(), thisType), field);
}
else
{
*parent = ILNode_MemberField_create
(ILNode_This_create(),
field);
}
}
yysetfilename(*parent, yygetfilename(node));
yysetlinenum(*parent, yygetlinenum(node));
}
break;
case JAVA_SEMKIND_METHOD_GROUP:
{
/* Reference to a method group */
if(!(info->currentMethod))
{
/* We are performing semantic analysis of
declarations,
which does not permit methods to be used as
types */
CCErrorOnLine(yygetfilename(node),
yygetlinenum(node),
"`%s' is not declared as a type in
the current scope",
name);
JavaSemSetType(value, ILType_Int32);
return value;
}
/* Replace the node with either the object expression
or "this" */
if(expr)
{
*parent = ILNode_MarkType_create(expr,
JavaSemGetType(*exprSem));
}
else
{
thisType = CurrentClassType(info);
if(thisType)
{
*parent = ILNode_MarkType_create
(ILNode_This_create(),
thisType);
}
else
{
*parent = ILNode_This_create();
}
}
yysetfilename(*parent, yygetfilename(node));
yysetlinenum(*parent, yygetlinenum(node));
/* Copy the "base" indication to the method group */
if(exprSem && JavaSemIsSuper(*exprSem))
{
JavaSemSetSuper(value);
}
}
break;
}
// TODO
return value;
}
%}
/*
* Perform semantic analysis for singleton identifiers.
*/
ILNode_JSemAnalysis(ILNode_Identifier)
{
JavaSemValue value;
ILScopeData *data;
unsigned long index;
ILNode_MethodDeclaration *method;
ILType *type;
/* Look for local variables in the current scope */
data = ILScopeLookup(info->currentScope, node->name, 1);
if(data && ILScopeDataGetKind(data) == IL_SCOPE_LOCAL)
{
index = ILScopeDataGetIndex(data);
method = (ILNode_MethodDeclaration *)(info->currentMethod);
if((index & JAVA_LOCAL_IS_ARG) == 0)
{
/* Local variable reference */
type = ILTypeGetLocal(method->localVarSig, index);
JavaSemSetLValue(value, type);
*parent = ILNode_LocalVar_create(index,
ILTypeToMachineType(type));
yysetfilename(*parent, yygetfilename(node));
yysetlinenum(*parent, yygetlinenum(node));
}
else
{
/* Argument reference */
index &= ~JAVA_LOCAL_IS_ARG;
if((method->modifiers & IL_META_METHODDEF_STATIC) == 0)
{
ILGenGetParamInfo(method->methodInfo, 0,
index, &type);
}
else
{
ILGenGetParamInfo(method->methodInfo, 0,
index + 1, &type);
}
*parent = ILNode_ArgumentVar_create
(index,
ILTypeToMachineType(type));
JavaSemSetLValue(value, type);
}
return value;
}
#if TODO
else if(data && ILScopeDataGetKind(data) == IL_SCOPE_LOCAL_CONST)
{
method = (ILNode_MethodDeclaration *)(info->currentMethod);
constVar = (ILNode_JSemGuard *)(ILScopeDataGetData1(data));
*parent = constVar->expr;
JavaSemSetRValue(value, JavaSemGetType(constVar->value));
return value;
}
#endif
value = JavaResolveSimpleName(info, (ILNode *)node, node->name, 0);
/* Convert the result into an l-value or r-value and return it */
return SemToLRValue((ILNode *)node, info, parent,
value, node->name, 0,
0);
}
/*
* Perform semantic analysis for qualified identifiers.
*/
ILNode_JSemAnalysis(ILNode_QualIdent)
{
JavaSemValue value;
JavaSemValue value2;
char *name;
/* Get the semantic value for the left part of the identifier */
value = ILNode_JSemAnalysis(node->left, info, &(node->left));
/* Resolve the member */
name = ILQualIdentName(node->right, 0);
value2 = JavaResolveMemberName(info, (ILNode *)node, value, name, 0);
/* Convert the result into an l-value or r-value and return it */
return SemToLRValue((ILNode *)node, info, parent, value2,
name, node->left, &value);
}
/*
* Perform semantic analysis for member access operators.
*/
ILNode_JSemAnalysis(ILNode_MemberAccess)
{
JavaSemValue value;
JavaSemValue value2;
char *name;
ILEvalValue evalue;
/* Get the semantic value for the left part of the identifier */
value = ILNode_JSemAnalysis(node->expr1, info, &(node->expr1));
/* Set the rvalue if it is a constant expression */
if(yyisa(node->expr1,ILNode_Constant))
{
if(ILNode_EvalConst(node->expr1,info,&evalue))
{
/* Set the RValue to the type .. to handle Boxing later
on*/
if(JavaSemGetType(value)==ILType_Null)
{
JavaSemSetRValue(value,ILValueTypeToType(info,evalue.valueType));
}
else
{
JavaSemSetRValue(value,JavaSemGetType(value));
}
}
}
/* Convert the second subexpression into a name */
name = ILQualIdentName(node->expr2, 0);
/* Check for the special case of "array.Length" */
if(JavaSemIsValue(value) && !strcmp(name, "Length") &&
ILType_IsSimpleArray(JavaSemGetType(value)))
{
*parent = ILNode_ArrayLength_create(node->expr1);
yysetfilename(*parent, yygetfilename(node));
yysetlinenum(*parent, yygetlinenum(node));
*parent = ILNode_CastSimple_create(*parent,
ILMachineType_Int32);
JavaSemSetRValue(value, ILType_Int32);
return value;
}
else if(JavaSemIsValue(value) && !strcmp(name, "length") &&
ILType_IsSimpleArray(JavaSemGetType(value)))
{
*parent = ILNode_ArrayLength_create(node->expr1);
yysetfilename(*parent, yygetfilename(node));
yysetlinenum(*parent, yygetlinenum(node));
*parent = ILNode_CastSimple_create(*parent,
ILMachineType_Int32);
JavaSemSetRValue(value, ILType_Int32);
return value;
}
/* Resolve the member */
value2 = JavaResolveMemberName(info, (ILNode *)node, value, name, 0);
if (JavaSemGetKind(value2) != JAVA_SEMKIND_VOID)
{
/* Convert the result into an l-value or r-value and return it
*/
return SemToLRValue((ILNode *)node, info, parent, value2,
name, node->expr1, &value);
}
return JavaSemValueDefault;
}
/*
* Perform semantic analysis for the "new scope" statement.
*/
ILNode_JSemAnalysis(ILNode_NewScope)
{
ILScope *savedScope = info->currentScope;
if(!(node->scope))
{
node->scope = ILScopeCreate(info, savedScope);
}
info->currentScope = node->scope;
StmtSem(node->stmt, info, &(node->stmt));
info->currentScope = savedScope;
return JavaSemValueDefault;
}
%{
/*
* Wrap an array index expression in an overflow conversion to "int".
*/
static ILNode *ArrayIndexToInt(ILGenInfo *info, ILNode *node,
ILNode **parent,
ILType *currentType)
{
ILNode *result;
if(info->overflowInsns)
{
/* We are already in overflow mode, so just wrap it */
result = ILNode_CastSimple_create(node, ILMachineType_Int32);
}
else
{
/* The index is not being computed in overflow mode,
but we want an overflow conversion for the cast */
result = ILNode_Overflow_create
(ILNode_CastSimple_create
(ILNode_NoOverflow_create(node), ILMachineType_Int32));
}
*parent = result;
return result;
}
/*
* Coerce an array index to "int", "uint", "long", or "ulong".
*/
static void CoerceArrayIndex(ILGenInfo *info, ILNode **node,
ILNode **parent,
ILType *type)
{
if(ILCoerce(info, *node, parent, type, ILType_Int32, 1))
{
*node = ArrayIndexToInt
(info, *parent, parent, ILType_Int32);
}
else if(ILCoerce(info, *node, parent, type, ILType_UInt32, 1))
{
*node = ArrayIndexToInt
(info, *parent, parent, ILType_UInt32);
}
else if(ILCoerce(info, *node, parent, type, ILType_Int64, 1))
{
*node = ArrayIndexToInt
(info, *parent, parent, ILType_Int64);
}
else if(ILCoerce(info, *node, parent, type, ILType_UInt64, 1))
{
*node = ArrayIndexToInt
(info, *parent, parent, ILType_Int64);
}
else
{
CCErrorOnLine(yygetfilename(*node), yygetlinenum(*node),
"no conversion from `%s' to `int'",
JavaTypeToName(type));
}
}
static int GetArrayDepth(ILType *array)
{
int dims=0;
while(ILType_IsArray(array))
{
array=ILType_ElemType(array);
dims++;
}
return dims;
}
%}
/*
* Perform semantic analysis for an array access operation.
*/
ILNode_JSemAnalysis(ILNode_ArrayAccess)
{
JavaSemValue value;
JavaEvalArg *args;
int numArgs, argNum;
/* Perform semantic analysis on the array expression */
if(!JavaSemExpectValue(node->array, info, &(node->array), &value))
{
CCErrorOnLine(yygetfilename(node->array),
yygetlinenum(node->array),
"array expected");
JavaSemSetLValue(value, ILType_Int32);
return value;
}
/* Perform semantic analysis on the index argument list */
numArgs = JavaEvalArguments(info, node->indices, &(node->indices),
&args);
if(numArgs < 0)
{
JavaSemSetLValue(value, ILType_Int32);
return value;
}
/* Is this an array element or an indexer access? */
if(ILType_IsArray(JavaSemGetType(value)))
{
/* All arguments must be coercable to one of "int", "uint",
"long", or "ulong", and are converted to "int" */
for(argNum = 0; argNum < numArgs; ++argNum)
{
CoerceArrayIndex(info, &(args[argNum].node),
args[argNum].parent,
args[argNum].type);
}
/* Check the array's rank */
if(numArgs > GetArrayDepth(JavaSemGetType(value)))
{
CCErrorOnLine(yygetfilename(node->indices),
yygetlinenum(node->indices),
"incorrect number of indices
for `%s'",
JavaTypeToName(JavaSemGetType(value)));
}
/* Store the type information in the node for the code
generator */
node->arrayType = JavaSemGetType(value);
node->elemType = node->arrayType;
for(argNum=0 ; argNum<numArgs; argNum++)
{
node->elemType=ILType_ElemType(node->elemType);
}
/* Construct the semantic value for the element type */
JavaSemSetLValue(value, node->elemType);
}
else
{
/* Not an appropriate value for array or indexer access */
CCErrorOnLine(yygetfilename(node->array),
yygetlinenum(node->array),
"array expected");
JavaSemSetLValue(value, ILType_Int32);
}
/* Free the argument list and return the element type */
JavaEvalFreeArguments(args);
return value;
}
ILNode_JSemAnalysis(ILNode_This)
{
JavaSemValue value;
ILNode_MethodDeclaration *method;
ILType *type;
/* Find the method declaration */
method = (ILNode_MethodDeclaration *)(info->currentMethod);
/* If the method is static, then we cannot use "this" */
if((method->modifiers & IL_META_METHODDEF_STATIC) != 0)
{
CCErrorOnLine(yygetfilename(node), yygetlinenum(node),
"cannot use `this' in static
methods");
}
/* Get the type from the method's class and return */
type = ILClassToType(ILMethod_Owner(method->methodInfo));
if(ILTypeIsValue(type) && !(info->outputIsJava))
{
JavaSemSetLValue(value, type);
}
else
{
JavaSemSetRValue(value, type);
}
return value;
}
/*
* Perform semantic analysis for base member access operators.
*/
ILNode_JSemAnalysis(ILNode_BaseAccess)
{
JavaSemValue value;
JavaSemValue value2;
ILNode_MethodDeclaration *caller;
ILClass *classInfo;
ILNode *thisExpr;
char *name;
/* Bail out if "base" is used within a static method */
caller = (ILNode_MethodDeclaration *)(info->currentMethod);
if(!caller || (caller->modifiers & IL_META_METHODDEF_STATIC) != 0)
{
CCErrorOnLine(yygetfilename(node), yygetlinenum(node),
"cannot use base reference in a static method");
JavaSemSetType(value, ILType_Int32);
return value;
}
/* Find the parent class to start searching from */
classInfo = ILClass_Parent(ILMethod_Owner(caller->methodInfo));
if(!classInfo)
{
CCErrorOnLine(yygetfilename(node), yygetlinenum(node),
"cannot use base reference in `System.Object'");
JavaSemSetType(value, ILType_Int32);
return value;
}
/* Get the semantic value for the "base" part of the node */
JavaSemSetRValue(value, ILClassToType(classInfo));
JavaSemSetSuper(value);
/* Construct a dummy "this" expression to represent the object */
thisExpr = ILNode_This_create();
/* Resolve the member */
name = ILQualIdentName(node->expr, 0);
value2 = JavaResolveMemberName(info, (ILNode *)node, value, name, 0);
/* Convert the result into an l-value or r-value and return it */
return SemToLRValue((ILNode *)node, info, parent, value2,
name, thisExpr, &value);
}
--- NEW FILE ---
/*
* java_misc.tc - Miscellaneous nodes and their operations
*
* Copyright (C) 2001 Southern Storm Software, Pty Ltd.
* Copyright (C) 2003 Gopal.V
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
%decls %{
void GenArrayOfArray(ILGenInfo *info, ILType *arrayType,
ILNode *dims);
%}
ILNode_JSemAnalysis(ILNode_NewExpression)
{
JavaSemValue value;
ILNode_ListIter iter;
ILNode *child;
ILNode *expr;
ILNode **parentNode;
ILNode **parentOfExpr;
ILEvalValue evalValue;
int numDimensions = 0;
int dim,dimCount;
/* Determine if the array creation is normal or initializer-based */
if(node->indexes)
{
/* Build the full type node, by combining the element
type, indexed dimensions, and the rank specifiers */
if(yyisa(node->type, ILNode_JArrayType))
{
/* Cannot use array types in this context */
CCErrorOnLine(yygetfilename(node->type),
yygetlinenum(node->type),
"invalid array element type");
}
dimCount = CountArgList(node->indexes);
for(dim=0;dim<dimCount;dim++)
{
node->type = ILNode_JArrayType_create(node->type, 1);
}
ILNode_ListIter_Init(&iter, node->rank);
while((child = ILNode_ListIter_Next(&iter)) != 0)
{
node->type = ILNode_JArrayType_create
(node->type, ((ILNode_JTypeSuffix
*)child)->count);
}
/* Perform semantic analysis on the array type */
node->arrayType = JavaSemType(node->type, info, &(node->type));
/* Perform semantic analysis on the array dimensions */
child = node->indexes;
parentOfExpr = &(node->indexes);
while(yyisa(child, ILNode_ArgList))
{
++numDimensions;
expr = ((ILNode_ArgList *)child)->expr2;
parentNode = &(((ILNode_ArgList *)child)->expr2);
if(JavaSemExpectValue(expr, info, parentNode, &value))
{
if(!ILCoerce(info, *parentNode, parentNode,
JavaSemGetType(value),
ILType_Int32,1) &&
!ILCoerce(info, *parentNode, parentNode,
JavaSemGetType(value),
ILType_UInt32,1) &&
!ILCoerce(info, *parentNode, parentNode,
JavaSemGetType(value),
ILType_Int64,1) &&
!ILCoerce(info, *parentNode, parentNode,
JavaSemGetType(value),
ILType_UInt64,1))
{
CCErrorOnLine
(yygetfilename(expr),
yygetlinenum(expr),
"incompatible types in
dimension specifier: "
"no conversion from
`%s' to `int', `uint', "
"`long', or `ulong'",
JavaTypeToName(JavaSemGetType(value)));
}
}
else
{
CCErrorOnLine(yygetfilename(expr),
yygetlinenum(expr),
"invalid dimension in
array creation expression");
}
parentOfExpr = &(((ILNode_ArgList *)child)->expr1);
child = *parentOfExpr;
}
++numDimensions;
expr = child;
parentNode = parentOfExpr;
if(JavaSemExpectValue(expr, info, parentNode, &value))
{
if(!ILCoerce(info, *parentNode, parentNode,
JavaSemGetType(value),
ILType_Int32,1) &&
!ILCoerce(info, *parentNode, parentNode,
JavaSemGetType(value),
ILType_UInt32,1) &&
!ILCoerce(info, *parentNode, parentNode,
JavaSemGetType(value),
ILType_Int64,1) &&
!ILCoerce(info, *parentNode, parentNode,
JavaSemGetType(value),
ILType_UInt64,1))
{
CCErrorOnLine
(yygetfilename(expr),
yygetlinenum(expr),
"incompatible types in dimension
specifier: "
"no conversion from `%s' to
`int', `uint', "
"`long', or `ulong'",
JavaTypeToName(JavaSemGetType(value)));
}
}
else
{
CCErrorOnLine(yygetfilename(expr), yygetlinenum(expr),
"invalid dimension in array
creation expression");
}
}
else
{
/* Perform semantic analysis on the array type, which is
assumed to already have rank specifiers */
node->arrayType = JavaSemType(node->type, info, &(node->type));
/* Check that the supplied type is actually an array */
if(!ILType_IsArray(node->arrayType))
{
CCErrorOnLine(yygetfilename(node->type),
yygetlinenum(node->type),
"array initializer used with
non-array type");
JavaSemSetRValue(value, node->arrayType);
return value;
}
}
/* Handle array initializers */
if(node->arrayInitializer)
{
/*
* Since java supports untyped array initializers like
* int a[]={1,2}; The grammar with wrap the arrays in
* in an ILNode_ArrayInit by default.
*/
if(!yyisa(node->arrayInitializer,ILNode_ArrayInit))
{
/* Wrap the initializer in an "ILNode_ArrayInit" node */
node->arrayInitializer =
ILNode_ArrayInit_create(node->arrayInitializer);
}
/* Validate the initializer's shape against the actual type,
and then coerce all of the elements to their final types */
if(!ILArrayInitShapeOK(info, node->arrayInitializer,
node->arrayType))
{
CCErrorOnLine(yygetfilename(node), yygetlinenum(node),
"incorrect pattern of elements in array initializer");
}
else
{
CoerceArrayInit(info, node->arrayInitializer,
&(node->arrayInitializer),
ILTypeGetElemType(node->arrayType));
}
/* If we have indices, then they must be constant and match
the sizes of the initializer dimensions */
if(node->indexes)
{
dim = numDimensions;
child = node->indexes;
while(yyisa(child, ILNode_ArgList))
{
expr = ((ILNode_ArgList *)child)->expr2;
if(!ILNode_EvalConst(expr, info, &evalValue) ||
!ILGenCastConst(info, &evalValue,
evalValue.valueType,
ILMachineType_Int64) ||
evalValue.un.i8Value !=
(ILInt64)ILGetArrayInitLength
(((ILNode_ArrayInit
*)(node->arrayInitializer))
->expr,
dim - 1))
{
CCErrorOnLine(yygetfilename(expr),
yygetlinenum(expr),
"dimension %d does not match
initializer", dim);
}
child = (((ILNode_ArgList *)child)->expr1);
--dim;
}
expr = child;
if(!ILNode_EvalConst(expr, info, &evalValue) ||
!ILGenCastConst(info, &evalValue,
evalValue.valueType,
ILMachineType_Int64)
||
evalValue.un.i8Value !=
(ILInt64)ILGetArrayInitLength
(((ILNode_ArrayInit
*)(node->arrayInitializer))
->expr, dim -
1))
{
CCErrorOnLine(yygetfilename(expr),
yygetlinenum(expr),
"dimension %d does not match
initializer", dim);
}
}
/* Replace the current node with the initializer node */
*parent = node->arrayInitializer;
}
/* Done */
JavaSemSetRValue(value, node->arrayType);
return value;
}
ILNode_JSemAnalysis(ILNode_ArrayInit)
{
if(node->arrayType)
{
/* We've already visited this node, so return its type */
JavaSemValue value;
JavaSemSetRValue(value, node->arrayType);
return value;
}
else
{
/* We haven't visited this node, so it has been used in
an incorrect context. Initializers can be used on
fields and variables using regular assignment, or in
array creation expressions */
CCErrorOnLine(yygetfilename(node), yygetlinenum(node),
_("internal error in array
initializer"));
return JavaSemValueDefault;
}
}
/*
* Synthesised helper function to proxy main(java.lang.String[])
* with a Main(System.String[])
*/
ILNode_JSemAnalysis(ILNode_JMain)
{
/* Nothing to do here */
return JavaSemValueDefault;
}
ILNode_GenDiscard(ILNode_JMain)
{
unsigned arrayVar;
unsigned indexVar;
ILType *sig=ILMethod_Signature(node->method);
ILType * arrayType=ILTypeGetParam(sig,1);
ILType * elemType=ILTypeGetElemType(arrayType);
ILLabel label1 = ILLabel_Undefined;
ILLabel label2 = ILLabel_Undefined;
ILLabel label3 = ILLabel_Undefined;
ILLabel label4 = ILLabel_Undefined;
/* We need a temporary variable for the evaluated array */
arrayVar = ILGenTempTypedVar(info, arrayType);
/* We need a temporary variable for the array index */
indexVar = ILGenTempTypedVar(info, ILType_Int32);
ILGenSimple(info,IL_OP_LDARG_0); /* load args[] */
ILGenSimple(info,IL_OP_LDLEN); /* args.length */
ILGenSimple(info,IL_OP_CONV_I4); /* convert to I4 */
ILGenAdjust(info,2);
ILGenArrayNew(info,elemType); /* newargs = new String[..]; */
ILGenStoreLocal(info,arrayVar);
ILGenAdjust(info, -1);
ILGenSimple(info,IL_OP_LDC_I4_0);
ILGenStoreLocal(info,indexVar);
ILGenJump(info,IL_OP_BR,&label1);
ILGenLabel(info,&label2);
ILGenLoadLocal(info,arrayVar);
ILGenLoadLocal(info,indexVar);
ILGenAdjust(info,2);
ILGenSimple(info,IL_OP_LDARG_0);
ILGenLoadLocal(info,indexVar);
ILGenAdjust(info,2);
ILGenSimple(info,IL_OP_LDELEM_REF);
ILGenAdjust(info,-1);
ILGenCallByName(info,
"class ['java.lang']'java.lang'.'String' "
"['java.lang']'dotgnu.javawrappers'.'StringWrapper'::'op_Implicit'"
"(class [.library]'System'.'String')");
ILGenSimple(info,IL_OP_STELEM_REF);
ILGenAdjust(info,-1);
ILGenLabel(info,&label3);
ILGenLoadLocal(info,indexVar);
ILGenSimple(info,IL_OP_LDC_I4_1);
ILGenAdjust(info,2);
ILGenSimple(info,IL_OP_ADD);
ILGenAdjust(info,-1);
ILGenStoreLocal(info,indexVar);
ILGenAdjust(info,-1);
ILGenLabel(info,&label1);
ILGenLoadLocal(info,indexVar);
ILGenSimple(info,IL_OP_LDARG_0);
ILGenAdjust(info,2);
ILGenSimple(info,IL_OP_LDLEN);
ILGenSimple(info,IL_OP_CONV_I4); /* convert to I4 */
ILGenJump(info,IL_OP_BLT,&label2);
ILGenAdjust(info,-2);
ILGenLabel(info,&label4);
ILGenLoadLocal(info,arrayVar);
ILGenAdjust(info,1);
ILGenCallByMethod(info, node->method);
}
JavaGenDiscard(ILNode_JMain)
{
// why ?
}
%{
static ILType * GetUnderlyingElementType(ILType *arrayType)
{
if(ILType_IsArray(arrayType))
{
return GetUnderlyingElementType(ILType_ElemType(arrayType));
}
return arrayType;
}
void GenArrayOfArray(ILGenInfo *info, ILType *arrayType,
ILNode *dims)
{
ILNode *argArray= ILNode_ArgArray_create(ILType_UInt32,
CountArgList(dims),
dims);
ILGenTypeToken(info,IL_OP_LDTOKEN,arrayType);
ILGenAdjust(info,1);
/* Convert the type handle into a type object */
ILGenCallByName(info,
"class [.library]System.Type "
"[.library]System.Type::GetTypeFromHandle"
"(valuetype
[.library]System.RuntimeTypeHandle)");
ILNode_GenValue(argArray,info);
ILGenCallByName(info,
"class [.library]System.Array "
"['java.lang']dotgnu.javawrappers.ArrayWrapper::CreateMultiArray"
"(class [.library]System.Type type, unsigned int32[]
dims)");
ILGenAdjust(info,-1);
ILGenTypeToken(info, IL_OP_CASTCLASS , arrayType);
}
%}
ILNode_GenValue(ILNode_JNewExpression)
{
long saveStack;
/* Bail out if initializer-based (semantic analysis should
have turned this node into "ILNode_ArrayInit") */
if(!(node->indexes))
{
return ILMachineType_ObjectRef;
}
/* Output the indexes */
saveStack = info->stackHeight;
if(yyisa(node->indexes,ILNode_ArgList))
{
/* Create the array */
GenArrayOfArray(info,node->arrayType,node->indexes);
}
else
{
ILNode_GenValue(node->indexes,info);
ILGenArrayNew(info,ILType_ElemType(node->arrayType));
}
/* Set the final stack position */
info->stackHeight = saveStack + 1;
/* Arrays are always object references */
return ILMachineType_ObjectRef;
}
--- NEW FILE ---
/*
* java_modifiers.c - Various access modifiers and other flags
*
* Copyright (C) 2001 Southern Storm Software, Pty Ltd.
* Copyright (C) 2003 Gopal.V
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "java_internal.h"
/*
* Report errors for each modifier in a mask.
*/
static void ModifierError(char *filename, long linenum,
ILUInt32 modifiers, const
char *msg)
{
if((modifiers & JAVA_MODIFIER_PUBLIC) != 0)
{
CCErrorOnLine(filename, linenum, msg, "public");
}
if((modifiers & JAVA_MODIFIER_PRIVATE) != 0)
{
CCErrorOnLine(filename, linenum, msg, "private");
}
if((modifiers & JAVA_MODIFIER_PROTECTED) != 0)
{
CCErrorOnLine(filename, linenum, msg, "protected");
}
if((modifiers & JAVA_MODIFIER_ABSTRACT) != 0)
{
CCErrorOnLine(filename, linenum, msg, "abstract");
}
if((modifiers & JAVA_MODIFIER_STATIC) != 0)
{
CCErrorOnLine(filename, linenum, msg, "static");
}
if((modifiers & JAVA_MODIFIER_VOLATILE) != 0)
{
CCErrorOnLine(filename, linenum, msg, "volatile");
}
}
/*
* Report errors for modifiers that cannot be used in a particular context.
*/
static void BadModifiers(ILNode *node, ILUInt32 modifiers)
{
ModifierError(yygetfilename(node), yygetlinenum(node),
modifiers, "`%s' cannot be used in this
context");
}
/*
* Validate access modifiers and return the access level.
*/
static ILUInt32 ValidateAccess(ILNode *node, ILUInt32 modifiers)
{
if((modifiers & JAVA_MODIFIER_PUBLIC) != 0)
{
if((modifiers & JAVA_MODIFIER_PRIVATE) != 0)
{
CCErrorOnLine(yygetfilename(node), yygetlinenum(node),
"cannot use both `public' and
`private'");
}
if((modifiers & JAVA_MODIFIER_PROTECTED) != 0)
{
CCErrorOnLine(yygetfilename(node), yygetlinenum(node),
"cannot use both `public' and
`protected'");
}
return IL_META_FIELDDEF_PUBLIC;
}
else if((modifiers & JAVA_MODIFIER_PRIVATE) != 0)
{
if((modifiers & JAVA_MODIFIER_PROTECTED) != 0)
{
CCErrorOnLine(yygetfilename(node), yygetlinenum(node),
"cannot use both `private'
and `protected'");
}
return IL_META_FIELDDEF_PRIVATE;
}
else if((modifiers & JAVA_MODIFIER_PROTECTED) != 0)
{
return IL_META_FIELDDEF_FAMILY;
}
else
{
return IL_META_FIELDDEF_PRIVATE;
}
}
static void JavaModifiersUsedTwice(char *filename, long linenum, ILUInt32
modifiers)
{
ModifierError(filename, linenum,
modifiers, "`%s' specified multiple times");
}
/*
* Validate calling conventions for a method-like construct.
*/
static ILUInt32 ValidateCalling(ILNode *node, ILUInt32 modifiers,
ILUInt32 access)
{
ILUInt32 attrs = 0;
/* Process the calling convention modifiers */
if((modifiers & JAVA_MODIFIER_STATIC) != 0)
{
attrs |= IL_META_METHODDEF_STATIC;
if((modifiers & JAVA_MODIFIER_ABSTRACT) != 0)
{
CCErrorOnLine(yygetfilename(node), yygetlinenum(node),
"cannot use both `static' and
`abstract'");
}
if((modifiers & JAVA_MODIFIER_FINAL) != 0)
{
CCErrorOnLine(yygetfilename(node), yygetlinenum(node),
"cannot use both `static' and
`sealed'");
}
}
else if((modifiers & JAVA_MODIFIER_ABSTRACT) != 0)
{
attrs |= IL_META_METHODDEF_VIRTUAL | IL_META_METHODDEF_ABSTRACT;
if((modifiers & JAVA_MODIFIER_FINAL) != 0)
{
CCErrorOnLine(yygetfilename(node), yygetlinenum(node),
"cannot use both `abstract'
and `final'");
}
}
else if((modifiers & IL_META_METHODDEF_FINAL)==0)
{
attrs |= IL_META_METHODDEF_VIRTUAL;
}
/* Virtual methods cannot be private */
if((modifiers & (JAVA_MODIFIER_ABSTRACT)) != 0)
{
if(access == IL_META_FIELDDEF_PRIVATE)
{
CCErrorOnLine(yygetfilename(node), yygetlinenum(node),
"cannot declare abstract methods to be
private");
}
}
/* Methods always need "hide by sig" */
attrs |= IL_META_METHODDEF_HIDE_BY_SIG;
/* Done */
return attrs;
}
ILUInt32 JavaModifiersToTypeAttrs(ILNode *node, ILUInt32 modifiers,
int
isNested)
{
ILUInt32 attrs;
if(isNested)
{
modifiers = modifiers & (~JAVA_MODIFIER_STATIC);
}
/* Determine the access level of the class */
if(!isNested)
{
/* Only "public" and "internal" can be used at the outermost
scope */
if((modifiers & JAVA_MODIFIER_PUBLIC) != 0)
{
attrs = IL_META_TYPEDEF_PUBLIC;
if((modifiers & JAVA_MODIFIER_PRIVATE) != 0)
{
CCErrorOnLine(yygetfilename(node),
yygetlinenum(node),
"cannot use both
`public' and `private'");
}
if((modifiers & JAVA_MODIFIER_PROTECTED) != 0)
{
CCErrorOnLine(yygetfilename(node),
yygetlinenum(node),
"cannot use both
`public' and `protected'");
}
}
else
{
attrs = IL_META_TYPEDEF_NOT_PUBLIC;
if((modifiers & JAVA_MODIFIER_PRIVATE) != 0)
{
CCErrorOnLine(yygetfilename(node),
yygetlinenum(node),
"`private' modifier
is not permitted "
"on non-nested types");
}
if((modifiers & JAVA_MODIFIER_PROTECTED) != 0)
{
CCErrorOnLine(yygetfilename(node),
yygetlinenum(node),
"`protected' modifier
is not permitted "
"on non-nested
types");
}
}
}
else
{
/* Nested classes have a greater range of accessibilities */
if((modifiers & JAVA_MODIFIER_PUBLIC) != 0)
{
attrs = IL_META_TYPEDEF_NESTED_PUBLIC;
if((modifiers & JAVA_MODIFIER_PRIVATE) != 0)
{
CCErrorOnLine(yygetfilename(node),
yygetlinenum(node),
"cannot use both
`public' and `private'");
}
if((modifiers & JAVA_MODIFIER_PROTECTED) != 0)
{
CCErrorOnLine(yygetfilename(node),
yygetlinenum(node),
"cannot use both
`public' and `protected'");
}
}
else if((modifiers & JAVA_MODIFIER_PRIVATE) != 0)
{
attrs = IL_META_TYPEDEF_NESTED_PRIVATE;
if((modifiers & JAVA_MODIFIER_PROTECTED) != 0)
{
CCErrorOnLine(yygetfilename(node),
yygetlinenum(node),
"cannot use both
`private' and `protected'");
}
}
else if((modifiers & JAVA_MODIFIER_PROTECTED) != 0)
{
attrs = IL_META_TYPEDEF_NESTED_FAMILY;
}
else
{
attrs = IL_META_TYPEDEF_NESTED_PRIVATE;
}
}
if((modifiers & JAVA_MODIFIER_ABSTRACT) != 0)
{
attrs |= IL_META_TYPEDEF_ABSTRACT;
}
/* Report errors for any remaining modifiers */
BadModifiers(node,
modifiers & (JAVA_MODIFIER_STATIC |
JAVA_MODIFIER_VOLATILE));
/* We have the attributes we wanted now */
return attrs;
}
ILUInt32 JavaModifiersToConstructorAttrs(ILNode *node, ILUInt32 modifiers)
{
ILUInt32 attrs;
/* Different flags are used for instance and static constructors */
if((modifiers & JAVA_MODIFIER_STATIC) == 0)
{
attrs = ValidateAccess(node, modifiers);
BadModifiers(node,
modifiers & ~(JAVA_MODIFIER_PUBLIC |
JAVA_MODIFIER_PRIVATE |
JAVA_MODIFIER_PROTECTED));
}
else
{
BadModifiers(node,
modifiers & ~(JAVA_MODIFIER_STATIC));
attrs = IL_META_METHODDEF_PRIVATE | IL_META_METHODDEF_STATIC;
}
/* Add the "hidebysig" and "*specialname" attributes always */
attrs |= IL_META_METHODDEF_HIDE_BY_SIG |
IL_META_METHODDEF_SPECIAL_NAME |
IL_META_METHODDEF_RT_SPECIAL_NAME;
/* Done */
return attrs;
}
ILUInt32 JavaModifiersToMethodAttrs(ILNode *node, ILUInt32 modifiers)
{
ILUInt32 attrs;
/* Process the common attributes */
attrs = ValidateAccess(node, modifiers);
/* Process the calling convention attributes */
attrs |= ValidateCalling(node, modifiers, attrs);
if((attrs & IL_META_METHODDEF_STATIC) == 0)
{
attrs|=IL_META_METHODDEF_VIRTUAL;
}
/* Report errors for the remaining modifiers */
BadModifiers(node, modifiers & JAVA_MODIFIER_VOLATILE);
/* Done */
return attrs;
}
ILUInt32 JavaModifiersToFieldAttrs(ILNode *node, ILUInt32 modifiers)
{
ILUInt32 attrs;
/* Process the common attributes */
attrs = ValidateAccess(node, modifiers);
/* Process the "static" modifier */
if((modifiers & JAVA_MODIFIER_STATIC) != 0)
{
attrs |= IL_META_FIELDDEF_STATIC;
}
/* Report errors for the remaining modifiers */
BadModifiers(node,
modifiers & (JAVA_MODIFIER_ABSTRACT |
JAVA_MODIFIER_FINAL
|
JAVA_MODIFIER_SYNCHRONIZED));
/* Done */
return attrs;
}
--- NEW FILE ---
/*
* java_oper.tc - Semantic analysis for arithmetic and other operators
*
* Copyright (C) 2001 Southern Storm Software, Pty Ltd.
* Copyright (C) 2003 Gopal.V
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
[...1308 lines suppressed...]
}
else if(ILCanCoerceNode(info, node->expr3, JavaSemGetType(value2),
JavaSemGetType(value1),1) &&
!ILCanCoerceNode(info, node->expr2, JavaSemGetType(value1),
JavaSemGetType(value2),1))
{
ILCoerce(info, node->expr3, &(node->expr3),
JavaSemGetType(value2),
JavaSemGetType(value1),1);
JavaSemSetRValue(value1, JavaSemGetType(value1));
EvalOperator(info, *parent, parent, &value1);
return value1;
}
/* Report an error with the arguments to "?:" */
error:
CCErrorOnLine(yygetfilename(node), yygetlinenum(node),
"invalid operands to ternary `?:'");
JavaSemSetRValue(value1, ILType_Int32);
return value1;
}
--- NEW FILE ---
/*
* java_rename.h - Helper file for renaming yacc symbols for multiple parsers.
*
* Copyright (C) 2001 Southern Storm Software, Pty Ltd.
* Copyright (C) 2003 Gopal.V
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _CSCC_JAVA_RENAME_H
#define _CSCC_JAVA_RENAME_H
/*
* This list was extracted from the GNU automake documentation,
* and is supposed to be reasonably complete for all known
* yacc/lex implementations.
*/
#define yymaxdepth java_maxdepth
#define yyparse java_parse
#define yylex java_lex
#define yyerror java_error
#define yylval java_lval
#define yychar java_char
#define yydebug java_debug
#define yypact java_pact
#define yyr1 java_r1
#define yyr2 java_r2
#define yydef java_def
#define yychk java_chk
#define yypgo java_pgo
#define yyact java_act
#define yyexca java_exca
#define yyerrflag java_errflag
#define yynerrs java_nerrs
#define yyps java_ps
#define yypv java_pv
#define yys java_s
#define yy_yys java_yys
#define yystate java_state
#define yytmp java_tmp
#define yyv java_v
#define yy_yyv java_yyv
#define yyval java_val
#define yylloc java_lloc
#define yyreds java_reds
#define yytoks java_toks
#define yylhs java_yylhs
#define yylen java_yylen
#define yydefred java_yydefred
#define yydgoto java_yydgoto
#define yysindex java_yysindex
#define yyrindex java_yyrindex
#define yygindex java_yygindex
#define yytable java_yytable
#define yycheck java_yycheck
#define yyname java_yyname
#define yyrule java_yyrule
#endif /* _CSCC_JAVA_RENAME_H */
--- NEW FILE ---
%{
/*
* java_scanner.l - Input file for lex that defines the Java token syntax.
*
* Copyright (C) 2001 Southern Storm Software, Pty Ltd.
* Copyright (C) 2003 Gopal.V
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* Rename the lex/yacc symbols to support multiple parsers */
#include "java_rename.h"
#include <stdio.h>
#include "java_internal.h"
#include "java_grammar.h"
extern YYSTYPE yylval;
#ifdef YYLTYPE
extern YYLTYPE yylloc;
#endif
/*
* Get the next line of input from the C# pre-processor.
*/
#define YY_INPUT(buf,result,maxSize) \
{ \
result = CCPluginInput((buf), (maxSize)); \
}
/*
* Update the line number information and return a token code.
*/
#ifdef YYLTYPE
#define RETURNTOK(x) \
do { \
yylloc.first_line = yycurrlinenum(); \
return (x); \
} while (0)
#else
#define RETURNTOK(x) return (x)
#endif
/*
* Parse a floating point quantity into yylval.
*/
static int ParseFloat(char *text)
{
char *endptr;
#ifdef HAVE_STRTOD
/* Use "strtod" to parse the value */
yylval.real.value = (ILDouble)(strtod(text, &endptr));
#else
/* Use "sscanf" to parse the value */
double result;
int num;
if(sscanf(text, "%lf%n", &result, &num) <= 0)
{
/* Shouldn't happen, but do something reasonable */
yylval.real.value = (ILDouble)0.0;
yylval.real.type = JAVA_NUMTYPE_FLOAT64;
return FLOAT_LITERAL;
}
yylval.real.value = (ILDouble)result;
endptr = text + num;
#endif
/* Process the floating point suffix, if present */
if(*endptr == 'f' || *endptr == 'F')
{
yylval.real.type = JAVA_NUMTYPE_FLOAT32;
return FLOAT_LITERAL;
}
else
{
yylval.real.type = JAVA_NUMTYPE_FLOAT64;
return FLOAT_LITERAL;
}
}
/*
* Parse an integer quantity into yylval.
*/
static void ParseInt(char *text)
{
ILUInt64 value = 0;
ILUInt64 digit;
int errorType = 0;
/* Parse the main parse of the value */
if(*text == '0' && (text[1] == 'x' || text[1] == 'X'))
{
/* Hexadecimal integer constant */
text += 2;
while(*text != '\0')
{
if(*text >= 'A' && *text <= 'F')
{
digit = (ILUInt64)(*text - 'A' + 10);
}
else if(*text >= 'a' && *text <= 'f')
{
digit = (ILUInt64)(*text - 'a' + 10);
}
else if(*text >= '0' && *text <= '9')
{
digit = (ILUInt64)(*text - '0');
}
else
{
break;
}
if((value & 0xF000000000000000ULL) != 0)
{
errorType |= 1;
}
value = (value << 4) + digit;
++text;
}
}
else if(*text == '0' && text[1] != '\0' && text[1] != 'u' &&
text[1] != 'U' && text[1] != 'l' && text[1] != 'L')
{
/* The C# standard does not support octal integer constants,
but we have provided an option to turn them back on */
if(CCStringListContains(extension_flags, num_extension_flags,
"octal-constants"))
{
/* Octal integer constant: only active with
"-foctal-constants" */
while(*text != '\0')
{
if(*text >= '0' && *text <= '7')
{
digit = (ILUInt64)(*text - '0');
}
else if(*text == '8' || *text == '9')
{
/* Cannot use '8' and '9' in octal
constants! */
errorType |= 2;
digit = 0;
}
else
{
break;
}
if((value & 0xE000000000000000ULL) != 0)
{
errorType |= 1;
}
value = (value << 3) + digit;
++text;
}
}
else
{
/* Parse as a decimal constant */
goto decimal;
}
}
else
{
/* Decimal integer constant */
decimal:
while(*text != '\0')
{
if(*text >= '0' && *text <= '9')
{
if((value & 0x8000000000000000ULL) != 0)
{
errorType |= 1;
}
value <<= 1;
if((value & 0xC000000000000000ULL) != 0)
{
errorType |= 1;
}
digit = value << 2;
if((value += digit) < digit)
{
errorType |= 1;
}
digit = (ILUInt64)(*text - '0');
if((value += digit) < digit)
{
errorType |= 1;
}
}
else
{
break;
}
++text;
}
}
/* Report errors */
if(errorType)
{
if((errorType & 1) != 0)
{
CCError("integer constant is too large");
}
if((errorType & 2) != 0)
{
CCError("invalid octal constant");
}
value = 0;
}
/* Set the return value */
yylval.integer.value = value;
/* Parse the type information and determine if the value can be negated
*/
if((*text == 'l' || *text == 'L') && text[1] == '\0')
{
/* Long constant */
yylval.integer.type = JAVA_NUMTYPE_INT64;
yylval.integer.canneg = 1;
}
else if(*text != '\0')
{
/* Unsigned long constant */
yylval.integer.type = JAVA_NUMTYPE_INT64;
yylval.integer.canneg = 0;
}
else
{
/* Untyped constant */
if(value == 0x8000000000000000ULL)
{
yylval.integer.type = JAVA_NUMTYPE_INT64;
yylval.integer.canneg = 1;
}
else if((value & 0xFFFFFFFF00000000ULL) != 0)
{
yylval.integer.type = JAVA_NUMTYPE_INT64;
yylval.integer.canneg = 1;
}
else if(value == 0x0000000080000000ULL)
{
yylval.integer.type = JAVA_NUMTYPE_INT32;
yylval.integer.canneg = 1;
}
else if((value & 0x0000000080000000ULL) != 0)
{
yylval.integer.type = JAVA_NUMTYPE_INT32;
yylval.integer.canneg = 1;
}
else
{
yylval.integer.type = JAVA_NUMTYPE_INT32;
yylval.integer.canneg = 1;
}
}
}
/*
* Parse a single hex digit.
*/
#define PARSE_HEX_DIGIT(need) \
do { \
if(*temp >= '0' && *temp <= '9') \
{ \
*value = *value * 16 + (ILUInt32)(*temp
- '0'); \
++temp; \
} \
else if(*temp >= 'A' && *temp <= 'F') \
{ \
*value = *value * 16 + (ILUInt32)(*temp
- 'A' + 10); \
++temp; \
} \
else if(*temp >= 'a' && *temp <= 'f') \
{ \
*value = *value * 16 + (ILUInt32)(*temp
- 'a' + 10); \
++temp; \
} \
else if((need)) \
{ \
goto invalidHex; \
} \
} while (0)
/*
* Parse an escape sequence within a character or string.
*/
static int ParseEscape(const char *temp, ILUInt32 *value)
{
const char *begin = temp;
static char escapechars[] =
"\007\010cde\014ghijklm\012opq\015s\011u\013wxyz";
if(*temp == 'x')
{
/* Hex character: the C# specification allows 1-4 hex chars */
++temp;
*value = 0;
PARSE_HEX_DIGIT(1);
PARSE_HEX_DIGIT(0);
PARSE_HEX_DIGIT(0);
PARSE_HEX_DIGIT(0);
}
else if(*temp == 'u')
{
/* 16-bit Unicode character */
++temp;
*value = 0;
PARSE_HEX_DIGIT(1);
PARSE_HEX_DIGIT(1);
PARSE_HEX_DIGIT(1);
PARSE_HEX_DIGIT(1);
}
else if(*temp == 'U')
{
/* 32-bit Unicode character */
++temp;
*value = 0;
PARSE_HEX_DIGIT(1);
PARSE_HEX_DIGIT(1);
PARSE_HEX_DIGIT(1);
PARSE_HEX_DIGIT(1);
PARSE_HEX_DIGIT(1);
PARSE_HEX_DIGIT(1);
PARSE_HEX_DIGIT(1);
PARSE_HEX_DIGIT(1);
}
else if(*temp >= 'a' && *temp <= 'z')
{
*value = (ILUInt32)(escapechars[*temp - 'a']);
if(*value == (ILUInt32)(*temp))
{
CCTypedWarning("-unknown-escapes",
"unknown escape sequence
`\\%c'", *temp);
}
++temp;
}
else if(*temp >= '0' && *temp <= '7')
{
/* Octal character constant. The C# standard only supports
'\0', but we allow others to be used also, with a warning */
if(*temp == '0' && (temp[1] < '0' || temp[1] > '7'))
{
/* Unambiguous "\0" escape sequence */
*value = 0;
++temp;
}
else
{
/* The programmer can supply "-fno-octal-chars" to
disable
the use of octal character constants */
if(CCStringListContainsInv(extension_flags,
num_extension_flags,
"octal-chars"))
{
if(*temp == '0')
{
*value = 0;
++temp;
}
else
{
goto unknown;
}
}
else
{
if(*temp != '0' || (temp[1] >= '0' && temp[1]
<= '7'))
{
CCTypedWarning("-octal-chars",
"non-standard octal
character escape used");
CCTypedWarning("-octal-chars",
"(use
-fno-octal-chars to disable the use");
CCTypedWarning("-octal-chars",
"(of
non-standard octal character escapes)");
}
*value = 0;
do
{
*value = *value * 8 + (ILUInt32)(*temp
- '0');
++temp;
}
while(*temp >= '0' && *temp <= '7');
}
}
}
else
{
unknown:
if(*temp != '\'' && *temp != '"' && *temp != '\\')
{
CCTypedWarning("-unknown-escapes",
"unknown escape sequence
`\\%c'", *temp);
}
*value = (((ILUInt32)(*temp)) & (ILUInt32)0xFF);
++temp;
}
return (int)(temp - begin);
invalidHex:
{
char save = *temp;
*((char *)temp) = '\0';
CCError("invalid hexadecimal escape sequence `%s'", begin - 1);
*((char *)temp) = save;
return (int)(temp - begin);
}
}
/*
* Parse a character according to the prevailing charset encoding.
* Returns the length of the sequence.
*/
static int ParseEncodedChar(const char *text, ILUInt32 *value)
{
const char *begin = text;
if(CCStringListContains(extension_flags, num_extension_flags,
"latin1-charset"))
{
/* Latin-1 character */
*value = (((ILUInt32)(*text)) & (ILUInt32)0xFF);
++text;
}
else if((*text & (char)0xE0) == (char)0xC0 &&
(text[1] & (char)0xC0) == (char)0x80)
{
/* Two-byte UTF-8 character */
*value = ((((ILUInt32)(*text)) & 0x1F) << 6) |
(((ILUInt32)(text[1])) & 0x3F);
text += 2;
}
else if((*text & (char)0xF0) == (char)0xE0 &&
(text[1] & (char)0xC0) == (char)0x80 &&
(text[2] & (char)0xC0) == (char)0x80)
{
/* Three-byte UTF-8 character */
*value = ((((ILUInt32)(*text)) & 0x0F) << 12) |
((((ILUInt32)(text[1])) & 0x3F) << 6) |
(((ILUInt32)(text[2])) & 0x3F);
text += 3;
}
else if((*text & (char)0xF8) == (char)0xF0 &&
(text[1] & (char)0xC0) == (char)0x80 &&
(text[2] & (char)0xC0) == (char)0x80 &&
(text[3] & (char)0xC0) == (char)0x80)
{
/* Four-byte UTF-8 character */
*value = ((((ILUInt32)(*text)) & 0x07) << 18) |
((((ILUInt32)(text[1])) & 0x3F) << 12) |
((((ILUInt32)(text[2])) & 0x3F) << 6) |
(((ILUInt32)(text[3])) & 0x3F);
text += 4;
}
else if((*text & (char)0xFC) == (char)0xF8 &&
(text[1] & (char)0xC0) == (char)0x80 &&
(text[2] & (char)0xC0) == (char)0x80 &&
(text[3] & (char)0xC0) == (char)0x80 &&
(text[4] & (char)0xC0) == (char)0x80)
{
/* Five-byte UTF-8 character */
*value = ((((ILUInt32)(*text)) & 0x03) << 24) |
((((ILUInt32)(text[1])) & 0x3F) << 18) |
((((ILUInt32)(text[2])) & 0x3F) << 12) |
((((ILUInt32)(text[3])) & 0x3F) << 6) |
(((ILUInt32)(text[4])) & 0x3F);
text += 5;
}
else if((*text & (char)0xFC) == (char)0xFC &&
(text[1] & (char)0xC0) == (char)0x80 &&
(text[2] & (char)0xC0) == (char)0x80 &&
(text[3] & (char)0xC0) == (char)0x80 &&
(text[4] & (char)0xC0) == (char)0x80)
{
/* Six-byte UTF-8 character */
*value = ((((ILUInt32)(*text)) & 0x03) << 30) |
((((ILUInt32)(text[1])) & 0x3F) << 24) |
((((ILUInt32)(text[2])) & 0x3F) << 18) |
((((ILUInt32)(text[3])) & 0x3F) << 12) |
((((ILUInt32)(text[4])) & 0x3F) << 6) |
(((ILUInt32)(text[5])) & 0x3F);
text += 6;
}
else
{
/* Invalid sequence: treat it as an 8-bit character and skip it
*/
CCTypedWarning("-invalid-utf8", "invalid UTF-8 sequence");
*value = (((ILUInt32)(*text)) & (ILUInt32)0xFF);
++text;
}
return (int)(text - begin);
}
/*
* Parse a wide character value. Returns the length of the parsed data.
*/
static int ParseWChar(const char *text, ILUInt32 *result)
{
const char *begin = text;
/* Parse the character */
if(*text == '\\')
{
/* Escaped character */
++text;
text += ParseEscape(text, result);
}
else if((*text & (char)0x80) == 0)
{
/* Normal 7-bit character */
*result = (((ILUInt32)(*text)) & (ILUInt32)0xFF);
++text;
}
else
{
/* Character in the prevailing charset encoding */
text += ParseEncodedChar(text, result);
}
/* Return the length of the character to the caller */
return (int)(text - begin);
}
/*
* Parse a character constant value.
*/
static ILUInt32 ParseCharConstant(const char *text)
{
ILUInt32 value;
/* Skip the leading "'" */
++text;
/* Parse the character */
text += ParseWChar(text, &value);
/* Warn if the character is greater than 16-bits */
if(value >= (ILUInt32)0x00010000)
{
CCTypedWarning("-large-unicode-chars",
"32-bit Unicode character `\\U%08lX'
used: truncating "
"to 16 bits", (unsigned long)value);
}
/* Make sure that the constant is terminated correctly */
if(*text != '\'')
{
CCTypedWarning("-multi-char-constant", "multi-character
constant");
}
/* Return the value to the caller */
return value;
}
/*
* Parse a string value, converting it into UTF-8.
*/
static ILIntString ParseString(char *text)
{
char buffer[128];
ILUInt32 ch;
int posn;
ILIntString intern;
ILIntString append;
/* Initialize the value to be returned */
intern.string = 0;
intern.len = 0;
posn = 0;
/* Read characters from the string and encode them in UTF-8 */
while(*text != '"' && *text != '\0')
{
/* Get the next character */
text += ParseWChar(text, &ch);
/* Encode it in UTF-8 */
if(!ch)
{
/* Encode embedded NUL's using 2 bytes to protect
them from higher-level code that may try to use
the string as a normal C string */
buffer[posn++] = (char)0xC0;
buffer[posn++] = (char)0x80;
}
else if(ch < 0x80)
{
buffer[posn++] = (char)ch;
}
else if(ch < (1 << 11))
{
buffer[posn++] = (char)((ch >> 6) | 0xC0);
buffer[posn++] = (char)((ch & 0x3F) | 0x80);
}
else if(ch < (1 << 16))
{
buffer[posn++] = (char)((ch >> 12) | 0xE0);
buffer[posn++] = (char)(((ch >> 6) & 0x3F) | 0x80);
buffer[posn++] = (char)((ch & 0x3F) | 0x80);
}
else if(ch < (1 << 21))
{
buffer[posn++] = (char)((ch >> 18) | 0xF0);
buffer[posn++] = (char)(((ch >> 12) & 0x3F) | 0x80);
buffer[posn++] = (char)(((ch >> 6) & 0x3F) | 0x80);
buffer[posn++] = (char)((ch & 0x3F) | 0x80);
}
else if(ch < (1 << 26))
{
buffer[posn++] = (char)((ch >> 24) | 0xF8);
buffer[posn++] = (char)(((ch >> 18) & 0x3F) | 0x80);
buffer[posn++] = (char)(((ch >> 12) & 0x3F) | 0x80);
buffer[posn++] = (char)(((ch >> 6) & 0x3F) | 0x80);
buffer[posn++] = (char)((ch & 0x3F) | 0x80);
}
else
{
buffer[posn++] = (char)((ch >> 30) | 0xFC);
buffer[posn++] = (char)(((ch >> 24) & 0x3F) | 0x80);
buffer[posn++] = (char)(((ch >> 18) & 0x3F) | 0x80);
buffer[posn++] = (char)(((ch >> 12) & 0x3F) | 0x80);
buffer[posn++] = (char)(((ch >> 6) & 0x3F) | 0x80);
buffer[posn++] = (char)((ch & 0x3F) | 0x80);
}
/* Flush the buffer into "intern" if it is nearly full */
if(posn >= 120)
{
if(intern.len)
{
append.string = buffer;
append.len = posn;
intern = ILInternAppendedString(intern, append);
}
else
{
intern = ILInternString(buffer, posn);
}
posn = 0;
}
}
/* Flush the remainder of the buffer into "intern" */
if(intern.len)
{
append.string = buffer;
append.len = posn;
intern = ILInternAppendedString(intern, append);
}
else
{
intern = ILInternString(buffer, posn);
}
/* Return the final string to the caller */
return intern;
}
/*
* Parse an identifier value, converting it into UTF-8.
*/
static ILIntString ParseIdentifier(char *text)
{
char buffer[128];
ILUInt32 ch;
int posn;
ILIntString intern;
ILIntString append;
int first;
ILUnicodeCategory category;
int invalid;
/* Initialize the value to be returned */
intern.string = 0;
intern.len = 0;
posn = 0;
first = 1;
invalid = 0;
/* Read characters from the string and encode them in UTF-8 */
while(*text != '\0')
{
/* Get the next character */
text += ParseWChar(text, &ch);
/* Validate it */
if(first)
{
if(!((ch >= 'A' && ch <= 'Z') ||
(ch >= 'a' && ch <= 'z') || ch == '_'))
{
category = ILGetUnicodeCategory((unsigned)ch);
if(ch != '_' &&
category != ILUnicode_UppercaseLetter &&
category != ILUnicode_LowercaseLetter &&
category != ILUnicode_TitlecaseLetter &&
category != ILUnicode_ModifierLetter &&
category != ILUnicode_OtherLetter &&
category != ILUnicode_LetterNumber)
{
invalid = 1;
}
}
first = 0;
}
else
{
if(!((ch >= 'A' && ch <= 'Z') ||
(ch >= 'a' && ch <= 'z') ||
(ch >= '0' && ch <= '9') || ch == '_'))
{
category = ILGetUnicodeCategory((unsigned)ch);
if(category != ILUnicode_UppercaseLetter &&
category != ILUnicode_LowercaseLetter &&
category != ILUnicode_TitlecaseLetter &&
category != ILUnicode_ModifierLetter &&
category != ILUnicode_OtherLetter &&
category != ILUnicode_LetterNumber &&
category != ILUnicode_DecimalDigitNumber &&
category != ILUnicode_NonSpacingMark &&
category != ILUnicode_SpaceCombiningMark &&
category != ILUnicode_ConnectorPunctuation &&
category != ILUnicode_Format)
{
invalid = 1;
}
}
}
/* Encode it in UTF-8 */
if(!ch)
{
/* Encode embedded NUL's using 2 bytes to protect
them from higher-level code that may try to use
the string as a normal C string */
buffer[posn++] = (char)0xC0;
buffer[posn++] = (char)0x80;
}
else if(ch < 0x80)
{
buffer[posn++] = (char)ch;
}
else if(ch < (1 << 11))
{
buffer[posn++] = (char)((ch >> 6) | 0xC0);
buffer[posn++] = (char)((ch & 0x3F) | 0x80);
}
else if(ch < (1 << 16))
{
buffer[posn++] = (char)((ch >> 12) | 0xE0);
buffer[posn++] = (char)(((ch >> 6) & 0x3F) | 0x80);
buffer[posn++] = (char)((ch & 0x3F) | 0x80);
}
else if(ch < (1 << 21))
{
buffer[posn++] = (char)((ch >> 18) | 0xF0);
buffer[posn++] = (char)(((ch >> 12) & 0x3F) | 0x80);
buffer[posn++] = (char)(((ch >> 6) & 0x3F) | 0x80);
buffer[posn++] = (char)((ch & 0x3F) | 0x80);
}
else if(ch < (1 << 26))
{
buffer[posn++] = (char)((ch >> 24) | 0xF8);
buffer[posn++] = (char)(((ch >> 18) & 0x3F) | 0x80);
buffer[posn++] = (char)(((ch >> 12) & 0x3F) | 0x80);
buffer[posn++] = (char)(((ch >> 6) & 0x3F) | 0x80);
buffer[posn++] = (char)((ch & 0x3F) | 0x80);
}
else
{
buffer[posn++] = (char)((ch >> 30) | 0xFC);
buffer[posn++] = (char)(((ch >> 24) & 0x3F) | 0x80);
buffer[posn++] = (char)(((ch >> 18) & 0x3F) | 0x80);
buffer[posn++] = (char)(((ch >> 12) & 0x3F) | 0x80);
buffer[posn++] = (char)(((ch >> 6) & 0x3F) | 0x80);
buffer[posn++] = (char)((ch & 0x3F) | 0x80);
}
/* Flush the buffer into "intern" if it is nearly full */
if(posn >= 120)
{
if(intern.len)
{
append.string = buffer;
append.len = posn;
intern = ILInternAppendedString(intern, append);
}
else
{
intern = ILInternString(buffer, posn);
}
posn = 0;
}
}
/* Flush the remainder of the buffer into "intern" */
if(intern.len)
{
append.string = buffer;
append.len = posn;
intern = ILInternAppendedString(intern, append);
}
else
{
intern = ILInternString(buffer, posn);
}
/* Report an error if there was an invalid character in the identifier
*/
if(invalid)
{
CCError("invalid character in identifier");
}
/* Return the final string to the caller */
return intern;
}
%}
%option outfile="lex.yy.c"
%option prefix="java_"
%option noyywrap
%option nounput
DIGIT [0-9]
HEX [a-fA-F0-9]
IDALPHA
([a-zA-Z_]|\\u{HEX}{HEX}{HEX}{HEX}|\\U{HEX}{HEX}{HEX}{HEX}{HEX}{HEX}{HEX}{HEX})
EXPONENT [Ee][+-]?{DIGIT}+
FTYPE (f|F|d|D)
ITYPE (L|l)
WHITE [ \t\r\f\v\032]
%x COMMENT
%%
"++" { RETURNTOK(INC_OP); }
"--" { RETURNTOK(DEC_OP); }
"<<" { RETURNTOK(SHL_OP); }
">>" { RETURNTOK(SHR_OP); }
">>>" { RETURNTOK(USHR_OP); }
"<" { RETURNTOK(L_OP); }
">" { RETURNTOK(G_OP); }
"<=" { RETURNTOK(LE_OP); }
">=" { RETURNTOK(GE_OP); }
"==" { RETURNTOK(EQ_OP); }
"!=" { RETURNTOK(NEQ_OP); }
"&&" { RETURNTOK(AND_OP); }
"||" { RETURNTOK(OR_OP); }
"*=" { RETURNTOK(MUL_ASSIGN_OP); }
"/=" { RETURNTOK(DIV_ASSIGN_OP); }
"%=" { RETURNTOK(MOD_ASSIGN_OP); }
"+=" { RETURNTOK(ADD_ASSIGN_OP); }
"-=" { RETURNTOK(SUB_ASSIGN_OP); }
"<<=" { RETURNTOK(SHL_ASSIGN_OP); }
">>=" { RETURNTOK(SHR_ASSIGN_OP); }
">>>=" { RETURNTOK(USHR_ASSIGN_OP); }
"&=" { RETURNTOK(AND_ASSIGN_OP); }
"|=" { RETURNTOK(OR_ASSIGN_OP); }
"^=" { RETURNTOK(XOR_ASSIGN_OP); }
"abstract" { RETURNTOK(ABSTRACT); }
"private" { RETURNTOK(PRIVATE); }
"public" { RETURNTOK(PUBLIC); }
"transient" { RETURNTOK(TRANSIENT); }
"protected" { RETURNTOK(PROTECTED); }
"final" { RETURNTOK(FINAL); }
"interface" { RETURNTOK(INTERFACE); }
"static" { RETURNTOK(STATIC); }
"synchronized" { RETURNTOK(SYNCHRONIZED); }
"throws" { RETURNTOK(THROWS); }
"implements" { RETURNTOK(IMPLEMENTS); }
"extends" { RETURNTOK(EXTENDS); }
"if" { RETURNTOK(IF); }
"else" { RETURNTOK(ELSE); }
"do" { RETURNTOK(DO); }
"while" { RETURNTOK(WHILE); }
"for" { RETURNTOK(FOR); }
"try" { RETURNTOK(TRY); }
"catch" { RETURNTOK(CATCH); }
"throw" { RETURNTOK(THROW); }
"finally" { RETURNTOK(FINALLY); }
"switch" { RETURNTOK(SWITCH); }
"case" { RETURNTOK(CASE); }
"default" { RETURNTOK(DEFAULT); }
"break" { RETURNTOK(BREAK); }
"continue" { RETURNTOK(CONTINUE); }
"return" { RETURNTOK(RETURN); }
"goto" { RETURNTOK(GOTO); }
"byte" { RETURNTOK(BYTE); }
"boolean" { RETURNTOK(BOOLEAN); }
"class" { RETURNTOK(CLASS); }
"double" { RETURNTOK(DOUBLE); }
"int" { RETURNTOK(INT); }
"short" { RETURNTOK(SHORT); }
"void" { RETURNTOK(VOID); }
"char" { RETURNTOK(CHAR); }
"long" { RETURNTOK(LONG); }
"float" { RETURNTOK(FLOAT); }
"import" { RETURNTOK(IMPORT); }
"instanceof" { RETURNTOK(INSTANCEOF); }
"strictfp" { RETURNTOK(STRICTFP); }
"volatile" { RETURNTOK(VOLATILE); }
"native" { RETURNTOK(NATIVE); }
"super" { RETURNTOK(SUPER); }
"const" { RETURNTOK(CONST); }
"new" { RETURNTOK(NEW); }
"package" { RETURNTOK(PACKAGE_KEY); }
"this" { RETURNTOK(THIS); }
"true" { RETURNTOK(TRUE); }
"false" { RETURNTOK(FALSE); }
"null" { RETURNTOK(NULL_LITERAL); }
{IDALPHA}({DIGIT}|{IDALPHA})* {
yylval.name = (ParseIdentifier(yytext)).string;
RETURNTOK(IDENTIFIER);
}
{DIGIT}+{EXPONENT}{FTYPE}? {
RETURNTOK(ParseFloat(yytext)); }
{DIGIT}*"."{DIGIT}+({EXPONENT})?{FTYPE}? {
RETURNTOK(ParseFloat(yytext)); }
{DIGIT}+{FTYPE} {
RETURNTOK(ParseFloat(yytext)); }
0[xX]{HEX}+{ITYPE}? { ParseInt(yytext);
RETURNTOK(INTEGER_LITERAL); }
{DIGIT}+{ITYPE}? { ParseInt(yytext);
RETURNTOK(INTEGER_LITERAL); }
'(\\.|[^\\'])+' {
yylval.charValue =
(ILUInt16)(ParseCharConstant(yytext));
RETURNTOK(CHAR_LITERAL);
}
\"(\\.|[^\\"])*\" { yylval.string = ParseString(yytext +
1);
RETURNTOK(STRING_LITERAL); }
{WHITE}+ ;
\/\* { BEGIN(COMMENT); }
<COMMENT>\*\/ { BEGIN(INITIAL); }
"//".* { } /* comment - discard */
<COMMENT>. { } /* comment - discard */
<COMMENT>\n { } /* comment - discard */
\n ;
. { RETURNTOK(((int)(yytext[0])) & 0xFF);
}
%%
--- NEW FILE ---
/*
* java_semantics.tc - Semantic analysis operations for Java
*
* Copyright (C) 2001 Southern Storm Software, Pty Ltd.
* Copyright (C) 2003 Gopal.V
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
%output "java_semantics.c"
%{
#include "java_internal.h"
#include "java_semvalue.h"
%}
%operation JavaSemValue ILNode_JSemAnalysis([ILNode *node],
ILGenInfo *info,
ILNode **parent) =
{JavaSemValueDefault}
ILNode_JSemAnalysis(ILNode)
{
fprintf(stderr,"%s:%d <%s>\n",__FILE__,__LINE__,yykindname(node));
return JavaSemValueDefault;
}
%decls %end %{
/*
* Perform semantic analysis on a type. This is
* guaranteed to always return a correct type value.
* The "void" type will produce an error, if present.
*/
ILType *JavaSemType(ILNode *type, ILGenInfo *info, ILNode **parent);
/*
* Perform semantic analysis on a literal type identifier.
* This function changes the compiler state and then calls
* JavaSemType;
*/
ILType *JavaSemTypeLiteral(ILNode *type, ILGenInfo *info, ILNode **parent);
/*
* Perform semantic analysis on a type that can also
* include the "void" type.
*/
ILType *JavaSemTypeVoid(ILNode *type, ILGenInfo *info, ILNode **parent);
/*
* Perform semantic analysis on a base type. Returns
* zero if not a legal base type.
*/
int JavaSemBaseType(ILNode *type, ILGenInfo *info, ILNode **parent,
ILNode **baseNode, ILClass **baseClass);
/*
* Perform semantic analysis on a node and expect a value.
* Returns non-zero if a value, or zero on error.
*/
int JavaSemExpectValue(ILNode *node, ILGenInfo *info,
ILNode **parent, JavaSemValue *value);
/*
* Perform semantic analysis on a node and expect a type.
* Returns non-zero if a value, or zero on error.
*/
int JavaSemExpectType (ILNode *type, ILGenInfo *info, ILNode **parent);
/*
* Perform semantic analysis on the node corresponding to a
* program item. This is used to finialize semantic analysis
* on declarations that are forward-declared at the point of use.
*/
void JavaSemProgramItem(ILGenInfo *info, ILProgramItem *item);
%}
%{
#include <codegen/cg_nodemap.h>
%}
%end %{
static ILType *JavaSemFilterVoid(ILType *resultType, ILNode *type)
{
if(resultType == ILType_Void)
{
CCErrorOnLine(yygetfilename(type), yygetlinenum(type),
"`void' type is not allowed in this
context");
resultType = ILType_Int32;
}
return resultType;
}
static ILType *JavaSemValidate(ILNode *type, JavaSemValue value)
{
if(!JavaSemIsType(value))
{
if(!JavaSemIsError(value))
{
if(yyisa(type, ILNode_QualIdent)
|| yyisa(type, ILNode_Identifier))
{
CCErrorOnLine(yygetfilename(type),
yygetlinenum(type),
"invalid type specification
`%s' ",
ILQualIdentName(type,0));
}
else if(yyisa(type, ILNode_MemberAccess))
{
CCErrorOnLine(yygetfilename(type),
yygetlinenum(type),
"invalid type specification
`%s' ",
ILMemberAccessName(type));
}
else
{
CCErrorOnLine(yygetfilename(type),
yygetlinenum(type),
"invalid type specification");
}
}
return ILType_Int32;
}
else
{
return JavaSemGetType(value);
}
}
ILType *JavaSemType(ILNode *type, ILGenInfo *info, ILNode **parent)
{
return JavaSemFilterVoid(JavaSemTypeVoid(type, info, parent), type);
}
ILType *JavaSemTypeLiteral(ILNode *type, ILGenInfo *info, ILNode **parent)
{
JavaSemValue value;
int save;
/* NULL is used in some places in the grammar to indicate "void" */
if(!type) return JavaSemFilterVoid(ILType_Void, type);
save = info->inSemType;
info->inSemType = info->typeGather;
value = ILNode_JSemAnalysis(type, info, parent);
info->inSemType = save;
return JavaSemFilterVoid(JavaSemValidate(type, value),type);
}
ILType *JavaSemTypeVoid(ILNode *type, ILGenInfo *info, ILNode **parent)
{
JavaSemValue value;
int save;
/* NULL is used in some places in the grammar to indicate "void" */
if(!type) return ILType_Void;
save = info->inSemType;
info->inSemType = info->typeGather;
value = ILNode_JSemAnalysis(type, info, parent);
info->inSemType = save;
return JavaSemValidate(type, value);
}
int JavaSemExpectType (ILNode *type, ILGenInfo *info, ILNode **parent)
{
JavaSemValue value;
value = ILNode_JSemAnalysis(type, info, parent);
return JavaSemIsType(value);
}
int JavaSemBaseType(ILNode *type, ILGenInfo *info, ILNode **parent,
ILNode **baseNode, ILClass **baseClass)
{
JavaSemValue value;
int save = info->inSemType;
info->inSemType = info->typeGather;
value = ILNode_JSemAnalysis(type, info, parent);
info->inSemType = save;
if(JavaSemIsType(value))
{
*baseNode = 0;
*baseClass = ILTypeToClass(info, JavaSemGetType(value));
return (*baseClass != 0);
}
else if(JavaSemIsTypeNode(value))
{
*baseNode = JavaSemGetTypeNode(value);
*baseClass = 0;
return 1;
}
else
{
return 0;
}
}
int JavaSemExpectValue(ILNode *node, ILGenInfo *info,
ILNode **parent, JavaSemValue *value)
{
*value = ILNode_JSemAnalysis(node, info, parent);
return JavaSemIsValue(*value);
}
void JavaSemProgramItem(ILGenInfo *info, ILProgramItem *item)
{
ILGenItemContext context;
ILNode *node;
node = ILEnterProgramItemContext(info, item, CCGlobalScope, &context);
if(node)
{
ILNode_JSemAnalysis(node, info, &node);
ILLeaveProgramItemContext(info, &context);
}
}
%}
--- NEW FILE ---
/*
* java_semvalue.c - JavaSemValueDefault and JavaSemValueError definitions
*
* Copyright (C) 2001 Southern Storm Software, Pty Ltd.
* Copyright (C) 2003 Gopal.V
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "java_internal.h"
#ifdef __cplusplus
extern "C" {
#endif
JavaSemValue JavaSemValueDefault = {JAVA_SEMKIND_VOID, 0, 0};
JavaSemValue JavaSemValueError = {JAVA_SEMKIND_ERROR, 0, 0};
void _JavaSemReplaceWithConstant(ILNode **parent, ILEvalValue *value)
{
if(!value)
{
return;
}
switch(value->valueType)
{
case ILMachineType_Boolean:
{
if(value->un.i4Value)
{
*parent = ILNode_True_create();
}
else
{
*parent = ILNode_False_create();
}
}
break;
case ILMachineType_Int8:
{
if(value->un.i4Value >= 0)
{
*parent = ILNode_Int8_create
((ILUInt64)(ILInt64)(value->un.i4Value), 0, 0);
}
else
{
*parent = ILNode_Int8_create
((ILUInt64)(ILInt64)(-(value->un.i4Value)), 1, 0);
}
}
break;
case ILMachineType_UInt8:
{
*parent = ILNode_UInt8_create
((ILUInt64)(ILInt64)(value->un.i4Value), 0, 0);
}
break;
case ILMachineType_Int16:
{
if(value->un.i4Value >= 0)
{
*parent = ILNode_Int16_create
((ILUInt64)(ILInt64)(value->un.i4Value), 0, 0);
}
else
{
*parent = ILNode_Int16_create
((ILUInt64)(ILInt64)(-(value->un.i4Value)), 1, 0);
}
}
break;
case ILMachineType_UInt16:
{
*parent = ILNode_UInt16_create
((ILUInt64)(ILInt64)(value->un.i4Value), 0, 0);
}
break;
case ILMachineType_Char:
{
*parent = ILNode_Char_create
((ILUInt64)(ILInt64)(value->un.i4Value), 0, 0);
}
break;
case ILMachineType_Int32:
{
if(value->un.i4Value >= 0)
{
*parent = ILNode_Int32_create
((ILUInt64)(ILInt64)(value->un.i4Value), 0, 0);
}
else
{
*parent = ILNode_Int32_create
((ILUInt64)(-((ILInt64)(value->un.i4Value))), 1, 0);
}
}
break;
case ILMachineType_UInt32:
{
*parent = ILNode_UInt32_create
((ILUInt64)(ILUInt32)(value->un.i4Value), 0, 0);
}
break;
case ILMachineType_Int64:
{
if(value->un.i8Value >= 0)
{
*parent = ILNode_Int64_create
((ILUInt64)(value->un.i8Value), 0, 0);
}
else
{
*parent = ILNode_Int64_create
((ILUInt64)(-(value->un.i8Value)), 1,
0);
}
}
break;
case ILMachineType_UInt64:
{
*parent = ILNode_UInt64_create
((ILUInt64)(value->un.i8Value), 0, 0);
}
break;
case ILMachineType_Float32:
{
*parent =
ILNode_Float32_create((ILDouble)(value->un.r4Value));
}
break;
case ILMachineType_Float64:
{
*parent = ILNode_Float64_create(value->un.r8Value);
}
break;
case ILMachineType_NativeFloat:
{
*parent = ILNode_Float_create(value->un.r8Value);
}
break;
case ILMachineType_Decimal:
{
*parent = ILNode_Decimal_create(value->un.decValue);
}
break;
case ILMachineType_String:
{
*parent = ILNode_String_create(value->un.strValue.str,
value->un.strValue.len);
}
break;
case ILMachineType_ObjectRef:
{
*parent = ILNode_Null_create();
}
break;
case ILMachineType_UnmanagedPtr:
{
*parent = ILNode_NullPtr_create();
}
break;
default: break;
}
}
#ifdef __cplusplus
};
#endif
--- NEW FILE ---
/*
* java_semvalue.h - Semantic value handling
*
* Copyright (C) 2001 Southern Storm Software, Pty Ltd.
* Copyright (C) 2003 Gopal.V
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _JavaCC_JAVA_SEMVALUE_H
#define _JavaCC_JAVA_SEMVALUE_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* Define the semantic analysis return type.
*/
typedef struct
{
int kind__;
ILType *type__;
void *extra__;
} JavaSemValue;
extern JavaSemValue JavaSemValueDefault;
extern JavaSemValue JavaSemValueError;
/*
* Semantic value kinds.
*/
#define JAVA_SEMKIND_VOID (1<<0)
#define JAVA_SEMKIND_RVALUE (1<<1)
#define JAVA_SEMKIND_LVALUE (1<<2)
#define JAVA_SEMKIND_SVALUE (1<<3)
#define JAVA_SEMKIND_TYPE (1<<4)
#define JAVA_SEMKIND_FIELD (1<<5)
#define JAVA_SEMKIND_METHOD_GROUP (1<<6)
#define JAVA_SEMKIND_NAMESPACE (1<<9)
#define JAVA_SEMKIND_TYPE_NODE (1<<10)
#define JAVA_SEMKIND_AMBIGUOUS (1<<11)
#define JAVA_SEMKIND_CONSTANT (1<<13)
#define JAVA_SEMKIND_ERROR (1<<15)
#define JAVA_SEMKIND_SUPER (1<<16)
/*
* Set a semantic value to "void".
*/
#define JavaSemSetVoid(value) \
do { \
(value).kind__ = JAVA_SEMKIND_VOID; \
(value).type__ = 0; \
(value).extra__ = 0; \
} while (0)
/*
* Set a semantic value to an r-value with no constant.
*/
#define JavaSemSetRValue(value,type) \
do { \
(value).kind__ = JAVA_SEMKIND_RVALUE; \
(value).type__ = (type); \
(value).extra__ = 0; \
} while (0)
/*
* Set a semantic value to an l-value.
*/
#define JavaSemSetLValue(value,type) \
do { \
(value).kind__ = JAVA_SEMKIND_LVALUE; \
(value).type__ = (type); \
(value).extra__ = 0; \
} while (0)
/*
* Set a semantic value to an s-value.
*/
#define JavaSemSetSValue(value,type) \
do { \
(value).kind__ = JAVA_SEMKIND_SVALUE; \
(value).type__ = (type); \
(value).extra__ = 0; \
} while (0)
/*
* Set a semantic value to an r-value, l-value, or s-value, by kind.
*/
#define JavaSemSetValueKind(value,kind,type) \
do { \
(value).kind__ = (kind); \
(value).type__ = (type); \
(value).extra__ = 0; \
} while (0)
/*
* Set a semantic value to a field, etc, by kind.
*/
#define JavaSemSetKind(value,kind,extra) \
do { \
(value).kind__ = (kind); \
(value).type__ = ILType_Void; \
(value).extra__ = (void *)(extra); \
} while (0)
/*
* Set a semantic value to a type.
*/
#define JavaSemSetType(value,type) \
do { \
(value).kind__ = JAVA_SEMKIND_TYPE; \
(value).type__ = (type); \
(value).extra__ = 0; \
} while (0)
/*
* Set a semantic value to a type node.
*/
#define JavaSemSetTypeNode(value,node) \
do { \
(value).kind__ = JAVA_SEMKIND_TYPE_NODE; \
(value).type__ = ILType_Void; \
(value).extra__ = (void *)(node); \
} while (0)
/*
* Set a semantic value to a namespace.
*/
#define JavaSemSetNamespace(value,ns) \
do { \
(value).kind__ = JAVA_SEMKIND_TYPE; \
(value).type__ = ILType_Void; \
(value).extra__ = (void *)(ns); \
} while (0)
/*
* Set a semantic value to a compile-time constant.
*/
#define JavaSemSetConstant(value,type,constValue) \
do { \
(value).kind__ = JAVA_SEMKIND_RVALUE |
JAVA_SEMKIND_CONSTANT; \
(value).type__ = (type); \
(value).extra__ =
yynodealloc(sizeof(ILEvalValue)); \
*((ILEvalValue *)((value).extra__)) =
(constValue); \
} while (0)
/*
* Set a semantic value to a method group.
*/
#define JavaSemSetMethodGroup(value,group) \
do { \
(value).kind__ = JAVA_SEMKIND_METHOD_GROUP; \
(value).type__ = ILType_Void; \
(value).extra__ = (void *)(group); \
} while (0)
/*
* Modify a semantic value to indicate "base" access.
*/
#define JavaSemSetSuper(value) \
do { \
(value).kind__ |= JAVA_SEMKIND_SUPER; \
} while (0)
/*
* Determine if a semantic value has a specific kind.
*/
#define JavaSemHasKind(value,kind) (((value).kind__ & (kind)) != 0)
/*
* Get the kind of a semantic value.
*/
#define JavaSemGetKind(value) ((value).kind__)
/*
* Determine if a semantic value is an error.
*/
#define JavaSemIsError(value) (JavaSemHasKind((value),
JAVA_SEMKIND_ERROR))
/*
* Determine if a semantic value is "void".
*/
#define JavaSemIsVoid(value) (JavaSemHasKind((value),
JAVA_SEMKIND_VOID))
/*
* Get the namespace associated with a semantic value.
*/
#define JavaSemGetNamespace(value) ((char *)((value).extra__))
/*
* Determine if a semantic value is a type.
*/
#define JavaSemIsType(value) (JavaSemHasKind((value), JAVA_SEMKIND_TYPE))
/*
* Determine if a semantic value is a type node.
*/
#define JavaSemIsTypeNode(value) (JavaSemHasKind((value),
JAVA_SEMKIND_TYPE_NODE))
/*
* Get the type associated with a semantic value.
*/
#define JavaSemGetType(value) ((value).type__)
/*
* Get the type node associated with a semantic value.
*/
#define JavaSemGetTypeNode(value) ((ILNode *)((value).extra__))
/*
* Determine if a semantic value is an l-value, r-value, or s-value.
*/
#define JavaSemIsLValue(value) (JavaSemHasKind((value), JAVA_SEMKIND_LVALUE))
#define JavaSemIsRValue(value) (JavaSemHasKind((value), JAVA_SEMKIND_RVALUE))
#define JavaSemIsSValue(value) (JavaSemHasKind((value), JAVA_SEMKIND_SVALUE))
/*
* Determine if a semantic value is an l-value or r-value.
*/
#define JavaSemIsValue(value) \
(((value).kind__ & (JAVA_SEMKIND_LVALUE |
JAVA_SEMKIND_RVALUE)) != 0)
/*
* Determine if a semantic value is a field.
*/
#define JavaSemIsField(value) (JavaSemHasKind((value), JAVA_SEMKIND_FIELD))
/*
* Get the field record associated with a semantic value.
*/
#define JavaSemGetField(value) ((ILField *)((value).extra__))
/*
* Determine if a semantic value is a method group.
*/
#define JavaSemIsMethodGroup(value) \
(JavaSemHasKind((value), JAVA_SEMKIND_METHOD_GROUP))
/*
* Modify the group associated with a semantic value.
*/
#define JavaSemModifyGroup(value,group) ((value).extra__ = (void *)(group))
/*
* Get the group associated with a semantic value.
*/
#define JavaSemGetGroup(value) ((value).extra__)
/*
* Determine if a semantic value has the "base" flag.
*/
#define JavaSemIsSuper(value) (JavaSemHasKind((value), JAVA_SEMKIND_SUPER))
/*
* Determine if a semantic value is a constant.
*/
#define JavaSemIsConstant(value) (JavaSemHasKind((value),
JAVA_SEMKIND_CONSTANT))
/*
* Get the constant value slot within a value.
*/
#define JavaSemGetConstant(value) \
(JavaSemHasKind((value), JAVA_SEMKIND_CONSTANT) ? \
(ILEvalValue *)((value).extra__) : (ILEvalValue
*)0)
/*
* Replace a node with its constant representation, if we
* were able to evaluate a constant value.
*/
void _JavaSemReplaceWithConstant(ILNode **parent, ILEvalValue *value);
#define JavaSemReplaceWithConstant(parent,value) \
do { \
if(JavaSemIsConstant((value))) \
{ \
_JavaSemReplaceWithConstant \
((parent),
JavaSemGetConstant((value))); \
} \
} while (0)
#ifdef __cplusplus
};
#endif
#endif /* _JavaCC_JAVA_SEMVALUE_H */
--- NEW FILE ---
/*
* java_stmt.tc - Semantic analysis of Java statements
*
* Copyright (C) 2001 Southern Storm Software, Pty Ltd.
* Copyright (C) 2003 Gopal.V
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
[...1141 lines suppressed...]
{
if(CompareCaseLabels(&(switchExpr->switchValues[posn]),
&(switchValue)) == 0)
{
node->switchSection=(ILNode_SwitchSection*)
(switchExpr->switchValues[posn].section);
if(node->switchSection->visited==ILVisitMode_Processing)
{
CCWarningOnLine(yygetfilename(node),
yygetlinenum(node),
"circularity in 'goto' detected");
}
return JavaSemValueDefault;
}
}
/* if we get here , the case entry was not locatable */
CCErrorOnLine(yygetfilename(node), yygetlinenum(node),
"could not find a matching case for 'goto'");
return JavaSemValueDefault;
}
--- NEW FILE ---
/*
* java_types.tc - Semantic analysis of Java type nodes
*
* Copyright (C) 2001 Southern Storm Software, Pty Ltd.
* Copyright (C) 2003 Gopal.V
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
%decls %{
/*
* Convert a type into a printable name, suitable for use in error messages.
*/
const char *JavaTypeToName(ILType *type);
%}
/*
* Perform semantic analysis for primitive types.
*/
ILNode_JSemAnalysis(ILNode_JPrimitiveType)
{
JavaSemValue value;
JavaSemSetType(value, ILType_FromElement(node->elementType));
return value;
}
/*
* Perform semantic analysis for the "object" type.
*/
ILNode_JSemAnalysis(ILNode_JSystemType)
{
JavaSemValue value;
JavaSemSetType(value, ILFindNonSystemType(info,
node->className,"java.lang"));
if(!(JavaSemGetType(value)))
{
value=ILNode_JSemAnalysis(
ILQualIdentTwo("java.lang",node->className),info,parent);
}
if(!(JavaSemGetType(value)))
{
CCOutOfMemory();
}
return value;
}
ILNode_JSemAnalysis(ILNode_ILSystemType)
{
JavaSemValue value;
JavaSemSetType(value, ILFindSystemType(info, node->className));
if(!(JavaSemGetType(value)))
{
value=ILNode_JSemAnalysis(
ILQualIdentTwo("System",node->className),info,parent);
}
if(!(JavaSemGetType(value)))
{
CCOutOfMemory();
}
return value;
}
/*
* Perform semantic analysis for array types. Array types are
* constructed by the C# grammar with the rank specifiers in the
* reverse of the true order, which this function fixes up.
*/
ILNode_JSemAnalysis(ILNode_JArrayType)
{
JavaSemValue value;
ILNode *elemType;
ILNode **elemTypeParent;
ILType *arrayType;
ILType *type;
/* Find the element type at the end of the rank specifiers */
elemType = node->type;
elemTypeParent = &(node->type);
while(yykind(elemType) == yykindof(ILNode_JArrayType))
{
elemTypeParent = &(((ILNode_JArrayType *)elemType)->type);
elemType = ((ILNode_JArrayType *)elemType)->type;
}
/* Perform semantic analysis on the element type */
type = JavaSemTypeLiteral(elemType, info, elemTypeParent);
/* Create the array type from the outermost rank inwards */
arrayType = ILTypeCreateArray(info->context, node->numDimensions, type);
if(!arrayType)
{
CCOutOfMemory();
}
elemType = node->type;
while(yykind(elemType) == yykindof(ILNode_JArrayType))
{
arrayType = ILTypeCreateArray
(info->context, ((ILNode_JArrayType
*)elemType)->numDimensions,
arrayType);
if(!arrayType)
{
CCOutOfMemory();
}
elemType = ((ILNode_JArrayType *)elemType)->type;
}
/* Return the final array type */
JavaSemSetType(value, arrayType);
return value;
}
%end %{
const char *JavaTypeToName(ILType *type)
{
if(ILType_IsPrimitive(type))
{
/* Get the name of a primitive type */
switch(ILType_ToElement(type))
{
case IL_META_ELEMTYPE_VOID: return
"void";
case IL_META_ELEMTYPE_BOOLEAN: return
"boolean";
case IL_META_ELEMTYPE_I1: return
"sbyte";
case IL_META_ELEMTYPE_U1: return
"byte";
case IL_META_ELEMTYPE_I2: return
"short";
case IL_META_ELEMTYPE_U2: return
"ushort";
case IL_META_ELEMTYPE_CHAR: return
"char";
case IL_META_ELEMTYPE_I4: return
"int";
case IL_META_ELEMTYPE_U4: return
"uint";
case IL_META_ELEMTYPE_I8: return
"long";
case IL_META_ELEMTYPE_U8: return
"ulong";
case IL_META_ELEMTYPE_R4: return
"float";
case IL_META_ELEMTYPE_R8: return
"double";
case IL_META_ELEMTYPE_R: return
"double";
case IL_META_ELEMTYPE_I: return
"System.IntPtr";
case IL_META_ELEMTYPE_U: return
"System.UIntPtr";
case IL_META_ELEMTYPE_STRING: return
"System.String";
case IL_META_ELEMTYPE_OBJECT: return
"System.Object";
case IL_META_ELEMTYPE_TYPEDBYREF: return
"System.TypedReference";
}
if(type == ILType_Null)
{
return "null";
}
}
else if(ILType_IsValueType(type) || ILType_IsClass(type))
{
/* Get the name of a value or class type */
ILClass *classInfo = ILType_ToClass(type);
const char *name = ILClass_Name(classInfo);
const char *namespace = ILClass_Namespace(classInfo);
if(namespace)
{
return ILInternAppendedString
(ILInternAppendedString
(ILInternString((char
*)namespace, -1),
ILInternString((char
*)".", 1)),
ILInternString((char *)name,
-1)).string;
}
else
{
return name;
}
}
else if(type != ILType_Invalid)
{
/* Get the name of a complex type */
int kind = ILType_Kind(type);
if(kind == IL_TYPE_COMPLEX_BYREF)
{
return ILInternAppendedString
(ILInternString((char
*)JavaTypeToName(ILType_Ref(type)), -1),
ILInternString((char *)" &",
2)).string;
}
else if(kind == IL_TYPE_COMPLEX_PTR)
{
return ILInternAppendedString
(ILInternString((char
*)JavaTypeToName(ILType_Ref(type)), -1),
ILInternString((char *)" *",
2)).string;
}
else if(kind == IL_TYPE_COMPLEX_ARRAY ||
kind == IL_TYPE_COMPLEX_ARRAY_CONTINUE)
{
ILType *elemType = ILType_ElemType(type);
ILIntString str;
ILIntString open;
ILIntString close;
ILIntString comma;
while(ILType_IsComplex(elemType) && elemType !=
ILType_Invalid &&
(ILType_Kind(elemType) == IL_TYPE_COMPLEX_ARRAY ||
ILType_Kind(elemType) ==
IL_TYPE_COMPLEX_ARRAY))
{
elemType = ILType_ElemType(elemType);
}
str = ILInternString((char *)JavaTypeToName(elemType),
-1);
open = ILInternString((char *)"[", 1);
close = ILInternString((char *)"]", 1);
comma = ILInternString((char *)",", 1);
str = ILInternAppendedString(str, open);
while(type != elemType)
{
if(ILType_Kind(type) == IL_TYPE_COMPLEX_ARRAY)
{
str = ILInternAppendedString(str,
close);
type = ILType_ElemType(type);
if(type != elemType)
{
str =
ILInternAppendedString(str, open);
}
}
else
{
str = ILInternAppendedString(str,
comma);
type = ILType_ElemType(type);
}
}
return str.string;
}
else if(kind == IL_TYPE_COMPLEX_CMOD_REQD ||
kind == IL_TYPE_COMPLEX_CMOD_OPT)
{
ILIntString str;
ILIntString temp;
if(kind == IL_TYPE_COMPLEX_CMOD_REQD)
{
str = ILInternString("/* reqd ", -1);
}
else
{
str = ILInternString("/* opt ", -1);
}
temp = ILInternString
((char *)(JavaTypeToName(ILType_FromClass
(type->un.modifier__.info__))), -1);
str = ILInternAppendedString(str, temp);
temp = ILInternString(" */ ", -1);
str = ILInternAppendedString(str, temp);
temp = ILInternString
((char
*)(JavaTypeToName(type->un.modifier__.type__)), -1);
str = ILInternAppendedString(str, temp);
return str.string;
}
else if((kind & IL_TYPE_COMPLEX_METHOD) != 0)
{
ILIntString str;
ILIntString temp;
unsigned long num;
unsigned long param;
ILType *paramType;
/* Convert the return type */
str = ILInternString
((char
*)(JavaTypeToName(ILTypeGetReturnWithPrefixes(type))), -1);
/* Add the start of the parameter list */
temp = ILInternString(" * (", -1);
str = ILInternAppendedString(str, temp);
/* Indicate if the type has a "this" parameter */
if(ILType_HasThis(type))
{
temp = ILInternString("/*this,*/ ", -1);
str = ILInternAppendedString(str, temp);
}
/* Add the parameters to the list */
num = ILTypeNumParams(type);
for(param = 1; param <= num; ++param)
{
paramType = ILTypeGetParamWithPrefixes(type,
param);
temp = ILInternString((char
*)(JavaTypeToName(paramType)), -1);
str = ILInternAppendedString(str, temp);
if(param < num)
{
temp = ILInternString(", ", 2);
str = ILInternAppendedString(str, temp);
}
}
/* Terminate the parameter list and return */
temp = ILInternString(")", 1);
str = ILInternAppendedString(str, temp);
return str.string;
}
}
return "invalid type";
}
%}
--- NEW FILE ---
noinst_LIBRARIES = libILJava.a
TREECC_INPUTS = java_defs.tc \
java_semantics.tc \
java_lvalue.tc \
java_types.tc \
java_stmt.tc \
java_decls.tc \
java_invoke.tc \
java_const.tc \
java_oper.tc \
java_misc.tc \
java_cast.tc
TREECC_SRCOUT = java_nodes.c java_semantics.c
TREECC_OUTPUT = $(TREECC_SRCOUT) java_defs.h
libILJava_a_SOURCES = $(TREECC_SRCOUT) \
java_grammar.y \
java_scanner.l \
java_gather.c \
java_modifiers.c \
java_lookup.c \
java_semvalue.c
AM_YFLAGS = -d
AM_CFLAGS = -I$(top_srcdir) -I$(top_builddir) -I$(top_srcdir)/include
STAMP = stamp-treecc
BUILT_SOURCES = $(STAMP)
libILJava_a_DEPENDENCIES = $(STAMP)
$(STAMP): $(TREECC_INPUTS) ../../codegen/$(STAMP)
$(TREECC) $(srcdir)/java_defs.tc && touch $@
CLEANFILES = java_grammar.c java_scanner.c java_grammar.h $(TREECC_OUTPUT)
$(STAMP)
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Dotgnu-pnet-commits] CVS: pnet/cscc/java java_cast.tc,NONE,1.1 java_const.tc,NONE,1.1 java_decls.tc,NONE,1.1 java_defs.tc,NONE,1.1 java_gather.c,NONE,1.1 java_grammar.y,NONE,1.1 java_internal.h,NONE,1.1 java_invoke.tc,NONE,1.1 java_lookup.c,NONE,1.1 java_lvalue.tc,NONE,1.1 java_misc.tc,NONE,1.1 java_modifiers.c,NONE,1.1 java_oper.tc,NONE,1.1 java_rename.h,NONE,1.1 java_scanner.l,NONE,1.1 java_semantics.tc,NONE,1.1 java_semvalue.c,NONE,1.1 java_semvalue.h,NONE,1.1 java_stmt.tc,NONE,1.1 java_types.tc,NONE,1.1 Makefile.am,NONE,1.1,
Gopal.V <address@hidden> <=
- Prev by Date:
[Dotgnu-pnet-commits] CVS: pnet configure.in,1.122,1.123 ChangeLog,1.2362,1.2363
- Next by Date:
[Dotgnu-pnet-commits] CVS: pnet/cscc java_main.c,NONE,1.1 Makefile.am,1.20,1.21
- Previous by thread:
[Dotgnu-pnet-commits] CVS: pnet configure.in,1.122,1.123 ChangeLog,1.2362,1.2363
- Next by thread:
[Dotgnu-pnet-commits] CVS: pnet/cscc java_main.c,NONE,1.1 Makefile.am,1.20,1.21
- Index(es):