delete a bunch of duplicated type printing logic, using the type printing

stuff in AsmWriter.cpp for Type::getDescription().

llvm-svn: 65734
This commit is contained in:
Chris Lattner 2009-02-28 23:01:57 +00:00
parent 63220af1ca
commit b543cae7d6
2 changed files with 18 additions and 154 deletions

View File

@ -177,8 +177,8 @@ public:
///
inline TypeID getTypeID() const { return ID; }
/// getDescription - Return the string representation of the type...
const std::string &getDescription() const;
/// getDescription - Return the string representation of the type.
std::string getDescription() const;
/// isInteger - True if this is an instance of IntegerType.
///

View File

@ -13,14 +13,16 @@
#include "llvm/DerivedTypes.h"
#include "llvm/Constants.h"
#include "llvm/Assembly/Writer.h"
#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/SCCIterator.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cstdarg>
using namespace llvm;
@ -42,10 +44,8 @@ AbstractTypeUser::~AbstractTypeUser() {}
// for types as they are needed. Because resolution of types must invalidate
// all of the abstract type descriptions, we keep them in a seperate map to make
// this easy.
static ManagedStatic<std::map<const Type*,
std::string> > ConcreteTypeDescriptions;
static ManagedStatic<std::map<const Type*,
std::string> > AbstractTypeDescriptions;
static ManagedStatic<TypePrinting> ConcreteTypeDescriptions;
static ManagedStatic<TypePrinting> AbstractTypeDescriptions;
/// Because of the way Type subclasses are allocated, this function is necessary
/// to use the correct kind of "delete" operator to deallocate the Type object.
@ -229,151 +229,14 @@ void Type::typeBecameConcrete(const DerivedType *AbsTy) {
}
// getTypeDescription - This is a recursive function that walks a type hierarchy
// calculating the description for a type.
//
static std::string getTypeDescription(const Type *Ty,
std::vector<const Type *> &TypeStack) {
if (isa<OpaqueType>(Ty)) { // Base case for the recursion
std::map<const Type*, std::string>::iterator I =
AbstractTypeDescriptions->find(Ty);
if (I != AbstractTypeDescriptions->end())
return I->second;
std::string Desc = "opaque";
AbstractTypeDescriptions->insert(std::make_pair(Ty, Desc));
return Desc;
}
if (!Ty->isAbstract()) { // Base case for the recursion
std::map<const Type*, std::string>::iterator I =
ConcreteTypeDescriptions->find(Ty);
if (I != ConcreteTypeDescriptions->end())
return I->second;
if (Ty->isPrimitiveType()) {
switch (Ty->getTypeID()) {
default: assert(0 && "Unknown prim type!");
case Type::VoidTyID: return (*ConcreteTypeDescriptions)[Ty] = "void";
case Type::FloatTyID: return (*ConcreteTypeDescriptions)[Ty] = "float";
case Type::DoubleTyID: return (*ConcreteTypeDescriptions)[Ty] = "double";
case Type::X86_FP80TyID:
return (*ConcreteTypeDescriptions)[Ty] = "x86_fp80";
case Type::FP128TyID: return (*ConcreteTypeDescriptions)[Ty] = "fp128";
case Type::PPC_FP128TyID:
return (*ConcreteTypeDescriptions)[Ty] = "ppc_fp128";
case Type::LabelTyID: return (*ConcreteTypeDescriptions)[Ty] = "label";
}
}
}
// Check to see if the Type is already on the stack...
unsigned Slot = 0, CurSize = TypeStack.size();
while (Slot < CurSize && TypeStack[Slot] != Ty) ++Slot; // Scan for type
// This is another base case for the recursion. In this case, we know
// that we have looped back to a type that we have previously visited.
// Generate the appropriate upreference to handle this.
//
if (Slot < CurSize)
return "\\" + utostr(CurSize-Slot); // Here's the upreference
// Recursive case: derived types...
std::string Result;
TypeStack.push_back(Ty); // Add us to the stack..
switch (Ty->getTypeID()) {
case Type::IntegerTyID: {
const IntegerType *ITy = cast<IntegerType>(Ty);
Result = "i" + utostr(ITy->getBitWidth());
break;
}
case Type::FunctionTyID: {
const FunctionType *FTy = cast<FunctionType>(Ty);
if (!Result.empty())
Result += " ";
Result += getTypeDescription(FTy->getReturnType(), TypeStack) + " (";
for (FunctionType::param_iterator I = FTy->param_begin(),
E = FTy->param_end(); I != E; ++I) {
if (I != FTy->param_begin())
Result += ", ";
Result += getTypeDescription(*I, TypeStack);
}
if (FTy->isVarArg()) {
if (FTy->getNumParams()) Result += ", ";
Result += "...";
}
Result += ")";
break;
}
case Type::StructTyID: {
const StructType *STy = cast<StructType>(Ty);
if (STy->isPacked())
Result = "<{ ";
else
Result = "{ ";
for (StructType::element_iterator I = STy->element_begin(),
E = STy->element_end(); I != E; ++I) {
if (I != STy->element_begin())
Result += ", ";
Result += getTypeDescription(*I, TypeStack);
}
Result += " }";
if (STy->isPacked())
Result += ">";
break;
}
case Type::PointerTyID: {
const PointerType *PTy = cast<PointerType>(Ty);
Result = getTypeDescription(PTy->getElementType(), TypeStack);
if (unsigned AddressSpace = PTy->getAddressSpace())
Result += " addrspace(" + utostr(AddressSpace) + ")";
Result += " *";
break;
}
case Type::ArrayTyID: {
const ArrayType *ATy = cast<ArrayType>(Ty);
unsigned NumElements = ATy->getNumElements();
Result = "[";
Result += utostr(NumElements) + " x ";
Result += getTypeDescription(ATy->getElementType(), TypeStack) + "]";
break;
}
case Type::VectorTyID: {
const VectorType *PTy = cast<VectorType>(Ty);
unsigned NumElements = PTy->getNumElements();
Result = "<";
Result += utostr(NumElements) + " x ";
Result += getTypeDescription(PTy->getElementType(), TypeStack) + ">";
break;
}
default:
Result = "<error>";
assert(0 && "Unhandled type in getTypeDescription!");
}
TypeStack.pop_back(); // Remove self from stack...
return Result;
}
static const std::string &getOrCreateDesc(std::map<const Type*,std::string>&Map,
const Type *Ty) {
std::map<const Type*, std::string>::iterator I = Map.find(Ty);
if (I != Map.end()) return I->second;
std::vector<const Type *> TypeStack;
std::string Result = getTypeDescription(Ty, TypeStack);
return Map[Ty] = Result;
}
const std::string &Type::getDescription() const {
if (isAbstract())
return getOrCreateDesc(*AbstractTypeDescriptions, this);
else
return getOrCreateDesc(*ConcreteTypeDescriptions, this);
std::string Type::getDescription() const {
TypePrinting &Map =
isAbstract() ? *AbstractTypeDescriptions : *ConcreteTypeDescriptions;
std::string DescStr;
raw_string_ostream DescOS(DescStr);
Map.print(this, DescOS);
return DescOS.str();
}
@ -1372,7 +1235,8 @@ void DerivedType::refineAbstractTypeTo(const Type *NewType) {
assert(ForwardType == 0 && "This type has already been refined!");
// The descriptions may be out of date. Conservatively clear them all!
AbstractTypeDescriptions->clear();
if (AbstractTypeDescriptions.isConstructed())
AbstractTypeDescriptions->clear();
#ifdef DEBUG_MERGE_TYPES
DOUT << "REFINING abstract type [" << (void*)this << " "