GP-272 - Gnu Demangler - updated to handle a lambda function parameter

with templates
This commit is contained in:
dragonmacher
2020-11-06 11:01:42 -05:00
parent ea851ffe7b
commit 839f9eeac2
3 changed files with 60 additions and 14 deletions

View File

@@ -90,6 +90,7 @@ public class DemangledDataType extends DemangledType {
private boolean isEnum;
private boolean isPointer64;
private boolean isReference;
private boolean isRValueReference;
private boolean isSigned;
private boolean isStruct;
private boolean isTemplate;
@@ -445,6 +446,13 @@ public class DemangledDataType extends DemangledType {
isReference = true;
}
/**
* rvalue reference; C++11
*/
public void setRValueReference() {
isRValueReference = true;
}
public void setSigned() {
isSigned = true;
}
@@ -671,6 +679,9 @@ public class DemangledDataType extends DemangledType {
if (isReference) {
buffer.append(SPACE + REF_NOTATION);
if (isRValueReference) {
buffer.append(REF_NOTATION); // &&
}
}
// the order of __ptr64 and __restrict can vary--with fuzzing...
@@ -703,5 +714,4 @@ public class DemangledDataType extends DemangledType {
public String toString() {
return getSignature();
}
}

View File

@@ -193,17 +193,18 @@ public class GnuDemanglerParser {
*
* Sample: {lambda(void const*, unsigned int)#1}
* {lambda(NS1::Class1 const&, int, int)#1} const&
* {lambda(auto:1&&)#1}<NS1::NS2>&&
*
* Pattern: [optional text] brace lambda([parameters])#digits brace [optional modifiers]
* Pattern: [optional text] brace lambda([parameters])#digits brace [trailing text]
*
* Parts:
* -full text without leading characters (capture group 1)
* -parameters of the lambda function (capture group 2)
* -trailing id (capture group 3)
* -trailing modifiers (e.g., const, &) (capture group 4)
* -trailing modifiers (e.g., const, &, templates) (capture group 4)
*/
private static final Pattern LAMBDA_PATTERN =
Pattern.compile(".*(\\{" + LAMBDA + "\\((.*)\\)(#\\d+)\\})(\\s*(?:const|\\*|\\&)*){0,1}");
Pattern.compile(".*(\\{" + LAMBDA + "\\((.*)\\)(#\\d+)\\})(.*)");
/*
* Sample: {unnamed type#1}
@@ -395,8 +396,14 @@ public class GnuDemanglerParser {
DemangledFunction function = new DemangledFunction(mangledSource, demangled, null);
String simpleName = signatureParts.getName();
LambdaName lambdaName = getLambdaName(demangled);
if (lambdaName != null) {
if (simpleName.endsWith(LAMBDA_START)) {
//
// For lambdas, the signature parser will set the name to '{lambda', with the parameters
// following that text in the original string. We want the name to be the full lambda
// text, without spaces.
//
LambdaName lambdaName = getLambdaName(demangled);
String uniqueName = lambdaName.getFullText();
String escapedLambda = removeBadSpaces(uniqueName);
simpleName = simpleName.replace(LAMBDA_START, escapedLambda);
@@ -706,6 +713,7 @@ public class GnuDemanglerParser {
// e.g., short (&)[7]
// lambda function
// e.g., {lambda(NS1::Class1 const&, int, int)#1} const&
// {lambda(auto:1&&)#1}<NS1::NS2>>&&
//
LambdaName lambdaName = getLambdaName(datatype);
@@ -724,7 +732,8 @@ public class GnuDemanglerParser {
ddt.setName(fullText);
int offset = fullText.indexOf('(');
int remaining = fullText.length() - offset;
i = i + remaining;
i = i + remaining; // end of lambda's closing '}'
i = i - 1; // back up one space to catch optional templates on next loop pass
}
else {
int startParenCount =
@@ -770,7 +779,7 @@ public class GnuDemanglerParser {
ddt.setReference();
}
else {
ddt.incrementPointerLevels();
ddt.setRValueReference();
}
continue;
}
@@ -1498,18 +1507,19 @@ public class GnuDemanglerParser {
}
}
// {lambda(void const*, unsigned int)#1}
private class LambdaName {
private String fullText;
private String params;
private String id;
private String trailing;
private String modifiers;
LambdaName(String fullText, String params, String trailing, String modifiers) {
LambdaName(String fullText, String params, String id, String trailing) {
this.fullText = fullText;
this.params = params;
this.trailing = trailing;
this.modifiers = modifiers == null ? "" : modifiers;
this.id = id;
this.trailing = trailing == null ? "" : trailing;
}
String getFullText() {
@@ -1521,8 +1531,8 @@ public class GnuDemanglerParser {
ToStringBuilder builder = new ToStringBuilder(this, ToStringStyle.JSON_STYLE);
return builder.append("fullText", fullText)
.append("params", params)
.append("id", id)
.append("trailing", trailing)
.append("modifiers", modifiers)
.toString();
}
}

View File

@@ -1233,7 +1233,7 @@ public class GnuDemanglerParserTest extends AbstractGenericTest {
parameters.get(0).getTemplate().toString());
assertEquals(
"undefined Core::AsyncFile::perform(WTF::F<WTF::F<void (Core::FileClient &)> (Core::File &)> * &)",
"undefined Core::AsyncFile::perform(WTF::F<WTF::F<void (Core::FileClient &)> (Core::File &)> &&)",
object.getSignature(false));
}
@@ -1460,6 +1460,32 @@ public class GnuDemanglerParserTest extends AbstractGenericTest {
signature);
}
@Test
public void testLambdaWithTemplates() throws Exception {
// _ZN7brigand13for_each_argsIZN7WebCore9ConverterINS1_8IDLUnionIJNS1_12IDLDOMStringENS1_12IDLInterfaceINS1_14CanvasGradientEEENS5_INS1_13CanvasPatternEEEEEEE7convertERN3JSC9ExecStateENSC_7JSValueEEUlOT_E_JNS_5type_IS7_EENSJ_IS9_EEEEESG_SG_DpOT0_
// {lambda(auto:1&&)#1}
// {lambda(auto:1&&)#1}<NS1::NS2>>&&
DemangledObject object = parser.parse(
"_ZN3WTF6VectorINS_9RetainPtrI29AVAssetResourceLoadingRequestEELm0ENS_15CrashOnOverflowELm16ENS_10FastMallocEE17removeAllMatchingIZNS6_9removeAllIPS2_EEjRKT_EUlRKS3_E_EEjSC_m",
"WebCore::Converter<WebCore::IDLUnion<WebCore::IDLDOMString, WebCore::IDLInterface<WebCore::CanvasGradient>, WebCore::IDLInterface<WebCore::CanvasPattern> > >::convert(JSC::ExecState&, JSC::JSValue)::{lambda(auto:1&&)#1} brigand::for_each_args<WebCore::Converter<WebCore::IDLUnion<WebCore::IDLDOMString, WebCore::IDLInterface<WebCore::CanvasGradient>, WebCore::IDLInterface<WebCore::CanvasPattern> > >::convert(JSC::ExecState&, JSC::JSValue)::{lambda(auto:1&&)#1}, brigand::type_<WebCore::IDLInterface<WebCore::CanvasGradient> >, WebCore::Converter<WebCore::IDLUnion<WebCore::IDLDOMString, WebCore::IDLInterface<WebCore::CanvasGradient>, WebCore::IDLInterface<WebCore::CanvasPattern> > >::convert(JSC::ExecState&, JSC::JSValue)::{lambda(auto:1&&)#1}<WebCore::IDLInterface<WebCore::CanvasPattern> > >(WebCore::Converter<WebCore::IDLUnion<WebCore::IDLDOMString, WebCore::IDLInterface<WebCore::CanvasGradient>, WebCore::IDLInterface<WebCore::CanvasPattern> > >::convert(JSC::ExecState&, JSC::JSValue)::{lambda(auto:1&&)#1}, brigand::type_<WebCore::IDLInterface<WebCore::CanvasGradient> >&&, WebCore::Converter<WebCore::IDLUnion<WebCore::IDLDOMString, WebCore::IDLInterface<WebCore::CanvasGradient>, WebCore::IDLInterface<WebCore::CanvasPattern> > >::convert(JSC::ExecState&, JSC::JSValue)::{lambda(auto:1&&)#1}<WebCore::IDLInterface<WebCore::CanvasPattern> >&&)");
assertNotNull(object);
assertType(object, DemangledFunction.class);
String name =
"for_each_args<WebCore::Converter<WebCore::IDLUnion<WebCore::IDLDOMString,WebCore::IDLInterface<WebCore::CanvasGradient>,WebCore::IDLInterface<WebCore::CanvasPattern>>>::convert(JSC::ExecState&,JSC::JSValue)::{lambda(auto:1&&)#1},brigand::type_<WebCore::IDLInterface<WebCore::CanvasGradient>>,WebCore::Converter<WebCore::IDLUnion<WebCore::IDLDOMString,WebCore::IDLInterface<WebCore::CanvasGradient>,WebCore::IDLInterface<WebCore::CanvasPattern>>>::convert(JSC::ExecState&,JSC::JSValue)::{lambda(auto:1&&)#1}<WebCore::IDLInterface<WebCore::CanvasPattern>>>";
assertName(object, name, "brigand");
String signature = object.getSignature(false);
assertEquals(
"WebCore::Converter<WebCore::IDLUnion<WebCore::IDLDOMString,WebCore::IDLInterface<WebCore::CanvasGradient>,WebCore::IDLInterface<WebCore::CanvasPattern>>>::convert(JSC::ExecState&,JSC::JSValue)::{lambda(auto:1&&)#1} brigand::for_each_args<WebCore::Converter<WebCore::IDLUnion<WebCore::IDLDOMString,WebCore::IDLInterface<WebCore::CanvasGradient>,WebCore::IDLInterface<WebCore::CanvasPattern>>>::convert(JSC::ExecState&,JSC::JSValue)::{lambda(auto:1&&)#1},brigand::type_<WebCore::IDLInterface<WebCore::CanvasGradient>>,WebCore::Converter<WebCore::IDLUnion<WebCore::IDLDOMString,WebCore::IDLInterface<WebCore::CanvasGradient>,WebCore::IDLInterface<WebCore::CanvasPattern>>>::convert(JSC::ExecState&,JSC::JSValue)::{lambda(auto:1&&)#1}<WebCore::IDLInterface<WebCore::CanvasPattern>>>(WebCore::Converter<WebCore::IDLUnion<WebCore::IDLDOMString,WebCore::IDLInterface<WebCore::CanvasGradient>,WebCore::IDLInterface<WebCore::CanvasPattern>>>::convert(JSC::ExecState&,JSC::JSValue)::{lambda(auto:1&&)#1},brigand::type_<WebCore::IDLInterface<WebCore::CanvasGradient>> &&,WebCore::Converter<WebCore::IDLUnion<WebCore::IDLDOMString,WebCore::IDLInterface<WebCore::CanvasGradient>,WebCore::IDLInterface<WebCore::CanvasPattern>>>::convert(JSC::ExecState&,JSC::JSValue)::{lambda(auto:1&&)#1}<WebCore::IDLInterface<WebCore::CanvasPattern>> &&)",
signature);
}
@Test
public void testFunctionWithLambdaParameter() throws Exception {