in impl/src/tooling/icpp/transpiler/icppdecls_emitter.ts [51:189]
private processAssembly(entrypoint: MIRInvokeKey) {
const cinits = [...this.assembly.constantDecls].map((cdecl) => cdecl[1].value);
xxxx; //see SMT version
const cginfo = constructCallGraphInfo([entrypoint, ...cinits], this.assembly);
const rcg = [...cginfo.topologicalOrder].reverse();
for (let i = 0; i < rcg.length; ++i) {
const cn = rcg[i];
const cscc = cginfo.recursive.find((scc) => scc.has(cn.invoke));
let worklist = cscc !== undefined ? [...cscc].sort() : [cn.invoke];
for (let mi = 0; mi < worklist.length; ++mi) {
const ikey = worklist[mi];
const idcl = (this.assembly.invokeDecls.get(ikey) || this.assembly.primitiveInvokeDecls.get(ikey)) as MIRInvokeDecl;
const finfo = this.bemitter.generateICPPInvoke(idcl);
this.processVirtualEntityUpdates();
if (finfo !== undefined) {
this.icppasm.invdecls.push(finfo);
}
}
}
this.bemitter.requiredProjectVirtualTupleIndex.forEach((rvpt) => {
const vtype = rvpt.argflowtype;
const opts = [...this.assembly.typeMap].filter((tme) => this.temitter.isUniqueTupleType(tme[1]) && this.assembly.subtypeOf(tme[1], vtype)).map((tme) => tme[1]);
opts.forEach((ttup) => {
const oper = this.bemitter.generateProjectTupleIndexVirtual(rvpt, new SourceInfo(-1, -1, -1 ,-1), ttup);
this.icppasm.invdecls.push(oper);
let vte = this.icppasm.vtable.find((v) => v.oftype === ttup.trkey);
if(vte !== undefined) {
vte.vtable.push({vcall: rvpt.inv, inv: oper.ikey});
}
else {
vte = { oftype: ttup.trkey, vtable: [{vcall: rvpt.inv, inv: oper.ikey}] };
this.icppasm.vtable.push(vte);
}
});
});
this.bemitter.requiredProjectVirtualRecordProperty.forEach((rvpr) => {
const vtype = rvpr.argflowtype;
const opts = [...this.assembly.typeMap].filter((tme) => this.temitter.isUniqueRecordType(tme[1]) && this.assembly.subtypeOf(tme[1], vtype)).map((tme) => tme[1]);
opts.forEach((trec) => {
const oper = this.bemitter.generateProjectRecordPropertyVirtual(rvpr, new SourceInfo(-1, -1, -1 ,-1), trec);
this.icppasm.invdecls.push(oper);
let vte = this.icppasm.vtable.find((v) => v.oftype === trec.trkey);
if(vte !== undefined) {
vte.vtable.push({vcall: rvpr.inv, inv: oper.ikey});
}
else {
vte = { oftype: trec.trkey, vtable: [{vcall: rvpr.inv, inv: oper.ikey}] };
this.icppasm.vtable.push(vte);
}
});
});
this.bemitter.requiredProjectVirtualEntityField.forEach((rvpe) => {
const vtype = rvpe.argflowtype;
const opts = [...this.assembly.typeMap].filter((tme) => this.temitter.isUniqueEntityType(tme[1]) && this.assembly.subtypeOf(tme[1], vtype)).map((tme) => tme[1]);
opts.forEach((tentity) => {
const oper = this.bemitter.generateProjectEntityFieldVirtual(rvpe, new SourceInfo(-1, -1, -1 ,-1), tentity);
this.icppasm.invdecls.push(oper);
let vte = this.icppasm.vtable.find((v) => v.oftype === tentity.trkey);
if(vte !== undefined) {
vte.vtable.push({vcall: rvpe.inv, inv: oper.ikey});
}
else {
vte = { oftype: tentity.trkey, vtable: [{vcall: rvpe.inv, inv: oper.ikey}] };
this.icppasm.vtable.push(vte);
}
});
});
this.icppasm.cbuffsize = this.bemitter.constsize;
this.icppasm.cmask = "111111";
for(let i = 1; i < this.bemitter.constlayout.length; ++i) {
this.icppasm.cmask += this.bemitter.constlayout[i].storage.allocinfo.inlinedmask;
}
this.assembly.constantDecls.forEach((cdecl) => {
const decltype = this.temitter.getICPPTypeData(this.temitter.getMIRType(cdecl.declaredType));
const offset = this.bemitter.constMap.get(cdecl.gkey) as number;
let optenumname: [string, string] | undefined = undefined;
if(cdecl.attributes.includes("enum")) {
optenumname = [cdecl.enclosingDecl as string, cdecl.cname];
}
const icppdecl = new ICPPConstDecl(cdecl.gkey, optenumname, offset, cdecl.value, decltype);
this.icppasm.constdecls.push(icppdecl);
this.icppasm.cbuffsize += decltype.allocinfo.inlinedatasize;
this.icppasm.cmask += decltype.allocinfo.inlinedmask;
});
this.icppasm.litdecls = this.bemitter.constlayout.slice(1)
.filter((cle) => cle.isliteral)
.map((cle) => {
return { offset: cle.offset, storage: cle.storage, value: cle.value };
});
const basetypes = [...this.assembly.typeMap].map((tt) => tt[1]).filter((tt) => tt.options.length === 1 && !(tt.options[0] instanceof MIRConceptType));
this.icppasm.typenames.forEach((tt) => {
const mirtype = this.temitter.getMIRType(tt);
const icpptype = this.temitter.getICPPTypeData(mirtype);
if (icpptype.ptag !== ICPPParseTag.BuiltinTag) {
this.icppasm.typedecls.push(icpptype);
if (icpptype instanceof ICPPTypeInlineUnion || icpptype instanceof ICPPTypeRefUnion) {
const subtypes = basetypes.filter((btype) => this.assembly.subtypeOf(btype, mirtype)).map((tt) => tt.trkey).sort();
this.icppasm.subtypes.set(mirtype.trkey, new Set<MIRResolvedTypeKey>(subtypes));
}
if (this.temitter.isUniqueEntityType(mirtype)) {
const mdecl = this.assembly.entityDecls.get(mirtype.trkey) as MIREntityTypeDecl;
let vte = this.icppasm.vtable.find((v) => v.oftype === mdecl.tkey);
if (vte === undefined) {
vte = { oftype: mdecl.tkey, vtable: [] };
this.icppasm.vtable.push(vte);
}
mdecl.vcallMap.forEach((vc) => {
(vte as { oftype: MIRResolvedTypeKey, vtable: { vcall: MIRVirtualMethodKey, inv: MIRInvokeKey }[] }).vtable.push({ vcall: vc[0], inv: vc[1] });
});
}
}
});
}