aboutsummaryrefslogtreecommitdiffstats
path: root/include/llvm/MC/MCSymbol.h
blob: 53443b01d96d5d3f2fee626071d845562cda41e2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
//===- 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.
//
//===----------------------------------------------------------------------===//
//
// This file contains the declaration of the MCSymbol class.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_MC_MCSYMBOL_H
#define LLVM_MC_MCSYMBOL_H

#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Compiler.h"

namespace llvm {
  class MCExpr;
  class MCSection;
  class MCContext;
  class raw_ostream;

  /// MCSymbol - Instances of this class represent a symbol name in the MC file,
  /// and MCSymbols are created and unique'd 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 {
    // Special sentinal value for the absolute pseudo section.
    //
    // FIXME: Use a PointerInt wrapper for this?
    static const MCSection *AbsolutePseudoSection;

    /// Name - The name of the symbol.  The referred-to string data is actually
    /// held by the StringMap that lives in MCContext.
    StringRef Name;

    /// Section - The section the symbol is defined in. This is null for
    /// undefined symbols, and the special AbsolutePseudoSection value for
    /// absolute symbols.
    const MCSection *Section;

    /// Value - If non-null, the value for a variable symbol.
    const MCExpr *Value;

    /// 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;

    /// \brief True if this symbol can be redefined.
    unsigned IsRedefinable : 1;

    /// IsUsed - True if this symbol has been used.
    mutable unsigned IsUsed : 1;

  private:  // MCContext creates and uniques these.
    friend class MCExpr;
    friend class MCContext;
    MCSymbol(StringRef name, bool isTemporary)
      : Name(name), Section(nullptr), Value(nullptr),
        IsTemporary(isTemporary), IsRedefinable(false), IsUsed(false) {}

    MCSymbol(const MCSymbol&) = delete;
    void operator=(const MCSymbol&) = delete;
  public:
    /// getName - Get the symbol name.
    StringRef getName() const { return Name; }

    /// @name Accessors
    /// @{

    /// isTemporary - Check if this is an assembler temporary symbol.
    bool isTemporary() const { return IsTemporary; }

    /// isUsed - Check if this is used.
    bool isUsed() const { return IsUsed; }
    void setUsed(bool Value) const { IsUsed = Value; }

    /// \brief Check if this symbol is redefinable.
    bool isRedefinable() const { return IsRedefinable; }
    /// \brief Mark this symbol as redefinable.
    void setRedefinable(bool Value) { IsRedefinable = Value; }
    /// \brief Prepare this symbol to be redefined.
    void redefineIfPossible() {
      if (IsRedefinable) {
        Value = nullptr;
        Section = nullptr;
        IsRedefinable = false;
      }
    }

    /// @}
    /// @name Associated Sections
    /// @{

    /// isDefined - Check if this symbol is defined (i.e., it has an address).
    ///
    /// Defined symbols are either absolute or in some section.
    bool isDefined() const {
      return Section != nullptr;
    }

    /// isInSection - Check if this symbol is defined in some section (i.e., it
    /// is defined but not absolute).
    bool isInSection() const {
      return isDefined() && !isAbsolute();
    }

    /// isUndefined - Check if this symbol undefined (i.e., implicitly defined).
    bool isUndefined() const {
      return !isDefined();
    }

    /// isAbsolute - Check if this is an absolute symbol.
    bool isAbsolute() const {
      return Section == AbsolutePseudoSection;
    }

    /// getSection - Get the section associated with a defined, non-absolute
    /// symbol.
    const MCSection &getSection() const {
      assert(isInSection() && "Invalid accessor!");
      return *Section;
    }

    /// setSection - Mark the symbol as defined in the section \p S.
    void setSection(const MCSection &S) { Section = &S; }

    /// setUndefined - Mark the symbol as undefined.
    void setUndefined() {
      Section = nullptr;
    }

    /// setAbsolute - Mark the symbol as absolute.
    void setAbsolute() { Section = AbsolutePseudoSection; }

    /// @}
    /// @name Variable Symbols
    /// @{

    /// isVariable - Check if this is a variable symbol.
    bool isVariable() const {
      return Value != nullptr;
    }

    /// getVariableValue() - Get the value for variable symbols.
    const MCExpr *getVariableValue() const {
      assert(isVariable() && "Invalid accessor!");
      IsUsed = true;
      return Value;
    }

    // AliasedSymbol() - If this is an alias (a = b), return the symbol
    // we ultimately point to. For a non-alias, this just returns the symbol
    // itself.
    const MCSymbol &AliasedSymbol() const;

    void setVariableValue(const MCExpr *Value);

    /// @}

    /// print - Print the value to the stream \p OS.
    void print(raw_ostream &OS) const;

    /// dump - Print the value to stderr.
    void dump() const;
  };

  inline raw_ostream &operator<<(raw_ostream &OS, const MCSymbol &Sym) {
    Sym.print(OS);
    return OS;
  }
} // end namespace llvm

#endif