~ubuntu-branches/ubuntu/maverick/clamav/maverick-backports

« back to all changes in this revision

Viewing changes to libclamav/c++/llvm/lib/VMCore/Globals.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Stephen Gran, Stephen Gran, Michael Tautschnig
  • Date: 2010-04-26 21:41:18 UTC
  • mfrom: (2.1.6 squeeze)
  • Revision ID: james.westby@ubuntu.com-20100426214118-i6lo606wnh7ywfj6
Tags: 0.96+dfsg-4
[ Stephen Gran ]
* Fixed typo in clamav-milter's postinst

[ Michael Tautschnig ]
* Fixed typo in clamav-freshclam's postinst (closes: #579271)
* Debconf translation updates
  - Portuguese (closes: #579068)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//===-- Globals.cpp - Implement the GlobalValue & GlobalVariable class ----===//
 
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
// This file implements the GlobalValue & GlobalVariable classes for the VMCore
 
11
// library.
 
12
//
 
13
//===----------------------------------------------------------------------===//
 
14
 
 
15
#include "llvm/Constants.h"
 
16
#include "llvm/GlobalVariable.h"
 
17
#include "llvm/GlobalAlias.h"
 
18
#include "llvm/DerivedTypes.h"
 
19
#include "llvm/Module.h"
 
20
#include "llvm/ADT/SmallPtrSet.h"
 
21
#include "llvm/Support/ErrorHandling.h"
 
22
#include "llvm/Support/LeakDetector.h"
 
23
using namespace llvm;
 
24
 
 
25
//===----------------------------------------------------------------------===//
 
26
//                            GlobalValue Class
 
27
//===----------------------------------------------------------------------===//
 
28
 
 
29
/// removeDeadUsersOfConstant - If the specified constantexpr is dead, remove
 
30
/// it.  This involves recursively eliminating any dead users of the
 
31
/// constantexpr.
 
32
static bool removeDeadUsersOfConstant(const Constant *C) {
 
33
  if (isa<GlobalValue>(C)) return false; // Cannot remove this
 
34
 
 
35
  while (!C->use_empty()) {
 
36
    const Constant *User = dyn_cast<Constant>(C->use_back());
 
37
    if (!User) return false; // Non-constant usage;
 
38
    if (!removeDeadUsersOfConstant(User))
 
39
      return false; // Constant wasn't dead
 
40
  }
 
41
 
 
42
  const_cast<Constant*>(C)->destroyConstant();
 
43
  return true;
 
44
}
 
45
 
 
46
bool GlobalValue::isMaterializable() const {
 
47
  return getParent() && getParent()->isMaterializable(this);
 
48
}
 
49
bool GlobalValue::isDematerializable() const {
 
50
  return getParent() && getParent()->isDematerializable(this);
 
51
}
 
52
bool GlobalValue::Materialize(std::string *ErrInfo) {
 
53
  return getParent()->Materialize(this, ErrInfo);
 
54
}
 
55
void GlobalValue::Dematerialize() {
 
56
  getParent()->Dematerialize(this);
 
57
}
 
58
 
 
59
/// removeDeadConstantUsers - If there are any dead constant users dangling
 
60
/// off of this global value, remove them.  This method is useful for clients
 
61
/// that want to check to see if a global is unused, but don't want to deal
 
62
/// with potentially dead constants hanging off of the globals.
 
63
void GlobalValue::removeDeadConstantUsers() const {
 
64
  Value::use_const_iterator I = use_begin(), E = use_end();
 
65
  Value::use_const_iterator LastNonDeadUser = E;
 
66
  while (I != E) {
 
67
    if (const Constant *User = dyn_cast<Constant>(*I)) {
 
68
      if (!removeDeadUsersOfConstant(User)) {
 
69
        // If the constant wasn't dead, remember that this was the last live use
 
70
        // and move on to the next constant.
 
71
        LastNonDeadUser = I;
 
72
        ++I;
 
73
      } else {
 
74
        // If the constant was dead, then the iterator is invalidated.
 
75
        if (LastNonDeadUser == E) {
 
76
          I = use_begin();
 
77
          if (I == E) break;
 
78
        } else {
 
79
          I = LastNonDeadUser;
 
80
          ++I;
 
81
        }
 
82
      }
 
83
    } else {
 
84
      LastNonDeadUser = I;
 
85
      ++I;
 
86
    }
 
87
  }
 
88
}
 
89
 
 
90
 
 
91
/// Override destroyConstant to make sure it doesn't get called on
 
92
/// GlobalValue's because they shouldn't be treated like other constants.
 
93
void GlobalValue::destroyConstant() {
 
94
  llvm_unreachable("You can't GV->destroyConstant()!");
 
95
}
 
96
 
 
97
/// copyAttributesFrom - copy all additional attributes (those not needed to
 
98
/// create a GlobalValue) from the GlobalValue Src to this one.
 
99
void GlobalValue::copyAttributesFrom(const GlobalValue *Src) {
 
100
  setAlignment(Src->getAlignment());
 
101
  setSection(Src->getSection());
 
102
  setVisibility(Src->getVisibility());
 
103
}
 
104
 
 
105
 
 
106
//===----------------------------------------------------------------------===//
 
107
// GlobalVariable Implementation
 
108
//===----------------------------------------------------------------------===//
 
109
 
 
110
GlobalVariable::GlobalVariable(const Type *Ty, bool constant, LinkageTypes Link,
 
111
                               Constant *InitVal, const Twine &Name,
 
112
                               bool ThreadLocal, unsigned AddressSpace)
 
113
  : GlobalValue(PointerType::get(Ty, AddressSpace), 
 
114
                Value::GlobalVariableVal,
 
115
                OperandTraits<GlobalVariable>::op_begin(this),
 
116
                InitVal != 0, Link, Name),
 
117
    isConstantGlobal(constant), isThreadLocalSymbol(ThreadLocal) {
 
118
  if (InitVal) {
 
119
    assert(InitVal->getType() == Ty &&
 
120
           "Initializer should be the same type as the GlobalVariable!");
 
121
    Op<0>() = InitVal;
 
122
  }
 
123
 
 
124
  LeakDetector::addGarbageObject(this);
 
125
}
 
126
 
 
127
GlobalVariable::GlobalVariable(Module &M, const Type *Ty, bool constant,
 
128
                               LinkageTypes Link, Constant *InitVal,
 
129
                               const Twine &Name,
 
130
                               GlobalVariable *Before, bool ThreadLocal,
 
131
                               unsigned AddressSpace)
 
132
  : GlobalValue(PointerType::get(Ty, AddressSpace), 
 
133
                Value::GlobalVariableVal,
 
134
                OperandTraits<GlobalVariable>::op_begin(this),
 
135
                InitVal != 0, Link, Name),
 
136
    isConstantGlobal(constant), isThreadLocalSymbol(ThreadLocal) {
 
137
  if (InitVal) {
 
138
    assert(InitVal->getType() == Ty &&
 
139
           "Initializer should be the same type as the GlobalVariable!");
 
140
    Op<0>() = InitVal;
 
141
  }
 
142
  
 
143
  LeakDetector::addGarbageObject(this);
 
144
  
 
145
  if (Before)
 
146
    Before->getParent()->getGlobalList().insert(Before, this);
 
147
  else
 
148
    M.getGlobalList().push_back(this);
 
149
}
 
150
 
 
151
void GlobalVariable::setParent(Module *parent) {
 
152
  if (getParent())
 
153
    LeakDetector::addGarbageObject(this);
 
154
  Parent = parent;
 
155
  if (getParent())
 
156
    LeakDetector::removeGarbageObject(this);
 
157
}
 
158
 
 
159
void GlobalVariable::removeFromParent() {
 
160
  getParent()->getGlobalList().remove(this);
 
161
}
 
162
 
 
163
void GlobalVariable::eraseFromParent() {
 
164
  getParent()->getGlobalList().erase(this);
 
165
}
 
166
 
 
167
void GlobalVariable::replaceUsesOfWithOnConstant(Value *From, Value *To,
 
168
                                                 Use *U) {
 
169
  // If you call this, then you better know this GVar has a constant
 
170
  // initializer worth replacing. Enforce that here.
 
171
  assert(getNumOperands() == 1 &&
 
172
         "Attempt to replace uses of Constants on a GVar with no initializer");
 
173
 
 
174
  // And, since you know it has an initializer, the From value better be
 
175
  // the initializer :)
 
176
  assert(getOperand(0) == From &&
 
177
         "Attempt to replace wrong constant initializer in GVar");
 
178
 
 
179
  // And, you better have a constant for the replacement value
 
180
  assert(isa<Constant>(To) &&
 
181
         "Attempt to replace GVar initializer with non-constant");
 
182
 
 
183
  // Okay, preconditions out of the way, replace the constant initializer.
 
184
  this->setOperand(0, cast<Constant>(To));
 
185
}
 
186
 
 
187
void GlobalVariable::setInitializer(Constant *InitVal) {
 
188
  if (InitVal == 0) {
 
189
    if (hasInitializer()) {
 
190
      Op<0>().set(0);
 
191
      NumOperands = 0;
 
192
    }
 
193
  } else {
 
194
    assert(InitVal->getType() == getType()->getElementType() &&
 
195
           "Initializer type must match GlobalVariable type");
 
196
    if (!hasInitializer())
 
197
      NumOperands = 1;
 
198
    Op<0>().set(InitVal);
 
199
  }
 
200
}
 
201
 
 
202
/// copyAttributesFrom - copy all additional attributes (those not needed to
 
203
/// create a GlobalVariable) from the GlobalVariable Src to this one.
 
204
void GlobalVariable::copyAttributesFrom(const GlobalValue *Src) {
 
205
  assert(isa<GlobalVariable>(Src) && "Expected a GlobalVariable!");
 
206
  GlobalValue::copyAttributesFrom(Src);
 
207
  const GlobalVariable *SrcVar = cast<GlobalVariable>(Src);
 
208
  setThreadLocal(SrcVar->isThreadLocal());
 
209
}
 
210
 
 
211
 
 
212
//===----------------------------------------------------------------------===//
 
213
// GlobalAlias Implementation
 
214
//===----------------------------------------------------------------------===//
 
215
 
 
216
GlobalAlias::GlobalAlias(const Type *Ty, LinkageTypes Link,
 
217
                         const Twine &Name, Constant* aliasee,
 
218
                         Module *ParentModule)
 
219
  : GlobalValue(Ty, Value::GlobalAliasVal, &Op<0>(), 1, Link, Name) {
 
220
  LeakDetector::addGarbageObject(this);
 
221
 
 
222
  if (aliasee)
 
223
    assert(aliasee->getType() == Ty && "Alias and aliasee types should match!");
 
224
  Op<0>() = aliasee;
 
225
 
 
226
  if (ParentModule)
 
227
    ParentModule->getAliasList().push_back(this);
 
228
}
 
229
 
 
230
void GlobalAlias::setParent(Module *parent) {
 
231
  if (getParent())
 
232
    LeakDetector::addGarbageObject(this);
 
233
  Parent = parent;
 
234
  if (getParent())
 
235
    LeakDetector::removeGarbageObject(this);
 
236
}
 
237
 
 
238
void GlobalAlias::removeFromParent() {
 
239
  getParent()->getAliasList().remove(this);
 
240
}
 
241
 
 
242
void GlobalAlias::eraseFromParent() {
 
243
  getParent()->getAliasList().erase(this);
 
244
}
 
245
 
 
246
bool GlobalAlias::isDeclaration() const {
 
247
  const GlobalValue* AV = getAliasedGlobal();
 
248
  if (AV)
 
249
    return AV->isDeclaration();
 
250
  else
 
251
    return false;
 
252
}
 
253
 
 
254
void GlobalAlias::setAliasee(Constant *Aliasee) 
 
255
{
 
256
  if (Aliasee)
 
257
    assert(Aliasee->getType() == getType() &&
 
258
           "Alias and aliasee types should match!");
 
259
  
 
260
  setOperand(0, Aliasee);
 
261
}
 
262
 
 
263
const GlobalValue *GlobalAlias::getAliasedGlobal() const {
 
264
  const Constant *C = getAliasee();
 
265
  if (C) {
 
266
    if (const GlobalValue *GV = dyn_cast<GlobalValue>(C))
 
267
      return GV;
 
268
    else {
 
269
      const ConstantExpr *CE = 0;
 
270
      if ((CE = dyn_cast<ConstantExpr>(C)) &&
 
271
          (CE->getOpcode() == Instruction::BitCast || 
 
272
           CE->getOpcode() == Instruction::GetElementPtr))
 
273
        return dyn_cast<GlobalValue>(CE->getOperand(0));
 
274
      else
 
275
        llvm_unreachable("Unsupported aliasee");
 
276
    }
 
277
  }
 
278
  return 0;
 
279
}
 
280
 
 
281
const GlobalValue *GlobalAlias::resolveAliasedGlobal(bool stopOnWeak) const {
 
282
  SmallPtrSet<const GlobalValue*, 3> Visited;
 
283
 
 
284
  // Check if we need to stop early.
 
285
  if (stopOnWeak && mayBeOverridden())
 
286
    return this;
 
287
 
 
288
  const GlobalValue *GV = getAliasedGlobal();
 
289
  Visited.insert(GV);
 
290
 
 
291
  // Iterate over aliasing chain, stopping on weak alias if necessary.
 
292
  while (const GlobalAlias *GA = dyn_cast<GlobalAlias>(GV)) {
 
293
    if (stopOnWeak && GA->mayBeOverridden())
 
294
      break;
 
295
 
 
296
    GV = GA->getAliasedGlobal();
 
297
 
 
298
    if (!Visited.insert(GV))
 
299
      return NULL;
 
300
  }
 
301
 
 
302
  return GV;
 
303
}