Switch to QualifiedType everywhere

This commit is contained in:
Duncan Ogilvie 2023-04-06 10:25:13 +02:00
parent 659a8e87a6
commit 07a7b308e8
4 changed files with 128 additions and 121 deletions

View File

@ -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:");

View File

@ -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();");
} }

View File

@ -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;
}; };

View File

@ -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());
} }
} }
} }