diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/dwarf_const.rs b/compiler/rustc_codegen_llvm/src/debuginfo/dwarf_const.rs index 408429152223d..6f7ada9ac46a9 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/dwarf_const.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/dwarf_const.rs @@ -16,7 +16,9 @@ macro_rules! declare_constant { }; } +// DWARF attribute tags declare_constant!(DW_TAG_const_type: c_uint); +declare_constant!(DW_TAG_reference_type: c_uint); // DWARF languages. declare_constant!(DW_LANG_Rust: c_uint); diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index 8d782a618fc07..e3ad7bcefb96a 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -166,16 +166,118 @@ fn build_pointer_or_reference_di_node<'ll, 'tcx>( "ptr_type={ptr_type}, pointee_type={pointee_type}", ); - let di_node = unsafe { - llvm::LLVMRustDIBuilderCreatePointerType( - DIB(cx), - pointee_type_di_node, - data_layout.pointer_size.bits(), - data_layout.pointer_align.abi.bits() as u32, - 0, // Ignore DWARF address space. - ptr_type_debuginfo_name.as_c_char_ptr(), - ptr_type_debuginfo_name.len(), - ) + let di_node = match (ptr_type.kind(), pointee_type.kind()) { + // if we have a ref-to-ref, treat the outter ref as a pointer and wrap it in a `ref$<>` pseudo-struct. + // This is necessary because LLDB (or more specifically, `TypeSystemClang`) seems to implicitly treat + // references to references as invalid, and treats them as a reference to the first + // non-reference/pointer underlying type (e.g. "&&u8" -> "&u8", "&&&&&u8" -> "&u8"). This is expected + // behavior for C/C++ since ref-to-ref isn't valid in those languages, so it's not possible to fix on + // the LLDB end outside of creating a `TypeSystemRust`. + (ty::Ref(_, _, ptr_mut), ty::Ref(_, _, _)) => unsafe { + let qualified_ref = llvm::LLVMRustDIBuilderCreatePointerType( + DIB(cx), + pointee_type_di_node, + data_layout.pointer_size.bits(), + data_layout.pointer_align.abi.bits() as u32, + 0, // Ignore DWARF address space. + ptr_type_debuginfo_name.as_c_char_ptr(), + ptr_type_debuginfo_name.len(), + ); + + let qualified_ref = if ptr_mut.is_not() { + llvm::LLVMRustDIBuilderCreateQualifiedType( + DIB(cx), + dwarf_const::DW_TAG_const_type, + qualified_ref, + ) + } else { + qualified_ref + }; + + // now we create a wrapper struct that holds the pointer. This provides the + // info necessary to differentiate a pointer from a ref, but doesn't run into + // the ref-to-ref problem + + return type_map::build_type_with_children( + cx, + type_map::stub( + cx, + Stub::Struct, + unique_type_id, + &ptr_type_debuginfo_name, + None, + cx.size_and_align_of(ptr_type), + NO_SCOPE_METADATA, + DIFlags::FlagZero, + ), + |cx, owner| { + smallvec![build_field_di_node( + cx, + owner, + "ptr", + cx.size_and_align_of(ptr_type), + Size::ZERO, + DIFlags::FlagZero, + qualified_ref, + None, + )] + }, + |_cx| smallvec![pointee_type_di_node], + ); + }, + // if we have a ref-to-, apply `const` to the inner value as necessary + (ty::Ref(_, _, ptr_mut), _) => unsafe { + let pointee_type_di_node = if ptr_mut.is_not() { + llvm::LLVMRustDIBuilderCreateQualifiedType( + DIB(cx), + dwarf_const::DW_TAG_const_type, + pointee_type_di_node, + ) + } else { + pointee_type_di_node + }; + + llvm::LLVMRustDIBuilderCreateReferenceType( + DIB(cx), + dwarf_const::DW_TAG_reference_type, + pointee_type_di_node, + ) + }, + // if we have any pointer, apply `const` to the inner value as necessary + (ty::RawPtr(_, ptr_mut), _) => unsafe { + let pointee_type_di_node = if ptr_mut.is_not() { + llvm::LLVMRustDIBuilderCreateQualifiedType( + DIB(cx), + dwarf_const::DW_TAG_const_type, + pointee_type_di_node, + ) + } else { + pointee_type_di_node + }; + + llvm::LLVMRustDIBuilderCreatePointerType( + DIB(cx), + pointee_type_di_node, + data_layout.pointer_size.bits(), + data_layout.pointer_align.abi.bits() as u32, + 0, // Ignore DWARF address space. + ptr_type_debuginfo_name.as_c_char_ptr(), + ptr_type_debuginfo_name.len(), + ) + }, + // apply no modifications to `Box` + (ty::Adt(_, _), _) => unsafe { + llvm::LLVMRustDIBuilderCreatePointerType( + DIB(cx), + pointee_type_di_node, + data_layout.pointer_size.bits(), + data_layout.pointer_align.abi.bits() as u32, + 0, // Ignore DWARF address space. + ptr_type_debuginfo_name.as_c_char_ptr(), + ptr_type_debuginfo_name.len(), + ) + }, + _ => todo!(), }; DINodeCreationResult { di_node, already_stored_in_typemap: false } diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 009d15a932f7a..108b24af8b899 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -2030,6 +2030,12 @@ unsafe extern "C" { Type: &'a DIType, ) -> &'a DIDerivedType; + pub fn LLVMRustDIBuilderCreateReferenceType<'a>( + Builder: &DIBuilder<'a>, + Tag: c_uint, + Type: &'a DIType, + ) -> &'a DIDerivedType; + pub fn LLVMRustDIBuilderCreateLexicalBlock<'a>( Builder: &DIBuilder<'a>, Scope: &'a DIScope, diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs index 869798d8be194..98582e9ae72d8 100644 --- a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs +++ b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs @@ -160,7 +160,9 @@ fn push_debuginfo_type_name<'tcx>( } } ty::Ref(_, inner_type, mutbl) => { - if cpp_like_debuginfo { + // Use the MSVC style whenever we have a ref-to-ref, since LLDB does not properly handle + // ref-to-ref. + if cpp_like_debuginfo || matches!(inner_type.kind(), ty::Ref(_, _, _)) { match mutbl { Mutability::Not => output.push_str("ref$<"), Mutability::Mut => output.push_str("ref_mut$<"), @@ -172,7 +174,7 @@ fn push_debuginfo_type_name<'tcx>( push_debuginfo_type_name(tcx, inner_type, qualified, output, visited); - if cpp_like_debuginfo { + if cpp_like_debuginfo || matches!(inner_type.kind(), ty::Ref(_, _, _)) { push_close_angle_bracket(cpp_like_debuginfo, output); } } diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index 35186778671bc..d2a9ec9817ed4 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -1182,6 +1182,13 @@ LLVMRustDIBuilderCreateQualifiedType(LLVMDIBuilderRef Builder, unsigned Tag, unwrap(Builder)->createQualifiedType(Tag, unwrapDI(Type))); } +extern "C" LLVMMetadataRef +LLVMRustDIBuilderCreateReferenceType(LLVMDIBuilderRef Builder, unsigned Tag, + LLVMMetadataRef Type) { + return wrap( + unwrap(Builder)->createReferenceType(Tag, unwrapDI(Type))); +} + extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateLexicalBlock(LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, LLVMMetadataRef File, diff --git a/src/etc/gdb_load_rust_pretty_printers.py b/src/etc/gdb_load_rust_pretty_printers.py index 73d1e79f9617d..3183659e6c85b 100644 --- a/src/etc/gdb_load_rust_pretty_printers.py +++ b/src/etc/gdb_load_rust_pretty_printers.py @@ -14,3 +14,8 @@ gdb_lookup.register_printers(gdb.current_objfile()) except Exception: gdb_lookup.register_printers(gdb.selected_inferior().progspace) + +try: + gdb_lookup.register_type_printers(gdb.current_objfile()) +except Exception: + gdb_lookup.register_type_printers(gdb.selected_inferior().progspace) diff --git a/src/etc/gdb_lookup.py b/src/etc/gdb_lookup.py index d368f7ed1ec5c..379d8ca0f734f 100644 --- a/src/etc/gdb_lookup.py +++ b/src/etc/gdb_lookup.py @@ -16,6 +16,10 @@ def register_printers(objfile): objfile.pretty_printers.append(printer) +def register_type_printers(objfile): + gdb.types.register_type_printer(objfile, PtrTypePrinter("PtrOrRef")) + + # BACKCOMPAT: rust 1.35 def is_hashbrown_hashmap(hash_map): return len(hash_map.type.fields()) == 1 diff --git a/src/etc/gdb_providers.py b/src/etc/gdb_providers.py index 34bb5c39909e4..6242aa561fd60 100644 --- a/src/etc/gdb_providers.py +++ b/src/etc/gdb_providers.py @@ -480,3 +480,68 @@ def children(self): def display_hint(self): return "map" if self._show_values else "array" + + +class NestedRefProvider(printer_base): + def __init__(self, valobj): + self._valobj = valobj + self._ptr = self._valobj["ptr"] + + def to_string(self): + return str(self._valobj.cast(self._ptr.type)) + + def children(self): + yield ("*ptr", self._ptr.referenced_value()) + + def num_children(self): + return 1 + + def display_hint(self): + return "array" + + +PTR_CODES = ( + gdb.TYPE_CODE_PTR, + gdb.TYPE_CODE_REF, + gdb.TYPE_CODE_RVALUE_REF, + gdb.TYPE_CODE_MEMBERPTR, +) + + +class PtrTypeRecognizer: + def recognize(self, type: gdb.Type) -> str: + if type.code not in PTR_CODES: + return None + + name_parts = [] + + ptr_type: gdb.Type = type + ptee_type: gdb.Type = type.target() + + while ptr_type.code in PTR_CODES: + is_ref: bool = ptr_type.code == gdb.TYPE_CODE_REF + + if ptee_type.const() == ptee_type: + if is_ref: + name_parts.append("&") + else: + name_parts.append("*const ") + else: + if is_ref: + name_parts.append("&mut ") + else: + name_parts.append("*mut ") + + ptr_type = ptee_type + try: + ptee_type = ptee_type.target() + except RuntimeError: + break + + name_parts.append(ptr_type.unqualified().name) + return "".join(name_parts) + + +class PtrTypePrinter(gdb.types.TypePrinter): + def instantiate(self): + return PtrTypeRecognizer() diff --git a/src/etc/lldb_commands b/src/etc/lldb_commands index ef0c3740f0326..7524e6ff65927 100644 --- a/src/etc/lldb_commands +++ b/src/etc/lldb_commands @@ -1,43 +1,91 @@ -type synthetic add -l lldb_lookup.synthetic_lookup -x "^(alloc::([a-z_]+::)+)String$" --category Rust +# Default +type synthetic add -l lldb_lookup.synthetic_lookup -x ".*" --category Rust +type summary add -F lldb_lookup.summary_lookup -x ".*" --category Rust +# String +type synthetic add -l lldb_lookup.StdStringSyntheticProvider -x "^(alloc::([a-z_]+::)+)String$" --category Rust +type summary add -F lldb_lookup.StdStringSummaryProvider -e -x -h "^(alloc::([a-z_]+::)+)String$" --category Rust +# Ref/Ptr +type synthetic add -l lldb_lookup.PtrSyntheticProvider -x "^(const )?.* \*$" --category Rust +type synthetic add -l lldb_lookup.PtrSyntheticProvider -x "^(const )?.* &$" --category Rust +type summary add -F lldb_lookup.PtrSummaryProvider -e -h -x "^(const )?.* &$" --category Rust +type summary add -F lldb_lookup.PtrSummaryProvider -e -h -x "^(const )?.* \*$" --category Rust +## Nested Ref (must occur before &str) +type synthetic add -l lldb_lookup.NestedRefSyntheticProvider -x "^ref(_mut)?\$<.+>$" --category Rust +type summary add -F lldb_lookup.NestedRefSummaryProvider -x "^ref(_mut)?\$<.+>$" --category Rust +# &str/&mut str type synthetic add -l lldb_lookup.synthetic_lookup -x "^&(mut )?str$" --category Rust +type summary add -F lldb_lookup.summary_lookup -e -x -h "^&(mut )?str$" --category Rust +## MSVC +type synthetic add -l lldb_lookup.MSVCStrSyntheticProvider -x "^ref(_mut)?\$$" --category Rust +type summary add -F lldb_lookup.StdStrSummaryProvider -e -h -x "^ref(_mut)?\$$" --category Rust +# Array type synthetic add -l lldb_lookup.synthetic_lookup -x "^&(mut )?\\[.+\\]$" --category Rust +type summary add -F lldb_lookup.summary_lookup -e -x -h "^&(mut )?\\[.+\\]$" --category Rust +# Slice +type synthetic add -l lldb_lookup.StdSliceSyntheticProvider -x "^ref(_mut)?\$<\[.+\]>" --category Rust +type summary add -F lldb_lookup.StdSliceSummaryProvider -e -x -h "^ref(_mut)?\$<\[.+\]>" --category Rust +## MSVC +type synthetic add -l lldb_lookup.MSVCStdSliceSyntheticProvider -x "^ref(_mut)?\$ >" --category Rust +type summary add -F lldb_lookup.StdSliceSummaryProvider -e -x -h "^ref(_mut)?\$ >" --category Rust +# OsString type synthetic add -l lldb_lookup.synthetic_lookup -x "^(std::ffi::([a-z_]+::)+)OsString$" --category Rust +type summary add -F lldb_lookup.summary_lookup -e -x -h "^(std::ffi::([a-z_]+::)+)OsString$" --category Rust +# Vec type synthetic add -l lldb_lookup.synthetic_lookup -x "^(alloc::([a-z_]+::)+)Vec<.+>$" --category Rust +type summary add -F lldb_lookup.summary_lookup -e -x -h "^(alloc::([a-z_]+::)+)Vec<.+>$" --category Rust +# VecDeque type synthetic add -l lldb_lookup.synthetic_lookup -x "^(alloc::([a-z_]+::)+)VecDeque<.+>$" --category Rust +type summary add -F lldb_lookup.summary_lookup -e -x -h "^(alloc::([a-z_]+::)+)VecDeque<.+>$" --category Rust +# BTreeSet type synthetic add -l lldb_lookup.synthetic_lookup -x "^(alloc::([a-z_]+::)+)BTreeSet<.+>$" --category Rust +type summary add -F lldb_lookup.summary_lookup -e -x -h "^(alloc::([a-z_]+::)+)BTreeSet<.+>$" --category Rust +# BTreeMap type synthetic add -l lldb_lookup.synthetic_lookup -x "^(alloc::([a-z_]+::)+)BTreeMap<.+>$" --category Rust +type summary add -F lldb_lookup.summary_lookup -e -x -h "^(alloc::([a-z_]+::)+)BTreeMap<.+>$" --category Rust +# HashMap type synthetic add -l lldb_lookup.synthetic_lookup -x "^(std::collections::([a-z_]+::)+)HashMap<.+>$" --category Rust +type summary add -F lldb_lookup.summary_lookup -e -x -h "^(std::collections::([a-z_]+::)+)HashMap<.+>$" --category Rust +# HashSet type synthetic add -l lldb_lookup.synthetic_lookup -x "^(std::collections::([a-z_]+::)+)HashSet<.+>$" --category Rust +type summary add -F lldb_lookup.summary_lookup -e -x -h "^(std::collections::([a-z_]+::)+)HashSet<.+>$" --category Rust +# Rc type synthetic add -l lldb_lookup.synthetic_lookup -x "^(alloc::([a-z_]+::)+)Rc<.+>$" --category Rust +type summary add -F lldb_lookup.summary_lookup -e -x -h "^(alloc::([a-z_]+::)+)Rc<.+>$" --category Rust +# Arc type synthetic add -l lldb_lookup.synthetic_lookup -x "^(alloc::([a-z_]+::)+)Arc<.+>$" --category Rust +type summary add -F lldb_lookup.summary_lookup -e -x -h "^(alloc::([a-z_]+::)+)Arc<.+>$" --category Rust +# Cell type synthetic add -l lldb_lookup.synthetic_lookup -x "^(core::([a-z_]+::)+)Cell<.+>$" --category Rust +type summary add -F lldb_lookup.summary_lookup -e -x -h "^(core::([a-z_]+::)+)Cell<.+>$" --category Rust +# RefCell type synthetic add -l lldb_lookup.synthetic_lookup -x "^(core::([a-z_]+::)+)Ref<.+>$" --category Rust type synthetic add -l lldb_lookup.synthetic_lookup -x "^(core::([a-z_]+::)+)RefMut<.+>$" --category Rust type synthetic add -l lldb_lookup.synthetic_lookup -x "^(core::([a-z_]+::)+)RefCell<.+>$" --category Rust -type synthetic add -l lldb_lookup.synthetic_lookup -x "^(core::([a-z_]+::)+)NonZero<.+>$" --category Rust -type synthetic add -l lldb_lookup.synthetic_lookup -x "^core::num::([a-z_]+::)*NonZero.+$" --category Rust -type synthetic add -l lldb_lookup.synthetic_lookup -x "^(std::([a-z_]+::)+)PathBuf$" --category Rust -type synthetic add -l lldb_lookup.synthetic_lookup -x "^&(mut )?(std::([a-z_]+::)+)Path$" --category Rust -type synthetic add -l lldb_lookup.synthetic_lookup -x "^(.*)$" --category Rust -type summary add -F _ -e -x -h "^.*$" --category Rust -type summary add -F lldb_lookup.summary_lookup -e -x -h "^(alloc::([a-z_]+::)+)String$" --category Rust -type summary add -F lldb_lookup.summary_lookup -e -x -h "^&(mut )?str$" --category Rust -type summary add -F lldb_lookup.summary_lookup -e -x -h "^&(mut )?\\[.+\\]$" --category Rust -type summary add -F lldb_lookup.summary_lookup -e -x -h "^(std::ffi::([a-z_]+::)+)OsString$" --category Rust -type summary add -F lldb_lookup.summary_lookup -e -x -h "^(alloc::([a-z_]+::)+)Vec<.+>$" --category Rust -type summary add -F lldb_lookup.summary_lookup -e -x -h "^(alloc::([a-z_]+::)+)VecDeque<.+>$" --category Rust -type summary add -F lldb_lookup.summary_lookup -e -x -h "^(alloc::([a-z_]+::)+)BTreeSet<.+>$" --category Rust -type summary add -F lldb_lookup.summary_lookup -e -x -h "^(alloc::([a-z_]+::)+)BTreeMap<.+>$" --category Rust -type summary add -F lldb_lookup.summary_lookup -e -x -h "^(std::collections::([a-z_]+::)+)HashMap<.+>$" --category Rust -type summary add -F lldb_lookup.summary_lookup -e -x -h "^(std::collections::([a-z_]+::)+)HashSet<.+>$" --category Rust -type summary add -F lldb_lookup.summary_lookup -e -x -h "^(alloc::([a-z_]+::)+)Rc<.+>$" --category Rust -type summary add -F lldb_lookup.summary_lookup -e -x -h "^(alloc::([a-z_]+::)+)Arc<.+>$" --category Rust -type summary add -F lldb_lookup.summary_lookup -e -x -h "^(core::([a-z_]+::)+)Cell<.+>$" --category Rust type summary add -F lldb_lookup.summary_lookup -e -x -h "^(core::([a-z_]+::)+)Ref<.+>$" --category Rust type summary add -F lldb_lookup.summary_lookup -e -x -h "^(core::([a-z_]+::)+)RefMut<.+>$" --category Rust type summary add -F lldb_lookup.summary_lookup -e -x -h "^(core::([a-z_]+::)+)RefCell<.+>$" --category Rust +# NonZero +type synthetic add -l lldb_lookup.synthetic_lookup -x "^(core::([a-z_]+::)+)NonZero<.+>$" --category Rust +type synthetic add -l lldb_lookup.synthetic_lookup -x "^core::num::([a-z_]+::)*NonZero.+$" --category Rust type summary add -F lldb_lookup.summary_lookup -e -x -h "^(core::([a-z_]+::)+)NonZero<.+>$" --category Rust type summary add -F lldb_lookup.summary_lookup -e -x -h "^core::num::([a-z_]+::)*NonZero.+$" --category Rust +# PathBuf +type synthetic add -l lldb_lookup.synthetic_lookup -x "^(std::([a-z_]+::)+)PathBuf$" --category Rust type summary add -F lldb_lookup.summary_lookup -e -x -h "^(std::([a-z_]+::)+)PathBuf$" --category Rust +# Path +type synthetic add -l lldb_lookup.synthetic_lookup -x "^&(mut )?(std::([a-z_]+::)+)Path$" --category Rust type summary add -F lldb_lookup.summary_lookup -e -x -h "^&(mut )?(std::([a-z_]+::)+)Path$" --category Rust -type category enable Rust +# Enum +## MSVC +type synthetic add -l lldb_lookup.MSVCEnumSyntheticProvider -x "^enum2\$<.+>$" --category Rust +type summary add -F lldb_lookup.MSVCEnumSummaryProvider -e -x -h "^enum2\$<.+>$" --category Rust +## MSVC Variants +type synthetic add -l lldb_lookup.synthetic_lookup -x "^enum2\$<.+>::.*$" --category Rust +type summary add -F lldb_lookup.summary_lookup -e -x -h "^enum2\$<.+>::.*$" --category Rust +# Tuple +type synthetic add -l lldb_lookup.synthetic_lookup -x "^\(.*\)$" --category Rust +## MSVC +type synthetic add -l lldb_lookup.MSVCTupleSyntheticProvider -x "^tuple\$<.+>$" --category Rust +type summary add -F lldb_lookup.TupleSummaryProvider -e -x -h "^tuple\$<.+>$" --category Rust + +type category enable Rust \ No newline at end of file diff --git a/src/etc/lldb_providers.py b/src/etc/lldb_providers.py index 2f32ed833af1e..fe670f547d018 100644 --- a/src/etc/lldb_providers.py +++ b/src/etc/lldb_providers.py @@ -3,6 +3,7 @@ from lldb import ( SBData, SBError, + SBType, SBValue, eBasicTypeLong, eBasicTypeUnsignedLong, @@ -838,3 +839,159 @@ def StdNonZeroNumberSummaryProvider(valobj: SBValue, _dict: LLDBOpaque) -> str: return str(inner_inner.GetValueAsSigned()) else: return inner_inner.GetValue() + + +class NestedRefSyntheticProvider: + def __init__(self, valobj: SBValue, _dict: LLDBOpaque): + self.valobj = valobj + + def num_children(self) -> int: + return 0 + + def get_child_index(self, name: str) -> int: + return -1 + + def get_child_at_index(self, index: int) -> SBValue: + return None + + def update(self): + pass + + def has_children(self) -> bool: + return False + + def get_type_name(self) -> str: + name: str = self.valobj.GetTypeName() + + # on MSVC + if name.endswith(" >"): + name = name[:-2] + elif name.endswith(">"): + name = name[:-1] + + if name.startswith("ref$<"): + ref_type = "&" + elif name.startswith("ref_mut$<"): + ref_type = "&mut " + + ptee: SBValue = ( + self.valobj.GetNonSyntheticValue() + .GetChildMemberWithName("ptr") + .Dereference() + ) + + return ref_type + ptee.GetDisplayTypeName() + + +def NestedRefSummaryProvider(valobj: SBValue, _dict: LLDBOpaque) -> str: + inner_val: SBValue = valobj + inner_type: SBType = valobj.GetType() + inner_type_name: str = inner_type.GetName() + while inner_type_name.startswith("ref$<") or inner_type_name.startswith( + "ref_mut$<" + ): + inner_val = ( + inner_val.GetNonSyntheticValue().GetChildMemberWithName("ptr").Dereference() + ) + + inner_type = inner_val.GetType() + inner_type_name = inner_type.GetName() + + summary = inner_val.summary + if summary is None: + summary = inner_val.value + if summary is None: + summary = "{...}" + return summary + + +class PtrSyntheticProvider: + def __init__(self, valobj: SBValue, _dict: LLDBOpaque): + self.valobj = valobj + + def num_children(self) -> int: + return 0 + + def get_child_index(self, name: str) -> int: + return -1 + + def get_child_at_index(self, index: int) -> SBValue: + return None + + def update(self): + pass + + def has_children(self) -> bool: + return False + + def get_type_name(self) -> str: + type: SBType = self.valobj.GetType() + name_parts: list[str] = [] + + ptr_type: SBType = type + ptee_type: SBType = type.GetPointeeType() + ptee_val: SBValue = self.valobj + + # if ptee_name.endswith() + while ptr_type.is_pointer or ptr_type.is_reference: + ptee_val: SBValue = ptee_val.Dereference() + # remove the `const` modifier as it indicates the const-ness of any pointer/ref pointing + # *to* it not its own constness + # For example: + # const u8 *const * -> *const *const u8 + # u8 *const * -> *const *mut u8 + # const u8 ** -> *mut *const u8 + # u8 ** -> *mut *mut u8 + ptr_name: str = ptr_type.GetName() + if ptr_name.endswith("const"): + ptr_name = ptr_name[:-5] + ptee_name: str = ptee_type.GetName() + + is_ref: bool = ptr_name[-1] == "&" + + if ptee_type.is_pointer or ptee_type.is_reference: + if ptee_name.endswith("const"): + if is_ref: + name_parts.append("&") + else: + name_parts.append("*const ") + else: + if is_ref: + name_parts.append("&mut ") + else: + name_parts.append("*mut ") + + else: + if ptee_name.startswith("const "): + if is_ref: + name_parts.append("&") + else: + name_parts.append("*const ") + else: + if is_ref: + name_parts.append("&mut ") + else: + name_parts.append("*mut ") + + ptr_type = ptee_type + ptee_type = ptee_type.GetPointeeType() + + inner_name = ptee_val.GetDisplayTypeName() + if inner_name.startswith("const "): + inner_name = inner_name[6:] + name_parts.append(inner_name) + return "".join(name_parts) + + +def PtrSummaryProvider(valobj: SBValue, dict) -> str: + t: SBType = valobj.GetType() + while t.is_pointer or t.is_reference: + valobj = valobj.Dereference() + t = valobj.GetType() + + summary = valobj.summary + if summary is None: + summary = valobj.value + if summary is None: + summary = "{...}" + return summary diff --git a/src/etc/natvis/intrinsic.natvis b/src/etc/natvis/intrinsic.natvis index 49e0ce319efac..120b5841700ae 100644 --- a/src/etc/natvis/intrinsic.natvis +++ b/src/etc/natvis/intrinsic.natvis @@ -33,6 +33,10 @@ + + + {*ptr} + @@ -231,6 +235,91 @@ + {variant0.NAME,en} ({variant0.value.__0}, {variant0.value.__1}, {variant0.value.__2}, {variant0.value.__3}, ...) + {variant1.NAME,en} ({variant1.value.__0}, {variant1.value.__1}, {variant1.value.__2}, {variant1.value.__3}, ...) + {variant2.NAME,en} ({variant2.value.__0}, {variant2.value.__1}, {variant2.value.__2}, {variant2.value.__3}, ...) + {variant3.NAME,en} ({variant3.value.__0}, {variant3.value.__1}, {variant3.value.__2}, {variant3.value.__3}, ...) + {variant4.NAME,en} ({variant4.value.__0}, {variant4.value.__1}, {variant4.value.__2}, {variant4.value.__3}, ...) + {variant5.NAME,en} ({variant5.value.__0}, {variant5.value.__1}, {variant5.value.__2}, {variant5.value.__3}, ...) + {variant6.NAME,en} ({variant6.value.__0}, {variant6.value.__1}, {variant6.value.__2}, {variant6.value.__3}, ...) + {variant7.NAME,en} ({variant7.value.__0}, {variant7.value.__1}, {variant7.value.__2}, {variant7.value.__3}, ...) + {variant8.NAME,en} ({variant8.value.__0}, {variant8.value.__1}, {variant8.value.__2}, {variant8.value.__3}, ...) + {variant9.NAME,en} ({variant9.value.__0}, {variant9.value.__1}, {variant9.value.__2}, {variant9.value.__3}, ...) + {variant10.NAME,en} ({variant10.value.__0}, {variant10.value.__1}, {variant10.value.__2}, {variant10.value.__3}, ...) + {variant11.NAME,en} ({variant11.value.__0}, {variant11.value.__1}, {variant11.value.__2}, {variant11.value.__3}, ...) + {variant12.NAME,en} ({variant12.value.__0}, {variant12.value.__1}, {variant12.value.__2}, {variant12.value.__3}, ...) + {variant13.NAME,en} ({variant13.value.__0}, {variant13.value.__1}, {variant13.value.__2}, {variant13.value.__3}, ...) + {variant14.NAME,en} ({variant14.value.__0}, {variant14.value.__1}, {variant14.value.__2}, {variant14.value.__3}, ...) + {variant15.NAME,en} ({variant15.value.__0}, {variant15.value.__1}, {variant15.value.__2}, {variant15.value.__3}, ...) + + {variant0.NAME,en} ({variant0.value.__0}, {variant0.value.__1}, {variant0.value.__2}) + {variant1.NAME,en} ({variant1.value.__0}, {variant1.value.__1}, {variant1.value.__2}) + {variant2.NAME,en} ({variant2.value.__0}, {variant2.value.__1}, {variant2.value.__2}) + {variant3.NAME,en} ({variant3.value.__0}, {variant3.value.__1}, {variant3.value.__2}) + {variant4.NAME,en} ({variant4.value.__0}, {variant4.value.__1}, {variant4.value.__2}) + {variant5.NAME,en} ({variant5.value.__0}, {variant5.value.__1}, {variant5.value.__2}) + {variant6.NAME,en} ({variant6.value.__0}, {variant6.value.__1}, {variant6.value.__2}) + {variant7.NAME,en} ({variant7.value.__0}, {variant7.value.__1}, {variant7.value.__2}) + {variant8.NAME,en} ({variant8.value.__0}, {variant8.value.__1}, {variant8.value.__2}) + {variant9.NAME,en} ({variant9.value.__0}, {variant9.value.__1}, {variant9.value.__2}) + {variant10.NAME,en} ({variant10.value.__0}, {variant10.value.__1}, {variant10.value.__2}) + {variant11.NAME,en} ({variant11.value.__0}, {variant11.value.__1}, {variant11.value.__2}) + {variant12.NAME,en} ({variant12.value.__0}, {variant12.value.__1}, {variant12.value.__2}) + {variant13.NAME,en} ({variant13.value.__0}, {variant13.value.__1}, {variant13.value.__2}) + {variant14.NAME,en} ({variant14.value.__0}, {variant14.value.__1}, {variant14.value.__2}) + {variant15.NAME,en} ({variant15.value.__0}, {variant15.value.__1}, {variant15.value.__2}) + + {variant0.NAME,en} ({variant0.value.__0}, {variant0.value.__1}) + {variant1.NAME,en} ({variant1.value.__0}, {variant1.value.__1}) + {variant2.NAME,en} ({variant2.value.__0}, {variant2.value.__1}) + {variant3.NAME,en} ({variant3.value.__0}, {variant3.value.__1}) + {variant4.NAME,en} ({variant4.value.__0}, {variant4.value.__1}) + {variant5.NAME,en} ({variant5.value.__0}, {variant5.value.__1}) + {variant6.NAME,en} ({variant6.value.__0}, {variant6.value.__1}) + {variant7.NAME,en} ({variant7.value.__0}, {variant7.value.__1}) + {variant8.NAME,en} ({variant8.value.__0}, {variant8.value.__1}) + {variant9.NAME,en} ({variant9.value.__0}, {variant9.value.__1}) + {variant10.NAME,en} ({variant10.value.__0}, {variant10.value.__1}) + {variant11.NAME,en} ({variant11.value.__0}, {variant11.value.__1}) + {variant12.NAME,en} ({variant12.value.__0}, {variant12.value.__1}) + {variant13.NAME,en} ({variant13.value.__0}, {variant13.value.__1}) + {variant14.NAME,en} ({variant14.value.__0}, {variant14.value.__1}) + {variant15.NAME,en} ({variant15.value.__0}, {variant15.value.__1}) + + {variant0.NAME,en} ({variant0.value.__0}) + {variant1.NAME,en} ({variant1.value.__0}) + {variant2.NAME,en} ({variant2.value.__0}) + {variant3.NAME,en} ({variant3.value.__0}) + {variant4.NAME,en} ({variant4.value.__0}) + {variant5.NAME,en} ({variant5.value.__0}) + {variant6.NAME,en} ({variant6.value.__0}) + {variant7.NAME,en} ({variant7.value.__0}) + {variant8.NAME,en} ({variant8.value.__0}) + {variant9.NAME,en} ({variant9.value.__0}) + {variant10.NAME,en} ({variant10.value.__0}) + {variant11.NAME,en} ({variant11.value.__0}) + {variant12.NAME,en} ({variant12.value.__0}) + {variant13.NAME,en} ({variant13.value.__0}) + {variant14.NAME,en} ({variant14.value.__0}) + {variant15.NAME,en} ({variant15.value.__0}) + + {variant0.NAME,en} {variant0.value} + {variant1.NAME,en} {variant1.value} + {variant2.NAME,en} {variant2.value} + {variant3.NAME,en} {variant3.value} + {variant4.NAME,en} {variant4.value} + {variant5.NAME,en} {variant5.value} + {variant6.NAME,en} {variant6.value} + {variant7.NAME,en} {variant7.value} + {variant8.NAME,en} {variant8.value} + {variant9.NAME,en} {variant9.value} + {variant10.NAME,en} {variant10.value} + {variant11.NAME,en} {variant11.value} + {variant12.NAME,en} {variant12.value} + {variant13.NAME,en} {variant13.value} + {variant14.NAME,en} {variant14.value} + {variant15.NAME,en} {variant15.value} + {variant0.NAME,en} {variant1.NAME,en} {variant2.NAME,en} @@ -248,6 +337,91 @@ {variant14.NAME,en} {variant15.NAME,en} + {variant0.NAME,en} ({variant0.value.__0}, {variant0.value.__1}, {variant0.value.__2}, {variant0.value.__3}, ...) + {variant1.NAME,en} ({variant1.value.__0}, {variant1.value.__1}, {variant1.value.__2}, {variant1.value.__3}, ...) + {variant2.NAME,en} ({variant2.value.__0}, {variant2.value.__1}, {variant2.value.__2}, {variant2.value.__3}, ...) + {variant3.NAME,en} ({variant3.value.__0}, {variant3.value.__1}, {variant3.value.__2}, {variant3.value.__3}, ...) + {variant4.NAME,en} ({variant4.value.__0}, {variant4.value.__1}, {variant4.value.__2}, {variant4.value.__3}, ...) + {variant5.NAME,en} ({variant5.value.__0}, {variant5.value.__1}, {variant5.value.__2}, {variant5.value.__3}, ...) + {variant6.NAME,en} ({variant6.value.__0}, {variant6.value.__1}, {variant6.value.__2}, {variant6.value.__3}, ...) + {variant7.NAME,en} ({variant7.value.__0}, {variant7.value.__1}, {variant7.value.__2}, {variant7.value.__3}, ...) + {variant8.NAME,en} ({variant8.value.__0}, {variant8.value.__1}, {variant8.value.__2}, {variant8.value.__3}, ...) + {variant9.NAME,en} ({variant9.value.__0}, {variant9.value.__1}, {variant9.value.__2}, {variant9.value.__3}, ...) + {variant10.NAME,en} ({variant10.value.__0}, {variant10.value.__1}, {variant10.value.__2}, {variant10.value.__3}, ...) + {variant11.NAME,en} ({variant11.value.__0}, {variant11.value.__1}, {variant11.value.__2}, {variant11.value.__3}, ...) + {variant12.NAME,en} ({variant12.value.__0}, {variant12.value.__1}, {variant12.value.__2}, {variant12.value.__3}, ...) + {variant13.NAME,en} ({variant13.value.__0}, {variant13.value.__1}, {variant13.value.__2}, {variant13.value.__3}, ...) + {variant14.NAME,en} ({variant14.value.__0}, {variant14.value.__1}, {variant14.value.__2}, {variant14.value.__3}, ...) + {variant15.NAME,en} ({variant15.value.__0}, {variant15.value.__1}, {variant15.value.__2}, {variant15.value.__3}, ...) + + {variant0.NAME,en} ({variant0.value.__0}, {variant0.value.__1}, {variant0.value.__2}) + {variant1.NAME,en} ({variant1.value.__0}, {variant1.value.__1}, {variant1.value.__2}) + {variant2.NAME,en} ({variant2.value.__0}, {variant2.value.__1}, {variant2.value.__2}) + {variant3.NAME,en} ({variant3.value.__0}, {variant3.value.__1}, {variant3.value.__2}) + {variant4.NAME,en} ({variant4.value.__0}, {variant4.value.__1}, {variant4.value.__2}) + {variant5.NAME,en} ({variant5.value.__0}, {variant5.value.__1}, {variant5.value.__2}) + {variant6.NAME,en} ({variant6.value.__0}, {variant6.value.__1}, {variant6.value.__2}) + {variant7.NAME,en} ({variant7.value.__0}, {variant7.value.__1}, {variant7.value.__2}) + {variant8.NAME,en} ({variant8.value.__0}, {variant8.value.__1}, {variant8.value.__2}) + {variant9.NAME,en} ({variant9.value.__0}, {variant9.value.__1}, {variant9.value.__2}) + {variant10.NAME,en} ({variant10.value.__0}, {variant10.value.__1}, {variant10.value.__2}) + {variant11.NAME,en} ({variant11.value.__0}, {variant11.value.__1}, {variant11.value.__2}) + {variant12.NAME,en} ({variant12.value.__0}, {variant12.value.__1}, {variant12.value.__2}) + {variant13.NAME,en} ({variant13.value.__0}, {variant13.value.__1}, {variant13.value.__2}) + {variant14.NAME,en} ({variant14.value.__0}, {variant14.value.__1}, {variant14.value.__2}) + {variant15.NAME,en} ({variant15.value.__0}, {variant15.value.__1}, {variant15.value.__2}) + + {variant0.NAME,en} ({variant0.value.__0}, {variant0.value.__1}) + {variant1.NAME,en} ({variant1.value.__0}, {variant1.value.__1}) + {variant2.NAME,en} ({variant2.value.__0}, {variant2.value.__1}) + {variant3.NAME,en} ({variant3.value.__0}, {variant3.value.__1}) + {variant4.NAME,en} ({variant4.value.__0}, {variant4.value.__1}) + {variant5.NAME,en} ({variant5.value.__0}, {variant5.value.__1}) + {variant6.NAME,en} ({variant6.value.__0}, {variant6.value.__1}) + {variant7.NAME,en} ({variant7.value.__0}, {variant7.value.__1}) + {variant8.NAME,en} ({variant8.value.__0}, {variant8.value.__1}) + {variant9.NAME,en} ({variant9.value.__0}, {variant9.value.__1}) + {variant10.NAME,en} ({variant10.value.__0}, {variant10.value.__1}) + {variant11.NAME,en} ({variant11.value.__0}, {variant11.value.__1}) + {variant12.NAME,en} ({variant12.value.__0}, {variant12.value.__1}) + {variant13.NAME,en} ({variant13.value.__0}, {variant13.value.__1}) + {variant14.NAME,en} ({variant14.value.__0}, {variant14.value.__1}) + {variant15.NAME,en} ({variant15.value.__0}, {variant15.value.__1}) + + {variant0.NAME,en} ({variant0.value.__0}) + {variant1.NAME,en} ({variant1.value.__0}) + {variant2.NAME,en} ({variant2.value.__0}) + {variant3.NAME,en} ({variant3.value.__0}) + {variant4.NAME,en} ({variant4.value.__0}) + {variant5.NAME,en} ({variant5.value.__0}) + {variant6.NAME,en} ({variant6.value.__0}) + {variant7.NAME,en} ({variant7.value.__0}) + {variant8.NAME,en} ({variant8.value.__0}) + {variant9.NAME,en} ({variant9.value.__0}) + {variant10.NAME,en} ({variant10.value.__0}) + {variant11.NAME,en} ({variant11.value.__0}) + {variant12.NAME,en} ({variant12.value.__0}) + {variant13.NAME,en} ({variant13.value.__0}) + {variant14.NAME,en} ({variant14.value.__0}) + {variant15.NAME,en} ({variant15.value.__0}) + + {variant0.NAME,en} {variant0.value} + {variant1.NAME,en} {variant1.value} + {variant2.NAME,en} {variant2.value} + {variant3.NAME,en} {variant3.value} + {variant4.NAME,en} {variant4.value} + {variant5.NAME,en} {variant5.value} + {variant6.NAME,en} {variant6.value} + {variant7.NAME,en} {variant7.value} + {variant8.NAME,en} {variant8.value} + {variant9.NAME,en} {variant9.value} + {variant10.NAME,en} {variant10.value} + {variant11.NAME,en} {variant11.value} + {variant12.NAME,en} {variant12.value} + {variant13.NAME,en} {variant13.value} + {variant14.NAME,en} {variant14.value} + {variant15.NAME,en} {variant15.value} + {variant0.NAME,en} {variant1.NAME,en} {variant2.NAME,en} @@ -265,6 +439,91 @@ {variant14.NAME,en} {variant15.NAME,en} + {variant0.NAME,en} ({variant0.value.__0}, {variant0.value.__1}, {variant0.value.__2}, {variant0.value.__3}, ...) + {variant1.NAME,en} ({variant1.value.__0}, {variant1.value.__1}, {variant1.value.__2}, {variant1.value.__3}, ...) + {variant2.NAME,en} ({variant2.value.__0}, {variant2.value.__1}, {variant2.value.__2}, {variant2.value.__3}, ...) + {variant3.NAME,en} ({variant3.value.__0}, {variant3.value.__1}, {variant3.value.__2}, {variant3.value.__3}, ...) + {variant4.NAME,en} ({variant4.value.__0}, {variant4.value.__1}, {variant4.value.__2}, {variant4.value.__3}, ...) + {variant5.NAME,en} ({variant5.value.__0}, {variant5.value.__1}, {variant5.value.__2}, {variant5.value.__3}, ...) + {variant6.NAME,en} ({variant6.value.__0}, {variant6.value.__1}, {variant6.value.__2}, {variant6.value.__3}, ...) + {variant7.NAME,en} ({variant7.value.__0}, {variant7.value.__1}, {variant7.value.__2}, {variant7.value.__3}, ...) + {variant8.NAME,en} ({variant8.value.__0}, {variant8.value.__1}, {variant8.value.__2}, {variant8.value.__3}, ...) + {variant9.NAME,en} ({variant9.value.__0}, {variant9.value.__1}, {variant9.value.__2}, {variant9.value.__3}, ...) + {variant10.NAME,en} ({variant10.value.__0}, {variant10.value.__1}, {variant10.value.__2}, {variant10.value.__3}, ...) + {variant11.NAME,en} ({variant11.value.__0}, {variant11.value.__1}, {variant11.value.__2}, {variant11.value.__3}, ...) + {variant12.NAME,en} ({variant12.value.__0}, {variant12.value.__1}, {variant12.value.__2}, {variant12.value.__3}, ...) + {variant13.NAME,en} ({variant13.value.__0}, {variant13.value.__1}, {variant13.value.__2}, {variant13.value.__3}, ...) + {variant14.NAME,en} ({variant14.value.__0}, {variant14.value.__1}, {variant14.value.__2}, {variant14.value.__3}, ...) + {variant15.NAME,en} ({variant15.value.__0}, {variant15.value.__1}, {variant15.value.__2}, {variant15.value.__3}, ...) + + {variant0.NAME,en} ({variant0.value.__0}, {variant0.value.__1}, {variant0.value.__2}) + {variant1.NAME,en} ({variant1.value.__0}, {variant1.value.__1}, {variant1.value.__2}) + {variant2.NAME,en} ({variant2.value.__0}, {variant2.value.__1}, {variant2.value.__2}) + {variant3.NAME,en} ({variant3.value.__0}, {variant3.value.__1}, {variant3.value.__2}) + {variant4.NAME,en} ({variant4.value.__0}, {variant4.value.__1}, {variant4.value.__2}) + {variant5.NAME,en} ({variant5.value.__0}, {variant5.value.__1}, {variant5.value.__2}) + {variant6.NAME,en} ({variant6.value.__0}, {variant6.value.__1}, {variant6.value.__2}) + {variant7.NAME,en} ({variant7.value.__0}, {variant7.value.__1}, {variant7.value.__2}) + {variant8.NAME,en} ({variant8.value.__0}, {variant8.value.__1}, {variant8.value.__2}) + {variant9.NAME,en} ({variant9.value.__0}, {variant9.value.__1}, {variant9.value.__2}) + {variant10.NAME,en} ({variant10.value.__0}, {variant10.value.__1}, {variant10.value.__2}) + {variant11.NAME,en} ({variant11.value.__0}, {variant11.value.__1}, {variant11.value.__2}) + {variant12.NAME,en} ({variant12.value.__0}, {variant12.value.__1}, {variant12.value.__2}) + {variant13.NAME,en} ({variant13.value.__0}, {variant13.value.__1}, {variant13.value.__2}) + {variant14.NAME,en} ({variant14.value.__0}, {variant14.value.__1}, {variant14.value.__2}) + {variant15.NAME,en} ({variant15.value.__0}, {variant15.value.__1}, {variant15.value.__2}) + + {variant0.NAME,en} ({variant0.value.__0}, {variant0.value.__1}) + {variant1.NAME,en} ({variant1.value.__0}, {variant1.value.__1}) + {variant2.NAME,en} ({variant2.value.__0}, {variant2.value.__1}) + {variant3.NAME,en} ({variant3.value.__0}, {variant3.value.__1}) + {variant4.NAME,en} ({variant4.value.__0}, {variant4.value.__1}) + {variant5.NAME,en} ({variant5.value.__0}, {variant5.value.__1}) + {variant6.NAME,en} ({variant6.value.__0}, {variant6.value.__1}) + {variant7.NAME,en} ({variant7.value.__0}, {variant7.value.__1}) + {variant8.NAME,en} ({variant8.value.__0}, {variant8.value.__1}) + {variant9.NAME,en} ({variant9.value.__0}, {variant9.value.__1}) + {variant10.NAME,en} ({variant10.value.__0}, {variant10.value.__1}) + {variant11.NAME,en} ({variant11.value.__0}, {variant11.value.__1}) + {variant12.NAME,en} ({variant12.value.__0}, {variant12.value.__1}) + {variant13.NAME,en} ({variant13.value.__0}, {variant13.value.__1}) + {variant14.NAME,en} ({variant14.value.__0}, {variant14.value.__1}) + {variant15.NAME,en} ({variant15.value.__0}, {variant15.value.__1}) + + {variant0.NAME,en} ({variant0.value.__0}) + {variant1.NAME,en} ({variant1.value.__0}) + {variant2.NAME,en} ({variant2.value.__0}) + {variant3.NAME,en} ({variant3.value.__0}) + {variant4.NAME,en} ({variant4.value.__0}) + {variant5.NAME,en} ({variant5.value.__0}) + {variant6.NAME,en} ({variant6.value.__0}) + {variant7.NAME,en} ({variant7.value.__0}) + {variant8.NAME,en} ({variant8.value.__0}) + {variant9.NAME,en} ({variant9.value.__0}) + {variant10.NAME,en} ({variant10.value.__0}) + {variant11.NAME,en} ({variant11.value.__0}) + {variant12.NAME,en} ({variant12.value.__0}) + {variant13.NAME,en} ({variant13.value.__0}) + {variant14.NAME,en} ({variant14.value.__0}) + {variant15.NAME,en} ({variant15.value.__0}) + + {variant0.NAME,en} {variant0.value} + {variant1.NAME,en} {variant1.value} + {variant2.NAME,en} {variant2.value} + {variant3.NAME,en} {variant3.value} + {variant4.NAME,en} {variant4.value} + {variant5.NAME,en} {variant5.value} + {variant6.NAME,en} {variant6.value} + {variant7.NAME,en} {variant7.value} + {variant8.NAME,en} {variant8.value} + {variant9.NAME,en} {variant9.value} + {variant10.NAME,en} {variant10.value} + {variant11.NAME,en} {variant11.value} + {variant12.NAME,en} {variant12.value} + {variant13.NAME,en} {variant13.value} + {variant14.NAME,en} {variant14.value} + {variant15.NAME,en} {variant15.value} + {variant0.NAME,en} {variant1.NAME,en} {variant2.NAME,en} @@ -282,6 +541,91 @@ {variant14.NAME,en} {variant15.NAME,en} + {variant0.NAME,en} ({variant0.value.__0}, {variant0.value.__1}, {variant0.value.__2}, {variant0.value.__3}, ...) + {variant1.NAME,en} ({variant1.value.__0}, {variant1.value.__1}, {variant1.value.__2}, {variant1.value.__3}, ...) + {variant2.NAME,en} ({variant2.value.__0}, {variant2.value.__1}, {variant2.value.__2}, {variant2.value.__3}, ...) + {variant3.NAME,en} ({variant3.value.__0}, {variant3.value.__1}, {variant3.value.__2}, {variant3.value.__3}, ...) + {variant4.NAME,en} ({variant4.value.__0}, {variant4.value.__1}, {variant4.value.__2}, {variant4.value.__3}, ...) + {variant5.NAME,en} ({variant5.value.__0}, {variant5.value.__1}, {variant5.value.__2}, {variant5.value.__3}, ...) + {variant6.NAME,en} ({variant6.value.__0}, {variant6.value.__1}, {variant6.value.__2}, {variant6.value.__3}, ...) + {variant7.NAME,en} ({variant7.value.__0}, {variant7.value.__1}, {variant7.value.__2}, {variant7.value.__3}, ...) + {variant8.NAME,en} ({variant8.value.__0}, {variant8.value.__1}, {variant8.value.__2}, {variant8.value.__3}, ...) + {variant9.NAME,en} ({variant9.value.__0}, {variant9.value.__1}, {variant9.value.__2}, {variant9.value.__3}, ...) + {variant10.NAME,en} ({variant10.value.__0}, {variant10.value.__1}, {variant10.value.__2}, {variant10.value.__3}, ...) + {variant11.NAME,en} ({variant11.value.__0}, {variant11.value.__1}, {variant11.value.__2}, {variant11.value.__3}, ...) + {variant12.NAME,en} ({variant12.value.__0}, {variant12.value.__1}, {variant12.value.__2}, {variant12.value.__3}, ...) + {variant13.NAME,en} ({variant13.value.__0}, {variant13.value.__1}, {variant13.value.__2}, {variant13.value.__3}, ...) + {variant14.NAME,en} ({variant14.value.__0}, {variant14.value.__1}, {variant14.value.__2}, {variant14.value.__3}, ...) + {variant15.NAME,en} ({variant15.value.__0}, {variant15.value.__1}, {variant15.value.__2}, {variant15.value.__3}, ...) + + {variant0.NAME,en} ({variant0.value.__0}, {variant0.value.__1}, {variant0.value.__2}) + {variant1.NAME,en} ({variant1.value.__0}, {variant1.value.__1}, {variant1.value.__2}) + {variant2.NAME,en} ({variant2.value.__0}, {variant2.value.__1}, {variant2.value.__2}) + {variant3.NAME,en} ({variant3.value.__0}, {variant3.value.__1}, {variant3.value.__2}) + {variant4.NAME,en} ({variant4.value.__0}, {variant4.value.__1}, {variant4.value.__2}) + {variant5.NAME,en} ({variant5.value.__0}, {variant5.value.__1}, {variant5.value.__2}) + {variant6.NAME,en} ({variant6.value.__0}, {variant6.value.__1}, {variant6.value.__2}) + {variant7.NAME,en} ({variant7.value.__0}, {variant7.value.__1}, {variant7.value.__2}) + {variant8.NAME,en} ({variant8.value.__0}, {variant8.value.__1}, {variant8.value.__2}) + {variant9.NAME,en} ({variant9.value.__0}, {variant9.value.__1}, {variant9.value.__2}) + {variant10.NAME,en} ({variant10.value.__0}, {variant10.value.__1}, {variant10.value.__2}) + {variant11.NAME,en} ({variant11.value.__0}, {variant11.value.__1}, {variant11.value.__2}) + {variant12.NAME,en} ({variant12.value.__0}, {variant12.value.__1}, {variant12.value.__2}) + {variant13.NAME,en} ({variant13.value.__0}, {variant13.value.__1}, {variant13.value.__2}) + {variant14.NAME,en} ({variant14.value.__0}, {variant14.value.__1}, {variant14.value.__2}) + {variant15.NAME,en} ({variant15.value.__0}, {variant15.value.__1}, {variant15.value.__2}) + + {variant0.NAME,en} ({variant0.value.__0}, {variant0.value.__1}) + {variant1.NAME,en} ({variant1.value.__0}, {variant1.value.__1}) + {variant2.NAME,en} ({variant2.value.__0}, {variant2.value.__1}) + {variant3.NAME,en} ({variant3.value.__0}, {variant3.value.__1}) + {variant4.NAME,en} ({variant4.value.__0}, {variant4.value.__1}) + {variant5.NAME,en} ({variant5.value.__0}, {variant5.value.__1}) + {variant6.NAME,en} ({variant6.value.__0}, {variant6.value.__1}) + {variant7.NAME,en} ({variant7.value.__0}, {variant7.value.__1}) + {variant8.NAME,en} ({variant8.value.__0}, {variant8.value.__1}) + {variant9.NAME,en} ({variant9.value.__0}, {variant9.value.__1}) + {variant10.NAME,en} ({variant10.value.__0}, {variant10.value.__1}) + {variant11.NAME,en} ({variant11.value.__0}, {variant11.value.__1}) + {variant12.NAME,en} ({variant12.value.__0}, {variant12.value.__1}) + {variant13.NAME,en} ({variant13.value.__0}, {variant13.value.__1}) + {variant14.NAME,en} ({variant14.value.__0}, {variant14.value.__1}) + {variant15.NAME,en} ({variant15.value.__0}, {variant15.value.__1}) + + {variant0.NAME,en} ({variant0.value.__0}) + {variant1.NAME,en} ({variant1.value.__0}) + {variant2.NAME,en} ({variant2.value.__0}) + {variant3.NAME,en} ({variant3.value.__0}) + {variant4.NAME,en} ({variant4.value.__0}) + {variant5.NAME,en} ({variant5.value.__0}) + {variant6.NAME,en} ({variant6.value.__0}) + {variant7.NAME,en} ({variant7.value.__0}) + {variant8.NAME,en} ({variant8.value.__0}) + {variant9.NAME,en} ({variant9.value.__0}) + {variant10.NAME,en} ({variant10.value.__0}) + {variant11.NAME,en} ({variant11.value.__0}) + {variant12.NAME,en} ({variant12.value.__0}) + {variant13.NAME,en} ({variant13.value.__0}) + {variant14.NAME,en} ({variant14.value.__0}) + {variant15.NAME,en} ({variant15.value.__0}) + + {variant0.NAME,en} {variant0.value} + {variant1.NAME,en} {variant1.value} + {variant2.NAME,en} {variant2.value} + {variant3.NAME,en} {variant3.value} + {variant4.NAME,en} {variant4.value} + {variant5.NAME,en} {variant5.value} + {variant6.NAME,en} {variant6.value} + {variant7.NAME,en} {variant7.value} + {variant8.NAME,en} {variant8.value} + {variant9.NAME,en} {variant9.value} + {variant10.NAME,en} {variant10.value} + {variant11.NAME,en} {variant11.value} + {variant12.NAME,en} {variant12.value} + {variant13.NAME,en} {variant13.value} + {variant14.NAME,en} {variant14.value} + {variant15.NAME,en} {variant15.value} + {variant0.NAME,en} {variant1.NAME,en} {variant2.NAME,en} @@ -369,4 +713,4 @@ variant15.value - + \ No newline at end of file