3 #define YYLTYPE Location
6 extern External curExternal;
7 ///////////////// INSTANCE DECLARATION PASS ///////////////////////
9 // Returns true if we should add a * to the declarator
10 static int ReplaceClassSpec(OldList specs, Specifier spec, bool param)
12 if(spec.type == templateTypeSpecifier)
14 TemplateParameter parameter = spec.templateParameter;
16 if(!param && parameter.dataTypeString)
18 OldList * newSpecs = MkList();
19 Declarator decl = SpecDeclFromString(parameter.dataTypeString, newSpecs, null);
22 Specifier newSpec = CopySpecifier(newSpecs->first);
26 FreeList(newSpecs, FreeSpecifier);
30 bool isPointer = decl.type == pointerDeclarator;
37 else if(!param && parameter.dataType)
39 OldList * newSpecs = parameter.dataType.specifiers;
40 Declarator decl = parameter.dataType.decl;
43 Specifier newSpec = CopySpecifier(newSpecs->first);
50 bool isPointer = decl.type == pointerDeclarator;
57 spec.type = nameSpecifier;
58 spec.name = CopyString("uint64");
59 spec.symbol = FindClass("uint64");
63 if(spec.type == nameSpecifier || spec.type == subClassSpecifier)
65 // TODO: Apply more care because nameSpecifier / subClassSpecifier use different parts of the union!
66 Symbol classSym = spec.symbol;
67 if(spec.type == subClassSpecifier)
69 classSym = FindClass("ecere::com::Class");
74 Class _class = classSym.registered;
76 FreeSpecifierContents(spec);
78 spec.type = nameSpecifier;
79 if(_class && _class.type == structClass)
84 FullClassNameCat(name, _class.fullName, false);
85 FreeSpecifierContents(spec);
86 spec.type = structSpecifier;
87 spec.baseSpecs = null;
88 spec.id = MkIdentifier(name);
90 spec.definitions = null;
92 spec.addNameSpace = false;
94 else if(_class && _class.type == noHeadClass)
97 FullClassNameCat(name, _class.fullName, false);
98 spec.type = structSpecifier;
99 spec.baseSpecs = null;
100 spec.id = MkIdentifier(name);
102 spec.definitions = null;
104 spec.addNameSpace = false;
108 if((_class.type != systemClass ||
109 !strcmp(_class.fullName, "enum") ||
110 (_class.dataTypeString && !strcmp(_class.dataTypeString, "char *")) ||
111 //strcmp(_class.fullName, "bool") &&
112 !strcmp(_class.fullName, "uint64") ||
113 !strcmp(_class.fullName, "uint32") ||
114 !strcmp(_class.fullName, "uint16") ||
115 !strcmp(_class.fullName, "uintptr") ||
116 !strcmp(_class.fullName, "intptr") ||
117 !strcmp(_class.fullName, "uintsize") ||
118 !strcmp(_class.fullName, "intsize") ||
119 !strcmp(_class.fullName, "uint") ||
120 !strcmp(_class.fullName, "byte")))
122 if(_class.dataTypeString)
124 if(!strcmp(_class.dataTypeString, "uint64") ||
125 !strcmp(_class.dataTypeString, "uint32") ||
126 !strcmp(_class.dataTypeString, "uint16") ||
127 !strcmp(_class.dataTypeString, "uintptr") ||
128 !strcmp(_class.dataTypeString, "intptr") ||
129 !strcmp(_class.dataTypeString, "uintsize") ||
130 !strcmp(_class.dataTypeString, "intsize") ||
131 !strcmp(_class.dataTypeString, "uint") ||
132 !strcmp(_class.dataTypeString, "byte"))
135 _class.dataType = ProcessTypeString(_class.dataTypeString, false);
136 if(_class.dataType && _class.dataType.kind == classType)
137 classSym = _class.dataType._class;
139 classSym = FindClass(_class.dataTypeString);
140 _class = classSym ? classSym.registered : null;
143 spec.name = CopyString(!strcmp(_class.dataTypeString, "char *") ? "char" : _class.dataTypeString);
148 spec.name = CopyString(null);
152 else if(!_class.base)
154 spec.type = baseSpecifier;
155 spec.specifier = VOID;
161 spec.type = structSpecifier;
162 spec.id = MkIdentifier("__ecereNameSpace__ecere__com__Instance");
164 spec.baseSpecs = null;
165 spec.definitions = null;
167 spec.addNameSpace = false;
170 if(_class && _class.dataTypeString && !strcmp(_class.dataTypeString, "char *"))
172 if(!_class || _class.type == normalClass || _class.type == noHeadClass)
174 else if(param && _class.type == structClass)
178 else if(spec.type == baseSpecifier)
180 if(spec.specifier == ANY_OBJECT || spec.specifier == CLASS)
182 spec.specifier = CONST;
183 specs.Add(MkSpecifier(VOID));
190 static void ReplaceByInstancePtr(Specifier spec, Declarator * declPtr, int type)
192 Declarator decl = *declPtr;
193 if(decl && decl.type == pointerDeclarator)
195 // Pointers to simple classes shouldn't be added pointers
199 decl.pointer.pointer = MkPointer(null, decl.pointer.pointer);
203 Declarator newDecl { };
207 decl.declarator = newDecl;
211 decl.type = pointerDeclarator;
212 decl.pointer.pointer = MkPointer(null, null);
217 static void InstDeclPassSpecifier(Specifier spec, bool byRefTypedObject)
222 if(spec.specifier == TYPED_OBJECT)
224 spec.type = extendedSpecifier;
225 spec.extDecl = MkExtDeclString(CopyString(byRefTypedObject ?
226 "struct __ecereNameSpace__ecere__com__Class * class, void *" :
227 "struct __ecereNameSpace__ecere__com__Class * class, const void *"));
237 for(e = spec.list->first; e; e = e.next)
244 case structSpecifier:
250 for(def = spec.definitions->first; def; def = def.next)
252 InstDeclPassDeclaration(def.decl);
255 InstDeclPassIdentifier(spec.id);
258 case extendedSpecifier:
259 if(spec.extDecl && spec.extDecl.type == extDeclString && spec.extDecl.s)
261 if(!strcmp(spec.extDecl.s, "dllexport"))
264 delete spec.extDecl.s;
265 for(prevSpec = spec.prev; prevSpec; prevSpec = prevSpec.prev)
266 if(prevSpec.type == baseSpecifier && prevSpec.specifier == EXTERN)
270 if(targetPlatform == win32)
271 spec.extDecl.s = CopyString("__declspec(dllexport)");
273 spec.extDecl.s = CopyString("__attribute__ ((visibility(\"default\")))");
277 if(targetPlatform == win32)
278 spec.extDecl.s = CopyString("extern __declspec(dllexport)");
280 spec.extDecl.s = CopyString("extern __attribute__ ((visibility(\"default\")))");
283 else if(!strcmp(spec.extDecl.s, "stdcall") || !strcmp(spec.extDecl.s, "_stdcall") ||
284 !strcmp(spec.extDecl.s, "__stdcall") || !strcmp(spec.extDecl.s, "__stdcall__"))
286 delete spec.extDecl.s;
287 if(targetPlatform == win32)
288 spec.extDecl.s = CopyString("__attribute__((__stdcall__))");
290 spec.extDecl.s = CopyString("");
297 static void InstDeclPassDeclarator(Declarator decl)
301 case structDeclarator:
303 InstDeclPassDeclarator(decl.declarator);
305 case identifierDeclarator:
308 InstDeclPassIdentifier(decl.identifier);
311 case bracketsDeclarator:
313 InstDeclPassDeclarator(decl.declarator);
315 case arrayDeclarator:
317 InstDeclPassDeclarator(decl.declarator);
319 case functionDeclarator:
322 InstDeclPassDeclarator(decl.declarator);
323 if(decl.function.parameters)
327 InstDeclPassDeclarator(decl.declarator);
328 for(type = decl.function.parameters->first; type; type = type.next)
330 bool typedObject = false;
331 Specifier spec = null;
334 spec = (Specifier)type.qualifiers->first;
335 if(spec && spec.type == nameSpecifier && !strcmp(spec.name, "class"))
339 InstDeclPassTypeName(type, true);
344 qualifiers = MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier("__ecereNameSpace__ecere__com__Class"), null));
345 declarator = MkDeclaratorPointer(MkPointer(null,null), MkDeclaratorIdentifier(MkIdentifier("class")));
347 decl.function.parameters->Insert(spec.prev, _class);
353 case pointerDeclarator:
354 case extendedDeclarator:
355 case extendedDeclaratorEnd:
356 if((decl.type == extendedDeclarator || decl.type == extendedDeclaratorEnd) && decl.extended.extended)
358 if(decl.extended.extended.type == extDeclString && decl.extended.extended.s && !strcmp(decl.extended.extended.s, "dllexport"))
360 delete decl.extended.extended.s;
361 if(targetPlatform == win32)
362 decl.extended.extended.s = CopyString("extern __declspec(dllexport)");
364 decl.extended.extended.s = CopyString("extern __attribute__ ((visibility(\"default\")))");
366 else if(decl.extended.extended.type == extDeclString && decl.extended.extended.s &&
367 (!strcmp(decl.extended.extended.s, "stdcall") || !strcmp(decl.extended.extended.s, "_stdcall") ||
368 !strcmp(decl.extended.extended.s, "__stdcall") || !strcmp(decl.extended.extended.s, "__stdcall__")))
370 delete decl.extended.extended.s;
371 if(targetPlatform == win32)
372 decl.extended.extended.s = CopyString("__attribute__((__stdcall__))");
374 decl.extended.extended.s = CopyString("");
378 InstDeclPassDeclarator(decl.declarator);
383 /*static */void InstDeclPassTypeName(TypeName type, bool param)
388 for(spec = type.qualifiers->first; spec; spec = spec.next)
391 if((result = ReplaceClassSpec(type.qualifiers, spec, param)))
392 ReplaceByInstancePtr(spec, &type.declarator, result);
395 Symbol classSym = (spec.type == nameSpecifier) ? spec.symbol /*FindClass(spec.name)*/ : null;
396 if(type.classObjectType && (!classSym || (classSym && classSym.registered &&
397 (classSym.registered.type == enumClass || classSym.registered.type == bitClass || classSym.registered.type == unitClass))))
398 ReplaceByInstancePtr(spec, &type.declarator, 2);
400 InstDeclPassSpecifier(spec, type.declarator && type.declarator.type == pointerDeclarator);
404 InstDeclPassDeclarator(type.declarator);
407 static void InstDeclPassIdentifier(Identifier id)
409 if(strchr(id.string, ':'))
415 strcpy(newID, "__ecereNameSpace__");
418 for(c = 0; (ch = id.string[c]); c++)
420 if(ch == ':') ch = '_';
426 id.string = CopyString(newID);
430 static bool IsVoidPtrCast(TypeName typeName)
433 Declarator d = typeName.declarator;
434 if(d && d.type == pointerDeclarator && d.pointer.pointer == null)
436 if(typeName.qualifiers)
439 for(s = typeName.qualifiers->first; s; s = s.next)
441 if(s.type == baseSpecifier && s.specifier == VOID)
449 static void InstDeclPassExpression(Expression exp)
456 InstDeclPassIdentifier(exp.identifier);
465 InstDeclPassExpression(exp.op.exp1);
467 InstDeclPassExpression(exp.op.exp2);
469 case extensionExpressionExp:
473 for(e = exp.list->first; e; e = e.next)
474 InstDeclPassExpression(e);
480 InstDeclPassExpression(exp.index.exp);
481 for(e = exp.index.index->first; e; e = e.next)
482 InstDeclPassExpression(e);
488 InstDeclPassExpression(exp.call.exp);
489 if(exp.call.arguments)
491 for(e = exp.call.arguments->first; e; e = e.next)
493 Type src = e.expType;
495 InstDeclPassExpression(e);
497 if(src && (src.kind == templateType || src.kind == classType))
499 if(e.type != castExp || !IsVoidPtrCast(e.cast.typeName))
501 if(src) src.refCount++;
502 if(src.kind == templateType)
504 if(src.templateParameter && src.templateParameter.type == type)
507 if(src.templateParameter.dataTypeString)
508 newType = ProcessTypeString(src.templateParameter.dataTypeString, false);
509 else if(src.templateParameter.dataType)
510 newType = ProcessType(src.templateParameter.dataType.specifiers, src.templateParameter.dataType.decl);
518 if(src && src.kind == classType && src._class)
520 Class sc = src._class.registered;
521 if(sc && (sc.type == structClass || sc.type == noHeadClass))
523 Type dest = e.destType;
524 if(dest && (dest.kind == templateType || dest.kind == classType))
526 if(dest) dest.refCount++;
528 if(dest.templateParameter && dest.templateParameter.type == type)
531 if(dest.templateParameter.dataTypeString)
532 newType = ProcessTypeString(dest.templateParameter.dataTypeString, false);
533 else if(dest.templateParameter.dataType)
534 newType = ProcessType(dest.templateParameter.dataType.specifiers, dest.templateParameter.dataType.decl);
541 if(!dest.passAsTemplate && dest.kind == classType && dest._class && dest._class.registered)
543 Class dc = dest._class.registered;
544 if(sc.templateClass) sc = sc.templateClass;
545 if(dc.templateClass) dc = dc.templateClass;
546 if(dc.base && (sc != dc || sc.base.type == structClass))
548 e.cast.exp = CopyExpContents(e);
550 e.typeName = MkTypeName(MkListOne(MkSpecifier(VOID)), QMkPtrDecl(null));
567 InstDeclPassExpression(exp.member.exp);
573 InstDeclPassExpression(exp.member.exp);
577 InstDeclPassTypeName(exp.typeName, false);
581 Type type = exp.expType;
582 // Remove casts to simple structs... (Watch out for pointers later...)
583 if(type && type.kind == classType && type._class.registered && type._class.registered.type == structClass && !exp.needCast)
585 Expression castExp = exp.cast.exp;
586 Expression prev = exp.prev, next = exp.next;
588 FreeExpContents(exp);
589 FreeType(exp.expType);
590 FreeType(exp.destType);
595 InstDeclPassExpression(exp);
599 InstDeclPassTypeName(exp.cast.typeName, exp.usage.usageArg /*false*/);
601 InstDeclPassExpression(exp.cast.exp);
608 InstDeclPassExpression(exp.cond.cond);
609 for(e = exp.cond.exp->first; e; e = e.next)
610 InstDeclPassExpression(e);
611 InstDeclPassExpression(exp.cond.elseExp);
614 case extensionCompoundExp:
616 InstDeclPassStatement(exp.compound);
621 InstDeclPassExpression(exp.vaArg.exp);
624 case extensionInitializerExp:
626 InstDeclPassTypeName(exp.initializer.typeName, false);
627 InstDeclPassInitializer(exp.initializer.initializer);
633 static void InstDeclPassInitializer(Initializer init)
639 InstDeclPassExpression(init.exp);
641 case listInitializer:
644 for(i = init.list->first; i; i = i.next)
645 InstDeclPassInitializer(i);
651 static void InstDeclPassDeclaration(Declaration decl)
655 case initDeclaration:
660 for(spec = decl.specifiers->first; spec; spec = spec.next)
663 if((type = ReplaceClassSpec(decl.specifiers, spec, false)))
668 for(d = decl.declarators->first; d; d = d.next)
669 ReplaceByInstancePtr(spec, &d.declarator, type);
672 InstDeclPassSpecifier(spec, false);
678 for(d = decl.declarators->first; d; d = d.next)
680 InstDeclPassDeclarator(d.declarator);
682 InstDeclPassInitializer(d.initializer);
687 case structDeclaration:
692 for(spec = decl.specifiers->first; spec; spec = spec.next)
695 if((type = ReplaceClassSpec(decl.specifiers, spec, false)))
700 for(d = decl.declarators->first; d; d = d.next)
701 ReplaceByInstancePtr(spec, &d, type);
704 InstDeclPassSpecifier(spec, false);
711 for(d = decl.declarators->first; d; d = d.next)
712 InstDeclPassDeclarator(d);
716 // This should be removed by now?
717 case instDeclaration:
718 // InstDeclPassInstantiation(decl.inst);
723 static void InstDeclPassStatement(Statement stmt)
727 case badDeclarationStmt:
729 InstDeclPassDeclaration(stmt.decl);
732 InstDeclPassStatement(stmt.labeled.stmt);
735 // This expression should be constant...
736 if(stmt.caseStmt.exp)
737 InstDeclPassExpression(stmt.caseStmt.exp);
738 if(stmt.caseStmt.stmt)
739 InstDeclPassStatement(stmt.caseStmt.stmt);
745 Context prevContext = curContext;
747 if(!stmt.compound.isSwitch)
748 curContext = stmt.compound.context;
750 if(stmt.compound.declarations)
752 for(decl = stmt.compound.declarations->first; decl; decl = decl.next)
753 InstDeclPassDeclaration(decl);
755 if(stmt.compound.statements)
757 for(s = stmt.compound.statements->first; s; s = s.next)
758 InstDeclPassStatement(s);
760 curContext = prevContext;
768 for(exp = stmt.expressions->first; exp; exp = exp.next)
769 InstDeclPassExpression(exp);
778 for(exp = stmt.ifStmt.exp->first; exp; exp = exp.next)
779 InstDeclPassExpression(exp);
782 InstDeclPassStatement(stmt.ifStmt.stmt);
783 if(stmt.ifStmt.elseStmt)
784 InstDeclPassStatement(stmt.ifStmt.elseStmt);
790 if(stmt.switchStmt.exp)
792 for(exp = stmt.switchStmt.exp->first; exp; exp = exp.next)
793 InstDeclPassExpression(exp);
795 InstDeclPassStatement(stmt.switchStmt.stmt);
801 if(stmt.whileStmt.exp)
803 for(exp = stmt.whileStmt.exp->first; exp; exp = exp.next)
804 InstDeclPassExpression(exp);
806 InstDeclPassStatement(stmt.whileStmt.stmt);
814 for(exp = stmt.doWhile.exp->first; exp; exp = exp.next)
815 InstDeclPassExpression(exp);
817 if(stmt.doWhile.stmt)
818 InstDeclPassStatement(stmt.doWhile.stmt);
824 if(stmt.forStmt.init)
825 InstDeclPassStatement(stmt.forStmt.init);
826 if(stmt.forStmt.check)
827 InstDeclPassStatement(stmt.forStmt.check);
828 if(stmt.forStmt.increment)
830 for(exp = stmt.forStmt.increment->first; exp; exp = exp.next)
831 InstDeclPassExpression(exp);
833 if(stmt.forStmt.stmt)
834 InstDeclPassStatement(stmt.forStmt.stmt);
848 for(exp = stmt.expressions->first; exp; exp = exp.next)
849 InstDeclPassExpression(exp);
856 if(stmt.asmStmt.inputFields)
858 for(field = stmt.asmStmt.inputFields->first; field; field = field.next)
860 InstDeclPassExpression(field.expression);
862 if(stmt.asmStmt.outputFields)
864 for(field = stmt.asmStmt.outputFields->first; field; field = field.next)
866 InstDeclPassExpression(field.expression);
868 if(stmt.asmStmt.clobberedFields)
870 for(field = stmt.asmStmt.clobberedFields->first; field; field = field.next)
872 InstDeclPassExpression(field.expression);
879 public void ProcessInstanceDeclarations()
882 curContext = globalContext;
883 for(external = ast->first; external; external = external.next)
885 curExternal = external;
886 if(external.type == functionExternal)
888 FunctionDefinition func = external.function;
892 for(spec = func.specifiers->first; spec; spec = spec.next)
895 if((type = ReplaceClassSpec(func.specifiers, spec, false)))
896 ReplaceByInstancePtr(spec, &func.declarator, type);
897 InstDeclPassSpecifier(spec, false);
900 InstDeclPassDeclarator(func.declarator);
902 InstDeclPassStatement(func.body);
904 else if(external.type == declarationExternal)
906 if(external.declaration)
907 InstDeclPassDeclaration(external.declaration);