bool inCompiler = false;
public void SetInCompiler(bool b) { inCompiler = b; }
+bool inDebugger = false;
+public void SetInDebugger(bool b) { inDebugger = b; }
+
Context curContext;
Context globalContext;
OldList * excludedSymbols;
File fileInput;
public void SetFileInput(File file) { fileInput = file; }
char * symbolsDir = null;
-public void SetSymbolsDir(char * s) {
+public void SetSymbolsDir(const char * s) {
delete symbolsDir;
symbolsDir = CopyString(s);
-} public char * GetSymbolsDir() { return symbolsDir ? symbolsDir : ""; }
-char * outputFile;
-public void SetOutputFile(char * s) { outputFile = s; } public char * GetOutputFile() { return outputFile; }
-char * sourceFile;
-public void SetSourceFile(char * s) { sourceFile = s; } public char * GetSourceFile() { return sourceFile; }
-char * i18nModuleName;
-public void SetI18nModuleName(char * s) { i18nModuleName = s; } public char * GetI18nModuleName() { return i18nModuleName; }
+} public const char * GetSymbolsDir() { return symbolsDir ? symbolsDir : ""; }
+const char * outputFile;
+public void SetOutputFile(const char * s) { outputFile = s; } public const char * GetOutputFile() { return outputFile; }
+const char * sourceFile;
+public void SetSourceFile(const char * s) { sourceFile = s; } public const char * GetSourceFile() { return sourceFile; }
+const char * i18nModuleName;
+public void SetI18nModuleName(const char * s) { i18nModuleName = s; } public const char * GetI18nModuleName() { return i18nModuleName; }
public void SetGlobalContext(Context context) { globalContext = context; } public Context GetGlobalContext() { return globalContext; }
public void SetTopContext(Context context) { topContext = context; } public Context GetTopContext() { return topContext; }
const char * escCharsQuoted = "\"()$";
#endif
bool quoting = false;
- char *o = output, *i = input, *l = input;
+ char *o = output;
+ const char *i = input, *l = input;
#ifdef __WIN32__
while(*l && !strchr(escChars, *l)) l++;
if(*l) quoting = true;
extensionCompoundExp, classExp, classDataExp, new0Exp, renew0Exp,
dbopenExp, dbfieldExp, dbtableExp, dbindexExp, extensionExpressionExp, extensionInitializerExp,
vaArgExp, arrayExp, typeAlignExp,
- memberPropertyErrorExp, functionCallErrorExp
+ memberPropertyErrorExp, functionCallErrorExp, divideBy0ErrorExp
};
public enum MemberType
TemplateArgument defaultArgument;
// For type parameters
- char * dataTypeString;
+ const char * dataTypeString;
Type baseType;
}
ExtDecl extDecl;
char * name;
Symbol symbol;
- OldList * templateArgs;
+ OldList/*<TemplateArgument>*/ * templateArgs;
};
struct
{
Identifier id;
- OldList * list;
- OldList * baseSpecs;
- OldList * definitions;
+ OldList/*<Enumerator>*/ * list;
+ OldList/*<Specifier>*/ * baseSpecs;
+ OldList/*<ClassDef>*/ * definitions;
bool addNameSpace;
Context ctx;
ExtDecl extDeclStruct;
{
char * string;
bool intlString;
+ bool wideString;
};
OldList * list;
struct
bool addedThis;
bool needCast;
bool thisPtr;
+ bool opDestType;
+ uint needTemplateCast;
void Clear()
{
addedThis = false;
needCast = false;
thisPtr = false;
+ opDestType = false;
+ needTemplateCast = 0;
}
};
OldList * list;
};
bool isConstant;
+ Identifier id;
};
public class InitDeclarator : struct
Symbol symbol;
Location blockStart;
Location nameLoc;
- int endid;
AccessMode declMode;
bool deleteWatchable;
};
void * object;
};
+// An 'edge from' is a 'dependency on'
+class TopoEdge : struct
+{
+ public LinkElement<TopoEdge> in, out;
+ External from, to;
+ bool breakable;
+};
+
public enum ExternalType { functionExternal, declarationExternal, classExternal, importExternal, nameSpaceExternal, dbtableExternal };
public class External : struct
DBTableDef table;
};
ImportType importType;
+
+ // For the TopoSort
+ External fwdDecl;
+ LinkList<TopoEdge, link = out> outgoing { };
+ LinkList<TopoEdge, link = in> incoming { };
+ int nonBreakableIncoming;
+
+ void CreateUniqueEdge(External from, bool soft)
+ {
+ for(i : from.outgoing; i.to == this)
+ {
+ if(i.breakable && !soft)
+ {
+#ifdef _DEBUG
+ if(from == this)
+ PrintLn("bug: self-dependency");
+#endif
+ i.breakable = false;
+ nonBreakableIncoming++;
+ }
+ return;
+ }
+ CreateEdge(from, soft);
+ }
+
+ void CreateEdge(External from, bool soft)
+ {
+ TopoEdge e { from = from, to = this, breakable = soft };
+
+#ifdef _DEBUG
+ if(from == this && !soft)
+ PrintLn("bug: self-dependency");
+
+ /*for(i : from.outgoing)
+ {
+ if(i.to == this)
+ PrintLn("Warning: adding a duplicate edge");
+ }*/
+#endif
+
+ from.outgoing.Add(e);
+ incoming.Add(e);
+ if(!soft)
+ nonBreakableIncoming++;
+ }
+
+ External ForwardDeclare()
+ {
+ External f = null;
+ Context tmpContext = curContext;
+
+ switch(type)
+ {
+ case declarationExternal:
+ {
+ if(declaration.type == initDeclaration)
+ {
+ OldList * specs = declaration.specifiers;
+ if(specs)
+ {
+ Specifier s;
+ for(s = specs->first; s; s = s.next)
+ {
+ if(s.type == structSpecifier || s.type == unionSpecifier)
+ break;
+ }
+ if(s)
+ {
+ curContext = null;
+ f = MkExternalDeclaration(MkDeclaration(MkListOne(MkStructOrUnion(s.type, CopyIdentifier(s.id), null)), null));
+ curContext = tmpContext;
+ }
+ }
+ }
+ break;
+ }
+ case functionExternal:
+ {
+ curContext = null;
+ f = MkExternalDeclaration(MkDeclaration(CopyList(function.specifiers, CopySpecifier), MkListOne(MkInitDeclarator(CopyDeclarator(function.declarator), null))));
+ curContext = tmpContext;
+ f.symbol = symbol;
+
+ DeclareTypeForwardDeclare(f, symbol.type, false, false);
+ break;
+ }
+ }
+
+ /*
+ for(i : m.protoDepsExternal)
+ {
+ // If the edge is already added, don't bother
+ if(i.incoming.count)
+ CreateEdge(f, i.fwdDecl ? i.fwdDecl : i, i.fwdDecl ? false : true);
+ }
+ */
+
+ fwdDecl = f;
+
+ if(!f)
+ PrintLn("warning: unhandled forward declaration requested");
+ return f;
+ }
};
public class Context : struct
Property _property;
Class registered;
};
- int id, idCode;
+ bool notYetDeclared;
union
{
struct
OldList methods;
OldList properties;
bool itself;
- bool isRemote;
+ int isRemote;
};
public class FunctionImport : struct
uint size;
char * name;
char * typeName;
+ Class thisClassFrom;
ClassObjectType classObjectType;
int alignment;
uint offset;
int bitFieldCount;
- int count;
+ int count; // This is used to avoid outputting warnings when non-zero
bool isSigned:1;
bool constant:1;
bool attrStdcall:1;
bool declaredWithStruct:1;
bool typedByReference:1; // Originally typed by reference, regardless of class type
+ bool casted:1;
+ bool pointerAlignment:1; // true if the alignment is the pointer size
+ // bool wasThisClass:1;
// TODO: Add _Complex & _Imaginary support
// bool complex:1, imaginary:1;
- char * OnGetString(char * tempString, void * fieldData, bool * needClass)
+ const char * OnGetString(char * tempString, void * fieldData, bool * needClass)
{
Type type = (Type)this;
tempString[0] = '\0';
{
}
+
+ property bool specConst
+ {
+ get
+ {
+ Type t = this;
+ while((t.kind == pointerType || t.kind == arrayType) && t.type) t = t.type;
+ return t.constant;
+ }
+ }
+
+ // Used for generating calls to eClass_AddDataMember (differs slightly from 'isPointerType' below), meant to return true where ComputeTypeSize returns targetBits / 8
+ property bool isPointerTypeSize
+ {
+ get
+ {
+ bool result = false;
+ if(this)
+ {
+ switch(kind)
+ {
+ case classType:
+ {
+ Class _class = this._class ? this._class.registered : null;
+ if(!_class || (_class.type != structClass && _class.type != unitClass && _class.type != enumClass && _class.type != bitClass))
+ result = true;
+ break;
+ }
+ case pointerType:
+ case subClassType:
+ case thisClassType:
+ case intPtrType:
+ case intSizeType:
+ result = true;
+ break;
+ case templateType:
+ {
+ TemplateParameter param = templateParameter;
+ Type baseType = ProcessTemplateParameterType(param);
+ if(baseType)
+ result = baseType.isPointerTypeSize;
+ break;
+ }
+ }
+ }
+ return result;
+ }
+ }
+
+ property bool isPointerType
+ {
+ get
+ {
+ if(this)
+ {
+ if(kind == pointerType || kind == methodType || kind == functionType || kind == arrayType || kind == subClassType)
+ return true;
+ else if(kind == classType)
+ {
+ if(_class && _class.registered)
+ {
+ Class c = _class.registered;
+ if(c.type == bitClass || c.type == unitClass || c.type == enumClass || c.type == systemClass)
+ return false;
+ else if(c.type == structClass && !byReference)
+ return false;
+ }
+ return true;
+ }
+ else if(kind == templateType)
+ {
+ if(passAsTemplate) return false;
+ if(templateParameter)
+ {
+ if(templateParameter.dataType)
+ {
+ Specifier spec = templateParameter.dataType.specifiers ? templateParameter.dataType.specifiers->first : null;
+ if(templateParameter.dataType.decl && templateParameter.dataType.decl.type == pointerDeclarator)
+ return true;
+ if(spec && spec.type == nameSpecifier && strcmp(spec.name, "uint64"))
+ return true;
+ }
+ if(templateParameter.dataTypeString)
+ return true;
+ }
+ }
+ else
+ return false;
+ }
+ return false;
+ }
+ }
};
public struct Operand
#include <stdarg.h>
-void Compiler_Error(char * format, ...)
+void Compiler_Error(const char * format, ...)
{
if(inCompiler)
{
GetWorkingDir(string, sizeof(string));
PathCat(string, sourceFile);
}
- printf(string);
+ printf("%s", string);
/*
yylloc.start.col = yylloc.end.col = 1;
*/
#ifdef _DEBUG
if(!yylloc.start.line)
- printf("");
+ printf("no line");
#endif
//printf("(%d, %d) : error: ", yylloc.start.line, yylloc.start.charPos);
string[sizeof(string)-1] = 0;
va_end(args);
fputs(string, stdout);
+ fflush(stdout);
__thisModule.application.exitCode = 1;
}
else
int numWarnings;
public int GetNumWarnings() { return numWarnings; }
-void Compiler_Warning(char * format, ...)
+void Compiler_Warning(const char * format, ...)
{
if(inCompiler)
{
GetLastDirectory(string, fileName);
if(!strcmp(fileName, "intrin-impl.h")) return;
- printf(string);
+ printf("%s", string);
//printf("(%d, %d) : warning: ", yylloc.start.line, yylloc.start.charPos);
printf($":%d:%d: warning: ", yylloc.start.line, yylloc.start.charPos);
string[sizeof(string)-1] = 0;
va_end(args);
fputs(string, stdout);
+ fflush(stdout);
numWarnings++;
}
}