This patch implements PR31013 by introducing a DIGlobalVariableExpression that holds a pair of DIGlobalVariable and DIExpression.
Currently, DIGlobalVariables holds a DIExpression. This is not the best way to model this:
- The DIGlobalVariable should describe the source level variable, not how to get to its location.
- It makes it unsafe/hard to update the expressions when we call replaceExpression on the DIGLobalVariable.
- It makes it impossible to represent a global variable that is in more than one location (e.g., a variable with multiple DW_OP_piece-s). We also moved away from attaching the DIExpression to DILocalVariable for the same reasons.
A better representation would be to add a DIGlobalVariableExpression(var: !DIGlobalVariable(...), expr: !DIExpression(...)) that wraps a global variable and an expression. For example, let's say we have a global symbol g that doesn't need an expression — this would still be represented as:
@g = global i32 0, !dbg !0 !0 = DIGlobalVariable(name: "g", ...)
Later, after some transformation, this becomes:
@opt_g = global i32 *, !dbg !1 !0 = distinct !DIGlobalVariable(name: "g", ...) ; Identical to !0 above. !1 = !DIGlobalVariableExpr(var: !0, expr: !2) ; Not distinct. !2 = !DIExpression(DW_OP_deref, ...)
This allows transformations to just add new mergeable metadata on top of the existing DIGlobalVariable without blowing up the representation if they aren't needed.
[reply] [-] Comment 1
For more discussion see https://llvm.org/bugs/show_bug.cgi?id=31013.
Usually best to make operators non-members where possible (helps with symmetric implicit conversions of LHS and RHS operands, for example). They can still be defined inline if you prefer - by declaring them as friends (which you probably want/need to do anyway)