diff options
Diffstat (limited to 'compiler/cgendata.nim')
-rw-r--r-- | compiler/cgendata.nim | 55 |
1 files changed, 33 insertions, 22 deletions
diff --git a/compiler/cgendata.nim b/compiler/cgendata.nim index 3384558f8..5368e9dc7 100644 --- a/compiler/cgendata.nim +++ b/compiler/cgendata.nim @@ -10,13 +10,14 @@ ## This module contains the data structures for the C code generation phase. import - ast, ropes, options, intsets, - tables, ndi, lineinfos, pathutils, modulegraphs, sets + ast, ropes, options, + ndi, lineinfos, pathutils, modulegraphs + +import std/[intsets, tables, sets] type TLabel* = Rope # for the C generator a label is just a rope TCFileSection* = enum # the sections a generated C file consists of - cfsMergeInfo, # section containing merge information cfsHeaders, # section for C include file headers cfsFrameDefines # section for nim frame macros cfsForwardTypes, # section for C forward typedefs @@ -24,21 +25,17 @@ type cfsSeqTypes, # section for sequence types only # this is needed for strange type generation # reasons - cfsFieldInfo, # section for field information cfsTypeInfo, # section for type information (ag ABI checks) cfsProcHeaders, # section for C procs prototypes + cfsStrData, # section for constant string literals cfsData, # section for C constant data cfsVars, # section for C variable declarations cfsProcs, # section for C procs that are not inline cfsInitProc, # section for the C init proc cfsDatInitProc, # section for the C datInit proc cfsTypeInit1, # section 1 for declarations of type information - cfsTypeInit2, # section 2 for init of type information cfsTypeInit3, # section 3 for init of type information - cfsDebugInit, # section for init of debug information cfsDynLibInit, # section for init of dynamic library binding - cfsDynLibDeinit # section for deinitialization of dynamic - # libraries TCTypeKind* = enum # describes the type kind of a C type ctVoid, ctChar, ctBool, ctInt, ctInt8, ctInt16, ctInt32, ctInt64, @@ -91,6 +88,7 @@ type options*: TOptions # options that should be used for code # generation; this is the same as prc.options # unless prc == nil + optionsStack*: seq[(TOptions, TNoteKinds)] module*: BModule # used to prevent excessive parameter passing withinLoop*: int # > 0 if we are within a loop splitDecls*: int # > 0 if we are in some context for C++ that @@ -99,10 +97,11 @@ type withinTryWithExcept*: int # required for goto based exception handling withinBlockLeaveActions*: int # complex to explain sigConflicts*: CountTable[string] + inUncheckedAssignSection*: int TTypeSeq* = seq[PType] TypeCache* = Table[SigHash, Rope] - TypeCacheWithOwner* = Table[SigHash, tuple[str: Rope, owner: PSym]] + TypeCacheWithOwner* = Table[SigHash, tuple[str: Rope, owner: int32]] CodegenFlag* = enum preventStackTrace, # true if stack traces need to be prevented @@ -112,7 +111,8 @@ type isHeaderFile, # C source file is the header file includesStringh, # C source file already includes ``<string.h>`` objHasKidsValid # whether we can rely on tfObjHasKids - + useAliveDataFromDce # use the `alive: IntSet` field instead of + # computing alive data on our own. BModuleList* = ref object of RootObj mainModProcs*, mainModInit*, otherModsInit*, mainDatInit*: Rope @@ -122,6 +122,7 @@ type forwardedProcs*: seq[PSym] # proc:s that did not yet have a body generatedHeader*: BModule typeInfoMarker*: TypeCacheWithOwner + typeInfoMarkerV2*: TypeCacheWithOwner config*: ConfigRef graph*: ModuleGraph strVersion*, seqVersion*: int # version of the string/seq implementation to use @@ -136,6 +137,7 @@ type # unconditionally... # nimtvDeps is VERY hard to cache because it's # not a list of IDs nor can it be made to be one. + mangledPrcs*: HashSet[string] TCGen = object of PPassContext # represents a C source file s*: TCFileSections # sections of the C file @@ -149,12 +151,14 @@ type typeABICache*: HashSet[SigHash] # cache for ABI checks; reusing typeCache # would be ideal but for some reason enums # don't seem to get cached so it'd generate - # 1 ABI check per occurence in code + # 1 ABI check per occurrence in code forwTypeCache*: TypeCache # cache for forward declarations of types declaredThings*: IntSet # things we have declared in this .c file declaredProtos*: IntSet # prototypes we have declared in this .c file + alive*: IntSet # symbol IDs of alive data as computed by `dce.nim` headerFiles*: seq[string] # needed headers to include typeInfoMarker*: TypeCache # needed for generating type information + typeInfoMarkerV2*: TypeCache initProc*: BProc # code for init procedure preInitProc*: BProc # code executed before the init proc hcrCreateTypeInfosProc*: Rope # type info globals are in here when HCR=on @@ -166,13 +170,13 @@ type labels*: Natural # for generating unique module-scope names extensionLoaders*: array['0'..'9', Rope] # special procs for the # OpenGL wrapper - injectStmt*: Rope sigConflicts*: CountTable[SigHash] g*: BModuleList ndi*: NdiFile template config*(m: BModule): ConfigRef = m.g.config template config*(p: BProc): ConfigRef = p.module.g.config +template vccAndC*(p: BProc): bool = p.module.config.cCompiler == ccVcc and p.module.config.backend == backendC proc includeHeader*(this: BModule; header: string) = if not this.headerFiles.contains header: @@ -186,19 +190,26 @@ proc procSec*(p: BProc, s: TCProcSection): var Rope {.inline.} = # top level proc sections result = p.blocks[0].sections[s] +proc initBlock*(): TBlock = + result = TBlock() + for i in low(result.sections)..high(result.sections): + result.sections[i] = newRopeAppender() + proc newProc*(prc: PSym, module: BModule): BProc = - new(result) - result.prc = prc - result.module = module - result.options = if prc != nil: prc.options - else: module.config.options - newSeq(result.blocks, 1) - result.nestedTryStmts = @[] - result.finallySafePoints = @[] - result.sigConflicts = initCountTable[string]() + result = BProc( + prc: prc, + module: module, + optionsStack: if module.initProc != nil: module.initProc.optionsStack + else: @[], + options: if prc != nil: prc.options + else: module.config.options, + blocks: @[initBlock()], + sigConflicts: initCountTable[string]()) + if optQuirky in result.options: + result.flags = {nimErrorFlagDisabled} proc newModuleList*(g: ModuleGraph): BModuleList = - BModuleList(typeInfoMarker: initTable[SigHash, tuple[str: Rope, owner: PSym]](), + BModuleList(typeInfoMarker: initTable[SigHash, tuple[str: Rope, owner: int32]](), config: g.config, graph: g, nimtvDeclared: initIntSet()) iterator cgenModules*(g: BModuleList): BModule = |