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; ????
}
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;
DataMember topMember = isMember ? (DataMember) _class : null;
uint totalSize = 0;
uint maxSize = 0;
- int alignment, size;
+ int alignment;
+ uint size;
DataMember member;
Context context = isMember ? null : SetupTemplatesContext(_class);
if(addedPadding)
static int DeclareMembers(Class _class, bool isMember)
{
DataMember topMember = isMember ? (DataMember) _class : null;
- uint totalSize = 0;
DataMember member;
Context context = isMember ? null : SetupTemplatesContext(_class);
return topMember ? topMember.memberID : _class.memberID;
}
-void DeclareStruct(char * name, bool skipNoHead)
+void DeclareStruct(const char * name, bool skipNoHead)
{
External external = null;
Symbol classSym = FindClass(name);
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;
}
}
//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(inCompiler)
{
-
- Type type = declarator.symbol.type;
+ //Type type = declarator.symbol.type;
External oldExternal = curExternal;
// *** Commented this out... Any negative impact? Yes: makes double prototypes declarations... Why was it commented out?
}
}
-public void DeclareMethod(Method method, char * name)
+public void DeclareMethod(Method method, const char * name)
{
Symbol symbol = method.symbol;
if(!symbol || (!symbol.pointerExternal && method.type == virtualMethod) || symbol.id > (curExternal ? curExternal.symbol.idCode : -1))
Type resultType;
};
-public bool MatchTypes(Type source, Type dest, OldList conversions, Class owningClassSource, Class owningClassDest, bool doConversion, bool enumBaseType, bool acceptReversedParams, bool isConversionExploration)
+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 &&
+ ((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.type && (sourceType.kind == pointerType || sourceType.kind == arrayType)) sourceType = sourceType.type;
+ while(destType.type && (destType.kind == pointerType || destType.kind == arrayType)) destType = destType.type;
+ if(!destType.constant && sourceType.constant)
+ Compiler_Warning($"discarding const qualifier\n");
+ }
+ }
// Property convert;
if(source.kind == templateType && dest.kind != templateType)
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)*/)
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))
+ 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.refCount++;
+ 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(success)
+ return true;
+ if(constType)
+ FreeType(constType);
}
}
}
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, dest._class.registered.dataType.kind == classType, false, false))
+ if(MatchTypes(source, dest._class.registered.dataType, conversions, null, null, true, dest._class.registered.dataType.kind == classType, false, false, warnConst))
{
return true;
}
convert.dataType = ProcessTypeString(convert.dataTypeString, false);
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))
+ MatchTypes(convert.dataType, dest, conversions, null, null, convert.dataType.kind == classType, convert.dataType.kind == classType, false, true, warnConst))
{
if(!conversions && !convert.Get)
return true;
source._class.registered.dataType = ProcessTypeString(source._class.registered.dataTypeString, false);
if(!isConversionExploration || source._class.registered.dataType.kind == classType || !strcmp(source._class.registered.name, "String"))
{
- if(MatchTypes(source._class.registered.dataType, dest, conversions, null, null, source._class.registered.dataType.kind == classType, source._class.registered.dataType.kind == classType, false, false))
+ 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))
+ else if(MatchTypes(dest, source._class.registered.dataType, null, null, null, false, false, false, false, warnConst))
return true;
}
}
// 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;
}
// 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))
+ if(MatchTypes(source.type, dest.type, null, null, null, true, true, false, false, warnConst))
return true;
}
}
_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, true, false, false, false, false))
{
NamedLink value;
Class enumClass = eSystem_FindClass(privateModule, "enum");
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;
Type realDest = dest;
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;
{
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);
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(!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);
return op;
}
-static void UnusedFunction()
+static __attribute__((unused)) void UnusedFunction()
{
int a;
a.OnGetString(0,0,0);
switch(type.kind)
{
case _BoolType:
- case charType: { byte v; type.isSigned ? GetChar(value, &v) : GetUChar(value, &v); part = (uint64)v; break; }
- case shortType: { uint16 v; type.isSigned ? GetShort(value, &v) : GetUShort(value, &v); part = (uint64)v; 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, (uint16 *)&v) : GetUShort(value, &v); part = (uint64)v; break; }
case intType:
- case longType: { uint v; type.isSigned ? GetInt(value, &v) : GetUInt(value, &v); part = (uint64)v; break; }
- case int64Type: { uint64 v; type.isSigned ? GetInt64(value, &v) : GetUInt64(value, &v); part = (uint64)v; break; }
- case intPtrType: { intptr v; type.isSigned ? GetIntPtr(value, &v) : GetUIntPtr(value, &v); part = (uint64)v; break; }
- case intSizeType: { intsize v; type.isSigned ? GetIntSize(value, &v) : GetUIntSize(value, &v); part = (uint64)v; break; }
+ case longType: { uint v; type.isSigned ? GetInt(value, (uint *)&v) : GetUInt(value, &v); part = (uint64)v; break; }
+ case int64Type: { uint64 v; type.isSigned ? GetInt64(value, (uint64 *)&v) : GetUInt64(value, &v); part = (uint64)v; break; }
+ case intPtrType: { uintptr v; type.isSigned ? GetIntPtr(value, (uintptr *)&v) : GetUIntPtr(value, &v); part = (uint64)v; break; }
+ case intSizeType: { uintsize v; type.isSigned ? GetIntSize(value, (uintsize *)&v) : GetUIntSize(value, &v); part = (uint64)v; break; }
}
bits |= part << bitMember.pos;
}
}
}
-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)
{
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)
{
if(exp.destType && exp.destType.passAsTemplate && exp.expType && exp.expType.kind != templateType && !exp.expType.passAsTemplate)
{
Expression newExp { };
- Statement compound;
Context context;
*newExp = *exp;
if(exp.destType) exp.destType.refCount++;
// - 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';
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();
}
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
}
}
+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);
+ }
+ 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;
+ }
+}
+
void ProcessExpressionType(Expression exp)
{
bool unresolved = false;
// 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
{
FreeIdentifier(id);
exp.type = bracketsExp;
exp.list = MkListOne(parsedExpression);
- parsedExpression.loc = yylloc;
+ ApplyLocation(parsedExpression, yylloc);
ProcessExpressionType(exp);
definedExpStackPos--;
return;
//_class = classSym ? classSym.registered : null;
ProcessInstantiationType(exp.instance);
+
exp.isConstant = exp.instance.isConstant;
/*
// 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;
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(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
{
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;
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++;
}
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++;
}
exp.op.exp2.destType = type1._class.registered.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;
exp.op.exp1.destType = type2._class.registered.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;
exp.expType = type1;
type1.refCount++;
// Convert the enum to an int instead for these operators
if(op1IsEnum && exp.op.exp2.expType)
{
- if(CheckExpressionType(exp.op.exp1, exp.op.exp2.expType, false))
+ if(CheckExpressionType(exp.op.exp1, exp.op.exp2.expType, false, false))
{
if(exp.expType) FreeType(exp.expType);
exp.expType = exp.op.exp2.expType;
}
else if(op2IsEnum && exp.op.exp1.expType)
{
- if(CheckExpressionType(exp.op.exp2, exp.op.exp1.expType, false))
+ if(CheckExpressionType(exp.op.exp2, exp.op.exp1.expType, false, false))
{
if(exp.expType) FreeType(exp.expType);
exp.expType = exp.op.exp1.expType;
{
if(op1IsEnum && exp.op.exp2.expType)
{
- if(CheckExpressionType(exp.op.exp1, exp.op.exp2.expType, false))
+ if(CheckExpressionType(exp.op.exp1, exp.op.exp2.expType, false, false))
{
if(exp.expType) FreeType(exp.expType);
exp.expType = exp.op.exp1.expType;
}
else if(op2IsEnum && exp.op.exp1.expType)
{
- if(CheckExpressionType(exp.op.exp2, exp.op.exp1.expType, false))
+ if(CheckExpressionType(exp.op.exp2, exp.op.exp1.expType, false, false))
{
if(exp.expType) FreeType(exp.expType);
exp.expType = exp.op.exp2.expType;
exp.op.exp1.destType = type2;
type2.refCount++;
- 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(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;
{
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;
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 == '!')
{
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.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(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)
{
// 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;
{
ClassTemplateArgument arg = tClass.templateArgs[id];
Context context = SetupTemplatesContext(tClass);
+ bool constant = exp.expType.constant;
/*if(!arg.dataType)
arg.dataType = ProcessTypeString(arg.dataTypeString, false);*/
FreeType(exp.expType);
+
exp.expType = ProcessTypeString(arg.dataTypeString, false);
+ 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)
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)
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 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;
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(!CheckExpressionType(exp, exp.destType, false, !exp.destType.casted))
{
if(!exp.destType.count || unresolved)
{
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")))
qualifiers = MkListOne(MkSpecifier(VOID));
declarator = MkDeclaratorPointer(MkPointer(null,null), d);
};
+ if(d.type != pointerDeclarator)
+ newParam.qualifiers->Insert(null, MkSpecifier(CONST));
FreeList(param.qualifiers, FreeSpecifier);
FreeList(param.qualifiers, FreeSpecifier);
param.qualifiers = MkListOne(MkSpecifier(VOID));
+ if(d.type != pointerDeclarator)
+ param.qualifiers->Insert(null, MkSpecifier(CONST));
param.declarator = MkDeclaratorPointer(MkPointer(null,null), d);
}
else if(spec.specifier == THISCLASS)
(((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");
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;
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;
}
}
-void DeclareFunctionUtil(String s)
+void DeclareFunctionUtil(const String s)
{
GlobalFunction function = eSystem_FindFunction(privateModule, s);
if(function)
DeclareFunctionUtil("eSystem_Renew0");
DeclareFunctionUtil("eSystem_Delete");
DeclareFunctionUtil("eClass_GetProperty");
+ DeclareFunctionUtil("eClass_SetProperty");
DeclareFunctionUtil("eInstance_FireSelfWatchers");
+ DeclareFunctionUtil("eInstance_SetMethod");
+ DeclareFunctionUtil("eInstance_IncRef");
+ DeclareFunctionUtil("eInstance_StopWatching");
+ DeclareFunctionUtil("eInstance_Watch");
+ DeclareFunctionUtil("eInstance_FireWatchers");
DeclareStruct("ecere::com::Class", false);
DeclareStruct("ecere::com::Instance", false);