mirror of
https://github.com/mappu/miqt.git
synced 2024-12-22 08:58:37 +00:00
genbindings: preserve const/ptr attributes through typedefs
This commit is contained in:
parent
db09326a76
commit
eae85ac325
@ -84,11 +84,19 @@ func (p CppParameter) RenderTypeCabi() string {
|
||||
ret += "*"
|
||||
}
|
||||
|
||||
return ret // ignore const
|
||||
return ret
|
||||
}
|
||||
|
||||
// RenderTypeQtCpp renders the Qt C++ type in the original form from the function
|
||||
// definition, before any typedefs or transformations were applied.
|
||||
func (p CppParameter) RenderTypeQtCpp() string {
|
||||
cppType := p.GetQtCppType()
|
||||
return p.GetQtCppType().RenderTypeIntermediateCpp()
|
||||
}
|
||||
|
||||
// RenderTypeIntermediateCpp renders the Qt C++ type WITHOUT resolving the
|
||||
// interior QtCppOriginalType. This is used for intermediate const_cast<>s.
|
||||
func (p CppParameter) RenderTypeIntermediateCpp() string {
|
||||
cppType := p.ParameterType
|
||||
|
||||
if p.Const {
|
||||
cppType = "const " + cppType
|
||||
@ -178,9 +186,13 @@ func emitParametersCABI2CppForwarding(params []CppParameter, indent string) (pre
|
||||
return preamble, strings.Join(tmp, ", ")
|
||||
}
|
||||
|
||||
func makeNamePrefix(in string) string {
|
||||
return strings.Replace(strings.Replace(in, `[`, `_`, -1), `]`, "", -1)
|
||||
}
|
||||
|
||||
func emitCABI2CppForwarding(p CppParameter, indent string) (preamble string, forwarding string) {
|
||||
|
||||
nameprefix := strings.Replace(strings.Replace(p.ParameterName, `[`, `_`, -1), `]`, "", -1)
|
||||
nameprefix := makeNamePrefix(p.ParameterName)
|
||||
|
||||
if p.ParameterType == "QString" {
|
||||
// The CABI has accepted two parameters - need to convert to one real QString
|
||||
@ -204,17 +216,7 @@ func emitCABI2CppForwarding(p CppParameter, indent string) (preamble string, for
|
||||
preamble += indent + "}\n"
|
||||
return preamble, nameprefix + "_QList"
|
||||
|
||||
} else if p.IsKnownEnum() {
|
||||
// The enums are projected in CABI as their underlying int types.
|
||||
// Cast to the Qt enum type so that we get the correct overload
|
||||
return preamble, "static_cast<" + p.RenderTypeQtCpp() + ">(" + p.ParameterName + ")"
|
||||
|
||||
} else if p.IsFlagType() {
|
||||
return preamble, "static_cast<" + p.RenderTypeQtCpp() + ">(" + p.ParameterName + ")"
|
||||
|
||||
} else if p.IntType() {
|
||||
// Use the raw ParameterType to select an explicit integer overload
|
||||
// Don't use RenderTypeCabi() since it canonicalizes some int types for CABI
|
||||
} else if p.IntType() || p.IsFlagType() || p.IsKnownEnum() {
|
||||
castSrc := p.ParameterName
|
||||
castType := p.RenderTypeQtCpp()
|
||||
|
||||
@ -222,6 +224,10 @@ func emitCABI2CppForwarding(p CppParameter, indent string) (preamble string, for
|
||||
castSrc = "*" + castSrc
|
||||
}
|
||||
|
||||
if p.QtCppOriginalType != nil && p.QtCppOriginalType.Const != p.Const {
|
||||
return preamble, "static_cast<" + p.RenderTypeQtCpp() + ">(const_cast<" + p.RenderTypeIntermediateCpp() + ">(" + p.ParameterName + "))"
|
||||
}
|
||||
|
||||
if p.ParameterType == "qint64" ||
|
||||
p.ParameterType == "quint64" ||
|
||||
p.ParameterType == "qlonglong" ||
|
||||
@ -283,7 +289,7 @@ func emitAssignCppToCabi(assignExpression string, p CppParameter, rvalue string)
|
||||
|
||||
shouldReturn = shouldReturn[len(indent):]
|
||||
|
||||
namePrefix := p.ParameterName // TODO make unique, strip out [0], etc
|
||||
namePrefix := makeNamePrefix(p.ParameterName)
|
||||
|
||||
if p.ParameterType == "void" && !p.Pointer {
|
||||
shouldReturn = ""
|
||||
@ -366,15 +372,15 @@ func emitAssignCppToCabi(assignExpression string, p CppParameter, rvalue string)
|
||||
// Elide temporary and emit directly from the rvalue
|
||||
return indent + assignExpression + "new " + p.ParameterType + "(" + rvalue + ");\n"
|
||||
|
||||
} else if p.IsFlagType() {
|
||||
// Needs an explicit int cast
|
||||
} else if p.IsFlagType() || p.IsKnownEnum() || p.QtCppOriginalType != nil {
|
||||
// Needs an explicit cast
|
||||
shouldReturn = p.RenderTypeQtCpp() + " " + namePrefix + "_ret = "
|
||||
afterCall += indent + "" + assignExpression + "static_cast<int>(" + namePrefix + "_ret);\n"
|
||||
|
||||
} else if p.IsKnownEnum() || p.QtCppOriginalType != "" {
|
||||
// Needs an explicit uintptr cast
|
||||
shouldReturn = p.RenderTypeQtCpp() + " " + namePrefix + "_ret = "
|
||||
afterCall += indent + "" + assignExpression + "static_cast<" + p.RenderTypeCabi() + ">(" + namePrefix + "_ret);\n"
|
||||
if p.QtCppOriginalType != nil && p.QtCppOriginalType.Const != p.Const {
|
||||
afterCall += indent + "" + assignExpression + "const_cast<" + p.RenderTypeCabi() + ">(static_cast<" + p.RenderTypeIntermediateCpp() + ">(" + namePrefix + "_ret));\n"
|
||||
} else {
|
||||
afterCall += indent + "" + assignExpression + "static_cast<" + p.RenderTypeCabi() + ">(" + namePrefix + "_ret);\n"
|
||||
}
|
||||
|
||||
} else if p.Const {
|
||||
shouldReturn += "(" + p.RenderTypeCabi() + ") "
|
||||
|
@ -214,7 +214,7 @@ func (gfs *goFileState) emitParametersGo2CABIForwarding(m CppMethod) (preamble s
|
||||
|
||||
func (gfs *goFileState) emitParameterGo2CABIForwarding(p CppParameter) (preamble string, rvalue string) {
|
||||
|
||||
nameprefix := strings.Replace(strings.Replace(p.ParameterName, `[`, `_`, -1), `]`, "", -1)
|
||||
nameprefix := makeNamePrefix(p.ParameterName)
|
||||
|
||||
if p.ParameterType == "QString" {
|
||||
// Go: convert string -> miqt_string*
|
||||
@ -285,7 +285,7 @@ func (gfs *goFileState) emitCabiToGo(assignExpr string, rt CppParameter, rvalue
|
||||
|
||||
shouldReturn := "return "
|
||||
afterword := ""
|
||||
namePrefix := rt.ParameterName
|
||||
namePrefix := makeNamePrefix(rt.ParameterName)
|
||||
|
||||
if rt.ParameterType == "void" && !rt.Pointer {
|
||||
shouldReturn = ""
|
||||
@ -370,7 +370,7 @@ func (gfs *goFileState) emitCabiToGo(assignExpr string, rt CppParameter, rvalue
|
||||
}
|
||||
}
|
||||
|
||||
} else if rt.IntType() || rt.IsKnownEnum() || rt.IsFlagType() || rt.ParameterType == "bool" || rt.QtCppOriginalType != "" {
|
||||
} else if rt.IntType() || rt.IsKnownEnum() || rt.IsFlagType() || rt.ParameterType == "bool" || rt.QtCppOriginalType != nil {
|
||||
// Need to cast Cgo type to Go int type
|
||||
// Optimize assignment to avoid temporary
|
||||
return assignExpr + "(" + rt.RenderTypeGo() + ")(" + rvalue + ")\n"
|
||||
|
@ -133,16 +133,13 @@ func CheckComplexity(p CppParameter, isReturnType bool) error {
|
||||
// std::seed_seq QRandom
|
||||
return ErrTooComplex
|
||||
}
|
||||
if strings.Contains(p.ParameterType, `::reverse_iterator`) || strings.Contains(p.ParameterType, `::const_reverse_iterator`) {
|
||||
return ErrTooComplex // e.g. qbytearray.h
|
||||
}
|
||||
if strings.Contains(p.ParameterType, `Iterator::value_type`) {
|
||||
return ErrTooComplex // e.g. qcbormap
|
||||
}
|
||||
if strings.Contains(p.ParameterType, `::QPrivate`) {
|
||||
return ErrTooComplex // e.g. QAbstractItemModel::QPrivateSignal
|
||||
}
|
||||
if strings.Contains(p.GetQtCppType(), `::DataPtr`) {
|
||||
if strings.Contains(p.GetQtCppType().ParameterType, `::DataPtr`) {
|
||||
return ErrTooComplex // e.g. QImage::data_ptr()
|
||||
}
|
||||
|
||||
@ -191,9 +188,6 @@ func CheckComplexity(p CppParameter, isReturnType bool) error {
|
||||
"char16_t", // e.g. QChar() constructor overload, just unnecessary
|
||||
"char32_t", // e.g. QDebug().operator<< overload, unnecessary
|
||||
"wchar_t", // e.g. qstringview.h overloads, unnecessary
|
||||
"QStringView::const_pointer", // e.g. qstringview.h data()
|
||||
"QStringView::const_iterator", // e.g. qstringview.h
|
||||
"QStringView::value_type", // e.g. qstringview.h
|
||||
"FILE", // e.g. qfile.h constructors
|
||||
"qInternalCallback", // e.g. qnamespace.h
|
||||
"QGraphicsEffectSource", // e.g. used by qgraphicseffect.h, but the definition is in ????
|
||||
@ -233,11 +227,11 @@ func CheckComplexity(p CppParameter, isReturnType bool) error {
|
||||
// generated headers (generated on Linux) with other OSes such as Windows.
|
||||
// These methods will be blocked on non-Linux OSes.
|
||||
func LinuxWindowsCompatCheck(p CppParameter) bool {
|
||||
if p.GetQtCppType() == "Q_PID" {
|
||||
if p.GetQtCppType().ParameterType == "Q_PID" {
|
||||
return true // int64 on Linux, _PROCESS_INFORMATION* on Windows
|
||||
}
|
||||
|
||||
if p.GetQtCppType() == "QSocketDescriptor::DescriptorType" {
|
||||
if p.GetQtCppType().ParameterType == "QSocketDescriptor::DescriptorType" {
|
||||
return true // uintptr_t-compatible on Linux, void* on Windows
|
||||
}
|
||||
return false
|
||||
|
@ -37,25 +37,23 @@ func init() {
|
||||
}
|
||||
|
||||
type CppParameter struct {
|
||||
ParameterName string
|
||||
ParameterType string
|
||||
QtCppOriginalType string // If we rewrote QStringList->QList<String>, this field contains the original QStringList. Otherwise, it's blank
|
||||
Const bool
|
||||
Pointer bool
|
||||
PointerCount int
|
||||
ByRef bool
|
||||
Optional bool
|
||||
}
|
||||
ParameterName string
|
||||
ParameterType string
|
||||
Const bool
|
||||
Pointer bool
|
||||
PointerCount int
|
||||
ByRef bool
|
||||
Optional bool
|
||||
|
||||
func (p *CppParameter) AssignAlias(newType string) {
|
||||
if p.QtCppOriginalType == "" {
|
||||
p.QtCppOriginalType = p.ParameterType // Overwrite once only, at the earliest base type
|
||||
}
|
||||
p.ParameterType = newType
|
||||
QtCppOriginalType *CppParameter // If we rewrote QStringList->QList<String>, this field contains the original QStringList. Otherwise, it's blank
|
||||
}
|
||||
|
||||
func (p *CppParameter) ApplyTypedef(matchedUnderlyingType CppParameter) {
|
||||
p.AssignAlias(matchedUnderlyingType.ParameterType)
|
||||
if p.QtCppOriginalType == nil {
|
||||
tmp := *p // Copy
|
||||
p.QtCppOriginalType = &tmp // Overwrite once only, at the earliest base type
|
||||
}
|
||||
p.ParameterType = matchedUnderlyingType.ParameterType
|
||||
|
||||
// If this was a pointer to a typedef'd type, or a typedef of a pointer type, we need to preserve that
|
||||
p.Const = p.Const || matchedUnderlyingType.Const
|
||||
@ -78,20 +76,17 @@ func (p *CppParameter) ConstCast(isConst bool) CppParameter {
|
||||
return ret
|
||||
}
|
||||
|
||||
func (p *CppParameter) GetQtCppType() string {
|
||||
if p.QtCppOriginalType != "" {
|
||||
func (p *CppParameter) GetQtCppType() *CppParameter {
|
||||
if p.QtCppOriginalType != nil {
|
||||
return p.QtCppOriginalType
|
||||
}
|
||||
|
||||
return p.ParameterType
|
||||
return p
|
||||
}
|
||||
|
||||
func (p CppParameter) IsFlagType() bool {
|
||||
if strings.HasPrefix(p.ParameterType, `QFlags<`) {
|
||||
return true // This catches most cases through the typedef system
|
||||
}
|
||||
|
||||
if strings.HasPrefix(p.GetQtCppType(), `QFlags<`) {
|
||||
if strings.HasPrefix(p.ParameterType, `QFlags<`) ||
|
||||
strings.HasPrefix(p.GetQtCppType().ParameterType, `QFlags<`) {
|
||||
return true // This catches most cases through the typedef system
|
||||
}
|
||||
|
||||
|
@ -18,12 +18,17 @@ func applyTypedefs(p CppParameter) CppParameter {
|
||||
t2 := applyTypedefs(t) // recursive
|
||||
|
||||
// Wipe out so that RenderTypeQtCpp() does not see it
|
||||
t2.QtCppOriginalType = ""
|
||||
t2.QtCppOriginalType = nil
|
||||
|
||||
// QListOf returns for either QList< or QVector<
|
||||
// Patch it up to the first < position and last character
|
||||
bpos := strings.Index(p.ParameterType, `<`)
|
||||
p.AssignAlias(p.ParameterType[0:bpos] + `<` + t2.RenderTypeQtCpp() + `>`)
|
||||
|
||||
if p.QtCppOriginalType == nil {
|
||||
tmp := p // copy
|
||||
p.QtCppOriginalType = &tmp
|
||||
}
|
||||
p.ParameterType = p.ParameterType[0:bpos] + `<` + t2.RenderTypeQtCpp() + `>`
|
||||
}
|
||||
|
||||
return p
|
||||
|
@ -735,43 +735,43 @@ QByteArray* QByteArray_FromPercentEncoding(QByteArray* pctEncoded) {
|
||||
}
|
||||
|
||||
char* QByteArray_Begin(QByteArray* self) {
|
||||
QByteArray::iterator* _ret = self->begin();
|
||||
QByteArray::iterator _ret = self->begin();
|
||||
return static_cast<char*>(_ret);
|
||||
}
|
||||
|
||||
const char* QByteArray_Begin2(const QByteArray* self) {
|
||||
const QByteArray::const_iterator* _ret = self->begin();
|
||||
return static_cast<const char*>(_ret);
|
||||
QByteArray::const_iterator _ret = self->begin();
|
||||
return const_cast<const char*>(static_cast<const char*>(_ret));
|
||||
}
|
||||
|
||||
const char* QByteArray_Cbegin(const QByteArray* self) {
|
||||
const QByteArray::const_iterator* _ret = self->cbegin();
|
||||
return static_cast<const char*>(_ret);
|
||||
QByteArray::const_iterator _ret = self->cbegin();
|
||||
return const_cast<const char*>(static_cast<const char*>(_ret));
|
||||
}
|
||||
|
||||
const char* QByteArray_ConstBegin(const QByteArray* self) {
|
||||
const QByteArray::const_iterator* _ret = self->constBegin();
|
||||
return static_cast<const char*>(_ret);
|
||||
QByteArray::const_iterator _ret = self->constBegin();
|
||||
return const_cast<const char*>(static_cast<const char*>(_ret));
|
||||
}
|
||||
|
||||
char* QByteArray_End(QByteArray* self) {
|
||||
QByteArray::iterator* _ret = self->end();
|
||||
QByteArray::iterator _ret = self->end();
|
||||
return static_cast<char*>(_ret);
|
||||
}
|
||||
|
||||
const char* QByteArray_End2(const QByteArray* self) {
|
||||
const QByteArray::const_iterator* _ret = self->end();
|
||||
return static_cast<const char*>(_ret);
|
||||
QByteArray::const_iterator _ret = self->end();
|
||||
return const_cast<const char*>(static_cast<const char*>(_ret));
|
||||
}
|
||||
|
||||
const char* QByteArray_Cend(const QByteArray* self) {
|
||||
const QByteArray::const_iterator* _ret = self->cend();
|
||||
return static_cast<const char*>(_ret);
|
||||
QByteArray::const_iterator _ret = self->cend();
|
||||
return const_cast<const char*>(static_cast<const char*>(_ret));
|
||||
}
|
||||
|
||||
const char* QByteArray_ConstEnd(const QByteArray* self) {
|
||||
const QByteArray::const_iterator* _ret = self->constEnd();
|
||||
return static_cast<const char*>(_ret);
|
||||
QByteArray::const_iterator _ret = self->constEnd();
|
||||
return const_cast<const char*>(static_cast<const char*>(_ret));
|
||||
}
|
||||
|
||||
void QByteArray_PushBack(QByteArray* self, char c) {
|
||||
|
@ -52,23 +52,23 @@ bool QRegion_IsNull(const QRegion* self) {
|
||||
}
|
||||
|
||||
QRect* QRegion_Begin(const QRegion* self) {
|
||||
const QRegion::const_iterator* _ret = self->begin();
|
||||
return static_cast<QRect*>(_ret);
|
||||
QRegion::const_iterator _ret = self->begin();
|
||||
return const_cast<QRect*>(static_cast<const QRect*>(_ret));
|
||||
}
|
||||
|
||||
QRect* QRegion_Cbegin(const QRegion* self) {
|
||||
const QRegion::const_iterator* _ret = self->cbegin();
|
||||
return static_cast<QRect*>(_ret);
|
||||
QRegion::const_iterator _ret = self->cbegin();
|
||||
return const_cast<QRect*>(static_cast<const QRect*>(_ret));
|
||||
}
|
||||
|
||||
QRect* QRegion_End(const QRegion* self) {
|
||||
const QRegion::const_iterator* _ret = self->end();
|
||||
return static_cast<QRect*>(_ret);
|
||||
QRegion::const_iterator _ret = self->end();
|
||||
return const_cast<QRect*>(static_cast<const QRect*>(_ret));
|
||||
}
|
||||
|
||||
QRect* QRegion_Cend(const QRegion* self) {
|
||||
const QRegion::const_iterator* _ret = self->cend();
|
||||
return static_cast<QRect*>(_ret);
|
||||
QRegion::const_iterator _ret = self->cend();
|
||||
return const_cast<QRect*>(static_cast<const QRect*>(_ret));
|
||||
}
|
||||
|
||||
bool QRegion_Contains(const QRegion* self, QPoint* p) {
|
||||
|
@ -25,8 +25,8 @@ size_t QStringView_Size(const QStringView* self) {
|
||||
}
|
||||
|
||||
QChar* QStringView_Data(const QStringView* self) {
|
||||
const QStringView::const_pointer* _ret = self->data();
|
||||
return static_cast<QChar*>(_ret);
|
||||
QStringView::const_pointer _ret = self->data();
|
||||
return const_cast<QChar*>(static_cast<const QChar*>(_ret));
|
||||
}
|
||||
|
||||
QChar* QStringView_OperatorSubscript(const QStringView* self, size_t n) {
|
||||
@ -164,23 +164,23 @@ double QStringView_ToDouble(const QStringView* self) {
|
||||
}
|
||||
|
||||
QChar* QStringView_Begin(const QStringView* self) {
|
||||
const QStringView::const_iterator* _ret = self->begin();
|
||||
return static_cast<QChar*>(_ret);
|
||||
QStringView::const_iterator _ret = self->begin();
|
||||
return const_cast<QChar*>(static_cast<const QChar*>(_ret));
|
||||
}
|
||||
|
||||
QChar* QStringView_End(const QStringView* self) {
|
||||
const QStringView::const_iterator* _ret = self->end();
|
||||
return static_cast<QChar*>(_ret);
|
||||
QStringView::const_iterator _ret = self->end();
|
||||
return const_cast<QChar*>(static_cast<const QChar*>(_ret));
|
||||
}
|
||||
|
||||
QChar* QStringView_Cbegin(const QStringView* self) {
|
||||
const QStringView::const_iterator* _ret = self->cbegin();
|
||||
return static_cast<QChar*>(_ret);
|
||||
QStringView::const_iterator _ret = self->cbegin();
|
||||
return const_cast<QChar*>(static_cast<const QChar*>(_ret));
|
||||
}
|
||||
|
||||
QChar* QStringView_Cend(const QStringView* self) {
|
||||
const QStringView::const_iterator* _ret = self->cend();
|
||||
return static_cast<QChar*>(_ret);
|
||||
QStringView::const_iterator _ret = self->cend();
|
||||
return const_cast<QChar*>(static_cast<const QChar*>(_ret));
|
||||
}
|
||||
|
||||
bool QStringView_Empty(const QStringView* self) {
|
||||
|
Loading…
Reference in New Issue
Block a user