gdb/ChangeLog:
* Makefile.in (SFILES): Add d-typeprint.c
(COMMON_OBJS): Add d-typeprint.o
* d-lang.c (d_language_defn): Change c_print_type to d_print_type.
* d-lang.h (d_print_type): New declaration.
* d-typeprint.c: New file.
* dwarf2read.c (read_structure_type): Set TYPE_DECLARED_CLASS also for
classes in D language.
gdb/testsuite/ChangeLog:
* typeprint.S: New file.
* typeprint.exp: New file.
---
@@ -838,7 +838,7 @@ SFILES = ada-exp.y ada-lang.c ada-typeprint.c ada-valprint.c ada-tasks.c \
charset.c common/cleanups.c cli-out.c coffread.c coff-pe-read.c \
complaints.c completer.c continuations.c corefile.c corelow.c \
cp-abi.c cp-support.c cp-namespace.c cp-valprint.c \
- d-exp.y d-lang.c d-namespace.c d-valprint.c \
+ d-exp.y d-lang.c d-namespace.c d-typeprint.c d-valprint.c \
cp-name-parser.y \
dbxread.c demangle.c dictionary.c disasm.c doublest.c \
dtrace-probe.c dummy-frame.c \
@@ -1063,7 +1063,8 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $(YYOBJ) \
m2-lang.o opencl-lang.o p-lang.o p-typeprint.o p-valprint.o \
sentinel-frame.o \
complaints.o typeprint.o \
- ada-typeprint.o c-typeprint.o f-typeprint.o m2-typeprint.o \
+ ada-typeprint.o c-typeprint.o d-typeprint.o f-typeprint.o \
+ m2-typeprint.o \
ada-valprint.o c-valprint.o cp-valprint.o d-valprint.o f-valprint.o \
m2-valprint.o \
serial.o mdebugread.o top.o utils.o \
@@ -206,7 +206,7 @@ static const struct language_defn d_language_defn =
c_printchar, /* Print a character constant. */
c_printstr, /* Function to print string constant. */
c_emit_char, /* Print a single char. */
- c_print_type, /* Print a type using appropriate syntax. */
+ d_print_type, /* Print a type using appropriate syntax. */
c_print_typedef, /* Print a typedef using appropriate
syntax. */
d_val_print, /* Print a value using appropriate syntax. */
@@ -20,6 +20,8 @@
#if !defined (D_LANG_H)
#define D_LANG_H 1
+struct type_print_options;
+
#include "symtab.h"
/* Language specific builtin types for D. Any additional types added
@@ -78,6 +80,12 @@ extern struct block_symbol d_lookup_symbol_nonlocal (const struct language_defn
extern struct block_symbol d_lookup_nested_symbol (struct type *, const char *,
const struct block *);
+/* Defined in d-typeprint.c. */
+
+extern void d_print_type (struct type *type, const char *varstring,
+ struct ui_file *stream, int show, int level,
+ const struct type_print_options *flags);
+
/* Defined in d-valprint.c */
extern void d_val_print (struct type *type, const gdb_byte *valaddr,
new file mode 100644
@@ -0,0 +1,384 @@
+/* Support for printing D types for GDB, the GNU debugger.
+ Copyright (C) 2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ 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/>. */
+
+#include "defs.h"
+#include "gdbtypes.h"
+#include "demangle.h"
+#include "typeprint.h"
+#include "c-lang.h"
+#include "cp-support.h"
+#include "d-lang.h"
+
+/* Print the name of the type (or the ultimate pointer target,
+ function value or array element), or the description of a
+ structure or union.
+
+ SHOW positive means print details about the type (e.g. enum
+ values), and print structure elements passing SHOW - 1 for show.
+
+ SHOW negative means just print the type name or struct tag if there
+ is one. If there is no name, print something sensible but concise
+ like "struct {...}".
+
+ SHOW zero means just print the type name or struct tag if there is
+ one. If there is no name, print something sensible but not as
+ concise like "struct {int x; int y;}".
+
+ LEVEL is the number of spaces to indent by.
+ We increase it for some recursive calls. */
+
+static void
+d_type_print_base (struct type *type, struct ui_file *stream, int show,
+ int level, const struct type_print_options *flags)
+{
+ QUIT;
+ wrap_here (" ");
+
+ if (type == NULL)
+ {
+ fputs_filtered ("<type unknown>", stream);
+ return;
+ }
+
+ /* When SHOW is zero or less, and there is a valid type name, then always
+ just print the type name directly from the type. */
+ if ((show <= 0) && (TYPE_NAME (type) != NULL))
+ {
+ fputs_filtered (TYPE_NAME (type), stream);
+ return;
+ }
+
+ if (TYPE_CODE (type) != TYPE_CODE_TYPEDEF)
+ type = check_typedef (type);
+
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_TYPEDEF:
+ d_type_print_base (TYPE_TARGET_TYPE (type), stream, 0, level, flags);
+ break;
+
+ case TYPE_CODE_ARRAY:
+ {
+ LONGEST low_bound, high_bound;
+ int is_vector = TYPE_VECTOR (type);
+
+ if (is_vector)
+ fputs_filtered ("__vector(", stream);
+
+ d_type_print_base (TYPE_TARGET_TYPE (type), stream, 0, level, flags);
+ fputs_filtered ("[", stream);
+ /* Bounds are not yet resolved, print a bounds placeholder instead. */
+ if (TYPE_HIGH_BOUND_KIND (TYPE_INDEX_TYPE (type)) == PROP_LOCEXPR
+ || TYPE_HIGH_BOUND_KIND (TYPE_INDEX_TYPE (type)) == PROP_LOCLIST)
+ fputs_filtered ("variable length", stream);
+ else if (get_array_bounds (type, &low_bound, &high_bound))
+ fprintf_filtered (stream, "%s",
+ plongest (high_bound - low_bound + 1));
+ fputs_filtered ("]", stream);
+
+ if (is_vector)
+ fputs_filtered (")", stream);
+ }
+ break;
+
+ case TYPE_CODE_PTR:
+ {
+ struct type *target = TYPE_TARGET_TYPE (type);
+ int is_funcptr = (target != NULL
+ && TYPE_CODE (target) == TYPE_CODE_FUNC);
+ int is_class = (target != NULL
+ && TYPE_CODE (target) == TYPE_CODE_STRUCT
+ && TYPE_DECLARED_CLASS (target));
+
+ /* Want to show the contents of top-level class pointers. */
+ if (show > 0 && !is_class)
+ show = 0;
+
+ d_type_print_base (target, stream, show, level, flags);
+
+ /* Function pointers have their own syntax. */
+ if (is_funcptr)
+ {
+ int i;
+
+ fputs_filtered (" function(", stream);
+ for (i = 0; i < TYPE_NFIELDS (target); i++)
+ {
+ struct field f = TYPE_FIELDS (target)[i];
+
+ if (i > 0)
+ fputs_filtered (", ", stream);
+
+ d_type_print_base (FIELD_TYPE (f), stream, 0, level, flags);
+ }
+ fputs_filtered (")", stream);
+ }
+ else
+ {
+ /* Skip emitting the '*' for classes, as they are all represented
+ as pointer types in D. */
+ if (!is_class)
+ fprintf_filtered (stream, "*");
+ }
+ }
+ break;
+
+ case TYPE_CODE_REF:
+ {
+ fputs_filtered ("ref ", stream);
+ d_type_print_base (TYPE_TARGET_TYPE (type), stream,
+ show, level, flags);
+ }
+ break;
+
+ case TYPE_CODE_FUNC:
+ d_type_print_base (TYPE_TARGET_TYPE (type), stream,
+ show, level, flags);
+ break;
+
+ case TYPE_CODE_STRUCT:
+ case TYPE_CODE_UNION:
+ {
+ const char *tagname = TYPE_TAG_NAME (type);
+
+ if (tagname != NULL)
+ {
+ char lastchar = tagname[strlen (tagname) - 1];
+
+ fputs_filtered (tagname, stream);
+ /* If it's a dynamic or associative array, or a delegate function,
+ don't print the underlying type structure. */
+ if (lastchar == ']' || lastchar == ')')
+ break;
+
+ /* String types in D are aliases to dynamic arrays, however their
+ aliases are written to debug instead of the underlying type. */
+ if ((strcmp (tagname, "string") == 0
+ || strcmp (tagname, "wstring") == 0
+ || strcmp (tagname, "dstring") == 0)
+ && TYPE_NFIELDS (type) == 2
+ && strcmp (TYPE_FIELD_NAME (type, 0), "length") == 0
+ && strcmp (TYPE_FIELD_NAME (type, 1), "ptr") == 0)
+ break;
+
+ if (show > 0)
+ fputs_filtered (" ", stream);
+ }
+ else
+ {
+ /* Anonymous class/struct/union. */
+ if (TYPE_CODE (type) == TYPE_CODE_UNION)
+ fputs_filtered ("union ", stream);
+ else if (TYPE_DECLARED_CLASS (type))
+ fputs_filtered ("class ", stream);
+ else
+ fputs_filtered ("struct ", stream);
+ }
+
+ wrap_here (" ");
+
+ if (show < 0)
+ {
+ /* If we just printed a tag name, no need to print anything else. */
+ if (tagname == NULL)
+ fprintf_filtered (stream, "{...}");
+ }
+ else if (show > 0 || TYPE_TAG_NAME (type) == NULL)
+ {
+ int len;
+ int i, j;
+
+ // FIXME: print inheritance / interfaces
+
+ fputs_filtered ("{\n", stream);
+ if ((TYPE_NFIELDS (type) == 0) && (TYPE_NFN_FIELDS (type) == 0))
+ {
+ if (TYPE_STUB (type))
+ fprintfi_filtered (level + 4, stream, "<incomplete type>\n");
+ else
+ fprintfi_filtered (level + 4, stream, "<no data fields>\n");
+ }
+
+ QUIT;
+
+ /* If there is a base class for this type,
+ do not print the field that it occupies. */
+ len = TYPE_NFIELDS (type);
+ for (i = TYPE_N_BASECLASSES (type); i < len; i++)
+ {
+ QUIT;
+ /* Don't print out virtual function table or monitor.
+ These are the first two fields placed in the class,
+ and should be marked as artificial. */
+ if (i < 2 && TYPE_DECLARED_CLASS (type))
+ {
+ if (TYPE_FIELD_ARTIFICIAL (type, i))
+ continue;
+ else if (startswith (TYPE_FIELD_NAME (type, i), "__vptr"))
+ continue;
+ else if (startswith (TYPE_FIELD_NAME (type, i), "__monitor"))
+ continue;
+ }
+
+ print_spaces_filtered (level + 4, stream);
+
+ if (TYPE_FIELD_PROTECTED (type, i))
+ fputs_filtered ("protected ", stream);
+ else if (TYPE_FIELD_PRIVATE (type, i))
+ fputs_filtered ("private ", stream);
+
+ if (field_is_static (&TYPE_FIELD (type, i)))
+ fputs_filtered ("static ", stream);
+
+ d_print_type (TYPE_FIELD_TYPE (type, i),
+ TYPE_FIELD_NAME (type, i),
+ stream, show - 1, level + 4, flags);
+ fputs_filtered (";\n", stream);
+ }
+
+ /* Print out the methods, artificial methods will be hidden. */
+ len = TYPE_NFN_FIELDS (type);
+ if (!flags->print_methods)
+ len = 0;
+
+ for (i = 0; i < len; i++)
+ {
+ for (j = 0; j < TYPE_FN_FIELDLIST_LENGTH (type, i); j++)
+ {
+ struct fn_field *fields = TYPE_FN_FIELDLIST1 (type, i);
+ const char *method_name;
+ char *mangled_name;
+ char *demangled_name;
+ struct type *target;
+
+ /* Do not print out artificial methods. */
+ if (TYPE_FN_FIELD_ARTIFICIAL (fields, j))
+ continue;
+
+ method_name = TYPE_FN_FIELDLIST_NAME (type, i);
+
+ /* Build something we can demangle. */
+ if (TYPE_FN_FIELD_STUB (fields, j))
+ mangled_name = gdb_mangle_name (type, i, j);
+ else
+ {
+ const char *physname;
+ int physname_len;
+
+ physname = TYPE_FN_FIELD_PHYSNAME (fields, j);
+ physname_len = strlen(physname);
+
+ mangled_name = alloca (physname_len + 1);
+ memcpy (mangled_name, physname, physname_len);
+ mangled_name[physname_len] = '\0';
+ }
+
+ QUIT;
+ print_spaces_filtered (level + 4, stream);
+
+ if (TYPE_FN_FIELD_PROTECTED (fields, j))
+ fputs_filtered ("protected ", stream);
+ else if (TYPE_FN_FIELD_PRIVATE (fields, j))
+ fputs_filtered ("private ", stream);
+
+ if (TYPE_FN_FIELD_ABSTRACT (fields, j))
+ fputs_filtered ("abstract ", stream);
+ if (TYPE_FN_FIELD_STATIC (fields, j))
+ fputs_filtered ("static ", stream);
+ if (TYPE_FN_FIELD_FINAL (fields, j))
+ fputs_filtered ("final ", stream);
+ if (TYPE_FN_FIELD_SYNCHRONIZED (fields, j))
+ fputs_filtered ("synchronized ", stream);
+
+ target = TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (fields, j));
+ if (target == NULL)
+ {
+ /* Keep GDB from crashing here. */
+ fprintf_filtered (stream, "<undefined type> %s;\n",
+ TYPE_FN_FIELD_PHYSNAME (fields, j));
+ break;
+ }
+ else if (strcmp (method_name, "__ctor") != 0
+ && strcmp (method_name, "__dtor") != 0
+ && strcmp (method_name, "__postblit") != 0)
+ {
+ d_print_type (target, "", stream, -1, 0, flags);
+ fputs_filtered (" ", stream);
+ }
+
+ demangled_name = gdb_demangle (mangled_name, DMGL_DLANG);
+
+ if (demangled_name != NULL)
+ {
+ /* Skip to the base name of the demangled symbol. */
+ char *p = strchr (demangled_name, '(');
+ gdb_assert (p != NULL);
+ while (p > demangled_name && p[-1] != '.')
+ p--;
+
+ fputs_filtered (p, stream);
+ xfree (demangled_name);
+ }
+ else
+ fputs_filtered (mangled_name, stream);
+
+ if (TYPE_FN_FIELD_STUB (fields, j))
+ xfree (mangled_name);
+
+ fputs_filtered (";\n", stream);
+ }
+ }
+
+ fprintfi_filtered (level, stream, "}");
+ }
+ }
+ break;
+
+ case TYPE_CODE_MODULE:
+ fprintf_filtered (stream, "module %s", TYPE_TAG_NAME (type));
+ break;
+
+ default:
+ /* Handle types not explicitly handled by the other cases,
+ such as fundamental types. For these, just print whatever
+ the type name is, as recorded in the type itself. If there
+ is no type name, then hand it down to c_type_print_base. */
+ if (TYPE_NAME (type) != NULL)
+ fprintfi_filtered (level, stream, "%s", TYPE_NAME (type));
+ else
+ c_type_print_base (type, stream, show, level, flags);
+ break;
+ }
+}
+
+/* LEVEL is the depth to indent lines by. */
+
+void
+d_print_type (struct type *type, const char *varstring,
+ struct ui_file *stream, int show, int level,
+ const struct type_print_options *flags)
+{
+ d_type_print_base (type, stream, show, level, flags);
+
+ if (varstring != NULL && *varstring != '\0')
+ {
+ fputs_filtered (" ", stream);
+ fputs_filtered (varstring, stream);
+ }
+}
+
@@ -13199,7 +13199,8 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
TYPE_CODE (type) = TYPE_CODE_STRUCT;
}
- if (cu->language == language_cplus && die->tag == DW_TAG_class_type)
+ if ((cu->language == language_cplus || cu->language == language_d)
+ && die->tag == DW_TAG_class_type)
TYPE_DECLARED_CLASS (type) = 1;
attr = dwarf2_attr (die, DW_AT_byte_size, cu);
new file mode 100644
@@ -0,0 +1,588 @@
+/* Copyright 2016 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/>. */
+
+/* This file was generated using:
+
+ $ gdc -g -Og -dA typeprint.d -S -o typeprint.S
+
+ with
+
+ $ gdc -v
+ gcc version 6.0.0 20160123 (experimental) (GCC)
+ Target: x86_64-pc-linux-gnu
+ Thread model: posix
+
+ And then manually cleaned up some debug comments. */
+ .file "typeprint.d"
+ .text
+.Ltext0:
+ .globl main
+ .type main, @function
+main:
+.LFB0:
+ .file 1 "typeprint.d"
+ # typeprint.d:3
+ .loc 1 3 0
+ .cfi_startproc
+ rep ret
+ .cfi_endproc
+.LFE0:
+ .size main, .-main
+.Letext0:
+ .file 2 "<built-in>"
+ .section .debug_info,"",@progbits
+.Ldebug_info0:
+ .long 0x235 # Length of Compilation Unit Info
+ .value 0x4 # DWARF version number
+ .long .Ldebug_abbrev0 # Offset Into Abbrev. Section
+ .byte 0x8 # Pointer Size (in bytes)
+ .uleb128 0x1 # (DIE (0xb) DW_TAG_compile_unit)
+ .long .LASF28 # DW_AT_producer: "GNU D 6.0.0 20160123 (experimental)"
+ .byte 0x13 # DW_AT_language
+ .long .LASF29 # DW_AT_name: "typeprint.d"
+ .long .LASF30 # DW_AT_comp_dir: "/tmp"
+ .quad .Ltext0 # DW_AT_low_pc
+ .quad .Letext0-.Ltext0 # DW_AT_high_pc
+ .long .Ldebug_line0 # DW_AT_stmt_list
+ .uleb128 0x2 # (DIE (0x2d) DW_TAG_module)
+ .long .LASF31 # DW_AT_name: "typeprint"
+ # DW_AT_declaration
+ .long 0xbf # DW_AT_sibling
+ .uleb128 0x3 # (DIE (0x36) DW_TAG_subprogram)
+ # DW_AT_external
+ .long .LASF32 # DW_AT_name: "main"
+ .byte 0x1 # DW_AT_decl_file (typeprint.d)
+ .byte 0x3 # DW_AT_decl_line
+ .quad .LFB0 # DW_AT_low_pc
+ .quad .LFE0-.LFB0 # DW_AT_high_pc
+ .uleb128 0x1 # DW_AT_frame_base
+ .byte 0x9c # DW_OP_call_frame_cfa
+ # DW_AT_GNU_all_call_sites
+ .uleb128 0x4 # (DIE (0x4f) DW_TAG_variable)
+ .long .LASF0 # DW_AT_name: "vectorarray"
+ .byte 0x1 # DW_AT_decl_file (typeprint.d)
+ .byte 0xf # DW_AT_decl_line
+ .long 0xbf # DW_AT_type
+ .uleb128 0x4 # (DIE (0x5a) DW_TAG_variable)
+ .long .LASF1 # DW_AT_name: "dstringvalue"
+ .byte 0x1 # DW_AT_decl_file (typeprint.d)
+ .byte 0xe # DW_AT_decl_line
+ .long 0xd2 # DW_AT_type
+ .uleb128 0x4 # (DIE (0x65) DW_TAG_variable)
+ .long .LASF2 # DW_AT_name: "wstringvalue"
+ .byte 0x1 # DW_AT_decl_file (typeprint.d)
+ .byte 0xd # DW_AT_decl_line
+ .long 0x10e # DW_AT_type
+ .uleb128 0x4 # (DIE (0x70) DW_TAG_variable)
+ .long .LASF3 # DW_AT_name: "stringvalue"
+ .byte 0x1 # DW_AT_decl_file (typeprint.d)
+ .byte 0xc # DW_AT_decl_line
+ .long 0x143 # DW_AT_type
+ .uleb128 0x4 # (DIE (0x7b) DW_TAG_variable)
+ .long .LASF4 # DW_AT_name: "associativearray"
+ .byte 0x1 # DW_AT_decl_file (typeprint.d)
+ .byte 0xb # DW_AT_decl_line
+ .long 0x178 # DW_AT_type
+ .uleb128 0x4 # (DIE (0x86) DW_TAG_variable)
+ .long .LASF5 # DW_AT_name: "dynamicarray"
+ .byte 0x1 # DW_AT_decl_file (typeprint.d)
+ .byte 0xa # DW_AT_decl_line
+ .long 0x191 # DW_AT_type
+ .uleb128 0x4 # (DIE (0x91) DW_TAG_variable)
+ .long .LASF6 # DW_AT_name: "delegateptr"
+ .byte 0x1 # DW_AT_decl_file (typeprint.d)
+ .byte 0x9 # DW_AT_decl_line
+ .long 0x1c1 # DW_AT_type
+ .uleb128 0x4 # (DIE (0x9c) DW_TAG_variable)
+ .long .LASF7 # DW_AT_name: "funcptr"
+ .byte 0x1 # DW_AT_decl_file (typeprint.d)
+ .byte 0x8 # DW_AT_decl_line
+ .long 0x214 # DW_AT_type
+ .uleb128 0x4 # (DIE (0xa7) DW_TAG_variable)
+ .long .LASF8 # DW_AT_name: "staticarray"
+ .byte 0x1 # DW_AT_decl_file (typeprint.d)
+ .byte 0x7 # DW_AT_decl_line
+ .long 0x21a # DW_AT_type
+ .uleb128 0x4 # (DIE (0xb2) DW_TAG_variable)
+ .long .LASF9 # DW_AT_name: "voidptr"
+ .byte 0x1 # DW_AT_decl_file (typeprint.d)
+ .byte 0x6 # DW_AT_decl_line
+ .long 0x18f # DW_AT_type
+ .byte 0 # end of children of DIE 0x36
+ .byte 0 # end of children of DIE 0x2d
+ .uleb128 0x5 # (DIE (0xbf) DW_TAG_array_type)
+ # DW_AT_GNU_vector
+ .long 0xcb # DW_AT_type
+ .long 0xcb # DW_AT_sibling
+ .uleb128 0x6 # (DIE (0xc8) DW_TAG_subrange_type)
+ .byte 0x7 # DW_AT_upper_bound
+ .byte 0 # end of children of DIE 0xbf
+ .uleb128 0x7 # (DIE (0xcb) DW_TAG_base_type)
+ .byte 0x1 # DW_AT_byte_size
+ .byte 0x7 # DW_AT_encoding
+ .long .LASF11 # DW_AT_name: "ubyte"
+ .uleb128 0x8 # (DIE (0xd2) DW_TAG_structure_type)
+ .long .LASF14 # DW_AT_name: "dstring"
+ .byte 0x10 # DW_AT_byte_size
+ .long 0xf5 # DW_AT_sibling
+ .uleb128 0x9 # (DIE (0xdc) DW_TAG_member)
+ .long .LASF10 # DW_AT_name: "length"
+ .byte 0x2 # DW_AT_decl_file (<built-in>)
+ .byte 0 # DW_AT_decl_line
+ .long 0xf5 # DW_AT_type
+ .byte 0 # DW_AT_data_member_location
+ .uleb128 0xa # (DIE (0xe8) DW_TAG_member)
+ .ascii "ptr\0" # DW_AT_name
+ .byte 0x2 # DW_AT_decl_file (<built-in>)
+ .byte 0 # DW_AT_decl_line
+ .long 0xfc # DW_AT_type
+ .byte 0x8 # DW_AT_data_member_location
+ .byte 0 # end of children of DIE 0xd2
+ .uleb128 0x7 # (DIE (0xf5) DW_TAG_base_type)
+ .byte 0x8 # DW_AT_byte_size
+ .byte 0x7 # DW_AT_encoding
+ .long .LASF12 # DW_AT_name: "ulong"
+ .uleb128 0xb # (DIE (0xfc) DW_TAG_pointer_type)
+ .byte 0x8 # DW_AT_byte_size
+ .long 0x109 # DW_AT_type
+ .uleb128 0x7 # (DIE (0x102) DW_TAG_base_type)
+ .byte 0x4 # DW_AT_byte_size
+ .byte 0x8 # DW_AT_encoding
+ .long .LASF13 # DW_AT_name: "dchar"
+ .uleb128 0xc # (DIE (0x109) DW_TAG_const_type)
+ .long 0x102 # DW_AT_type
+ .uleb128 0x8 # (DIE (0x10e) DW_TAG_structure_type)
+ .long .LASF15 # DW_AT_name: "wstring"
+ .byte 0x10 # DW_AT_byte_size
+ .long 0x131 # DW_AT_sibling
+ .uleb128 0x9 # (DIE (0x118) DW_TAG_member)
+ .long .LASF10 # DW_AT_name: "length"
+ .byte 0x2 # DW_AT_decl_file (<built-in>)
+ .byte 0 # DW_AT_decl_line
+ .long 0xf5 # DW_AT_type
+ .byte 0 # DW_AT_data_member_location
+ .uleb128 0xa # (DIE (0x124) DW_TAG_member)
+ .ascii "ptr\0" # DW_AT_name
+ .byte 0x2 # DW_AT_decl_file (<built-in>)
+ .byte 0 # DW_AT_decl_line
+ .long 0x131 # DW_AT_type
+ .byte 0x8 # DW_AT_data_member_location
+ .byte 0 # end of children of DIE 0x10e
+ .uleb128 0xb # (DIE (0x131) DW_TAG_pointer_type)
+ .byte 0x8 # DW_AT_byte_size
+ .long 0x13e # DW_AT_type
+ .uleb128 0x7 # (DIE (0x137) DW_TAG_base_type)
+ .byte 0x2 # DW_AT_byte_size
+ .byte 0x8 # DW_AT_encoding
+ .long .LASF16 # DW_AT_name: "wchar"
+ .uleb128 0xc # (DIE (0x13e) DW_TAG_const_type)
+ .long 0x137 # DW_AT_type
+ .uleb128 0x8 # (DIE (0x143) DW_TAG_structure_type)
+ .long .LASF17 # DW_AT_name: "string"
+ .byte 0x10 # DW_AT_byte_size
+ .long 0x166 # DW_AT_sibling
+ .uleb128 0x9 # (DIE (0x14d) DW_TAG_member)
+ .long .LASF10 # DW_AT_name: "length"
+ .byte 0x2 # DW_AT_decl_file (<built-in>)
+ .byte 0 # DW_AT_decl_line
+ .long 0xf5 # DW_AT_type
+ .byte 0 # DW_AT_data_member_location
+ .uleb128 0xa # (DIE (0x159) DW_TAG_member)
+ .ascii "ptr\0" # DW_AT_name
+ .byte 0x2 # DW_AT_decl_file (<built-in>)
+ .byte 0 # DW_AT_decl_line
+ .long 0x166 # DW_AT_type
+ .byte 0x8 # DW_AT_data_member_location
+ .byte 0 # end of children of DIE 0x143
+ .uleb128 0xb # (DIE (0x166) DW_TAG_pointer_type)
+ .byte 0x8 # DW_AT_byte_size
+ .long 0x173 # DW_AT_type
+ .uleb128 0x7 # (DIE (0x16c) DW_TAG_base_type)
+ .byte 0x1 # DW_AT_byte_size
+ .byte 0x8 # DW_AT_encoding
+ .long .LASF18 # DW_AT_name: "char"
+ .uleb128 0xc # (DIE (0x173) DW_TAG_const_type)
+ .long 0x16c # DW_AT_type
+ .uleb128 0x8 # (DIE (0x178) DW_TAG_structure_type)
+ .long .LASF19 # DW_AT_name: "uint[uint]"
+ .byte 0x8 # DW_AT_byte_size
+ .long 0x18f # DW_AT_sibling
+ .uleb128 0xa # (DIE (0x182) DW_TAG_member)
+ .ascii "ptr\0" # DW_AT_name
+ .byte 0x2 # DW_AT_decl_file (<built-in>)
+ .byte 0 # DW_AT_decl_line
+ .long 0x18f # DW_AT_type
+ .byte 0 # DW_AT_data_member_location
+ .byte 0 # end of children of DIE 0x178
+ .uleb128 0xd # (DIE (0x18f) DW_TAG_pointer_type)
+ .byte 0x8 # DW_AT_byte_size
+ .uleb128 0x8 # (DIE (0x191) DW_TAG_structure_type)
+ .long .LASF20 # DW_AT_name: "long[]"
+ .byte 0x10 # DW_AT_byte_size
+ .long 0x1b4 # DW_AT_sibling
+ .uleb128 0x9 # (DIE (0x19b) DW_TAG_member)
+ .long .LASF10 # DW_AT_name: "length"
+ .byte 0x2 # DW_AT_decl_file (<built-in>)
+ .byte 0 # DW_AT_decl_line
+ .long 0xf5 # DW_AT_type
+ .byte 0 # DW_AT_data_member_location
+ .uleb128 0xa # (DIE (0x1a7) DW_TAG_member)
+ .ascii "ptr\0" # DW_AT_name
+ .byte 0x2 # DW_AT_decl_file (<built-in>)
+ .byte 0 # DW_AT_decl_line
+ .long 0x1b4 # DW_AT_type
+ .byte 0x8 # DW_AT_data_member_location
+ .byte 0 # end of children of DIE 0x191
+ .uleb128 0xb # (DIE (0x1b4) DW_TAG_pointer_type)
+ .byte 0x8 # DW_AT_byte_size
+ .long 0x1ba # DW_AT_type
+ .uleb128 0x7 # (DIE (0x1ba) DW_TAG_base_type)
+ .byte 0x8 # DW_AT_byte_size
+ .byte 0x5 # DW_AT_encoding
+ .long .LASF21 # DW_AT_name: "long"
+ .uleb128 0x8 # (DIE (0x1c1) DW_TAG_structure_type)
+ .long .LASF22 # DW_AT_name: "char delegate(byte)"
+ .byte 0x10 # DW_AT_byte_size
+ .long 0x1e4 # DW_AT_sibling
+ .uleb128 0x9 # (DIE (0x1cb) DW_TAG_member)
+ .long .LASF23 # DW_AT_name: "object"
+ .byte 0x2 # DW_AT_decl_file (<built-in>)
+ .byte 0 # DW_AT_decl_line
+ .long 0x18f # DW_AT_type
+ .byte 0 # DW_AT_data_member_location
+ .uleb128 0x9 # (DIE (0x1d7) DW_TAG_member)
+ .long .LASF24 # DW_AT_name: "func"
+ .byte 0x2 # DW_AT_decl_file (<built-in>)
+ .byte 0 # DW_AT_decl_line
+ .long 0x1ff # DW_AT_type
+ .byte 0x8 # DW_AT_data_member_location
+ .byte 0 # end of children of DIE 0x1c1
+ .uleb128 0xe # (DIE (0x1e4) DW_TAG_subroutine_type)
+ .long 0x16c # DW_AT_type
+ .long 0x1f8 # DW_AT_sibling
+ .uleb128 0xf # (DIE (0x1ed) DW_TAG_formal_parameter)
+ .long 0x18f # DW_AT_type
+ .uleb128 0xf # (DIE (0x1f2) DW_TAG_formal_parameter)
+ .long 0x1f8 # DW_AT_type
+ .byte 0 # end of children of DIE 0x1e4
+ .uleb128 0x7 # (DIE (0x1f8) DW_TAG_base_type)
+ .byte 0x1 # DW_AT_byte_size
+ .byte 0x5 # DW_AT_encoding
+ .long .LASF25 # DW_AT_name: "byte"
+ .uleb128 0xb # (DIE (0x1ff) DW_TAG_pointer_type)
+ .byte 0x8 # DW_AT_byte_size
+ .long 0x1e4 # DW_AT_type
+ .uleb128 0xe # (DIE (0x205) DW_TAG_subroutine_type)
+ .long 0x16c # DW_AT_type
+ .long 0x214 # DW_AT_sibling
+ .uleb128 0xf # (DIE (0x20e) DW_TAG_formal_parameter)
+ .long 0x1f8 # DW_AT_type
+ .byte 0 # end of children of DIE 0x205
+ .uleb128 0xb # (DIE (0x214) DW_TAG_pointer_type)
+ .byte 0x8 # DW_AT_byte_size
+ .long 0x205 # DW_AT_type
+ .uleb128 0x10 # (DIE (0x21a) DW_TAG_array_type)
+ .long 0x231 # DW_AT_type
+ .long 0x22a # DW_AT_sibling
+ .uleb128 0x11 # (DIE (0x223) DW_TAG_subrange_type)
+ .long 0x22a # DW_AT_type
+ .byte 0 # DW_AT_upper_bound
+ .byte 0 # end of children of DIE 0x21a
+ .uleb128 0x7 # (DIE (0x22a) DW_TAG_base_type)
+ .byte 0x8 # DW_AT_byte_size
+ .byte 0x7 # DW_AT_encoding
+ .long .LASF26 # DW_AT_name: "sizetype"
+ .uleb128 0x7 # (DIE (0x231) DW_TAG_base_type)
+ .byte 0x2 # DW_AT_byte_size
+ .byte 0x5 # DW_AT_encoding
+ .long .LASF27 # DW_AT_name: "short"
+ .byte 0 # end of children of DIE 0xb
+ .section .debug_abbrev,"",@progbits
+.Ldebug_abbrev0:
+ .uleb128 0x1 # (abbrev code)
+ .uleb128 0x11 # (TAG: DW_TAG_compile_unit)
+ .byte 0x1 # DW_children_yes
+ .uleb128 0x25 # (DW_AT_producer)
+ .uleb128 0xe # (DW_FORM_strp)
+ .uleb128 0x13 # (DW_AT_language)
+ .uleb128 0xb # (DW_FORM_data1)
+ .uleb128 0x3 # (DW_AT_name)
+ .uleb128 0xe # (DW_FORM_strp)
+ .uleb128 0x1b # (DW_AT_comp_dir)
+ .uleb128 0xe # (DW_FORM_strp)
+ .uleb128 0x11 # (DW_AT_low_pc)
+ .uleb128 0x1 # (DW_FORM_addr)
+ .uleb128 0x12 # (DW_AT_high_pc)
+ .uleb128 0x7 # (DW_FORM_data8)
+ .uleb128 0x10 # (DW_AT_stmt_list)
+ .uleb128 0x17 # (DW_FORM_sec_offset)
+ .byte 0
+ .byte 0
+ .uleb128 0x2 # (abbrev code)
+ .uleb128 0x1e # (TAG: DW_TAG_module)
+ .byte 0x1 # DW_children_yes
+ .uleb128 0x3 # (DW_AT_name)
+ .uleb128 0xe # (DW_FORM_strp)
+ .uleb128 0x3c # (DW_AT_declaration)
+ .uleb128 0x19 # (DW_FORM_flag_present)
+ .uleb128 0x1 # (DW_AT_sibling)
+ .uleb128 0x13 # (DW_FORM_ref4)
+ .byte 0
+ .byte 0
+ .uleb128 0x3 # (abbrev code)
+ .uleb128 0x2e # (TAG: DW_TAG_subprogram)
+ .byte 0x1 # DW_children_yes
+ .uleb128 0x3f # (DW_AT_external)
+ .uleb128 0x19 # (DW_FORM_flag_present)
+ .uleb128 0x3 # (DW_AT_name)
+ .uleb128 0xe # (DW_FORM_strp)
+ .uleb128 0x3a # (DW_AT_decl_file)
+ .uleb128 0xb # (DW_FORM_data1)
+ .uleb128 0x3b # (DW_AT_decl_line)
+ .uleb128 0xb # (DW_FORM_data1)
+ .uleb128 0x11 # (DW_AT_low_pc)
+ .uleb128 0x1 # (DW_FORM_addr)
+ .uleb128 0x12 # (DW_AT_high_pc)
+ .uleb128 0x7 # (DW_FORM_data8)
+ .uleb128 0x40 # (DW_AT_frame_base)
+ .uleb128 0x18 # (DW_FORM_exprloc)
+ .uleb128 0x2117 # (DW_AT_GNU_all_call_sites)
+ .uleb128 0x19 # (DW_FORM_flag_present)
+ .byte 0
+ .byte 0
+ .uleb128 0x4 # (abbrev code)
+ .uleb128 0x34 # (TAG: DW_TAG_variable)
+ .byte 0 # DW_children_no
+ .uleb128 0x3 # (DW_AT_name)
+ .uleb128 0xe # (DW_FORM_strp)
+ .uleb128 0x3a # (DW_AT_decl_file)
+ .uleb128 0xb # (DW_FORM_data1)
+ .uleb128 0x3b # (DW_AT_decl_line)
+ .uleb128 0xb # (DW_FORM_data1)
+ .uleb128 0x49 # (DW_AT_type)
+ .uleb128 0x13 # (DW_FORM_ref4)
+ .byte 0
+ .byte 0
+ .uleb128 0x5 # (abbrev code)
+ .uleb128 0x1 # (TAG: DW_TAG_array_type)
+ .byte 0x1 # DW_children_yes
+ .uleb128 0x2107 # (DW_AT_GNU_vector)
+ .uleb128 0x19 # (DW_FORM_flag_present)
+ .uleb128 0x49 # (DW_AT_type)
+ .uleb128 0x13 # (DW_FORM_ref4)
+ .uleb128 0x1 # (DW_AT_sibling)
+ .uleb128 0x13 # (DW_FORM_ref4)
+ .byte 0
+ .byte 0
+ .uleb128 0x6 # (abbrev code)
+ .uleb128 0x21 # (TAG: DW_TAG_subrange_type)
+ .byte 0 # DW_children_no
+ .uleb128 0x2f # (DW_AT_upper_bound)
+ .uleb128 0xb # (DW_FORM_data1)
+ .byte 0
+ .byte 0
+ .uleb128 0x7 # (abbrev code)
+ .uleb128 0x24 # (TAG: DW_TAG_base_type)
+ .byte 0 # DW_children_no
+ .uleb128 0xb # (DW_AT_byte_size)
+ .uleb128 0xb # (DW_FORM_data1)
+ .uleb128 0x3e # (DW_AT_encoding)
+ .uleb128 0xb # (DW_FORM_data1)
+ .uleb128 0x3 # (DW_AT_name)
+ .uleb128 0xe # (DW_FORM_strp)
+ .byte 0
+ .byte 0
+ .uleb128 0x8 # (abbrev code)
+ .uleb128 0x13 # (TAG: DW_TAG_structure_type)
+ .byte 0x1 # DW_children_yes
+ .uleb128 0x3 # (DW_AT_name)
+ .uleb128 0xe # (DW_FORM_strp)
+ .uleb128 0xb # (DW_AT_byte_size)
+ .uleb128 0xb # (DW_FORM_data1)
+ .uleb128 0x1 # (DW_AT_sibling)
+ .uleb128 0x13 # (DW_FORM_ref4)
+ .byte 0
+ .byte 0
+ .uleb128 0x9 # (abbrev code)
+ .uleb128 0xd # (TAG: DW_TAG_member)
+ .byte 0 # DW_children_no
+ .uleb128 0x3 # (DW_AT_name)
+ .uleb128 0xe # (DW_FORM_strp)
+ .uleb128 0x3a # (DW_AT_decl_file)
+ .uleb128 0xb # (DW_FORM_data1)
+ .uleb128 0x3b # (DW_AT_decl_line)
+ .uleb128 0xb # (DW_FORM_data1)
+ .uleb128 0x49 # (DW_AT_type)
+ .uleb128 0x13 # (DW_FORM_ref4)
+ .uleb128 0x38 # (DW_AT_data_member_location)
+ .uleb128 0xb # (DW_FORM_data1)
+ .byte 0
+ .byte 0
+ .uleb128 0xa # (abbrev code)
+ .uleb128 0xd # (TAG: DW_TAG_member)
+ .byte 0 # DW_children_no
+ .uleb128 0x3 # (DW_AT_name)
+ .uleb128 0x8 # (DW_FORM_string)
+ .uleb128 0x3a # (DW_AT_decl_file)
+ .uleb128 0xb # (DW_FORM_data1)
+ .uleb128 0x3b # (DW_AT_decl_line)
+ .uleb128 0xb # (DW_FORM_data1)
+ .uleb128 0x49 # (DW_AT_type)
+ .uleb128 0x13 # (DW_FORM_ref4)
+ .uleb128 0x38 # (DW_AT_data_member_location)
+ .uleb128 0xb # (DW_FORM_data1)
+ .byte 0
+ .byte 0
+ .uleb128 0xb # (abbrev code)
+ .uleb128 0xf # (TAG: DW_TAG_pointer_type)
+ .byte 0 # DW_children_no
+ .uleb128 0xb # (DW_AT_byte_size)
+ .uleb128 0xb # (DW_FORM_data1)
+ .uleb128 0x49 # (DW_AT_type)
+ .uleb128 0x13 # (DW_FORM_ref4)
+ .byte 0
+ .byte 0
+ .uleb128 0xc # (abbrev code)
+ .uleb128 0x26 # (TAG: DW_TAG_const_type)
+ .byte 0 # DW_children_no
+ .uleb128 0x49 # (DW_AT_type)
+ .uleb128 0x13 # (DW_FORM_ref4)
+ .byte 0
+ .byte 0
+ .uleb128 0xd # (abbrev code)
+ .uleb128 0xf # (TAG: DW_TAG_pointer_type)
+ .byte 0 # DW_children_no
+ .uleb128 0xb # (DW_AT_byte_size)
+ .uleb128 0xb # (DW_FORM_data1)
+ .byte 0
+ .byte 0
+ .uleb128 0xe # (abbrev code)
+ .uleb128 0x15 # (TAG: DW_TAG_subroutine_type)
+ .byte 0x1 # DW_children_yes
+ .uleb128 0x49 # (DW_AT_type)
+ .uleb128 0x13 # (DW_FORM_ref4)
+ .uleb128 0x1 # (DW_AT_sibling)
+ .uleb128 0x13 # (DW_FORM_ref4)
+ .byte 0
+ .byte 0
+ .uleb128 0xf # (abbrev code)
+ .uleb128 0x5 # (TAG: DW_TAG_formal_parameter)
+ .byte 0 # DW_children_no
+ .uleb128 0x49 # (DW_AT_type)
+ .uleb128 0x13 # (DW_FORM_ref4)
+ .byte 0
+ .byte 0
+ .uleb128 0x10 # (abbrev code)
+ .uleb128 0x1 # (TAG: DW_TAG_array_type)
+ .byte 0x1 # DW_children_yes
+ .uleb128 0x49 # (DW_AT_type)
+ .uleb128 0x13 # (DW_FORM_ref4)
+ .uleb128 0x1 # (DW_AT_sibling)
+ .uleb128 0x13 # (DW_FORM_ref4)
+ .byte 0
+ .byte 0
+ .uleb128 0x11 # (abbrev code)
+ .uleb128 0x21 # (TAG: DW_TAG_subrange_type)
+ .byte 0 # DW_children_no
+ .uleb128 0x49 # (DW_AT_type)
+ .uleb128 0x13 # (DW_FORM_ref4)
+ .uleb128 0x2f # (DW_AT_upper_bound)
+ .uleb128 0xb # (DW_FORM_data1)
+ .byte 0
+ .byte 0
+ .byte 0
+ .section .debug_aranges,"",@progbits
+ .long 0x2c # Length of Address Ranges Info
+ .value 0x2 # DWARF Version
+ .long .Ldebug_info0 # Offset of Compilation Unit Info
+ .byte 0x8 # Size of Address
+ .byte 0 # Size of Segment Descriptor
+ .value 0 # Pad to 16 byte boundary
+ .value 0
+ .quad .Ltext0 # Address
+ .quad .Letext0-.Ltext0 # Length
+ .quad 0
+ .quad 0
+ .section .debug_line,"",@progbits
+.Ldebug_line0:
+ .section .debug_str,"MS",@progbits,1
+.LASF14:
+ .string "dstring"
+.LASF19:
+ .string "uint[uint]"
+.LASF3:
+ .string "stringvalue"
+.LASF17:
+ .string "string"
+.LASF23:
+ .string "object"
+.LASF5:
+ .string "dynamicarray"
+.LASF16:
+ .string "wchar"
+.LASF25:
+ .string "byte"
+.LASF1:
+ .string "dstringvalue"
+.LASF10:
+ .string "length"
+.LASF30:
+ .string "/tmp"
+.LASF13:
+ .string "dchar"
+.LASF27:
+ .string "short"
+.LASF31:
+ .string "typeprint"
+.LASF2:
+ .string "wstringvalue"
+.LASF6:
+ .string "delegateptr"
+.LASF32:
+ .string "main"
+.LASF4:
+ .string "associativearray"
+.LASF26:
+ .string "sizetype"
+.LASF21:
+ .string "long"
+.LASF29:
+ .string "typeprint.d"
+.LASF22:
+ .string "char delegate(byte)"
+.LASF12:
+ .string "ulong"
+.LASF28:
+ .string "GNU D 6.0.0 20160123 (experimental)"
+.LASF11:
+ .string "ubyte"
+.LASF8:
+ .string "staticarray"
+.LASF7:
+ .string "funcptr"
+.LASF0:
+ .string "vectorarray"
+.LASF9:
+ .string "voidptr"
+.LASF15:
+ .string "wstring"
+.LASF24:
+ .string "func"
+.LASF18:
+ .string "char"
+.LASF20:
+ .string "long[]"
+ .ident "GCC: (GNU) 6.0.0 20160123 (experimental)"
+ .section .note.GNU-stack,"",@progbits
new file mode 100644
@@ -0,0 +1,80 @@
+# Copyright (C) 2016 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/>.
+
+# Test printing various built-in types.
+
+load_lib "d-support.exp"
+load_lib "dwarf.exp"
+
+if { [skip_d_tests] } { continue }
+
+# This test can only be run on x86-64 targets which support DWARF.
+if {![dwarf2_support] || ![istarget "x86_64-*-*"] || ![is_lp64_target]} {
+ return 0
+}
+
+standard_testfile .S
+
+# Compile and start with a fresh gdb.
+
+if {[prepare_for_testing $testfile.exp $testfile $srcfile {nodebug}]} {
+ return -1
+}
+
+if {![runto_main]} {
+ return -1
+}
+
+# Simple pointer type.
+gdb_test "ptype voidptr" "type = void\\*"
+
+# Simple array type.
+gdb_test "ptype staticarray" "type = short\\\[1\\\]"
+
+# Function types are also pointers, but printed without the asterisk.
+gdb_test "ptype funcptr" "type = char function\\(byte\\)"
+
+# Delegates are two-field record types, but only the name is printed.
+gdb_test "ptype delegateptr" "type = char delegate\\(byte\\)"
+gdb_test "ptype delegateptr.object" "type = void\\*"
+gdb_test "ptype delegateptr.func" "type = char function\\(void\\*, byte\\)"
+
+# Likewise for dynamic arrays.
+gdb_test "ptype dynamicarray" "type = long\\\[\\\]"
+gdb_test "ptype dynamicarray.length" "type = ulong"
+gdb_test "ptype dynamicarray.ptr" "type = long\\*"
+
+# Likewise for associative arrays.
+gdb_test "ptype associativearray" "type = uint\\\[uint\\\]"
+gdb_test "ptype associativearray.ptr" "type = void\\*"
+
+# Strings are really dynamic arrays, but they are given a typename.
+gdb_test "ptype stringvalue" "type = string"
+gdb_test "ptype stringvalue.length" "type = ulong"
+gdb_test "ptype stringvalue.ptr" "type = char\\*"
+
+gdb_test "ptype wstringvalue" "type = wstring"
+gdb_test "ptype wstringvalue.length" "type = ulong"
+gdb_test "ptype wstringvalue.ptr" "type = wchar\\*"
+
+gdb_test "ptype dstringvalue" "type = dstring"
+gdb_test "ptype dstringvalue.length" "type = ulong"
+gdb_test "ptype dstringvalue.ptr" "type = dchar\\*"
+
+# Vectors have their own special syntax.
+gdb_test "ptype vectorarray" "type = __vector\\(ubyte\\\[8\\\]\\)"
+
+# Finally, recognize D modules.
+gdb_test "ptype typeprint" "type = module typeprint"