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)
return false;
}
- if(type1.kind == type2.kind)
+ if(type1.kind == type2.kind && type1.isLong == type2.isLong)
{
switch(type1.kind)
{
// 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;
}
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)
{
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)
+ {
+ Symbol symbol = FindStruct(curContext, type.enumName);
+ if(symbol && symbol.type)
+ {
+ ComputeTypeSize(symbol.type);
+ size = symbol.type.size;
+ }
+ }
+ 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;
+ 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)
{
- uint addSize = ComputeTypeSize(member);
+ Symbol symbol = FindStruct(curContext, type.enumName);
+ if(symbol && symbol.type)
+ {
+ ComputeTypeSize(symbol.type);
+ size = symbol.type.size;
+ type.alignment = symbol.type.alignment;
+ }
+ }
+ 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 = Max(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 = 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;
{
// 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);
}
/*
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, MkListOne(MkDeclaratorIdentifier(MkIdentifier(id))),null)));
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;
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;
}
}
}
}
-void DeclareStruct(const char * name, bool skipNoHead)
+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];
- Specifier spec = null;
- 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.declaration && external.declaration.specifiers)
+ classSym.declaredStructSym = true;
+ if(!external || (classSym.registered.type == noHeadClass && !skipNoHead && !curDeclarations))
{
- for(spec = external.declaration.specifiers->first; spec; spec = spec.next)
+ bool add = false;
+ if(!external)
{
- if(spec.type == structSpecifier || spec.type == unionSpecifier)
- break;
- }
- }
-
- /*if(!external)
- external = MkExternalDeclaration(null);*/
-
- if(!skipNoHead && (!spec || !spec.definitions))
- {
- bool addedPadding = false;
- classSym.declaredStructSym = true;
+ 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(spec)
- {
- if(declarations)
- spec.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
+ else if(!classSym.declaredStructSym && classSym.structExternal)
{
- if(classSym.structExternal && classSym.structExternal.declaration && classSym.structExternal.declaration.specifiers)
+ classSym.declaredStructSym = true;
+
+ if(classSym.registered)
+ DeclareMembers(classSym.structExternal, classSym.registered, false);
+
+ if(classSym.structExternal.declaration && classSym.structExternal.declaration.specifiers)
{
Specifier spec;
for(spec = classSym.structExternal.declaration.specifiers->first; spec; spec = spec.next)
{
- IdentifyAnonStructs(spec.definitions);
+ if(spec.definitions)
+ IdentifyAnonStructs(spec.definitions);
}
}
-
- if(curExternal && curExternal.symbol && curExternal.symbol.idCode < classSym.id)
+ }
+ if(inCompiler && neededBy && (external || !classSym.imported))
+ {
+ if(!external)
{
- // TEMPORARY HACK: Pass 3 will move up struct declarations without moving members
- // Moved this one up because DeclareClass done later will need it
-
- // TESTING THIS:
- classSym.declaring++;
-
- //if(!skipNoHead)
- {
- if(classSym.registered)
- DeclareMembers(classSym.registered, false);
- }
-
- if(classSym.registered && (classSym.registered.type == structClass || classSym.registered.type == noHeadClass))
- {
- // 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.declaring--;
+ classSym.structExternal = external = MkExternalDeclaration(null);
+ external.symbol = classSym;
+ ast->Add(external);
}
+ 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;
+ 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);
- //MangleClassName(setName);
strcpy(getName, "__ecereProp_");
FullClassNameCat(getName, prop._class.fullName, false);
strcat(getName, "_Get_");
FullClassNameCat(getName, prop.name, true);
- // strcat(getName, prop.name);
-
- // To support "char *" property
- //MangleClassName(getName);
- 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;
- // 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;
+ 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);
- }
- if(!strcmp(prop._class.base.fullName, "eda::Row") || !strcmp(prop._class.base.fullName, "eda::Id"))
- specifiers->Insert(null, MkSpecifier(CONST));
+ ListAdd(declarators, MkInitDeclarator(d, null));
- ListAdd(params, MkTypeName(specifiers, d));
+ specifiers = MkList();
+ if(dllImport)
+ specifiers->Insert(null, MkSpecifier(EXTERN));
+ else if(prop._class.symbol && ((Symbol)prop._class.symbol).isStatic)
+ specifiers->Insert(null, MkSpecifier(STATIC));
- d = MkDeclaratorIdentifier(MkIdentifier(setName));
- //if(imported)
- if(dllImport)
- d = MkDeclaratorBrackets(MkDeclaratorPointer(MkPointer(null, null), d));
- d = MkDeclaratorFunction(d, params);
+ if(!prop.conversion || prop._class.type == structClass)
+ ListAdd(specifiers, MkSpecifier(VOID));
+ else
+ ListAdd(specifiers, MkSpecifierName(prop._class.fullName));
- // 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);
- }
- }
- }
+ decl = MkDeclaration(specifiers, declarators);
- ListAdd(declarators, MkInitDeclarator(d, null));
+ external = MkExternalDeclaration(decl);
- 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));
+ if(structExternal)
+ external.CreateEdge(structExternal, false);
+ if(instExternal)
+ external.CreateEdge(instExternal, false);
- // 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(spec)
+ DeclareStruct(external, spec.name, false, needReference);
- decl = MkDeclaration(specifiers, declarators);
+ ast->Add(external);
+ external.symbol = symbol;
+ symbol.externalSet = external;
- external = MkExternalDeclaration(decl);
- ast->Insert(curExternal.prev, external);
- external.symbol = symbol;
- symbol.externalSet = external;
+ ReplaceThisClassSpecifiers(specifiers, prop._class);
+ }
- ReplaceThisClassSpecifiers(specifiers, prop._class);
- }
- else
- {
- // Move declaration higher...
- ast->Move(symbol.externalSet, curExternal.prev);
- }
- }
+ // 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();
- char propName[1024];
+ 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"));
- ListAdd(specifiers, MkSpecifierName("Property"));
+ strcpy(propName, "__ecereProp_");
+ FullClassNameCat(propName, prop._class.fullName, false);
+ strcat(propName, "_");
+ FullClassNameCat(propName, prop.name, true);
- strcpy(propName, "__ecereProp_");
- FullClassNameCat(propName, prop._class.fullName, false);
- strcat(propName, "_");
- FullClassNameCat(propName, prop.name, true);
- // strcat(propName, prop.name);
- //MangleClassName(propName);
+ {
+ 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);
- symbol.id = curExternal.symbol.idCode;
+ if(symbol.externalSet)
+ neededBy.CreateUniqueEdge(symbol.externalSet, symbol.externalSet.type == functionExternal);
+
+ // IsSet ?
}
}
Type type = null;
if(source)
{
- if(source.kind == pointerType || source.kind == arrayType)
+ if(source.isVector)
+ {
+ type = { refCount = 1 };
+ CopyTypeInto(type, source);
+ type.isVector = false;
+ }
+ else if(source.kind == pointerType || source.kind == arrayType)
{
type = source.type;
source.type.refCount++;
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)
nameID._class = null;
}
+ curExternal = createdExternal;
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;
- }
- }
- }
+ if(createdExternal.function)
+ ProcessFunction(createdExternal.function);
}
else if(declarator)
{
}
}
-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 ? type._class.registered : null;
+ _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, const 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 || !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);
}
}
}
// 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
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))
{
return true;
else if(dest.kind == int64Type && (source.kind == shortType || source.kind == charType || source.kind == _BoolType || source.kind == intType || source.kind == intPtrType || source.kind == intSizeType))
return true;
+ else if(dest.kind == int128Type && (source.kind == shortType || source.kind == charType || source.kind == _BoolType || source.kind == intType || source.kind == intPtrType || source.kind == int64Type || source.kind == intSizeType))
+ return true;
else if(dest.kind == intPtrType && (source.kind == shortType || source.kind == charType || source.kind == _BoolType || source.kind == intType || source.kind == intSizeType || source.kind == int64Type))
return true;
else if(dest.kind == intSizeType && (source.kind == shortType || source.kind == charType || source.kind == _BoolType || source.kind == intType || source.kind == int64Type || source.kind == intPtrType))
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, warnConst))
- 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, false))
+ if(MatchTypes(type, dest, &converts, null, null, dest.kind != classType || !dest._class || strcmp(dest._class.string, "bool"),
+ false, false, false, false))
{
NamedLink64 value;
Class enumClass = eSystem_FindClass(privateModule, "enum");
}
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") || !strcmp(baseClass.dataTypeString, "int64") || !strcmp(baseClass.dataTypeString, "short") || !strcmp(baseClass.dataTypeString, "char"))
sprintf(constant, FORMAT64D, value.data);
Type source;
Type realDest = dest;
Type backupSourceExpType = null;
- Expression computedExp = sourceExp;
+ 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(sourceExp); // Keep the original expression, but compute for checking enum ranges
+ computedExp = CopyExpression(nbExp); // Keep the original expression, but compute for checking enum ranges
ComputeExpression(computedExp /*sourceExp*/);
}
if(dest.kind == pointerType && sourceExp.type == constantExp && !strtoul(sourceExp.constant, null, 0))
{
- if(computedExp != sourceExp)
+ if(computedExp != nbExp)
{
FreeExpression(computedExp);
- computedExp = sourceExp;
+ computedExp = nbExp;
}
FreeType(dest);
return true;
//if(source._class.registered == dest._class.registered)
if(sourceBase == destBase)
{
- if(computedExp != sourceExp)
+ if(computedExp != nbExp)
{
FreeExpression(computedExp);
- computedExp = sourceExp;
+ computedExp = nbExp;
}
FreeType(dest);
return true;
else
value = strtoull(computedExp.constant, null, 0);
}
- else if(computedExp.type == opExp && sourceExp.op.op == '-' && !computedExp.op.exp1 && computedExp.op.exp2 && computedExp.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(computedExp.op.exp2.constant, null, 0);
else
value = -strtoull(computedExp.op.exp2.constant, null, 0);
}
- if(computedExp != sourceExp)
+ if(computedExp != nbExp)
{
FreeExpression(computedExp);
- computedExp = sourceExp;
+ 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 };
// 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;
{
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)
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++;
+
+ // This fixes passing unit as template to a double
+ modifyPassAsTemplate(&((Conversion)(conversions.last)).resultType, false);
}
FreeType(sourceExp.expType);
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))
{
}
else
{
- if(computedExp != sourceExp)
+ if(computedExp != nbExp)
{
FreeExpression(computedExp);
- computedExp = sourceExp;
+ computedExp = nbExp;
}
while((sourceExp.type == bracketsExp || sourceExp.type == extensionExpressionExp) && sourceExp.list) sourceExp = sourceExp.list->last;
}
if(value)
{
- FreeExpContents(sourceExp);
FreeType(sourceExp.expType);
sourceExp.isConstant = true;
sourceExp.expType = MkClassType(_class.fullName);
- //if(inCompiler)
+ if(inCompiler || inPreCompiler || inDebugger)
{
+ FreeExpContents(sourceExp);
+
sourceExp.type = constantExp;
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);
{ \
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; \
{ \
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; \
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)
}
if(exp.type == stringExp && op.kind == pointerType)
{
- op.ui64 = (uint64)exp.string;
+ op.ui64 = (uint64)(uintptr)exp.string;
op.kind = pointerType;
op.ops = uint64Ops;
}
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;
{
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(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)
{
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);
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);
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;
return result;
}
+void modifyPassAsTemplate(Type * typePtr, bool value)
+{
+ if(*typePtr && typePtr->passAsTemplate != value)
+ {
+ Type type { refCount = 1 };
+ CopyTypeInto(type, *typePtr);
+ type.passAsTemplate = value;
+ FreeType(*typePtr);
+ *typePtr = type;
+ }
+}
+
void CheckTemplateTypes(Expression exp)
{
+ /*
+ 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 { };
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)
}
else
{
- // If we're looking for value:
- // ({ union { double d; uint64 i; } u; u.i = [newExp]; u.d; })
+ // We want to pass as a template argument
+ // ({ union { double d; uint64 i; } u; u.d = [newExp]; u.i; })
OldList * specs;
OldList * unionDefs = MkList();
OldList * statements = MkList();
ListAdd(unionDefs, MkClassDefDeclaration(MkStructDeclaration(MkListOne(MkSpecifierName("uint64")), MkListOne(MkDeclaratorIdentifier(MkIdentifier("i"))), null)));
specs = MkListOne(MkStructOrUnion(unionSpecifier, null, unionDefs ));
exp.type = extensionCompoundExp;
+
+ modifyPassAsTemplate(&exp.expType, true);
+ modifyPassAsTemplate(&newExp.destType, false);
+ modifyPassAsTemplate(&newExp.expType, false);
+
exp.compound = MkCompoundStmt(MkListOne(MkDeclaration(specs, MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("__internal_union")), null)))),statements);
ListAdd(statements, MkExpressionStmt(MkListOne(MkExpOp(MkExpMember(MkExpIdentifier(MkIdentifier("__internal_union")), MkIdentifier("d")), '=', newExp))));
ListAdd(statements, MkExpressionStmt(MkListOne(MkExpMember(MkExpIdentifier(MkIdentifier("__internal_union")), MkIdentifier("i")))));
PopContext(context);
}
break;
+ case floatType:
+ if(exp.destType.classObjectType)
+ {
+ // We need to pass the address, just pass it along (Undo what was done above)
+ if(exp.destType) exp.destType.refCount--;
+ if(exp.expType) exp.expType.refCount--;
+ delete newExp;
+ }
+ else
+ {
+ // We want to pass as a template argument
+ // ({ union { float f; uint64 i; } u; u.f = [newExp]; u.i; })
+ OldList * specs;
+ OldList * unionDefs = MkList();
+ OldList * statements = MkList();
+ context = PushContext();
+ ListAdd(unionDefs, MkClassDefDeclaration(MkStructDeclaration(MkListOne(MkSpecifier(FLOAT)), MkListOne(MkDeclaratorIdentifier(MkIdentifier("f"))), null)));
+ ListAdd(unionDefs, MkClassDefDeclaration(MkStructDeclaration(MkListOne(MkSpecifierName("uint64")), MkListOne(MkDeclaratorIdentifier(MkIdentifier("i"))), null)));
+ specs = MkListOne(MkStructOrUnion(unionSpecifier, null, unionDefs ));
+ exp.type = extensionCompoundExp;
+ exp.compound = MkCompoundStmt(MkListOne(MkDeclaration(specs, MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("__internal_union")), null)))),statements);
+
+ modifyPassAsTemplate(&exp.expType, true);
+ modifyPassAsTemplate(&newExp.destType, false);
+ modifyPassAsTemplate(&newExp.expType, false);
+
+ ListAdd(statements, MkExpressionStmt(MkListOne(MkExpOp(MkExpMember(MkExpIdentifier(MkIdentifier("__internal_union")), MkIdentifier("f")), '=', newExp))));
+ ListAdd(statements, MkExpressionStmt(MkListOne(MkExpMember(MkExpIdentifier(MkIdentifier("__internal_union")), MkIdentifier("i")))));
+ exp.compound.compound.context = context;
+ PopContext(context);
+ }
+ break;
+ case voidType:
+ // Generated code already processed...
+ break;
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;
}
{
Expression newExp { };
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)
specs = MkListOne(MkStructOrUnion(unionSpecifier, null, unionDefs ));
exp.type = extensionCompoundExp;
exp.compound = MkCompoundStmt(MkListOne(MkDeclaration(specs, MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("__internal_union")), null)))),statements);
+
+ modifyPassAsTemplate(&exp.expType, false);
+ modifyPassAsTemplate(&newExp.destType, true);
+ modifyPassAsTemplate(&newExp.expType, true);
+
ListAdd(statements, MkExpressionStmt(MkListOne(MkExpOp(MkExpMember(MkExpIdentifier(MkIdentifier("__internal_union")), MkIdentifier("i")), '=', newExp))));
ListAdd(statements, MkExpressionStmt(MkListOne(MkExpMember(MkExpIdentifier(MkIdentifier("__internal_union")), MkIdentifier("d")))));
exp.compound.compound.context = context;
PopContext(context);
}
break;
+ case floatType:
+ if(exp.destType.classObjectType)
+ {
+ // We need to pass the address, just pass it along (Undo what was done above)
+ if(exp.destType) exp.destType.refCount--;
+ if(exp.expType) exp.expType.refCount--;
+ delete newExp;
+ }
+ else
+ {
+ // If we're looking for value:
+ // ({ union { float f; uint64 i; } u; u.i = [newExp]; u.f; })
+ OldList * specs;
+ OldList * unionDefs = MkList();
+ OldList * statements = MkList();
+ context = PushContext();
+ ListAdd(unionDefs, MkClassDefDeclaration(MkStructDeclaration(MkListOne(MkSpecifier(FLOAT)), MkListOne(MkDeclaratorIdentifier(MkIdentifier("f"))), null)));
+ ListAdd(unionDefs, MkClassDefDeclaration(MkStructDeclaration(MkListOne(MkSpecifierName("uint64")), MkListOne(MkDeclaratorIdentifier(MkIdentifier("i"))), null)));
+ specs = MkListOne(MkStructOrUnion(unionSpecifier, null, unionDefs ));
+ exp.type = extensionCompoundExp;
+ exp.compound = MkCompoundStmt(MkListOne(MkDeclaration(specs, MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("__internal_union")), null)))),statements);
+
+ modifyPassAsTemplate(&exp.expType, false);
+ modifyPassAsTemplate(&newExp.destType, true);
+ modifyPassAsTemplate(&newExp.expType, true);
+
+ ListAdd(statements, MkExpressionStmt(MkListOne(MkExpOp(MkExpMember(MkExpIdentifier(MkIdentifier("__internal_union")), MkIdentifier("i")), '=', newExp))));
+ ListAdd(statements, MkExpressionStmt(MkListOne(MkExpMember(MkExpIdentifier(MkIdentifier("__internal_union")), MkIdentifier("f")))));
+ exp.compound.compound.context = context;
+ PopContext(context);
+ }
+ break;
case classType:
{
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;
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;
}
return null;
}
-static void ProcessDeclaration(Declaration decl);
-
/*static */Symbol FindSymbol(const char * name, Context startContext, Context endContext, bool isStruct, bool globalNameSpace)
{
#ifdef _DEBUG
// 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 _BoolType: ListAdd(specs, MkSpecifier(_BOOL)); break;
case shortType: ListAdd(specs, MkSpecifier(SHORT)); break;
case int64Type: ListAdd(specs, MkSpecifier(INT64)); break;
+ case int128Type: ListAdd(specs, MkSpecifier(INT128)); break;
case intPtrType: ListAdd(specs, MkSpecifierName(type.isSigned ? "intptr" : "uintptr")); break;
case intSizeType: ListAdd(specs, MkSpecifierName(type.isSigned ? "intsize" : "uintsize")); break;
case intType:
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
{
case voidType: strcat(string, "void"); break;
case intType: strcat(string, type.isSigned ? "int" : "uint"); break;
case int64Type: strcat(string, type.isSigned ? "int64" : "uint64"); break;
+ case int128Type: strcat(string, type.isSigned ? "__int128" : "unsigned __int128"); break;
case intPtrType: strcat(string, type.isSigned ? "intptr" : "uintptr"); break;
case intSizeType: strcat(string, type.isSigned ? "intsize" : "uintsize"); break;
case charType: strcat(string, type.isSigned ? "char" : "byte"); break;
}
if(value)
{
- char constant[256];
-
- FreeExpContents(exp);
-
- exp.type = constantExp;
exp.isConstant = true;
- 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);
+ 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))))));
(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;
}
e.expType = type;
type.refCount++;
}
+
+ if(e.destType)
+ FreeType(e.destType);
+
e.destType = destType;
destType.refCount++;
}
}
}
+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;
}
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*/)
{
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)
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);
char * endP = null;
int64 i64 = strtoll(constant, &endP, 0);
uint64 ui64 = strtoull(constant, &endP, 0);
- bool is64Bit = endP && (!strcmp(endP, "LL") || !strcmp(endP, "ll"));
+ 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:
{
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 '-':
case LEFT_OP:
case RIGHT_OP:
- useSideType = true;
- useDestType = true;
+ // useSideType = true;
+ // useDestType = true;
break;
case '|':
case '%':
useSideType = true;
useDestType = true;
+ if(exp.op.op == '/') powerOp = true;
break;
case '&':
case '*':
// 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;
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--;
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 &&
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 != '&')
+ if(!exp.op.exp1 || (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 = exp.destType;
- if(exp.op.op != '&')
+ 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)
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)
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;
}
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)
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")))))
{
((type1.kind == classType && type1._class && strcmp(type1._class.string, "String")) == (type2.kind == classType && type2._class && strcmp(type2._class.string, "String"))))
{
// Added this check for enum subtraction to result in an int type:
- if(exp.op.op == '-' &&
- ((type1.kind == classType && type1._class.registered && type1._class.registered.type == enumClass) ||
- (type2.kind == classType && type2._class.registered && type2._class.registered.type == enumClass)) )
+ if(exp.op.op == '-' && ((c1 && c1.type == enumClass) || (c2 && c2.type == enumClass)) )
{
- Type intType;
- if(!type1._class.registered.dataType)
- type1._class.registered.dataType = ProcessTypeString(type1._class.registered.dataTypeString, false);
- if(!type2._class.registered.dataType)
- type2._class.registered.dataType = ProcessTypeString(type2._class.registered.dataTypeString, false);
-
- intType = ProcessTypeString(
- (type1._class.registered.dataType.kind == int64Type || type2._class.registered.dataType.kind == int64Type) ? "int64" : "int", false);
+ 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);
}
// 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)
{
{
if(type2)
FreeType(type2);
- type2 = exp.op.exp2.expType = ProcessTypeString("int", false);
+ type2 = exp.op.exp2.expType = ProcessTypeString("int", false); c2 = null;
type2.refCount++;
}
}
}
// 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.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
{
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, 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, 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 == '<' || exp.op.op == GE_OP || exp.op.op == LE_OP)
{
- bool op1IsEnum = type1 && type1.kind == classType && type1._class && type1._class.registered && type1._class.registered.type == enumClass;
- bool op2IsEnum = type2 && type2.kind == classType && type2._class && type2._class.registered && type2._class.registered.type == enumClass;
+ 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 == '^')
{
// Convert the enum to an int instead for these operators
if(!valid)
{
// 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(type2 && type2.kind == classType && type2._class && type2._class.registered && type2._class.registered.type == unitClass &&
- (type1.kind != classType || !type1._class || !type1._class.registered || type1._class.registered.type != unitClass))
+ if(c2 && c2.type == unitClass && (!c1 || c1.type != unitClass))
{
if(exp.op.exp1.destType) FreeType(exp.op.exp1.destType);
exp.op.exp1.destType = type2;
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)
+ if(c1 && c1.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)
+ 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;
}
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
}
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
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)
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.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;
}
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;
- }*/
+ {
+ //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);
}
}
- // *([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")))))))
));
}
kind = classType;
_class = prop ? prop._class.symbol : method ? method._class.symbol : _class.symbol;
// wasThisClass = type ? type.wasThisClass : false;
+ thisClassFrom = type ? type.thisClassFrom : null;
};
}
}
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++;
}
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)
{
exp.expType = ReplaceThisClassType(_class);
}
- if(tClass.templateClass && (exp.expType.kind != templateType || (!exp.expType.templateParameter || (!exp.expType.templateParameter.dataTypeString && !exp.expType.templateParameter.dataType))))
+ if(passAsTemplate)
exp.expType.passAsTemplate = true;
//exp.expType.refCount++;
if(!exp.destType)
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.isConstant = true;
- DeclareType(type, false, false);
+ DeclareType(curExternal, type, true, false);
FreeType(type);
break;
}
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:
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);
}
}
+ // 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) );
else if(exp.destType && !exp.destType.keepCast)
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, true);
+ 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:
{
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(d.type != pointerDeclarator)
- newParam.qualifiers->Insert(null, MkSpecifier(CONST));
+ 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));
- if(d.type != pointerDeclarator)
- param.qualifiers->Insert(null, MkSpecifier(CONST));
- 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)
{
- spec.type = nameSpecifier;
- spec.name = ReplaceThisClass(thisClass);
- spec.symbol = FindClass(spec.name);
- ProcessSpecifier(spec, false);
+ ProcessSpecifier(spec, isFunction, true);
+ }
+ else if((spec.type == structSpecifier || spec.type == unionSpecifier) && !spec.definitions && spec.id && spec.id.string)
+ {
+ 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) &&
if(stmt.compound.declarations)
{
for(decl = stmt.compound.declarations->first; decl; decl = decl.next)
- ProcessDeclaration(decl);
+ ProcessDeclaration(decl, true);
}
if(stmt.compound.statements)
{
Symbol symbol;
Expression expIt = null;
bool isMap = false, isArray = false, isLinkList = false, isList = false, isCustomAVLTree = false; //, isAVLTree = false;
+ // TODO: Find these once on loadup
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))
{
isList = eClass_IsDerived(source._class.registered, listClass);
}
- if(isArray)
+ if(inCompiler && isArray)
{
Declarator decl;
OldList * specs = MkList();
}
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;
+ 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))));
+
+ 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));
- 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));
+ sprintf(count, "%d", builtinCount);
- /*
- 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"))
- {
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)), '=', 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
+ 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", 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)));
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 = null;
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(const 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;
- }
- }
- }
- }
- }
- }
- }
- }
-
- {
- // Workaround until we have proper toposort for declarations reordering
- External e = MkExternalDeclaration(MkDeclaration(MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier("__ecereNameSpace__ecere__com__Instance"), null)), null));
- ast->Insert(after, e);
- after = e;
- }
-
- 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("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);
- 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;
if(external.declaration)
- ProcessDeclaration(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;
curExternal = null;
-
- delete temp.symbol;
- delete temp;
}