aboutsummaryrefslogtreecommitdiffstats
path: root/lib/VMCore/Function.cpp
blob: c15a88808d0172501a183b01e757af3eeb03fd42 (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
//===-- Function.cpp - Implement the Global object classes -------*- C++ -*--=//
//
// This file implements the Function & GlobalVariable classes for the VMCore
// library.
//
//===----------------------------------------------------------------------===//

#include "llvm/Function.h"
#include "llvm/DerivedTypes.h"
#include "llvm/SymbolTable.h"
#include "llvm/Module.h"
#include "llvm/GlobalVariable.h"
#include "llvm/BasicBlock.h"
#include "llvm/iOther.h"
#include "llvm/Argument.h"
#include "ValueHolderImpl.h"

//===----------------------------------------------------------------------===//
// Argument Implementation
//===----------------------------------------------------------------------===//

// Specialize setName to take care of symbol table majik
void Argument::setName(const std::string &name, SymbolTable *ST) {
  Function *P;
  assert((ST == 0 || (!getParent() || ST == getParent()->getSymbolTable())) &&
	 "Invalid symtab argument!");
  if ((P = getParent()) && hasName()) P->getSymbolTable()->remove(this);
  Value::setName(name);
  if (P && hasName()) P->getSymbolTable()->insert(this);
}



//===----------------------------------------------------------------------===//
// Function Implementation
//===----------------------------------------------------------------------===//


// Instantiate Templates - This ugliness is the price we have to pay
// for having a ValueHolderImpl.h file seperate from ValueHolder.h!  :(
//
template class ValueHolder<Argument  , Function, Function>;
template class ValueHolder<BasicBlock, Function, Function>;

Function::Function(const FunctionType *Ty, bool isInternal,
                   const std::string &name)
  : GlobalValue(PointerType::get(Ty), Value::FunctionVal, isInternal, name),
    BasicBlocks(this), ArgumentList(this, this) {
  ParentSymTab = SymTab = 0;
}

Function::~Function() {
  dropAllReferences();    // After this it is safe to delete instructions.

  // TODO: Should remove from the end, not the beginning of vector!
  iterator BI = begin();
  while ((BI = begin()) != end())
    delete BasicBlocks.remove(BI);

  // Delete all of the method arguments and unlink from symbol table...
  ArgumentList.delete_all();
  ArgumentList.setParent(0);
  delete SymTab;
}

// Specialize setName to take care of symbol table majik
void Function::setName(const std::string &name, SymbolTable *ST) {
  Module *P;
  assert((ST == 0 || (!getParent() || ST == getParent()->getSymbolTable())) &&
	 "Invalid symtab argument!");
  if ((P = getParent()) && hasName()) P->getSymbolTable()->remove(this);
  Value::setName(name);
  if (P && getName() != "") P->getSymbolTableSure()->insert(this);
}

void Function::setParent(Module *parent) {
  Parent = parent;

  // Relink symbol tables together...
  ParentSymTab = Parent ? Parent->getSymbolTableSure() : 0;
  if (SymTab) SymTab->setParentSymTab(ParentSymTab);
}

const FunctionType *Function::getFunctionType() const {
  return cast<FunctionType>(getType()->getElementType());
}

const Type *Function::getReturnType() const { 
  return getFunctionType()->getReturnType();
}

SymbolTable *Function::getSymbolTableSure() {
  if (!SymTab) SymTab = new SymbolTable(ParentSymTab);
  return SymTab;
}

// hasSymbolTable() - Returns true if there is a symbol table allocated to
// this object AND if there is at least one name in it!
//
bool Function::hasSymbolTable() const {
  if (!SymTab) return false;

  for (SymbolTable::const_iterator I = SymTab->begin(); 
       I != SymTab->end(); ++I) {
    if (I->second.begin() != I->second.end())
      return true;                                // Found nonempty type plane!
  }
  
  return false;
}


// dropAllReferences() - This function causes all the subinstructions to "let
// go" of all references that they are maintaining.  This allows one to
// 'delete' a whole class at a time, even though there may be circular
// references... first all references are dropped, and all use counts go to
// zero.  Then everything is delete'd for real.  Note that no operations are
// valid on an object that has "dropped all references", except operator 
// delete.
//
void Function::dropAllReferences() {
  for_each(begin(), end(), std::mem_fun(&BasicBlock::dropAllReferences));
}

//===----------------------------------------------------------------------===//
// GlobalVariable Implementation
//===----------------------------------------------------------------------===//

GlobalVariable::GlobalVariable(const Type *Ty, bool constant, bool isIntern,
			       Constant *Initializer = 0,
			       const std::string &Name = "")
  : GlobalValue(PointerType::get(Ty), Value::GlobalVariableVal, isIntern, Name),
    isConstantGlobal(constant) {
  if (Initializer) Operands.push_back(Use((Value*)Initializer, this));
}

// Specialize setName to take care of symbol table majik
void GlobalVariable::setName(const std::string &name, SymbolTable *ST) {
  Module *P;
  assert((ST == 0 || (!getParent() || ST == getParent()->getSymbolTable())) &&
	 "Invalid symtab argument!");
  if ((P = getParent()) && hasName()) P->getSymbolTable()->remove(this);
  Value::setName(name);
  if (P && getName() != "") P->getSymbolTableSure()->insert(this);
}