From 4a5e29f03cddef8cba2df98b35e31528ee067d36 Mon Sep 17 00:00:00 2001 From: "Scott L. Burson" Date: Sun, 24 May 2026 00:39:28 -0700 Subject: [PATCH 1/7] Append ref qualifier to signed-as type on 'this' --- src/gen/common/generator/function.lisp | 3 ++- src/gen/common/packages.lisp | 1 + src/gen/iffi/cxx/generator/function.lisp | 12 ++++++++++-- src/resect/resect.lisp | 1 + src/spec/entity.lisp | 6 +++++- 5 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/gen/common/generator/function.lisp b/src/gen/common/generator/function.lisp index ed5e98e..4157375 100644 --- a/src/gen/common/generator/function.lisp +++ b/src/gen/common/generator/function.lisp @@ -1,5 +1,6 @@ (cl:in-package :claw.generator.common) +(alexandria:define-constant this-parameter-entity-name "__claw_this_" :test #'string=) (defvar *adapt-mode* :c) @@ -210,7 +211,7 @@ (not (claw.spec:foreign-method-static-p entity))) (list* (make-instance 'claw.spec:foreign-parameter - :name "__claw_this_" + :name this-parameter-entity-name :enveloped (make-instance 'claw.spec:foreign-pointer :enveloped (claw.spec:foreign-owner entity))) params) diff --git a/src/gen/common/packages.lisp b/src/gen/common/packages.lisp index 44920ba..d42d037 100644 --- a/src/gen/common/packages.lisp +++ b/src/gen/common/packages.lisp @@ -27,6 +27,7 @@ #:adapted-function-result-type #:adapted-function-body #:adapted-function-entity + #:this-parameter-entity-name #:adapt-type diff --git a/src/gen/iffi/cxx/generator/function.lisp b/src/gen/iffi/cxx/generator/function.lisp index e6996cd..e967420 100644 --- a/src/gen/iffi/cxx/generator/function.lisp +++ b/src/gen/iffi/cxx/generator/function.lisp @@ -42,11 +42,19 @@ for iffi-type = (when from (entity->iffi-type (claw.spec:foreign-enveloped-entity from))) + for ref-qual = (and (string= (claw.spec:foreign-entity-name param) + this-parameter-entity-name) + (let ((rq (claw.spec:foreign-method-ref-qualifier + (adapted-function-entity adapted-function)))) + (and (not (eq rq ':none)) rq))) collect `(,name ,cffi-type ,@(unless (and (equal cffi-type cffi-type-no-override) (or (null iffi-type) - (equal cffi-type iffi-type))) - (list :signed-as (or iffi-type cffi-type-no-override)))))) + (equal cffi-type iffi-type)) + (null ref-qual)) + (list :signed-as + (append (ensure-cons (or iffi-type cffi-type-no-override)) + (and ref-qual (list ref-qual)))))))) (defun generate-function-binding (entity) diff --git a/src/resect/resect.lisp b/src/resect/resect.lisp index c2152d2..02c9960 100644 --- a/src/resect/resect.lisp +++ b/src/resect/resect.lisp @@ -718,6 +718,7 @@ :variadic (%resect:function-proto-variadic-p method-prototype) :static (%resect:type-method-static-p type-method) :const (%resect:type-method-const-p type-method) + :ref-qualifier (%resect:method-ref-qualifier method-decl) :template (if (cffi:null-pointer-p method-decl) nil (%resect:declaration-template-p method-decl))) diff --git a/src/spec/entity.lisp b/src/spec/entity.lisp index e65dc40..0d2f001 100644 --- a/src/spec/entity.lisp +++ b/src/spec/entity.lisp @@ -80,6 +80,7 @@ #:foreign-method-static-p #:foreign-method-const-p #:foreign-method-deleted-p + #:foreign-method-ref-qualifier #:foreign-variable #:foreing-variable-type @@ -477,7 +478,10 @@ :reader foreign-method-const-p) (deleted-p :initarg :deleted :initform nil - :reader foreign-method-deleted-p))) + :reader foreign-method-deleted-p) + (ref-qualifier :initarg :ref-qualifier + :initform nil + :reader foreign-method-ref-qualifier))) ;;; From f72c45065cd352c16d42dc417b6b150e2db7d690 Mon Sep 17 00:00:00 2001 From: "Scott L. Burson" Date: Wed, 10 Jun 2026 02:01:41 -0700 Subject: [PATCH 2/7] Skip deleted methods --- src/resect/resect.lisp | 97 +++++++++++++++++++++--------------------- src/spec/entity.lisp | 3 -- 2 files changed, 49 insertions(+), 51 deletions(-) diff --git a/src/resect/resect.lisp b/src/resect/resect.lisp index 02c9960..401b86a 100644 --- a/src/resect/resect.lisp +++ b/src/resect/resect.lisp @@ -673,57 +673,58 @@ (%resect:function-proto-result-type method-prototype) (parse-type-by-category (%resect:function-proto-result-type method-prototype))))) - (multiple-value-bind (method newp) - (register-entity 'foreign-method - :id (%resect:type-method-id type-method) - :kind (cond - (constructor-p - :constructor) - ((starts-with #\~ pure-method-name) - :destructor) - ((starts-with-subseq "operator" pure-method-name) - :operator) - (t :regular)) - :source (if (cffi:null-pointer-p method-decl) - (%resect:type-method-source type-method) + (unless (%resect:method-deleted-p method-decl) + (multiple-value-bind (method newp) + (register-entity 'foreign-method + :id (%resect:type-method-id type-method) + :kind (cond + (constructor-p + :constructor) + ((starts-with #\~ pure-method-name) + :destructor) + ((starts-with-subseq "operator" pure-method-name) + :operator) + (t :regular)) + :source (if (cffi:null-pointer-p method-decl) + (%resect:type-method-source type-method) (%resect:declaration-source method-decl)) - :name (cond - (constructor-p - (string+ pure-method-name - (extract-template-argument-string - (%resect:type-name record-type)))) - ((cast-operator-p pure-method-name - result-type) - (string+ "operator " - (foreign-entity-name result-type))) - - (t (%resect:type-method-name type-method))) - :owner entity - :namespace (unless-empty - (if (cffi:null-pointer-p method-decl) - (claw.spec:foreign-entity-namespace entity) - (%resect:declaration-namespace method-decl))) - :mangled mangled-name - :location (if (cffi:null-pointer-p method-decl) - (make-instance 'foreign-location - :path "" - :line 0 - :column 0) + :name (cond + (constructor-p + (string+ pure-method-name + (extract-template-argument-string + (%resect:type-name record-type)))) + ((cast-operator-p pure-method-name + result-type) + (string+ "operator " + (foreign-entity-name result-type))) + + (t (%resect:type-method-name type-method))) + :owner entity + :namespace (unless-empty + (if (cffi:null-pointer-p method-decl) + (claw.spec:foreign-entity-namespace entity) + (%resect:declaration-namespace method-decl))) + :mangled mangled-name + :location (if (cffi:null-pointer-p method-decl) + (make-instance 'foreign-location + :path "" + :line 0 + :column 0) (make-declaration-location method-decl)) - :result-type result-type - :parameters (parse-instantiated-method-parameters - (%resect:function-proto-parameters method-prototype) - (unless (cffi:null-pointer-p method-decl) - (%resect:method-parameters method-decl))) - :variadic (%resect:function-proto-variadic-p method-prototype) - :static (%resect:type-method-static-p type-method) - :const (%resect:type-method-const-p type-method) - :ref-qualifier (%resect:method-ref-qualifier method-decl) - :template (if (cffi:null-pointer-p method-decl) - nil + :result-type result-type + :parameters (parse-instantiated-method-parameters + (%resect:function-proto-parameters method-prototype) + (unless (cffi:null-pointer-p method-decl) + (%resect:method-parameters method-decl))) + :variadic (%resect:function-proto-variadic-p method-prototype) + :static (%resect:type-method-static-p type-method) + :const (%resect:type-method-const-p type-method) + :ref-qualifier (%resect:method-ref-qualifier method-decl) + :template (if (cffi:null-pointer-p method-decl) + nil (%resect:declaration-template-p method-decl))) - (when newp - (setf (gethash mangled-name *mangled-table*) method))))))) + (when newp + (setf (gethash mangled-name *mangled-table*) method)))))))) (defun method-exists-p (decl) diff --git a/src/spec/entity.lisp b/src/spec/entity.lisp index 0d2f001..47f97fa 100644 --- a/src/spec/entity.lisp +++ b/src/spec/entity.lisp @@ -476,9 +476,6 @@ (const-p :initarg :const :initform nil :reader foreign-method-const-p) - (deleted-p :initarg :deleted - :initform nil - :reader foreign-method-deleted-p) (ref-qualifier :initarg :ref-qualifier :initform nil :reader foreign-method-ref-qualifier))) From 84467d4096f099000d2b2a2b2288d4e23b8f9e81 Mon Sep 17 00:00:00 2001 From: "Scott L. Burson" Date: Wed, 10 Jun 2026 02:04:17 -0700 Subject: [PATCH 3/7] Remove named constant I saw that there were more occurrences of "__claw_this_", so instead of converting them all, I just took out the named constant. --- src/gen/common/generator/function.lisp | 4 +--- src/gen/common/packages.lisp | 1 - src/gen/iffi/cxx/generator/function.lisp | 2 +- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/gen/common/generator/function.lisp b/src/gen/common/generator/function.lisp index 4157375..8c0f52d 100644 --- a/src/gen/common/generator/function.lisp +++ b/src/gen/common/generator/function.lisp @@ -1,7 +1,5 @@ (cl:in-package :claw.generator.common) -(alexandria:define-constant this-parameter-entity-name "__claw_this_" :test #'string=) - (defvar *adapt-mode* :c) (defgeneric adapt-type (entity) @@ -211,7 +209,7 @@ (not (claw.spec:foreign-method-static-p entity))) (list* (make-instance 'claw.spec:foreign-parameter - :name this-parameter-entity-name + :name "__claw_this_" :enveloped (make-instance 'claw.spec:foreign-pointer :enveloped (claw.spec:foreign-owner entity))) params) diff --git a/src/gen/common/packages.lisp b/src/gen/common/packages.lisp index d42d037..44920ba 100644 --- a/src/gen/common/packages.lisp +++ b/src/gen/common/packages.lisp @@ -27,7 +27,6 @@ #:adapted-function-result-type #:adapted-function-body #:adapted-function-entity - #:this-parameter-entity-name #:adapt-type diff --git a/src/gen/iffi/cxx/generator/function.lisp b/src/gen/iffi/cxx/generator/function.lisp index e967420..b30a12b 100644 --- a/src/gen/iffi/cxx/generator/function.lisp +++ b/src/gen/iffi/cxx/generator/function.lisp @@ -43,7 +43,7 @@ (entity->iffi-type (claw.spec:foreign-enveloped-entity from))) for ref-qual = (and (string= (claw.spec:foreign-entity-name param) - this-parameter-entity-name) + "__claw_this_") (let ((rq (claw.spec:foreign-method-ref-qualifier (adapted-function-entity adapted-function)))) (and (not (eq rq ':none)) rq))) From 1e3de77dbaff6edd2d46f9da34b744167b541605 Mon Sep 17 00:00:00 2001 From: "Scott L. Burson" Date: Wed, 10 Jun 2026 02:10:01 -0700 Subject: [PATCH 4/7] Generate rvalue of 'this' when calling rvalue-qualified methods This is occasionally needed for overload resolution. --- src/gen/common/generator/function.lisp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/gen/common/generator/function.lisp b/src/gen/common/generator/function.lisp index 8c0f52d..65f2c07 100644 --- a/src/gen/common/generator/function.lisp +++ b/src/gen/common/generator/function.lisp @@ -150,6 +150,12 @@ (format nil "~A(~{~A~^, ~})" (claw.spec:format-full-foreign-entity-name entity) param-names)) + ;; For rvalue-qualified methods, be careful to generate an rvalue; + ;; this is occasionally needed for overload disambiguation. + ((eq (claw.spec:foreign-method-ref-qualifier entity) :rvalue) + (format nil "std::move(*__claw_this_).~A(~{~A~^, ~})" + name + param-names)) (t (format nil "__claw_this_->~A(~{~A~^, ~})" name From 9836bc7942b524a920b16cc567fe042b333f29a7 Mon Sep 17 00:00:00 2001 From: "Scott L. Burson" Date: Wed, 10 Jun 2026 02:11:33 -0700 Subject: [PATCH 5/7] On const methods, declare 'this' param to be const --- src/gen/common/generator/function.lisp | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/gen/common/generator/function.lisp b/src/gen/common/generator/function.lisp index 65f2c07..0a8d67d 100644 --- a/src/gen/common/generator/function.lisp +++ b/src/gen/common/generator/function.lisp @@ -213,12 +213,22 @@ adapted-params)) (params (if (and (typep entity 'claw.spec:foreign-method) (not (claw.spec:foreign-method-static-p entity))) - (list* (make-instance - 'claw.spec:foreign-parameter - :name "__claw_this_" - :enveloped (make-instance 'claw.spec:foreign-pointer - :enveloped (claw.spec:foreign-owner entity))) - params) + (let* ((owner (claw.spec:foreign-owner entity)) + ;; Constness of `this' occasionally matters for + ;; overload resolution. + (target-type + (if (claw.spec:foreign-method-const-p entity) + (make-instance 'claw.spec:foreign-const-qualifier + :enveloped owner) + owner)) + (this-type + (make-instance 'claw.spec:foreign-pointer + :enveloped target-type))) + (list* (make-instance + 'claw.spec:foreign-parameter + :name "__claw_this_" + :enveloped this-type) + params)) params)) (params (if (and result-type-adapted-from (not (typep result-type-adapted-from 'claw.spec:foreign-reference))) From c24012183ef1b8db8484ab8f4dceb06297d1785d Mon Sep 17 00:00:00 2001 From: "Scott L. Burson" Date: Sun, 12 Jul 2026 15:47:09 -0700 Subject: [PATCH 6/7] Ignore deleted nonmember functions We were already ignoring deleted methods. --- src/resect/resect.lisp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/resect/resect.lisp b/src/resect/resect.lisp index 401b86a..53d8203 100644 --- a/src/resect/resect.lisp +++ b/src/resect/resect.lisp @@ -983,7 +983,8 @@ (defmethod parse-declaration ((type (eql :function)) decl &key) - (unless (eq :static (%resect:function-storage-class decl)) + (unless (or (eq :static (%resect:function-storage-class decl)) + (%resect:function-deleted-p decl)) (if (starts-with-subseq +instantiation-prefix+ (%resect:declaration-name decl)) (on-post-parse (let ((template-mangled-name (subseq (%resect:declaration-name decl) From c7f5876c86989c045bcb99d59c20889938947c9d Mon Sep 17 00:00:00 2001 From: "Scott L. Burson" Date: Tue, 30 Jun 2026 15:20:50 -0700 Subject: [PATCH 7/7] Silence SBCL warnings about a function being redefined as a macro... .. and conversely. --- src/iffi/function.lisp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/iffi/function.lisp b/src/iffi/function.lisp index f010817..34af046 100644 --- a/src/iffi/function.lisp +++ b/src/iffi/function.lisp @@ -173,7 +173,8 @@ (intricately-defined (gethash name *intricate-table*)) (cfun-name (format-symbol (symbol-package name) "~A~A$~A" 'iffi-cfun$ name mangled))) `(progn - ,@(when inline-p + ;; If `&rest' is present, `cffi:defcfun' defines `cfun-name' as a macro. + ,@(when (and inline-p (not (eq (car (last param-config)) '&rest))) `((declaim (inline ,cfun-name)))) (cffi:defcfun (,mangled ,cfun-name ,@(nreverse cffi-opts)) ,return-type ,@(when doc