Provided by: llvm-16_16.0.0-1~exp5ubuntu3_amd64 bug

NAME

       llvm-debuginfo-analyzer - Print a logical representation of low-level debug information.

       • SYNOPSISDESCRIPTIONOPTIONSGENERALATTRIBUTESPRINTOUTPUTREPORTSELECTIONELEMENTSLINESSCOPESSYMBOLSTYPESCOMPAREWARNINGINTERNALEXAMPLESTEST CASE 1 - GENERAL OPTIONSPRINTING MODEBASIC DETAILSSELECT LOGICAL ELEMENTSCOMPARISON MODELOGICAL VIEWLOGICAL ELEMENTSTEST CASE 2 - ASSEMBLER INSTRUCTIONSCodeView - Clang (Windows)CodeView - MSVC (Windows)DWARF - Clang (Linux)DWARF - GCC (Linux)TEST CASE 3 - INCORRECT LEXICAL SCOPE FOR TYPEDEFCodeView - Clang (Windows)CodeView - MSVC (Windows)DWARF - Clang (Linux)DWARF - GCC (Linux)TEST CASE 4 - MISSING NESTED ENUMERATIONSCodeView - Clang (Windows)CodeView - MSVC (Windows)DWARF - Clang (Linux)DWARF - GCC (Linux)TEST CASE 5 - INCORRECT LEXICAL SCOPE FOR VARIABLECODEVIEW - Clang (Windows)CODEVIEW - MSVC (Windows)DWARF - Clang (Linux)DWARF - GCC (Linux)TEST CASE 6 - FULL LOGICAL VIEWEXIT STATUSSEE ALSO

SYNOPSIS

       llvm-debuginfo-analyzer [options] [filename ]

DESCRIPTION

       llvm-debuginfo-analyzer  parses  debug and text sections in binary object files and prints
       their contents in a logical view, which is a human readable  representation  that  closely
       matches  the  structure  of  the  original user source code. Supported object file formats
       include ELF, Mach-O, PDB and COFF.

       The logical  view  abstracts  the  complexity  associated  with  the  different  low-level
       representations  of  the  debugging  information  that  is  embedded  in  the object file.
       llvm-debuginfo-analyzer produces a canonical view of the debug information  regardless  of
       how  it is formatted. The same logical view will be seen regardless of object file format,
       assuming the debug information correctly represents the same original source code.

       The logical view includes the following logical elements: type, scope,  symbol  and  line,
       which are the basic software elements used in the C/C++ programming language. Each logical
       element has a set of attributes, such as types, classes, functions, variables, parameters,
       etc.  The  --attribute  can be used to specify which attributes to include when printing a
       logical element. A logical element may have  a  kind  that  describes  specific  types  of
       elements. For instance, a scope could have a kind value of function, class, namespace.

       llvm-debuginfo-analyzer  defaults  to  print  a pre-defined layout of logical elements and
       attributes. The command line options can be  used  to  control  the  printed  elements  (‐
       --print),  using  a  specific  layout  (--report),  matching  a  given  pattern (--select,
       --select-offsets). Also, the output can be limited to specified logical elements using  (‐
       --select-lines, --select-scopes, --select-symbols, --select-types).

       llvm-debuginfo-analyzer  can  also  compare  a  set  of logical views (--compare), to find
       differences and identify possible debug  information  syntax  issues  (--warning)  in  any
       object file.

