xref: /freebsd/contrib/llvm-project/llvm/lib/MC/MCSymbol.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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