1 //===- lib/MC/MCContext.cpp - Machine Code Context ------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "llvm/MC/MCContext.h"
10 #include "llvm/ADT/Optional.h"
11 #include "llvm/ADT/SmallString.h"
12 #include "llvm/ADT/SmallVector.h"
13 #include "llvm/ADT/StringMap.h"
14 #include "llvm/ADT/StringRef.h"
15 #include "llvm/ADT/Twine.h"
16 #include "llvm/BinaryFormat/COFF.h"
17 #include "llvm/BinaryFormat/ELF.h"
18 #include "llvm/MC/MCAsmInfo.h"
19 #include "llvm/MC/MCCodeView.h"
20 #include "llvm/MC/MCDwarf.h"
21 #include "llvm/MC/MCExpr.h"
22 #include "llvm/MC/MCFragment.h"
23 #include "llvm/MC/MCLabel.h"
24 #include "llvm/MC/MCObjectFileInfo.h"
25 #include "llvm/MC/MCSectionCOFF.h"
26 #include "llvm/MC/MCSectionELF.h"
27 #include "llvm/MC/MCSectionMachO.h"
28 #include "llvm/MC/MCSectionWasm.h"
29 #include "llvm/MC/MCSectionXCOFF.h"
30 #include "llvm/MC/MCStreamer.h"
31 #include "llvm/MC/MCSymbol.h"
32 #include "llvm/MC/MCSymbolCOFF.h"
33 #include "llvm/MC/MCSymbolELF.h"
34 #include "llvm/MC/MCSymbolMachO.h"
35 #include "llvm/MC/MCSymbolWasm.h"
36 #include "llvm/MC/MCSymbolXCOFF.h"
37 #include "llvm/MC/SectionKind.h"
38 #include "llvm/Support/Casting.h"
39 #include "llvm/Support/CommandLine.h"
40 #include "llvm/Support/ErrorHandling.h"
41 #include "llvm/Support/MemoryBuffer.h"
42 #include "llvm/Support/Path.h"
43 #include "llvm/Support/Signals.h"
44 #include "llvm/Support/SourceMgr.h"
45 #include "llvm/Support/raw_ostream.h"
54 AsSecureLogFileName("as-secure-log-file-name",
55 cl::desc("As secure log file name (initialized from "
56 "AS_SECURE_LOG_FILE env variable)"),
57 cl::init(getenv("AS_SECURE_LOG_FILE")), cl::Hidden
);
59 MCContext::MCContext(const MCAsmInfo
*mai
, const MCRegisterInfo
*mri
,
60 const MCObjectFileInfo
*mofi
, const SourceMgr
*mgr
,
61 MCTargetOptions
const *TargetOpts
, bool DoAutoReset
)
62 : SrcMgr(mgr
), InlineSrcMgr(nullptr), MAI(mai
), MRI(mri
), MOFI(mofi
),
63 Symbols(Allocator
), UsedNames(Allocator
),
64 InlineAsmUsedLabelNames(Allocator
),
65 CurrentDwarfLoc(0, 0, 0, DWARF2_FLAG_IS_STMT
, 0, 0),
66 AutoReset(DoAutoReset
), TargetOptions(TargetOpts
) {
67 SecureLogFile
= AsSecureLogFileName
;
69 if (SrcMgr
&& SrcMgr
->getNumBuffers())
71 SrcMgr
->getMemoryBuffer(SrcMgr
->getMainFileID())->getBufferIdentifier();
74 MCContext::~MCContext() {
78 // NOTE: The symbols are all allocated out of a bump pointer allocator,
79 // we don't need to free them here.
82 //===----------------------------------------------------------------------===//
83 // Module Lifetime Management
84 //===----------------------------------------------------------------------===//
86 void MCContext::reset() {
87 // Call the destructors so the fragments are freed
88 COFFAllocator
.DestroyAll();
89 ELFAllocator
.DestroyAll();
90 MachOAllocator
.DestroyAll();
91 XCOFFAllocator
.DestroyAll();
93 MCSubtargetAllocator
.DestroyAll();
94 InlineAsmUsedLabelNames
.clear();
99 CompilationDir
.clear();
100 MainFileName
.clear();
101 MCDwarfLineTablesCUMap
.clear();
102 SectionsForRanges
.clear();
103 MCGenDwarfLabelEntries
.clear();
104 DwarfDebugFlags
= StringRef();
105 DwarfCompileUnitID
= 0;
106 CurrentDwarfLoc
= MCDwarfLoc(0, 0, 0, DWARF2_FLAG_IS_STMT
, 0, 0);
110 MachOUniquingMap
.clear();
111 ELFUniquingMap
.clear();
112 COFFUniquingMap
.clear();
113 WasmUniquingMap
.clear();
114 XCOFFUniquingMap
.clear();
117 AllowTemporaryLabels
= true;
118 DwarfLocSeen
= false;
119 GenDwarfForAssembly
= false;
120 GenDwarfFileNumber
= 0;
125 //===----------------------------------------------------------------------===//
126 // Symbol Manipulation
127 //===----------------------------------------------------------------------===//
129 MCSymbol
*MCContext::getOrCreateSymbol(const Twine
&Name
) {
130 SmallString
<128> NameSV
;
131 StringRef NameRef
= Name
.toStringRef(NameSV
);
133 assert(!NameRef
.empty() && "Normal symbols cannot be unnamed!");
135 MCSymbol
*&Sym
= Symbols
[NameRef
];
137 Sym
= createSymbol(NameRef
, false, false);
142 MCSymbol
*MCContext::getOrCreateFrameAllocSymbol(StringRef FuncName
,
144 return getOrCreateSymbol(Twine(MAI
->getPrivateGlobalPrefix()) + FuncName
+
145 "$frame_escape_" + Twine(Idx
));
148 MCSymbol
*MCContext::getOrCreateParentFrameOffsetSymbol(StringRef FuncName
) {
149 return getOrCreateSymbol(Twine(MAI
->getPrivateGlobalPrefix()) + FuncName
+
150 "$parent_frame_offset");
153 MCSymbol
*MCContext::getOrCreateLSDASymbol(StringRef FuncName
) {
154 return getOrCreateSymbol(Twine(MAI
->getPrivateGlobalPrefix()) + "__ehtable$" +
158 MCSymbol
*MCContext::createSymbolImpl(const StringMapEntry
<bool> *Name
,
161 switch (MOFI
->getObjectFileType()) {
162 case MCObjectFileInfo::IsCOFF
:
163 return new (Name
, *this) MCSymbolCOFF(Name
, IsTemporary
);
164 case MCObjectFileInfo::IsELF
:
165 return new (Name
, *this) MCSymbolELF(Name
, IsTemporary
);
166 case MCObjectFileInfo::IsMachO
:
167 return new (Name
, *this) MCSymbolMachO(Name
, IsTemporary
);
168 case MCObjectFileInfo::IsWasm
:
169 return new (Name
, *this) MCSymbolWasm(Name
, IsTemporary
);
170 case MCObjectFileInfo::IsXCOFF
:
171 return new (Name
, *this) MCSymbolXCOFF(Name
, IsTemporary
);
174 return new (Name
, *this) MCSymbol(MCSymbol::SymbolKindUnset
, Name
,
178 MCSymbol
*MCContext::createSymbol(StringRef Name
, bool AlwaysAddSuffix
,
180 if (CanBeUnnamed
&& !UseNamesOnTempLabels
)
181 return createSymbolImpl(nullptr, true);
183 // Determine whether this is a user written assembler temporary or normal
185 bool IsTemporary
= CanBeUnnamed
;
186 if (AllowTemporaryLabels
&& !IsTemporary
)
187 IsTemporary
= Name
.startswith(MAI
->getPrivateGlobalPrefix());
189 SmallString
<128> NewName
= Name
;
190 bool AddSuffix
= AlwaysAddSuffix
;
191 unsigned &NextUniqueID
= NextID
[Name
];
194 NewName
.resize(Name
.size());
195 raw_svector_ostream(NewName
) << NextUniqueID
++;
197 auto NameEntry
= UsedNames
.insert(std::make_pair(NewName
, true));
198 if (NameEntry
.second
|| !NameEntry
.first
->second
) {
199 // Ok, we found a name.
200 // Mark it as used for a non-section symbol.
201 NameEntry
.first
->second
= true;
202 // Have the MCSymbol object itself refer to the copy of the string that is
203 // embedded in the UsedNames entry.
204 return createSymbolImpl(&*NameEntry
.first
, IsTemporary
);
206 assert(IsTemporary
&& "Cannot rename non-temporary symbols");
209 llvm_unreachable("Infinite loop");
212 MCSymbol
*MCContext::createTempSymbol(const Twine
&Name
, bool AlwaysAddSuffix
,
214 SmallString
<128> NameSV
;
215 raw_svector_ostream(NameSV
) << MAI
->getPrivateGlobalPrefix() << Name
;
216 return createSymbol(NameSV
, AlwaysAddSuffix
, CanBeUnnamed
);
219 MCSymbol
*MCContext::createLinkerPrivateTempSymbol() {
220 SmallString
<128> NameSV
;
221 raw_svector_ostream(NameSV
) << MAI
->getLinkerPrivateGlobalPrefix() << "tmp";
222 return createSymbol(NameSV
, true, false);
225 MCSymbol
*MCContext::createTempSymbol(bool CanBeUnnamed
) {
226 return createTempSymbol("tmp", true, CanBeUnnamed
);
229 unsigned MCContext::NextInstance(unsigned LocalLabelVal
) {
230 MCLabel
*&Label
= Instances
[LocalLabelVal
];
232 Label
= new (*this) MCLabel(0);
233 return Label
->incInstance();
236 unsigned MCContext::GetInstance(unsigned LocalLabelVal
) {
237 MCLabel
*&Label
= Instances
[LocalLabelVal
];
239 Label
= new (*this) MCLabel(0);
240 return Label
->getInstance();
243 MCSymbol
*MCContext::getOrCreateDirectionalLocalSymbol(unsigned LocalLabelVal
,
245 MCSymbol
*&Sym
= LocalSymbols
[std::make_pair(LocalLabelVal
, Instance
)];
247 Sym
= createTempSymbol(false);
251 MCSymbol
*MCContext::createDirectionalLocalSymbol(unsigned LocalLabelVal
) {
252 unsigned Instance
= NextInstance(LocalLabelVal
);
253 return getOrCreateDirectionalLocalSymbol(LocalLabelVal
, Instance
);
256 MCSymbol
*MCContext::getDirectionalLocalSymbol(unsigned LocalLabelVal
,
258 unsigned Instance
= GetInstance(LocalLabelVal
);
261 return getOrCreateDirectionalLocalSymbol(LocalLabelVal
, Instance
);
264 MCSymbol
*MCContext::lookupSymbol(const Twine
&Name
) const {
265 SmallString
<128> NameSV
;
266 StringRef NameRef
= Name
.toStringRef(NameSV
);
267 return Symbols
.lookup(NameRef
);
270 void MCContext::setSymbolValue(MCStreamer
&Streamer
,
273 auto Symbol
= getOrCreateSymbol(Sym
);
274 Streamer
.EmitAssignment(Symbol
, MCConstantExpr::create(Val
, *this));
277 void MCContext::registerInlineAsmLabel(MCSymbol
*Sym
) {
278 InlineAsmUsedLabelNames
[Sym
->getName()] = Sym
;
281 //===----------------------------------------------------------------------===//
282 // Section Management
283 //===----------------------------------------------------------------------===//
285 MCSectionMachO
*MCContext::getMachOSection(StringRef Segment
, StringRef Section
,
286 unsigned TypeAndAttributes
,
287 unsigned Reserved2
, SectionKind Kind
,
288 const char *BeginSymName
) {
289 // We unique sections by their segment/section pair. The returned section
290 // may not have the same flags as the requested section, if so this should be
291 // diagnosed by the client as an error.
293 // Form the name to look up.
294 SmallString
<64> Name
;
299 // Do the lookup, if we have a hit, return it.
300 MCSectionMachO
*&Entry
= MachOUniquingMap
[Name
];
304 MCSymbol
*Begin
= nullptr;
306 Begin
= createTempSymbol(BeginSymName
, false);
308 // Otherwise, return a new section.
309 return Entry
= new (MachOAllocator
.Allocate()) MCSectionMachO(
310 Segment
, Section
, TypeAndAttributes
, Reserved2
, Kind
, Begin
);
313 void MCContext::renameELFSection(MCSectionELF
*Section
, StringRef Name
) {
315 if (const MCSymbol
*Group
= Section
->getGroup())
316 GroupName
= Group
->getName();
318 unsigned UniqueID
= Section
->getUniqueID();
319 ELFUniquingMap
.erase(
320 ELFSectionKey
{Section
->getSectionName(), GroupName
, UniqueID
});
321 auto I
= ELFUniquingMap
.insert(std::make_pair(
322 ELFSectionKey
{Name
, GroupName
, UniqueID
},
325 StringRef CachedName
= I
->first
.SectionName
;
326 const_cast<MCSectionELF
*>(Section
)->setSectionName(CachedName
);
329 MCSectionELF
*MCContext::createELFSectionImpl(StringRef Section
, unsigned Type
,
330 unsigned Flags
, SectionKind K
,
332 const MCSymbolELF
*Group
,
334 const MCSymbolELF
*Associated
) {
336 MCSymbol
*&Sym
= Symbols
[Section
];
337 // A section symbol can not redefine regular symbols. There may be multiple
338 // sections with the same name, in which case the first such section wins.
339 if (Sym
&& Sym
->isDefined() &&
340 (!Sym
->isInSection() || Sym
->getSection().getBeginSymbol() != Sym
))
341 reportError(SMLoc(), "invalid symbol redefinition");
342 if (Sym
&& Sym
->isUndefined()) {
343 R
= cast
<MCSymbolELF
>(Sym
);
345 auto NameIter
= UsedNames
.insert(std::make_pair(Section
, false)).first
;
346 R
= new (&*NameIter
, *this) MCSymbolELF(&*NameIter
, /*isTemporary*/ false);
350 R
->setBinding(ELF::STB_LOCAL
);
351 R
->setType(ELF::STT_SECTION
);
353 auto *Ret
= new (ELFAllocator
.Allocate()) MCSectionELF(
354 Section
, Type
, Flags
, K
, EntrySize
, Group
, UniqueID
, R
, Associated
);
356 auto *F
= new MCDataFragment();
357 Ret
->getFragmentList().insert(Ret
->begin(), F
);
364 MCSectionELF
*MCContext::createELFRelSection(const Twine
&Name
, unsigned Type
,
365 unsigned Flags
, unsigned EntrySize
,
366 const MCSymbolELF
*Group
,
367 const MCSectionELF
*RelInfoSection
) {
368 StringMap
<bool>::iterator I
;
370 std::tie(I
, Inserted
) =
371 RelSecNames
.insert(std::make_pair(Name
.str(), true));
373 return createELFSectionImpl(
374 I
->getKey(), Type
, Flags
, SectionKind::getReadOnly(), EntrySize
, Group
,
375 true, cast
<MCSymbolELF
>(RelInfoSection
->getBeginSymbol()));
378 MCSectionELF
*MCContext::getELFNamedSection(const Twine
&Prefix
,
379 const Twine
&Suffix
, unsigned Type
,
381 unsigned EntrySize
) {
382 return getELFSection(Prefix
+ "." + Suffix
, Type
, Flags
, EntrySize
, Suffix
);
385 MCSectionELF
*MCContext::getELFSection(const Twine
&Section
, unsigned Type
,
386 unsigned Flags
, unsigned EntrySize
,
387 const Twine
&Group
, unsigned UniqueID
,
388 const MCSymbolELF
*Associated
) {
389 MCSymbolELF
*GroupSym
= nullptr;
390 if (!Group
.isTriviallyEmpty() && !Group
.str().empty())
391 GroupSym
= cast
<MCSymbolELF
>(getOrCreateSymbol(Group
));
393 return getELFSection(Section
, Type
, Flags
, EntrySize
, GroupSym
, UniqueID
,
397 MCSectionELF
*MCContext::getELFSection(const Twine
&Section
, unsigned Type
,
398 unsigned Flags
, unsigned EntrySize
,
399 const MCSymbolELF
*GroupSym
,
401 const MCSymbolELF
*Associated
) {
402 StringRef Group
= "";
404 Group
= GroupSym
->getName();
405 // Do the lookup, if we have a hit, return it.
406 auto IterBool
= ELFUniquingMap
.insert(
407 std::make_pair(ELFSectionKey
{Section
.str(), Group
, UniqueID
}, nullptr));
408 auto &Entry
= *IterBool
.first
;
409 if (!IterBool
.second
)
412 StringRef CachedName
= Entry
.first
.SectionName
;
415 if (Flags
& ELF::SHF_ARM_PURECODE
)
416 Kind
= SectionKind::getExecuteOnly();
417 else if (Flags
& ELF::SHF_EXECINSTR
)
418 Kind
= SectionKind::getText();
420 Kind
= SectionKind::getReadOnly();
422 MCSectionELF
*Result
= createELFSectionImpl(
423 CachedName
, Type
, Flags
, Kind
, EntrySize
, GroupSym
, UniqueID
, Associated
);
424 Entry
.second
= Result
;
428 MCSectionELF
*MCContext::createELFGroupSection(const MCSymbolELF
*Group
) {
429 return createELFSectionImpl(".group", ELF::SHT_GROUP
, 0,
430 SectionKind::getReadOnly(), 4, Group
, ~0,
434 MCSectionCOFF
*MCContext::getCOFFSection(StringRef Section
,
435 unsigned Characteristics
,
437 StringRef COMDATSymName
, int Selection
,
439 const char *BeginSymName
) {
440 MCSymbol
*COMDATSymbol
= nullptr;
441 if (!COMDATSymName
.empty()) {
442 COMDATSymbol
= getOrCreateSymbol(COMDATSymName
);
443 COMDATSymName
= COMDATSymbol
->getName();
447 // Do the lookup, if we have a hit, return it.
448 COFFSectionKey T
{Section
, COMDATSymName
, Selection
, UniqueID
};
449 auto IterBool
= COFFUniquingMap
.insert(std::make_pair(T
, nullptr));
450 auto Iter
= IterBool
.first
;
451 if (!IterBool
.second
)
454 MCSymbol
*Begin
= nullptr;
456 Begin
= createTempSymbol(BeginSymName
, false);
458 StringRef CachedName
= Iter
->first
.SectionName
;
459 MCSectionCOFF
*Result
= new (COFFAllocator
.Allocate()) MCSectionCOFF(
460 CachedName
, Characteristics
, COMDATSymbol
, Selection
, Kind
, Begin
);
462 Iter
->second
= Result
;
466 MCSectionCOFF
*MCContext::getCOFFSection(StringRef Section
,
467 unsigned Characteristics
,
469 const char *BeginSymName
) {
470 return getCOFFSection(Section
, Characteristics
, Kind
, "", 0, GenericSectionID
,
474 MCSectionCOFF
*MCContext::getAssociativeCOFFSection(MCSectionCOFF
*Sec
,
475 const MCSymbol
*KeySym
,
477 // Return the normal section if we don't have to be associative or unique.
478 if (!KeySym
&& UniqueID
== GenericSectionID
)
481 // If we have a key symbol, make an associative section with the same name and
482 // kind as the normal section.
483 unsigned Characteristics
= Sec
->getCharacteristics();
485 Characteristics
|= COFF::IMAGE_SCN_LNK_COMDAT
;
486 return getCOFFSection(Sec
->getSectionName(), Characteristics
,
487 Sec
->getKind(), KeySym
->getName(),
488 COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE
, UniqueID
);
491 return getCOFFSection(Sec
->getSectionName(), Characteristics
, Sec
->getKind(),
495 MCSectionWasm
*MCContext::getWasmSection(const Twine
&Section
, SectionKind K
,
496 const Twine
&Group
, unsigned UniqueID
,
497 const char *BeginSymName
) {
498 MCSymbolWasm
*GroupSym
= nullptr;
499 if (!Group
.isTriviallyEmpty() && !Group
.str().empty()) {
500 GroupSym
= cast
<MCSymbolWasm
>(getOrCreateSymbol(Group
));
501 GroupSym
->setComdat(true);
504 return getWasmSection(Section
, K
, GroupSym
, UniqueID
, BeginSymName
);
507 MCSectionWasm
*MCContext::getWasmSection(const Twine
&Section
, SectionKind Kind
,
508 const MCSymbolWasm
*GroupSym
,
510 const char *BeginSymName
) {
511 StringRef Group
= "";
513 Group
= GroupSym
->getName();
514 // Do the lookup, if we have a hit, return it.
515 auto IterBool
= WasmUniquingMap
.insert(
516 std::make_pair(WasmSectionKey
{Section
.str(), Group
, UniqueID
}, nullptr));
517 auto &Entry
= *IterBool
.first
;
518 if (!IterBool
.second
)
521 StringRef CachedName
= Entry
.first
.SectionName
;
523 MCSymbol
*Begin
= createSymbol(CachedName
, false, false);
524 cast
<MCSymbolWasm
>(Begin
)->setType(wasm::WASM_SYMBOL_TYPE_SECTION
);
526 MCSectionWasm
*Result
= new (WasmAllocator
.Allocate())
527 MCSectionWasm(CachedName
, Kind
, GroupSym
, UniqueID
, Begin
);
528 Entry
.second
= Result
;
530 auto *F
= new MCDataFragment();
531 Result
->getFragmentList().insert(Result
->begin(), F
);
532 F
->setParent(Result
);
533 Begin
->setFragment(F
);
538 MCSectionXCOFF
*MCContext::getXCOFFSection(StringRef Section
,
539 XCOFF::StorageMappingClass SMC
,
540 XCOFF::SymbolType Type
,
541 XCOFF::StorageClass SC
,
543 const char *BeginSymName
) {
544 // Do the lookup. If we have a hit, return it.
545 auto IterBool
= XCOFFUniquingMap
.insert(
546 std::make_pair(XCOFFSectionKey
{Section
.str(), SMC
}, nullptr));
547 auto &Entry
= *IterBool
.first
;
548 if (!IterBool
.second
)
551 // Otherwise, return a new section.
552 StringRef CachedName
= Entry
.first
.SectionName
;
554 MCSymbol
*Begin
= nullptr;
556 Begin
= createTempSymbol(BeginSymName
, false);
558 MCSectionXCOFF
*Result
= new (XCOFFAllocator
.Allocate())
559 MCSectionXCOFF(CachedName
, SMC
, Type
, SC
, Kind
, Begin
);
560 Entry
.second
= Result
;
562 auto *F
= new MCDataFragment();
563 Result
->getFragmentList().insert(Result
->begin(), F
);
564 F
->setParent(Result
);
567 Begin
->setFragment(F
);
572 MCSubtargetInfo
&MCContext::getSubtargetCopy(const MCSubtargetInfo
&STI
) {
573 return *new (MCSubtargetAllocator
.Allocate()) MCSubtargetInfo(STI
);
576 void MCContext::addDebugPrefixMapEntry(const std::string
&From
,
577 const std::string
&To
) {
578 DebugPrefixMap
.insert(std::make_pair(From
, To
));
581 void MCContext::RemapDebugPaths() {
582 const auto &DebugPrefixMap
= this->DebugPrefixMap
;
583 const auto RemapDebugPath
= [&DebugPrefixMap
](std::string
&Path
) {
584 for (const auto &Entry
: DebugPrefixMap
)
585 if (StringRef(Path
).startswith(Entry
.first
)) {
586 std::string RemappedPath
=
587 (Twine(Entry
.second
) + Path
.substr(Entry
.first
.size())).str();
588 Path
.swap(RemappedPath
);
592 // Remap compilation directory.
593 std::string CompDir
= CompilationDir
.str();
594 RemapDebugPath(CompDir
);
595 CompilationDir
= CompDir
;
597 // Remap MCDwarfDirs in all compilation units.
598 for (auto &CUIDTablePair
: MCDwarfLineTablesCUMap
)
599 for (auto &Dir
: CUIDTablePair
.second
.getMCDwarfDirs())
603 //===----------------------------------------------------------------------===//
605 //===----------------------------------------------------------------------===//
607 void MCContext::setGenDwarfRootFile(StringRef InputFileName
, StringRef Buffer
) {
608 // MCDwarf needs the root file as well as the compilation directory.
609 // If we find a '.file 0' directive that will supersede these values.
610 Optional
<MD5::MD5Result
> Cksum
;
611 if (getDwarfVersion() >= 5) {
618 // Canonicalize the root filename. It cannot be empty, and should not
619 // repeat the compilation dir.
620 // The MCContext ctor initializes MainFileName to the name associated with
621 // the SrcMgr's main file ID, which might be the same as InputFileName (and
622 // possibly include directory components).
623 // Or, MainFileName might have been overridden by a -main-file-name option,
624 // which is supposed to be just a base filename with no directory component.
625 // So, if the InputFileName and MainFileName are not equal, assume
626 // MainFileName is a substitute basename and replace the last component.
627 SmallString
<1024> FileNameBuf
= InputFileName
;
628 if (FileNameBuf
.empty() || FileNameBuf
== "-")
629 FileNameBuf
= "<stdin>";
630 if (!getMainFileName().empty() && FileNameBuf
!= getMainFileName()) {
631 llvm::sys::path::remove_filename(FileNameBuf
);
632 llvm::sys::path::append(FileNameBuf
, getMainFileName());
634 StringRef FileName
= FileNameBuf
;
635 if (FileName
.consume_front(getCompilationDir()))
636 if (llvm::sys::path::is_separator(FileName
.front()))
637 FileName
= FileName
.drop_front();
638 assert(!FileName
.empty());
639 setMCLineTableRootFile(
640 /*CUID=*/0, getCompilationDir(), FileName
, Cksum
, None
);
643 /// getDwarfFile - takes a file name and number to place in the dwarf file and
644 /// directory tables. If the file number has already been allocated it is an
645 /// error and zero is returned and the client reports the error, else the
646 /// allocated file number is returned. The file numbers may be in any order.
647 Expected
<unsigned> MCContext::getDwarfFile(StringRef Directory
,
650 Optional
<MD5::MD5Result
> Checksum
,
651 Optional
<StringRef
> Source
,
653 MCDwarfLineTable
&Table
= MCDwarfLineTablesCUMap
[CUID
];
654 return Table
.tryGetFile(Directory
, FileName
, Checksum
, Source
, DwarfVersion
,
658 /// isValidDwarfFileNumber - takes a dwarf file number and returns true if it
659 /// currently is assigned and false otherwise.
660 bool MCContext::isValidDwarfFileNumber(unsigned FileNumber
, unsigned CUID
) {
661 const MCDwarfLineTable
&LineTable
= getMCDwarfLineTable(CUID
);
663 return getDwarfVersion() >= 5;
664 if (FileNumber
>= LineTable
.getMCDwarfFiles().size())
667 return !LineTable
.getMCDwarfFiles()[FileNumber
].Name
.empty();
670 /// Remove empty sections from SectionsForRanges, to avoid generating
671 /// useless debug info for them.
672 void MCContext::finalizeDwarfSections(MCStreamer
&MCOS
) {
673 SectionsForRanges
.remove_if(
674 [&](MCSection
*Sec
) { return !MCOS
.mayHaveInstructions(*Sec
); });
677 CodeViewContext
&MCContext::getCVContext() {
678 if (!CVContext
.get())
679 CVContext
.reset(new CodeViewContext
);
680 return *CVContext
.get();
683 //===----------------------------------------------------------------------===//
685 //===----------------------------------------------------------------------===//
687 void MCContext::reportError(SMLoc Loc
, const Twine
&Msg
) {
690 // If we have a source manager use it. Otherwise, try using the inline source
692 // If that fails, use the generic report_fatal_error().
694 SrcMgr
->PrintMessage(Loc
, SourceMgr::DK_Error
, Msg
);
695 else if (InlineSrcMgr
)
696 InlineSrcMgr
->PrintMessage(Loc
, SourceMgr::DK_Error
, Msg
);
698 report_fatal_error(Msg
, false);
701 void MCContext::reportWarning(SMLoc Loc
, const Twine
&Msg
) {
702 if (TargetOptions
&& TargetOptions
->MCNoWarn
)
704 if (TargetOptions
&& TargetOptions
->MCFatalWarnings
)
705 reportError(Loc
, Msg
);
707 // If we have a source manager use it. Otherwise, try using the inline
710 SrcMgr
->PrintMessage(Loc
, SourceMgr::DK_Warning
, Msg
);
711 else if (InlineSrcMgr
)
712 InlineSrcMgr
->PrintMessage(Loc
, SourceMgr::DK_Warning
, Msg
);
716 void MCContext::reportFatalError(SMLoc Loc
, const Twine
&Msg
) {
717 reportError(Loc
, Msg
);
719 // If we reached here, we are failing ungracefully. Run the interrupt handlers
720 // to make sure any special cleanups get done, in particular that we remove
721 // files registered with RemoveFileOnSignal.
722 sys::RunInterruptHandlers();