]> git.proxmox.com Git - rustc.git/blame - src/librustc_trans/debuginfo/type_names.rs
New upstream version 1.12.1+dfsg1
[rustc.git] / src / librustc_trans / debuginfo / type_names.rs
CommitLineData
d9579d0f
AL
1// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2// file at the top-level directory of this distribution and at
3// http://rust-lang.org/COPYRIGHT.
4//
5// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8// option. This file may not be copied, modified, or distributed
9// except according to those terms.
10
11// Type Names for Debug Info.
12
54a0048b
SL
13use common::CrateContext;
14use rustc::hir::def_id::DefId;
54a0048b
SL
15use rustc::ty::subst;
16use rustc::ty::{self, Ty};
d9579d0f 17
54a0048b 18use rustc::hir;
d9579d0f
AL
19
20// Compute the name of the type as it should be stored in debuginfo. Does not do
21// any caching, i.e. calling the function twice with the same type will also do
22// the work twice. The `qualified` parameter only affects the first level of the
23// type name, further levels (i.e. type parameters) are always fully qualified.
24pub fn compute_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
25 t: Ty<'tcx>,
26 qualified: bool)
27 -> String {
28 let mut result = String::with_capacity(64);
29 push_debuginfo_type_name(cx, t, qualified, &mut result);
30 result
31}
32
33// Pushes the name of the type as it should be stored in debuginfo on the
34// `output` String. See also compute_debuginfo_type_name().
35pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
36 t: Ty<'tcx>,
37 qualified: bool,
38 output: &mut String) {
39 match t.sty {
92a42be0
SL
40 ty::TyBool => output.push_str("bool"),
41 ty::TyChar => output.push_str("char"),
42 ty::TyStr => output.push_str("str"),
5bcae85e 43 ty::TyNever => output.push_str("!"),
9cc50fc6
SL
44 ty::TyInt(int_ty) => output.push_str(int_ty.ty_to_string()),
45 ty::TyUint(uint_ty) => output.push_str(uint_ty.ty_to_string()),
46 ty::TyFloat(float_ty) => output.push_str(float_ty.ty_to_string()),
e9174d1e
SL
47 ty::TyStruct(def, substs) |
48 ty::TyEnum(def, substs) => {
49 push_item_name(cx, def.did, qualified, output);
d9579d0f
AL
50 push_type_params(cx, substs, output);
51 },
a7813a04 52 ty::TyTuple(component_types) => {
d9579d0f
AL
53 output.push('(');
54 for &component_type in component_types {
55 push_debuginfo_type_name(cx, component_type, true, output);
56 output.push_str(", ");
57 }
58 if !component_types.is_empty() {
59 output.pop();
60 output.pop();
61 }
62 output.push(')');
63 },
62682a34 64 ty::TyBox(inner_type) => {
d9579d0f
AL
65 output.push_str("Box<");
66 push_debuginfo_type_name(cx, inner_type, true, output);
67 output.push('>');
68 },
c1a9b12d 69 ty::TyRawPtr(ty::TypeAndMut { ty: inner_type, mutbl } ) => {
d9579d0f
AL
70 output.push('*');
71 match mutbl {
e9174d1e
SL
72 hir::MutImmutable => output.push_str("const "),
73 hir::MutMutable => output.push_str("mut "),
d9579d0f
AL
74 }
75
76 push_debuginfo_type_name(cx, inner_type, true, output);
77 },
c1a9b12d 78 ty::TyRef(_, ty::TypeAndMut { ty: inner_type, mutbl }) => {
d9579d0f 79 output.push('&');
e9174d1e 80 if mutbl == hir::MutMutable {
d9579d0f
AL
81 output.push_str("mut ");
82 }
83
84 push_debuginfo_type_name(cx, inner_type, true, output);
85 },
62682a34
SL
86 ty::TyArray(inner_type, len) => {
87 output.push('[');
88 push_debuginfo_type_name(cx, inner_type, true, output);
89 output.push_str(&format!("; {}", len));
90 output.push(']');
91 },
92 ty::TySlice(inner_type) => {
d9579d0f
AL
93 output.push('[');
94 push_debuginfo_type_name(cx, inner_type, true, output);
d9579d0f
AL
95 output.push(']');
96 },
62682a34 97 ty::TyTrait(ref trait_data) => {
c1a9b12d 98 let principal = cx.tcx().erase_late_bound_regions(&trait_data.principal);
d9579d0f
AL
99 push_item_name(cx, principal.def_id, false, output);
100 push_type_params(cx, principal.substs, output);
101 },
54a0048b
SL
102 ty::TyFnDef(_, _, &ty::BareFnTy{ unsafety, abi, ref sig } ) |
103 ty::TyFnPtr(&ty::BareFnTy{ unsafety, abi, ref sig } ) => {
e9174d1e 104 if unsafety == hir::Unsafety::Unsafe {
d9579d0f
AL
105 output.push_str("unsafe ");
106 }
107
54a0048b 108 if abi != ::abi::Abi::Rust {
d9579d0f
AL
109 output.push_str("extern \"");
110 output.push_str(abi.name());
111 output.push_str("\" ");
112 }
113
114 output.push_str("fn(");
115
c1a9b12d 116 let sig = cx.tcx().erase_late_bound_regions(sig);
a7813a04 117 let sig = cx.tcx().normalize_associated_type(&sig);
d9579d0f
AL
118 if !sig.inputs.is_empty() {
119 for &parameter_type in &sig.inputs {
120 push_debuginfo_type_name(cx, parameter_type, true, output);
121 output.push_str(", ");
122 }
123 output.pop();
124 output.pop();
125 }
126
127 if sig.variadic {
128 if !sig.inputs.is_empty() {
129 output.push_str(", ...");
130 } else {
131 output.push_str("...");
132 }
133 }
134
135 output.push(')');
136
5bcae85e
SL
137 if !sig.output.is_nil() {
138 output.push_str(" -> ");
139 push_debuginfo_type_name(cx, sig.output, true, output);
d9579d0f
AL
140 }
141 },
62682a34 142 ty::TyClosure(..) => {
d9579d0f
AL
143 output.push_str("closure");
144 }
62682a34
SL
145 ty::TyError |
146 ty::TyInfer(_) |
147 ty::TyProjection(..) |
5bcae85e 148 ty::TyAnon(..) |
62682a34 149 ty::TyParam(_) => {
54a0048b
SL
150 bug!("debuginfo: Trying to create type name for \
151 unexpected type: {:?}", t);
d9579d0f
AL
152 }
153 }
154
155 fn push_item_name(cx: &CrateContext,
e9174d1e 156 def_id: DefId,
d9579d0f
AL
157 qualified: bool,
158 output: &mut String) {
54a0048b
SL
159 if qualified {
160 output.push_str(&cx.tcx().crate_name(def_id.krate));
161 for path_element in cx.tcx().def_path(def_id).data {
162 output.push_str("::");
163 output.push_str(&path_element.data.as_interned_str());
d9579d0f 164 }
54a0048b
SL
165 } else {
166 output.push_str(&cx.tcx().item_name(def_id).as_str());
167 }
d9579d0f
AL
168 }
169
170 // Pushes the type parameters in the given `Substs` to the output string.
171 // This ignores region parameters, since they can't reliably be
172 // reconstructed for items from non-local crates. For local crates, this
173 // would be possible but with inlining and LTO we have to use the least
174 // common denominator - otherwise we would run into conflicts.
175 fn push_type_params<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
176 substs: &subst::Substs<'tcx>,
177 output: &mut String) {
178 if substs.types.is_empty() {
179 return;
180 }
181
182 output.push('<');
183
62682a34 184 for &type_parameter in &substs.types {
d9579d0f
AL
185 push_debuginfo_type_name(cx, type_parameter, true, output);
186 output.push_str(", ");
187 }
188
189 output.pop();
190 output.pop();
191
192 output.push('>');
193 }
194}