implemented alignas pragma (#12643)
* implemented alignas pragma * fix bootstrap * generate c++ compatible syntax for alignas * Make it work. * Multiple alignof expressions. Implement top level alignof.
This commit is contained in:
parent
84861eb48a
commit
0496a666e2
13 changed files with 153 additions and 19 deletions
|
|
@ -824,6 +824,7 @@ type
|
|||
of skLet, skVar, skField, skForVar:
|
||||
guard*: PSym
|
||||
bitsize*: int
|
||||
alignment*: int # for alignas(X) expressions
|
||||
else: nil
|
||||
magic*: TMagic
|
||||
typ*: PType
|
||||
|
|
|
|||
|
|
@ -549,6 +549,8 @@ proc genRecordFieldsAux(m: BModule, n: PNode,
|
|||
#assert(field.ast == nil)
|
||||
let sname = mangleRecFieldName(m, field)
|
||||
fillLoc(field.loc, locField, n, sname, OnUnknown)
|
||||
if field.alignment > 0:
|
||||
result.addf "alignas($1) ", [rope(field.alignment)]
|
||||
# for importcpp'ed objects, we only need to set field.loc, but don't
|
||||
# have to recurse via 'getTypeDescAux'. And not doing so prevents problems
|
||||
# with heavily templatized C++ code:
|
||||
|
|
|
|||
|
|
@ -478,7 +478,9 @@ proc localVarDecl(p: BProc; n: PNode): Rope =
|
|||
if s.loc.k == locNone:
|
||||
fillLoc(s.loc, locLocalVar, n, mangleLocalName(p, s), OnStack)
|
||||
if s.kind == skLet: incl(s.loc.flags, lfNoDeepCopy)
|
||||
result = getTypeDesc(p.module, s.typ)
|
||||
if s.kind in {skLet, skVar} and s.alignment > 0:
|
||||
result.addf("alignas($1) ", [rope(s.alignment)])
|
||||
result.add getTypeDesc(p.module, s.typ)
|
||||
if s.constraint.isNil:
|
||||
if sfRegister in s.flags: add(result, " register")
|
||||
#elif skipTypes(s.typ, abstractInst).kind in GcTypeKinds:
|
||||
|
|
@ -529,6 +531,8 @@ proc assignGlobalVar(p: BProc, n: PNode) =
|
|||
var decl: Rope = nil
|
||||
var td = getTypeDesc(p.module, s.loc.t)
|
||||
if s.constraint.isNil:
|
||||
if s.alignment > 0:
|
||||
decl.addf "alignas($1) ", [rope(s.alignment)]
|
||||
if p.hcrOn: add(decl, "static ")
|
||||
elif sfImportc in s.flags: add(decl, "extern ")
|
||||
add(decl, td)
|
||||
|
|
@ -1187,6 +1191,8 @@ proc genVarPrototype(m: BModule, n: PNode) =
|
|||
declareThreadVar(m, sym, true)
|
||||
else:
|
||||
incl(m.declaredThings, sym.id)
|
||||
if sym.alignment > 0:
|
||||
m.s[cfsVars].addf "alignas($1) ", [rope(sym.alignment)]
|
||||
add(m.s[cfsVars], if m.hcrOn: "static " else: "extern ")
|
||||
add(m.s[cfsVars], getTypeDesc(m, sym.loc.t))
|
||||
if m.hcrOn: add(m.s[cfsVars], "*")
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ const
|
|||
|
||||
const
|
||||
declPragmas = {wImportc, wImportObjC, wImportCpp, wImportJs, wExportc, wExportCpp,
|
||||
wExportNims, wExtern, wDeprecated, wNodecl, wError, wUsed}
|
||||
wExportNims, wExtern, wDeprecated, wNodecl, wError, wUsed, wAlignas}
|
||||
## common pragmas for declarations, to a good approximation
|
||||
procPragmas* = declPragmas + {FirstCallConv..LastCallConv,
|
||||
wMagic, wNoSideEffect, wSideEffect, wNoreturn, wDynlib, wHeader,
|
||||
|
|
@ -803,13 +803,6 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
|
|||
setExternName(c, sym, name, it.info)
|
||||
of wImportObjC:
|
||||
processImportObjC(c, sym, getOptionalStr(c, it, "$1"), it.info)
|
||||
of wAlign:
|
||||
if sym.typ == nil: invalidPragma(c, it)
|
||||
var align = expectIntLit(c, it)
|
||||
if (not isPowerOfTwo(align) and align != 0) or align >% high(int16):
|
||||
localError(c.config, it.info, "power of two expected")
|
||||
else:
|
||||
sym.typ.align = align.int16
|
||||
of wSize:
|
||||
if sym.typ == nil: invalidPragma(c, it)
|
||||
var size = expectIntLit(c, it)
|
||||
|
|
@ -822,6 +815,14 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
|
|||
sym.typ.align = floatInt64Align(c.config)
|
||||
else:
|
||||
localError(c.config, it.info, "size may only be 1, 2, 4 or 8")
|
||||
of wAlignas:
|
||||
let alignment = expectIntLit(c, it)
|
||||
if alignment == 0:
|
||||
discard
|
||||
elif isPowerOfTwo(alignment):
|
||||
sym.alignment = max(sym.alignment, alignment)
|
||||
else:
|
||||
localError(c.config, it.info, "power of two or 0 expected")
|
||||
of wNodecl:
|
||||
noVal(c, it)
|
||||
incl(sym.loc.flags, lfNoDecl)
|
||||
|
|
|
|||
|
|
@ -156,6 +156,8 @@ proc computeObjectOffsetsFoldFunction(conf: ConfigRef; n: PNode, packed: bool, a
|
|||
size = n.sym.typ.size.int
|
||||
align = if packed: 1 else: n.sym.typ.align.int
|
||||
accum.align(align)
|
||||
if n.sym.alignment > 0:
|
||||
accum.align(n.sym.alignment)
|
||||
n.sym.offset = accum.offset
|
||||
accum.inc(size)
|
||||
else:
|
||||
|
|
@ -183,6 +185,8 @@ proc computeUnionObjectOffsetsFoldFunction(conf: ConfigRef; n: PNode; accum: var
|
|||
size = n.sym.typ.size.int
|
||||
align = n.sym.typ.align.int
|
||||
accum.align(align)
|
||||
if n.sym.alignment > 0:
|
||||
accum.align(n.sym.alignment)
|
||||
n.sym.offset = accum.offset
|
||||
accum.inc(size)
|
||||
else:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue