This commit is contained in:
Araq 2012-07-28 14:16:08 +02:00
commit 538b06a123
11 changed files with 114 additions and 39 deletions

View file

@ -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)