mirror of
https://github.com/JakeHillion/object-introspection.git
synced 2024-11-09 21:24:14 +00:00
codegen: carry decl and func with containerinfo
This commit is contained in:
parent
10f47510d1
commit
76f525f43d
54
src/Common.h
54
src/Common.h
@ -25,7 +25,54 @@ extern "C" {
|
|||||||
|
|
||||||
constexpr int oidMagicId = 0x01DE8;
|
constexpr int oidMagicId = 0x01DE8;
|
||||||
|
|
||||||
struct ContainerInfo;
|
#define LIST_OF_CONTAINER_TYPES \
|
||||||
|
X(UNKNOWN_TYPE) \
|
||||||
|
X(ARRAY_TYPE) \
|
||||||
|
X(SMALL_VEC_TYPE) \
|
||||||
|
X(SET_TYPE) \
|
||||||
|
X(UNORDERED_SET_TYPE) \
|
||||||
|
X(SEQ_TYPE) \
|
||||||
|
X(LIST_TYPE) \
|
||||||
|
X(STD_MAP_TYPE) \
|
||||||
|
X(STD_UNORDERED_MAP_TYPE) \
|
||||||
|
X(MAP_SEQ_TYPE) \
|
||||||
|
X(BY_MULTI_QRT_TYPE) \
|
||||||
|
X(F14_MAP) \
|
||||||
|
X(F14_SET) \
|
||||||
|
X(FEED_QUICK_HASH_SET) \
|
||||||
|
X(FEED_QUICK_HASH_MAP) \
|
||||||
|
X(RADIX_TREE_TYPE) \
|
||||||
|
X(PAIR_TYPE) \
|
||||||
|
X(STRING_TYPE) \
|
||||||
|
X(FOLLY_IOBUF_TYPE) \
|
||||||
|
X(FOLLY_IOBUFQUEUE_TYPE) \
|
||||||
|
X(FB_STRING_TYPE) \
|
||||||
|
X(UNIQ_PTR_TYPE) \
|
||||||
|
X(SHRD_PTR_TYPE) \
|
||||||
|
X(FB_HASH_MAP_TYPE) \
|
||||||
|
X(FB_HASH_SET_TYPE) \
|
||||||
|
X(FOLLY_OPTIONAL_TYPE) \
|
||||||
|
X(OPTIONAL_TYPE) \
|
||||||
|
X(TRY_TYPE) \
|
||||||
|
X(REF_WRAPPER_TYPE) \
|
||||||
|
X(SORTED_VEC_SET_TYPE) \
|
||||||
|
X(REPEATED_FIELD_TYPE) \
|
||||||
|
X(CAFFE2_BLOB_TYPE) \
|
||||||
|
X(MULTI_MAP_TYPE) \
|
||||||
|
X(FOLLY_SMALL_HEAP_VECTOR_MAP) \
|
||||||
|
X(CONTAINER_ADAPTER_TYPE) \
|
||||||
|
X(MICROLIST_TYPE) \
|
||||||
|
X(ENUM_MAP_TYPE) \
|
||||||
|
X(BOOST_BIMAP_TYPE) \
|
||||||
|
X(STD_VARIANT_TYPE) \
|
||||||
|
X(THRIFT_ISSET_TYPE) \
|
||||||
|
X(WEAK_PTR_TYPE)
|
||||||
|
|
||||||
|
enum ContainerTypeEnum {
|
||||||
|
#define X(name) name,
|
||||||
|
LIST_OF_CONTAINER_TYPES
|
||||||
|
#undef X
|
||||||
|
};
|
||||||
|
|
||||||
struct RootInfo {
|
struct RootInfo {
|
||||||
std::string varName;
|
std::string varName;
|
||||||
@ -47,8 +94,9 @@ struct DrgnClassMemberInfo {
|
|||||||
|
|
||||||
struct TypeHierarchy {
|
struct TypeHierarchy {
|
||||||
std::map<struct drgn_type*, std::vector<DrgnClassMemberInfo>> classMembersMap;
|
std::map<struct drgn_type*, std::vector<DrgnClassMemberInfo>> classMembersMap;
|
||||||
std::map<struct drgn_type*,
|
std::map<
|
||||||
std::pair<ContainerInfo, std::vector<struct drgn_qualified_type>>>
|
struct drgn_type*,
|
||||||
|
std::pair<ContainerTypeEnum, std::vector<struct drgn_qualified_type>>>
|
||||||
containerTypeMap;
|
containerTypeMap;
|
||||||
std::map<struct drgn_type*, struct drgn_type*> typedefMap;
|
std::map<struct drgn_type*, struct drgn_type*> typedefMap;
|
||||||
std::map<std::string, size_t> sizeMap;
|
std::map<std::string, size_t> sizeMap;
|
||||||
|
@ -20,6 +20,8 @@
|
|||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
ContainerTypeEnum containerTypeEnumFromStr(std::string& str) {
|
ContainerTypeEnum containerTypeEnumFromStr(std::string& str) {
|
||||||
static const std::map<std::string, ContainerTypeEnum> nameMap = {
|
static const std::map<std::string, ContainerTypeEnum> nameMap = {
|
||||||
#define X(name) {#name, name},
|
#define X(name) {#name, name},
|
||||||
@ -128,6 +130,30 @@ std::unique_ptr<ContainerInfo> ContainerInfo::loadFromFile(
|
|||||||
std::optional<size_t> underlyingContainerIndex =
|
std::optional<size_t> underlyingContainerIndex =
|
||||||
(*info)["underlyingContainerIndex"].value<size_t>();
|
(*info)["underlyingContainerIndex"].value<size_t>();
|
||||||
|
|
||||||
|
toml::table* codegen = container["codegen"].as_table();
|
||||||
|
if (!codegen) {
|
||||||
|
LOG(ERROR) << "a container info file requires an `codegen` table";
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string decl;
|
||||||
|
if (std::optional<std::string> str =
|
||||||
|
(*codegen)["decl"].value<std::string>()) {
|
||||||
|
decl = std::move(*str);
|
||||||
|
} else {
|
||||||
|
LOG(ERROR) << "`codegen.decl` is a required field";
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string func;
|
||||||
|
if (std::optional<std::string> str =
|
||||||
|
(*codegen)["func"].value<std::string>()) {
|
||||||
|
func = std::move(*str);
|
||||||
|
} else {
|
||||||
|
LOG(ERROR) << "`codegen.func` is a required field";
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
return std::unique_ptr<ContainerInfo>(new ContainerInfo{
|
return std::unique_ptr<ContainerInfo>(new ContainerInfo{
|
||||||
std::move(typeName),
|
std::move(typeName),
|
||||||
std::move(matcher),
|
std::move(matcher),
|
||||||
@ -138,5 +164,10 @@ std::unique_ptr<ContainerInfo> ContainerInfo::loadFromFile(
|
|||||||
std::move(replaceTemplateParamIndex),
|
std::move(replaceTemplateParamIndex),
|
||||||
allocatorIndex,
|
allocatorIndex,
|
||||||
underlyingContainerIndex,
|
underlyingContainerIndex,
|
||||||
|
|
||||||
|
{
|
||||||
|
std::move(decl),
|
||||||
|
std::move(func),
|
||||||
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -17,63 +17,45 @@
|
|||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <regex>
|
#include <regex>
|
||||||
|
#include <set>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace fs = std::filesystem;
|
#include "Common.h"
|
||||||
|
|
||||||
#define LIST_OF_CONTAINER_TYPES \
|
|
||||||
X(UNKNOWN_TYPE) \
|
|
||||||
X(ARRAY_TYPE) \
|
|
||||||
X(SMALL_VEC_TYPE) \
|
|
||||||
X(SET_TYPE) \
|
|
||||||
X(UNORDERED_SET_TYPE) \
|
|
||||||
X(SEQ_TYPE) \
|
|
||||||
X(LIST_TYPE) \
|
|
||||||
X(STD_MAP_TYPE) \
|
|
||||||
X(STD_UNORDERED_MAP_TYPE) \
|
|
||||||
X(MAP_SEQ_TYPE) \
|
|
||||||
X(BY_MULTI_QRT_TYPE) \
|
|
||||||
X(F14_MAP) \
|
|
||||||
X(F14_SET) \
|
|
||||||
X(FEED_QUICK_HASH_SET) \
|
|
||||||
X(FEED_QUICK_HASH_MAP) \
|
|
||||||
X(RADIX_TREE_TYPE) \
|
|
||||||
X(PAIR_TYPE) \
|
|
||||||
X(STRING_TYPE) \
|
|
||||||
X(FOLLY_IOBUF_TYPE) \
|
|
||||||
X(FOLLY_IOBUFQUEUE_TYPE) \
|
|
||||||
X(FB_STRING_TYPE) \
|
|
||||||
X(UNIQ_PTR_TYPE) \
|
|
||||||
X(SHRD_PTR_TYPE) \
|
|
||||||
X(FB_HASH_MAP_TYPE) \
|
|
||||||
X(FB_HASH_SET_TYPE) \
|
|
||||||
X(FOLLY_OPTIONAL_TYPE) \
|
|
||||||
X(OPTIONAL_TYPE) \
|
|
||||||
X(TRY_TYPE) \
|
|
||||||
X(REF_WRAPPER_TYPE) \
|
|
||||||
X(SORTED_VEC_SET_TYPE) \
|
|
||||||
X(REPEATED_FIELD_TYPE) \
|
|
||||||
X(CAFFE2_BLOB_TYPE) \
|
|
||||||
X(MULTI_MAP_TYPE) \
|
|
||||||
X(FOLLY_SMALL_HEAP_VECTOR_MAP) \
|
|
||||||
X(CONTAINER_ADAPTER_TYPE) \
|
|
||||||
X(MICROLIST_TYPE) \
|
|
||||||
X(ENUM_MAP_TYPE) \
|
|
||||||
X(BOOST_BIMAP_TYPE) \
|
|
||||||
X(STD_VARIANT_TYPE) \
|
|
||||||
X(THRIFT_ISSET_TYPE) \
|
|
||||||
X(WEAK_PTR_TYPE)
|
|
||||||
|
|
||||||
enum ContainerTypeEnum {
|
|
||||||
#define X(name) name,
|
|
||||||
LIST_OF_CONTAINER_TYPES
|
|
||||||
#undef X
|
|
||||||
};
|
|
||||||
ContainerTypeEnum containerTypeEnumFromStr(std::string& str);
|
ContainerTypeEnum containerTypeEnumFromStr(std::string& str);
|
||||||
const char* containerTypeEnumToStr(ContainerTypeEnum ty);
|
const char* containerTypeEnumToStr(ContainerTypeEnum ty);
|
||||||
|
|
||||||
struct ContainerInfo {
|
struct ContainerInfo {
|
||||||
|
struct Codegen {
|
||||||
|
std::string decl;
|
||||||
|
std::string func;
|
||||||
|
};
|
||||||
|
|
||||||
|
ContainerInfo(const ContainerInfo&) = delete;
|
||||||
|
ContainerInfo& operator=(const ContainerInfo& other) = delete;
|
||||||
|
|
||||||
|
ContainerInfo() = default;
|
||||||
|
ContainerInfo(std::string typeName_, std::regex matcher_,
|
||||||
|
std::optional<size_t> numTemplateParams_,
|
||||||
|
ContainerTypeEnum ctype_, std::string header_,
|
||||||
|
std::vector<std::string> ns_,
|
||||||
|
std::vector<size_t> replaceTemplateParamIndex_,
|
||||||
|
std::optional<size_t> allocatorIndex_,
|
||||||
|
std::optional<size_t> underlyingContainerIndex_,
|
||||||
|
ContainerInfo::Codegen codegen_)
|
||||||
|
: typeName(std::move(typeName_)),
|
||||||
|
matcher(std::move(matcher_)),
|
||||||
|
numTemplateParams(numTemplateParams_),
|
||||||
|
ctype(ctype_),
|
||||||
|
header(std::move(header_)),
|
||||||
|
ns(std::move(ns_)),
|
||||||
|
replaceTemplateParamIndex(std::move(replaceTemplateParamIndex_)),
|
||||||
|
allocatorIndex(allocatorIndex_),
|
||||||
|
underlyingContainerIndex(underlyingContainerIndex_),
|
||||||
|
codegen(std::move(codegen_)) {
|
||||||
|
}
|
||||||
|
|
||||||
std::string typeName;
|
std::string typeName;
|
||||||
std::regex matcher;
|
std::regex matcher;
|
||||||
std::optional<size_t> numTemplateParams;
|
std::optional<size_t> numTemplateParams;
|
||||||
@ -86,9 +68,16 @@ struct ContainerInfo {
|
|||||||
// adapter
|
// adapter
|
||||||
std::optional<size_t> underlyingContainerIndex{};
|
std::optional<size_t> underlyingContainerIndex{};
|
||||||
|
|
||||||
static std::unique_ptr<ContainerInfo> loadFromFile(const fs::path& path);
|
Codegen codegen;
|
||||||
|
|
||||||
|
static std::unique_ptr<ContainerInfo> loadFromFile(
|
||||||
|
const std::filesystem::path& path);
|
||||||
|
|
||||||
bool operator<(const ContainerInfo& rhs) const {
|
bool operator<(const ContainerInfo& rhs) const {
|
||||||
return (typeName < rhs.typeName);
|
return (typeName < rhs.typeName);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using ContainerInfoRefSet =
|
||||||
|
std::set<std::reference_wrapper<const ContainerInfo>,
|
||||||
|
std::less<ContainerInfo>>;
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
#include "FuncGen.h"
|
#include "FuncGen.h"
|
||||||
|
|
||||||
#include <glog/logging.h>
|
#include <glog/logging.h>
|
||||||
#include <toml++/toml.h>
|
|
||||||
|
|
||||||
#include <boost/format.hpp>
|
#include <boost/format.hpp>
|
||||||
#include <map>
|
#include <map>
|
||||||
@ -322,27 +321,14 @@ void FuncGen::DefineTopLevelGetSizeSmartPtr(std::string& testCode,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool FuncGen::DeclareGetSizeFuncs(std::string& testCode,
|
bool FuncGen::DeclareGetSizeFuncs(std::string& testCode,
|
||||||
const std::set<ContainerInfo>& containerInfo,
|
const ContainerInfoRefSet& containerInfo,
|
||||||
bool chaseRawPointers) {
|
bool chaseRawPointers) {
|
||||||
for (auto& cInfo : containerInfo) {
|
for (const ContainerInfo& cInfo : containerInfo) {
|
||||||
std::string ctype = cInfo.typeName;
|
std::string ctype = cInfo.typeName;
|
||||||
ctype = ctype.substr(0, ctype.find("<", 0));
|
ctype = ctype.substr(0, ctype.find("<", 0));
|
||||||
|
|
||||||
if (!typeToFuncMap.contains(cInfo.ctype)) {
|
auto& decl = cInfo.codegen.decl;
|
||||||
LOG(ERROR) << "attempted to use container `"
|
boost::format fmt = boost::format(decl) % ctype;
|
||||||
<< containerTypeEnumToStr(cInfo.ctype)
|
|
||||||
<< "` for which a declaration was not provided";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto& func = typeToDeclMap[cInfo.ctype];
|
|
||||||
boost::format fmt;
|
|
||||||
fmt = boost::format(func) % ctype;
|
|
||||||
/*if (cInfo.ctype == STRING_TYPE) {
|
|
||||||
fmt = boost::format(func);
|
|
||||||
} else {
|
|
||||||
fmt = boost::format(func) % ctype;
|
|
||||||
}*/
|
|
||||||
testCode.append(fmt.str());
|
testCode.append(fmt.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -359,28 +345,14 @@ bool FuncGen::DeclareGetSizeFuncs(std::string& testCode,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool FuncGen::DefineGetSizeFuncs(std::string& testCode,
|
bool FuncGen::DefineGetSizeFuncs(std::string& testCode,
|
||||||
const std::set<ContainerInfo>& containerInfo,
|
const ContainerInfoRefSet& containerInfo,
|
||||||
bool chaseRawPointers) {
|
bool chaseRawPointers) {
|
||||||
for (auto& cInfo : containerInfo) {
|
for (const ContainerInfo& cInfo : containerInfo) {
|
||||||
std::string ctype = cInfo.typeName;
|
std::string ctype = cInfo.typeName;
|
||||||
ctype = ctype.substr(0, ctype.find("<", 0));
|
ctype = ctype.substr(0, ctype.find("<", 0));
|
||||||
|
|
||||||
if (!typeToFuncMap.contains(cInfo.ctype)) {
|
auto& func = cInfo.codegen.func;
|
||||||
LOG(ERROR) << "attempted to use container `"
|
boost::format fmt = boost::format(func) % ctype;
|
||||||
<< containerTypeEnumToStr(cInfo.ctype)
|
|
||||||
<< "` for which a definition was not provided";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
auto& func = typeToFuncMap[cInfo.ctype];
|
|
||||||
|
|
||||||
boost::format fmt;
|
|
||||||
fmt = boost::format(func) % ctype;
|
|
||||||
/*if (cInfo.ctype == STRING_TYPE) {
|
|
||||||
fmt = boost::format(func);
|
|
||||||
} else {
|
|
||||||
fmt = boost::format(func) % ctype;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
testCode.append(fmt.str());
|
testCode.append(fmt.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -422,38 +394,3 @@ void FuncGen::DeclareGetContainer(std::string& testCode) {
|
|||||||
)";
|
)";
|
||||||
testCode.append(func);
|
testCode.append(func);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FuncGen::RegisterContainer(ContainerTypeEnum ctype, const fs::path& path) {
|
|
||||||
toml::table container;
|
|
||||||
try {
|
|
||||||
container = toml::parse_file(std::string(path));
|
|
||||||
} catch (const toml::parse_error& ex) {
|
|
||||||
LOG(ERROR) << "FuncGen::RegisterContainer: " << path << " : "
|
|
||||||
<< ex.description();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
toml::table* codegen = container["codegen"].as_table();
|
|
||||||
if (!codegen) {
|
|
||||||
LOG(ERROR) << "a container info file requires an `codegen` table";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (std::optional<std::string> str =
|
|
||||||
(*codegen)["decl"].value<std::string>()) {
|
|
||||||
typeToDeclMap.emplace(ctype, std::move(*str));
|
|
||||||
} else {
|
|
||||||
LOG(ERROR) << "`codegen.decl` is a required field";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (std::optional<std::string> str =
|
|
||||||
(*codegen)["func"].value<std::string>()) {
|
|
||||||
typeToFuncMap.emplace(ctype, std::move(*str));
|
|
||||||
} else {
|
|
||||||
LOG(ERROR) << "`codegen.func` is a required field";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
@ -25,8 +25,6 @@ namespace fs = std::filesystem;
|
|||||||
|
|
||||||
class FuncGen {
|
class FuncGen {
|
||||||
public:
|
public:
|
||||||
bool RegisterContainer(ContainerTypeEnum, const fs::path& path);
|
|
||||||
|
|
||||||
static void DeclareStoreData(std::string& testCode);
|
static void DeclareStoreData(std::string& testCode);
|
||||||
static void DefineStoreData(std::string& testCode);
|
static void DefineStoreData(std::string& testCode);
|
||||||
|
|
||||||
@ -40,10 +38,10 @@ class FuncGen {
|
|||||||
static void DefineEncodeDataSize(std::string& testCode);
|
static void DefineEncodeDataSize(std::string& testCode);
|
||||||
|
|
||||||
bool DeclareGetSizeFuncs(std::string& testCode,
|
bool DeclareGetSizeFuncs(std::string& testCode,
|
||||||
const std::set<ContainerInfo>& containerInfo,
|
const ContainerInfoRefSet& containerInfo,
|
||||||
bool chaseRawPointers);
|
bool chaseRawPointers);
|
||||||
bool DefineGetSizeFuncs(std::string& testCode,
|
bool DefineGetSizeFuncs(std::string& testCode,
|
||||||
const std::set<ContainerInfo>& containerInfo,
|
const ContainerInfoRefSet& containerInfo,
|
||||||
bool chaseRawPointers);
|
bool chaseRawPointers);
|
||||||
|
|
||||||
static void DeclareGetContainer(std::string& testCode);
|
static void DeclareGetContainer(std::string& testCode);
|
||||||
@ -67,8 +65,4 @@ class FuncGen {
|
|||||||
|
|
||||||
static void DefineGetSizeTypedValueFunc(std::string& testCode,
|
static void DefineGetSizeTypedValueFunc(std::string& testCode,
|
||||||
const std::string& ctype);
|
const std::string& ctype);
|
||||||
|
|
||||||
private:
|
|
||||||
std::map<ContainerTypeEnum, std::string> typeToDeclMap;
|
|
||||||
std::map<ContainerTypeEnum, std::string> typeToFuncMap;
|
|
||||||
};
|
};
|
||||||
|
@ -106,7 +106,7 @@ OICodeGen::OICodeGen(const Config& c, SymbolService& s)
|
|||||||
bool OICodeGen::registerContainer(const fs::path& path) {
|
bool OICodeGen::registerContainer(const fs::path& path) {
|
||||||
VLOG(1) << "registering container, path: " << path;
|
VLOG(1) << "registering container, path: " << path;
|
||||||
auto info = ContainerInfo::loadFromFile(path);
|
auto info = ContainerInfo::loadFromFile(path);
|
||||||
if (!info || !funcGen.RegisterContainer(info->ctype, path)) {
|
if (!info) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,7 +159,8 @@ std::optional<const std::string_view> OICodeGen::fullyQualifiedName(
|
|||||||
return typeNamePair->second.contents;
|
return typeNamePair->second.contents;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<ContainerInfo> OICodeGen::getContainerInfo(drgn_type* type) {
|
std::optional<std::reference_wrapper<const ContainerInfo>>
|
||||||
|
OICodeGen::getContainerInfo(drgn_type* type) {
|
||||||
auto name = fullyQualifiedName(type);
|
auto name = fullyQualifiedName(type);
|
||||||
if (!name.has_value()) {
|
if (!name.has_value()) {
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
@ -168,9 +169,9 @@ std::optional<ContainerInfo> OICodeGen::getContainerInfo(drgn_type* type) {
|
|||||||
std::string nameStr = std::string(*name);
|
std::string nameStr = std::string(*name);
|
||||||
for (auto it = containerInfoList.rbegin(); it != containerInfoList.rend();
|
for (auto it = containerInfoList.rbegin(); it != containerInfoList.rend();
|
||||||
++it) {
|
++it) {
|
||||||
const auto& info = *it;
|
const ContainerInfo& info = **it;
|
||||||
if (std::regex_search(nameStr, info->matcher)) {
|
if (std::regex_search(nameStr, info.matcher)) {
|
||||||
return *info;
|
return info;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
@ -359,11 +360,12 @@ void OICodeGen::replaceTemplateParameters(
|
|||||||
drgn_type* type, TemplateParamList& template_params,
|
drgn_type* type, TemplateParamList& template_params,
|
||||||
std::vector<std::string>& template_params_strings,
|
std::vector<std::string>& template_params_strings,
|
||||||
const std::string& nameWithoutTemplate) {
|
const std::string& nameWithoutTemplate) {
|
||||||
auto containerInfo = getContainerInfo(type);
|
auto optContainerInfo = getContainerInfo(type);
|
||||||
if (!containerInfo.has_value()) {
|
if (!optContainerInfo.has_value()) {
|
||||||
LOG(ERROR) << "Unknown container type: " << nameWithoutTemplate;
|
LOG(ERROR) << "Unknown container type: " << nameWithoutTemplate;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const ContainerInfo& containerInfo = *optContainerInfo;
|
||||||
|
|
||||||
// Some containers will need special handling
|
// Some containers will need special handling
|
||||||
if (nameWithoutTemplate == "bimap<") {
|
if (nameWithoutTemplate == "bimap<") {
|
||||||
@ -373,12 +375,12 @@ void OICodeGen::replaceTemplateParameters(
|
|||||||
removeTemplateParamAtIndex(template_params_strings, 3);
|
removeTemplateParamAtIndex(template_params_strings, 3);
|
||||||
removeTemplateParamAtIndex(template_params_strings, 2);
|
removeTemplateParamAtIndex(template_params_strings, 2);
|
||||||
} else {
|
} else {
|
||||||
for (auto const& index : containerInfo->replaceTemplateParamIndex) {
|
for (auto const& index : containerInfo.replaceTemplateParamIndex) {
|
||||||
replaceTemplateOperator(template_params, template_params_strings, index);
|
replaceTemplateOperator(template_params, template_params_strings, index);
|
||||||
}
|
}
|
||||||
if (containerInfo->allocatorIndex) {
|
if (containerInfo.allocatorIndex) {
|
||||||
removeTemplateParamAtIndex(template_params_strings,
|
removeTemplateParamAtIndex(template_params_strings,
|
||||||
*containerInfo->allocatorIndex);
|
*containerInfo.allocatorIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -672,22 +674,23 @@ bool OICodeGen::getContainerTemplateParams(drgn_type* type, bool& ifStub) {
|
|||||||
}
|
}
|
||||||
typeName = transformTypeName(type, typeName);
|
typeName = transformTypeName(type, typeName);
|
||||||
|
|
||||||
auto containerInfo = getContainerInfo(type);
|
auto optContainerInfo = getContainerInfo(type);
|
||||||
if (!containerInfo.has_value()) {
|
if (!optContainerInfo.has_value()) {
|
||||||
LOG(ERROR) << "Unknown container type: " << typeName;
|
LOG(ERROR) << "Unknown container type: " << typeName;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
const ContainerInfo& containerInfo = *optContainerInfo;
|
||||||
|
|
||||||
std::vector<size_t> paramIdxs;
|
std::vector<size_t> paramIdxs;
|
||||||
if (containerInfo->underlyingContainerIndex.has_value()) {
|
if (containerInfo.underlyingContainerIndex.has_value()) {
|
||||||
if (containerInfo->numTemplateParams.has_value()) {
|
if (containerInfo.numTemplateParams.has_value()) {
|
||||||
LOG(ERROR) << "Container adapters should not enumerate their template "
|
LOG(ERROR) << "Container adapters should not enumerate their template "
|
||||||
"parameters";
|
"parameters";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
paramIdxs.push_back(*containerInfo->underlyingContainerIndex);
|
paramIdxs.push_back(*containerInfo.underlyingContainerIndex);
|
||||||
} else {
|
} else {
|
||||||
auto numTemplateParams = containerInfo->numTemplateParams;
|
auto numTemplateParams = containerInfo.numTemplateParams;
|
||||||
if (!numTemplateParams.has_value()) {
|
if (!numTemplateParams.has_value()) {
|
||||||
if (!drgn_type_has_template_parameters(type)) {
|
if (!drgn_type_has_template_parameters(type)) {
|
||||||
LOG(ERROR) << "Failed to find template params";
|
LOG(ERROR) << "Failed to find template params";
|
||||||
@ -703,7 +706,7 @@ bool OICodeGen::getContainerTemplateParams(drgn_type* type, bool& ifStub) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return enumerateTemplateParamIdxs(type, *containerInfo, paramIdxs, ifStub);
|
return enumerateTemplateParamIdxs(type, containerInfo, paramIdxs, ifStub);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OICodeGen::enumerateTemplateParamIdxs(drgn_type* type,
|
bool OICodeGen::enumerateTemplateParamIdxs(drgn_type* type,
|
||||||
@ -776,8 +779,8 @@ bool OICodeGen::enumerateTemplateParamIdxs(drgn_type* type,
|
|||||||
|
|
||||||
auto& templateTypes =
|
auto& templateTypes =
|
||||||
containerTypeMapDrgn
|
containerTypeMapDrgn
|
||||||
.emplace(type,
|
.emplace(type, std::pair(std::ref(containerInfo),
|
||||||
std::pair(containerInfo, std::vector<drgn_qualified_type>()))
|
std::vector<drgn_qualified_type>()))
|
||||||
.first->second.second;
|
.first->second.second;
|
||||||
|
|
||||||
for (auto i : paramIdxs) {
|
for (auto i : paramIdxs) {
|
||||||
@ -3011,7 +3014,7 @@ bool OICodeGen::generateJitCode(std::string& code) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::set<std::string> includedHeaders = config.defaultHeaders;
|
std::set<std::string> includedHeaders = config.defaultHeaders;
|
||||||
for (auto& e : containerTypesFuncDef) {
|
for (const ContainerInfo& e : containerTypesFuncDef) {
|
||||||
includedHeaders.insert(e.header);
|
includedHeaders.insert(e.header);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3070,7 +3073,7 @@ bool OICodeGen::generateJitCode(std::string& code) {
|
|||||||
definitionsCode.append("// namespace uses\n");
|
definitionsCode.append("// namespace uses\n");
|
||||||
|
|
||||||
std::set<std::string> usedNamespaces = config.defaultNamespaces;
|
std::set<std::string> usedNamespaces = config.defaultNamespaces;
|
||||||
for (const auto& v : containerTypesFuncDef) {
|
for (const ContainerInfo& v : containerTypesFuncDef) {
|
||||||
for (auto& e : v.ns) {
|
for (auto& e : v.ns) {
|
||||||
usedNamespaces.insert(std::string(e));
|
usedNamespaces.insert(std::string(e));
|
||||||
}
|
}
|
||||||
@ -3705,9 +3708,18 @@ void OICodeGen::setRootType(drgn_qualified_type rt) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TypeHierarchy OICodeGen::getTypeHierarchy() {
|
TypeHierarchy OICodeGen::getTypeHierarchy() {
|
||||||
|
std::map<
|
||||||
|
struct drgn_type*,
|
||||||
|
std::pair<ContainerTypeEnum, std::vector<struct drgn_qualified_type>>>
|
||||||
|
containerTypeMap;
|
||||||
|
for (auto const& [k, v] : containerTypeMapDrgn) {
|
||||||
|
const ContainerInfo& cinfo = v.first;
|
||||||
|
containerTypeMap[k] = {cinfo.ctype, v.second};
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
.classMembersMap = getClassMembersMap(),
|
.classMembersMap = getClassMembersMap(),
|
||||||
.containerTypeMap = containerTypeMapDrgn,
|
.containerTypeMap = std::move(containerTypeMap),
|
||||||
.typedefMap = typedefTypes,
|
.typedefMap = typedefTypes,
|
||||||
.sizeMap = sizeMap,
|
.sizeMap = sizeMap,
|
||||||
.knownDummyTypeList = knownDummyTypeList,
|
.knownDummyTypeList = knownDummyTypeList,
|
||||||
|
@ -114,8 +114,9 @@ class OICodeGen {
|
|||||||
Config config{};
|
Config config{};
|
||||||
FuncGen funcGen;
|
FuncGen funcGen;
|
||||||
|
|
||||||
using ContainerTypeMap =
|
using ContainerTypeMapEntry =
|
||||||
std::pair<ContainerInfo, std::vector<drgn_qualified_type>>;
|
std::pair<std::reference_wrapper<const ContainerInfo>,
|
||||||
|
std::vector<drgn_qualified_type>>;
|
||||||
|
|
||||||
using TemplateParamList =
|
using TemplateParamList =
|
||||||
std::vector<std::pair<drgn_qualified_type, std::string>>;
|
std::vector<std::pair<drgn_qualified_type, std::string>>;
|
||||||
@ -126,7 +127,7 @@ class OICodeGen {
|
|||||||
std::string linkageName;
|
std::string linkageName;
|
||||||
std::map<drgn_type*, std::string> unnamedUnion;
|
std::map<drgn_type*, std::string> unnamedUnion;
|
||||||
std::map<std::string, size_t> sizeMap;
|
std::map<std::string, size_t> sizeMap;
|
||||||
std::map<drgn_type*, ContainerTypeMap> containerTypeMapDrgn;
|
std::map<drgn_type*, ContainerTypeMapEntry> containerTypeMapDrgn;
|
||||||
std::vector<std::unique_ptr<ContainerInfo>> containerInfoList;
|
std::vector<std::unique_ptr<ContainerInfo>> containerInfoList;
|
||||||
std::vector<drgn_type*> enumTypes;
|
std::vector<drgn_type*> enumTypes;
|
||||||
std::vector<std::string> knownTypes;
|
std::vector<std::string> knownTypes;
|
||||||
@ -155,7 +156,7 @@ class OICodeGen {
|
|||||||
std::set<drgn_type*> thriftIssetStructTypes;
|
std::set<drgn_type*> thriftIssetStructTypes;
|
||||||
std::vector<drgn_type*> topoSortedStructTypes;
|
std::vector<drgn_type*> topoSortedStructTypes;
|
||||||
|
|
||||||
std::set<ContainerInfo> containerTypesFuncDef;
|
ContainerInfoRefSet containerTypesFuncDef;
|
||||||
|
|
||||||
std::map<std::string, PaddingInfo> paddedStructs;
|
std::map<std::string, PaddingInfo> paddedStructs;
|
||||||
|
|
||||||
@ -191,7 +192,8 @@ class OICodeGen {
|
|||||||
static SortedTypeDefMap getSortedTypeDefMap(
|
static SortedTypeDefMap getSortedTypeDefMap(
|
||||||
const std::map<drgn_type*, drgn_type*>& typedefTypeMap);
|
const std::map<drgn_type*, drgn_type*>& typedefTypeMap);
|
||||||
|
|
||||||
std::optional<ContainerInfo> getContainerInfo(drgn_type* type);
|
std::optional<std::reference_wrapper<const ContainerInfo>> getContainerInfo(
|
||||||
|
drgn_type* type);
|
||||||
void printAllTypes();
|
void printAllTypes();
|
||||||
void printAllTypeNames();
|
void printAllTypeNames();
|
||||||
|
|
||||||
|
@ -66,32 +66,6 @@ void serialize(Archive& ar, PaddingInfo& p, const unsigned int version) {
|
|||||||
|
|
||||||
INSTANCIATE_SERIALIZE(PaddingInfo)
|
INSTANCIATE_SERIALIZE(PaddingInfo)
|
||||||
|
|
||||||
template <class Archive>
|
|
||||||
void serialize(Archive& ar, ContainerInfo& info, const unsigned int version) {
|
|
||||||
verify_version<ContainerInfo>(version);
|
|
||||||
ar& info.typeName;
|
|
||||||
// Unfortunately boost serialization doesn't support `std::optional`,
|
|
||||||
// so we have to do this ourselves
|
|
||||||
size_t numTemplateParams = 0;
|
|
||||||
if (Archive::is_saving::value) {
|
|
||||||
numTemplateParams =
|
|
||||||
info.numTemplateParams.value_or(std::numeric_limits<size_t>::max());
|
|
||||||
}
|
|
||||||
ar& numTemplateParams;
|
|
||||||
if (Archive::is_loading::value) {
|
|
||||||
if (numTemplateParams == std::numeric_limits<size_t>::max()) {
|
|
||||||
info.numTemplateParams = std::nullopt;
|
|
||||||
} else {
|
|
||||||
info.numTemplateParams = numTemplateParams;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ar& info.ctype;
|
|
||||||
ar& info.header;
|
|
||||||
ar& info.ns;
|
|
||||||
}
|
|
||||||
|
|
||||||
INSTANCIATE_SERIALIZE(ContainerInfo)
|
|
||||||
|
|
||||||
template <class Archive>
|
template <class Archive>
|
||||||
void serialize(Archive& ar, struct drgn_location_description& location,
|
void serialize(Archive& ar, struct drgn_location_description& location,
|
||||||
const unsigned int version) {
|
const unsigned int version) {
|
||||||
|
@ -25,7 +25,6 @@
|
|||||||
#include <boost/serialization/vector.hpp>
|
#include <boost/serialization/vector.hpp>
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include "ContainerInfo.h"
|
|
||||||
#include "PaddingHunter.h"
|
#include "PaddingHunter.h"
|
||||||
#include "SymbolService.h"
|
#include "SymbolService.h"
|
||||||
|
|
||||||
@ -39,7 +38,6 @@
|
|||||||
BOOST_CLASS_VERSION(Type, version)
|
BOOST_CLASS_VERSION(Type, version)
|
||||||
|
|
||||||
DEFINE_TYPE_VERSION(PaddingInfo, 120, 3)
|
DEFINE_TYPE_VERSION(PaddingInfo, 120, 3)
|
||||||
DEFINE_TYPE_VERSION(ContainerInfo, 200, 5)
|
|
||||||
DEFINE_TYPE_VERSION(struct drgn_location_description, 32, 2)
|
DEFINE_TYPE_VERSION(struct drgn_location_description, 32, 2)
|
||||||
DEFINE_TYPE_VERSION(struct drgn_object_locator, 72, 2)
|
DEFINE_TYPE_VERSION(struct drgn_object_locator, 72, 2)
|
||||||
DEFINE_TYPE_VERSION(FuncDesc::Arg, 128, 2)
|
DEFINE_TYPE_VERSION(FuncDesc::Arg, 128, 2)
|
||||||
@ -51,7 +49,7 @@ DEFINE_TYPE_VERSION(struct drgn_type, 152, 4)
|
|||||||
DEFINE_TYPE_VERSION(DrgnClassMemberInfo, 64, 3)
|
DEFINE_TYPE_VERSION(DrgnClassMemberInfo, 64, 3)
|
||||||
DEFINE_TYPE_VERSION(struct drgn_qualified_type, 16, 2)
|
DEFINE_TYPE_VERSION(struct drgn_qualified_type, 16, 2)
|
||||||
DEFINE_TYPE_VERSION(RootInfo, 48, 2)
|
DEFINE_TYPE_VERSION(RootInfo, 48, 2)
|
||||||
DEFINE_TYPE_VERSION(TypeHierarchy, 384, 6)
|
DEFINE_TYPE_VERSION(TypeHierarchy, 384, 7)
|
||||||
|
|
||||||
#undef DEFINE_TYPE_VERSION
|
#undef DEFINE_TYPE_VERSION
|
||||||
|
|
||||||
@ -62,7 +60,6 @@ namespace boost::serialization {
|
|||||||
void serialize(Archive&, Type&, const unsigned int)
|
void serialize(Archive&, Type&, const unsigned int)
|
||||||
|
|
||||||
DECL_SERIALIZE(PaddingInfo);
|
DECL_SERIALIZE(PaddingInfo);
|
||||||
DECL_SERIALIZE(ContainerInfo);
|
|
||||||
|
|
||||||
DECL_SERIALIZE(FuncDesc::Arg);
|
DECL_SERIALIZE(FuncDesc::Arg);
|
||||||
DECL_SERIALIZE(FuncDesc);
|
DECL_SERIALIZE(FuncDesc);
|
||||||
|
@ -571,8 +571,8 @@ void TreeBuilder::processContainer(const Variable& variable, Node& node) {
|
|||||||
node.typeName + "'");
|
node.typeName + "'");
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& [containerInfo, templateTypes] = entry->second;
|
auto& [containerKind, templateTypes] = entry->second;
|
||||||
kind = containerInfo.ctype;
|
kind = containerKind;
|
||||||
for (const auto& tt : templateTypes) {
|
for (const auto& tt : templateTypes) {
|
||||||
elementTypes.push_back(tt);
|
elementTypes.push_back(tt);
|
||||||
}
|
}
|
||||||
|
@ -76,7 +76,7 @@ void printClassMembersMap(
|
|||||||
void printContainerTypeMap(
|
void printContainerTypeMap(
|
||||||
const std::map<
|
const std::map<
|
||||||
struct drgn_type*,
|
struct drgn_type*,
|
||||||
std::pair<ContainerInfo, std::vector<struct drgn_qualified_type>>>&
|
std::pair<ContainerTypeEnum, std::vector<struct drgn_qualified_type>>>&
|
||||||
containerTypeMap) {
|
containerTypeMap) {
|
||||||
printf("{");
|
printf("{");
|
||||||
bool isFirstItem = true;
|
bool isFirstItem = true;
|
||||||
|
Loading…
Reference in New Issue
Block a user