diff options
author | Juan M Gómez <info@jmgomez.me> | 2023-05-02 09:10:51 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-05-02 10:10:51 +0200 |
commit | 3e82a315fce0c0b11be5094092d8cf4b12b49299 (patch) | |
tree | db1e4e779ece482c1017b660ce422c0f05a3efe7 | |
parent | aec5a4c4744a81e19954daf330bafac948098835 (diff) | |
download | Nim-3e82a315fce0c0b11be5094092d8cf4b12b49299.tar.gz |
implements #21747 (#21748)
-rw-r--r-- | compiler/ccgtypes.nim | 60 | ||||
-rw-r--r-- | compiler/pragmas.nim | 2 |
2 files changed, 34 insertions, 28 deletions
diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index 9757f6aa9..adefffc8b 100644 --- a/compiler/ccgtypes.nim +++ b/compiler/ccgtypes.nim @@ -576,22 +576,11 @@ proc fillObjectFields*(m: BModule; typ: PType) = proc mangleDynLibProc(sym: PSym): Rope -proc getRecordDesc(m: BModule; typ: PType, name: Rope, - check: var IntSet): Rope = - # declare the record: - var hasField = false - - if tfPacked in typ.flags: - if hasAttribute in CC[m.config.cCompiler].props: - result = structOrUnion(typ) & " __attribute__((__packed__))" - else: - result = "#pragma pack(push, 1)\L" & structOrUnion(typ) - else: - result = structOrUnion(typ) - - result.add " " - result.add name - +template cgDeclFrmt*(s: PSym): string = + s.constraint.strVal + +proc getRecordDescAux(m: BModule; typ: PType, name, baseType: Rope, + check: var IntSet, hasField:var bool): Rope = if typ.kind == tyObject: if typ[0] == nil: if lacksMTypeField(typ): @@ -603,8 +592,7 @@ proc getRecordDesc(m: BModule; typ: PType, name: Rope, appcg(m, result, " {$n#TNimType* m_type;\n", []) hasField = true elif m.compileToCpp: - appcg(m, result, " : public $1 {\n", - [getTypeDescAux(m, typ[0].skipTypes(skipPtrs), check, skField)]) + appcg(m, result, " : public $1 {\n", [baseType]) if typ.isException and m.config.exc == excCpp: when false: appcg(m, result, "virtual void raise() { throw *this; }\n", []) # required for polymorphic exceptions @@ -616,18 +604,38 @@ proc getRecordDesc(m: BModule; typ: PType, name: Rope, appcg(m, cfsProcs, "inline $1::~$1() {if(this->raiseId) #popCurrentExceptionEx(this->raiseId);}\n", [name]) hasField = true else: - appcg(m, result, " {$n $1 Sup;\n", - [getTypeDescAux(m, typ[0].skipTypes(skipPtrs), check, skField)]) + appcg(m, result, " {$n $1 Sup;\n", [baseType]) hasField = true else: result.addf(" {\n", [name]) - let desc = getRecordFields(m, typ, check) - if desc == "" and not hasField: - result.addf("char dummy;\n", []) +proc getRecordDesc(m: BModule; typ: PType, name: Rope, + check: var IntSet): Rope = + # declare the record: + var hasField = false + var structOrUnion: string + if tfPacked in typ.flags: + if hasAttribute in CC[m.config.cCompiler].props: + structOrUnion = structOrUnion(typ) & " __attribute__((__packed__))" + else: + structOrUnion = "#pragma pack(push, 1)\L" & structOrUnion(typ) else: - result.add(desc) - result.add("};\L") + structOrUnion = structOrUnion(typ) + var baseType: string + if typ[0] != nil: + baseType = getTypeDescAux(m, typ[0].skipTypes(skipPtrs), check, skField) + if typ.sym == nil or typ.sym.constraint == nil: + result = structOrUnion & " " & name + result.add(getRecordDescAux(m, typ, name, baseType, check, hasField)) + let desc = getRecordFields(m, typ, check) + if desc == "" and not hasField: + result.addf("char dummy;\n", []) + else: + result.add(desc) + result.add("};\L") + else: + let desc = getRecordFields(m, typ, check) + result = runtimeFormat(typ.sym.cgDeclFrmt, [name, desc, baseType]) if tfPacked in typ.flags and hasAttribute notin CC[m.config.cCompiler].props: result.add "#pragma pack(pop)\L" @@ -956,8 +964,6 @@ proc finishTypeDescriptions(m: BModule) = inc(i) m.typeStack.setLen 0 -template cgDeclFrmt*(s: PSym): string = - s.constraint.strVal proc isReloadable(m: BModule; prc: PSym): bool = return m.hcrOn and sfNonReloadable notin prc.flags diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index 22677ba01..a91f359d5 100644 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -71,7 +71,7 @@ const wPure, wHeader, wCompilerProc, wCore, wFinal, wSize, wShallow, wIncompleteStruct, wCompleteStruct, wByCopy, wByRef, wInheritable, wGensym, wInject, wRequiresInit, wUnchecked, wUnion, wPacked, - wCppNonPod, wBorrow, wGcSafe, wPartial, wExplain, wPackage} + wCppNonPod, wBorrow, wGcSafe, wPartial, wExplain, wPackage, wCodegenDecl} fieldPragmas* = declPragmas + {wGuard, wBitsize, wCursor, wRequiresInit, wNoalias, wAlign} - {wExportNims, wNodecl} # why exclude these? varPragmas* = declPragmas + {wVolatile, wRegister, wThreadVar, |