aboutsummaryrefslogtreecommitdiff
path: root/lib/VMCore
diff options
context:
space:
mode:
Diffstat (limited to 'lib/VMCore')
-rw-r--r--lib/VMCore/AsmWriter.cpp74
-rw-r--r--lib/VMCore/Globals.cpp45
-rw-r--r--lib/VMCore/Module.cpp23
-rw-r--r--lib/VMCore/Verifier.cpp19
4 files changed, 150 insertions, 11 deletions
diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp
index 90f0198b57..ec9a5539b9 100644
--- a/lib/VMCore/AsmWriter.cpp
+++ b/lib/VMCore/AsmWriter.cpp
@@ -166,6 +166,8 @@ static SlotMachine *createSlotMachine(const Value *V) {
return new SlotMachine(BB->getParent());
} else if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(V)){
return new SlotMachine(GV->getParent());
+ } else if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(V)){
+ return new SlotMachine(GA->getParent());
} else if (const Function *Func = dyn_cast<Function>(V)) {
return new SlotMachine(Func);
}
@@ -683,12 +685,13 @@ public:
fillTypeNameTable(M, TypeNames);
}
- inline void write(const Module *M) { printModule(M); }
- inline void write(const GlobalVariable *G) { printGlobal(G); }
- inline void write(const Function *F) { printFunction(F); }
- inline void write(const BasicBlock *BB) { printBasicBlock(BB); }
+ inline void write(const Module *M) { printModule(M); }
+ inline void write(const GlobalVariable *G) { printGlobal(G); }
+ inline void write(const GlobalAlias *G) { printAlias(G); }
+ inline void write(const Function *F) { printFunction(F); }
+ inline void write(const BasicBlock *BB) { printBasicBlock(BB); }
inline void write(const Instruction *I) { printInstruction(*I); }
- inline void write(const Type *Ty) { printType(Ty); }
+ inline void write(const Type *Ty) { printType(Ty); }
void writeOperand(const Value *Op, bool PrintType);
@@ -698,6 +701,7 @@ private:
void printModule(const Module *M);
void printTypeSymbolTable(const TypeSymbolTable &ST);
void printGlobal(const GlobalVariable *GV);
+ void printAlias(const GlobalAlias *GV);
void printFunction(const Function *F);
void printArgument(const Argument *FA, uint16_t ParamAttrs);
void printBasicBlock(const BasicBlock *BB);
@@ -848,6 +852,11 @@ void AssemblyWriter::printModule(const Module *M) {
// Output all of the functions.
for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I)
printFunction(I);
+
+ // Output all aliases
+ for (Module::const_alias_iterator I = M->alias_begin(), E = M->alias_end();
+ I != E; ++I)
+ printAlias(I);
}
void AssemblyWriter::printGlobal(const GlobalVariable *GV) {
@@ -888,16 +897,55 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) {
assert(C && "GlobalVar initializer isn't constant?");
writeOperand(GV->getInitializer(), false);
}
-
+
if (GV->hasSection())
Out << ", section \"" << GV->getSection() << '"';
if (GV->getAlignment())
Out << ", align " << GV->getAlignment();
-
+
printInfoComment(*GV);
Out << "\n";
}
+void AssemblyWriter::printAlias(const GlobalAlias *GA) {
+ Out << getLLVMName(GA->getName(), GlobalPrefix) << " = ";
+ switch (GA->getVisibility()) {
+ default: assert(0 && "Invalid visibility style!");
+ case GlobalValue::DefaultVisibility: break;
+ case GlobalValue::HiddenVisibility: Out << "hidden "; break;
+ }
+
+ Out << "alias ";
+
+ switch (GA->getLinkage()) {
+ case GlobalValue::WeakLinkage: Out << "weak "; break;
+ case GlobalValue::InternalLinkage: Out << "internal "; break;
+ case GlobalValue::ExternalLinkage: break;
+ default:
+ assert(0 && "Invalid alias linkage");
+ }
+
+ const GlobalValue *Aliasee = GA->getAliasee();
+ assert(Aliasee && "Aliasee cannot be null");
+
+ if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(Aliasee)) {
+ printType(GV->getType());
+ Out << " " << getLLVMName(GV->getName(), GlobalPrefix);
+ } else if (const Function *F = dyn_cast<Function>(Aliasee)) {
+ printType(F->getFunctionType());
+ Out << "* ";
+
+ if (!F->getName().empty())
+ Out << getLLVMName(F->getName(), GlobalPrefix);
+ else
+ Out << "@\"\"";
+ } else
+ assert(0 && "Unsupported aliasee");
+
+ printInfoComment(*GA);
+ Out << "\n";
+}
+
void AssemblyWriter::printTypeSymbolTable(const TypeSymbolTable &ST) {
// Print the types.
for (TypeSymbolTable::const_iterator TI = ST.begin(), TE = ST.end();
@@ -1336,6 +1384,12 @@ void GlobalVariable::print(std::ostream &o) const {
W.write(this);
}
+void GlobalAlias::print(std::ostream &o) const {
+ SlotMachine SlotTable(getParent());
+ AssemblyWriter W(o, SlotTable, getParent(), 0);
+ W.write(this);
+}
+
void Function::print(std::ostream &o, AssemblyAnnotationWriter *AAW) const {
SlotMachine SlotTable(getParent());
AssemblyWriter W(o, SlotTable, getParent(), AAW);
@@ -1538,8 +1592,10 @@ void SlotMachine::CreateModuleSlot(const GlobalValue *V) {
SC_DEBUG(" Inserting value [" << V->getType() << "] = " << V << " slot=" <<
DestSlot << " [");
- // G = Global, F = Function, o = other
- SC_DEBUG((isa<GlobalVariable>(V) ? 'G' : 'F') << "]\n");
+ // G = Global, F = Function, A = Alias, o = other
+ SC_DEBUG((isa<GlobalVariable>(V) ? 'G' :
+ (isa<Function> ? 'F' :
+ (isa<GlobalAlias> ? 'A' : 'o'))) << "]\n");
}
diff --git a/lib/VMCore/Globals.cpp b/lib/VMCore/Globals.cpp
index 61d9de3a23..c64b719095 100644
--- a/lib/VMCore/Globals.cpp
+++ b/lib/VMCore/Globals.cpp
@@ -13,6 +13,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/GlobalVariable.h"
+#include "llvm/GlobalAlias.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Module.h"
#include "llvm/Support/LeakDetector.h"
@@ -76,6 +77,7 @@ void GlobalValue::destroyConstant() {
assert(0 && "You can't GV->destroyConstant()!");
abort();
}
+
//===----------------------------------------------------------------------===//
// GlobalVariable Implementation
//===----------------------------------------------------------------------===//
@@ -120,7 +122,6 @@ GlobalVariable::GlobalVariable(const Type *Ty, bool constant, LinkageTypes Link,
Before->getParent()->getGlobalList().insert(Before, this);
}
-
void GlobalVariable::setParent(Module *parent) {
if (getParent())
LeakDetector::addGarbageObject(this);
@@ -156,3 +157,45 @@ void GlobalVariable::replaceUsesOfWithOnConstant(Value *From, Value *To,
// Okay, preconditions out of the way, replace the constant initializer.
this->setOperand(0, cast<Constant>(To));
}
+
+//===----------------------------------------------------------------------===//
+// GlobalAlias Implementation
+//===----------------------------------------------------------------------===//
+
+GlobalAlias::GlobalAlias(const Type *Ty, LinkageTypes Link,
+ const std::string &Name, const GlobalValue* aliasee,
+ Module *ParentModule)
+ : GlobalValue(Ty, Value::GlobalAliasVal, 0, 0,
+ Link, Name), Aliasee(aliasee) {
+ LeakDetector::addGarbageObject(this);
+
+ if (ParentModule)
+ ParentModule->getAliasList().push_back(this);
+}
+
+void GlobalAlias::setParent(Module *parent) {
+ if (getParent())
+ LeakDetector::addGarbageObject(this);
+ Parent = parent;
+ if (getParent())
+ LeakDetector::removeGarbageObject(this);
+}
+
+void GlobalAlias::removeFromParent() {
+ getParent()->getAliasList().remove(this);
+}
+
+void GlobalAlias::eraseFromParent() {
+ getParent()->getAliasList().erase(this);
+}
+
+bool GlobalAlias::isDeclaration() const {
+ return (Aliasee && Aliasee->isDeclaration());
+}
+
+void GlobalAlias::setAliasee(const GlobalValue *GV)
+{
+ // FIXME: Some checks?
+ Aliasee = GV;
+}
+
diff --git a/lib/VMCore/Module.cpp b/lib/VMCore/Module.cpp
index ddd503dea1..c66032388b 100644
--- a/lib/VMCore/Module.cpp
+++ b/lib/VMCore/Module.cpp
@@ -45,6 +45,12 @@ GlobalVariable *ilist_traits<GlobalVariable>::createSentinel() {
LeakDetector::removeGarbageObject(Ret);
return Ret;
}
+GlobalAlias *ilist_traits<GlobalAlias>::createSentinel() {
+ GlobalAlias *Ret = new GlobalAlias(Type::Int32Ty, GlobalValue::ExternalLinkage);
+ // This should not be garbage monitored.
+ LeakDetector::removeGarbageObject(Ret);
+ return Ret;
+}
iplist<Function> &ilist_traits<Function>::getList(Module *M) {
return M->getFunctionList();
@@ -52,11 +58,15 @@ iplist<Function> &ilist_traits<Function>::getList(Module *M) {
iplist<GlobalVariable> &ilist_traits<GlobalVariable>::getList(Module *M) {
return M->getGlobalList();
}
+iplist<GlobalAlias> &ilist_traits<GlobalAlias>::getList(Module *M) {
+ return M->getAliasList();
+}
// Explicit instantiations of SymbolTableListTraits since some of the methods
// are not in the public header file.
template class SymbolTableListTraits<GlobalVariable, Module>;
template class SymbolTableListTraits<Function, Module>;
+template class SymbolTableListTraits<GlobalAlias, Module>;
//===----------------------------------------------------------------------===//
// Primitive Module methods.
@@ -72,6 +82,7 @@ Module::~Module() {
dropAllReferences();
GlobalList.clear();
FunctionList.clear();
+ AliasList.clear();
LibraryList.clear();
delete ValSymTab;
delete TypeSymTab;
@@ -212,6 +223,18 @@ GlobalVariable *Module::getGlobalVariable(const std::string &Name,
}
//===----------------------------------------------------------------------===//
+// Methods for easy access to the global variables in the module.
+//
+
+// getNamedAlias - Look up the specified global in the module symbol table.
+// If it does not exist, return null.
+//
+GlobalAlias *Module::getNamedAlias(const std::string &Name) const {
+ const ValueSymbolTable &SymTab = getValueSymbolTable();
+ return dyn_cast_or_null<GlobalAlias>(SymTab.lookup(Name));
+}
+
+//===----------------------------------------------------------------------===//
// Methods for easy access to the types in the module.
//
diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp
index 19367662d2..1578c2ddd6 100644
--- a/lib/VMCore/Verifier.cpp
+++ b/lib/VMCore/Verifier.cpp
@@ -141,6 +141,10 @@ namespace { // Anonymous namespace for class
I != E; ++I)
visitGlobalVariable(*I);
+ for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end();
+ I != E; ++I)
+ visitGlobalAlias(*I);
+
// If the module is broken, abort at this time.
return abortIfBroken();
}
@@ -179,6 +183,7 @@ namespace { // Anonymous namespace for class
void verifyTypeSymbolTable(TypeSymbolTable &ST);
void visitGlobalValue(GlobalValue &GV);
void visitGlobalVariable(GlobalVariable &GV);
+ void visitGlobalAlias(GlobalAlias &GA);
void visitFunction(Function &F);
void visitBasicBlock(BasicBlock &BB);
void visitTruncInst(TruncInst &I);
@@ -277,7 +282,9 @@ void Verifier::visitGlobalValue(GlobalValue &GV) {
Assert1(!GV.isDeclaration() ||
GV.hasExternalLinkage() ||
GV.hasDLLImportLinkage() ||
- GV.hasExternalWeakLinkage(),
+ GV.hasExternalWeakLinkage() ||
+ (isa<GlobalAlias>(GV) &&
+ (GV.hasInternalLinkage() || GV.hasWeakLinkage())),
"Global is external, but doesn't have external or dllimport or weak linkage!",
&GV);
@@ -303,6 +310,16 @@ void Verifier::visitGlobalVariable(GlobalVariable &GV) {
visitGlobalValue(GV);
}
+void Verifier::visitGlobalAlias(GlobalAlias &GA) {
+ Assert1(!GA.getName().empty(),
+ "Alias name cannot be empty!", &GA);
+ Assert1(GA.hasExternalLinkage() || GA.hasInternalLinkage() ||
+ GA.hasWeakLinkage(),
+ "Alias should have external or external weak linkage!", &GA);
+
+ visitGlobalValue(GA);
+}
+
void Verifier::verifyTypeSymbolTable(TypeSymbolTable &ST) {
}