import "ecdefs"
-#define uint _uint
-#include <stdlib.h> // For strtoll
-#undef uint
-
// UNTIL IMPLEMENTED IN GRAMMAR
#define ACCESS_CLASSDATA(_class, baseClass) \
(_class ? ((void *)(((char *)_class.data) + baseClass.offsetClass)) : null)
{
TempFile f { };
int count;
+ bool backOutputLineNumbers = outputLineNumbers;
+ outputLineNumbers = false;
if(exp)
OutputExpression(exp, f);
count += f.Read(string + count, 1, 1023);
string[count] = '\0';
delete f;
+
+ outputLineNumbers = backOutputLineNumbers;
}
}
return false;
}
- if(type1.kind == type2.kind)
+ if(type1.kind == type2.kind && type1.isLong == type2.isLong)
{
switch(type1.kind)
{
case classType:
return type1._class != type2._class;
case pointerType:
- return NeedCast(type1.type, type2.type);
+ return (type1.type && type2.type && type1.type.constant != type2.type.constant) || NeedCast(type1.type, type2.type);
default:
return true; //false; ????
}
// First, check if the identifier is declared inside the function
for(ctx = curContext; ctx != topContext.parent && !symbol; ctx = ctx.parent)
{
+ if(!ctx) break; // This happened opening old mapTileCache.ec from archives?
symbol = (Symbol)ctx.symbols.FindString(id.string);
if(symbol) break;
}
public char * PrintInt(int64 result)
{
char temp[100];
- if(result > MAXINT64)
- sprintf(temp, FORMAT64HEXLL /*"0x%I64XLL"*/, result);
+ if(result > MAXINT)
+ sprintf(temp, FORMAT64HEX /*"0x%I64XLL"*/, result);
else
- sprintf(temp, FORMAT64DLL /*"%I64d"*/, result);
+ sprintf(temp, FORMAT64D /*"%I64d"*/, result);
+ if(result > MAXINT || result < MININT)
+ strcat(temp, "LL");
return CopyString(temp);
}
{
char temp[100];
if(result > MAXDWORD)
- sprintf(temp, FORMAT64HEXLL /*"0x%I64XLL"*/, result);
+ sprintf(temp, FORMAT64HEXLL /*"0x%I64X"*/, result);
else if(result > MAXINT)
sprintf(temp, FORMAT64HEX /*"0x%I64X"*/, result);
else
return CopyString(temp);
}
-public char * PrintInt64(int64 result)
+public char * PrintInt64(int64 result)
{
char temp[100];
- sprintf(temp, FORMAT64DLL /*"%I64d"*/, result);
+ if(result > MAXINT || result < MININT)
+ sprintf(temp, FORMAT64DLL /*"%I64d"*/, result);
+ else
+ sprintf(temp, FORMAT64D /*"%I64d"*/, result);
return CopyString(temp);
}
public char * PrintUInt64(uint64 result)
{
char temp[100];
- if(result > MAXINT64)
+ if(result > MAXDWORD)
sprintf(temp, FORMAT64HEXLL /*"0x%I64XLL"*/, result);
+ else if(result > MAXINT)
+ sprintf(temp, FORMAT64HEX /*"0x%I64XLL"*/, result);
else
- sprintf(temp, FORMAT64DLL /*"%I64d"*/, result);
+ sprintf(temp, FORMAT64D /*"%I64d"*/, result);
return CopyString(temp);
}
{
char temp[100];
if(result > MAXDWORD)
- sprintf(temp, FORMAT64HEXLL /*"0x%I64xLL"*/, result);
+ sprintf(temp, FORMAT64HEX /*"0x%I64xLL"*/, result);
else
sprintf(temp, FORMAT64HEX /*"0x%I64x"*/, result);
+ if(result > MAXDWORD)
+ strcat(temp, "LL");
return CopyString(temp);
}
public char * PrintFloat(float result)
{
char temp[350];
- sprintf(temp, "%.16ff", result);
+ if(result.isInf)
+ {
+ if(result.signBit)
+ strcpy(temp, "-inf");
+ else
+ strcpy(temp, "inf");
+ }
+ else if(result.isNan)
+ {
+ if(result.signBit)
+ strcpy(temp, "-nan");
+ else
+ strcpy(temp, "nan");
+ }
+ else
+ sprintf(temp, "%.16ff", result);
return CopyString(temp);
}
public char * PrintDouble(double result)
{
char temp[350];
- sprintf(temp, "%.16f", result);
+ if(result.isInf)
+ {
+ if(result.signBit)
+ strcpy(temp, "-inf");
+ else
+ strcpy(temp, "inf");
+ }
+ else if(result.isNan)
+ {
+ if(result.signBit)
+ strcpy(temp, "-nan");
+ else
+ strcpy(temp, "nan");
+ }
+ else
+ sprintf(temp, "%.16f", result);
return CopyString(temp);
}
//public Operand GetOperand(Expression exp);
#define GETVALUE(name, t) \
- public bool Get##name(Expression exp, t * value2) \
+ public bool GetOp##name(Operand op2, t * value2) \
{ \
- Operand op2 = GetOperand(exp); \
if(op2.kind == intType && op2.type.isSigned) *value2 = (t) op2.i; \
else if(op2.kind == intType) *value2 = (t) op2.ui; \
else if(op2.kind == int64Type && op2.type.isSigned) *value2 = (t) op2.i64; \
else \
return false; \
return true; \
+ } \
+ public bool Get##name(Expression exp, t * value2) \
+ { \
+ Operand op2 = GetOperand(exp); \
+ return GetOp##name(op2, value2); \
}
-// To help the deubugger currently not preprocessing...
+// To help the debugger currently not preprocessing...
#define HELP(x) x
GETVALUE(Int, HELP(int));
if(member || ((_class.type == bitClass || _class.type == normalClass || _class.type == structClass || _class.type == noHeadClass) &&
(_class.type == bitClass || (!_class.structSize || _class.structSize == _class.offset)) && _class.computeSize))
{
- int c;
int unionMemberOffset = 0;
int bitFields = 0;
if(_class.memberOffset % _class.structAlignment)
extra += _class.structAlignment - (_class.memberOffset % _class.structAlignment);
}
- _class.structSize = (_class.base ? (_class.base.templateClass ? _class.base.templateClass.structSize : _class.base.structSize) : 0) + _class.memberOffset + extra;
+ _class.structSize = (_class.base ? (_class.base.templateClass ?
+ (_class.base.type == noHeadClass ? _class.base.templateClass.memberOffset : _class.base.templateClass.structSize) :
+ (_class.base.type == noHeadClass ? _class.base.memberOffset : _class.base.structSize) ) : 0) + _class.memberOffset + extra;
if(!member)
{
Property prop;
if(deriv.computeSize)
{
// TESTING THIS NEW CODE HERE... TRYING TO FIX ScrollBar MEMBERS DEBUGGING
- deriv.offset = /*_class.offset + */_class.structSize;
+ deriv.offset = /*_class.offset + */(_class.type == noHeadClass ? _class.memberOffset : _class.structSize);
deriv.memberOffset = 0;
// ----------------------
case charType: type.alignment = size = sizeof(char); break;
case intType: type.alignment = size = sizeof(int); break;
case int64Type: type.alignment = size = sizeof(int64); break;
- case intPtrType: type.alignment = size = targetBits / 8; break;
- case intSizeType: type.alignment = size = targetBits / 8; break;
+ case intPtrType: type.alignment = size = targetBits / 8; type.pointerAlignment = true; break;
+ case intSizeType: type.alignment = size = targetBits / 8; type.pointerAlignment = true; break;
case longType: type.alignment = size = sizeof(long); break;
case shortType: type.alignment = size = sizeof(short); break;
case floatType: type.alignment = size = sizeof(float); break;
// Ensure all members are properly registered
ComputeClassMembers(_class, false);
type.alignment = _class.structAlignment;
+ type.pointerAlignment = (bool)_class.pointerAlignment;
size = _class.structSize;
if(type.alignment && size % type.alignment)
size += type.alignment - (size % type.alignment);
size = type.alignment = ComputeTypeSize(_class.dataType);
}
else
+ {
size = type.alignment = targetBits / 8; // sizeof(Instance *);
+ type.pointerAlignment = true;
+ }
break;
}
- case pointerType: case subClassType: size = type.alignment = targetBits / 8; /*sizeof(void *); */break;
+ case pointerType: case subClassType: size = type.alignment = targetBits / 8; /*sizeof(void *); */ type.pointerAlignment = true; break;
case arrayType:
if(type.arraySizeExp)
{
ProcessExpressionType(type.arraySizeExp);
ComputeExpression(type.arraySizeExp);
- if(!type.arraySizeExp.isConstant || (type.arraySizeExp.expType.kind != intType && type.arraySizeExp.expType.kind != enumType &&
+ if(!type.arraySizeExp.isConstant || (type.arraySizeExp.expType.kind != intType &&
+ type.arraySizeExp.expType.kind != shortType &&
+ type.arraySizeExp.expType.kind != charType &&
+ type.arraySizeExp.expType.kind != longType &&
+ type.arraySizeExp.expType.kind != int64Type &&
+ type.arraySizeExp.expType.kind != intSizeType &&
+ type.arraySizeExp.expType.kind != intPtrType &&
+ type.arraySizeExp.expType.kind != enumType &&
(type.arraySizeExp.expType.kind != classType || !type.arraySizeExp.expType._class.registered || type.arraySizeExp.expType._class.registered.type != enumClass)))
{
Location oldLoc = yylloc;
size = ComputeTypeSize(type.type) * type.arraySize;
if(type.type)
+ {
type.alignment = type.type.alignment;
+ type.pointerAlignment = type.type.pointerAlignment;
+ }
break;
case structType:
{
- Type member;
- for(member = type.members.first; member; member = member.next)
+ if(!type.members.first && type.enumName)
{
- uint addSize = ComputeTypeSize(member);
+ Symbol symbol = FindStruct(curContext, type.enumName);
+ if(symbol && symbol.type)
+ {
+ ComputeTypeSize(symbol.type);
+ size = symbol.type.size;
+ }
+ }
+ else
+ {
+ Type member;
+ for(member = type.members.first; member; member = member.next)
+ {
+ uint addSize = ComputeTypeSize(member);
- member.offset = size;
- if(member.alignment && size % member.alignment)
- member.offset += member.alignment - (size % member.alignment);
- size = member.offset;
+ member.offset = size;
+ if(member.alignment && size % member.alignment)
+ member.offset += member.alignment - (size % member.alignment);
+ size = member.offset;
- type.alignment = Max(type.alignment, member.alignment);
- size += addSize;
+ if(member.pointerAlignment && type.size <= 4)
+ type.pointerAlignment = true;
+ else if(!member.pointerAlignment && member.alignment >= 8)
+ type.pointerAlignment = false;
+
+ type.alignment = Max(type.alignment, member.alignment);
+ size += addSize;
+ }
+ if(type.alignment && size % type.alignment)
+ size += type.alignment - (size % type.alignment);
}
- if(type.alignment && size % type.alignment)
- size += type.alignment - (size % type.alignment);
break;
}
case unionType:
{
- Type member;
- for(member = type.members.first; member; member = member.next)
+ if(!type.members.first && type.enumName)
+ {
+ Symbol symbol = FindStruct(curContext, type.enumName);
+ if(symbol && symbol.type)
+ {
+ ComputeTypeSize(symbol.type);
+ size = symbol.type.size;
+ type.alignment = symbol.type.alignment;
+ }
+ }
+ else
{
- uint addSize = ComputeTypeSize(member);
+ Type member;
+ for(member = type.members.first; member; member = member.next)
+ {
+ uint addSize = ComputeTypeSize(member);
+
+ member.offset = size;
+ if(member.alignment && size % member.alignment)
+ member.offset += member.alignment - (size % member.alignment);
+ size = member.offset;
+
+ if(member.pointerAlignment && type.size <= 4)
+ type.pointerAlignment = true;
+ else if(!member.pointerAlignment && member.alignment >= 8)
+ type.pointerAlignment = false;
- member.offset = size;
- if(member.alignment && size % member.alignment)
- member.offset += member.alignment - (size % member.alignment);
- size = member.offset;
+ type.alignment = Max(type.alignment, member.alignment);
- type.alignment = Max(type.alignment, member.alignment);
- size = Max(size, addSize);
+ size = Max(size, addSize);
+ }
+ if(type.alignment && size % type.alignment)
+ size += type.alignment - (size % type.alignment);
}
- if(type.alignment && size % type.alignment)
- size += type.alignment - (size % type.alignment);
break;
}
case templateType:
{
size = ComputeTypeSize(baseType);
type.alignment = baseType.alignment;
+ type.pointerAlignment = baseType.pointerAlignment;
}
else
type.alignment = size = sizeof(uint64);
case thisClassType:
{
type.alignment = size = targetBits / 8; //sizeof(void *);
+ type.pointerAlignment = true;
break;
}
}
}
-/*static */int AddMembers(OldList * declarations, Class _class, bool isMember, uint * retSize, Class topClass, bool *addedPadding)
+/*static */int AddMembers(External neededBy, OldList * declarations, Class _class, bool isMember, uint * retSize, Class topClass, bool *addedPadding)
{
// This function is in need of a major review when implementing private members etc.
DataMember topMember = isMember ? (DataMember) _class : null;
uint totalSize = 0;
uint maxSize = 0;
- int alignment, size;
+ int alignment;
+ uint size;
DataMember member;
+ int anonID = 1;
Context context = isMember ? null : SetupTemplatesContext(_class);
if(addedPadding)
*addedPadding = false;
{
// DANGER: Testing this noHeadClass here...
if(_class.type == structClass || _class.type == noHeadClass)
- /*totalSize = */AddMembers(declarations, _class.base, false, &totalSize, topClass, null);
+ /*totalSize = */AddMembers(neededBy, declarations, _class.base, false, &totalSize, topClass, null);
else
{
uint baseSize = _class.base.templateClass ? _class.base.templateClass.structSize : _class.base.structSize;
{
Type type = ProcessType(specs, decl);
- DeclareType(member.dataType, false, false);
+ DeclareType(neededBy, member.dataType, true, false);
FreeType(type);
}
/*
case structMember:
{
OldList * specs = MkList(), * list = MkList();
+ char id[100];
+ sprintf(id, "__anon%d", anonID++);
size = 0;
- AddMembers(list, (Class)member, true, &size, topClass, null);
+ AddMembers(neededBy, list, (Class)member, true, &size, topClass, null);
ListAdd(specs,
MkStructOrUnion((member.type == unionMember)?unionSpecifier:structSpecifier, null, list));
- ListAdd(declarations, MkClassDefDeclaration(MkStructDeclaration(specs, null, null)));
+ ListAdd(declarations, MkClassDefDeclaration(MkStructDeclaration(specs, MkListOne(MkDeclaratorIdentifier(MkIdentifier(id))),null)));
alignment = member.structAlignment;
if(alignment)
return topMember ? topMember.memberID : _class.memberID;
}
-static int DeclareMembers(Class _class, bool isMember)
+static int DeclareMembers(External neededBy, Class _class, bool isMember)
{
DataMember topMember = isMember ? (DataMember) _class : null;
- uint totalSize = 0;
DataMember member;
Context context = isMember ? null : SetupTemplatesContext(_class);
if(!isMember && (_class.type == structClass || _class.type == noHeadClass) && _class.base.type != systemClass)
- DeclareMembers(_class.base, false);
+ DeclareMembers(neededBy, _class.base, false);
for(member = isMember ? topMember.members.first : _class.membersAndProperties.first; member; member = member.next)
{
{
case normalMember:
{
- /*
- if(member.dataType && member.dataType.kind == classType && member.dataType._class &&
- member.dataType._class.registered && member.dataType._class.registered.type == structClass)
- DeclareStruct(member.dataType._class.string, false);
- */
if(!member.dataType && member.dataTypeString)
member.dataType = ProcessTypeString(member.dataTypeString, false);
if(member.dataType)
- DeclareType(member.dataType, false, false);
+ DeclareType(neededBy, member.dataType, true, false);
break;
}
case unionMember:
case structMember:
{
- DeclareMembers((Class)member, true);
+ DeclareMembers(neededBy, (Class)member, true);
break;
}
}
return topMember ? topMember.memberID : _class.memberID;
}
-void DeclareStruct(char * name, bool skipNoHead)
+static void IdentifyAnonStructs(OldList/*<ClassDef>*/ * definitions)
+{
+ ClassDef def;
+ int anonID = 1;
+ for(def = definitions->first; def; def = def.next)
+ {
+ if(def.type == declarationClassDef)
+ {
+ Declaration decl = def.decl;
+ if(decl && decl.specifiers)
+ {
+ Specifier spec;
+ bool isStruct = false;
+ for(spec = decl.specifiers->first; spec; spec = spec.next)
+ {
+ if(spec.type == structSpecifier || spec.type == unionSpecifier)
+ {
+ if(spec.definitions)
+ IdentifyAnonStructs(spec.definitions);
+ isStruct = true;
+ }
+ }
+ if(isStruct)
+ {
+ Declarator d = null;
+ if(decl.declarators)
+ {
+ for(d = decl.declarators->first; d; d = d.next)
+ {
+ Identifier idDecl = GetDeclId(d);
+ if(idDecl)
+ break;
+ }
+ }
+ if(!d)
+ {
+ char id[100];
+ sprintf(id, "__anon%d", anonID++);
+ if(!decl.declarators)
+ decl.declarators = MkList();
+ ListAdd(decl.declarators, MkDeclaratorIdentifier(MkIdentifier(id)));
+ }
+ }
+ }
+ }
+ }
+}
+
+External DeclareStruct(External neededBy, const char * name, bool skipNoHead, bool needDereference)
+{
+ return _DeclareStruct(neededBy, name, skipNoHead, needDereference, false);
+}
+
+External _DeclareStruct(External neededBy, const char * name, bool skipNoHead, bool needDereference, bool fwdDecl)
{
External external = null;
Symbol classSym = FindClass(name);
+ OldList * curDeclarations = null;
- if(!inCompiler || !classSym) return;
+ if(!inCompiler || !classSym) return null;
// We don't need any declaration for bit classes...
if(classSym.registered &&
(classSym.registered.type == bitClass || classSym.registered.type == unitClass || classSym.registered.type == enumClass))
- return;
+ return null;
- /*if(classSym.registered.templateClass)
- return DeclareStruct(classSym.registered.templateClass.fullName, skipNoHead);
- */
+ if(!classSym.registered || (classSym.registered.type == normalClass && classSym.registered.structSize && classSym.registered.base && classSym.registered.base.base))
+ _DeclareStruct(neededBy, "ecere::com::Instance", false, true, fwdDecl);
+
+ external = classSym.structExternal;
- if(classSym.registered && classSym.imported && !classSym.declaredStructSym)
+ if(external && external.declaration)
+ {
+ Specifier spec;
+ for(spec = external.declaration.specifiers ? external.declaration.specifiers->first : null; spec; spec = spec.next)
+ if(spec.type == structSpecifier || spec.type == unionSpecifier)
+ {
+ curDeclarations = spec.definitions;
+ break;
+ }
+ }
+
+ if(classSym.registered && !classSym.declaring && classSym.imported && (!classSym.declaredStructSym || (classSym.registered.type == noHeadClass && !skipNoHead && external && !curDeclarations)))
{
- // Add typedef struct
- Declaration decl;
OldList * specifiers, * declarators;
OldList * declarations = null;
char structName[1024];
- external = (classSym.registered && classSym.registered.type == structClass) ?
- classSym.pointerExternal : classSym.structExternal;
-
- // TEMPORARY HACK: Pass 3 will move up struct declarations without moving members
- // Moved this one up because DeclareClass done later will need it
+ bool addedPadding = false;
+ Specifier curSpec = null;
classSym.declaring++;
if(strchr(classSym.string, '<'))
{
if(classSym.registered.templateClass)
- {
- DeclareStruct(classSym.registered.templateClass.fullName, skipNoHead);
- classSym.declaring--;
- }
- return;
+ external = _DeclareStruct(neededBy, classSym.registered.templateClass.fullName, skipNoHead, needDereference, fwdDecl);
+ classSym.declaring--;
+ return external;
}
- //if(!skipNoHead)
- DeclareMembers(classSym.registered, false);
-
structName[0] = 0;
FullClassNameCat(structName, name, false);
- /*if(!external)
- external = MkExternalDeclaration(null);*/
-
- if(!skipNoHead)
+ classSym.declaredStructSym = true;
+ if(!external || (classSym.registered.type == noHeadClass && !skipNoHead && !curDeclarations))
{
- bool addedPadding = false;
- classSym.declaredStructSym = true;
+ bool add = false;
+ if(!external)
+ {
+ external = MkExternalDeclaration(null);
+ classSym.structExternal = external;
+ external.symbol = classSym;
- declarations = MkList();
+ add = true;
+ }
- AddMembers(declarations, classSym.registered, false, null, classSym.registered, &addedPadding);
+ if(!skipNoHead)
+ {
+ declarations = MkList();
+ AddMembers(external, declarations, classSym.registered, false, null, classSym.registered, &addedPadding);
+ }
- //ListAdd(specifiers, MkSpecifier(TYPEDEF));
- //ListAdd(specifiers, MkStructOrUnion(structSpecifier, null, declarations));
+ if(external.declaration)
+ {
+ Specifier spec;
+ for(spec = external.declaration.specifiers ? external.declaration.specifiers->first : null; spec; spec = spec.next)
+ if(spec.type == structSpecifier || spec.type == unionSpecifier)
+ {
+ curSpec = spec;
+ curDeclarations = spec.definitions;
+ break;
+ }
+ }
- if(!declarations->count || (declarations->count == 1 && addedPadding))
+ if(declarations && (!declarations->count || (declarations->count == 1 && addedPadding)))
{
FreeList(declarations, FreeClassDef);
declarations = null;
}
- }
- if(skipNoHead || declarations)
- {
- if(external && external.declaration)
- {
- ((Specifier)external.declaration.specifiers->first).definitions = declarations;
-
- if(curExternal && curExternal.symbol && curExternal.symbol.idCode < classSym.id)
- {
- // TODO: Fix this
- //ast->Move(classSym.structExternal ? classSym.structExternal : classSym.pointerExternal, curExternal.prev);
-
- // DANGER
- if(classSym.structExternal)
- ast->Move(classSym.structExternal, curExternal.prev);
- ast->Move(classSym.pointerExternal, curExternal.prev);
- classSym.id = curExternal.symbol.idCode;
- classSym.idCode = curExternal.symbol.idCode;
- // external = classSym.pointerExternal;
- //external = classSym.structExternal ? classSym.structExternal : classSym.pointerExternal;
- }
+ if(classSym.registered.type != noHeadClass && !declarations)
+ {
+ FreeExternal(external);
+ external = null;
+ classSym.structExternal = null;
}
else
{
- if(!external)
- external = MkExternalDeclaration(null);
-
- specifiers = MkList();
- declarators = MkList();
- ListAdd(specifiers, MkStructOrUnion(structSpecifier, MkIdentifier(structName), declarations));
-
- /*
- d = MkDeclaratorIdentifier(MkIdentifier(structName));
- ListAdd(declarators, MkInitDeclarator(d, null));
- */
- external.declaration = decl = MkDeclaration(specifiers, declarators);
- if(decl.symbol && !decl.symbol.pointerExternal)
- decl.symbol.pointerExternal = external;
-
- // For simple classes, keep the declaration as the external to move around
- if(classSym.registered && classSym.registered.type == structClass)
- {
- char className[1024];
- strcpy(className, "__ecereClass_");
- FullClassNameCat(className, classSym.string, true);
- MangleClassName(className);
-
- // Testing This
- DeclareClass(classSym, className);
-
- external.symbol = classSym;
- classSym.pointerExternal = external;
- classSym.id = (curExternal && curExternal.symbol) ? curExternal.symbol.idCode : 0;
- classSym.idCode = (curExternal && curExternal.symbol) ? curExternal.symbol.idCode : 0;
- }
+ if(curSpec)
+ curSpec.definitions = declarations;
else
{
- char className[1024];
- strcpy(className, "__ecereClass_");
- FullClassNameCat(className, classSym.string, true);
- MangleClassName(className);
-
- // TOFIX: TESTING THIS...
- classSym.structExternal = external;
- DeclareClass(classSym, className);
- external.symbol = classSym;
+ specifiers = MkList();
+ declarators = MkList();
+ ListAdd(specifiers, MkStructOrUnion(structSpecifier, MkIdentifier(structName), declarations));
+ external.declaration = MkDeclaration(specifiers, declarators);
}
-
- //if(curExternal)
- ast->Insert(curExternal ? curExternal.prev : null, external);
+ if(add)
+ ast->Add(external);
}
}
-
classSym.declaring--;
}
- else if(curExternal && curExternal.symbol && curExternal.symbol.idCode < classSym.id)
+ else if(!classSym.declaredStructSym && classSym.structExternal)
{
- // TEMPORARY HACK: Pass 3 will move up struct declarations without moving members
- // Moved this one up because DeclareClass done later will need it
+ classSym.declaredStructSym = true;
- // TESTING THIS:
- classSym.declaring++;
+ if(classSym.registered)
+ DeclareMembers(classSym.structExternal, classSym.registered, false);
- //if(!skipNoHead)
+ if(classSym.structExternal.declaration && classSym.structExternal.declaration.specifiers)
{
- if(classSym.registered)
- DeclareMembers(classSym.registered, false);
+ Specifier spec;
+ for(spec = classSym.structExternal.declaration.specifiers->first; spec; spec = spec.next)
+ {
+ if(spec.definitions)
+ IdentifyAnonStructs(spec.definitions);
+ }
}
-
- if(classSym.registered && (classSym.registered.type == structClass || classSym.registered.type == noHeadClass))
+ }
+ if(inCompiler && neededBy && (external || !classSym.imported))
+ {
+ if(!external)
{
- // TODO: Fix this
- //ast->Move(classSym.structExternal ? classSym.structExternal : classSym.pointerExternal, curExternal.prev);
-
- // DANGER
- if(classSym.structExternal)
- ast->Move(classSym.structExternal, curExternal.prev);
- ast->Move(classSym.pointerExternal, curExternal.prev);
-
- classSym.id = curExternal.symbol.idCode;
- classSym.idCode = curExternal.symbol.idCode;
- // external = classSym.pointerExternal;
- // external = classSym.structExternal ? classSym.structExternal : classSym.pointerExternal;
+ classSym.structExternal = external = MkExternalDeclaration(null);
+ external.symbol = classSym;
+ ast->Add(external);
}
-
- classSym.declaring--;
+ if(reachedPass15 && !external.declaration && classSym.registered && classSym.registered.type == noHeadClass)
+ {
+ // Declare nohead classes without definitions here (e.g. IteratorPointer)
+ char structName[1024];
+ OldList * specifiers, * declarators;
+ structName[0] = 0;
+ FullClassNameCat(structName, name, false);
+ specifiers = MkList();
+ declarators = MkList();
+ ListAdd(specifiers, MkStructOrUnion(structSpecifier, MkIdentifier(structName), null));
+ external.declaration = MkDeclaration(specifiers, declarators);
+ }
+ if(fwdDecl)
+ {
+ External e = external.fwdDecl ? external.fwdDecl : external;
+ if(e.incoming.count)
+ neededBy.CreateUniqueEdge(e, !needDereference && !external.fwdDecl);
+ }
+ else
+ neededBy.CreateUniqueEdge(external, !needDereference);
}
- //return external;
+ return external;
}
-void DeclareProperty(Property prop, char * setName, char * getName)
+void DeclareProperty(External neededBy, Property prop, char * setName, char * getName)
{
Symbol symbol = prop.symbol;
- char propName[1024];
+ bool imported = false;
+ bool dllImport = false;
+ External structExternal = null;
+ External instExternal = null;
strcpy(setName, "__ecereProp_");
FullClassNameCat(setName, prop._class.fullName, false);
strcat(setName, "_Set_");
- // strcat(setName, prop.name);
FullClassNameCat(setName, prop.name, true);
strcpy(getName, "__ecereProp_");
FullClassNameCat(getName, prop._class.fullName, false);
strcat(getName, "_Get_");
FullClassNameCat(getName, prop.name, true);
- // strcat(getName, prop.name);
- strcpy(propName, "__ecereProp_");
- FullClassNameCat(propName, prop._class.fullName, false);
- strcat(propName, "_");
- FullClassNameCat(propName, prop.name, true);
- // strcat(propName, prop.name);
-
- // To support "char *" property
- MangleClassName(getName);
- MangleClassName(setName);
- MangleClassName(propName);
-
- if(prop._class.type == structClass)
- DeclareStruct(prop._class.fullName, false);
-
- if(!symbol || curExternal.symbol.idCode < symbol.id)
+ if(!symbol || symbol._import)
{
- bool imported = false;
- bool dllImport = false;
- if(!symbol || symbol._import)
+ if(!symbol)
{
- if(!symbol)
+ Symbol classSym;
+
+ if(!prop._class.symbol)
+ prop._class.symbol = FindClass(prop._class.fullName);
+ classSym = prop._class.symbol;
+ if(classSym && !classSym._import)
{
- Symbol classSym;
- if(!prop._class.symbol)
- prop._class.symbol = FindClass(prop._class.fullName);
- classSym = prop._class.symbol;
- if(classSym && !classSym._import)
- {
- ModuleImport module;
+ ModuleImport module;
- if(prop._class.module)
- module = FindModule(prop._class.module);
- else
- module = mainModule;
+ if(prop._class.module)
+ module = FindModule(prop._class.module);
+ else
+ module = mainModule;
- classSym._import = ClassImport
- {
- name = CopyString(prop._class.fullName);
- isRemote = prop._class.isRemote;
- };
- module.classes.Add(classSym._import);
- }
- symbol = prop.symbol = Symbol { };
- symbol._import = (ClassImport)PropertyImport
+ classSym._import = ClassImport
{
- name = CopyString(prop.name);
- isVirtual = false; //prop.isVirtual;
- hasSet = prop.Set ? true : false;
- hasGet = prop.Get ? true : false;
+ name = CopyString(prop._class.fullName);
+ isRemote = prop._class.isRemote;
};
- if(classSym)
- classSym._import.properties.Add(symbol._import);
+ module.classes.Add(classSym._import);
}
- imported = true;
- if(prop._class.module != privateModule && prop._class.module.importType != staticImport)
- dllImport = true;
- }
+ symbol = prop.symbol = Symbol { };
+ symbol._import = (ClassImport)PropertyImport
+ {
+ name = CopyString(prop.name);
+ isVirtual = false; //prop.isVirtual;
+ hasSet = prop.Set ? true : false;
+ hasGet = prop.Get ? true : false;
+ };
+ if(classSym)
+ classSym._import.properties.Add(symbol._import);
+ }
+ imported = true;
+ // Ugly work around for isNan properties declared within float/double classes which are initialized with ecereCOM
+ if((prop._class.module != privateModule || !strcmp(prop._class.name, "float") || !strcmp(prop._class.name, "double")) &&
+ prop._class.module.importType != staticImport)
+ dllImport = true;
+ }
+
+ if(!symbol.type)
+ {
+ Context context = SetupTemplatesContext(prop._class);
+ symbol.type = ProcessTypeString(prop.dataTypeString, false);
+ FinishTemplatesContext(context);
+ }
+
+ if((prop.Get && !symbol.externalGet) || (prop.Set && !symbol.externalSet))
+ {
+ if(prop._class.type == normalClass && prop._class.structSize)
+ instExternal = DeclareStruct(null, "ecere::com::Instance", false, true);
+ structExternal = DeclareStruct(null, prop._class.fullName, prop._class.type != structClass /*true*/, false);
+ }
+
+ // Get
+ if(prop.Get && !symbol.externalGet)
+ {
+ Declaration decl;
+ OldList * specifiers, * declarators;
+ Declarator d;
+ OldList * params;
+ Specifier spec = null;
+ External external;
+ Declarator typeDecl;
+ bool simple = false;
+ bool needReference;
+
+ specifiers = MkList();
+ declarators = MkList();
+ params = MkList();
+
+ ListAdd(params, MkTypeName(MkListOne(MkSpecifierName(prop._class.fullName)),
+ MkDeclaratorIdentifier(MkIdentifier("this"))));
+
+ d = MkDeclaratorIdentifier(MkIdentifier(getName));
+ //if(imported)
+ if(dllImport)
+ d = MkDeclaratorBrackets(MkDeclaratorPointer(MkPointer(null, null), d));
- if(!symbol.type)
{
Context context = SetupTemplatesContext(prop._class);
- symbol.type = ProcessTypeString(prop.dataTypeString, false);
+ typeDecl = SpecDeclFromString(prop.dataTypeString, specifiers, null);
FinishTemplatesContext(context);
}
- // Get
- if(prop.Get)
+ // Make sure the simple _class's type is declared
+ needReference = !typeDecl || typeDecl.type == identifierDeclarator;
+ for(spec = specifiers->first; spec; spec = spec.next)
{
- if(!symbol.externalGet || symbol.externalGet.type == functionExternal)
+ if(spec.type == nameSpecifier)
{
- Declaration decl;
- OldList * specifiers, * declarators;
- Declarator d;
- OldList * params;
- Specifier spec;
- External external;
- Declarator typeDecl;
- bool simple = false;
+ Symbol classSym = spec.symbol;
+ if(needReference)
+ {
+ symbol._class = classSym.registered;
+ if(classSym.registered && classSym.registered.type == structClass)
+ simple = true;
+ }
+ break;
+ }
+ }
- specifiers = MkList();
- declarators = MkList();
- params = MkList();
+ if(!simple)
+ d = PlugDeclarator(typeDecl, d);
+ else
+ {
+ ListAdd(params, MkTypeName(specifiers,
+ PlugDeclarator(typeDecl, MkDeclaratorIdentifier(MkIdentifier("value")))));
+ specifiers = MkList();
+ }
- ListAdd(params, MkTypeName(MkListOne(MkSpecifierName /*MkClassName*/(prop._class.fullName)),
- MkDeclaratorIdentifier(MkIdentifier("this"))));
+ d = MkDeclaratorFunction(d, params);
- d = MkDeclaratorIdentifier(MkIdentifier(getName));
- //if(imported)
- if(dllImport)
- d = MkDeclaratorBrackets(MkDeclaratorPointer(MkPointer(null, null), d));
+ //if(imported)
+ if(dllImport)
+ specifiers->Insert(null, MkSpecifier(EXTERN));
+ else if(prop._class.symbol && ((Symbol)prop._class.symbol).isStatic)
+ specifiers->Insert(null, MkSpecifier(STATIC));
+ if(simple)
+ ListAdd(specifiers, MkSpecifier(VOID));
- {
- Context context = SetupTemplatesContext(prop._class);
- typeDecl = SpecDeclFromString(prop.dataTypeString, specifiers, null);
- FinishTemplatesContext(context);
- }
+ ListAdd(declarators, MkInitDeclarator(d, null));
- // Make sure the simple _class's type is declared
- for(spec = specifiers->first; spec; spec = spec.next)
- {
- if(spec.type == nameSpecifier /*SpecifierClass*/)
- {
- if((!typeDecl || typeDecl.type == identifierDeclarator))
- {
- Symbol classSym = spec.symbol; // FindClass(spec.name);
- symbol._class = classSym.registered;
- if(classSym.registered && classSym.registered.type == structClass)
- {
- DeclareStruct(spec.name, false);
- simple = true;
- }
- }
- }
- }
+ decl = MkDeclaration(specifiers, declarators);
- if(!simple)
- d = PlugDeclarator(typeDecl, d);
- else
- {
- ListAdd(params, MkTypeName(specifiers,
- PlugDeclarator(typeDecl, MkDeclaratorIdentifier(MkIdentifier("value")))));
- specifiers = MkList();
- }
+ external = MkExternalDeclaration(decl);
- d = MkDeclaratorFunction(d, params);
+ if(structExternal)
+ external.CreateEdge(structExternal, false);
+ if(instExternal)
+ external.CreateEdge(instExternal, false);
- //if(imported)
- if(dllImport)
- specifiers->Insert(null, MkSpecifier(EXTERN));
- else if(prop._class.symbol && ((Symbol)prop._class.symbol).isStatic)
- specifiers->Insert(null, MkSpecifier(STATIC));
- if(simple)
- ListAdd(specifiers, MkSpecifier(VOID));
+ if(spec)
+ DeclareStruct(external, spec.name, false, needReference);
- ListAdd(declarators, MkInitDeclarator(d, null));
+ ast->Add(external);
+ external.symbol = symbol;
+ symbol.externalGet = external;
- decl = MkDeclaration(specifiers, declarators);
+ ReplaceThisClassSpecifiers(specifiers, prop._class);
- external = MkExternalDeclaration(decl);
- ast->Insert(curExternal.prev, external);
- external.symbol = symbol;
- symbol.externalGet = external;
+ if(typeDecl)
+ FreeDeclarator(typeDecl);
+ }
- ReplaceThisClassSpecifiers(specifiers, prop._class);
+ // Set
+ if(prop.Set && !symbol.externalSet)
+ {
+ Declaration decl;
+ OldList * specifiers, * declarators;
+ Declarator d;
+ OldList * params;
+ Specifier spec = null;
+ External external;
+ Declarator typeDecl;
+ bool needReference;
- if(typeDecl)
- FreeDeclarator(typeDecl);
- }
- else
- {
- // Move declaration higher...
- ast->Move(symbol.externalGet, curExternal.prev);
- }
+ declarators = MkList();
+ params = MkList();
+
+ if(!prop.conversion || prop._class.type == structClass)
+ {
+ ListAdd(params, MkTypeName(MkListOne(MkSpecifierName(prop._class.fullName)),
+ MkDeclaratorIdentifier(MkIdentifier("this"))));
}
- // Set
- if(prop.Set)
+ specifiers = MkList();
+
{
- if(!symbol.externalSet || symbol.externalSet.type == functionExternal)
- {
- Declaration decl;
- OldList * specifiers, * declarators;
- Declarator d;
- OldList * params;
- Specifier spec;
- External external;
- Declarator typeDecl;
+ Context context = SetupTemplatesContext(prop._class);
+ typeDecl = d = SpecDeclFromString(prop.dataTypeString, specifiers,
+ MkDeclaratorIdentifier(MkIdentifier("value")));
+ FinishTemplatesContext(context);
+ }
+ if(!strcmp(prop._class.base.fullName, "eda::Row") || !strcmp(prop._class.base.fullName, "eda::Id"))
+ specifiers->Insert(null, MkSpecifier(CONST));
- declarators = MkList();
- params = MkList();
+ ListAdd(params, MkTypeName(specifiers, d));
- // TESTING COMMENTING THIS FIRST LINE OUT, what was the problem? Trying to add noHeadClass here ...
- if(!prop.conversion || prop._class.type == structClass)
- {
- ListAdd(params, MkTypeName(MkListOne(MkSpecifierName/*MkClassName*/(prop._class.fullName)),
- MkDeclaratorIdentifier(MkIdentifier("this"))));
- }
+ d = MkDeclaratorIdentifier(MkIdentifier(setName));
+ if(dllImport)
+ d = MkDeclaratorBrackets(MkDeclaratorPointer(MkPointer(null, null), d));
+ d = MkDeclaratorFunction(d, params);
- specifiers = MkList();
+ // Make sure the simple _class's type is declared
+ needReference = !typeDecl || typeDecl.type == identifierDeclarator;
+ for(spec = specifiers->first; spec; spec = spec.next)
+ {
+ if(spec.type == nameSpecifier)
+ {
+ Symbol classSym = spec.symbol;
+ if(needReference)
+ symbol._class = classSym.registered;
+ break;
+ }
+ }
- {
- Context context = SetupTemplatesContext(prop._class);
- typeDecl = d = SpecDeclFromString(prop.dataTypeString, specifiers,
- MkDeclaratorIdentifier(MkIdentifier("value")));
- FinishTemplatesContext(context);
- }
- ListAdd(params, MkTypeName(specifiers, d));
+ ListAdd(declarators, MkInitDeclarator(d, null));
- d = MkDeclaratorIdentifier(MkIdentifier(setName));
- //if(imported)
- if(dllImport)
- d = MkDeclaratorBrackets(MkDeclaratorPointer(MkPointer(null, null), d));
- d = MkDeclaratorFunction(d, params);
+ specifiers = MkList();
+ if(dllImport)
+ specifiers->Insert(null, MkSpecifier(EXTERN));
+ else if(prop._class.symbol && ((Symbol)prop._class.symbol).isStatic)
+ specifiers->Insert(null, MkSpecifier(STATIC));
- // Make sure the simple _class's type is declared
- for(spec = specifiers->first; spec; spec = spec.next)
- {
- if(spec.type == nameSpecifier /*SpecifierClass*/)
- {
- if((!typeDecl || typeDecl.type == identifierDeclarator))
- {
- Symbol classSym = spec.symbol; // FindClass(spec.name);
- symbol._class = classSym.registered;
- if(classSym.registered && classSym.registered.type == structClass)
- DeclareStruct(spec.name, false);
- }
- }
- }
+ if(!prop.conversion || prop._class.type == structClass)
+ ListAdd(specifiers, MkSpecifier(VOID));
+ else
+ ListAdd(specifiers, MkSpecifierName(prop._class.fullName));
- ListAdd(declarators, MkInitDeclarator(d, null));
+ decl = MkDeclaration(specifiers, declarators);
- specifiers = MkList();
- //if(imported)
- if(dllImport)
- specifiers->Insert(null, MkSpecifier(EXTERN));
- else if(prop._class.symbol && ((Symbol)prop._class.symbol).isStatic)
- specifiers->Insert(null, MkSpecifier(STATIC));
+ external = MkExternalDeclaration(decl);
- // TESTING COMMENTING THIS FIRST LINE OUT, what was the problem? Trying to add noHeadClass here ...
- if(!prop.conversion || prop._class.type == structClass)
- ListAdd(specifiers, MkSpecifier(VOID));
- else
- ListAdd(specifiers, MkSpecifierName/*MkClassName*/(prop._class.fullName));
+ if(structExternal)
+ external.CreateEdge(structExternal, false);
+ if(instExternal)
+ external.CreateEdge(instExternal, false);
- decl = MkDeclaration(specifiers, declarators);
+ if(spec)
+ DeclareStruct(external, spec.name, false, needReference);
- external = MkExternalDeclaration(decl);
- ast->Insert(curExternal.prev, external);
- external.symbol = symbol;
- symbol.externalSet = external;
+ ast->Add(external);
+ external.symbol = symbol;
+ symbol.externalSet = external;
- ReplaceThisClassSpecifiers(specifiers, prop._class);
- }
- else
- {
- // Move declaration higher...
- ast->Move(symbol.externalSet, curExternal.prev);
- }
- }
+ ReplaceThisClassSpecifiers(specifiers, prop._class);
+ }
+
+ // Property (for Watchers)
+ if(!symbol.externalPtr)
+ {
+ Declaration decl;
+ External external;
+ OldList * specifiers = MkList();
+ char propName[1024];
- // Property (for Watchers)
- if(!symbol.externalPtr)
+ if(imported)
+ specifiers->Insert(null, MkSpecifier(EXTERN));
+ else
{
- Declaration decl;
- External external;
- OldList * specifiers = MkList();
+ specifiers->Insert(null, MkSpecifier(STATIC));
+ specifiers->Add(MkSpecifierExtended(MkExtDeclAttrib(MkAttrib(ATTRIB, MkListOne(MkAttribute(CopyString("unused"), null))))));
+ }
- if(imported)
- specifiers->Insert(null, MkSpecifier(EXTERN));
- else
- specifiers->Insert(null, MkSpecifier(STATIC));
+ ListAdd(specifiers, MkSpecifierName("Property"));
+
+ strcpy(propName, "__ecereProp_");
+ FullClassNameCat(propName, prop._class.fullName, false);
+ strcat(propName, "_");
+ FullClassNameCat(propName, prop.name, true);
- ListAdd(specifiers, MkSpecifierName("Property"));
+ {
+ OldList * list = MkList();
+ ListAdd(list, MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier(propName)), null));
+ if(!imported)
{
- OldList * list = MkList();
- ListAdd(list, MkInitDeclarator(MkDeclaratorPointer(MkPointer(null, null),
- MkDeclaratorIdentifier(MkIdentifier(propName))), null));
+ strcpy(propName, "__ecerePropM_");
+ FullClassNameCat(propName, prop._class.fullName, false);
+ strcat(propName, "_");
+ FullClassNameCat(propName, prop.name, true);
- if(!imported)
- {
- strcpy(propName, "__ecerePropM_");
- FullClassNameCat(propName, prop._class.fullName, false);
- strcat(propName, "_");
- // strcat(propName, prop.name);
- FullClassNameCat(propName, prop.name, true);
+ ListAdd(list, MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier(propName)), null));
+ }
+ decl = MkDeclaration(specifiers, list);
+ }
- MangleClassName(propName);
+ external = MkExternalDeclaration(decl);
+ ast->Insert(curExternal.prev, external);
+ external.symbol = symbol;
+ symbol.externalPtr = external;
+ }
- ListAdd(list, MkInitDeclarator(MkDeclaratorPointer(MkPointer(null, null),
- MkDeclaratorIdentifier(MkIdentifier(propName))), null));
- }
- decl = MkDeclaration(specifiers, list);
- }
+ if(inCompiler && neededBy)
+ {
+ // Could improve this to create edge on only what is needed...
+ if(symbol.externalPtr)
+ neededBy.CreateUniqueEdge(symbol.externalPtr, false);
- external = MkExternalDeclaration(decl);
- ast->Insert(curExternal.prev, external);
- external.symbol = symbol;
- symbol.externalPtr = external;
- }
- else
- {
- // Move declaration higher...
- ast->Move(symbol.externalPtr, curExternal.prev);
- }
+ if(symbol.externalGet)
+ neededBy.CreateUniqueEdge(symbol.externalGet, symbol.externalGet.type == functionExternal);
+
+ if(symbol.externalSet)
+ neededBy.CreateUniqueEdge(symbol.externalSet, symbol.externalSet.type == functionExternal);
- symbol.id = curExternal.symbol.idCode;
+ // IsSet ?
}
}
ClassTemplateArgument arg = _class.templateArgs[id];
if(arg.dataTypeString)
{
+ bool constant = type.constant;
// FreeType(type);
type = ProcessTypeString(arg.dataTypeString, false);
+ if(type.kind == classType && constant) type.constant = true;
+ else if(type.kind == pointerType)
+ {
+ Type t = type.type;
+ while(t.kind == pointerType) t = t.type;
+ if(constant) t.constant = constant;
+ }
freeType = true;
if(type && _class.templateClass)
type.passAsTemplate = true;
{
Class expClass = type._class.registered;
Class cClass = null;
- int c;
int paramCount = 0;
int lastParam = -1;
Expression exp;
char * string = PrintHexUInt64(arg.expression.ui64);
exp = MkExpCast(MkTypeName(specs, decl), MkExpConstant(string));
+ delete string;
ProcessExpressionType(exp);
ComputeExpression(exp);
}
}
//else if(!MatchTypes(member.exp.expType, type, null, _class, null, true, true, false, false))
- else if(!MatchTypes(member.initializer.exp.expType, type, null, null, _class, true, true, false, false))
+ else if(!MatchTypes(member.initializer.exp.expType, type, null, null, _class, true, true, false, false, true))
{
Compiler_Error($"incompatible instance method %s\n", ident.string);
}
if(inst._class)
{
MembersInit members;
- Symbol classSym; // = inst._class.symbol; // FindClass(inst._class.name);
+ Symbol classSym;
Class _class;
- /*if(!inst._class.symbol)
- inst._class.symbol = FindClass(inst._class.name);*/
classSym = inst._class.symbol;
_class = classSym ? classSym.registered : null;
- // DANGER: Patch for mutex not declaring its struct when not needed
if(!_class || _class.type != noHeadClass)
- DeclareStruct(inst._class.name, false); //_class && _class.type == noHeadClass);
+ DeclareStruct(curExternal, inst._class.name, false, true);
afterExternal = afterExternal ? afterExternal : curExternal;
if(inCompiler)
{
char number[16];
- //members.function.dontMangle = true;
strcpy(name, "__ecereInstMeth_");
FullClassNameCat(name, _class ? _class.fullName : "_UNKNOWNCLASS", false);
strcat(name, "_");
symbol.type.thisClass = _class.symbol;
}
}
- // TESTING THIS HERE:
- DeclareType(symbol.type, true, true);
+ DeclareType(curExternal, symbol.type, true, true);
}
else if(classSym)
}
}
- //declarator.symbol.id = declarator.symbol.idCode = curExternal.symbol.idCode;
createdExternal = ProcessClassFunction(classSym ? classSym.registered : null, members.function, ast, afterExternal, true);
if(nameID)
FreeSpecifier(nameID._class);
nameID._class = null;
}
-
- if(inCompiler)
- {
-
- Type type = declarator.symbol.type;
- External oldExternal = curExternal;
-
- // *** Commented this out... Any negative impact? Yes: makes double prototypes declarations... Why was it commented out?
- // *** It was commented out for problems such as
- /*
- class VirtualDesktop : Window
- {
- clientSize = Size { };
- Timer timer
- {
- bool DelayExpired()
- {
- clientSize.w;
- return true;
- }
- };
- }
- */
- // Commented Out: Good for bet.ec in Poker (Otherwise: obj\bet.c:187: error: `currentBet' undeclared (first use in this function))
-
- declarator.symbol.id = declarator.symbol.idCode = curExternal.symbol.idCode;
-
- /*
- if(strcmp(declarator.symbol.string, name))
- {
- printf("TOCHECK: Look out for this\n");
- delete declarator.symbol.string;
- declarator.symbol.string = CopyString(name);
- }
-
- if(!declarator.symbol.parent && globalContext.symbols.root != (BTNode)declarator.symbol)
- {
- printf("TOCHECK: Will this ever be in a list? Yes.\n");
- excludedSymbols->Remove(declarator.symbol);
- globalContext.symbols.Add((BTNode)declarator.symbol);
- if(strstr(declarator.symbol.string), "::")
- globalContext.hasNameSpace = true;
-
- }
- */
-
- //curExternal = curExternal.prev;
- //afterExternal = afterExternal->next;
-
- //ProcessFunction(afterExternal->function);
-
- //curExternal = afterExternal;
- {
- External externalDecl;
- externalDecl = MkExternalDeclaration(null);
- ast->Insert(oldExternal.prev, externalDecl);
-
- // Which function does this process?
- if(createdExternal.function)
- {
- ProcessFunction(createdExternal.function);
-
- //curExternal = oldExternal;
-
- {
- //Declaration decl = MkDeclaration(members.function.specifiers, MkListOne(MkInitDeclarator(CopyDeclarator(declarator), null)));
-
- Declaration decl = MkDeclaration(CopyList(createdExternal.function.specifiers, CopySpecifier),
- MkListOne(MkInitDeclarator(CopyDeclarator(declarator), null)));
-
- //externalDecl = MkExternalDeclaration(decl);
-
- //***** ast->Insert(external.prev, externalDecl);
- //ast->Insert(curExternal.prev, externalDecl);
- externalDecl.declaration = decl;
- if(decl.symbol && !decl.symbol.pointerExternal)
- decl.symbol.pointerExternal = externalDecl;
-
- // Trying this out...
- declarator.symbol.pointerExternal = externalDecl;
- }
- }
- }
- }
+
+ curExternal = createdExternal;
+ if(inCompiler)
+ {
+ if(createdExternal.function)
+ ProcessFunction(createdExternal.function);
+ }
else if(declarator)
{
curExternal = declarator.symbol.pointerExternal;
}
}
-static void DeclareType(Type type, bool declarePointers, bool declareParams)
+void DeclareType(External neededFor, Type type, bool needDereference, bool forFunctionDef)
+{
+ _DeclareType(neededFor, type, needDereference, forFunctionDef, false);
+}
+
+void DeclareTypeForwardDeclare(External neededFor, Type type, bool needDereference, bool forFunctionDef)
+{
+ _DeclareType(neededFor, type, needDereference, forFunctionDef, true);
+}
+
+static void _DeclareType(External neededFor, Type type, bool needDereference, bool forFunctionDef, bool fwdDecl)
{
- // OPTIMIZATIONS: TESTING THIS...
if(inCompiler)
{
if(type.kind == functionType)
{
Type param;
- if(declareParams)
- {
- for(param = type.params.first; param; param = param.next)
- DeclareType(param, declarePointers, true);
- }
- DeclareType(type.returnType, declarePointers, true);
+ for(param = type.params.first; param; param = param.next)
+ _DeclareType(neededFor, param, forFunctionDef, false, fwdDecl);
+ _DeclareType(neededFor, type.returnType, forFunctionDef, false, fwdDecl);
}
- else if(type.kind == pointerType && declarePointers)
- DeclareType(type.type, declarePointers, false);
+ else if(type.kind == pointerType)
+ _DeclareType(neededFor, type.type, false, false, fwdDecl);
else if(type.kind == classType)
{
- if(type._class.registered && (type._class.registered.type == structClass || type._class.registered.type == noHeadClass) && !type._class.declaring)
- DeclareStruct(type._class.registered.fullName, type._class.registered.type == noHeadClass);
+ Class c = type._class.registered;
+ _DeclareStruct(neededFor, c ? c.fullName : "ecere::com::Instance", c ? c.type == noHeadClass : false, needDereference && c && c.type == structClass, fwdDecl);
}
else if(type.kind == structType || type.kind == unionType)
{
Type member;
for(member = type.members.first; member; member = member.next)
- DeclareType(member, false, false);
+ _DeclareType(neededFor, member, needDereference, forFunctionDef, fwdDecl);
}
else if(type.kind == arrayType)
- DeclareType(type.arrayType, declarePointers, false);
+ _DeclareType(neededFor, type.arrayType, true, false, fwdDecl);
}
}
}
}
-public void DeclareMethod(Method method, char * name)
+public void DeclareMethod(External neededFor, Method method, const char * name)
{
Symbol symbol = method.symbol;
- if(!symbol || (!symbol.pointerExternal && method.type == virtualMethod) || symbol.id > (curExternal ? curExternal.symbol.idCode : -1))
+ if(!symbol || (!symbol.pointerExternal && (!symbol.methodCodeExternal || method.type == virtualMethod)))
{
- bool imported = false;
bool dllImport = false;
if(!method.dataType)
method.dataType = ProcessTypeString(method.dataTypeString, false);
- if(!symbol || symbol._import || method.type == virtualMethod)
+ //if(!symbol || symbol._import || method.type == virtualMethod)
{
if(!symbol || method.type == virtualMethod)
{
}
if(!symbol)
{
- // Set the symbol type
- /*
- if(!type.thisClass)
- {
- type.thisClass = method._class.symbol; // FindClass(method._class.fullName);
- }
- else if(type.thisClass == (void *)-1)
- {
- type.thisClass = null;
- }
- */
- // symbol.type = ProcessTypeString(method.dataTypeString, false);
symbol.type = method.dataType;
if(symbol.type) symbol.type.refCount++;
}
- /*
- if(!method.thisClass || strcmp(method.thisClass, "void"))
- symbol.type.params.Insert(null,
- MkClassType(method.thisClass ? method.thisClass : method._class.fullName));
- */
}
if(!method.dataType.dllExport)
{
- imported = true;
- if(method._class.module != privateModule && method._class.module.importType != staticImport)
+ if((method._class.module != privateModule || !strcmp(method._class.name, "float") || !strcmp(method._class.name, "double")) && method._class.module.importType != staticImport)
dllImport = true;
}
}
- /* MOVING THIS UP
- if(!method.dataType)
- method.dataType = ((Symbol)method.symbol).type;
- //ProcessMethodType(method);
- */
-
- if(method.type != virtualMethod && method.dataType)
- DeclareType(method.dataType, true, true);
-
- if(!symbol.pointerExternal || symbol.pointerExternal.type == functionExternal)
+ if(inCompiler)
{
// We need a declaration here :)
Declaration decl;
specifiers = MkList();
declarators = MkList();
- //if(imported)
if(dllImport)
ListAdd(specifiers, MkSpecifier(EXTERN));
else if(method._class.symbol && ((Symbol)method._class.symbol).isStatic)
else
{
d = MkDeclaratorIdentifier(MkIdentifier(name));
- //if(imported)
if(dllImport)
d = MkDeclaratorBrackets(MkDeclaratorPointer(MkPointer(null, null), d));
{
{
Class _class = method.dataType.thisClass ? method.dataType.thisClass.registered : method._class;
TypeName thisParam = MkTypeName(MkListOne(
- MkSpecifierName/*MkClassName*/(method.dataType.thisClass ? method.dataType.thisClass.string : method._class.fullName)),
+ MkSpecifierName(method.dataType.thisClass ? method.dataType.thisClass.string : method._class.fullName)),
(_class && _class.type == systemClass) ? MkDeclaratorPointer(MkPointer(null,null), MkDeclaratorIdentifier(MkIdentifier("this"))) : MkDeclaratorIdentifier(MkIdentifier("this")));
TypeName firstParam = ((TypeName)funcDecl.function.parameters->first);
Specifier firstSpec = firstParam.qualifiers ? firstParam.qualifiers->first : null;
funcDecl.function.parameters->Insert(null, thisParam);
}
}
- // Make sure we don't have empty parameter declarations for static methods...
- /*
- else if(!funcDecl.function.parameters)
- {
- funcDecl.function.parameters = MkList();
- funcDecl.function.parameters->Insert(null,
- MkTypeName(MkListOne(MkSpecifier(VOID)),null));
- }*/
}
- // TESTING THIS:
- ProcessDeclarator(d);
+ ProcessDeclarator(d, true);
ListAdd(declarators, MkInitDeclarator(d, null));
ReplaceThisClassSpecifiers(specifiers, method._class);
- // Keep a different symbol for the function definition than the declaration...
- if(symbol.pointerExternal)
- {
- Symbol functionSymbol { };
-
- // Copy symbol
- {
- *functionSymbol = *symbol;
- functionSymbol.string = CopyString(symbol.string);
- if(functionSymbol.type)
- functionSymbol.type.refCount++;
- }
-
- excludedSymbols->Add(functionSymbol);
- symbol.pointerExternal.symbol = functionSymbol;
- }
external = MkExternalDeclaration(decl);
- if(curExternal)
- ast->Insert(curExternal ? curExternal.prev : null, external);
external.symbol = symbol;
symbol.pointerExternal = external;
+ ast->Add(external);
+ DeclareStruct(external, method._class.fullName, true, true);
+ if(method.dataType)
+ DeclareType(external, method.dataType, true, true);
}
- else if(ast)
- {
- // Move declaration higher...
- ast->Move(symbol.pointerExternal, curExternal.prev);
- }
-
- symbol.id = curExternal ? curExternal.symbol.idCode : MAXINT;
+ }
+ if(inCompiler && neededFor)
+ {
+ External external = symbol.pointerExternal ? symbol.pointerExternal : symbol.methodCodeExternal;
+ neededFor.CreateUniqueEdge(external, external.type == functionExternal);
}
}
Type ReplaceThisClassType(Class _class)
{
+ Type type;
if(thisClassParams && _class.templateParams.count && !_class.templateClass)
{
bool first = true;
className[len++] = '>';
className[len++] = '\0';
}
- return MkClassType(className);
- //return ProcessTypeString(className, false);
+ type = MkClassType(className);
+ //type = ProcessTypeString(className, false);
}
else
{
- return MkClassType(_class.fullName);
- //return ProcessTypeString(_class.fullName, false);
+ type = MkClassType(_class.fullName);
+ //type = ProcessTypeString(_class.fullName, false);
}
+ //type.wasThisClass = true;
+ return type;
}
void ReplaceThisClassSpecifiers(OldList specs, Class _class)
}
// Returns imported or not
-bool DeclareFunction(GlobalFunction function, char * name)
+bool DeclareFunction(External neededFor, GlobalFunction function, char * name)
{
Symbol symbol = function.symbol;
- if(curExternal && (!symbol || symbol.id > curExternal.symbol.idCode))
+ // TOCHECK: Might get rid of the pointerExternal check in favor of marking the edge as breakable
+ if(!symbol || !symbol.pointerExternal)
{
bool imported = false;
bool dllImport = false;
dllImport = true;
}
- DeclareType(function.dataType, true, true);
-
if(inCompiler)
{
- if(!symbol.pointerExternal || symbol.pointerExternal.type == functionExternal)
+ // TOCHECK: What's with the functionExternal check here? Is it Edge breaking / forward declaration?
+ //if(!symbol.pointerExternal || symbol.pointerExternal.type == functionExternal)
{
// We need a declaration here :)
Declaration decl;
specifiers = MkList();
declarators = MkList();
- //if(imported)
- ListAdd(specifiers, MkSpecifier(EXTERN));
- /*
- else
- ListAdd(specifiers, MkSpecifier(STATIC));
- */
+ ListAdd(specifiers, MkSpecifier(EXTERN));
d = MkDeclaratorIdentifier(MkIdentifier(imported ? name : function.name));
- //if(imported)
if(dllImport)
d = MkDeclaratorBrackets(MkDeclaratorPointer(MkPointer(null, null), d));
}
// Keep a different symbol for the function definition than the declaration...
- if(symbol.pointerExternal)
+ /* Note: This should be handled by the edge breaking...
+ if(symbol.pointerExternal && symbol.pointerExternal.type == functionExternal)
{
Symbol functionSymbol { };
// Copy symbol
symbol.pointerExternal.symbol = functionSymbol;
}
+ */
external = MkExternalDeclaration(decl);
- if(curExternal)
- ast->Insert(curExternal.prev, external);
+ ast->Add(external);
external.symbol = symbol;
symbol.pointerExternal = external;
- }
- else
- {
- // Move declaration higher...
- ast->Move(symbol.pointerExternal, curExternal.prev);
- }
- if(curExternal)
- symbol.id = curExternal.symbol.idCode;
+ DeclareType(external, function.dataType, true, true);
+ }
}
}
+ if(inCompiler && neededFor && symbol && symbol.pointerExternal)
+ neededFor.CreateUniqueEdge(symbol.pointerExternal, symbol.pointerExternal.type == functionExternal);
return (symbol && symbol._import && function.module != privateModule && function.module.importType != staticImport) ? true : false;
}
-void DeclareGlobalData(GlobalData data)
+void DeclareGlobalData(External neededFor, GlobalData data)
{
Symbol symbol = data.symbol;
- if(curExternal && (!symbol || symbol.id > curExternal.symbol.idCode))
+ // TOCHECK: Might get rid of the pointerExternal check in favor of marking the edge as breakable
+ if(!symbol || !symbol.pointerExternal)
{
if(inCompiler)
{
}
if(!data.dataType)
data.dataType = ProcessTypeString(data.dataTypeString, false);
- DeclareType(data.dataType, true, true);
+
if(inCompiler)
{
- if(!symbol.pointerExternal)
- {
- // We need a declaration here :)
- Declaration decl;
- OldList * specifiers, * declarators;
- Declarator d;
- External external;
-
- specifiers = MkList();
- declarators = MkList();
+ // We need a declaration here :)
+ Declaration decl;
+ OldList * specifiers, * declarators;
+ Declarator d;
+ External external;
- ListAdd(specifiers, MkSpecifier(EXTERN));
- d = MkDeclaratorIdentifier(MkIdentifier(data.fullName));
- d = SpecDeclFromString(data.dataTypeString, specifiers, d);
+ specifiers = MkList();
+ declarators = MkList();
- ListAdd(declarators, MkInitDeclarator(d, null));
+ ListAdd(specifiers, MkSpecifier(EXTERN));
+ d = MkDeclaratorIdentifier(MkIdentifier(data.fullName));
+ d = SpecDeclFromString(data.dataTypeString, specifiers, d);
- decl = MkDeclaration(specifiers, declarators);
- external = MkExternalDeclaration(decl);
- if(curExternal)
- ast->Insert(curExternal.prev, external);
- external.symbol = symbol;
- symbol.pointerExternal = external;
- }
- else
- {
- // Move declaration higher...
- ast->Move(symbol.pointerExternal, curExternal.prev);
- }
+ ListAdd(declarators, MkInitDeclarator(d, null));
+ decl = MkDeclaration(specifiers, declarators);
+ external = MkExternalDeclaration(decl);
if(curExternal)
- symbol.id = curExternal.symbol.idCode;
+ ast->Insert(curExternal.prev, external);
+ external.symbol = symbol;
+ symbol.pointerExternal = external;
+
+ DeclareType(external, data.dataType, true, true);
}
}
+ if(inCompiler && neededFor && symbol && symbol.pointerExternal)
+ neededFor.CreateUniqueEdge(symbol.pointerExternal, false);
}
class Conversion : struct
Type resultType;
};
-public bool MatchTypes(Type source, Type dest, OldList conversions, Class owningClassSource, Class owningClassDest, bool doConversion, bool enumBaseType, bool acceptReversedParams, bool isConversionExploration)
+static bool CheckConstCompatibility(Type source, Type dest, bool warn)
+{
+ bool status = true;
+ if(((source.kind == classType && source._class && source._class.registered) || source.kind == arrayType || source.kind == pointerType) &&
+ ((dest.kind == classType && dest._class && dest._class.registered) || /*dest.kind == arrayType || */dest.kind == pointerType))
+ {
+ Class sourceClass = source.kind == classType ? source._class.registered : null;
+ Class destClass = dest.kind == classType ? dest._class.registered : null;
+ if((!sourceClass || (sourceClass && sourceClass.type == normalClass && !sourceClass.structSize)) &&
+ (!destClass || (destClass && destClass.type == normalClass && !destClass.structSize)))
+ {
+ Type sourceType = source, destType = dest;
+ while((sourceType.kind == pointerType || sourceType.kind == arrayType) && sourceType.type) sourceType = sourceType.type;
+ while((destType.kind == pointerType || destType.kind == arrayType) && destType.type) destType = destType.type;
+ if(!destType.constant && sourceType.constant)
+ {
+ status = false;
+ if(warn)
+ Compiler_Warning($"discarding const qualifier\n");
+ }
+ }
+ }
+ return status;
+}
+
+public bool MatchTypes(Type source, Type dest, OldList conversions, Class owningClassSource, Class owningClassDest, bool doConversion, bool enumBaseType, bool acceptReversedParams,
+ bool isConversionExploration, bool warnConst)
{
if(source && dest)
{
+ if(warnConst)
+ CheckConstCompatibility(source, dest, true);
// Property convert;
if(source.kind == templateType && dest.kind != templateType)
if(type) dest = type;
}
- if(dest.classObjectType == typedObject)
+ if(dest.classObjectType == typedObject && dest.kind != functionType)
{
if(source.classObjectType != anyObject)
return true;
}
else
{
- if(source.classObjectType == anyObject)
+ if(source.kind != functionType && source.classObjectType == anyObject)
return true;
- if(dest.classObjectType == anyObject && source.classObjectType != typedObject)
+ if(dest.kind != functionType && dest.classObjectType == anyObject && source.classObjectType != typedObject)
return true;
}
if(!isConversionExploration && source.kind == pointerType && source.type.kind == voidType &&
((dest.kind == classType && (!dest._class || !dest._class.registered || dest._class.registered.type == structClass || dest._class.registered.type == normalClass || dest._class.registered.type == noHeadClass || dest._class.registered.type == systemClass))
|| dest.kind == subClassType || dest.kind == pointerType || dest.kind == arrayType || dest.kind == functionType || dest.kind == thisClassType)
-
/* dest.kind != voidType && dest.kind != structType && dest.kind != unionType */
/*&& (dest.kind != classType || dest._class.registered.type != structClass)*/)
else
{
// Added this so that DefinedColor = Color doesn't go through ColorRGB property
- if(enumBaseType &&
- dest._class && dest._class.registered && dest._class.registered.type == enumClass &&
- ((source._class && source._class.registered && source._class.registered.type != enumClass) || source.kind == classType)) // Added this here for a base enum to be acceptable for a derived enum (#139)
+ if(dest._class && dest._class.registered && source._class && source._class.registered &&
+ (dest.casted || (enumBaseType && dest._class.registered.type == enumClass &&
+ (source.kind == classType || // Added this here for a base enum to be acceptable for a derived enum (#139)
+ source._class.registered.type != enumClass)
+ ) ) )
{
if(eClass_IsDerived(dest._class.registered, source._class.registered))
{
if(!convert.dataType)
convert.dataType = ProcessTypeString(convert.dataTypeString, false);
- if(MatchTypes(convert.dataType, dest, conversions, null, null, false, true, false, true))
+ // Only go ahead with this conversion flow while processing an existing conversion if the conversion data type is a class
+ if((!isConversionExploration || convert.dataType.kind == classType || !strcmp(_class.name, "String")) &&
+ MatchTypes(convert.dataType, dest, conversions, null, null,
+ (convert.dataType.kind == classType && !strcmp(convert.dataTypeString, "String")) ? true : false,
+ convert.dataType.kind == classType, false, true, warnConst))
{
if(!conversions && !convert.Get)
return true;
Conversion conv { convert = convert, isGet = true };
// conversions.Add(conv);
conversions.Insert(after, conv);
+
return true;
}
}
{
if(convert.memberAccess == publicAccess || _class.module == privateModule)
{
+ Type constType = null;
+ bool success = false;
// Conversion after = (conversions != null) ? conversions.last : null;
if(!convert.dataType)
convert.dataType = ProcessTypeString(convert.dataTypeString, false);
+
+ if(warnConst && convert.dataType.kind == pointerType && convert.dataType.type && dest.constant)
+ {
+ Type ptrType { };
+ constType = { kind = pointerType, refCount = 1, type = ptrType };
+ CopyTypeInto(ptrType, convert.dataType.type);
+ ptrType.constant = true;
+ }
+
// Just added this equality check to prevent recursion.... Make it safer?
// Changed enumBaseType to false here to prevent all int-compatible enums to show up in AnchorValues
- if(convert.dataType != dest && MatchTypes(source, convert.dataType, conversions, null, null, true, false /*true*/, false, true))
+ if((constType || convert.dataType != dest) && MatchTypes(source, constType ? constType : convert.dataType, conversions, null, null, true, false /*true*/, false, true, warnConst))
{
if(!conversions && !convert.Set)
- return true;
+ success = true;
else if(conversions != null)
{
if(_class.type == unitClass && convert.dataType.kind == classType && convert.dataType._class &&
convert.dataType._class.registered && _class.base == convert.dataType._class.registered.base &&
(source.kind != classType || source._class.registered != _class.base))
- return true;
+ success = true;
else
{
// *** Testing this! ***
Conversion conv { convert = convert };
conversions.Add(conv);
//conversions.Insert(after, conv);
- return true;
+ success = true;
}
}
}
+ if(constType)
+ FreeType(constType);
+ if(success)
+ return true;
}
}
}
if(dest._class.registered.dataType.kind == classType || source.truth || dest.truth/* ||
!strcmp(dest._class.registered.name, "bool") || (source.kind == classType && !strcmp(source._class.string, "bool"))*/)
{
- if(MatchTypes(source, dest._class.registered.dataType, conversions, null, null, true, true, false, false))
+ if(MatchTypes(source, dest._class.registered.dataType, conversions, null, null, true, dest._class.registered.dataType.kind == classType, false, false, warnConst))
{
return true;
}
if(!convert.dataType)
convert.dataType = ProcessTypeString(convert.dataTypeString, false);
- if(convert.dataType != source && MatchTypes(convert.dataType, dest, conversions, null, null, true, true, false, true))
+ if(convert.dataType != source &&
+ (!isConversionExploration || convert.dataType.kind == classType || !strcmp(_class.name, "String")) &&
+ MatchTypes(convert.dataType, dest, conversions, null, null, convert.dataType.kind == classType, convert.dataType.kind == classType, false, true, warnConst))
{
if(!conversions && !convert.Get)
return true;
{
if(!source._class.registered.dataType)
source._class.registered.dataType = ProcessTypeString(source._class.registered.dataTypeString, false);
- if(MatchTypes(source._class.registered.dataType, dest, conversions, null, null, true, true, false, false))
+ if(!isConversionExploration || source._class.registered.dataType.kind == classType || !strcmp(source._class.registered.name, "String"))
{
- return true;
+ if(MatchTypes(source._class.registered.dataType, dest, conversions, null, null, source._class.registered.dataType.kind == classType, source._class.registered.dataType.kind == classType, false, false, warnConst))
+ return true;
+ // For bool to be accepted by byte, short, etc.
+ else if(MatchTypes(dest, source._class.registered.dataType, null, null, null, false, false, false, false, warnConst))
+ return true;
}
}
}
else if(source.kind == enumType &&
(dest.kind == intType || dest.kind == shortType || dest.kind == charType || source.kind == _BoolType || dest.kind == longType || dest.kind == int64Type || dest.kind == intPtrType || dest.kind == intSizeType))
return true;
- else if(dest.kind == enumType &&
+ else if(dest.kind == enumType && !isConversionExploration &&
(source.kind == intType || source.kind == shortType || source.kind == charType || source.kind == _BoolType || source.kind == longType || source.kind == int64Type || source.kind == intPtrType || source.kind == intSizeType))
return true;
else if((dest.kind == functionType || (dest.kind == pointerType && dest.type.kind == functionType) || dest.kind == methodType) &&
// Source return type must be derived from destination return type
- if(!MatchTypes(source.returnType, dest.returnType, null, null, null, true, true, false, false))
+ if(!MatchTypes(source.returnType, dest.returnType, null, null, null, true, true, false, false, warnConst))
{
Compiler_Warning($"incompatible return type for function\n");
return false;
}
+ // The const check is backwards from the MatchTypes above (for derivative classes checks)
+ else
+ CheckConstCompatibility(dest.returnType, source.returnType, true);
// Check parameters
}
// paramDest must be derived from paramSource
- if(!MatchTypes(paramDestType, paramSourceType, null, null, null, true, true, false, false) &&
- (!acceptReversedParams || !MatchTypes(paramSourceType, paramDestType, null, null, null, true, true, false, false)))
+ if(!MatchTypes(paramDestType, paramSourceType, null, null, null, true, true, false, false, warnConst) &&
+ (!acceptReversedParams || !MatchTypes(paramSourceType, paramDestType, null, null, null, true, true, false, false, warnConst)))
{
char type[1024];
type[0] = 0;
else if((dest.kind == pointerType || dest.kind == arrayType) &&
(source.kind == arrayType || source.kind == pointerType))
{
- if(MatchTypes(source.type, dest.type, null, null, null, true, true, false, false))
- return true;
+ // Pointers to pointer is incompatible with non normal/nohead classes
+ if(!(dest.type && dest.type.kind == pointerType && source.type.kind == classType && source.type._class &&
+ source.type._class.registered && (source.type._class.registered.type != normalClass && source.type._class.registered.type != noHeadClass) && !source.type.byReference))
+ {
+ ComputeTypeSize(source.type);
+ ComputeTypeSize(dest.type);
+ if(source.type.size == dest.type.size && MatchTypes(source.type, dest.type, null, null, null, true, true, false, false, warnConst))
+ return true;
+ }
}
}
return false;
_class.symbol = FindClass(_class.fullName);
type._class = _class.symbol;
- if(MatchTypes(type, dest, &converts, null, null, true, false, false, false))
+ if(MatchTypes(type, dest, &converts, null, null, dest.kind != classType || !dest._class || strcmp(dest._class.string, "bool"),
+ false, false, false, false))
{
- NamedLink value;
+ NamedLink64 value;
Class enumClass = eSystem_FindClass(privateModule, "enum");
if(enumClass)
{
}
if(value)
{
- FreeExpContents(sourceExp);
FreeType(sourceExp.expType);
sourceExp.isConstant = true;
sourceExp.expType = MkClassType(baseClass.fullName);
- //if(inCompiler)
+ if(inCompiler || inPreCompiler || inDebugger)
{
char constant[256];
+ FreeExpContents(sourceExp);
+
sourceExp.type = constantExp;
- if(!strcmp(baseClass.dataTypeString, "int"))
- sprintf(constant, "%d",(int)value.data);
+ if(!strcmp(baseClass.dataTypeString, "int") || !strcmp(baseClass.dataTypeString, "int64") || !strcmp(baseClass.dataTypeString, "short") || !strcmp(baseClass.dataTypeString, "char"))
+ sprintf(constant, FORMAT64D, value.data);
else
- sprintf(constant, "0x%X",(int)value.data);
+ sprintf(constant, FORMAT64HEXLL, value.data);
sourceExp.constant = CopyString(constant);
//for(;baseClass.base && baseClass.base.type != systemClass; baseClass = baseClass.base);
}
return false;
}
-bool MatchTypeExpression(Expression sourceExp, Type dest, OldList conversions, bool skipUnitBla)
+bool MatchTypeExpression(Expression sourceExp, Type dest, OldList conversions, bool skipUnitBla, bool warnConst)
{
- Type source = sourceExp.expType;
+ Type source;
Type realDest = dest;
Type backupSourceExpType = null;
+ Expression nbExp = GetNonBracketsExp(sourceExp);
+ Expression computedExp = nbExp;
+ dest.refCount++;
+
+ if(sourceExp.isConstant && sourceExp.type != constantExp && sourceExp.type != identifierExp && sourceExp.type != castExp &&
+ dest.kind == classType && dest._class && dest._class.registered && dest._class.registered.type == enumClass)
+ {
+ computedExp = CopyExpression(nbExp); // Keep the original expression, but compute for checking enum ranges
+ ComputeExpression(computedExp /*sourceExp*/);
+ }
+
+ source = sourceExp.expType;
if(dest.kind == pointerType && sourceExp.type == constantExp && !strtoul(sourceExp.constant, null, 0))
+ {
+ if(computedExp != nbExp)
+ {
+ FreeExpression(computedExp);
+ computedExp = nbExp;
+ }
+ FreeType(dest);
return true;
+ }
if(!skipUnitBla && source && dest && source.kind == classType && dest.kind == classType)
{
destBase = destBase.base);
//if(source._class.registered == dest._class.registered)
if(sourceBase == destBase)
- return true;
- }
+ {
+ if(computedExp != nbExp)
+ {
+ FreeExpression(computedExp);
+ computedExp = nbExp;
+ }
+ FreeType(dest);
+ return true;
+ }
+ }
}
if(source)
int64 value = MAXINT;
source.refCount++;
- dest.refCount++;
- if(sourceExp.type == constantExp)
+ if(computedExp.type == constantExp)
{
if(source.isSigned)
- value = strtoll(sourceExp.constant, null, 0);
+ value = strtoll(computedExp.constant, null, 0);
else
- value = strtoull(sourceExp.constant, null, 0);
+ value = strtoull(computedExp.constant, null, 0);
}
- else if(sourceExp.type == opExp && sourceExp.op.op == '-' && !sourceExp.op.exp1 && sourceExp.op.exp2 && sourceExp.op.exp2.type == constantExp)
+ else if(computedExp.type == opExp && computedExp.op.op == '-' && !computedExp.op.exp1 && computedExp.op.exp2 && computedExp.op.exp2.type == constantExp)
{
if(source.isSigned)
- value = -strtoll(sourceExp.op.exp2.constant, null, 0);
+ value = -strtoll(computedExp.op.exp2.constant, null, 0);
else
- value = -strtoull(sourceExp.op.exp2.constant, null, 0);
+ value = -strtoull(computedExp.op.exp2.constant, null, 0);
+ }
+ if(computedExp != nbExp)
+ {
+ FreeExpression(computedExp);
+ computedExp = nbExp;
}
if(dest.kind != classType && source.kind == classType && source._class && source._class.registered &&
- !strcmp(source._class.registered.fullName, "ecere::com::unichar"))
+ !strcmp(source._class.registered.fullName, "unichar" /*"ecere::com::unichar"*/))
{
FreeType(source);
source = Type { kind = intType, isSigned = false, refCount = 1 };
tempType._class = _class.symbol;
tempType.truth = dest.truth;
if(tempType._class)
- MatchTypes(tempSource, tempDest, conversions, null, null, true, true, false, false);
+ MatchTypes(tempSource, tempDest, conversions, null, null, true, true, false, false, warnConst);
// NOTE: To handle bad warnings on int64 vs 32 bit eda::Id incompatibilities
backupSourceExpType = sourceExp.expType;
- sourceExp.expType = dest; dest.refCount++;
+ if(dest.passAsTemplate)
+ {
+ // Don't carry passAsTemplate
+ sourceExp.expType = { };
+ CopyTypeInto(sourceExp.expType, dest);
+ sourceExp.expType.passAsTemplate = false;
+ }
+ else
+ {
+ sourceExp.expType = dest;
+ dest.refCount++;
+ }
//sourceExp.expType = MkClassType(_class.fullName);
flag = true;
{
if(!dest._class.registered.dataType)
dest._class.registered.dataType = ProcessTypeString(dest._class.registered.dataTypeString, false);
- if(MatchTypes(source, dest._class.registered.dataType, conversions, null, null, true, true, false, false))
+ if(MatchTypes(source, dest._class.registered.dataType, conversions, null, null, true, true, false, false, warnConst))
{
FreeType(source);
FreeType(sourceExp.expType);
{
Class _class = source._class ? source._class.registered : null;
- if(_class && (_class.type == unitClass || !strcmp(_class.fullName, "bool") || /*_class.type == enumClass || */_class.type == bitClass )) // TOCHECK: enumClass, bitClass is new here...
+ if(_class && (_class.type == unitClass || /*!strcmp(_class.fullName, "bool") || _class.type == enumClass || */_class.type == bitClass )) // TOCHECK: enumClass, bitClass is new here...
{
/*
if(dest.kind != classType)
tempType.classObjectType = source.classObjectType;
if(tempType._class)
- MatchTypes(tempSource, tempDest, conversions, null, null, true, true, false, false);
+ MatchTypes(tempSource, tempDest, conversions, null, null, true, true, false, false, warnConst);
// PUT THIS BACK TESTING UNITS?
- if(conversions.last)
+ if(conversions && conversions.last)
{
((Conversion)(conversions.last)).resultType = dest;
dest.refCount++;
if(!flag)
{
- if(MatchTypes(source, dest, conversions, null, null, true, true, false, false))
+ if(MatchTypes(source, dest, conversions, null, null, true, true, false, false, warnConst))
{
FreeType(source);
FreeType(dest);
if(dest.kind == classType)
{
Class _class = dest._class ? dest._class.registered : null;
- if(_class && !dest.truth && (_class.type == unitClass || !strcmp(_class.fullName, "bool") ||
+ bool fittingValue = false;
+ if(_class && _class.type == enumClass)
+ {
+ Class enumClass = eSystem_FindClass(privateModule, "enum");
+ EnumClassData c = ACCESS_CLASSDATA(_class, enumClass);
+ if(c && value >= 0 && value <= c.largest)
+ fittingValue = true;
+ }
+
+ if(_class && !dest.truth && (_class.type == unitClass || fittingValue ||
(/*_class.type == enumClass*/_class.type != structClass && !value && source.kind == intType) || _class.type == bitClass)) // TOCHECK: enumClass, bitClass is new here...
{
if(_class.type == normalClass || _class.type == noHeadClass)
else if(dest.kind == charType && (source.kind == _BoolType || source.kind == charType || source.kind == enumType || source.kind == shortType || source.kind == intType) &&
(dest.isSigned ? (value >= -128 && value <= 127) : (value >= 0 && value <= 255)))
{
- specs = MkList();
- if(!dest.isSigned) ListAdd(specs, MkSpecifier(UNSIGNED));
- ListAdd(specs, MkSpecifier(CHAR));
+ if(source.kind == intType)
+ {
+ FreeType(dest);
+ FreeType(source);
+ if(backupSourceExpType) FreeType(backupSourceExpType);
+ return true;
+ }
+ else
+ {
+ specs = MkList();
+ if(!dest.isSigned) ListAdd(specs, MkSpecifier(UNSIGNED));
+ ListAdd(specs, MkSpecifier(CHAR));
+ }
}
else if(dest.kind == shortType && (source.kind == enumType || source.kind == _BoolType || source.kind == charType || source.kind == shortType ||
(source.kind == intType && (dest.isSigned ? (value >= -32768 && value <= 32767) : (value >= 0 && value <= 65535)))))
{
- specs = MkList();
- if(!dest.isSigned) ListAdd(specs, MkSpecifier(UNSIGNED));
- ListAdd(specs, MkSpecifier(SHORT));
+ if(source.kind == intType)
+ {
+ FreeType(dest);
+ FreeType(source);
+ if(backupSourceExpType) FreeType(backupSourceExpType);
+ return true;
+ }
+ else
+ {
+ specs = MkList();
+ if(!dest.isSigned) ListAdd(specs, MkSpecifier(UNSIGNED));
+ ListAdd(specs, MkSpecifier(SHORT));
+ }
}
else if(dest.kind == intType && (source.kind == enumType || source.kind == shortType || source.kind == _BoolType || source.kind == charType || source.kind == intType))
{
return false;
}
- if(!flag)
+ if(!flag && !sourceExp.opDestType)
{
Expression newExp { };
*newExp = *sourceExp;
}
else
{
+ if(computedExp != nbExp)
+ {
+ FreeExpression(computedExp);
+ computedExp = nbExp;
+ }
+
while((sourceExp.type == bracketsExp || sourceExp.type == extensionExpressionExp) && sourceExp.list) sourceExp = sourceExp.list->last;
if(sourceExp.type == identifierExp)
{
{
for( ; _class && _class.type == ClassType::enumClass; _class = _class.base)
{
- NamedLink value;
+ NamedLink64 value;
EnumClassData e = ACCESS_CLASSDATA(_class, enumClass);
for(value = e.values.first; value; value = value.next)
{
}
if(value)
{
- FreeExpContents(sourceExp);
FreeType(sourceExp.expType);
sourceExp.isConstant = true;
sourceExp.expType = MkClassType(_class.fullName);
- //if(inCompiler)
+ if(inCompiler || inPreCompiler || inDebugger)
{
- char constant[256];
+ FreeExpContents(sourceExp);
+
sourceExp.type = constantExp;
- if(/*_class && */_class.dataTypeString && !strcmp(_class.dataTypeString, "int")) // _class cannot be null here!
- sprintf(constant, "%d", (int) value.data);
+ if(_class.dataTypeString && (!strcmp(_class.dataTypeString, "int") || !strcmp(_class.dataTypeString, "int64") || !strcmp(_class.dataTypeString, "short") || !strcmp(_class.dataTypeString, "char"))) // _class cannot be null here!
+ sourceExp.constant = PrintInt64(value.data);
else
- sprintf(constant, "0x%X", (int) value.data);
- sourceExp.constant = CopyString(constant);
+ sourceExp.constant = PrintUInt64(value.data);
//for(;_class.base && _class.base.type != systemClass; _class = _class.base);
}
+ FreeType(dest);
return true;
}
}
// Loop through all enum classes
if(dest.classObjectType != typedObject && dest.kind == classType /*!= ellipsisType */&& MatchWithEnums_Module(privateModule, sourceExp, dest, id.string, conversions))
+ {
+ FreeType(dest);
return true;
+ }
}
+ FreeType(dest);
}
return false;
}
{ \
t value2 = op2.m; \
exp.type = constantExp; \
- exp.string = p(op1.m o value2); \
+ exp.string = p((t)(op1.m o value2)); \
if(!exp.expType) \
{ exp.expType = op1.type; if(op1.type) op1.type.refCount++; } \
return true; \
}
-#define BINARY_DIVIDE(o, name, m, t, p) \
+#define BINARY_DIVIDEINT(o, name, m, t, p) \
static bool name(Expression exp, Operand op1, Operand op2) \
{ \
t value2 = op2.m; \
exp.type = constantExp; \
- exp.string = p(value2 ? (op1.m o value2) : 0); \
+ exp.string = p(value2 ? ((t)(op1.m o value2)) : 0); \
+ if(!exp.expType) \
+ { exp.expType = op1.type; if(op1.type) op1.type.refCount++; } \
+ return true; \
+ }
+
+#define BINARY_DIVIDEREAL(o, name, m, t, p) \
+ static bool name(Expression exp, Operand op1, Operand op2) \
+ { \
+ t value2 = op2.m; \
+ exp.type = constantExp; \
+ exp.string = p((t)(op1.m o value2)); \
if(!exp.expType) \
{ exp.expType = op1.type; if(op1.type) op1.type.refCount++; } \
return true; \
#define OPERATOR_ALL(macro, o, name) \
macro(o, Int##name, i, int, PrintInt) \
macro(o, UInt##name, ui, unsigned int, PrintUInt) \
- macro(o, Int64##name, i, int, PrintInt64) \
- macro(o, UInt64##name, ui, unsigned int, PrintUInt64) \
+ macro(o, Int64##name, i64, int64, PrintInt64) \
+ macro(o, UInt64##name, ui64, uint64, PrintUInt64) \
macro(o, Short##name, s, short, PrintShort) \
macro(o, UShort##name, us, unsigned short, PrintUShort) \
macro(o, Char##name, c, char, PrintChar) \
#define OPERATOR_INTTYPES(macro, o, name) \
macro(o, Int##name, i, int, PrintInt) \
macro(o, UInt##name, ui, unsigned int, PrintUInt) \
- macro(o, Int64##name, i, int, PrintInt64) \
- macro(o, UInt64##name, ui, unsigned int, PrintUInt64) \
+ macro(o, Int64##name, i64, int64, PrintInt64) \
+ macro(o, UInt64##name, ui64, uint64, PrintUInt64) \
macro(o, Short##name, s, short, PrintShort) \
macro(o, UShort##name, us, unsigned short, PrintUShort) \
macro(o, Char##name, c, char, PrintChar) \
macro(o, UChar##name, uc, unsigned char, PrintUChar)
+#define OPERATOR_REALTYPES(macro, o, name) \
+ macro(o, Float##name, f, float, PrintFloat) \
+ macro(o, Double##name, d, double, PrintDouble)
// binary arithmetic
OPERATOR_ALL(BINARY, +, Add)
OPERATOR_ALL(BINARY, -, Sub)
OPERATOR_ALL(BINARY, *, Mul)
-OPERATOR_ALL(BINARY_DIVIDE, /, Div)
-OPERATOR_INTTYPES(BINARY_DIVIDE, %, Mod)
+OPERATOR_INTTYPES(BINARY_DIVIDEINT, /, Div)
+OPERATOR_REALTYPES(BINARY_DIVIDEREAL, /, Div)
+OPERATOR_INTTYPES(BINARY_DIVIDEINT, %, Mod)
// unary arithmetic
OPERATOR_ALL(UNARY, -, Neg)
OPERATOR_ALL(BINARY, +=, AddAsign)
OPERATOR_ALL(BINARY, -=, SubAsign)
OPERATOR_ALL(BINARY, *=, MulAsign)
-OPERATOR_ALL(BINARY_DIVIDE, /=, DivAsign)
-OPERATOR_INTTYPES(BINARY_DIVIDE, %=, ModAsign)
+OPERATOR_INTTYPES(BINARY_DIVIDEINT, /=, DivAsign)
+OPERATOR_REALTYPES(BINARY_DIVIDEREAL, /=, DivAsign)
+OPERATOR_INTTYPES(BINARY_DIVIDEINT, %=, ModAsign)
// binary bitwise
OPERATOR_INTTYPES(BINARY, &, BitAnd)
OPERATOR_ALL(BINARY, <=, SmaEqu)
// tertiary condition operator
-OPERATOR_ALL(TERTIARY, ?, Cond)
+OPERATOR_INTTYPES(TERTIARY, ?, Cond)
//Add, Sub, Mul, Div, Mod, , Neg, Inc, Dec, Asign, AddAsign, SubAsign, MulAsign, DivAsign, ModAsign, BitAnd, BitOr, BitXor, LShift, RShift, BitNot, AndAsign, OrAsign, XorAsign, LShiftAsign, RShiftAsign, Not, Equ, Nqu, And, Or, Grt, Sma, GrtEqu, SmaEqu
#define OPERATOR_TABLE_ALL(name, type) \
case 'v': output[d] = '\v'; break;
case '\\': output[d] = '\\'; break;
case '\"': output[d] = '\"'; break;
- default: output[d++] = '\\'; output[d] = ch;
- //default: output[d] = ch;
+ case '\'': output[d] = '\''; break;
+ default: output[d] = ch;
}
d++;
escaped = false;
output[d] = '\0';
}
+// String Unescape Copy
+
+// TOFIX: THIS DOESN'T HANDLE NUMERIC ESCAPE CODES (OCTAL/HEXADECIMAL...)?
+// This is the same as ReadString above (which also misses numeric escape codes) except it doesn't handle external quotes
+public int UnescapeString(char * d, char * s, int len)
+{
+ int j = 0, k = 0;
+ char ch;
+ while(j < len && (ch = s[j]))
+ {
+ switch(ch)
+ {
+ case '\\':
+ switch((ch = s[++j]))
+ {
+ case 'n': d[k] = '\n'; break;
+ case 't': d[k] = '\t'; break;
+ case 'a': d[k] = '\a'; break;
+ case 'b': d[k] = '\b'; break;
+ case 'f': d[k] = '\f'; break;
+ case 'r': d[k] = '\r'; break;
+ case 'v': d[k] = '\v'; break;
+ case '\\': d[k] = '\\'; break;
+ case '\"': d[k] = '\"'; break;
+ case '\'': d[k] = '\''; break;
+ default: d[k] = '\\'; d[k] = ch;
+ }
+ break;
+ default:
+ d[k] = ch;
+ }
+ j++, k++;
+ }
+ d[k] = '\0';
+ return k;
+}
+
+public char * OffsetEscapedString(char * s, int len, int offset)
+{
+ char ch;
+ int j = 0, k = 0;
+ while(j < len && k < offset && (ch = s[j]))
+ {
+ if(ch == '\\') ++j;
+ j++, k++;
+ }
+ return (k == offset) ? s + j : null;
+}
+
public Operand GetOperand(Expression exp)
{
Operand op { };
Type type = exp.expType;
if(type)
{
- while(type.kind == classType &&
+ while(type.kind == classType && type._class &&
type._class.registered && (type._class.registered.type == bitClass || type._class.registered.type == unitClass || type._class.registered.type == enumClass))
{
if(!type._class.registered.dataType)
type = type._class.registered.dataType;
}
- op.kind = type.kind;
- op.type = exp.expType;
- if(exp.isConstant && exp.type == constantExp)
+ if(exp.type == stringExp && op.kind == pointerType)
+ {
+ op.ui64 = (uint64)(uintptr)exp.string;
+ op.kind = pointerType;
+ op.ops = uint64Ops;
+ }
+ else if(exp.isConstant && exp.type == constantExp)
{
+ op.kind = type.kind;
+ op.type = type;
+
switch(op.kind)
{
case _BoolType:
case charType:
{
if(exp.constant[0] == '\'')
+ {
op.c = exp.constant[1];
+ op.ops = charOps;
+ }
else if(type.isSigned)
{
op.c = (char)strtol(exp.constant, null, 0);
break;
}
case shortType:
- if(type.isSigned)
+ if(exp.constant[0] == '\'')
+ {
+ op.s = exp.constant[1];
+ op.ops = shortOps;
+ }
+ else if(type.isSigned)
{
op.s = (short)strtol(exp.constant, null, 0);
op.ops = shortOps;
break;
case intType:
case longType:
- if(type.isSigned)
+ if(exp.constant[0] == '\'')
+ {
+ op.i = exp.constant[1];
+ op.ops = intOps;
+ }
+ else if(type.isSigned)
{
op.i = (int)strtol(exp.constant, null, 0);
op.ops = intOps;
if(type.isSigned)
{
op.i64 = (int64)_strtoi64(exp.constant, null, 0);
- op.ops = intOps;
+ op.ops = int64Ops;
}
else
{
op.ui64 = (uint64)_strtoui64(exp.constant, null, 0);
- op.ops = uintOps;
+ op.ops = uint64Ops;
}
op.kind = int64Type;
break;
op.kind = int64Type;
break;
case floatType:
- op.f = (float)strtod(exp.constant, null);
+ if(!strcmp(exp.constant, "inf")) op.f = float::inf();
+ else if(!strcmp(exp.constant, "-inf")) op.f = -float::inf();
+ else if(!strcmp(exp.constant, "nan")) op.f = float::nan();
+ else if(!strcmp(exp.constant, "-nan")) op.f = -float::nan();
+ else
+ op.f = (float)strtod(exp.constant, null);
op.ops = floatOps;
break;
case doubleType:
- op.d = (double)strtod(exp.constant, null);
+ if(!strcmp(exp.constant, "inf")) op.d = double::inf();
+ else if(!strcmp(exp.constant, "-inf")) op.d = -double::inf();
+ else if(!strcmp(exp.constant, "nan")) op.d = double::nan();
+ else if(!strcmp(exp.constant, "-nan")) op.d = -double::nan();
+ else
+ op.d = (double)strtod(exp.constant, null);
op.ops = doubleOps;
break;
//case classType: For when we have operator overloading...
case classType:
op.ui64 = _strtoui64(exp.constant, null, 0);
op.kind = pointerType;
- op.ops = uintOps;
+ op.ops = uint64Ops;
// op.ptrSize =
break;
}
return op;
}
-static void UnusedFunction()
+static int64 GetEnumValue(Class _class, void * ptr)
+{
+ int64 v = 0;
+ switch(_class.typeSize)
+ {
+ case 8:
+ if(!strcmp(_class.dataTypeString, "uint64"))
+ v = (int64)*(uint64 *)ptr;
+ else
+ v = (int64)*(int64 *)ptr;
+ break;
+ case 4:
+ if(!strcmp(_class.dataTypeString, "uint"))
+ v = (int64)*(uint *)ptr;
+ else
+ v = (int64)*(int *)ptr;
+ break;
+ case 2:
+ if(!strcmp(_class.dataTypeString, "uint16"))
+ v = (int64)*(uint16 *)ptr;
+ else
+ v = (int64)*(short *)ptr;
+ break;
+ case 1:
+ if(!strcmp(_class.dataTypeString, "byte"))
+ v = (int64)*(byte *)ptr;
+ else
+ v = (int64)*(char *)ptr;
+ break;
+ }
+ return v;
+}
+
+static __attribute__((unused)) void UnusedFunction()
{
int a;
a.OnGetString(0,0,0);
if(enumClass)
{
EnumClassData e = ACCESS_CLASSDATA(_class, enumClass);
- NamedLink item;
+ NamedLink64 item;
for(item = e.values.first; item; item = item.next)
{
- if((int)item.data == *(int *)ptr)
+ if(item.data == GetEnumValue(_class, ptr))
{
result = item.name;
break;
{
FreeExpContents(exp);
// TODO: This should probably use proper type
- exp.constant = PrintInt64((int64)*(intptr*)ptr);
+ exp.constant = PrintInt64((int64)*(intsize*)ptr);
exp.type = constantExp;
break;
}
if(enumClass)
{
EnumClassData e = ACCESS_CLASSDATA(_class, enumClass);
- NamedLink item;
+ NamedLink64 item;
for(item = e.values.first; item; item = item.next)
{
- if((int)item.data == *(int *)ptr)
+ if(item.data == GetEnumValue(_class, ptr))
{
result = item.name;
break;
Property prop = null;
DataMember dataMember = null;
- Method method = null;
uint dataMemberOffset;
if(!ident)
if(type.kind == classType)
{
Class _class = type._class.registered;
- if(_class.type == bitClass || _class.type == unitClass ||
- _class.type == enumClass)
+ if(_class && (_class.type == bitClass || _class.type == unitClass || _class.type == enumClass))
{
if(!_class.dataType)
_class.dataType = ProcessTypeString(_class.dataTypeString, false);
}
}
}
- else if(prop)
+ else if(prop && prop.Set != (void *)(intptr)1)
{
if(value.type == instanceExp && value.instance.data)
{
{
BitMember bitMember = (BitMember) dataMember;
Type type;
- int part = 0;
- GetInt(value, &part);
+ uint64 part = 0;
bits = (bits & ~bitMember.mask);
if(!bitMember.dataType)
bitMember.dataType = ProcessTypeString(bitMember.dataTypeString, false);
-
type = bitMember.dataType;
-
if(type.kind == classType && type._class && type._class.registered)
{
if(!type._class.registered.dataType)
type._class.registered.dataType = ProcessTypeString(type._class.registered.dataTypeString, false);
type = type._class.registered.dataType;
}
-
switch(type.kind)
{
case _BoolType:
- case charType:
- if(type.isSigned)
- bits |= ((char)part << bitMember.pos);
- else
- bits |= ((unsigned char)part << bitMember.pos);
- break;
- case shortType:
- if(type.isSigned)
- bits |= ((short)part << bitMember.pos);
- else
- bits |= ((unsigned short)part << bitMember.pos);
- break;
+ case charType: { byte v; type.isSigned ? GetChar(value, (char *)&v) : GetUChar(value, &v); part = (uint64)v; break; }
+ case shortType: { uint16 v; type.isSigned ? GetShort(value, (short *)&v) : GetUShort(value, &v); part = (uint64)v; break; }
case intType:
- case longType:
- if(type.isSigned)
- bits |= ((int)part << bitMember.pos);
- else
- bits |= ((unsigned int)part << bitMember.pos);
- break;
- case int64Type:
- if(type.isSigned)
- bits |= ((int64)part << bitMember.pos);
- else
- bits |= ((uint64)part << bitMember.pos);
- break;
- case intPtrType:
- if(type.isSigned)
- {
- bits |= ((intptr)part << bitMember.pos);
- }
- else
- {
- bits |= ((uintptr)part << bitMember.pos);
- }
- break;
- case intSizeType:
- if(type.isSigned)
- {
- bits |= ((ssize_t)(intsize)part << bitMember.pos);
- }
- else
- {
- bits |= ((size_t) (uintsize)part << bitMember.pos);
- }
- break;
+ case longType: { uint v; type.isSigned ? GetInt(value, (int *)&v) : GetUInt(value, &v); part = (uint64)v; break; }
+ case int64Type: { uint64 v; type.isSigned ? GetInt64(value, (int64 *)&v) : GetUInt64(value, &v); part = (uint64)v; break; }
+ case intPtrType: { uintptr v; type.isSigned ? GetIntPtr(value, (intptr *)&v) : GetUIntPtr(value, &v); part = (uint64)v; break; }
+ case intSizeType: { uintsize v; type.isSigned ? GetIntSize(value, (intsize *)&v) : GetUIntSize(value, &v); part = (uint64)v; break; }
}
+ bits |= part << bitMember.pos;
}
}
}
}
}
+static bool Promote(Operand op, TypeKind kind, bool isSigned)
+{
+ bool result = false;
+ switch(kind)
+ {
+ case shortType:
+ if(op.kind == charType || op.kind == enumType || op.kind == _BoolType)
+ result = isSigned ? GetOpShort(op, &op.s) : GetOpUShort(op, &op.us);
+ break;
+ case intType:
+ case longType:
+ if(op.kind == charType || op.kind == shortType || op.kind == enumType || op.kind == _BoolType)
+ result = isSigned ? GetOpInt(op, &op.i) : GetOpUInt(op, &op.ui);
+ break;
+ case int64Type:
+ if(op.kind == charType || op.kind == shortType || op.kind == intType || op.kind == int64Type || op.kind == longType || op.kind == floatType || op.kind == doubleType ||
+ op.kind == pointerType || op.kind == enumType || op.kind == intPtrType || op.kind == intSizeType || op.kind == _BoolType)
+ result = isSigned ? GetOpInt64(op, &op.i64) : GetOpUInt64(op, &op.ui64);
+ break;
+ case floatType:
+ if(op.kind == charType || op.kind == shortType || op.kind == intType || op.kind == int64Type || op.kind == longType ||
+ op.kind == enumType || op.kind == intPtrType || op.kind == intSizeType || op.kind == _BoolType)
+ result = GetOpFloat(op, &op.f);
+ break;
+ case doubleType:
+ if(op.kind == charType || op.kind == shortType || op.kind == intType || op.kind == int64Type || op.kind == longType || op.kind == floatType ||
+ op.kind == enumType || op.kind == intPtrType || op.kind == intSizeType || op.kind == _BoolType)
+ result = GetOpDouble(op, &op.d);
+ break;
+ case pointerType:
+ if(op.kind == charType || op.kind == shortType || op.kind == intType || op.kind == int64Type || op.kind == longType || op.kind == floatType || op.kind == doubleType ||
+ op.kind == pointerType || op.kind == enumType || op.kind == intPtrType || op.kind == intSizeType || op.kind == _BoolType)
+ result = GetOpUInt64 /*GetOpUIntPtr*/(op, &op.ui64);
+ break;
+ case enumType:
+ if(op.kind == charType || op.kind == shortType || op.kind == intType || op.kind == int64Type || op.kind == longType || op.kind == floatType || op.kind == doubleType ||
+ op.kind == pointerType || op.kind == enumType || op.kind == intPtrType || op.kind == intSizeType || op.kind == _BoolType)
+ result = isSigned ? GetOpInt(op, &op.i) : GetOpUInt(op, &op.ui);
+ break;
+ case intPtrType:
+ if(op.kind == charType || op.kind == shortType || op.kind == intType || op.kind == longType || op.kind == enumType || op.kind == _BoolType)
+ result = isSigned ? GetOpInt64 /*GetOpIntPtr*/(op, &op.i64) : GetOpUInt64 /*GetOpUIntPtr*/(op, &op.ui64);
+ break;
+ case intSizeType:
+ if(op.kind == charType || op.kind == shortType || op.kind == intType || op.kind == longType || op.kind == enumType || op.kind == _BoolType)
+ result = isSigned ? GetOpInt64 /*GetOpIntSize*/(op, &op.i64) : GetOpUInt64 /*GetOpUIntSize*/(op, &op.ui64);
+ break;
+ }
+ return result;
+}
+
void CallOperator(Expression exp, Expression exp1, Expression exp2, Operand op1, Operand op2)
{
if(exp.op.op == SIZEOF)
}
else
{
+ if(op1 && op2 && op1.type && op2.type && op1.kind != op2.kind)
+ {
+ if(Promote(op2, op1.kind, op1.type.isSigned))
+ op2.kind = op1.kind, op2.ops = op1.ops;
+ else if(Promote(op1, op2.kind, op2.type.isSigned))
+ op1.kind = op2.kind, op1.ops = op2.ops;
+ }
switch(exp.op.op)
{
// binary arithmetic
void ComputeExpression(Expression exp)
{
+#ifdef _DEBUG
char expString[10240];
expString[0] = '\0';
-#ifdef _DEBUG
PrintExpression(exp, expString);
#endif
switch(exp.type)
{
+ case identifierExp:
+ {
+ Identifier id = exp.identifier;
+ if(id && exp.isConstant && !inCompiler && !inPreCompiler && !inDebugger)
+ {
+ Class c = (exp.expType && exp.expType.kind == classType && exp.expType._class) ? exp.expType._class.registered : null;
+ if(c && c.type == enumClass)
+ {
+ Class enumClass = eSystem_FindClass(privateModule, "enum");
+ if(enumClass)
+ {
+ NamedLink64 value;
+ EnumClassData e = ACCESS_CLASSDATA(c, enumClass);
+ for(value = e.values.first; value; value = value.next)
+ {
+ if(!strcmp(value.name, id.string))
+ break;
+ }
+ if(value)
+ {
+ const String dts = c.dataTypeString;
+ FreeExpContents(exp);
+ exp.type = constantExp;
+ exp.constant = (dts && (!strcmp(dts, "int") || !strcmp(dts, "int64") || !strcmp(dts, "short") || !strcmp(dts, "char"))) ? PrintInt64(value.data) : PrintUInt64(value.data);
+ }
+ }
+ }
+ }
+ break;
+ }
case instanceExp:
{
ComputeInstantiation(exp);
// We don't care about operations with only exp2 (INC_OP, DEC_OP...)
if(exp.op.exp2)
- ComputeExpression(exp.op.exp2);
+ {
+ Expression e = exp.op.exp2;
+
+ while((e.type == bracketsExp || e.type == extensionExpressionExp || e.type == extensionCompoundExp) && e.list)
+ {
+ if(e.type == bracketsExp || e.type == extensionExpressionExp || e.type == extensionCompoundExp)
+ {
+ if(e.type == extensionCompoundExp)
+ e = ((Statement)e.compound.compound.statements->last).expressions->last;
+ else
+ e = e.list->last;
+ }
+ }
+ if(exp.op.op == TokenType::sizeOf && e && e.expType)
+ {
+ if(e.type == stringExp && e.string)
+ {
+ char * string = e.string;
+ int len = strlen(string);
+ char * tmp = new char[len-2+1];
+ len = UnescapeString(tmp, string + 1, len - 2);
+ delete tmp;
+ FreeExpContents(exp);
+ exp.type = constantExp;
+ exp.constant = PrintUInt(len + 1);
+ }
+ else
+ {
+ Type type = e.expType;
+ type.refCount++;
+ FreeExpContents(exp);
+ exp.type = constantExp;
+ exp.constant = PrintUInt(ComputeTypeSize(type));
+ FreeType(type);
+ }
+ break;
+ }
+ else
+ ComputeExpression(exp.op.exp2);
+ }
if(exp.op.exp1)
{
ComputeExpression(exp.op.exp1);
if(!n)
{
OldList * list = exp.list;
+ Expression prev = exp.prev;
+ Expression next = exp.next;
+
+ // For operations which set the exp type on brackets exp after the inner exp was processed...
+ if(exp.expType && exp.expType.kind == classType && (!e.expType || e.expType.kind != classType))
+ {
+ FreeType(e.expType);
+ e.expType = exp.expType;
+ e.expType.refCount++;
+ }
ComputeExpression(e);
//FreeExpContents(exp);
FreeType(exp.expType);
FreeType(exp.destType);
*exp = *e;
+ exp.prev = prev;
+ exp.next = next;
delete e;
delete list;
}
void (*Set)(void *, void *) = (void *)prop.Set;
exp.instance = Instantiation { };
exp.instance.data = new0 byte[_class.structSize];
- exp.instance._class = MkSpecifierName/*MkClassName*/(_class.fullName);
+ exp.instance._class = MkSpecifierName(_class.fullName);
exp.instance.loc = exp.loc;
exp.type = instanceExp;
Set(exp.instance.data, value.instance.data);
exp.instance = Instantiation { };
exp.instance.data = new0 byte[_class.structSize];
- exp.instance._class = MkSpecifierName/*MkClassName*/(_class.fullName);
+ exp.instance._class = MkSpecifierName(_class.fullName);
exp.instance.loc = exp.loc;
exp.type = instanceExp;
exp.instance = Instantiation { };
exp.instance.data = new0 byte[_class.structSize];
- exp.instance._class = MkSpecifierName/*MkClassName*/(_class.fullName);
+ exp.instance._class = MkSpecifierName(_class.fullName);
exp.instance.loc = exp.loc;
exp.type = instanceExp;
exp.instance = Instantiation { };
exp.instance.data = new0 byte[_class.structSize];
- exp.instance._class = MkSpecifierName/*MkClassName*/(_class.fullName);
+ exp.instance._class = MkSpecifierName(_class.fullName);
exp.instance.loc = exp.loc;
exp.type = instanceExp;
PopulateInstance(exp.instance);
break;
}
+ case floatType:
+ {
+ float floatValue;
+ void (*Set)(void *, float) = (void *)prop.Set;
+
+ exp.instance = Instantiation { };
+ exp.instance.data = new0 byte[_class.structSize];
+ exp.instance._class = MkSpecifierName(_class.fullName);
+ exp.instance.loc = exp.loc;
+ exp.type = instanceExp;
+
+ GetFloat(value, &floatValue);
+
+ Set(exp.instance.data, floatValue);
+ PopulateInstance(exp.instance);
+ break;
+ }
case doubleType:
{
double doubleValue;
exp.instance = Instantiation { };
exp.instance.data = new0 byte[_class.structSize];
- exp.instance._class = MkSpecifierName/*MkClassName*/(_class.fullName);
+ exp.instance._class = MkSpecifierName(_class.fullName);
exp.instance.loc = exp.loc;
exp.type = instanceExp;
exp.instance = Instantiation { };
exp.instance.data = new0 byte[_class.structSize];
- exp.instance._class = MkSpecifierName/*MkClassName*/(_class.fullName);
+ exp.instance._class = MkSpecifierName(_class.fullName);
exp.instance.loc = exp.loc;
//exp.instance.fullSet = true;
exp.type = instanceExp;
}
else if(_class.type == structClass)
{
- char * value = (exp.member.exp.type == instanceExp ) ? exp.member.exp.instance.data : null;
+ byte * value = (exp.member.exp.type == instanceExp ) ? exp.member.exp.instance.data : null;
switch(type.kind)
{
case classType:
exp.instance = Instantiation { };
exp.instance.data = new0 byte[_class.structSize];
- exp.instance._class = MkSpecifierName/*MkClassName*/(_class.fullName);
+ exp.instance._class = MkSpecifierName(_class.fullName);
exp.instance.loc = exp.loc;
//exp.instance.fullSet = true;
exp.type = instanceExp;
char className[1024];
strcpy(className, "__ecereClass_");
FullClassNameCat(className, classSym.string, true);
- MangleClassName(className);
- DeclareClass(classSym, className);
+ DeclareClass(curExternal, classSym, className);
FreeExpContents(exp);
exp.type = pointerExp;
case charType:
if(type.isSigned)
{
- char value;
- GetChar(e, &value);
- FreeExpContents(exp);
- exp.constant = PrintChar(value);
- exp.type = constantExp;
+ char value = 0;
+ if(GetChar(e, &value))
+ {
+ FreeExpContents(exp);
+ exp.constant = PrintChar(value);
+ exp.type = constantExp;
+ }
}
else
{
- unsigned char value;
- GetUChar(e, &value);
- FreeExpContents(exp);
- exp.constant = PrintUChar(value);
- exp.type = constantExp;
+ unsigned char value = 0;
+ if(GetUChar(e, &value))
+ {
+ FreeExpContents(exp);
+ exp.constant = PrintUChar(value);
+ exp.type = constantExp;
+ }
}
break;
case shortType:
if(type.isSigned)
{
- short value;
- GetShort(e, &value);
- FreeExpContents(exp);
- exp.constant = PrintShort(value);
- exp.type = constantExp;
+ short value = 0;
+ if(GetShort(e, &value))
+ {
+ FreeExpContents(exp);
+ exp.constant = PrintShort(value);
+ exp.type = constantExp;
+ }
}
else
{
- unsigned short value;
- GetUShort(e, &value);
- FreeExpContents(exp);
- exp.constant = PrintUShort(value);
- exp.type = constantExp;
+ unsigned short value = 0;
+ if(GetUShort(e, &value))
+ {
+ FreeExpContents(exp);
+ exp.constant = PrintUShort(value);
+ exp.type = constantExp;
+ }
}
break;
case intType:
if(type.isSigned)
{
- int value;
- GetInt(e, &value);
- FreeExpContents(exp);
- exp.constant = PrintInt(value);
- exp.type = constantExp;
+ int value = 0;
+ if(GetInt(e, &value))
+ {
+ FreeExpContents(exp);
+ exp.constant = PrintInt(value);
+ exp.type = constantExp;
+ }
}
else
{
- unsigned int value;
- GetUInt(e, &value);
- FreeExpContents(exp);
- exp.constant = PrintUInt(value);
- exp.type = constantExp;
+ unsigned int value = 0;
+ if(GetUInt(e, &value))
+ {
+ FreeExpContents(exp);
+ exp.constant = PrintUInt(value);
+ exp.type = constantExp;
+ }
}
break;
case int64Type:
if(type.isSigned)
{
- int64 value;
- GetInt64(e, &value);
- FreeExpContents(exp);
- exp.constant = PrintInt64(value);
- exp.type = constantExp;
+ int64 value = 0;
+ if(GetInt64(e, &value))
+ {
+ FreeExpContents(exp);
+ exp.constant = PrintInt64(value);
+ exp.type = constantExp;
+ }
}
else
{
- uint64 value;
- GetUInt64(e, &value);
- FreeExpContents(exp);
- exp.constant = PrintUInt64(value);
- exp.type = constantExp;
+ uint64 value = 0;
+ if(GetUInt64(e, &value))
+ {
+ FreeExpContents(exp);
+ exp.constant = PrintUInt64(value);
+ exp.type = constantExp;
+ }
}
break;
case intPtrType:
if(type.isSigned)
{
- intptr value;
- GetIntPtr(e, &value);
- FreeExpContents(exp);
- exp.constant = PrintInt64((int64)value);
- exp.type = constantExp;
+ intptr value = 0;
+ if(GetIntPtr(e, &value))
+ {
+ FreeExpContents(exp);
+ exp.constant = PrintInt64((int64)value);
+ exp.type = constantExp;
+ }
}
else
{
- uintptr value;
- GetUIntPtr(e, &value);
- FreeExpContents(exp);
- exp.constant = PrintUInt64((uint64)value);
- exp.type = constantExp;
+ uintptr value = 0;
+ if(GetUIntPtr(e, &value))
+ {
+ FreeExpContents(exp);
+ exp.constant = PrintUInt64((uint64)value);
+ exp.type = constantExp;
+ }
}
break;
case intSizeType:
if(type.isSigned)
{
- intsize value;
- GetIntSize(e, &value);
- FreeExpContents(exp);
- exp.constant = PrintInt64((int64)value);
- exp.type = constantExp;
+ intsize value = 0;
+ if(GetIntSize(e, &value))
+ {
+ FreeExpContents(exp);
+ exp.constant = PrintInt64((int64)value);
+ exp.type = constantExp;
+ }
}
else
{
- uintsize value;
- GetUIntSize(e, &value);
- FreeExpContents(exp);
- exp.constant = PrintUInt64((uint64)value);
- exp.type = constantExp;
+ uintsize value = 0;
+ if(GetUIntSize(e, &value))
+ {
+ FreeExpContents(exp);
+ exp.constant = PrintUInt64((uint64)value);
+ exp.type = constantExp;
+ }
}
break;
case floatType:
{
- float value;
- GetFloat(e, &value);
- FreeExpContents(exp);
- exp.constant = PrintFloat(value);
- exp.type = constantExp;
+ float value = 0;
+ if(GetFloat(e, &value))
+ {
+ FreeExpContents(exp);
+ exp.constant = PrintFloat(value);
+ exp.type = constantExp;
+ }
break;
}
case doubleType:
{
- double value;
- GetDouble(e, &value);
- FreeExpContents(exp);
- exp.constant = PrintDouble(value);
- exp.type = constantExp;
+ double value = 0;
+ if(GetDouble(e, &value))
+ {
+ FreeExpContents(exp);
+ exp.constant = PrintDouble(value);
+ exp.type = constantExp;
+ }
break;
}
}
}
}
-static bool CheckExpressionType(Expression exp, Type destType, bool skipUnitBla)
+static bool CheckExpressionType(Expression exp, Type destType, bool skipUnitBla, bool warnConst)
{
bool result = true;
if(destType)
if(destType.kind == voidType)
return false;
- if(!MatchTypeExpression(exp, destType, &converts, skipUnitBla))
+ if(!MatchTypeExpression(exp, destType, &converts, skipUnitBla, warnConst))
result = false;
if(converts.count)
{
// TODO: Check this...
*newExp = *exp;
+ newExp.prev = null;
+ newExp.next = null;
newExp.destType = null;
if(convert.isGet)
if(convert.isGet)
{
exp.expType = convert.resultType ? convert.resultType : convert.convert.dataType;
- exp.needCast = true;
+ if(exp.destType.casted)
+ exp.needCast = true;
if(exp.expType) exp.expType.refCount++;
}
else
{
exp.expType = convert.resultType ? convert.resultType : MkClassType(convert.convert._class.fullName);
- exp.needCast = true;
+ if(exp.destType.casted)
+ exp.needCast = true;
if(convert.resultType)
convert.resultType.refCount++;
}
if(!result && exp.expType && converts.count) // TO TEST: Added converts.count here to avoid a double warning with function type
{
- result = MatchTypes(exp.expType, exp.destType, null, null, null, true, true, false, false);
+ result = MatchTypes(exp.expType, exp.destType, null, null, null, true, true, false, false, warnConst);
}
if(!result && exp.expType && exp.destType)
{
void CheckTemplateTypes(Expression exp)
{
- if(exp.destType && exp.destType.passAsTemplate && exp.expType && exp.expType.kind != templateType && !exp.expType.passAsTemplate)
+ /*
+ bool et = exp.expType ? exp.expType.passAsTemplate : false;
+ bool dt = exp.destType ? exp.destType.passAsTemplate : false;
+ */
+ Expression nbExp = GetNonBracketsExp(exp);
+ if(exp.destType && exp.destType.passAsTemplate && exp.expType && exp.expType.kind != templateType && !exp.expType.passAsTemplate &&
+ (nbExp == exp || nbExp.type != castExp))
{
Expression newExp { };
- Statement compound;
Context context;
+ TypeKind kind = exp.expType.kind;
*newExp = *exp;
if(exp.destType) exp.destType.refCount++;
if(exp.expType) exp.expType.refCount++;
newExp.prev = null;
newExp.next = null;
- switch(exp.expType.kind)
+ if(exp.expType.kind == classType && exp.expType._class && exp.expType._class.registered)
+ {
+ Class c = exp.expType._class.registered;
+ if(c.type == bitClass || c.type == enumClass || c.type == unitClass)
+ {
+ if(!c.dataType)
+ c.dataType = ProcessTypeString(c.dataTypeString, false);
+ kind = c.dataType.kind;
+ }
+ }
+
+ switch(kind)
{
case doubleType:
if(exp.destType.classObjectType)
default:
exp.type = castExp;
exp.cast.typeName = MkTypeName(MkListOne(MkSpecifierName("uint64")), null);
- exp.cast.exp = MkExpBrackets(MkListOne(newExp));
+ if((exp.expType.kind == classType && exp.expType._class && exp.expType._class.registered && exp.expType._class.registered.type == structClass) || exp.expType.isPointerType)
+ exp.cast.exp = MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uintptr")), null), MkExpBrackets(MkListOne(newExp)));
+ else
+ exp.cast.exp = MkExpBrackets(MkListOne(newExp));
+ exp.needCast = true;
break;
}
}
else if(exp.expType && exp.expType.passAsTemplate && exp.destType && exp.usage.usageGet && exp.destType.kind != templateType && !exp.destType.passAsTemplate)
{
Expression newExp { };
- Statement compound;
Context context;
+ TypeKind kind = exp.expType.kind;
*newExp = *exp;
if(exp.destType) exp.destType.refCount++;
if(exp.expType) exp.expType.refCount++;
newExp.prev = null;
newExp.next = null;
- switch(exp.expType.kind)
+ if(exp.expType.kind == classType && exp.expType._class && exp.expType._class.registered)
+ {
+ Class c = exp.expType._class.registered;
+ if(c.type == bitClass || c.type == enumClass || c.type == unitClass)
+ {
+ if(!c.dataType)
+ c.dataType = ProcessTypeString(c.dataTypeString, false);
+ kind = c.dataType.kind;
+ }
+ }
+
+ switch(kind)
{
case doubleType:
if(exp.destType.classObjectType)
if(exp.expType._class && exp.expType._class.registered && exp.expType._class.registered.type == structClass)
{
exp.type = bracketsExp;
+
+ newExp = MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uintptr")), null), newExp);
exp.list = MkListOne(MkExpOp(null, '*', MkExpCast(MkTypeName(MkListOne(MkSpecifierName(exp.expType._class.string)),
MkDeclaratorPointer(MkPointer(null, null), null)), newExp)));
ProcessExpressionType(exp.list->first);
else
{
exp.type = bracketsExp;
+ if(exp.expType.isPointerType)
+ {
+ exp.needTemplateCast = 2;
+ newExp.needCast = true;
+ newExp.needTemplateCast = 2;
+ newExp = MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uintptr")), null), newExp);
+ }
+
exp.list = MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName(exp.expType._class.string)), null), newExp));
+ exp.needTemplateCast = 2;
newExp.needCast = true;
+ newExp.needTemplateCast = 2;
ProcessExpressionType(exp.list->first);
break;
}
break;
}
}
- if(newExp.type == memberExp && newExp.member.memberType == dataMember)
+ /*if(newExp.type == memberExp && newExp.member.memberType == dataMember)
{
+ // When was this required? Removed to address using templated values to pass to printf()
exp.type = opExp;
exp.op.op = '*';
exp.op.exp1 = null;
exp.op.exp2 = MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), MkDeclaratorPointer(MkPointer(null, null), null)),
MkExpBrackets(MkListOne(MkExpOp(null, '&', newExp))));
}
- else
+ else*/
{
char typeString[1024];
Declarator decl;
exp.cast.typeName = MkTypeName(specs, decl);
exp.cast.exp = MkExpBrackets(MkListOne(newExp));
exp.cast.exp.needCast = true;
+ exp.needTemplateCast = 2;
+ newExp.needTemplateCast = 2;
}
break;
}
// - Tree of all symbols within (stored without namespace)
// - Tree of sub-namespaces
-static Symbol ScanWithNameSpace(BinaryTree tree, char * nameSpace, char * name)
+static Symbol ScanWithNameSpace(BinaryTree tree, const char * nameSpace, const char * name)
{
int nsLen = strlen(nameSpace);
Symbol symbol;
return null;
}
-static Symbol FindWithNameSpace(BinaryTree tree, char * name)
+static Symbol FindWithNameSpace(BinaryTree tree, const char * name)
{
int c;
char nameSpace[1024];
- char * namePart;
+ const char * namePart;
bool gotColon = false;
nameSpace[0] = '\0';
return null;
}
-static void ProcessDeclaration(Declaration decl);
-
-/*static */Symbol FindSymbol(char * name, Context startContext, Context endContext, bool isStruct, bool globalNameSpace)
+/*static */Symbol FindSymbol(const char * name, Context startContext, Context endContext, bool isStruct, bool globalNameSpace)
{
#ifdef _DEBUG
//Time startTime = GetTime();
// Optimize this later? Do this before/less?
Context ctx;
Symbol symbol = null;
+
// First, check if the identifier is declared inside the function
//for(ctx = curContext; ctx /*!= topContext.parent */&& !symbol; ctx = ctx.parent)
if(symbol || ctx == endContext) break;
}
- if(inCompiler && curExternal && symbol && ctx == globalContext && curExternal.symbol && symbol.id > curExternal.symbol.idCode && symbol.pointerExternal)
- {
- if(symbol.pointerExternal.type == functionExternal)
- {
- FunctionDefinition function = symbol.pointerExternal.function;
-
- // Modified this recently...
- Context tmpContext = curContext;
- curContext = null;
- symbol.pointerExternal = MkExternalDeclaration(MkDeclaration(CopyList(function.specifiers, CopySpecifier), MkListOne(MkInitDeclarator(CopyDeclarator(function.declarator), null))));
- curContext = tmpContext;
-
- symbol.pointerExternal.symbol = symbol;
-
- // TESTING THIS:
- DeclareType(symbol.type, true, true);
-
- ast->Insert(curExternal.prev, symbol.pointerExternal);
-
- symbol.id = curExternal.symbol.idCode;
-
- }
- else if(symbol.pointerExternal.type == declarationExternal && curExternal.symbol.idCode < symbol.pointerExternal.symbol.id) // Added id comparison because Global Function prototypes were broken
- {
- ast->Move(symbol.pointerExternal, curExternal.prev);
- symbol.id = curExternal.symbol.idCode;
- }
- }
+ if(inCompiler && symbol && ctx == globalContext && symbol.pointerExternal && curExternal && symbol.pointerExternal != curExternal)
+ curExternal.CreateUniqueEdge(symbol.pointerExternal, symbol.pointerExternal.type == functionExternal);
#ifdef _DEBUG
//findSymbolTotalTime += GetTime() - startTime;
#endif
case classType:
{
Symbol c = type._class;
+ bool isObjectBaseClass = !c || !c.string || !strcmp(c.string, "class");
// TODO: typed_object does not fully qualify the type, as it may have taken up an actual class (Stored in _class) from overriding
// look into merging with thisclass ?
- if(type.classObjectType == typedObject)
+ if(type.classObjectType == typedObject && isObjectBaseClass)
strcat(string, "typed_object");
- else if(type.classObjectType == anyObject)
+ else if(type.classObjectType == anyObject && isObjectBaseClass)
strcat(string, "any_object");
else
{
{
if(type.kind == arrayType || type.kind == pointerType || type.kind == functionType || type.kind == methodType)
{
- Type attrType = null;
if((type.kind == functionType || type.kind == methodType) && (!parentType || parentType.kind != pointerType))
PrintAttribs(type, string);
if(printConst && type.constant && (type.kind == functionType || type.kind == methodType))
return null;
}
+public bool GetParseError() { return parseError; }
+
Expression ParseExpressionString(char * expression)
{
+ parseError = false;
+
fileInput = TempFile { };
fileInput.Write(expression, 1, strlen(expression));
fileInput.Seek(0, start);
if(_class && _class.type == enumClass)
{
- NamedLink value = null;
+ NamedLink64 value = null;
Class enumClass = eSystem_FindClass(privateModule, "enum");
if(enumClass)
{
}
if(value)
{
- char constant[256];
-
- FreeExpContents(exp);
-
- exp.type = constantExp;
exp.isConstant = true;
- if(!strcmp(baseClass.dataTypeString, "int"))
- sprintf(constant, "%d",(int)value.data);
- else
- sprintf(constant, "0x%X",(int)value.data);
- exp.constant = CopyString(constant);
+ if(inCompiler || inPreCompiler || inDebugger)
+ {
+ char constant[256];
+ FreeExpContents(exp);
+
+ exp.type = constantExp;
+ if(!strcmp(baseClass.dataTypeString, "int") || !strcmp(baseClass.dataTypeString, "int64") || !strcmp(baseClass.dataTypeString, "char") || !strcmp(baseClass.dataTypeString, "short"))
+ sprintf(constant, FORMAT64D, value.data);
+ else
+ sprintf(constant, FORMAT64HEX, value.data);
+ exp.constant = CopyString(constant);
+ }
//for(;_class.base && _class.base.type != systemClass; _class = _class.base);
exp.expType = MkClassType(baseClass.fullName);
break;
{
//char constant[256];
exp.type = stringExp;
- exp.constant = QMkString((char *)classProp.Get(_class));
+ exp.constant = QMkString((char *)(uintptr)classProp.Get(_class));
}
else
{
{
char size[100];
ComputeTypeSize(e.expType);
- sprintf(size, "%d", e.expType.size);
+ sprintf(size, "%d", e.expType.size); // Potential 32/64 Bootstrap issue
newExp = MkExpBrackets(MkListOne(MkExpOp(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)),
MkDeclaratorPointer(MkPointer(null, null), null)), newExp), '+',
MkExpCall(MkExpIdentifier(MkIdentifier("__ENDIAN_PAD")), MkListOne(MkExpConstant(size))))));
}
else if(!e.byReference || (_class && _class.type == noHeadClass)) // TESTING THIS HERE...
{
- Expression checkedExp, newExp;
+ Expression checkedExp; //, newExp;
{
// TODO: Move code from debugTools.ec for hasAddress flag, this is just temporary
{
Expression operand { };
operand = *checkedExp;
- checkedExp.destType = null;
- checkedExp.expType = null;
checkedExp.Clear();
+ checkedExp.destType = ProcessTypeString("void *", false);
+ checkedExp.expType = checkedExp.destType;
+ checkedExp.destType.refCount++;
+
checkedExp.type = opExp;
checkedExp.op.op = '&';
checkedExp.op.exp1 = null;
(type.kind != pointerType && type.kind != intPtrType && type.kind != arrayType && type.kind != classType) ||
(!destType.byReference && byReference && (destType.kind != pointerType || type.kind != pointerType)))
{
+ bool passAsTemplate = thisExp.destType.passAsTemplate;
+ Type t;
+
+ destType.refCount++;
+
e.type = opExp;
e.op.op = '*';
e.op.exp1 = null;
e.op.exp2 = MkExpCast(MkTypeName(specs, MkDeclaratorPointer(MkPointer(null, null), decl)), thisExp);
+ t = { };
+ CopyTypeInto(t, thisExp.destType);
+ t.passAsTemplate = false;
+ FreeType(thisExp.destType);
+ thisExp.destType = t;
+
+ t = { };
+ CopyTypeInto(t, destType);
+ t.passAsTemplate = passAsTemplate;
+ FreeType(destType);
+ destType = t;
+ destType.refCount = 0;
+
e.expType = { };
CopyTypeInto(e.expType, type);
+ if(type.passAsTemplate)
+ {
+ e.expType.classObjectType = none;
+ e.expType.passAsTemplate = false;
+ }
e.expType.byReference = false;
e.expType.refCount = 1;
}
else
{
- e.type = castExp;
- e.cast.typeName = MkTypeName(specs, decl);
- e.cast.exp = thisExp;
- e.byReference = true;
- e.expType = type;
- type.refCount++;
+ e.type = castExp;
+ e.cast.typeName = MkTypeName(specs, decl);
+ e.cast.exp = thisExp;
+ e.byReference = true;
+ e.expType = type;
+ type.refCount++;
+ }
+
+ if(e.destType)
+ FreeType(e.destType);
+
+ e.destType = destType;
+ destType.refCount++;
+ }
+ }
+}
+
+void ApplyLocation(Expression exp, Location loc)
+{
+ exp.loc = loc;
+ switch(exp.type)
+ {
+ case opExp:
+ if(exp.op.exp1) ApplyLocation(exp.op.exp1, loc);
+ if(exp.op.exp2) ApplyLocation(exp.op.exp2, loc);
+ break;
+ case bracketsExp:
+ if(exp.list)
+ {
+ Expression e;
+ for(e = exp.list->first; e; e = e.next)
+ ApplyLocation(e, loc);
+ }
+ break;
+ case indexExp:
+ if(exp.index.index)
+ {
+ Expression e;
+ for(e = exp.index.index->first; e; e = e.next)
+ ApplyLocation(e, loc);
+ }
+ if(exp.index.exp)
+ ApplyLocation(exp.index.exp, loc);
+ break;
+ case callExp:
+ if(exp.call.arguments)
+ {
+ Expression arg;
+ for(arg = exp.call.arguments->first; arg; arg = arg.next)
+ ApplyLocation(arg, loc);
+ }
+ if(exp.call.exp)
+ ApplyLocation(exp.call.exp, loc);
+ break;
+ case memberExp:
+ case pointerExp:
+ if(exp.member.exp)
+ ApplyLocation(exp.member.exp, loc);
+ break;
+ case castExp:
+ if(exp.cast.exp)
+ ApplyLocation(exp.cast.exp, loc);
+ break;
+ case conditionExp:
+ if(exp.cond.exp)
+ {
+ Expression e;
+ for(e = exp.cond.exp->first; e; e = e.next)
+ ApplyLocation(e, loc);
}
- e.destType = destType;
- destType.refCount++;
- }
+ if(exp.cond.cond)
+ ApplyLocation(exp.cond.cond, loc);
+ if(exp.cond.elseExp)
+ ApplyLocation(exp.cond.elseExp, loc);
+ break;
+ case vaArgExp:
+ if(exp.vaArg.exp)
+ ApplyLocation(exp.vaArg.exp, loc);
+ break;
+ default:
+ break;
}
}
+bool RelatedUnits(Class c1, Class c2)
+{
+ if(c1.base.type == unitClass) c1 = c1.base;
+ if(c2.base.type == unitClass) c2 = c2.base;
+ return c1 == c2;
+}
+
void ProcessExpressionType(Expression exp)
{
bool unresolved = false;
case identifierExp:
{
Identifier id = exp.identifier;
- if(!id) return;
+ if(!id || !topContext) return;
// DOING THIS LATER NOW...
if(id._class && id._class.name)
exp.expType = ProcessTypeString("Module", true);
break;
}
- else */if(strstr(id.string, "__ecereClass") == id.string)
+ else */
+ if(!strcmp(id.string, "__runtimePlatform"))
+ {
+ exp.expType = ProcessTypeString("ecere::com::Platform", true);
+ break;
+ }
+ else if(strstr(id.string, "__ecereClass") == id.string)
{
exp.expType = ProcessTypeString("ecere::com::Class", true);
break;
}
else
{
- Symbol symbol = FindSymbol(id.string, curContext, topContext /*exp.destType ? topContext : globalContext*/, false, id._class && id._class.name == null);
+ Symbol symbol = null;
+ bool findInGlobal = false;
+ if(!topContext.parent && exp.destType && exp.destType.kind == classType && exp.destType._class && exp.destType._class.registered && exp.destType._class.registered.type == enumClass)
+ findInGlobal = true; // In global context, look at enum values first
+ else
+ symbol = FindSymbol(id.string, curContext, topContext /*exp.destType ? topContext : globalContext*/, false, id._class && id._class.name == null);
+
// Enums should be resolved here (Special pass in opExp to fix identifiers not seen as enum on the first pass)
if(!symbol/* && exp.destType*/)
{
- if(exp.destType && CheckExpressionType(exp, exp.destType, false))
+ if(exp.destType && CheckExpressionType(exp, exp.destType, false, false))
break;
else
{
symbol = FindSymbol(id.string, topContext.parent, globalContext, false, id._class && id._class.name == null);
}
}
+ if(findInGlobal)
+ symbol = FindSymbol(id.string, curContext, topContext, false, id._class && id._class.name == null);
// If we manage to resolve this symbol
if(symbol)
exp.expType = type;
if(type)
type.refCount++;
- if(type && (type.kind == enumType || (_class && _class.type == enumClass)))
+
+ // Commented this out, it was making non-constant enum parameters seen as constant
+ // enums should have been resolved by ResolveIdWithClass, changed to constantExp and marked as constant
+ if(type && (type.kind == enumType /*|| (_class && _class.type == enumClass)*/))
// Add missing cases here... enum Classes...
exp.isConstant = true;
if(c == definedExpStackPos && c < sizeof(definedExpStack) / sizeof(void *))
{
Location backupYylloc = yylloc;
+ File backInput = fileInput;
definedExpStack[definedExpStackPos++] = definedExp;
+
fileInput = TempFile { };
fileInput.Write(definedExp.value, 1, strlen(definedExp.value));
fileInput.Seek(0, start);
resetScanner();
expression_yyparse();
delete fileInput;
+ if(backInput)
+ fileInput = backInput;
yylloc = backupYylloc;
FreeIdentifier(id);
exp.type = bracketsExp;
exp.list = MkListOne(parsedExpression);
- parsedExpression.loc = yylloc;
+ ApplyLocation(parsedExpression, yylloc);
ProcessExpressionType(exp);
definedExpStackPos--;
return;
data = FindGlobalData(id.string);
if(data)
{
- DeclareGlobalData(data);
+ DeclareGlobalData(curExternal, data);
exp.expType = data.dataType;
if(data.dataType) data.dataType.refCount++;
if(function.module.importType != staticImport && (!function.dataType || !function.dataType.dllExport))
strcpy(name, "__ecereFunction_");
FullClassNameCat(name, id.string, false); // Why is this using FullClassNameCat ?
- if(DeclareFunction(function, name))
+ if(DeclareFunction(curExternal, function, name))
{
delete id.string;
id.string = CopyString(name);
}
case instanceExp:
{
- Class _class;
+ // Class _class;
// Symbol classSym;
if(!exp.instance._class)
//_class = classSym ? classSym.registered : null;
ProcessInstantiationType(exp.instance);
+
exp.isConstant = exp.instance.isConstant;
/*
else
{
bool isSigned = constant[0] == '-';
- int64 i64 = strtoll(constant, null, 0);
- uint64 ui64 = strtoull(constant, null, 0);
- bool is64Bit = false;
+ char * endP = null;
+ int64 i64 = strtoll(constant, &endP, 0);
+ uint64 ui64 = strtoull(constant, &endP, 0);
+ bool is64Bit = endP && (!strcmp(endP, "LL") || !strcmp(endP, "ll") || !strcmp(endP, "LLU") || !strcmp(endP, "llu") || !strcmp(endP, "ull") || !strcmp(endP, "ULL"));
+ bool forceUnsigned = endP && (!strcmp(endP, "U") || !strcmp(endP, "u") || !strcmp(endP, "LLU") || !strcmp(endP, "llu") || !strcmp(endP, "ull") || !strcmp(endP, "ULL"));
if(isSigned)
{
if(i64 < MININT)
else if(constant[0] != '0' || !constant[1])
isSigned = true;
}
+ if(forceUnsigned)
+ isSigned = false;
type.kind = is64Bit ? int64Type : intType;
type.isSigned = isSigned;
}
type = Type
{
refCount = 1;
- kind = charType;
+ kind = exp.wideString ? shortType : charType;
constant = true;
- isSigned = true;
+ isSigned = exp.wideString ? false : true;
}
};
break;
kind = pointerType;
type = ProcessType(exp._new.typeName.qualifiers, exp._new.typeName.declarator);
};
- DeclareType(exp.expType.type, false, false);
+ DeclareType(curExternal, exp.expType.type, true, false);
break;
case renewExp:
case renew0Exp:
kind = pointerType;
type = ProcessType(exp._renew.typeName.qualifiers, exp._renew.typeName.declarator);
};
- DeclareType(exp.expType.type, false, false);
+ DeclareType(curExternal, exp.expType.type, true, false);
break;
case opExp:
{
bool useDestType = false, useSideType = false;
Location oldyylloc = yylloc;
bool useSideUnit = false;
+ Class destClass = (exp.destType && exp.destType.kind == classType && exp.destType._class) ? exp.destType._class.registered : null;
+ bool powerOp = false, relationOp = false;
+ Class c1 = null, c2 = null;
// Dummy type to prevent ProcessExpression of operands to say unresolved identifiers yet
Type dummy
// Gives boolean result
boolResult = true;
useSideType = true;
+ relationOp = true;
break;
case '+':
case '-':
useSideUnit = true;
+ useSideType = true;
+ useDestType = true;
+ break;
+
+ case LEFT_OP:
+ case RIGHT_OP:
+ // useSideType = true;
+ // useDestType = true;
+ break;
- // Just added these... testing
case '|':
- case '&':
case '^':
+ useSideType = true;
+ useDestType = true;
+ break;
- // DANGER: Verify units
case '/':
case '%':
+ useSideType = true;
+ useDestType = true;
+ if(exp.op.op == '/') powerOp = true;
+ break;
+ case '&':
case '*':
-
- if(exp.op.op != '*' || exp.op.exp1)
+ if(exp.op.exp1)
{
+ // For & operator, useDestType nicely ensures the result will fit in a bool (TODO: Fix for generic enum)
useSideType = true;
useDestType = true;
+ if(exp.op.op == '*') powerOp = true;
}
break;
}
//dummy.kind = TypeDummy;
-
if(exp.op.exp1)
{
- if(exp.destType && exp.destType.kind == classType &&
- exp.destType._class && exp.destType._class.registered && useDestType &&
+ // Added this check here to use the dest type only for units derived from the base unit
+ // So that untyped units will use the side unit as opposed to the untyped destination unit
+ // This fixes (#771) sin(Degrees { 5 } + 5) to be equivalent to sin(Degrees { 10 }), since sin expects a generic Angle
+ if(exp.op.exp2 && useSideUnit && useDestType && destClass && destClass.type == unitClass && destClass.base.type != unitClass)
+ useDestType = false;
- ((exp.destType._class.registered.type == unitClass && useSideUnit) ||
- exp.destType._class.registered.type == enumClass ||
- exp.destType._class.registered.type == bitClass
- ))
+ if(destClass && useDestType &&
+ ((destClass.type == unitClass && useSideUnit) || destClass.type == enumClass || destClass.type == bitClass))
//(exp.destType._class.registered.type == unitClass || exp.destType._class.registered.type == enumClass) && useDestType)
{
if(exp.op.exp1.destType) FreeType(exp.op.exp1.destType);
exp.op.exp1.destType = exp.destType;
+ exp.op.exp1.opDestType = true;
if(exp.destType)
exp.destType.refCount++;
}
if(exp.op.exp1.destType) FreeType(exp.op.exp1.destType);
exp.op.exp1.destType = dummy;
dummy.refCount++;
+ if(powerOp)
+ exp.op.exp1.opDestType = true;
+ if(relationOp)
+ exp.op.exp1.usedInComparison = true;
+ }
+ if(exp.op.op == '+' || exp.op.op == '-')
+ {
+ if(exp.opDestType)
+ exp.op.exp1.parentOpDestType = true;
+ if(exp.usedInComparison)
+ exp.op.exp1.usedInComparison = true;
}
// TESTING THIS HERE...
if(exp.op.exp1.destType && exp.op.op != '=') exp.op.exp1.destType.count++;
- ProcessExpressionType(exp.op.exp1);
+ ProcessExpressionType(exp.op.exp1);
if(exp.op.exp1.destType && exp.op.op != '=') exp.op.exp1.destType.count--;
+ exp.op.exp1.opDestType = false;
+ exp.op.exp1.usedInComparison = false;
+
+ // Fix for unit and ++ / --
+ if(!exp.op.exp2 && (exp.op.op == INC_OP || exp.op.op == DEC_OP) && exp.op.exp1.expType && exp.op.exp1.expType.kind == classType &&
+ exp.op.exp1.expType._class && exp.op.exp1.expType._class.registered && exp.op.exp1.expType._class.registered.type == unitClass)
+ {
+ exp.op.exp2 = MkExpConstant("1");
+ exp.op.op = exp.op.op == INC_OP ? ADD_ASSIGN : SUB_ASSIGN;
+ assign = true;
+ }
+
if(exp.op.exp1.destType == dummy)
{
FreeType(dummy);
exp.op.exp1.destType = null;
}
+
+ if(exp.op.exp2)
+ {
+ if(!assign && exp.op.exp1.expType && (exp.op.exp1.expType.kind == charType || exp.op.exp1.expType.kind == shortType))
+ {
+ Type type { kind = intType, isSigned = true, refCount = 1, signedBeforePromotion = exp.op.exp1.expType.isSigned, bitMemberSize = exp.op.exp1.expType.bitMemberSize, promotedFrom = exp.op.exp1.expType.kind };
+ FreeType(exp.op.exp1.expType);
+ exp.op.exp1.expType = type;
+ }
+ }
+
type1 = exp.op.exp1.expType;
}
else
{
exp.op.exp2.destType = exp.destType;
+ if(!exp.op.exp1 || (exp.op.op != '&' && exp.op.op != '^'))
+ exp.op.exp2.opDestType = true;
if(exp.destType)
exp.destType.refCount++;
}
if(type1) type1.refCount++;
exp.expType = type1;
}
- else if(exp.destType && exp.destType.kind == classType &&
- exp.destType._class && exp.destType._class.registered &&
-
- ((exp.destType._class.registered.type == unitClass && useDestType && useSideUnit) ||
- (exp.destType._class.registered.type == enumClass && useDestType))
- )
+ else if(destClass &&
+ ((destClass.type == unitClass && useDestType && useSideUnit) ||
+ (destClass.type == enumClass && useDestType)))
{
if(exp.op.exp2.destType) FreeType(exp.op.exp2.destType);
exp.op.exp2.destType = exp.destType;
+ if(exp.op.op != '&' && exp.op.op != '^')
+ exp.op.exp2.opDestType = true;
if(exp.destType)
exp.destType.refCount++;
}
if(exp.op.exp2.destType) FreeType(exp.op.exp2.destType);
exp.op.exp2.destType = dummy;
dummy.refCount++;
+ if(powerOp)
+ exp.op.exp2.opDestType = true;
+ if(relationOp)
+ exp.op.exp2.usedInComparison = true;
}
// TESTING THIS HERE... (DANGEROUS)
type1.refCount++;
}
if(exp.op.exp2.destType && exp.op.op != '=') exp.op.exp2.destType.count++;
+ // Cannot lose the cast on a sizeof
+ if(exp.op.op == SIZEOF)
+ {
+ Expression e = exp.op.exp2;
+ while((e.type == bracketsExp || e.type == extensionExpressionExp || e.type == extensionCompoundExp) && e.list)
+ {
+ if(e.type == bracketsExp || e.type == extensionExpressionExp || e.type == extensionCompoundExp)
+ {
+ if(e.type == extensionCompoundExp)
+ e = ((Statement)e.compound.compound.statements->last).expressions->last;
+ else
+ e = e.list->last;
+ }
+ }
+ if(e.type == castExp && e.cast.exp)
+ e.cast.exp.needCast = true;
+ }
+ if(exp.op.op == '+' || exp.op.op == '-')
+ {
+ if(exp.opDestType)
+ exp.op.exp2.parentOpDestType = true;
+ if(exp.usedInComparison)
+ exp.op.exp2.usedInComparison = true;
+ }
ProcessExpressionType(exp.op.exp2);
+ exp.op.exp2.opDestType = false;
+ exp.op.exp2.usedInComparison = false;
if(exp.op.exp2.destType && exp.op.op != '=') exp.op.exp2.destType.count--;
+ if(!assign && (exp.op.exp1 || exp.op.op == '~'))
+ {
+ if(exp.op.exp2.expType && (exp.op.exp2.expType.kind == charType || exp.op.exp2.expType.kind == shortType))
+ {
+ Type type { kind = intType, isSigned = true, refCount = 1, signedBeforePromotion = exp.op.exp2.expType.isSigned, bitMemberSize = exp.op.exp2.expType.bitMemberSize, promotedFrom = exp.op.exp2.expType.kind };
+ FreeType(exp.op.exp2.expType);
+ exp.op.exp2.expType = type;
+ }
+ }
+
if(assign && type1 && type1.kind == pointerType && exp.op.exp2.expType)
{
if(exp.op.exp2.expType.kind == intSizeType || exp.op.exp2.expType.kind == intPtrType || exp.op.exp2.expType.kind == int64Type || exp.op.exp2.expType.kind == intType || exp.op.exp2.expType.kind == shortType || exp.op.exp2.expType.kind == charType)
type2.isSigned = true;
}
else
+ {
type2 = exp.op.exp2.expType;
+ if(type2) type2.refCount++;
+ }
+ }
+ c1 = type1 && type1.kind == classType && type1._class ? type1._class.registered : null;
+ c2 = type2 && type2.kind == classType && type2._class ? type2._class.registered : null;
+
+ if(relationOp &&
+ ( (exp.op.exp1 && exp.op.exp1.ambiguousUnits && (!c2 || c2.type != unitClass)) ||
+ (exp.op.exp2 && exp.op.exp2.ambiguousUnits && (!c1 || c1.type != unitClass))) )
+ Compiler_Warning($"ambiguous units in relational operation\n");
+
+ if(!relationOp &&
+ ((exp.op.exp1 && exp.op.exp1.ambiguousUnits) ||
+ (exp.op.exp2 && exp.op.exp2.ambiguousUnits)) &&
+ (!powerOp || !c1 || c1.type != unitClass || !c2 || c2.type != unitClass || !RelatedUnits(c1, c2)))
+ {
+ if(exp.opDestType || exp.usedInComparison)
+ exp.ambiguousUnits = true;
+ else
+ Compiler_Warning($"ambiguous units\n");
}
dummy.kind = voidType;
exp.expType = Type
{
refCount = 1;
- kind = intType;
+ kind = intSizeType;
};
exp.isConstant = true;
}
}
else if(exp.op.op == '&' && !exp.op.exp1)
exp.expType = Reference(type2);
+ else if(exp.op.op == LEFT_OP || exp.op.op == RIGHT_OP)
+ {
+ if(exp.op.exp1.expType)
+ {
+ exp.expType = exp.op.exp1.expType;
+ exp.expType.refCount++;
+ }
+ }
else if(!assign)
{
+ if(c1 && !c1.dataType)
+ c1.dataType = ProcessTypeString(c1.dataTypeString, false);
+ if(c2 && !c2.dataType)
+ c2.dataType = ProcessTypeString(c2.dataTypeString, false);
+
if(boolOps)
{
if(exp.op.exp1)
if(!exp.op.exp1.expType)
ProcessExpressionType(exp.op.exp1);
else
- CheckExpressionType(exp.op.exp1, exp.op.exp1.destType, false);
+ CheckExpressionType(exp.op.exp1, exp.op.exp1.destType, false, false);
FreeType(exp.op.exp1.expType);
exp.op.exp1.expType = MkClassType("bool");
exp.op.exp1.expType.truth = true;
if(!exp.op.exp2.expType)
ProcessExpressionType(exp.op.exp2);
else
- CheckExpressionType(exp.op.exp2, exp.op.exp2.destType, false);
+ CheckExpressionType(exp.op.exp2, exp.op.exp2.destType, false, false);
FreeType(exp.op.exp2.expType);
exp.op.exp2.expType = MkClassType("bool");
exp.op.exp2.expType.truth = true;
}
}
+ else if(powerOp && exp.op.exp1 && exp.op.exp2 && ((c1 && c1.type == unitClass) || (c2 && c2.type == unitClass)))
+ {
+ // * or / with at least one unit operand
+ if(c1 && c1.type == unitClass && c2 && c2.type == unitClass)
+ {
+ // This is where we'd handle unit powers e.g. square meters or meters/seconds
+ // For now using base types
+ if(c1.dataType.kind == doubleType) exp.expType = c1.dataType;
+ else if(c2.dataType.kind == doubleType) exp.expType = c2.dataType;
+ else if(c1.dataType.kind == floatType) exp.expType = c1.dataType;
+ else if(c2.dataType.kind == floatType) exp.expType = c2.dataType;
+ else
+ exp.expType = c1.dataType;
+ }
+ else if((c1 && c1.type == unitClass) || exp.op.op == '/') // 1/units should not be typed with unit
+ exp.expType = type1;
+ else
+ exp.expType = type2;
+
+ if(exp.expType)
+ exp.expType.refCount++;
+ }
else if(exp.op.exp1 && exp.op.exp2 &&
((useSideType /*&&
(useSideUnit ||
- ((!type1 || type1.kind != classType || type1._class.registered.type != unitClass) &&
- (!type2 || type2.kind != classType || type2._class.registered.type != unitClass)))*/) ||
+ ((!c1 || c1.type != unitClass) &&
+ (!c2 || c2.type != unitClass)))*/) ||
((!type1 || type1.kind != classType || !strcmp(type1._class.string, "String")) &&
(!type2 || type2.kind != classType || !strcmp(type2._class.string, "String")))))
{
// If either both are class or both are not class
((type1.kind == classType && type1._class && strcmp(type1._class.string, "String")) == (type2.kind == classType && type2._class && strcmp(type2._class.string, "String"))))
{
- if(exp.op.exp2.destType) FreeType(exp.op.exp2.destType);
- exp.op.exp2.destType = type1;
- type1.refCount++;
- if(exp.op.exp1.destType) FreeType(exp.op.exp1.destType);
- exp.op.exp1.destType = type2;
- type2.refCount++;
+ // Added this check for enum subtraction to result in an int type:
+ if(exp.op.op == '-' && ((c1 && c1.type == enumClass) || (c2 && c2.type == enumClass)) )
+ {
+ Type intType = ProcessTypeString((c1 && c1.dataType.kind == int64Type) || (c2 && c2.dataType.kind == int64Type) ? "int64" : "int", false);
+
+ if(exp.op.exp1.destType) FreeType(exp.op.exp1.destType);
+ if(exp.op.exp2.destType) FreeType(exp.op.exp2.destType);
+ exp.op.exp1.destType = intType;
+ exp.op.exp2.destType = intType;
+ intType.refCount++;
+ }
+ else
+ {
+ if(exp.op.exp2.destType) FreeType(exp.op.exp2.destType);
+ exp.op.exp2.destType = type1;
+ type1.refCount++;
+ if(exp.op.exp1.destType) FreeType(exp.op.exp1.destType);
+ exp.op.exp1.destType = type2;
+ type2.refCount++;
+ }
+
// Warning here for adding Radians + Degrees with no destination type
- if(!boolResult && type1.kind == classType && (!exp.destType || exp.destType.kind != classType) &&
- type1._class.registered && type1._class.registered.type == unitClass &&
- type2._class.registered && type2._class.registered.type == unitClass &&
- type1._class.registered != type2._class.registered)
- Compiler_Warning($"operating on %s and %s with an untyped result, assuming %s\n",
- type1._class.string, type2._class.string, type1._class.string);
+ if(!boolResult && !exp.opDestType && (!exp.destType || exp.destType.kind != classType) &&
+ c1 && c1.type == unitClass &&
+ c2 && c2.type == unitClass &&
+ c1 != c2)
+ {
+ if(exp.usedInComparison || exp.parentOpDestType)
+ exp.ambiguousUnits = true;
+ else
+ Compiler_Warning($"operating on %s and %s with an untyped result, assuming %s\n",
+ type1._class.string, type2._class.string, type1._class.string);
+ }
if(type1.kind == pointerType && type1.type.kind == templateType && type2.kind != pointerType)
{
{
ProcessExpressionType(classExp);
- exp.op.exp2 = MkExpBrackets(MkListOne(MkExpOp(exp.op.exp2, '*',
- // ((_class.type == noHeadClass || _class.type == normalClass) ? sizeof(void *) : type.size)
- MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(
- // noHeadClass
- MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpConstant("5")),
- OR_OP,
- // normalClass
- MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpConstant("0"))))),
- MkListOne(MkExpTypeSize(MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(
- MkPointer(null, null), null)))),
- MkExpMember(classExp, MkIdentifier("typeSize"))))))));
+ exp.op.exp2 = MkExpBrackets(MkListOne(MkExpOp(exp.op.exp2, '*', MkExpMember(classExp, MkIdentifier("typeSize")) )));
if(!exp.op.exp2.expType)
- type2 = exp.op.exp2.expType = ProcessTypeString("int", false);
+ {
+ if(type2)
+ FreeType(type2);
+ type2 = exp.op.exp2.expType = ProcessTypeString("int", false); c2 = null;
+ type2.refCount++;
+ }
ProcessExpressionType(exp.op.exp2);
}
else if(exp.op.op == '-')
{
// Pointer Subtraction gives integer
- if(MatchTypes(type1.type, type2.type, null, null, null, false, false, false, false))
+ if(MatchTypes(type1.type, type2.type, null, null, null, false, false, false, false, false))
{
exp.expType = Type
{
MkExpCast(MkTypeName(MkListOne(MkSpecifierName("byte")), MkDeclaratorPointer(MkPointer(null, null), null)), MkExpBrackets(MkListOne(exp.op.exp1)))
, exp.op.op,
MkExpCast(MkTypeName(MkListOne(MkSpecifierName("byte")), MkDeclaratorPointer(MkPointer(null, null), null)), MkExpBrackets(MkListOne(exp.op.exp2)))))), '/',
-
- //MkExpMember(classExp, MkIdentifier("typeSize"))
-
- // ((_class.type == noHeadClass || _class.type == normalClass) ? sizeof(void *) : type.size)
- MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(
- // noHeadClass
- MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("noHeadClass"))),
- OR_OP,
- // normalClass
- MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("normalClass")))))),
- MkListOne(MkExpTypeSize(MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(
- MkPointer(null, null), null)))),
- MkExpMember(classExp, MkIdentifier("typeSize")))))
-
-
- ));
+ MkExpMember(classExp, MkIdentifier("typeSize"))));
ProcessExpressionType(((Expression)exp.list->first).op.exp2);
FreeType(dummy);
if(!success && exp.op.exp1.type == constantExp)
{
// If first expression is constant, try to match that first
- if(CheckExpressionType(exp.op.exp1, exp.op.exp1.destType, false))
+ if(CheckExpressionType(exp.op.exp1, exp.op.exp1.destType, false, false))
{
if(exp.expType) FreeType(exp.expType);
exp.expType = exp.op.exp1.destType;
if(exp.op.exp1.destType) exp.op.exp1.destType.refCount++;
success = true;
}
- else if(CheckExpressionType(exp.op.exp2, exp.op.exp2.destType, false))
+ else if(CheckExpressionType(exp.op.exp2, exp.op.exp2.destType, false, false))
{
if(exp.expType) FreeType(exp.expType);
exp.expType = exp.op.exp2.destType;
}
else if(!success)
{
- if(CheckExpressionType(exp.op.exp2, exp.op.exp2.destType, false))
+ if(CheckExpressionType(exp.op.exp2, exp.op.exp2.destType, false, false))
{
if(exp.expType) FreeType(exp.expType);
exp.expType = exp.op.exp2.destType;
if(exp.op.exp2.destType) exp.op.exp2.destType.refCount++;
success = true;
}
- else if(CheckExpressionType(exp.op.exp1, exp.op.exp1.destType, false))
+ else if(CheckExpressionType(exp.op.exp1, exp.op.exp1.destType, false, false))
{
if(exp.expType) FreeType(exp.expType);
exp.expType = exp.op.exp1.destType;
}
}
// ADDED THESE TWO FROM OUTSIDE useSideType CHECK
- else if(!boolResult && (!useSideUnit /*|| exp.destType*/) && type2 && type1 && type2.kind == classType && type1.kind != classType && type2._class && type2._class.registered && type2._class.registered.type == unitClass)
+ else if(!boolResult && !useSideUnit && c2 && c2.type == unitClass && type1 && type1.kind != classType)
{
if(exp.op.exp1.destType) FreeType(exp.op.exp1.destType);
// Convert e.g. / 4 into / 4.0
exp.op.exp1.destType = type2._class.registered.dataType;
if(type2._class.registered.dataType)
type2._class.registered.dataType.refCount++;
- CheckExpressionType(exp.op.exp1, exp.op.exp1.destType, false);
+ CheckExpressionType(exp.op.exp1, exp.op.exp1.destType, false, false);
exp.expType = type2;
if(type2) type2.refCount++;
}
- else if(!boolResult && (!useSideUnit /*|| exp.destType*/) && type1 && type2 && type1.kind == classType && type2.kind != classType && type1._class && type1._class.registered && type1._class.registered.type == unitClass)
+ else if(!boolResult && !useSideUnit && c1 && c1.type == unitClass && type2 && type2.kind != classType)
{
if(exp.op.exp2.destType) FreeType(exp.op.exp2.destType);
// Convert e.g. / 4 into / 4.0
exp.op.exp2.destType = type1._class.registered.dataType;
if(type1._class.registered.dataType)
type1._class.registered.dataType.refCount++;
- CheckExpressionType(exp.op.exp2, exp.op.exp2.destType, false);
+ CheckExpressionType(exp.op.exp2, exp.op.exp2.destType, false, false);
exp.expType = type1;
if(type1) type1.refCount++;
}
{
bool valid = false;
- if(!boolResult && useSideUnit && type1 && type1.kind == classType && type1._class.registered && type1._class.registered.type == unitClass && type2 && type2.kind != classType)
+ if(!boolResult && useSideUnit && c1 && c1.type == unitClass && type2 && type2.kind != classType)
{
if(exp.op.exp2.destType) FreeType(exp.op.exp2.destType);
- if(!type1._class.registered.dataType)
- type1._class.registered.dataType = ProcessTypeString(type1._class.registered.dataTypeString, false);
- exp.op.exp2.destType = type1._class.registered.dataType;
+ exp.op.exp2.destType = c1.dataType;
exp.op.exp2.destType.refCount++;
- CheckExpressionType(exp.op.exp2, exp.op.exp2.destType, false);
+ CheckExpressionType(exp.op.exp2, exp.op.exp2.destType, false, false);
+ if(type2)
+ FreeType(type2);
type2 = exp.op.exp2.destType;
+ c2 = type2 && type2.kind == classType && type2._class ? type2._class.registered : null;
+ if(type2) type2.refCount++;
exp.expType = type2;
type2.refCount++;
}
- if(!boolResult && useSideUnit && type2 && type2.kind == classType && type2._class.registered && type2._class.registered.type == unitClass && type1 && type1.kind != classType)
+ if(!boolResult && useSideUnit && c2 && c2.type == unitClass && type1 && type1.kind != classType)
{
if(exp.op.exp1.destType) FreeType(exp.op.exp1.destType);
- if(!type2._class.registered.dataType)
- type2._class.registered.dataType = ProcessTypeString(type2._class.registered.dataTypeString, false);
- exp.op.exp1.destType = type2._class.registered.dataType;
+ exp.op.exp1.destType = c2.dataType;
exp.op.exp1.destType.refCount++;
- CheckExpressionType(exp.op.exp1, exp.op.exp1.destType, false);
+ CheckExpressionType(exp.op.exp1, exp.op.exp1.destType, false, false);
type1 = exp.op.exp1.destType;
+ c1 = type1 && type1.kind == classType && type1._class ? type1._class.registered : null;
exp.expType = type1;
type1.refCount++;
}
// TESTING THIS NEW CODE
- if(!boolResult || exp.op.op == '>' || exp.op.op == '<')
+ if(!boolResult || exp.op.op == '>' || exp.op.op == '<' || exp.op.op == GE_OP || exp.op.op == LE_OP)
{
- if(type1.kind == classType && type1._class && type1._class.registered && type1._class.registered.type == enumClass && exp.op.exp2.expType)
+ bool op1IsEnum = c1 && c1.type == enumClass;
+ bool op2IsEnum = c2 && c2.type == enumClass;
+ if(exp.op.op == '*' || exp.op.op == '/' || exp.op.op == '-' || exp.op.op == '|' || exp.op.op == '^')
{
- if(CheckExpressionType(exp.op.exp1, exp.op.exp2.expType, false))
+ // Convert the enum to an int instead for these operators
+ if(op1IsEnum && exp.op.exp2.expType)
{
- if(exp.expType) FreeType(exp.expType);
- exp.expType = exp.op.exp1.expType;
- if(exp.op.exp2.expType) exp.op.exp1.expType.refCount++;
- valid = true;
+ if(CheckExpressionType(exp.op.exp1, exp.op.exp2.expType, false, false))
+ {
+ if(exp.expType) FreeType(exp.expType);
+ exp.expType = exp.op.exp2.expType;
+ if(exp.op.exp2.expType) exp.op.exp2.expType.refCount++;
+ valid = true;
+ }
+ }
+ else if(op2IsEnum && exp.op.exp1.expType)
+ {
+ if(CheckExpressionType(exp.op.exp2, exp.op.exp1.expType, false, false))
+ {
+ if(exp.expType) FreeType(exp.expType);
+ exp.expType = exp.op.exp1.expType;
+ if(exp.op.exp1.expType) exp.op.exp1.expType.refCount++;
+ valid = true;
+ }
}
}
-
- else if(type2 && (type2.kind == classType && type2._class && type2._class.registered && type2._class.registered.type == enumClass && exp.op.exp1.expType))
+ else
{
- if(CheckExpressionType(exp.op.exp2, exp.op.exp1.expType, false))
+ if(op1IsEnum && exp.op.exp2.expType)
{
- if(exp.expType) FreeType(exp.expType);
- exp.expType = exp.op.exp2.expType;
- if(exp.op.exp2.expType) exp.op.exp2.expType.refCount++;
- valid = true;
+ if(CheckExpressionType(exp.op.exp1, exp.op.exp2.expType, false, false))
+ {
+ if(exp.expType) FreeType(exp.expType);
+ exp.expType = exp.op.exp1.expType;
+ if(exp.op.exp1.expType) exp.op.exp1.expType.refCount++;
+ valid = true;
+ }
+ }
+ else if(op2IsEnum && exp.op.exp1.expType)
+ {
+ if(CheckExpressionType(exp.op.exp2, exp.op.exp1.expType, false, false))
+ {
+ if(exp.expType) FreeType(exp.expType);
+ exp.expType = exp.op.exp2.expType;
+ if(exp.op.exp2.expType) exp.op.exp2.expType.refCount++;
+ valid = true;
+ }
}
}
}
if(!valid)
{
- if(exp.op.exp2.destType) FreeType(exp.op.exp2.destType);
- exp.op.exp2.destType = type1;
- type1.refCount++;
+ // Added this first part of the if here to handle 5 + Degrees { 5 } with either a base unit dest or not a unit dest type
+ if(c2 && c2.type == unitClass && (!c1 || c1.type != unitClass))
+ {
+ if(exp.op.exp1.destType) FreeType(exp.op.exp1.destType);
+ exp.op.exp1.destType = type2;
+ type2.refCount++;
+
+ if(CheckExpressionType(exp.op.exp1, exp.op.exp1.destType, false, false))
+ {
+ if(exp.expType) FreeType(exp.expType);
+ exp.expType = exp.op.exp1.destType;
+ if(exp.op.exp1.destType) exp.op.exp1.destType.refCount++;
+ }
+ }
+ else
+ {
+ if(exp.op.exp2.destType) FreeType(exp.op.exp2.destType);
+ exp.op.exp2.destType = type1;
+ type1.refCount++;
/*
// Maybe this was meant to be an enum...
}
*/
- if(CheckExpressionType(exp.op.exp2, exp.op.exp2.destType, false))
- {
- if(exp.expType) FreeType(exp.expType);
- exp.expType = exp.op.exp2.destType;
- if(exp.op.exp2.destType) exp.op.exp2.destType.refCount++;
- }
- else if(type1 && type2)
- {
- char expString1[10240];
- char expString2[10240];
- char type1String[1024];
- char type2String[1024];
- expString1[0] = '\0';
- expString2[0] = '\0';
- type1String[0] = '\0';
- type2String[0] = '\0';
- if(inCompiler)
+ if(CheckExpressionType(exp.op.exp2, exp.op.exp2.destType, false, false))
{
- PrintExpression(exp.op.exp1, expString1);
- ChangeCh(expString1, '\n', ' ');
- PrintExpression(exp.op.exp2, expString2);
- ChangeCh(expString2, '\n', ' ');
- PrintType(exp.op.exp1.expType, type1String, false, true);
- PrintType(exp.op.exp2.expType, type2String, false, true);
+ if(exp.expType) FreeType(exp.expType);
+ exp.expType = exp.op.exp2.destType;
+ if(exp.op.exp2.destType) exp.op.exp2.destType.refCount++;
}
+ else if(type1 && type2)
+ {
+ char expString1[10240];
+ char expString2[10240];
+ char type1String[1024];
+ char type2String[1024];
+ expString1[0] = '\0';
+ expString2[0] = '\0';
+ type1String[0] = '\0';
+ type2String[0] = '\0';
+ if(inCompiler)
+ {
+ PrintExpression(exp.op.exp1, expString1);
+ ChangeCh(expString1, '\n', ' ');
+ PrintExpression(exp.op.exp2, expString2);
+ ChangeCh(expString2, '\n', ' ');
+ PrintType(exp.op.exp1.expType, type1String, false, true);
+ PrintType(exp.op.exp2.expType, type2String, false, true);
+ }
- Compiler_Warning($"incompatible expressions %s (%s) and %s (%s)\n", expString1, type1String, expString2, type2String);
+ Compiler_Warning($"incompatible expressions %s (%s) and %s (%s)\n", expString1, type1String, expString2, type2String);
- if(type1.kind == classType && type1._class && type1._class.registered && type1._class.registered.type == enumClass)
- {
- exp.expType = exp.op.exp1.expType;
- if(exp.op.exp1.expType) exp.op.exp1.expType.refCount++;
- }
- else if(type2.kind == classType && type2._class && type2._class.registered && type2._class.registered.type == enumClass)
- {
- exp.expType = exp.op.exp2.expType;
- if(exp.op.exp2.expType) exp.op.exp2.expType.refCount++;
+ if(c1 && c1.type == enumClass)
+ {
+ exp.expType = exp.op.exp1.expType;
+ if(exp.op.exp1.expType) exp.op.exp1.expType.refCount++;
+ }
+ else if(c2 && c2.type == enumClass)
+ {
+ exp.expType = exp.op.exp2.expType;
+ if(exp.op.exp2.expType) exp.op.exp2.expType.refCount++;
+ }
}
}
}
else if(type2)
{
// Maybe this was meant to be an enum...
- if(type2.kind == classType && type2._class && type2._class.registered && type2._class.registered.type == enumClass)
+ if(c2 && c2.type == enumClass)
{
Type oldType = exp.op.exp1.expType;
exp.op.exp1.expType = null;
- if(CheckExpressionType(exp.op.exp1, exp.op.exp1.destType, false))
+ if(CheckExpressionType(exp.op.exp1, exp.op.exp1.destType, false, false))
FreeType(oldType);
else
exp.op.exp1.expType = oldType;
}
*/
- if(CheckExpressionType(exp.op.exp1, exp.op.exp1.destType, false))
+ if(CheckExpressionType(exp.op.exp1, exp.op.exp1.destType, false, false))
{
if(exp.expType) FreeType(exp.expType);
exp.expType = exp.op.exp1.destType;
}
else if(type2 && (!type1 || (type2.kind == classType && type1.kind != classType)))
{
- if(type1 && type2._class && type2._class.registered && type2._class.registered.type == unitClass)
+ if(type1 && c2 && c2.type == unitClass)
{
if(exp.op.exp1.destType) FreeType(exp.op.exp1.destType);
// Convert e.g. / 4 into / 4.0
exp.op.exp1.destType = type2._class.registered.dataType;
if(type2._class.registered.dataType)
type2._class.registered.dataType.refCount++;
- CheckExpressionType(exp.op.exp1, exp.op.exp1.destType, false);
+ CheckExpressionType(exp.op.exp1, exp.op.exp1.destType, false, false);
}
if(exp.op.op == '!')
{
}
else if(type1 && (!type2 || (type1.kind == classType && type2.kind != classType)))
{
- if(type2 && type1._class && type1._class.registered && type1._class.registered.type == unitClass)
+ if(c2 && c2.type == unitClass)
{
if(exp.op.exp2.destType) FreeType(exp.op.exp2.destType);
// Convert e.g. / 4 into / 4.0
exp.op.exp2.destType = type1._class.registered.dataType;
if(type1._class.registered.dataType)
type1._class.registered.dataType.refCount++;
- CheckExpressionType(exp.op.exp2, exp.op.exp2.destType, false);
+ CheckExpressionType(exp.op.exp2, exp.op.exp2.destType, false, false);
}
exp.expType = type1;
if(type1) type1.refCount++;
if(exp.op.op == SIZEOF && exp.op.exp2.expType)
{
- DeclareType(exp.op.exp2.expType, false, false);
+ DeclareType(curExternal, exp.op.exp2.expType, true, false);
}
+ if(exp.op.op == DELETE && exp.op.exp2 && exp.op.exp2.expType && exp.op.exp2.expType.specConst)
+ Compiler_Warning($"deleting const qualified object\n");
+
yylloc = oldyylloc;
FreeType(dummy);
+ if(type2)
+ FreeType(type2);
break;
}
case bracketsExp:
exp.isConstant = true;
for(e = exp.list->first; e; e = e.next)
{
- bool inced = false;
+ //bool inced = false;
if(!e.next)
{
FreeType(e.destType);
+ e.opDestType = exp.opDestType;
+ e.usedInComparison = exp.usedInComparison;
+ e.parentOpDestType = exp.parentOpDestType;
e.destType = exp.destType;
- if(e.destType) { exp.destType.refCount++; e.destType.count++; inced = true; }
+ if(e.destType) { exp.destType.refCount++; /*e.destType.count++; inced = true;*/ }
}
ProcessExpressionType(e);
- if(inced)
- exp.destType.count--;
+ if(e.ambiguousUnits)
+ exp.ambiguousUnits = true;
+ /*if(inced)
+ exp.destType.count--;*/
if(!exp.expType && !e.next)
{
exp.expType = e.expType;
if(e.expType) e.expType.refCount++;
+ exp.needCast = e.needCast;
}
if(!e.isConstant)
exp.isConstant = false;
if(exp.index.index && exp.index.index->last)
{
- ((Expression)exp.index.index->last).destType = ProcessTypeString(_class.templateArgs[1].dataTypeString, false);
+ Type type = ProcessTypeString(_class.templateArgs[1].dataTypeString, false);
+
+ if(type.kind == classType) type.constant = true;
+ else if(type.kind == pointerType)
+ {
+ Type t = type;
+ while(t.kind == pointerType) t = t.type;
+ t.constant = true;
+ }
+
+ ((Expression)exp.index.index->last).destType = type;
}
}
}
if(!exp.expType)
exp.expType = Dereference(exp.index.exp.expType);
if(exp.expType)
- DeclareType(exp.expType, false, false);
+ DeclareType(curExternal, exp.expType, true, false);
break;
}
case callExp:
{
Class backupThisClass = thisClass;
thisClass = exp.call.exp.expType.usedClass;
- ProcessDeclarator(decl);
+ ProcessDeclarator(decl, true);
thisClass = backupThisClass;
}
functionType = ProcessType(specs, decl);
functionType.refCount = 0;
FinishTemplatesContext(context);
+
+ // Mark parameters that were 'thisclass'
+ {
+ Type p, op;
+ for(p = functionType.params.first, op = methodType.method.dataType.params.first; p && op; p = p.next, op = op.next)
+ {
+ //p.wasThisClass = op.kind == thisClassType;
+ if(op.kind == thisClassType)
+ p.thisClassFrom = methodType.method._class;
+ }
+ }
+ if(methodType.method.dataType.returnType.kind == thisClassType)
+ {
+ // functionType.returnType.wasThisClass = true;
+ functionType.returnType.thisClassFrom = methodType.method._class;
+ }
}
FreeList(specs, FreeSpecifier);
}
if(curParam && _class.templateArgs[id].dataTypeString)
{
+ bool constant = type.constant;
ClassTemplateArgument arg = _class.templateArgs[id];
{
Context context = SetupTemplatesContext(_class);
templatedType = ProcessTypeString(arg.dataTypeString, false);
FinishTemplatesContext(context);
}
+
+ if(templatedType.kind == classType && constant) templatedType.constant = true;
+ else if(templatedType.kind == pointerType)
+ {
+ Type t = templatedType.type;
+ while(t.kind == pointerType) t = t.type;
+ if(constant) t.constant = constant;
+ }
+
e.destType = templatedType;
if(templatedType)
{
if(exp.call.arguments)
{
for(e = exp.call.arguments->first; e; e = e.next)
- {
- Type destType = e.destType;
ProcessExpressionType(e);
- }
}
break;
}
char * colon = strstr(param.defaultArg.memberString, "::");
if(colon)
{
- char className[1024];
- Class sClass;
-
memcpy(thisClassTypeString, param.defaultArg.memberString, colon - param.defaultArg.memberString);
thisClassTypeString[colon - param.defaultArg.memberString] = '\0';
}
{
Class expClass = exp.expType._class.registered;
Class cClass = null;
- int c;
int paramCount = 0;
int lastParam = -1;
Expression exp;
char * string = PrintHexUInt64(arg.expression.ui64);
exp = MkExpCast(MkTypeName(specs, decl), MkExpConstant(string));
+ delete string;
ProcessExpressionType(exp);
ComputeExpression(exp);
}
}
- // *([expType] *)(((byte *)[exp.member.exp]) + [argExp].member.offset)
+ if(!expMember.expType.isPointerType)
+ expMember = MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uintptr")), null), expMember);
+ // *([expType] *)(((byte *)(uintptr)[exp.member.exp]) + [argExp].member.offset)
exp.type = bracketsExp;
exp.list = MkListOne(MkExpOp(null, '*',
/*opExp;
exp.op.exp2 = */
MkExpCast(MkTypeName(specs, MkDeclaratorPointer(MkPointer(null, null), decl)), MkExpBrackets(MkListOne(MkExpOp(
MkExpBrackets(MkListOne(
- MkExpCast(MkTypeName(MkListOne(MkSpecifierName("byte")), MkDeclaratorPointer(MkPointer(null, null), null)), expMember))),
- '+',
- MkExpOp(MkExpMember(MkExpMember(argExp, MkIdentifier("member")), MkIdentifier("offset")),
- '+',
- MkExpMember(MkExpMember(MkExpMember(CopyExpression(argExp), MkIdentifier("member")), MkIdentifier("_class")), MkIdentifier("offset")))))))
+ MkExpCast(MkTypeName(MkListOne(MkSpecifierName("byte")), MkDeclaratorPointer(MkPointer(null, null), null)),
+ expMember))),
+ '+',
+ MkExpOp(MkExpMember(MkExpMember(argExp, MkIdentifier("member")), MkIdentifier("offset")),
+ '+',
+ MkExpMember(MkExpMember(MkExpMember(CopyExpression(argExp), MkIdentifier("member")), MkIdentifier("_class")), MkIdentifier("offset")))))))
));
}
// Prioritize properties over data members otherwise
else
{
+ bool useMemberForNonConst = false;
// First look for Public Members (Unless class specifier is provided, which skips public priority)
if(!id.classSym)
{
prop = eClass_FindProperty(_class, id.string, null);
- if(!id._class || !id._class.name || strcmp(id._class.name, "property"))
+
+ useMemberForNonConst = prop && exp.destType &&
+ ( (exp.destType.kind == classType && !exp.destType.constant) || ((exp.destType.kind == pointerType || exp.destType.kind == arrayType) && exp.destType.type && !exp.destType.type.constant) ) &&
+ !strncmp(prop.dataTypeString, "const ", 6);
+
+ if(useMemberForNonConst || !id._class || !id._class.name || strcmp(id._class.name, "property"))
member = eClass_FindDataMember(_class, id.string, null, null, null);
}
- if(!prop && !member)
+ if((!prop || useMemberForNonConst) && !member)
{
- method = eClass_FindMethod(_class, id.string, null);
+ method = useMemberForNonConst ? null : eClass_FindMethod(_class, id.string, null);
if(!method)
{
prop = eClass_FindProperty(_class, id.string, privateModule);
- if(!id._class || !id._class.name || strcmp(id._class.name, "property"))
+
+ useMemberForNonConst |= prop && exp.destType &&
+ ( (exp.destType.kind == classType && !exp.destType.constant) || ((exp.destType.kind == pointerType || exp.destType.kind == arrayType) && exp.destType.type && !exp.destType.type.constant) ) &&
+ !strncmp(prop.dataTypeString, "const ", 6);
+
+ if(useMemberForNonConst || !id._class || !id._class.name || strcmp(id._class.name, "property"))
member = eClass_FindDataMember(_class, id.string, privateModule, null, null);
}
}
if(member && prop)
{
- if(member._class != prop._class && !id._class && eClass_IsDerived(member._class, prop._class))
+ if(useMemberForNonConst || (member._class != prop._class && !id._class && eClass_IsDerived(member._class, prop._class)))
prop = null;
else
member = null;
}
}
+ //if(!exp.member.exp.destType)
+ if(exp.member.exp.destType)
+ FreeType(exp.member.exp.destType);
+ {
+ if(method && !method._class.symbol)
+ method._class.symbol = FindClass(method._class.fullName);
+ if(prop && !prop._class.symbol)
+ prop._class.symbol = FindClass(prop._class.fullName);
+
+ exp.member.exp.destType = Type
+ {
+ refCount = 1;
+ kind = classType;
+ _class = prop ? prop._class.symbol : method ? method._class.symbol : _class.symbol;
+ // wasThisClass = type ? type.wasThisClass : false;
+ thisClassFrom = type ? type.thisClassFrom : null;
+ };
+ }
+
if(prop)
{
exp.member.memberType = propertyMember;
if(!prop.dataType)
ProcessPropertyType(prop);
exp.expType = prop.dataType;
- if(prop.dataType) prop.dataType.refCount++;
+ if(!strcmp(_class.base.fullName, "eda::Row") && !exp.expType.constant && !exp.destType)
+ {
+ Type type { };
+ CopyTypeInto(type, exp.expType);
+ type.refCount = 1;
+ type.constant = true;
+ exp.expType = type;
+ }
+ else if(prop.dataType)
+ prop.dataType.refCount++;
}
else if(member)
{
}
exp.member.memberType = dataMember;
- DeclareStruct(_class.fullName, false);
+ DeclareStruct(curExternal, _class.fullName, false, true);
+ if(member._class != _class)
+ DeclareStruct(curExternal, member._class.fullName, false, true);
+
if(!member.dataType)
{
Context context = SetupTemplatesContext(_class);
member.dataType = ProcessTypeString(member.dataTypeString, false);
FinishTemplatesContext(context);
}
+ if(exp.member.exp.expType.kind == classType && exp.member.exp.expType._class && exp.member.exp.expType._class.registered && exp.member.exp.expType._class.registered.type == bitClass)
+ member.dataType.bitMemberSize = ((BitMember)member).size;
exp.expType = member.dataType;
if(member.dataType) member.dataType.refCount++;
}
FreeExpContents(exp);
exp.type = identifierExp;
exp.identifier = MkIdentifier("class");
- ProcessExpressionType(exp);
+ FreeType(exp.expType);
+ exp.expType = MkClassType("ecere::com::Class");
return;
}
yylloc = exp.member.member.loc;
{
Class tClass;
- tClass = _class;
+ tClass = type._class && type._class.registered ? type._class.registered : _class;
while(tClass && !tClass.templateClass) tClass = tClass.base;
if(tClass && exp.expType.kind == templateType && exp.expType.templateParameter.type == TemplateParameterType::type)
{
ClassTemplateArgument arg = tClass.templateArgs[id];
Context context = SetupTemplatesContext(tClass);
+ bool constant = exp.expType.constant;
+ bool passAsTemplate = false;
+ Class thisClassFrom = null;
+ Type t = ProcessTypeString(exp.expType.templateParameter.dataTypeString, false);
+ if(t && t.kind == classType && t._class)
+ thisClassFrom = t._class.registered;
+ else
+ // Mark that 'thisClassFrom' was set to something
+ thisClassFrom = eSystem_FindClass(GetPrivateModule(), "class");
+
+ FreeType(t);
+
+ passAsTemplate = tClass.templateClass && (exp.expType.kind != templateType ||
+ (!exp.expType.templateParameter || (!exp.expType.templateParameter.dataTypeString && !exp.expType.templateParameter.dataType)));
+
/*if(!arg.dataType)
arg.dataType = ProcessTypeString(arg.dataTypeString, false);*/
FreeType(exp.expType);
+
exp.expType = ProcessTypeString(arg.dataTypeString, false);
+ exp.expType.thisClassFrom = thisClassFrom;
+ if(exp.expType.kind == classType && constant) exp.expType.constant = true;
+ else if(exp.expType.kind == pointerType)
+ {
+ Type t = exp.expType.type;
+ while(t.kind == pointerType) t = t.type;
+ if(constant) t.constant = constant;
+ }
if(exp.expType)
{
if(exp.expType.kind == thisClassType)
exp.expType = ReplaceThisClassType(_class);
}
- if(tClass.templateClass)
+ if(passAsTemplate)
exp.expType.passAsTemplate = true;
//exp.expType.refCount++;
if(!exp.destType)
{
exp.destType = ProcessTypeString(arg.dataTypeString, false);
+ if(exp.destType.kind == classType && constant) exp.destType.constant = true;
+ else if(exp.destType.kind == pointerType)
+ {
+ Type t = exp.destType.type;
+ while(t.kind == pointerType) t = t.type;
+ if(constant) t.constant = constant;
+ }
+
//exp.destType.refCount++;
if(exp.destType.kind == thisClassType)
if(expClass)
{
Class cClass = null;
- int c;
int p = 0;
int paramCount = 0;
int lastParam = -1;
for(param = cClass.templateParams.first; param; param = param.next)
{
Class cClassCur = null;
- int c;
int cp = 0;
ClassTemplateParameter paramCur = null;
ClassTemplateArgument arg;
Expression exp;
char * string = PrintHexUInt64(arg.expression.ui64);
exp = MkExpCast(MkTypeName(specs, decl), MkExpConstant(string));
+ delete string;
ProcessExpressionType(exp);
ComputeExpression(exp);
Symbol classSym = exp._class.symbol; // FindClass(exp._class.name);
if(classSym && classSym.registered)
{
- if(classSym.registered.type == noHeadClass)
+ if(classSym.registered.type == noHeadClass || (classSym.registered.fixed && classSym.registered.structSize))
{
char name[1024];
+ Class b = classSym.registered;
name[0] = '\0';
- DeclareStruct(classSym.string, false);
+ DeclareStruct(curExternal, classSym.string, false, true);
FreeSpecifier(exp._class);
- exp.type = typeSizeExp;
FullClassNameCat(name, classSym.string, false);
- exp.typeName = MkTypeName(MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier(name), null)), null);
+
+ if(b.offset == 0)
+ {
+ exp.type = typeSizeExp;
+ exp.typeName = MkTypeName(MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier(name), null)), null);
+ }
+ else
+ {
+ Expression e;
+ exp.type = opExp;
+ if(b.structSize == b.offset)
+ exp.op.exp1 = MkExpConstant("0");
+ else
+ exp.op.exp1 = MkExpTypeSize(MkTypeName(MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier(name), null)), null));
+ exp.op.op = '+';
+ e = exp;
+ while(b.offset != 0)
+ {
+ Symbol sym;
+ Expression typeSize;
+
+ b = b.base;
+ sym = FindClass(b.fullName);
+
+ name[0] = '\0';
+ DeclareStruct(curExternal, sym.string, false, true);
+ FullClassNameCat(name, sym.string, false);
+
+ if(b.structSize == b.offset)
+ typeSize = MkExpConstant("0");
+ else
+ typeSize = MkExpTypeSize(MkTypeName(MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier(name), null)), null));
+ e.op.exp2 = b.offset ? MkExpOp(typeSize, '+', null) : typeSize;
+ e = e.op.exp2;
+ }
+ }
}
else
{
- if(classSym.registered.fixed)
+ if(classSym.registered.fixed && !classSym.registered.structSize)
{
FreeSpecifier(exp._class);
exp.constant = PrintUInt(classSym.registered.templateClass ? classSym.registered.templateClass.structSize : classSym.registered.structSize);
char className[1024];
strcpy(className, "__ecereClass_");
FullClassNameCat(className, classSym.string, true);
- MangleClassName(className);
- DeclareClass(classSym, className);
+ DeclareClass(curExternal, classSym, className);
FreeExpContents(exp);
exp.type = pointerExp;
exp.expType = Type
{
refCount = 1;
- kind = intType;
+ kind = intSizeType;
};
// exp.isConstant = true;
break;
exp.expType = Type
{
refCount = 1;
- kind = intType;
+ kind = intSizeType;
};
exp.isConstant = true;
- DeclareType(type, false, false);
+ DeclareType(curExternal, type, true, false);
FreeType(type);
break;
}
FreeType(exp.cast.exp.destType);
exp.cast.exp.destType = type;
type.refCount++;
+ type.casted = true;
ProcessExpressionType(exp.cast.exp);
+ type.casted = false;
type.count = 0;
exp.expType = type;
//type.refCount++;
case conditionExp:
{
Expression e;
+ Type t = exp.destType;
+ if(t && !exp.destType.casted)
+ {
+ t = { };
+ CopyTypeInto(t, exp.destType);
+ t.count = 0;
+ }
+ else if(t)
+ t.refCount++;
+
exp.isConstant = true;
FreeType(exp.cond.cond.destType);
if(!e.next)
{
FreeType(e.destType);
- e.destType = exp.destType;
+ e.destType = t;
if(e.destType) e.destType.refCount++;
}
ProcessExpressionType(e);
// exp.cond.elseExp.destType = exp.expType ? exp.expType : exp.destType;
// Reversed it...
- exp.cond.elseExp.destType = exp.destType ? exp.destType : exp.expType;
+ exp.cond.elseExp.destType = t ? t : exp.expType;
if(exp.cond.elseExp.destType)
exp.cond.elseExp.destType.refCount++;
// FIXED THIS: Was done before calling process on elseExp
if(!exp.cond.elseExp.isConstant)
exp.isConstant = false;
+
+ FreeType(t);
break;
}
case extensionCompoundExp:
case arrayExp:
{
Type type = null;
- char * typeString = null;
+ const char * typeString = null;
char typeStringBuf[1024];
if(exp.destType && exp.destType.kind == classType && exp.destType._class && exp.destType._class.registered &&
exp.destType._class.registered != containerClass && eClass_IsDerived(exp.destType._class.registered, containerClass))
else
{
// if(!MatchType(e.expType, type, null, null, null, false, false, false))
- if(!MatchTypeExpression(e, type, null, false))
+ if(!MatchTypeExpression(e, type, null, false, true))
{
FreeType(type);
type = e.expType;
if(e.expType)
{
//if(!MatchTypes(e.expType, type, null, null, null, false, false, false))
- if(!MatchTypeExpression(e, type, null, false))
+ if(!MatchTypeExpression(e, type, null, false, true))
{
FreeType(e.expType);
e.expType = null;
{
Expression e;
type = ProcessTypeString(typeString, false);
- while(e = exp.list->first)
+ while((e = exp.list->first))
{
exp.list->Remove(e);
e.destType = type;
delete exp.list;
}
- DeclareStruct("ecere::com::BuiltInContainer", false);
+ DeclareStruct(curExternal, "ecere::com::BuiltInContainer", false, true);
ListAdd(structInitializers, /*MkIdentifier("_vTbl")*/ MkInitializerAssignment(MkExpMember(MkExpClass(MkListOne(MkSpecifierName("BuiltInContainer")), null), MkIdentifier("_vTbl"))));
ProcessExpressionType(((Initializer)structInitializers->last).exp);
}
else
{
- NamedLink member;
+ NamedLink64 member;
for(member = symbol.type.members.first; member; member = member.next)
{
- NamedLink value { name = CopyString(member.name) };
+ NamedLink64 value { name = CopyString(member.name) };
exp.expType.members.Add(value);
}
}
}
}
+ // Trying to do this here before conversion properties kick in and this becomes a new expression... (Fixing Class c; const char * a = c;)
+ // Mark nohead classes as by reference, unless we're casting them to an integral type
+ if(!notByReference && exp.expType && exp.expType.kind == classType && exp.expType._class && exp.expType._class.registered &&
+ exp.expType._class.registered.type == noHeadClass && (!exp.destType ||
+ (exp.destType.kind != intType && exp.destType.kind != int64Type && exp.destType.kind != intPtrType && exp.destType.kind != intSizeType &&
+ exp.destType.kind != longType && exp.destType.kind != shortType && exp.destType.kind != charType && exp.destType.kind != _BoolType)))
+ {
+ exp.byReference = true;
+ }
+
yylloc = exp.loc;
- if(exp.destType && (exp.destType.kind == voidType || exp.destType.kind == dummyType) );
+ if(exp.destType && (/*exp.destType.kind == voidType || */exp.destType.kind == dummyType) );
else if(exp.destType && !exp.destType.keepCast)
{
- if(!CheckExpressionType(exp, exp.destType, false))
+ if(!exp.needTemplateCast && exp.expType && (exp.expType.kind == templateType || exp.expType.passAsTemplate)) // && exp.destType && !exp.destType.passAsTemplate)
+ exp.needTemplateCast = 1;
+
+ if(exp.destType.kind == voidType);
+ else if(!CheckExpressionType(exp, exp.destType, false, !exp.destType.casted))
{
- if(!exp.destType.count || unresolved)
+ // Warn for casting unrelated types to/from struct classes
+ bool invalidCast = false;
+ if(inCompiler && exp.destType.count && exp.expType)
+ {
+ Class c1 = (exp.expType.kind == classType && exp.expType._class) ? exp.expType._class.registered : null;
+ Class c2 = (exp.destType.kind == classType && exp.destType._class) ? exp.destType._class.registered : null;
+ if(c1 && c1.type != structClass) c1 = null;
+ if(c2 && c2.type != structClass) c2 = null;
+ if((c1 && !exp.expType.byReference && !c2 && !exp.destType.isPointerType) || (c2 && !exp.destType.byReference && !c1 && !exp.expType.isPointerType))
+ invalidCast = true;
+ }
+ if(!exp.destType.count || unresolved || invalidCast)
{
if(!exp.expType)
{
(exp.expType.kind != classType || exp.expType.classObjectType || (exp.expType._class && exp.expType._class.registered && exp.expType._class.registered.type != structClass)));
else
{
- char expString[10240];
- expString[0] = '\0';
- if(inCompiler) { PrintExpression(exp, expString); ChangeCh(expString, '\n', ' '); }
+ Expression nbExp = GetNonBracketsExp(exp);
+ bool skipWarning = false;
+ TypeKind kind = exp.destType.kind;
+ if(nbExp.type == conditionExp && nbExp.destType && !nbExp.destType.casted && nbExp.destType.kind == exp.destType.kind)
+ // The if/else operands have already been checked / warned about
+ skipWarning = true;
+ if((kind == charType || kind == shortType) && exp.destType.isSigned == exp.expType.signedBeforePromotion && nbExp.type == opExp && nbExp.op.exp1 && nbExp.op.exp2)
+ {
+ int op = nbExp.op.op;
+ Expression nbExp1, nbExp2;
+ TypeKind from;
+
+ switch(op)
+ {
+ case '%': case '/':
+ nbExp1 = GetNonBracketsExp(nbExp.op.exp1);
+ from = nbExp1.expType.promotedFrom;
+ // Division and Modulo will not take more room than type before promotion
+ if(from == charType || (kind == shortType && from == shortType))
+ skipWarning = true;
+ break;
+ // Left shift
+ case LEFT_OP: case RIGHT_OP:
+ nbExp1 = GetNonBracketsExp(nbExp.op.exp1);
+ nbExp2 = GetNonBracketsExp(nbExp.op.exp2);
+ from = nbExp1.expType.promotedFrom;
+ // Right shift will not take more room than type before promotion
+ if(op == RIGHT_OP && (from == charType || (kind == shortType && from == shortType)))
+ skipWarning = true;
+ else if(nbExp2.isConstant && nbExp2.type == constantExp && (nbExp.op.op == RIGHT_OP || nbExp1.expType.bitMemberSize))
+ {
+ int n = (int)strtol(nbExp2.constant, null, 0);
+ int s = from == charType ? 8 : 16;
+ // Left shifting a bit member constrained in size may still fit in type before promotion
+ if(nbExp1.expType.bitMemberSize && nbExp1.expType.bitMemberSize < s)
+ s = nbExp1.expType.bitMemberSize;
+
+ // If right shifted enough things will fit in smaller type
+ if(nbExp.op.op == RIGHT_OP)
+ s -= n;
+ else
+ s += n;
+ if(s <= (kind == charType ? 8 : 16))
+ skipWarning = true;
+ }
+ break;
+ case '-':
+ if(!exp.destType.isSigned)
+ {
+ nbExp1 = GetNonBracketsExp(nbExp.op.exp1);
+ nbExp2 = GetNonBracketsExp(nbExp.op.exp2);
+ from = nbExp2.expType.promotedFrom;
+ // Max value of unsigned type before promotion minus the same will always fit
+ if((from == charType || from == shortType) && nbExp1.isConstant && nbExp1.type == constantExp)
+ {
+ int n = (int)strtol(nbExp1.constant, null, 0);
+ if(n == (from == charType ? 255 : 65535))
+ skipWarning = true;
+ }
+ }
+ break;
+ case '|':
+ {
+ TypeKind kind1, kind2;
+ nbExp1 = GetNonBracketsExp(nbExp.op.exp1);
+ nbExp2 = GetNonBracketsExp(nbExp.op.exp2);
+ kind1 = nbExp1.expType.promotedFrom ? nbExp1.expType.promotedFrom : nbExp1.expType.kind;
+ kind2 = nbExp2.expType.promotedFrom ? nbExp2.expType.promotedFrom : nbExp2.expType.kind;
+ if(((kind1 == charType || (kind1 == shortType && kind == shortType)) || MatchTypeExpression(nbExp1, exp.destType, null, false, false)) &&
+ ((kind2 == charType || (kind2 == shortType && kind == shortType)) || MatchTypeExpression(nbExp2, exp.destType, null, false, false)))
+ skipWarning = true;
+ break;
+ }
+ case '&':
+ {
+ TypeKind kind1, kind2;
+ nbExp1 = GetNonBracketsExp(nbExp.op.exp1);
+ nbExp2 = GetNonBracketsExp(nbExp.op.exp2);
+ kind1 = nbExp1.expType.promotedFrom ? nbExp1.expType.promotedFrom : nbExp1.expType.kind;
+ kind2 = nbExp2.expType.promotedFrom ? nbExp2.expType.promotedFrom : nbExp2.expType.kind;
+ if(((kind1 == charType || (kind1 == shortType && kind == shortType)) || MatchTypeExpression(nbExp1, exp.destType, null, false, false)) ||
+ ((kind2 == charType || (kind2 == shortType && kind == shortType)) || MatchTypeExpression(nbExp2, exp.destType, null, false, false)))
+ skipWarning = true;
+ break;
+ }
+ }
+ }
+
+ if(!skipWarning)
+ {
+ char expString[10240];
+ expString[0] = '\0';
+ if(inCompiler) { PrintExpression(exp, expString); ChangeCh(expString, '\n', ' '); }
#ifdef _DEBUG
- CheckExpressionType(exp, exp.destType, false);
+ CheckExpressionType(exp, exp.destType, false, true);
#endif
- // Flex & Bison generate code that triggers this, so we ignore it for a quiet sdk build:
- if(!sourceFile || (strcmp(sourceFile, "src\\lexer.ec") && strcmp(sourceFile, "src/lexer.ec") && strcmp(sourceFile, "src\\grammar.ec") && strcmp(sourceFile, "src/grammar.ec")))
- Compiler_Warning($"incompatible expression %s (%s); expected %s\n", expString, type1, type2);
+
+ // Flex & Bison generate code that triggers this, so we ignore it for a quiet sdk build:
+ if(!sourceFile || (!strstr(sourceFile, "src\\lexer.ec") && !strstr(sourceFile, "src/lexer.ec") &&
+ !strstr(sourceFile, "src\\grammar.ec") && !strstr(sourceFile, "src/grammar.ec") &&
+ !strstr(sourceFile, "src\\type.ec") && !strstr(sourceFile, "src/type.ec") &&
+ !strstr(sourceFile, "src\\expression.ec") && !strstr(sourceFile, "src/expression.ec")))
+ {
+ if(invalidCast)
+ Compiler_Error($"incompatible expression %s (%s); expected %s\n", expString, type1, type2);
+ else
+ Compiler_Warning($"incompatible expression %s (%s); expected %s\n", expString, type1, type2);
+ }
+ }
// TO CHECK: FORCING HERE TO HELP DEBUGGER
- FreeType(exp.expType);
- exp.destType.refCount++;
- exp.expType = exp.destType;
+ if(!inCompiler)
+ {
+ FreeType(exp.expType);
+ exp.destType.refCount++;
+ exp.expType = exp.destType;
+ }
}
}
}
}
- else if(exp.destType && exp.destType.kind == ellipsisType && exp.expType && exp.expType.passAsTemplate)
+ // Cast function pointers to void * as eC already checked compatibility
+ else if(exp.destType && exp.destType.kind == pointerType && exp.destType.type && exp.destType.type.kind == functionType &&
+ exp.expType && (exp.expType.kind == functionType || exp.expType.kind == methodType))
{
- Expression newExp { };
- char typeString[1024];
- OldList * specs = MkList();
- Declarator decl;
-
- typeString[0] = '\0';
-
- *newExp = *exp;
-
- if(exp.expType) exp.expType.refCount++;
- if(exp.expType) exp.expType.refCount++;
- exp.type = castExp;
- newExp.destType = exp.expType;
-
- PrintType(exp.expType, typeString, false, false);
- decl = SpecDeclFromString(typeString, specs, null);
-
- exp.cast.typeName = MkTypeName(specs, decl);
- exp.cast.exp = newExp;
+ Expression nbExp = GetNonBracketsExp(exp);
+ if(nbExp.type != castExp || !IsVoidPtrCast(nbExp.cast.typeName))
+ {
+ Expression e = MoveExpContents(exp);
+ exp.cast.exp = MkExpBrackets(MkListOne(e));
+ exp.type = castExp;
+ exp.cast.exp.destType = exp.destType;
+ if(exp.destType) exp.destType.refCount++;
+ exp.cast.typeName = MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null, null), null));
+ }
}
}
else if(unresolved)
}
}
-static void ProcessSpecifier(Specifier spec, bool declareStruct)
+static void ProcessSpecifier(Specifier spec, bool declareStruct, bool warnClasses)
{
switch(spec.type)
{
spec.type = nameSpecifier;
spec.name = ReplaceThisClass(thisClass);
spec.symbol = FindClass(spec.name);
- ProcessSpecifier(spec, declareStruct);
+ ProcessSpecifier(spec, declareStruct, false);
}
}
break;
{
Symbol symbol = FindType(curContext, spec.name);
if(symbol)
- DeclareType(symbol.type, true, true);
- else if((symbol = spec.symbol /*FindClass(spec.name)*/) && symbol.registered && symbol.registered.type == structClass && declareStruct)
- DeclareStruct(spec.name, false);
+ DeclareType(curExternal, symbol.type, true, true);
+ else if(spec.symbol /*&& declareStruct*/)
+ {
+ Class c = spec.symbol.registered;
+ if(warnClasses && !c)
+ Compiler_Warning("Undeclared class %s\n", spec.name);
+ DeclareStruct(curExternal, spec.name, c && c.type == noHeadClass, declareStruct && c && c.type == structClass);
+ }
break;
}
case enumSpecifier:
ProcessExpressionType(e.exp);
}
}
- break;
+ // Fall through for IDE type processing
+ if(inCompiler)
+ break;
}
case structSpecifier:
case unionSpecifier:
{
if(spec.definitions)
{
- ClassDef def;
+ //ClassDef def;
Symbol symbol = spec.id ? FindClass(spec.id.string) : null;
//if(symbol)
ProcessClass(spec.definitions, symbol);
{
Symbol classSym = FindClass(spec.name);
if(classSym && classSym.registered && classSym.registered.type == structClass)
- DeclareStruct(spec.name, false);
+ DeclareStruct(spec.name, false, true);
break;
}
*/
}
-static void ProcessDeclarator(Declarator decl)
+static void ProcessDeclarator(Declarator decl, bool isFunction)
{
switch(decl.type)
{
case pointerDeclarator:
case extendedDeclarator:
case extendedDeclaratorEnd:
- if(decl.declarator)
- ProcessDeclarator(decl.declarator);
+ {
+ Identifier id = null;
+ Specifier classSpec = null;
if(decl.type == functionDeclarator)
{
- Identifier id = GetDeclId(decl);
+ id = GetDeclId(decl);
if(id && id._class)
{
+ classSpec = id._class;
+ id._class = null;
+ }
+ }
+ if(decl.declarator)
+ ProcessDeclarator(decl.declarator, isFunction);
+ if(decl.type == functionDeclarator)
+ {
+ if(classSpec)
+ {
TypeName param
{
- qualifiers = MkListOne(id._class);
+ qualifiers = MkListOne(classSpec);
declarator = null;
};
if(!decl.function.parameters)
decl.function.parameters = MkList();
decl.function.parameters->Insert(null, param);
- id._class = null;
}
if(decl.function.parameters)
{
for(param = decl.function.parameters->first; param; param = param.next)
{
- if(param.qualifiers && param.qualifiers->first)
+ if(param.qualifiers)
{
- Specifier spec = param.qualifiers->first;
- if(spec && spec.specifier == TYPED_OBJECT)
+ Specifier spec;
+ for(spec = param.qualifiers->first; spec; spec = spec.next)
{
- Declarator d = param.declarator;
- TypeName newParam
+ if(spec.type == baseSpecifier)
{
- qualifiers = MkListOne(MkSpecifier(VOID));
- declarator = MkDeclaratorPointer(MkPointer(null,null), d);
- };
+ if(spec.specifier == TYPED_OBJECT)
+ {
+ Declarator d = param.declarator;
+ TypeName newParam
+ {
+ qualifiers = MkListOne(MkSpecifier(VOID));
+ declarator = MkDeclaratorPointer(MkPointer(null,null), d);
+ };
+ if(!d || d.type != pointerDeclarator)
+ newParam.qualifiers->Insert(null, MkSpecifier(CONST));
- FreeList(param.qualifiers, FreeSpecifier);
+ FreeList(param.qualifiers, FreeSpecifier);
- param.qualifiers = MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier("__ecereNameSpace__ecere__com__Class"), null));
- param.declarator = MkDeclaratorPointer(MkPointer(null,null), MkDeclaratorIdentifier(MkIdentifier("class")));
+ param.qualifiers = MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier("__ecereNameSpace__ecere__com__Class"), null));
+ param.declarator = MkDeclaratorPointer(MkPointer(null,null), MkDeclaratorIdentifier(MkIdentifier("class")));
- decl.function.parameters->Insert(param, newParam);
- param = newParam;
- }
- else if(spec && spec.specifier == ANY_OBJECT)
- {
- Declarator d = param.declarator;
+ DeclareStruct(curExternal, "ecere::com::Class", false, true);
+
+ decl.function.parameters->Insert(param, newParam);
+ param = newParam;
+ break;
+ }
+ else if(spec.specifier == ANY_OBJECT)
+ {
+ Declarator d = param.declarator;
- FreeList(param.qualifiers, FreeSpecifier);
+ FreeList(param.qualifiers, FreeSpecifier);
- param.qualifiers = MkListOne(MkSpecifier(VOID));
- param.declarator = MkDeclaratorPointer(MkPointer(null,null), d);
- }
- else if(spec.specifier == THISCLASS)
- {
- if(thisClass)
+ param.qualifiers = MkListOne(MkSpecifier(VOID));
+ if(!d || d.type != pointerDeclarator)
+ param.qualifiers->Insert(null, MkSpecifier(CONST));
+ param.declarator = MkDeclaratorPointer(MkPointer(null,null), d);
+ break;
+ }
+ else if(spec.specifier == THISCLASS)
+ {
+ if(thisClass)
+ {
+ spec.type = nameSpecifier;
+ spec.name = ReplaceThisClass(thisClass);
+ spec.symbol = FindClass(spec.name);
+ ProcessSpecifier(spec, false, false);
+ }
+ break;
+ }
+ }
+ else if(spec.type == nameSpecifier)
+ {
+ ProcessSpecifier(spec, isFunction, true);
+ }
+ else if((spec.type == structSpecifier || spec.type == unionSpecifier) && !spec.definitions && spec.id && spec.id.string)
{
- spec.type = nameSpecifier;
- spec.name = ReplaceThisClass(thisClass);
- spec.symbol = FindClass(spec.name);
- ProcessSpecifier(spec, false);
+ Declarator d = param.declarator;
+ if(!d || d.type != pointerDeclarator)
+ DeclareStruct(curExternal, spec.id.string, false, true);
}
}
}
if(param.declarator)
- ProcessDeclarator(param.declarator);
+ ProcessDeclarator(param.declarator, false);
}
}
}
break;
+ }
}
}
-static void ProcessDeclaration(Declaration decl)
+static void ProcessDeclaration(Declaration decl, bool warnClasses)
{
yylloc = decl.loc;
switch(decl.type)
for(d = decl.declarators->first; d; d = d.next)
{
Type type, subType;
- ProcessDeclarator(d.declarator);
+ ProcessDeclarator(d.declarator, false);
type = ProcessType(decl.specifiers, d.declarator);
Specifier s;
for(s = decl.specifiers->first; s; s = s.next)
{
- ProcessSpecifier(s, declareStruct);
+ ProcessSpecifier(s, declareStruct, true);
}
}
break;
{
Type type = ProcessType(decl.specifiers, d.declarator);
Type subType;
- ProcessDeclarator(d);
+ ProcessDeclarator(d, false);
for(subType = type; subType;)
{
if(subType.kind == classType)
if(decl.specifiers)
{
for(spec = decl.specifiers->first; spec; spec = spec.next)
- ProcessSpecifier(spec, declareStruct);
+ ProcessSpecifier(spec, declareStruct, warnClasses);
}
break;
}
char getName[1024], setName[1024];
OldList * args;
- DeclareProperty(prop, setName, getName);
+ DeclareProperty(curExternal, prop, setName, getName);
// eInstance_FireWatchers(object, prop);
strcpy(propName, "__ecereProp_");
FullClassNameCat(propName, prop._class.fullName, false);
strcat(propName, "_");
- // strcat(propName, prop.name);
FullClassNameCat(propName, prop.name, true);
- MangleClassName(propName);
strcpy(propNameM, "__ecerePropM_");
FullClassNameCat(propNameM, prop._class.fullName, false);
strcat(propNameM, "_");
- // strcat(propNameM, prop.name);
FullClassNameCat(propNameM, prop.name, true);
- MangleClassName(propNameM);
if(prop.isWatchable)
{
ListAdd(args, object ? CopyExpression(object) : MkExpIdentifier(MkIdentifier("this")));
ListAdd(args, MkExpIdentifier(MkIdentifier(propNameM)));
ListAdd(stmt.expressions, MkExpCall(MkExpIdentifier(MkIdentifier("ecere::com::eInstance_FireWatchers")), args));
- }
+ DeclareFunctionUtil(curExternal, "eInstance_FireWatchers");
+ }
{
args = MkList();
ListAdd(args, object ? CopyExpression(object) : MkExpIdentifier(MkIdentifier("this")));
ListAdd(args, MkExpIdentifier(MkIdentifier(propNameM)));
ListAdd(stmt.expressions, MkExpCall(MkExpIdentifier(MkIdentifier("ecere::com::eInstance_FireSelfWatchers")), args));
+
+ DeclareFunctionUtil(curExternal, "eInstance_FireSelfWatchers");
}
if(curFunction.propSet && !strcmp(curFunction.propSet.string, prop.name) &&
Context prevContext = curContext;
if(!stmt.compound.isSwitch)
- {
curCompound = stmt;
- curContext = stmt.compound.context;
- }
+ curContext = stmt.compound.context;
if(stmt.compound.declarations)
{
for(decl = stmt.compound.declarations->first; decl; decl = decl.next)
- ProcessDeclaration(decl);
+ ProcessDeclaration(decl, true);
}
if(stmt.compound.statements)
{
(((Expression)exp->last).type == ExpressionType::arrayExp ||
(((Expression)exp->last).type == castExp && ((Expression)exp->last).cast.exp.type == ExpressionType::arrayExp));
Expression arrayExp;
- char * typeString = null;
+ const char * typeString = null;
int builtinCount = 0;
for(e = exp ? exp->first : null; e; e = e.next)
Class _class = source ? source._class.registered : null;
Symbol symbol;
Expression expIt = null;
- bool isMap = false, isArray = false, isLinkList = false, isList = false, isCustomAVLTree = false, isAVLTree = false;
+ bool isMap = false, isArray = false, isLinkList = false, isList = false, isCustomAVLTree = false; //, isAVLTree = false;
Class arrayClass = eSystem_FindClass(privateModule, "Array");
Class linkListClass = eSystem_FindClass(privateModule, "LinkList");
Class customAVLTreeClass = eSystem_FindClass(privateModule, "CustomAVLTree");
- stmt.type = compoundStmt;
- stmt.compound.context = Context { };
- stmt.compound.context.parent = curContext;
- curContext = stmt.compound.context;
+ if(inCompiler)
+ {
+ stmt.type = compoundStmt;
+
+ stmt.compound.context = Context { };
+ stmt.compound.context.parent = curContext;
+ curContext = stmt.compound.context;
+ }
if(source && eClass_IsDerived(source._class.registered, customAVLTreeClass))
{
Class mapClass = eSystem_FindClass(privateModule, "Map");
- Class avlTreeClass = eSystem_FindClass(privateModule, "AVLTree");
+ //Class avlTreeClass = eSystem_FindClass(privateModule, "AVLTree");
isCustomAVLTree = true;
- if(eClass_IsDerived(source._class.registered, avlTreeClass))
+ /*if(eClass_IsDerived(source._class.registered, avlTreeClass))
isAVLTree = true;
- else if(eClass_IsDerived(source._class.registered, mapClass))
+ else */if(eClass_IsDerived(source._class.registered, mapClass))
isMap = true;
}
else if(source && eClass_IsDerived(source._class.registered, arrayClass)) isArray = true;
isList = eClass_IsDerived(source._class.registered, listClass);
}
- if(isArray)
+ if(inCompiler && isArray)
{
Declarator decl;
OldList * specs = MkList();
else
{
// if(!MatchType(e.expType, type, null, null, null, false, false, false))
- if(!MatchTypeExpression(e, type, null, false))
+ if(!MatchTypeExpression(e, type, null, false, true))
{
FreeType(type);
type = e.expType;
if(e.expType)
{
//if(!MatchTypes(e.expType, type, null, null, null, false, false, false, false))
- if(!MatchTypeExpression(e, type, null, false))
+ if(!MatchTypeExpression(e, type, null, false, true))
{
FreeType(e.expType);
e.expType = null;
}
if(typeString)
{
- OldList * initializers = MkList();
- Declarator decl;
- OldList * specs = MkList();
- if(arrayExp.list)
+ if(inCompiler)
{
- Expression e;
+ OldList * initializers = MkList();
+ Declarator decl;
+ OldList * specs = MkList();
+ if(arrayExp.list)
+ {
+ Expression e;
+
+ builtinCount = arrayExp.list->count;
+ type = ProcessTypeString(typeString, false);
+ while((e = arrayExp.list->first))
+ {
+ arrayExp.list->Remove(e);
+ e.destType = type;
+ type.refCount++;
+ ProcessExpressionType(e);
+ if(inCompiler)
+ ListAdd(initializers, MkInitializerAssignment(e));
+ }
+ FreeType(type);
+ delete arrayExp.list;
+ }
+ decl = SpecDeclFromString(typeString, specs, MkDeclaratorIdentifier(id));
+
+ stmt.compound.declarations = MkListOne(MkDeclaration(CopyList(specs, CopySpecifier),
+ MkListOne(MkInitDeclarator(MkDeclaratorPointer(MkPointer(null, null), /*CopyDeclarator(*/decl/*)*/), null))));
- builtinCount = arrayExp.list->count;
+ ListAdd(stmt.compound.declarations, MkDeclaration(specs, MkListOne(MkInitDeclarator(
+ PlugDeclarator(
+ /*CopyDeclarator(*/decl/*)*/, MkDeclaratorArray(MkDeclaratorIdentifier(MkIdentifier("__internalArray")), null)
+ ), MkInitializerList(initializers)))));
+ FreeList(exp, FreeExpression);
+ }
+ else if(arrayExp.list)
+ {
+ Expression e;
type = ProcessTypeString(typeString, false);
- while(e = arrayExp.list->first)
+ for(e = arrayExp.list->first; e; e = e.next)
{
- arrayExp.list->Remove(e);
e.destType = type;
type.refCount++;
ProcessExpressionType(e);
- ListAdd(initializers, MkInitializerAssignment(e));
}
FreeType(type);
- delete arrayExp.list;
}
- decl = SpecDeclFromString(typeString, specs, MkDeclaratorIdentifier(id));
- stmt.compound.declarations = MkListOne(MkDeclaration(CopyList(specs, CopySpecifier),
- MkListOne(MkInitDeclarator(MkDeclaratorPointer(MkPointer(null, null), /*CopyDeclarator(*/decl/*)*/), null))));
-
- ListAdd(stmt.compound.declarations, MkDeclaration(specs, MkListOne(MkInitDeclarator(
- PlugDeclarator(
- /*CopyDeclarator(*/decl/*)*/, MkDeclaratorArray(MkDeclaratorIdentifier(MkIdentifier("__internalArray")), null)
- ), MkInitializerList(initializers)))));
- FreeList(exp, FreeExpression);
}
else
{
MkInitializerAssignment(MkExpBrackets(exp))))));
*/
}
- else if(isLinkList && !isList)
+ else if(inCompiler && isLinkList && !isList)
{
Declarator decl;
OldList * specs = MkList();
MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("__internalTree")),
MkInitializerAssignment(MkExpBrackets(exp))))));
}*/
- else if(_class.templateArgs)
+ else if(inCompiler && _class.templateArgs)
{
if(isMap)
sprintf(iteratorType, "MapIterator<%s, %s >", _class.templateArgs[5].dataTypeString, _class.templateArgs[6].dataTypeString);
MkExpIdentifier(id), MkListOne(MkMembersInitList(MkListOne(MkMemberInit(isMap ? MkListOne(MkIdentifier("map")) : null,
MkInitializerAssignment(MkExpBrackets(exp)))))))));
}
- symbol = FindSymbol(id.string, curContext, curContext, false, false);
-
- if(block)
+ if(inCompiler)
{
- // Reparent sub-contexts in this statement
- switch(block.type)
+ symbol = FindSymbol(id.string, curContext, curContext, false, false);
+
+ if(block)
{
- case compoundStmt:
- if(block.compound.context)
- block.compound.context.parent = stmt.compound.context;
- break;
- case ifStmt:
- if(block.ifStmt.stmt && block.ifStmt.stmt.type == compoundStmt && block.ifStmt.stmt.compound.context)
- block.ifStmt.stmt.compound.context.parent = stmt.compound.context;
- if(block.ifStmt.elseStmt && block.ifStmt.elseStmt.type == compoundStmt && block.ifStmt.elseStmt.compound.context)
- block.ifStmt.elseStmt.compound.context.parent = stmt.compound.context;
- break;
- case switchStmt:
- if(block.switchStmt.stmt && block.switchStmt.stmt.type == compoundStmt && block.switchStmt.stmt.compound.context)
- block.switchStmt.stmt.compound.context.parent = stmt.compound.context;
- break;
- case whileStmt:
- if(block.whileStmt.stmt && block.whileStmt.stmt.type == compoundStmt && block.whileStmt.stmt.compound.context)
- block.whileStmt.stmt.compound.context.parent = stmt.compound.context;
- break;
- case doWhileStmt:
- if(block.doWhile.stmt && block.doWhile.stmt.type == compoundStmt && block.doWhile.stmt.compound.context)
- block.doWhile.stmt.compound.context.parent = stmt.compound.context;
- break;
- case forStmt:
- if(block.forStmt.stmt && block.forStmt.stmt.type == compoundStmt && block.forStmt.stmt.compound.context)
- block.forStmt.stmt.compound.context.parent = stmt.compound.context;
- break;
- case forEachStmt:
- if(block.forEachStmt.stmt && block.forEachStmt.stmt.type == compoundStmt && block.forEachStmt.stmt.compound.context)
- block.forEachStmt.stmt.compound.context.parent = stmt.compound.context;
- break;
- /* Only handle those with compound blocks for now... (Potential limitation on compound statements within expressions)
- case labeledStmt:
- case caseStmt
- case expressionStmt:
- case gotoStmt:
- case continueStmt:
- case breakStmt
- case returnStmt:
- case asmStmt:
- case badDeclarationStmt:
- case fireWatchersStmt:
- case stopWatchingStmt:
- case watchStmt:
- */
+ // Reparent sub-contexts in this statement
+ switch(block.type)
+ {
+ case compoundStmt:
+ if(block.compound.context)
+ block.compound.context.parent = stmt.compound.context;
+ break;
+ case ifStmt:
+ if(block.ifStmt.stmt && block.ifStmt.stmt.type == compoundStmt && block.ifStmt.stmt.compound.context)
+ block.ifStmt.stmt.compound.context.parent = stmt.compound.context;
+ if(block.ifStmt.elseStmt && block.ifStmt.elseStmt.type == compoundStmt && block.ifStmt.elseStmt.compound.context)
+ block.ifStmt.elseStmt.compound.context.parent = stmt.compound.context;
+ break;
+ case switchStmt:
+ if(block.switchStmt.stmt && block.switchStmt.stmt.type == compoundStmt && block.switchStmt.stmt.compound.context)
+ block.switchStmt.stmt.compound.context.parent = stmt.compound.context;
+ break;
+ case whileStmt:
+ if(block.whileStmt.stmt && block.whileStmt.stmt.type == compoundStmt && block.whileStmt.stmt.compound.context)
+ block.whileStmt.stmt.compound.context.parent = stmt.compound.context;
+ break;
+ case doWhileStmt:
+ if(block.doWhile.stmt && block.doWhile.stmt.type == compoundStmt && block.doWhile.stmt.compound.context)
+ block.doWhile.stmt.compound.context.parent = stmt.compound.context;
+ break;
+ case forStmt:
+ if(block.forStmt.stmt && block.forStmt.stmt.type == compoundStmt && block.forStmt.stmt.compound.context)
+ block.forStmt.stmt.compound.context.parent = stmt.compound.context;
+ break;
+ case forEachStmt:
+ if(block.forEachStmt.stmt && block.forEachStmt.stmt.type == compoundStmt && block.forEachStmt.stmt.compound.context)
+ block.forEachStmt.stmt.compound.context.parent = stmt.compound.context;
+ break;
+ /* Only handle those with compound blocks for now... (Potential limitation on compound statements within expressions)
+ case labeledStmt:
+ case caseStmt
+ case expressionStmt:
+ case gotoStmt:
+ case continueStmt:
+ case breakStmt
+ case returnStmt:
+ case asmStmt:
+ case badDeclarationStmt:
+ case fireWatchersStmt:
+ case stopWatchingStmt:
+ case watchStmt:
+ */
+ }
}
- }
- if(filter)
- {
- block = MkIfStmt(filter, block, null);
- }
- if(isArray)
- {
- stmt.compound.statements = MkListOne(MkForStmt(
- MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(CopyIdentifier(id)), '=', MkExpMember(MkExpIdentifier(MkIdentifier("__internalArray")), MkIdentifier("array"))))),
- MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(CopyIdentifier(id)), '<',
- MkExpOp(MkExpMember(MkExpIdentifier(MkIdentifier("__internalArray")), MkIdentifier("array")), '+', MkExpMember(MkExpIdentifier(MkIdentifier("__internalArray")), MkIdentifier("count")))))),
- MkListOne(MkExpOp(MkExpIdentifier(CopyIdentifier(id)), INC_OP, null)),
- block));
- ProcessStatement(((Statement)stmt.compound.statements->first).forStmt.init);
- ProcessStatement(((Statement)stmt.compound.statements->first).forStmt.check);
- ProcessExpressionType(((Statement)stmt.compound.statements->first).forStmt.increment->first);
- }
- else if(isBuiltin)
- {
- char count[128];
- //OldList * specs = MkList();
- // Declarator decl = SpecDeclFromString(typeString, specs, MkDeclaratorPointer(MkPointer(null, null), null));
- sprintf(count, "%d", builtinCount);
+ if(filter)
+ {
+ block = MkIfStmt(filter, block, null);
+ }
+ if(isArray)
+ {
+ stmt.compound.statements = MkListOne(MkForStmt(
+ MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(CopyIdentifier(id)), '=', MkExpMember(MkExpIdentifier(MkIdentifier("__internalArray")), MkIdentifier("array"))))),
+ MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(CopyIdentifier(id)), '<',
+ MkExpOp(MkExpMember(MkExpIdentifier(MkIdentifier("__internalArray")), MkIdentifier("array")), '+', MkExpMember(MkExpIdentifier(MkIdentifier("__internalArray")), MkIdentifier("count")))))),
+ MkListOne(MkExpOp(MkExpIdentifier(CopyIdentifier(id)), INC_OP, null)),
+ block));
+ ProcessStatement(((Statement)stmt.compound.statements->first).forStmt.init);
+ ProcessStatement(((Statement)stmt.compound.statements->first).forStmt.check);
+ ProcessExpressionType(((Statement)stmt.compound.statements->first).forStmt.increment->first);
+ }
+ else if(isBuiltin)
+ {
+ char count[128];
+ //OldList * specs = MkList();
+ // Declarator decl = SpecDeclFromString(typeString, specs, MkDeclaratorPointer(MkPointer(null, null), null));
+
+ sprintf(count, "%d", builtinCount);
- stmt.compound.statements = MkListOne(MkForStmt(
- MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(CopyIdentifier(id)), '=', MkExpIdentifier(MkIdentifier("__internalArray"))))),
- MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(CopyIdentifier(id)), '<',
- MkExpOp(MkExpIdentifier(MkIdentifier("__internalArray")), '+', MkExpConstant(count))))),
- MkListOne(MkExpOp(MkExpIdentifier(CopyIdentifier(id)), INC_OP, null)),
- block));
+ stmt.compound.statements = MkListOne(MkForStmt(
+ MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(CopyIdentifier(id)), '=', MkExpIdentifier(MkIdentifier("__internalArray"))))),
+ MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(CopyIdentifier(id)), '<',
+ MkExpOp(MkExpIdentifier(MkIdentifier("__internalArray")), '+', MkExpConstant(count))))),
+ MkListOne(MkExpOp(MkExpIdentifier(CopyIdentifier(id)), INC_OP, null)),
+ block));
- /*
- Declarator decl = SpecDeclFromString(_class.templateArgs[2].dataTypeString, specs, MkDeclaratorPointer(MkPointer(null, null), null));
- stmt.compound.statements = MkListOne(MkForStmt(
- MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(CopyIdentifier(id)), '=', MkExpPointer(MkExpIdentifier(MkIdentifier("__internalArray")), MkIdentifier("data"))))),
- MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(CopyIdentifier(id)), '<',
- MkExpOp(MkExpCast(MkTypeName(specs, decl), MkExpPointer(MkExpIdentifier(MkIdentifier("__internalArray")), MkIdentifier("data"))), '+', MkExpPointer(MkExpIdentifier(MkIdentifier("__internalArray")), MkIdentifier("count")))))),
- MkListOne(MkExpOp(MkExpIdentifier(CopyIdentifier(id)), INC_OP, null)),
- block));
- */
- ProcessStatement(((Statement)stmt.compound.statements->first).forStmt.init);
- ProcessStatement(((Statement)stmt.compound.statements->first).forStmt.check);
- ProcessExpressionType(((Statement)stmt.compound.statements->first).forStmt.increment->first);
- }
- else if(isLinkList && !isList)
- {
- Class typeClass = eSystem_FindClass(_class.module, _class.templateArgs[3].dataTypeString);
- Class listItemClass = eSystem_FindClass(_class.module, "ListItem");
- if(typeClass && eClass_IsDerived(typeClass, listItemClass) && _class.templateArgs[5].dataTypeString &&
- !strcmp(_class.templateArgs[5].dataTypeString, "LT::link"))
- {
+ /*
+ Declarator decl = SpecDeclFromString(_class.templateArgs[2].dataTypeString, specs, MkDeclaratorPointer(MkPointer(null, null), null));
stmt.compound.statements = MkListOne(MkForStmt(
- MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(CopyIdentifier(id)), '=', MkExpMember(MkExpIdentifier(MkIdentifier("__internalLinkList")), MkIdentifier("first"))))),
- MkExpressionStmt(MkListOne(MkExpIdentifier(CopyIdentifier(id)))),
- MkListOne(MkExpOp(MkExpIdentifier(CopyIdentifier(id)), '=', MkExpMember(MkExpIdentifier(CopyIdentifier(id)), MkIdentifier("next")))),
+ MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(CopyIdentifier(id)), '=', MkExpPointer(MkExpIdentifier(MkIdentifier("__internalArray")), MkIdentifier("data"))))),
+ MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(CopyIdentifier(id)), '<',
+ MkExpOp(MkExpCast(MkTypeName(specs, decl), MkExpPointer(MkExpIdentifier(MkIdentifier("__internalArray")), MkIdentifier("data"))), '+', MkExpPointer(MkExpIdentifier(MkIdentifier("__internalArray")), MkIdentifier("count")))))),
+ MkListOne(MkExpOp(MkExpIdentifier(CopyIdentifier(id)), INC_OP, null)),
block));
+ */
+ ProcessStatement(((Statement)stmt.compound.statements->first).forStmt.init);
+ ProcessStatement(((Statement)stmt.compound.statements->first).forStmt.check);
+ ProcessExpressionType(((Statement)stmt.compound.statements->first).forStmt.increment->first);
}
- else
+ else if(isLinkList && !isList)
+ {
+ Class typeClass = eSystem_FindClass(_class.module, _class.templateArgs[3].dataTypeString);
+ Class listItemClass = eSystem_FindClass(_class.module, "ListItem");
+ if(typeClass && eClass_IsDerived(typeClass, listItemClass) && _class.templateArgs[5].dataTypeString &&
+ !strcmp(_class.templateArgs[5].dataTypeString, "LT::link"))
+ {
+ stmt.compound.statements = MkListOne(MkForStmt(
+ MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(CopyIdentifier(id)), '=', MkExpMember(MkExpIdentifier(MkIdentifier("__internalLinkList")), MkIdentifier("first"))))),
+ MkExpressionStmt(MkListOne(MkExpIdentifier(CopyIdentifier(id)))),
+ MkListOne(MkExpOp(MkExpIdentifier(CopyIdentifier(id)), '=', MkExpMember(MkExpIdentifier(CopyIdentifier(id)), MkIdentifier("next")))),
+ block));
+ }
+ else
+ {
+ OldList * specs = MkList();
+ Declarator decl = SpecDeclFromString(_class.templateArgs[3].dataTypeString, specs, null);
+ stmt.compound.statements = MkListOne(MkForStmt(
+ MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(CopyIdentifier(id)), '=', MkExpMember(MkExpIdentifier(MkIdentifier("__internalLinkList")), MkIdentifier("first"))))),
+ MkExpressionStmt(MkListOne(MkExpIdentifier(CopyIdentifier(id)))),
+ MkListOne(MkExpOp(MkExpIdentifier(CopyIdentifier(id)), '=', MkExpCast(MkTypeName(specs, decl), MkExpCall(
+ MkExpMember(MkExpIdentifier(MkIdentifier("__internalLinkList")), MkIdentifier("GetNext")),
+ MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("IteratorPointer")), null), MkExpIdentifier(CopyIdentifier(id)))))))),
+ block));
+ }
+ ProcessStatement(((Statement)stmt.compound.statements->first).forStmt.init);
+ ProcessStatement(((Statement)stmt.compound.statements->first).forStmt.check);
+ ProcessExpressionType(((Statement)stmt.compound.statements->first).forStmt.increment->first);
+ }
+ /*else if(isCustomAVLTree)
{
- OldList * specs = MkList();
- Declarator decl = SpecDeclFromString(_class.templateArgs[3].dataTypeString, specs, null);
stmt.compound.statements = MkListOne(MkForStmt(
- MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(CopyIdentifier(id)), '=', MkExpMember(MkExpIdentifier(MkIdentifier("__internalLinkList")), MkIdentifier("first"))))),
+ MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(CopyIdentifier(id)), '=', MkExpMember(MkExpMember(MkExpIdentifier(
+ MkIdentifier("__internalTree")), MkIdentifier("root")), MkIdentifier("minimum"))))),
MkExpressionStmt(MkListOne(MkExpIdentifier(CopyIdentifier(id)))),
- MkListOne(MkExpOp(MkExpIdentifier(CopyIdentifier(id)), '=', MkExpCast(MkTypeName(specs, decl), MkExpCall(
- MkExpMember(MkExpIdentifier(MkIdentifier("__internalLinkList")), MkIdentifier("GetNext")),
- MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("IteratorPointer")), null), MkExpIdentifier(CopyIdentifier(id)))))))),
+ MkListOne(MkExpOp(MkExpIdentifier(CopyIdentifier(id)), '=', MkExpMember(MkExpIdentifier(CopyIdentifier(id)), MkIdentifier("next")))),
block));
- }
- ProcessStatement(((Statement)stmt.compound.statements->first).forStmt.init);
- ProcessStatement(((Statement)stmt.compound.statements->first).forStmt.check);
- ProcessExpressionType(((Statement)stmt.compound.statements->first).forStmt.increment->first);
- }
- /*else if(isCustomAVLTree)
- {
- stmt.compound.statements = MkListOne(MkForStmt(
- MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(CopyIdentifier(id)), '=', MkExpMember(MkExpMember(MkExpIdentifier(
- MkIdentifier("__internalTree")), MkIdentifier("root")), MkIdentifier("minimum"))))),
- MkExpressionStmt(MkListOne(MkExpIdentifier(CopyIdentifier(id)))),
- MkListOne(MkExpOp(MkExpIdentifier(CopyIdentifier(id)), '=', MkExpMember(MkExpIdentifier(CopyIdentifier(id)), MkIdentifier("next")))),
- block));
- ProcessStatement(((Statement)stmt.compound.statements->first).forStmt.init);
- ProcessStatement(((Statement)stmt.compound.statements->first).forStmt.check);
- ProcessExpressionType(((Statement)stmt.compound.statements->first).forStmt.increment->first);
- }*/
- else
- {
- stmt.compound.statements = MkListOne(MkWhileStmt(MkListOne(MkExpCall(MkExpMember(expIt = MkExpIdentifier(CopyIdentifier(id)),
- MkIdentifier("Next")), null)), block));
- }
- ProcessExpressionType(expIt);
- if(stmt.compound.declarations->first)
- ProcessDeclaration(stmt.compound.declarations->first);
+ ProcessStatement(((Statement)stmt.compound.statements->first).forStmt.init);
+ ProcessStatement(((Statement)stmt.compound.statements->first).forStmt.check);
+ ProcessExpressionType(((Statement)stmt.compound.statements->first).forStmt.increment->first);
+ }*/
+ else
+ {
+ stmt.compound.statements = MkListOne(MkWhileStmt(MkListOne(MkExpCall(MkExpMember(expIt = MkExpIdentifier(CopyIdentifier(id)),
+ MkIdentifier("Next")), null)), block));
+ }
+ ProcessExpressionType(expIt);
+ if(stmt.compound.declarations->first)
+ ProcessDeclaration(stmt.compound.declarations->first, true);
- if(symbol)
- symbol.isIterator = isMap ? 2 : ((isArray || isBuiltin) ? 3 : (isLinkList ? (isList ? 5 : 4) : (isCustomAVLTree ? 6 : 1)));
+ if(symbol)
+ symbol.isIterator = isMap ? 2 : ((isArray || isBuiltin) ? 3 : (isLinkList ? (isList ? 5 : 4) : (isCustomAVLTree ? 6 : 1)));
- ProcessStatement(stmt);
- curContext = stmt.compound.context.parent;
+ ProcessStatement(stmt);
+ }
+ else
+ ProcessStatement(stmt.forEachStmt.stmt);
+ if(inCompiler)
+ curContext = stmt.compound.context.parent;
break;
}
else
curFunction.type = ProcessType(
curFunction.specifiers, curFunction.declarator);
FreeType(exp.destType);
+ // TODO: current property if not compiling
exp.destType = (curFunction && curFunction.type && curFunction.type.kind == functionType) ? curFunction.type.returnType : null;
if(exp.destType) exp.destType.refCount++;
}
}
case badDeclarationStmt:
{
- ProcessDeclaration(stmt.decl);
+ ProcessDeclaration(stmt.decl, true);
break;
}
case asmStmt:
stmt.type = expressionStmt;
stmt.expressions = MkList();
- curExternal = external.prev;
-
for(propWatch = watches->first; propWatch; propWatch = propWatch.next)
{
ClassFunction func;
((watcher.expType && watcher.expType.kind == classType && watcher.expType._class) ? watcher.expType._class.registered : null) : thisClass;
External createdExternal;
- // Create a declaration above
- External externalDecl = MkExternalDeclaration(null);
- ast->Insert(curExternal.prev, externalDecl);
-
sprintf(watcherName,"__ecerePropertyWatcher_%d", propWatcherID++);
if(propWatch.deleteWatch)
strcat(watcherName, "_delete");
if(object && object.expType && object.expType.kind == classType && object.expType._class && object.expType._class.registered)
{
- // TESTING THIS STUFF... BEWARE OF SYMBOL ID ISSUES
func = MkClassFunction(MkListOne(MkSpecifier(VOID)), null, MkDeclaratorFunction(MkDeclaratorIdentifier(MkIdentifier(watcherName)),
- //MkListOne(MkTypeName(MkListOne(MkSpecifier(VOID)), null))), null);
MkListOne(MkTypeName(MkListOne(MkSpecifierName(object.expType._class.string)), MkDeclaratorIdentifier(MkIdentifier("value"))))), null);
ProcessClassFunctionBody(func, propWatch.compound);
propWatch.compound = null;
- //afterExternal = afterExternal ? afterExternal : curExternal;
-
- //createdExternal = ProcessClassFunction(watcherClass, func, ast, curExternal.prev);
createdExternal = ProcessClassFunction(watcherClass, func, ast, curExternal, true);
- // TESTING THIS...
- createdExternal.symbol.idCode = external.symbol.idCode;
+
+ FreeClassFunction(func);
curExternal = createdExternal;
ProcessFunction(createdExternal.function);
-
- // Create a declaration above
- {
- Declaration decl = MkDeclaration(CopyList(createdExternal.function.specifiers, CopySpecifier),
- MkListOne(MkInitDeclarator(CopyDeclarator(createdExternal.function.declarator), null)));
- externalDecl.declaration = decl;
- if(decl.symbol && !decl.symbol.pointerExternal)
- decl.symbol.pointerExternal = externalDecl;
- }
-
if(propWatch.deleteWatch)
{
OldList * args = MkList();
char getName[1024], setName[1024];
OldList * args = MkList();
- DeclareProperty(prop, setName, getName);
+ DeclareProperty(createdExternal, prop, setName, getName);
// eInstance_Watch(stmt.watch.object, prop, stmt.watch.watcher, callback);
strcpy(propName, "__ecereProp_");
FullClassNameCat(propName, prop._class.fullName, false);
strcat(propName, "_");
- // strcat(propName, prop.name);
FullClassNameCat(propName, prop.name, true);
ListAdd(args, CopyExpression(object));
ListAdd(args, MkExpIdentifier(MkIdentifier(propName)));
ListAdd(args, watcher ? CopyExpression(watcher) : MkExpIdentifier(MkIdentifier("this")));
- ListAdd(args, MkExpIdentifier(MkIdentifier(watcherName)));
+ ListAdd(args, MkExpCast(MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null, null), null)), MkExpIdentifier(MkIdentifier(watcherName))));
ListAdd(stmt.expressions, MkExpCall(MkExpIdentifier(MkIdentifier("ecere::com::eInstance_Watch")), args));
+
+ external.CreateUniqueEdge(createdExternal, true);
}
else
- Compiler_Error($"Property %s not found in class %s\n", prop.name, _class.fullName);
+ Compiler_Error($"Property %s not found in class %s\n", propID.string, _class.fullName);
}
}
}
FreeList(watches, FreePropertyWatch);
}
else
- Compiler_Error($"No observer specified and not inside a _class\n");
+ Compiler_Error($"No observer specified and not inside a class\n");
}
else
{
char getName[1024], setName[1024];
OldList * args = MkList();
- DeclareProperty(prop, setName, getName);
+ DeclareProperty(curExternal, prop, setName, getName);
// eInstance_StopWatching(object, prop, watcher);
strcpy(propName, "__ecereProp_");
FullClassNameCat(propName, prop._class.fullName, false);
strcat(propName, "_");
- // strcat(propName, prop.name);
FullClassNameCat(propName, prop.name, true);
- MangleClassName(propName);
ListAdd(args, CopyExpression(object));
ListAdd(args, MkExpIdentifier(MkIdentifier(propName)));
ListAdd(stmt.expressions, MkExpCall(MkExpIdentifier(MkIdentifier("ecere::com::eInstance_StopWatching")), args));
}
else
- Compiler_Error($"Property %s not found in class %s\n", prop.name, _class.fullName);
+ Compiler_Error($"Property %s not found in class %s\n", propID.string, _class.fullName);
}
}
strcpy(className, "__ecereClass_");
FullClassNameCat(className, _class.fullName, true);
- MangleClassName(className);
-
structName[0] = 0;
FullClassNameCat(structName, _class.fullName, false);
// [class] this
-
-
funcDecl = GetFuncDecl(function.declarator);
if(funcDecl)
{
}
}
- // DANGER: Watch for this... Check if it's a Conversion?
- // if((_class.type != bitClass && _class.type != unitClass && _class.type != enumClass) || function != (FunctionDefinition)symbol.externalSet)
-
- // WAS TRYING THIS FOR CONVERSION PROPERTIES ON NOHEAD CLASSES: if((_class.type == structClass) || function != (FunctionDefinition)symbol.externalSet)
if(!function.propertyNoThis)
{
- TypeName thisParam;
+ TypeName thisParam = null;
if(type.classObjectType != classPointer)
{
declarator = MkDeclaratorPointer(MkPointer(null,null), MkDeclaratorIdentifier(MkIdentifier("class")));
qualifiers = MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier("__ecereNameSpace__ecere__com__Class"), null));
};
+ DeclareStruct(curExternal, "ecere::com::Class", false, true);
funcDecl.function.parameters->Insert(null, thisParam);
}
}
if(type.classObjectType != classPointer)
{
- // DANGER: Watch for this... Check if it's a Conversion?
if((_class.type != bitClass && _class.type != unitClass && _class.type != enumClass) || function != (FunctionDefinition)symbol.externalSet)
{
TypeName thisParam = QMkClass(_class.fullName, MkDeclaratorIdentifier(MkIdentifier("this")));
thisSymbol = Symbol
{
string = CopyString("this");
- type = classSym ? MkClassType(classSym.string) : null; //_class.fullName);
+ type = classSym ? MkClassType(classSym.string) : null;
};
function.body.compound.context.symbols.Add((BTNode)thisSymbol);
thisSymbol.type.classObjectType = ClassObjectType::typedObject;
thisSymbol.type.byReference = type.byReference;
thisSymbol.type.typedByReference = type.byReference;
- /*
- thisSymbol = Symbol { string = CopyString("class") };
- function.body.compound.context.symbols.Add(thisSymbol);
- */
}
}
}
// Pointer to class data
-
- if(inCompiler && _class && (_class.type == normalClass /*|| _class.type == noHeadClass*/) && type.classObjectType != classPointer)
+ if(inCompiler && _class && _class.type == normalClass && type.classObjectType != classPointer)
{
DataMember member = null;
{
char className[1024];
strcpy(className, "__ecereClass_");
FullClassNameCat(className, classSym.string, true);
- MangleClassName(className);
- // Testing This
- DeclareClass(classSym, className);
+ DeclareClass(curExternal, classSym, className);
}
// ((byte *) this)
if(_class.fixed)
{
- char string[256];
- sprintf(string, "%d", _class.offset);
- exp = QBrackets(MkExpOp(bytePtr, '+', MkExpConstant(string)));
+ Expression e;
+ if(_class.offset && _class.offset == (_class.base.type == noHeadClass ? _class.base.memberOffset : _class.base.structSize))
+ {
+ e = MkExpClassSize(MkSpecifierName(_class.base.fullName));
+ ProcessExpressionType(e);
+ }
+ else
+ {
+ char string[256];
+ sprintf(string, "%d", _class.offset); // Need Bootstrap Fix
+ e = MkExpConstant(string);
+ }
+ exp = QBrackets(MkExpOp(bytePtr, '+', e));
}
else
{
{
Context prevContext = curContext;
+ OldList * list;
curContext = function.body.compound.context;
- decl = MkDeclaration(MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier(structName), null)),
+ decl = MkDeclaration((list = MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier(structName), null))),
MkListOne(MkInitDeclarator(QMkPtrDecl(pointerName), initializer)));
+ list->Insert(null, MkSpecifierExtended(MkExtDeclAttrib(MkAttrib(ATTRIB, MkListOne(MkAttribute(CopyString("unused"), null))))));
curContext = prevContext;
}
if(function.declarator)
{
- ProcessDeclarator(function.declarator);
+ ProcessDeclarator(function.declarator, true);
}
topContext = oldTopContext;
{
Class backThisClass = thisClass;
if(regClass) thisClass = regClass;
- ProcessDeclaration(def.decl);
+ ProcessDeclaration(def.decl, symbol ? true : false);
thisClass = backThisClass;
}
}
PropertyDef prop = def.propertyDef;
// Add this to the context
- /*
- Symbol thisSymbol = Symbol { string = CopyString("this"), type = MkClassType(regClass.fullName) };
- globalContext.symbols.Add(thisSymbol);
- */
-
thisClass = regClass;
if(prop.setStmt)
{
}
thisClass = null;
-
- /*
- globalContext.symbols.Remove(thisSymbol);
- FreeSymbol(thisSymbol);
- */
}
else if(def.type == propertyWatchClassDef && def.propertyWatch)
{
}
}
-void DeclareFunctionUtil(String s)
+void DeclareFunctionUtil(External neededBy, const String s)
{
GlobalFunction function = eSystem_FindFunction(privateModule, s);
if(function)
if(function.module.importType != staticImport && (!function.dataType || !function.dataType.dllExport))
strcpy(name, "__ecereFunction_");
FullClassNameCat(name, s, false); // Why is this using FullClassNameCat ?
- DeclareFunction(function, name);
+ DeclareFunction(neededBy, function, name);
}
+ else if(neededBy)
+ FindSymbol(s, globalContext, globalContext, false, false);
}
+bool reachedPass15;
+
void ComputeDataTypes()
{
External external;
- External temp { };
- External after = null;
currentClass = null;
containerClass = eSystem_FindClass(GetPrivateModule(), "Container");
- for(external = ast->first; external; external = external.next)
- {
- if(external.type == declarationExternal)
- {
- Declaration decl = external.declaration;
- if(decl)
- {
- OldList * decls = decl.declarators;
- if(decls)
- {
- InitDeclarator initDecl = decls->first;
- if(initDecl)
- {
- Declarator declarator = initDecl.declarator;
- if(declarator && declarator.type == identifierDeclarator)
- {
- Identifier id = declarator.identifier;
- if(id && id.string)
- {
- if(!strcmp(id.string, "uintptr_t") || !strcmp(id.string, "intptr_t") || !strcmp(id.string, "size_t") || !strcmp(id.string, "ssize_t"))
- {
- external.symbol.id = -1001, external.symbol.idCode = -1001;
- after = external;
- }
- }
- }
- }
- }
- }
- }
- }
-
- temp.symbol = Symbol { id = -1000, idCode = -1000 };
- ast->Insert(after, temp);
- curExternal = temp;
-
- DeclareFunctionUtil("eSystem_New");
- DeclareFunctionUtil("eSystem_New0");
- DeclareFunctionUtil("eSystem_Renew");
- DeclareFunctionUtil("eSystem_Renew0");
- DeclareFunctionUtil("eClass_GetProperty");
-
- DeclareStruct("ecere::com::Class", false);
- DeclareStruct("ecere::com::Instance", false);
- DeclareStruct("ecere::com::Property", false);
- DeclareStruct("ecere::com::DataMember", false);
- DeclareStruct("ecere::com::Method", false);
- DeclareStruct("ecere::com::SerialBuffer", false);
- DeclareStruct("ecere::com::ClassTemplateArgument", false);
-
- ast->Remove(temp);
+ DeclareStruct(null, "ecere::com::Class", false, true);
+ DeclareStruct(null, "ecere::com::Instance", false, true);
+ DeclareStruct(null, "ecere::com::Property", false, true);
+ DeclareStruct(null, "ecere::com::DataMember", false, true);
+ DeclareStruct(null, "ecere::com::Method", false, true);
+ DeclareStruct(null, "ecere::com::SerialBuffer", false, true);
+ DeclareStruct(null, "ecere::com::ClassTemplateArgument", false, true);
+
+ DeclareFunctionUtil(null, "eSystem_New");
+ DeclareFunctionUtil(null, "eSystem_New0");
+ DeclareFunctionUtil(null, "eSystem_Renew");
+ DeclareFunctionUtil(null, "eSystem_Renew0");
+ DeclareFunctionUtil(null, "eSystem_Delete");
+ DeclareFunctionUtil(null, "eClass_GetProperty");
+ DeclareFunctionUtil(null, "eClass_SetProperty");
+ DeclareFunctionUtil(null, "eInstance_FireSelfWatchers");
+ DeclareFunctionUtil(null, "eInstance_SetMethod");
+ DeclareFunctionUtil(null, "eInstance_IncRef");
+ DeclareFunctionUtil(null, "eInstance_StopWatching");
+ DeclareFunctionUtil(null, "eInstance_Watch");
+ DeclareFunctionUtil(null, "eInstance_FireWatchers");
+ reachedPass15 = true;
for(external = ast->first; external; external = external.next)
{
afterExternal = curExternal = external;
if(external.type == functionExternal)
{
+ if(memoryGuard)
+ {
+ DeclareFunctionUtil(external, "MemoryGuard_PushLoc");
+ DeclareFunctionUtil(external, "MemoryGuard_PopLoc");
+ }
+
currentClass = external.function._class;
ProcessFunction(external.function);
}
// There shouldn't be any _class member access here anyways...
else if(external.type == declarationExternal)
{
+ if(memoryGuard && external.declaration && external.declaration.type == instDeclaration)
+ {
+ DeclareFunctionUtil(external, "MemoryGuard_PushLoc");
+ DeclareFunctionUtil(external, "MemoryGuard_PopLoc");
+ }
+
currentClass = null;
- ProcessDeclaration(external.declaration);
+ if(external.declaration)
+ ProcessDeclaration(external.declaration, true);
}
else if(external.type == classExternal)
{
ClassDefinition _class = external._class;
currentClass = external.symbol.registered;
+ if(memoryGuard)
+ {
+ DeclareFunctionUtil(external, "MemoryGuard_PushLoc");
+ DeclareFunctionUtil(external, "MemoryGuard_PopLoc");
+ }
if(_class.definitions)
{
ProcessClass(_class.definitions, _class.symbol);
}
currentClass = null;
thisNameSpace = null;
-
- delete temp.symbol;
- delete temp;
+ curExternal = null;
}