Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cpp: remove this pragma, breaks codegen #398

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions compiler/ast/ast_types.nim
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,6 @@ const
sfWrittenTo* = sfBorrow ## param is assigned to
sfEscapes* = sfProcvar ## param escapes
sfBase* = sfDiscriminant
sfIsSelf* = sfOverriden ## param is 'self'
sfCustomPragma* = sfRegister ## symbol is custom pragma template

const
Expand Down Expand Up @@ -493,7 +492,6 @@ type
nfDotField ## the call can use a dot operator
nfDotSetter ## the call can use a setter dot operarator
nfExplicitCall ## `x.y()` was used instead of x.y
nfExprCall ## this is an attempt to call a regular expression
nfIsRef ## this node is a 'ref' node; used for the VM
nfIsPtr ## this node is a 'ptr' node; used for the VM
nfPreventCg ## this node should be ignored by the codegen
Expand Down
2 changes: 1 addition & 1 deletion compiler/ast/wordrecg.nim
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ type
wProtected = "protected", wPublic = "public", wRegister = "register",
wReinterpret_cast = "reinterpret_cast", wRestrict = "restrict", wShort = "short",
wSigned = "signed", wSizeof = "sizeof", wStatic_cast = "static_cast", wStruct = "struct",
wSwitch = "switch", wThis = "this", wThrow = "throw", wTrue = "true", wTypedef = "typedef",
wSwitch = "switch", wThrow = "throw", wTrue = "true", wTypedef = "typedef",
wTypeid = "typeid", wTypeof = "typeof", wTypename = "typename",
wUnion = "union", wPacked = "packed", wUnsigned = "unsigned", wVirtual = "virtual",
wVoid = "void", wVolatile = "volatile", wWchar_t = "wchar_t",
Expand Down
20 changes: 1 addition & 19 deletions compiler/sem/pragmas.nim
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ const
wDeprecated,
wFloatChecks, wInfChecks, wNanChecks, wPragma, wEmit, wUnroll,
wLinearScanEnd, wPatterns, wTrMacros, wEffects, wComputedGoto,
wExperimental, wThis, wUsed, wAssert}
wExperimental, wUsed, wAssert}
lambdaPragmas* = {FirstCallConv..LastCallConv,
wNoSideEffect, wSideEffect, wNoreturn, wNosinks, wDynlib, wHeader,
wThread, wAsmNoStackFrame,
Expand Down Expand Up @@ -1760,24 +1760,6 @@ proc prepareSinglePragma(
if not isTopLevel(c):
result = c.config.newError(it, reportSem rsemExperimentalRequiresToplevel)
result = processExperimental(c, it)
of wThis:
if it.kind in nkPragmaCallKinds and it.len == 2:
(c.selfName, result) = considerQuotedIdent(c, it[1])
if result == nil:
result = it
localReport(
c.config, n.info,
reportStr(rsemDeprecated, "'.this' pragma is deprecated"))
else:
it[1] = result # we retrieved it above from `it[1]`, so making sure return the same node
result = wrapError(c.config, it)
elif it.kind == nkIdent or it.len == 1:
c.selfName = getIdent(c.cache, "self")
localReport(
c.config, n.info,
reportStr(rsemDeprecated, "'.this' pragma is deprecated"))
else:
result = c.config.newError(it, reportSem rsemThisPragmaRequires01Args)
of wNoRewrite:
result = noVal(c, it)
of wBase:
Expand Down
27 changes: 4 additions & 23 deletions compiler/sem/semcall.nim
Original file line number Diff line number Diff line change
Expand Up @@ -311,20 +311,6 @@ proc resolveOverloads(c: PContext, n: PNode,

let overloadsState = result.state
if overloadsState != csMatch:
if c.p != nil and c.p.selfSym != nil:
# we need to enforce semchecking of selfSym again because it
# might need auto-deref:
var hiddenArg = newSymNode(c.p.selfSym)
hiddenArg.typ = nil
n.sons.insert(hiddenArg, 1)

pickBest(f)

if result.state != csMatch:
n.sons.delete(1)
excl n.flags, nfExprCall
else: return

template tryOp(x) =
let op = newIdentNode(getIdent(c.cache, x), n.info)
n[0] = op
Expand Down Expand Up @@ -368,15 +354,10 @@ proc resolveOverloads(c: PContext, n: PNode,

return
elif result.state != csMatch:
if nfExprCall in n.flags:
result.call = c.config.newError(
n, reportAst(rsemExpressionCannotBeCalled, n))

else:
if {nfDotField, nfDotSetter} * n.flags != {}:
# clean up the inserted ops
n.sons.delete(2)
n[0] = f
if {nfDotField, nfDotSetter} * n.flags != {}:
# clean up the inserted ops
n.sons.delete(2)
n[0] = f
return
if alt.state == csMatch and cmpCandidates(result, alt) == 0 and
not sameMethodDispatcher(result.calleeSym, alt.calleeSym):
Expand Down
17 changes: 8 additions & 9 deletions compiler/sem/semdata.nim
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ type
## statements
owner*: PSym ## the symbol this context belongs to
resultSym*: PSym ## the result symbol (if we are in a proc)
selfSym*: PSym ## the 'self' symbol (if available)
nestedLoopCounter*: int ## whether we are in a loop or not
nestedBlockCounter*: int ## whether we are in a block or not
next*: PProcCon ## used for stacking procedure contexts
Expand Down Expand Up @@ -355,14 +354,6 @@ type
# -------------------------------------------------------------------------
# start: module env; module lifetime
# -------------------------------------------------------------------------
selfName*: PIdent
## used for the experimental `this` pragma support (remove me!)
##
## written:
## - pragmas: `prepareSinglePragma` writes the name of the `this` param
## read:
## - seminst: `rawHandleSelf` reads the name of the `this` param
# xxx: remove the pragma features and this field

# lookups: imports / scopes
module*: PSym
Expand Down Expand Up @@ -766,6 +757,14 @@ proc popOwner*(c: PContext) =
proc lastOptionEntry*(c: PContext): POptionEntry =
result = c.optionStack[^1]

proc pushProcCon*(c: PContext, owner: PSym) {.inline.} =
c.config.internalAssert(owner != nil, "owner is nil")
var x: PProcCon
new(x)
x.owner = owner
x.next = c.p
c.p = x

proc popProcCon*(c: PContext) {.inline.} = c.p = c.p.next

proc put*(p: PProcCon; key, val: PSym) =
Expand Down
36 changes: 6 additions & 30 deletions compiler/sem/semexprs.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1134,9 +1134,10 @@ proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode =
# XXX: hmm, what kind of symbols will end up here?
# do we really need to try the overload resolution?
n[0] = prc
n.flags.incl nfExprCall
result = semOverloadedCallAnalyseEffects(c, n, flags)
if result == nil: return errorNode(c, n)

if result == nil:
return c.config.newError(n, reportAst(rsemExpressionCannotBeCalled, n))
elif result.kind notin nkCallKinds:
# the semExpr() in overloadedCallOpr can even break this condition!
# See bug #904 of how to trigger it:
Expand Down Expand Up @@ -1384,7 +1385,6 @@ proc semSym(c: PContext, n: PNode, sym: PSym, flags: TExprFlags): PNode =
# genericThatUsesLen(x) # marked as taking a closure?
if hasWarn(c.config, rsemResultUsed):
localReport(c.config, n, reportSem rsemResultUsed)

of skGenericParam:
onUse(n.info, s)
if s.typ.kind == tyStatic:
Expand All @@ -1403,36 +1403,12 @@ proc semSym(c: PContext, n: PNode, sym: PSym, flags: TExprFlags): PNode =
result = newSymNode(s, n.info)
result.typ = makeTypeDesc(c, s.typ)
of skField:
var p = c.p
while p != nil and p.selfSym == nil:
p = p.next
if p != nil and p.selfSym != nil:
var ty = skipTypes(p.selfSym.typ, {tyGenericInst, tyVar, tyLent, tyPtr, tyRef,
tyAlias, tySink, tyOwned})
while tfBorrowDot in ty.flags: ty = ty.skipTypes({tyDistinct, tyGenericInst, tyAlias})
var check: PNode = nil
if ty.kind == tyObject:
while true:
check = nil
let f = lookupInRecordAndBuildCheck(c, n, ty.n, s.name, check)
if f != nil and fieldVisible(c, f):
# is the access to a public field or in the same module or in a friend?
doAssert f == s
markUsed(c, n.info, f)
onUse(n.info, f)
result = newNodeIT(nkDotExpr, n.info, f.typ)
result.add makeDeref(newSymNode(p.selfSym))
result.add newSymNode(f) # we now have the correct field
if check != nil:
check[0] = result
check.typ = result.typ
result = check
return result
if ty[0] == nil: break
ty = skipTypes(ty[0], skipPtrs)
# old code, not sure if it's live code:
markUsed(c, n.info, s)
onUse(n.info, s)
if sfGenSym in s.flags:
# the owner should have been set by now by addParamOrResult
c.config.internalAssert s.owner != nil
result = newSymNode(s, n.info)
else:
if s.kind == skError and not s.ast.isNil and s.ast.kind == nkError:
Expand Down
46 changes: 1 addition & 45 deletions compiler/sem/seminst.nim
Original file line number Diff line number Diff line change
Expand Up @@ -10,49 +10,6 @@
## This module implements the instantiation of generic procs.
## included from sem.nim

proc addObjFieldsToLocalScope(c: PContext; n: PNode) =
template rec(n) = addObjFieldsToLocalScope(c, n)
case n.kind
of nkRecList:
for i in 0..<n.len:
rec n[i]
of nkRecCase:
if n.len > 0: rec n[0]
for i in 1..<n.len:
if n[i].kind in {nkOfBranch, nkElse}: rec lastSon(n[i])
of nkSym:
let f = n.sym
if f.kind == skField and fieldVisible(c, f):
c.currentScope.symbols.strTableIncl(f, onConflictKeepOld=true)
incl(f.flags, sfUsed)
# it is not an error to shadow fields via parameters
else: discard

proc rawPushProcCon(c: PContext, owner: PSym) =
var x: PProcCon
new(x)
x.owner = owner
x.next = c.p
c.p = x

proc rawHandleSelf(c: PContext; owner: PSym) =
const callableSymbols = {skProc, skFunc, skMethod, skConverter, skIterator, skMacro}
if c.selfName != nil and owner.kind in callableSymbols and owner.typ != nil:
let params = owner.typ.n
if params.len > 1:
let arg = params[1].sym
if arg.name.id == c.selfName.id:
c.p.selfSym = arg
arg.flags.incl sfIsSelf
var t = c.p.selfSym.typ.skipTypes(abstractPtrs)
while t.kind == tyObject:
addObjFieldsToLocalScope(c, t.n)
if t[0] == nil: break
t = t[0].skipTypes(skipPtrs)

proc pushProcCon*(c: PContext; owner: PSym) =
rawPushProcCon(c, owner)
rawHandleSelf(c, owner)

iterator instantiateGenericParamList(c: PContext, n: PNode, pt: TIdTable): PSym =
internalAssert(
Expand Down Expand Up @@ -405,7 +362,7 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
addDecl(c, s)
entry.concreteTypes[i] = s.typ
inc i
rawPushProcCon(c, result)
pushProcCon(c, result)
instantiateProcType(c, pt, result, info)
for j in 1..<result.typ.len:
entry.concreteTypes[i] = result.typ[j]
Expand All @@ -420,7 +377,6 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
# a ``compiles`` context but this is the lesser evil. See
# bug #1055 (tevilcompiles).
#if c.compilesContextId == 0:
rawHandleSelf(c, result)
entry.compilesId = c.compilesContextId
addToGenericProcCache(c, fn, entry)
c.generics.add(makeInstPair(fn, entry))
Expand Down
2 changes: 1 addition & 1 deletion tests/array/tarray.nim
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
discard """
joinable: false
target: "c cpp js"
target: "c !cpp js"
labels: "array"
description: '''
. From https://github.com/nim-lang/Nim/issues/1669
Expand Down
4 changes: 2 additions & 2 deletions tests/ccgbugs/tcodegen_anonymous_aggregate.nim
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
discard """
targets: "c cpp"
targets: "c !cpp"
labels: "atomics pragma union"
description: '''
. From https://github.com/nim-lang/Nim/issues/13062
C++ Atomics in union: ::<unnamed union>::<unnamed struct>::field
with constructor not allowed in anonymous aggregate
. The folloing compiles with C backend, but not with C++
. The following compiles with C backend, but not with C++
. Works in Nim 1.2.6 and above
'''
"""
Expand Down
2 changes: 1 addition & 1 deletion tests/collections/ttables.nim
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ And we get here
3
'''
joinable: false
targets: "c cpp js"
targets: "c !cpp js"
"""

# xxx wrap in a template to test in VM, see https://github.com/timotheecour/Nim/issues/534#issuecomment-769565033
Expand Down
1 change: 1 addition & 0 deletions tests/cpp/temitlist.nim
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ discard """
output: '''
6.0
0'''
knownIssue: "Broken from this pragma removal"
disabled: "windows" # pending bug #18011
"""

Expand Down
20 changes: 9 additions & 11 deletions tests/destructor/tcustomstrings.nim
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ after 20 20'''
joinable: false
"""

{.this: self.}

type
mystring = object
len, cap: int
Expand Down Expand Up @@ -51,7 +49,7 @@ proc resize(self: var mystring) =
if self.cap == 0: self.cap = 8
else: self.cap = (self.cap * 3) shr 1
if self.data == nil: inc allocCount
self.data = cast[type(data)](realloc(self.data, self.cap + 1))
self.data = cast[type(self.data)](realloc(self.data, self.cap + 1))

proc add*(self: var mystring; c: char) =
if self.len >= self.cap: resize(self)
Expand All @@ -60,17 +58,17 @@ proc add*(self: var mystring; c: char) =
inc self.len

proc ensure(self: var mystring; newLen: int) =
if newLen >= cap:
cap = max((cap * 3) shr 1, newLen)
if cap > 0:
if data == nil: inc allocCount
data = cast[type(data)](realloc(data, cap + 1))
if newLen >= self.cap:
self.cap = max((self.cap * 3) shr 1, newLen)
if self.cap > 0:
if self.data == nil: inc allocCount
self.data = cast[type(self.data)](realloc(self.data, self.cap + 1))

proc add*(self: var mystring; y: mystring) =
let newLen = len + y.len
let newLen = self.len + y.len
ensure(self, newLen)
copyMem(addr data[len], y.data, y.data.len + 1)
len = newLen
copyMem(addr self.data[self.len], y.data, y.data.len + 1)
self.len = newLen

proc create*(lit: string): mystring =
let newLen = lit.len
Expand Down
2 changes: 1 addition & 1 deletion tests/float/tfloatmod.nim
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
discard """
targets: "c cpp js"
targets: "c !cpp js"
output: "ok"
exitcode: "0"
"""
Expand Down
2 changes: 1 addition & 1 deletion tests/float/tfloats.nim
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
discard """
matrix: "-d:nimPreviewFloatRoundtrip; -u:nimPreviewFloatRoundtrip"
targets: "c cpp js"
targets: "c !cpp js"
"""

#[
Expand Down
6 changes: 3 additions & 3 deletions tests/lang/s05_pragmas/s02_misc/t06_union_pragma.nim
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ targets: "!js !vm"
"""

block union_pragma:
## The union pragma can be applied to any object type. It means all of the object's
## fields are overlaid in memory.This produces a union instead of a struct in the
## generated C/C++ code.
## The union pragma can be applied to any object type. It means all of the
## object's fields are overlaid in memory. This produces a union instead of a
## struct in the generated C/C++ code.
type
Union {.union.} = object
field1: int
Expand Down
2 changes: 1 addition & 1 deletion tests/misc/treservedcidentsasfields.nim
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
discard """
targets: "c cpp"
targets: "c !cpp"
"""

import macros
Expand Down
Loading