forked from OSchip/llvm-project
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:
parent
63220af1ca
commit
b543cae7d6
|
@ -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.
|
||||
///
|
||||
|
|
|
@ -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 << " "
|
||||
|
|
Loading…
Reference in New Issue