From 6a01cc2d860ba3f86a693a1d744d815263f2d950 Mon Sep 17 00:00:00 2001 From: mappu Date: Mon, 14 Oct 2024 19:27:57 +1300 Subject: [PATCH] genbindings/clang: handle FullComment in enum declarations --- cmd/genbindings/clang2il.go | 91 +++++++++++++++++++++---------------- 1 file changed, 52 insertions(+), 39 deletions(-) diff --git a/cmd/genbindings/clang2il.go b/cmd/genbindings/clang2il.go index 802c6186..1c6cc16e 100644 --- a/cmd/genbindings/clang2il.go +++ b/cmd/genbindings/clang2il.go @@ -525,7 +525,7 @@ nextEnumEntry: } kind, ok := entry["kind"].(string) - if kind == "DeprecatedAttr" { + if kind == "DeprecatedAttr" || kind == "FullComment" { continue nextEnumEntry // skip } else if kind == "EnumConstantDecl" { // allow @@ -545,56 +545,69 @@ nextEnumEntry: // Try to find the enum value ei1, ok := entry["inner"].([]interface{}) - if !ok || len(ei1) == 0 { - // Enum case without definition e.g. QCalendar::Gregorian - // This means one more than the last value - cee.EntryValue = fmt.Sprintf("%d", lastImplicitValue+1) + if !ok { + // No inner value on the enum = autoincrement + // Fall through as if a blank ei1, this will be handled + } - } else if len(ei1) >= 1 { + // There may be more than one RHS `inner` expression if one of them + // is a comment + // Iterate through each of the ei1 entries and see if any of them + // work for the purposes of enum constant value parsing + foundValidInner := false + for _, ei1_0 := range ei1 { - // There may be more than one RHS `inner` expression if one of them - // is a comment - // Iterate through each of the ei1 entries and see if any of them - // work for the purposes of enum constant value parsing - for _, ei1_0 := range ei1 { + ei1_0 := ei1_0.(map[string]interface{}) + ei1Kind, ok := ei1_0["kind"].(string) + if !ok { + panic("inner with no kind (1)") + } - ei1_0 := ei1_0.(map[string]interface{}) + if ei1Kind == "FullComment" { + continue + } + foundValidInner = true - // Best case: .inner -> kind=ConstantExpr value=xx - // e.g. qabstractitemmodel - if ei1Kind, ok := ei1_0["kind"].(string); ok && ei1Kind == "ConstantExpr" { - log.Printf("Got ConstantExpr OK") - if ei1Value, ok := ei1_0["value"].(string); ok { - cee.EntryValue = ei1Value - goto afterParse - } + // Best case: .inner -> kind=ConstantExpr value=xx + // e.g. qabstractitemmodel + if ei1Kind == "ConstantExpr" { + log.Printf("Got ConstantExpr OK") + if ei1Value, ok := ei1_0["value"].(string); ok { + cee.EntryValue = ei1Value + goto afterParse } + } - // Best case: .inner -> kind=ImplicitCastExpr .inner -> kind=ConstantExpr value=xx - // e.g. QCalendar (when there is a int typecast) - if ei1Kind, ok := ei1_0["kind"].(string); ok && ei1Kind == "ImplicitCastExpr" { - log.Printf("Got ImplicitCastExpr OK") - if ei2, ok := ei1_0["inner"].([]interface{}); ok && len(ei2) > 0 { - ei2_0 := ei2[0].(map[string]interface{}) - if ei2Kind, ok := ei2_0["kind"].(string); ok && ei2Kind == "ConstantExpr" { - log.Printf("Got ConstantExpr OK") - if ei2Value, ok := ei2_0["value"].(string); ok { - cee.EntryValue = ei2Value - goto afterParse - } + // Best case: .inner -> kind=ImplicitCastExpr .inner -> kind=ConstantExpr value=xx + // e.g. QCalendar (when there is a int typecast) + if ei1Kind == "ImplicitCastExpr" { + log.Printf("Got ImplicitCastExpr OK") + if ei2, ok := ei1_0["inner"].([]interface{}); ok && len(ei2) > 0 { + ei2_0 := ei2[0].(map[string]interface{}) + if ei2Kind, ok := ei2_0["kind"].(string); ok && ei2Kind == "ConstantExpr" { + log.Printf("Got ConstantExpr OK") + if ei2Value, ok := ei2_0["value"].(string); ok { + cee.EntryValue = ei2Value + goto afterParse } } } - - if ei1Kind, ok := ei1_0["kind"].(string); ok && ei1Kind == "DeprecatedAttr" { - log.Printf("Enum entry %q is deprecated, skipping", ret.EnumName+"::"+entryname) - continue nextEnumEntry - } - } - // If we made it here, we did not hit any of the `goto afterParse` cases + + if ei1Kind == "DeprecatedAttr" { + log.Printf("Enum entry %q is deprecated, skipping", ret.EnumName+"::"+entryname) + continue nextEnumEntry + } } + + // If we made it here, we did not hit any of the `goto afterParse` cases + if !foundValidInner { + // Enum case without definition e.g. QCalendar::Gregorian + // This means one more than the last value + cee.EntryValue = fmt.Sprintf("%d", lastImplicitValue+1) + } + afterParse: if cee.EntryValue == "" { return ret, fmt.Errorf("Complex enum %q entry %q", ret.EnumName, entryname)