I'm not sure if it answers your question, but here is how I would use the rudimentary TreeForm:
decompose[expr_?AtomQ] := expr decompose[expr_] := Block[{lev = Level[expr, {1}]}, Sow[Thread[expr -> lev]]; decompose /@ lev;] treeForm[expr_] := Reap[decompose[expr]][[-1, 1]] // Flatten
Then:
EDIT Yes, you're right, this is not a tree. To make this a tree, each expression must carry its position with it. It looks like this:
ClearAll[treePlot, node, decompose2]; SetAttributes[{treePlot, node, decompose2}, HoldAll]; decompose2[expr_] /; AtomQ[Unevaluated[expr]] := node[expr]; decompose2[expr_] := Module[{pos, list}, pos = SortBy[ Position[Unevaluated[expr], _, {0, Infinity}, Heads -> False], Length]; list = Extract[Unevaluated[expr], pos, node]; list = MapThread[Append, {list, pos}]; ReplaceList[ list, {___, node[e1_, p1_], ___, node[e2_, p2_], ___} /; Length[p2] == Length[p1] + 1 && Most[p2] == p1 :> (node[e1, p1] -> node[e2, p2])] ]
Then
treePlot2[expr_] := Module[{data = decompose2[a^2 + Subscript[b, 2] + 3 c], gr, vlbls}, gr = Graph[data]; vlbls = Table[vl -> (HoldForm @@ {vl[[1]]}), {vl, VertexList[gr]}]; Graph[data, VertexLabels -> vlbls, ImagePadding -> 50] ]