implements #173
This commit is contained in:
parent
2ff8d17369
commit
538b06a123
11 changed files with 114 additions and 39 deletions
|
|
@ -22,6 +22,9 @@ when options.hasTinyCBackend:
|
|||
proc cgenPass*(): TPass
|
||||
# implementation
|
||||
|
||||
var
|
||||
generatedHeader: BModule
|
||||
|
||||
proc ropeff(cformat, llvmformat: string, args: openarray[PRope]): PRope =
|
||||
if gCmd == cmdCompileToLLVM: result = ropef(llvmformat, args)
|
||||
else: result = ropef(cformat, args)
|
||||
|
|
@ -721,7 +724,7 @@ proc genProcNoForward(m: BModule, prc: PSym) =
|
|||
# dependency to a compilerproc:
|
||||
discard cgsym(m, prc.name.s)
|
||||
return
|
||||
genProcPrototype(m, prc)
|
||||
genProcPrototype(m, prc)
|
||||
if lfNoDecl in prc.loc.Flags: nil
|
||||
elif prc.typ.callConv == ccInline:
|
||||
# We add inline procs to the calling module to enable C based inlining.
|
||||
|
|
@ -754,16 +757,26 @@ proc requestConstImpl(p: BProc, sym: PSym) =
|
|||
# declare header:
|
||||
if q != m and not ContainsOrIncl(m.declaredThings, sym.id):
|
||||
assert(sym.loc.r != nil)
|
||||
appf(m.s[cfsData], "extern NIM_CONST $1 $2;$n",
|
||||
let headerDecl = ropef("extern NIM_CONST $1 $2;$n",
|
||||
[getTypeDesc(m, sym.loc.t), sym.loc.r])
|
||||
app(m.s[cfsData], headerDecl)
|
||||
if sfExportc in sym.flags and generatedHeader != nil:
|
||||
app(generatedHeader.s[cfsData], headerDecl)
|
||||
|
||||
proc genProc(m: BModule, prc: PSym) =
|
||||
if sfBorrow in prc.flags: return
|
||||
fillProcLoc(prc)
|
||||
if {sfForward, sfFromGeneric} * prc.flags != {}: addForwardedProc(m, prc)
|
||||
else: genProcNoForward(m, prc)
|
||||
|
||||
proc genVarPrototype(m: BModule, sym: PSym) =
|
||||
else:
|
||||
genProcNoForward(m, prc)
|
||||
if {sfExportc, sfCompilerProc} * prc.flags == {sfExportc} and
|
||||
generatedHeader != nil and lfNoDecl notin prc.loc.Flags:
|
||||
genProcPrototype(generatedHeader, prc)
|
||||
if prc.typ.callConv == ccInline:
|
||||
if not ContainsOrIncl(generatedHeader.declaredThings, prc.id):
|
||||
genProcAux(generatedHeader, prc)
|
||||
|
||||
proc genVarPrototypeAux(m: BModule, sym: PSym) =
|
||||
assert(sfGlobal in sym.flags)
|
||||
useHeader(m, sym)
|
||||
fillLoc(sym.loc, locGlobalVar, sym.typ, mangleName(sym), OnHeap)
|
||||
|
|
@ -782,27 +795,14 @@ proc genVarPrototype(m: BModule, sym: PSym) =
|
|||
if sfVolatile in sym.flags: app(m.s[cfsVars], " volatile")
|
||||
appf(m.s[cfsVars], " $1;$n", [sym.loc.r])
|
||||
|
||||
proc getFileHeader(cfilenoext: string): PRope =
|
||||
if optCompileOnly in gGlobalOptions:
|
||||
result = ropeff("/* Generated by Nimrod Compiler v$1 */$n" &
|
||||
"/* (c) 2012 Andreas Rumpf */$n",
|
||||
"; Generated by Nimrod Compiler v$1$n" &
|
||||
"; (c) 2012 Andreas Rumpf$n", [toRope(versionAsString)])
|
||||
else:
|
||||
result = ropeff("/* Generated by Nimrod Compiler v$1 */$n" &
|
||||
"/* (c) 2012 Andreas Rumpf */$n" &
|
||||
"/* Compiled for: $2, $3, $4 */$n" &
|
||||
"/* Command for C compiler:$n $5 */$n",
|
||||
"; Generated by Nimrod Compiler v$1$n" &
|
||||
"; (c) 2012 Andreas Rumpf$n" &
|
||||
"; Compiled for: $2, $3, $4$n" &
|
||||
"; Command for LLVM compiler:$n $5$n", [toRope(versionAsString),
|
||||
toRope(platform.OS[targetOS].name),
|
||||
toRope(platform.CPU[targetCPU].name),
|
||||
toRope(extccomp.CC[extccomp.ccompiler].name),
|
||||
toRope(getCompileCFileCmd(cfilenoext))])
|
||||
proc genVarPrototype(m: BModule, sym: PSym) =
|
||||
genVarPrototypeAux(m, sym)
|
||||
if sfExportc in sym.flags and generatedHeader != nil:
|
||||
genVarPrototypeAux(generatedHeader, sym)
|
||||
|
||||
proc addIntTypes(result: var PRope) =
|
||||
case platform.CPU[targetCPU].intSize
|
||||
of 16:
|
||||
of 16:
|
||||
appff(result,
|
||||
"$ntypedef short int NI;$n" & "typedef unsigned short int NU;$n",
|
||||
"$n%NI = type i16$n", [])
|
||||
|
|
@ -813,8 +813,33 @@ proc getFileHeader(cfilenoext: string): PRope =
|
|||
of 64:
|
||||
appff(result, "$ntypedef long long int NI;$n" &
|
||||
"typedef unsigned long long int NU;$n", "$n%NI = type i64$n", [])
|
||||
else: nil
|
||||
|
||||
proc getCopyright(cfilenoext: string): PRope =
|
||||
if optCompileOnly in gGlobalOptions:
|
||||
result = ropeff("/* Generated by Nimrod Compiler v$1 */$n" &
|
||||
"/* (c) 2012 Andreas Rumpf */$n" &
|
||||
"/* The generated code is subject to the original license. */$n",
|
||||
"; Generated by Nimrod Compiler v$1$n" &
|
||||
"; (c) 2012 Andreas Rumpf$n", [toRope(versionAsString)])
|
||||
else:
|
||||
nil
|
||||
result = ropeff("/* Generated by Nimrod Compiler v$1 */$n" &
|
||||
"/* (c) 2012 Andreas Rumpf */$n" &
|
||||
"/* The generated code is subject to the original license. */$n" &
|
||||
"/* Compiled for: $2, $3, $4 */$n" &
|
||||
"/* Command for C compiler:$n $5 */$n",
|
||||
"; Generated by Nimrod Compiler v$1$n" &
|
||||
"; (c) 2012 Andreas Rumpf$n" &
|
||||
"; Compiled for: $2, $3, $4$n" &
|
||||
"; Command for LLVM compiler:$n $5$n", [toRope(versionAsString),
|
||||
toRope(platform.OS[targetOS].name),
|
||||
toRope(platform.CPU[targetCPU].name),
|
||||
toRope(extccomp.CC[extccomp.ccompiler].name),
|
||||
toRope(getCompileCFileCmd(cfilenoext))])
|
||||
|
||||
proc getFileHeader(cfilenoext: string): PRope =
|
||||
result = getCopyright(cfilenoext)
|
||||
addIntTypes(result)
|
||||
|
||||
proc genMainProc(m: BModule) =
|
||||
const
|
||||
|
|
@ -1008,6 +1033,31 @@ proc newModule(module: PSym, filename: string): BModule =
|
|||
|
||||
proc myOpen(module: PSym, filename: string): PPassContext =
|
||||
result = newModule(module, filename)
|
||||
if optGenIndex in gGlobalOptions and generatedHeader == nil:
|
||||
let f = if headerFile.len > 0: headerFile else: gProjectFull
|
||||
generatedHeader = rawNewModule(module,
|
||||
changeFileExt(completeCFilePath(f), hExt))
|
||||
generatedHeader.isHeaderFile = true
|
||||
|
||||
proc writeHeader(m: BModule) =
|
||||
var result = getCopyright(m.filename)
|
||||
var guard = ropef("__$1__", m.filename.splitFile.name.toRope)
|
||||
result.appf("#ifndef $1$n#define $1$n", guard)
|
||||
addIntTypes(result)
|
||||
generateHeaders(m)
|
||||
|
||||
generateThreadLocalStorage(m)
|
||||
for i in countup(cfsHeaders, cfsProcs):
|
||||
app(result, genSectionStart(i))
|
||||
app(result, m.s[i])
|
||||
app(result, genSectionEnd(i))
|
||||
app(result, m.s[cfsInitProc])
|
||||
|
||||
if optGenDynLib in gGlobalOptions:
|
||||
result.app("N_LIB_IMPORT ")
|
||||
result.appf("N_CDECL(void, NimMain)(void);$n")
|
||||
result.appf("#endif /* $1 */$n", guard)
|
||||
writeRope(result, m.filename)
|
||||
|
||||
proc getCFile(m: BModule): string =
|
||||
result = changeFileExt(completeCFilePath(m.cfilename), cExt)
|
||||
|
|
@ -1106,12 +1156,14 @@ proc myClose(b: PPassContext, n: PNode): PNode =
|
|||
# we need to process the transitive closure because recursive module
|
||||
# deps are allowed (and the system module is processed in the wrong
|
||||
# order anyway)
|
||||
if generatedHeader != nil: finishModule(generatedHeader)
|
||||
while gForwardedProcsCounter > 0:
|
||||
for i in countup(0, high(gModules)):
|
||||
finishModule(gModules[i])
|
||||
for i in countup(0, high(gModules)):
|
||||
writeModule(gModules[i], pending=true)
|
||||
writeMapping(gMapping)
|
||||
if generatedHeader != nil: writeHeader(generatedHeader)
|
||||
|
||||
proc cgenPass(): TPass =
|
||||
initPass(result)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue