blob: e0568861bd0d672d9b36e8e0632633aa0f4bd056 [file] [log] [blame]
;; Type utilities.
;; Copyright (C) 2010-2021 Free Software Foundation, Inc.
;;
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 3 of the License, or
;; (at your option) any later version.
;;
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
(define-module (gdb types)
#:use-module (gdb)
#:use-module (gdb iterator)
#:use-module (gdb support))
(define-public (type-has-field-deep? type field-name)
"Return #t if the type, including baseclasses, has the specified field.
Arguments:
type: The type to examine. It must be a struct or union.
field-name: The name of the field to look up.
Returns:
True if the field is present either in type_ or any baseclass.
Raises:
wrong-type-arg: The type is not a struct or union."
(define (search-class type)
(let ((find-in-baseclass (lambda (field)
(if (field-baseclass? field)
(search-class (field-type field))
;; Not a baseclass, search ends now.
;; Return #:end to end search.
#:end))))
(let ((search-baseclasses
(lambda (type)
(iterator-until find-in-baseclass
(make-field-iterator type)))))
(or (type-has-field? type field-name)
(not (eq? (search-baseclasses type) #:end))))))
(if (= (type-code type) TYPE_CODE_REF)
(set! type (type-target type)))
(set! type (type-strip-typedefs type))
(assert-type (memq (type-code type) (list TYPE_CODE_STRUCT TYPE_CODE_UNION))
type SCM_ARG1 'type-has-field-deep? "struct or union")
(search-class type))
(define-public (make-enum-hashtable enum-type)
"Return a hash table from a program's enum type.
Elements in the hash table are fetched with hashq-ref.
Arguments:
enum-type: The enum to compute the hash table for.
Returns:
The hash table of the enum.
Raises:
wrong-type-arg: The type is not an enum."
(assert-type (= (type-code enum-type) TYPE_CODE_ENUM)
enum-type SCM_ARG1 'make-enum-hashtable "enum")
(let ((htab (make-hash-table)))
(for-each (lambda (enum)
(hash-set! htab (field-name enum) (field-enumval enum)))
(type-fields enum-type))
htab))