FIR CFA: add a hack for enum classes and LL API
No clue what's going on there.
This commit is contained in:
+13
-6
@@ -434,15 +434,25 @@ class ControlFlowGraphBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun exitClass(): Pair<ClassExitNode?, ControlFlowGraph>? {
|
fun exitClass(): Pair<ClassExitNode?, ControlFlowGraph>? {
|
||||||
|
assert(currentGraph.kind == ControlFlowGraph.Kind.Class)
|
||||||
if (currentGraph.declaration == null) {
|
if (currentGraph.declaration == null) {
|
||||||
graphs.pop().also { assert(it.kind == ControlFlowGraph.Kind.Class) }
|
graphs.pop()
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
// Members of a class can be visited in any order, so data flow between them is unordered,
|
// Members of a class can be visited in any order, so data flow between them is unordered,
|
||||||
// and we have to recreate the control flow after the fact.
|
// and we have to recreate the control flow after the fact.
|
||||||
assert(currentGraph.kind == ControlFlowGraph.Kind.Class)
|
val enterNode = lastNodes.pop() as ClassEnterNode
|
||||||
val klass = currentGraph.declaration as FirClass
|
val exitNode = currentGraph.exitNode as ClassExitNode
|
||||||
|
val klass = enterNode.fir
|
||||||
|
if ((klass as FirControlFlowGraphOwner).controlFlowGraphReference != null) {
|
||||||
|
// TODO: IDE LL API sometimes attempts to analyze a enum class while already analyzing it, causing
|
||||||
|
// this graph to be built twice (or more). Not sure what this means. Nothing good, probably.
|
||||||
|
// In any case, attempting to add more edges to subgraphs will be fatal.
|
||||||
|
graphs.pop()
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
val calledInPlace = mutableListOf<ControlFlowGraph>()
|
val calledInPlace = mutableListOf<ControlFlowGraph>()
|
||||||
val calledLater = mutableListOf<ControlFlowGraph>()
|
val calledLater = mutableListOf<ControlFlowGraph>()
|
||||||
klass.forEachGraphOwner { member, isInPlace ->
|
klass.forEachGraphOwner { member, isInPlace ->
|
||||||
@@ -450,9 +460,6 @@ class ControlFlowGraphBuilder {
|
|||||||
if (isInPlace) calledInPlace.add(graph) else calledLater.add(graph)
|
if (isInPlace) calledInPlace.add(graph) else calledLater.add(graph)
|
||||||
}
|
}
|
||||||
|
|
||||||
val enterNode = lastNodes.pop() as ClassEnterNode
|
|
||||||
val exitNode = currentGraph.exitNode as ClassExitNode
|
|
||||||
|
|
||||||
// Classes are not initialized in place so no point in merging data flow - it will not be used.
|
// Classes are not initialized in place so no point in merging data flow - it will not be used.
|
||||||
val mergeDataFlow = klass is FirAnonymousObject && klass.classKind != ClassKind.ENUM_ENTRY
|
val mergeDataFlow = klass is FirAnonymousObject && klass.classKind != ClassKind.ENUM_ENTRY
|
||||||
val exitKind = if (mergeDataFlow) EdgeKind.Forward else EdgeKind.CfgForward
|
val exitKind = if (mergeDataFlow) EdgeKind.Forward else EdgeKind.CfgForward
|
||||||
|
|||||||
Reference in New Issue
Block a user