-//===----------------------------------------------------------------------===//
-// Derived Type setDerivedTypeProperties Function
-//===----------------------------------------------------------------------===//
-
-// getTypeProps - This is a recursive function that walks a type hierarchy
-// calculating the description for a type and whether or not it is abstract or
-// recursive. Worst case it will have to do a lot of traversing if you have
-// some whacko opaque types, but in most cases, it will do some simple stuff
-// when it hits non-abstract types that aren't recursive.
-//
-static std::string getTypeProps(const Type *Ty,
- std::vector<const Type *> &TypeStack,
- bool &isAbstract, bool &isRecursive) {
- if (!Ty->isAbstract() && !Ty->isRecursive() && // Base case for the recursion
- Ty->getDescription().size()) {
- return Ty->getDescription(); // Primitive = leaf type
- } else if (isa<OpaqueType>(Ty)) { // Base case for the recursion
- isAbstract = true; // This whole type is abstract!
- return Ty->getDescription(); // Opaque = leaf type
- } else {
- // 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) {
- isRecursive = true; // We know we are recursive
- return "\\" + utostr(CurSize-Slot); // Here's the upreference
- } else { // Recursive case: abstract derived type...
- std::string Result;
- TypeStack.push_back(Ty); // Add us to the stack..
-
- switch (Ty->getPrimitiveID()) {
- case Type::FunctionTyID: {
- const FunctionType *MTy = cast<const FunctionType>(Ty);
- Result = getTypeProps(MTy->getReturnType(), TypeStack,
- isAbstract, isRecursive)+" (";
- for (FunctionType::ParamTypes::const_iterator
- I = MTy->getParamTypes().begin(),
- E = MTy->getParamTypes().end(); I != E; ++I) {
- if (I != MTy->getParamTypes().begin())
- Result += ", ";
- Result += getTypeProps(*I, TypeStack, isAbstract, isRecursive);
- }
- if (MTy->isVarArg()) {
- if (!MTy->getParamTypes().empty()) Result += ", ";
- Result += "...";
- }
- Result += ")";
- break;
- }
- case Type::StructTyID: {
- const StructType *STy = cast<const StructType>(Ty);
- Result = "{ ";
- for (StructType::ElementTypes::const_iterator
- I = STy->getElementTypes().begin(),
- E = STy->getElementTypes().end(); I != E; ++I) {
- if (I != STy->getElementTypes().begin())
- Result += ", ";
- Result += getTypeProps(*I, TypeStack, isAbstract, isRecursive);
- }
- Result += " }";
- break;
- }
- case Type::PointerTyID: {
- const PointerType *PTy = cast<const PointerType>(Ty);
- Result = getTypeProps(PTy->getElementType(), TypeStack,
- isAbstract, isRecursive) + " *";
- break;
- }
- case Type::ArrayTyID: {
- const ArrayType *ATy = cast<const ArrayType>(Ty);
- unsigned NumElements = ATy->getNumElements();
- Result = "[";
- Result += utostr(NumElements) + " x ";
- Result += getTypeProps(ATy->getElementType(), TypeStack,
- isAbstract, isRecursive) + "]";
- break;
- }
- default:
- assert(0 && "Unhandled case in getTypeProps!");
- Result = "<error>";
- }