OPTIONS

       llvm-debuginfo-analyzer  options are separated into several categories, each tailored to a
       different purpose:

          • GENERAL - Standard LLVM options to display help, version, etc.

          • ATTRIBUTES - Describe how to include different details when printing an element.

          • PRINT - Specify which elements will be included when printing the view.

          • OUTPUT - Describe the supported formats when printing the view.

          • REPORT - Describe the format layouts for view printing.

          • SELECTION - Allows to use specific criteria or conditions to select which elements to
            print.

          • COMPARE - Compare logical views and print missing and/or added elements.

          • WARNING - Print the warnings detected during the creation of the view.

          • INTERNAL - Internal analysis of the logical view.

   GENERAL
       This  section  describes  the  standard  help options, used to display the usage, version,
       response files, etc.

       -h, --help
              Show help and usage for this command. (–help-hidden for more).

       --help-list
              Show help and usage for this command without grouping the options  into  categories
              (–help-list-hidden for more).

       --help-hidden
              Display all available options.

       --print-all-options
              Print all option values after command line parsing.

       --print-options
              Print non-default options after command line parsing

       --version
              Display the version of the tool.

       @<FILE>
              Read command-line options from <FILE>.

       If  no  input file is specified, llvm-debuginfo-analyzer defaults to read a.out and return
       an error when no input file is found.

       If - is used as the input file, llvm-debuginfo-analyzer reads the input from its  standard
       input stream.

   ATTRIBUTES
       The  following  options  enable attributes given for the printed elements.  The attributes
       are divided in categories based on the type of data being added, such as: internal offsets
       in  the  binary  file,  location  descriptors,  register  names,  user  source  filenames,
       additional element transformations, toolchain name, binary file format, etc.

       --attribute=<value[,value,...]>
              With value being one of the options in the following lists.

                 =all: Include all the below attributes.
                 =extended: Add low-level attributes.
                 =standard: Add standard high-level attributes.

              The following attributes  describe  the  most  common  information  for  a  logical
              element.  They  help  to  identify  the lexical scope level; the element visibility
              across modules (global, local); the toolchain name that produced the binary file.

                 =global: Element referenced across Compile Units.
                 =format: Object file format name.
                 =level: Lexical scope level (File=0, Compile Unit=1).
                 =local: Element referenced only in the Compile Unit.
                 =producer: Toolchain identification name.

              The following attributes describe files and directory names from  the  user  source
              code,  where the elements are declared or defined; functions with public visibility
              across modules. These options  allow  to  map  the  elements  to  their  user  code
              location, for cross references purposes.

                 =directories: Directories referenced in the debug information.
                 =filename: Filename where the element is defined.
                 =files: Files referenced in the debug information.
                 =pathname: Pathname where the object is defined.
                 =publics: Function names that are public.

              The    following    attributes   describe   additional   logical   element   source
              transformations, in order to display built-in types (int, bool,  etc.);  parameters
              and  arguments  used  during  template  instantiation; parent name hierarchy; array
              dimensions information;  compiler  generated  elements  and  the  underlying  types
              associated with the types aliases.

                 =argument: Template parameters replaced by its arguments.
                 =base: Base types (int, bool, etc.).
                 =generated: Compiler generated elements.
                 =encoded: Template arguments encoded in the template name.
                 =qualified: The element type include parents in its name.
                 =reference: Element declaration and definition references.
                 =subrange: Subrange encoding information for arrays.
                 =typename: Template parameters.
                 =underlying: Underlying type for type definitions.

              The  following  attributes  describe the debug location information for a symbol or
              scope. It includes the symbol percentage coverage and any gaps within the  location
              layout;  ranges  determining  the  code  sections  attached  to  a  function.  When
              descriptors are used, the target processor registers are displayed.

                 =coverage: Symbol location coverage.
                 =gaps: Missing debug location (gaps).
                 =location: Symbol debug location.
                 =range: Debug location ranges.
                 =register: Processor register names.

              The following attributes are associated with low level details, such as: offsets in
              the binary file; discriminators added to the lines of inlined functions in order to
              distinguish specific instances;  debug  lines  state  machine  registers;  elements
              discarded   by   the   compiler   (inlining)   or   by   the  linker  optimizations
              (dead-stripping); system compile units generated by the MS toolchain in PDBs.

                 =discarded: Discarded elements by the linker.
                 =discriminator: Discriminators for inlined function instances.
                 =inserted: Generated inlined abstract references.
                 =linkage: Object file linkage name.
                 =offset: Debug information offset.
                 =qualifier: Line qualifiers (Newstatement, BasicBlock, etc).
                 =zero: Zero line numbers.

              The following attribute described specific information for the PE/COFF file format.
              It includes MS runtime types.

                 =system: Display PDB's MS system elements.

              The  above attributes are grouped into standard and extended categories that can be
              enabled.

              The standard group, contains those attributes that add  sufficient  information  to
              describe  a  logical element and that can cover the normal situations while dealing
              with debug information.

                 =base
                 =coverage
                 =directories
                 =discriminator
                 =filename
                 =files
                 =format
                 =level
                 =producer
                 =publics
                 =range
                 =reference
                 =zero

              The extended  group,  contains  those  attributes  that  require  a  more  extended
              knowledge  about  debug information. They are intended when a lower level of detail
              is required.

                 =argument
                 =discarded
                 =encoded
                 =gaps
                 =generated
                 =global
                 =inserted
                 =linkage
                 =local
                 =location
                 =offset
                 =operation
                 =pathname
                 =qualified
                 =qualifier
                 =register
                 =subrange
                 =system
                 =typename

   PRINT
       The following options describe the elements to print. The layout used is determined by the
       --report.  In  the  tree  layout,  all  the  elements  have their enclosing lexical scopes
       printed, even when not explicitly specified.

       --print=<value[,value,...]>
              With value being one of the options in the following lists.

                 =all: Include all the below attributes.

              The following options print the requested elements; in the case of any given select
              conditions  (--select),  only  those elements that match them, will be printed. The
              elements value is a convenient way to specify instructions, lines, scopes,  symbols
              and types all at once.

                 =elements: Instructions, lines, scopes, symbols and types.
                 =instructions: Assembler instructions for code sections.
                 =lines: Source lines referenced in the debug information.
                 =scopes: Lexical blocks (function, class, namespace, etc).
                 =symbols: Symbols (variable, member, parameter, etc).
                 =types: Types (pointer, reference, type alias, etc).

              The  following  options  print  information,  collected  during the creation of the
              elements, such as:  scope  contributions  to  the  debug  information;  summary  of
              elements  created, printed or matched (--select); warnings produced during the view
              creation.

                 =sizes: Debug Information scopes contributions.
                 =summary: Summary of elements allocated, selected or printed.
                 =warnings: Warnings detected.

              Note: The –print=sizes option is ELF specific.

   OUTPUT
       The following options describe how to control  the  output  generated  when  printing  the
       logical elements.

       --output-file=<path>
              Redirect  the  output to a file specified by <path>, where - is the standard output
              stream.

       llvm-debuginfo-analyzer has the concept of split view.  When redirecting the output from a
       complex  binary  format,  it  is  divided  into  individual files, each one containing the
       logical view output for a single compilation unit.

       --output-folder=<name>
              The folder to write a file per compilation unit when –output=split is specified.

       --output-level=<level>
              Only print elements up to the given lexical level  value.  The  input  file  is  at
              lexical level zero and a compilation unit is at lexical level one.

       --output=<value[,value,...]>
              With value being one of the options in the following lists.

                 =all: Include all the below outputs.

                 =json: Use JSON as the output format (Not implemented).
                 =split: Split the output by Compile Units.
                 =text: Use a free form text output.

       --output-sort=<key>
              Primary  key  when ordering the elements in the output (default: line).  Sorting by
              logical element kind, requires be  familiarity  with  the  element  kind  selection
              options  (--select-lines,  --select-scopes,  --select-symbols,  --select-types), as
              those options describe the different logical element kinds.

                 =kind: Sort by element kind.
                 =line: Sort by element line number.
                 =name: Sort by element name.
                 =offset: Sort by element offset.

   REPORT
       Depending on the task  being  executed  (print,  compare,  select),  several  layouts  are
       supported  to  display  the  elements in a more suitable way, to make the output easier to
       understand.

       --report=<value[,value,...]>
              With value being one of the options in the following list.

                 =all: Include all the below reports.

                 =children: Elements and children are displayed in a tree format.
                 =list: Elements are displayed in a tabular format.
                 =parents: Elements and parents are displayed in a tree format.
                 =view: Elements, parents and children are displayed in a tree format.

       The list layout presents the logical elements in a tabular form without  any  parent-child
       relationship.  This  may  be  the  preferred  way  to display elements that match specific
       conditions when comparing logical views, making it easier to find differences.

       The children, parents and view layout displays the elements in a  tree  format,  with  the
       scopes  representing  their nodes, and types, symbols, lines and other scopes representing
       the children. The layout shows the lexical scoping relationship between elements, with the
       binary  file  being the tree root (level 0) and each compilation unit being a child (level
       1).

       The children layout includes the elements that match any given criteria (--select)  or  (‐
       --compare) and its children.

       The  parents  layout  includes the elements that match any given criteria (--select) or (‐
       --compare) and its parents.

       The combined view layout includes the elements that match any given criteria (--select) or
       (--compare), its parents and children.

       Notes:

       1. When  a  selection  criteria  (--select)  is  specified with no report option, the list
          layout is selected.

       2. The comparison mode always uses the view layout.

   SELECTION
       When printing an element, different data can be included and it varies (--attribute)  from
       data  directly  associated  with  the  binary  file (offset) to high level details such as
       coverage, lexical scope level, location. As the printed output can  reach  a  considerable
       size, several selection options, enable printing of specific elements.

       The  pattern matching can ignore the case (--select-nocase) and be extended to use regular
       expressions (--select-regex).

   ELEMENTS
       The following options allow printing of elements that match the  given  <pattern>,  offset
       <value> or an element <condition>.

       --select=<pattern>
              Print all elements whose name or line number matches the given <pattern>.

       --select-offsets=<value[,value,...]>
              Print all elements whose offset matches the given values. See --attribute option.

       --select-elements=<condition[,condition,...]>
              Print  all elements that satisfy the given <condition>. With condition being one of
              the options in the following list.

                 =discarded: Discarded elements by the linker.
                 =global: Element referenced across Compile Units.
                 =optimized: Optimized inlined abstract references.

       --select-nocase
              Pattern matching is case-insensitive when using --select.

       --select-regex
              Treat any <pattern> strings as regular expressions  when  selecting  with  --select
              option.   If   --select-nocase   is   specified,  the  regular  expression  becomes
              case-insensitive.

       If the <pattern> criteria is too general, a more selective  option  can  be  specified  to
       target   a   particular   category   of   elements:   lines  (--select-lines),  scopes  (‐
       --select-scopes), symbols (--select-symbols) and types  (--select-types).   These  options
       require  knowledge  of  the debug information format (DWARF, CodeView, COFF), as the given
       kind describes a very specific type of element.

   LINES
       The following options allow printing of lines that match  the  given  <kind>.   The  given
       criteria describes the debug line state machine registers.

       --select-lines=<kind[,kind,...]>
              With kind being one of the options in the following list.

                 =AlwaysStepInto: marks an always step into.
                 =BasicBlock: Marks a new basic block.
                 =Discriminator: Line that has a discriminator.
                 =EndSequence: Marks the end in the sequence of lines.
                 =EpilogueBegin: Marks the start of a function epilogue.
                 =LineDebug: Lines that correspond to debug lines.
                 =LineAssembler: Lines that correspond to disassembly text.
                 =NeverStepInto: marks a never step into.
                 =NewStatement: Marks a new statement.
                 =PrologueEnd: Marks the end of a function prologue.

   SCOPES
       The following options allow printing of scopes that match the given <kind>.

       --select-scopes=<kind[,kind,...]>
              With kind being one of the options in the following list.

                 =Aggregate: A class, structure or union.
                 =Array: An array.
                 =Block: A generic block (lexical block or exception block).
                 =CallSite: A call site.
                 =CatchBlock: An exception block.
                 =Class: A class.
                 =CompileUnit: A compile unit.
                 =EntryPoint: A subroutine entry point.
                 =Enumeration: An enumeration.
                 =Function: A function.
                 =FunctionType: A function pointer.
                 =InlinedFunction: An inlined function.
                 =Label: A label.
                 =LexicalBlock: A lexical block.
                 =Namespace: A namespace.
                 =Root: The element representing the main scope.
                 =Structure: A structure.
                 =Subprogram: A subprogram.
                 =Template: A template definition.
                 =TemplateAlias: A template alias.
                 =TemplatePack: A template pack.
                 =TryBlock: An exception try block.
                 =Union: A union.

   SYMBOLS
       The following options allow printing of symbols that match the given <kind>.

       --select-symbols=<kind[,kind,...]>
              With kind being one of the options in the following list.

                 =CallSiteParameter: A call site parameter.
                 =Constant: A constant symbol.
                 =Inheritance: A base class.
                 =Member: A member class.
                 =Parameter: A parameter to function.
                 =Unspecified: Unspecified parameters to function.
                 =Variable: A variable.

   TYPES
       The following options allow printing of types that match the given <kind>.

       --select-types=<kind[,kind,...]>
              With kind being one of the options in the following list.

                 =Base: Base type (integer, boolean, etc).
                 =Const: Constant specifier.
                 =Enumerator: Enumerator.
                 =Import: Import declaration.
                 =ImportDeclaration: Import declaration.
                 =ImportModule: Import module.
                 =Pointer: Pointer type.
                 =PointerMember: Pointer to member function.
                 =Reference: Reference type.
                 =Restrict: Restrict specifier.
                 =RvalueReference: R-value reference.
                 =Subrange: Array subrange.
                 =TemplateParam: Template parameter.
                 =TemplateTemplateParam: Template template parameter.
                 =TemplateTypeParam: Template type parameter.
                 =TemplateValueParam: Template value parameter.
                 =Typedef: Type definition.
                 =Unspecified: Unspecified type.
                 =Volatile: Volatile specifier.

   COMPARE
       When  dealing  with  debug  information,  there  are  situations  when the printing of the
       elements is not the correct approach. That is the case, when  we  are  interested  in  the
       effects  caused  by  different  versions  of the same toolchain, or the impact of specific
       compiler optimizations.

       For those cases, we are looking to see which elements have been added or removed.  Due  to
       the  complicated debug information format, it is very difficult to use a regular diff tool
       to find those elements; even impossible when dealing with different debug formats.

       llvm-debuginfo-analyzer supports a logical element comparison, allowing to  find  semantic
       differences  between logical views, produced by different toolchain versions or even debug
       information formats.

       When comparing logical views created from different debug formats, its accuracy depends on
       how  close  the  debug  information represents the user code. For instance, a logical view
       created from a binary file with DWARF debug information may  include  more  detailed  data
       than a logical view created from a binary file with CodeView/COFF debug information.

       The following options describe the elements to compare.

       --compare=<value[,value,...]>
              With value being one of the options in the following list.

                 =all: Include all the below elements.

                 =lines: Include lines.
                 =scopes: Include scopes.
                 =symbols: Include symbols.
                 =types: Include types.

       llvm-debuginfo-analyzer  takes  the first binary file on the command line as the reference
       and the second one as the target.  To get a more descriptive  report,  the  comparison  is
       done  twice. The reference and target views are swapped, in order to produce those missing
       elements from the target view and those added elements to the reference view.

       See --report options on how to describe the comparison reports.

   WARNING
       When reading the input object files, llvm-debuginfo-analyzer can detect issues in the  raw
       debug  information. These may not be considered fatal to the purpose of printing a logical
       view but they can give an indication about the quality and potentially expose issues  with
       the generated debug information.

       The following options describe the warnings to be recorded for later printing, if they are
       requested by --print.

       --warning=<value[,value,...]>
              With value being one of the options in the following list.

                 =all: Include all the below warnings.

              The following options collect additional information during  the  creation  of  the
              logical view, to include invalid coverage values and locations for symbols; invalid
              code ranges; lines that are zero.

                 =coverages: Invalid symbol coverages values.
                 =lines: Debug lines that are zero.
                 =locations: Invalid symbol locations.
                 =ranges: Invalid code ranges.

   INTERNAL
          For a better understanding of the  logical  view,  access  to  more  detailed  internal
          information  could  be  needed.  Such  data  would  help  to identify debug information
          processed or incorrect logical element management.  Typically these kind of options are
          available only in debug builds.

          llvm-debuginfo-analyzer  supports  these  advanced  options  in  both release and debug
          builds, with the exception of the unique ID that is generated only in debug builds.

       --internal=<value[,value,...]>
              With value being one of the options in the following list.

                 =all: Include all the below options.

              The following options allow to check the integrity of the logical view; collect the
              debug  tags  that are processed or not implemented; ignore the logical element line
              number, to facilitate the logical view comparison when  using  external  comparison
              tools; print the command line options used to invoke llvm-debuginfo-analyzer.

                 =id: Print unique element ID.
                 =cmdline: Print command line.
                 =integrity: Check elements integrity.
                 =none: Ignore element line number.
                 =tag: Debug information tags.

              Note:  For  ELF  format,  the  collected tags represent the debug tags that are not
              processed. For PE/COFF format, they represent the tags that are processed.

