diff options
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/ast.nim | 2 | ||||
-rw-r--r-- | compiler/c2nim/cparse.nim | 21 | ||||
-rw-r--r-- | compiler/ccgexprs.nim | 2 | ||||
-rw-r--r-- | compiler/ccgtypes.nim | 44 | ||||
-rw-r--r-- | compiler/condsyms.nim | 1 | ||||
-rw-r--r-- | compiler/pragmas.nim | 12 | ||||
-rw-r--r-- | compiler/wordrecg.nim | 4 |
7 files changed, 54 insertions, 32 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim index 61b8ca795..93630979b 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -488,6 +488,8 @@ const routineKinds* = {skProc, skMethod, skIterator, skConverter, skMacro, skTemplate} tfIncompleteStruct* = tfVarargs + tfUncheckedArray* = tfVarargs + tfUnion* = tfNoSideEffect skError* = skUnknown # type flags that are essential for type equality: diff --git a/compiler/c2nim/cparse.nim b/compiler/c2nim/cparse.nim index e4abe11a0..555e1af10 100644 --- a/compiler/c2nim/cparse.nim +++ b/compiler/c2nim/cparse.nim @@ -681,11 +681,6 @@ proc parseField(p: var TParser, kind: TNodeKind): PNode = else: result = mangledIdent(p.tok.s, p) getTok(p, result) -proc takeOnlyFirstField(p: TParser, isUnion: bool): bool = - # if we generate an interface to a header file, *all* fields can be - # generated: - result = isUnion and p.options.header.len == 0 - proc parseStructBody(p: var TParser, isUnion: bool, kind: TNodeKind = nkRecList): PNode = result = newNodeP(kind, p) @@ -698,8 +693,7 @@ proc parseStructBody(p: var TParser, isUnion: bool, var i = parseField(p, kind) t = parseTypeSuffix(p, t) addSon(def, i, t, ast.emptyNode) - if not takeOnlyFirstField(p, isUnion) or sonsLen(result) < 1: - addSon(result, def) + addSon(result, def) if p.tok.xkind != pxComma: break getTok(p, def) eat(p, pxSemicolon, lastSon(result)) @@ -710,11 +704,12 @@ proc structPragmas(p: TParser, name: PNode, origName: string): PNode = result = newNodeP(nkPragmaExpr, p) addSon(result, exportSym(p, name, origName)) var pragmas = newNodeP(nkPragma, p) - addSon(pragmas, newIdentNodeP("pure", p), newIdentNodeP("final", p)) + #addSon(pragmas, newIdentNodeP("pure", p), newIdentNodeP("final", p)) if p.options.header.len > 0: addSon(pragmas, newIdentStrLitPair("importc", origName, p), newIdentStrLitPair("header", p.options.header, p)) - addSon(result, pragmas) + if pragmas.len > 0: addSon(result, pragmas) + else: addSon(result, ast.emptyNode) proc enumPragmas(p: TParser, name: PNode): PNode = result = newNodeP(nkPragmaExpr, p) @@ -726,9 +721,13 @@ proc enumPragmas(p: TParser, name: PNode): PNode = addSon(pragmas, e) addSon(result, pragmas) -proc parseStruct(p: var TParser, isUnion: bool): PNode = +proc parseStruct(p: var TParser, isUnion: bool): PNode = result = newNodeP(nkObjectTy, p) - addSon(result, ast.emptyNode, ast.emptyNode) # no pragmas, no inheritance + var pragmas = ast.emptyNode + if isUnion: + pragmas = newNodeP(nkPragma, p) + addSon(pragmas, newIdentNodeP("union", p)) + addSon(result, pragmas, ast.emptyNode) # no inheritance if p.tok.xkind == pxCurlyLe: addSon(result, parseStructBody(p, isUnion)) else: diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index 8cb423688..40ebcbfa8 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -736,7 +736,7 @@ proc genArrayElem(p: BProc, e: PNode, d: var TLoc) = var ty = skipTypes(skipTypes(a.t, abstractVarRange), abstractPtrs) var first = intLiteral(firstOrd(ty)) # emit range check: - if (optBoundsCheck in p.options): + if optBoundsCheck in p.options and tfUncheckedArray notin ty.flags: if not isConstExpr(e.sons[1]): # semantic pass has already checked for const index expressions if firstOrd(ty) == 0: diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index 673e888fe..156ebee5e 100644 --- a/compiler/ccgtypes.nim +++ b/compiler/ccgtypes.nim @@ -376,10 +376,13 @@ proc getTypePre(m: BModule, typ: PType): PRope = else: result = getSimpleTypeDesc(m, typ) if result == nil: result = cacheGetType(m.typeCache, typ) - + +proc structOrUnion(t: PType): PRope = + (if tfUnion in t.flags: toRope("union") else: toRope("struct")) + proc getForwardStructFormat(): string = - if gCmd == cmdCompileToCpp: result = "struct $1;$n" - else: result = "typedef struct $1 $1;$n" + if gCmd == cmdCompileToCpp: result = "$1 $2;$n" + else: result = "typedef $1 $2 $2;$n" proc getTypeForward(m: BModule, typ: PType): PRope = result = cacheGetType(m.forwTypeCache, typ) @@ -390,7 +393,8 @@ proc getTypeForward(m: BModule, typ: PType): PRope = of tySequence, tyTuple, tyObject: result = getTypeName(typ) if not isImportedType(typ): - appf(m.s[cfsForwardTypes], getForwardStructFormat(), [result]) + appf(m.s[cfsForwardTypes], getForwardStructFormat(), + [structOrUnion(typ), result]) idTablePut(m.forwTypeCache, typ, result) else: internalError("getTypeForward(" & $typ.kind & ')') @@ -445,7 +449,12 @@ proc genRecordFieldsAux(m: BModule, n: PNode, if accessExpr != nil: ae = ropef("$1.$2", [accessExpr, sname]) else: ae = sname fillLoc(field.loc, locField, field.typ, ae, OnUnknown) - appf(result, "$1 $2;$n", [getTypeDescAux(m, field.loc.t, check), sname]) + let fieldType = field.loc.t + if fieldType.kind == tyArray and tfUncheckedArray in fieldType.flags: + appf(result, "$1 $2[SEQ_DECL_SIZE];$n", + [getTypeDescAux(m, fieldType.elemType, check), sname]) + else: + appf(result, "$1 $2;$n", [getTypeDescAux(m, fieldType, check), sname]) else: internalError(n.info, "genRecordFieldsAux()") proc getRecordFields(m: BModule, typ: PType, check: var TIntSet): PRope = @@ -455,23 +464,24 @@ proc getRecordDesc(m: BModule, typ: PType, name: PRope, check: var TIntSet): PRope = # declare the record: var hasField = false + let aStruct = structOrUnion(typ) if typ.kind == tyObject: if typ.sons[0] == nil: if (typ.sym != nil and sfPure in typ.sym.flags) or tfFinal in typ.flags: - result = ropecg(m, "struct $1 {$n", [name]) + result = ropecg(m, "$1 $2 {$n", [aStruct, name]) else: - result = ropecg(m, "struct $1 {$n#TNimType* m_type;$n", [name]) + result = ropecg(m, "$1 $2 {$n#TNimType* m_type;$n", [aStruct, name]) hasField = true elif gCmd == cmdCompileToCpp: - result = ropecg(m, "struct $1 : public $2 {$n", - [name, getTypeDescAux(m, typ.sons[0], check)]) + result = ropecg(m, "$1 $2 : public $3 {$n", + [aStruct, name, getTypeDescAux(m, typ.sons[0], check)]) hasField = true else: - result = ropecg(m, "struct $1 {$n $2 Sup;$n", - [name, getTypeDescAux(m, typ.sons[0], check)]) + result = ropecg(m, "$1 $2 {$n $3 Sup;$n", + [aStruct, name, getTypeDescAux(m, typ.sons[0], check)]) hasField = true else: - result = ropef("struct $1 {$n", [name]) + result = ropef("$1 $2 {$n", [aStruct, name]) var desc = getRecordFields(m, typ, check) if (desc == nil) and not hasField: appf(result, "char dummy;$n", []) @@ -480,8 +490,8 @@ proc getRecordDesc(m: BModule, typ: PType, name: PRope, app(result, "};" & tnl) proc getTupleDesc(m: BModule, typ: PType, name: PRope, - check: var TIntSet): PRope = - result = ropef("struct $1 {$n", [name]) + check: var TIntSet): PRope = + result = ropef("$1 $2 {$n", [structOrUnion(typ), name]) var desc: PRope = nil for i in countup(0, sonsLen(typ) - 1): appf(desc, "$1 Field$2;$n", @@ -557,7 +567,8 @@ proc getTypeDescAux(m: BModule, typ: PType, check: var TIntSet): PRope = if result == nil: result = getTypeName(t) if not isImportedType(t): - appf(m.s[cfsForwardTypes], getForwardStructFormat(), [result]) + appf(m.s[cfsForwardTypes], getForwardStructFormat(), + [structOrUnion(t), result]) idTablePut(m.forwTypeCache, t, result) assert(cacheGetType(m.typeCache, t) == nil) idTablePut(m.typeCache, t, con(result, "*")) @@ -588,7 +599,8 @@ proc getTypeDescAux(m: BModule, typ: PType, check: var TIntSet): PRope = if result == nil: result = getTypeName(t) if not isImportedType(t): - appf(m.s[cfsForwardTypes], getForwardStructFormat(), [result]) + appf(m.s[cfsForwardTypes], getForwardStructFormat(), + [structOrUnion(t), result]) idTablePut(m.forwTypeCache, t, result) idTablePut(m.typeCache, t, result) # always call for sideeffects: if t.kind != tyTuple: recdesc = getRecordDesc(m, t, result, check) diff --git a/compiler/condsyms.nim b/compiler/condsyms.nim index c79fda13e..ddf2075b4 100644 --- a/compiler/condsyms.nim +++ b/compiler/condsyms.nim @@ -47,6 +47,7 @@ proc initDefines*() = defineSymbol("nimeffects") defineSymbol("nimbabel") defineSymbol("nimcomputedgoto") + defineSymbol("nimunion") # add platform specific symbols: case targetCPU diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index 4304e5fb7..bf3564016 100644 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -50,9 +50,9 @@ const wDeprecated, wExtern, wThread, wImportCpp, wImportObjC, wAsmNoStackFrame, wRaises, wTags} typePragmas* = {wImportc, wExportc, wDeprecated, wMagic, wAcyclic, wNodecl, - wPure, wHeader, wCompilerproc, wFinal, wSize, wExtern, wShallow, + wPure, wHeader, wCompilerproc, wFinal, wSize, wExtern, wShallow, wImportCpp, wImportObjC, wError, wIncompleteStruct, wByCopy, wByRef, - wInheritable, wGensym, wInject, wRequiresInit} + wInheritable, wGensym, wInject, wRequiresInit, wUnchecked, wUnion} fieldPragmas* = {wImportc, wExportc, wDeprecated, wExtern, wImportCpp, wImportObjC, wError} varPragmas* = {wImportc, wExportc, wVolatile, wRegister, wThreadVar, wNodecl, @@ -718,6 +718,14 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int, noVal(it) if sym.typ == nil: invalidPragma(it) else: incl(sym.typ.flags, tfIncompleteStruct) + of wUnchecked: + noVal(it) + if sym.typ == nil: invalidPragma(it) + else: incl(sym.typ.flags, tfUncheckedArray) + of wUnion: + noVal(it) + if sym.typ == nil: invalidPragma(it) + else: incl(sym.typ.flags, tfUnion) of wRequiresInit: noVal(it) if sym.typ == nil: invalidPragma(it) diff --git a/compiler/wordrecg.nim b/compiler/wordrecg.nim index 1c8e4516c..f4a0c59f4 100644 --- a/compiler/wordrecg.nim +++ b/compiler/wordrecg.nim @@ -63,7 +63,7 @@ type wAcyclic, wShallow, wUnroll, wLinearScanEnd, wComputedGoto, wInjectStmt, wWrite, wGensym, wInject, wDirty, wInheritable, wThreadVar, wEmit, wAsmNoStackFrame, - wImplicitStatic, wGlobal, wCodegenDecl, + wImplicitStatic, wGlobal, wCodegenDecl, wUnchecked, wAuto, wBool, wCatch, wChar, wClass, wConst_cast, wDefault, wDelete, wDouble, wDynamic_cast, @@ -145,7 +145,7 @@ const "subschar", "acyclic", "shallow", "unroll", "linearscanend", "computedgoto", "injectstmt", "write", "gensym", "inject", "dirty", "inheritable", "threadvar", "emit", - "asmnostackframe", "implicitstatic", "global", "codegendecl", + "asmnostackframe", "implicitstatic", "global", "codegendecl", "unchecked", "auto", "bool", "catch", "char", "class", "const_cast", "default", "delete", "double", |