1 //===-- RecordStreamer.cpp - Record asm defined and used symbols ----------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "RecordStreamer.h"
11 #include "llvm/MC/MCContext.h"
12 #include "llvm/MC/MCSymbol.h"
13 
14 using namespace llvm;
15 
16 void RecordStreamer::markDefined(const MCSymbol &Symbol) {
17   State &S = Symbols[Symbol.getName()];
18   switch (S) {
19   case DefinedGlobal:
20   case Global:
21     S = DefinedGlobal;
22     break;
23   case NeverSeen:
24   case Defined:
25   case Used:
26     S = Defined;
27     break;
28   case DefinedWeak:
29     break;
30   case UndefinedWeak:
31     S = DefinedWeak;
32   }
33 }
34 
35 void RecordStreamer::markGlobal(const MCSymbol &Symbol,
36                                 MCSymbolAttr Attribute) {
37   State &S = Symbols[Symbol.getName()];
38   switch (S) {
39   case DefinedGlobal:
40   case Defined:
41     S = (Attribute == MCSA_Weak) ? DefinedWeak : DefinedGlobal;
42     break;
43 
44   case NeverSeen:
45   case Global:
46   case Used:
47     S = (Attribute == MCSA_Weak) ? UndefinedWeak : Global;
48     break;
49   case UndefinedWeak:
50   case DefinedWeak:
51     break;
52   }
53 }
54 
55 void RecordStreamer::markUsed(const MCSymbol &Symbol) {
56   State &S = Symbols[Symbol.getName()];
57   switch (S) {
58   case DefinedGlobal:
59   case Defined:
60   case Global:
61   case DefinedWeak:
62   case UndefinedWeak:
63     break;
64 
65   case NeverSeen:
66   case Used:
67     S = Used;
68     break;
69   }
70 }
71 
72 void RecordStreamer::visitUsedSymbol(const MCSymbol &Sym) { markUsed(Sym); }
73 
74 RecordStreamer::RecordStreamer(MCContext &Context) : MCStreamer(Context) {}
75 
76 RecordStreamer::const_iterator RecordStreamer::begin() {
77   return Symbols.begin();
78 }
79 
80 RecordStreamer::const_iterator RecordStreamer::end() { return Symbols.end(); }
81 
82 void RecordStreamer::EmitInstruction(const MCInst &Inst,
83                                      const MCSubtargetInfo &STI, bool) {
84   MCStreamer::EmitInstruction(Inst, STI);
85 }
86 
87 void RecordStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc) {
88   MCStreamer::EmitLabel(Symbol);
89   markDefined(*Symbol);
90 }
91 
92 void RecordStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
93   markDefined(*Symbol);
94   MCStreamer::EmitAssignment(Symbol, Value);
95 }
96 
97 bool RecordStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
98                                          MCSymbolAttr Attribute) {
99   if (Attribute == MCSA_Global || Attribute == MCSA_Weak)
100     markGlobal(*Symbol, Attribute);
101   if (Attribute == MCSA_LazyReference)
102     markUsed(*Symbol);
103   return true;
104 }
105 
106 void RecordStreamer::EmitZerofill(MCSection *Section, MCSymbol *Symbol,
107                                   uint64_t Size, unsigned ByteAlignment) {
108   markDefined(*Symbol);
109 }
110 
111 void RecordStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
112                                       unsigned ByteAlignment) {
113   markDefined(*Symbol);
114 }
115 
116 void RecordStreamer::emitELFSymverDirective(StringRef AliasName,
117                                             const MCSymbol *Aliasee) {
118   MCSymbol *Alias = getContext().getOrCreateSymbol(AliasName);
119   const MCExpr *Value = MCSymbolRefExpr::create(Aliasee, getContext());
120   EmitAssignment(Alias, Value);
121   SymverAliasMap[Aliasee].push_back(Alias);
122 }
123