diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-04-01 15:47:24 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-04-01 15:47:24 +0000 |
commit | 969c689d893a248eca4f049f5b89f747e66e4bff (patch) | |
tree | 326ff6ad11948fb780b0b4efaead9da1e719ab0d /lib | |
parent | cb5a955afb6dca9ad5f9fbdfa97789a93ba10660 (diff) |
Give Type::getDesugaredType a "for-display" mode that can apply more
heuristics to determine when it's useful to desugar a type for display
to the user. Introduce two C++-specific heuristics:
- For a qualified type (like "foo::bar"), only produce a new
desugred type if desugaring the qualified type ("bar", in this
case) produces something interesting. For example, if "foo::bar"
refers to a class named "bar", don't desugar. However, if
"foo::bar" refers to a typedef of something else, desugar to that
something else. This gives some useful desugaring such as
"foo::bar (aka 'int')".
- Don't desugar class template specialization types like
"basic_string<char>" down to their underlying "class
basic_string<char, char_traits<char>, allocator<char>>, etc.";
it's better just to leave such types alone.
Update diagnostics.html with some discussion and examples of type
preservation in C++, showing qualified names and class template
specialization types.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@68207 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/Type.cpp | 34 | ||||
-rw-r--r-- | lib/Sema/Sema.cpp | 2 |
2 files changed, 28 insertions, 8 deletions
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index b9bd0bae04..97245c699a 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -75,8 +75,13 @@ const Type *Type::getArrayElementTypeNoTypeQual() const { /// to getting the canonical type, but it doesn't remove *all* typedefs. For /// example, it returns "T*" as "T*", (not as "int*"), because the pointer is /// concrete. -QualType QualType::getDesugaredType() const { - return getTypePtr()->getDesugaredType() +/// +/// \param ForDisplay When true, the desugaring is provided for +/// display purposes only. In this case, we apply more heuristics to +/// decide whether it is worth providing a desugared form of the type +/// or not. +QualType QualType::getDesugaredType(bool ForDisplay) const { + return getTypePtr()->getDesugaredType(ForDisplay) .getWithAdditionalQualifiers(getCVRQualifiers()); } @@ -86,7 +91,12 @@ QualType QualType::getDesugaredType() const { /// to getting the canonical type, but it doesn't remove *all* typedefs. For /// example, it return "T*" as "T*", (not as "int*"), because the pointer is /// concrete. -QualType Type::getDesugaredType() const { +/// +/// \param ForDisplay When true, the desugaring is provided for +/// display purposes only. In this case, we apply more heuristics to +/// decide whether it is worth providing a desugared form of the type +/// or not. +QualType Type::getDesugaredType(bool ForDisplay) const { if (const TypedefType *TDT = dyn_cast<TypedefType>(this)) return TDT->LookThroughTypedefs().getDesugaredType(); if (const TypeOfExprType *TOE = dyn_cast<TypeOfExprType>(this)) @@ -95,16 +105,26 @@ QualType Type::getDesugaredType() const { return TOT->getUnderlyingType().getDesugaredType(); if (const TemplateSpecializationType *Spec = dyn_cast<TemplateSpecializationType>(this)) { + if (ForDisplay) + return QualType(this, 0); + QualType Canon = Spec->getCanonicalTypeInternal(); if (Canon->getAsTemplateSpecializationType()) return QualType(this, 0); return Canon->getDesugaredType(); } - if (const QualifiedNameType *QualName = dyn_cast<QualifiedNameType>(this)) - return QualName->getNamedType().getDesugaredType(); + if (const QualifiedNameType *QualName = dyn_cast<QualifiedNameType>(this)) { + if (ForDisplay) { + // If desugaring the type that the qualified name is referring to + // produces something interesting, that's our desugared type. + QualType NamedType = QualName->getNamedType().getDesugaredType(); + if (NamedType != QualName->getNamedType()) + return NamedType; + } else + return QualName->getNamedType().getDesugaredType(); + } - // FIXME: remove this cast. - return QualType(const_cast<Type*>(this), 0); + return QualType(this, 0); } /// isVoidType - Helper method to determine if this is the 'void' type. diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp index 7e72a8453b..f11ce2043a 100644 --- a/lib/Sema/Sema.cpp +++ b/lib/Sema/Sema.cpp @@ -40,7 +40,7 @@ static void ConvertArgToStringFn(Diagnostic::ArgumentKind Kind, intptr_t Val, // If this is a sugared type (like a typedef, typeof, etc), then unwrap one // level of the sugar so that the type is more obvious to the user. - QualType DesugaredTy = Ty->getDesugaredType(); + QualType DesugaredTy = Ty->getDesugaredType(true); DesugaredTy.setCVRQualifiers(DesugaredTy.getCVRQualifiers() | Ty.getCVRQualifiers()); |