mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-19 14:00:35 +00:00
cbuilder: implement designated initializers, finish default value braces (#24312)
follows up #24259
This is the remaining missing use of `StructInitializer` in
`getDefaultValue` after #24259 and #24302. The only remaining direct C
code in getDefaultValue is [this
line](922f7dfd71/compiler/ccgexprs.nim (L3525))
which creates a global array variable, which isn't implemented yet. Next
steps would be all remaining variable and `typedef` declarations, then
hopefully we can move on to general statements and expressions.
This commit is contained in:
@@ -77,9 +77,7 @@ type
|
||||
needsComma: bool
|
||||
|
||||
proc initStructInitializer(builder: var Builder, kind: StructInitializerKind): StructInitializer =
|
||||
## starts building a struct initializer, `orderCompliant = true` means
|
||||
## built fields must be ordered correctly
|
||||
assert kind != siNamedStruct, "named struct constructors unimplemented"
|
||||
## starts building a struct initializer, i.e. braced initializer list
|
||||
result = StructInitializer(kind: kind, needsComma: false)
|
||||
if kind != siWrapper:
|
||||
builder.add("{")
|
||||
@@ -100,7 +98,11 @@ template addField(builder: var Builder, constr: var StructInitializer, name: str
|
||||
assert name.len != 0, "name has to be given for struct initializer field"
|
||||
valueBody
|
||||
of siNamedStruct:
|
||||
assert false, "named struct constructors unimplemented"
|
||||
assert name.len != 0, "name has to be given for struct initializer field"
|
||||
builder.add(".")
|
||||
builder.add(name)
|
||||
builder.add(" = ")
|
||||
valueBody
|
||||
|
||||
proc finishStructInitializer(builder: var Builder, constr: StructInitializer) =
|
||||
## finishes building a struct initializer
|
||||
|
||||
@@ -3289,26 +3289,35 @@ proc getNullValueAux(p: BProc; t: PType; obj, constOrNil: PNode,
|
||||
break
|
||||
|
||||
let selectedBranch = caseObjDefaultBranch(obj, branch)
|
||||
# XXX siNamedStruct needs to be implemented to replace `res` here
|
||||
var res = "{"
|
||||
var branchInit: StructInitializer
|
||||
let b = lastSon(obj[selectedBranch])
|
||||
# designated initilization is the only way to init non first element of unions
|
||||
# branches are allowed to have no members (b.len == 0), in this case they don't need initializer
|
||||
var fieldName: string = ""
|
||||
if b.kind == nkRecList and not isEmptyCaseObjectBranch(b):
|
||||
res.add "._" & mangleRecFieldName(p.module, obj[0].sym) & "_" & $selectedBranch & " = "
|
||||
res.addStructInitializer(branchInit, kind = siOrderedStruct):
|
||||
getNullValueAux(p, t, b, constOrNil, res, branchInit, isConst, info)
|
||||
fieldName = "_" & mangleRecFieldName(p.module, obj[0].sym) & "_" & $selectedBranch
|
||||
result.addField(init, name = "<anonymous union>"):
|
||||
# XXX figure out name for the union, see use of `addAnonUnion`
|
||||
var branchInit: StructInitializer
|
||||
result.addStructInitializer(branchInit, kind = siNamedStruct):
|
||||
result.addField(branchInit, name = fieldName):
|
||||
var branchObjInit: StructInitializer
|
||||
result.addStructInitializer(branchObjInit, kind = siOrderedStruct):
|
||||
getNullValueAux(p, t, b, constOrNil, result, branchObjInit, isConst, info)
|
||||
elif b.kind == nkSym:
|
||||
res.add "." & mangleRecFieldName(p.module, b.sym) & " = "
|
||||
res.addStructInitializer(branchInit, kind = siWrapper):
|
||||
getNullValueAux(p, t, b, constOrNil, res, branchInit, isConst, info)
|
||||
fieldName = mangleRecFieldName(p.module, b.sym)
|
||||
result.addField(init, name = "<anonymous union>"):
|
||||
# XXX figure out name for the union, see use of `addAnonUnion`
|
||||
var branchInit: StructInitializer
|
||||
result.addStructInitializer(branchInit, kind = siNamedStruct):
|
||||
result.addField(branchInit, name = fieldName):
|
||||
# we need to generate the default value of the single sym,
|
||||
# to do this create a dummy wrapper initializer and recurse
|
||||
var branchFieldInit: StructInitializer
|
||||
result.addStructInitializer(branchFieldInit, kind = siWrapper):
|
||||
getNullValueAux(p, t, b, constOrNil, result, branchFieldInit, isConst, info)
|
||||
else:
|
||||
# no fields, don't initialize
|
||||
return
|
||||
result.addField(init, name = "<anonymous union>"):
|
||||
# XXX figure out name for the union, see use of `addAnonUnion`
|
||||
result.add res
|
||||
result.add "}"
|
||||
|
||||
of nkSym:
|
||||
let field = obj.sym
|
||||
|
||||
Reference in New Issue
Block a user