1 //===- lib/MC/MCContext.cpp - Machine Code Context ------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "llvm/MC/MCContext.h"
11 #include "llvm/ADT/SmallString.h"
12 #include "llvm/ADT/Twine.h"
13 #include "llvm/MC/MCAsmInfo.h"
14 #include "llvm/MC/MCAssembler.h"
15 #include "llvm/MC/MCCodeView.h"
16 #include "llvm/MC/MCDwarf.h"
17 #include "llvm/MC/MCLabel.h"
18 #include "llvm/MC/MCObjectFileInfo.h"
19 #include "llvm/MC/MCRegisterInfo.h"
20 #include "llvm/MC/MCSectionCOFF.h"
21 #include "llvm/MC/MCSectionELF.h"
22 #include "llvm/MC/MCSectionMachO.h"
23 #include "llvm/MC/MCStreamer.h"
24 #include "llvm/MC/MCSymbolCOFF.h"
25 #include "llvm/MC/MCSymbolELF.h"
26 #include "llvm/MC/MCSymbolMachO.h"
27 #include "llvm/Support/COFF.h"
28 #include "llvm/Support/CommandLine.h"
29 #include "llvm/Support/ELF.h"
30 #include "llvm/Support/ErrorHandling.h"
31 #include "llvm/Support/MemoryBuffer.h"
32 #include "llvm/Support/Signals.h"
33 #include "llvm/Support/SourceMgr.h"
34
35 using namespace llvm;
36
37 static cl::opt<char*>
38 AsSecureLogFileName("as-secure-log-file-name",
39 cl::desc("As secure log file name (initialized from "
40 "AS_SECURE_LOG_FILE env variable)"),
41 cl::init(getenv("AS_SECURE_LOG_FILE")), cl::Hidden);
42
43
MCContext(const MCAsmInfo * mai,const MCRegisterInfo * mri,const MCObjectFileInfo * mofi,const SourceMgr * mgr,bool DoAutoReset)44 MCContext::MCContext(const MCAsmInfo *mai, const MCRegisterInfo *mri,
45 const MCObjectFileInfo *mofi, const SourceMgr *mgr,
46 bool DoAutoReset)
47 : SrcMgr(mgr), MAI(mai), MRI(mri), MOFI(mofi), Allocator(),
48 Symbols(Allocator), UsedNames(Allocator),
49 CurrentDwarfLoc(0, 0, 0, DWARF2_FLAG_IS_STMT, 0, 0), DwarfLocSeen(false),
50 GenDwarfForAssembly(false), GenDwarfFileNumber(0), DwarfVersion(4),
51 AllowTemporaryLabels(true), DwarfCompileUnitID(0),
52 AutoReset(DoAutoReset), HadError(false) {
53 SecureLogFile = AsSecureLogFileName;
54 SecureLog = nullptr;
55 SecureLogUsed = false;
56
57 if (SrcMgr && SrcMgr->getNumBuffers())
58 MainFileName =
59 SrcMgr->getMemoryBuffer(SrcMgr->getMainFileID())->getBufferIdentifier();
60 }
61
~MCContext()62 MCContext::~MCContext() {
63 if (AutoReset)
64 reset();
65
66 // NOTE: The symbols are all allocated out of a bump pointer allocator,
67 // we don't need to free them here.
68 }
69
70 //===----------------------------------------------------------------------===//
71 // Module Lifetime Management
72 //===----------------------------------------------------------------------===//
73
reset()74 void MCContext::reset() {
75 // Call the destructors so the fragments are freed
76 COFFAllocator.DestroyAll();
77 ELFAllocator.DestroyAll();
78 MachOAllocator.DestroyAll();
79
80 MCSubtargetAllocator.DestroyAll();
81 UsedNames.clear();
82 Symbols.clear();
83 SectionSymbols.clear();
84 Allocator.Reset();
85 Instances.clear();
86 CompilationDir.clear();
87 MainFileName.clear();
88 MCDwarfLineTablesCUMap.clear();
89 SectionsForRanges.clear();
90 MCGenDwarfLabelEntries.clear();
91 DwarfDebugFlags = StringRef();
92 DwarfCompileUnitID = 0;
93 CurrentDwarfLoc = MCDwarfLoc(0, 0, 0, DWARF2_FLAG_IS_STMT, 0, 0);
94
95 CVContext.reset();
96
97 MachOUniquingMap.clear();
98 ELFUniquingMap.clear();
99 COFFUniquingMap.clear();
100
101 NextID.clear();
102 AllowTemporaryLabels = true;
103 DwarfLocSeen = false;
104 GenDwarfForAssembly = false;
105 GenDwarfFileNumber = 0;
106
107 HadError = false;
108 }
109
110 //===----------------------------------------------------------------------===//
111 // Symbol Manipulation
112 //===----------------------------------------------------------------------===//
113
getOrCreateSymbol(const Twine & Name)114 MCSymbol *MCContext::getOrCreateSymbol(const Twine &Name) {
115 SmallString<128> NameSV;
116 StringRef NameRef = Name.toStringRef(NameSV);
117
118 assert(!NameRef.empty() && "Normal symbols cannot be unnamed!");
119
120 MCSymbol *&Sym = Symbols[NameRef];
121 if (!Sym)
122 Sym = createSymbol(NameRef, false, false);
123
124 return Sym;
125 }
126
getOrCreateSectionSymbol(const MCSectionELF & Section)127 MCSymbolELF *MCContext::getOrCreateSectionSymbol(const MCSectionELF &Section) {
128 MCSymbolELF *&Sym = SectionSymbols[&Section];
129 if (Sym)
130 return Sym;
131
132 StringRef Name = Section.getSectionName();
133 auto NameIter = UsedNames.insert(std::make_pair(Name, false)).first;
134 Sym = new (&*NameIter, *this) MCSymbolELF(&*NameIter, /*isTemporary*/ false);
135
136 return Sym;
137 }
138
getOrCreateFrameAllocSymbol(StringRef FuncName,unsigned Idx)139 MCSymbol *MCContext::getOrCreateFrameAllocSymbol(StringRef FuncName,
140 unsigned Idx) {
141 return getOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix()) + FuncName +
142 "$frame_escape_" + Twine(Idx));
143 }
144
getOrCreateParentFrameOffsetSymbol(StringRef FuncName)145 MCSymbol *MCContext::getOrCreateParentFrameOffsetSymbol(StringRef FuncName) {
146 return getOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix()) + FuncName +
147 "$parent_frame_offset");
148 }
149
getOrCreateLSDASymbol(StringRef FuncName)150 MCSymbol *MCContext::getOrCreateLSDASymbol(StringRef FuncName) {
151 return getOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix()) + "__ehtable$" +
152 FuncName);
153 }
154
createSymbolImpl(const StringMapEntry<bool> * Name,bool IsTemporary)155 MCSymbol *MCContext::createSymbolImpl(const StringMapEntry<bool> *Name,
156 bool IsTemporary) {
157 if (MOFI) {
158 switch (MOFI->getObjectFileType()) {
159 case MCObjectFileInfo::IsCOFF:
160 return new (Name, *this) MCSymbolCOFF(Name, IsTemporary);
161 case MCObjectFileInfo::IsELF:
162 return new (Name, *this) MCSymbolELF(Name, IsTemporary);
163 case MCObjectFileInfo::IsMachO:
164 return new (Name, *this) MCSymbolMachO(Name, IsTemporary);
165 }
166 }
167 return new (Name, *this) MCSymbol(MCSymbol::SymbolKindUnset, Name,
168 IsTemporary);
169 }
170
createSymbol(StringRef Name,bool AlwaysAddSuffix,bool CanBeUnnamed)171 MCSymbol *MCContext::createSymbol(StringRef Name, bool AlwaysAddSuffix,
172 bool CanBeUnnamed) {
173 if (CanBeUnnamed && !UseNamesOnTempLabels)
174 return createSymbolImpl(nullptr, true);
175
176 // Determine whether this is an user writter assembler temporary or normal
177 // label, if used.
178 bool IsTemporary = CanBeUnnamed;
179 if (AllowTemporaryLabels && !IsTemporary)
180 IsTemporary = Name.startswith(MAI->getPrivateGlobalPrefix());
181
182 SmallString<128> NewName = Name;
183 bool AddSuffix = AlwaysAddSuffix;
184 unsigned &NextUniqueID = NextID[Name];
185 for (;;) {
186 if (AddSuffix) {
187 NewName.resize(Name.size());
188 raw_svector_ostream(NewName) << NextUniqueID++;
189 }
190 auto NameEntry = UsedNames.insert(std::make_pair(NewName, true));
191 if (NameEntry.second || !NameEntry.first->second) {
192 // Ok, we found a name.
193 // Mark it as used for a non-section symbol.
194 NameEntry.first->second = true;
195 // Have the MCSymbol object itself refer to the copy of the string that is
196 // embedded in the UsedNames entry.
197 return createSymbolImpl(&*NameEntry.first, IsTemporary);
198 }
199 assert(IsTemporary && "Cannot rename non-temporary symbols");
200 AddSuffix = true;
201 }
202 llvm_unreachable("Infinite loop");
203 }
204
createTempSymbol(const Twine & Name,bool AlwaysAddSuffix,bool CanBeUnnamed)205 MCSymbol *MCContext::createTempSymbol(const Twine &Name, bool AlwaysAddSuffix,
206 bool CanBeUnnamed) {
207 SmallString<128> NameSV;
208 raw_svector_ostream(NameSV) << MAI->getPrivateGlobalPrefix() << Name;
209 return createSymbol(NameSV, AlwaysAddSuffix, CanBeUnnamed);
210 }
211
createLinkerPrivateTempSymbol()212 MCSymbol *MCContext::createLinkerPrivateTempSymbol() {
213 SmallString<128> NameSV;
214 raw_svector_ostream(NameSV) << MAI->getLinkerPrivateGlobalPrefix() << "tmp";
215 return createSymbol(NameSV, true, false);
216 }
217
createTempSymbol(bool CanBeUnnamed)218 MCSymbol *MCContext::createTempSymbol(bool CanBeUnnamed) {
219 return createTempSymbol("tmp", true, CanBeUnnamed);
220 }
221
NextInstance(unsigned LocalLabelVal)222 unsigned MCContext::NextInstance(unsigned LocalLabelVal) {
223 MCLabel *&Label = Instances[LocalLabelVal];
224 if (!Label)
225 Label = new (*this) MCLabel(0);
226 return Label->incInstance();
227 }
228
GetInstance(unsigned LocalLabelVal)229 unsigned MCContext::GetInstance(unsigned LocalLabelVal) {
230 MCLabel *&Label = Instances[LocalLabelVal];
231 if (!Label)
232 Label = new (*this) MCLabel(0);
233 return Label->getInstance();
234 }
235
getOrCreateDirectionalLocalSymbol(unsigned LocalLabelVal,unsigned Instance)236 MCSymbol *MCContext::getOrCreateDirectionalLocalSymbol(unsigned LocalLabelVal,
237 unsigned Instance) {
238 MCSymbol *&Sym = LocalSymbols[std::make_pair(LocalLabelVal, Instance)];
239 if (!Sym)
240 Sym = createTempSymbol(false);
241 return Sym;
242 }
243
createDirectionalLocalSymbol(unsigned LocalLabelVal)244 MCSymbol *MCContext::createDirectionalLocalSymbol(unsigned LocalLabelVal) {
245 unsigned Instance = NextInstance(LocalLabelVal);
246 return getOrCreateDirectionalLocalSymbol(LocalLabelVal, Instance);
247 }
248
getDirectionalLocalSymbol(unsigned LocalLabelVal,bool Before)249 MCSymbol *MCContext::getDirectionalLocalSymbol(unsigned LocalLabelVal,
250 bool Before) {
251 unsigned Instance = GetInstance(LocalLabelVal);
252 if (!Before)
253 ++Instance;
254 return getOrCreateDirectionalLocalSymbol(LocalLabelVal, Instance);
255 }
256
lookupSymbol(const Twine & Name) const257 MCSymbol *MCContext::lookupSymbol(const Twine &Name) const {
258 SmallString<128> NameSV;
259 StringRef NameRef = Name.toStringRef(NameSV);
260 return Symbols.lookup(NameRef);
261 }
262
263 //===----------------------------------------------------------------------===//
264 // Section Management
265 //===----------------------------------------------------------------------===//
266
getMachOSection(StringRef Segment,StringRef Section,unsigned TypeAndAttributes,unsigned Reserved2,SectionKind Kind,const char * BeginSymName)267 MCSectionMachO *MCContext::getMachOSection(StringRef Segment, StringRef Section,
268 unsigned TypeAndAttributes,
269 unsigned Reserved2, SectionKind Kind,
270 const char *BeginSymName) {
271
272 // We unique sections by their segment/section pair. The returned section
273 // may not have the same flags as the requested section, if so this should be
274 // diagnosed by the client as an error.
275
276 // Form the name to look up.
277 SmallString<64> Name;
278 Name += Segment;
279 Name.push_back(',');
280 Name += Section;
281
282 // Do the lookup, if we have a hit, return it.
283 MCSectionMachO *&Entry = MachOUniquingMap[Name];
284 if (Entry)
285 return Entry;
286
287 MCSymbol *Begin = nullptr;
288 if (BeginSymName)
289 Begin = createTempSymbol(BeginSymName, false);
290
291 // Otherwise, return a new section.
292 return Entry = new (MachOAllocator.Allocate()) MCSectionMachO(
293 Segment, Section, TypeAndAttributes, Reserved2, Kind, Begin);
294 }
295
renameELFSection(MCSectionELF * Section,StringRef Name)296 void MCContext::renameELFSection(MCSectionELF *Section, StringRef Name) {
297 StringRef GroupName;
298 if (const MCSymbol *Group = Section->getGroup())
299 GroupName = Group->getName();
300
301 unsigned UniqueID = Section->getUniqueID();
302 ELFUniquingMap.erase(
303 ELFSectionKey{Section->getSectionName(), GroupName, UniqueID});
304 auto I = ELFUniquingMap.insert(std::make_pair(
305 ELFSectionKey{Name, GroupName, UniqueID},
306 Section))
307 .first;
308 StringRef CachedName = I->first.SectionName;
309 const_cast<MCSectionELF *>(Section)->setSectionName(CachedName);
310 }
311
createELFRelSection(const Twine & Name,unsigned Type,unsigned Flags,unsigned EntrySize,const MCSymbolELF * Group,const MCSectionELF * Associated)312 MCSectionELF *MCContext::createELFRelSection(const Twine &Name, unsigned Type,
313 unsigned Flags, unsigned EntrySize,
314 const MCSymbolELF *Group,
315 const MCSectionELF *Associated) {
316 StringMap<bool>::iterator I;
317 bool Inserted;
318 std::tie(I, Inserted) =
319 ELFRelSecNames.insert(std::make_pair(Name.str(), true));
320
321 return new (ELFAllocator.Allocate())
322 MCSectionELF(I->getKey(), Type, Flags, SectionKind::getReadOnly(),
323 EntrySize, Group, true, nullptr, Associated);
324 }
325
getELFNamedSection(const Twine & Prefix,const Twine & Suffix,unsigned Type,unsigned Flags,unsigned EntrySize)326 MCSectionELF *MCContext::getELFNamedSection(const Twine &Prefix,
327 const Twine &Suffix, unsigned Type,
328 unsigned Flags,
329 unsigned EntrySize) {
330 return getELFSection(Prefix + "." + Suffix, Type, Flags, EntrySize, Suffix);
331 }
332
getELFSection(const Twine & Section,unsigned Type,unsigned Flags,unsigned EntrySize,const Twine & Group,unsigned UniqueID,const char * BeginSymName)333 MCSectionELF *MCContext::getELFSection(const Twine &Section, unsigned Type,
334 unsigned Flags, unsigned EntrySize,
335 const Twine &Group, unsigned UniqueID,
336 const char *BeginSymName) {
337 MCSymbolELF *GroupSym = nullptr;
338 if (!Group.isTriviallyEmpty() && !Group.str().empty())
339 GroupSym = cast<MCSymbolELF>(getOrCreateSymbol(Group));
340
341 return getELFSection(Section, Type, Flags, EntrySize, GroupSym, UniqueID,
342 BeginSymName, nullptr);
343 }
344
getELFSection(const Twine & Section,unsigned Type,unsigned Flags,unsigned EntrySize,const MCSymbolELF * GroupSym,unsigned UniqueID,const char * BeginSymName,const MCSectionELF * Associated)345 MCSectionELF *MCContext::getELFSection(const Twine &Section, unsigned Type,
346 unsigned Flags, unsigned EntrySize,
347 const MCSymbolELF *GroupSym,
348 unsigned UniqueID,
349 const char *BeginSymName,
350 const MCSectionELF *Associated) {
351 StringRef Group = "";
352 if (GroupSym)
353 Group = GroupSym->getName();
354 // Do the lookup, if we have a hit, return it.
355 auto IterBool = ELFUniquingMap.insert(
356 std::make_pair(ELFSectionKey{Section.str(), Group, UniqueID}, nullptr));
357 auto &Entry = *IterBool.first;
358 if (!IterBool.second)
359 return Entry.second;
360
361 StringRef CachedName = Entry.first.SectionName;
362
363 SectionKind Kind;
364 if (Flags & ELF::SHF_EXECINSTR)
365 Kind = SectionKind::getText();
366 else
367 Kind = SectionKind::getReadOnly();
368
369 MCSymbol *Begin = nullptr;
370 if (BeginSymName)
371 Begin = createTempSymbol(BeginSymName, false);
372
373 MCSectionELF *Result = new (ELFAllocator.Allocate())
374 MCSectionELF(CachedName, Type, Flags, Kind, EntrySize, GroupSym, UniqueID,
375 Begin, Associated);
376 Entry.second = Result;
377 return Result;
378 }
379
createELFGroupSection(const MCSymbolELF * Group)380 MCSectionELF *MCContext::createELFGroupSection(const MCSymbolELF *Group) {
381 MCSectionELF *Result = new (ELFAllocator.Allocate())
382 MCSectionELF(".group", ELF::SHT_GROUP, 0, SectionKind::getReadOnly(), 4,
383 Group, ~0, nullptr, nullptr);
384 return Result;
385 }
386
getCOFFSection(StringRef Section,unsigned Characteristics,SectionKind Kind,StringRef COMDATSymName,int Selection,unsigned UniqueID,const char * BeginSymName)387 MCSectionCOFF *MCContext::getCOFFSection(StringRef Section,
388 unsigned Characteristics,
389 SectionKind Kind,
390 StringRef COMDATSymName, int Selection,
391 unsigned UniqueID,
392 const char *BeginSymName) {
393 MCSymbol *COMDATSymbol = nullptr;
394 if (!COMDATSymName.empty()) {
395 COMDATSymbol = getOrCreateSymbol(COMDATSymName);
396 COMDATSymName = COMDATSymbol->getName();
397 }
398
399
400 // Do the lookup, if we have a hit, return it.
401 COFFSectionKey T{Section, COMDATSymName, Selection, UniqueID};
402 auto IterBool = COFFUniquingMap.insert(std::make_pair(T, nullptr));
403 auto Iter = IterBool.first;
404 if (!IterBool.second)
405 return Iter->second;
406
407 MCSymbol *Begin = nullptr;
408 if (BeginSymName)
409 Begin = createTempSymbol(BeginSymName, false);
410
411 StringRef CachedName = Iter->first.SectionName;
412 MCSectionCOFF *Result = new (COFFAllocator.Allocate()) MCSectionCOFF(
413 CachedName, Characteristics, COMDATSymbol, Selection, Kind, Begin);
414
415 Iter->second = Result;
416 return Result;
417 }
418
getCOFFSection(StringRef Section,unsigned Characteristics,SectionKind Kind,const char * BeginSymName)419 MCSectionCOFF *MCContext::getCOFFSection(StringRef Section,
420 unsigned Characteristics,
421 SectionKind Kind,
422 const char *BeginSymName) {
423 return getCOFFSection(Section, Characteristics, Kind, "", 0, GenericSectionID,
424 BeginSymName);
425 }
426
getCOFFSection(StringRef Section)427 MCSectionCOFF *MCContext::getCOFFSection(StringRef Section) {
428 COFFSectionKey T{Section, "", 0, GenericSectionID};
429 auto Iter = COFFUniquingMap.find(T);
430 if (Iter == COFFUniquingMap.end())
431 return nullptr;
432 return Iter->second;
433 }
434
getAssociativeCOFFSection(MCSectionCOFF * Sec,const MCSymbol * KeySym,unsigned UniqueID)435 MCSectionCOFF *MCContext::getAssociativeCOFFSection(MCSectionCOFF *Sec,
436 const MCSymbol *KeySym,
437 unsigned UniqueID) {
438 // Return the normal section if we don't have to be associative or unique.
439 if (!KeySym && UniqueID == GenericSectionID)
440 return Sec;
441
442 // If we have a key symbol, make an associative section with the same name and
443 // kind as the normal section.
444 unsigned Characteristics = Sec->getCharacteristics();
445 if (KeySym) {
446 Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT;
447 return getCOFFSection(Sec->getSectionName(), Characteristics,
448 Sec->getKind(), KeySym->getName(),
449 COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE, UniqueID);
450 }
451
452 return getCOFFSection(Sec->getSectionName(), Characteristics, Sec->getKind(),
453 "", 0, UniqueID);
454 }
455
getSubtargetCopy(const MCSubtargetInfo & STI)456 MCSubtargetInfo &MCContext::getSubtargetCopy(const MCSubtargetInfo &STI) {
457 return *new (MCSubtargetAllocator.Allocate()) MCSubtargetInfo(STI);
458 }
459
460 //===----------------------------------------------------------------------===//
461 // Dwarf Management
462 //===----------------------------------------------------------------------===//
463
464 /// getDwarfFile - takes a file name an number to place in the dwarf file and
465 /// directory tables. If the file number has already been allocated it is an
466 /// error and zero is returned and the client reports the error, else the
467 /// allocated file number is returned. The file numbers may be in any order.
getDwarfFile(StringRef Directory,StringRef FileName,unsigned FileNumber,unsigned CUID)468 unsigned MCContext::getDwarfFile(StringRef Directory, StringRef FileName,
469 unsigned FileNumber, unsigned CUID) {
470 MCDwarfLineTable &Table = MCDwarfLineTablesCUMap[CUID];
471 return Table.getFile(Directory, FileName, FileNumber);
472 }
473
474 /// isValidDwarfFileNumber - takes a dwarf file number and returns true if it
475 /// currently is assigned and false otherwise.
isValidDwarfFileNumber(unsigned FileNumber,unsigned CUID)476 bool MCContext::isValidDwarfFileNumber(unsigned FileNumber, unsigned CUID) {
477 const SmallVectorImpl<MCDwarfFile> &MCDwarfFiles = getMCDwarfFiles(CUID);
478 if (FileNumber == 0 || FileNumber >= MCDwarfFiles.size())
479 return false;
480
481 return !MCDwarfFiles[FileNumber].Name.empty();
482 }
483
484 /// Remove empty sections from SectionStartEndSyms, to avoid generating
485 /// useless debug info for them.
finalizeDwarfSections(MCStreamer & MCOS)486 void MCContext::finalizeDwarfSections(MCStreamer &MCOS) {
487 SectionsForRanges.remove_if(
488 [&](MCSection *Sec) { return !MCOS.mayHaveInstructions(*Sec); });
489 }
490
getCVContext()491 CodeViewContext &MCContext::getCVContext() {
492 if (!CVContext.get())
493 CVContext.reset(new CodeViewContext);
494 return *CVContext.get();
495 }
496
getCVFile(StringRef FileName,unsigned FileNumber)497 unsigned MCContext::getCVFile(StringRef FileName, unsigned FileNumber) {
498 return getCVContext().addFile(FileNumber, FileName) ? FileNumber : 0;
499 }
500
isValidCVFileNumber(unsigned FileNumber)501 bool MCContext::isValidCVFileNumber(unsigned FileNumber) {
502 return getCVContext().isValidFileNumber(FileNumber);
503 }
504
505 //===----------------------------------------------------------------------===//
506 // Error Reporting
507 //===----------------------------------------------------------------------===//
508
reportError(SMLoc Loc,const Twine & Msg)509 void MCContext::reportError(SMLoc Loc, const Twine &Msg) {
510 HadError = true;
511
512 // If we have a source manager use it. Otherwise just use the generic
513 // report_fatal_error().
514 if (!SrcMgr)
515 report_fatal_error(Msg, false);
516
517 // Use the source manager to print the message.
518 SrcMgr->PrintMessage(Loc, SourceMgr::DK_Error, Msg);
519 }
520
reportFatalError(SMLoc Loc,const Twine & Msg)521 void MCContext::reportFatalError(SMLoc Loc, const Twine &Msg) {
522 reportError(Loc, Msg);
523
524 // If we reached here, we are failing ungracefully. Run the interrupt handlers
525 // to make sure any special cleanups get done, in particular that we remove
526 // files registered with RemoveFileOnSignal.
527 sys::RunInterruptHandlers();
528 exit(1);
529 }
530