aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-04-01 15:47:24 +0000
committerDouglas Gregor <dgregor@apple.com>2009-04-01 15:47:24 +0000
commit969c689d893a248eca4f049f5b89f747e66e4bff (patch)
tree326ff6ad11948fb780b0b4efaead9da1e719ab0d /lib
parentcb5a955afb6dca9ad5f9fbdfa97789a93ba10660 (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.cpp34
-rw-r--r--lib/Sema/Sema.cpp2
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());