brintos

brintos / llvm-project-archived public Read only

0
0
Text · 72.3 KiB · e039326 Raw
2134 lines · cpp
1//===-- LVScope.cpp -------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This implements the LVScope class.10//11//===----------------------------------------------------------------------===//12 13#include "llvm/DebugInfo/LogicalView/Core/LVScope.h"14#include "llvm/DebugInfo/LogicalView/Core/LVCompare.h"15#include "llvm/DebugInfo/LogicalView/Core/LVLine.h"16#include "llvm/DebugInfo/LogicalView/Core/LVLocation.h"17#include "llvm/DebugInfo/LogicalView/Core/LVRange.h"18#include "llvm/DebugInfo/LogicalView/Core/LVReader.h"19#include "llvm/DebugInfo/LogicalView/Core/LVSymbol.h"20#include "llvm/DebugInfo/LogicalView/Core/LVType.h"21 22using namespace llvm;23using namespace llvm::logicalview;24 25#define DEBUG_TYPE "Scope"26 27namespace {28const char *const KindArray = "Array";29const char *const KindBlock = "Block";30const char *const KindCallSite = "CallSite";31const char *const KindClass = "Class";32const char *const KindCompileUnit = "CompileUnit";33const char *const KindEnumeration = "Enumeration";34const char *const KindFile = "File";35const char *const KindFunction = "Function";36const char *const KindInlinedFunction = "InlinedFunction";37const char *const KindModule = "Module";38const char *const KindNamespace = "Namespace";39const char *const KindStruct = "Struct";40const char *const KindTemplateAlias = "TemplateAlias";41const char *const KindTemplatePack = "TemplatePack";42const char *const KindUndefined = "Undefined";43const char *const KindUnion = "Union";44} // end anonymous namespace45 46//===----------------------------------------------------------------------===//47// DWARF lexical block, such as: namespace, function, compile unit, module, etc.48//===----------------------------------------------------------------------===//49// Return a string representation for the scope kind.50const char *LVScope::kind() const {51  const char *Kind = KindUndefined;52  if (getIsArray())53    Kind = KindArray;54  else if (getIsModule())55    Kind = KindModule;56  else if (getIsBlock())57    Kind = KindBlock;58  else if (getIsCallSite())59    Kind = KindCallSite;60  else if (getIsCompileUnit())61    Kind = KindCompileUnit;62  else if (getIsEnumeration())63    Kind = KindEnumeration;64  else if (getIsInlinedFunction())65    Kind = KindInlinedFunction;66  else if (getIsNamespace())67    Kind = KindNamespace;68  else if (getIsTemplatePack())69    Kind = KindTemplatePack;70  else if (getIsRoot())71    Kind = KindFile;72  else if (getIsTemplateAlias())73    Kind = KindTemplateAlias;74  else if (getIsClass())75    Kind = KindClass;76  else if (getIsFunction())77    Kind = KindFunction;78  else if (getIsStructure())79    Kind = KindStruct;80  else if (getIsUnion())81    Kind = KindUnion;82  return Kind;83}84 85LVScopeDispatch LVScope::Dispatch = {86    {LVScopeKind::IsAggregate, &LVScope::getIsAggregate},87    {LVScopeKind::IsArray, &LVScope::getIsArray},88    {LVScopeKind::IsBlock, &LVScope::getIsBlock},89    {LVScopeKind::IsCallSite, &LVScope::getIsCallSite},90    {LVScopeKind::IsCatchBlock, &LVScope::getIsCatchBlock},91    {LVScopeKind::IsClass, &LVScope::getIsClass},92    {LVScopeKind::IsCompileUnit, &LVScope::getIsCompileUnit},93    {LVScopeKind::IsEntryPoint, &LVScope::getIsEntryPoint},94    {LVScopeKind::IsEnumeration, &LVScope::getIsEnumeration},95    {LVScopeKind::IsFunction, &LVScope::getIsFunction},96    {LVScopeKind::IsFunctionType, &LVScope::getIsFunctionType},97    {LVScopeKind::IsInlinedFunction, &LVScope::getIsInlinedFunction},98    {LVScopeKind::IsLabel, &LVScope::getIsLabel},99    {LVScopeKind::IsLexicalBlock, &LVScope::getIsLexicalBlock},100    {LVScopeKind::IsModule, &LVScope::getIsModule},101    {LVScopeKind::IsNamespace, &LVScope::getIsNamespace},102    {LVScopeKind::IsRoot, &LVScope::getIsRoot},103    {LVScopeKind::IsStructure, &LVScope::getIsStructure},104    {LVScopeKind::IsTemplate, &LVScope::getIsTemplate},105    {LVScopeKind::IsTemplateAlias, &LVScope::getIsTemplateAlias},106    {LVScopeKind::IsTemplatePack, &LVScope::getIsTemplatePack},107    {LVScopeKind::IsTryBlock, &LVScope::getIsTryBlock},108    {LVScopeKind::IsUnion, &LVScope::getIsUnion}};109 110const LVTypes LVScope::EmptyTypes{};111const LVSymbols LVScope::EmptySymbols{};112const LVScopes LVScope::EmptyScopes{};113 114LVElements LVScope::getSortedChildren(LVSortFunction SortFunction) const {115  const auto UnsortedChildren = getChildren();116  LVElements Elements{UnsortedChildren.begin(), UnsortedChildren.end()};117  if (SortFunction)118    llvm::stable_sort(Elements, SortFunction);119  return Elements;120}121 122void LVScope::addElement(LVElement *Element) {123  assert(Element && "Invalid element.");124  if (Element->getIsType())125    addElement(static_cast<LVType *>(Element));126  else if (Element->getIsScope())127    addElement(static_cast<LVScope *>(Element));128  else if (Element->getIsSymbol())129    addElement(static_cast<LVSymbol *>(Element));130  else if (Element->getIsLine())131    addElement(static_cast<LVLine *>(Element));132  else133    llvm_unreachable("Invalid Element.");134}135 136// Adds the line info item to the ones stored in the scope.137void LVScope::addElement(LVLine *Line) {138  assert(Line && "Invalid line.");139  assert(!Line->getParent() && "Line already inserted");140  if (!Lines)141    Lines = std::make_unique<LVLines>();142 143  // Add it to parent.144  Lines->push_back(Line);145  Line->setParent(this);146 147  // Notify the reader about the new element being added.148  getReaderCompileUnit()->addedElement(Line);149 150  // All logical elements added to the children, are sorted by any of the151  // following criterias: offset, name, line number, kind.152  // Do not add the line records to the children, as they represent the153  // logical view for the text section and any sorting will not preserve154  // the original sequence.155 156  // Indicate that this tree branch has lines.157  traverseParents(&LVScope::getHasLines, &LVScope::setHasLines);158}159 160// Add a location.161void LVScope::addObject(LVLocation *Location) {162  assert(Location && "Invalid location.");163  assert(!Location->getParent() && "Location already inserted");164  if (!Ranges)165    Ranges = std::make_unique<LVLocations>();166 167  // Add it to parent.168  Location->setParent(this);169  Location->setOffset(getOffset());170 171  Ranges->push_back(Location);172  setHasRanges();173}174 175// Adds the scope to the child scopes and sets the parent in the child.176void LVScope::addElement(LVScope *Scope) {177  assert(Scope && "Invalid scope.");178  assert(!Scope->getParent() && "Scope already inserted");179  if (!Scopes)180    Scopes = std::make_unique<LVScopes>();181 182  // Add it to parent.183  Scopes->push_back(Scope);184  Scope->setParent(this);185 186  // Notify the reader about the new element being added.187  getReaderCompileUnit()->addedElement(Scope);188 189  // If the element is a global reference, mark its parent as having global190  // references; that information is used, to print only those branches191  // with global references.192  if (Scope->getIsGlobalReference())193    traverseParents(&LVScope::getHasGlobals, &LVScope::setHasGlobals);194  else195    traverseParents(&LVScope::getHasLocals, &LVScope::setHasLocals);196 197  // Indicate that this tree branch has scopes.198  traverseParents(&LVScope::getHasScopes, &LVScope::setHasScopes);199}200 201// Adds a symbol to the ones stored in the scope.202void LVScope::addElement(LVSymbol *Symbol) {203  assert(Symbol && "Invalid symbol.");204  assert(!Symbol->getParent() && "Symbol already inserted");205  if (!Symbols)206    Symbols = std::make_unique<LVSymbols>();207 208  // Add it to parent.209  Symbols->push_back(Symbol);210  Symbol->setParent(this);211 212  // Notify the reader about the new element being added.213  getReaderCompileUnit()->addedElement(Symbol);214 215  // If the element is a global reference, mark its parent as having global216  // references; that information is used, to print only those branches217  // with global references.218  if (Symbol->getIsGlobalReference())219    traverseParents(&LVScope::getHasGlobals, &LVScope::setHasGlobals);220  else221    traverseParents(&LVScope::getHasLocals, &LVScope::setHasLocals);222 223  // Indicate that this tree branch has symbols.224  traverseParents(&LVScope::getHasSymbols, &LVScope::setHasSymbols);225}226 227// Adds a type to the ones stored in the scope.228void LVScope::addElement(LVType *Type) {229  assert(Type && "Invalid type.");230  assert(!Type->getParent() && "Type already inserted");231  if (!Types)232    Types = std::make_unique<LVTypes>();233 234  // Add it to parent.235  Types->push_back(Type);236  Type->setParent(this);237 238  // Notify the reader about the new element being added.239  getReaderCompileUnit()->addedElement(Type);240 241  // If the element is a global reference, mark its parent as having global242  // references; that information is used, to print only those branches243  // with global references.244  if (Type->getIsGlobalReference())245    traverseParents(&LVScope::getHasGlobals, &LVScope::setHasGlobals);246  else247    traverseParents(&LVScope::getHasLocals, &LVScope::setHasLocals);248 249  // Indicate that this tree branch has types.250  traverseParents(&LVScope::getHasTypes, &LVScope::setHasTypes);251}252 253// Add a pair of ranges.254void LVScope::addObject(LVAddress LowerAddress, LVAddress UpperAddress) {255  // Pack the ranges into a Location object.256  LVLocation *Location = getReader().createLocation();257  Location->setLowerAddress(LowerAddress);258  Location->setUpperAddress(UpperAddress);259  Location->setIsAddressRange();260 261  addObject(Location);262}263 264bool LVScope::removeElement(LVElement *Element) {265  auto Predicate = [Element](LVElement *Item) -> bool {266    return Item == Element;267  };268  auto RemoveElement = [Element, Predicate](auto &Container) -> bool {269    auto Iter = llvm::remove_if(*Container, Predicate);270    if (Iter != Container->end()) {271      Container->erase(Iter, Container->end());272      Element->resetParent();273      return true;274    }275    return false;276  };277 278  // As 'children' contains only (scopes, symbols and types), check if the279  // element we are deleting is a line.280  if (Element->getIsLine())281    return RemoveElement(Lines);282 283  if (Element->getIsSymbol())284    return RemoveElement(Symbols);285  if (Element->getIsType())286    return RemoveElement(Types);287  if (Element->getIsScope())288    return RemoveElement(Scopes);289 290  return false;291}292 293void LVScope::addMissingElements(LVScope *Reference) {294  setAddedMissing();295  if (!Reference)296    return;297 298  // Get abstract symbols for the given scope reference.299  const LVSymbols *ReferenceSymbols = Reference->getSymbols();300  if (!ReferenceSymbols)301    return;302 303  LVSymbols References;304  References.append(ReferenceSymbols->begin(), ReferenceSymbols->end());305 306  // Erase abstract symbols already in this scope from the collection of307  // symbols in the referenced scope.308  if (getSymbols())309    for (const LVSymbol *Symbol : *getSymbols())310      if (Symbol->getHasReferenceAbstract())311        llvm::erase(References, Symbol->getReference());312 313  // If we have elements left in 'References', those are the elements that314  // need to be inserted in the current scope.315  if (References.size()) {316    LLVM_DEBUG({317      dbgs() << "Insert Missing Inlined Elements\n"318             << "Offset = " << hexSquareString(getOffset()) << " "319             << "Abstract = " << hexSquareString(Reference->getOffset())320             << "\n";321    });322    for (LVSymbol *Reference : References) {323      LLVM_DEBUG({324        dbgs() << "Missing Offset = " << hexSquareString(Reference->getOffset())325               << "\n";326      });327      // We can't clone the abstract origin reference, as it contain extra328      // information that is incorrect for the element to be inserted.329      // As the symbol being added does not exist in the debug section,330      // use its parent scope offset, to indicate its DIE location.331      LVSymbol *Symbol = getReader().createSymbol();332      addElement(Symbol);333      Symbol->setOffset(getOffset());334      Symbol->setIsOptimized();335      Symbol->setReference(Reference);336 337      // The symbol can be a constant, parameter, variable or unspecified338      // parameters (i.e. `...`).339      if (Reference->getIsConstant())340        Symbol->setIsConstant();341      else if (Reference->getIsParameter())342        Symbol->setIsParameter();343      else if (Reference->getIsVariable())344        Symbol->setIsVariable();345      else if (Reference->getIsUnspecified())346        Symbol->setIsUnspecified();347      else348        llvm_unreachable("Invalid symbol kind.");349    }350  }351}352 353void LVScope::updateLevel(LVScope *Parent, bool Moved) {354  // Update the level for the element itself and all its children, using the355  // given scope parent as reference.356  setLevel(Parent->getLevel() + 1);357 358  // Update the children.359  for (LVElement *Element : getChildren())360    Element->updateLevel(this, Moved);361 362  // Update any lines.363  if (Lines)364    for (LVLine *Line : *Lines)365      Line->updateLevel(this, Moved);366}367 368void LVScope::resolve() {369  if (getIsResolved())370    return;371 372  // Resolve the element itself.373  LVElement::resolve();374 375  // Resolve the children.376  for (LVElement *Element : getChildren()) {377    if (getIsGlobalReference())378      // If the scope is a global reference, mark all its children as well.379      Element->setIsGlobalReference();380    Element->resolve();381  }382}383 384void LVScope::resolveName() {385  if (getIsResolvedName())386    return;387  setIsResolvedName();388 389  // If the scope is a template, resolve the template parameters and get390  // the name for the template with the encoded arguments.391  if (getIsTemplate())392    resolveTemplate();393  else {394    if (LVElement *BaseType = getType()) {395      BaseType->resolveName();396      resolveFullname(BaseType);397    }398  }399 400  // In the case of unnamed scopes, try to generate a name for it, using401  // the parents name and the line information. In the case of compiler402  // generated functions, use its linkage name if is available.403  if (!isNamed()) {404    if (getIsArtificial())405      setName(getLinkageName());406    else407      generateName();408  }409 410  LVElement::resolveName();411 412  // Resolve any given pattern.413  patterns().resolvePatternMatch(this);414}415 416void LVScope::resolveReferences() {417  // The scopes can have the following references to other elements:418  //   A type:419  //     DW_AT_type             ->  Type or Scope420  //     DW_AT_import           ->  Type421  //   A Reference:422  //     DW_AT_specification    ->  Scope423  //     DW_AT_abstract_origin  ->  Scope424  //     DW_AT_extension        ->  Scope425 426  // Resolve any referenced scope.427  LVScope *Reference = getReference();428  if (Reference) {429    Reference->resolve();430    // Recursively resolve the scope names.431    resolveReferencesChain();432  }433 434  // Set the file/line information using the Debug Information entry.435  setFile(Reference);436 437  // Resolve any referenced type or scope.438  if (LVElement *Element = getType())439    Element->resolve();440}441 442void LVScope::resolveElements() {443  // The current element represents the Root. Traverse each Compile Unit.444  if (!Scopes)445    return;446 447  for (LVScope *Scope : *Scopes) {448    LVScopeCompileUnit *CompileUnit = static_cast<LVScopeCompileUnit *>(Scope);449    getReader().setCompileUnit(CompileUnit);450    CompileUnit->resolve();451    // Propagate any matching information into the scopes tree.452    CompileUnit->propagatePatternMatch();453  }454}455 456StringRef LVScope::resolveReferencesChain() {457  // If the scope has a DW_AT_specification or DW_AT_abstract_origin,458  // follow the chain to resolve the name from those references.459  if (getHasReference() && !isNamed())460    setName(getReference()->resolveReferencesChain());461 462  return getName();463}464 465// Get template parameter types.466bool LVScope::getTemplateParameterTypes(LVTypes &Params) {467  // Traverse the scope types and populate the given container with those468  // types that are template parameters; that container will be used by469  // 'encodeTemplateArguments' to resolve them.470  if (const LVTypes *Types = getTypes())471    for (LVType *Type : *Types)472      if (Type->getIsTemplateParam()) {473        Type->resolve();474        Params.push_back(Type);475      }476 477  return !Params.empty();478}479 480// Resolve the template parameters/arguments relationship.481void LVScope::resolveTemplate() {482  if (getIsTemplateResolved())483    return;484  setIsTemplateResolved();485 486  // Check if we need to encode the template arguments.487  if (options().getAttributeEncoded()) {488    LVTypes Params;489    if (getTemplateParameterTypes(Params)) {490      std::string EncodedArgs;491      // Encode the arguments as part of the template name and update the492      // template name, to reflect the encoded parameters.493      encodeTemplateArguments(EncodedArgs, &Params);494      setEncodedArgs(EncodedArgs);495    }496  }497}498 499// Get the qualified name for the template.500void LVScope::getQualifiedName(std::string &QualifiedName) const {501  if (getIsRoot() || getIsCompileUnit())502    return;503 504  if (LVScope *Parent = getParentScope())505    Parent->getQualifiedName(QualifiedName);506  if (!QualifiedName.empty())507    QualifiedName.append("::");508  QualifiedName.append(std::string(getName()));509}510 511// Encode the template arguments as part of the template name.512void LVScope::encodeTemplateArguments(std::string &Name) const {513  // Qualify only when we are expanding parameters that are template514  // instances; the debugger will assume the current scope symbol as515  // the qualifying tag for the symbol being generated, which gives:516  //   namespace std {517  //     ...518  //     set<float,std::less<float>,std::allocator<float>>519  //     ...520  //   }521  // The 'set' symbol is assumed to have the qualified tag 'std'.522 523  // We are resolving a template parameter which is another template. If524  // it is already resolved, just get the qualified name and return.525  std::string BaseName;526  getQualifiedName(BaseName);527  if (getIsTemplateResolved())528    Name.append(BaseName);529}530 531void LVScope::encodeTemplateArguments(std::string &Name,532                                      const LVTypes *Types) const {533  // The encoded string will start with the scope name.534  Name.append("<");535 536  // The list of types are the template parameters.537  if (Types) {538    bool AddComma = false;539    for (const LVType *Type : *Types) {540      if (AddComma)541        Name.append(", ");542      Type->encodeTemplateArgument(Name);543      AddComma = true;544    }545  }546 547  Name.append(">");548}549 550bool LVScope::resolvePrinting() const {551  // The warnings collected during the scope creation as per compile unit.552  // If there is a request for printing warnings, always print its associate553  // Compile Unit.554  if (options().getPrintWarnings() && (getIsRoot() || getIsCompileUnit()))555    return true;556 557  // In selection mode, always print the root scope regardless of the558  // number of matched elements. If no matches, the root by itself will559  // indicate no matches.560  if (options().getSelectExecute()) {561    return getIsRoot() || getIsCompileUnit() || getHasPattern();562  }563 564  bool Globals = options().getAttributeGlobal();565  bool Locals = options().getAttributeLocal();566  if ((Globals && Locals) || (!Globals && !Locals)) {567    // Print both Global and Local.568  } else {569    // Check for Global or Local Objects.570    if ((Globals && !(getHasGlobals() || getIsGlobalReference())) ||571        (Locals && !(getHasLocals() || !getIsGlobalReference())))572      return false;573  }574 575  // For the case of functions, skip it if is compiler generated.576  if (getIsFunction() && getIsArtificial() &&577      !options().getAttributeGenerated())578    return false;579 580  return true;581}582 583Error LVScope::doPrint(bool Split, bool Match, bool Print, raw_ostream &OS,584                       bool Full) const {585  // During a view output splitting, use the output stream created by the586  // split context, then switch to the reader output stream.587  raw_ostream *StreamSplit = &OS;588 589  // Ignore the CU generated by the VS toolchain, when compiling to PDB.590  if (getIsSystem() && !options().getAttributeSystem())591    return Error::success();592 593  // If 'Split', we use the scope name (CU name) as the ouput file; the594  // delimiters in the pathname, must be replaced by a normal character.595  if (getIsCompileUnit()) {596    getReader().setCompileUnit(const_cast<LVScope *>(this));597    if (Split) {598      std::string ScopeName(getName());599      if (std::error_code EC =600              getReaderSplitContext().open(ScopeName, ".txt", OS))601        return createStringError(EC, "Unable to create split output file %s",602                                 ScopeName.c_str());603      StreamSplit = static_cast<raw_ostream *>(&getReaderSplitContext().os());604    }605  }606 607  // Ignore discarded or stripped scopes (functions).608  bool DoPrint = (options().getAttributeDiscarded()) ? true : !getIsDiscarded();609 610  // If we are in compare mode, the only conditions are related to the611  // element being missing. In the case of elements comparison, we print the612  // augmented view, that includes added elements.613  // In print mode, we check other conditions, such as local, global, etc.614  if (DoPrint) {615    DoPrint =616        getIsInCompare() ? options().getReportExecute() : resolvePrinting();617  }618 619  // At this point we have checked for very specific options, to decide if the620  // element will be printed. Include the caller's test for element general621  // print.622  DoPrint = DoPrint && (Print || options().getOutputSplit());623 624  if (DoPrint) {625    // Print the element itself.626    print(*StreamSplit, Full);627 628    // Check if we have reached the requested lexical level specified in the629    // command line options. Input file is level zero and the CU is level 1.630    if ((getIsRoot() || options().getPrintAnyElement()) &&631        options().getPrintFormatting() &&632        getLevel() < options().getOutputLevel()) {633      // Print the children.634      for (const LVElement *Element : getSortedChildren()) {635        if (Match && !Element->getHasPattern())636          continue;637        if (Error Err =638                Element->doPrint(Split, Match, Print, *StreamSplit, Full))639          return Err;640      }641 642      // Print the line records.643      if (Lines)644        for (const LVLine *Line : *Lines) {645          if (Match && !Line->getHasPattern())646            continue;647          if (Error Err =648                  Line->doPrint(Split, Match, Print, *StreamSplit, Full))649            return Err;650        }651 652      // Print the warnings.653      if (options().getPrintWarnings())654        printWarnings(*StreamSplit, Full);655    }656  }657 658  // Done printing the compile unit. Print any requested summary and659  // restore the original output context.660  if (getIsCompileUnit()) {661    if (options().getPrintSummary())662      printSummary(*StreamSplit);663    if (options().getPrintSizes())664      printSizes(*StreamSplit);665    if (Split) {666      getReaderSplitContext().close();667      StreamSplit = &getReader().outputStream();668    }669  }670 671  if (getIsRoot() && options().getPrintWarnings()) {672    getReader().printRecords(*StreamSplit);673  }674 675  return Error::success();676}677 678void LVScope::sort() {679  // Preserve the lines order as they are associated with user code.680  LVSortFunction SortFunction = getSortFunction();681  if (SortFunction) {682    std::function<void(LVScope * Parent, LVSortFunction SortFunction)> Sort =683        [&](LVScope *Parent, LVSortFunction SortFunction) {684          auto Traverse = [&](auto &Set, LVSortFunction SortFunction) {685            if (Set)686              llvm::stable_sort(*Set, SortFunction);687          };688          Traverse(Parent->Types, SortFunction);689          Traverse(Parent->Symbols, SortFunction);690          Traverse(Parent->Scopes, SortFunction);691          Traverse(Parent->Ranges, compareRange);692 693          if (Parent->Scopes)694            for (LVScope *Scope : *Parent->Scopes)695              Sort(Scope, SortFunction);696        };697 698    // Start traversing the scopes root and transform the element name.699    Sort(this, SortFunction);700  }701}702 703void LVScope::traverseParents(LVScopeGetFunction GetFunction,704                              LVScopeSetFunction SetFunction) {705  // Traverse the parent tree.706  LVScope *Parent = this;707  while (Parent) {708    // Terminates if the 'SetFunction' has been already executed.709    if ((Parent->*GetFunction)())710      break;711    (Parent->*SetFunction)();712    Parent = Parent->getParentScope();713  }714}715 716void LVScope::traverseParentsAndChildren(LVObjectGetFunction GetFunction,717                                         LVObjectSetFunction SetFunction) {718  if (options().getReportParents()) {719    // First traverse the parent tree.720    LVScope *Parent = this;721    while (Parent) {722      // Terminates if the 'SetFunction' has been already executed.723      if ((Parent->*GetFunction)())724        break;725      (Parent->*SetFunction)();726      Parent = Parent->getParentScope();727    }728  }729 730  std::function<void(LVScope * Scope)> TraverseChildren = [&](LVScope *Scope) {731    auto Traverse = [&](const auto *Set) {732      if (Set)733        for (const auto &Entry : *Set)734          (Entry->*SetFunction)();735    };736 737    (Scope->*SetFunction)();738 739    Traverse(Scope->getTypes());740    Traverse(Scope->getSymbols());741    Traverse(Scope->getLines());742 743    if (const LVScopes *Scopes = Scope->getScopes())744      for (LVScope *Scope : *Scopes)745        TraverseChildren(Scope);746  };747 748  if (options().getReportChildren())749    TraverseChildren(this);750}751 752// Traverse the symbol location ranges and for each range:753// - Apply the 'ValidLocation' validation criteria.754// - Add any failed range to the 'LocationList'.755// - Calculate location coverage.756void LVScope::getLocations(LVLocations &LocationList,757                           LVValidLocation ValidLocation, bool RecordInvalid) {758  // Traverse scopes and symbols.759  if (Symbols)760    for (LVSymbol *Symbol : *Symbols)761      Symbol->getLocations(LocationList, ValidLocation, RecordInvalid);762  if (Scopes)763    for (LVScope *Scope : *Scopes)764      Scope->getLocations(LocationList, ValidLocation, RecordInvalid);765}766 767// Traverse the scope ranges and for each range:768// - Apply the 'ValidLocation' validation criteria.769// - Add any failed range to the 'LocationList'.770// - Calculate location coverage.771void LVScope::getRanges(LVLocations &LocationList,772                        LVValidLocation ValidLocation, bool RecordInvalid) {773  // Ignore discarded or stripped scopes (functions).774  if (getIsDiscarded())775    return;776 777  // Process the ranges for current scope.778  if (Ranges) {779    for (LVLocation *Location : *Ranges) {780      // Add the invalid location object.781      if (!(Location->*ValidLocation)() && RecordInvalid)782        LocationList.push_back(Location);783    }784 785    // Calculate coverage factor.786    calculateCoverage();787  }788 789  // Traverse the scopes.790  if (Scopes)791    for (LVScope *Scope : *Scopes)792      Scope->getRanges(LocationList, ValidLocation, RecordInvalid);793}794 795// Get all the ranges associated with scopes.796void LVScope::getRanges(LVRange &RangeList) {797  // Ignore discarded or stripped scopes (functions).798  if (getIsDiscarded())799    return;800 801  if (Ranges)802    RangeList.addEntry(this);803  if (Scopes)804    for (LVScope *Scope : *Scopes)805      Scope->getRanges(RangeList);806}807 808LVScope *LVScope::outermostParent(LVAddress Address) {809  LVScope *Parent = this;810  while (Parent) {811    const LVLocations *ParentRanges = Parent->getRanges();812    if (ParentRanges)813      for (const LVLocation *Location : *ParentRanges)814        if (Location->getLowerAddress() <= Address)815          return Parent;816    Parent = Parent->getParentScope();817  }818  return Parent;819}820 821LVScope *LVScope::findIn(const LVScopes *Targets) const {822  if (!Targets)823    return nullptr;824 825  // In the case of overloaded functions, sometimes the DWARF used to826  // describe them, does not give suficient information. Try to find a827  // perfect match or mark them as possible conflicts.828  LVScopes Candidates;829  for (LVScope *Target : *Targets)830    if (LVScope::equals(Target))831      Candidates.push_back(Target);832 833  LLVM_DEBUG({834    if (!Candidates.empty()) {835      dbgs() << "\n[LVScope::findIn]\n"836             << "Reference: "837             << "Offset = " << hexSquareString(getOffset()) << ", "838             << "Level = " << getLevel() << ", "839             << "Kind = " << formattedKind(kind()) << ", "840             << "Name = " << formattedName(getName()) << "\n";841      for (const LVScope *Candidate : Candidates)842        dbgs() << "Candidate: "843               << "Offset = " << hexSquareString(Candidate->getOffset()) << ", "844               << "Level = " << Candidate->getLevel() << ", "845               << "Kind = " << formattedKind(Candidate->kind()) << ", "846               << "Name = " << formattedName(Candidate->getName()) << "\n";847    }848  });849 850  if (!Candidates.empty())851    return (Candidates.size() == 1)852               ? (equals(Candidates[0]) ? Candidates[0] : nullptr)853               : findEqualScope(&Candidates);854 855  return nullptr;856}857 858bool LVScope::equalNumberOfChildren(const LVScope *Scope) const {859  // Same number of children. Take into account which elements are requested860  // to be included in the comparison.861  return !(862      (options().getCompareScopes() && scopeCount() != Scope->scopeCount()) ||863      (options().getCompareSymbols() &&864       symbolCount() != Scope->symbolCount()) ||865      (options().getCompareTypes() && typeCount() != Scope->typeCount()) ||866      (options().getCompareLines() && lineCount() != Scope->lineCount()));867}868 869void LVScope::markMissingParents(const LVScope *Target, bool TraverseChildren) {870  auto SetCompareState = [&](auto &Container) {871    if (Container)872      for (auto *Entry : *Container)873        Entry->setIsInCompare();874  };875  SetCompareState(Types);876  SetCompareState(Symbols);877  SetCompareState(Lines);878  SetCompareState(Scopes);879 880  // At this point, we are ready to start comparing the current scope, once881  // the compare bits have been set.882  if (options().getCompareTypes() && getTypes() && Target->getTypes())883    LVType::markMissingParents(getTypes(), Target->getTypes());884  if (options().getCompareSymbols() && getSymbols() && Target->getSymbols())885    LVSymbol::markMissingParents(getSymbols(), Target->getSymbols());886  if (options().getCompareLines() && getLines() && Target->getLines())887    LVLine::markMissingParents(getLines(), Target->getLines());888  if (getScopes() && Target->getScopes())889    LVScope::markMissingParents(getScopes(), Target->getScopes(),890                                TraverseChildren);891}892 893void LVScope::markMissingParents(const LVScopes *References,894                                 const LVScopes *Targets,895                                 bool TraverseChildren) {896  if (!(References && Targets))897    return;898 899  LLVM_DEBUG({900    dbgs() << "\n[LVScope::markMissingParents]\n";901    for (const LVScope *Reference : *References)902      dbgs() << "References: "903             << "Offset = " << hexSquareString(Reference->getOffset()) << ", "904             << "Level = " << Reference->getLevel() << ", "905             << "Kind = " << formattedKind(Reference->kind()) << ", "906             << "Name = " << formattedName(Reference->getName()) << "\n";907    for (const LVScope *Target : *Targets)908      dbgs() << "Targets   : "909             << "Offset = " << hexSquareString(Target->getOffset()) << ", "910             << "Level = " << Target->getLevel() << ", "911             << "Kind = " << formattedKind(Target->kind()) << ", "912             << "Name = " << formattedName(Target->getName()) << "\n";913  });914 915  for (LVScope *Reference : *References) {916    // Don't process 'Block' scopes, as we can't identify them.917    if (Reference->getIsBlock() || Reference->getIsGeneratedName())918      continue;919 920    LLVM_DEBUG({921      dbgs() << "\nSearch Reference: "922             << "Offset = " << hexSquareString(Reference->getOffset()) << " "923             << "Name = " << formattedName(Reference->getName()) << "\n";924    });925    LVScope *Target = Reference->findIn(Targets);926    if (Target) {927      LLVM_DEBUG({928        dbgs() << "\nFound Target: "929               << "Offset = " << hexSquareString(Target->getOffset()) << " "930               << "Name = " << formattedName(Target->getName()) << "\n";931      });932      if (TraverseChildren)933        Reference->markMissingParents(Target, TraverseChildren);934    } else {935      LLVM_DEBUG({936        dbgs() << "Missing Reference: "937               << "Offset = " << hexSquareString(Reference->getOffset()) << " "938               << "Name = " << formattedName(Reference->getName()) << "\n";939      });940      Reference->markBranchAsMissing();941    }942  }943}944 945bool LVScope::equals(const LVScope *Scope) const {946  if (!LVElement::equals(Scope))947    return false;948  // For lexical scopes, check if their parents are the same.949  if (getIsLexicalBlock() && Scope->getIsLexicalBlock())950    return getParentScope()->equals(Scope->getParentScope());951  return true;952}953 954LVScope *LVScope::findEqualScope(const LVScopes *Scopes) const {955  assert(Scopes && "Scopes must not be nullptr");956  for (LVScope *Scope : *Scopes)957    if (equals(Scope))958      return Scope;959  return nullptr;960}961 962bool LVScope::equals(const LVScopes *References, const LVScopes *Targets) {963  if (!References && !Targets)964    return true;965  if (References && Targets && References->size() == Targets->size()) {966    for (const LVScope *Reference : *References)967      if (!Reference->findIn(Targets))968        return false;969    return true;970  }971  return false;972}973 974void LVScope::report(LVComparePass Pass) {975  getComparator().printItem(this, Pass);976  getComparator().push(this);977  for (LVElement *Element : getSortedChildren())978    Element->report(Pass);979 980  if (Lines)981    for (LVLine *Line : *Lines)982      Line->report(Pass);983  getComparator().pop();984}985 986void LVScope::printActiveRanges(raw_ostream &OS, bool Full) const {987  if (options().getPrintFormatting() && options().getAttributeRange() &&988      Ranges) {989    for (const LVLocation *Location : *Ranges)990      Location->print(OS, Full);991  }992}993 994void LVScope::printEncodedArgs(raw_ostream &OS, bool Full) const {995  if (options().getPrintFormatting() && options().getAttributeEncoded())996    printAttributes(OS, Full, "{Encoded} ", const_cast<LVScope *>(this),997                    getEncodedArgs(), /*UseQuotes=*/false, /*PrintRef=*/false);998}999 1000void LVScope::print(raw_ostream &OS, bool Full) const {1001  if (getIncludeInPrint() && getReader().doPrintScope(this)) {1002    // For a summary (printed elements), do not count the scope root.1003    // For a summary (selected elements) do not count a compile unit.1004    if (!(getIsRoot() || (getIsCompileUnit() && options().getSelectExecute())))1005      getReaderCompileUnit()->incrementPrintedScopes();1006    LVElement::print(OS, Full);1007    printExtra(OS, Full);1008  }1009}1010 1011void LVScope::printExtra(raw_ostream &OS, bool Full) const {1012  OS << formattedKind(kind());1013  // Do not print any type or name for a lexical block.1014  if (!getIsBlock()) {1015    OS << " " << formattedName(getName());1016    if (!getIsAggregate()) {1017      OS << " -> " << typeOffsetAsString()1018         << formattedNames(getTypeQualifiedName(), typeAsString());1019    }1020    if (options().getAttributeSize())1021      if (uint32_t Size = getStorageSizeInBytes())1022        OS << " [Size = " << Size << "]";1023  }1024  OS << "\n";1025 1026  // Print any active ranges.1027  if (Full && getIsBlock())1028    printActiveRanges(OS, Full);1029}1030 1031//===----------------------------------------------------------------------===//1032// DWARF Union/Structure/Class.1033//===----------------------------------------------------------------------===//1034bool LVScopeAggregate::equals(const LVScope *Scope) const {1035  if (!LVScope::equals(Scope))1036    return false;1037 1038  if (!equalNumberOfChildren(Scope))1039    return false;1040 1041  // Check if the parameters match in the case of templates.1042  if (!LVType::parametersMatch(getTypes(), Scope->getTypes()))1043    return false;1044 1045  if (!isNamed() && !Scope->isNamed())1046    // In the case of unnamed union/structure/class compare the file name.1047    if (getFilenameIndex() != Scope->getFilenameIndex())1048      return false;1049 1050  return true;1051}1052 1053LVScope *LVScopeAggregate::findEqualScope(const LVScopes *Scopes) const {1054  assert(Scopes && "Scopes must not be nullptr");1055  for (LVScope *Scope : *Scopes)1056    if (equals(Scope))1057      return Scope;1058  return nullptr;1059}1060 1061void LVScopeAggregate::printExtra(raw_ostream &OS, bool Full) const {1062  LVScope::printExtra(OS, Full);1063  if (Full) {1064    if (getIsTemplateResolved())1065      printEncodedArgs(OS, Full);1066    LVScope *Reference = getReference();1067    if (Reference)1068      Reference->printReference(OS, Full, const_cast<LVScopeAggregate *>(this));1069  }1070}1071 1072//===----------------------------------------------------------------------===//1073// DWARF Template alias.1074//===----------------------------------------------------------------------===//1075bool LVScopeAlias::equals(const LVScope *Scope) const {1076  if (!LVScope::equals(Scope))1077    return false;1078  return equalNumberOfChildren(Scope);1079}1080 1081void LVScopeAlias::printExtra(raw_ostream &OS, bool Full) const {1082  OS << formattedKind(kind()) << " " << formattedName(getName()) << " -> "1083     << typeOffsetAsString()1084     << formattedNames(getTypeQualifiedName(), typeAsString()) << "\n";1085}1086 1087//===----------------------------------------------------------------------===//1088// DWARF array (DW_TAG_array_type).1089//===----------------------------------------------------------------------===//1090void LVScopeArray::resolveExtra() {1091  // If the scope is an array, resolve the subrange entries and get those1092  // values encoded and assigned to the scope type.1093  // Encode the array subrange entries as part of the name.1094  if (getIsArrayResolved())1095    return;1096  setIsArrayResolved();1097 1098  // There are 2 cases to represent the bounds information for an array:1099  // 1) DW_TAG_array_type1100  //      DW_AT_type --> ref_type1101  //      DW_TAG_subrange_type1102  //        DW_AT_type --> ref_type (type of object)1103  //        DW_AT_count --> value (number of elements in subrange)1104 1105  // 2) DW_TAG_array_type1106  //      DW_AT_type --> ref_type1107  //        DW_TAG_subrange_type1108  //          DW_AT_lower_bound --> value1109  //          DW_AT_upper_bound --> value1110 1111  // The idea is to represent the bounds as a string, depending on the format:1112  // 1) [count]1113  // 2) [lower][upper]1114 1115  // Traverse scope types, looking for those types that are subranges.1116  LVTypes Subranges;1117  if (const LVTypes *Types = getTypes())1118    for (LVType *Type : *Types)1119      if (Type->getIsSubrange()) {1120        Type->resolve();1121        Subranges.push_back(Type);1122      }1123 1124  // Use the subrange types to generate the high level name for the array.1125  // Check the type has been fully resolved.1126  if (LVElement *BaseType = getType()) {1127    BaseType->resolveName();1128    resolveFullname(BaseType);1129  }1130 1131  // In 'resolveFullname' a check is done for double spaces in the type name.1132  std::stringstream ArrayInfo;1133  if (ElementType)1134    ArrayInfo << getTypeName().str() << " ";1135 1136  for (const LVType *Type : Subranges) {1137    if (Type->getIsSubrangeCount())1138      // Check if we have DW_AT_count subrange style.1139      ArrayInfo << "[" << Type->getCount() << "]";1140    else {1141      // Get lower and upper subrange values.1142      unsigned LowerBound;1143      unsigned UpperBound;1144      std::tie(LowerBound, UpperBound) = Type->getBounds();1145 1146      // The representation depends on the bound values. If the lower value1147      // is zero, treat the pair as the elements count. Otherwise, just use1148      // the pair, as they are representing arrays in languages other than1149      // C/C++ and the lower limit is not zero.1150      if (LowerBound)1151        ArrayInfo << "[" << LowerBound << ".." << UpperBound << "]";1152      else1153        ArrayInfo << "[" << UpperBound + 1 << "]";1154    }1155  }1156 1157  // Update the scope name, to reflect the encoded subranges.1158  setName(ArrayInfo.str());1159}1160 1161bool LVScopeArray::equals(const LVScope *Scope) const {1162  if (!LVScope::equals(Scope))1163    return false;1164 1165  if (!equalNumberOfChildren(Scope))1166    return false;1167 1168  // Despite the arrays are encoded, to reflect the dimensions, we have to1169  // check the subranges, in order to determine if they are the same.1170  if (!LVType::equals(getTypes(), Scope->getTypes()))1171    return false;1172 1173  return true;1174}1175 1176void LVScopeArray::printExtra(raw_ostream &OS, bool Full) const {1177  OS << formattedKind(kind()) << " " << typeOffsetAsString()1178     << formattedName(getName()) << "\n";1179}1180 1181//===----------------------------------------------------------------------===//1182// An object file (single or multiple CUs).1183//===----------------------------------------------------------------------===//1184void LVScopeCompileUnit::addSize(LVScope *Scope, LVOffset Lower,1185                                 LVOffset Upper) {1186  LLVM_DEBUG({1187    dbgs() << format(1188        "CU [0x%08" PRIx64 "], Scope [0x%08" PRIx64 "], Range [0x%08" PRIx641189        ":0x%08" PRIx64 "], Size = %" PRId64 "\n",1190        getOffset(), Scope->getOffset(), Lower, Upper, Upper - Lower);1191  });1192 1193  // There is no need to check for a previous entry, as we are traversing the1194  // debug information in sequential order.1195  LVOffset Size = Upper - Lower;1196  Sizes[Scope] = Size;1197  if (this == Scope)1198    // Record contribution size for the compilation unit.1199    CUContributionSize = Size;1200}1201 1202// Update parents and children with pattern information.1203void LVScopeCompileUnit::propagatePatternMatch() {1204  // At this stage, we have finished creating the Scopes tree and we have1205  // a list of elements that match the pattern specified in the command line.1206  // The pattern corresponds to a scope or element; mark parents and/or1207  // children as having that pattern, before any printing is done.1208  if (!options().getSelectExecute())1209    return;1210 1211  if (MatchedScopes.size()) {1212    for (LVScope *Scope : MatchedScopes)1213      Scope->traverseParentsAndChildren(&LVScope::getHasPattern,1214                                        &LVScope::setHasPattern);1215  } else {1216    // Mark the compile unit as having a pattern to enable any requests to1217    // print sizes and summary as that information is recorded at that level.1218    setHasPattern();1219  }1220}1221 1222void LVScopeCompileUnit::processRangeLocationCoverage(1223    LVValidLocation ValidLocation) {1224  if (options().getAttributeRange()) {1225    // Traverse the scopes to get scopes that have invalid ranges.1226    LVLocations Locations;1227    bool RecordInvalid = options().getWarningRanges();1228    getRanges(Locations, ValidLocation, RecordInvalid);1229 1230    // Validate ranges associated with scopes.1231    if (RecordInvalid)1232      for (LVLocation *Location : Locations)1233        addInvalidRange(Location);1234  }1235 1236  if (options().getAttributeLocation()) {1237    // Traverse the scopes to get locations that have invalid ranges.1238    LVLocations Locations;1239    bool RecordInvalid = options().getWarningLocations();1240    getLocations(Locations, ValidLocation, RecordInvalid);1241 1242    // Validate ranges associated with locations.1243    if (RecordInvalid)1244      for (LVLocation *Location : Locations)1245        addInvalidLocation(Location);1246  }1247}1248 1249void LVScopeCompileUnit::addMapping(LVLine *Line, LVSectionIndex SectionIndex) {1250  LVAddress Address = Line->getOffset();1251  SectionMappings.add(SectionIndex, Address, Line);1252}1253 1254LVLine *LVScopeCompileUnit::lineLowerBound(LVAddress Address,1255                                           LVScope *Scope) const {1256  LVSectionIndex SectionIndex = getReader().getSectionIndex(Scope);1257  LVAddressToLine *Map = SectionMappings.findMap(SectionIndex);1258  if (!Map || Map->empty())1259    return nullptr;1260  LVAddressToLine::const_iterator Iter = Map->lower_bound(Address);1261  return (Iter != Map->end()) ? Iter->second : nullptr;1262}1263 1264LVLine *LVScopeCompileUnit::lineUpperBound(LVAddress Address,1265                                           LVScope *Scope) const {1266  LVSectionIndex SectionIndex = getReader().getSectionIndex(Scope);1267  LVAddressToLine *Map = SectionMappings.findMap(SectionIndex);1268  if (!Map || Map->empty())1269    return nullptr;1270  LVAddressToLine::const_iterator Iter = Map->upper_bound(Address);1271  if (Iter != Map->begin())1272    Iter = std::prev(Iter);1273  return Iter->second;1274}1275 1276LVLineRange LVScopeCompileUnit::lineRange(LVLocation *Location) const {1277  // The parent of a location can be a symbol or a scope.1278  LVElement *Element = Location->getParent();1279  LVScope *Parent = Element->getIsScope() ? static_cast<LVScope *>(Element)1280                                          : Element->getParentScope();1281  LVLine *LowLine = lineLowerBound(Location->getLowerAddress(), Parent);1282  LVLine *HighLine = lineUpperBound(Location->getUpperAddress(), Parent);1283  return LVLineRange(LowLine, HighLine);1284}1285 1286StringRef LVScopeCompileUnit::getFilename(size_t Index) const {1287  if (Index <= 0 || Index > Filenames.size())1288    return StringRef();1289  return getStringPool().getString(Filenames[Index - 1]);1290}1291 1292bool LVScopeCompileUnit::equals(const LVScope *Scope) const {1293  if (!LVScope::equals(Scope))1294    return false;1295 1296  return getNameIndex() == Scope->getNameIndex();1297}1298 1299void LVScopeCompileUnit::incrementPrintedLines() {1300  options().getSelectExecute() ? ++Found.Lines : ++Printed.Lines;1301}1302void LVScopeCompileUnit::incrementPrintedScopes() {1303  options().getSelectExecute() ? ++Found.Scopes : ++Printed.Scopes;1304}1305void LVScopeCompileUnit::incrementPrintedSymbols() {1306  options().getSelectExecute() ? ++Found.Symbols : ++Printed.Symbols;1307}1308void LVScopeCompileUnit::incrementPrintedTypes() {1309  options().getSelectExecute() ? ++Found.Types : ++Printed.Types;1310}1311 1312// Values are used by '--summary' option (allocated).1313void LVScopeCompileUnit::increment(LVLine *Line) {1314  if (Line->getIncludeInPrint())1315    ++Allocated.Lines;1316}1317void LVScopeCompileUnit::increment(LVScope *Scope) {1318  if (Scope->getIncludeInPrint())1319    ++Allocated.Scopes;1320}1321void LVScopeCompileUnit::increment(LVSymbol *Symbol) {1322  if (Symbol->getIncludeInPrint())1323    ++Allocated.Symbols;1324}1325void LVScopeCompileUnit::increment(LVType *Type) {1326  if (Type->getIncludeInPrint())1327    ++Allocated.Types;1328}1329 1330// A new element has been added to the scopes tree. Take the following steps:1331// Increase the added element counters, for printing summary.1332// During comparison notify the Reader of the new element.1333void LVScopeCompileUnit::addedElement(LVLine *Line) {1334  increment(Line);1335  getReader().notifyAddedElement(Line);1336}1337void LVScopeCompileUnit::addedElement(LVScope *Scope) {1338  increment(Scope);1339  getReader().notifyAddedElement(Scope);1340}1341void LVScopeCompileUnit::addedElement(LVSymbol *Symbol) {1342  increment(Symbol);1343  getReader().notifyAddedElement(Symbol);1344}1345void LVScopeCompileUnit::addedElement(LVType *Type) {1346  increment(Type);1347  getReader().notifyAddedElement(Type);1348}1349 1350// Record unsuported DWARF tags.1351void LVScopeCompileUnit::addDebugTag(dwarf::Tag Target, LVOffset Offset) {1352  addItem<LVTagOffsetsMap, dwarf::Tag, LVOffset>(&DebugTags, Target, Offset);1353}1354 1355// Record elements with invalid offsets.1356void LVScopeCompileUnit::addInvalidOffset(LVOffset Offset, LVElement *Element) {1357  if (WarningOffsets.find(Offset) == WarningOffsets.end())1358    WarningOffsets.emplace(Offset, Element);1359}1360 1361// Record symbols with invalid coverage values.1362void LVScopeCompileUnit::addInvalidCoverage(LVSymbol *Symbol) {1363  LVOffset Offset = Symbol->getOffset();1364  if (InvalidCoverages.find(Offset) == InvalidCoverages.end())1365    InvalidCoverages.emplace(Offset, Symbol);1366}1367 1368// Record symbols with invalid locations.1369void LVScopeCompileUnit::addInvalidLocation(LVLocation *Location) {1370  addInvalidLocationOrRange(Location, Location->getParentSymbol(),1371                            &InvalidLocations);1372}1373 1374// Record scopes with invalid ranges.1375void LVScopeCompileUnit::addInvalidRange(LVLocation *Location) {1376  addInvalidLocationOrRange(Location, Location->getParentScope(),1377                            &InvalidRanges);1378}1379 1380// Record line zero.1381void LVScopeCompileUnit::addLineZero(LVLine *Line) {1382  LVScope *Scope = Line->getParentScope();1383  LVOffset Offset = Scope->getOffset();1384  addInvalidOffset(Offset, Scope);1385  addItem<LVOffsetLinesMap, LVOffset, LVLine *>(&LinesZero, Offset, Line);1386}1387 1388void LVScopeCompileUnit::printLocalNames(raw_ostream &OS, bool Full) const {1389  if (!options().getPrintFormatting())1390    return;1391 1392  // Calculate an indentation value, to preserve a nice layout.1393  size_t Indentation = options().indentationSize() +1394                       lineNumberAsString().length() +1395                       indentAsString(getLevel() + 1).length() + 3;1396 1397  enum class Option { Directory, File };1398  auto PrintNames = [&](Option Action) {1399    StringRef Kind = Action == Option::Directory ? "Directory" : "File";1400    std::set<std::string> UniqueNames;1401    for (size_t Index : Filenames) {1402      // In the case of missing directory name in the .debug_line table,1403      // the returned string has a leading '/'.1404      StringRef Name = getStringPool().getString(Index);1405      size_t Pos = Name.rfind('/');1406      if (Pos != std::string::npos)1407        Name = (Action == Option::File) ? Name.substr(Pos + 1)1408                                        : Name.substr(0, Pos);1409      // Collect only unique names.1410      UniqueNames.insert(std::string(Name));1411    }1412    for (const std::string &Name : UniqueNames)1413      OS << std::string(Indentation, ' ') << formattedKind(Kind) << " "1414         << formattedName(Name) << "\n";1415  };1416 1417  if (options().getAttributeDirectories())1418    PrintNames(Option::Directory);1419  if (options().getAttributeFiles())1420    PrintNames(Option::File);1421  if (options().getAttributePublics()) {1422    StringRef Kind = "Public";1423    // The public names are indexed by 'LVScope *'. We want to print1424    // them by logical element address, to show the scopes layout.1425    using OffsetSorted = std::map<LVAddress, LVPublicNames::const_iterator>;1426    OffsetSorted SortedNames;1427    for (LVPublicNames::const_iterator Iter = PublicNames.begin();1428         Iter != PublicNames.end(); ++Iter)1429      SortedNames.emplace(Iter->first->getOffset(), Iter);1430 1431    LVPublicNames::const_iterator Iter;1432    for (OffsetSorted::reference Entry : SortedNames) {1433      Iter = Entry.second;1434      OS << std::string(Indentation, ' ') << formattedKind(Kind) << " "1435         << formattedName((*Iter).first->getName());1436      if (options().getAttributeOffset()) {1437        LVAddress Address = (*Iter).second.first;1438        size_t Size = (*Iter).second.second;1439        OS << " [" << hexString(Address) << ":" << hexString(Address + Size)1440           << "]";1441      }1442      OS << "\n";1443    }1444  }1445}1446 1447void LVScopeCompileUnit::printWarnings(raw_ostream &OS, bool Full) const {1448  auto PrintHeader = [&](const char *Header) { OS << "\n" << Header << ":\n"; };1449  auto PrintFooter = [&](auto &Set) {1450    if (Set.empty())1451      OS << "None\n";1452  };1453  auto PrintOffset = [&](unsigned &Count, LVOffset Offset) {1454    if (Count == 5) {1455      Count = 0;1456      OS << "\n";1457    }1458    ++Count;1459    OS << hexSquareString(Offset) << " ";1460  };1461  auto PrintElement = [&](const LVOffsetElementMap &Map, LVOffset Offset) {1462    LVOffsetElementMap::const_iterator Iter = Map.find(Offset);1463    LVElement *Element = Iter != Map.end() ? Iter->second : nullptr;1464    OS << "[" << hexString(Offset) << "]";1465    if (Element)1466      OS << " " << formattedKind(Element->kind()) << " "1467         << formattedName(Element->getName());1468    OS << "\n";1469  };1470  auto PrintInvalidLocations = [&](const LVOffsetLocationsMap &Map,1471                                   const char *Header) {1472    PrintHeader(Header);1473    for (LVOffsetLocationsMap::const_reference Entry : Map) {1474      PrintElement(WarningOffsets, Entry.first);1475      for (const LVLocation *Location : Entry.second)1476        OS << hexSquareString(Location->getOffset()) << " "1477           << Location->getIntervalInfo() << "\n";1478    }1479    PrintFooter(Map);1480  };1481 1482  if (options().getInternalTag() && getReader().isBinaryTypeELF()) {1483    PrintHeader("Unsupported DWARF Tags");1484    for (LVTagOffsetsMap::const_reference Entry : DebugTags) {1485      OS << format("\n0x%02x", (unsigned)Entry.first) << ", "1486         << dwarf::TagString(Entry.first) << "\n";1487      unsigned Count = 0;1488      for (const LVOffset &Offset : Entry.second)1489        PrintOffset(Count, Offset);1490      OS << "\n";1491    }1492    PrintFooter(DebugTags);1493  }1494 1495  if (options().getWarningCoverages()) {1496    PrintHeader("Symbols Invalid Coverages");1497    for (LVOffsetSymbolMap::const_reference Entry : InvalidCoverages) {1498      // Symbol basic information.1499      LVSymbol *Symbol = Entry.second;1500      OS << hexSquareString(Entry.first) << " {Coverage} "1501         << format("%.2f%%", Symbol->getCoveragePercentage()) << " "1502         << formattedKind(Symbol->kind()) << " "1503         << formattedName(Symbol->getName()) << "\n";1504    }1505    PrintFooter(InvalidCoverages);1506  }1507 1508  if (options().getWarningLines()) {1509    PrintHeader("Lines Zero References");1510    for (LVOffsetLinesMap::const_reference Entry : LinesZero) {1511      PrintElement(WarningOffsets, Entry.first);1512      unsigned Count = 0;1513      for (const LVLine *Line : Entry.second)1514        PrintOffset(Count, Line->getOffset());1515      OS << "\n";1516    }1517    PrintFooter(LinesZero);1518  }1519 1520  if (options().getWarningLocations())1521    PrintInvalidLocations(InvalidLocations, "Invalid Location Ranges");1522 1523  if (options().getWarningRanges())1524    PrintInvalidLocations(InvalidRanges, "Invalid Code Ranges");1525}1526 1527void LVScopeCompileUnit::printTotals(raw_ostream &OS) const {1528  OS << "\nTotals by lexical level:\n";1529  for (size_t Index = 1; Index <= MaxSeenLevel; ++Index)1530    OS << format("[%03d]: %10d (%6.2f%%)\n", Index, Totals[Index].first,1531                 Totals[Index].second);1532}1533 1534void LVScopeCompileUnit::printScopeSize(const LVScope *Scope, raw_ostream &OS) {1535  LVSizesMap::const_iterator Iter = Sizes.find(Scope);1536  if (Iter != Sizes.end()) {1537    LVOffset Size = Iter->second;1538    assert(CUContributionSize && "Invalid CU contribution size.");1539    // Get a percentage rounded to two decimal digits. This avoids1540    // implementation-defined rounding inside printing functions.1541    float Percentage =1542        rint((float(Size) / CUContributionSize) * 100.0 * 100.0) / 100.0;1543    OS << format("%10" PRId64 " (%6.2f%%) : ", Size, Percentage);1544    Scope->print(OS);1545 1546    // Keep record of the total sizes at each lexical level.1547    LVLevel Level = Scope->getLevel();1548    if (Level > MaxSeenLevel)1549      MaxSeenLevel = Level;1550    if (Level >= Totals.size())1551      Totals.resize(2 * Level);1552    Totals[Level].first += Size;1553    Totals[Level].second += Percentage;1554  }1555}1556 1557void LVScopeCompileUnit::printSizes(raw_ostream &OS) const {1558  // Recursively print the contributions for each scope.1559  std::function<void(const LVScope *Scope)> PrintScope =1560      [&](const LVScope *Scope) {1561        // If we have selection criteria, then use only the selected scopes.1562        if (options().getSelectExecute() && options().getReportAnyView()) {1563          for (const LVScope *Scope : MatchedScopes)1564            if (Scope->getLevel() < options().getOutputLevel())1565              printScopeSize(Scope, OS);1566          return;1567        }1568        if (Scope->getLevel() < options().getOutputLevel()) {1569          if (const LVScopes *Scopes = Scope->getScopes())1570            for (const LVScope *Scope : *Scopes) {1571              printScopeSize(Scope, OS);1572              PrintScope(Scope);1573            }1574        }1575      };1576 1577  bool PrintScopes = options().getPrintScopes();1578  if (!PrintScopes)1579    options().setPrintScopes();1580  getReader().setCompileUnit(const_cast<LVScopeCompileUnit *>(this));1581 1582  OS << "\nScope Sizes:\n";1583  options().resetPrintFormatting();1584  options().setPrintOffset();1585 1586  // Print the scopes regardless if the user has requested any scopes1587  // printing. Set the option just to allow printing the contributions.1588  printScopeSize(this, OS);1589  PrintScope(this);1590 1591  // Print total scope sizes by level.1592  printTotals(OS);1593 1594  options().resetPrintOffset();1595  options().setPrintFormatting();1596 1597  if (!PrintScopes)1598    options().resetPrintScopes();1599}1600 1601void LVScopeCompileUnit::printSummary(raw_ostream &OS) const {1602  printSummary(OS, options().getSelectExecute() ? Found : Printed, "Printed");1603}1604 1605// Print summary details for the scopes tree.1606void LVScopeCompileUnit::printSummary(raw_ostream &OS, const LVCounter &Counter,1607                                      const char *Header) const {1608  std::string Separator = std::string(29, '-');1609  auto PrintSeparator = [&]() { OS << Separator << "\n"; };1610  auto PrintHeadingRow = [&](const char *T, const char *U, const char *V) {1611    OS << format("%-9s%9s  %9s\n", T, U, V);1612  };1613  auto PrintDataRow = [&](const char *T, unsigned U, unsigned V) {1614    OS << format("%-9s%9d  %9d\n", T, U, V);1615  };1616 1617  OS << "\n";1618  PrintSeparator();1619  PrintHeadingRow("Element", "Total", Header);1620  PrintSeparator();1621  PrintDataRow("Scopes", Allocated.Scopes, Counter.Scopes);1622  PrintDataRow("Symbols", Allocated.Symbols, Counter.Symbols);1623  PrintDataRow("Types", Allocated.Types, Counter.Types);1624  PrintDataRow("Lines", Allocated.Lines, Counter.Lines);1625  PrintSeparator();1626  PrintDataRow(1627      "Total",1628      Allocated.Scopes + Allocated.Symbols + Allocated.Lines + Allocated.Types,1629      Counter.Scopes + Counter.Symbols + Counter.Lines + Counter.Types);1630}1631 1632void LVScopeCompileUnit::printMatchedElements(raw_ostream &OS,1633                                              bool UseMatchedElements) {1634  LVSortFunction SortFunction = getSortFunction();1635  if (SortFunction)1636    llvm::stable_sort(MatchedElements, SortFunction);1637 1638  // Check the type of elements required to be printed. 'MatchedElements'1639  // contains generic elements (lines, scopes, symbols, types). If we have a1640  // request to print any generic element, then allow the normal printing.1641  if (options().getPrintAnyElement()) {1642    if (UseMatchedElements)1643      OS << "\n";1644    print(OS);1645 1646    if (UseMatchedElements) {1647      // Print the details for the matched elements.1648      for (const LVElement *Element : MatchedElements)1649        Element->print(OS);1650    } else {1651      // Print the view for the matched scopes.1652      for (const LVScope *Scope : MatchedScopes) {1653        Scope->print(OS);1654        for (LVElement *Element : Scope->getSortedChildren())1655          Element->print(OS);1656      }1657    }1658 1659    // Print any requested summary.1660    if (options().getPrintSummary()) {1661      // In the case of '--report=details' the matched elements are1662      // already counted; just proceed to print any requested summary.1663      // Otherwise, count them and print the summary.1664      if (!options().getReportList()) {1665        for (LVElement *Element : MatchedElements) {1666          if (!Element->getIncludeInPrint())1667            continue;1668          if (Element->getIsType())1669            ++Found.Types;1670          else if (Element->getIsSymbol())1671            ++Found.Symbols;1672          else if (Element->getIsScope())1673            ++Found.Scopes;1674          else if (Element->getIsLine())1675            ++Found.Lines;1676          else1677            assert(Element && "Invalid element.");1678        }1679      }1680      printSummary(OS, Found, "Printed");1681    }1682  }1683 1684  // Check if we have a request to print sizes for the matched elements1685  // that are scopes.1686  if (options().getPrintSizes()) {1687    OS << "\n";1688    print(OS);1689 1690    OS << "\nScope Sizes:\n";1691    printScopeSize(this, OS);1692    for (LVElement *Element : MatchedElements)1693      if (Element->getIsScope())1694        // Print sizes only for scopes.1695        printScopeSize(static_cast<LVScope *>(Element), OS);1696 1697    printTotals(OS);1698  }1699}1700 1701void LVScopeCompileUnit::print(raw_ostream &OS, bool Full) const {1702  // Reset counters for printed and found elements.1703  const_cast<LVScopeCompileUnit *>(this)->Found.reset();1704  const_cast<LVScopeCompileUnit *>(this)->Printed.reset();1705 1706  if (getReader().doPrintScope(this) && options().getPrintFormatting())1707    OS << "\n";1708 1709  LVScope::print(OS, Full);1710}1711 1712void LVScopeCompileUnit::printExtra(raw_ostream &OS, bool Full) const {1713  OS << formattedKind(kind()) << " '" << getName() << "'\n";1714  if (options().getPrintFormatting()) {1715    if (options().getAttributeProducer())1716      printAttributes(OS, Full, "{Producer} ",1717                      const_cast<LVScopeCompileUnit *>(this), getProducer(),1718                      /*UseQuotes=*/true,1719                      /*PrintRef=*/false);1720    if (options().getAttributeLanguage())1721      if (auto SL = getSourceLanguage(); SL.isValid())1722        printAttributes(OS, Full, "{Language} ",1723                        const_cast<LVScopeCompileUnit *>(this), SL.getName(),1724                        /*UseQuotes=*/true,1725                        /*PrintRef=*/false);1726  }1727 1728  // Reset file index, to allow its children to print the correct filename.1729  options().resetFilenameIndex();1730 1731  // Print any files, directories, public names and active ranges.1732  if (Full) {1733    printLocalNames(OS, Full);1734    printActiveRanges(OS, Full);1735  }1736}1737 1738//===----------------------------------------------------------------------===//1739// DWARF enumeration (DW_TAG_enumeration_type).1740//===----------------------------------------------------------------------===//1741bool LVScopeEnumeration::equals(const LVScope *Scope) const {1742  if (!LVScope::equals(Scope))1743    return false;1744  return equalNumberOfChildren(Scope);1745}1746 1747void LVScopeEnumeration::printExtra(raw_ostream &OS, bool Full) const {1748  // Print the full type name.1749  OS << formattedKind(kind()) << " " << (getIsEnumClass() ? "class " : "")1750     << formattedName(getName());1751  if (getHasType())1752    OS << " -> " << typeOffsetAsString()1753       << formattedNames(getTypeQualifiedName(), typeAsString());1754  OS << "\n";1755}1756 1757//===----------------------------------------------------------------------===//1758// DWARF formal parameter pack (DW_TAG_GNU_formal_parameter_pack).1759//===----------------------------------------------------------------------===//1760bool LVScopeFormalPack::equals(const LVScope *Scope) const {1761  if (!LVScope::equals(Scope))1762    return false;1763  return equalNumberOfChildren(Scope);1764}1765 1766void LVScopeFormalPack::printExtra(raw_ostream &OS, bool Full) const {1767  OS << formattedKind(kind()) << " " << formattedName(getName()) << "\n";1768}1769 1770//===----------------------------------------------------------------------===//1771// DWARF function.1772//===----------------------------------------------------------------------===//1773void LVScopeFunction::resolveReferences() {1774  // Before we resolve any references to other elements, check if we have1775  // to insert missing elements, that have been stripped, which will help1776  // the logical view comparison.1777  if (options().getAttributeInserted() && getHasReferenceAbstract() &&1778      !getAddedMissing()) {1779    // Add missing elements at the function scope.1780    addMissingElements(getReference());1781    if (Scopes)1782      for (LVScope *Scope : *Scopes)1783        if (Scope->getHasReferenceAbstract() && !Scope->getAddedMissing())1784          Scope->addMissingElements(Scope->getReference());1785  }1786 1787  LVScope::resolveReferences();1788 1789  // The DWARF 'extern' attribute is generated at the class level.1790  // 0000003f DW_TAG_class_type "CLASS"1791  //   00000048 DW_TAG_subprogram "bar"1792  //	            DW_AT_external DW_FORM_flag_present1793  // 00000070 DW_TAG_subprogram "bar"1794  //   DW_AT_specification DW_FORM_ref4 0x000000481795  // CodeView does not include any information at the class level to1796  // mark the member function as external.1797  // If there is a reference linking the declaration and definition, mark1798  // the definition as extern, to facilitate the logical view comparison.1799  if (getHasReferenceSpecification()) {1800    LVScope *Reference = getReference();1801    if (Reference && Reference->getIsExternal()) {1802      Reference->resetIsExternal();1803      setIsExternal();1804    }1805  }1806 1807  // Resolve the function associated type.1808  if (!getType())1809    if (LVScope *Reference = getReference())1810      setType(Reference->getType());1811}1812 1813void LVScopeFunction::setName(StringRef ObjectName) {1814  LVScope::setName(ObjectName);1815  // Check for system generated functions.1816  getReader().isSystemEntry(this, ObjectName);1817}1818 1819void LVScopeFunction::resolveExtra() {1820  // Check if we need to encode the template arguments.1821  if (getIsTemplate())1822    resolveTemplate();1823}1824 1825bool LVScopeFunction::equals(const LVScope *Scope) const {1826  if (!LVScope::equals(Scope))1827    return false;1828 1829  // When comparing logical elements, ignore any difference in the children.1830  if (options().getCompareContext() && !equalNumberOfChildren(Scope))1831    return false;1832 1833  // Check if the linkage name matches.1834  if (getLinkageNameIndex() != Scope->getLinkageNameIndex())1835    return false;1836 1837  // Check if the parameters match in the case of templates.1838  if (!LVType::parametersMatch(getTypes(), Scope->getTypes()))1839    return false;1840 1841  // Check if the arguments match.1842  if (!LVSymbol::parametersMatch(getSymbols(), Scope->getSymbols()))1843    return false;1844 1845  // Check if the lines match.1846  if (options().getCompareLines() &&1847      !LVLine::equals(getLines(), Scope->getLines()))1848    return false;1849 1850  // Check if any reference is the same.1851  if (!referenceMatch(Scope))1852    return false;1853 1854  if (getReference() && !getReference()->equals(Scope->getReference()))1855    return false;1856 1857  return true;1858}1859 1860LVScope *LVScopeFunction::findEqualScope(const LVScopes *Scopes) const {1861  assert(Scopes && "Scopes must not be nullptr");1862  // Go through candidates and try to find a best match.1863  for (LVScope *Scope : *Scopes)1864    // Match arguments, children, lines, references.1865    if (equals(Scope))1866      return Scope;1867  return nullptr;1868}1869 1870void LVScopeFunction::printExtra(raw_ostream &OS, bool Full) const {1871  LVScope *Reference = getReference();1872 1873  // Inline attributes based on the reference element.1874  uint32_t InlineCode =1875      Reference ? Reference->getInlineCode() : getInlineCode();1876 1877  // Accessibility depends on the parent (class, structure).1878  uint32_t AccessCode = 0;1879  if (getIsMember())1880    AccessCode = getParentScope()->getIsClass() ? dwarf::DW_ACCESS_private1881                                                : dwarf::DW_ACCESS_public;1882 1883  std::string Attributes =1884      getIsCallSite()1885          ? ""1886          : formatAttributes(externalString(), accessibilityString(AccessCode),1887                             inlineCodeString(InlineCode), virtualityString());1888 1889  OS << formattedKind(kind()) << " " << Attributes << formattedName(getName())1890     << discriminatorAsString() << " -> " << typeOffsetAsString()1891     << formattedNames(getTypeQualifiedName(), typeAsString()) << "\n";1892 1893  // Print any active ranges.1894  if (Full) {1895    if (getIsTemplateResolved())1896      printEncodedArgs(OS, Full);1897    printActiveRanges(OS, Full);1898    if (getLinkageNameIndex())1899      printLinkageName(OS, Full, const_cast<LVScopeFunction *>(this),1900                       const_cast<LVScopeFunction *>(this));1901    if (Reference)1902      Reference->printReference(OS, Full, const_cast<LVScopeFunction *>(this));1903  }1904}1905 1906//===----------------------------------------------------------------------===//1907// DWARF inlined function (DW_TAG_inlined_function).1908//===----------------------------------------------------------------------===//1909void LVScopeFunctionInlined::resolveExtra() {1910  // Check if we need to encode the template arguments.1911  if (getIsTemplate())1912    resolveTemplate();1913}1914 1915bool LVScopeFunctionInlined::equals(const LVScope *Scope) const {1916  if (!LVScopeFunction::equals(Scope))1917    return false;1918 1919  // Check if any reference is the same.1920  if (getHasDiscriminator() && Scope->getHasDiscriminator())1921    if (getDiscriminator() != Scope->getDiscriminator())1922      return false;1923 1924  // Check the call site information.1925  if (getCallFilenameIndex() != Scope->getCallFilenameIndex() ||1926      getCallLineNumber() != Scope->getCallLineNumber())1927    return false;1928 1929  return true;1930}1931 1932LVScope *LVScopeFunctionInlined::findEqualScope(const LVScopes *Scopes) const {1933  return LVScopeFunction::findEqualScope(Scopes);1934}1935 1936void LVScopeFunctionInlined::printExtra(raw_ostream &OS, bool Full) const {1937  LVScopeFunction::printExtra(OS, Full);1938}1939 1940//===----------------------------------------------------------------------===//1941// DWARF subroutine type.1942//===----------------------------------------------------------------------===//1943// Resolve a Subroutine Type (Callback).1944void LVScopeFunctionType::resolveExtra() {1945  if (getIsMemberPointerResolved())1946    return;1947  setIsMemberPointerResolved();1948 1949  // The encoded string has the return type and the formal parameters type.1950  std::string Name(typeAsString());1951  Name.append(" (*)");1952  Name.append("(");1953 1954  // Traverse the scope symbols, looking for those which are parameters.1955  if (const LVSymbols *Symbols = getSymbols()) {1956    bool AddComma = false;1957    for (LVSymbol *Symbol : *Symbols)1958      if (Symbol->getIsParameter()) {1959        Symbol->resolve();1960        if (LVElement *Type = Symbol->getType())1961          Type->resolveName();1962        if (AddComma)1963          Name.append(", ");1964        Name.append(std::string(Symbol->getTypeName()));1965        AddComma = true;1966      }1967  }1968 1969  Name.append(")");1970 1971  // Update the scope name, to reflect the encoded parameters.1972  setName(Name);1973}1974 1975//===----------------------------------------------------------------------===//1976// DWARF module (DW_TAG_module).1977//===----------------------------------------------------------------------===//1978bool LVScopeModule::equals(const LVScope *Scope) const {1979  // For lexical blocks, LVScope::equals() compares the parent scope.1980  return LVScope::equals(Scope) && (Scope->getName() == getName());1981}1982 1983void LVScopeModule::printExtra(raw_ostream &OS, bool Full) const {1984  OS << formattedKind(kind()) << " " << formattedName(getName()) << "\n";1985}1986 1987//===----------------------------------------------------------------------===//1988// DWARF namespace (DW_TAG_namespace).1989//===----------------------------------------------------------------------===//1990bool LVScopeNamespace::equals(const LVScope *Scope) const {1991  if (!LVScope::equals(Scope))1992    return false;1993 1994  if (!equalNumberOfChildren(Scope))1995    return false;1996 1997  // Check if any reference is the same.1998  if (!referenceMatch(Scope))1999    return false;2000 2001  if (getReference() && !getReference()->equals(Scope->getReference()))2002    return false;2003 2004  return true;2005}2006 2007LVScope *LVScopeNamespace::findEqualScope(const LVScopes *Scopes) const {2008  assert(Scopes && "Scopes must not be nullptr");2009  // Go through candidates and try to find a best match.2010  for (LVScope *Scope : *Scopes)2011    if (equals(Scope))2012      return Scope;2013  return nullptr;2014}2015 2016void LVScopeNamespace::printExtra(raw_ostream &OS, bool Full) const {2017  OS << formattedKind(kind()) << " " << formattedName(getName()) << "\n";2018 2019  // Print any active ranges.2020  if (Full) {2021    printActiveRanges(OS, Full);2022 2023    if (LVScope *Reference = getReference())2024      Reference->printReference(OS, Full, const_cast<LVScopeNamespace *>(this));2025  }2026}2027 2028//===----------------------------------------------------------------------===//2029// An object file (single or multiple CUs).2030//===----------------------------------------------------------------------===//2031void LVScopeRoot::processRangeInformation() {2032  if (!options().getAttributeAnyLocation())2033    return;2034 2035  if (Scopes)2036    for (LVScope *Scope : *Scopes) {2037      LVScopeCompileUnit *CompileUnit =2038          static_cast<LVScopeCompileUnit *>(Scope);2039      getReader().setCompileUnit(CompileUnit);2040      CompileUnit->processRangeLocationCoverage();2041    }2042}2043 2044void LVScopeRoot::transformScopedName() {2045  // Recursively transform all names.2046  std::function<void(LVScope * Parent)> TraverseScope = [&](LVScope *Parent) {2047    auto Traverse = [&](const auto *Set) {2048      if (Set)2049        for (const auto &Entry : *Set)2050          Entry->setInnerComponent();2051    };2052    if (const LVScopes *Scopes = Parent->getScopes())2053      for (LVScope *Scope : *Scopes) {2054        Scope->setInnerComponent();2055        TraverseScope(Scope);2056      }2057    Traverse(Parent->getSymbols());2058    Traverse(Parent->getTypes());2059    Traverse(Parent->getLines());2060  };2061 2062  // Start traversing the scopes root and transform the element name.2063  TraverseScope(this);2064}2065 2066bool LVScopeRoot::equals(const LVScope *Scope) const {2067  return LVScope::equals(Scope);2068}2069 2070void LVScopeRoot::print(raw_ostream &OS, bool Full) const {2071  OS << "\nLogical View:\n";2072  LVScope::print(OS, Full);2073}2074 2075void LVScopeRoot::printExtra(raw_ostream &OS, bool Full) const {2076  OS << formattedKind(kind()) << " " << formattedName(getName()) << "";2077  if (options().getAttributeFormat())2078    OS << " -> " << getFileFormatName();2079  OS << "\n";2080}2081 2082Error LVScopeRoot::doPrintMatches(bool Split, raw_ostream &OS,2083                                  bool UseMatchedElements) const {2084  // During a view output splitting, use the output stream created by the2085  // split context, then switch to the reader output stream.2086  static raw_ostream *StreamSplit = &OS;2087 2088  if (Scopes) {2089    if (UseMatchedElements)2090      options().resetPrintFormatting();2091    print(OS);2092 2093    for (LVScope *Scope : *Scopes) {2094      getReader().setCompileUnit(Scope);2095 2096      // If 'Split', we use the scope name (CU name) as the ouput file; the2097      // delimiters in the pathname, must be replaced by a normal character.2098      if (Split) {2099        std::string ScopeName(Scope->getName());2100        if (std::error_code EC =2101                getReaderSplitContext().open(ScopeName, ".txt", OS))2102          return createStringError(EC, "Unable to create split output file %s",2103                                   ScopeName.c_str());2104        StreamSplit = static_cast<raw_ostream *>(&getReaderSplitContext().os());2105      }2106 2107      Scope->printMatchedElements(*StreamSplit, UseMatchedElements);2108 2109      // Done printing the compile unit. Restore the original output context.2110      if (Split) {2111        getReaderSplitContext().close();2112        StreamSplit = &getReader().outputStream();2113      }2114    }2115    if (UseMatchedElements)2116      options().setPrintFormatting();2117  }2118 2119  return Error::success();2120}2121 2122//===----------------------------------------------------------------------===//2123// DWARF template parameter pack (DW_TAG_GNU_template_parameter_pack).2124//===----------------------------------------------------------------------===//2125bool LVScopeTemplatePack::equals(const LVScope *Scope) const {2126  if (!LVScope::equals(Scope))2127    return false;2128  return equalNumberOfChildren(Scope);2129}2130 2131void LVScopeTemplatePack::printExtra(raw_ostream &OS, bool Full) const {2132  OS << formattedKind(kind()) << " " << formattedName(getName()) << "\n";2133}2134