// We want to visit the functions backward now so we can list function-local
// constants in the last Function they're used in. Module-level constants
// have already been visited above.
- for (auto I = M->rbegin(), E = M->rend(); I != E; ++I) {
- const Function &F = *I;
+ for (const Function &F : make_range(M->rbegin(), M->rend())) {
if (F.isDeclaration())
continue;
for (const BasicBlock &BB : F)
case Type::LabelTyID: OS << "label"; return;
case Type::MetadataTyID: OS << "metadata"; return;
case Type::X86_MMXTyID: OS << "x86_mmx"; return;
+ case Type::TokenTyID: OS << "token"; return;
case Type::IntegerTyID:
OS << 'i' << cast<IntegerType>(Ty)->getBitWidth();
return;
this->F = &F;
}
-static SlotTracker *createSlotTracker(const Module *M) {
- return new SlotTracker(M);
+int ModuleSlotTracker::getLocalSlot(const Value *V) {
+ assert(F && "No function incorporated");
+ return Machine->getLocalSlot(V);
}
static SlotTracker *createSlotTracker(const Value *V) {
ST_DEBUG("begin processFunction!\n");
fNext = 0;
+ // Process function metadata if it wasn't hit at the module-level.
+ if (!ShouldInitializeAllMetadata)
+ processFunctionMetadata(*TheFunction);
+
// Add all the function arguments with no names.
for(Function::const_arg_iterator AI = TheFunction->arg_begin(),
AE = TheFunction->arg_end(); AI != AE; ++AI)
if (!BB.hasName())
CreateFunctionSlot(&BB);
- processFunctionMetadata(*TheFunction);
-
for (auto &I : BB) {
if (!I.getType()->isVoidTy() && !I.hasName())
CreateFunctionSlot(&I);
void SlotTracker::processFunctionMetadata(const Function &F) {
SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
- for (auto &BB : F) {
- F.getAllMetadata(MDs);
- for (auto &MD : MDs)
- CreateMetadataSlot(MD.second);
+ F.getAllMetadata(MDs);
+ for (auto &MD : MDs)
+ CreateMetadataSlot(MD.second);
+ for (auto &BB : F) {
for (auto &I : BB)
processInstructionMetadata(I);
}
Out << " (";
if (const GEPOperator *GEP = dyn_cast<GEPOperator>(CE)) {
- TypePrinter.print(
- cast<PointerType>(GEP->getPointerOperandType()->getScalarType())
- ->getElementType(),
- Out);
+ TypePrinter.print(GEP->getSourceElementType(), Out);
Out << ", ";
}
SlotTracker *Machine, const Module *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.printInt("arg", N->getArg());
Printer.printMetadata("scope", N->getRawScope(), /* ShouldSkipNull */ false);
Printer.printMetadata("file", N->getRawFile());
Printer.printInt("line", N->getLine());
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 printUseLists(const Function *F);
private:
- void init();
-
/// \brief Print out metadata attachments.
void printMetadataAttachments(
const SmallVectorImpl<std::pair<unsigned, MDNode *>> &MDs,
};
} // namespace
-void AssemblyWriter::init() {
+AssemblyWriter::AssemblyWriter(formatted_raw_ostream &o, SlotTracker &Mac,
+ const Module *M, AssemblyAnnotationWriter *AAW,
+ bool ShouldPreserveUseListOrder)
+ : Out(o), TheModule(M), Machine(Mac), AnnotationWriter(AAW),
+ ShouldPreserveUseListOrder(ShouldPreserveUseListOrder) {
if (!TheModule)
return;
TypePrinter.incorporateTypes(*TheModule);
Comdats.insert(C);
}
-AssemblyWriter::AssemblyWriter(formatted_raw_ostream &o, SlotTracker &Mac,
- 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,
- bool ShouldPreserveUseListOrder)
- : Out(o), TheModule(M), SlotTrackerStorage(createSlotTracker(M)),
- Machine(*SlotTrackerStorage), AnnotationWriter(AAW),
- ShouldPreserveUseListOrder(ShouldPreserveUseListOrder) {
- init();
-}
-
void AssemblyWriter::writeOperand(const Value *Operand, bool PrintType) {
if (!Operand) {
Out << "<null operand!>";
Out << "alias ";
+ TypePrinter.print(GA->getValueType(), Out);
+
+ Out << ", ";
+
const Constant *Aliasee = GA->getAliasee();
if (!Aliasee) {
Machine.incorporateFunction(F);
// Loop over the arguments, printing them...
-
- unsigned Idx = 1;
- if (!F->isDeclaration()) {
- // If this isn't a declaration, print the argument names as well.
- for (Function::const_arg_iterator I = F->arg_begin(), E = F->arg_end();
- I != E; ++I) {
+ if (F->isDeclaration()) {
+ // We're only interested in the type here - don't print argument names.
+ for (unsigned I = 0, E = FT->getNumParams(); I != E; ++I) {
// Insert commas as we go... the first arg doesn't get a comma
- if (I != F->arg_begin()) Out << ", ";
- printArgument(I, Attrs, Idx);
- Idx++;
+ if (I)
+ Out << ", ";
+ // Output type...
+ TypePrinter.print(FT->getParamType(I), Out);
+
+ if (Attrs.hasAttributes(I + 1))
+ Out << ' ' << Attrs.getAsString(I + 1);
}
} else {
- // Otherwise, print the types from the function type.
- for (unsigned i = 0, e = FT->getNumParams(); i != e; ++i) {
+ // The arguments are meaningful here, print them in detail.
+ unsigned Idx = 1;
+ for (const Argument &Arg : F->args()) {
// Insert commas as we go... the first arg doesn't get a comma
- if (i) Out << ", ";
-
- // Output type...
- TypePrinter.print(FT->getParamType(i), Out);
-
- if (Attrs.hasAttributes(i+1))
- Out << ' ' << Attrs.getAsString(i+1);
+ if (Idx != 1)
+ Out << ", ";
+ printArgument(&Arg, Attrs, Idx++);
}
}
writeOperand(LPI->getClause(i), true);
}
+ } else if (const auto *CPI = dyn_cast<CatchPadInst>(&I)) {
+ Out << " [";
+ for (unsigned Op = 0, NumOps = CPI->getNumArgOperands(); Op < NumOps;
+ ++Op) {
+ if (Op > 0)
+ Out << ", ";
+ writeOperand(CPI->getArgOperand(Op), /*PrintType=*/true);
+ }
+ Out << "]\n to ";
+ writeOperand(CPI->getNormalDest(), /*PrintType=*/true);
+ Out << " unwind ";
+ writeOperand(CPI->getUnwindDest(), /*PrintType=*/true);
+ } else if (const auto *TPI = dyn_cast<TerminatePadInst>(&I)) {
+ Out << " [";
+ for (unsigned Op = 0, NumOps = TPI->getNumArgOperands(); Op < NumOps;
+ ++Op) {
+ if (Op > 0)
+ Out << ", ";
+ writeOperand(TPI->getArgOperand(Op), /*PrintType=*/true);
+ }
+ Out << "] unwind ";
+ if (TPI->hasUnwindDest())
+ writeOperand(TPI->getUnwindDest(), /*PrintType=*/true);
+ else
+ Out << "to caller";
+ } else if (const auto *CPI = dyn_cast<CleanupPadInst>(&I)) {
+ Out << " [";
+ for (unsigned Op = 0, NumOps = CPI->getNumOperands(); Op < NumOps; ++Op) {
+ if (Op > 0)
+ Out << ", ";
+ writeOperand(CPI->getOperand(Op), /*PrintType=*/true);
+ }
+ Out << "]";
} else if (isa<ReturnInst>(I) && !Operand) {
Out << " void";
+ } else if (const auto *CRI = dyn_cast<CatchReturnInst>(&I)) {
+ Out << ' ';
+ writeOperand(CRI->getCatchPad(), /*PrintType=*/false);
+
+ Out << " to ";
+ writeOperand(CRI->getSuccessor(), /*PrintType=*/true);
+ } else if (const auto *CRI = dyn_cast<CleanupReturnInst>(&I)) {
+ Out << ' ';
+ writeOperand(CRI->getCleanupPad(), /*PrintType=*/false);
+
+ Out << " unwind ";
+ if (CRI->hasUnwindDest())
+ writeOperand(CRI->getUnwindDest(), /*PrintType=*/true);
+ else
+ Out << "to caller";
+ } else if (const auto *CEPI = dyn_cast<CatchEndPadInst>(&I)) {
+ Out << " unwind ";
+ if (CEPI->hasUnwindDest())
+ writeOperand(CEPI->getUnwindDest(), /*PrintType=*/true);
+ else
+ Out << "to caller";
+ } else if (const auto *CEPI = dyn_cast<CleanupEndPadInst>(&I)) {
+ Out << ' ';
+ writeOperand(CEPI->getCleanupPad(), /*PrintType=*/false);
+
+ Out << " unwind ";
+ if (CEPI->hasUnwindDest())
+ writeOperand(CEPI->getUnwindDest(), /*PrintType=*/true);
+ else
+ Out << "to caller";
} else if (const CallInst *CI = dyn_cast<CallInst>(&I)) {
// Print the calling convention being used.
if (CI->getCallingConv() != CallingConv::C) {
// External Interface declarations
//===----------------------------------------------------------------------===//
-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);
/// Print without a type, skipping the TypePrinting object.
///
-/// \return \c true iff printing was succesful.
+/// \return \c true iff printing was successful.
static bool printWithoutType(const Value &V, raw_ostream &O,
SlotTracker *Machine, const Module *M) {
if (V.hasName() || isa<GlobalValue>(V) ||