2009-06-23 22:01:43 +00:00
|
|
|
//===- MCSymbol.h - Machine Code Symbols ------------------------*- C++ -*-===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
2009-07-01 06:21:53 +00:00
|
|
|
//
|
|
|
|
// This file contains the declaration of the MCSymbol class.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
2009-06-23 22:01:43 +00:00
|
|
|
|
|
|
|
#ifndef LLVM_MC_MCSYMBOL_H
|
|
|
|
#define LLVM_MC_MCSYMBOL_H
|
|
|
|
|
2015-06-30 20:54:21 +00:00
|
|
|
#include "llvm/ADT/PointerIntPair.h"
|
2015-05-22 06:04:42 +00:00
|
|
|
#include "llvm/ADT/StringMap.h"
|
2017-02-08 22:23:19 +00:00
|
|
|
#include "llvm/ADT/StringRef.h"
|
2016-06-22 23:23:08 +00:00
|
|
|
#include "llvm/MC/MCFragment.h"
|
2017-02-08 22:23:19 +00:00
|
|
|
#include "llvm/Support/ErrorHandling.h"
|
|
|
|
#include "llvm/Support/MathExtras.h"
|
|
|
|
#include <cassert>
|
|
|
|
#include <cstddef>
|
|
|
|
#include <cstdint>
|
2009-06-23 22:01:43 +00:00
|
|
|
|
|
|
|
namespace llvm {
|
2017-02-08 22:23:19 +00:00
|
|
|
|
2015-06-09 00:31:39 +00:00
|
|
|
class MCAsmInfo;
|
2017-02-08 22:23:19 +00:00
|
|
|
class MCContext;
|
2015-05-13 21:41:14 +00:00
|
|
|
class MCExpr;
|
|
|
|
class MCSection;
|
|
|
|
class raw_ostream;
|
|
|
|
|
|
|
|
/// MCSymbol - Instances of this class represent a symbol name in the MC file,
|
|
|
|
/// and MCSymbols are created and uniqued by the MCContext class. MCSymbols
|
|
|
|
/// should only be constructed with valid names for the object file.
|
|
|
|
///
|
|
|
|
/// If the symbol is defined/emitted into the current translation unit, the
|
|
|
|
/// Section member is set to indicate what section it lives in. Otherwise, if
|
|
|
|
/// it is a reference to an external entity, it has a null section.
|
|
|
|
class MCSymbol {
|
2015-06-08 17:17:09 +00:00
|
|
|
protected:
|
|
|
|
/// The kind of the symbol. If it is any value other than unset then this
|
|
|
|
/// class is actually one of the appropriate subclasses of MCSymbol.
|
|
|
|
enum SymbolKind {
|
|
|
|
SymbolKindUnset,
|
|
|
|
SymbolKindCOFF,
|
|
|
|
SymbolKindELF,
|
|
|
|
SymbolKindMachO,
|
2017-02-22 01:23:18 +00:00
|
|
|
SymbolKindWasm,
|
2015-06-08 17:17:09 +00:00
|
|
|
};
|
|
|
|
|
2015-06-22 19:57:33 +00:00
|
|
|
/// A symbol can contain an Offset, or Value, or be Common, but never more
|
|
|
|
/// than one of these.
|
|
|
|
enum Contents : uint8_t {
|
|
|
|
SymContentsUnset,
|
|
|
|
SymContentsOffset,
|
|
|
|
SymContentsVariable,
|
|
|
|
SymContentsCommon,
|
|
|
|
};
|
|
|
|
|
2015-10-05 12:07:05 +00:00
|
|
|
// Special sentinal value for the absolute pseudo fragment.
|
|
|
|
static MCFragment *AbsolutePseudoFragment;
|
2015-05-13 21:41:14 +00:00
|
|
|
|
2015-06-01 14:34:40 +00:00
|
|
|
/// If a symbol has a Fragment, the section is implied, so we only need
|
|
|
|
/// one pointer.
|
2015-10-05 12:07:05 +00:00
|
|
|
/// The special AbsolutePseudoFragment value is for absolute symbols.
|
|
|
|
/// If this is a variable symbol, this caches the variable value's fragment.
|
2015-06-01 14:34:40 +00:00
|
|
|
/// FIXME: We might be able to simplify this by having the asm streamer create
|
|
|
|
/// dummy fragments.
|
2015-06-08 18:41:57 +00:00
|
|
|
/// If this is a section, then it gives the symbol is defined in. This is null
|
2015-10-05 12:07:05 +00:00
|
|
|
/// for undefined symbols.
|
2015-06-08 18:41:57 +00:00
|
|
|
///
|
|
|
|
/// If this is a fragment, then it gives the fragment this symbol's value is
|
|
|
|
/// relative to, if any.
|
2015-06-30 20:54:21 +00:00
|
|
|
///
|
|
|
|
/// For the 'HasName' integer, this is true if this symbol is named.
|
|
|
|
/// A named symbol will have a pointer to the name allocated in the bytes
|
|
|
|
/// immediately prior to the MCSymbol.
|
2015-10-05 12:07:05 +00:00
|
|
|
mutable PointerIntPair<MCFragment *, 1> FragmentAndHasName;
|
2015-05-13 21:41:14 +00:00
|
|
|
|
|
|
|
/// IsTemporary - True if this is an assembler temporary label, which
|
|
|
|
/// typically does not survive in the .o file's symbol table. Usually
|
|
|
|
/// "Lfoo" or ".foo".
|
|
|
|
unsigned IsTemporary : 1;
|
|
|
|
|
2018-05-01 15:54:18 +00:00
|
|
|
/// True if this symbol can be redefined.
|
2015-05-13 21:41:14 +00:00
|
|
|
unsigned IsRedefinable : 1;
|
|
|
|
|
|
|
|
/// IsUsed - True if this symbol has been used.
|
|
|
|
mutable unsigned IsUsed : 1;
|
|
|
|
|
2016-06-24 04:05:25 +00:00
|
|
|
mutable unsigned IsRegistered : 1;
|
2015-05-16 00:03:06 +00:00
|
|
|
|
2015-06-01 14:34:40 +00:00
|
|
|
/// This symbol is visible outside this translation unit.
|
|
|
|
mutable unsigned IsExternal : 1;
|
|
|
|
|
|
|
|
/// This symbol is private extern.
|
|
|
|
mutable unsigned IsPrivateExtern : 1;
|
|
|
|
|
2015-06-08 22:12:44 +00:00
|
|
|
/// LLVM RTTI discriminator. This is actually a SymbolKind enumerator, but is
|
|
|
|
/// unsigned to avoid sign extension and achieve better bitpacking with MSVC.
|
2017-02-22 01:23:18 +00:00
|
|
|
unsigned Kind : 3;
|
2015-06-02 00:25:12 +00:00
|
|
|
|
2015-06-17 20:08:20 +00:00
|
|
|
/// True if we have created a relocation that uses this symbol.
|
|
|
|
mutable unsigned IsUsedInReloc : 1;
|
|
|
|
|
2015-06-22 19:57:33 +00:00
|
|
|
/// This is actually a Contents enumerator, but is unsigned to avoid sign
|
|
|
|
/// extension and achieve better bitpacking with MSVC.
|
|
|
|
unsigned SymbolContents : 2;
|
|
|
|
|
2015-07-01 21:07:03 +00:00
|
|
|
/// The alignment of the symbol, if it is 'common', or -1.
|
|
|
|
///
|
|
|
|
/// The alignment is stored as log2(align) + 1. This allows all values from
|
|
|
|
/// 0 to 2^31 to be stored which is every power of 2 representable by an
|
|
|
|
/// unsigned.
|
2015-07-10 21:50:04 +00:00
|
|
|
enum : unsigned { NumCommonAlignmentBits = 5 };
|
2015-07-01 21:07:03 +00:00
|
|
|
unsigned CommonAlignLog2 : NumCommonAlignmentBits;
|
|
|
|
|
2015-07-01 21:57:51 +00:00
|
|
|
/// The Flags field is used by object file implementations to store
|
|
|
|
/// additional per symbol information which is not easily classified.
|
2015-07-10 21:50:04 +00:00
|
|
|
enum : unsigned { NumFlagsBits = 16 };
|
2015-07-01 21:57:51 +00:00
|
|
|
mutable uint32_t Flags : NumFlagsBits;
|
|
|
|
|
2015-05-22 05:54:01 +00:00
|
|
|
/// Index field, for use by the object file implementation.
|
2015-06-01 00:58:31 +00:00
|
|
|
mutable uint32_t Index = 0;
|
2015-05-22 05:59:05 +00:00
|
|
|
|
2015-05-29 17:48:04 +00:00
|
|
|
union {
|
|
|
|
/// The offset to apply to the fragment address to form this symbol's value.
|
|
|
|
uint64_t Offset;
|
|
|
|
|
|
|
|
/// The size of the symbol, if it is 'common'.
|
|
|
|
uint64_t CommonSize;
|
2015-06-22 19:57:33 +00:00
|
|
|
|
|
|
|
/// If non-null, the value for a variable symbol.
|
|
|
|
const MCExpr *Value;
|
2015-05-29 17:48:04 +00:00
|
|
|
};
|
|
|
|
|
2017-02-08 22:23:19 +00:00
|
|
|
// MCContext creates and uniques these.
|
2015-05-13 21:41:14 +00:00
|
|
|
friend class MCExpr;
|
|
|
|
friend class MCContext;
|
2015-06-09 18:36:13 +00:00
|
|
|
|
2018-05-01 15:54:18 +00:00
|
|
|
/// The name for a symbol.
|
2015-06-09 19:56:05 +00:00
|
|
|
/// MCSymbol contains a uint64_t so is probably aligned to 8. On a 32-bit
|
|
|
|
/// system, the name is a pointer so isn't going to satisfy the 8 byte
|
|
|
|
/// alignment of uint64_t. Account for that here.
|
2017-04-26 22:31:39 +00:00
|
|
|
using NameEntryStorageTy = union {
|
2015-06-09 19:56:05 +00:00
|
|
|
const StringMapEntry<bool> *NameEntry;
|
|
|
|
uint64_t AlignmentPadding;
|
2017-04-26 22:31:39 +00:00
|
|
|
};
|
2015-06-09 19:56:05 +00:00
|
|
|
|
|
|
|
MCSymbol(SymbolKind Kind, const StringMapEntry<bool> *Name, bool isTemporary)
|
2015-06-30 20:54:21 +00:00
|
|
|
: IsTemporary(isTemporary), IsRedefinable(false), IsUsed(false),
|
|
|
|
IsRegistered(false), IsExternal(false), IsPrivateExtern(false),
|
2015-07-01 21:07:03 +00:00
|
|
|
Kind(Kind), IsUsedInReloc(false), SymbolContents(SymContentsUnset),
|
2015-07-01 21:57:51 +00:00
|
|
|
CommonAlignLog2(0), Flags(0) {
|
2015-05-29 17:48:04 +00:00
|
|
|
Offset = 0;
|
2015-10-05 12:07:05 +00:00
|
|
|
FragmentAndHasName.setInt(!!Name);
|
2015-06-09 18:36:13 +00:00
|
|
|
if (Name)
|
2015-06-09 20:41:08 +00:00
|
|
|
getNameEntryPtr() = Name;
|
2015-05-29 17:48:04 +00:00
|
|
|
}
|
2015-05-13 21:41:14 +00:00
|
|
|
|
2015-06-09 18:36:13 +00:00
|
|
|
// Provide custom new/delete as we will only allocate space for a name
|
|
|
|
// if we need one.
|
2015-06-09 19:56:05 +00:00
|
|
|
void *operator new(size_t s, const StringMapEntry<bool> *Name,
|
|
|
|
MCContext &Ctx);
|
2015-06-09 18:36:13 +00:00
|
|
|
|
2015-06-02 00:25:12 +00:00
|
|
|
private:
|
2015-06-09 18:36:13 +00:00
|
|
|
void operator delete(void *);
|
2018-05-01 15:54:18 +00:00
|
|
|
/// Placement delete - required by std, but never called.
|
2015-06-09 18:36:13 +00:00
|
|
|
void operator delete(void*, unsigned) {
|
|
|
|
llvm_unreachable("Constructor throws?");
|
|
|
|
}
|
2018-05-01 15:54:18 +00:00
|
|
|
/// Placement delete - required by std, but never called.
|
2015-06-09 18:36:13 +00:00
|
|
|
void operator delete(void*, unsigned, bool) {
|
|
|
|
llvm_unreachable("Constructor throws?");
|
|
|
|
}
|
|
|
|
|
2018-01-12 18:05:40 +00:00
|
|
|
MCSection *getSectionPtr() const {
|
|
|
|
if (MCFragment *F = getFragment()) {
|
2015-10-05 12:07:05 +00:00
|
|
|
assert(F != AbsolutePseudoFragment);
|
2015-06-01 14:34:40 +00:00
|
|
|
return F->getParent();
|
2015-10-05 12:07:05 +00:00
|
|
|
}
|
|
|
|
return nullptr;
|
2015-05-13 21:41:14 +00:00
|
|
|
}
|
2014-12-24 10:27:50 +00:00
|
|
|
|
2018-05-01 15:54:18 +00:00
|
|
|
/// Get a reference to the name field. Requires that we have a name
|
2015-06-09 20:41:08 +00:00
|
|
|
const StringMapEntry<bool> *&getNameEntryPtr() {
|
2015-10-05 12:07:05 +00:00
|
|
|
assert(FragmentAndHasName.getInt() && "Name is required");
|
2015-06-09 19:56:05 +00:00
|
|
|
NameEntryStorageTy *Name = reinterpret_cast<NameEntryStorageTy *>(this);
|
2015-06-09 20:41:08 +00:00
|
|
|
return (*(Name - 1)).NameEntry;
|
2015-06-09 18:36:13 +00:00
|
|
|
}
|
2015-06-09 20:41:08 +00:00
|
|
|
const StringMapEntry<bool> *&getNameEntryPtr() const {
|
|
|
|
return const_cast<MCSymbol*>(this)->getNameEntryPtr();
|
2015-06-09 18:36:13 +00:00
|
|
|
}
|
|
|
|
|
2015-05-13 21:41:14 +00:00
|
|
|
public:
|
2017-02-08 22:23:19 +00:00
|
|
|
MCSymbol(const MCSymbol &) = delete;
|
|
|
|
MCSymbol &operator=(const MCSymbol &) = delete;
|
|
|
|
|
2015-05-13 21:41:14 +00:00
|
|
|
/// getName - Get the symbol name.
|
2015-06-09 18:36:13 +00:00
|
|
|
StringRef getName() const {
|
2015-10-05 12:07:05 +00:00
|
|
|
if (!FragmentAndHasName.getInt())
|
2015-06-09 18:36:13 +00:00
|
|
|
return StringRef();
|
|
|
|
|
2015-06-09 20:41:08 +00:00
|
|
|
return getNameEntryPtr()->first();
|
2015-06-09 18:36:13 +00:00
|
|
|
}
|
2009-10-16 01:33:57 +00:00
|
|
|
|
2015-06-01 01:52:18 +00:00
|
|
|
bool isRegistered() const { return IsRegistered; }
|
|
|
|
void setIsRegistered(bool Value) const { IsRegistered = Value; }
|
2015-05-16 00:03:06 +00:00
|
|
|
|
2015-06-17 20:08:20 +00:00
|
|
|
void setUsedInReloc() const { IsUsedInReloc = true; }
|
|
|
|
bool isUsedInReloc() const { return IsUsedInReloc; }
|
|
|
|
|
2015-05-13 21:41:14 +00:00
|
|
|
/// \name Accessors
|
|
|
|
/// @{
|
2009-08-26 00:10:55 +00:00
|
|
|
|
2015-05-13 21:41:14 +00:00
|
|
|
/// isTemporary - Check if this is an assembler temporary symbol.
|
|
|
|
bool isTemporary() const { return IsTemporary; }
|
2010-03-18 00:59:02 +00:00
|
|
|
|
2015-05-13 21:41:14 +00:00
|
|
|
/// isUsed - Check if this is used.
|
|
|
|
bool isUsed() const { return IsUsed; }
|
2009-08-22 07:22:36 +00:00
|
|
|
|
2018-05-01 15:54:18 +00:00
|
|
|
/// Check if this symbol is redefinable.
|
2015-05-13 21:41:14 +00:00
|
|
|
bool isRedefinable() const { return IsRedefinable; }
|
2018-05-01 15:54:18 +00:00
|
|
|
/// Mark this symbol as redefinable.
|
2015-05-13 21:41:14 +00:00
|
|
|
void setRedefinable(bool Value) { IsRedefinable = Value; }
|
2018-05-01 15:54:18 +00:00
|
|
|
/// Prepare this symbol to be redefined.
|
2015-05-13 21:41:14 +00:00
|
|
|
void redefineIfPossible() {
|
|
|
|
if (IsRedefinable) {
|
2015-06-22 19:57:33 +00:00
|
|
|
if (SymbolContents == SymContentsVariable) {
|
|
|
|
Value = nullptr;
|
|
|
|
SymbolContents = SymContentsUnset;
|
|
|
|
}
|
2015-06-30 20:54:21 +00:00
|
|
|
setUndefined();
|
2015-05-13 21:41:14 +00:00
|
|
|
IsRedefinable = false;
|
2009-08-22 07:22:36 +00:00
|
|
|
}
|
2015-05-13 21:41:14 +00:00
|
|
|
}
|
2009-08-22 07:22:36 +00:00
|
|
|
|
2015-05-13 21:41:14 +00:00
|
|
|
/// @}
|
|
|
|
/// \name Associated Sections
|
|
|
|
/// @{
|
2009-08-22 07:22:36 +00:00
|
|
|
|
2015-05-13 21:41:14 +00:00
|
|
|
/// isDefined - Check if this symbol is defined (i.e., it has an address).
|
|
|
|
///
|
|
|
|
/// Defined symbols are either absolute or in some section.
|
2018-01-12 18:05:40 +00:00
|
|
|
bool isDefined() const { return !isUndefined(); }
|
2009-08-22 07:22:36 +00:00
|
|
|
|
2015-05-13 21:41:14 +00:00
|
|
|
/// isInSection - Check if this symbol is defined in some section (i.e., it
|
|
|
|
/// is defined but not absolute).
|
2018-01-12 18:05:40 +00:00
|
|
|
bool isInSection() const {
|
|
|
|
return isDefined() && !isAbsolute();
|
2015-08-25 22:06:07 +00:00
|
|
|
}
|
2009-08-22 07:22:36 +00:00
|
|
|
|
2015-05-13 21:41:14 +00:00
|
|
|
/// isUndefined - Check if this symbol undefined (i.e., implicitly defined).
|
2018-01-12 18:05:40 +00:00
|
|
|
bool isUndefined(bool SetUsed = true) const {
|
|
|
|
return getFragment(SetUsed) == nullptr;
|
|
|
|
}
|
2009-10-16 01:33:57 +00:00
|
|
|
|
2015-05-13 21:41:14 +00:00
|
|
|
/// isAbsolute - Check if this is an absolute symbol.
|
2018-01-12 18:05:40 +00:00
|
|
|
bool isAbsolute() const {
|
|
|
|
return getFragment() == AbsolutePseudoFragment;
|
2015-08-25 22:06:07 +00:00
|
|
|
}
|
2009-10-16 01:33:57 +00:00
|
|
|
|
2015-05-21 19:20:38 +00:00
|
|
|
/// Get the section associated with a defined, non-absolute symbol.
|
2018-01-12 18:05:40 +00:00
|
|
|
MCSection &getSection() const {
|
|
|
|
assert(isInSection() && "Invalid accessor!");
|
|
|
|
return *getSectionPtr();
|
2015-05-13 21:41:14 +00:00
|
|
|
}
|
2009-10-16 01:33:57 +00:00
|
|
|
|
2015-10-05 12:07:05 +00:00
|
|
|
/// Mark the symbol as defined in the fragment \p F.
|
|
|
|
void setFragment(MCFragment *F) const {
|
|
|
|
assert(!isVariable() && "Cannot set fragment of variable");
|
|
|
|
FragmentAndHasName.setPointer(F);
|
2015-05-13 21:41:14 +00:00
|
|
|
}
|
2009-10-16 01:33:57 +00:00
|
|
|
|
2015-06-01 14:34:40 +00:00
|
|
|
/// Mark the symbol as undefined.
|
2015-10-05 12:07:05 +00:00
|
|
|
void setUndefined() { FragmentAndHasName.setPointer(nullptr); }
|
2009-08-14 03:41:23 +00:00
|
|
|
|
2015-06-08 17:17:09 +00:00
|
|
|
bool isELF() const { return Kind == SymbolKindELF; }
|
|
|
|
|
|
|
|
bool isCOFF() const { return Kind == SymbolKindCOFF; }
|
|
|
|
|
|
|
|
bool isMachO() const { return Kind == SymbolKindMachO; }
|
2015-06-02 00:25:12 +00:00
|
|
|
|
2017-02-22 01:23:18 +00:00
|
|
|
bool isWasm() const { return Kind == SymbolKindWasm; }
|
|
|
|
|
2015-05-13 21:41:14 +00:00
|
|
|
/// @}
|
|
|
|
/// \name Variable Symbols
|
|
|
|
/// @{
|
2009-08-14 03:41:23 +00:00
|
|
|
|
2015-05-13 21:41:14 +00:00
|
|
|
/// isVariable - Check if this is a variable symbol.
|
2015-06-22 19:57:33 +00:00
|
|
|
bool isVariable() const {
|
|
|
|
return SymbolContents == SymContentsVariable;
|
|
|
|
}
|
2009-06-23 22:01:43 +00:00
|
|
|
|
2015-08-25 22:06:07 +00:00
|
|
|
/// getVariableValue - Get the value for variable symbols.
|
|
|
|
const MCExpr *getVariableValue(bool SetUsed = true) const {
|
2015-05-13 21:41:14 +00:00
|
|
|
assert(isVariable() && "Invalid accessor!");
|
2015-08-25 22:06:07 +00:00
|
|
|
IsUsed |= SetUsed;
|
2015-05-13 21:41:14 +00:00
|
|
|
return Value;
|
2010-01-17 21:43:43 +00:00
|
|
|
}
|
2015-05-13 21:41:14 +00:00
|
|
|
|
|
|
|
void setVariableValue(const MCExpr *Value);
|
|
|
|
|
|
|
|
/// @}
|
|
|
|
|
2015-05-22 05:54:01 +00:00
|
|
|
/// Get the (implementation defined) index.
|
2015-06-01 00:58:31 +00:00
|
|
|
uint32_t getIndex() const {
|
2015-05-22 05:54:01 +00:00
|
|
|
return Index;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Set the (implementation defined) index.
|
2015-06-01 00:58:31 +00:00
|
|
|
void setIndex(uint32_t Value) const {
|
2015-05-22 05:54:01 +00:00
|
|
|
Index = Value;
|
|
|
|
}
|
|
|
|
|
[MC] Change AsmParser to leverage Assembler during evaluation
Teach AsmParser to check with Assembler for when evaluating constant
expressions. This improves the handing of preprocessor expressions
that must be resolved at parse time. This idiom can be found as
assembling-time assertion checks in source-level assemblers. Note that
this relies on the MCStreamer to keep sufficient tabs on Section /
Fragment information which the MCAsmStreamer does not. As a result the
textual output may fail where the equivalent object generation would
pass. This can most easily be resolved by folding the MCAsmStreamer
and MCObjectStreamer together which is planned for in a separate
patch.
Currently, this feature is only enabled for assembly input, keeping IR
compilation consistent between assembly and object generation.
Reviewers: echristo, rnk, probinson, espindola, peter.smith
Reviewed By: peter.smith
Subscribers: eraman, peter.smith, arichardson, jyknight, hiraditya, llvm-commits
Differential Revision: https://reviews.llvm.org/D45164
llvm-svn: 331218
2018-04-30 19:22:40 +00:00
|
|
|
bool isUnset() const { return SymbolContents == SymContentsUnset; }
|
|
|
|
|
2015-05-29 17:48:04 +00:00
|
|
|
uint64_t getOffset() const {
|
2015-06-22 19:57:33 +00:00
|
|
|
assert((SymbolContents == SymContentsUnset ||
|
|
|
|
SymbolContents == SymContentsOffset) &&
|
|
|
|
"Cannot get offset for a common/variable symbol");
|
2015-05-29 17:48:04 +00:00
|
|
|
return Offset;
|
|
|
|
}
|
|
|
|
void setOffset(uint64_t Value) {
|
2015-06-22 19:57:33 +00:00
|
|
|
assert((SymbolContents == SymContentsUnset ||
|
|
|
|
SymbolContents == SymContentsOffset) &&
|
|
|
|
"Cannot set offset for a common/variable symbol");
|
2015-05-29 17:48:04 +00:00
|
|
|
Offset = Value;
|
2015-06-22 19:57:33 +00:00
|
|
|
SymbolContents = SymContentsOffset;
|
2015-05-29 17:48:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Return the size of a 'common' symbol.
|
|
|
|
uint64_t getCommonSize() const {
|
|
|
|
assert(isCommon() && "Not a 'common' symbol!");
|
|
|
|
return CommonSize;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Mark this symbol as being 'common'.
|
|
|
|
///
|
|
|
|
/// \param Size - The size of the symbol.
|
|
|
|
/// \param Align - The alignment of the symbol.
|
|
|
|
void setCommon(uint64_t Size, unsigned Align) {
|
|
|
|
assert(getOffset() == 0);
|
|
|
|
CommonSize = Size;
|
2015-06-22 19:57:33 +00:00
|
|
|
SymbolContents = SymContentsCommon;
|
2015-07-01 21:07:03 +00:00
|
|
|
|
|
|
|
assert((!Align || isPowerOf2_32(Align)) &&
|
|
|
|
"Alignment must be a power of 2");
|
|
|
|
unsigned Log2Align = Log2_32(Align) + 1;
|
|
|
|
assert(Log2Align < (1U << NumCommonAlignmentBits) &&
|
|
|
|
"Out of range alignment");
|
|
|
|
CommonAlignLog2 = Log2Align;
|
2015-05-29 17:48:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Return the alignment of a 'common' symbol.
|
|
|
|
unsigned getCommonAlignment() const {
|
|
|
|
assert(isCommon() && "Not a 'common' symbol!");
|
2015-07-01 21:07:03 +00:00
|
|
|
return CommonAlignLog2 ? (1U << (CommonAlignLog2 - 1)) : 0;
|
2015-05-29 17:48:04 +00:00
|
|
|
}
|
|
|
|
|
2015-06-06 20:12:40 +00:00
|
|
|
/// Declare this symbol as being 'common'.
|
|
|
|
///
|
|
|
|
/// \param Size - The size of the symbol.
|
|
|
|
/// \param Align - The alignment of the symbol.
|
|
|
|
/// \return True if symbol was already declared as a different type
|
|
|
|
bool declareCommon(uint64_t Size, unsigned Align) {
|
|
|
|
assert(isCommon() || getOffset() == 0);
|
|
|
|
if(isCommon()) {
|
2015-07-01 21:07:03 +00:00
|
|
|
if(CommonSize != Size || getCommonAlignment() != Align)
|
2015-06-06 20:12:40 +00:00
|
|
|
return true;
|
|
|
|
} else
|
|
|
|
setCommon(Size, Align);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-05-29 17:48:04 +00:00
|
|
|
/// Is this a 'common' symbol.
|
2015-06-22 19:57:33 +00:00
|
|
|
bool isCommon() const {
|
|
|
|
return SymbolContents == SymContentsCommon;
|
|
|
|
}
|
2015-05-29 17:48:04 +00:00
|
|
|
|
2015-10-05 12:07:05 +00:00
|
|
|
MCFragment *getFragment(bool SetUsed = true) const {
|
|
|
|
MCFragment *Fragment = FragmentAndHasName.getPointer();
|
|
|
|
if (Fragment || !isVariable())
|
|
|
|
return Fragment;
|
|
|
|
Fragment = getVariableValue(SetUsed)->findAssociatedFragment();
|
|
|
|
FragmentAndHasName.setPointer(Fragment);
|
|
|
|
return Fragment;
|
2015-05-29 20:31:23 +00:00
|
|
|
}
|
|
|
|
|
2015-06-01 14:34:40 +00:00
|
|
|
bool isExternal() const { return IsExternal; }
|
|
|
|
void setExternal(bool Value) const { IsExternal = Value; }
|
|
|
|
|
|
|
|
bool isPrivateExtern() const { return IsPrivateExtern; }
|
|
|
|
void setPrivateExtern(bool Value) { IsPrivateExtern = Value; }
|
|
|
|
|
2015-05-13 21:41:14 +00:00
|
|
|
/// print - Print the value to the stream \p OS.
|
2015-06-09 00:31:39 +00:00
|
|
|
void print(raw_ostream &OS, const MCAsmInfo *MAI) const;
|
2015-05-13 21:41:14 +00:00
|
|
|
|
|
|
|
/// dump - Print the value to stderr.
|
|
|
|
void dump() const;
|
2015-06-08 17:17:30 +00:00
|
|
|
|
|
|
|
protected:
|
|
|
|
/// Get the (implementation defined) symbol flags.
|
|
|
|
uint32_t getFlags() const { return Flags; }
|
|
|
|
|
|
|
|
/// Set the (implementation defined) symbol flags.
|
2015-07-01 21:57:51 +00:00
|
|
|
void setFlags(uint32_t Value) const {
|
|
|
|
assert(Value < (1U << NumFlagsBits) && "Out of range flags");
|
|
|
|
Flags = Value;
|
|
|
|
}
|
2015-06-08 17:17:30 +00:00
|
|
|
|
|
|
|
/// Modify the flags via a mask
|
|
|
|
void modifyFlags(uint32_t Value, uint32_t Mask) const {
|
2015-07-01 21:57:51 +00:00
|
|
|
assert(Value < (1U << NumFlagsBits) && "Out of range flags");
|
2015-06-08 17:17:30 +00:00
|
|
|
Flags = (Flags & ~Mask) | Value;
|
|
|
|
}
|
2015-05-13 21:41:14 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
inline raw_ostream &operator<<(raw_ostream &OS, const MCSymbol &Sym) {
|
2015-06-09 00:31:39 +00:00
|
|
|
Sym.print(OS, nullptr);
|
2015-05-13 21:41:14 +00:00
|
|
|
return OS;
|
|
|
|
}
|
2017-02-08 22:23:19 +00:00
|
|
|
|
2009-06-23 22:01:43 +00:00
|
|
|
} // end namespace llvm
|
|
|
|
|
2017-02-08 22:23:19 +00:00
|
|
|
#endif // LLVM_MC_MCSYMBOL_H
|