mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-18 05:20:31 +00:00
* Expands codegenDecl to work in function params. fixes #22306 * makes the test more concrete so T{lit} params dont match * adds sfCodegenDecl
This commit is contained in:
@@ -314,6 +314,7 @@ type
|
||||
# an infinite loop, this flag is used as a sentinel to stop it.
|
||||
sfVirtual # proc is a C++ virtual function
|
||||
sfByCopy # param is marked as pass bycopy
|
||||
sfCodegenDecl # type, proc, global or proc param is marked as codegenDecl
|
||||
|
||||
TSymFlags* = set[TSymFlag]
|
||||
|
||||
|
||||
@@ -483,6 +483,9 @@ proc multiFormat*(frmt: var string, chars : static openArray[char], args: openAr
|
||||
res.add(substr(frmt, start, i - 1))
|
||||
frmt = res
|
||||
|
||||
template cgDeclFrmt*(s: PSym): string =
|
||||
s.constraint.strVal
|
||||
|
||||
proc genMemberProcParams(m: BModule; prc: PSym, superCall, rettype, params: var string,
|
||||
check: var IntSet, declareEnvironment=true;
|
||||
weakDep=false;) =
|
||||
@@ -535,7 +538,10 @@ proc genMemberProcParams(m: BModule; prc: PSym, superCall, rettype, params: var
|
||||
name = param.loc.r
|
||||
types.add typ
|
||||
names.add name
|
||||
args.add types[^1] & " " & names[^1]
|
||||
if sfCodegenDecl notin param.flags:
|
||||
args.add types[^1] & " " & names[^1]
|
||||
else:
|
||||
args.add runtimeFormat(param.cgDeclFrmt, [types[^1], names[^1]])
|
||||
|
||||
multiFormat(params, @['\'', '#'], [types, names])
|
||||
multiFormat(superCall, @['\'', '#'], [types, names])
|
||||
@@ -570,19 +576,24 @@ proc genProcParams(m: BModule; t: PType, rettype, params: var Rope,
|
||||
fillParamName(m, param)
|
||||
fillLoc(param.loc, locParam, t.n[i],
|
||||
param.paramStorageLoc)
|
||||
var typ: Rope
|
||||
if ccgIntroducedPtr(m.config, param, t[0]) and descKind == dkParam:
|
||||
params.add(getTypeDescWeak(m, param.typ, check, descKind))
|
||||
params.add("*")
|
||||
typ = (getTypeDescWeak(m, param.typ, check, descKind))
|
||||
typ.add("*")
|
||||
incl(param.loc.flags, lfIndirect)
|
||||
param.loc.storage = OnUnknown
|
||||
elif weakDep:
|
||||
params.add(getTypeDescWeak(m, param.typ, check, descKind))
|
||||
typ = (getTypeDescWeak(m, param.typ, check, descKind))
|
||||
else:
|
||||
params.add(getTypeDescAux(m, param.typ, check, descKind))
|
||||
params.add(" ")
|
||||
typ = (getTypeDescAux(m, param.typ, check, descKind))
|
||||
typ.add(" ")
|
||||
if sfNoalias in param.flags:
|
||||
params.add("NIM_NOALIAS ")
|
||||
params.add(param.loc.r)
|
||||
typ.add("NIM_NOALIAS ")
|
||||
if sfCodegenDecl notin param.flags:
|
||||
params.add(typ)
|
||||
params.add(param.loc.r)
|
||||
else:
|
||||
params.add runtimeFormat(param.cgDeclFrmt, [typ, param.loc.r])
|
||||
# declare the len field for open arrays:
|
||||
var arr = param.typ.skipTypes({tyGenericInst})
|
||||
if arr.kind in {tyVar, tyLent, tySink}: arr = arr.lastSon
|
||||
@@ -721,9 +732,6 @@ proc fillObjectFields*(m: BModule; typ: PType) =
|
||||
discard getRecordFields(m, typ, check)
|
||||
|
||||
proc mangleDynLibProc(sym: PSym): Rope
|
||||
|
||||
template cgDeclFrmt*(s: PSym): string =
|
||||
s.constraint.strVal
|
||||
|
||||
proc getRecordDescAux(m: BModule; typ: PType, name, baseType: Rope,
|
||||
check: var IntSet, hasField:var bool): Rope =
|
||||
@@ -770,7 +778,7 @@ proc getRecordDesc(m: BModule; typ: PType, name: Rope,
|
||||
var baseType: string
|
||||
if typ[0] != nil:
|
||||
baseType = getTypeDescAux(m, typ[0].skipTypes(skipPtrs), check, dkField)
|
||||
if typ.sym == nil or typ.sym.constraint == nil:
|
||||
if typ.sym == nil or sfCodegenDecl notin typ.sym.flags:
|
||||
result = structOrUnion & " " & name
|
||||
result.add(getRecordDescAux(m, typ, name, baseType, check, hasField))
|
||||
let desc = getRecordFields(m, typ, check)
|
||||
@@ -1198,7 +1206,7 @@ proc genProcHeader(m: BModule; prc: PSym; result: var Rope; asPtr: bool = false)
|
||||
name.add("_actual")
|
||||
# careful here! don't access ``prc.ast`` as that could reload large parts of
|
||||
# the object graph!
|
||||
if prc.constraint.isNil:
|
||||
if sfCodegenDecl notin prc.flags:
|
||||
if lfExportLib in prc.loc.flags:
|
||||
if isHeaderFile in m.flags:
|
||||
result.add "N_LIB_IMPORT "
|
||||
|
||||
@@ -590,7 +590,7 @@ proc localVarDecl(p: BProc; n: PNode): Rope =
|
||||
genCLineDir(result, p, n.info, p.config)
|
||||
|
||||
result.add getTypeDesc(p.module, s.typ, dkVar)
|
||||
if s.constraint.isNil:
|
||||
if sfCodegenDecl notin s.flags:
|
||||
if sfRegister in s.flags: result.add(" register")
|
||||
#elif skipTypes(s.typ, abstractInst).kind in GcTypeKinds:
|
||||
# decl.add(" GC_GUARD")
|
||||
@@ -621,7 +621,7 @@ proc treatGlobalDifferentlyForHCR(m: BModule, s: PSym): bool =
|
||||
|
||||
proc genGlobalVarDecl(p: BProc, n: PNode; td, value: Rope; decl: var Rope) =
|
||||
let s = n.sym
|
||||
if s.constraint.isNil:
|
||||
if sfCodegenDecl notin s.flags:
|
||||
if s.kind in {skLet, skVar, skField, skForVar} and s.alignment > 0:
|
||||
decl.addf "NIM_ALIGN($1) ", [rope(s.alignment)]
|
||||
if p.hcrOn: decl.add("static ")
|
||||
|
||||
@@ -84,7 +84,7 @@ const
|
||||
wGensym, wInject,
|
||||
wIntDefine, wStrDefine, wBoolDefine, wDefine,
|
||||
wCompilerProc, wCore}
|
||||
paramPragmas* = {wNoalias, wInject, wGensym, wByRef, wByCopy}
|
||||
paramPragmas* = {wNoalias, wInject, wGensym, wByRef, wByCopy, wCodegenDecl}
|
||||
letPragmas* = varPragmas
|
||||
procTypePragmas* = {FirstCallConv..LastCallConv, wVarargs, wNoSideEffect,
|
||||
wThread, wRaises, wEffectsOf, wLocks, wTags, wForbids, wGcSafe,
|
||||
@@ -253,6 +253,7 @@ proc processVirtual(c: PContext, n: PNode, s: PSym) =
|
||||
|
||||
proc processCodegenDecl(c: PContext, n: PNode, sym: PSym) =
|
||||
sym.constraint = getStrLitNode(c, n)
|
||||
sym.flags.incl sfCodegenDecl
|
||||
|
||||
proc processMagic(c: PContext, n: PNode, s: PSym) =
|
||||
#if sfSystemModule notin c.module.flags:
|
||||
|
||||
@@ -1356,7 +1356,9 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode,
|
||||
let finalType = if lifted != nil: lifted else: typ.skipIntLit(c.idgen)
|
||||
arg.typ = finalType
|
||||
arg.position = counter
|
||||
arg.constraint = constraint
|
||||
if constraint != nil:
|
||||
#only replace the constraint when it has been set as arg could contain codegenDecl
|
||||
arg.constraint = constraint
|
||||
inc(counter)
|
||||
if def != nil and def.kind != nkEmpty:
|
||||
arg.ast = copyTree(def)
|
||||
|
||||
@@ -2432,7 +2432,7 @@ proc matchesAux(c: PContext, n, nOrig: PNode, m: var TCandidate, marker: var Int
|
||||
return
|
||||
|
||||
template checkConstraint(n: untyped) {.dirty.} =
|
||||
if not formal.constraint.isNil:
|
||||
if not formal.constraint.isNil and sfCodegenDecl notin formal.flags:
|
||||
if matchNodeKinds(formal.constraint, n):
|
||||
# better match over other routines with no such restriction:
|
||||
inc(m.genericMatches, 100)
|
||||
|
||||
17
tests/cpp/tcodegendecl.nim
Normal file
17
tests/cpp/tcodegendecl.nim
Normal file
@@ -0,0 +1,17 @@
|
||||
discard """
|
||||
targets: "cpp"
|
||||
cmd: "nim cpp $file"
|
||||
output: "3"
|
||||
"""
|
||||
|
||||
{.emit:"""/*TYPESECTION*/
|
||||
int operate(int x, int y, int (*func)(const int&, const int&)){
|
||||
return func(x, y);
|
||||
};
|
||||
""".}
|
||||
|
||||
proc operate(x, y: int32, fn: proc(x, y: int32 ): int32 {.cdecl.}): int32 {.importcpp:"$1(@)".}
|
||||
|
||||
proc add(a {.codegenDecl:"const $#& $#".}, b {.codegenDecl:"const $# $#", byref.}: int32): int32 {.cdecl.} = a + b
|
||||
|
||||
echo operate(1, 2, add)
|
||||
Reference in New Issue
Block a user