GP-1051 - Demangler - fixed spaces inside of namespaces for demangled

address tables
This commit is contained in:
dragonmacher 2021-06-22 18:02:27 -04:00
parent 82c8ba1a1c
commit a74b0c7871
3 changed files with 63 additions and 37 deletions

View file

@ -32,10 +32,10 @@ public class DemangledAddressTable extends DemangledObject {
/**
* Constructor
*
* @param mangled the source mangled string
* @param mangled the source mangled string
* @param originalDemangled the original demangled string
* @param name the name of the address table
* @param calculateLength true if the length of this address table should be calculdated at
* @param calculateLength true if the length of this address table should be calculdated at
* analysis time
*/
public DemangledAddressTable(String mangled, String originalDemangled, String name,
@ -56,7 +56,7 @@ public class DemangledAddressTable extends DemangledObject {
@Override
public String getSignature(boolean format) {
StringBuffer buffer = new StringBuffer();
StringBuilder buffer = new StringBuilder();
if (specialPrefix != null) {
buffer.append(specialPrefix);
@ -120,11 +120,11 @@ public class DemangledAddressTable extends DemangledObject {
}
/**
* Perform a best guess at the length of an address table assuming that
* Perform a best guess at the length of an address table assuming that
* another label (or end of block) can be used to identify the end.
* @param program the program
* @param address start of address table
* @return maximum length of table or -1 if address does not reside
* @return maximum length of table or -1 if address does not reside
* within an initialized memory block
*/
private static int guessTableLength(Program program, Address address) {
@ -191,7 +191,7 @@ public class DemangledAddressTable extends DemangledObject {
if (!mem.contains(refAddr)) {
// terminate table early if pointer reference address does not exist
// within memory (demangled address tables should only refer to entities
// within memory (demangled address tables should only refer to entities
// contained within program memory).
return;
}

View file

@ -245,7 +245,7 @@ public class GnuDemanglerParser {
* -'for' or 'to' (capture group 3) | (capture group 1)
* -a space -+
* -optional text (capture group 4)
*
*
* Note: capture group 1 is the combination of groups 2 and 3 with trailing space
*
* Examples:
@ -313,7 +313,7 @@ public class GnuDemanglerParser {
/**
* Pattern to catch literal strings of the form:
*
*
* -1l
* 2l
* 0u
@ -365,7 +365,7 @@ public class GnuDemanglerParser {
return operatorHandler;
}
// Note: this really is a 'special handler' check that used to be handled above. However,
// Note: this really is a 'special handler' check that used to be handled above. However,
// some demangled operator strings begin with this text. If we do this check above,
// then we will not correctly handle those operators.
if (mangledSource.startsWith("_ZZ")) {
@ -490,14 +490,14 @@ public class GnuDemanglerParser {
private LambdaName getLambdaName(String name) {
if (!name.startsWith("{")) {
// the text must start with the lambda syntax; ignore lambdas that are internal to
// the text must start with the lambda syntax; ignore lambdas that are internal to
// the given name
return null;
}
// This replacement string will leave the initial 'lambda' text and replace all others
// with a placeholder value. This allows us to use a simple regex pattern when pulling
// the lambda apart. This is required to handle the case where a lambda expression
// the lambda apart. This is required to handle the case where a lambda expression
// contains a nested lambda expression.
LambdaReplacedString replacedString = new LambdaReplacedString(name);
String updatedName = replacedString.getModifiedText();
@ -552,20 +552,8 @@ public class GnuDemanglerParser {
String name = itemText.substring(pos + 2);
DemangledObject item = parseFunctionOrVariable(name);
//
// Convert the parent type to a suitable namespace. The parent type may have spaces
// in its name, which is not allowed in an applied namespace.
//
// We may eventually want to move this logic into the DemangledObject's
// createNamespace() method. This would also apply to the convertToNamespaces()
// method in this class.
//
String namespaceName = parent.getNamespaceName();
String escapedName = removeBadSpaces(namespaceName);
DemangledType type = new DemangledType(mangledSource, demangledSource, escapedName);
type.setNamespace(parent.getNamespace());
item.setNamespace(type);
DemangledType namespaceType = createNamespaceDemangledType(parent);
item.setNamespace(namespaceType);
return item;
}
@ -758,7 +746,7 @@ public class GnuDemanglerParser {
}
// note: we should only encounter literals as template arguments. Function parameters
// and return types should never be literals.
// and return types should never be literals.
if (isLiteral(fullDatatype)) {
return createLiteral(fullDatatype);
}
@ -814,7 +802,7 @@ public class GnuDemanglerParser {
//
// Check for array case
//
// remove the templates to allow us to use a simpler regex when checking for arrays
// remove the templates to allow us to use a simpler regex when checking for arrays
DemangledDataType newDt = tryToParseArrayPointerOrReference(dt, datatype);
if (newDt != null) {
dt = newDt;
@ -834,7 +822,7 @@ public class GnuDemanglerParser {
String fullText = lambdaName.getFullText();
dt.setName(fullText);
int offset = fullText.indexOf('(');
// to to the end of the lambda, which is its length, minus our position
// to to the end of the lambda, which is its length, minus our position
// inside the lambda
int remaining = fullText.length() - offset;
i = i + remaining; // end of lambda's closing '}'
@ -1583,11 +1571,30 @@ public class GnuDemanglerParser {
DemangledObject doBuild(Demangled namespace) {
DemangledAddressTable addressTable =
new DemangledAddressTable(mangledSource, demangled, name, true);
addressTable.setNamespace(namespace);
DemangledType namespaceType = createNamespaceDemangledType(namespace);
addressTable.setNamespace(namespaceType);
return addressTable;
}
}
//
// Convert the given demangled object into a suitable namespace. The given type may have spaces
// in its name, which is not allowed in an *applied* namespace.
//
// We may eventually want to move this logic into the DemangledObject's createNamespace()
// method. This would also apply to the convertToNamespaces() method in this class. The
// reasoning is that this parser should create namespaces just as they are given to the parser,
// while the code responsible for applying the namespace should be responsible for domain
// logic, such as removing spaces in the namespace name.
//
private DemangledType createNamespaceDemangledType(Demangled namespace) {
String namespaceName = namespace.getNamespaceName();
String escapedName = removeBadSpaces(namespaceName);
DemangledType type = new DemangledType(mangledSource, demangledSource, escapedName);
type.setNamespace(namespace.getNamespace());
return type;
}
private class OverloadOperatorHandler extends OperatorHandler {
OverloadOperatorHandler(String demangled) {
@ -2088,8 +2095,8 @@ public class GnuDemanglerParser {
/**
* A class that allows us to pass around string content that has had some of its text
* replaced with temporary values. Clients can also use this class to get back the original
* text.
* replaced with temporary values. Clients can also use this class to get back the original
* text.
*/
private abstract class ReplacedString {

View file

@ -540,6 +540,25 @@ public class GnuDemanglerParserTest extends AbstractGenericTest {
assertEquals("class_with_trailing_numbers1234::typeinfo", object.getSignature(false));
}
@Test
public void testTypeInfo_AddressTable_InFunctionNamespace() throws Exception {
String mangled =
"_ZTIFR17ClimateAttributesPSt4pairISt17reference_wrapperI5BiomeES2_I24IWorldRegistriesProviderEEE";
String demangled = process.demangle(mangled);
assertEquals(
"typeinfo for ClimateAttributes& (std::pair<std::reference_wrapper<Biome>, std::reference_wrapper<IWorldRegistriesProvider> >*)",
demangled);
DemangledObject object = parser.parse(mangled, demangled);
String namespaceString =
"ClimateAttributes&(std::pair<std::reference_wrapper<Biome>,std::reference_wrapper<IWorldRegistriesProvider>>*)";
assertType(object, DemangledAddressTable.class);
assertName(object, "typeinfo", namespaceString);
assertEquals(namespaceString + "::typeinfo", object.getSignature(false));
}
@Test
public void testTypeInfo() throws Exception {
String mangled = "_ZTIN4Arts28FileInputStream_impl_FactoryE";
@ -1085,7 +1104,7 @@ public class GnuDemanglerParserTest extends AbstractGenericTest {
/*
Note: the empty template type: '<, std...'
Note: the empty template type: '<, std...'
<, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>
@ -1147,7 +1166,7 @@ public class GnuDemanglerParserTest extends AbstractGenericTest {
lambda contents - lambdas in templates and as a parameter
bool (***
bool (***
const* std::
__addressof<
Bedrock::
@ -1237,7 +1256,7 @@ public class GnuDemanglerParserTest extends AbstractGenericTest {
assertType(object, DemangledFunction.class);
//@formatter:off
String expected =
String expected =
"void (* " +
"entt::" +
"basic_registry::" +
@ -1848,16 +1867,16 @@ public class GnuDemanglerParserTest extends AbstractGenericTest {
//
// Test to ensure proper handling of 'float AvoidBlockGoal::Definition::* const&'
// which is a const reference to a floating point member of the class
// which is a const reference to a floating point member of the class
// AvoidBlockGoal::Definition
//
//
/*
Demangled:
auto && JsonUtil::
addMember<std::shared_ptr<JsonUtil::JsonSchemaObjectNode<JsonUtil::EmptyClass,AvoidBlockGoal::Definition>>,AvoidBlockGoal::Definition,float>
addMember<std::shared_ptr<JsonUtil::JsonSchemaObjectNode<JsonUtil::EmptyClass,AvoidBlockGoal::Definition>>,AvoidBlockGoal::Definition,float>
(
std::shared_ptr<JsonUtil::JsonSchemaObjectNode<JsonUtil::EmptyClass,AvoidBlockGoal::Definition>>,