10b57cec5SDimitry Andric //===- lib/MC/MCSymbol.cpp - MCSymbol implementation ----------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric
90b57cec5SDimitry Andric #include "llvm/MC/MCSymbol.h"
100b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
110b57cec5SDimitry Andric #include "llvm/Config/llvm-config.h"
120b57cec5SDimitry Andric #include "llvm/MC/MCAsmInfo.h"
130b57cec5SDimitry Andric #include "llvm/MC/MCContext.h"
140b57cec5SDimitry Andric #include "llvm/MC/MCFragment.h"
150b57cec5SDimitry Andric #include "llvm/Support/Compiler.h"
160b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
170b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
180b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
190b57cec5SDimitry Andric #include <cassert>
200b57cec5SDimitry Andric #include <cstddef>
210b57cec5SDimitry Andric
220b57cec5SDimitry Andric using namespace llvm;
230b57cec5SDimitry Andric
240b57cec5SDimitry Andric // Only the address of this fragment is ever actually used.
25*0fca6ea1SDimitry Andric static MCDummyFragment SentinelFragment;
260b57cec5SDimitry Andric
270b57cec5SDimitry Andric // Sentinel value for the absolute pseudo fragment.
280b57cec5SDimitry Andric MCFragment *MCSymbol::AbsolutePseudoFragment = &SentinelFragment;
290b57cec5SDimitry Andric
operator new(size_t s,const MCSymbolTableEntry * Name,MCContext & Ctx)30*0fca6ea1SDimitry Andric void *MCSymbol::operator new(size_t s, const MCSymbolTableEntry *Name,
310b57cec5SDimitry Andric MCContext &Ctx) {
320b57cec5SDimitry Andric // We may need more space for a Name to account for alignment. So allocate
330b57cec5SDimitry Andric // space for the storage type and not the name pointer.
340b57cec5SDimitry Andric size_t Size = s + (Name ? sizeof(NameEntryStorageTy) : 0);
350b57cec5SDimitry Andric
360b57cec5SDimitry Andric // For safety, ensure that the alignment of a pointer is enough for an
370b57cec5SDimitry Andric // MCSymbol. This also ensures we don't need padding between the name and
380b57cec5SDimitry Andric // symbol.
390b57cec5SDimitry Andric static_assert((unsigned)alignof(MCSymbol) <= alignof(NameEntryStorageTy),
400b57cec5SDimitry Andric "Bad alignment of MCSymbol");
410b57cec5SDimitry Andric void *Storage = Ctx.allocate(Size, alignof(NameEntryStorageTy));
420b57cec5SDimitry Andric NameEntryStorageTy *Start = static_cast<NameEntryStorageTy*>(Storage);
430b57cec5SDimitry Andric NameEntryStorageTy *End = Start + (Name ? 1 : 0);
440b57cec5SDimitry Andric return End;
450b57cec5SDimitry Andric }
460b57cec5SDimitry Andric
setVariableValue(const MCExpr * Value)470b57cec5SDimitry Andric void MCSymbol::setVariableValue(const MCExpr *Value) {
480b57cec5SDimitry Andric assert(!IsUsed && "Cannot set a variable that has already been used.");
490b57cec5SDimitry Andric assert(Value && "Invalid variable value!");
500b57cec5SDimitry Andric assert((SymbolContents == SymContentsUnset ||
510b57cec5SDimitry Andric SymbolContents == SymContentsVariable) &&
520b57cec5SDimitry Andric "Cannot give common/offset symbol a variable value");
530b57cec5SDimitry Andric this->Value = Value;
540b57cec5SDimitry Andric SymbolContents = SymContentsVariable;
550b57cec5SDimitry Andric setUndefined();
560b57cec5SDimitry Andric }
570b57cec5SDimitry Andric
print(raw_ostream & OS,const MCAsmInfo * MAI) const580b57cec5SDimitry Andric void MCSymbol::print(raw_ostream &OS, const MCAsmInfo *MAI) const {
590b57cec5SDimitry Andric // The name for this MCSymbol is required to be a valid target name. However,
600b57cec5SDimitry Andric // some targets support quoting names with funny characters. If the name
610b57cec5SDimitry Andric // contains a funny character, then print it quoted.
620b57cec5SDimitry Andric StringRef Name = getName();
630b57cec5SDimitry Andric if (!MAI || MAI->isValidUnquotedName(Name)) {
640b57cec5SDimitry Andric OS << Name;
650b57cec5SDimitry Andric return;
660b57cec5SDimitry Andric }
670b57cec5SDimitry Andric
680b57cec5SDimitry Andric if (MAI && !MAI->supportsNameQuoting())
690b57cec5SDimitry Andric report_fatal_error("Symbol name with unsupported characters");
700b57cec5SDimitry Andric
710b57cec5SDimitry Andric OS << '"';
720b57cec5SDimitry Andric for (char C : Name) {
730b57cec5SDimitry Andric if (C == '\n')
740b57cec5SDimitry Andric OS << "\\n";
750b57cec5SDimitry Andric else if (C == '"')
760b57cec5SDimitry Andric OS << "\\\"";
770b57cec5SDimitry Andric else
780b57cec5SDimitry Andric OS << C;
790b57cec5SDimitry Andric }
800b57cec5SDimitry Andric OS << '"';
810b57cec5SDimitry Andric }
820b57cec5SDimitry Andric
830b57cec5SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const840b57cec5SDimitry Andric LLVM_DUMP_METHOD void MCSymbol::dump() const {
850b57cec5SDimitry Andric dbgs() << *this;
860b57cec5SDimitry Andric }
870b57cec5SDimitry Andric #endif
88