GP-214 - Gnu Demangler - fixed parsing failure for templated left-shift

operator
This commit is contained in:
dragonmacher 2020-09-29 16:03:25 -04:00
parent 4a036e56ff
commit bc4cf7de5f
2 changed files with 48 additions and 18 deletions

View File

@ -1109,8 +1109,11 @@ public class GnuDemanglerParser {
@Override
public String toString() {
ToStringBuilder builder = new ToStringBuilder(this, ToStringStyle.JSON_STYLE);
return builder.append("name", name).append("prefix", prefix).append("type",
type).append("demangled", demangled).toString();
return builder.append("name", name)
.append("prefix", prefix)
.append("type", type)
.append("demangled", demangled)
.toString();
}
}
@ -1246,31 +1249,36 @@ public class GnuDemanglerParser {
//
String operatorChars = matcher.group(2);
String templates = matcher.group(3);
templates = templates == null ? "" : templates;
int start = matcher.start(2); // operator chars start
int end = matcher.end(3); // templates end
if (templates == null) {
templates = "";
end = matcher.end(2); // no templates; end of the operator chars
}
//
// The 'operator' functions have symbols that confuse our default function parsing.
// Specifically, operators that use shift symbols (<, <<, >, >>) will cause our
// template parsing to fail. To default the failure, we will install a temporary
// template parsing to fail. To defeat the failure, we will install a temporary
// function name here and then restore it after parsing is finished.
//
String originalPrefix = OPERATOR + operatorChars + templates;
String rawPrefix = OPERATOR + demangled.substring(start, end);
String placeholder = "TEMPNAMEPLACEHOLDERVALUE";
String tempName = demangled.replace(originalPrefix, placeholder);
String tempName = demangled.replace(rawPrefix, placeholder);
DemangledFunction function = (DemangledFunction) parseFunctionOrVariable(tempName);
function.setOverloadedOperator(true);
function.setName(originalPrefix);
if (!StringUtils.isBlank(templates)) {
String escapedPrefix = removeBadSpaces(originalPrefix);
String simpleName = OPERATOR + operatorChars;
if (StringUtils.isBlank(templates)) {
function.setName(simpleName);
}
else {
String escapedTemplates = removeBadSpaces(templates);
int templateIndex = escapedPrefix.indexOf(escapedTemplates);
String operatorName = escapedPrefix.substring(0, templateIndex);
DemangledTemplate demangledTemplate = parseTemplate(escapedTemplates);
function.setTemplate(demangledTemplate);
function.setName(operatorName);
function.setName(simpleName);
}
return function;
@ -1431,8 +1439,10 @@ public class GnuDemanglerParser {
@Override
public String toString() {
ToStringBuilder builder = new ToStringBuilder(this, ToStringStyle.JSON_STYLE);
return builder.append("text", text).append("paramStart", paramStart).append("paramEnd",
paramEnd).toString();
return builder.append("text", text)
.append("paramStart", paramStart)
.append("paramEnd", paramEnd)
.toString();
}
private boolean isContainedWithinNamespace() {
@ -1490,8 +1500,10 @@ public class GnuDemanglerParser {
@Override
public String toString() {
ToStringBuilder builder = new ToStringBuilder(this, ToStringStyle.JSON_STYLE);
return builder.append("fullText", fullText).append("params", params).append("trailing",
trailing).toString();
return builder.append("fullText", fullText)
.append("params", params)
.append("trailing", trailing)
.toString();
}
}

View File

@ -843,7 +843,7 @@ public class GnuDemanglerParserTest extends AbstractGenericTest {
}
@Test
public void testOverloadedShiftOperatorParsingBug() {
public void testOverloadedShiftOperatorTemplated_RightShift() {
parser = new GnuDemanglerParser();
DemangledObject object = parser.parse("fakemangled",
"std::basic_istream<char, std::char_traits<char> >& " +
@ -858,6 +858,24 @@ public class GnuDemanglerParserTest extends AbstractGenericTest {
object.getSignature());
}
@Test
public void testOverloadedShiftOperatorTemplated_LeftShift() {
String raw =
"std::basic_ostream<char, std::char_traits<char> >& " +
"std::operator<< <std::char_traits<char> >" +
"(std::basic_ostream<char, std::char_traits<char> >&, char const*)";
String formatted = "std::basic_ostream<char,std::char_traits<char>> & " +
"std::operator<<<std::char_traits<char>>" +
"(std::basic_ostream<char,std::char_traits<char>> &,char const *)";
DemangledObject object = parser.parse(
"_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc",
raw);
String name = object.getName();
assertEquals("operator<<", name);
assertEquals(formatted, object.getSignature());
}
@Test
public void testOverloadedLeftShiftOperatorWithFunctionPointer() {