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("typed_object"); //"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 = (uintptr)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;
251 // TODO: Should this be automated somehow?
258 int OnCompare(ContextStringPair b)
261 result = (string && b.string) ? strcmp(string, b.string) :
262 (!string && b.string) ? 1 : (string && !b.string) ? -1 : 0;
263 if(result) return result;
265 result = (context && b.context) ? strcmp(context, b.context) :
266 (!context && b.context) ? 1 : (context && !b.context) ? -1 : 0;
267 // TODO: Support these
268 // result = CaseSensitiveString::OnCompare(string, b.string);
269 // result = ((CaseSensitiveString)string).OnCompare(b.string);
274 Map<ContextStringPair, List<Location>> intlStrings { };
276 Expression MkExpIntlString(char * string, char * context)
278 OldList * list = MkList();
281 ContextStringPair pair { };
283 int len = strlen(string);
285 pair.string = new byte[len-2+1]; memcpy(pair.string, string+1, len-2); pair.string[len-2] = '\0';
286 if(context) { len = strlen(context); pair.context = new byte[len-2+1]; memcpy(pair.context, context+1, len-2); pair.context[len-2] = '\0'; }
288 list = intlStrings[pair];
292 intlStrings[pair] = list;
301 ListAdd(list, QMkExpId("__thisModule"));
302 ListAdd(list, MkExpString(string));
305 int lenString = strlen(string), lenContext = strlen(context);
306 char * msgid = new char[lenString-2 + lenContext-2 + 4];
308 memcpy(msgid+1, context+1, lenContext-2);
309 msgid[1+lenContext-2] = 4; // EOT
310 memcpy(msgid+1+lenContext-2+1, string+1, lenString-2);
311 memcpy(msgid+1+lenContext-2+1+lenString-2, "\"", 2);
312 ListAdd(list, MkExpString(msgid));
316 ListAdd(list, QMkExpId("null"));
317 return MkExpCall(QMkExpId("GetTranslatedString"), list);
320 Expression MkExpOp(Expression exp1, int op, Expression exp2)
331 exp.loc.start = exp1 ? exp1.loc.start : exp2.loc.start;
332 exp.loc.end = exp2 ? exp2.loc.end : exp1.loc.end;
337 Expression MkExpBrackets(OldList expressions)
344 if(expressions && expressions.first)
346 exp.loc.start = ((Expression)expressions.first).loc.start;
347 exp.loc.end = ((Expression)expressions.last).loc.end;
352 Expression MkExpIndex(Expression expression, OldList index)
354 return { type = indexExp, index.exp = expression, index.index = index };
357 Expression MkExpCall(Expression expression, OldList arguments)
359 return { type = callExp, call.exp = expression, call.arguments = arguments };
362 Expression MkExpMember(Expression expression, Identifier member)
364 return { type = memberExp, member.exp = expression, member.member = member };
367 Expression MkExpPointer(Expression expression, Identifier member)
369 return { type = pointerExp, member.exp = expression, member.member = member };
372 Expression MkExpTypeSize(TypeName typeName)
374 return { type = typeSizeExp, typeName = typeName };
377 Expression MkExpTypeAlign(TypeName typeName)
379 return { type = typeAlignExp, typeName = typeName };
382 Expression MkExpClassSize(Specifier _class)
384 return { type = classSizeExp, _class = _class };
387 Expression MkExpCast(TypeName typeName, Expression expression)
389 return { type = castExp, cast.typeName = typeName, cast.exp = expression };
392 Expression MkExpCondition(Expression cond, OldList expressions, Expression elseExp)
394 return { type = conditionExp, cond.cond = cond, cond.exp = expressions, cond.elseExp = elseExp };
397 Expression MkExpRenew(Expression memExp, TypeName type, Expression size)
399 return { type = renewExp, _renew.exp = memExp, _renew.typeName = type, _renew.size = size };
402 Expression MkExpRenew0(Expression memExp, TypeName type, Expression size)
404 return { type = renew0Exp, _renew.exp = memExp, _renew.typeName = type, _renew.size = size };
407 Expression MkExpNew(TypeName type, Expression size)
409 return { type = newExp, _new.typeName = type, _new.size = size };
412 Expression MkExpNew0(TypeName type, Expression size)
414 return { type = new0Exp, _new.typeName = type, _new.size = size };
417 Expression MkExpVaArg(Expression exp, TypeName type)
419 return { type = vaArgExp, vaArg.exp = exp, vaArg.typeName = type };
422 Specifier MkSpecifier(int specifier)
424 return { type = baseSpecifier, specifier = specifier };
427 Specifier MkSpecifierTypeOf(Expression expression)
429 return { type = typeOfSpecifier, expression = expression };
432 Specifier MkSpecifierSubClass(Specifier _class)
434 return { type = subClassSpecifier, _class = _class };
437 Specifier MkSpecifierExtended(ExtDecl extDecl)
439 return { type = extendedSpecifier, extDecl = extDecl /*name = CopyString(name)*/ };
442 Specifier MkEnum(Identifier id, OldList list)
446 type = enumSpecifier;
450 if(list && (!declMode || !id))
456 type = ProcessType(&specs, null);
460 Symbol symbol { string = CopyString(id.string), isStruct = true, type = type };
462 if(strstr(symbol.string, "::"))
463 curContext.hasNameSpace = true;
464 if(!curContext.structSymbols.Add((BTNode)symbol))
467 for(e = list.first; e; e = e.next)
469 Symbol symbol { string = CopyString(e.id.string), type = type };
471 if(strstr(symbol.string, "::"))
472 curContext.hasNameSpace = true;
473 if(!(curContext.templateTypesOnly ? curContext.parent : curContext).symbols.Add((BTNode)symbol))
481 Specifier MkStructOrUnion(SpecifierType type, Identifier id, OldList definitions)
483 Specifier spec { type = type, id = id };
484 if(id && FindType(curContext, id.string))
485 declMode = defaultAccess;
486 spec.definitions = definitions;
487 if(definitions && id && !declMode)
492 symbol = Symbol { string = CopyString(id.string), type = ProcessType(specs, null), isStruct = true };
493 if(!curContext.structSymbols.Add((BTNode)symbol))
499 void AddStructDefinitions(Specifier spec, OldList definitions)
501 spec.definitions = definitions;
502 if(definitions && spec.id && !declMode)
507 symbol = Symbol { string = CopyString(spec.id.string), type = ProcessType(specs, null), isStruct = true };
508 if(!curContext.parent.structSymbols.Add((BTNode)symbol))
513 Attribute MkAttribute(String attr, Expression exp)
515 return { attr = attr, exp = exp };
518 Attrib MkAttrib(int type, OldList * attribs)
520 return { type = type, attribs = attribs };
523 ExtDecl MkExtDeclString(String s)
525 return { type = extDeclString, s = s };
529 ExtDecl MkExtDeclAttrib(Attrib attr)
531 return { type = extDeclAttrib, attr = attr };
535 public Declarator MkDeclaratorIdentifier(Identifier id)
537 return { type = identifierDeclarator, identifier = id };
540 Declarator MkDeclaratorFunction(Declarator declarator, OldList parameters)
542 return { type = functionDeclarator, declarator = declarator, function.parameters = parameters };
545 Declarator MkDeclaratorExtended(ExtDecl extended, Declarator declarator)
547 return { type = extendedDeclarator, declarator = declarator, extended.extended = extended };
550 Declarator MkDeclaratorExtendedEnd(ExtDecl extended, Declarator declarator)
552 return { type = extendedDeclaratorEnd, declarator = declarator, extended.extended = extended };
555 Declarator MkStructDeclarator(Declarator declarator, Expression exp)
557 return { type = structDeclarator, declarator = declarator, structDecl.exp = exp };
560 Declarator MkDeclaratorBrackets(Declarator declarator)
562 return { type = bracketsDeclarator, declarator = declarator };
565 Declarator MkDeclaratorArray(Declarator declarator, Expression exp)
567 return { type = arrayDeclarator, declarator = declarator, array.exp = exp };
570 Declarator MkDeclaratorEnumArray(Declarator declarator, Specifier _class)
572 return { type = arrayDeclarator, declarator = declarator, array.enumClass = _class };
575 Declarator MkDeclaratorPointer(Pointer pointer, Declarator declarator)
577 return { type = pointerDeclarator, declarator = declarator, pointer.pointer = pointer };
580 Enumerator MkEnumerator(Identifier id, Expression exp)
582 return { id = id, exp = exp };
585 Pointer MkPointer(OldList qualifiers, Pointer pointer)
587 return { qualifiers = qualifiers, pointer = pointer };
590 Initializer MkInitializerAssignment(Expression exp)
592 /*if(yylloc.start.line == 1)
594 return { type = expInitializer, exp = exp, loc = yylloc };
597 Initializer MkInitializerList(OldList list)
599 /*if(yylloc.start.line == 1)
601 return { type = listInitializer, list = list, loc = yylloc };
604 InitDeclarator MkInitDeclarator(Declarator declarator, Initializer initializer)
606 return { declarator = declarator, initializer = initializer };
609 public TypeName MkTypeName(OldList qualifiers, Declarator declarator)
611 if(qualifiers != null)
613 Declarator parentDecl = declarator;
614 Declarator decl = declarator;
615 while(decl && decl.type == arrayDeclarator)
616 decl = decl.declarator;
617 if(decl && decl.type == identifierDeclarator && decl.identifier.string && CheckType(decl.identifier.string) == TYPE_NAME)
620 // Check if we're missing a real type specifier here
621 for(spec = qualifiers.first; spec; spec = spec.next)
623 if(spec.type == baseSpecifier)
625 if(spec.specifier == CONST || spec.specifier == VOLATILE ||
626 spec.specifier == EXTERN || spec.specifier == STATIC ||
627 spec.specifier == AUTO || spec.specifier == REGISTER)
631 else if(spec.type != extendedSpecifier)
636 // This is actually a type
637 ListAdd(qualifiers, MkSpecifierName(decl.identifier.string));
638 FreeDeclarator(decl);
639 parentDecl.declarator = null;
643 return { qualifiers = qualifiers, declarator = declarator };
646 public TypeName MkTypeNameGuessDecl(OldList qualifiers, Declarator declarator)
648 if(qualifiers != null)
650 bool gotType = false;
651 bool gotFullType = false;
652 Specifier spec, next;
653 for(spec = qualifiers.first; spec; spec = next)
656 if(gotType && !declarator && ((spec.type == nameSpecifier && spec.name) || (spec.type == baseSpecifier && gotFullType)))
659 if(spec.type == nameSpecifier)
661 char * colon = RSearchString(spec.name, "::", strlen(spec.name), true, false);
662 s = colon ? colon + 2 : spec.name;
664 else if(spec.type == baseSpecifier)
666 if(spec.specifier == INT64) s = "int64";
670 declarator = MkDeclaratorIdentifier(MkIdentifier(s));
671 qualifiers.Remove(spec);
676 if(spec && spec.type != extendedSpecifier)
678 if(spec.type == baseSpecifier)
680 if(spec.specifier == CONST || spec.specifier == VOLATILE ||
681 spec.specifier == EXTERN || spec.specifier == STATIC ||
682 spec.specifier == AUTO || spec.specifier == REGISTER)
684 else if(spec.specifier != UNSIGNED && spec.specifier != SIGNED && spec.specifier != LONG)
696 return { qualifiers = qualifiers, declarator = declarator };
699 public Identifier GetDeclId(Declarator decl)
701 while(decl && decl.type != identifierDeclarator)
702 decl = decl.declarator;
703 return decl ? decl.identifier : null;
706 Declaration MkDeclarationClassInst(Instantiation inst)
708 return { type = instDeclaration, inst = inst, loc = yylloc };
711 Declaration MkDeclarationInst(Instantiation inst)
713 Declaration decl { type = instDeclaration, inst = inst, loc = yylloc };
715 if(curContext == globalContext && (currentNameSpace || defaultNameSpace) && declMode != defaultAccess && defaultDeclMode != defaultAccess)
718 int len = 0, stringLen;
721 memcpy(name, defaultNameSpace, defaultNameSpaceLen);
722 len += defaultNameSpaceLen;
728 memcpy(name + len, currentNameSpace, currentNameSpaceLen);
729 len += currentNameSpaceLen;
734 stringLen = strlen(inst.exp.identifier.string);
735 memcpy(name + len, inst.exp.identifier.string, stringLen);
738 delete inst.exp.identifier.string;
739 inst.exp.identifier.string = CopyString(name);
744 string = (inst.exp.type == identifierExp) ? CopyString(inst.exp.identifier.string) : null;
745 type = MkClassTypeSymbol(inst._class.symbol);
747 symbol.idCode = symbol.id = curContext.nextID++;
748 if(strstr(symbol.string, "::"))
749 curContext.hasNameSpace = true;
750 if(!(curContext.templateTypesOnly ? curContext.parent : curContext).symbols.Add((BTNode)symbol))
751 excludedSymbols->Add(symbol);
752 decl.symbol = inst.symbol = symbol;
756 Declaration MkDeclarationDefine(Identifier id, Expression exp)
758 Declaration decl { type = defineDeclaration, id = id, exp = exp, loc = yylloc };
759 char expString[1024];
762 PrintExpression(exp, expString);
764 if(curContext == globalContext && (currentNameSpace || defaultNameSpace) && declMode != defaultAccess && defaultDeclMode != defaultAccess)
767 int len = 0, stringLen;
770 memcpy(name, defaultNameSpace, defaultNameSpaceLen);
771 len += defaultNameSpaceLen;
777 memcpy(name + len, currentNameSpace, currentNameSpaceLen);
778 len += currentNameSpaceLen;
782 stringLen = strlen(id.string);
783 memcpy(name + len, id.string, stringLen);
787 id.string = CopyString(name);
790 if(!eSystem_FindDefine(privateModule, id.string))
791 eSystem_RegisterDefine(id.string, expString, privateModule, buildingECERECOMModule ? baseSystemAccess : publicAccess);
793 Compiler_Warning($"Redefinition of %s ignored\n", id.string);
797 Declaration MkDeclaration(OldList specifiers, OldList initDeclarators)
799 Declaration decl { type = initDeclaration, declarators = initDeclarators, specifiers = specifiers, loc = yylloc };
800 bool variable = true;
802 if(specifiers != null)
804 bool gotType = false;
805 Specifier spec, next;
806 for(spec = specifiers.first; spec; spec = next)
809 if(spec.type == baseSpecifier && spec.specifier == TYPEDEF)
811 if(initDeclarators != null)
815 for(d = initDeclarators.first; d; d = d.next)
817 if(GetDeclId(d.declarator).string)
821 string = CopyString(GetDeclId(d.declarator).string);
822 type = ProcessType(specifiers, d.declarator);
824 type.id = type.idCode = curContext.nextID++;
826 if(!(curContext.templateTypesOnly ? curContext.parent : curContext).types.Add((BTNode)type))
827 excludedSymbols->Add(type);
828 decl.symbol = d.declarator.symbol = type;
834 //for(spec = spec.next; spec; spec = spec.next)
835 spec = specifiers.last;
837 if((spec.type == nameSpecifier && spec.name) || spec.type == baseSpecifier)
840 if(spec.type == nameSpecifier)
842 char * colon = RSearchString(spec.name, "::", strlen(spec.name), true, false);
843 s = colon ? colon + 2 : spec.name;
845 else if(spec.type == baseSpecifier)
847 if(spec.specifier == INT64) s = "int64";
851 Symbol type { string = CopyString(s), type = ProcessType(specifiers, null) };
852 type.id = type.idCode = curContext.nextID++;
854 decl.declarators = initDeclarators = MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier(s)), null));
855 specifiers.Remove(spec);
857 if(!(curContext.templateTypesOnly ? curContext.parent : curContext).types.Add((BTNode)type))
858 excludedSymbols->Add(type);
866 else if(spec.type == baseSpecifier &&
867 (spec.specifier == STRUCT || spec.specifier == UNION))
871 if(gotType && initDeclarators == null && !spec.next && ((spec.type == nameSpecifier && spec.name) || spec.type == baseSpecifier))
874 if(spec.type == nameSpecifier)
876 char * colon = RSearchString(spec.name, "::", strlen(spec.name), true, false);
877 s = colon ? colon + 2 : spec.name;
879 else if(spec.type == baseSpecifier)
881 if(spec.specifier == INT64) s = "int64";
885 decl.declarators = initDeclarators = MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier(s)), null));
886 specifiers.Remove(spec);
892 if(spec && spec.type != extendedSpecifier)
896 if(variable && initDeclarators)
899 for(d = initDeclarators.first; d; d = d.next)
901 Identifier id = GetDeclId(d.declarator);
902 if(id && id.string && id.string[0])
908 if(curContext == globalContext && (currentNameSpace || defaultNameSpace) && declMode != defaultAccess && defaultDeclMode != defaultAccess)
911 int len = 0, stringLen;
914 memcpy(name, defaultNameSpace, defaultNameSpaceLen);
915 len += defaultNameSpaceLen;
921 memcpy(name + len, currentNameSpace, currentNameSpaceLen);
922 len += currentNameSpaceLen;
926 stringLen = strlen(id.string);
927 memcpy(name + len, id.string, stringLen);
931 id.string = CopyString(name);
934 // Avoid memory leaks on duplicated symbols (BinaryTree::Add Would Fail)
935 symbol = (Symbol)(curContext.templateTypesOnly ? curContext.parent : curContext).symbols.FindString(id.string);
938 symbol = Symbol { string = CopyString(id.string), type = ProcessType(specifiers, d.declarator) };
939 if(strstr(symbol.string, "::"))
940 curContext.hasNameSpace = true;
941 if(!(curContext.templateTypesOnly ? curContext.parent : curContext).symbols.Add((BTNode)symbol))
942 excludedSymbols->Add(symbol);
943 // TODO: Add better support to count declarators
944 if(symbol.type && symbol.type.kind == arrayType && !symbol.type.arraySizeExp && d.initializer)
946 if(d.initializer.type == listInitializer)
949 sprintf(string, "%d",d.initializer.list->count);
950 symbol.type.arraySizeExp = MkExpConstant(string);
951 symbol.type.freeExp = true;
953 else if(d.initializer.type == expInitializer && d.initializer.exp.type == stringExp && d.initializer.exp.string)
958 bool escaped = false;
959 char * s = d.initializer.exp.string;
961 // MAKE MORE ACCURATE
962 for(c = 1; (ch = s[c]); c++)
964 if(ch == '\\' && !escaped)
973 sprintf(string, "%d", count);
974 symbol.type.arraySizeExp = MkExpConstant(string);
975 symbol.type.freeExp = true;
978 symbol.id = symbol.idCode = curContext.nextID++;
980 decl.symbol = d.declarator.symbol = symbol;
987 decl.symbol = Symbol { };
988 decl.symbol.id = decl.symbol.idCode = curContext.nextID++;
989 excludedSymbols->Add(decl.symbol);
994 Declaration MkStructDeclaration(OldList specifiers, OldList declarators, Specifier extStorage)
996 Declaration decl { type = structDeclaration, declarators = declarators, specifiers = specifiers, extStorage = extStorage, loc = yylloc };
997 if(specifiers != null)
999 bool gotType = false;
1000 Specifier spec, next;
1001 for(spec = specifiers.first; spec; spec = next)
1004 if(gotType && declarators == null && ((spec.type == nameSpecifier && spec.name) || spec.type == baseSpecifier))
1007 if(spec.type == nameSpecifier)
1009 char * colon = RSearchString(spec.name, "::", strlen(spec.name), true, false);
1010 s = colon ? colon + 2 : spec.name;
1012 else if(spec.type == baseSpecifier)
1014 if(spec.specifier == INT64) s = "int64";
1018 decl.declarators = declarators = MkListOne(MkStructDeclarator(MkDeclaratorIdentifier(MkIdentifier(s)), null));
1019 specifiers.Remove(spec);
1020 FreeSpecifier(spec);
1024 if(spec && spec.type != extendedSpecifier)
1031 Statement MkLabeledStmt(Identifier id, Statement statement)
1033 return { type = labeledStmt, labeled.id = id, labeled.stmt = statement, loc = yylloc };
1036 Statement MkCaseStmt(Expression exp, Statement statement)
1038 return { type = caseStmt, caseStmt.exp = exp, caseStmt.stmt = statement, loc = yylloc };
1041 Statement MkCompoundStmt(OldList declarations, OldList statements)
1043 return { type = compoundStmt, compound.declarations = declarations, compound.statements = statements, loc = yylloc };
1046 Statement MkExpressionStmt(OldList expressions)
1048 return { type = expressionStmt, expressions = expressions, loc = yylloc };
1051 Statement MkBadDeclStmt(Declaration decl)
1053 return { type = badDeclarationStmt, decl = decl, loc = yylloc };
1056 Statement MkIfStmt(OldList exp, Statement statement, Statement elseStmt)
1058 return { type = ifStmt, ifStmt.exp = exp, ifStmt.stmt = statement, ifStmt.elseStmt = elseStmt, loc = yylloc };
1061 Statement MkSwitchStmt(OldList exp, Statement statement)
1063 // To know it's a switch compound... (Don't want declarations in there... bugs)
1065 statement.compound.isSwitch = true;
1066 return { type = switchStmt, switchStmt.exp = exp, switchStmt.stmt = statement, loc = yylloc };
1069 Statement MkWhileStmt(OldList exp, Statement statement)
1071 return { type = whileStmt, whileStmt.exp = exp, whileStmt.stmt = statement, loc = yylloc };
1074 Statement MkDoWhileStmt(Statement statement, OldList exp)
1076 return { type = doWhileStmt, doWhile.exp = exp, doWhile.stmt = statement, loc = yylloc };
1079 Statement MkForStmt(Statement init, Statement check, OldList inc, Statement statement)
1081 return { type = forStmt, forStmt.init = init, forStmt.check = check, forStmt.increment = inc, forStmt.stmt = statement, loc = yylloc };
1084 Statement MkForEachStmt(Identifier id, OldList exp, OldList filter, Statement statement)
1086 return { type = forEachStmt, forEachStmt.id = id, forEachStmt.exp = exp, forEachStmt.filter = filter, forEachStmt.stmt = statement, loc = yylloc };
1089 Statement MkGotoStmt(Identifier id)
1091 return { type = gotoStmt, gotoStmt.id = id, loc = yylloc };
1094 Statement MkContinueStmt()
1096 return { type = continueStmt, loc = yylloc };
1099 Statement MkBreakStmt()
1101 return { type = breakStmt, loc = yylloc };
1104 Statement MkReturnStmt(OldList exp)
1106 return { type = returnStmt, expressions = exp, loc = yylloc };
1109 FunctionDefinition MkFunction(OldList specifiers, Declarator declarator, OldList declarationList)
1111 return _MkFunction(specifiers, declarator, declarationList, true);
1114 FunctionDefinition _MkFunction(OldList specifiers, Declarator declarator, OldList declarationList, bool errorOnOmit)
1118 Declarator funcDecl = GetFuncDecl(declarator);
1119 if(funcDecl && funcDecl.function.parameters)
1122 for(tn = funcDecl.function.parameters->first; tn; tn = tn.next)
1124 if(tn.qualifiers || tn.declarator)
1126 Identifier declID = tn.declarator ? GetDeclId(tn.declarator) : null;
1130 Specifier spec = tn.qualifiers ? tn.qualifiers->first : null;
1131 if(!tn.declarator && !tn.prev && !tn.next && spec && !spec.next && spec.type == baseSpecifier && spec.specifier == VOID);
1133 Compiler_Error("parameter name omitted\n");
1140 return { specifiers = specifiers, declarator = declarator, declarations = declarationList };
1143 void ProcessFunctionBody(FunctionDefinition func, Statement body)
1145 Declarator declarator = func.declarator;
1146 Declarator funcDecl = GetFuncDecl(declarator);
1151 if(funcDecl && funcDecl.function.parameters && body)
1153 Context context = body.compound.context;
1155 for(param = funcDecl.function.parameters->first; param; param = param.next)
1157 if(param.declarator)
1159 Symbol symbol = null;
1160 Identifier id = GetDeclId(param.declarator);
1161 char * string = id ? id.string : null;
1164 for(symbol = (Symbol)context.symbols.first; symbol; symbol = (Symbol)((BTNode)symbol).next)
1165 if(!strcmp(symbol.string, string))
1167 // This parameter is not shadowed by a local declaration
1170 symbol = Symbol { string = CopyString(id.string), type = ProcessType(param.qualifiers, param.declarator), isParam = true };
1171 if(!context.symbols.Add((BTNode)symbol))
1172 excludedSymbols->Add(symbol);
1174 // TODO: Fix this, the parameters' IDs should really be smaller...
1175 symbol.id = context.nextID++;
1176 param.declarator.symbol = symbol;
1183 if(!declarator.symbol)
1185 Identifier id = GetDeclId(declarator);
1187 if((currentNameSpace || defaultNameSpace) && declMode != defaultAccess && defaultDeclMode != defaultAccess && strcmp(id.string, "__on_register_module"))
1190 int len = 0, stringLen;
1191 if(defaultNameSpace)
1193 memcpy(name, defaultNameSpace, defaultNameSpaceLen);
1194 len += defaultNameSpaceLen;
1198 if(currentNameSpace)
1200 memcpy(name + len, currentNameSpace, currentNameSpaceLen);
1201 len += currentNameSpaceLen;
1205 stringLen = strlen(id.string);
1206 memcpy(name + len, id.string, stringLen);
1210 id.string = CopyString(name);
1212 symbol = Symbol { string = CopyString(id.string), type = ProcessType(func.specifiers, declarator) };
1213 symbol.idCode = symbol.id = globalContext.nextID++;
1214 if(strstr(symbol.string, "::"))
1215 globalContext.hasNameSpace = true;
1216 if(!globalContext.symbols.Add((BTNode)symbol))
1217 excludedSymbols->Add(symbol);
1218 declarator.symbol = symbol;
1222 symbol = declarator.symbol;
1223 excludedSymbols->Remove(declarator.symbol);
1224 delete symbol.string;
1225 symbol.string = CopyString(GetDeclId(declarator).string);
1226 if(strstr(symbol.string, "::"))
1227 globalContext.hasNameSpace = true;
1228 if(!globalContext.symbols.Add((BTNode)symbol))
1229 excludedSymbols->Add(symbol);
1232 symbol.type = ProcessType(func.specifiers, declarator);
1234 if(symbol.type && (symbol.type.kind == functionType || symbol.type.kind == methodType))
1236 if(!symbol.type.params.count)
1238 Type type { refCount = 1 };
1239 symbol.type.params.Add(type);
1248 External MkExternalFunction(FunctionDefinition function)
1250 External external { type = functionExternal, function = function, symbol = function.declarator.symbol };
1251 if(function.specifiers)
1254 for(spec = function.specifiers->first; spec; spec = spec.next)
1255 if(spec.type == baseSpecifier && spec.specifier == STATIC)
1257 declMode = staticAccess;
1262 if(external.symbol && !external.symbol.methodExternal)
1263 external.symbol.methodExternal = external;
1267 External MkExternalImport(char * name, ImportType importType, AccessMode importAccess)
1269 External external { type = importExternal };
1270 int len = strlen(name) - 2;
1271 external.importString = new char[len + 1];
1272 strncpy(external.importString, name+1, len);
1273 external.importString[len] = '\0';
1278 Time startTime = GetTime();
1281 ImportModule(external.importString, importType, importAccess, true);
1282 ImportModule(external.importString, importType, importAccess, false);
1284 time = GetTime() - startTime;
1285 printf("Importing took %.3f seconds for %s\n", time, external.importString);
1286 externalImportTotalTime += time;
1292 External MkExternalDeclaration(Declaration declaration)
1294 External external { type = declarationExternal, declaration = declaration, symbol = declaration ? declaration.symbol : null };
1295 InitDeclarator d = (declaration && declaration.declarators) ? declaration.declarators->last : null;
1296 if(declaration && declaration.type == initDeclaration && declaration.specifiers)
1299 for(spec = declaration.specifiers->first; spec; spec = spec.next)
1300 if(spec.type == baseSpecifier && spec.specifier == TYPEDEF)
1302 declMode = defaultAccess;
1305 else if(spec.type == baseSpecifier && spec.specifier == STATIC)
1307 declMode = staticAccess;
1311 if(declaration && declaration.symbol && !declaration.symbol.methodExternal)
1312 declaration.symbol.methodExternal = external;
1316 External MkExternalNameSpace(Identifier identifier)
1318 External external { type = nameSpaceExternal, id = identifier };
1319 currentNameSpace = identifier ? identifier.string : null;
1320 currentNameSpaceLen = currentNameSpace ? strlen(currentNameSpace) : 0;
1324 void SetClassTemplateArgs(Specifier spec, OldList templateArgs)
1326 if(spec.type == nameSpecifier)
1328 Symbol symbol = spec.symbol;
1329 spec.templateArgs = templateArgs;
1330 if(templateArgs && templateArgs.first)
1332 char templateString[1024];
1333 TemplateArgument arg;
1334 strcpy(templateString, symbol ? symbol.string : spec.name);
1335 strcat(templateString, "<");
1336 for(arg = templateArgs.first; arg; arg = arg.next)
1344 char expString[1024];
1345 Class backupThisClass = thisClass;
1347 expString[0] = '\0';
1348 // Will this work here?
1350 Location oldLocation = yylloc;
1351 File backFileInput = fileInput;
1356 // TESTING THIS SCANNER RESUME STUFF
1359 yylloc = oldLocation;
1360 fileInput = backFileInput;
1363 fileInput.Seek(yylloc.start.pos, start);
1364 resetScannerPos(&yylloc.start);
1369 //ProcessExpressionType(arg.expression);
1370 //ComputeExpression(arg.expression);
1371 PrintExpression(arg.expression, expString);
1372 strcat(argument, expString);
1373 thisClass = backupThisClass;
1378 strcat(argument, arg.identifier.string);
1383 char * typeString = StringFromSpecDecl(arg.templateDatatype.specifiers, arg.templateDatatype.decl);
1384 strcat(argument, typeString);
1391 if(arg.prev) strcat(templateString, ", ");
1394 strcat(templateString, arg.name.string);
1395 strcat(templateString, " = ");
1397 strcat(templateString, argument);
1401 int len = strlen(templateString);
1402 if(templateString[len-1] == '>') templateString[len++] = ' ';
1403 templateString[len++] = '>';
1404 templateString[len++] = '\0';
1406 // printf("SetClassTemplateArgs templateString: %s\n", templateString);
1407 symbol = FindClass(templateString);
1408 if(!symbol && spec.symbol)
1410 // If class was only decl'ed, invoke DeclClass on this templated class as well
1411 symbol = _DeclClass(MAXINT, templateString);
1413 // Add a reference to all templated class to the basic class
1415 spec.symbol.templatedClasses.Add(OldLink { data = symbol });
1417 spec.symbol = symbol;
1418 spec.name = CopyString(symbol ? symbol.string : templateString);
1422 FreeList(templateArgs, FreeTemplateArgument);
1425 Specifier _MkSpecifierName(char * name, Symbol symbol, OldList templateArgs)
1427 Specifier spec { type = nameSpecifier };
1433 TemplatedType templatedType = FindTemplateTypeParameter(curContext, name);
1436 spec.templateParameter = templatedType.param;
1437 spec.type = templateTypeSpecifier;
1441 symbol = FindClass(name);
1443 if(symbol && symbol.registered && symbol.registered.isRemote == 1)
1445 char className[1024];
1446 strcpy(className, "DCOMClient_");
1447 if(!strncmp(name, className, strlen(className)))
1448 spec.name = CopyString(name);
1451 strcat(className, name);
1452 spec.name = CopyString(className);
1456 spec.name = CopyString(symbol.string);
1458 spec.name = CopyString(name);
1459 spec.symbol = symbol;
1460 if(templateArgs != null)
1461 SetClassTemplateArgs(spec, templateArgs);
1466 public Specifier MkSpecifierName(char * name)
1468 return _MkSpecifierName(name, null, null);
1471 public Specifier MkSpecifierNameArgs(char * name, OldList * templateArgs)
1473 return _MkSpecifierName(name, null, templateArgs);
1477 Specifier MkClassName(char * string)
1479 return { type = SpecifierClass, name = CopyString(string) };
1482 ClassFunction MkClassFunction(OldList specifiers, Specifier _class, Declarator decl, OldList declList)
1484 return { specifiers = specifiers, /*_class = _class,*/ declarator = decl, declarations = declList };
1487 void ProcessClassFunctionBody(ClassFunction func, Statement body)
1491 Declarator decl = func.declarator;
1493 //Declarator decl = GetFuncDecl(func.declarator);
1494 Declarator funcDecl = GetFuncDecl(func.declarator);
1498 if(decl && !decl.symbol)
1500 OldList * symbolSpecs = MkList();
1502 // WHAT WILL WE DO WITH THIS? Double instances?
1503 //if(decl.function.parameters && body)
1504 if(funcDecl && funcDecl.function.parameters && body)
1506 Context context = body.compound.context;
1508 for(param = funcDecl.function.parameters->first; param; param = param.next)
1510 if(param.declarator)
1512 Symbol symbol = null;
1513 Identifier id = GetDeclId(param.declarator);
1514 char * string = id ? id.string : null;
1517 symbol = (Symbol)context.symbols.FindString(string);
1519 // This parameter is not shadowed by a local declaration
1524 string = CopyString(id.string);
1525 type = ProcessType(param.qualifiers, param.declarator);
1529 // TODO: Fix this, the parameters' IDs should really be smaller...
1530 symbol.idCode = symbol.id = context.nextID++;
1531 if(!context.symbols.Add((BTNode)symbol))
1532 excludedSymbols->Add(symbol);
1534 param.declarator.symbol = symbol;
1539 //////////////////////////////////
1547 Identifier id = GetDeclId(funcDecl);
1551 for(c = strlen(id.string)-1; c >= 0; c--)
1553 if(id.string[c] == ':')
1555 char * string = CopyString(id.string + c + 1);
1556 id.string[c - 1] = 0;
1557 id._class = MkSpecifierName(id.string);
1563 symbol.string = CopyString(id.string);
1570 for(spec = func.specifiers->first; spec; spec = spec.next)
1571 symbolSpecs->Add(CopySpecifier(spec));
1573 symbol.type = ProcessType(symbolSpecs, decl);
1574 symbol.idCode = symbol.id = globalContext.nextID++;
1575 decl.symbol = symbol;
1577 excludedSymbols->Add(symbol);
1579 FreeList(symbolSpecs, FreeSpecifier);
1583 OldList * MkSpecsClass(Specifier _class)
1585 OldList * list = MkList();
1586 ListAdd(list, _class);
1590 MemberInit MkMemberInit(OldList ids, Initializer initializer)
1592 return { identifiers = ids, initializer = initializer };
1595 MemberInit MkMemberInitExp(Expression idExp, Initializer initializer)
1597 MemberInit init { initializer = initializer, identifiers = MkList() };
1600 for(exp = idExp; exp && exp.type == memberExp; exp = exp.member.exp)
1602 init.identifiers->Insert(null, exp.member.member);
1603 exp.member.member = null;
1605 if(exp && exp.type == identifierExp)
1607 init.identifiers->Insert(null, exp.identifier);
1608 exp.identifier = null;
1610 FreeExpression(idExp);
1614 MembersInit MkMembersInitList(OldList dataMembers)
1616 return { type = dataMembersInit, dataMembers = dataMembers };
1619 MembersInit MkMembersInitMethod(ClassFunction function)
1621 return { type = methodMembersInit, function = function };
1624 Instantiation MkInstantiation(Specifier _class, Expression exp, OldList members)
1626 return { _class = _class, exp = exp, members = members };
1629 Instantiation MkInstantiationNamed(OldList specs, Expression exp, OldList members)
1631 Instantiation inst { exp = exp, members = members };
1636 for(spec = specs.first; spec; spec = spec.next)
1637 if(spec.type == nameSpecifier /*classSpecifier*/)
1644 FreeList(specs, FreeSpecifier);
1648 Compiler_Error($"Expecting class specifier\n");
1649 inst._class = MkSpecifierName /*MkClassName*/("");
1657 ClassDef MkClassDefAccessOverride(AccessMode access, Identifier id)
1659 return { type = accessOverrideClassDef, id = id, memberAccess = access };
1662 ClassDef MkClassDefMemberAccess()
1664 return { type = memberAccessClassDef };
1667 ClassDef MkClassDefDeclaration(Declaration decl)
1669 return { type = declarationClassDef, decl = decl };
1672 ClassDef MkClassDefClassData(Declaration decl)
1674 return { type = classDataClassDef, decl = decl };
1677 ClassDef MkClassDefDesigner(char * designer)
1679 return { type = classDesignerClassDef, designer = CopyString(designer) };
1682 ClassDef MkClassDefNoExpansion()
1684 return { type = classNoExpansionClassDef };
1687 ClassDef MkClassDefFixed()
1689 return { type = classFixedClassDef };
1692 ClassDef MkClassDefDesignerDefaultProperty(Identifier id)
1694 return { type = designerDefaultPropertyClassDef, defaultProperty = id };
1697 ClassDef MkClassDefDefaultProperty(OldList defProperties)
1699 return { type = defaultPropertiesClassDef, defProperties = defProperties };
1702 ClassDef MkClassDefFunction(ClassFunction function)
1705 if(function && function.declarator)
1707 Declarator funcDecl = GetFuncDecl(function.declarator);
1708 if(funcDecl && funcDecl.declarator && funcDecl.declarator.type == bracketsDeclarator)
1710 def.type = declarationClassDef;
1711 def.decl = MkStructDeclaration(function.specifiers, MkListOne(MkStructDeclarator(function.declarator, null)), null);
1712 function.declarator = null;
1713 function.specifiers = null;
1714 FreeClassFunction(function);
1718 def.type = functionClassDef;
1719 def.function = function;
1723 Symbol DeclClassAddNameSpace(int symbolID, char * className)
1726 int len = 0, stringLen;
1728 if((currentNameSpace || defaultNameSpace) && declMode != defaultAccess && defaultDeclMode != defaultAccess)
1730 if(defaultNameSpace)
1732 memcpy(name, defaultNameSpace, defaultNameSpaceLen);
1733 len += defaultNameSpaceLen;
1737 if(currentNameSpace)
1739 memcpy(name + len, currentNameSpace, currentNameSpaceLen);
1740 len += currentNameSpaceLen;
1745 stringLen = strlen(className);
1746 memcpy(name + len, className, stringLen);
1749 return _DeclClass(symbolID, name);
1752 Symbol DeclClass(int symbolID, char * name)
1754 if(strchr(name, ':'))
1755 return _DeclClass(symbolID, name);
1757 return DeclClassAddNameSpace(symbolID, name);
1760 Symbol _DeclClass(int symbolID, char * name)
1762 Symbol symbol = FindClass(name);
1766 Context classContext;
1767 for(classContext = curContext; classContext && !classContext.classDef; classContext = classContext.parent);
1773 if(name[0] == ':' && name[1] == ':')
1777 string = CopyString(name);
1778 idCode = symbolID, id = symbolID;
1780 if(!globalContext.classes.Add((BTNode)symbol))
1781 excludedSymbols->Add(symbol);
1786 for(c = 0; (ch = name[c]); c++)
1788 if(ch == '.' || (ch == ':' && name[c+1] == ':'))
1794 if(start && c - start)
1795 symbol.shortName = CopyString(name + start);
1799 symbol.idCode = symbol.id = symbolID;
1803 void SetupBaseSpecs(Symbol symbol, OldList baseSpecs)
1805 if(baseSpecs && baseSpecs.first && ((Specifier)baseSpecs.first).type == nameSpecifier)
1810 strcpy(name, ((Specifier)baseSpecs.first).name);
1811 tpl = strchr(name, '<');
1814 baseClass = FindClass(name);
1815 if(baseClass && baseClass.ctx)
1818 for(copy = (TemplatedType)baseClass.ctx.templateTypes.first; copy; copy = (TemplatedType)copy.next)
1820 TemplatedType type { key = copy.key, param = copy.param };
1821 if(!curContext.templateTypes.Add((BTNode)type))
1825 else if(baseClass && baseClass.registered)
1828 for(sClass = baseClass.registered; sClass; sClass = sClass.base)
1830 ClassTemplateParameter p;
1831 for(p = sClass.templateParams.first; p; p = p.next)
1833 //OldList * specs = MkList();
1834 //Declarator decl = null;
1835 //decl = SpecDeclFromString(p.dataTypeString, specs, null);
1838 TemplateParameter param = p.param;
1842 p.param = param = TemplateParameter
1844 identifier = MkIdentifier(p.name), type = p.type,
1845 dataTypeString = p.dataTypeString /*, dataType = { specs, decl }*/
1848 type = TemplatedType { key = (uintptr)p.name, param = param };
1849 if(!curContext.templateTypes.Add((BTNode)type))
1858 ClassDefinition MkClass(Symbol symbol, OldList baseSpecs, OldList definitions)
1860 ClassDefinition classDef;
1861 SetupBaseSpecs(symbol, baseSpecs);
1864 ClassDefinition classDef = symbol.ctx.classDef;
1867 // This can occur if two instances of a class are defined...
1868 // To avoid dangling 'parent' Contexts, we free the previous class definition
1870 for(external = ast->first; external; external = external.next)
1872 if(external.type == classExternal && external._class == classDef)
1874 ast->Remove(external);
1875 FreeExternal(external);
1880 FreeContext(symbol.ctx);
1883 symbol.ctx = curContext;
1884 classDef = { symbol = symbol, _class = MkSpecifierName /*MkClassName*/(symbol.string), baseSpecs = baseSpecs, definitions = definitions, nameLoc = symbol.nameLoc };
1885 curContext.classDef = classDef;
1889 Expression MkExpInstance(Instantiation inst)
1891 return { type = instanceExp, instance = inst };
1894 External MkExternalClass(ClassDefinition _class)
1896 return { type = classExternal, _class = _class, symbol = _class.symbol };
1899 PropertyDef MkProperty(OldList specs, Declarator decl, Identifier id, Statement setStmt, Statement getStmt)
1909 Type type = ProcessType(specs, decl);
1912 char typeString[1024];
1913 typeString[0] = '\0';
1914 PrintTypeNoConst(type, typeString, false, true);
1915 id = MkIdentifier(typeString);
1916 prop.conversion = true;
1922 string = CopyString(id.string);
1925 symbol.idCode = symbol.id = globalContext.nextID++;
1926 excludedSymbols->Add(symbol);
1927 globalContext.nextID++;
1928 globalContext.nextID++;
1929 prop.symbol = symbol;
1933 ClassDef MkClassDefProperty(PropertyDef propertyDef)
1935 return { type = propertyClassDef, propertyDef = propertyDef };
1938 ClassDef MkClassDefClassProperty(PropertyDef propertyDef)
1940 return { type = classPropertyClassDef, propertyDef = propertyDef };
1943 ClassDef MkClassDefClassPropertyValue(Identifier id, Initializer initializer)
1945 return { type = classPropertyValueClassDef, id = id, initializer = initializer };
1948 int CheckType(char * text)
1951 Time startTime = GetTime();
1953 if(FindTemplateTypeParameter(curContext, text))
1956 checkTypeTotalTime += GetTime() - startTime;
1960 if(FindType(curContext, text))
1963 checkTypeTotalTime += GetTime() - startTime;
1970 checkTypeTotalTime += GetTime() - startTime;
1972 return TYPE_NAME; //CLASS_NAME;
1975 checkTypeTotalTime += GetTime() - startTime;
1982 return CheckType(yytext);
1985 Context PushContext()
1987 Context ctx { parent = curContext };
1992 void PopContext(Context ctx)
1994 curContext = ctx.parent;
1997 Symbol FindType(Context ctx, char * name)
2002 //char output[8192];
2003 type = (Symbol)ctx.types.FindString(name);
2004 /*if(!strcmp(name, "intptr_t") && !type)
2006 ctx.types.Print(output, depthOrder);
2009 if(!type && ctx.parent)
2010 type = FindType(ctx.parent, name);
2015 TemplatedType FindTemplateTypeParameter(Context ctx, char * name)
2017 TemplatedType templatedType = null;
2020 templatedType = (TemplatedType)ctx.templateTypes.FindString(name);
2021 if(!templatedType && ctx.parent)
2022 templatedType = FindTemplateTypeParameter(ctx.parent, name);
2024 return templatedType;
2027 bool ModuleAccess(Module searchIn, Module searchFor)
2029 SubModule subModule;
2031 if(searchFor == searchIn)
2034 for(subModule = searchIn.modules.first; subModule; subModule = subModule.next)
2036 if(subModule.importMode == publicAccess /*|| searchIn == searchIn.application*/)
2038 if(ModuleAccess(subModule.module, searchFor))
2045 ModuleImport FindModule(Module moduleToFind)
2047 ModuleImport module;
2048 if(!moduleToFind.name)
2050 for(module = imports->first; module; module = module.next)
2051 if(module.name && !strcmp(module.name, moduleToFind.name))
2055 module = ModuleImport
2057 name = CopyString(moduleToFind.name), importType = moduleToFind.importType,
2058 importAccess = ModuleAccess(privateModule, moduleToFind) ? publicAccess : privateAccess
2060 imports->Add(module);
2066 // TO REMOVE: OBSOLETE...
2067 static void GetFullClassNameSpace(NameSpace * ns, char * name)
2071 GetFullClassNameSpace(ns->parent, name);
2072 strcat(name, ns->name);
2077 static char * GetFullClassName(Class c, char * name)
2079 NameSpace * nameSpace;
2081 GetFullClassNameSpace(c.nameSpace, name);
2082 strcat(name, c.name);
2087 public Symbol FindClass(char * name)
2090 Time startTime = GetTime();
2094 bool global = false;
2095 char fullName[1024];
2097 if(name[0] == ':' && name[1] == ':')
2103 if(!global && (currentNameSpace || defaultNameSpace) && declMode != defaultAccess && defaultDeclMode != defaultAccess)
2105 int len = 0, stringLen;
2106 if(defaultNameSpace)
2108 memcpy(fullName, defaultNameSpace, defaultNameSpaceLen);
2109 len += defaultNameSpaceLen;
2110 fullName[len++] = ':';
2111 fullName[len++] = ':';
2113 if(currentNameSpace)
2115 memcpy(fullName + len, currentNameSpace, currentNameSpaceLen);
2116 len += currentNameSpaceLen;
2117 fullName[len++] = ':';
2118 fullName[len++] = ':';
2120 stringLen = strlen(name);
2121 memcpy(fullName + len, name, stringLen);
2124 cl = globalContext ? (Symbol)globalContext.classes.FindString(fullName) : null;
2128 cl = globalContext ? (Symbol)globalContext.classes.FindString(name) : null;
2133 Time startTime = GetTime();
2135 // Ignore name space name when searching
2136 for(cl = globalContext ? (Symbol)globalContext.classes.first : null; cl; cl = (Symbol)((BTNode)cl).next)
2140 char * string = cl.string;
2142 for(c = 0; (ch = string[c]); c++)
2144 if(ch == '.' || (ch == ':' && string[c+1] == ':'))
2150 if(start && c - start)
2152 if(!strcmp(string + start, name))
2156 if(cl.shortName && !strcmp(cl.shortName, name))
2160 findClassIgnoreNSTotalTime += GetTime() - startTime;
2166 if(!global && (currentNameSpace || defaultNameSpace) && declMode != defaultAccess && defaultDeclMode != defaultAccess)
2167 _class = eSystem_FindClass(privateModule, fullName);
2169 _class = eSystem_FindClass(privateModule, name);
2173 name = _class.fullName;
2175 cl = (Symbol)globalContext.classes.FindString(name);
2180 string = CopyString(name);
2181 registered = _class;
2188 cl.module = FindModule(_class.module);
2190 cl.module = mainModule;
2191 if(!globalContext.classes.Add((BTNode)cl))
2192 excludedSymbols->Add(cl);
2193 if(strcmp(name, _class.name))
2194 cl.shortName = CopyString(_class.name);
2199 findClassTotalTime += GetTime() - startTime;
2204 void CopyTypeInto(Type type, Type src)
2207 type.name = CopyString(src.name);
2210 if(src.kind == enumType)
2214 type.members.Clear();
2215 // This must have been a mistake: member = **type**.members.first
2216 for(member = src.members.first; member; member = member.next)
2218 type.members.Add(NamedLink { name = CopyString(member.name), data = member.data });
2220 type.enumName = CopyString(src.enumName);
2222 else if(src.kind == structType || src.kind == unionType)
2225 // Tricky stuff... will be removed from list only when ref count reaches 0
2226 for(member = type.members.first; member; member = member.next)
2228 type.enumName = CopyString(src.enumName);
2230 else if(src.kind == functionType)
2233 type.returnType.refCount++;
2234 for(param = type.params.first; param; param = param.next)
2237 else if(src.kind == pointerType || src.kind == arrayType)
2239 type.type.refCount++;
2240 if(src.kind == arrayType)
2242 if(type.arraySizeExp)
2243 type.arraySizeExp = CopyExpression(type.arraySizeExp);
2249 static Type ProcessTypeSpecs(OldList specs, bool assumeEllipsis, bool keepTypeName)
2251 Type specType { refCount = 1, kind = intType, isSigned = true };
2254 bool isTypedef = false;
2256 bool isLong = false;
2257 for(spec = specs.first; spec; spec = spec.next)
2259 if(spec.type == extendedSpecifier)
2261 ExtDecl extDecl = spec.extDecl;
2262 if(extDecl.type == extDeclString)
2264 String s = spec.extDecl.s;
2265 if(!strcmp(spec.extDecl.s, "__declspec(dllexport)") || !strcmp(spec.extDecl.s, "dllexport"))
2266 specType.dllExport = true;
2267 else if(!strcmp(spec.extDecl.s, "__declspec(stdcall)") || !strcmp(spec.extDecl.s, "stdcall"))
2268 specType.attrStdcall = true;
2270 else if(extDecl.type == extDeclAttrib)
2272 OldList * attribs = extDecl.attr.attribs;
2276 for(attr = attribs->first; attr; attr = attr.next)
2278 String s = attr.attr;
2281 if(!strcmp(s, "dllexport"))
2282 specType.dllExport = true;
2283 else if(!strcmp(s, "stdcall"))
2284 specType.attrStdcall = true;
2288 specType.keepCast = true;
2292 if(spec.specifier != CONST && (specType.kind == structType || specType.kind == unionType))
2295 specType = { kind = intType, isSigned = true, refCount = 1 };
2298 if(isTypedef && keepTypeName)
2300 specType.kind = dummyType;
2303 else if(spec.type == baseSpecifier)
2305 if(spec.specifier == TYPEDEF)
2307 else if(spec.specifier == VOID) specType.kind = voidType;
2308 else if(spec.specifier == CHAR) specType.kind = charType;
2309 else if(spec.specifier == INT) { if(specType.kind != shortType && specType.kind != longType && !isLong) specType.kind = intType; }
2310 else if(spec.specifier == UINT) { if(specType.kind != shortType && specType.kind != longType) specType.kind = intType; specType.isSigned = false; }
2311 else if(spec.specifier == INT64) specType.kind = int64Type;
2312 else if(spec.specifier == VALIST)
2313 specType.kind = vaListType;
2314 else if(spec.specifier == SHORT) specType.kind = shortType;
2315 else if(spec.specifier == LONG)
2317 if(isLong || (targetBits == 64 && targetPlatform != win32))
2318 specType.kind = int64Type;
2320 specType.kind = intType;
2323 else if(spec.specifier == FLOAT) specType.kind = floatType;
2324 else if(spec.specifier == DOUBLE) specType.kind = doubleType;
2325 else if(spec.specifier == SIGNED) specType.isSigned = true;
2326 else if(spec.specifier == UNSIGNED) specType.isSigned = false;
2327 else if(spec.specifier == CONST)
2328 specType.constant = true;
2329 else if(spec.specifier == TYPED_OBJECT || spec.specifier == ANY_OBJECT || spec.specifier == CLASS)
2331 switch(spec.specifier)
2333 case TYPED_OBJECT: specType.classObjectType = typedObject; break;
2334 case ANY_OBJECT: specType.classObjectType = anyObject; break;
2335 case CLASS: specType.classObjectType = classPointer; break;
2337 specType.kind = classType;
2338 specType._class = FindClass("class");
2340 else if(spec.specifier == THISCLASS)
2341 specType.kind = thisClassType;
2343 else if(spec.type == nameSpecifier)
2345 if(spec.name && (!strcmp(spec.name, "intptr") || !strcmp(spec.name, "uintptr")))
2347 specType.kind = intPtrType;
2348 if(!strcmp(spec.name, "uintptr"))
2349 specType.isSigned = false;
2351 else if(spec.name && (!strcmp(spec.name, "uintsize") || !strcmp(spec.name, "intsize")))
2353 specType.kind = intSizeType;
2354 if(!strcmp(spec.name, "uintsize"))
2355 specType.isSigned = false;
2359 Symbol symbol = spec.name ? FindType(curContext, spec.name) : null;
2360 if(symbol && symbol.type)
2362 // Free Type Contents:
2367 CopyTypeInto(specType, symbol.type);
2368 specType.typeName = CopyString(symbol.type.name);
2370 else if(!isTypedef) // !specType.kind) // TESTING THIS FOR enum / typedef problem
2372 // key.sym enum values need FindClass:
2373 specType._class = spec.name ? FindClass(spec.name) : null;
2374 specType.kind = classType;
2375 if(!specType._class)
2376 specType.kind = intType;
2380 else if(spec.type == enumSpecifier)
2382 specType.kind = enumType;
2383 specType.enumName = spec.id ? CopyString(spec.id.string) : null;
2389 for(e = spec.list->first; e; e = e.next)
2391 // TOFIX: NamedItem i { } causes cryptic error, bad .c!
2392 NamedLink i { name = CopyString(e.id.string) };
2393 specType.members.Add(i);
2397 else if(spec.type == templateTypeSpecifier)
2399 specType.kind = templateType;
2400 specType.templateParameter = spec.templateParameter;
2402 else if(spec.type == structSpecifier || spec.type == unionSpecifier)
2404 Symbol _class = spec.id ? FindClass(spec.id.string) : null;
2407 specType.declaredWithStruct = true;
2408 if(!_class.registered || _class.registered.type != structClass)
2409 specType.directClassAccess = true; // TODO: Need to clarify what 'directClassAccess' is about
2410 specType._class = _class;
2411 specType.kind = classType;
2414 specType.members.Clear();
2415 if(spec.type == structSpecifier)
2416 specType.kind = structType;
2417 else if(spec.type == unionSpecifier)
2418 specType.kind = unionType;
2421 // TESTING THIS HERE... Had 0 type size
2422 if(!spec.definitions && !isTypedef)
2424 Symbol symbol = spec.id.string ? FindSymbol(spec.id.string, curContext, globalContext, true, false) : null;
2425 if(symbol && symbol.type)
2427 specType = *symbol.type;
2428 specType.name = CopyString(symbol.type.name);
2429 specType.typeName = CopyString(spec.name);
2430 specType.enumName = CopyString(symbol.type.enumName);
2431 specType.refCount = 1;
2433 if(symbol.type.kind == enumType)
2437 specType.members.Clear();
2438 for(member = symbol.type.members.first; member; member = member.next)
2440 NamedLink item { name = CopyString(member.name), data = member.data };
2441 specType.members.Add(item);
2444 else if(symbol.type.kind == structType || symbol.type.kind == unionType)
2447 // Tricky stuff... will be removed from list only when ref count reaches 0
2448 for(member = specType.members.first; member; member = member.next)
2451 else if(symbol.type.kind == functionType)
2454 specType.returnType.refCount++;
2455 for(param = specType.params.first; param; param = param.next)
2458 else if(symbol.type.kind == pointerType || symbol.type.kind == arrayType)
2460 specType.type.refCount++;
2461 if(symbol.type.kind == arrayType)
2463 if(specType.arraySizeExp)
2464 specType.arraySizeExp = CopyExpression(specType.arraySizeExp);
2470 specType.enumName = CopyString(spec.id.string);
2473 specType.enumName = CopyString(spec.id.string);
2476 if(spec.definitions)
2479 for(def = spec.definitions->first; def; def = def.next)
2481 if(def.type == declarationClassDef && def.decl.type == structDeclaration)
2483 Declaration decl = def.decl;
2484 if(decl.declarators)
2487 for(d = decl.declarators->first; d; d = d.next)
2489 Type memberType = ProcessType(decl.specifiers, d);
2490 specType.members.Add(memberType);
2493 else if(decl.specifiers)
2495 Type memberType = ProcessType(decl.specifiers, null);
2496 specType.members.Add(memberType);
2503 else if(spec.type == subClassSpecifier)
2505 specType.kind = specType.kind = subClassType;
2506 specType._class = spec._class.symbol;
2510 else if(assumeEllipsis)
2511 specType.kind = ellipsisType;
2515 static Type ProcessTypeDecls(OldList specs, Declarator decl, Type parentType)
2517 Type type = parentType;
2518 Declarator subDecl = decl ? decl.declarator : null;
2520 type = ProcessTypeSpecs(specs, decl == null, (decl && decl.type == extendedDeclaratorEnd) ? true : false);
2525 case bracketsDeclarator: break;
2526 case extendedDeclarator:
2527 case extendedDeclaratorEnd:
2529 ExtDecl extDecl = decl.extended.extended;
2532 switch(extDecl.type)
2536 String s = extDecl.s;
2539 if(!strcmp(s, "__declspec(dllexport)") || !strcmp(s, "dllexport"))
2540 type.dllExport = true;
2541 else if(!strcmp(s, "__declspec(stdcall)") || !strcmp(s, "stdcall"))
2542 type.attrStdcall = true;
2548 OldList * attribs = extDecl.attr.attribs;
2552 for(attr = attribs->first; attr; attr = attr.next)
2554 String s = attr.attr;
2557 if(!strcmp(s, "dllexport"))
2558 type.dllExport = true;
2559 else if(!strcmp(s, "stdcall"))
2560 type.attrStdcall = true;
2564 type.keepCast = true;
2571 case structDeclarator:
2573 Expression exp = decl.structDecl.exp;
2576 ProcessExpressionType(exp);
2577 ComputeExpression(exp);
2578 if(exp.type == constantExp)
2579 type.bitFieldCount = (uint)strtoul(exp.constant, null, 0);
2583 case functionDeclarator:
2585 type = { refCount = 1, kind = functionType, returnType = type, dllExport = type.dllExport, attrStdcall = type.attrStdcall };
2586 if(decl.function.parameters)
2589 for(param = decl.function.parameters->first; param; param = param.next)
2590 type.params.Add(ProcessType(param.qualifiers, param.declarator));
2594 case arrayDeclarator:
2596 type = { refCount = 1, kind = arrayType, arraySizeExp = CopyExpression(decl.array.exp), freeExp = true, type = type, dllExport = type.dllExport, attrStdcall = type.attrStdcall };
2597 if(decl.array.enumClass)
2598 type.enumClass = decl.array.enumClass.symbol;
2601 case pointerDeclarator:
2603 Pointer pointer = decl.pointer.pointer;
2606 OldList * qualifiers = pointer.qualifiers;
2607 if(type.classObjectType)
2608 type.byReference = true;
2610 type = { refCount = 1, kind = pointerType, type = type, dllExport = type.dllExport, attrStdcall = type.attrStdcall };
2614 for(spec = qualifiers->first; spec; spec = spec.next)
2616 if(spec.type == baseSpecifier && spec.specifier == CONST)
2617 type.constant = true;
2620 pointer = pointer.pointer;
2624 case identifierDeclarator:
2626 Identifier id = decl.identifier;
2627 Specifier _class = id._class;
2629 type.name = CopyString(id.string);
2632 if(_class.type == templateTypeSpecifier)
2634 type.thisClassTemplate = _class.templateParameter;
2635 type.extraParam = true;
2639 String name = _class.name;
2641 type.staticMethod = true;
2645 id.classSym = _class.symbol; // FindClass(_class.name);
2646 /* TODO: Name Space Fix ups
2647 id.nameSpace = eSystem_FindNameSpace(privateModule, _class.name);
2650 if(name[strlen(name)-1] == '&')
2652 type.thisClass = FindClass("class");
2653 type.byReference = true;
2656 type.thisClass = _class.symbol;
2658 if(type.thisClass && strcmp(type.thisClass.string, "class"))
2659 type.extraParam = true;
2660 else if(!strcmp(name, "any_object"))
2662 type.extraParam = true;
2663 type.thisClass = FindClass("class");
2665 else if(!strcmp(name, "class"))
2667 type.thisClass = FindClass("class");
2668 type.classObjectType = classPointer; // This is used for class properties
2670 else if(!strcmp(name, "typed_object") || !strcmp(name, "typed_object&"))
2672 type.thisClass = FindClass("class");
2673 type.classObjectType = typedObject;
2681 PrintLn("Unhandled Declarator Type: ", decl.type);
2686 Type curType = type;
2687 type = ProcessTypeDecls(null, subDecl, type);
2688 if(curType && type.kind != functionType)
2690 curType.thisClassTemplate = type.thisClassTemplate;
2691 curType.extraParam = type.extraParam;
2692 curType.staticMethod = type.staticMethod;
2693 curType.thisClass = type.thisClass;
2694 curType.byReference = type.byReference;
2695 curType.classObjectType = type.classObjectType;
2701 public Type ProcessType(OldList specs, Declarator decl)
2703 return ProcessTypeDecls(specs, decl, null);
2706 public Type ProcessTypeString(char * string, bool staticMethod)
2708 OldList * specs = MkList();
2709 Declarator decl = SpecDeclFromString(string, specs, null);
2710 Type type = ProcessType(specs, decl);
2711 if(type && !type.thisClass && staticMethod) type.staticMethod = true;
2712 FreeList(specs, FreeSpecifier);
2713 if(decl) FreeDeclarator(decl);
2717 Type MkClassTypeSymbol(Symbol symbol)
2721 Type type { kind = classType, _class = symbol };
2724 // Defaults to an int instead...
2725 type.kind = intType;
2733 public Type MkClassType(char * name)
2737 Type type { kind = classType, _class = FindClass(name) };
2740 // Defaults to an int instead...
2741 type.kind = intType;
2749 AsmField MkAsmField(char * command, Expression expression)
2751 return { command = command, expression = expression };
2754 Statement MkAsmStmt(Specifier spec, char * statements, OldList inputFields, OldList outputFields, OldList clobberedFields)
2756 return { type = asmStmt, asmStmt.spec = spec, asmStmt.statements = statements,
2757 asmStmt.inputFields = inputFields, asmStmt.outputFields = outputFields,
2758 asmStmt.clobberedFields = clobberedFields };
2761 ClassDef MkClassDefPropertyWatch(PropertyWatch watcher)
2763 return { type = propertyWatchClassDef, propertyWatch = watcher };
2766 Statement MkFireWatchersStmt(Expression object, OldList watches)
2768 return { type = fireWatchersStmt, _watch.object = object, _watch.watches = watches };
2771 Statement MkStopWatchingStmt(Expression watcher, Expression object, OldList watches)
2773 return { type = stopWatchingStmt, _watch.watcher = watcher, _watch.object = object, _watch.watches = watches };
2776 Statement MkWatchStmt(Expression watcher, Expression object, OldList watches)
2778 return { type = watchStmt, _watch.watcher = watcher, _watch.object = object, _watch.watches = watches };
2781 PropertyWatch MkDeleteWatch(Statement compound)
2783 return { compound = compound, deleteWatch = true };
2786 PropertyWatch MkPropertyWatch(OldList properties, Statement compound)
2788 return { compound = compound, properties = properties };
2791 Expression MkExpClass(OldList * specifiers, Declarator decl)
2793 return { type = classExp, _classExp.specifiers = specifiers, _classExp.decl = decl };
2796 Expression MkExpClassData(Identifier id)
2798 return { type = classDataExp, classData.id = id };
2802 External MkExternalDBTable(DBTableDef table)
2804 return { type = dbtableExternal, table = table };
2807 DBTableDef MkDBTableDef(char * name, Symbol symbol, OldList * definitions)
2809 return { name = name, symbol = symbol, definitions = definitions };
2812 DBTableEntry MkDBFieldEntry(TypeName type, Identifier id, char * name)
2814 return { type = fieldEntry, dataType = type, id = id, name = name };
2817 DBIndexItem MkDBIndexItem(Identifier id, Order order)
2819 return { id = id, order = order };
2822 DBTableEntry MkDBIndexEntry(OldList * items, Identifier id)
2824 return { type = indexEntry, items = items, id = id };
2827 Expression MkExpDBOpen(Expression ds, Expression dbName)
2829 return { type = dbopenExp, dbopen.ds = ds, dbopen.name = dbName };
2832 Expression MkExpDBField(char * table, Identifier id)
2834 return { type = dbfieldExp, db.table = table, db.id = id };
2837 Expression MkExpDBIndex(char * table, Identifier id)
2839 return { type = dbindexExp, db.table = table, db.id = id };
2842 Expression MkExpDBTable(char * table)
2844 return { type = dbtableExp, db.table = table };
2847 Expression MkExpArray(OldList * expressions)
2849 return { type = arrayExp, list = expressions };
2852 Expression GetTemplateArgExpByName(char * paramName, Class curClass, TemplateParameterType tplType)
2854 Expression argExp = null;
2855 Class _class = curClass ? curClass : ((curExternal && curExternal.type == functionExternal && curExternal.function) ? curExternal.function._class : null);
2859 ClassTemplateParameter curParam;
2861 for(sClass = _class; sClass; sClass = sClass.base)
2864 for(curParam = sClass.templateParams.first; curParam; curParam = curParam.next)
2866 if(!strcmp(curParam.name, paramName))
2868 for(sClass = sClass.base; sClass; sClass = sClass.base)
2869 id += sClass.templateParams.count;
2877 if(curParam && curParam.type != tplType)
2883 char className[1024];
2884 Expression classExp;
2886 sprintf(idString, "%d", id);
2887 strcpy(className, "__ecereClass_");
2888 FullClassNameCat(className, _class.fullName, true);
2889 MangleClassName(className);
2890 DeclareClass(FindClass(_class.fullName), className);
2892 argExp = MkExpIndex((/*pointer ? MkExpPointer : */MkExpMember)
2893 (MkExpMember(MkExpIdentifier(MkIdentifier("this")), MkIdentifier("_class")) /*MkExpIdentifier(MkIdentifier(className))*/,
2894 MkIdentifier("templateArgs")), MkListOne(MkExpConstant(idString)));
2900 Expression GetTemplateArgExp(TemplateParameter param, Class curClass, bool pointer)
2902 return param.identifier ? GetTemplateArgExpByName(param.identifier.string, curClass, type) : null;
2905 /*char * CreateMsgID(char * string, char * context)
2907 int lenString = strlen(string), lenContext = strlen(context);
2908 char * msgid = new char[lenString + lenContext + 20];
2909 memcpy(msgid, string, lenString);
2910 memcpy(msgid+lenString, " [msgctxt: ", 11);
2911 memcpy(msgid+lenString+11, context, lenContext);
2912 memcpy(msgid+lenString+11+lenContext, "]", 2);
2916 public void OutputIntlStrings()
2918 if(intlStrings.count)
2920 char * srcFile = GetSourceFile();
2921 char * objFile = GetOutputFile();
2922 char srcFileFixed[MAX_LOCATION];
2923 char potFile[MAX_LOCATION];
2925 ChangeExtension(objFile, "bowl", potFile);
2926 f = FileOpen(potFile, write);
2929 char * filePrefix = "";
2930 if(!(srcFile[0] && (srcFile[1] == ':' || srcFile[0] == '/')))
2931 filePrefix = "./"; //(GetRuntimePlatform() == win32) ? ".\\" : "./";
2932 // GetSystemPathBuffer(srcFileFixed, srcFile);
2933 GetSlashPathBuffer(srcFileFixed, srcFile);
2934 for(s : intlStrings)
2936 // TOFIX: (#654) ContextStringPair * pair = &s;
2937 ContextStringPair pair = &s;
2939 f.Printf("#: %s%s:%d\n", filePrefix, srcFileFixed, l.start.line);
2940 // PoEdit now preserves and distinguish msgctxt
2942 f.Printf("msgctxt \"%s\"\n", pair.context);
2943 f.Printf("msgid \"%s\"\n", pair.string);
2944 f.Printf("msgstr \"%s\"\n\n", pair.string);
2952 default extern OldList * ast;
2953 default extern int yyparse ();
2954 default extern int yylex ();
2956 public void SetAST(OldList * list) { ast = list; }
2957 public OldList * GetAST() { return ast; }
2958 public void ParseEc()
2968 public const char * GetYYText()