LLVM 17.0.0git
MCFragment.cpp
Go to the documentation of this file.
1//===- lib/MC/MCFragment.cpp - Assembler Fragment Implementation ----------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
12#include "llvm/ADT/Twine.h"
13#include "llvm/Config/llvm-config.h"
14#include "llvm/MC/MCAsmLayout.h"
15#include "llvm/MC/MCAssembler.h"
16#include "llvm/MC/MCContext.h"
17#include "llvm/MC/MCExpr.h"
18#include "llvm/MC/MCFixup.h"
19#include "llvm/MC/MCSection.h"
20#include "llvm/MC/MCSymbol.h"
21#include "llvm/MC/MCValue.h"
26#include <cassert>
27#include <cstdint>
28#include <utility>
29
30using namespace llvm;
31
32MCAsmLayout::MCAsmLayout(MCAssembler &Asm) : Assembler(Asm) {
33 // Compute the section layout order. Virtual sections must go last.
34 for (MCSection &Sec : Asm)
35 if (!Sec.isVirtualSection())
36 SectionOrder.push_back(&Sec);
37 for (MCSection &Sec : Asm)
38 if (Sec.isVirtualSection())
39 SectionOrder.push_back(&Sec);
40}
41
42bool MCAsmLayout::isFragmentValid(const MCFragment *F) const {
43 const MCSection *Sec = F->getParent();
44 const MCFragment *LastValid = LastValidFragment.lookup(Sec);
45 if (!LastValid)
46 return false;
47 assert(LastValid->getParent() == Sec);
48 return F->getLayoutOrder() <= LastValid->getLayoutOrder();
49}
50
52 MCSection *Sec = F->getParent();
54 if (MCFragment *LastValid = LastValidFragment[Sec]) {
55 // Fragment already valid, offset is available.
56 if (F->getLayoutOrder() <= LastValid->getLayoutOrder())
57 return true;
58 I = ++MCSection::iterator(LastValid);
59 } else
60 I = Sec->begin();
61
62 // A fragment ordered before F is currently being laid out.
63 const MCFragment *FirstInvalidFragment = &*I;
64 if (FirstInvalidFragment->IsBeingLaidOut)
65 return false;
66
67 return true;
68}
69
71 // If this fragment wasn't already valid, we don't need to do anything.
72 if (!isFragmentValid(F))
73 return;
74
75 // Otherwise, reset the last valid fragment to the previous fragment
76 // (if this is the first fragment, it will be NULL).
77 LastValidFragment[F->getParent()] = F->getPrevNode();
78}
79
80void MCAsmLayout::ensureValid(const MCFragment *F) const {
81 MCSection *Sec = F->getParent();
83 if (MCFragment *Cur = LastValidFragment[Sec])
84 I = ++MCSection::iterator(Cur);
85 else
86 I = Sec->begin();
87
88 // Advance the layout position until the fragment is valid.
89 while (!isFragmentValid(F)) {
90 assert(I != Sec->end() && "Layout bookkeeping error");
91 const_cast<MCAsmLayout *>(this)->layoutFragment(&*I);
92 ++I;
93 }
94}
95
97 ensureValid(F);
98 assert(F->Offset != ~UINT64_C(0) && "Address not set!");
99 return F->Offset;
100}
101
102// Simple getSymbolOffset helper for the non-variable case.
103static bool getLabelOffset(const MCAsmLayout &Layout, const MCSymbol &S,
104 bool ReportError, uint64_t &Val) {
105 if (!S.getFragment()) {
106 if (ReportError)
107 report_fatal_error("unable to evaluate offset to undefined symbol '" +
108 S.getName() + "'");
109 return false;
110 }
111 Val = Layout.getFragmentOffset(S.getFragment()) + S.getOffset();
112 return true;
113}
114
115static bool getSymbolOffsetImpl(const MCAsmLayout &Layout, const MCSymbol &S,
116 bool ReportError, uint64_t &Val) {
117 if (!S.isVariable())
118 return getLabelOffset(Layout, S, ReportError, Val);
119
120 // If SD is a variable, evaluate it.
122 if (!S.getVariableValue()->evaluateAsValue(Target, Layout))
123 report_fatal_error("unable to evaluate offset for variable '" +
124 S.getName() + "'");
125
126 uint64_t Offset = Target.getConstant();
127
128 const MCSymbolRefExpr *A = Target.getSymA();
129 if (A) {
130 uint64_t ValA;
131 // FIXME: On most platforms, `Target`'s component symbols are labels from
132 // having been simplified during evaluation, but on Mach-O they can be
133 // variables due to PR19203. This, and the line below for `B` can be
134 // restored to call `getLabelOffset` when PR19203 is fixed.
135 if (!getSymbolOffsetImpl(Layout, A->getSymbol(), ReportError, ValA))
136 return false;
137 Offset += ValA;
138 }
139
140 const MCSymbolRefExpr *B = Target.getSymB();
141 if (B) {
142 uint64_t ValB;
143 if (!getSymbolOffsetImpl(Layout, B->getSymbol(), ReportError, ValB))
144 return false;
145 Offset -= ValB;
146 }
147
148 Val = Offset;
149 return true;
150}
151
153 return getSymbolOffsetImpl(*this, S, false, Val);
154}
155
157 uint64_t Val;
158 getSymbolOffsetImpl(*this, S, true, Val);
159 return Val;
160}
161
162const MCSymbol *MCAsmLayout::getBaseSymbol(const MCSymbol &Symbol) const {
163 if (!Symbol.isVariable())
164 return &Symbol;
165
166 const MCExpr *Expr = Symbol.getVariableValue();
168 if (!Expr->evaluateAsValue(Value, *this)) {
169 Assembler.getContext().reportError(
170 Expr->getLoc(), "expression could not be evaluated");
171 return nullptr;
172 }
173
174 const MCSymbolRefExpr *RefB = Value.getSymB();
175 if (RefB) {
176 Assembler.getContext().reportError(
177 Expr->getLoc(), Twine("symbol '") + RefB->getSymbol().getName() +
178 "' could not be evaluated in a subtraction expression");
179 return nullptr;
180 }
181
182 const MCSymbolRefExpr *A = Value.getSymA();
183 if (!A)
184 return nullptr;
185
186 const MCSymbol &ASym = A->getSymbol();
187 const MCAssembler &Asm = getAssembler();
188 if (ASym.isCommon()) {
189 Asm.getContext().reportError(Expr->getLoc(),
190 "Common symbol '" + ASym.getName() +
191 "' cannot be used in assignment expr");
192 return nullptr;
193 }
194
195 return &ASym;
196}
197
199 // The size is the last fragment's end offset.
200 const MCFragment &F = Sec->getFragmentList().back();
202}
203
205 // Virtual sections have no file size.
206 if (Sec->isVirtualSection())
207 return 0;
208
209 // Otherwise, the file size is the same as the address space size.
210 return getSectionAddressSize(Sec);
211}
212
214 const MCEncodedFragment *F,
215 uint64_t FOffset, uint64_t FSize) {
216 uint64_t BundleSize = Assembler.getBundleAlignSize();
217 assert(BundleSize > 0 &&
218 "computeBundlePadding should only be called if bundling is enabled");
219 uint64_t BundleMask = BundleSize - 1;
220 uint64_t OffsetInBundle = FOffset & BundleMask;
221 uint64_t EndOfFragment = OffsetInBundle + FSize;
222
223 // There are two kinds of bundling restrictions:
224 //
225 // 1) For alignToBundleEnd(), add padding to ensure that the fragment will
226 // *end* on a bundle boundary.
227 // 2) Otherwise, check if the fragment would cross a bundle boundary. If it
228 // would, add padding until the end of the bundle so that the fragment
229 // will start in a new one.
230 if (F->alignToBundleEnd()) {
231 // Three possibilities here:
232 //
233 // A) The fragment just happens to end at a bundle boundary, so we're good.
234 // B) The fragment ends before the current bundle boundary: pad it just
235 // enough to reach the boundary.
236 // C) The fragment ends after the current bundle boundary: pad it until it
237 // reaches the end of the next bundle boundary.
238 //
239 // Note: this code could be made shorter with some modulo trickery, but it's
240 // intentionally kept in its more explicit form for simplicity.
241 if (EndOfFragment == BundleSize)
242 return 0;
243 else if (EndOfFragment < BundleSize)
244 return BundleSize - EndOfFragment;
245 else { // EndOfFragment > BundleSize
246 return 2 * BundleSize - EndOfFragment;
247 }
248 } else if (OffsetInBundle > 0 && EndOfFragment > BundleSize)
249 return BundleSize - OffsetInBundle;
250 else
251 return 0;
252}
253
254/* *** */
255
257
258MCFragment::MCFragment(FragmentType Kind, bool HasInstructions,
259 MCSection *Parent)
260 : Parent(Parent), Atom(nullptr), Offset(~UINT64_C(0)), LayoutOrder(0),
261 Kind(Kind), IsBeingLaidOut(false), HasInstructions(HasInstructions) {
262 if (Parent && !isa<MCDummyFragment>(*this))
263 Parent->getFragmentList().push_back(this);
264}
265
267 // First check if we are the sentinal.
268 if (Kind == FragmentType(~0)) {
269 delete this;
270 return;
271 }
272
273 switch (Kind) {
274 case FT_Align:
275 delete cast<MCAlignFragment>(this);
276 return;
277 case FT_Data:
278 delete cast<MCDataFragment>(this);
279 return;
281 delete cast<MCCompactEncodedInstFragment>(this);
282 return;
283 case FT_Fill:
284 delete cast<MCFillFragment>(this);
285 return;
286 case FT_Nops:
287 delete cast<MCNopsFragment>(this);
288 return;
289 case FT_Relaxable:
290 delete cast<MCRelaxableFragment>(this);
291 return;
292 case FT_Org:
293 delete cast<MCOrgFragment>(this);
294 return;
295 case FT_Dwarf:
296 delete cast<MCDwarfLineAddrFragment>(this);
297 return;
298 case FT_DwarfFrame:
299 delete cast<MCDwarfCallFrameFragment>(this);
300 return;
301 case FT_LEB:
302 delete cast<MCLEBFragment>(this);
303 return;
304 case FT_BoundaryAlign:
305 delete cast<MCBoundaryAlignFragment>(this);
306 return;
307 case FT_SymbolId:
308 delete cast<MCSymbolIdFragment>(this);
309 return;
310 case FT_CVInlineLines:
311 delete cast<MCCVInlineLineTableFragment>(this);
312 return;
313 case FT_CVDefRange:
314 delete cast<MCCVDefRangeFragment>(this);
315 return;
316 case FT_PseudoProbe:
317 delete cast<MCPseudoProbeAddrFragment>(this);
318 return;
319 case FT_Dummy:
320 delete cast<MCDummyFragment>(this);
321 return;
322 }
323}
324
325// Debugging methods
326
327namespace llvm {
328
330 OS << "<MCFixup" << " Offset:" << AF.getOffset()
331 << " Value:" << *AF.getValue()
332 << " Kind:" << AF.getKind() << ">";
333 return OS;
334}
335
336} // end namespace llvm
337
338#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
340 raw_ostream &OS = errs();
341
342 OS << "<";
343 switch (getKind()) {
344 case MCFragment::FT_Align: OS << "MCAlignFragment"; break;
345 case MCFragment::FT_Data: OS << "MCDataFragment"; break;
347 OS << "MCCompactEncodedInstFragment"; break;
348 case MCFragment::FT_Fill: OS << "MCFillFragment"; break;
350 OS << "MCFNopsFragment";
351 break;
352 case MCFragment::FT_Relaxable: OS << "MCRelaxableFragment"; break;
353 case MCFragment::FT_Org: OS << "MCOrgFragment"; break;
354 case MCFragment::FT_Dwarf: OS << "MCDwarfFragment"; break;
355 case MCFragment::FT_DwarfFrame: OS << "MCDwarfCallFrameFragment"; break;
356 case MCFragment::FT_LEB: OS << "MCLEBFragment"; break;
357 case MCFragment::FT_BoundaryAlign: OS<<"MCBoundaryAlignFragment"; break;
358 case MCFragment::FT_SymbolId: OS << "MCSymbolIdFragment"; break;
359 case MCFragment::FT_CVInlineLines: OS << "MCCVInlineLineTableFragment"; break;
360 case MCFragment::FT_CVDefRange: OS << "MCCVDefRangeTableFragment"; break;
362 OS << "MCPseudoProbe";
363 break;
364 case MCFragment::FT_Dummy: OS << "MCDummyFragment"; break;
365 }
366
367 OS << "<MCFragment " << (const void *)this << " LayoutOrder:" << LayoutOrder
368 << " Offset:" << Offset << " HasInstructions:" << hasInstructions();
369 if (const auto *EF = dyn_cast<MCEncodedFragment>(this))
370 OS << " BundlePadding:" << static_cast<unsigned>(EF->getBundlePadding());
371 OS << ">";
372
373 switch (getKind()) {
375 const auto *AF = cast<MCAlignFragment>(this);
376 if (AF->hasEmitNops())
377 OS << " (emit nops)";
378 OS << "\n ";
379 OS << " Alignment:" << AF->getAlignment().value()
380 << " Value:" << AF->getValue() << " ValueSize:" << AF->getValueSize()
381 << " MaxBytesToEmit:" << AF->getMaxBytesToEmit() << ">";
382 break;
383 }
384 case MCFragment::FT_Data: {
385 const auto *DF = cast<MCDataFragment>(this);
386 OS << "\n ";
387 OS << " Contents:[";
388 const SmallVectorImpl<char> &Contents = DF->getContents();
389 for (unsigned i = 0, e = Contents.size(); i != e; ++i) {
390 if (i) OS << ",";
391 OS << hexdigit((Contents[i] >> 4) & 0xF) << hexdigit(Contents[i] & 0xF);
392 }
393 OS << "] (" << Contents.size() << " bytes)";
394
395 if (DF->fixup_begin() != DF->fixup_end()) {
396 OS << ",\n ";
397 OS << " Fixups:[";
398 for (MCDataFragment::const_fixup_iterator it = DF->fixup_begin(),
399 ie = DF->fixup_end(); it != ie; ++it) {
400 if (it != DF->fixup_begin()) OS << ",\n ";
401 OS << *it;
402 }
403 OS << "]";
404 }
405 break;
406 }
408 const auto *CEIF =
409 cast<MCCompactEncodedInstFragment>(this);
410 OS << "\n ";
411 OS << " Contents:[";
412 const SmallVectorImpl<char> &Contents = CEIF->getContents();
413 for (unsigned i = 0, e = Contents.size(); i != e; ++i) {
414 if (i) OS << ",";
415 OS << hexdigit((Contents[i] >> 4) & 0xF) << hexdigit(Contents[i] & 0xF);
416 }
417 OS << "] (" << Contents.size() << " bytes)";
418 break;
419 }
420 case MCFragment::FT_Fill: {
421 const auto *FF = cast<MCFillFragment>(this);
422 OS << " Value:" << static_cast<unsigned>(FF->getValue())
423 << " ValueSize:" << static_cast<unsigned>(FF->getValueSize())
424 << " NumValues:" << FF->getNumValues();
425 break;
426 }
427 case MCFragment::FT_Nops: {
428 const auto *NF = cast<MCNopsFragment>(this);
429 OS << " NumBytes:" << NF->getNumBytes()
430 << " ControlledNopLength:" << NF->getControlledNopLength();
431 break;
432 }
434 const auto *F = cast<MCRelaxableFragment>(this);
435 OS << "\n ";
436 OS << " Inst:";
437 F->getInst().dump_pretty(OS);
438 OS << " (" << F->getContents().size() << " bytes)";
439 break;
440 }
441 case MCFragment::FT_Org: {
442 const auto *OF = cast<MCOrgFragment>(this);
443 OS << "\n ";
444 OS << " Offset:" << OF->getOffset()
445 << " Value:" << static_cast<unsigned>(OF->getValue());
446 break;
447 }
449 const auto *OF = cast<MCDwarfLineAddrFragment>(this);
450 OS << "\n ";
451 OS << " AddrDelta:" << OF->getAddrDelta()
452 << " LineDelta:" << OF->getLineDelta();
453 break;
454 }
456 const auto *CF = cast<MCDwarfCallFrameFragment>(this);
457 OS << "\n ";
458 OS << " AddrDelta:" << CF->getAddrDelta();
459 break;
460 }
461 case MCFragment::FT_LEB: {
462 const auto *LF = cast<MCLEBFragment>(this);
463 OS << "\n ";
464 OS << " Value:" << LF->getValue() << " Signed:" << LF->isSigned();
465 break;
466 }
468 const auto *BF = cast<MCBoundaryAlignFragment>(this);
469 OS << "\n ";
470 OS << " BoundarySize:" << BF->getAlignment().value()
471 << " LastFragment:" << BF->getLastFragment()
472 << " Size:" << BF->getSize();
473 break;
474 }
476 const auto *F = cast<MCSymbolIdFragment>(this);
477 OS << "\n ";
478 OS << " Sym:" << F->getSymbol();
479 break;
480 }
482 const auto *F = cast<MCCVInlineLineTableFragment>(this);
483 OS << "\n ";
484 OS << " Sym:" << *F->getFnStartSym();
485 break;
486 }
488 const auto *F = cast<MCCVDefRangeFragment>(this);
489 OS << "\n ";
490 for (std::pair<const MCSymbol *, const MCSymbol *> RangeStartEnd :
491 F->getRanges()) {
492 OS << " RangeStart:" << RangeStartEnd.first;
493 OS << " RangeEnd:" << RangeStartEnd.second;
494 }
495 break;
496 }
498 const auto *OF = cast<MCPseudoProbeAddrFragment>(this);
499 OS << "\n ";
500 OS << " AddrDelta:" << OF->getAddrDelta();
501 break;
502 }
504 break;
505 }
506 OS << ">";
507}
508#endif
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Definition: Compiler.h:492
static RegisterPass< DebugifyFunctionPass > DF("debugify-function", "Attach debug info to a function")
static bool getSymbolOffsetImpl(const MCAsmLayout &Layout, const MCSymbol &S, bool ReportError, uint64_t &Val)
Definition: MCFragment.cpp:115
static bool getLabelOffset(const MCAsmLayout &Layout, const MCSymbol &S, bool ReportError, uint64_t &Val)
Definition: MCFragment.cpp:103
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
This file contains some functions that are useful when dealing with strings.
Encapsulates the layout of an assembly file at a particular point in time.
Definition: MCAsmLayout.h:28
void invalidateFragmentsFrom(MCFragment *F)
Invalidate the fragments starting with F because it has been resized.
Definition: MCFragment.cpp:70
const MCSymbol * getBaseSymbol(const MCSymbol &Symbol) const
If this symbol is equivalent to A + Constant, return A.
Definition: MCFragment.cpp:162
uint64_t getSectionAddressSize(const MCSection *Sec) const
Get the address space size of the given section, as it effects layout.
Definition: MCFragment.cpp:198
uint64_t getSectionFileSize(const MCSection *Sec) const
Get the data size of the given section, as emitted to the object file.
Definition: MCFragment.cpp:204
bool getSymbolOffset(const MCSymbol &S, uint64_t &Val) const
Get the offset of the given symbol, as computed in the current layout.
Definition: MCFragment.cpp:152
MCAsmLayout(MCAssembler &Assembler)
Definition: MCFragment.cpp:32
void layoutFragment(MCFragment *Fragment)
Perform layout for a single fragment, assuming that the previous fragment has already been laid out c...
uint64_t getFragmentOffset(const MCFragment *F) const
Get the offset of the given fragment inside its containing section.
Definition: MCFragment.cpp:96
bool canGetFragmentOffset(const MCFragment *F) const
Definition: MCFragment.cpp:51
MCAssembler & getAssembler() const
Get the assembler object this is a layout for.
Definition: MCAsmLayout.h:50
MCContext & getContext() const
Definition: MCAssembler.h:321
unsigned getBundleAlignSize() const
Definition: MCAssembler.h:362
uint64_t computeFragmentSize(const MCAsmLayout &Layout, const MCFragment &F) const
Compute the effective fragment size assuming it is laid out at the given SectionAddress and FragmentO...
void reportError(SMLoc L, const Twine &Msg)
Definition: MCContext.cpp:1055
SmallVectorImpl< MCFixup >::const_iterator const_fixup_iterator
Definition: MCFragment.h:219
Interface implemented by fragments that contain encoded instructions and/or data.
Definition: MCFragment.h:124
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:35
bool evaluateAsValue(MCValue &Res, const MCAsmLayout &Layout) const
Try to evaluate the expression to the form (a - b + constant) where neither a nor b are variables.
Definition: MCExpr.cpp:757
SMLoc getLoc() const
Definition: MCExpr.h:82
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
Definition: MCFixup.h:71
const MCExpr * getValue() const
Definition: MCFixup.h:105
uint32_t getOffset() const
Definition: MCFixup.h:102
MCFixupKind getKind() const
Definition: MCFixup.h:98
FragmentType getKind() const
Definition: MCFragment.h:93
MCFragment()=delete
unsigned getLayoutOrder() const
Definition: MCFragment.h:101
void destroy()
Destroys the current fragment.
Definition: MCFragment.cpp:266
void dump() const
Definition: MCFragment.cpp:339
MCSection * getParent() const
Definition: MCFragment.h:95
bool hasInstructions() const
Does this fragment have instructions emitted into it? By default this is false, but specific fragment...
Definition: MCFragment.h:106
Instances of this class represent a uniqued identifier for a section in the current translation unit.
Definition: MCSection.h:39
MCSection::FragmentListType & getFragmentList()
Definition: MCSection.h:172
virtual bool isVirtualSection() const =0
Check whether this section is "virtual", that is has no actual object file contents.
FragmentListType::iterator iterator
Definition: MCSection.h:64
iterator begin()
Definition: MCSection.h:185
Represent a reference to a symbol from inside an expression.
Definition: MCExpr.h:192
const MCSymbol & getSymbol() const
Definition: MCExpr.h:399
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
const MCExpr * getVariableValue(bool SetUsed=true) const
getVariableValue - Get the value for variable symbols.
Definition: MCSymbol.h:303
bool isCommon() const
Is this a 'common' symbol.
Definition: MCSymbol.h:385
StringRef getName() const
getName - Get the symbol name.
Definition: MCSymbol.h:203
bool isVariable() const
isVariable - Check if this is a variable symbol.
Definition: MCSymbol.h:298
uint64_t getOffset() const
Definition: MCSymbol.h:325
MCFragment * getFragment(bool SetUsed=true) const
Definition: MCSymbol.h:395
This represents an "assembler immediate".
Definition: MCValue.h:36
size_t size() const
Definition: SmallVector.h:91
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:577
Target - Wrapper for Target specific information.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
LLVM Value Representation.
Definition: Value.h:74
void push_back(pointer val)
Definition: ilist.h:314
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:406
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:145
uint64_t computeBundlePadding(const MCAssembler &Assembler, const MCEncodedFragment *F, uint64_t FOffset, uint64_t FSize)
Compute the amount of padding required before the fragment F to obey bundling restrictions,...
Definition: MCFragment.cpp:213
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
Definition: APFixedPoint.h:292
static void deleteNode(NodeTy *V)
Definition: ilist.h:42