public inbox for gdb-prs@sourceware.org
help / color / mirror / Atom feed
From: "gjongren at gmail dot com" <sourceware-bugzilla@sourceware.org>
To: gdb-prs@sourceware.org
Subject: [Bug c++/31081] New: XMethods for C++23 multi-dimensional operator[](idx1, idx2, ...) do not work
Date: Wed, 22 Nov 2023 08:45:30 +0000	[thread overview]
Message-ID: <bug-31081-4717@http.sourceware.org/bugzilla/> (raw)

https://sourceware.org/bugzilla/show_bug.cgi?id=31081

            Bug ID: 31081
           Summary: XMethods for C++23 multi-dimensional operator[](idx1,
                    idx2, ...) do not work
           Product: gdb
           Version: 13.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: c++
          Assignee: unassigned at sourceware dot org
          Reporter: gjongren at gmail dot com
  Target Milestone: ---

(Tried using g++ version 12.1 with GDB version 13.2, the latter which is not
available in bug reporting drop-down)

Using XMethods, GDB understands syntax for single index operator[](idx1) making
it possible to write
(gdb) p mc[1]
where mc is a class instance. This instead of having to type the very
cumbersome (which becomes even more inconvenient in the case of nested
containers)
(gdb) p mc.operator[](1)

However, GDB seems not to understand the syntax for the corresponding case with
C++23's new multi-dimensional operator[](idx1, idx2, ...). 
Hence, this works
(gdb) p mc.operator[](1,2)
but this does not work
(gdb) p mc[1,2]

This is very unfortunate as there is currently then no convenient syntax in GDB
for dealing with multi-dimensional matrices (operator()(idx1, idx2, ...)) does
not work either since GDB seems to think that mc(1,2) is a call to a function
named "mc", c.f. Bug ID 12213), including for C++23's std::mdspan.

Debugging test.cpp below using the Xmethods file custom_xmehods.py give rise to
the following gdb output:

> g++ -g -std=c++23 test.cpp -o test.exe
> gdb ./test.exe
(gdb) source custom_xmethods.py
(gdb) py register_custom_xmethods()
(gdb) b 14
(gdb) run


(gdb) p mc[1]
Single index
1
$1 = 1

(gdb) p mc.operator[](1)
Single index
1
$2 = 1

(gdb) p mc.operator[](1,2)
Two indices
1
2
$3 = 3

(gdb) p mc[1,2]
Single index
2
$4 = 2
# Note how the single index operator[](idx1) is erronously picked.
# If MyClass_subscript_x() is removed as an XMethod, then the output is
instead:
(gdb) p mc[1,2]
Could not find operator[].
(gdb) p mc.operator[](1,2)
Two indices
1
2
$1 = 3

(gdb) p mc.elem(1,2)
Two indices
1
2
$5 = 3


//=========================
// test.cpp
//=========================
struct MyClass
{
  int operator[](int idx1) { return idx1; }
  int operator[](int idx1, int idx2) { return idx1 + idx2; }
  int elem(int idx1, int idx2) { return idx1 + idx2; }
};

int
main(int argc,
     char * argv[])
{
  MyClass mc;
  return 0;
}

#=========================
# custom_xmethods.py
#=========================
class MyClassWorker_subscript_x(gdb.xmethod.XMethodWorker):
    def get_arg_types(self):
        return gdb.lookup_type("int")

    def get_result_type(self, obj):
        return gdb.lookup_type("int")

    def __call__(self, obj, idx1):
        print("Single index")
        print(idx1)
        return idx1


class MyClassWorker_subscript_xx(gdb.xmethod.XMethodWorker):
    def get_arg_types(self):
        return (gdb.lookup_type("int"), gdb.lookup_type("int"))

    def get_result_type(self, obj):
        return gdb.lookup_type("int")

    def __call__(self, obj, idx1, idx2):
        print("Two indices")
        print(idx1)
        print(idx2)
        return idx1 + idx2


class MyClass_subscript_x(gdb.xmethod.XMethod):
    def __init__(self):
        gdb.xmethod.XMethod.__init__(self, "operator[]")

    def get_worker(self, method_name):
        if method_name == "operator[]":
            return MyClassWorker_subscript_x()


class MyClass_subscript_xx(gdb.xmethod.XMethod):
    def __init__(self):
        gdb.xmethod.XMethod.__init__(self, "operator[] / elem")

    def get_worker(self, method_name):
        if method_name == "operator[]" or method_name == "elem":
            return MyClassWorker_subscript_xx()


class MyClassMatcher(gdb.xmethod.XMethodMatcher):
    def __init__(self):
        gdb.xmethod.XMethodMatcher.__init__(self, "MyClassMatcher")
        self.methods = [
            MyClass_subscript_x(),
            MyClass_subscript_xx()
        ]

    def match(self, class_type, method_name):
        if class_type.tag != "MyClass":
            return None
        workers = []
        for method in self.methods:
            if method.enabled:
                worker = method.get_worker(method_name)
                if worker:
                    workers.append(worker)

        return workers

-- 
You are receiving this mail because:
You are on the CC list for the bug.

             reply	other threads:[~2023-11-22  8:45 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-11-22  8:45 gjongren at gmail dot com [this message]
2023-11-22  8:48 ` [Bug c++/31081] " gjongren at gmail dot com
2023-11-22 14:59 ` tromey at sourceware dot org
2023-11-22 17:50 ` ssbssa at sourceware dot org

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=bug-31081-4717@http.sourceware.org/bugzilla/ \
    --to=sourceware-bugzilla@sourceware.org \
    --cc=gdb-prs@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).