TypeGraph: Apply qualifiers to template params

This is necessary when replacing the allocator of a map type, for
example.

`std::map<int, int>` will need an allocator which allocates elements of
type `std::pair<const int, int>>`
This commit is contained in:
Alastair Robertson 2023-05-31 04:40:15 -07:00 committed by Alastair Robertson
parent 1723611411
commit 3a7a647a73
4 changed files with 38 additions and 2 deletions

View File

@ -291,8 +291,12 @@ void DrgnParser::enumerateTemplateParam(drgn_type_template_parameter* tparams,
struct drgn_type* tparamType = tparamQualType.type;
QualifierSet qualifiers;
qualifiers[Qualifier::Const] =
(tparamQualType.qualifiers & DRGN_QUALIFIER_CONST);
auto ttype = enumerateType(tparamType);
params.emplace_back(ttype);
params.emplace_back(ttype, qualifiers);
} else {
// This template parameter is a value
// TODO why do we need the type of a value?

View File

@ -95,6 +95,9 @@ void NameGen::visit(Container& c) {
if (param.value) {
name += *param.value;
} else {
if (param.qualifiers[Qualifier::Const]) {
name += "const ";
}
name += param.type->name();
}
name += ", ";

View File

@ -21,6 +21,7 @@
#include <vector>
#include "oi/ContainerInfo.h"
#include "oi/EnumBitset.h"
#define OI_TYPE_LIST \
X(Class) \
@ -37,6 +38,12 @@ struct ContainerInfo;
namespace type_graph {
enum class Qualifier {
Const,
Max,
};
using QualifierSet = EnumBitset<Qualifier, static_cast<size_t>(Qualifier::Max)>;
class Visitor;
class ConstVisitor;
#define DECLARE_ACCEPT \
@ -92,14 +99,18 @@ struct Parent {
};
struct TemplateParam {
// TODO make ctors explicit?
// TODO make ctors explicit
TemplateParam(Type* type) : type(type) {
}
TemplateParam(Type* type, QualifierSet qualifiers)
: type(type), qualifiers(qualifiers) {
}
TemplateParam(Type* type, std::string value)
: type(type), value(std::move(value)) {
}
Type* type;
QualifierSet qualifiers;
std::optional<std::string>
value; // TODO is there any reason not to store all values as strings?
};

View File

@ -162,6 +162,24 @@ TEST(NameGenTest, ContainerParamsDuplicatesAcrossContainers) {
EXPECT_EQ(mycontainer2.name(), "std::vector<MyParam_1, MyParam_2>");
}
TEST(NameGenTest, ContainerParamsConst) {
auto myparam1 =
std::make_unique<Class>(Class::Kind::Struct, "MyConstParam", 13);
auto myparam2 = std::make_unique<Class>(Class::Kind::Struct, "MyParam", 13);
auto mycontainer = getVector();
mycontainer.templateParams.push_back(
TemplateParam{myparam1.get(), {Qualifier::Const}});
mycontainer.templateParams.push_back(TemplateParam{myparam2.get()});
NameGen nameGen;
nameGen.generateNames({mycontainer});
EXPECT_EQ(myparam1->name(), "MyConstParam_0");
EXPECT_EQ(myparam2->name(), "MyParam_1");
EXPECT_EQ(mycontainer.name(), "std::vector<const MyConstParam_0, MyParam_1>");
}
TEST(NameGenTest, Array) {
auto myparam1 = std::make_unique<Class>(Class::Kind::Struct, "MyParam", 13);
auto myparam2 = std::make_unique<Class>(Class::Kind::Struct, "MyParam", 13);