summaryrefslogtreecommitdiff
path: root/src/main/java/com/seaofnodes/simple/node/FldOffNode.java
blob: ef8949296349a63267e560ded4feb82386714d22 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
package com.seaofnodes.simple.node;

import com.seaofnodes.print.ExprPrinter;

import com.seaofnodes.simple.Parser;
import com.seaofnodes.simple.codegen.CodeGen;
import com.seaofnodes.simple.type.*;
import com.seaofnodes.simple.util.SB;
import com.seaofnodes.simple.util.Utils;
import java.util.HashMap;

/**
 * A field offset.  This becomes a constant *after* other optimizations which
 * determine field sizes - some fields might be dead, or hold only zeros or
 * small values.
 */

public class FldOffNode extends TypeNode {
    public final String _fname; // Field name
    public final Parser.Lexer _loc;   //
    public FldOffNode( Node base, String fname, Parser.Lexer loc ) { super(TypeInteger.BOT,base); _fname = fname; _loc=loc; }
    @Override public Tag serialTag() { throw Utils.TODO("should not reach here"); }

    @Override public String label() {
        return _fname == " len" ? "sizeof()" : "#"+_fname;
    }

    @Override protected ExprPrinter<Node> _print1(ExprPrinter<Node> p) {
        return p.p(label());
    }

    @Override public Type compute() {
        return Type.BOTTOM;
    }

    @Override public Node idealize() {
        // When base() gets typed, this xforms into a ConFldOffNode
        if( in(0)._type instanceof TypeMemPtr tmp )
            return new ConFldOffNode(tmp._obj,_fname);
        return null;
    }

    @Override public boolean eq(Node n) {
        FldOffNode off = (FldOffNode)n; // Invariant
        return _fname.equals(off._fname) && super.eq(n);
    }
    @Override int hash() { return super.hash() * _fname.hashCode(); }
}