Skip to content

Commit

Permalink
test moving out anon struct for case branches
Browse files Browse the repository at this point in the history
  • Loading branch information
metagn committed Nov 22, 2024
1 parent 6556ae4 commit 55cba34
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 20 deletions.
37 changes: 22 additions & 15 deletions compiler/cbuilderdecls.nim
Original file line number Diff line number Diff line change
Expand Up @@ -594,22 +594,29 @@ template addStruct(obj: var Builder; m: BModule; typ: PType; name: string; baseT
body
finishStruct(obj, m, typ, info)

template addFieldWithStructType(obj: var Builder; m: BModule; parentTyp: PType; fieldName: string, body: typed) =
## adds a field with a `struct { ... }` type, building the fields according to `body`
obj.add('\t')
if tfPacked in parentTyp.flags:
if hasAttribute in CC[m.config.cCompiler].props:
obj.add("struct __attribute__((__packed__)) {\n")
else:
obj.add("#pragma pack(push, 1)\nstruct {")
proc addFieldStruct(obj: var Builder; m: BModule; parentTyp: PType; name: string, fields: Snippet) =
## see `genRecordFieldsAux` for use
when buildNifc:
# XXX packed not implemented in nifc
obj.addTypedef(name):
obj.add(fields)
else:
obj.add("struct {\n")
body
obj.add("} ")
obj.add(fieldName)
obj.add(";\n")
if tfPacked in parentTyp.flags and hasAttribute notin CC[m.config.cCompiler].props:
obj.add("#pragma pack(pop)\n")
obj.add('\t')
if tfPacked in parentTyp.flags:
if hasAttribute in CC[m.config.cCompiler].props:
obj.add("typedef struct __attribute__((__packed__)) ")
else:
obj.add("#pragma pack(push, 1)\ntypedef struct ")
else:
obj.add("typedef struct ")
obj.add(name)
obj.add(" {\n")
obj.add(fields)
obj.add("} ")
obj.add(name)
obj.add(";\n")
if tfPacked in parentTyp.flags and hasAttribute notin CC[m.config.cCompiler].props:
obj.add("#pragma pack(pop)\n")

template addAnonUnion(obj: var Builder; body: typed) =
## adds an anonymous union i.e. `union { ... };` with fields according to `body`
Expand Down
14 changes: 9 additions & 5 deletions compiler/ccgtypes.nim
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,8 @@ proc genCppInitializer(m: BModule, prc: BProc; typ: PType; didGenTemp: var bool)
proc genRecordFieldsAux(m: BModule; n: PNode,
rectype: PType,
check: var IntSet; result: var Builder; unionPrefix = "") =
template maybeDotField(a, b: Snippet): Snippet =
if a.len != 0: dotField(a, b) else: b
case n.kind
of nkRecList:
for i in 0..<n.len:
Expand All @@ -688,12 +690,14 @@ proc genRecordFieldsAux(m: BModule; n: PNode,
of nkOfBranch, nkElse:
let k = lastSon(n[i])
if k.kind != nkSym:
let structName = "_" & mangleRecFieldName(m, n[0].sym) & "_" & $i
let fieldName = "_" & mangleRecFieldName(m, n[0].sym) & "_" & $i
var a = newBuilder("")
genRecordFieldsAux(m, k, rectype, check, a, unionPrefix & $structName & ".")
genRecordFieldsAux(m, k, rectype, check, a, maybeDotField(unionPrefix, $fieldName))
if a.buf.len != 0:
unionBody.addFieldWithStructType(m, rectype, structName):
unionBody.add(extract(a))
let tmp = getTempName(m)
let structName = tmp & "_" & fieldName & "_Struct"
m.s[cfsTypes].addFieldStruct(m, rectype, structName, extract(a))
unionBody.addField(name = fieldName, typ = structName)
else:
genRecordFieldsAux(m, k, rectype, check, unionBody, unionPrefix)
else: internalError(m.config, "genRecordFieldsAux(record case branch)")
Expand All @@ -706,7 +710,7 @@ proc genRecordFieldsAux(m: BModule; n: PNode,
if field.typ.kind == tyVoid: return
#assert(field.ast == nil)
let sname = mangleRecFieldName(m, field)
fillLoc(field.loc, locField, n, unionPrefix & sname, OnUnknown)
fillLoc(field.loc, locField, n, maybeDotField(unionPrefix, sname), OnUnknown)
# for importcpp'ed objects, we only need to set field.loc, but don't
# have to recurse via 'getTypeDescAux'. And not doing so prevents problems
# with heavily templatized C++ code:
Expand Down

0 comments on commit 55cba34

Please sign in to comment.