//===----------------------------------------------------------------------===//
#include "llvm/Transforms/Utils/Linker.h"
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
#include "llvm/Module.h"
#include "llvm/SymbolTable.h"
-#include "llvm/DerivedTypes.h"
#include "llvm/iOther.h"
-#include "llvm/Constants.h"
+#include "llvm/Assembly/Writer.h"
+using namespace llvm;
// Error - Simple wrapper function to conditionally assign to E and return true.
// This just makes error return conditions a little bit simpler...
return true;
}
-// ResolveTypes - Attempt to link the two specified types together. Return true
-// if there is an error and they cannot yet be linked.
+//
+// Function: ResolveTypes()
+//
+// Description:
+// Attempt to link the two specified types together.
+//
+// Inputs:
+// DestTy - The type to which we wish to resolve.
+// SrcTy - The original type which we want to resolve.
+// Name - The name of the type.
+//
+// Outputs:
+// DestST - The symbol table in which the new type should be placed.
+//
+// Return value:
+// true - There is an error and the types cannot yet be linked.
+// false - No errors.
//
static bool ResolveTypes(const Type *DestTy, const Type *SrcTy,
SymbolTable *DestST, const std::string &Name) {
const Type *T1 = cast<Type>(VM.find(Name)->second);
const Type *T2 = cast<Type>(DestST->lookup(Type::TypeTy, Name));
std::cerr << "WARNING: Type conflict between types named '" << Name
- << "'.\n Src='" << *T1 << "'.\n Dest='" << *T2 << "'\n";
+ << "'.\n Src='";
+ WriteTypeSymbolic(std::cerr, T1, Src);
+ std::cerr << "'.\n Dest='";
+ WriteTypeSymbolic(std::cerr, T2, Dest);
+ std::cerr << "'\n";
// Remove the symbol name from the destination.
DelayedTypesToResolve.pop_back();
Value *V2 = RemapOperand(CE->getOperand(1), LocalMap, GlobalMap);
Result = ConstantExpr::get(CE->getOpcode(), cast<Constant>(V1),
- cast<Constant>(V2));
+ cast<Constant>(V2));
} else {
assert(0 && "Unknown constant expr type!");
}
for (SymbolTable::iterator I = ST->begin(), E = ST->end(); I != E; ++I)
if (I->first != Type::TypeTy) {
SymbolTable::VarMap &VM = I->second;
+
// Does this type plane contain an entry with the specified name?
SymbolTable::type_iterator TI = VM.find(Name);
if (TI != VM.end()) {
+ //
+ // Ensure that this type if placed correctly into the symbol table.
+ //
+ assert(TI->second->getType() == I->first && "Type conflict!");
+
+ //
+ // Save a reference to the new type. Resolving the type can modify the
+ // symbol table, invalidating the TI variable.
+ //
+ Value *ValPtr = TI->second;
+
+ //
// Determine whether we can fold the two types together, resolving them.
// If so, we can use this value.
+ //
if (!RecursiveResolveTypes(Ty, I->first, ST, ""))
- return cast<GlobalValue>(TI->second);
+ return cast<GlobalValue>(ValPtr);
}
}
return 0; // Otherwise, nothing could be found.
// the problem. Upon failure, the Dest module could be in a modified state, and
// shouldn't be relied on to be consistent.
//
-bool LinkModules(Module *Dest, const Module *Src, std::string *ErrorMsg) {
+bool llvm::LinkModules(Module *Dest, const Module *Src, std::string *ErrorMsg) {
if (Dest->getEndianness() == Module::AnyEndianness)
Dest->setEndianness(Src->getEndianness());
if (Dest->getPointerSize() == Module::AnyPointerSize)