EXAMPLES

       This section includes some real binary files to show how to use llvm-debuginfo-analyzer to
       print a logical view and to diagnose possible debug information issues.

   TEST CASE 1 - GENERAL OPTIONS
       The  below  example is used to show different output generated by llvm-debuginfo-analyzer.
       We compiled the example for an X86 ELF target with Clang (-O0 -g):

          1  using INTPTR = const int *;
          2  int foo(INTPTR ParamPtr, unsigned ParamUnsigned, bool ParamBool) {
          3    if (ParamBool) {
          4      typedef int INTEGER;
          5      const INTEGER CONSTANT = 7;
          6      return CONSTANT;
          7    }
          8    return ParamUnsigned;
          9  }

   PRINTING MODE
       In this mode llvm-debuginfo-analyzer prints the logical view or portions of it,  based  on
       criteria  patterns  (including regular expressions) to select the kind of logical elements
       to be included in the output.

   BASIC DETAILS
       The following command prints basic details for all the  logical  elements  sorted  by  the
       debug information internal offset; it includes its lexical level and debug info format.

          llvm-debuginfo-analyzer --attribute=level,format
                                  --output-sort=offset
                                  --print=scopes,symbols,types,lines,instructions
                                  test-dwarf-clang.o

       or

          llvm-debuginfo-analyzer --attribute=level,format
                                  --output-sort=offset
                                  --print=elements
                                  test-dwarf-clang.o

       Each  row  represents  an  element that is present within the debug information. The first
       column represents the scope level, followed by the associated line number  (if  any),  and
       finally the description of the element.

          Logical View:
          [000]           {File} 'test-dwarf-clang.o' -> elf64-x86-64

          [001]             {CompileUnit} 'test.cpp'
          [002]     2         {Function} extern not_inlined 'foo' -> 'int'
          [003]     2           {Parameter} 'ParamPtr' -> 'INTPTR'
          [003]     2           {Parameter} 'ParamUnsigned' -> 'unsigned int'
          [003]     2           {Parameter} 'ParamBool' -> 'bool'
          [003]                 {Block}
          [004]     5             {Variable} 'CONSTANT' -> 'const INTEGER'
          [004]     5             {Line}
          [004]                   {Code} 'movl  $0x7, -0x1c(%rbp)'
          [004]     6             {Line}
          [004]                   {Code} 'movl  $0x7, -0x4(%rbp)'
          [004]                   {Code} 'jmp   0x6'
          [004]     8             {Line}
          [004]                   {Code} 'movl  -0x14(%rbp), %eax'
          [003]     4           {TypeAlias} 'INTEGER' -> 'int'
          [003]     2           {Line}
          [003]                 {Code} 'pushq   %rbp'
          [003]                 {Code} 'movq    %rsp, %rbp'
          [003]                 {Code} 'movb    %dl, %al'
          [003]                 {Code} 'movq    %rdi, -0x10(%rbp)'
          [003]                 {Code} 'movl    %esi, -0x14(%rbp)'
          [003]                 {Code} 'andb    $0x1, %al'
          [003]                 {Code} 'movb    %al, -0x15(%rbp)'
          [003]     3           {Line}
          [003]                 {Code} 'testb   $0x1, -0x15(%rbp)'
          [003]                 {Code} 'je      0x13'
          [003]     8           {Line}
          [003]                 {Code} 'movl    %eax, -0x4(%rbp)'
          [003]     9           {Line}
          [003]                 {Code} 'movl    -0x4(%rbp), %eax'
          [003]                 {Code} 'popq    %rbp'
          [003]                 {Code} 'retq'
          [003]     9           {Line}
          [002]     1         {TypeAlias} 'INTPTR' -> '* const int'

       On closer inspection, we can see what could be a potential debug issue:

          [003]                 {Block}
          [003]     4           {TypeAlias} 'INTEGER' -> 'int'

       The  ‘INTEGER’  definition  is  at  level  [003],  the same lexical scope as the anonymous
       {Block} (‘true’ branch for the ‘if’ statement) whereas in the  original  source  code  the
       typedef statement is clearly inside that block, so the ‘INTEGER’ definition should also be
       at level [004] inside the block.

   SELECT LOGICAL ELEMENTS
       The following prints all instructions, symbols and types that contain ‘inte’ or ‘movl’  in
       their names or types, using a tab layout and given the number of matches.

          llvm-debuginfo-analyzer --attribute=level
                                  --select-nocase --select-regex
                                  --select=INTe --select=movl
                                  --report=list
                                  --print=symbols,types,instructions,summary
                                  test-dwarf-clang.o

          Logical View:
          [000]           {File} 'test-dwarf-clang.o'

          [001]           {CompileUnit} 'test.cpp'
          [003]           {Code} 'movl  $0x7, -0x1c(%rbp)'
          [003]           {Code} 'movl  $0x7, -0x4(%rbp)'
          [003]           {Code} 'movl  %eax, -0x4(%rbp)'
          [003]           {Code} 'movl  %esi, -0x14(%rbp)'
          [003]           {Code} 'movl  -0x14(%rbp), %eax'
          [003]           {Code} 'movl  -0x4(%rbp), %eax'
          [003]     4     {TypeAlias} 'INTEGER' -> 'int'
          [004]     5     {Variable} 'CONSTANT' -> 'const INTEGER'

          -----------------------------
          Element      Total      Found
          -----------------------------
          Scopes           3          0
          Symbols          4          1
          Types            2          1
          Lines           17          6
          -----------------------------
          Total           26          8

   COMPARISON MODE
       In  this  mode llvm-debuginfo-analyzer compares logical views to produce a report with the
       logical elements that are missing or added.  This a very powerful aid in finding  semantic
       differences  in  the  debug  information  produced by different toolchain versions or even
       completely different toolchains altogether (For example a compiler producing DWARF can  be
       directly compared against a completely different compiler that produces CodeView).

       Given  the  previous  example  we  found the above debug information issue (related to the
       previous invalid scope location for  the  ‘typedef  int  INTEGER’)  by  comparing  against
       another compiler.

       Using GCC to generate test-dwarf-gcc.o, we can apply a selection pattern with the printing
       mode to obtain the following logical view output.

          llvm-debuginfo-analyzer --attribute=level
                                  --select-regex --select-nocase --select=INTe
                                  --report=list
                                  --print=symbols,types
                                  test-dwarf-clang.o test-dwarf-gcc.o

          Logical View:
          [000]           {File} 'test-dwarf-clang.o'

          [001]           {CompileUnit} 'test.cpp'
          [003]     4     {TypeAlias} 'INTEGER' -> 'int'
          [004]     5     {Variable} 'CONSTANT' -> 'const INTEGER'

          Logical View:
          [000]           {File} 'test-dwarf-gcc.o'

          [001]           {CompileUnit} 'test.cpp'
          [004]     4     {TypeAlias} 'INTEGER' -> 'int'
          [004]     5     {Variable} 'CONSTANT' -> 'const INTEGER'

       The output shows that both objects contain the same elements. But the ‘typedef INTEGER’ is
       located  at  different  scope  level.  The  GCC  generated object, shows ‘4’, which is the
       correct value.

       Note that there is no requirement that GCC must produce  identical  or  similar  DWARF  to
       Clang  to  allow  the  comparison.  We’re only comparing the semantics. The same case when
       comparing CodeView debug information generated by MSVC and Clang.

       There are 2 comparison methods: logical view and logical elements.

   LOGICAL VIEW
       It compares the logical view as a whole unit; for a match, each compared  logical  element
       must have the same parents and children.

       Using  the  llvm-debuginfo-analyzer  comparison functionality, that issue can be seen in a
       more global context, that can include the logical view.

       The output shows in view form the missing (-), added (+) elements, giving more context  by
       swapping the reference and target object files.

          llvm-debuginfo-analyzer --attribute=level
                                  --compare=types
                                  --report=view
                                  --print=symbols,types
                                  test-dwarf-clang.o test-dwarf-gcc.o

          Reference: 'test-dwarf-clang.o'
          Target:    'test-dwarf-gcc.o'

          Logical View:
           [000]           {File} 'test-dwarf-clang.o'

           [001]             {CompileUnit} 'test.cpp'
           [002]     1         {TypeAlias} 'INTPTR' -> '* const int'
           [002]     2         {Function} extern not_inlined 'foo' -> 'int'
           [003]                 {Block}
           [004]     5             {Variable} 'CONSTANT' -> 'const INTEGER'
          +[004]     4             {TypeAlias} 'INTEGER' -> 'int'
           [003]     2           {Parameter} 'ParamBool' -> 'bool'
           [003]     2           {Parameter} 'ParamPtr' -> 'INTPTR'
           [003]     2           {Parameter} 'ParamUnsigned' -> 'unsigned int'
          -[003]     4           {TypeAlias} 'INTEGER' -> 'int'

       The  output  shows the merging view path (reference and target) with the missing and added
       elements.

   LOGICAL ELEMENTS
       It compares individual logical elements without considering if their parents are the same.
       For  both  comparison methods, the equal criteria includes the name, source code location,
       type, lexical scope level.

          llvm-debuginfo-analyzer --attribute=level
                                  --compare=types
                                  --report=list
                                  --print=symbols,types,summary
                                  test-dwarf-clang.o test-dwarf-gcc.o

          Reference: 'test-dwarf-clang.o'
          Target:    'test-dwarf-gcc.o'

          (1) Missing Types:
          -[003]     4     {TypeAlias} 'INTEGER' -> 'int'

          (1) Added Types:
          +[004]     4     {TypeAlias} 'INTEGER' -> 'int'

          ----------------------------------------
          Element   Expected    Missing      Added
          ----------------------------------------
          Scopes           4          0          0
          Symbols          0          0          0
          Types            2          1          1
          Lines            0          0          0
          ----------------------------------------
          Total            6          1          1

       Changing the Reference and Target order:

          llvm-debuginfo-analyzer --attribute=level
                                  --compare=types
                                  --report=list
                                  --print=symbols,types,summary
                                  test-dwarf-gcc.o test-dwarf-clang.o

          Reference: 'test-dwarf-gcc.o'
          Target:    'test-dwarf-clang.o'

          (1) Missing Types:
          -[004]     4     {TypeAlias} 'INTEGER' -> 'int'

          (1) Added Types:
          +[003]     4     {TypeAlias} 'INTEGER' -> 'int'

          ----------------------------------------
          Element   Expected    Missing      Added
          ----------------------------------------
          Scopes           4          0          0
          Symbols          0          0          0
          Types            2          1          1
          Lines            0          0          0
          ----------------------------------------
          Total            6          1          1

       As the Reference and Target are switched, the Added Types from  the  first  case  now  are
       listed as Missing Types.

   TEST CASE 2 - ASSEMBLER INSTRUCTIONS
       The  below  example is used to show different output generated by llvm-debuginfo-analyzer.
       We compiled the example for an X86 Codeview and ELF targets with recent versions of Clang,
       GCC and MSVC (-O0 -g) for Windows and Linux.

          1  extern int printf(const char * format, ... );
          2
          3  int main()
          4  {
          5    printf("Hello, World\n");
          6    return 0;
          7  }

       These  are  the  logical  views  that  llvm-debuginfo-analyzer  generates  for 3 different
       compilers (MSVC, Clang and GCC), emitting different debug information  formats  (CodeView,
       DWARF) on Windows and Linux.

          llvm-debuginfo-analyzer --attribute=level,format,producer
                                  --print=lines,instructions
                                  hello-world-codeview-clang.o
                                  hello-world-codeview-msvc.o
                                  hello-world-dwarf-clang.o
                                  hello-world-dwarf-gcc.o

   CodeView - Clang (Windows)
          Logical View:
          [000]           {File} 'hello-world-codeview-clang.o' -> COFF-x86-64

          [001]             {CompileUnit} 'hello-world.cpp'
          [002]               {Producer} 'clang version 14.0.0'
          [002]               {Function} extern not_inlined 'main' -> 'int'
          [003]     4           {Line}
          [003]                 {Code} 'subq    $0x28, %rsp'
          [003]                 {Code} 'movl    $0x0, 0x24(%rsp)'
          [003]     5           {Line}
          [003]                 {Code} 'leaq    (%rip), %rcx'
          [003]                 {Code} 'callq   0x0'
          [003]     6           {Line}
          [003]                 {Code} 'xorl    %eax, %eax'
          [003]                 {Code} 'addq    $0x28, %rsp'
          [003]                 {Code} 'retq'

   CodeView - MSVC (Windows)
          Logical View:
          [000]           {File} 'hello-world-codeview-msvc.o' -> COFF-i386

          [001]             {CompileUnit} 'hello-world.cpp'
          [002]               {Producer} 'Microsoft (R) Optimizing Compiler'
          [002]               {Function} extern not_inlined 'main' -> 'int'
          [003]     4           {Line}
          [003]                 {Code} 'pushl   %ebp'
          [003]                 {Code} 'movl    %esp, %ebp'
          [003]     5           {Line}
          [003]                 {Code} 'pushl   $0x0'
          [003]                 {Code} 'calll   0x0'
          [003]                 {Code} 'addl    $0x4, %esp'
          [003]     6           {Line}
          [003]                 {Code} 'xorl    %eax, %eax'
          [003]     7           {Line}
          [003]                 {Code} 'popl    %ebp'
          [003]                 {Code} 'retl'

   DWARF - Clang (Linux)
          Logical View:
          [000]           {File} 'hello-world-dwarf-clang.o' -> elf64-x86-64

          [001]             {CompileUnit} 'hello-world.cpp'
          [002]               {Producer} 'clang version 14.0.0'
          [002]     3         {Function} extern not_inlined 'main' -> 'int'
          [003]     4           {Line}
          [003]                 {Code} 'pushq   %rbp'
          [003]                 {Code} 'movq    %rsp, %rbp'
          [003]                 {Code} 'subq    $0x10, %rsp'
          [003]                 {Code} 'movl    $0x0, -0x4(%rbp)'
          [003]     5           {Line}
          [003]                 {Code} 'movabsq $0x0, %rdi'
          [003]                 {Code} 'movb    $0x0, %al'
          [003]                 {Code} 'callq   0x0'
          [003]     6           {Line}
          [003]                 {Code} 'xorl    %eax, %eax'
          [003]                 {Code} 'addq    $0x10, %rsp'
          [003]                 {Code} 'popq    %rbp'
          [003]                 {Code} 'retq'
          [003]     6           {Line}

   DWARF - GCC (Linux)
          Logical View:
          [000]           {File} 'hello-world-dwarf-gcc.o' -> elf64-x86-64

          [001]             {CompileUnit} 'hello-world.cpp'
          [002]               {Producer} 'GNU C++14 9.3.0'
          [002]     3         {Function} extern not_inlined 'main' -> 'int'
          [003]     4           {Line}
          [003]                 {Code} 'endbr64'
          [003]                 {Code} 'pushq   %rbp'
          [003]                 {Code} 'movq    %rsp, %rbp'
          [003]     5           {Line}
          [003]                 {Code} 'leaq    (%rip), %rdi'
          [003]                 {Code} 'movl    $0x0, %eax'
          [003]                 {Code} 'callq   0x0'
          [003]     6           {Line}
          [003]                 {Code} 'movl    $0x0, %eax'
          [003]     7           {Line}
          [003]                 {Code} 'popq    %rbp'
          [003]                 {Code} 'retq'
          [003]     7           {Line}

       The  logical  views  shows  the  intermixed  lines and assembler instructions, allowing to
       compare the code generated by the different toolchains.

   TEST CASE 3 - INCORRECT LEXICAL SCOPE FOR TYPEDEF
       The below example is used to show different output generated  by  llvm-debuginfo-analyzer.
       We compiled the example for an X86 Codeview and ELF targets with recent versions of Clang,
       GCC and MSVC (-O0 -g).

           1  int bar(float Input) { return (int)Input; }
           2
           3  unsigned foo(char Param) {
           4    typedef int INT;                // ** Definition for INT **
           5    INT Value = Param;
           6    {
           7      typedef float FLOAT;          // ** Definition for FLOAT **
           8      {
           9        FLOAT Added = Value + Param;
          10        Value = bar(Added);
          11      }
          12    }
          13    return Value + Param;
          14  }

       The above test is used to illustrate a scope issue found in the  Clang  compiler:  PR44884
       (Bugs LLVM) / PR44229 (GitHub LLVM)

       The lines 4 and 7 contains 2 typedefs, defined at different lexical scopes.

          4    typedef int INT;
          7      typedef float FLOAT;

       These  are  the  logical  views  that  llvm-debuginfo-analyzer  generates  for 3 different
       compilers (MSVC, Clang and GCC), emitting different debug information  formats  (CodeView,
       DWARF) on different platforms.

          llvm-debuginfo-analyzer --attribute=level,format,producer
                                  --print=symbols,types,lines
                                  --output-sort=kind
                                  pr-44884-codeview-clang.o
                                  pr-44884-codeview-msvc.o
                                  pr-44884-dwarf-clang.o
                                  pr-44884-dwarf-gcc.o

   CodeView - Clang (Windows)
          Logical View:
          [000]           {File} 'pr-44884-codeview-clang.o' -> COFF-x86-64

          [001]             {CompileUnit} 'pr-44884.cpp'
          [002]               {Producer} 'clang version 14.0.0'
          [002]               {Function} extern not_inlined 'bar' -> 'int'
          [003]                 {Parameter} 'Input' -> 'float'
          [003]     1           {Line}
          [002]               {Function} extern not_inlined 'foo' -> 'unsigned'
          [003]                 {Block}
          [004]                   {Variable} 'Added' -> 'float'
          [004]     9             {Line}
          [004]    10             {Line}
          [003]                 {Parameter} 'Param' -> 'char'
          [003]                 {TypeAlias} 'FLOAT' -> 'float'
          [003]                 {TypeAlias} 'INT' -> 'int'
          [003]                 {Variable} 'Value' -> 'int'
          [003]     3           {Line}
          [003]     5           {Line}
          [003]    13           {Line}

   CodeView - MSVC (Windows)
          Logical View:
          [000]           {File} 'pr-44884-codeview-msvc.o' -> COFF-i386

          [001]             {CompileUnit} 'pr-44884.cpp'
          [002]               {Producer} 'Microsoft (R) Optimizing Compiler'
          [002]               {Function} extern not_inlined 'bar' -> 'int'
          [003]                 {Variable} 'Input' -> 'float'
          [003]     1           {Line}
          [002]               {Function} extern not_inlined 'foo' -> 'unsigned'
          [003]                 {Block}
          [004]                   {Block}
          [005]                     {Variable} 'Added' -> 'float'
          [004]                   {TypeAlias} 'FLOAT' -> 'float'
          [004]     9             {Line}
          [004]    10             {Line}
          [003]                 {TypeAlias} 'INT' -> 'int'
          [003]                 {Variable} 'Param' -> 'char'
          [003]                 {Variable} 'Value' -> 'int'
          [003]     3           {Line}
          [003]     5           {Line}
          [003]    13           {Line}
          [003]    14           {Line}

   DWARF - Clang (Linux)
          Logical View:
          [000]           {File} 'pr-44884-dwarf-clang.o' -> elf64-x86-64

          [001]             {CompileUnit} 'pr-44884.cpp'
          [002]               {Producer} 'clang version 14.0.0'
          [002]     1         {Function} extern not_inlined 'bar' -> 'int'
          [003]     1           {Parameter} 'Input' -> 'float'
          [003]     1           {Line}
          [003]     1           {Line}
          [003]     1           {Line}
          [002]     3         {Function} extern not_inlined 'foo' -> 'unsigned int'
          [003]                 {Block}
          [004]     9             {Variable} 'Added' -> 'FLOAT'
          [004]     9             {Line}
          [004]     9             {Line}
          [004]     9             {Line}
          [004]     9             {Line}
          [004]     9             {Line}
          [004]    10             {Line}
          [004]    10             {Line}
          [004]    10             {Line}
          [004]    13             {Line}
          [003]     3           {Parameter} 'Param' -> 'char'
          [003]     7           {TypeAlias} 'FLOAT' -> 'float'
          [003]     4           {TypeAlias} 'INT' -> 'int'
          [003]     5           {Variable} 'Value' -> 'INT'
          [003]     3           {Line}
          [003]     5           {Line}
          [003]     5           {Line}
          [003]    13           {Line}
          [003]    13           {Line}
          [003]    13           {Line}
          [003]    13           {Line}

   DWARF - GCC (Linux)
          Logical View:
          [000]           {File} 'pr-44884-dwarf-gcc.o' -> elf32-littlearm

          [001]             {CompileUnit} 'pr-44884.cpp'
          [002]               {Producer} 'GNU C++14 10.2.1 20201103'
          [002]     1         {Function} extern not_inlined 'bar' -> 'int'
          [003]     1           {Parameter} 'Input' -> 'float'
          [003]     1           {Line}
          [003]     1           {Line}
          [003]     1           {Line}
          [002]     3         {Function} extern not_inlined 'foo' -> 'unsigned int'
          [003]                 {Block}
          [004]                   {Block}
          [005]     9               {Variable} 'Added' -> 'FLOAT'
          [005]     9               {Line}
          [005]     9               {Line}
          [005]     9               {Line}
          [005]    10               {Line}
          [005]    13               {Line}
          [004]     7             {TypeAlias} 'FLOAT' -> 'float'
          [003]     3           {Parameter} 'Param' -> 'char'
          [003]     4           {TypeAlias} 'INT' -> 'int'
          [003]     5           {Variable} 'Value' -> 'INT'
          [003]     3           {Line}
          [003]     5           {Line}
          [003]    13           {Line}
          [003]    14           {Line}
          [003]    14           {Line}

       From the previous logical views, we can see that the Clang compiler emits both typedefs at
       the same lexical scope (3), which is wrong.  GCC and MSVC emit correct lexical  scope  for
       both typedefs.

       Using  the  llvm-debuginfo-analyzer  selection facilities, we can produce a simple tabular
       output showing just the logical types that are Typedef.

          llvm-debuginfo-analyzer --attribute=level,format
                                  --output-sort=name
                                  --select-types=Typedef
                                  --report=list
                                  --print=types
                                  pr-44884-*.o

          Logical View:
          [000]           {File} 'pr-44884-codeview-clang.o' -> COFF-x86-64

          [001]           {CompileUnit} 'pr_44884.cpp'
          [003]           {TypeAlias} 'FLOAT' -> 'float'
          [003]           {TypeAlias} 'INT' -> 'int'

          Logical View:
          [000]           {File} 'pr-44884-codeview-msvc.o' -> COFF-i386

          [001]           {CompileUnit} 'pr_44884.cpp'
          [004]           {TypeAlias} 'FLOAT' -> 'float'
          [003]           {TypeAlias} 'INT' -> 'int'

          Logical View:
          [000]           {File} 'pr-44884-dwarf-clang.o' -> elf64-x86-64

          [001]           {CompileUnit} 'pr_44884.cpp'
          [003]     7     {TypeAlias} 'FLOAT' -> 'float'
          [003]     4     {TypeAlias} 'INT' -> 'int'

          Logical View:
          [000]           {File} 'pr-44884-dwarf-gcc.o' -> elf32-littlearm

          [001]           {CompileUnit} 'pr_44884.cpp'
          [004]     7     {TypeAlias} 'FLOAT' -> 'float'
          [003]     4     {TypeAlias} 'INT' -> 'int'

       It also shows, that the CodeView debug information does  not  generate  source  code  line
       numbers for the those logical types. The logical view is sorted by the types name.

   TEST CASE 4 - MISSING NESTED ENUMERATIONS
       The  below  example is used to show different output generated by llvm-debuginfo-analyzer.
       We compiled the example for an X86 Codeview and ELF targets with recent versions of Clang,
       GCC and MSVC (-O0 -g).

           1  struct Struct {
           2    union Union {
           3      enum NestedEnum { RED, BLUE };
           4    };
           5    Union U;
           6  };
           7
           8  Struct S;
           9  int test() {
          10    return S.U.BLUE;
          11  }

       The  above  test  is used to illustrate a scope issue found in the Clang compiler: PR46466
       (Bugs LLVM) / PR45811 (GitHub LLVM)

       These are the  logical  views  that  llvm-debuginfo-analyzer  generates  for  3  different
       compilers  (MSVC,  Clang and GCC), emitting different debug information formats (CodeView,
       DWARF) on different platforms.

          llvm-debuginfo-analyzer --attribute=level,format,producer
                                  --output-sort=name
                                  --print=symbols,types
                                  pr-46466-codeview-clang.o
                                  pr-46466-codeview-msvc.o
                                  pr-46466-dwarf-clang.o
                                  pr-46466-dwarf-gcc.o

   CodeView - Clang (Windows)
          Logical View:
          [000]           {File} 'pr-46466-codeview-clang.o' -> COFF-x86-64

          [001]             {CompileUnit} 'pr-46466.cpp'
          [002]               {Producer} 'clang version 14.0.0'
          [002]               {Variable} extern 'S' -> 'Struct'
          [002]     1         {Struct} 'Struct'
          [003]                 {Member} public 'U' -> 'Union'
          [003]     2           {Union} 'Union'
          [004]     3             {Enumeration} 'NestedEnum' -> 'int'
          [005]                     {Enumerator} 'BLUE' = '0x1'
          [005]                     {Enumerator} 'RED' = '0x0'

   CodeView - MSVC (Windows)
          Logical View:
          [000]           {File} 'pr-46466-codeview-msvc.o' -> COFF-i386

          [001]             {CompileUnit} 'pr-46466.cpp'
          [002]               {Producer} 'Microsoft (R) Optimizing Compiler'
          [002]               {Variable} extern 'S' -> 'Struct'
          [002]     1         {Struct} 'Struct'
          [003]                 {Member} public 'U' -> 'Union'
          [003]     2           {Union} 'Union'
          [004]     3             {Enumeration} 'NestedEnum' -> 'int'
          [005]                     {Enumerator} 'BLUE' = '0x1'
          [005]                     {Enumerator} 'RED' = '0x0'

   DWARF - Clang (Linux)
          Logical View:
          [000]           {File} 'pr-46466-dwarf-clang.o' -> elf64-x86-64

          [001]             {CompileUnit} 'pr-46466.cpp'
          [002]               {Producer} 'clang version 14.0.0'
          [002]     8         {Variable} extern 'S' -> 'Struct'
          [002]     1         {Struct} 'Struct'
          [003]     5           {Member} public 'U' -> 'Union'

   DWARF - GCC (Linux)
          Logical View:
          [000]           {File} 'pr-46466-dwarf-gcc.o' -> elf64-x86-64

          [001]             {CompileUnit} 'pr-46466.cpp'
          [002]               {Producer} 'GNU C++14 9.3.0'
          [002]     8         {Variable} extern 'S' -> 'Struct'
          [002]     1         {Struct} 'Struct'
          [003]     5           {Member} public 'U' -> 'Union'
          [003]     2           {Union} 'Union'
          [004]     3             {Enumeration} 'NestedEnum' -> 'unsigned int'
          [005]                     {Enumerator} 'BLUE' = '0x1'
          [005]                     {Enumerator} 'RED' = '0x0'

       From the previous logical views, we can see that the DWARF debug information generated  by
       the  Clang  compiler  does not include any references to the enumerators RED and BLUE. The
       DWARF generated by GCC, CodeView generated  by  Clang  and  MSVC,  they  do  include  such
       references.

       Using  the  llvm-debuginfo-analyzer  selection  facilities,  we can produce a logical view
       showing just the logical types that are Enumerator and its parents. The  logical  view  is
       sorted by the types name.

          llvm-debuginfo-analyzer --attribute=format,level
                                  --output-sort=name
                                  --select-types=Enumerator
                                  --report=parents
                                  --print=types
                                  pr-46466-*.o

          Logical View:
          [000]           {File} 'pr-46466-codeview-clang.o' -> COFF-x86-64

          [001]             {CompileUnit} 'pr-46466.cpp'
          [002]     1         {Struct} 'Struct'
          [003]     2           {Union} 'Union'
          [004]     3             {Enumeration} 'NestedEnum' -> 'int'
          [005]                     {Enumerator} 'BLUE' = '0x1'
          [005]                     {Enumerator} 'RED' = '0x0'

          Logical View:
          [000]           {File} 'pr-46466-codeview-msvc.o' -> COFF-i386

          [001]             {CompileUnit} 'pr-46466.cpp'
          [002]     1         {Struct} 'Struct'
          [003]     2           {Union} 'Union'
          [004]     3             {Enumeration} 'NestedEnum' -> 'int'
          [005]                     {Enumerator} 'BLUE' = '0x1'
          [005]                     {Enumerator} 'RED' = '0x0'

          Logical View:
          [000]           {File} 'pr-46466-dwarf-clang.o' -> elf64-x86-64

          [001]             {CompileUnit} 'pr-46466.cpp'

          Logical View:
          [000]           {File} 'pr-46466-dwarf-gcc.o' -> elf64-x86-64

          [001]             {CompileUnit} 'pr-46466.cpp'
          [002]     1         {Struct} 'Struct'
          [003]     2           {Union} 'Union'
          [004]     3             {Enumeration} 'NestedEnum' -> 'unsigned int'
          [005]                     {Enumerator} 'BLUE' = '0x1'
          [005]                     {Enumerator} 'RED' = '0x0'

       Using  the  llvm-debuginfo-analyzer  selection facilities, we can produce a simple tabular
       output including a summary for the logical types that are Enumerator. The logical view  is
       sorted by the types name.

          llvm-debuginfo-analyzer --attribute=format,level
                                  --output-sort=name
                                  --select-types=Enumerator
                                  --print=types,summary
                                  pr-46466-*.o

          Logical View:
          [000]           {File} 'pr-46466-codeview-clang.o' -> COFF-x86-64

          [001]           {CompileUnit} 'pr-46466.cpp'
          [005]           {Enumerator} 'BLUE' = '0x1'
          [005]           {Enumerator} 'RED' = '0x0'

          -----------------------------
          Element      Total      Found
          -----------------------------
          Scopes           5          0
          Symbols          2          0
          Types            6          2
          Lines            0          0
          -----------------------------
          Total           13          2

          Logical View:
          [000]           {File} 'pr-46466-codeview-msvc.o' -> COFF-i386

          [001]           {CompileUnit} 'pr-46466.cpp'
          [005]           {Enumerator} 'BLUE' = '0x1'
          [005]           {Enumerator} 'RED' = '0x0'

          -----------------------------
          Element      Total      Found
          -----------------------------
          Scopes           5          0
          Symbols          2          0
          Types            7          2
          Lines            0          0
          -----------------------------
          Total           14          2

          Logical View:
          [000]           {File} 'pr-46466-dwarf-clang.o' -> elf64-x86-64

          [001]           {CompileUnit} 'pr-46466.cpp'

          -----------------------------
          Element      Total      Found
          -----------------------------
          Scopes           4          0
          Symbols          0          0
          Types            0          0
          Lines            0          0
          -----------------------------
          Total            4          0

          Logical View:
          [000]           {File} 'pr-46466-dwarf-gcc.o' -> elf64-x86-64

          [001]           {CompileUnit} 'pr-46466.cpp'
          [005]           {Enumerator} 'BLUE' = '0x1'
          [005]           {Enumerator} 'RED' = '0x0'

          -----------------------------
          Element      Total      Found
          -----------------------------
          Scopes           5          0
          Symbols          0          0
          Types            2          2
          Lines            0          0
          -----------------------------
          Total            7          2

       From the values printed under the Found column, we can see that no Types were found in the
       DWARF debug information generated by Clang.

   TEST CASE 5 - INCORRECT LEXICAL SCOPE FOR VARIABLE
       The below example is used to show different output generated  by  llvm-debuginfo-analyzer.
       We compiled the example for an X86 Codeview and ELF targets with recent versions of Clang,
       GCC and MSVC (-O0 -g).

          // definitions.h
          #ifdef _MSC_VER
            #define forceinline __forceinline
          #elif defined(__clang__)
            #if __has_attribute(__always_inline__)
              #define forceinline inline __attribute__((__always_inline__))
            #else
              #define forceinline inline
            #endif
          #elif defined(__GNUC__)
            #define forceinline inline __attribute__((__always_inline__))
          #else
            #define forceinline inline
            #error
          #endif

       As the test is dependent on  inline  compiler  options,  the  above  header  file  defines
       forceinline.

          #include "definitions.h"

           1  #include "definitions.h"
           2  forceinline int InlineFunction(int Param) {
           3    int Var_1 = Param;
           4    {
           5      int Var_2 = Param + Var_1;
           6      Var_1 = Var_2;
           7    }
           8    return Var_1;
           9  }
          10
          11  int test(int Param_1, int Param_2) {
          12    int A = Param_1;
          13    A += InlineFunction(Param_2);
          14    return A;
          15  }

       The above test is used to illustrate a variable issue found in the Clang compiler: PR43860
       (Bugs LLVM) / PR43205 (GitHub)

       These are the  logical  views  that  llvm-debuginfo-analyzer  generates  for  3  different
       compilers  (MSVC,  Clang and GCC), emitting different debug information formats (CodeView,
       DWARF) on different platforms.

          llvm-debuginfo-analyzer --attribute=level,format,producer
                                  --output-sort=name
                                  --print=symbols
                                  pr-43860-codeview-clang.o
                                  pr-43860-codeview-msvc.o
                                  pr-43860-dwarf-clang.o
                                  pr-43860-dwarf-gcc.o

   CODEVIEW - Clang (Windows)
          Logical View:
          [000]           {File} 'pr-43860-codeview-clang.o' -> COFF-x86-64

          [001]             {CompileUnit} 'pr-43860.cpp'
          [002]               {Producer} 'clang version 14.0.0'
          [002]     2         {Function} inlined 'InlineFunction' -> 'int'
          [003]                 {Parameter} '' -> 'int'
          [002]               {Function} extern not_inlined 'test' -> 'int'
          [003]                 {Variable} 'A' -> 'int'
          [003]                 {InlinedFunction} inlined 'InlineFunction' -> 'int'
          [004]                   {Parameter} 'Param' -> 'int'
          [004]                   {Variable} 'Var_1' -> 'int'
          [004]                   {Variable} 'Var_2' -> 'int'
          [003]                 {Parameter} 'Param_1' -> 'int'
          [003]                 {Parameter} 'Param_2' -> 'int'

   CODEVIEW - MSVC (Windows)
          Logical View:
          [000]           {File} 'pr-43860-codeview-msvc.o' -> COFF-i386

          [001]             {CompileUnit} 'pr-43860.cpp'
          [002]               {Producer} 'Microsoft (R) Optimizing Compiler'
          [002]               {Function} extern not_inlined 'InlineFunction' -> 'int'
          [003]                 {Block}
          [004]                   {Variable} 'Var_2' -> 'int'
          [003]                 {Variable} 'Param' -> 'int'
          [003]                 {Variable} 'Var_1' -> 'int'
          [002]               {Function} extern not_inlined 'test' -> 'int'
          [003]                 {Variable} 'A' -> 'int'
          [003]                 {Variable} 'Param_1' -> 'int'
          [003]                 {Variable} 'Param_2' -> 'int'

   DWARF - Clang (Linux)
          Logical View:
          [000]           {File} 'pr-43860-dwarf-clang.o' -> elf64-x86-64

          [001]             {CompileUnit} 'pr-43860.cpp'
          [002]               {Producer} 'clang version 14.0.0'
          [002]     2         {Function} extern inlined 'InlineFunction' -> 'int'
          [003]                 {Block}
          [004]     5             {Variable} 'Var_2' -> 'int'
          [003]     2           {Parameter} 'Param' -> 'int'
          [003]     3           {Variable} 'Var_1' -> 'int'
          [002]    11         {Function} extern not_inlined 'test' -> 'int'
          [003]    12           {Variable} 'A' -> 'int'
          [003]    14           {InlinedFunction} inlined 'InlineFunction' -> 'int'
          [004]                   {Block}
          [005]                     {Variable} 'Var_2' -> 'int'
          [004]                   {Parameter} 'Param' -> 'int'
          [004]                   {Variable} 'Var_1' -> 'int'
          [003]    11           {Parameter} 'Param_1' -> 'int'
          [003]    11           {Parameter} 'Param_2' -> 'int'

   DWARF - GCC (Linux)
          Logical View:
          [000]           {File} 'pr-43860-dwarf-gcc.o' -> elf64-x86-64

          [001]             {CompileUnit} 'pr-43860.cpp'
          [002]               {Producer} 'GNU C++14 9.3.0'
          [002]     2         {Function} extern declared_inlined 'InlineFunction' -> 'int'
          [003]                 {Block}
          [004]     5             {Variable} 'Var_2' -> 'int'
          [003]     2           {Parameter} 'Param' -> 'int'
          [003]     3           {Variable} 'Var_1' -> 'int'
          [002]    11         {Function} extern not_inlined 'test' -> 'int'
          [003]    12           {Variable} 'A' -> 'int'
          [003]    13           {InlinedFunction} declared_inlined 'InlineFunction' -> 'int'
          [004]                   {Block}
          [005]                     {Variable} 'Var_2' -> 'int'
          [004]                   {Parameter} 'Param' -> 'int'
          [004]                   {Variable} 'Var_1' -> 'int'
          [003]    11           {Parameter} 'Param_1' -> 'int'
          [003]    11           {Parameter} 'Param_2' -> 'int'

       From the previous logical views, we can see that the CodeView debug information  generated
       by  the  Clang  compiler shows the variables Var_1 and Var_2 are at the same lexical scope
       (4) in the function InlineFuction. The DWARF generated by GCC/Clang and CodeView generated
       by MSVC, show those variables at the correct lexical scope: 3 and 4 respectively.

       Using  the  llvm-debuginfo-analyzer  selection facilities, we can produce a simple tabular
       output showing just the logical elements that have in their  name  the  var  pattern.  The
       logical view is sorted by the variables name.

          llvm-debuginfo-analyzer --attribute=level,format
                                  --output-sort=name
                                  --select-regex --select-nocase --select=Var
                                  --report=list
                                  --print=symbols
                                  pr-43860-*.o

          Logical View:
          [000]           {File} 'pr-43860-codeview-clang.o' -> COFF-x86-64

          [001]           {CompileUnit} 'pr-43860.cpp'
          [004]           {Variable} 'Var_1' -> 'int'
          [004]           {Variable} 'Var_2' -> 'int'

          Logical View:
          [000]           {File} 'pr-43860-codeview-msvc.o' -> COFF-i386

          [001]           {CompileUnit} 'pr-43860.cpp'
          [003]           {Variable} 'Var_1' -> 'int'
          [004]           {Variable} 'Var_2' -> 'int'

          Logical View:
          [000]           {File} 'pr-43860-dwarf-clang.o' -> elf64-x86-64

          [001]           {CompileUnit} 'pr-43860.cpp'
          [004]           {Variable} 'Var_1' -> 'int'
          [003]     3     {Variable} 'Var_1' -> 'int'
          [005]           {Variable} 'Var_2' -> 'int'
          [004]     5     {Variable} 'Var_2' -> 'int'

          Logical View:
          [000]           {File} 'pr-43860-dwarf-gcc.o' -> elf64-x86-64

          [001]           {CompileUnit} 'pr-43860.cpp'
          [004]           {Variable} 'Var_1' -> 'int'
          [003]     3     {Variable} 'Var_1' -> 'int'
          [005]           {Variable} 'Var_2' -> 'int'
          [004]     5     {Variable} 'Var_2' -> 'int'

       It  also  shows,  that  the  CodeView debug information does not generate source code line
       numbers for the those logical symbols. The logical view is sorted by the types name.

   TEST CASE 6 - FULL LOGICAL VIEW
       For advanced  users,  llvm-debuginfo-analyzer  can  display  low  level  information  that
       includes  offsets  within  the debug information section, debug location operands, linkage
       names, etc.

          llvm-debuginfo-analyzer --attribute=all
                                  --print=all
                                  test-dwarf-clang.o

          Logical View:
          [0x0000000000][000]            {File} 'test-dwarf-clang.o' -> elf64-x86-64

          [0x000000000b][001]              {CompileUnit} 'test.cpp'
          [0x000000000b][002]                {Producer} 'clang version 12.0.0'
                                             {Directory} ''
                                             {File} 'test.cpp'
                                             {Public} 'foo' [0x0000000000:0x000000003a]
          [0x000000000b][002]                {Range} Lines 2:9 [0x0000000000:0x000000003a]
          [0x00000000bc][002]                {BaseType} 'bool'
          [0x0000000099][002]                {BaseType} 'int'
          [0x00000000b5][002]                {BaseType} 'unsigned int'

          [0x00000000a0][002]   {Source} '/test.cpp'
          [0x00000000a0][002]      1         {TypeAlias} 'INTPTR' -> [0x00000000ab]'* const int'
          [0x000000002a][002]      2         {Function} extern not_inlined 'foo' -> [0x0000000099]'int'
          [0x000000002a][003]                  {Range} Lines 2:9 [0x0000000000:0x000000003a]
          [0x000000002a][003]                  {Linkage}  0x2 '_Z3fooPKijb'
          [0x0000000071][003]                  {Block}
          [0x0000000071][004]                    {Range} Lines 5:8 [0x000000001c:0x000000002f]
          [0x000000007e][004]      5             {Variable} 'CONSTANT' -> [0x00000000c3]'const INTEGER'
          [0x000000007e][005]                      {Coverage} 100.00%
          [0x000000007f][005]                      {Location}
          [0x000000007f][006]                        {Entry} Stack Offset: -28 (0xffffffffffffffe4) [DW_OP_fbreg]
          [0x000000001c][004]      5             {Line} {NewStatement} '/test.cpp'
          [0x000000001c][004]                    {Code} 'movl   $0x7, -0x1c(%rbp)'
          [0x0000000023][004]      6             {Line} {NewStatement} '/test.cpp'
          [0x0000000023][004]                    {Code} 'movl   $0x7, -0x4(%rbp)'
          [0x000000002a][004]                    {Code} 'jmp    0x6'
          [0x000000002f][004]      8             {Line} {NewStatement} '/test.cpp'
          [0x000000002f][004]                    {Code} 'movl   -0x14(%rbp), %eax'
          [0x0000000063][003]      2           {Parameter} 'ParamBool' -> [0x00000000bc]'bool'
          [0x0000000063][004]                    {Coverage} 100.00%
          [0x0000000064][004]                    {Location}
          [0x0000000064][005]                      {Entry} Stack Offset: -21 (0xffffffffffffffeb) [DW_OP_fbreg]
          [0x0000000047][003]      2           {Parameter} 'ParamPtr' -> [0x00000000a0]'INTPTR'
          [0x0000000047][004]                    {Coverage} 100.00%
          [0x0000000048][004]                    {Location}
          [0x0000000048][005]                      {Entry} Stack Offset: -16 (0xfffffffffffffff0) [DW_OP_fbreg]
          [0x0000000055][003]      2           {Parameter} 'ParamUnsigned' -> [0x00000000b5]'unsigned int'
          [0x0000000055][004]                    {Coverage} 100.00%
          [0x0000000056][004]                    {Location}
          [0x0000000056][005]                      {Entry} Stack Offset: -20 (0xffffffffffffffec) [DW_OP_fbreg]
          [0x000000008d][003]      4           {TypeAlias} 'INTEGER' -> [0x0000000099]'int'
          [0x0000000000][003]      2           {Line} {NewStatement} '/test.cpp'
          [0x0000000000][003]                  {Code} 'pushq    %rbp'
          [0x0000000001][003]                  {Code} 'movq     %rsp, %rbp'
          [0x0000000004][003]                  {Code} 'movb     %dl, %al'
          [0x0000000006][003]                  {Code} 'movq     %rdi, -0x10(%rbp)'
          [0x000000000a][003]                  {Code} 'movl     %esi, -0x14(%rbp)'
          [0x000000000d][003]                  {Code} 'andb     $0x1, %al'
          [0x000000000f][003]                  {Code} 'movb     %al, -0x15(%rbp)'
          [0x0000000012][003]      3           {Line} {NewStatement} {PrologueEnd} '/test.cpp'
          [0x0000000012][003]                  {Code} 'testb    $0x1, -0x15(%rbp)'
          [0x0000000016][003]                  {Code} 'je       0x13'
          [0x0000000032][003]      8           {Line} '/test.cpp'
          [0x0000000032][003]                  {Code} 'movl     %eax, -0x4(%rbp)'
          [0x0000000035][003]      9           {Line} {NewStatement} '/test.cpp'
          [0x0000000035][003]                  {Code} 'movl     -0x4(%rbp), %eax'
          [0x0000000038][003]                  {Code} 'popq     %rbp'
          [0x0000000039][003]                  {Code} 'retq'
          [0x000000003a][003]      9           {Line} {NewStatement} {EndSequence} '/test.cpp'

          -----------------------------
          Element      Total    Printed
          -----------------------------
          Scopes           3          3
          Symbols          4          4
          Types            5          5
          Lines           25         25
          -----------------------------
          Total           37         37

          Scope Sizes:
                 189 (100.00%) : [0x000000000b][001]              {CompileUnit} 'test.cpp'
                 110 ( 58.20%) : [0x000000002a][002]      2         {Function} extern not_inlined 'foo' -> [0x0000000099]'int'
                  27 ( 14.29%) : [0x0000000071][003]                  {Block}

          Totals by lexical level:
          [001]:        189 (100.00%)
          [002]:        110 ( 58.20%)
          [003]:         27 ( 14.29%)

       The Scope Sizes table shows the contribution in bytes to the  debug  information  by  each
       scope,  which  can  be  used  to  determine  unexpected size changes in the DWARF sections
       between different versions of the same toolchain.

          [0x000000002a][002]      2         {Function} extern not_inlined 'foo' -> [0x0000000099]'int'
          [0x000000002a][003]                  {Range} Lines 2:9 [0x0000000000:0x000000003a]
          [0x000000002a][003]                  {Linkage}  0x2 '_Z3fooPKijb'
          [0x0000000071][003]                  {Block}
          [0x0000000071][004]                    {Range} Lines 5:8 [0x000000001c:0x000000002f]
          [0x000000007e][004]      5             {Variable} 'CONSTANT' -> [0x00000000c3]'const INTEGER'
          [0x000000007e][005]                      {Coverage} 100.00%
          [0x000000007f][005]                      {Location}
          [0x000000007f][006]                        {Entry} Stack Offset: -28 (0xffffffffffffffe4) [DW_OP_fbreg]

       The {Range} attribute describe the line ranges for a logical scope.  For  this  case,  the
       function foo is within the lines 2 and 9.

       The  {Coverage}  and  {Location}  attributes  describe the debug location and coverage for
       logical symbols. For optimized code, the coverage  value  decreases  and  it  affects  the
       program debuggability.

EXIT STATUS

       llvm-debuginfo-analyzer returns 0 if the input files were parsed and printed successfully.
       Otherwise, it returns 1.

SEE ALSO

       llvm-dwarfdump

AUTHOR

       Maintained by the LLVM Team (https://llvm.org/).

COPYRIGHT

       2003-2023, LLVM Project