mirror of https://github.com/x64dbg/btparser
Switch to QualifiedType everywhere
This commit is contained in:
parent
659a8e87a6
commit
07a7b308e8
|
@ -110,7 +110,7 @@ bool DebugParser(const std::string & filename)
|
||||||
FileHelper::WriteAllText("tests\\" + filename + ".pp.h", ppData);
|
FileHelper::WriteAllText("tests\\" + filename + ".pp.h", ppData);
|
||||||
|
|
||||||
std::vector<std::string> errors;
|
std::vector<std::string> errors;
|
||||||
Types::TypeManager typeManager;
|
Types::TypeManager typeManager(sizeof(void*));
|
||||||
if (!typeManager.ParseTypes(ppData, filename, errors))
|
if (!typeManager.ParseTypes(ppData, filename, errors))
|
||||||
{
|
{
|
||||||
puts("Failed to parse types:");
|
puts("Failed to parse types:");
|
||||||
|
|
|
@ -9,7 +9,7 @@ using namespace Types;
|
||||||
#define EXCLUSIVE_ACQUIRE(x)
|
#define EXCLUSIVE_ACQUIRE(x)
|
||||||
#define SHARED_ACQUIRE(x)
|
#define SHARED_ACQUIRE(x)
|
||||||
|
|
||||||
TypeManager::TypeManager()
|
TypeManager::TypeManager(size_t pointerSize)
|
||||||
{
|
{
|
||||||
auto p = [this](const std::string & n, Primitive p, int size)
|
auto p = [this](const std::string & n, Primitive p, int size)
|
||||||
{
|
{
|
||||||
|
@ -21,21 +21,21 @@ TypeManager::TypeManager()
|
||||||
addType("", p, split);
|
addType("", p, split);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
p("int8_t,int8,char,byte,bool,signed char", Int8, sizeof(char));
|
p("int8_t,int8,char,byte,bool,signed char", Int8, sizeof(int8_t));
|
||||||
p("uint8_t,uint8,uchar,unsigned char,ubyte", Uint8, sizeof(unsigned char));
|
p("uint8_t,uint8,uchar,unsigned char,ubyte", Uint8, sizeof(uint8_t));
|
||||||
p("int16_t,int16,wchar_t,char16_t,short", Int16, sizeof(short));
|
p("int16_t,int16,wchar_t,char16_t,short", Int16, sizeof(int16_t));
|
||||||
p("uint16_t,uint16,ushort,unsigned short", Int16, sizeof(unsigned short));
|
p("uint16_t,uint16,ushort,unsigned short", Uint16, sizeof(uint16_t));
|
||||||
p("int32_t,int32,int,long", Int32, sizeof(int));
|
p("int32_t,int32,int,long", Int32, sizeof(int32_t));
|
||||||
p("uint32_t,uint32,unsigned int,unsigned long", Uint32, sizeof(unsigned int));
|
p("uint32_t,uint32,unsigned int,unsigned long", Uint32, sizeof(uint32_t));
|
||||||
p("int64_t,int64,long long", Int64, sizeof(long long));
|
p("int64_t,int64,long long", Int64, sizeof(int64_t));
|
||||||
p("uint64_t,uint64,unsigned long long", Uint64, sizeof(unsigned long long));
|
p("uint64_t,uint64,unsigned long long", Uint64, sizeof(uint64_t));
|
||||||
p("dsint", Dsint, sizeof(void*));
|
p("ssize_t,dsint", Dsint, pointerSize);
|
||||||
p("size_t,duint", Duint, sizeof(void*));
|
p("size_t,duint", Duint, pointerSize);
|
||||||
p("float", Float, sizeof(float));
|
p("float", Float, sizeof(float));
|
||||||
p("double", Double, sizeof(double));
|
p("double", Double, sizeof(double));
|
||||||
p("void*,ptr", Pointer, sizeof(void*));
|
p("void*,ptr", Pointer, pointerSize);
|
||||||
p("char*,const char*", PtrString, sizeof(char*));
|
p("char*,const char*", PtrString, pointerSize);
|
||||||
p("wchar_t*,const wchar_t*", PtrWString, sizeof(wchar_t*));
|
p("wchar_t*,const wchar_t*", PtrWString, pointerSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Types::TypeManager::PrimitiveName(Primitive primitive)
|
std::string Types::TypeManager::PrimitiveName(Primitive primitive)
|
||||||
|
@ -48,7 +48,6 @@ bool TypeManager::AddType(const std::string & owner, const std::string & type, c
|
||||||
{
|
{
|
||||||
if(owner.empty())
|
if(owner.empty())
|
||||||
return false;
|
return false;
|
||||||
validPtr(type);
|
|
||||||
auto found = types.find(type);
|
auto found = types.find(type);
|
||||||
if(found == types.end())
|
if(found == types.end())
|
||||||
return false;
|
return false;
|
||||||
|
@ -60,11 +59,10 @@ bool Types::TypeManager::AddEnum(const std::string& owner, const std::string& na
|
||||||
Enum e;
|
Enum e;
|
||||||
e.name = name;
|
e.name = name;
|
||||||
e.owner = owner;
|
e.owner = owner;
|
||||||
|
|
||||||
auto found = types.find(type);
|
auto found = types.find(type);
|
||||||
if (found == types.end())
|
if (found == types.end())
|
||||||
return false;
|
return false;
|
||||||
if (!found->second.pointto.empty())
|
|
||||||
return false;
|
|
||||||
switch (found->second.primitive)
|
switch (found->second.primitive)
|
||||||
{
|
{
|
||||||
case Void:
|
case Void:
|
||||||
|
@ -98,12 +96,12 @@ bool TypeManager::AddUnion(const std::string & owner, const std::string & name)
|
||||||
return addStructUnion(u);
|
return addStructUnion(u);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TypeManager::AddMember(const std::string & parent, const std::string & type, const std::string & name, int arrsize, int offset)
|
bool TypeManager::AddMember(const std::string & parent, const QualifiedType& type, const std::string & name, int arrsize, int offset)
|
||||||
{
|
{
|
||||||
if(!isDefined(type) && !validPtr(type))
|
if(!isDefined(type.name))
|
||||||
return false;
|
return false;
|
||||||
auto found = structs.find(parent);
|
auto found = structs.find(parent);
|
||||||
if(arrsize < 0 || found == structs.end() || !isDefined(type) || name.empty() || type.empty() || type == parent)
|
if(arrsize < 0 || found == structs.end() || name.empty() || type.empty() || type.name == parent)
|
||||||
return false;
|
return false;
|
||||||
auto & s = found->second;
|
auto & s = found->second;
|
||||||
|
|
||||||
|
@ -128,7 +126,7 @@ bool TypeManager::AddMember(const std::string & parent, const std::string & type
|
||||||
if(offset > s.size)
|
if(offset > s.size)
|
||||||
{
|
{
|
||||||
Member pad;
|
Member pad;
|
||||||
pad.type = "char";
|
pad.type = QualifiedType("char");
|
||||||
pad.arrsize = offset - s.size;
|
pad.arrsize = offset - s.size;
|
||||||
char padname[32] = "";
|
char padname[32] = "";
|
||||||
sprintf_s(padname, "padding%d", pad.arrsize);
|
sprintf_s(padname, "padding%d", pad.arrsize);
|
||||||
|
@ -152,7 +150,7 @@ bool TypeManager::AddMember(const std::string & parent, const std::string & type
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TypeManager::AppendMember(const std::string & type, const std::string & name, int arrsize, int offset)
|
bool TypeManager::AppendMember(const QualifiedType& type, const std::string & name, int arrsize, int offset)
|
||||||
{
|
{
|
||||||
return AddMember(laststruct, type, name, arrsize, offset);
|
return AddMember(laststruct, type, name, arrsize, offset);
|
||||||
}
|
}
|
||||||
|
@ -175,7 +173,7 @@ bool Types::TypeManager::AddEnumerator(const std::string& enumType, const std::s
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TypeManager::AddFunction(const std::string & owner, const std::string & name, const QualifiedType& retqtype, CallingConvention callconv, bool noreturn, bool typeonly)
|
bool TypeManager::AddFunction(const std::string & owner, const std::string & name, const QualifiedType& rettype, CallingConvention callconv, bool noreturn, bool typeonly)
|
||||||
{
|
{
|
||||||
auto found = functions.find(name);
|
auto found = functions.find(name);
|
||||||
if(found != functions.end() || name.empty() || owner.empty())
|
if(found != functions.end() || name.empty() || owner.empty())
|
||||||
|
@ -184,9 +182,10 @@ bool TypeManager::AddFunction(const std::string & owner, const std::string & nam
|
||||||
Function f;
|
Function f;
|
||||||
f.owner = owner;
|
f.owner = owner;
|
||||||
f.name = name;
|
f.name = name;
|
||||||
if (retqtype.name != "void" && !isDefined(retqtype.name))
|
auto isVoid = !rettype.isPointer() && rettype.name == "void";
|
||||||
|
if (!isVoid && !isDefined(rettype))
|
||||||
return false;
|
return false;
|
||||||
f.retqtype = retqtype;
|
f.rettype = rettype;
|
||||||
f.callconv = callconv;
|
f.callconv = callconv;
|
||||||
f.noreturn = noreturn;
|
f.noreturn = noreturn;
|
||||||
f.typeonly = typeonly;
|
f.typeonly = typeonly;
|
||||||
|
@ -194,28 +193,27 @@ bool TypeManager::AddFunction(const std::string & owner, const std::string & nam
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TypeManager::AddArg(const std::string & function, const std::string & type, const std::string & name, const QualifiedType& qtype)
|
bool TypeManager::AddArg(const std::string & function, const QualifiedType& type, const std::string & name)
|
||||||
{
|
{
|
||||||
auto found = functions.find(function);
|
auto found = functions.find(function);
|
||||||
if (found == functions.end() || name.empty())
|
if (found == functions.end() || name.empty())
|
||||||
return false;
|
return false;
|
||||||
if(type != "..." && !isDefined(type) && !validPtr(type))
|
if(type.name != "..." && !isDefined(type))
|
||||||
return false;
|
return false;
|
||||||
lastfunction = function;
|
lastfunction = function;
|
||||||
Member arg;
|
Member arg;
|
||||||
arg.name = name;
|
arg.name = name;
|
||||||
arg.type = type;
|
arg.type = type;
|
||||||
arg.qtype = qtype;
|
|
||||||
found->second.args.push_back(arg);
|
found->second.args.push_back(arg);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TypeManager::AppendArg(const std::string & type, const std::string & name, const QualifiedType& qtype)
|
bool TypeManager::AppendArg(const QualifiedType& type, const std::string & name)
|
||||||
{
|
{
|
||||||
return AddArg(lastfunction, type, name, qtype);
|
return AddArg(lastfunction, type, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
int TypeManager::Sizeof(const std::string & type) const
|
int TypeManager::Sizeof(const std::string& type) const
|
||||||
{
|
{
|
||||||
auto foundT = types.find(type);
|
auto foundT = types.find(type);
|
||||||
if(foundT != types.end())
|
if(foundT != types.end())
|
||||||
|
@ -224,21 +222,23 @@ int TypeManager::Sizeof(const std::string & type) const
|
||||||
if(foundS != structs.end())
|
if(foundS != structs.end())
|
||||||
return foundS->second.size;
|
return foundS->second.size;
|
||||||
auto foundF = functions.find(type);
|
auto foundF = functions.find(type);
|
||||||
if(foundF != functions.end())
|
if (foundF != functions.end())
|
||||||
{
|
return primitivesizes.at(Pointer);
|
||||||
const auto foundP = primitivesizes.find(Pointer);
|
|
||||||
if(foundP != primitivesizes.end())
|
|
||||||
return foundP->second;
|
|
||||||
return sizeof(void*);
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int TypeManager::Sizeof(const QualifiedType& type) const
|
||||||
|
{
|
||||||
|
if (type.isPointer())
|
||||||
|
return primitivesizes.at(Pointer);
|
||||||
|
return Sizeof(type.name);
|
||||||
|
}
|
||||||
|
|
||||||
bool TypeManager::Visit(const std::string & type, const std::string & name, Visitor & visitor) const
|
bool TypeManager::Visit(const std::string & type, const std::string & name, Visitor & visitor) const
|
||||||
{
|
{
|
||||||
Member m;
|
Member m;
|
||||||
m.name = name;
|
m.name = name;
|
||||||
m.type = type;
|
m.type = QualifiedType(type);
|
||||||
return visitMember(m, visitor);
|
return visitMember(m, visitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -363,30 +363,18 @@ static bool mapContains(const std::unordered_map<K, V> & map, const K & k)
|
||||||
return map.find(k) != map.end();
|
return map.find(k) != map.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Types::TypeManager::isDefined(const QualifiedType& type) const
|
||||||
|
{
|
||||||
|
if (type.name == "void" && type.isPointer())
|
||||||
|
return true;
|
||||||
|
return isDefined(type.name);
|
||||||
|
}
|
||||||
|
|
||||||
bool TypeManager::isDefined(const std::string & id) const
|
bool TypeManager::isDefined(const std::string & id) const
|
||||||
{
|
{
|
||||||
return mapContains(types, id) || mapContains(structs, id) || mapContains(enums, id) || mapContains(functions, id);
|
return mapContains(types, id) || mapContains(structs, id) || mapContains(enums, id) || mapContains(functions, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TypeManager::validPtr(const std::string & id)
|
|
||||||
{
|
|
||||||
if(id[id.length() - 1] == '*')
|
|
||||||
{
|
|
||||||
auto type = id.substr(0, id.length() - 1);
|
|
||||||
if(!isDefined(type) && !validPtr(type))
|
|
||||||
return false;
|
|
||||||
std::string owner("ptr");
|
|
||||||
auto foundT = types.find(type);
|
|
||||||
if(foundT != types.end())
|
|
||||||
owner = foundT->second.owner;
|
|
||||||
auto foundS = structs.find(type);
|
|
||||||
if(foundS != structs.end())
|
|
||||||
owner = foundS->second.owner;
|
|
||||||
return addType(owner, Pointer, id, type);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TypeManager::addStructUnion(const StructUnion & s)
|
bool TypeManager::addStructUnion(const StructUnion & s)
|
||||||
{
|
{
|
||||||
laststruct = s.name;
|
laststruct = s.name;
|
||||||
|
@ -410,7 +398,7 @@ bool TypeManager::addType(const Type & t)
|
||||||
return types.emplace(t.name, t).second;
|
return types.emplace(t.name, t).second;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TypeManager::addType(const std::string & owner, Primitive primitive, const std::string & name, const std::string & pointto)
|
bool TypeManager::addType(const std::string & owner, Primitive primitive, const std::string & name)
|
||||||
{
|
{
|
||||||
if(name.empty() || isDefined(name))
|
if(name.empty() || isDefined(name))
|
||||||
return false;
|
return false;
|
||||||
|
@ -419,16 +407,19 @@ bool TypeManager::addType(const std::string & owner, Primitive primitive, const
|
||||||
t.name = name;
|
t.name = name;
|
||||||
t.primitive = primitive;
|
t.primitive = primitive;
|
||||||
t.size = primitivesizes[primitive];
|
t.size = primitivesizes[primitive];
|
||||||
t.pointto = pointto;
|
|
||||||
return addType(t);
|
return addType(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TypeManager::visitMember(const Member & root, Visitor & visitor) const
|
bool TypeManager::visitMember(const Member & root, Visitor & visitor) const
|
||||||
{
|
{
|
||||||
auto foundT = types.find(root.type);
|
auto foundT = types.find(root.type.name);
|
||||||
if(foundT != types.end())
|
if(foundT != types.end())
|
||||||
{
|
{
|
||||||
const auto & t = foundT->second;
|
const auto & t = foundT->second;
|
||||||
|
// TODO: add back pointer support
|
||||||
|
if (root.type.isPointer())
|
||||||
|
__debugbreak();
|
||||||
|
#if 0
|
||||||
if(!t.pointto.empty())
|
if(!t.pointto.empty())
|
||||||
{
|
{
|
||||||
if(!isDefined(t.pointto))
|
if(!isDefined(t.pointto))
|
||||||
|
@ -441,9 +432,10 @@ bool TypeManager::visitMember(const Member & root, Visitor & visitor) const
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return visitor.visitType(root, t);
|
return visitor.visitType(root, t);
|
||||||
}
|
}
|
||||||
auto foundS = structs.find(root.type);
|
auto foundS = structs.find(root.type.name);
|
||||||
if(foundS != structs.end())
|
if(foundS != structs.end())
|
||||||
{
|
{
|
||||||
const auto & s = foundS->second;
|
const auto & s = foundS->second;
|
||||||
|
@ -475,17 +467,17 @@ bool TypeManager::GenerateStubs() const
|
||||||
std::unordered_set<std::string> declared;
|
std::unordered_set<std::string> declared;
|
||||||
auto formatFunctionPointer = [this](const std::string& name, const Function& fn)
|
auto formatFunctionPointer = [this](const std::string& name, const Function& fn)
|
||||||
{
|
{
|
||||||
std::string r = fn.retqtype.pretty();
|
std::string r = fn.rettype.pretty();
|
||||||
r += " (*";
|
r += " (*";
|
||||||
r += name;
|
r += name;
|
||||||
r += ")(";
|
r += ")(";
|
||||||
for(size_t i = 0; i < fn.args.size(); i++)
|
for(size_t i = 0; i < fn.args.size(); i++)
|
||||||
{
|
{
|
||||||
const auto& arg = fn.args[i];
|
const auto& arg = fn.args[i];
|
||||||
if(functions.count(arg.type) != 0)
|
if(functions.count(arg.type.name) != 0)
|
||||||
__debugbreak();
|
__debugbreak();
|
||||||
|
|
||||||
r += arg.qtype.pretty();
|
r += arg.type.pretty();
|
||||||
if(i + 1 < fn.args.size())
|
if(i + 1 < fn.args.size())
|
||||||
{
|
{
|
||||||
r += ", ";
|
r += ", ";
|
||||||
|
@ -513,7 +505,7 @@ bool TypeManager::GenerateStubs() const
|
||||||
auto variadic = false;
|
auto variadic = false;
|
||||||
for (const auto &arg: fn.args)
|
for (const auto &arg: fn.args)
|
||||||
{
|
{
|
||||||
if (arg.type == "...")
|
if (arg.type.name == "...")
|
||||||
{
|
{
|
||||||
variadic = true;
|
variadic = true;
|
||||||
break;
|
break;
|
||||||
|
@ -539,25 +531,25 @@ bool TypeManager::GenerateStubs() const
|
||||||
const auto& fn = functions.at(hook);
|
const auto& fn = functions.at(hook);
|
||||||
puts("");
|
puts("");
|
||||||
printf("static ");
|
printf("static ");
|
||||||
printf("%s", fn.retqtype.pretty().c_str());
|
printf("%s", fn.rettype.pretty().c_str());
|
||||||
printf(" hook_%s(\n", fn.name.c_str());
|
printf(" hook_%s(\n", fn.name.c_str());
|
||||||
std::vector<std::string> argtypes;
|
std::vector<std::string> argtypes;
|
||||||
for(size_t i = 0; i < fn.args.size(); i++)
|
for(size_t i = 0; i < fn.args.size(); i++)
|
||||||
{
|
{
|
||||||
const auto& arg = fn.args[i];
|
const auto& arg = fn.args[i];
|
||||||
printf(" ");
|
printf(" ");
|
||||||
auto argPtr = functions.find(arg.type);
|
auto argPtr = functions.find(arg.type.name);
|
||||||
if(argPtr != functions.end())
|
if(argPtr != functions.end())
|
||||||
{
|
{
|
||||||
argtypes.push_back(formatFunctionPointer(arg.name, argPtr->second));
|
argtypes.push_back(formatFunctionPointer(arg.name, argPtr->second));
|
||||||
printf("%s", argtypes.back().c_str());
|
printf("%s", argtypes.back().c_str());
|
||||||
if(arg.qtype.isConst)
|
if(arg.type.isConst)
|
||||||
__debugbreak();
|
__debugbreak();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
argtypes.push_back(arg.type);
|
argtypes.push_back(arg.type.pretty());
|
||||||
printf("%s", arg.qtype.pretty().c_str());
|
printf("%s", arg.type.pretty().c_str());
|
||||||
printf(" ");
|
printf(" ");
|
||||||
printf("%s", arg.name.c_str());
|
printf("%s", arg.name.c_str());
|
||||||
}
|
}
|
||||||
|
@ -574,7 +566,7 @@ bool TypeManager::GenerateStubs() const
|
||||||
{
|
{
|
||||||
printf(" LOG_ARGUMENT(\"%s\", %s);\n", argtypes[i].c_str(), fn.args[i].name.c_str());
|
printf(" LOG_ARGUMENT(\"%s\", %s);\n", argtypes[i].c_str(), fn.args[i].name.c_str());
|
||||||
}
|
}
|
||||||
if(fn.retqtype.name == "void")
|
if(fn.rettype.name == "void")
|
||||||
{
|
{
|
||||||
printf(" orig_%s(", fn.name.c_str());
|
printf(" orig_%s(", fn.name.c_str());
|
||||||
}
|
}
|
||||||
|
@ -592,7 +584,7 @@ bool TypeManager::GenerateStubs() const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
puts(");");
|
puts(");");
|
||||||
if(fn.retqtype.name == "void")
|
if(fn.rettype.name == "void")
|
||||||
{
|
{
|
||||||
puts(" LOG_RETURN_VOID();");
|
puts(" LOG_RETURN_VOID();");
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,6 @@ namespace Types
|
||||||
{
|
{
|
||||||
std::string owner; //Type owner
|
std::string owner; //Type owner
|
||||||
std::string name; //Type identifier.
|
std::string name; //Type identifier.
|
||||||
std::string pointto; //Type identifier of *Type (empty when the type is a primitive type)
|
|
||||||
Primitive primitive = Void; //Primitive type.
|
Primitive primitive = Void; //Primitive type.
|
||||||
int size = 0; //Size in bytes.
|
int size = 0; //Size in bytes.
|
||||||
};
|
};
|
||||||
|
@ -41,6 +40,12 @@ namespace Types
|
||||||
std::string name; // base name of the type
|
std::string name; // base name of the type
|
||||||
bool isConst = false; // whether the base type is const
|
bool isConst = false; // whether the base type is const
|
||||||
|
|
||||||
|
QualifiedType() = default;
|
||||||
|
explicit QualifiedType(const std::string& name)
|
||||||
|
: name(name)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
struct Ptr
|
struct Ptr
|
||||||
{
|
{
|
||||||
bool isConst = false;
|
bool isConst = false;
|
||||||
|
@ -70,13 +75,22 @@ namespace Types
|
||||||
r += '*';
|
r += '*';
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool empty() const
|
||||||
|
{
|
||||||
|
return name.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isPointer() const
|
||||||
|
{
|
||||||
|
return !pointers.empty();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Member
|
struct Member
|
||||||
{
|
{
|
||||||
std::string name; //Member identifier
|
std::string name; //Member identifier
|
||||||
std::string type; //Type.name
|
QualifiedType type; // Qualified Type
|
||||||
QualifiedType qtype; // Qualified Type
|
|
||||||
int arrsize = 0; //Number of elements if Member is an array (unused for function arguments)
|
int arrsize = 0; //Number of elements if Member is an array (unused for function arguments)
|
||||||
int offset = -1; //Member offset (only stored for reference)
|
int offset = -1; //Member offset (only stored for reference)
|
||||||
};
|
};
|
||||||
|
@ -94,7 +108,7 @@ namespace Types
|
||||||
{
|
{
|
||||||
std::string owner; //Function owner
|
std::string owner; //Function owner
|
||||||
std::string name; //Function identifier
|
std::string name; //Function identifier
|
||||||
QualifiedType retqtype; // Function return type
|
QualifiedType rettype; // Function return type
|
||||||
CallingConvention callconv = DefaultDecl; //Function calling convention
|
CallingConvention callconv = DefaultDecl; //Function calling convention
|
||||||
bool noreturn = false; //Function does not return (ExitProcess, _exit)
|
bool noreturn = false; //Function does not return (ExitProcess, _exit)
|
||||||
bool typeonly = false; //Function is only used as a type (the name is based on where it's used)
|
bool typeonly = false; //Function is only used as a type (the name is based on where it's used)
|
||||||
|
@ -153,19 +167,20 @@ namespace Types
|
||||||
int size = 0;
|
int size = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit TypeManager();
|
explicit TypeManager(size_t pointerSize);
|
||||||
std::string PrimitiveName(Primitive primitive);
|
std::string PrimitiveName(Primitive primitive);
|
||||||
bool AddType(const std::string & owner, const std::string & type, const std::string & name);
|
bool AddType(const std::string & owner, const std::string & type, const std::string & name);
|
||||||
bool AddEnum(const std::string& owner, const std::string& name, const std::string & type);
|
bool AddEnum(const std::string& owner, const std::string& name, const std::string & type);
|
||||||
bool AddStruct(const std::string & owner, const std::string & name);
|
bool AddStruct(const std::string & owner, const std::string & name);
|
||||||
bool AddUnion(const std::string & owner, const std::string & name);
|
bool AddUnion(const std::string & owner, const std::string & name);
|
||||||
bool AddMember(const std::string & parent, const std::string & type, const std::string & name, int arrsize = 0, int offset = -1);
|
bool AddMember(const std::string & parent, const QualifiedType & type, const std::string & name, int arrsize = 0, int offset = -1);
|
||||||
bool AppendMember(const std::string & type, const std::string & name, int arrsize = 0, int offset = -1);
|
bool AppendMember(const QualifiedType & type, const std::string & name, int arrsize = 0, int offset = -1);
|
||||||
bool AddFunction(const std::string & owner, const std::string & name, const QualifiedType& retqtype, CallingConvention callconv = Cdecl, bool noreturn = false, bool typeonly = false);
|
bool AddFunction(const std::string & owner, const std::string & name, const QualifiedType& rettype, CallingConvention callconv = Cdecl, bool noreturn = false, bool typeonly = false);
|
||||||
bool AddEnumerator(const std::string& enumType, const std::string& name, uint64_t value);
|
bool AddEnumerator(const std::string& enumType, const std::string& name, uint64_t value);
|
||||||
bool AddArg(const std::string & function, const std::string & type, const std::string & name, const QualifiedType& qtype);
|
bool AddArg(const std::string & function, const QualifiedType & type, const std::string & name);
|
||||||
bool AppendArg(const std::string & type, const std::string & name, const QualifiedType& qtype);
|
bool AppendArg(const QualifiedType& type, const std::string & name);
|
||||||
int Sizeof(const std::string & type) const;
|
int Sizeof(const QualifiedType& type) const;
|
||||||
|
int Sizeof(const std::string& type) const;
|
||||||
bool Visit(const std::string & type, const std::string & name, Visitor & visitor) const;
|
bool Visit(const std::string & type, const std::string & name, Visitor & visitor) const;
|
||||||
void Clear(const std::string & owner = "");
|
void Clear(const std::string & owner = "");
|
||||||
bool RemoveType(const std::string & type);
|
bool RemoveType(const std::string & type);
|
||||||
|
@ -186,11 +201,11 @@ namespace Types
|
||||||
std::string laststruct;
|
std::string laststruct;
|
||||||
std::string lastfunction;
|
std::string lastfunction;
|
||||||
|
|
||||||
|
bool isDefined(const QualifiedType& type) const;
|
||||||
bool isDefined(const std::string & id) const;
|
bool isDefined(const std::string & id) const;
|
||||||
bool validPtr(const std::string & id);
|
|
||||||
bool addStructUnion(const StructUnion & s);
|
bool addStructUnion(const StructUnion & s);
|
||||||
bool addEnum(const Enum& e);
|
bool addEnum(const Enum& e);
|
||||||
bool addType(const std::string & owner, Primitive primitive, const std::string & name, const std::string & pointto = "");
|
bool addType(const std::string & owner, Primitive primitive, const std::string & name);
|
||||||
bool addType(const Type & t);
|
bool addType(const Type & t);
|
||||||
bool visitMember(const Member & root, Visitor & visitor) const;
|
bool visitMember(const Member & root, Visitor & visitor) const;
|
||||||
};
|
};
|
||||||
|
|
|
@ -78,10 +78,10 @@ struct Parser
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool parseVariable(const std::vector<Lexer::TokenState>& tlist, QualifiedType& qtype, std::string& name)
|
bool parseVariable(const std::vector<Lexer::TokenState>& tlist, QualifiedType& type, std::string& name)
|
||||||
{
|
{
|
||||||
std::string type; // TODO: get rid of this variable
|
std::string stype; // TODO: get rid of this variable
|
||||||
qtype = QualifiedType();
|
type = QualifiedType();
|
||||||
name.clear();
|
name.clear();
|
||||||
|
|
||||||
bool sawPointer = false;
|
bool sawPointer = false;
|
||||||
|
@ -92,10 +92,10 @@ struct Parser
|
||||||
const auto& t = tlist[i];
|
const auto& t = tlist[i];
|
||||||
if (t.Is(Lexer::tok_const))
|
if (t.Is(Lexer::tok_const))
|
||||||
{
|
{
|
||||||
if(i == 0 || qtype.pointers.empty())
|
if(i == 0 || type.pointers.empty())
|
||||||
qtype.isConst = true;
|
type.isConst = true;
|
||||||
else
|
else
|
||||||
qtype.pointers.back().isConst = true;
|
type.pointers.back().isConst = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,9 +109,9 @@ struct Parser
|
||||||
{
|
{
|
||||||
if (isKeyword)
|
if (isKeyword)
|
||||||
{
|
{
|
||||||
if (!type.empty())
|
if (!stype.empty())
|
||||||
type += ' ';
|
stype += ' ';
|
||||||
type += lexer.TokString(t);
|
stype += lexer.TokString(t);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -121,9 +121,9 @@ struct Parser
|
||||||
}
|
}
|
||||||
else if (t.Is(Lexer::tok_identifier))
|
else if (t.Is(Lexer::tok_identifier))
|
||||||
{
|
{
|
||||||
if (type.empty())
|
if (stype.empty())
|
||||||
{
|
{
|
||||||
type = t.IdentifierStr;
|
stype = t.IdentifierStr;
|
||||||
}
|
}
|
||||||
else if (i + 1 == tlist.size())
|
else if (i + 1 == tlist.size())
|
||||||
{
|
{
|
||||||
|
@ -137,25 +137,25 @@ struct Parser
|
||||||
}
|
}
|
||||||
else if (t.Is(Lexer::tok_op_mul) || t.Is(Lexer::tok_op_and))
|
else if (t.Is(Lexer::tok_op_mul) || t.Is(Lexer::tok_op_and))
|
||||||
{
|
{
|
||||||
if (type.empty())
|
if (stype.empty())
|
||||||
{
|
{
|
||||||
errLine(t, "unexpected * in type");
|
errLine(t, "unexpected * in type");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sawPointer && type.back() != '*')
|
if (sawPointer && stype.back() != '*')
|
||||||
{
|
{
|
||||||
errLine(t, "unexpected * in type");
|
errLine(t, "unexpected * in type");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!sawPointer)
|
if(!sawPointer)
|
||||||
qtype.name = type;
|
type.name = stype;
|
||||||
|
|
||||||
qtype.pointers.emplace_back();
|
type.pointers.emplace_back();
|
||||||
|
|
||||||
// Apply the pointer to the type on the left
|
// Apply the pointer to the type on the left
|
||||||
type += '*';
|
stype += '*';
|
||||||
sawPointer = true;
|
sawPointer = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -164,10 +164,10 @@ struct Parser
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (type.empty())
|
if (stype.empty())
|
||||||
__debugbreak();
|
__debugbreak();
|
||||||
if(!sawPointer)
|
if(!sawPointer)
|
||||||
qtype.name = type;
|
type.name = stype;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,7 +182,7 @@ struct Parser
|
||||||
// TODO: calling conventions
|
// TODO: calling conventions
|
||||||
|
|
||||||
std::string retname;
|
std::string retname;
|
||||||
if (!parseVariable(rettypes, fn.retqtype, retname))
|
if (!parseVariable(rettypes, fn.rettype, retname))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (ptr)
|
if (ptr)
|
||||||
|
@ -248,9 +248,8 @@ struct Parser
|
||||||
auto finalizeArgument = [&]()
|
auto finalizeArgument = [&]()
|
||||||
{
|
{
|
||||||
Member am;
|
Member am;
|
||||||
if (!parseVariable(tlist, am.qtype, am.name))
|
if (!parseVariable(tlist, am.type, am.name))
|
||||||
return false;
|
return false;
|
||||||
am.type = am.qtype.noconst(); // TODO: remove
|
|
||||||
fn.args.push_back(am);
|
fn.args.push_back(am);
|
||||||
tlist.clear();
|
tlist.clear();
|
||||||
startToken = curToken();
|
startToken = curToken();
|
||||||
|
@ -336,7 +335,7 @@ struct Parser
|
||||||
}
|
}
|
||||||
|
|
||||||
Member am;
|
Member am;
|
||||||
am.type = "...";
|
am.type = QualifiedType("...");
|
||||||
fn.args.push_back(am);
|
fn.args.push_back(am);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -413,11 +412,10 @@ struct Parser
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!parseVariable(tlist, m.qtype, m.name))
|
if (!parseVariable(tlist, m.type, m.name))
|
||||||
return false;
|
return false;
|
||||||
m.type = m.qtype.noconst();
|
|
||||||
|
|
||||||
if (m.type == "void")
|
if (m.type.name == "void" && !m.type.isPointer())
|
||||||
{
|
{
|
||||||
errLine(startToken, "void is not a valid member type");
|
errLine(startToken, "void is not a valid member type");
|
||||||
return false;
|
return false;
|
||||||
|
@ -882,9 +880,8 @@ struct Parser
|
||||||
}
|
}
|
||||||
|
|
||||||
Member tm;
|
Member tm;
|
||||||
if (!parseVariable(tlist, tm.qtype, tm.name))
|
if (!parseVariable(tlist, tm.type, tm.name))
|
||||||
return false;
|
return false;
|
||||||
tm.type = tm.qtype.noconst();
|
|
||||||
model.types.push_back(tm);
|
model.types.push_back(tm);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -1033,11 +1030,14 @@ struct Parser
|
||||||
//Add simple typedefs
|
//Add simple typedefs
|
||||||
for (auto& type : model.types)
|
for (auto& type : model.types)
|
||||||
{
|
{
|
||||||
auto success = typeManager.AddType(owner, type.type, type.name);
|
// TODO: support pointers
|
||||||
|
if (type.type.isPointer() || type.type.isConst)
|
||||||
|
__debugbreak();
|
||||||
|
auto success = typeManager.AddType(owner, type.type.name, type.name);
|
||||||
if (!success)
|
if (!success)
|
||||||
{
|
{
|
||||||
//TODO properly handle errors
|
//TODO properly handle errors
|
||||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Failed to add typedef %s %s;\n"), type.type.c_str(), type.name.c_str());
|
dprintf(QT_TRANSLATE_NOOP("DBG", "Failed to add typedef %s %s;\n"), type.type.pretty().c_str(), type.name.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1067,11 +1067,11 @@ struct Parser
|
||||||
//Add base function types to avoid errors later
|
//Add base function types to avoid errors later
|
||||||
for (auto& function : model.functions)
|
for (auto& function : model.functions)
|
||||||
{
|
{
|
||||||
auto success = typeManager.AddFunction(owner, function.name, function.retqtype, function.callconv, function.noreturn, function.typeonly);
|
auto success = typeManager.AddFunction(owner, function.name, function.rettype, function.callconv, function.noreturn, function.typeonly);
|
||||||
if (!success)
|
if (!success)
|
||||||
{
|
{
|
||||||
//TODO properly handle errors
|
//TODO properly handle errors
|
||||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Failed to add function %s %s()\n"), function.retqtype.pretty().c_str(), function.name.c_str());
|
dprintf(QT_TRANSLATE_NOOP("DBG", "Failed to add function %s %s()\n"), function.rettype.pretty().c_str(), function.name.c_str());
|
||||||
function.name.clear(); //signal error
|
function.name.clear(); //signal error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1087,7 +1087,7 @@ struct Parser
|
||||||
if (!success)
|
if (!success)
|
||||||
{
|
{
|
||||||
//TODO properly handle errors
|
//TODO properly handle errors
|
||||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Failed to add member %s %s.%s;\n"), member.type.c_str(), su.name.c_str(), member.name.c_str());
|
dprintf(QT_TRANSLATE_NOOP("DBG", "Failed to add member %s %s.%s;\n"), member.type.pretty().c_str(), su.name.c_str(), member.name.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1102,11 +1102,11 @@ struct Parser
|
||||||
auto& arg = function.args[i];
|
auto& arg = function.args[i];
|
||||||
if (arg.name.empty())
|
if (arg.name.empty())
|
||||||
arg.name = "__unnamed_arg_" + std::to_string(i);
|
arg.name = "__unnamed_arg_" + std::to_string(i);
|
||||||
auto success = typeManager.AddArg(function.name, arg.type, arg.name, arg.qtype);
|
auto success = typeManager.AddArg(function.name, arg.type, arg.name);
|
||||||
if (!success)
|
if (!success)
|
||||||
{
|
{
|
||||||
//TODO properly handle errors
|
//TODO properly handle errors
|
||||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Failed to add argument %s[%zu]: %s %s;\n"), function.name.c_str(), i, arg.type.c_str(), arg.name.c_str());
|
dprintf(QT_TRANSLATE_NOOP("DBG", "Failed to add argument %s[%zu]: %s %s;\n"), function.name.c_str(), i, arg.type.pretty().c_str(), arg.name.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue