//
//===----------------------------------------------------------------------===//
-#include "AsmWriter.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/IR/AssemblyAnnotationWriter.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Operator.h"
+#include "llvm/IR/Statepoint.h"
#include "llvm/IR/TypeFinder.h"
+#include "llvm/IR/UseListOrder.h"
#include "llvm/IR/ValueSymbolTable.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cctype>
using namespace llvm;
}
-namespace llvm {
+namespace {
+class TypePrinting {
+ TypePrinting(const TypePrinting &) = delete;
+ void operator=(const TypePrinting&) = delete;
+public:
+
+ /// NamedTypes - The named types that are used by the current module.
+ TypeFinder NamedTypes;
+
+ /// NumberedTypes - The numbered types, along with their value.
+ DenseMap<StructType*, unsigned> NumberedTypes;
+
+ TypePrinting() = default;
+
+ void incorporateTypes(const Module &M);
+
+ void print(Type *Ty, raw_ostream &OS);
+
+ void printStructBody(StructType *Ty, raw_ostream &OS);
+};
+} // namespace
void TypePrinting::incorporateTypes(const Module &M) {
NamedTypes.run(M, false);
OS << '>';
}
+namespace {
//===----------------------------------------------------------------------===//
// SlotTracker Class: Enumerate slot numbers for unnamed values
//===----------------------------------------------------------------------===//
SlotTracker(const SlotTracker &) = delete;
void operator=(const SlotTracker &) = delete;
};
+} // namespace
-SlotTracker *createSlotTracker(const Module *M) {
+static SlotTracker *createSlotTracker(const Module *M) {
return new SlotTracker(M);
}
if (!BB.hasName())
CreateFunctionSlot(&BB);
+ processFunctionMetadata(*TheFunction);
+
for (auto &I : BB) {
if (!I.getType()->isVoidTy() && !I.hasName())
CreateFunctionSlot(&I);
- processInstructionMetadata(I);
-
// We allow direct calls to any llvm.foo function here, because the
// target may not be linked into the optimizer.
if (const CallInst *CI = dyn_cast<CallInst>(&I)) {
}
void SlotTracker::processFunctionMetadata(const Function &F) {
- for (auto &BB : F)
+ SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
+ for (auto &BB : F) {
+ F.getAllMetadata(MDs);
+ for (auto &MD : MDs)
+ CreateMetadataSlot(MD.second);
+
for (auto &I : BB)
processInstructionMetadata(I);
+ }
}
void SlotTracker::processInstructionMetadata(const Instruction &I) {
}
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 DINode *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 DINode *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,
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;
}
-static void writeGenericDebugNode(raw_ostream &Out, const GenericDebugNode *N,
- TypePrinting *TypePrinter,
- SlotTracker *Machine, const Module *Context) {
- Out << "!GenericDebugNode(";
- FieldSeparator FS;
- writeTag(Out, FS, N);
- writeStringField(Out, FS, "header", N->getHeader());
+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 = DINode::splitFlags(Flags, SplitFlags);
+
+ FieldSeparator FlagsFS(" | ");
+ for (unsigned F : SplitFlags) {
+ const char *StringF = DINode::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 writeGenericDINode(raw_ostream &Out, const GenericDINode *N,
+ TypePrinting *TypePrinter, SlotTracker *Machine,
+ const Module *Context) {
+ Out << "!GenericDINode(";
+ 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;
Out << ")";
}
-static void writeMDLocation(raw_ostream &Out, const MDLocation *DL,
+static void writeDILocation(raw_ostream &Out, const DILocation *DL,
TypePrinting *TypePrinter, SlotTracker *Machine,
const Module *Context) {
- Out << "!MDLocation(";
- FieldSeparator FS;
+ Out << "!DILocation(";
+ 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->getScope(), TypePrinter, Machine, Context);
- if (DL->getInlinedAt()) {
- Out << FS << "inlinedAt: ";
- WriteAsOperandInternal(Out, DL->getInlinedAt(), 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,
+static void writeDISubrange(raw_ostream &Out, const DISubrange *N,
TypePrinting *, SlotTracker *, const Module *) {
- Out << "!MDSubrange(";
- FieldSeparator FS;
- Out << FS << "count: " << N->getCount();
- if (N->getLo())
- Out << FS << "lowerBound: " << N->getLo();
+ Out << "!DISubrange(";
+ MDFieldPrinter Printer(Out);
+ Printer.printInt("count", N->getCount(), /* ShouldSkipZero */ false);
+ Printer.printInt("lowerBound", N->getLowerBound());
Out << ")";
}
-static void writeMDEnumerator(raw_ostream &Out, const MDEnumerator *N,
+static void writeDIEnumerator(raw_ostream &Out, const DIEnumerator *N,
TypePrinting *, SlotTracker *, const Module *) {
- Out << "!MDEnumerator(";
- FieldSeparator FS;
- writeStringField(Out, FS, "name", N->getName(), /* ShouldSkipEmpty */ false);
- Out << FS << "value: " << N->getValue();
+ Out << "!DIEnumerator(";
+ 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,
+static void writeDIBasicType(raw_ostream &Out, const DIBasicType *N,
TypePrinting *, SlotTracker *, const Module *) {
- Out << "!MDBasicType(";
- FieldSeparator FS;
+ Out << "!DIBasicType(";
+ 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,
+static void writeDIDerivedType(raw_ostream &Out, const DIDerivedType *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);
- }
+ Out << "!DIDerivedType(";
+ MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
+ Printer.printTag(N);
+ Printer.printString("name", N->getName());
+ Printer.printMetadata("scope", N->getRawScope());
+ Printer.printMetadata("file", N->getRawFile());
+ Printer.printInt("line", N->getLine());
+ Printer.printMetadata("baseType", N->getRawBaseType(),
+ /* 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->getRawExtraData());
Out << ")";
}
-static void writeMDCompositeType(raw_ostream &Out, const MDCompositeType *N,
+static void writeDICompositeType(raw_ostream &Out, const DICompositeType *N,
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());
+ Out << "!DICompositeType(";
+ MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
+ Printer.printTag(N);
+ Printer.printString("name", N->getName());
+ Printer.printMetadata("scope", N->getRawScope());
+ Printer.printMetadata("file", N->getRawFile());
+ Printer.printInt("line", N->getLine());
+ Printer.printMetadata("baseType", N->getRawBaseType());
+ Printer.printInt("size", N->getSizeInBits());
+ Printer.printInt("align", N->getAlignInBits());
+ Printer.printInt("offset", N->getOffsetInBits());
+ Printer.printDIFlags("flags", N->getFlags());
+ Printer.printMetadata("elements", N->getRawElements());
+ Printer.printDwarfEnum("runtimeLang", N->getRuntimeLang(),
+ dwarf::LanguageString);
+ Printer.printMetadata("vtableHolder", N->getRawVTableHolder());
+ Printer.printMetadata("templateParams", N->getRawTemplateParams());
+ Printer.printString("identifier", N->getIdentifier());
Out << ")";
}
-static void writeMDSubroutineType(raw_ostream &Out, const MDSubroutineType *N,
+static void writeDISubroutineType(raw_ostream &Out, const DISubroutineType *N,
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);
+ Out << "!DISubroutineType(";
+ MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
+ Printer.printDIFlags("flags", N->getFlags());
+ Printer.printMetadata("types", N->getRawTypeArray(),
+ /* ShouldSkipNull */ false);
Out << ")";
}
-static void writeMDFile(raw_ostream &Out, const MDFile *N, TypePrinting *,
+static void writeDIFile(raw_ostream &Out, const DIFile *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);
+ Out << "!DIFile(";
+ MDFieldPrinter Printer(Out);
+ Printer.printString("filename", N->getFilename(),
+ /* ShouldSkipEmpty */ false);
+ Printer.printString("directory", N->getDirectory(),
+ /* ShouldSkipEmpty */ false);
Out << ")";
}
-static void writeMDCompileUnit(raw_ostream &Out, const MDCompileUnit *N,
+static void writeDICompileUnit(raw_ostream &Out, const DICompileUnit *N,
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);
- }
+ Out << "!DICompileUnit(";
+ MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
+ Printer.printDwarfEnum("language", N->getSourceLanguage(),
+ dwarf::LanguageString, /* ShouldSkipZero */ false);
+ Printer.printMetadata("file", N->getRawFile(), /* 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->getRawEnumTypes());
+ Printer.printMetadata("retainedTypes", N->getRawRetainedTypes());
+ Printer.printMetadata("subprograms", N->getRawSubprograms());
+ Printer.printMetadata("globals", N->getRawGlobalVariables());
+ Printer.printMetadata("imports", N->getRawImportedEntities());
+ Printer.printInt("dwoId", N->getDWOId());
Out << ")";
}
-static void writeMDSubprogram(raw_ostream &Out, const MDSubprogram *N,
+static void writeDISubprogram(raw_ostream &Out, const DISubprogram *N,
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);
- }
+ Out << "!DISubprogram(";
+ MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
+ Printer.printString("name", N->getName());
+ Printer.printString("linkageName", N->getLinkageName());
+ Printer.printMetadata("scope", N->getRawScope(), /* ShouldSkipNull */ false);
+ Printer.printMetadata("file", N->getRawFile());
+ Printer.printInt("line", N->getLine());
+ Printer.printMetadata("type", N->getRawType());
+ Printer.printBool("isLocal", N->isLocalToUnit());
+ Printer.printBool("isDefinition", N->isDefinition());
+ Printer.printInt("scopeLine", N->getScopeLine());
+ Printer.printMetadata("containingType", N->getRawContainingType());
+ 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->getRawFunction());
+ Printer.printMetadata("templateParams", N->getRawTemplateParams());
+ Printer.printMetadata("declaration", N->getRawDeclaration());
+ Printer.printMetadata("variables", N->getRawVariables());
Out << ")";
}
-static void writeMDLexicalBlock(raw_ostream &Out, const MDLexicalBlock *N,
- 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();
+static void writeDILexicalBlock(raw_ostream &Out, const DILexicalBlock *N,
+ TypePrinting *TypePrinter, SlotTracker *Machine,
+ const Module *Context) {
+ Out << "!DILexicalBlock(";
+ MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
+ Printer.printMetadata("scope", N->getRawScope(), /* ShouldSkipNull */ false);
+ Printer.printMetadata("file", N->getRawFile());
+ Printer.printInt("line", N->getLine());
+ Printer.printInt("column", N->getColumn());
Out << ")";
}
-static void writeMDLexicalBlockFile(raw_ostream &Out,
- const MDLexicalBlockFile *N,
+static void writeDILexicalBlockFile(raw_ostream &Out,
+ const DILexicalBlockFile *N,
TypePrinting *TypePrinter,
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();
+ Out << "!DILexicalBlockFile(";
+ MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
+ Printer.printMetadata("scope", N->getRawScope(), /* ShouldSkipNull */ false);
+ Printer.printMetadata("file", N->getRawFile());
+ Printer.printInt("discriminator", N->getDiscriminator(),
+ /* ShouldSkipZero */ false);
Out << ")";
}
-static void writeMDNamespace(raw_ostream &Out, const MDNamespace *N,
+static void writeDINamespace(raw_ostream &Out, const DINamespace *N,
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();
+ Out << "!DINamespace(";
+ MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
+ Printer.printString("name", N->getName());
+ Printer.printMetadata("scope", N->getRawScope(), /* ShouldSkipNull */ false);
+ Printer.printMetadata("file", N->getRawFile());
+ Printer.printInt("line", N->getLine());
Out << ")";
}
-static void writeMDTemplateTypeParameter(raw_ostream &Out,
- const MDTemplateTypeParameter *N,
+static void writeDITemplateTypeParameter(raw_ostream &Out,
+ const DITemplateTypeParameter *N,
TypePrinting *TypePrinter,
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);
+ Out << "!DITemplateTypeParameter(";
+ MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
+ Printer.printString("name", N->getName());
+ Printer.printMetadata("type", N->getRawType(), /* ShouldSkipNull */ false);
Out << ")";
}
-static void writeMDTemplateValueParameter(raw_ostream &Out,
- const MDTemplateValueParameter *N,
+static void writeDITemplateValueParameter(raw_ostream &Out,
+ const DITemplateValueParameter *N,
TypePrinting *TypePrinter,
SlotTracker *Machine,
const Module *Context) {
- Out << "!MDTemplateValueParameter(";
- FieldSeparator FS;
+ Out << "!DITemplateValueParameter(";
+ 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->getRawType());
+ Printer.printMetadata("value", N->getValue(), /* ShouldSkipNull */ false);
Out << ")";
}
-static void writeMDGlobalVariable(raw_ostream &Out, const MDGlobalVariable *N,
+static void writeDIGlobalVariable(raw_ostream &Out, const DIGlobalVariable *N,
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);
- }
+ Out << "!DIGlobalVariable(";
+ MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
+ Printer.printString("name", N->getName());
+ Printer.printString("linkageName", N->getLinkageName());
+ Printer.printMetadata("scope", N->getRawScope(), /* ShouldSkipNull */ false);
+ Printer.printMetadata("file", N->getRawFile());
+ Printer.printInt("line", N->getLine());
+ Printer.printMetadata("type", N->getRawType());
+ Printer.printBool("isLocal", N->isLocalToUnit());
+ Printer.printBool("isDefinition", N->isDefinition());
+ Printer.printMetadata("variable", N->getRawVariable());
+ Printer.printMetadata("declaration", N->getRawStaticDataMemberDeclaration());
Out << ")";
}
-static void writeMDLocalVariable(raw_ostream &Out, const MDLocalVariable *N,
+static void writeDILocalVariable(raw_ostream &Out, const DILocalVariable *N,
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);
- }
+ Out << "!DILocalVariable(";
+ 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->getRawScope(), /* ShouldSkipNull */ false);
+ Printer.printMetadata("file", N->getRawFile());
+ Printer.printInt("line", N->getLine());
+ Printer.printMetadata("type", N->getRawType());
+ Printer.printDIFlags("flags", N->getFlags());
Out << ")";
}
-static void writeMDExpression(raw_ostream &Out, const MDExpression *N,
+static void writeDIExpression(raw_ostream &Out, const DIExpression *N,
TypePrinting *TypePrinter, SlotTracker *Machine,
const Module *Context) {
- Out << "!MDExpression(";
+ Out << "!DIExpression(";
FieldSeparator FS;
if (N->isValid()) {
for (auto I = N->expr_op_begin(), E = N->expr_op_end(); I != E; ++I) {
Out << ")";
}
-static void writeMDObjCProperty(raw_ostream &Out, const MDObjCProperty *N,
+static void writeDIObjCProperty(raw_ostream &Out, const DIObjCProperty *N,
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);
- }
+ Out << "!DIObjCProperty(";
+ MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
+ Printer.printString("name", N->getName());
+ Printer.printMetadata("file", N->getRawFile());
+ Printer.printInt("line", N->getLine());
+ Printer.printString("setter", N->getSetterName());
+ Printer.printString("getter", N->getGetterName());
+ Printer.printInt("attributes", N->getAttributes());
+ Printer.printMetadata("type", N->getRawType());
Out << ")";
}
-static void writeMDImportedEntity(raw_ostream &Out, const MDImportedEntity *N,
+static void writeDIImportedEntity(raw_ostream &Out, const DIImportedEntity *N,
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();
+ Out << "!DIImportedEntity(";
+ MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
+ Printer.printTag(N);
+ Printer.printString("name", N->getName());
+ Printer.printMetadata("scope", N->getRawScope(), /* ShouldSkipNull */ false);
+ Printer.printMetadata("entity", N->getRawEntity());
+ Printer.printInt("line", N->getLine());
Out << ")";
}
TypePrinting *TypePrinter,
SlotTracker *Machine,
const Module *Context) {
- assert(!Node->isTemporary() && "Unexpected forward declaration");
-
if (Node->isDistinct())
Out << "distinct ";
+ else if (Node->isTemporary())
+ Out << "<temporary!> "; // Handle broken code.
switch (Node->getMetadataID()) {
default:
WriteAsOperandInternal(Out, V->getValue(), TypePrinter, Machine, Context);
}
+namespace {
+class AssemblyWriter {
+ formatted_raw_ostream &Out;
+ const Module *TheModule;
+ std::unique_ptr<SlotTracker> ModuleSlotTracker;
+ SlotTracker &Machine;
+ TypePrinting TypePrinter;
+ AssemblyAnnotationWriter *AnnotationWriter;
+ SetVector<const Comdat *> Comdats;
+ bool ShouldPreserveUseListOrder;
+ UseListOrderStack UseListOrders;
+ SmallVector<StringRef, 8> MDNames;
+
+public:
+ /// Construct an AssemblyWriter with an external SlotTracker
+ AssemblyWriter(formatted_raw_ostream &o, SlotTracker &Mac, const Module *M,
+ AssemblyAnnotationWriter *AAW,
+ bool ShouldPreserveUseListOrder = false);
+
+ /// Construct an AssemblyWriter with an internally allocated SlotTracker
+ AssemblyWriter(formatted_raw_ostream &o, const Module *M,
+ AssemblyAnnotationWriter *AAW,
+ bool ShouldPreserveUseListOrder = false);
+
+ void printMDNodeBody(const MDNode *MD);
+ void printNamedMDNode(const NamedMDNode *NMD);
+
+ void printModule(const Module *M);
+
+ void writeOperand(const Value *Op, bool PrintType);
+ void writeParamOperand(const Value *Operand, AttributeSet Attrs,unsigned Idx);
+ void writeAtomic(AtomicOrdering Ordering, SynchronizationScope SynchScope);
+ void writeAtomicCmpXchg(AtomicOrdering SuccessOrdering,
+ AtomicOrdering FailureOrdering,
+ SynchronizationScope SynchScope);
+
+ void writeAllMDNodes();
+ void writeMDNode(unsigned Slot, const MDNode *Node);
+ void writeAllAttributeGroups();
+
+ void printTypeIdentities();
+ void printGlobal(const GlobalVariable *GV);
+ void printAlias(const GlobalAlias *GV);
+ void printComdat(const Comdat *C);
+ void printFunction(const Function *F);
+ void printArgument(const Argument *FA, AttributeSet Attrs, unsigned Idx);
+ void printBasicBlock(const BasicBlock *BB);
+ void printInstructionLine(const Instruction &I);
+ void printInstruction(const Instruction &I);
+
+ void printUseListOrder(const UseListOrder &Order);
+ void printUseLists(const Function *F);
+
+private:
+ void init();
+
+ /// \brief Print out metadata attachments.
+ void printMetadataAttachments(
+ const SmallVectorImpl<std::pair<unsigned, MDNode *>> &MDs,
+ StringRef Separator);
+
+ // printInfoComment - Print a little comment after the instruction indicating
+ // which slot it occupies.
+ void printInfoComment(const Value &V);
+
+ // printGCRelocateComment - print comment after call to the gc.relocate
+ // intrinsic indicating base and derived pointer names.
+ void printGCRelocateComment(const Value &V);
+};
+} // namespace
+
void AssemblyWriter::init() {
if (!TheModule)
return;
Comdats.insert(C);
}
-
AssemblyWriter::AssemblyWriter(formatted_raw_ostream &o, SlotTracker &Mac,
- const Module *M,
- AssemblyAnnotationWriter *AAW)
- : Out(o), TheModule(M), Machine(Mac), AnnotationWriter(AAW) {
+ const Module *M, AssemblyAnnotationWriter *AAW,
+ bool ShouldPreserveUseListOrder)
+ : Out(o), TheModule(M), Machine(Mac), AnnotationWriter(AAW),
+ ShouldPreserveUseListOrder(ShouldPreserveUseListOrder) {
init();
}
AssemblyWriter::AssemblyWriter(formatted_raw_ostream &o, const Module *M,
- AssemblyAnnotationWriter *AAW)
- : Out(o), TheModule(M), ModuleSlotTracker(createSlotTracker(M)),
- Machine(*ModuleSlotTracker), AnnotationWriter(AAW) {
+ AssemblyAnnotationWriter *AAW,
+ bool ShouldPreserveUseListOrder)
+ : Out(o), TheModule(M), ModuleSlotTracker(createSlotTracker(M)),
+ Machine(*ModuleSlotTracker), AnnotationWriter(AAW),
+ ShouldPreserveUseListOrder(ShouldPreserveUseListOrder) {
init();
}
-AssemblyWriter::~AssemblyWriter() { }
-
void AssemblyWriter::writeOperand(const Value *Operand, bool PrintType) {
if (!Operand) {
Out << "<null operand!>";
void AssemblyWriter::printModule(const Module *M) {
Machine.initialize();
- if (shouldPreserveAssemblyUseListOrder())
+ if (ShouldPreserveUseListOrder)
UseListOrders = predictUseListOrder(M);
if (!M->getModuleIdentifier().empty() &&
Out << "target triple = \"" << M->getTargetTriple() << "\"\n";
if (!M->getModuleInlineAsm().empty()) {
- // Split the string into lines, to make it easier to read the .ll file.
- std::string Asm = M->getModuleInlineAsm();
- size_t CurPos = 0;
- size_t NewLine = Asm.find_first_of('\n', CurPos);
Out << '\n';
- while (NewLine != std::string::npos) {
+
+ // Split the string into lines, to make it easier to read the .ll file.
+ StringRef Asm = M->getModuleInlineAsm();
+ do {
+ StringRef Front;
+ std::tie(Front, Asm) = Asm.split('\n');
+
// We found a newline, print the portion of the asm string from the
// last newline up to this newline.
Out << "module asm \"";
- PrintEscapedString(std::string(Asm.begin()+CurPos, Asm.begin()+NewLine),
- Out);
- Out << "\"\n";
- CurPos = NewLine+1;
- NewLine = Asm.find_first_of('\n', CurPos);
- }
- std::string rest(Asm.begin()+CurPos, Asm.end());
- if (!rest.empty()) {
- Out << "module asm \"";
- PrintEscapedString(rest, Out);
+ PrintEscapedString(Front, Out);
Out << "\"\n";
- }
+ } while (!Asm.empty());
}
printTypeIdentities();
}
}
-void AssemblyWriter::printNamedMDNode(const NamedMDNode *NMD) {
- Out << '!';
- StringRef Name = NMD->getName();
+static void printMetadataIdentifier(StringRef Name,
+ formatted_raw_ostream &Out) {
if (Name.empty()) {
Out << "<empty name> ";
} else {
- if (isalpha(static_cast<unsigned char>(Name[0])) ||
- Name[0] == '-' || Name[0] == '$' ||
- Name[0] == '.' || Name[0] == '_')
+ if (isalpha(static_cast<unsigned char>(Name[0])) || Name[0] == '-' ||
+ Name[0] == '$' || Name[0] == '.' || Name[0] == '_')
Out << Name[0];
else
Out << '\\' << hexdigit(Name[0] >> 4) << hexdigit(Name[0] & 0x0F);
Out << '\\' << hexdigit(C >> 4) << hexdigit(C & 0x0F);
}
}
+}
+
+void AssemblyWriter::printNamedMDNode(const NamedMDNode *NMD) {
+ Out << '!';
+ printMetadataIdentifier(NMD->getName(), Out);
Out << " = !{";
for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) {
- if (i) Out << ", ";
+ if (i)
+ Out << ", ";
int Slot = Machine.getMetadataSlot(NMD->getOperand(i));
if (Slot == -1)
Out << "<badref>";
Out << "}\n";
}
-
static void PrintLinkage(GlobalValue::LinkageTypes LT,
formatted_raw_ostream &Out) {
switch (LT) {
}
}
-
static void PrintVisibility(GlobalValue::VisibilityTypes Vis,
formatted_raw_ostream &Out) {
switch (Vis) {
writeOperand(F->getPrologueData(), true);
}
+ SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
+ F->getAllMetadata(MDs);
+ printMetadataAttachments(MDs, " ");
+
if (F->isDeclaration()) {
Out << '\n';
} else {
Out << '\n';
}
+/// printGCRelocateComment - print comment after call to the gc.relocate
+/// intrinsic indicating base and derived pointer names.
+void AssemblyWriter::printGCRelocateComment(const Value &V) {
+ assert(isGCRelocate(&V));
+ GCRelocateOperands GCOps(cast<Instruction>(&V));
+
+ Out << " ; (";
+ writeOperand(GCOps.getBasePtr(), false);
+ Out << ", ";
+ writeOperand(GCOps.getDerivedPtr(), false);
+ Out << ")";
+}
+
/// printInfoComment - Print a little comment after the instruction indicating
/// which slot it occupies.
///
void AssemblyWriter::printInfoComment(const Value &V) {
+ if (isGCRelocate(&V))
+ printGCRelocateComment(V);
+
if (AnnotationWriter)
AnnotationWriter->printInfoComment(V, Out);
}
}
Operand = CI->getCalledValue();
- PointerType *PTy = cast<PointerType>(Operand->getType());
- FunctionType *FTy = cast<FunctionType>(PTy->getElementType());
+ FunctionType *FTy = cast<FunctionType>(CI->getFunctionType());
Type *RetTy = FTy->getReturnType();
const AttributeSet &PAL = CI->getAttributes();
// and if the return type is not a pointer to a function.
//
Out << ' ';
- if (!FTy->isVarArg() &&
- (!RetTy->isPointerTy() ||
- !cast<PointerType>(RetTy)->getElementType()->isFunctionTy())) {
- TypePrinter.print(RetTy, Out);
- Out << ' ';
- writeOperand(Operand, false);
- } else {
- writeOperand(Operand, true);
- }
+ TypePrinter.print(FTy->isVarArg() ? FTy : RetTy, Out);
+ Out << ' ';
+ writeOperand(Operand, false);
Out << '(';
for (unsigned op = 0, Eop = CI->getNumArgOperands(); op < Eop; ++op) {
if (op > 0)
Out << " #" << Machine.getAttributeGroupSlot(PAL.getFnAttributes());
} else if (const InvokeInst *II = dyn_cast<InvokeInst>(&I)) {
Operand = II->getCalledValue();
- PointerType *PTy = cast<PointerType>(Operand->getType());
- FunctionType *FTy = cast<FunctionType>(PTy->getElementType());
+ FunctionType *FTy = cast<FunctionType>(II->getFunctionType());
Type *RetTy = FTy->getReturnType();
const AttributeSet &PAL = II->getAttributes();
// and if the return type is not a pointer to a function.
//
Out << ' ';
- if (!FTy->isVarArg() &&
- (!RetTy->isPointerTy() ||
- !cast<PointerType>(RetTy)->getElementType()->isFunctionTy())) {
- TypePrinter.print(RetTy, Out);
- Out << ' ';
- writeOperand(Operand, false);
- } else {
- writeOperand(Operand, true);
- }
+ TypePrinter.print(FTy->isVarArg() ? FTy : RetTy, Out);
+ Out << ' ';
+ writeOperand(Operand, false);
Out << '(';
for (unsigned op = 0, Eop = II->getNumArgOperands(); op < Eop; ++op) {
if (op)
// Print Metadata info.
SmallVector<std::pair<unsigned, MDNode *>, 4> InstMD;
I.getAllMetadata(InstMD);
- if (!InstMD.empty()) {
- SmallVector<StringRef, 8> MDNames;
- I.getType()->getContext().getMDKindNames(MDNames);
- for (unsigned i = 0, e = InstMD.size(); i != e; ++i) {
- unsigned Kind = InstMD[i].first;
- if (Kind < MDNames.size()) {
- Out << ", !" << MDNames[Kind];
- } else {
- Out << ", !<unknown kind #" << Kind << ">";
- }
- Out << ' ';
- WriteAsOperandInternal(Out, InstMD[i].second, &TypePrinter, &Machine,
- TheModule);
- }
- }
+ printMetadataAttachments(InstMD, ", ");
+
+ // Print a nice comment.
printInfoComment(I);
}
+void AssemblyWriter::printMetadataAttachments(
+ const SmallVectorImpl<std::pair<unsigned, MDNode *>> &MDs,
+ StringRef Separator) {
+ if (MDs.empty())
+ return;
+
+ if (MDNames.empty())
+ TheModule->getMDKindNames(MDNames);
+
+ for (const auto &I : MDs) {
+ unsigned Kind = I.first;
+ Out << Separator;
+ if (Kind < MDNames.size()) {
+ Out << "!";
+ printMetadataIdentifier(MDNames[Kind], Out);
+ } else
+ Out << "!<unknown kind #" << Kind << ">";
+ Out << ' ';
+ WriteAsOperandInternal(Out, I.second, &TypePrinter, &Machine, TheModule);
+ }
+}
+
void AssemblyWriter::writeMDNode(unsigned Slot, const MDNode *Node) {
Out << '!' << Slot << " = ";
printMDNodeBody(Node);
<< I->first.getAsString(AttributeSet::FunctionIndex, true) << " }\n";
}
-} // namespace llvm
-
void AssemblyWriter::printUseListOrder(const UseListOrder &Order) {
bool IsInFunction = Machine.getFunction();
if (IsInFunction)
// External Interface declarations
//===----------------------------------------------------------------------===//
-void Module::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW) const {
+void Function::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW) const {
+ SlotTracker SlotTable(this->getParent());
+ formatted_raw_ostream OS(ROS);
+ AssemblyWriter W(OS, SlotTable, this->getParent(), AAW);
+ W.printFunction(this);
+}
+
+void Module::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW,
+ bool ShouldPreserveUseListOrder) const {
SlotTracker SlotTable(this);
formatted_raw_ostream OS(ROS);
- AssemblyWriter W(OS, SlotTable, this, AAW);
+ AssemblyWriter W(OS, SlotTable, this, AAW, ShouldPreserveUseListOrder);
W.printModule(this);
}