summaryrefslogtreecommitdiff
path: root/include/llvm/Value.h
blob: d751eb1c6a8e960b689b895efe3f3b7d58013cb7 (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
//===-- llvm/Value.h - Definition of the Value class -------------*- C++ -*--=//
//
// This file defines the very important Value class.  This is subclassed by a
// bunch of other important classes, like Def, Method, Module, Type, etc...
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_VALUE_H
#define LLVM_VALUE_H

#include <string>
#include <list>

class User;
class Type;
template<class ValueSubclass, class ItemParentType> class ValueHolder;

//===----------------------------------------------------------------------===//
//                                 Value Class
//===----------------------------------------------------------------------===//

class Value {
public:
  enum ValueTy {
    TypeVal,                // This is an instance of Type
    ConstantVal,            // This is an instance of ConstPoolVal
    MethodArgumentVal,      // This is an instance of MethodArgument
    InstructionVal,         // This is an instance of Instruction

    BasicBlockVal,          // This is an instance of BasicBlock
    MethodVal,              // This is an instance of Method
    ModuleVal,              // This is an instance of Module
  };

private:
  list<User *> Uses;
  string Name;
  const Type *Ty;
  ValueTy VTy;

  Value(const Value &);              // Do not implement
protected:
  inline void setType(const Type *ty) { Ty = ty; }
public:
  Value(const Type *Ty, ValueTy vty, const string &name = "");
  virtual ~Value();

  inline const Type *getType() const { return Ty; }
  inline ValueTy getValueType() const { return VTy; }

  inline bool hasName() const { return Name != ""; }
  inline const string &getName() const { return Name; }
  virtual void setName(const string &name) { Name = name; }


  // replaceAllUsesWith - Go through the uses list for this definition and make
  // each use point to "D" instead of "this".  After this completes, 'this's 
  // use list should be empty.
  //
  void replaceAllUsesWith(Value *D);

  //----------------------------------------------------------------------
  // Methods for handling the list of uses of this DEF.
  //
  typedef list<User*>::iterator       use_iterator;
  typedef list<User*>::const_iterator use_const_iterator;

  inline bool               use_size()  const { return Uses.size();  }
  inline bool               use_empty() const { return Uses.empty(); }
  inline use_iterator       use_begin()       { return Uses.begin(); }
  inline use_const_iterator use_begin() const { return Uses.begin(); }
  inline use_iterator       use_end()         { return Uses.end();   }
  inline use_const_iterator use_end()   const { return Uses.end();   }

  inline void use_push_back(User *I)   { Uses.push_back(I); }
  User *use_remove(use_iterator &I);

  inline void addUse(User *I)      { Uses.push_back(I); }
  void killUse(User *I);
};

// UseTy and it's friendly typedefs (Use) are here to make keeping the "use" 
// list of a definition node up-to-date really easy.
//
template<class ValueSubclass>
class UseTy {
  ValueSubclass *Val;
  User *U;
public:
  inline UseTy<ValueSubclass>(ValueSubclass *v, User *user) {
    Val = v; U = user;
    if (Val) Val->addUse(U);
  }

  inline ~UseTy<ValueSubclass>() { if (Val) Val->killUse(U); }

  inline operator ValueSubclass *() const { return Val; }

  inline UseTy<ValueSubclass>(const UseTy<ValueSubclass> &user) {
    Val = 0;
    U = user.U;
    operator=(user);
  }
  inline ValueSubclass *operator=(ValueSubclass *V) { 
    if (Val) Val->killUse(U);
    Val = V;
    if (V) V->addUse(U);
    return V;
  }

  inline       ValueSubclass *operator->()       { return Val; }
  inline const ValueSubclass *operator->() const { return Val; }

  inline UseTy<ValueSubclass> &operator=(const UseTy<ValueSubclass> &user) {
    if (Val) Val->killUse(U);
    Val = user.Val;
    Val->addUse(U);
    return *this;
  }
};

typedef UseTy<Value> Use;

#endif