Skip to content

Commit 68ba72c

Browse files
committed
Merge pull request #77 from twitwi/fix-gcc4-mangling-complex-constchar
Fix gcc4 demangling of non-trivial const char* cases
2 parents 8bc527a + 2d2b048 commit 68ba72c

2 files changed

Lines changed: 15 additions & 13 deletions

File tree

src/main/java/org/bridj/demangling/GCC4Demangler.java

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public GCC4Demangler(NativeLibrary library, String symbol) {
6262
// Ss == std::string == std::basic_string<char, std::char_traits<char>, std::allocator<char> >
6363
put("s", Arrays.asList((IdentLike) new Ident("std"), new Ident("basic_string", new TemplateArg[]{classType(Byte.TYPE), charTraitsOfChar, allocatorOfChar})));
6464

65-
// used, as an helper: for i in a b c d e f g h i j k l m o p q r s t u v w x y z; do c++filt _Z1_S$i; done
65+
// used, as an helper: for i in {a..z}; do echo $i $(c++filt _Z1_S$i); done
6666
}
6767

6868
private ClassRef enclosed(String ns, ClassRef classRef) {
@@ -88,10 +88,11 @@ private String nextShortcutId() {
8888
}
8989

9090
private TypeRef parsePointerType(boolean memorizePointed, boolean isConst, boolean isReference) throws DemanglingException {
91-
String subId = memorizePointed ? nextShortcutId() : null;
9291
TypeRef pointed = parseType();
93-
if (memorizePointed)
92+
if (memorizePointed) { // force-save the pointed type (used for the case of "const" that is erased (ignored) in bridj internal representation
93+
String subId = memorizePointed ? nextShortcutId() : null;
9494
typeShortcuts.put(subId, pointed);
95+
}
9596
TypeRef res = pointerType(pointed, isConst, isReference);
9697
String id = nextShortcutId();
9798
typeShortcuts.put(id, res);
@@ -118,7 +119,7 @@ public TemplateArg parseTemplateArg() throws DemanglingException {
118119
public TypeRef parseType() throws DemanglingException {
119120
if (Character.isDigit(peekChar())) {
120121
Ident name = ensureOfType(parseNonCompoundIdent(), Ident.class);
121-
String id = nextShortcutId(); // we get the id before parsing the part (might be template parameters and we need to get the ids in the right order)
122+
String id = nextShortcutId();
122123
TypeRef res = simpleType(name);
123124
typeShortcuts.put(id, res);
124125
return res;
@@ -152,8 +153,9 @@ public TypeRef parseType() throws DemanglingException {
152153
return typeShortcuts.get(templatedId);
153154
}
154155
}
156+
} else {
157+
position -= delta;
155158
}
156-
position -= delta;
157159
}
158160
}
159161
// WARNING/INFO/NB: we intentionally continue to the N case
@@ -176,7 +178,7 @@ public TypeRef parseType() throws DemanglingException {
176178
char nextChar = peekChar();
177179
boolean isReference = c == 'R';
178180
boolean isConst = nextChar == 'K';
179-
return parsePointerType(isConst || nextChar == 'N', isConst, isReference);
181+
return parsePointerType(isConst, isConst, isReference);
180182
}
181183
case 'F': {
182184
// TODO parse function type correctly !!!
@@ -262,7 +264,6 @@ private String parseSimpleOrComplexIdentInto(List<IdentLike> res, boolean isPars
262264
}
263265
}
264266
if (shouldContinue) {
265-
int initialNextShortcutId = nextShortcutId;
266267
do {
267268
String id = nextShortcutId(); // we get the id before parsing the part (might be template parameters and we need to get the ids in the right order)
268269
newlyAddedShortcutForThisType = id;
@@ -272,8 +273,8 @@ private String parseSimpleOrComplexIdentInto(List<IdentLike> res, boolean isPars
272273
parsePossibleTemplateArguments(res);
273274
} while (Character.isDigit(peekChar()) || peekChar() == 'C' || peekChar() == 'D');
274275
if (isParsingNonShortcutableElement) {
275-
//prefixShortcuts.remove(previousShortcutId()); // correct the fact that we parsed one too much
276-
nextShortcutId = initialNextShortcutId;
276+
nextShortcutId--;
277+
newlyAddedShortcutForThisType = null;
277278
}
278279
}
279280
parsePossibleTemplateArguments(res);
@@ -433,9 +434,6 @@ public MemberRef parseSymbol() throws DemanglingException {
433434
mr.setMemberName(ns.remove(ns.size() - 1));
434435
if (!ns.isEmpty()) {
435436
ClassRef parent = new ClassRef(ensureOfType(ns.remove(ns.size() - 1), Ident.class));
436-
if (mr.getMemberName() == SpecialName.Constructor || mr.getMemberName() == SpecialName.SpecialConstructor) {
437-
typeShortcuts.put(nextShortcutId(), parent);
438-
}
439437
if (!ns.isEmpty()) {
440438
parent.setEnclosingType(new NamespaceRef(ns.toArray()));
441439
}

src/test/java/org/bridj/DemanglingTest.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,10 @@ public void simpleConstructor() {
311311
pointerType(pointerType(Byte.class))
312312
);
313313
}
314+
@Test
315+
public void twiceConstCharPointerFromBugRequests() {
316+
demangle(null, "_ZN16cmd_create_event6createEPKcS1_PS1_", "null cmd_create_event.create(const byte*, const byte*, const byte**)");
317+
}
314318
@Test
315319
public void methods() {
316320
demangle(
@@ -462,7 +466,7 @@ public void gccTrickyMemoryAndBuiltinShortcutsWithTemplates() {
462466
demangle(null, "_ZN3bla5inputEPSt6vectorISsSaISsEEPS0_IPN7Helping4HandESaIS6_EE",
463467
// bla::input(std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >*, std::vector<Helping::Hand*, std::allocator<Helping::Hand*> >*)
464468
// bla::input(vectorof(string)*, vectorof(Helping::Hand*)*)
465-
"null bla.input(std.vector<std.basic_string<byte, std.char_traits<byte>, std.allocator<byte>>, std.allocator<std.basic_string<byte, std.char_traits<byte>, std.allocator<byte>>>>*, std.allocator<std.basic_string<byte, std.char_traits<byte>, std.allocator<byte>>><Helping.Hand*, std.allocator<Helping.Hand*>>*)");
469+
"null bla.input(std.vector<std.basic_string<byte, std.char_traits<byte>, std.allocator<byte>>, std.allocator<std.basic_string<byte, std.char_traits<byte>, std.allocator<byte>>>>*, std.vector<Helping.Hand*, std.allocator<Helping.Hand*>>*)");
466470
//"null bla.input(" + vectorOfXYZ.replaceAll("XYZ", str) + "*, " + vectorOfXYZ.replaceAll("XYZ", "Helping.Hand*") + "*)");
467471
}
468472

0 commit comments

Comments
 (0)