xref: /llvm-project/llvm/lib/DebugInfo/LogicalView/Core/LVLocation.cpp (revision a912c81f651109c677dcfdf2b1173a78e853a19d)
13c397c90SCarlos Alberto Enciso //===-- LVLocation.cpp ----------------------------------------------------===//
23c397c90SCarlos Alberto Enciso //
33c397c90SCarlos Alberto Enciso // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
43c397c90SCarlos Alberto Enciso // See https://llvm.org/LICENSE.txt for license information.
53c397c90SCarlos Alberto Enciso // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
63c397c90SCarlos Alberto Enciso //
73c397c90SCarlos Alberto Enciso //===----------------------------------------------------------------------===//
83c397c90SCarlos Alberto Enciso //
93c397c90SCarlos Alberto Enciso // This implements the LVOperation and LVLocation classes.
103c397c90SCarlos Alberto Enciso //
113c397c90SCarlos Alberto Enciso //===----------------------------------------------------------------------===//
123c397c90SCarlos Alberto Enciso 
133c397c90SCarlos Alberto Enciso #include "llvm/DebugInfo/LogicalView/Core/LVLocation.h"
143c397c90SCarlos Alberto Enciso #include "llvm/DebugInfo/LogicalView/Core/LVReader.h"
153c397c90SCarlos Alberto Enciso #include "llvm/DebugInfo/LogicalView/Core/LVScope.h"
163c397c90SCarlos Alberto Enciso #include "llvm/DebugInfo/LogicalView/Core/LVSymbol.h"
173c397c90SCarlos Alberto Enciso 
183c397c90SCarlos Alberto Enciso using namespace llvm;
193c397c90SCarlos Alberto Enciso using namespace llvm::logicalview;
203c397c90SCarlos Alberto Enciso 
213c397c90SCarlos Alberto Enciso #define DEBUG_TYPE "Location"
223c397c90SCarlos Alberto Enciso 
233c397c90SCarlos Alberto Enciso void LVOperation::print(raw_ostream &OS, bool Full) const {}
243c397c90SCarlos Alberto Enciso 
253c397c90SCarlos Alberto Enciso // Identify the most common type of operations and print them using a high
263c397c90SCarlos Alberto Enciso // level format, trying to isolate the DWARF complexity.
273c397c90SCarlos Alberto Enciso std::string LVOperation::getOperandsDWARFInfo() {
283c397c90SCarlos Alberto Enciso   std::string String;
293c397c90SCarlos Alberto Enciso   raw_string_ostream Stream(String);
303c397c90SCarlos Alberto Enciso 
313c397c90SCarlos Alberto Enciso   auto PrintRegisterInfo = [&](LVSmall Code) {
323c397c90SCarlos Alberto Enciso     //-----------------------------------------------------------------------
333c397c90SCarlos Alberto Enciso     // 2.5.1.1 Literal encodings.
343c397c90SCarlos Alberto Enciso     //-----------------------------------------------------------------------
353c397c90SCarlos Alberto Enciso     if (dwarf::DW_OP_lit0 <= Code && Code <= dwarf::DW_OP_lit31) {
363c397c90SCarlos Alberto Enciso       Stream << format("lit%d", Code - dwarf::DW_OP_lit0);
373c397c90SCarlos Alberto Enciso       return;
383c397c90SCarlos Alberto Enciso     }
393c397c90SCarlos Alberto Enciso 
403c397c90SCarlos Alberto Enciso     //-----------------------------------------------------------------------
413c397c90SCarlos Alberto Enciso     // 2.5.1.2 Register values.
423c397c90SCarlos Alberto Enciso     //-----------------------------------------------------------------------
433c397c90SCarlos Alberto Enciso     if (dwarf::DW_OP_breg0 <= Code && Code <= dwarf::DW_OP_breg31) {
443c397c90SCarlos Alberto Enciso       std::string RegisterName(getReader().getRegisterName(Code, Operands));
453c397c90SCarlos Alberto Enciso       Stream << format("breg%d+%d%s", Code - dwarf::DW_OP_breg0, Operands[0],
463c397c90SCarlos Alberto Enciso                        RegisterName.c_str());
473c397c90SCarlos Alberto Enciso       return;
483c397c90SCarlos Alberto Enciso     }
493c397c90SCarlos Alberto Enciso 
503c397c90SCarlos Alberto Enciso     //-----------------------------------------------------------------------
513c397c90SCarlos Alberto Enciso     // 2.6.1.1.3 Register location descriptions.
523c397c90SCarlos Alberto Enciso     //-----------------------------------------------------------------------
533c397c90SCarlos Alberto Enciso     if (dwarf::DW_OP_reg0 <= Code && Code <= dwarf::DW_OP_reg31) {
543c397c90SCarlos Alberto Enciso       std::string RegisterName(getReader().getRegisterName(Code, Operands));
553c397c90SCarlos Alberto Enciso       Stream << format("reg%d%s", Code - dwarf::DW_OP_reg0,
563c397c90SCarlos Alberto Enciso                        RegisterName.c_str());
573c397c90SCarlos Alberto Enciso       return;
583c397c90SCarlos Alberto Enciso     }
593c397c90SCarlos Alberto Enciso 
603c397c90SCarlos Alberto Enciso     Stream << format("#0x%02x ", Code) << hexString(Operands[0]) << " "
613c397c90SCarlos Alberto Enciso            << hexString(Operands[1]) << "#";
623c397c90SCarlos Alberto Enciso   };
633c397c90SCarlos Alberto Enciso 
643c397c90SCarlos Alberto Enciso   switch (Opcode) {
653c397c90SCarlos Alberto Enciso   //-------------------------------------------------------------------------
663c397c90SCarlos Alberto Enciso   // 2.5.1.1 Literal encodings.
673c397c90SCarlos Alberto Enciso   //-------------------------------------------------------------------------
683c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_addr:
693c397c90SCarlos Alberto Enciso     Stream << "addr " << hexString(Operands[0]);
703c397c90SCarlos Alberto Enciso     break;
713c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_constu:
723c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_const1u:
733c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_const2u:
743c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_const4u:
753c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_const8u:
763c397c90SCarlos Alberto Enciso     Stream << "const_u " << unsigned(Operands[0]);
773c397c90SCarlos Alberto Enciso     break;
783c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_consts:
793c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_const1s:
803c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_const2s:
813c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_const4s:
823c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_const8s:
833c397c90SCarlos Alberto Enciso     Stream << "const_s " << int(Operands[0]);
843c397c90SCarlos Alberto Enciso     break;
853c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_addrx:
863c397c90SCarlos Alberto Enciso     Stream << "addrx " << unsigned(Operands[0]);
873c397c90SCarlos Alberto Enciso     break;
883c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_constx:
893c397c90SCarlos Alberto Enciso     Stream << "constx " << unsigned(Operands[0]);
903c397c90SCarlos Alberto Enciso     break;
913c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_const_type:
923c397c90SCarlos Alberto Enciso     Stream << "TODO: DW_OP_const_type";
933c397c90SCarlos Alberto Enciso     break;
943c397c90SCarlos Alberto Enciso 
953c397c90SCarlos Alberto Enciso   //-------------------------------------------------------------------------
963c397c90SCarlos Alberto Enciso   // 2.5.1.2 Register values.
973c397c90SCarlos Alberto Enciso   //-------------------------------------------------------------------------
983c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_fbreg:
993c397c90SCarlos Alberto Enciso     Stream << "fbreg " << int(Operands[0]);
1003c397c90SCarlos Alberto Enciso     break;
1013c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_bregx: {
1023c397c90SCarlos Alberto Enciso     std::string RegisterName(getReader().getRegisterName(Opcode, Operands));
1033c397c90SCarlos Alberto Enciso     Stream << format("bregx %d%s+%d", Operands[0], RegisterName.c_str(),
1043c397c90SCarlos Alberto Enciso                      unsigned(Operands[1]));
1053c397c90SCarlos Alberto Enciso     break;
1063c397c90SCarlos Alberto Enciso   }
1073c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_regval_type: {
1083c397c90SCarlos Alberto Enciso     std::string RegisterName(getReader().getRegisterName(Opcode, Operands));
1093c397c90SCarlos Alberto Enciso     Stream << format("regval_type %d%s+%d", Operands[0], RegisterName.c_str(),
1103c397c90SCarlos Alberto Enciso                      unsigned(Operands[1]));
1113c397c90SCarlos Alberto Enciso     break;
1123c397c90SCarlos Alberto Enciso   }
1133c397c90SCarlos Alberto Enciso 
1143c397c90SCarlos Alberto Enciso   //-------------------------------------------------------------------------
1153c397c90SCarlos Alberto Enciso   // 2.5.1.3 Stack operations.
1163c397c90SCarlos Alberto Enciso   //-------------------------------------------------------------------------
1173c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_dup:
1183c397c90SCarlos Alberto Enciso     Stream << "dup";
1193c397c90SCarlos Alberto Enciso     break;
1203c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_drop:
1213c397c90SCarlos Alberto Enciso     Stream << "drop";
1223c397c90SCarlos Alberto Enciso     break;
1233c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_pick:
1243c397c90SCarlos Alberto Enciso     Stream << "pick " << unsigned(Operands[0]);
1253c397c90SCarlos Alberto Enciso     break;
1263c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_over:
1273c397c90SCarlos Alberto Enciso     Stream << "over";
1283c397c90SCarlos Alberto Enciso     break;
1293c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_swap:
1303c397c90SCarlos Alberto Enciso     Stream << "swap";
1313c397c90SCarlos Alberto Enciso     break;
1323c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_rot:
1333c397c90SCarlos Alberto Enciso     Stream << "rot";
1343c397c90SCarlos Alberto Enciso     break;
1353c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_deref:
1363c397c90SCarlos Alberto Enciso     Stream << "deref";
1373c397c90SCarlos Alberto Enciso     break;
1383c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_deref_size:
1393c397c90SCarlos Alberto Enciso     Stream << "deref_size " << unsigned(Operands[0]);
1403c397c90SCarlos Alberto Enciso     break;
1413c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_deref_type:
1423c397c90SCarlos Alberto Enciso     Stream << "deref_type " << unsigned(Operands[0]) << " DIE offset "
1433c397c90SCarlos Alberto Enciso            << hexString(Operands[1]);
1443c397c90SCarlos Alberto Enciso     break;
1453c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_xderef:
1463c397c90SCarlos Alberto Enciso     Stream << "xderef";
1473c397c90SCarlos Alberto Enciso     break;
1483c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_xderef_size:
1493c397c90SCarlos Alberto Enciso     Stream << "xderef_size " << unsigned(Operands[0]);
1503c397c90SCarlos Alberto Enciso     break;
1513c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_xderef_type:
1523c397c90SCarlos Alberto Enciso     Stream << "xderef_type " << unsigned(Operands[0]) << " DIE offset "
1533c397c90SCarlos Alberto Enciso            << hexString(Operands[1]);
1543c397c90SCarlos Alberto Enciso     break;
1553c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_push_object_address:
1563c397c90SCarlos Alberto Enciso     Stream << "push_object_address";
1573c397c90SCarlos Alberto Enciso     break;
1583c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_form_tls_address:
159*a912c81fSCarlos Alberto Enciso     Stream << "form_tls_address";
1603c397c90SCarlos Alberto Enciso     break;
1613c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_call_frame_cfa:
1623c397c90SCarlos Alberto Enciso     Stream << "call_frame_cfa";
1633c397c90SCarlos Alberto Enciso     break;
1643c397c90SCarlos Alberto Enciso 
1653c397c90SCarlos Alberto Enciso   //-------------------------------------------------------------------------
1663c397c90SCarlos Alberto Enciso   // 2.5.1.4 Arithmetic and Logical Operations.
1673c397c90SCarlos Alberto Enciso   //-------------------------------------------------------------------------
1683c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_abs:
1693c397c90SCarlos Alberto Enciso     Stream << "abs";
1703c397c90SCarlos Alberto Enciso     break;
1713c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_and:
1723c397c90SCarlos Alberto Enciso     Stream << "and";
1733c397c90SCarlos Alberto Enciso     break;
1743c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_div:
1753c397c90SCarlos Alberto Enciso     Stream << "div";
1763c397c90SCarlos Alberto Enciso     break;
1773c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_minus:
1783c397c90SCarlos Alberto Enciso     Stream << "minus";
1793c397c90SCarlos Alberto Enciso     break;
1803c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_mod:
1813c397c90SCarlos Alberto Enciso     Stream << "mod";
1823c397c90SCarlos Alberto Enciso     break;
1833c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_mul:
1843c397c90SCarlos Alberto Enciso     Stream << "mul";
1853c397c90SCarlos Alberto Enciso     break;
1863c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_neg:
1873c397c90SCarlos Alberto Enciso     Stream << "neg";
1883c397c90SCarlos Alberto Enciso     break;
1893c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_not:
1903c397c90SCarlos Alberto Enciso     Stream << "not";
1913c397c90SCarlos Alberto Enciso     break;
1923c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_or:
1933c397c90SCarlos Alberto Enciso     Stream << "or";
1943c397c90SCarlos Alberto Enciso     break;
1953c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_plus:
1963c397c90SCarlos Alberto Enciso     Stream << "plus";
1973c397c90SCarlos Alberto Enciso     break;
1983c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_plus_uconst:
1993c397c90SCarlos Alberto Enciso     Stream << "plus_uconst " << unsigned(Operands[0]);
2003c397c90SCarlos Alberto Enciso     break;
2013c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_shl:
2023c397c90SCarlos Alberto Enciso     Stream << "shl";
2033c397c90SCarlos Alberto Enciso     break;
2043c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_shr:
2053c397c90SCarlos Alberto Enciso     Stream << "shr";
2063c397c90SCarlos Alberto Enciso     break;
2073c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_shra:
2083c397c90SCarlos Alberto Enciso     Stream << "shra";
2093c397c90SCarlos Alberto Enciso     break;
2103c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_xor:
2113c397c90SCarlos Alberto Enciso     Stream << "xor";
2123c397c90SCarlos Alberto Enciso     break;
2133c397c90SCarlos Alberto Enciso 
2143c397c90SCarlos Alberto Enciso   //-------------------------------------------------------------------------
2153c397c90SCarlos Alberto Enciso   // 2.5.1.5 Control Flow Operations.
2163c397c90SCarlos Alberto Enciso   //-------------------------------------------------------------------------
2173c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_le:
2183c397c90SCarlos Alberto Enciso     Stream << "le";
2193c397c90SCarlos Alberto Enciso     break;
2203c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_ge:
2213c397c90SCarlos Alberto Enciso     Stream << "ge";
2223c397c90SCarlos Alberto Enciso     break;
2233c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_eq:
2243c397c90SCarlos Alberto Enciso     Stream << "eq";
2253c397c90SCarlos Alberto Enciso     break;
2263c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_lt:
2273c397c90SCarlos Alberto Enciso     Stream << "lt";
2283c397c90SCarlos Alberto Enciso     break;
2293c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_gt:
2303c397c90SCarlos Alberto Enciso     Stream << "gt";
2313c397c90SCarlos Alberto Enciso     break;
2323c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_ne:
2333c397c90SCarlos Alberto Enciso     Stream << "ne";
2343c397c90SCarlos Alberto Enciso     break;
2353c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_skip:
2363c397c90SCarlos Alberto Enciso     Stream << "skip " << signed(Operands[0]);
2373c397c90SCarlos Alberto Enciso     break;
2383c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_bra:
2393c397c90SCarlos Alberto Enciso     Stream << "bra " << signed(Operands[0]);
2403c397c90SCarlos Alberto Enciso     break;
2413c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_call2:
2423c397c90SCarlos Alberto Enciso     Stream << "call2 DIE offset " << hexString(Operands[0]);
2433c397c90SCarlos Alberto Enciso     break;
2443c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_call4:
2453c397c90SCarlos Alberto Enciso     Stream << "call4 DIE offset " << hexString(Operands[0]);
2463c397c90SCarlos Alberto Enciso     break;
2473c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_call_ref:
2483c397c90SCarlos Alberto Enciso     Stream << "call_ref DIE offset " << hexString(Operands[0]);
2493c397c90SCarlos Alberto Enciso     break;
2503c397c90SCarlos Alberto Enciso 
2513c397c90SCarlos Alberto Enciso   //-------------------------------------------------------------------------
2523c397c90SCarlos Alberto Enciso   // 2.5.1.6 Type Conversions.
2533c397c90SCarlos Alberto Enciso   //-------------------------------------------------------------------------
2543c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_convert:
2553c397c90SCarlos Alberto Enciso     Stream << "convert DIE offset " << hexString(Operands[0]);
2563c397c90SCarlos Alberto Enciso     break;
2573c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_reinterpret:
2583c397c90SCarlos Alberto Enciso     Stream << "reinterpret DIE offset " << hexString(Operands[0]);
2593c397c90SCarlos Alberto Enciso     break;
2603c397c90SCarlos Alberto Enciso 
2613c397c90SCarlos Alberto Enciso   //-------------------------------------------------------------------------
2623c397c90SCarlos Alberto Enciso   // 2.5.1.7 Special Operations.
2633c397c90SCarlos Alberto Enciso   //-------------------------------------------------------------------------
2643c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_nop:
2653c397c90SCarlos Alberto Enciso     Stream << "nop";
2663c397c90SCarlos Alberto Enciso     break;
2673c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_entry_value:
2683c397c90SCarlos Alberto Enciso     Stream << "TODO: DW_OP_entry_value";
2693c397c90SCarlos Alberto Enciso     break;
2703c397c90SCarlos Alberto Enciso 
2713c397c90SCarlos Alberto Enciso   //-------------------------------------------------------------------------
2723c397c90SCarlos Alberto Enciso   // 2.6.1.1.3 Register location descriptions.
2733c397c90SCarlos Alberto Enciso   //-------------------------------------------------------------------------
2743c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_regx:
2753c397c90SCarlos Alberto Enciso     Stream << "regx" << getReader().getRegisterName(Opcode, Operands);
2763c397c90SCarlos Alberto Enciso     break;
2773c397c90SCarlos Alberto Enciso 
2783c397c90SCarlos Alberto Enciso   //-------------------------------------------------------------------------
2793c397c90SCarlos Alberto Enciso   // 2.6.1.1.4 Implicit location descriptions.
2803c397c90SCarlos Alberto Enciso   //-------------------------------------------------------------------------
2813c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_stack_value:
2823c397c90SCarlos Alberto Enciso     Stream << "stack_value";
2833c397c90SCarlos Alberto Enciso     break;
2843c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_implicit_value:
2853c397c90SCarlos Alberto Enciso     Stream << "TODO: DW_OP_implicit_value";
2863c397c90SCarlos Alberto Enciso     break;
2873c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_implicit_pointer:
2883c397c90SCarlos Alberto Enciso     Stream << "implicit_pointer DIE offset " << hexString(Operands[0]) << " "
2893c397c90SCarlos Alberto Enciso            << int(Operands[1]);
2903c397c90SCarlos Alberto Enciso     break;
2913c397c90SCarlos Alberto Enciso 
2923c397c90SCarlos Alberto Enciso   //-------------------------------------------------------------------------
2933c397c90SCarlos Alberto Enciso   // 2.6.1.2 Composite location descriptions.
2943c397c90SCarlos Alberto Enciso   //-------------------------------------------------------------------------
2953c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_piece:
2963c397c90SCarlos Alberto Enciso     Stream << "piece " << int(Operands[0]);
2973c397c90SCarlos Alberto Enciso     break;
2983c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_bit_piece:
2993c397c90SCarlos Alberto Enciso     Stream << "bit_piece " << int(Operands[0]) << " offset "
3003c397c90SCarlos Alberto Enciso            << int(Operands[1]);
3013c397c90SCarlos Alberto Enciso     break;
3023c397c90SCarlos Alberto Enciso 
3033c397c90SCarlos Alberto Enciso   //-------------------------------------------------------------------------
3043c397c90SCarlos Alberto Enciso   // GNU extensions.
3053c397c90SCarlos Alberto Enciso   //-------------------------------------------------------------------------
3063c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_GNU_entry_value:
3073c397c90SCarlos Alberto Enciso     Stream << "gnu_entry_value ";
3083c397c90SCarlos Alberto Enciso     PrintRegisterInfo(dwarf::DW_OP_reg0);
3093c397c90SCarlos Alberto Enciso     break;
3103c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_GNU_push_tls_address:
311*a912c81fSCarlos Alberto Enciso     Stream << "gnu_push_tls_address";
3123c397c90SCarlos Alberto Enciso     break;
3133c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_GNU_addr_index:
3143c397c90SCarlos Alberto Enciso     Stream << "gnu_addr_index " << unsigned(Operands[0]);
3153c397c90SCarlos Alberto Enciso     break;
3163c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_GNU_const_index:
3173c397c90SCarlos Alberto Enciso     Stream << "gnu_const_index " << unsigned(Operands[0]);
3183c397c90SCarlos Alberto Enciso     break;
3193c397c90SCarlos Alberto Enciso 
3203c397c90SCarlos Alberto Enciso   //-------------------------------------------------------------------------
3213c397c90SCarlos Alberto Enciso   // Member location.
3223c397c90SCarlos Alberto Enciso   //-------------------------------------------------------------------------
3233c397c90SCarlos Alberto Enciso   case LVLocationMemberOffset:
3243c397c90SCarlos Alberto Enciso     Stream << "offset " << int(Operands[0]);
3253c397c90SCarlos Alberto Enciso     break;
3263c397c90SCarlos Alberto Enciso 
3273c397c90SCarlos Alberto Enciso   //-------------------------------------------------------------------------
3283c397c90SCarlos Alberto Enciso   // Missing location.
3293c397c90SCarlos Alberto Enciso   //-------------------------------------------------------------------------
3303c397c90SCarlos Alberto Enciso   case dwarf::DW_OP_hi_user:
3313c397c90SCarlos Alberto Enciso     Stream << "missing";
3323c397c90SCarlos Alberto Enciso     break;
3333c397c90SCarlos Alberto Enciso 
3343c397c90SCarlos Alberto Enciso   //-------------------------------------------------------------------------
3353c397c90SCarlos Alberto Enciso   // Register values.
3363c397c90SCarlos Alberto Enciso   //-------------------------------------------------------------------------
3373c397c90SCarlos Alberto Enciso   default:
3383c397c90SCarlos Alberto Enciso     PrintRegisterInfo(Opcode);
3393c397c90SCarlos Alberto Enciso     break;
3403c397c90SCarlos Alberto Enciso   }
3413c397c90SCarlos Alberto Enciso 
3423c397c90SCarlos Alberto Enciso   return String;
3433c397c90SCarlos Alberto Enciso }
3443c397c90SCarlos Alberto Enciso 
3453c397c90SCarlos Alberto Enciso // Identify the most common type of operations and print them using a high
3463c397c90SCarlos Alberto Enciso // level format, trying to isolate the CodeView complexity.
3473c397c90SCarlos Alberto Enciso std::string LVOperation::getOperandsCodeViewInfo() {
3483c397c90SCarlos Alberto Enciso   std::string String;
3493c397c90SCarlos Alberto Enciso   raw_string_ostream Stream(String);
3503c397c90SCarlos Alberto Enciso 
3513c397c90SCarlos Alberto Enciso   // Get original CodeView operation code.
3523c397c90SCarlos Alberto Enciso   uint16_t OperationCode = getCodeViewOperationCode(Opcode);
3533c397c90SCarlos Alberto Enciso 
3543c397c90SCarlos Alberto Enciso   switch (OperationCode) {
3552e6bb8c9SScott Linder   // Operands: [Offset].
3563c397c90SCarlos Alberto Enciso   case codeview::SymbolKind::S_DEFRANGE_FRAMEPOINTER_REL:
3573c397c90SCarlos Alberto Enciso     Stream << "frame_pointer_rel " << int(Operands[0]);
3583c397c90SCarlos Alberto Enciso     break;
3593c397c90SCarlos Alberto Enciso   case codeview::SymbolKind::S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE:
3603c397c90SCarlos Alberto Enciso     Stream << "frame_pointer_rel_full_scope " << int(Operands[0]);
3613c397c90SCarlos Alberto Enciso     break;
3623c397c90SCarlos Alberto Enciso 
3632e6bb8c9SScott Linder   // Operands: [Register].
3643c397c90SCarlos Alberto Enciso   case codeview::SymbolKind::S_DEFRANGE_REGISTER:
3653c397c90SCarlos Alberto Enciso     Stream << "register " << getReader().getRegisterName(Opcode, Operands);
3663c397c90SCarlos Alberto Enciso     break;
3673c397c90SCarlos Alberto Enciso   case codeview::SymbolKind::S_DEFRANGE_SUBFIELD_REGISTER:
3683c397c90SCarlos Alberto Enciso     Stream << "subfield_register "
3693c397c90SCarlos Alberto Enciso            << getReader().getRegisterName(Opcode, Operands);
3703c397c90SCarlos Alberto Enciso     break;
3713c397c90SCarlos Alberto Enciso 
3723c397c90SCarlos Alberto Enciso   // Operands: [Register, Offset].
3733c397c90SCarlos Alberto Enciso   case codeview::SymbolKind::S_DEFRANGE_REGISTER_REL:
3743c397c90SCarlos Alberto Enciso     Stream << "register_rel " << getReader().getRegisterName(Opcode, Operands)
3753c397c90SCarlos Alberto Enciso            << " offset " << int(Operands[1]);
3763c397c90SCarlos Alberto Enciso     break;
3773c397c90SCarlos Alberto Enciso 
3782e6bb8c9SScott Linder   // Operands: [Program].
3793c397c90SCarlos Alberto Enciso   case codeview::SymbolKind::S_DEFRANGE:
3803c397c90SCarlos Alberto Enciso     Stream << "frame " << int(Operands[0]);
3813c397c90SCarlos Alberto Enciso     break;
3823c397c90SCarlos Alberto Enciso   case codeview::SymbolKind::S_DEFRANGE_SUBFIELD:
3833c397c90SCarlos Alberto Enciso     Stream << "subfield " << int(Operands[0]);
3843c397c90SCarlos Alberto Enciso     break;
3853c397c90SCarlos Alberto Enciso 
3863c397c90SCarlos Alberto Enciso   default:
3873c397c90SCarlos Alberto Enciso     Stream << format("#0x%02x: ", Opcode) << hexString(Operands[0]) << " "
3883c397c90SCarlos Alberto Enciso            << hexString(Operands[1]) << "#";
3893c397c90SCarlos Alberto Enciso     break;
3903c397c90SCarlos Alberto Enciso   }
3913c397c90SCarlos Alberto Enciso 
3923c397c90SCarlos Alberto Enciso   return String;
3933c397c90SCarlos Alberto Enciso }
3943c397c90SCarlos Alberto Enciso 
3953c397c90SCarlos Alberto Enciso namespace {
3963c397c90SCarlos Alberto Enciso const char *const KindBaseClassOffset = "BaseClassOffset";
3973c397c90SCarlos Alberto Enciso const char *const KindBaseClassStep = "BaseClassStep";
3983c397c90SCarlos Alberto Enciso const char *const KindClassOffset = "ClassOffset";
3993c397c90SCarlos Alberto Enciso const char *const KindFixedAddress = "FixedAddress";
4003c397c90SCarlos Alberto Enciso const char *const KindMissingInfo = "Missing";
4013c397c90SCarlos Alberto Enciso const char *const KindOperation = "Operation";
4023c397c90SCarlos Alberto Enciso const char *const KindOperationList = "OperationList";
4033c397c90SCarlos Alberto Enciso const char *const KindRegister = "Register";
4043c397c90SCarlos Alberto Enciso const char *const KindUndefined = "Undefined";
4053c397c90SCarlos Alberto Enciso } // end anonymous namespace
4063c397c90SCarlos Alberto Enciso 
4073c397c90SCarlos Alberto Enciso //===----------------------------------------------------------------------===//
4083c397c90SCarlos Alberto Enciso // DWARF location information.
4093c397c90SCarlos Alberto Enciso //===----------------------------------------------------------------------===//
4103c397c90SCarlos Alberto Enciso const char *LVLocation::kind() const {
4113c397c90SCarlos Alberto Enciso   const char *Kind = KindUndefined;
4123c397c90SCarlos Alberto Enciso   if (getIsBaseClassOffset())
4133c397c90SCarlos Alberto Enciso     Kind = KindBaseClassOffset;
4143c397c90SCarlos Alberto Enciso   else if (getIsBaseClassStep())
4153c397c90SCarlos Alberto Enciso     Kind = KindBaseClassStep;
4163c397c90SCarlos Alberto Enciso   else if (getIsClassOffset())
4173c397c90SCarlos Alberto Enciso     Kind = KindClassOffset;
4183c397c90SCarlos Alberto Enciso   else if (getIsFixedAddress())
4193c397c90SCarlos Alberto Enciso     Kind = KindFixedAddress;
4203c397c90SCarlos Alberto Enciso   else if (getIsGapEntry())
4213c397c90SCarlos Alberto Enciso     Kind = KindMissingInfo;
4223c397c90SCarlos Alberto Enciso   else if (getIsOperation())
4233c397c90SCarlos Alberto Enciso     Kind = KindOperation;
4243c397c90SCarlos Alberto Enciso   else if (getIsOperationList())
4253c397c90SCarlos Alberto Enciso     Kind = KindOperationList;
4263c397c90SCarlos Alberto Enciso   else if (getIsRegister())
4273c397c90SCarlos Alberto Enciso     Kind = KindRegister;
4283c397c90SCarlos Alberto Enciso   return Kind;
4293c397c90SCarlos Alberto Enciso }
4303c397c90SCarlos Alberto Enciso 
4313c397c90SCarlos Alberto Enciso std::string LVLocation::getIntervalInfo() const {
4323c397c90SCarlos Alberto Enciso   static const char *const Question = "?";
4333c397c90SCarlos Alberto Enciso   std::string String;
4343c397c90SCarlos Alberto Enciso   raw_string_ostream Stream(String);
4353c397c90SCarlos Alberto Enciso   if (getIsAddressRange())
4363c397c90SCarlos Alberto Enciso     Stream << "{Range}";
4373c397c90SCarlos Alberto Enciso 
4383c397c90SCarlos Alberto Enciso   auto PrintLine = [&](const LVLine *Line) {
4393c397c90SCarlos Alberto Enciso     if (Line) {
4403c397c90SCarlos Alberto Enciso       std::string TheLine;
4413c397c90SCarlos Alberto Enciso       TheLine = Line->lineNumberAsStringStripped();
4423c397c90SCarlos Alberto Enciso       Stream << TheLine.c_str();
4433c397c90SCarlos Alberto Enciso     } else {
4443c397c90SCarlos Alberto Enciso       Stream << Question;
4453c397c90SCarlos Alberto Enciso     }
4463c397c90SCarlos Alberto Enciso   };
4473c397c90SCarlos Alberto Enciso 
4483c397c90SCarlos Alberto Enciso   Stream << " Lines ";
4493c397c90SCarlos Alberto Enciso   PrintLine(getLowerLine());
4503c397c90SCarlos Alberto Enciso   Stream << ":";
4513c397c90SCarlos Alberto Enciso   PrintLine(getUpperLine());
4523c397c90SCarlos Alberto Enciso 
4533c397c90SCarlos Alberto Enciso   if (options().getAttributeOffset())
4543c397c90SCarlos Alberto Enciso     // Print the active range (low pc and high pc).
4553c397c90SCarlos Alberto Enciso     Stream << " [" << hexString(getLowerAddress()) << ":"
4563c397c90SCarlos Alberto Enciso            << hexString(getUpperAddress()) << "]";
4573c397c90SCarlos Alberto Enciso 
4583c397c90SCarlos Alberto Enciso   return String;
4593c397c90SCarlos Alberto Enciso }
4603c397c90SCarlos Alberto Enciso 
4613c397c90SCarlos Alberto Enciso // Validate the ranges associated with the location.
4623c397c90SCarlos Alberto Enciso bool LVLocation::validateRanges() {
4633c397c90SCarlos Alberto Enciso   // Traverse the locations and validate them against the address to line
4643c397c90SCarlos Alberto Enciso   // mapping in the current compile unit. Record those invalid ranges.
4653c397c90SCarlos Alberto Enciso   // A valid range must meet the following conditions:
4663c397c90SCarlos Alberto Enciso   // a) line(lopc) <= line(hipc)
4673c397c90SCarlos Alberto Enciso   // b) line(lopc) and line(hipc) are valid.
4683c397c90SCarlos Alberto Enciso 
4693c397c90SCarlos Alberto Enciso   if (!hasAssociatedRange())
4703c397c90SCarlos Alberto Enciso     return true;
4713c397c90SCarlos Alberto Enciso 
4724f06d46fSCarlos Alberto Enciso   LVLineRange Range = getReaderCompileUnit()->lineRange(this);
4734f06d46fSCarlos Alberto Enciso   LVLine *LowLine = Range.first;
4744f06d46fSCarlos Alberto Enciso   LVLine *HighLine = Range.second;
4753c397c90SCarlos Alberto Enciso   if (LowLine)
4763c397c90SCarlos Alberto Enciso     setLowerLine(LowLine);
4773c397c90SCarlos Alberto Enciso   else {
4783c397c90SCarlos Alberto Enciso     setIsInvalidLower();
4793c397c90SCarlos Alberto Enciso     return false;
4803c397c90SCarlos Alberto Enciso   }
4813c397c90SCarlos Alberto Enciso   if (HighLine)
4823c397c90SCarlos Alberto Enciso     setUpperLine(HighLine);
4833c397c90SCarlos Alberto Enciso   else {
4843c397c90SCarlos Alberto Enciso     setIsInvalidUpper();
4853c397c90SCarlos Alberto Enciso     return false;
4863c397c90SCarlos Alberto Enciso   }
4873c397c90SCarlos Alberto Enciso   // Check for a valid interval.
4883c397c90SCarlos Alberto Enciso   if (LowLine->getLineNumber() > HighLine->getLineNumber()) {
4893c397c90SCarlos Alberto Enciso     setIsInvalidRange();
4903c397c90SCarlos Alberto Enciso     return false;
4913c397c90SCarlos Alberto Enciso   }
4923c397c90SCarlos Alberto Enciso 
4933c397c90SCarlos Alberto Enciso   return true;
4943c397c90SCarlos Alberto Enciso }
4953c397c90SCarlos Alberto Enciso 
4963c397c90SCarlos Alberto Enciso bool LVLocation::calculateCoverage(LVLocations *Locations, unsigned &Factor,
4973c397c90SCarlos Alberto Enciso                                    float &Percentage) {
4983c397c90SCarlos Alberto Enciso   if (!options().getAttributeCoverage() && !Locations)
4993c397c90SCarlos Alberto Enciso     return false;
5003c397c90SCarlos Alberto Enciso 
5013c397c90SCarlos Alberto Enciso   // Calculate the coverage depending on the kind of location. We have
5023c397c90SCarlos Alberto Enciso   // the simple and composed locations.
5033c397c90SCarlos Alberto Enciso   if (Locations->size() == 1) {
5043c397c90SCarlos Alberto Enciso     // Simple: fixed address, class offset, stack offset.
5053c397c90SCarlos Alberto Enciso     LVLocation *Location = Locations->front();
5063c397c90SCarlos Alberto Enciso     // Some types of locations do not have specific kind. Now is the time
5073c397c90SCarlos Alberto Enciso     // to set those types, depending on the operation type.
5083c397c90SCarlos Alberto Enciso     Location->updateKind();
5093c397c90SCarlos Alberto Enciso     if (Location->getIsLocationSimple()) {
5103c397c90SCarlos Alberto Enciso       Factor = 100;
5113c397c90SCarlos Alberto Enciso       Percentage = 100;
5123c397c90SCarlos Alberto Enciso       return true;
5133c397c90SCarlos Alberto Enciso     }
5143c397c90SCarlos Alberto Enciso   }
5153c397c90SCarlos Alberto Enciso 
5163c397c90SCarlos Alberto Enciso   // Composed locations.
5173c397c90SCarlos Alberto Enciso   LVAddress LowerAddress = 0;
5183c397c90SCarlos Alberto Enciso   LVAddress UpperAddress = 0;
5193c397c90SCarlos Alberto Enciso   for (const LVLocation *Location : *Locations)
5203c397c90SCarlos Alberto Enciso     // Do not include locations representing a gap.
5213c397c90SCarlos Alberto Enciso     if (!Location->getIsGapEntry()) {
5223c397c90SCarlos Alberto Enciso       LowerAddress = Location->getLowerAddress();
5233c397c90SCarlos Alberto Enciso       UpperAddress = Location->getUpperAddress();
5243c397c90SCarlos Alberto Enciso       Factor += (UpperAddress > LowerAddress) ? UpperAddress - LowerAddress
5253c397c90SCarlos Alberto Enciso                                               : LowerAddress - UpperAddress;
5263c397c90SCarlos Alberto Enciso     }
5273c397c90SCarlos Alberto Enciso 
5283c397c90SCarlos Alberto Enciso   Percentage = 0;
5293c397c90SCarlos Alberto Enciso   return false;
5303c397c90SCarlos Alberto Enciso }
5313c397c90SCarlos Alberto Enciso 
5323c397c90SCarlos Alberto Enciso void LVLocation::printRaw(raw_ostream &OS, bool Full) const {
5333c397c90SCarlos Alberto Enciso   // Print the active range (low pc and high pc).
5343c397c90SCarlos Alberto Enciso   OS << " [" << hexString(getLowerAddress()) << ":"
5353c397c90SCarlos Alberto Enciso      << hexString(getUpperAddress()) << "]\n";
5363c397c90SCarlos Alberto Enciso   // Print any DWARF operations.
5373c397c90SCarlos Alberto Enciso   printRawExtra(OS, Full);
5383c397c90SCarlos Alberto Enciso }
5393c397c90SCarlos Alberto Enciso 
5403c397c90SCarlos Alberto Enciso void LVLocation::printInterval(raw_ostream &OS, bool Full) const {
5413c397c90SCarlos Alberto Enciso   if (hasAssociatedRange())
5423c397c90SCarlos Alberto Enciso     OS << getIntervalInfo();
5433c397c90SCarlos Alberto Enciso }
5443c397c90SCarlos Alberto Enciso 
5453c397c90SCarlos Alberto Enciso void LVLocation::print(raw_ostream &OS, bool Full) const {
5463c397c90SCarlos Alberto Enciso   if (getReader().doPrintLocation(this)) {
5473c397c90SCarlos Alberto Enciso     LVObject::print(OS, Full);
5483c397c90SCarlos Alberto Enciso     printExtra(OS, Full);
5493c397c90SCarlos Alberto Enciso   }
5503c397c90SCarlos Alberto Enciso }
5513c397c90SCarlos Alberto Enciso 
5523c397c90SCarlos Alberto Enciso void LVLocation::printExtra(raw_ostream &OS, bool Full) const {
5533c397c90SCarlos Alberto Enciso   printInterval(OS, Full);
5543c397c90SCarlos Alberto Enciso   OS << "\n";
5553c397c90SCarlos Alberto Enciso }
5563c397c90SCarlos Alberto Enciso 
5573c397c90SCarlos Alberto Enciso //===----------------------------------------------------------------------===//
5583c397c90SCarlos Alberto Enciso // DWARF location for a symbol.
5593c397c90SCarlos Alberto Enciso //===----------------------------------------------------------------------===//
5603c397c90SCarlos Alberto Enciso // Add a Location Entry.
5613c397c90SCarlos Alberto Enciso void LVLocationSymbol::addObject(LVAddress LowPC, LVAddress HighPC,
5623c397c90SCarlos Alberto Enciso                                  LVUnsigned SectionOffset,
5633c397c90SCarlos Alberto Enciso                                  uint64_t LocDescOffset) {
5643c397c90SCarlos Alberto Enciso   setLowerAddress(LowPC);
5653c397c90SCarlos Alberto Enciso   setUpperAddress(HighPC);
5663c397c90SCarlos Alberto Enciso 
5673c397c90SCarlos Alberto Enciso   // Record the offset where the location information begins.
5683c397c90SCarlos Alberto Enciso   setOffset(LocDescOffset ? LocDescOffset : SectionOffset);
5693c397c90SCarlos Alberto Enciso 
5703c397c90SCarlos Alberto Enciso   // A -1 HighPC value, indicates no range.
5713c397c90SCarlos Alberto Enciso   if (HighPC == LVAddress(UINT64_MAX))
5723c397c90SCarlos Alberto Enciso     setIsDiscardedRange();
5733c397c90SCarlos Alberto Enciso 
5743c397c90SCarlos Alberto Enciso   // Update the location kind, using the DWARF attribute.
5753c397c90SCarlos Alberto Enciso   setKind();
5763c397c90SCarlos Alberto Enciso }
5773c397c90SCarlos Alberto Enciso 
5783c397c90SCarlos Alberto Enciso // Add a Location Record.
5792e6bb8c9SScott Linder void LVLocationSymbol::addObject(LVSmall Opcode,
5802e6bb8c9SScott Linder                                  ArrayRef<LVUnsigned> Operands) {
5813c397c90SCarlos Alberto Enciso   if (!Entries)
5827fbcc244SCarlos Alberto Enciso     Entries = std::make_unique<LVOperations>();
5832e6bb8c9SScott Linder   Entries->push_back(getReader().createOperation(Opcode, Operands));
5843c397c90SCarlos Alberto Enciso }
5853c397c90SCarlos Alberto Enciso 
5863c397c90SCarlos Alberto Enciso // Based on the DWARF attribute, define the location kind.
5873c397c90SCarlos Alberto Enciso void LVLocation::setKind() {
5883c397c90SCarlos Alberto Enciso   switch (getAttr()) {
5893c397c90SCarlos Alberto Enciso   case dwarf::DW_AT_data_member_location:
5903c397c90SCarlos Alberto Enciso     setIsClassOffset();
5913c397c90SCarlos Alberto Enciso     break;
5923c397c90SCarlos Alberto Enciso   case dwarf::DW_AT_location:
5933c397c90SCarlos Alberto Enciso     // Depending on the operand, we have a fixed address.
5943c397c90SCarlos Alberto Enciso     setIsFixedAddress();
5953c397c90SCarlos Alberto Enciso     break;
5963c397c90SCarlos Alberto Enciso   default:
5973c397c90SCarlos Alberto Enciso     break;
5983c397c90SCarlos Alberto Enciso   }
5993c397c90SCarlos Alberto Enciso   // For those symbols with absolute location information, ignore any
6003c397c90SCarlos Alberto Enciso   // gaps in their location description; that is the case with absolute
6013c397c90SCarlos Alberto Enciso   // memory addresses and members located at specific offsets.
6023c397c90SCarlos Alberto Enciso   if (hasAssociatedRange())
6033c397c90SCarlos Alberto Enciso     getParentSymbol()->setFillGaps();
6043c397c90SCarlos Alberto Enciso }
6053c397c90SCarlos Alberto Enciso 
6063c397c90SCarlos Alberto Enciso void LVLocationSymbol::updateKind() {
6073c397c90SCarlos Alberto Enciso   // Update the location type for simple ones.
6083c397c90SCarlos Alberto Enciso   if (Entries && Entries->size() == 1) {
6097fbcc244SCarlos Alberto Enciso     if (dwarf::DW_OP_fbreg == Entries->front()->getOpcode())
6103c397c90SCarlos Alberto Enciso       setIsStackOffset();
6113c397c90SCarlos Alberto Enciso   }
6123c397c90SCarlos Alberto Enciso }
6133c397c90SCarlos Alberto Enciso 
6143c397c90SCarlos Alberto Enciso void LVLocationSymbol::printRawExtra(raw_ostream &OS, bool Full) const {
6153c397c90SCarlos Alberto Enciso   if (Entries)
6163c397c90SCarlos Alberto Enciso     for (const LVOperation *Operation : *Entries)
6173c397c90SCarlos Alberto Enciso       Operation->print(OS, Full);
6183c397c90SCarlos Alberto Enciso }
6193c397c90SCarlos Alberto Enciso 
6203c397c90SCarlos Alberto Enciso // Print location (formatted version).
6213c397c90SCarlos Alberto Enciso void LVLocation::print(LVLocations *Locations, raw_ostream &OS, bool Full) {
6223c397c90SCarlos Alberto Enciso   if (!Locations || Locations->empty())
6233c397c90SCarlos Alberto Enciso     return;
6243c397c90SCarlos Alberto Enciso 
6253c397c90SCarlos Alberto Enciso   // Print the symbol coverage.
6263c397c90SCarlos Alberto Enciso   if (options().getAttributeCoverage()) {
6273c397c90SCarlos Alberto Enciso     // The location entries are contained within a symbol. Get a location,
6283c397c90SCarlos Alberto Enciso     // to access basic information about indentation, parent, etc.
6293c397c90SCarlos Alberto Enciso     LVLocation *Location = Locations->front();
6303c397c90SCarlos Alberto Enciso     LVSymbol *Symbol = Location->getParentSymbol();
6313c397c90SCarlos Alberto Enciso     float Percentage = Symbol->getCoveragePercentage();
6323c397c90SCarlos Alberto Enciso 
6333c397c90SCarlos Alberto Enciso     // The coverage is dependent on the kind of location.
6343c397c90SCarlos Alberto Enciso     std::string String;
6353c397c90SCarlos Alberto Enciso     raw_string_ostream Stream(String);
6363c397c90SCarlos Alberto Enciso     Stream << format("%.2f%%", Percentage);
6373c397c90SCarlos Alberto Enciso     if (!Location->getIsLocationSimple())
6383c397c90SCarlos Alberto Enciso       Stream << format(" (%d/%d)", Symbol->getCoverageFactor(),
6393c397c90SCarlos Alberto Enciso                        Symbol->getParentScope()->getCoverageFactor());
6403c397c90SCarlos Alberto Enciso     Symbol->printAttributes(OS, Full, "{Coverage} ", Symbol, StringRef(String),
6413c397c90SCarlos Alberto Enciso                             /*UseQuotes=*/false,
6423c397c90SCarlos Alberto Enciso                             /*PrintRef=*/false);
6433c397c90SCarlos Alberto Enciso   }
6443c397c90SCarlos Alberto Enciso 
6453c397c90SCarlos Alberto Enciso   // Print the symbol location, including the missing entries.
6463c397c90SCarlos Alberto Enciso   if (getReader().doPrintLocation(/*Location=*/nullptr))
6473c397c90SCarlos Alberto Enciso     for (const LVLocation *Location : *Locations)
6483c397c90SCarlos Alberto Enciso       Location->print(OS, Full);
6493c397c90SCarlos Alberto Enciso }
6503c397c90SCarlos Alberto Enciso 
6513c397c90SCarlos Alberto Enciso void LVLocationSymbol::printExtra(raw_ostream &OS, bool Full) const {
6523c397c90SCarlos Alberto Enciso   OS << "{Location}";
6533c397c90SCarlos Alberto Enciso   if (getIsCallSite())
6543c397c90SCarlos Alberto Enciso     OS << " -> CallSite";
6553c397c90SCarlos Alberto Enciso   printInterval(OS, Full);
6563c397c90SCarlos Alberto Enciso   OS << "\n";
6573c397c90SCarlos Alberto Enciso 
6583c397c90SCarlos Alberto Enciso   // Print location entries.
6593c397c90SCarlos Alberto Enciso   if (Full && Entries) {
6603c397c90SCarlos Alberto Enciso     bool CodeViewLocation = getParentSymbol()->getHasCodeViewLocation();
6613c397c90SCarlos Alberto Enciso     std::stringstream Stream;
662282d114cSKazu Hirata     std::string Leading;
6633c397c90SCarlos Alberto Enciso     for (LVOperation *Operation : *Entries) {
6643c397c90SCarlos Alberto Enciso       Stream << Leading
6653c397c90SCarlos Alberto Enciso              << (CodeViewLocation ? Operation->getOperandsCodeViewInfo()
6663c397c90SCarlos Alberto Enciso                                   : Operation->getOperandsDWARFInfo());
6673c397c90SCarlos Alberto Enciso       Leading = ", ";
6683c397c90SCarlos Alberto Enciso     }
6693c397c90SCarlos Alberto Enciso     printAttributes(OS, Full, "{Entry} ", const_cast<LVLocationSymbol *>(this),
6703c397c90SCarlos Alberto Enciso                     StringRef(Stream.str()),
6713c397c90SCarlos Alberto Enciso                     /*UseQuotes=*/false,
6723c397c90SCarlos Alberto Enciso                     /*PrintRef=*/false);
6733c397c90SCarlos Alberto Enciso   }
6743c397c90SCarlos Alberto Enciso }
675