use cbuilder for most remaining structs, add typedef (#24253)

The only remaining use of `struct` after this is in
`genConstSeq`/`genConstSeqV2` which use `genBracedInit`, I figured these
should be done in the PR that adapts `genBracedInit` in general to
cbuilder.
This commit is contained in:
metagn
2024-10-07 23:10:05 +03:00
committed by GitHub
parent 30e552e3d3
commit 4515b2dae2
4 changed files with 62 additions and 31 deletions

View File

@@ -54,6 +54,15 @@ template addVarWithTypeAndInitializer(builder: var Builder, kind: VarKind = Loca
initializerBody
builder.add(";\n")
template addTypedef(builder: var Builder, name: string, typeBody: typed) =
## adds a typedef declaration to the builder with name `name` and type as
## built in `typeBody`
builder.add("typedef ")
typeBody
builder.add(" ")
builder.add(name)
builder.add(";\n")
type StructInitializer = object
## context for building struct initializers, i.e. `{ field1, field2 }`
# XXX use in genBracedInit

View File

@@ -3,5 +3,17 @@
proc ptrType(t: Snippet): Snippet =
t & "*"
const
CallingConvToStr: array[TCallingConvention, string] = ["N_NIMCALL",
"N_STDCALL", "N_CDECL", "N_SAFECALL",
"N_SYSCALL", # this is probably not correct for all platforms,
# but one can #define it to what one wants
"N_INLINE", "N_NOINLINE", "N_FASTCALL", "N_THISCALL", "N_CLOSURE", "N_NOCONV",
"N_NOCONV" #ccMember is N_NOCONV
]
proc procPtrType(conv: TCallingConvention, rettype: Snippet, name: string): Snippet =
CallingConvToStr[conv] & "_PTR(" & rettype & ", " & name & ")"
proc bitOr(a, b: Snippet): Snippet =
a & " | " & b

View File

@@ -47,7 +47,11 @@ proc generateThreadLocalStorage(m: BModule) =
if m.g.nimtv != "" and (usesThreadVars in m.flags or sfMainModule in m.module.flags):
for t in items(m.g.nimtvDeps): discard getTypeDesc(m, t)
finishTypeDescriptions(m)
m.s[cfsSeqTypes].addf("typedef struct {$1} NimThreadVars;$n", [m.g.nimtv])
var typedef = newBuilder("")
typedef.addTypedef(name = "NimThreadVars"):
typedef.addSimpleStruct(m, name = "", baseType = ""):
typedef.add(m.g.nimtv)
m.s[cfsSeqTypes].add(typedef)
proc generateThreadVarsSize(m: BModule) =
if m.g.nimtv != "":

View File

@@ -285,15 +285,6 @@ proc isInvalidReturnType(conf: ConfigRef; typ: PType, isProc = true): bool =
else: result = false
const
CallingConvToStr: array[TCallingConvention, string] = ["N_NIMCALL",
"N_STDCALL", "N_CDECL", "N_SAFECALL",
"N_SYSCALL", # this is probably not correct for all platforms,
# but one can #define it to what one wants
"N_INLINE", "N_NOINLINE", "N_FASTCALL", "N_THISCALL", "N_CLOSURE", "N_NOCONV",
"N_NOCONV" #ccMember is N_NOCONV
]
proc cacheGetType(tab: TypeCache; sig: SigHash): Rope =
# returns nil if we need to declare this type
# since types are now unique via the ``getUniqueType`` mechanism, this slow
@@ -433,10 +424,11 @@ proc getTypeDescWeak(m: BModule; t: PType; check: var IntSet; kind: TypeDescKind
if cacheGetType(m.typeCache, sig) == "":
m.typeCache[sig] = result
#echo "adding ", sig, " ", typeToString(t), " ", m.module.name.s
appcg(m, m.s[cfsTypes],
"struct $1 {\n" &
" NI len; $1_Content* p;\n" &
"};\n", [result])
var struct = newBuilder("")
struct.addSimpleStruct(m, name = result, baseType = ""):
struct.addField(name = "len", typ = "NI")
struct.addField(name = "p", typ = ptrType(result & "_Content"))
m.s[cfsTypes].add(struct)
pushType(m, t)
else:
result = getTypeForward(m, t, sig) & seqStar(m)
@@ -455,9 +447,13 @@ proc seqV2ContentType(m: BModule; t: PType; check: var IntSet) =
if result == "":
discard getTypeDescAux(m, t, check, dkVar)
else:
appcg(m, m.s[cfsTypes], """
struct $2_Content { NI cap; $1 data[SEQ_DECL_SIZE]; };
""", [getTypeDescAux(m, t.skipTypes(abstractInst)[0], check, dkVar), result])
var struct = newBuilder("")
struct.addSimpleStruct(m, name = result & "_Content", baseType = ""):
struct.addField(name = "cap", typ = "NI")
struct.addField(name = "data",
typ = getTypeDescAux(m, t.skipTypes(abstractInst)[0], check, dkVar),
isFlexArray = true)
m.s[cfsTypes].add(struct)
proc paramStorageLoc(param: PSym): TStorageLoc =
if param.typ.skipTypes({tyVar, tyLent, tyTypeDesc}).kind notin {
@@ -844,8 +840,12 @@ proc getOpenArrayDesc(m: BModule; t: PType, check: var IntSet; kind: TypeDescKin
result = getTypeName(m, t, sig)
m.typeCache[sig] = result
let elemType = getTypeDescWeak(m, t.elementType, check, kind)
m.s[cfsTypes].addf("typedef struct {$n$2* Field0;$nNI Field1;$n} $1;$n",
[result, elemType])
var typedef = newBuilder("")
typedef.addTypedef(name = result):
typedef.addSimpleStruct(m, name = "", baseType = ""):
typedef.addField(name = "Field0", typ = ptrType(elemType))
typedef.addField(name = "Field1", typ = "NI")
m.s[cfsTypes].add(typedef)
proc getTypeDescAux(m: BModule; origTyp: PType, check: var IntSet; kind: TypeDescKind): Rope =
# returns only the type's name
@@ -943,14 +943,17 @@ proc getTypeDescAux(m: BModule; origTyp: PType, check: var IntSet; kind: TypeDes
var rettype, desc: Rope = ""
genProcParams(m, t, rettype, desc, check, true, true)
if not isImportedType(t):
var typedef = newBuilder("")
if t.callConv != ccClosure: # procedure vars may need a closure!
m.s[cfsTypes].addf("typedef $1_PTR($2, $3) $4;$n",
[rope(CallingConvToStr[t.callConv]), rettype, result, desc])
typedef.addTypedef(name = desc):
typedef.add(procPtrType(t.callConv, rettype = rettype, name = result))
else:
m.s[cfsTypes].addf("typedef struct {$n" &
"N_NIMCALL_PTR($2, ClP_0) $3;$n" &
"void* ClE_0;$n} $1;$n",
[result, rettype, desc])
typedef.addTypedef(name = result):
typedef.addSimpleStruct(m, name = "", baseType = ""):
typedef.addField(name = desc, typ =
procPtrType(ccNimCall, rettype = rettype, name = "ClP_0"))
typedef.addField(name = "ClE_0", typ = "void*")
m.s[cfsTypes].add(typedef)
of tySequence:
if optSeqDestructors in m.config.globalOptions:
result = getTypeDescWeak(m, t, check, kind)
@@ -1096,14 +1099,17 @@ proc getClosureType(m: BModule; t: PType, kind: TClosureTypeKind): Rope =
var rettype, desc: Rope = ""
genProcParams(m, t, rettype, desc, check, declareEnvironment=kind != clHalf)
if not isImportedType(t):
var typedef = newBuilder("")
if t.callConv != ccClosure or kind != clFull:
m.s[cfsTypes].addf("typedef $1_PTR($2, $3) $4;$n",
[rope(CallingConvToStr[t.callConv]), rettype, result, desc])
typedef.addTypedef(name = desc):
typedef.add(procPtrType(t.callConv, rettype = rettype, name = result))
else:
m.s[cfsTypes].addf("typedef struct {$n" &
"N_NIMCALL_PTR($2, ClP_0) $3;$n" &
"void* ClE_0;$n} $1;$n",
[result, rettype, desc])
typedef.addTypedef(name = result):
typedef.addSimpleStruct(m, name = "", baseType = ""):
typedef.addField(name = desc, typ =
procPtrType(ccNimCall, rettype = rettype, name = "ClP_0"))
typedef.addField(name = "ClE_0", typ = "void*")
m.s[cfsTypes].add(typedef)
proc finishTypeDescriptions(m: BModule) =
var i = 0