diff options
Diffstat (limited to 'lib/IR/DebugInfoMetadata.cpp')
| -rw-r--r-- | lib/IR/DebugInfoMetadata.cpp | 225 | 
1 files changed, 176 insertions, 49 deletions
diff --git a/lib/IR/DebugInfoMetadata.cpp b/lib/IR/DebugInfoMetadata.cpp index 910e8c2fb74fd..92f3f21f754c9 100644 --- a/lib/IR/DebugInfoMetadata.cpp +++ b/lib/IR/DebugInfoMetadata.cpp @@ -14,16 +14,19 @@  #include "llvm/IR/DebugInfoMetadata.h"  #include "LLVMContextImpl.h"  #include "MetadataImpl.h" -#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/SmallSet.h"  #include "llvm/ADT/StringSwitch.h"  #include "llvm/IR/DIBuilder.h"  #include "llvm/IR/Function.h"  #include "llvm/IR/Instructions.h" +#include <numeric> +  using namespace llvm;  DILocation::DILocation(LLVMContext &C, StorageType Storage, unsigned Line, -                       unsigned Column, ArrayRef<Metadata *> MDs) +                       unsigned Column, ArrayRef<Metadata *> MDs, +                       bool ImplicitCode)      : MDNode(C, DILocationKind, Storage, MDs) {    assert((MDs.size() == 1 || MDs.size() == 2) &&           "Expected a scope and optional inlined-at"); @@ -33,6 +36,8 @@ DILocation::DILocation(LLVMContext &C, StorageType Storage, unsigned Line,    SubclassData32 = Line;    SubclassData16 = Column; + +  setImplicitCode(ImplicitCode);  }  static void adjustColumn(unsigned &Column) { @@ -43,15 +48,15 @@ static void adjustColumn(unsigned &Column) {  DILocation *DILocation::getImpl(LLVMContext &Context, unsigned Line,                                  unsigned Column, Metadata *Scope, -                                Metadata *InlinedAt, StorageType Storage, -                                bool ShouldCreate) { +                                Metadata *InlinedAt, bool ImplicitCode, +                                StorageType Storage, bool ShouldCreate) {    // Fixup column.    adjustColumn(Column);    if (Storage == Uniqued) { -    if (auto *N = -            getUniqued(Context.pImpl->DILocations, -                       DILocationInfo::KeyTy(Line, Column, Scope, InlinedAt))) +    if (auto *N = getUniqued(Context.pImpl->DILocations, +                             DILocationInfo::KeyTy(Line, Column, Scope, +                                                   InlinedAt, ImplicitCode)))        return N;      if (!ShouldCreate)        return nullptr; @@ -63,36 +68,94 @@ DILocation *DILocation::getImpl(LLVMContext &Context, unsigned Line,    Ops.push_back(Scope);    if (InlinedAt)      Ops.push_back(InlinedAt); -  return storeImpl(new (Ops.size()) -                       DILocation(Context, Storage, Line, Column, Ops), +  return storeImpl(new (Ops.size()) DILocation(Context, Storage, Line, Column, +                                               Ops, ImplicitCode),                     Storage, Context.pImpl->DILocations);  }  const DILocation *DILocation::getMergedLocation(const DILocation *LocA, -                                                const DILocation *LocB, -                                                bool GenerateLocation) { +                                                const DILocation *LocB) {    if (!LocA || !LocB)      return nullptr; -  if (LocA == LocB || !LocA->canDiscriminate(*LocB)) +  if (LocA == LocB)      return LocA; -  if (!GenerateLocation) -    return nullptr; -    SmallPtrSet<DILocation *, 5> InlinedLocationsA;    for (DILocation *L = LocA->getInlinedAt(); L; L = L->getInlinedAt())      InlinedLocationsA.insert(L); +  SmallSet<std::pair<DIScope *, DILocation *>, 5> Locations; +  DIScope *S = LocA->getScope(); +  DILocation *L = LocA->getInlinedAt(); +  while (S) { +    Locations.insert(std::make_pair(S, L)); +    S = S->getScope().resolve(); +    if (!S && L) { +      S = L->getScope(); +      L = L->getInlinedAt(); +    } +  }    const DILocation *Result = LocB; -  for (DILocation *L = LocB->getInlinedAt(); L; L = L->getInlinedAt()) { -    Result = L; -    if (InlinedLocationsA.count(L)) +  S = LocB->getScope(); +  L = LocB->getInlinedAt(); +  while (S) { +    if (Locations.count(std::make_pair(S, L)))        break; +    S = S->getScope().resolve(); +    if (!S && L) { +      S = L->getScope(); +      L = L->getInlinedAt(); +    }    } -  return DILocation::get(Result->getContext(), 0, 0, Result->getScope(), -                         Result->getInlinedAt()); + +  // If the two locations are irreconsilable, just pick one. This is misleading, +  // but on the other hand, it's a "line 0" location. +  if (!S || !isa<DILocalScope>(S)) +    S = LocA->getScope(); +  return DILocation::get(Result->getContext(), 0, 0, S, L);  } +Optional<unsigned> DILocation::encodeDiscriminator(unsigned BD, unsigned DF, unsigned CI) { +  SmallVector<unsigned, 3> Components = {BD, DF, CI}; +  uint64_t RemainingWork = 0U; +  // We use RemainingWork to figure out if we have no remaining components to +  // encode. For example: if BD != 0 but DF == 0 && CI == 0, we don't need to +  // encode anything for the latter 2. +  // Since any of the input components is at most 32 bits, their sum will be +  // less than 34 bits, and thus RemainingWork won't overflow. +  RemainingWork = std::accumulate(Components.begin(), Components.end(), RemainingWork); + +  int I = 0; +  unsigned Ret = 0; +  unsigned NextBitInsertionIndex = 0; +  while (RemainingWork > 0) { +    unsigned C = Components[I++]; +    RemainingWork -= C; +    unsigned EC = encodeComponent(C); +    Ret |= (EC << NextBitInsertionIndex); +    NextBitInsertionIndex += encodingBits(C); +  } + +  // Encoding may be unsuccessful because of overflow. We determine success by +  // checking equivalence of components before & after encoding. Alternatively, +  // we could determine Success during encoding, but the current alternative is +  // simpler. +  unsigned TBD, TDF, TCI = 0; +  decodeDiscriminator(Ret, TBD, TDF, TCI); +  if (TBD == BD && TDF == DF && TCI == CI) +    return Ret; +  return None; +} + +void DILocation::decodeDiscriminator(unsigned D, unsigned &BD, unsigned &DF, +                                     unsigned &CI) { +  BD = getUnsignedFromPrefixEncoding(D); +  DF = getUnsignedFromPrefixEncoding(getNextComponentInDiscriminator(D)); +  CI = getUnsignedFromPrefixEncoding( +      getNextComponentInDiscriminator(getNextComponentInDiscriminator(D))); +} + +  DINode::DIFlags DINode::getFlag(StringRef Flag) {    return StringSwitch<DIFlags>(Flag)  #define HANDLE_DI_FLAG(ID, NAME) .Case("DIFlag" #NAME, Flag##NAME) @@ -274,13 +337,14 @@ DIEnumerator *DIEnumerator::getImpl(LLVMContext &Context, int64_t Value,  DIBasicType *DIBasicType::getImpl(LLVMContext &Context, unsigned Tag,                                    MDString *Name, uint64_t SizeInBits,                                    uint32_t AlignInBits, unsigned Encoding, -                                  StorageType Storage, bool ShouldCreate) { +                                  DIFlags Flags, StorageType Storage, +                                  bool ShouldCreate) {    assert(isCanonical(Name) && "Expected canonical MDString");    DEFINE_GETIMPL_LOOKUP(DIBasicType, -                        (Tag, Name, SizeInBits, AlignInBits, Encoding)); +                        (Tag, Name, SizeInBits, AlignInBits, Encoding, Flags));    Metadata *Ops[] = {nullptr, nullptr, Name}; -  DEFINE_GETIMPL_STORE(DIBasicType, (Tag, SizeInBits, AlignInBits, Encoding), -                       Ops); +  DEFINE_GETIMPL_STORE(DIBasicType, (Tag, SizeInBits, AlignInBits, Encoding, +                      Flags), Ops);  }  Optional<DIBasicType::Signedness> DIBasicType::getSignedness() const { @@ -449,7 +513,8 @@ DICompileUnit *DICompileUnit::getImpl(      unsigned EmissionKind, Metadata *EnumTypes, Metadata *RetainedTypes,      Metadata *GlobalVariables, Metadata *ImportedEntities, Metadata *Macros,      uint64_t DWOId, bool SplitDebugInlining, bool DebugInfoForProfiling, -    bool GnuPubnames, StorageType Storage, bool ShouldCreate) { +    unsigned NameTableKind, bool RangesBaseAddress, StorageType Storage, +    bool ShouldCreate) {    assert(Storage != Uniqued && "Cannot unique DICompileUnit");    assert(isCanonical(Producer) && "Expected canonical MDString");    assert(isCanonical(Flags) && "Expected canonical MDString"); @@ -462,7 +527,8 @@ DICompileUnit *DICompileUnit::getImpl(    return storeImpl(new (array_lengthof(Ops)) DICompileUnit(                         Context, Storage, SourceLanguage, IsOptimized,                         RuntimeVersion, EmissionKind, DWOId, SplitDebugInlining, -                       DebugInfoForProfiling, GnuPubnames, Ops), +                       DebugInfoForProfiling, NameTableKind, RangesBaseAddress, +                       Ops),                     Storage);  } @@ -472,6 +538,16 @@ DICompileUnit::getEmissionKind(StringRef Str) {        .Case("NoDebug", NoDebug)        .Case("FullDebug", FullDebug)        .Case("LineTablesOnly", LineTablesOnly) +      .Case("DebugDirectivesOnly", DebugDirectivesOnly) +      .Default(None); +} + +Optional<DICompileUnit::DebugNameTableKind> +DICompileUnit::getNameTableKind(StringRef Str) { +  return StringSwitch<Optional<DebugNameTableKind>>(Str) +      .Case("Default", DebugNameTableKind::Default) +      .Case("GNU", DebugNameTableKind::GNU) +      .Case("None", DebugNameTableKind::None)        .Default(None);  } @@ -480,6 +556,19 @@ const char *DICompileUnit::emissionKindString(DebugEmissionKind EK) {    case NoDebug:        return "NoDebug";    case FullDebug:      return "FullDebug";    case LineTablesOnly: return "LineTablesOnly"; +  case DebugDirectivesOnly: return "DebugDirectivesOnly"; +  } +  return nullptr; +} + +const char *DICompileUnit::nameTableKindString(DebugNameTableKind NTK) { +  switch (NTK) { +  case DebugNameTableKind::Default: +    return nullptr; +  case DebugNameTableKind::GNU: +    return "GNU"; +  case DebugNameTableKind::None: +    return "None";    }    return nullptr;  } @@ -496,21 +585,55 @@ DILocalScope *DILocalScope::getNonLexicalBlockFileScope() const {    return const_cast<DILocalScope *>(this);  } +DISubprogram::DISPFlags DISubprogram::getFlag(StringRef Flag) { +  return StringSwitch<DISPFlags>(Flag) +#define HANDLE_DISP_FLAG(ID, NAME) .Case("DISPFlag" #NAME, SPFlag##NAME) +#include "llvm/IR/DebugInfoFlags.def" +      .Default(SPFlagZero); +} + +StringRef DISubprogram::getFlagString(DISPFlags Flag) { +  switch (Flag) { +  // Appease a warning. +  case SPFlagVirtuality: +    return ""; +#define HANDLE_DISP_FLAG(ID, NAME)                                             \ +  case SPFlag##NAME:                                                           \ +    return "DISPFlag" #NAME; +#include "llvm/IR/DebugInfoFlags.def" +  } +  return ""; +} + +DISubprogram::DISPFlags +DISubprogram::splitFlags(DISPFlags Flags, +                         SmallVectorImpl<DISPFlags> &SplitFlags) { +  // Multi-bit fields can require special handling. In our case, however, the +  // only multi-bit field is virtuality, and all its values happen to be +  // single-bit values, so the right behavior just falls out. +#define HANDLE_DISP_FLAG(ID, NAME)                                             \ +  if (DISPFlags Bit = Flags & SPFlag##NAME) {                                  \ +    SplitFlags.push_back(Bit);                                                 \ +    Flags &= ~Bit;                                                             \ +  } +#include "llvm/IR/DebugInfoFlags.def" +  return Flags; +} +  DISubprogram *DISubprogram::getImpl(      LLVMContext &Context, Metadata *Scope, MDString *Name,      MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type, -    bool IsLocalToUnit, bool IsDefinition, unsigned ScopeLine, -    Metadata *ContainingType, unsigned Virtuality, unsigned VirtualIndex, -    int ThisAdjustment, DIFlags Flags, bool IsOptimized, Metadata *Unit, +    unsigned ScopeLine, Metadata *ContainingType, unsigned VirtualIndex, +    int ThisAdjustment, DIFlags Flags, DISPFlags SPFlags, Metadata *Unit,      Metadata *TemplateParams, Metadata *Declaration, Metadata *RetainedNodes,      Metadata *ThrownTypes, StorageType Storage, bool ShouldCreate) {    assert(isCanonical(Name) && "Expected canonical MDString");    assert(isCanonical(LinkageName) && "Expected canonical MDString"); -  DEFINE_GETIMPL_LOOKUP( -      DISubprogram, (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, -                     IsDefinition, ScopeLine, ContainingType, Virtuality, -                     VirtualIndex, ThisAdjustment, Flags, IsOptimized, Unit, -                     TemplateParams, Declaration, RetainedNodes, ThrownTypes)); +  DEFINE_GETIMPL_LOOKUP(DISubprogram, +                        (Scope, Name, LinkageName, File, Line, Type, ScopeLine, +                         ContainingType, VirtualIndex, ThisAdjustment, Flags, +                         SPFlags, Unit, TemplateParams, Declaration, +                         RetainedNodes, ThrownTypes));    SmallVector<Metadata *, 11> Ops = {        File,        Scope,         Name,           LinkageName,    Type,       Unit,        Declaration, RetainedNodes, ContainingType, TemplateParams, ThrownTypes}; @@ -522,11 +645,10 @@ DISubprogram *DISubprogram::getImpl(          Ops.pop_back();      }    } -  DEFINE_GETIMPL_STORE_N(DISubprogram, -                         (Line, ScopeLine, Virtuality, VirtualIndex, -                          ThisAdjustment, Flags, IsLocalToUnit, IsDefinition, -                          IsOptimized), -                         Ops, Ops.size()); +  DEFINE_GETIMPL_STORE_N( +      DISubprogram, +      (Line, ScopeLine, VirtualIndex, ThisAdjustment, Flags, SPFlags), Ops, +      Ops.size());  }  bool DISubprogram::describes(const Function *F) const { @@ -609,19 +731,24 @@ DIGlobalVariable::getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,                            MDString *LinkageName, Metadata *File, unsigned Line,                            Metadata *Type, bool IsLocalToUnit, bool IsDefinition,                            Metadata *StaticDataMemberDeclaration, -                          uint32_t AlignInBits, StorageType Storage, -                          bool ShouldCreate) { +                          Metadata *TemplateParams, uint32_t AlignInBits, +                          StorageType Storage, bool ShouldCreate) {    assert(isCanonical(Name) && "Expected canonical MDString");    assert(isCanonical(LinkageName) && "Expected canonical MDString"); -  DEFINE_GETIMPL_LOOKUP(DIGlobalVariable, -                        (Scope, Name, LinkageName, File, Line, Type, -                         IsLocalToUnit, IsDefinition, -                         StaticDataMemberDeclaration, AlignInBits)); -  Metadata *Ops[] = { -      Scope, Name, File, Type, Name, LinkageName, StaticDataMemberDeclaration}; +  DEFINE_GETIMPL_LOOKUP(DIGlobalVariable, (Scope, Name, LinkageName, File, Line, +                                           Type, IsLocalToUnit, IsDefinition, +                                           StaticDataMemberDeclaration, +                                           TemplateParams, AlignInBits)); +  Metadata *Ops[] = {Scope, +                     Name, +                     File, +                     Type, +                     Name, +                     LinkageName, +                     StaticDataMemberDeclaration, +                     TemplateParams};    DEFINE_GETIMPL_STORE(DIGlobalVariable, -                       (Line, IsLocalToUnit, IsDefinition, AlignInBits), -                       Ops); +                       (Line, IsLocalToUnit, IsDefinition, AlignInBits), Ops);  }  DILocalVariable *DILocalVariable::getImpl(LLVMContext &Context, Metadata *Scope,  | 
