From: Douglas Gregor Date: Mon, 21 Dec 2009 20:18:30 +0000 (+0000) Subject: Improve on my previous fix for debug information. Rather than X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=840943d633fa6e1ea25419022f936cc20abb2148;p=clang Improve on my previous fix for debug information. Rather than recursing in CGDebugInfo::CreateTypeNode, teach CanonicalizeTypeForDebugInfo---now called UnwrapTypeForDebugInfo---to keep unwrapping the type until we hit something that can be represented by debug information. Thanks to Anders for pointing this out! git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@91840 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp index c54791b5c3..b7401a40f2 100644 --- a/lib/CodeGen/CGDebugInfo.cpp +++ b/lib/CodeGen/CGDebugInfo.cpp @@ -830,27 +830,43 @@ llvm::DIType CGDebugInfo::CreateType(const MemberPointerType *Ty, 0, 0, 0, llvm::DIType(), Elements); } -static QualType CanonicalizeTypeForDebugInfo(QualType T) { - switch (T->getTypeClass()) { - default: - return T; - case Type::TemplateSpecialization: - return cast(T)->desugar(); - case Type::TypeOfExpr: { - TypeOfExprType *Ty = cast(T); - return CanonicalizeTypeForDebugInfo(Ty->getUnderlyingExpr()->getType()); - } - case Type::TypeOf: - return cast(T)->getUnderlyingType(); - case Type::Decltype: - return cast(T)->getUnderlyingType(); - case Type::QualifiedName: - return cast(T)->getNamedType(); - case Type::SubstTemplateTypeParm: - return cast(T)->getReplacementType(); - case Type::Elaborated: - return cast(T)->getUnderlyingType(); - } +static QualType UnwrapTypeForDebugInfo(QualType T) { + do { + QualType LastT = T; + switch (T->getTypeClass()) { + default: + return T; + case Type::TemplateSpecialization: + T = cast(T)->desugar(); + break; + case Type::TypeOfExpr: { + TypeOfExprType *Ty = cast(T); + T = Ty->getUnderlyingExpr()->getType(); + break; + } + case Type::TypeOf: + T = cast(T)->getUnderlyingType(); + break; + case Type::Decltype: + T = cast(T)->getUnderlyingType(); + break; + case Type::QualifiedName: + T = cast(T)->getNamedType(); + break; + case Type::SubstTemplateTypeParm: + T = cast(T)->getReplacementType(); + break; + case Type::Elaborated: + T = cast(T)->getUnderlyingType(); + break; + } + + assert(T != LastT && "Type unwrapping failed to unwrap!"); + if (T == LastT) + return T; + } while (true); + + return T; } /// getOrCreateType - Get the type from the cache or create a new @@ -860,8 +876,8 @@ llvm::DIType CGDebugInfo::getOrCreateType(QualType Ty, if (Ty.isNull()) return llvm::DIType(); - // Canonicalize the type. - Ty = CanonicalizeTypeForDebugInfo(Ty); + // Unwrap the type as needed for debug information. + Ty = UnwrapTypeForDebugInfo(Ty); // Check for existing entry. std::map::iterator it = @@ -932,44 +948,19 @@ llvm::DIType CGDebugInfo::CreateTypeNode(QualType Ty, return CreateType(cast(Ty), Unit); case Type::TemplateSpecialization: - // DWARF can't represent template specialization types; instead, - // we drill down to the canonical type, which will be a record type. - return CreateType(cast(CGM.getContext().getCanonicalType(Ty)), - Unit); - case Type::Elaborated: - // DWARF can't represent elaborated type specifiers any differently from - // the underlying type, so create a type node for the underlying type. - return CreateTypeNode(cast(Ty)->getUnderlyingType(), Unit); - case Type::QualifiedName: - // DWARF can't represent qualified names any differently from the type - // being named, so create a type node for that type. - return CreateTypeNode(cast(Ty)->getNamedType(), Unit); - case Type::SubstTemplateTypeParm: - // DWARF can't represent substituted template type parameter types, - // so create a type node for the type that the template type parameter was - // replaced with. - return CreateTypeNode(cast(Ty) - ->getReplacementType(), - Unit); - case Type::TypeOfExpr: case Type::TypeOf: - // FIXME: Implement! - Diag = "typeof"; - break; + case Type::Decltype: + llvm_unreachable("type should have been unwrapped!"); + return llvm::DIType(); case Type::RValueReference: // FIXME: Implement! Diag = "rvalue references"; break; - - case Type::Decltype: - // FIXME: Implement! - Diag = "decltype"; - break; } assert(Diag && "Fall through without a diagnostic?");