+static /*@observer@*/ cstring stateAction_unparse (stateAction sa)
+{
+ switch (sa)
+ {
+ case SA_UNKNOWN: return cstring_makeLiteralTemp ("changed <unknown modification>");
+ case SA_CHANGED: return cstring_makeLiteralTemp ("changed");
+
+ case SA_CREATED: return cstring_makeLiteralTemp ("created");
+ case SA_DECLARED: return cstring_makeLiteralTemp ("declared");
+ case SA_DEFINED: return cstring_makeLiteralTemp ("defined");
+ case SA_PDEFINED: return cstring_makeLiteralTemp ("partially defined");
+ case SA_RELEASED: return cstring_makeLiteralTemp ("released");
+ case SA_ALLOCATED: return cstring_makeLiteralTemp ("allocated");
+ case SA_KILLED: return cstring_makeLiteralTemp ("released");
+ case SA_PKILLED: return cstring_makeLiteralTemp ("possibly released");
+ case SA_MERGED: return cstring_makeLiteralTemp ("merged");
+ case SA_UNDEFINED: return cstring_makeLiteralTemp ("becomes undefined");
+ case SA_MUNDEFINED: return cstring_makeLiteralTemp ("possibly undefined");
+
+ case SA_SHARED: return cstring_makeLiteralTemp ("becomes shared");
+ case SA_ONLY: return cstring_makeLiteralTemp ("becomes only");
+ case SA_IMPONLY: return cstring_makeLiteralTemp ("becomes implicitly only");
+ case SA_OWNED: return cstring_makeLiteralTemp ("becomes owned");
+ case SA_DEPENDENT: return cstring_makeLiteralTemp ("becomes dependent");
+ case SA_IMPDEPENDENT: return cstring_makeLiteralTemp ("becomes implicitly dependent");
+ case SA_KEPT: return cstring_makeLiteralTemp ("becomes kept");
+ case SA_KEEP: return cstring_makeLiteralTemp ("becomes keep");
+ case SA_FRESH: return cstring_makeLiteralTemp ("becomes fresh");
+ case SA_TEMP: return cstring_makeLiteralTemp ("becomes temp");
+ case SA_IMPTEMP: return cstring_makeLiteralTemp ("becomes implicitly temp");
+ case SA_XSTACK: return cstring_makeLiteralTemp ("becomes stack-allocated storage");
+ case SA_STATIC: return cstring_makeLiteralTemp ("becomes static");
+ case SA_LOCAL: return cstring_makeLiteralTemp ("becomes local");
+
+ case SA_REFCOUNTED: return cstring_makeLiteralTemp ("becomes refcounted");
+ case SA_REFS: return cstring_makeLiteralTemp ("becomes refs");
+ case SA_NEWREF: return cstring_makeLiteralTemp ("becomes newref");
+ case SA_KILLREF: return cstring_makeLiteralTemp ("becomes killref");
+
+ case SA_OBSERVER: return cstring_makeLiteralTemp ("becomes observer");
+ case SA_EXPOSED: return cstring_makeLiteralTemp ("becomes exposed");
+
+ case SA_BECOMESNULL: return cstring_makeLiteralTemp ("becomes null");
+ case SA_BECOMESNONNULL: return cstring_makeLiteralTemp ("becomes non-null");
+ case SA_BECOMESPOSSIBLYNULL: return cstring_makeLiteralTemp ("becomes possibly null");
+ }
+
+ DPRINTF (("Bad state action: %d", sa));
+ BADBRANCH;
+}
+
+void stateInfo_display (stateInfo s, cstring sname)
+{
+ bool showdeep = context_flagOn (FLG_SHOWDEEPHISTORY, g_currentloc);
+
+ s = stateInfo_sort (s);
+
+ while (stateInfo_isDefined (s))
+ {
+ cstring msg = message ("%s%s", sname, stateAction_unparse (s->action));
+
+ if (sRef_isValid (s->ref)) {
+ msg = message ("%q (through alias %q)", msg, sRef_unparse (s->ref));
+ }
+
+ llgenindentmsg (msg, s->loc);
+
+ if (!showdeep) {
+ break;
+ }
+
+ s = s->previous;
+ }
+
+ cstring_free (sname);
+}
+
+