public void DemangleAsInner(DemanglingContext context) { bool innerIsArray = false; while (context.Inner.Count > 0) { IDemangleAsInner inner = context.Inner.Pop(); innerIsArray = inner is ArrayType; if (!innerIsArray) { context.Writer.EnsureSpace(); context.Writer.Append("("); } inner.DemangleAsInner(context); if (!innerIsArray) { context.Writer.Append(")"); } } if (!innerIsArray) { context.Writer.EnsureSpace(); } context.Writer.Append("["); DemangleSize(context); context.Writer.Append("]"); }
public static void Demangle(IEnumerable <IParsingResult> types, DemanglingContext context) { // TODO: if ctx.options.no_params && stack.is_none() return; bool sawNeedsParentheses = false; Tuple <bool, bool> needsSpaceParentheses = context.Inner .DefaultIfEmpty(null) .Select(inner => { if (inner is PointerToMemberType) { return(Tuple.Create(true, true)); } else if (inner is Type.PointerTo || inner is Type.LvalueRef || inner is Type.RvalueRef) { return(Tuple.Create(false, true)); } return(Tuple.Create(false, false)); }) .TakeWhile(t => { if (sawNeedsParentheses) { return(false); } else { sawNeedsParentheses |= t.Item2; return(true); } }) .Aggregate((t1, t2) => Tuple.Create(t1.Item1 || t2.Item1, t1.Item2 || t2.Item2)); bool needsSpace = needsSpaceParentheses.Item1; bool needsParenentheses = needsSpaceParentheses.Item2; if (needsParenentheses) { if (context.Writer.Last != '(' && context.Writer.Last != '*') { needsSpace = true; } if (needsSpace) { context.Writer.EnsureSpace(); } context.Writer.Append("("); } List <IDemangleAsInner> newInner = new List <IDemangleAsInner>(); while (context.Inner.Count > 0) { IDemangleAsInner inner = context.Inner.Pop(); if (inner is Encoding.Function) { newInner.Add(inner); } else { inner.DemangleAsInner(context); } } foreach (IDemangleAsInner inner in newInner) { context.Inner.Push(inner); } if (needsParenentheses) { context.Writer.Append(")"); } context.Writer.Append("("); // To maintain compatibility with libiberty, print `()` instead of // `(void)` for functions that take no arguments. if (types.Count() == 1) { StandardBuiltinType voidType = types.First() as StandardBuiltinType; if (voidType != null && voidType.Value == StandardBuiltinType.Values.Void) { context.Writer.Append(")"); return; } } types.Demangle(context); context.Writer.Append(")"); }