[llvm] r233337 - AsmWriter: Cleanup debug info fields with MDFieldPrinter, NFC

Duncan P. N. Exon Smith dexonsmith at apple.com
Fri Mar 27 10:37:28 PDT 2015


> On 2015-Mar-27, at 10:07, David Blaikie <dblaikie at gmail.com> wrote:
> 
> 
> 
> On Thu, Mar 26, 2015 at 5:17 PM, Duncan P. N. Exon Smith <dexonsmith at apple.com> wrote:
> Author: dexonsmith
> Date: Thu Mar 26 19:17:42 2015
> New Revision: 233337
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=233337&view=rev
> Log:
> AsmWriter: Cleanup debug info fields with MDFieldPrinter, NFC
> 
> Move all the `MDNode` field helper methods into a new class,
> `MDFieldPrinter`, and add helpers for integers, bools, and `DW_*`
> symbolic constants.  This reduces a ton of code duplication, and makes
> it more mechanical to update `AsmWriter` to print broken code in the
> context of stricter accessors (like in r233322).
> 
> Modified:
>     llvm/trunk/lib/IR/AsmWriter.cpp
> 
> Modified: llvm/trunk/lib/IR/AsmWriter.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/AsmWriter.cpp?rev=233337&r1=233336&r2=233337&view=diff
> ==============================================================================
> --- llvm/trunk/lib/IR/AsmWriter.cpp (original)
> +++ llvm/trunk/lib/IR/AsmWriter.cpp Thu Mar 26 19:17:42 2015
> @@ -1358,8 +1358,52 @@ raw_ostream &operator<<(raw_ostream &OS,
>    }
>    return OS << FS.Sep;
>  }
> +struct MDFieldPrinter {
> +  raw_ostream &Out;
> +  FieldSeparator FS;
> +  TypePrinting *TypePrinter;
> +  SlotTracker *Machine;
> +  const Module *Context;
> +
> +  explicit MDFieldPrinter(raw_ostream &Out)
> +      : Out(Out), TypePrinter(nullptr), Machine(nullptr), Context(nullptr) {}
> +  MDFieldPrinter(raw_ostream &Out, TypePrinting *TypePrinter,
> +                 SlotTracker *Machine, const Module *Context)
> +      : Out(Out), TypePrinter(TypePrinter), Machine(Machine), Context(Context) {
> +  }
> +  void printTag(const DebugNode *N);
> +  void printString(StringRef Name, StringRef Value,
> +                   bool ShouldSkipEmpty = true);
> +  void printMetadata(StringRef Name, const Metadata *MD,
> +                     bool ShouldSkipNull = true);
> +  template <class IntTy>
> +  void printInt(StringRef Name, IntTy Int, bool ShouldSkipZero = true);
> +  void printBool(StringRef Name, bool Value);
> +  void printDIFlags(StringRef Name, unsigned Flags);
> +  template <class IntTy, class Stringifier>
> +  void printDwarfEnum(StringRef Name, IntTy Value, Stringifier toString,
> +                      bool ShouldSkipZero = true);
> +};
>  } // end namespace
> 
> +void MDFieldPrinter::printTag(const DebugNode *N) {
> +  Out << FS << "tag: ";
> +  if (const char *Tag = dwarf::TagString(N->getTag()))
> +    Out << Tag;
> +  else
> +    Out << N->getTag();
> +}
> +
> +void MDFieldPrinter::printString(StringRef Name, StringRef Value,
> +                                 bool ShouldSkipEmpty) {
> +  if (ShouldSkipEmpty && Value.empty())
> +    return;
> +
> +  Out << FS << Name << ": \"";
> +  PrintEscapedString(Value, Out);
> +  Out << "\"";
> +}
> +
>  static void writeMetadataAsOperand(raw_ostream &Out, const Metadata *MD,
>                                     TypePrinting *TypePrinter,
>                                     SlotTracker *Machine,
> @@ -1371,34 +1415,68 @@ static void writeMetadataAsOperand(raw_o
>    WriteAsOperandInternal(Out, MD, TypePrinter, Machine, Context);
>  }
> 
> -static void writeTag(raw_ostream &Out, FieldSeparator &FS, const DebugNode *N) {
> -  Out << FS << "tag: ";
> -  if (const char *Tag = dwarf::TagString(N->getTag()))
> -    Out << Tag;
> -  else
> -    Out << N->getTag();
> +void MDFieldPrinter::printMetadata(StringRef Name, const Metadata *MD,
> +                                   bool ShouldSkipNull) {
> +  if (ShouldSkipNull && !MD)
> +    return;
> +
> +  Out << FS << Name << ": ";
> +  writeMetadataAsOperand(Out, MD, TypePrinter, Machine, Context);
>  }
> 
> -static void writeStringField(raw_ostream &Out, FieldSeparator &FS,
> -                             StringRef Name, StringRef Value,
> -                             bool ShouldSkipEmpty = true) {
> -  if (ShouldSkipEmpty && Value.empty())
> +template <class IntTy>
> +void MDFieldPrinter::printInt(StringRef Name, IntTy Int, bool ShouldSkipZero) {
> +  if (ShouldSkipZero && !Int)
>      return;
> 
> -  Out << FS << Name << ": \"";
> -  PrintEscapedString(Value, Out);
> -  Out << "\"";
> +  Out << FS << Name << ": " << Int;
> +}
> +
> +void MDFieldPrinter::printBool(StringRef Name, bool Value) {
> +  Out << FS << Name << ": " << (Value ? "true" : "false");
> +}
> +
> +void MDFieldPrinter::printDIFlags(StringRef Name, unsigned Flags) {
> +  if (!Flags)
> +    return;
> +
> +  Out << FS << Name << ": ";
> +
> +  SmallVector<unsigned, 8> SplitFlags;
> +  unsigned Extra = DIDescriptor::splitFlags(Flags, SplitFlags);
> +
> +  FieldSeparator FlagsFS(" | ");
> +  for (unsigned F : SplitFlags) {
> +    const char *StringF = DIDescriptor::getFlagString(F);
> +    assert(StringF && "Expected valid flag");
> +    Out << FlagsFS << StringF;
> +  }
> +  if (Extra || SplitFlags.empty())
> +    Out << FlagsFS << Extra;
> +}
> +
> +template <class IntTy, class Stringifier>
> +void MDFieldPrinter::printDwarfEnum(StringRef Name, IntTy Value,
> +                                    Stringifier toString, bool ShouldSkipZero) {
> +  if (!Value)
> +    return;
> +
> +  Out << FS << Name << ": ";
> +  if (const char *S = toString(Value))
> +    Out << S;
> +  else
> +    Out << Value;
>  }
> 
>  static void writeGenericDebugNode(raw_ostream &Out, const GenericDebugNode *N,
>                                    TypePrinting *TypePrinter,
>                                    SlotTracker *Machine, const Module *Context) {
> 
> I have this vague idea that it'd be nice to simplify these further (based on the thread of hope for the idea I was throwing around ages ago that schematized metadata could be a generic construct that wouldn't necessarily need explicit LLVM support, with some being builtin and others being defined in-line, etc) by tablegening even these printing functions... 
> 
> The printing could be streamlined a bit by overloading the MDFieldPrinter::print functions - do we have unique types for each of the kinds of things such that we could just name all the functions "print" rather than printInt, printMetadata, etc?

I almost went there, but I was concerned about obviousness of what
happens with the printers that are templated.  IMO having the name
helps prevent coding errors here.  Of course, if you tablegen this,
that concern goes away.

There are a couple of things that have integer types that aren't
printed that way.  Have a look at `printDwarfEnum()` and
`printDIFlags()`.

> Beyond that - I'm not sure how to do a two-level tablegen kind of thing where we could just describe these structures in some kind of tabular way without having to write so much boilerplate (writing the type, its members, and their types only once would be the goal)... 

Yeah, it's not exactly clear to me how to proceed there, but it
would obviously be nice to have less code.  Feel free to hack away
if you have spare cycles (although maybe wait until I've got all
my Verifier patches in, since I'm touching the same code).

The ugliest thing right now is how `get()`, `getDistinct()`,
`getTemporary()`, and `getImpl()` are defined.  The macros make the
code hard to read, and there's still duplication.  At least, if I
get to it first, that's what I'll start with.

> 
>  
>    Out << "!GenericDebugNode(";
> -  FieldSeparator FS;
> -  writeTag(Out, FS, N);
> -  writeStringField(Out, FS, "header", N->getHeader());
> +  MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
> +  Printer.printTag(N);
> +  Printer.printString("header", N->getHeader());
>    if (N->getNumDwarfOperands()) {
> -    Out << FS << "operands: {";
> +    Out << Printer.FS << "operands: {";
>      FieldSeparator IFS;
>      for (auto &I : N->dwarf_operands()) {
>        Out << IFS;
> @@ -1413,109 +1491,64 @@ static void writeMDLocation(raw_ostream
>                              TypePrinting *TypePrinter, SlotTracker *Machine,
>                              const Module *Context) {
>    Out << "!MDLocation(";
> -  FieldSeparator FS;
> +  MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
>    // Always output the line, since 0 is a relevant and important value for it.
> -  Out << FS << "line: " << DL->getLine();
> -  if (DL->getColumn())
> -    Out << FS << "column: " << DL->getColumn();
> -  Out << FS << "scope: ";
> -  WriteAsOperandInternal(Out, DL->getRawScope(), TypePrinter, Machine, Context);
> -  if (auto *IA = DL->getRawInlinedAt()) {
> -    Out << FS << "inlinedAt: ";
> -    WriteAsOperandInternal(Out, IA, TypePrinter, Machine, Context);
> -  }
> +  Printer.printInt("line", DL->getLine(), /* ShouldSkipZero */ false);
> +  Printer.printInt("column", DL->getColumn());
> +  Printer.printMetadata("scope", DL->getRawScope(), /* ShouldSkipNull */ false);
> +  Printer.printMetadata("inlinedAt", DL->getRawInlinedAt());
>    Out << ")";
>  }
> 
>  static void writeMDSubrange(raw_ostream &Out, const MDSubrange *N,
>                              TypePrinting *, SlotTracker *, const Module *) {
>    Out << "!MDSubrange(";
> -  FieldSeparator FS;
> -  Out << FS << "count: " << N->getCount();
> -  if (N->getLo())
> -    Out << FS << "lowerBound: " << N->getLo();
> +  MDFieldPrinter Printer(Out);
> +  Printer.printInt("count", N->getCount(), /* ShouldSkipZero */ false);
> +  Printer.printInt("lowerBound", N->getLo());
>    Out << ")";
>  }
> 
>  static void writeMDEnumerator(raw_ostream &Out, const MDEnumerator *N,
>                                TypePrinting *, SlotTracker *, const Module *) {
>    Out << "!MDEnumerator(";
> -  FieldSeparator FS;
> -  writeStringField(Out, FS, "name", N->getName(), /* ShouldSkipEmpty */ false);
> -  Out << FS << "value: " << N->getValue();
> +  MDFieldPrinter Printer(Out);
> +  Printer.printString("name", N->getName(), /* ShouldSkipEmpty */ false);
> +  Printer.printInt("value", N->getValue(), /* ShouldSkipZero */ false);
>    Out << ")";
>  }
> 
>  static void writeMDBasicType(raw_ostream &Out, const MDBasicType *N,
>                               TypePrinting *, SlotTracker *, const Module *) {
>    Out << "!MDBasicType(";
> -  FieldSeparator FS;
> +  MDFieldPrinter Printer(Out);
>    if (N->getTag() != dwarf::DW_TAG_base_type)
> -    writeTag(Out, FS, N);
> -  writeStringField(Out, FS, "name", N->getName());
> -  if (N->getSizeInBits())
> -    Out << FS << "size: " << N->getSizeInBits();
> -  if (N->getAlignInBits())
> -    Out << FS << "align: " << N->getAlignInBits();
> -  if (unsigned Encoding = N->getEncoding()) {
> -    Out << FS << "encoding: ";
> -    if (const char *S = dwarf::AttributeEncodingString(Encoding))
> -      Out << S;
> -    else
> -      Out << Encoding;
> -  }
> +    Printer.printTag(N);
> +  Printer.printString("name", N->getName());
> +  Printer.printInt("size", N->getSizeInBits());
> +  Printer.printInt("align", N->getAlignInBits());
> +  Printer.printDwarfEnum("encoding", N->getEncoding(),
> +                         dwarf::AttributeEncodingString);
>    Out << ")";
>  }
> 
> -static void writeDIFlags(raw_ostream &Out, unsigned Flags) {
> -  SmallVector<unsigned, 8> SplitFlags;
> -  unsigned Extra = DIDescriptor::splitFlags(Flags, SplitFlags);
> -
> -  FieldSeparator FS(" | ");
> -  for (unsigned F : SplitFlags) {
> -    const char *StringF = DIDescriptor::getFlagString(F);
> -    assert(StringF && "Expected valid flag");
> -    Out << FS << StringF;
> -  }
> -  if (Extra || SplitFlags.empty())
> -    Out << FS << Extra;
> -}
> -
>  static void writeMDDerivedType(raw_ostream &Out, const MDDerivedType *N,
>                                 TypePrinting *TypePrinter, SlotTracker *Machine,
>                                 const Module *Context) {
>    Out << "!MDDerivedType(";
> -  FieldSeparator FS;
> -  writeTag(Out, FS, N);
> -  writeStringField(Out, FS, "name", N->getName());
> -  if (N->getScope()) {
> -    Out << FS << "scope: ";
> -    writeMetadataAsOperand(Out, N->getScope(), TypePrinter, Machine, Context);
> -  }
> -  if (N->getFile()) {
> -    Out << FS << "file: ";
> -    writeMetadataAsOperand(Out, N->getFile(), TypePrinter, Machine,
> -                           Context);
> -  }
> -  if (N->getLine())
> -    Out << FS << "line: " << N->getLine();
> -  Out << FS << "baseType: ";
> -  writeMetadataAsOperand(Out, N->getBaseType(), TypePrinter, Machine, Context);
> -  if (N->getSizeInBits())
> -    Out << FS << "size: " << N->getSizeInBits();
> -  if (N->getAlignInBits())
> -    Out << FS << "align: " << N->getAlignInBits();
> -  if (N->getOffsetInBits())
> -    Out << FS << "offset: " << N->getOffsetInBits();
> -  if (auto Flags = N->getFlags()) {
> -    Out << FS << "flags: ";
> -    writeDIFlags(Out, Flags);
> -  }
> -  if (N->getExtraData()) {
> -    Out << FS << "extraData: ";
> -    writeMetadataAsOperand(Out, N->getExtraData(), TypePrinter, Machine,
> -                           Context);
> -  }
> +  MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
> +  Printer.printTag(N);
> +  Printer.printString("name", N->getName());
> +  Printer.printMetadata("scope", N->getScope());
> +  Printer.printMetadata("file", N->getFile());
> +  Printer.printInt("line", N->getLine());
> +  Printer.printMetadata("baseType", N->getBaseType(),
> +                        /* ShouldSkipNull */ false);
> +  Printer.printInt("size", N->getSizeInBits());
> +  Printer.printInt("align", N->getAlignInBits());
> +  Printer.printInt("offset", N->getOffsetInBits());
> +  Printer.printDIFlags("flags", N->getFlags());
> +  Printer.printMetadata("extraData", N->getExtraData());
>    Out << ")";
>  }
> 
> @@ -1523,59 +1556,23 @@ static void writeMDCompositeType(raw_ost
>                                   TypePrinting *TypePrinter,
>                                   SlotTracker *Machine, const Module *Context) {
>    Out << "!MDCompositeType(";
> -  FieldSeparator FS;
> -  writeTag(Out, FS, N);
> -  writeStringField(Out, FS, "name", N->getName());
> -  if (N->getScope()) {
> -    Out << FS << "scope: ";
> -    writeMetadataAsOperand(Out, N->getScope(), TypePrinter, Machine, Context);
> -  }
> -  if (N->getFile()) {
> -    Out << FS << "file: ";
> -    writeMetadataAsOperand(Out, N->getFile(), TypePrinter, Machine,
> -                           Context);
> -  }
> -  if (N->getLine())
> -    Out << FS << "line: " << N->getLine();
> -  if (N->getBaseType()) {
> -    Out << FS << "baseType: ";
> -    writeMetadataAsOperand(Out, N->getBaseType(), TypePrinter, Machine,
> -                           Context);
> -  }
> -  if (N->getSizeInBits())
> -    Out << FS << "size: " << N->getSizeInBits();
> -  if (N->getAlignInBits())
> -    Out << FS << "align: " << N->getAlignInBits();
> -  if (N->getOffsetInBits())
> -    Out << FS << "offset: " << N->getOffsetInBits();
> -  if (auto Flags = N->getFlags()) {
> -    Out << FS << "flags: ";
> -    writeDIFlags(Out, Flags);
> -  }
> -  if (N->getElements()) {
> -    Out << FS << "elements: ";
> -    writeMetadataAsOperand(Out, N->getElements(), TypePrinter, Machine,
> -                           Context);
> -  }
> -  if (unsigned Lang = N->getRuntimeLang()) {
> -    Out << FS << "runtimeLang: ";
> -    if (const char *S = dwarf::LanguageString(Lang))
> -      Out << S;
> -    else
> -      Out << Lang;
> -  }
> -
> -  if (N->getVTableHolder()) {
> -    Out << FS << "vtableHolder: ";
> -    writeMetadataAsOperand(Out, N->getVTableHolder(), TypePrinter, Machine,
> -                           Context);
> -  }
> -  if (N->getTemplateParams()) {
> -    Out << FS << "templateParams: ";
> -    writeMetadataAsOperand(Out, N->getTemplateParams(), TypePrinter, Machine,
> -                           Context);
> -  }
> -  writeStringField(Out, FS, "identifier", N->getIdentifier());
> +  MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
> +  Printer.printTag(N);
> +  Printer.printString("name", N->getName());
> +  Printer.printMetadata("scope", N->getScope());
> +  Printer.printMetadata("file", N->getFile());
> +  Printer.printInt("line", N->getLine());
> +  Printer.printMetadata("baseType", N->getBaseType());
> +  Printer.printInt("size", N->getSizeInBits());
> +  Printer.printInt("align", N->getAlignInBits());
> +  Printer.printInt("offset", N->getOffsetInBits());
> +  Printer.printDIFlags("flags", N->getFlags());
> +  Printer.printMetadata("elements", N->getElements());
> +  Printer.printDwarfEnum("runtimeLang", N->getRuntimeLang(),
> +                         dwarf::LanguageString);
> +  Printer.printMetadata("vtableHolder", N->getVTableHolder());
> +  Printer.printMetadata("templateParams", N->getTemplateParams());
> +  Printer.printString("identifier", N->getIdentifier());
>    Out << ")";
>  }
> 
> @@ -1583,24 +1580,20 @@ static void writeMDSubroutineType(raw_os
>                                    TypePrinting *TypePrinter,
>                                    SlotTracker *Machine, const Module *Context) {
>    Out << "!MDSubroutineType(";
> -  FieldSeparator FS;
> -  if (auto Flags = N->getFlags()) {
> -    Out << FS << "flags: ";
> -    writeDIFlags(Out, Flags);
> -  }
> -  Out << FS << "types: ";
> -  writeMetadataAsOperand(Out, N->getTypeArray(), TypePrinter, Machine, Context);
> +  MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
> +  Printer.printDIFlags("flags", N->getFlags());
> +  Printer.printMetadata("types", N->getTypeArray(), /* ShouldSkipNull */ false);
>    Out << ")";
>  }
> 
>  static void writeMDFile(raw_ostream &Out, const MDFile *N, TypePrinting *,
>                          SlotTracker *, const Module *) {
>    Out << "!MDFile(";
> -  FieldSeparator FS;
> -  writeStringField(Out, FS, "filename", N->getFilename(),
> -                   /* ShouldSkipEmpty */ false);
> -  writeStringField(Out, FS, "directory", N->getDirectory(),
> -                   /* ShouldSkipEmpty */ false);
> +  MDFieldPrinter Printer(Out);
> +  Printer.printString("filename", N->getFilename(),
> +                      /* ShouldSkipEmpty */ false);
> +  Printer.printString("directory", N->getDirectory(),
> +                      /* ShouldSkipEmpty */ false);
>    Out << ")";
>  }
> 
> @@ -1608,45 +1601,23 @@ static void writeMDCompileUnit(raw_ostre
>                                 TypePrinting *TypePrinter, SlotTracker *Machine,
>                                 const Module *Context) {
>    Out << "!MDCompileUnit(";
> -  FieldSeparator FS;
> -  Out << FS << "language: ";
> -  if (const char *Lang = dwarf::LanguageString(N->getSourceLanguage()))
> -    Out << Lang;
> -  else
> -    Out << N->getSourceLanguage();
> -  Out << FS << "file: ";
> -  writeMetadataAsOperand(Out, N->getFile(), TypePrinter, Machine, Context);
> -  writeStringField(Out, FS, "producer", N->getProducer());
> -  Out << FS << "isOptimized: " << (N->isOptimized() ? "true" : "false");
> -  writeStringField(Out, FS, "flags", N->getFlags());
> -  Out << FS << "runtimeVersion: " << N->getRuntimeVersion();
> -  writeStringField(Out, FS, "splitDebugFilename", N->getSplitDebugFilename());
> -  Out << FS << "emissionKind: " << N->getEmissionKind();
> -  if (N->getEnumTypes()) {
> -    Out << FS << "enums: ";
> -    writeMetadataAsOperand(Out, N->getEnumTypes(), TypePrinter, Machine,
> -                           Context);
> -  }
> -  if (N->getRetainedTypes()) {
> -    Out << FS << "retainedTypes: ";
> -    writeMetadataAsOperand(Out, N->getRetainedTypes(), TypePrinter, Machine,
> -                           Context);
> -  }
> -  if (N->getSubprograms()) {
> -    Out << FS << "subprograms: ";
> -    writeMetadataAsOperand(Out, N->getSubprograms(), TypePrinter, Machine,
> -                           Context);
> -  }
> -  if (N->getGlobalVariables()) {
> -    Out << FS << "globals: ";
> -    writeMetadataAsOperand(Out, N->getGlobalVariables(), TypePrinter, Machine,
> -                           Context);
> -  }
> -  if (N->getImportedEntities()) {
> -    Out << FS << "imports: ";
> -    writeMetadataAsOperand(Out, N->getImportedEntities(), TypePrinter, Machine,
> -                           Context);
> -  }
> +  MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
> +  Printer.printDwarfEnum("language", N->getSourceLanguage(),
> +                         dwarf::LanguageString, /* ShouldSkipZero */ false);
> +  Printer.printMetadata("file", N->getFile(), /* ShouldSkipNull */ false);
> +  Printer.printString("producer", N->getProducer());
> +  Printer.printBool("isOptimized", N->isOptimized());
> +  Printer.printString("flags", N->getFlags());
> +  Printer.printInt("runtimeVersion", N->getRuntimeVersion(),
> +                   /* ShouldSkipZero */ false);
> +  Printer.printString("splitDebugFilename", N->getSplitDebugFilename());
> +  Printer.printInt("emissionKind", N->getEmissionKind(),
> +                   /* ShouldSkipZero */ false);
> +  Printer.printMetadata("enums", N->getEnumTypes());
> +  Printer.printMetadata("retainedTypes", N->getRetainedTypes());
> +  Printer.printMetadata("subprograms", N->getSubprograms());
> +  Printer.printMetadata("globals", N->getGlobalVariables());
> +  Printer.printMetadata("imports", N->getImportedEntities());
>    Out << ")";
>  }
> 
> @@ -1654,66 +1625,26 @@ static void writeMDSubprogram(raw_ostrea
>                                TypePrinting *TypePrinter, SlotTracker *Machine,
>                                const Module *Context) {
>    Out << "!MDSubprogram(";
> -  FieldSeparator FS;
> -  writeStringField(Out, FS, "name", N->getName());
> -  writeStringField(Out, FS, "linkageName", N->getLinkageName());
> -  Out << FS << "scope: ";
> -  writeMetadataAsOperand(Out, N->getScope(), TypePrinter, Machine, Context);
> -  if (N->getFile()) {
> -    Out << FS << "file: ";
> -    writeMetadataAsOperand(Out, N->getFile(), TypePrinter, Machine,
> -                           Context);
> -  }
> -  if (N->getLine())
> -    Out << FS << "line: " << N->getLine();
> -  if (N->getType()) {
> -    Out << FS << "type: ";
> -    writeMetadataAsOperand(Out, N->getType(), TypePrinter, Machine,
> -                           Context);
> -  }
> -  Out << FS << "isLocal: " << (N->isLocalToUnit() ? "true" : "false");
> -  Out << FS << "isDefinition: " << (N->isDefinition() ? "true" : "false");
> -  if (N->getScopeLine())
> -    Out << FS << "scopeLine: " << N->getScopeLine();
> -  if (N->getContainingType()) {
> -    Out << FS << "containingType: ";
> -    writeMetadataAsOperand(Out, N->getContainingType(), TypePrinter, Machine,
> -                           Context);
> -  }
> -  if (unsigned V = N->getVirtuality()) {
> -    Out << FS << "virtuality: ";
> -    if (const char *S = dwarf::VirtualityString(V))
> -      Out << S;
> -    else
> -      Out << V;
> -  }
> -  if (N->getVirtualIndex())
> -    Out << FS << "virtualIndex: " << N->getVirtualIndex();
> -  if (auto Flags = N->getFlags()) {
> -    Out << FS << "flags: ";
> -    writeDIFlags(Out, Flags);
> -  }
> -  Out << FS << "isOptimized: " << (N->isOptimized() ? "true" : "false");
> -  if (N->getFunction()) {
> -    Out << FS << "function: ";
> -    writeMetadataAsOperand(Out, N->getFunction(), TypePrinter, Machine,
> -                           Context);
> -  }
> -  if (N->getTemplateParams()) {
> -    Out << FS << "templateParams: ";
> -    writeMetadataAsOperand(Out, N->getTemplateParams(), TypePrinter, Machine,
> -                           Context);
> -  }
> -  if (N->getDeclaration()) {
> -    Out << FS << "declaration: ";
> -    writeMetadataAsOperand(Out, N->getDeclaration(), TypePrinter, Machine,
> -                           Context);
> -  }
> -  if (N->getVariables()) {
> -    Out << FS << "variables: ";
> -    writeMetadataAsOperand(Out, N->getVariables(), TypePrinter, Machine,
> -                           Context);
> -  }
> +  MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
> +  Printer.printString("name", N->getName());
> +  Printer.printString("linkageName", N->getLinkageName());
> +  Printer.printMetadata("scope", N->getScope(), /* ShouldSkipNull */ false);
> +  Printer.printMetadata("file", N->getFile());
> +  Printer.printInt("line", N->getLine());
> +  Printer.printMetadata("type", N->getType());
> +  Printer.printBool("isLocal", N->isLocalToUnit());
> +  Printer.printBool("isDefinition", N->isDefinition());
> +  Printer.printInt("scopeLine", N->getScopeLine());
> +  Printer.printMetadata("containingType", N->getContainingType());
> +  Printer.printDwarfEnum("virtuality", N->getVirtuality(),
> +                         dwarf::VirtualityString);
> +  Printer.printInt("virtualIndex", N->getVirtualIndex());
> +  Printer.printDIFlags("flags", N->getFlags());
> +  Printer.printBool("isOptimized", N->isOptimized());
> +  Printer.printMetadata("function", N->getFunction());
> +  Printer.printMetadata("templateParams", N->getTemplateParams());
> +  Printer.printMetadata("declaration", N->getDeclaration());
> +  Printer.printMetadata("variables", N->getVariables());
>    Out << ")";
>  }
> 
> @@ -1721,18 +1652,11 @@ static void writeMDLexicalBlock(raw_ostr
>                                TypePrinting *TypePrinter, SlotTracker *Machine,
>                                const Module *Context) {
>    Out << "!MDLexicalBlock(";
> -  FieldSeparator FS;
> -  Out << FS << "scope: ";
> -  writeMetadataAsOperand(Out, N->getScope(), TypePrinter, Machine, Context);
> -  if (N->getFile()) {
> -    Out << FS << "file: ";
> -    writeMetadataAsOperand(Out, N->getFile(), TypePrinter, Machine,
> -                           Context);
> -  }
> -  if (N->getLine())
> -    Out << FS << "line: " << N->getLine();
> -  if (N->getColumn())
> -    Out << FS << "column: " << N->getColumn();
> +  MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
> +  Printer.printMetadata("scope", N->getScope(), /* ShouldSkipNull */ false);
> +  Printer.printMetadata("file", N->getFile());
> +  Printer.printInt("line", N->getLine());
> +  Printer.printInt("column", N->getColumn());
>    Out << ")";
>  }
> 
> @@ -1742,15 +1666,11 @@ static void writeMDLexicalBlockFile(raw_
>                                      SlotTracker *Machine,
>                                      const Module *Context) {
>    Out << "!MDLexicalBlockFile(";
> -  FieldSeparator FS;
> -  Out << FS << "scope: ";
> -  writeMetadataAsOperand(Out, N->getScope(), TypePrinter, Machine, Context);
> -  if (N->getFile()) {
> -    Out << FS << "file: ";
> -    writeMetadataAsOperand(Out, N->getFile(), TypePrinter, Machine,
> -                           Context);
> -  }
> -  Out << FS << "discriminator: " << N->getDiscriminator();
> +  MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
> +  Printer.printMetadata("scope", N->getScope(), /* ShouldSkipNull */ false);
> +  Printer.printMetadata("file", N->getFile());
> +  Printer.printInt("discriminator", N->getDiscriminator(),
> +                   /* ShouldSkipZero */ false);
>    Out << ")";
>  }
> 
> @@ -1758,16 +1678,11 @@ static void writeMDNamespace(raw_ostream
>                               TypePrinting *TypePrinter, SlotTracker *Machine,
>                               const Module *Context) {
>    Out << "!MDNamespace(";
> -  FieldSeparator FS;
> -  writeStringField(Out, FS, "name", N->getName());
> -  Out << FS << "scope: ";
> -  writeMetadataAsOperand(Out, N->getScope(), TypePrinter, Machine, Context);
> -  if (N->getFile()) {
> -    Out << FS << "file: ";
> -    writeMetadataAsOperand(Out, N->getFile(), TypePrinter, Machine, Context);
> -  }
> -  if (N->getLine())
> -    Out << FS << "line: " << N->getLine();
> +  MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
> +  Printer.printString("name", N->getName());
> +  Printer.printMetadata("scope", N->getScope(), /* ShouldSkipNull */ false);
> +  Printer.printMetadata("file", N->getFile());
> +  Printer.printInt("line", N->getLine());
>    Out << ")";
>  }
> 
> @@ -1777,10 +1692,9 @@ static void writeMDTemplateTypeParameter
>                                           SlotTracker *Machine,
>                                           const Module *Context) {
>    Out << "!MDTemplateTypeParameter(";
> -  FieldSeparator FS;
> -  writeStringField(Out, FS, "name", N->getName());
> -  Out << FS << "type: ";
> -  writeMetadataAsOperand(Out, N->getType(), TypePrinter, Machine, Context);
> +  MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
> +  Printer.printString("name", N->getName());
> +  Printer.printMetadata("type", N->getType(), /* ShouldSkipNull */ false);
>    Out << ")";
>  }
> 
> @@ -1790,16 +1704,12 @@ static void writeMDTemplateValueParamete
>                                            SlotTracker *Machine,
>                                            const Module *Context) {
>    Out << "!MDTemplateValueParameter(";
> -  FieldSeparator FS;
> +  MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
>    if (N->getTag() != dwarf::DW_TAG_template_value_parameter)
> -    writeTag(Out, FS, N);
> -  writeStringField(Out, FS, "name", N->getName());
> -  if (auto *Type = N->getType()) {
> -    Out << FS << "type: ";
> -    writeMetadataAsOperand(Out, Type, TypePrinter, Machine, Context);
> -  }
> -  Out << FS << "value: ";
> -  writeMetadataAsOperand(Out, N->getValue(), TypePrinter, Machine, Context);
> +    Printer.printTag(N);
> +  Printer.printString("name", N->getName());
> +  Printer.printMetadata("type", N->getType());
> +  Printer.printMetadata("value", N->getValue(), /* ShouldSkipNull */ false);
>    Out << ")";
>  }
> 
> @@ -1807,35 +1717,17 @@ static void writeMDGlobalVariable(raw_os
>                                    TypePrinting *TypePrinter,
>                                    SlotTracker *Machine, const Module *Context) {
>    Out << "!MDGlobalVariable(";
> -  FieldSeparator FS;
> -  writeStringField(Out, FS, "name", N->getName());
> -  writeStringField(Out, FS, "linkageName", N->getLinkageName());
> -  Out << FS << "scope: ";
> -  writeMetadataAsOperand(Out, N->getScope(), TypePrinter, Machine, Context);
> -  if (N->getFile()) {
> -    Out << FS << "file: ";
> -    writeMetadataAsOperand(Out, N->getFile(), TypePrinter, Machine,
> -                           Context);
> -  }
> -  if (N->getLine())
> -    Out << FS << "line: " << N->getLine();
> -  if (N->getType()) {
> -    Out << FS << "type: ";
> -    writeMetadataAsOperand(Out, N->getType(), TypePrinter, Machine,
> -                           Context);
> -  }
> -  Out << FS << "isLocal: " << (N->isLocalToUnit() ? "true" : "false");
> -  Out << FS << "isDefinition: " << (N->isDefinition() ? "true" : "false");
> -  if (N->getVariable()) {
> -    Out << FS << "variable: ";
> -    writeMetadataAsOperand(Out, N->getVariable(), TypePrinter, Machine,
> -                           Context);
> -  }
> -  if (N->getStaticDataMemberDeclaration()) {
> -    Out << FS << "declaration: ";
> -    writeMetadataAsOperand(Out, N->getStaticDataMemberDeclaration(),
> -                           TypePrinter, Machine, Context);
> -  }
> +  MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
> +  Printer.printString("name", N->getName());
> +  Printer.printString("linkageName", N->getLinkageName());
> +  Printer.printMetadata("scope", N->getScope(), /* ShouldSkipNull */ false);
> +  Printer.printMetadata("file", N->getFile());
> +  Printer.printInt("line", N->getLine());
> +  Printer.printMetadata("type", N->getType());
> +  Printer.printBool("isLocal", N->isLocalToUnit());
> +  Printer.printBool("isDefinition", N->isDefinition());
> +  Printer.printMetadata("variable", N->getVariable());
> +  Printer.printMetadata("declaration", N->getStaticDataMemberDeclaration());
>    Out << ")";
>  }
> 
> @@ -1843,34 +1735,18 @@ static void writeMDLocalVariable(raw_ost
>                                   TypePrinting *TypePrinter,
>                                   SlotTracker *Machine, const Module *Context) {
>    Out << "!MDLocalVariable(";
> -  FieldSeparator FS;
> -  writeTag(Out, FS, N);
> -  writeStringField(Out, FS, "name", N->getName());
> -  if (N->getTag() == dwarf::DW_TAG_arg_variable || N->getArg())
> -    Out << FS << "arg: " << N->getArg();
> -  Out << FS << "scope: ";
> -  writeMetadataAsOperand(Out, N->getScope(), TypePrinter, Machine, Context);
> -  if (N->getFile()) {
> -    Out << FS << "file: ";
> -    writeMetadataAsOperand(Out, N->getFile(), TypePrinter, Machine,
> -                           Context);
> -  }
> -  if (N->getLine())
> -    Out << FS << "line: " << N->getLine();
> -  if (N->getType()) {
> -    Out << FS << "type: ";
> -    writeMetadataAsOperand(Out, N->getType(), TypePrinter, Machine,
> -                           Context);
> -  }
> -  if (auto Flags = N->getFlags()) {
> -    Out << FS << "flags: ";
> -    writeDIFlags(Out, Flags);
> -  }
> -  if (N->getInlinedAt()) {
> -    Out << FS << "inlinedAt: ";
> -    writeMetadataAsOperand(Out, N->getInlinedAt(), TypePrinter, Machine,
> -                           Context);
> -  }
> +  MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
> +  Printer.printTag(N);
> +  Printer.printString("name", N->getName());
> +  Printer.printInt("arg", N->getArg(),
> +                   /* ShouldSkipZero */
> +                   N->getTag() == dwarf::DW_TAG_auto_variable);
> +  Printer.printMetadata("scope", N->getScope(), /* ShouldSkipNull */ false);
> +  Printer.printMetadata("file", N->getFile());
> +  Printer.printInt("line", N->getLine());
> +  Printer.printMetadata("type", N->getType());
> +  Printer.printDIFlags("flags", N->getFlags());
> +  Printer.printMetadata("inlinedAt", N->getInlinedAt());
>    Out << ")";
>  }
> 
> @@ -1899,22 +1775,14 @@ static void writeMDObjCProperty(raw_ostr
>                                  TypePrinting *TypePrinter, SlotTracker *Machine,
>                                  const Module *Context) {
>    Out << "!MDObjCProperty(";
> -  FieldSeparator FS;
> -  writeStringField(Out, FS, "name", N->getName());
> -  if (N->getFile()) {
> -    Out << FS << "file: ";
> -    writeMetadataAsOperand(Out, N->getFile(), TypePrinter, Machine, Context);
> -  }
> -  if (N->getLine())
> -    Out << FS << "line: " << N->getLine();
> -  writeStringField(Out, FS, "setter", N->getSetterName());
> -  writeStringField(Out, FS, "getter", N->getGetterName());
> -  if (N->getAttributes())
> -    Out << FS << "attributes: " << N->getAttributes();
> -  if (N->getType()) {
> -    Out << FS << "type: ";
> -    writeMetadataAsOperand(Out, N->getType(), TypePrinter, Machine, Context);
> -  }
> +  MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
> +  Printer.printString("name", N->getName());
> +  Printer.printMetadata("file", N->getFile());
> +  Printer.printInt("line", N->getLine());
> +  Printer.printString("setter", N->getSetterName());
> +  Printer.printString("getter", N->getGetterName());
> +  Printer.printInt("attributes", N->getAttributes());
> +  Printer.printMetadata("type", N->getType());
>    Out << ")";
>  }
> 
> @@ -1922,17 +1790,12 @@ static void writeMDImportedEntity(raw_os
>                                    TypePrinting *TypePrinter,
>                                    SlotTracker *Machine, const Module *Context) {
>    Out << "!MDImportedEntity(";
> -  FieldSeparator FS;
> -  writeTag(Out, FS, N);
> -  writeStringField(Out, FS, "name", N->getName());
> -  Out << FS << "scope: ";
> -  writeMetadataAsOperand(Out, N->getScope(), TypePrinter, Machine, Context);
> -  if (N->getEntity()) {
> -    Out << FS << "entity: ";
> -    writeMetadataAsOperand(Out, N->getEntity(), TypePrinter, Machine, Context);
> -  }
> -  if (N->getLine())
> -    Out << FS << "line: " << N->getLine();
> +  MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
> +  Printer.printTag(N);
> +  Printer.printString("name", N->getName());
> +  Printer.printMetadata("scope", N->getScope(), /* ShouldSkipNull */ false);
> +  Printer.printMetadata("entity", N->getEntity());
> +  Printer.printInt("line", N->getLine());
>    Out << ")";
>  }
> 
> 
> 
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits





More information about the llvm-commits mailing list