3 #define YYLTYPE Location
7 char * defaultNameSpace;
8 int defaultNameSpaceLen;
9 public void SetDefaultNameSpace(char * s) { defaultNameSpace = s; defaultNameSpaceLen = s ? strlen(s) : 0; }
11 bool strictNameSpaces;
12 public void SetStrictNameSpaces(bool b) { strictNameSpaces = b; }
14 AccessMode declMode = privateAccess;
15 public void SetDeclMode(AccessMode accessMode) { declMode = accessMode; }
16 AccessMode defaultDeclMode = privateAccess;
17 public void SetDefaultDeclMode(AccessMode accessMode) { defaultDeclMode = accessMode; }
19 char * currentNameSpace;
20 int currentNameSpaceLen;
21 public void SetCurrentNameSpace(char * s) { currentNameSpace = s; currentNameSpaceLen = s ? strlen(s) : 0; }
24 Time findClassTotalTime;
25 Time checkTypeTotalTime;
26 Time externalImportTotalTime;
27 Time findClassIgnoreNSTotalTime;
30 public OldList * MkList()
32 return new0 OldList[1];
35 public OldList * MkListOne(void * item)
37 OldList * list = new0 OldList[1];
42 void ListAdd(OldList list, void * item)
48 void ListAddFront(OldList list, void * item)
51 list.Insert(null, item);
54 public Identifier MkIdentifier(char * string)
59 id._class = null; // Default class...
64 bool gotColon = false;
65 for(c = strlen(string)-1; c >= 0; c--)
72 namePart = string+c+1;
73 while(c >= 0 && string[c] == ':') c--;
79 memcpy(name, string, c+1);
81 // TODO: Do these better, keep in string?
82 if(!strcmp(name, "typed_object"))
84 id._class = MkSpecifierName("class");
85 id.string = CopyString(namePart);
87 else if(!strcmp(name, "property"))
89 id._class = MkSpecifierName("property");
90 id.string = CopyString(namePart);
92 else if(!strcmp(name, "typed_object&"))
94 id._class = MkSpecifierName("typed_object&");
95 id.string = CopyString(namePart);
97 else if(!strcmp(name, "any_object"))
99 id._class = MkSpecifierName("any_object");
100 id.string = CopyString(namePart);
104 TemplatedType templatedType = FindTemplateTypeParameter(curContext, name);
107 id._class = Specifier { type = templateTypeSpecifier, templateParameter = templatedType.param };
108 //id._class = MkSpecifierName(name);
109 id.string = CopyString(namePart);
113 symbol = FindClass(name);
116 id._class = _MkSpecifierName(symbol.string, symbol, null);
117 id.string = CopyString(namePart);
120 id.string = CopyString(string);
126 id._class = MkSpecifierName(null);
127 id.string = CopyString(namePart);
130 id.string = CopyString(string);
133 id.string = CopyString("");
137 public TemplateParameter MkTypeTemplateParameter(Identifier identifier, TemplateDatatype baseTplDatatype, TemplateArgument defaultArgument)
139 if(identifier.string)
141 TemplateParameter param { type = TemplateParameterType::type, identifier = identifier, dataType = baseTplDatatype, defaultArgument = defaultArgument };
142 TemplatedType type { key = (uint)identifier.string, param = param };
143 if(!curContext.templateTypes.Add((BTNode)type))
150 public TemplateParameter MkIdentifierTemplateParameter(Identifier identifier, TemplateMemberType memberType, TemplateArgument defaultArgument)
152 if(identifier.string)
154 TemplateParameter param { type = TemplateParameterType::identifier, identifier = identifier, memberType = memberType, defaultArgument = defaultArgument };
160 public TemplateParameter MkExpressionTemplateParameter(Identifier identifier, TemplateDatatype dataType, TemplateArgument defaultArgument)
162 if(identifier.string)
164 TemplateParameter param { type = TemplateParameterType::expression, identifier = identifier, dataType = dataType, defaultArgument = defaultArgument };
170 public TemplateDatatype MkTemplateDatatype(OldList * specifiers, Declarator decl)
172 TemplateDatatype datatype { specifiers = specifiers, decl = decl };
176 public TemplateArgument MkTemplateTypeArgument(TemplateDatatype tplDatatype)
178 TemplateArgument argument { type = type, templateDatatype = tplDatatype };
182 public TemplateArgument MkTemplateExpressionArgument(Expression expr)
184 TemplateArgument argument { type = expression, expression = expr };
188 public TemplateArgument MkTemplateIdentifierArgument(Identifier ident)
190 TemplateArgument argument { type = identifier, identifier = ident };
194 Expression MkExpExtensionCompound(Statement compound)
196 return { type = extensionCompoundExp, compound = compound };
199 Expression MkExpExtensionExpression(OldList * expressions)
201 return { type = extensionExpressionExp, list = expressions, loc = yylloc };
204 Expression MkExpExtensionInitializer(TypeName typeName, Initializer initializer)
206 return { type = extensionInitializerExp, initializer.typeName = typeName, initializer.initializer = initializer, loc = yylloc };
209 public Expression MkExpIdentifier(Identifier id)
211 return { type = identifierExp, identifier = id };
214 public Expression MkExpDummy()
216 Expression exp { type = dummyExp };
220 public Expression MkExpConstant(char * string)
222 return { type = constantExp, constant = CopyString(string) };
225 Expression MkExpString(char * string)
227 return { type = stringExp, string = CopyString(string) };
230 // TODO: String is case sensitive..
231 // What should we do about it?
232 /*public class CaseSensitiveString : String
234 int OnCompare(CaseSensitiveString string2)
238 result = strcmpi(this, string2);
239 else if(!this && string2)
241 else if(this && !string2)
247 public struct ContextStringPair
249 String string, context;
250 int OnCompare(ContextStringPair b)
253 result = (string && b.string) ? strcmp(string, b.string) :
254 (!string && b.string) ? 1 : (string && !b.string) ? -1 : 0;
255 if(result) return result;
257 result = (context && b.context) ? strcmp(context, b.context) :
258 (!context && b.context) ? 1 : (context && !b.context) ? -1 : 0;
259 if(result) return result;
260 // TODO: Support these
261 // result = CaseSensitiveString::OnCompare(string, b.string);
262 // result = ((CaseSensitiveString)string).OnCompare(b.string);
266 Map<ContextStringPair, List<Location> > intlStrings { };
268 Expression MkExpIntlString(char * string, char * context)
270 OldList * list = MkList();
273 ContextStringPair pair { };
275 int len = strlen(string);
277 pair.string = new byte[len-2+1]; memcpy(pair.string, string+1, len-2); pair.string[len-2] = '\0';
278 if(context) { len = strlen(context); pair.context = new byte[len-2+1]; memcpy(pair.context, context+1, len-2); pair.context[len-2] = '\0'; }
280 list = intlStrings[pair];
284 intlStrings[pair] = list;
293 ListAdd(list, QMkExpId("__thisModule"));
294 ListAdd(list, MkExpString(string));
297 int lenString = strlen(string), lenContext = strlen(context);
298 char * msgid = new char[lenString-2 + lenContext-2 + 4];
300 memcpy(msgid+1, context+1, lenContext-2);
301 msgid[1+lenContext-2] = 4; // EOT
302 memcpy(msgid+1+lenContext-2+1, string+1, lenString-2);
303 memcpy(msgid+1+lenContext-2+1+lenString-2, "\"", 2);
304 ListAdd(list, MkExpString(msgid));
307 ListAdd(list, QMkExpId("null"));
308 return MkExpCall(QMkExpId("GetTranslatedString"), list);
311 Expression MkExpOp(Expression exp1, int op, Expression exp2)
322 exp.loc.start = exp1 ? exp1.loc.start : exp2.loc.start;
323 exp.loc.end = exp2 ? exp2.loc.end : exp1.loc.end;
328 Expression MkExpBrackets(OldList expressions)
335 if(expressions && expressions.first)
337 exp.loc.start = ((Expression)expressions.first).loc.start;
338 exp.loc.end = ((Expression)expressions.last).loc.end;
343 Expression MkExpIndex(Expression expression, OldList index)
345 return { type = indexExp, index.exp = expression, index.index = index };
348 Expression MkExpCall(Expression expression, OldList arguments)
350 return { type = callExp, call.exp = expression, call.arguments = arguments };
353 Expression MkExpMember(Expression expression, Identifier member)
355 return { type = memberExp, member.exp = expression, member.member = member };
358 Expression MkExpPointer(Expression expression, Identifier member)
360 return { type = pointerExp, member.exp = expression, member.member = member };
363 Expression MkExpTypeSize(TypeName typeName)
365 return { type = typeSizeExp, typeName = typeName };
368 Expression MkExpClassSize(Specifier _class)
370 return { type = classSizeExp, _class = _class };
373 Expression MkExpCast(TypeName typeName, Expression expression)
375 return { type = castExp, cast.typeName = typeName, cast.exp = expression };
378 Expression MkExpCondition(Expression cond, OldList expressions, Expression elseExp)
380 return { type = conditionExp, cond.cond = cond, cond.exp = expressions, cond.elseExp = elseExp };
383 Expression MkExpRenew(Expression memExp, TypeName type, Expression size)
385 return { type = renewExp, _renew.exp = memExp, _renew.typeName = type, _renew.size = size };
388 Expression MkExpRenew0(Expression memExp, TypeName type, Expression size)
390 return { type = renew0Exp, _renew.exp = memExp, _renew.typeName = type, _renew.size = size };
393 Expression MkExpNew(TypeName type, Expression size)
395 return { type = newExp, _new.typeName = type, _new.size = size };
398 Expression MkExpNew0(TypeName type, Expression size)
400 return { type = new0Exp, _new.typeName = type, _new.size = size };
403 Expression MkExpVaArg(Expression exp, TypeName type)
405 return { type = vaArgExp, vaArg.exp = exp, vaArg.typeName = type };
408 Specifier MkSpecifier(int specifier)
410 return { type = baseSpecifier, specifier = specifier };
413 Specifier MkSpecifierTypeOf(Expression expression)
415 return { type = typeOfSpecifier, expression = expression };
418 Specifier MkSpecifierSubClass(Specifier _class)
420 return { type = subClassSpecifier, _class = _class };
423 Specifier MkSpecifierExtended(char * name)
425 return { type = extendedSpecifier, name = CopyString(name) };
428 Specifier MkEnum(Identifier id, OldList list)
432 type = enumSpecifier;
436 if(list && (!declMode || !id))
442 type = ProcessType(&specs, null);
446 Symbol symbol { string = CopyString(id.string), isStruct = true, type = type };
448 if(strstr(symbol.string, "::"))
449 curContext.hasNameSpace = true;
450 if(!curContext.structSymbols.Add((BTNode)symbol))
453 for(e = list.first; e; e = e.next)
455 Symbol symbol { string = CopyString(e.id.string), type = type };
457 if(strstr(symbol.string, "::"))
458 curContext.hasNameSpace = true;
459 if(!(curContext.templateTypesOnly ? curContext.parent : curContext).symbols.Add((BTNode)symbol))
467 Specifier MkStructOrUnion(SpecifierType type, Identifier id, OldList definitions)
469 Specifier spec { type = type, id = id };
470 if(id && FindType(curContext, id.string))
471 declMode = defaultAccess;
472 spec.definitions = definitions;
473 if(definitions && id && !declMode)
478 symbol = Symbol { string = CopyString(id.string), type = ProcessType(specs, null), isStruct = true };
479 if(!curContext.structSymbols.Add((BTNode)symbol))
485 void AddStructDefinitions(Specifier spec, OldList definitions)
487 spec.definitions = definitions;
488 if(definitions && spec.id && !declMode)
493 symbol = Symbol { string = CopyString(spec.id.string), type = ProcessType(specs, null), isStruct = true };
494 if(!curContext.parent.structSymbols.Add((BTNode)symbol))
499 public Declarator MkDeclaratorIdentifier(Identifier id)
501 return { type = identifierDeclarator, identifier = id };
504 Declarator MkDeclaratorFunction(Declarator declarator, OldList parameters)
506 return { type = functionDeclarator, declarator = declarator, function.parameters = parameters };
509 Declarator MkDeclaratorExtended(char * extended, Declarator declarator)
511 return { type = extendedDeclarator, declarator = declarator, extended.extended = extended };
514 Declarator MkDeclaratorExtendedEnd(char * extended, Declarator declarator)
516 return { type = extendedDeclaratorEnd, declarator = declarator, extended.extended = extended };
519 Declarator MkStructDeclarator(Declarator declarator, Expression exp)
521 return { type = structDeclarator, declarator = declarator, structDecl.exp = exp };
524 Declarator MkDeclaratorBrackets(Declarator declarator)
526 return { type = bracketsDeclarator, declarator = declarator };
529 Declarator MkDeclaratorArray(Declarator declarator, Expression exp)
531 return { type = arrayDeclarator, declarator = declarator, array.exp = exp };
534 Declarator MkDeclaratorEnumArray(Declarator declarator, Specifier _class)
536 return { type = arrayDeclarator, declarator = declarator, array.enumClass = _class };
539 Declarator MkDeclaratorPointer(Pointer pointer, Declarator declarator)
541 return { type = pointerDeclarator, declarator = declarator, pointer.pointer = pointer };
544 Enumerator MkEnumerator(Identifier id, Expression exp)
546 return { id = id, exp = exp };
549 Pointer MkPointer(OldList qualifiers, Pointer pointer)
551 return { qualifiers = qualifiers, pointer = pointer };
554 Initializer MkInitializerAssignment(Expression exp)
556 /*if(yylloc.start.line == 1)
558 return { type = expInitializer, exp = exp, loc = yylloc };
561 Initializer MkInitializerList(OldList list)
563 /*if(yylloc.start.line == 1)
565 return { type = listInitializer, list = list, loc = yylloc };
568 InitDeclarator MkInitDeclarator(Declarator declarator, Initializer initializer)
570 return { declarator = declarator, initializer = initializer };
573 public TypeName MkTypeName(OldList qualifiers, Declarator declarator)
575 return { qualifiers = qualifiers, declarator = declarator };
578 public Identifier GetDeclId(Declarator decl)
580 while(decl && decl.type != identifierDeclarator)
581 decl = decl.declarator;
582 return decl ? decl.identifier : null;
585 Declaration MkDeclarationClassInst(Instantiation inst)
587 return { type = instDeclaration, inst = inst, loc = yylloc };
590 Declaration MkDeclarationInst(Instantiation inst)
592 Declaration decl { type = instDeclaration, inst = inst, loc = yylloc };
594 if(curContext == globalContext && (currentNameSpace || defaultNameSpace) && declMode != defaultAccess && defaultDeclMode != defaultAccess)
597 int len = 0, stringLen;
600 memcpy(name, defaultNameSpace, defaultNameSpaceLen);
601 len += defaultNameSpaceLen;
607 memcpy(name + len, currentNameSpace, currentNameSpaceLen);
608 len += currentNameSpaceLen;
613 stringLen = strlen(inst.exp.identifier.string);
614 memcpy(name + len, inst.exp.identifier.string, stringLen);
617 delete inst.exp.identifier.string;
618 inst.exp.identifier.string = CopyString(name);
623 string = (inst.exp.type == identifierExp) ? CopyString(inst.exp.identifier.string) : null;
624 type = MkClassTypeSymbol(inst._class.symbol);
626 symbol.idCode = symbol.id = curContext.nextID++;
627 if(strstr(symbol.string, "::"))
628 curContext.hasNameSpace = true;
629 if(!(curContext.templateTypesOnly ? curContext.parent : curContext).symbols.Add((BTNode)symbol))
630 excludedSymbols->Add(symbol);
631 decl.symbol = inst.symbol = symbol;
635 Declaration MkDeclarationDefine(Identifier id, Expression exp)
637 Declaration decl { type = defineDeclaration, id = id, exp = exp, loc = yylloc };
638 char expString[1024];
641 PrintExpression(exp, expString);
643 if(curContext == globalContext && (currentNameSpace || defaultNameSpace) && declMode != defaultAccess && defaultDeclMode != defaultAccess)
646 int len = 0, stringLen;
649 memcpy(name, defaultNameSpace, defaultNameSpaceLen);
650 len += defaultNameSpaceLen;
656 memcpy(name + len, currentNameSpace, currentNameSpaceLen);
657 len += currentNameSpaceLen;
661 stringLen = strlen(id.string);
662 memcpy(name + len, id.string, stringLen);
666 id.string = CopyString(name);
669 if(!eSystem_FindDefine(privateModule, id.string))
670 eSystem_RegisterDefine(id.string, expString, privateModule, buildingECERECOMModule ? baseSystemAccess : publicAccess);
672 Compiler_Warning("Redefinition of %s ignored\n", id.string);
676 Declaration MkDeclaration(OldList specifiers, OldList initDeclarators)
678 Declaration decl { type = initDeclaration, declarators = initDeclarators, specifiers = specifiers, loc = yylloc };
679 bool variable = true;
681 if(specifiers != null)
684 for(spec = specifiers.first; spec; spec = spec.next)
686 if(spec.type == baseSpecifier && spec.specifier == TYPEDEF)
688 if(initDeclarators != null)
692 for(d = initDeclarators.first; d; d = d.next)
694 if(GetDeclId(d.declarator).string)
698 string = CopyString(GetDeclId(d.declarator).string);
699 type = ProcessType(specifiers, d.declarator);
701 type.id = type.idCode = curContext.nextID++;
703 if(!(curContext.templateTypesOnly ? curContext.parent : curContext).types.Add((BTNode)type))
704 excludedSymbols->Add(type);
705 decl.symbol = d.declarator.symbol = type;
711 for(; spec; spec = spec.next)
713 if(spec.type == nameSpecifier && spec.name)
717 string = CopyString(spec.name);
718 type = ProcessType(specifiers, null);
720 type.id = type.idCode = curContext.nextID++;
721 if(!(curContext.templateTypesOnly ? curContext.parent : curContext).types.Add((BTNode)type))
722 excludedSymbols->Add(type);
731 else if(spec.type == baseSpecifier &&
732 (spec.specifier == STRUCT || spec.specifier == UNION))
736 if(variable && initDeclarators)
739 for(d = initDeclarators.first; d; d = d.next)
741 Identifier id = GetDeclId(d.declarator);
742 if(id && id.string && id.string[0])
748 if(curContext == globalContext && (currentNameSpace || defaultNameSpace) && declMode != defaultAccess && defaultDeclMode != defaultAccess)
751 int len = 0, stringLen;
754 memcpy(name, defaultNameSpace, defaultNameSpaceLen);
755 len += defaultNameSpaceLen;
761 memcpy(name + len, currentNameSpace, currentNameSpaceLen);
762 len += currentNameSpaceLen;
766 stringLen = strlen(id.string);
767 memcpy(name + len, id.string, stringLen);
771 id.string = CopyString(name);
774 // Avoid memory leaks on duplicated symbols (BinaryTree::Add Would Fail)
775 symbol = (Symbol)(curContext.templateTypesOnly ? curContext.parent : curContext).symbols.FindString(id.string);
778 symbol = Symbol { string = CopyString(id.string), type = ProcessType(specifiers, d.declarator) };
779 if(strstr(symbol.string, "::"))
780 curContext.hasNameSpace = true;
781 if(!(curContext.templateTypesOnly ? curContext.parent : curContext).symbols.Add((BTNode)symbol))
782 excludedSymbols->Add(symbol);
783 // TODO: Add better support to count declarators
784 if(symbol.type && symbol.type.kind == arrayType && !symbol.type.arraySizeExp && d.initializer)
786 if(d.initializer.type == listInitializer)
789 sprintf(string, "%d",d.initializer.list->count);
790 symbol.type.arraySizeExp = MkExpConstant(string);
791 symbol.type.freeExp = true;
793 else if(d.initializer.type == expInitializer && d.initializer.exp.type == stringExp && d.initializer.exp.string)
798 bool escaped = false;
799 char * s = d.initializer.exp.string;
801 // MAKE MORE ACCURATE
802 for(c = 1; (ch = s[c]); c++)
804 if(ch == '\\' && !escaped)
813 sprintf(string, "%d", count);
814 symbol.type.arraySizeExp = MkExpConstant(string);
815 symbol.type.freeExp = true;
818 symbol.id = symbol.idCode = curContext.nextID++;
820 decl.symbol = d.declarator.symbol = symbol;
827 decl.symbol = Symbol { };
828 decl.symbol.id = decl.symbol.idCode = curContext.nextID++;
829 excludedSymbols->Add(decl.symbol);
834 Declaration MkStructDeclaration(OldList specifiers, OldList declarators, Specifier extStorage)
836 return { type = structDeclaration, declarators = declarators, specifiers = specifiers, extStorage = extStorage, loc = yylloc };
839 Statement MkLabeledStmt(Identifier id, Statement statement)
841 return { type = labeledStmt, labeled.id = id, labeled.stmt = statement, loc = yylloc };
844 Statement MkCaseStmt(Expression exp, Statement statement)
846 return { type = caseStmt, caseStmt.exp = exp, caseStmt.stmt = statement, loc = yylloc };
849 Statement MkCompoundStmt(OldList declarations, OldList statements)
851 return { type = compoundStmt, compound.declarations = declarations, compound.statements = statements, loc = yylloc };
854 Statement MkExpressionStmt(OldList expressions)
856 return { type = expressionStmt, expressions = expressions, loc = yylloc };
859 Statement MkBadDeclStmt(Declaration decl)
861 return { type = badDeclarationStmt, decl = decl, loc = yylloc };
864 Statement MkIfStmt(OldList exp, Statement statement, Statement elseStmt)
866 return { type = ifStmt, ifStmt.exp = exp, ifStmt.stmt = statement, ifStmt.elseStmt = elseStmt, loc = yylloc };
869 Statement MkSwitchStmt(OldList exp, Statement statement)
871 // To know it's a switch compound... (Don't want declarations in there... bugs)
873 statement.compound.isSwitch = true;
874 return { type = switchStmt, switchStmt.exp = exp, switchStmt.stmt = statement, loc = yylloc };
877 Statement MkWhileStmt(OldList exp, Statement statement)
879 return { type = whileStmt, whileStmt.exp = exp, whileStmt.stmt = statement, loc = yylloc };
882 Statement MkDoWhileStmt(Statement statement, OldList exp)
884 return { type = doWhileStmt, doWhile.exp = exp, doWhile.stmt = statement, loc = yylloc };
887 Statement MkForStmt(Statement init, Statement check, OldList inc, Statement statement)
889 return { type = forStmt, forStmt.init = init, forStmt.check = check, forStmt.increment = inc, forStmt.stmt = statement, loc = yylloc };
892 Statement MkForEachStmt(Identifier id, OldList exp, OldList filter, Statement statement)
894 return { type = forEachStmt, forEachStmt.id = id, forEachStmt.exp = exp, forEachStmt.filter = filter, forEachStmt.stmt = statement, loc = yylloc };
897 Statement MkGotoStmt(Identifier id)
899 return { type = gotoStmt, gotoStmt.id = id, loc = yylloc };
902 Statement MkContinueStmt()
904 return { type = continueStmt, loc = yylloc };
907 Statement MkBreakStmt()
909 return { type = breakStmt, loc = yylloc };
912 Statement MkReturnStmt(OldList exp)
914 return { type = returnStmt, expressions = exp, loc = yylloc };
917 FunctionDefinition MkFunction(OldList specifiers, Declarator declarator, OldList declarationList)
919 return { specifiers = specifiers, declarator = declarator, declarations = declarationList };
922 void ProcessFunctionBody(FunctionDefinition func, Statement body)
924 Declarator declarator = func.declarator;
925 Declarator funcDecl = GetFuncDecl(declarator);
930 if(funcDecl && funcDecl.function.parameters && body)
932 Context context = body.compound.context;
934 for(param = funcDecl.function.parameters->first; param; param = param.next)
938 Symbol symbol = null;
939 Identifier id = GetDeclId(param.declarator);
940 char * string = id ? id.string : null;
943 for(symbol = (Symbol)context.symbols.first; symbol; symbol = (Symbol)((BTNode)symbol).next)
944 if(!strcmp(symbol.string, string))
946 // This parameter is not shadowed by a local declaration
949 symbol = Symbol { string = CopyString(id.string), type = ProcessType(param.qualifiers, param.declarator), isParam = true };
950 if(!context.symbols.Add((BTNode)symbol))
951 excludedSymbols->Add(symbol);
953 // TODO: Fix this, the parameters' IDs should really be smaller...
954 symbol.id = context.nextID++;
955 param.declarator.symbol = symbol;
962 if(!declarator.symbol)
964 Identifier id = GetDeclId(declarator);
966 if((currentNameSpace || defaultNameSpace) && declMode != defaultAccess && defaultDeclMode != defaultAccess && strcmp(id.string, "__on_register_module"))
969 int len = 0, stringLen;
972 memcpy(name, defaultNameSpace, defaultNameSpaceLen);
973 len += defaultNameSpaceLen;
979 memcpy(name + len, currentNameSpace, currentNameSpaceLen);
980 len += currentNameSpaceLen;
984 stringLen = strlen(id.string);
985 memcpy(name + len, id.string, stringLen);
989 id.string = CopyString(name);
991 symbol = Symbol { string = CopyString(id.string), type = ProcessType(func.specifiers, declarator) };
992 symbol.idCode = symbol.id = globalContext.nextID++;
993 if(strstr(symbol.string, "::"))
994 globalContext.hasNameSpace = true;
995 if(!globalContext.symbols.Add((BTNode)symbol))
996 excludedSymbols->Add(symbol);
997 declarator.symbol = symbol;
1001 symbol = declarator.symbol;
1002 excludedSymbols->Remove(declarator.symbol);
1003 delete symbol.string;
1004 symbol.string = CopyString(GetDeclId(declarator).string);
1005 if(strstr(symbol.string, "::"))
1006 globalContext.hasNameSpace = true;
1007 if(!globalContext.symbols.Add((BTNode)symbol))
1008 excludedSymbols->Add(symbol);
1011 symbol.type = ProcessType(func.specifiers, declarator);
1013 if(symbol.type && (symbol.type.kind == functionType || symbol.type.kind == methodType))
1015 if(!symbol.type.params.count)
1017 Type type { refCount = 1 };
1018 symbol.type.params.Add(type);
1027 External MkExternalFunction(FunctionDefinition function)
1029 External external { type = functionExternal, function = function, symbol = function.declarator.symbol };
1030 if(function.specifiers)
1033 for(spec = function.specifiers->first; spec; spec = spec.next)
1034 if(spec.type == baseSpecifier && spec.specifier == STATIC)
1036 declMode = staticAccess;
1041 if(external.symbol && !external.symbol.methodExternal)
1042 external.symbol.methodExternal = external;
1046 External MkExternalImport(char * name, ImportType importType, AccessMode importAccess)
1048 External external { type = importExternal };
1049 int len = strlen(name) - 2;
1050 external.importString = new char[len + 1];
1051 strncpy(external.importString, name+1, len);
1052 external.importString[len] = '\0';
1057 Time startTime = GetTime();
1060 ImportModule(external.importString, importType, importAccess, true);
1061 ImportModule(external.importString, importType, importAccess, false);
1063 time = GetTime() - startTime;
1064 printf("Importing took %.3f seconds for %s\n", time, external.importString);
1065 externalImportTotalTime += time;
1071 External MkExternalDeclaration(Declaration declaration)
1073 External external { type = declarationExternal, declaration = declaration, symbol = declaration ? declaration.symbol : null };
1074 InitDeclarator d = (declaration && declaration.declarators) ? declaration.declarators->last : null;
1075 if(declaration && declaration.type == initDeclaration && declaration.specifiers)
1078 for(spec = declaration.specifiers->first; spec; spec = spec.next)
1079 if(spec.type == baseSpecifier && spec.specifier == TYPEDEF)
1081 declMode = defaultAccess;
1084 else if(spec.type == baseSpecifier && spec.specifier == STATIC)
1086 declMode = staticAccess;
1090 if(declaration && declaration.symbol && !declaration.symbol.methodExternal)
1091 declaration.symbol.methodExternal = external;
1095 External MkExternalNameSpace(Identifier identifier)
1097 External external { type = nameSpaceExternal, id = identifier };
1098 currentNameSpace = identifier ? identifier.string : null;
1099 currentNameSpaceLen = currentNameSpace ? strlen(currentNameSpace) : 0;
1103 void SetClassTemplateArgs(Specifier spec, OldList templateArgs)
1105 if(spec.type == nameSpecifier)
1107 Symbol symbol = spec.symbol;
1108 spec.templateArgs = templateArgs;
1109 if(templateArgs && templateArgs.first)
1111 char templateString[1024];
1112 TemplateArgument arg;
1113 strcpy(templateString, symbol ? symbol.string : spec.name);
1114 strcat(templateString, "<");
1115 for(arg = templateArgs.first; arg; arg = arg.next)
1123 char expString[1024];
1124 Class backupThisClass = thisClass;
1126 expString[0] = '\0';
1127 // Will this work here?
1129 Location oldLocation = yylloc;
1130 File backFileInput = fileInput;
1135 // TESTING THIS SCANNER RESUME STUFF
1138 yylloc = oldLocation;
1139 fileInput = backFileInput;
1142 fileInput.Seek(yylloc.start.pos, start);
1143 resetScannerPos(&yylloc.start);
1148 //ProcessExpressionType(arg.expression);
1149 //ComputeExpression(arg.expression);
1150 PrintExpression(arg.expression, expString);
1151 strcat(argument, expString);
1152 thisClass = backupThisClass;
1157 strcat(argument, arg.identifier.string);
1162 char * typeString = StringFromSpecDecl(arg.templateDatatype.specifiers, arg.templateDatatype.decl);
1163 strcat(argument, typeString);
1170 if(arg.prev) strcat(templateString, ", ");
1173 strcat(templateString, arg.name.string);
1174 strcat(templateString, " = ");
1176 strcat(templateString, argument);
1180 int len = strlen(templateString);
1181 if(templateString[len-1] == '>') templateString[len++] = ' ';
1182 templateString[len++] = '>';
1183 templateString[len++] = '\0';
1185 // printf("SetClassTemplateArgs templateString: %s\n", templateString);
1186 symbol = FindClass(templateString);
1187 if(!symbol && spec.symbol)
1189 // If class was only decl'ed, invoke DeclClass on this templated class as well
1190 symbol = _DeclClass(MAXINT, templateString);
1192 // Add a reference to all templated class to the basic class
1194 spec.symbol.templatedClasses.Add(OldLink { data = symbol });
1196 spec.symbol = symbol;
1197 spec.name = CopyString(symbol ? symbol.string : templateString);
1201 FreeList(templateArgs, FreeTemplateArgument);
1204 Specifier _MkSpecifierName(char * name, Symbol symbol, OldList templateArgs)
1206 Specifier spec { type = nameSpecifier };
1212 TemplatedType templatedType = FindTemplateTypeParameter(curContext, name);
1215 spec.templateParameter = templatedType.param;
1216 spec.type = templateTypeSpecifier;
1220 symbol = FindClass(name);
1222 if(symbol && symbol.registered && symbol.registered.isRemote == 1)
1224 char className[1024];
1225 strcpy(className, "DCOMClient_");
1226 if(!strncmp(name, className, strlen(className)))
1227 spec.name = CopyString(name);
1230 strcat(className, name);
1231 spec.name = CopyString(className);
1235 spec.name = CopyString(symbol.string);
1237 spec.name = CopyString(name);
1238 spec.symbol = symbol;
1239 if(templateArgs != null)
1240 SetClassTemplateArgs(spec, templateArgs);
1245 public Specifier MkSpecifierName(char * name)
1247 return _MkSpecifierName(name, null, null);
1250 public Specifier MkSpecifierNameArgs(char * name, OldList * templateArgs)
1252 return _MkSpecifierName(name, null, templateArgs);
1256 Specifier MkClassName(char * string)
1258 return { type = SpecifierClass, name = CopyString(string) };
1261 ClassFunction MkClassFunction(OldList specifiers, Specifier _class, Declarator decl, OldList declList)
1263 return { specifiers = specifiers, /*_class = _class,*/ declarator = decl, declarations = declList };
1266 void ProcessClassFunctionBody(ClassFunction func, Statement body)
1270 Declarator decl = func.declarator;
1272 //Declarator decl = GetFuncDecl(func.declarator);
1273 Declarator funcDecl = GetFuncDecl(func.declarator);
1277 if(decl && !decl.symbol)
1279 OldList * symbolSpecs = MkList();
1281 // WHAT WILL WE DO WITH THIS? Double instances?
1282 //if(decl.function.parameters && body)
1283 if(funcDecl && funcDecl.function.parameters && body)
1285 Context context = body.compound.context;
1287 for(param = funcDecl.function.parameters->first; param; param = param.next)
1289 if(param.declarator)
1291 Symbol symbol = null;
1292 Identifier id = GetDeclId(param.declarator);
1293 char * string = id ? id.string : null;
1296 symbol = (Symbol)context.symbols.FindString(string);
1298 // This parameter is not shadowed by a local declaration
1303 string = CopyString(id.string);
1304 type = ProcessType(param.qualifiers, param.declarator);
1308 // TODO: Fix this, the parameters' IDs should really be smaller...
1309 symbol.idCode = symbol.id = context.nextID++;
1310 if(!context.symbols.Add((BTNode)symbol))
1311 excludedSymbols->Add(symbol);
1313 param.declarator.symbol = symbol;
1318 //////////////////////////////////
1326 Identifier id = GetDeclId(funcDecl);
1330 for(c = strlen(id.string)-1; c >= 0; c--)
1332 if(id.string[c] == ':')
1334 char * string = CopyString(id.string + c + 1);
1335 id.string[c - 1] = 0;
1336 id._class = MkSpecifierName(id.string);
1342 symbol.string = CopyString(id.string);
1349 for(spec = func.specifiers->first; spec; spec = spec.next)
1350 symbolSpecs->Add(CopySpecifier(spec));
1352 symbol.type = ProcessType(symbolSpecs, decl);
1353 symbol.idCode = symbol.id = globalContext.nextID++;
1354 decl.symbol = symbol;
1356 excludedSymbols->Add(symbol);
1358 FreeList(symbolSpecs, FreeSpecifier);
1362 OldList * MkSpecsClass(Specifier _class)
1364 OldList * list = MkList();
1365 ListAdd(list, _class);
1369 MemberInit MkMemberInit(OldList ids, Initializer initializer)
1371 return { identifiers = ids, initializer = initializer };
1374 MemberInit MkMemberInitExp(Expression idExp, Initializer initializer)
1376 MemberInit init { initializer = initializer, identifiers = MkList() };
1379 for(exp = idExp; exp && exp.type == memberExp; exp = exp.member.exp)
1381 init.identifiers->Insert(null, exp.member.member);
1382 exp.member.member = null;
1384 if(exp && exp.type == identifierExp)
1386 init.identifiers->Insert(null, exp.identifier);
1387 exp.identifier = null;
1389 FreeExpression(idExp);
1393 MembersInit MkMembersInitList(OldList dataMembers)
1395 return { type = dataMembersInit, dataMembers = dataMembers };
1398 MembersInit MkMembersInitMethod(ClassFunction function)
1400 return { type = methodMembersInit, function = function };
1403 Instantiation MkInstantiation(Specifier _class, Expression exp, OldList members)
1405 return { _class = _class, exp = exp, members = members };
1408 Instantiation MkInstantiationNamed(OldList specs, Expression exp, OldList members)
1410 Instantiation inst { exp = exp, members = members };
1415 for(spec = specs.first; spec; spec = spec.next)
1416 if(spec.type == nameSpecifier /*classSpecifier*/)
1423 FreeList(specs, FreeSpecifier);
1427 Compiler_Error("Expecting class specifier\n");
1428 inst._class = MkSpecifierName /*MkClassName*/("");
1436 ClassDef MkClassDefAccessOverride(AccessMode access, Identifier id)
1438 return { type = accessOverrideClassDef, id = id, memberAccess = access };
1441 ClassDef MkClassDefMemberAccess()
1443 return { type = memberAccessClassDef };
1446 ClassDef MkClassDefDeclaration(Declaration decl)
1448 return { type = declarationClassDef, decl = decl };
1451 ClassDef MkClassDefClassData(Declaration decl)
1453 return { type = classDataClassDef, decl = decl };
1456 ClassDef MkClassDefDesigner(char * designer)
1458 return { type = classDesignerClassDef, designer = CopyString(designer) };
1461 ClassDef MkClassDefNoExpansion()
1463 return { type = classNoExpansionClassDef };
1466 ClassDef MkClassDefFixed()
1468 return { type = classFixedClassDef };
1471 ClassDef MkClassDefDesignerDefaultProperty(Identifier id)
1473 return { type = designerDefaultPropertyClassDef, defaultProperty = id };
1476 ClassDef MkClassDefDefaultProperty(OldList defProperties)
1478 return { type = defaultPropertiesClassDef, defProperties = defProperties };
1481 ClassDef MkClassDefFunction(ClassFunction function)
1484 if(function && function.declarator)
1486 Declarator funcDecl = GetFuncDecl(function.declarator);
1487 if(funcDecl && funcDecl.declarator && funcDecl.declarator.type == bracketsDeclarator)
1489 def.type = declarationClassDef;
1490 def.decl = MkStructDeclaration(function.specifiers, MkListOne(MkStructDeclarator(function.declarator, null)), null);
1491 function.declarator = null;
1492 function.specifiers = null;
1493 FreeClassFunction(function);
1497 def.type = functionClassDef;
1498 def.function = function;
1502 Symbol DeclClassAddNameSpace(int symbolID, char * className)
1505 int len = 0, stringLen;
1507 if((currentNameSpace || defaultNameSpace) && declMode != defaultAccess && defaultDeclMode != defaultAccess)
1509 if(defaultNameSpace)
1511 memcpy(name, defaultNameSpace, defaultNameSpaceLen);
1512 len += defaultNameSpaceLen;
1516 if(currentNameSpace)
1518 memcpy(name + len, currentNameSpace, currentNameSpaceLen);
1519 len += currentNameSpaceLen;
1524 stringLen = strlen(className);
1525 memcpy(name + len, className, stringLen);
1528 return _DeclClass(symbolID, name);
1531 Symbol DeclClass(int symbolID, char * name)
1533 if(strchr(name, ':'))
1534 return _DeclClass(symbolID, name);
1536 return DeclClassAddNameSpace(symbolID, name);
1539 Symbol _DeclClass(int symbolID, char * name)
1541 Symbol symbol = FindClass(name);
1545 Context classContext;
1546 for(classContext = curContext; classContext && !classContext.classDef; classContext = classContext.parent);
1552 if(name[0] == ':' && name[1] == ':')
1556 string = CopyString(name);
1557 idCode = symbolID, id = symbolID;
1559 if(!globalContext.classes.Add((BTNode)symbol))
1560 excludedSymbols->Add(symbol);
1565 for(c = 0; (ch = name[c]); c++)
1567 if(ch == '.' || (ch == ':' && name[c+1] == ':'))
1573 if(start && c - start)
1574 symbol.shortName = CopyString(name + start);
1578 symbol.idCode = symbol.id = symbolID;
1582 void SetupBaseSpecs(Symbol symbol, OldList baseSpecs)
1584 if(baseSpecs && baseSpecs.first && ((Specifier)baseSpecs.first).type == nameSpecifier)
1589 strcpy(name, ((Specifier)baseSpecs.first).name);
1590 tpl = strchr(name, '<');
1593 baseClass = FindClass(name);
1597 for(copy = (TemplatedType)baseClass.ctx.templateTypes.first; copy; copy = (TemplatedType)copy.next)
1599 TemplatedType type { key = copy.key, param = copy.param };
1600 if(!curContext.templateTypes.Add((BTNode)type))
1604 else if(baseClass.registered)
1607 for(sClass = baseClass.registered; sClass; sClass = sClass.base)
1609 ClassTemplateParameter p;
1610 for(p = sClass.templateParams.first; p; p = p.next)
1612 //OldList * specs = MkList();
1613 //Declarator decl = null;
1614 //decl = SpecDeclFromString(p.dataTypeString, specs, null);
1617 TemplateParameter param = p.param;
1621 p.param = param = TemplateParameter
1623 identifier = MkIdentifier(p.name), type = p.type,
1624 dataTypeString = p.dataTypeString /*, dataType = { specs, decl }*/
1627 type = TemplatedType { key = (uint)p.name, param = param };
1628 if(!curContext.templateTypes.Add((BTNode)type))
1637 ClassDefinition MkClass(Symbol symbol, OldList baseSpecs, OldList definitions)
1639 ClassDefinition classDef;
1640 SetupBaseSpecs(symbol, baseSpecs);
1643 FreeContext(symbol.ctx);
1646 symbol.ctx = curContext;
1647 classDef = { symbol = symbol, _class = MkSpecifierName /*MkClassName*/(symbol.string), baseSpecs = baseSpecs, definitions = definitions, nameLoc = symbol.nameLoc };
1648 curContext.classDef = classDef;
1652 Expression MkExpInstance(Instantiation inst)
1654 return { type = instanceExp, instance = inst };
1657 External MkExternalClass(ClassDefinition _class)
1659 return { type = classExternal, _class = _class, symbol = _class.symbol };
1662 PropertyDef MkProperty(OldList specs, Declarator decl, Identifier id, Statement setStmt, Statement getStmt)
1672 Type type = ProcessType(specs, decl);
1675 char typeString[1024];
1676 typeString[0] = '\0';
1677 PrintType(type, typeString, false, true);
1678 id = MkIdentifier(typeString);
1679 prop.conversion = true;
1685 string = CopyString(id.string);
1688 symbol.idCode = symbol.id = globalContext.nextID++;
1689 excludedSymbols->Add(symbol);
1690 globalContext.nextID++;
1691 globalContext.nextID++;
1692 prop.symbol = symbol;
1696 ClassDef MkClassDefProperty(PropertyDef propertyDef)
1698 return { type = propertyClassDef, propertyDef = propertyDef };
1701 ClassDef MkClassDefClassProperty(PropertyDef propertyDef)
1703 return { type = classPropertyClassDef, propertyDef = propertyDef };
1706 ClassDef MkClassDefClassPropertyValue(Identifier id, Initializer initializer)
1708 return { type = classPropertyValueClassDef, id = id, initializer = initializer };
1711 int CheckType(char * text)
1714 Time startTime = GetTime();
1716 if(FindTemplateTypeParameter(curContext, text))
1719 checkTypeTotalTime += GetTime() - startTime;
1723 if(FindType(curContext, text))
1726 checkTypeTotalTime += GetTime() - startTime;
1733 checkTypeTotalTime += GetTime() - startTime;
1735 return TYPE_NAME; //CLASS_NAME;
1738 checkTypeTotalTime += GetTime() - startTime;
1745 return CheckType(yytext);
1748 Context PushContext()
1750 Context ctx { parent = curContext };
1755 void PopContext(Context ctx)
1757 curContext = ctx.parent;
1760 Symbol FindType(Context ctx, char * name)
1765 type = (Symbol)ctx.types.FindString(name);
1766 if(!type && ctx.parent)
1767 type = FindType(ctx.parent, name);
1772 TemplatedType FindTemplateTypeParameter(Context ctx, char * name)
1774 TemplatedType templatedType = null;
1777 templatedType = (TemplatedType)ctx.templateTypes.FindString(name);
1778 if(!templatedType && ctx.parent)
1779 templatedType = FindTemplateTypeParameter(ctx.parent, name);
1781 return templatedType;
1784 bool ModuleAccess(Module searchIn, Module searchFor)
1786 SubModule subModule;
1788 if(searchFor == searchIn)
1791 for(subModule = searchIn.modules.first; subModule; subModule = subModule.next)
1793 if(subModule.importMode == publicAccess /*|| searchIn == searchIn.application*/)
1795 if(ModuleAccess(subModule.module, searchFor))
1802 ModuleImport FindModule(Module moduleToFind)
1804 ModuleImport module;
1805 if(!moduleToFind.name)
1807 for(module = imports->first; module; module = module.next)
1808 if(module.name && !strcmp(module.name, moduleToFind.name))
1812 module = ModuleImport
1814 name = CopyString(moduleToFind.name), importType = moduleToFind.importType,
1815 importAccess = ModuleAccess(privateModule, moduleToFind) ? publicAccess : privateAccess
1817 imports->Add(module);
1823 // TO REMOVE: OBSOLETE...
1824 static void GetFullClassNameSpace(NameSpace * ns, char * name)
1828 GetFullClassNameSpace(ns->parent, name);
1829 strcat(name, ns->name);
1834 static char * GetFullClassName(Class c, char * name)
1836 NameSpace * nameSpace;
1838 GetFullClassNameSpace(c.nameSpace, name);
1839 strcat(name, c.name);
1844 public Symbol FindClass(char * name)
1847 Time startTime = GetTime();
1851 bool global = false;
1852 char fullName[1024];
1854 if(name[0] == ':' && name[1] == ':')
1860 if(!global && (currentNameSpace || defaultNameSpace) && declMode != defaultAccess && defaultDeclMode != defaultAccess)
1862 int len = 0, stringLen;
1863 if(defaultNameSpace)
1865 memcpy(fullName, defaultNameSpace, defaultNameSpaceLen);
1866 len += defaultNameSpaceLen;
1867 fullName[len++] = ':';
1868 fullName[len++] = ':';
1870 if(currentNameSpace)
1872 memcpy(fullName + len, currentNameSpace, currentNameSpaceLen);
1873 len += currentNameSpaceLen;
1874 fullName[len++] = ':';
1875 fullName[len++] = ':';
1877 stringLen = strlen(name);
1878 memcpy(fullName + len, name, stringLen);
1881 cl = globalContext ? (Symbol)globalContext.classes.FindString(fullName) : null;
1885 cl = globalContext ? (Symbol)globalContext.classes.FindString(name) : null;
1890 Time startTime = GetTime();
1892 // Ignore name space name when searching
1893 for(cl = globalContext ? (Symbol)globalContext.classes.first : null; cl; cl = (Symbol)((BTNode)cl).next)
1897 char * string = cl.string;
1899 for(c = 0; (ch = string[c]); c++)
1901 if(ch == '.' || (ch == ':' && string[c+1] == ':'))
1907 if(start && c - start)
1909 if(!strcmp(string + start, name))
1913 if(cl.shortName && !strcmp(cl.shortName, name))
1917 findClassIgnoreNSTotalTime += GetTime() - startTime;
1923 if(!global && (currentNameSpace || defaultNameSpace) && declMode != defaultAccess && defaultDeclMode != defaultAccess)
1924 _class = eSystem_FindClass(privateModule, fullName);
1926 _class = eSystem_FindClass(privateModule, name);
1930 name = _class.fullName;
1932 cl = (Symbol)globalContext.classes.FindString(name);
1937 string = CopyString(name);
1938 registered = _class;
1945 cl.module = FindModule(_class.module);
1947 cl.module = mainModule;
1948 if(!globalContext.classes.Add((BTNode)cl))
1949 excludedSymbols->Add(cl);
1950 if(strcmp(name, _class.name))
1951 cl.shortName = CopyString(_class.name);
1956 findClassTotalTime += GetTime() - startTime;
1961 void CopyTypeInto(Type type, Type src)
1964 type.name = CopyString(src.name);
1965 type.enumName = CopyString(src.enumName);
1968 if(src.kind == enumType)
1972 type.members.Clear();
1973 // This must have been a mistake: member = **type**.members.first
1974 for(member = src.members.first; member; member = member.next)
1976 type.members.Add(NamedLink { name = CopyString(member.name), data = member.data });
1979 else if(src.kind == structType || src.kind == unionType)
1982 // Tricky stuff... will be removed from list only when ref count reaches 0
1983 for(member = type.members.first; member; member = member.next)
1986 else if(src.kind == functionType)
1989 type.returnType.refCount++;
1990 for(param = type.params.first; param; param = param.next)
1993 else if(src.kind == pointerType || src.kind == arrayType)
1995 type.type.refCount++;
1996 if(src.kind == arrayType)
1998 if(type.arraySizeExp)
1999 type.arraySizeExp = CopyExpression(type.arraySizeExp);
2005 public Type ProcessType(OldList specs, Declarator decl)
2008 bool isTypedef = false;
2009 if(!specs || specs.first)
2011 Declarator funcDecl = GetFuncDecl(decl);
2013 bool dllExport = false;
2015 specType.kind = intType;
2016 specType.isSigned = true;
2017 specType.refCount = 1;
2019 type = Type { refCount = 1 };
2021 while(decl && (decl.type == structDeclarator || decl.type == extendedDeclarator || decl.type == extendedDeclaratorEnd))
2023 if(decl.type == structDeclarator && decl.structDecl.exp)
2025 ProcessExpressionType(decl.structDecl.exp);
2026 ComputeExpression(decl.structDecl.exp);
2027 if(decl.structDecl.exp.type == constantExp)
2028 specType.bitFieldCount = strtoul(decl.structDecl.exp.constant, null, 0);
2030 if((decl.type == extendedDeclarator || decl.type == extendedDeclaratorEnd) && decl.extended.extended &&
2031 (!strcmp(decl.extended.extended, "__declspec(dllexport)") || !strcmp(decl.extended.extended, "dllexport")))
2035 if((decl.type == extendedDeclarator || decl.type == extendedDeclaratorEnd) && decl.extended.extended &&
2036 (strstr(decl.extended.extended, "__attribute__")))
2038 specType.keepCast = true;
2040 decl = decl.declarator;
2043 // If we'll be using the specType
2044 if(funcDecl || !decl || decl.type == identifierDeclarator)
2049 bool isLong = false;
2050 for(spec = specs.first; spec; spec = spec.next)
2052 if(spec.type == extendedSpecifier && (!strcmp(spec.name, "__declspec(dllexport)") || !strcmp(spec.name, "dllexport")))
2056 if(spec.type == extendedSpecifier && strstr(spec.name, "__attribute__"))
2058 specType.keepCast = true;
2061 if(spec.specifier != CONST && (specType.kind == structType || specType.kind == unionType))
2064 specType = { kind = intType, isSigned = true, refCount = 1 };
2067 if(spec.type == baseSpecifier)
2069 if(spec.specifier == TYPEDEF) isTypedef = true;
2070 else if(spec.specifier == VOID) specType.kind = voidType;
2071 else if(spec.specifier == CHAR) specType.kind = charType;
2072 else if(spec.specifier == INT) { if(specType.kind != shortType && specType.kind != longType) specType.kind = intType; }
2073 else if(spec.specifier == UINT) { if(specType.kind != shortType && specType.kind != longType) specType.kind = intType; specType.isSigned = false; }
2074 else if(spec.specifier == INT64) specType.kind = int64Type;
2075 else if(spec.specifier == VALIST)
2076 specType.kind = vaListType;
2077 else if(spec.specifier == SHORT) specType.kind = shortType;
2078 else if(spec.specifier == LONG)
2081 specType.kind = int64Type;
2083 specType.kind = intType;
2085 // specType.kind = longType;
2087 else if(spec.specifier == FLOAT) specType.kind = floatType;
2088 else if(spec.specifier == DOUBLE) specType.kind = doubleType;
2089 else if(spec.specifier == SIGNED) specType.isSigned = true;
2090 else if(spec.specifier == UNSIGNED) specType.isSigned = false;
2091 else if(spec.specifier == CONST) specType.constant = true;
2092 else if(spec.specifier == TYPED_OBJECT)
2094 specType.classObjectType = typedObject; specType.kind = classType; specType._class = FindClass("class");
2096 else if(spec.specifier == ANY_OBJECT)
2098 specType.classObjectType = anyObject; specType.kind = classType; specType._class = FindClass("class");
2100 else if(spec.specifier == CLASS)
2102 specType.classObjectType = classPointer; specType.kind = classType; specType._class = FindClass("class");
2104 else if(spec.specifier == THISCLASS)
2105 specType.kind = thisClassType;
2107 else if(spec.type == nameSpecifier)
2109 Symbol symbol = spec.name ? FindType(curContext, spec.name) : null;
2110 if(symbol && symbol.type)
2112 // Free Type Contents:
2117 CopyTypeInto(specType, symbol.type);
2118 specType.typeName = CopyString(symbol.type.name);
2120 else if(!isTypedef) // !specType.kind) // TESTING THIS FOR enum / typedef problem
2122 // key.sym enum values need FindClass:
2123 specType._class = spec.name ? FindClass(spec.name) : null;
2124 // specType._class = spec.symbol;
2125 specType.kind = classType;
2126 if(!specType._class)
2127 specType.kind = intType;
2130 else if(spec.type == enumSpecifier)
2133 specType.kind = enumType;
2134 specType.enumName = spec.id ? CopyString(spec.id.string) : null;
2140 for(e = spec.list->first; e; e = e.next)
2142 // TOFIX: NamedItem i { } causes cryptic error, bad .c!
2143 NamedLink i { name = CopyString(e.id.string) };
2144 specType.members.Add(i);
2146 if(e.exp && ComputeExpression(e.exp), e.exp.isConstant && e.exp.expType.kind == intType)
2147 value.data = (void *) nextValue = strtol(e.exp.string, null, 0);
2149 value.data = (void *)nextValue++;
2157 for(enumerator = spec.list->first; enumerator; enumerator = enumerator.next)
2158 if(decl.declarators)
2161 for(d = decl.declarators.first; d; d = d.next)
2163 Type memberType = ProcessType(decl.specifiers, d);
2164 specType.members.Add(memberType);
2167 else if(decl.specifiers)
2169 Type memberType = ProcessType(decl.specifiers, null);
2170 specType.members.Add(memberType);
2175 else if(spec.type == templateTypeSpecifier)
2178 printf("spec %x\n", spec);
2179 printf("template param %x\n", spec.templateParameter);
2180 printf("identifier %x\n", spec.templateParameter.identifier);
2181 printf("string %x\n", spec.templateParameter.identifier.string);
2183 specType.kind = templateType;
2184 specType.templateParameter = spec.templateParameter;
2186 else if(spec.type == structSpecifier || spec.type == unionSpecifier)
2188 Symbol _class = spec.id ? FindClass(spec.id.string) : null;
2191 if(!_class.registered || _class.registered.type != structClass)
2192 specType.directClassAccess = true;
2193 specType._class = _class;
2194 specType.kind = classType;
2197 if(spec.type == structSpecifier)
2198 specType.kind = structType;
2199 else if(spec.type == unionSpecifier)
2200 specType.kind = unionType;
2203 // TESTING THIS HERE... Had 0 type size
2204 if(!spec.definitions && !isTypedef)
2206 Symbol symbol = spec.id.string ? FindSymbol(spec.id.string, curContext, globalContext, true, false) : null;
2207 if(symbol && symbol.type)
2209 specType = *symbol.type;
2210 specType.name = CopyString(symbol.type.name);
2211 specType.typeName = CopyString(spec.name);
2212 specType.enumName = CopyString(symbol.type.enumName);
2213 specType.refCount = 1;
2215 if(symbol.type.kind == enumType)
2219 specType.members.Clear();
2220 for(member = symbol.type.members.first; member; member = member.next)
2222 NamedLink item { name = CopyString(member.name), data = member.data };
2223 specType.members.Add(item);
2226 else if(symbol.type.kind == structType || symbol.type.kind == unionType)
2229 // Tricky stuff... will be removed from list only when ref count reaches 0
2230 for(member = specType.members.first; member; member = member.next)
2233 else if(symbol.type.kind == functionType)
2236 specType.returnType.refCount++;
2237 for(param = specType.params.first; param; param = param.next)
2240 else if(symbol.type.kind == pointerType || symbol.type.kind == arrayType)
2242 specType.type.refCount++;
2243 if(symbol.type.kind == arrayType)
2245 if(specType.arraySizeExp)
2246 specType.arraySizeExp = CopyExpression(specType.arraySizeExp);
2252 specType.enumName = CopyString(spec.id.string);
2255 specType.enumName = CopyString(spec.id.string);
2258 if(spec.definitions)
2261 for(def = spec.definitions->first; def; def = def.next)
2263 if(def.type == declarationClassDef && def.decl.type == structDeclaration)
2265 Declaration decl = def.decl;
2266 if(decl.declarators)
2269 for(d = decl.declarators->first; d; d = d.next)
2271 Type memberType = ProcessType(decl.specifiers, d);
2272 specType.members.Add(memberType);
2275 else if(decl.specifiers)
2277 Type memberType = ProcessType(decl.specifiers, null);
2278 specType.members.Add(memberType);
2285 else if(spec.type == subClassSpecifier)
2287 specType.kind = specType.kind = subClassType;
2288 specType._class = spec._class.symbol; // FindClass(spec._class.name);
2291 else if(spec.type == classSpecifier)
2293 specType._class = FindClass(spec.name);
2294 specType.kind = classType;
2300 specType.kind = ellipsisType;
2305 Declarator d = funcDecl.declarator;
2309 funcType.kind = functionType;
2310 funcType.refCount = 1;
2311 if(funcDecl.function.parameters)
2313 for(param = funcDecl.function.parameters->first; param; param = param.next)
2316 if(param.typedObject)
2318 Type typedObjectType
2321 byReference = param.byReference;
2322 kind = TypeTypedObject;
2324 funcType.params.Add(typedObjectType);
2327 funcType.params.Add(ProcessType(param.qualifiers, param.declarator));
2331 // Function returning a pointer...
2332 if(decl.type == pointerDeclarator)
2334 Pointer pointer = decl.pointer.pointer;
2336 funcType.returnType = ptrType;
2337 funcType.returnType.refCount = 1;
2340 ptrType.kind = pointerType;
2341 pointer = pointer.pointer;
2344 ptrType.type = Type { refCount = 1 };
2345 ptrType = ptrType.type;
2348 ptrType.type = Type { refCount = 1 };
2349 *ptrType.type = specType;
2353 funcType.returnType = Type { refCount = 1 };
2354 *funcType.returnType = specType;
2357 // TESTING: Added extendedDeclarator here
2358 while(d && (d.type == bracketsDeclarator || d.type == extendedDeclarator || d.type == extendedDeclaratorEnd))
2360 if((d.type == extendedDeclarator || d.type == extendedDeclaratorEnd) && d.extended.extended &&
2361 (!strcmp(d.extended.extended, "__declspec(dllexport)") || !strcmp(d.extended.extended, "dllexport")))
2368 funcType.dllExport = dllExport;
2370 if(d && d.type == pointerDeclarator)
2375 if(d.declarator && d.declarator.type == arrayDeclarator)
2377 // Arrays of pointers to functions (extremely tricky :()
2378 Pointer pointer = d.pointer.pointer;
2380 // TO WORK ON: Fixed the order for the array...
2381 type.kind = arrayType;
2382 type.arraySizeExp = CopyExpression(d.declarator.array.exp);
2383 type.freeExp = true;
2384 if(d.declarator.array.enumClass)
2385 type.enumClass = d.declarator.array.enumClass.symbol; // FindClass(d.declarator.array.enumClass.name);
2386 if(d.declarator.declarator && d.declarator.declarator.type == arrayDeclarator)
2388 Type tmpType = type;
2390 type = ProcessType(null, d.declarator.declarator);
2392 type.type = tmpType;
2393 tmpType.type = inType;
2396 type.type = ProcessType(null, d.declarator.declarator);
2398 for(ptrType = type.type; ptrType && ptrType.kind && ptrType.type; ptrType = ptrType.type);
2402 ptrType.kind = pointerType;
2403 pointer = pointer.pointer;
2406 ptrType.type = Type { refCount = 1 };
2407 ptrType = ptrType.type;
2410 ptrType.type = ProcessType(specs, null);
2414 // WARNING: Not caring if this declarator contains a declarator between
2415 // the pointer and the function other than brackets (like in the case of array of pointers to functions)...
2416 // *********** Could it ever go in here??? Yes: void (* converters_table[10]) (); ***********
2417 Pointer pointer = d.pointer.pointer;
2422 ptrType.kind = pointerType;
2423 ptrType.type = Type { refCount = 1 };
2424 pointer = pointer.pointer;
2426 ptrType = ptrType.type;
2430 *ptrType.type = funcType;
2434 if(id._class && !id._class.name)
2435 ptrType.type.staticMethod = true;
2438 // TODO : Ensure classSym has been resolved here... (Is this gonna cause problems? Supposed to do this later...)
2441 if(id._class && id._class.name)
2443 id.classSym = id._class.symbol; // FindClass(id._class.name);
2444 /* TODO: Name Space Fix ups
2446 id.nameSpace = eSystem_FindNameSpace(privateModule, id._class.name);
2451 ptrType.type.thisClass = id.classSym;
2452 if(ptrType.type.thisClass && strcmp(ptrType.type.thisClass.string, "class"))
2453 ptrType.type.extraParam = true;
2454 else if(id._class && id._class.name && !strcmp(id._class.name, "any_object"))
2456 ptrType.type.extraParam = true;
2457 ptrType.type.thisClass = FindClass("class");
2461 type.name = CopyString(id.string);
2464 else if(!d || d.type == identifierDeclarator)
2470 if(d.identifier._class && d.identifier._class.type == templateTypeSpecifier)
2472 type.thisClassTemplate = d.identifier._class.templateParameter;
2473 type.extraParam = true;
2477 if(d.identifier._class && !d.identifier._class.name)
2478 type.staticMethod = true;
2481 if(d.identifier._class && d.identifier._class.name && d.identifier._class.name[strlen(d.identifier._class.name)-1] == '&')
2483 type.thisClass = FindClass("class");
2484 type.byReference = true;
2487 type.thisClass = d.identifier._class ? d.identifier._class.symbol /*FindClass(d.identifier._class.name)*/ : null;
2488 if(type.thisClass && strcmp(type.thisClass.string, "class"))
2490 type.extraParam = true;
2492 else if(d.identifier._class && d.identifier._class.name && !strcmp(d.identifier._class.name, "any_object"))
2494 type.extraParam = true;
2495 type.thisClass = FindClass("class");
2497 else if(d.identifier._class && d.identifier._class.name && !strcmp(d.identifier._class.name, "class"))
2499 //type.extraParam = true;
2500 type.thisClass = FindClass("class");
2501 type.classObjectType = classPointer;
2505 type.name = CopyString(d.identifier.string);
2510 else if(decl && decl.type == pointerDeclarator)
2512 if(decl.declarator && decl.declarator.type == arrayDeclarator)
2514 // Arrays of pointers (tricky :))
2516 Pointer pointer = decl.pointer.pointer;
2519 // TO WORK ON: Fixed the order for the array...
2520 type.kind = arrayType;
2521 type.arraySizeExp = CopyExpression(decl.declarator.array.exp);
2522 type.freeExp = true;
2523 if(decl.declarator.array.enumClass)
2524 type.enumClass = decl.declarator.array.enumClass.symbol; // FindClass(decl.declarator.array.enumClass.name);
2525 if(decl.declarator.declarator && decl.declarator.declarator.type == arrayDeclarator)
2527 Type tmpType = type;
2529 type = ProcessType(null, decl.declarator.declarator);
2531 type.type = tmpType;
2532 tmpType.type = inType;
2535 type.type = ProcessType(null, decl.declarator.declarator);
2537 type.type = ProcessType(null, decl.declarator.declarator);
2538 type.kind = arrayType;
2539 type.arraySizeExp = CopyExpression(decl.declarator.array.exp);
2540 type.arraySizeExp.freeExp = true;
2541 if(decl.array.enumClass)
2542 type.enumClass = FindClass(decl.array.enumClass.name);
2545 for(ptrType = type.type; ptrType && ptrType.kind && ptrType.type; ptrType = ptrType.type);
2549 ptrType.kind = pointerType;
2550 pointer = pointer.pointer;
2553 ptrType.type = Type { refCount = 1 };
2554 ptrType = ptrType.type;
2557 ptrType.type = ProcessType(specs, null);
2558 id = GetDeclId(decl);
2559 if(id) type.name = CopyString(id.string);
2564 Pointer pointer = decl.pointer.pointer;
2565 Type ptrType = type;
2567 if(type.classObjectType)
2569 type.byReference = true;
2575 ptrType.kind = pointerType;
2576 pointer = pointer.pointer;
2579 ptrType.type = Type { refCount = 1 };
2580 ptrType = ptrType.type;
2583 ptrType.type = ProcessType(specs, decl.declarator);
2585 if(type.type.classObjectType)
2587 Type subType = type.type;
2588 type.classObjectType = subType.classObjectType;
2589 type.kind = subType.kind;
2590 type._class = subType._class;
2591 type.byReference = true;
2595 id = GetDeclId(decl);
2596 if(id) type.name = CopyString(id.string);
2600 else if(decl && decl.type == arrayDeclarator)
2604 type.kind = arrayType;
2606 type.arraySizeExp = CopyExpression(decl.array.exp);
2607 type.freeExp = true;
2608 if(decl.array.enumClass)
2609 type.enumClass = decl.array.enumClass.symbol; // FindClass(decl.array.enumClass.name);
2610 id = GetDeclId(decl);
2612 // TO WORK ON: Fixed the order for the array...
2613 if(decl.declarator && decl.declarator.type == arrayDeclarator)
2615 Type tmpType = type;
2617 type = ProcessType(specs, decl.declarator);
2619 type.type = tmpType;
2620 tmpType.type = inType;
2623 type.type = ProcessType(specs, decl.declarator);
2628 type.name = CopyString(id.string);
2633 if(!decl || decl.type == identifierDeclarator)
2637 type.name = decl ? CopyString(decl.identifier.string) : null;
2646 public Type ProcessTypeString(char * string, bool staticMethod)
2648 OldList * specs = MkList();
2649 Declarator decl = SpecDeclFromString(string, specs, null);
2650 Type type = ProcessType(specs, decl);
2651 if(type && !type.thisClass && staticMethod) type.staticMethod = true;
2652 FreeList(specs, FreeSpecifier);
2653 if(decl) FreeDeclarator(decl);
2657 Type MkClassTypeSymbol(Symbol symbol)
2661 Type type { kind = classType, _class = symbol };
2664 // Defaults to an int instead...
2665 type.kind = intType;
2673 public Type MkClassType(char * name)
2677 Type type { kind = classType, _class = FindClass(name) };
2680 // Defaults to an int instead...
2681 type.kind = intType;
2689 AsmField MkAsmField(char * command, Expression expression)
2691 return { command = command, expression = expression };
2694 Statement MkAsmStmt(Specifier spec, char * statements, OldList inputFields, OldList outputFields, OldList clobberedFields)
2696 return { type = asmStmt, asmStmt.spec = spec, asmStmt.statements = statements,
2697 asmStmt.inputFields = inputFields, asmStmt.outputFields = outputFields,
2698 asmStmt.clobberedFields = clobberedFields };
2701 ClassDef MkClassDefPropertyWatch(PropertyWatch watcher)
2703 return { type = propertyWatchClassDef, propertyWatch = watcher };
2706 Statement MkFireWatchersStmt(Expression object, OldList watches)
2708 return { type = fireWatchersStmt, _watch.object = object, _watch.watches = watches };
2711 Statement MkStopWatchingStmt(Expression watcher, Expression object, OldList watches)
2713 return { type = stopWatchingStmt, _watch.watcher = watcher, _watch.object = object, _watch.watches = watches };
2716 Statement MkWatchStmt(Expression watcher, Expression object, OldList watches)
2718 return { type = watchStmt, _watch.watcher = watcher, _watch.object = object, _watch.watches = watches };
2721 PropertyWatch MkDeleteWatch(Statement compound)
2723 return { compound = compound, deleteWatch = true };
2726 PropertyWatch MkPropertyWatch(OldList properties, Statement compound)
2728 return { compound = compound, properties = properties };
2731 Expression MkExpClass(OldList * specifiers, Declarator decl)
2733 return { type = classExp, _classExp.specifiers = specifiers, _classExp.decl = decl };
2736 Expression MkExpClassData(Identifier id)
2738 return { type = classDataExp, classData.id = id };
2742 External MkExternalDBTable(DBTableDef table)
2744 return { type = dbtableExternal, table = table };
2747 DBTableDef MkDBTableDef(char * name, Symbol symbol, OldList * definitions)
2749 return { name = name, symbol = symbol, definitions = definitions };
2752 DBTableEntry MkDBFieldEntry(TypeName type, Identifier id, char * name)
2754 return { type = fieldEntry, dataType = type, id = id, name = name };
2757 DBIndexItem MkDBIndexItem(Identifier id, Order order)
2759 return { id = id, order = order };
2762 DBTableEntry MkDBIndexEntry(OldList * items, Identifier id)
2764 return { type = indexEntry, items = items, id = id };
2767 Expression MkExpDBOpen(Expression ds, Expression dbName)
2769 return { type = dbopenExp, dbopen.ds = ds, dbopen.name = dbName };
2772 Expression MkExpDBField(char * table, Identifier id)
2774 return { type = dbfieldExp, db.table = table, db.id = id };
2777 Expression MkExpDBIndex(char * table, Identifier id)
2779 return { type = dbindexExp, db.table = table, db.id = id };
2782 Expression MkExpDBTable(char * table)
2784 return { type = dbtableExp, db.table = table };
2787 Expression MkExpArray(OldList * expressions)
2789 return { type = arrayExp, list = expressions };
2792 Expression GetTemplateArgExpByName(char * paramName, Class curClass, TemplateParameterType tplType)
2794 Expression argExp = null;
2795 Class _class = curClass ? curClass : ((curExternal && curExternal.type == functionExternal && curExternal.function) ? curExternal.function._class : null);
2799 ClassTemplateParameter curParam;
2801 for(sClass = _class; sClass; sClass = sClass.base)
2804 for(curParam = sClass.templateParams.first; curParam; curParam = curParam.next)
2806 if(!strcmp(curParam.name, paramName))
2808 for(sClass = sClass.base; sClass; sClass = sClass.base)
2809 id += sClass.templateParams.count;
2817 if(curParam && curParam.type != tplType)
2823 char className[1024];
2824 Expression classExp;
2826 sprintf(idString, "%d", id);
2827 strcpy(className, "__ecereClass_");
2828 FullClassNameCat(className, _class.fullName, true);
2829 MangleClassName(className);
2830 DeclareClass(FindClass(_class.fullName), className);
2832 argExp = MkExpIndex((/*pointer ? MkExpPointer : */MkExpMember)
2833 (MkExpMember(MkExpIdentifier(MkIdentifier("this")), MkIdentifier("_class")) /*MkExpIdentifier(MkIdentifier(className))*/,
2834 MkIdentifier("templateArgs")), MkListOne(MkExpConstant(idString)));
2840 Expression GetTemplateArgExp(TemplateParameter param, Class curClass, bool pointer)
2842 return param.identifier ? GetTemplateArgExpByName(param.identifier.string, curClass, type) : null;
2845 /*char * CreateMsgID(char * string, char * context)
2847 int lenString = strlen(string), lenContext = strlen(context);
2848 char * msgid = new char[lenString + lenContext + 20];
2849 memcpy(msgid, string, lenString);
2850 memcpy(msgid+lenString, " [msgctxt: ", 11);
2851 memcpy(msgid+lenString+11, context, lenContext);
2852 memcpy(msgid+lenString+11+lenContext, "]", 2);
2856 public void OutputIntlStrings()
2858 if(intlStrings.count)
2860 char * srcFile = GetSourceFile();
2861 char * objFile = GetOutputFile();
2862 char srcFileFixed[MAX_LOCATION];
2863 char potFile[MAX_LOCATION];
2865 ChangeExtension(objFile, "bowl", potFile);
2866 f = FileOpen(potFile, write);
2869 char * filePrefix = "";
2870 if(!(srcFile[0] && (srcFile[1] == ':' || srcFile[0] == '/')))
2871 filePrefix = (GetRuntimePlatform() == win32) ? ".\\" : "./";
2872 GetSystemPathBuffer(srcFileFixed, srcFile);
2873 for(s : intlStrings)
2875 // TOFIX: (#654) ContextStringPair * pair = &s;
2876 ContextStringPair pair = &s;
2878 f.Printf("#: %s%s:%d\n", filePrefix, srcFileFixed, l.start.line);
2879 // PoEdit now preserves and distinguish msgctxt
2881 f.Printf("msgctxt \"%s\"\n", pair.context);
2882 f.Printf("msgid \"%s\"\n", pair.string);
2883 f.Printf("msgstr \"%s\"\n\n", pair.string);
2891 default extern OldList * ast;
2892 default extern int yyparse ();
2894 public void SetAST(OldList * list) { ast = list; }
2895 public OldList * GetAST() { return ast; }
2896 public void ParseEc()