# # # The Nim Compiler # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. # ## Simple alias analysis for the HLO and the code generators. import ast, astalgo, types, trees import std/intsets when defined(nimPreviewSlimSystem): import std/assertions type TAnalysisResult* = enum arNo, arMaybe, arYes PartFlag* = enum pfStructural ## use structural prefix-chain detection and tree-walk pfBidirectional ## also check reverse direction per field in nkObjConstr proc isCompileTimeOnlyNode(n: PNode): bool {.inline.} = ## `typeof` and typedesc/static values describe types at compile time; they ## do not read the runtime location that alias analysis is protecting. n.kind == nkTypeOfExpr or (n.typ != nil and n.typ.isCompileTimeOnly) func sameLocation(a, b: PNode): bool = template sameConstIndex(a, b: PNode): bool = a.kind in nkLiterals and b.kind in nkLiterals and a.intVal == b.intVal var a = a var b = b while a.kind in {nkHiddenStdConv, nkHiddenSubConv, nkConv}: a = a[1] while b.kind in {nkHiddenStdConv, nkHiddenSubConv, nkConv}: b = b[1] if a.kind != b.kind: return false case a.kind of nkSym: result = a.sym.id == b.sym.id of nkDotExpr, nkCheckedFieldExpr: result = a[1].kind == nkSym and b[1].kind == nkSym and sameLocation(a[0], b[0]) and a[1].sym.id == b[1].sym.id of nkBracketExpr: result = sameLocation(a[0], b[0]) and sameConstIndex(a[1], b[1]) of nkObjUpConv, nkObjDownConv, nkDerefExpr, nkHiddenDeref: result = sameLocation(a[0], b[0]) else: result = false proc isAccessorPrefixOf(a, b: PNode): bool = var cur = b while cur.kind in {nkDotExpr, nkBracketExpr, nkCheckedFieldExpr, nkObjUpConv, nkObjDownConv, nkHiddenDeref, nkDerefExpr, nkHiddenStdConv, nkHiddenSubConv, nkConv}: if sameLocation(cur, a): return true case cur.kind of nkDotExpr, nkBracketExpr, nkCheckedFieldExpr, nkObjUpConv, nkObjDownConv, nkHiddenDeref, nkDerefExpr: cur = cur[0] of nkHiddenStdConv, nkHiddenSubConv, nkConv: cur = cur[1] else: discard result = sameLocation(cur, a) proc isPartOfAux(a, b: PType, marker: var IntSet): TAnalysisResult proc isPartOfAux(n: PNode, b: PType, marker: var IntSet): TAnalysisResult = result = arNo case n.kind of nkRecList: for i in 0..