diff --git a/src/gen/common/generator/function.lisp b/src/gen/common/generator/function.lisp index ed5e98e..0a8d67d 100644 --- a/src/gen/common/generator/function.lisp +++ b/src/gen/common/generator/function.lisp @@ -1,6 +1,5 @@ (cl:in-package :claw.generator.common) - (defvar *adapt-mode* :c) (defgeneric adapt-type (entity) @@ -151,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 @@ -208,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))) diff --git a/src/gen/iffi/cxx/generator/function.lisp b/src/gen/iffi/cxx/generator/function.lisp index e6996cd..b30a12b 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) + "__claw_this_") + (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/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 diff --git a/src/resect/resect.lisp b/src/resect/resect.lisp index c2152d2..53d8203 100644 --- a/src/resect/resect.lisp +++ b/src/resect/resect.lisp @@ -673,56 +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) - :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) @@ -981,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) diff --git a/src/spec/entity.lisp b/src/spec/entity.lisp index e65dc40..47f97fa 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 @@ -475,9 +476,9 @@ (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))) ;;;