switch MCSectionCOFF from a syntactic to semantic representation,
[oota-llvm.git] / lib / MC / MCContext.cpp
1 //===- lib/MC/MCContext.cpp - Machine Code Context ------------------------===//
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 "llvm/MC/MCContext.h"
11 #include "llvm/MC/MCAsmInfo.h"
12 #include "llvm/MC/MCSectionMachO.h"
13 #include "llvm/MC/MCSectionELF.h"
14 #include "llvm/MC/MCSectionCOFF.h"
15 #include "llvm/MC/MCSymbol.h"
16 #include "llvm/ADT/SmallString.h"
17 #include "llvm/ADT/Twine.h"
18 using namespace llvm;
19
20 typedef StringMap<const MCSectionMachO*> MachOUniqueMapTy;
21 typedef StringMap<const MCSectionELF*> ELFUniqueMapTy;
22 typedef StringMap<const MCSectionCOFF*> COFFUniqueMapTy;
23
24
25 MCContext::MCContext(const MCAsmInfo &mai) : MAI(mai), NextUniqueID(0) {
26   MachOUniquingMap = 0;
27   ELFUniquingMap = 0;
28   COFFUniquingMap = 0;
29 }
30
31 MCContext::~MCContext() {
32   // NOTE: The symbols are all allocated out of a bump pointer allocator,
33   // we don't need to free them here.
34   
35   // If we have the MachO uniquing map, free it.
36   delete (MachOUniqueMapTy*)MachOUniquingMap;
37   delete (ELFUniqueMapTy*)ELFUniquingMap;
38   delete (COFFUniqueMapTy*)COFFUniquingMap;
39 }
40
41 //===----------------------------------------------------------------------===//
42 // Symbol Manipulation
43 //===----------------------------------------------------------------------===//
44
45 MCSymbol *MCContext::GetOrCreateSymbol(StringRef Name) {
46   assert(!Name.empty() && "Normal symbols cannot be unnamed!");
47   
48   // Determine whether this is an assembler temporary or normal label.
49   bool isTemporary = Name.startswith(MAI.getPrivateGlobalPrefix());
50   
51   // Do the lookup and get the entire StringMapEntry.  We want access to the
52   // key if we are creating the entry.
53   StringMapEntry<MCSymbol*> &Entry = Symbols.GetOrCreateValue(Name);
54   if (Entry.getValue()) return Entry.getValue();
55
56   // Ok, the entry doesn't already exist.  Have the MCSymbol object itself refer
57   // to the copy of the string that is embedded in the StringMapEntry.
58   MCSymbol *Result = new (*this) MCSymbol(Entry.getKey(), isTemporary);
59   Entry.setValue(Result);
60   return Result; 
61 }
62
63 MCSymbol *MCContext::GetOrCreateSymbol(const Twine &Name) {
64   SmallString<128> NameSV;
65   Name.toVector(NameSV);
66   return GetOrCreateSymbol(NameSV.str());
67 }
68
69 MCSymbol *MCContext::CreateTempSymbol() {
70   return GetOrCreateSymbol(Twine(MAI.getPrivateGlobalPrefix()) +
71                            "tmp" + Twine(NextUniqueID++));
72 }
73
74 MCSymbol *MCContext::LookupSymbol(StringRef Name) const {
75   return Symbols.lookup(Name);
76 }
77
78 //===----------------------------------------------------------------------===//
79 // Section Management
80 //===----------------------------------------------------------------------===//
81
82 const MCSectionMachO *MCContext::
83 getMachOSection(StringRef Segment, StringRef Section,
84                 unsigned TypeAndAttributes,
85                 unsigned Reserved2, SectionKind Kind) {
86   
87   // We unique sections by their segment/section pair.  The returned section
88   // may not have the same flags as the requested section, if so this should be
89   // diagnosed by the client as an error.
90   
91   // Create the map if it doesn't already exist.
92   if (MachOUniquingMap == 0)
93     MachOUniquingMap = new MachOUniqueMapTy();
94   MachOUniqueMapTy &Map = *(MachOUniqueMapTy*)MachOUniquingMap;
95   
96   // Form the name to look up.
97   SmallString<64> Name;
98   Name += Segment;
99   Name.push_back(',');
100   Name += Section;
101   
102   // Do the lookup, if we have a hit, return it.
103   const MCSectionMachO *&Entry = Map[Name.str()];
104   if (Entry) return Entry;
105   
106   // Otherwise, return a new section.
107   return Entry = new (*this) MCSectionMachO(Segment, Section, TypeAndAttributes,
108                                             Reserved2, Kind);
109 }
110
111
112 const MCSection *MCContext::
113 getELFSection(StringRef Section, unsigned Type, unsigned Flags,
114               SectionKind Kind, bool IsExplicit) {
115   if (ELFUniquingMap == 0)
116     ELFUniquingMap = new ELFUniqueMapTy();
117   ELFUniqueMapTy &Map = *(ELFUniqueMapTy*)ELFUniquingMap;
118   
119   // Do the lookup, if we have a hit, return it.
120   StringMapEntry<const MCSectionELF*> &Entry = Map.GetOrCreateValue(Section);
121   if (Entry.getValue()) return Entry.getValue();
122   
123   MCSectionELF *Result = new (*this) MCSectionELF(Entry.getKey(), Type, Flags,
124                                                   Kind, IsExplicit);
125   Entry.setValue(Result);
126   return Result;
127 }
128
129 const MCSection *MCContext::
130 getCOFFSection(StringRef Section, unsigned Flags, SectionKind Kind) {
131   if (COFFUniquingMap == 0)
132     COFFUniquingMap = new COFFUniqueMapTy();
133   COFFUniqueMapTy &Map = *(COFFUniqueMapTy*)COFFUniquingMap;
134   
135   // Do the lookup, if we have a hit, return it.
136   StringMapEntry<const MCSectionCOFF*> &Entry = Map.GetOrCreateValue(Section);
137   if (Entry.getValue()) return Entry.getValue();
138   
139   MCSectionCOFF *Result = new (*this) MCSectionCOFF(Entry.getKey(), Flags,
140                                                     Kind);
141   
142   Entry.setValue(Result);
143   return Result;
144 }