diff options
| author | Douglas Gregor <dgregor@apple.com> | 2010-06-09 03:53:18 +0000 |
|---|---|---|
| committer | Douglas Gregor <dgregor@apple.com> | 2010-06-09 03:53:18 +0000 |
| commit | 1fc3d66da4c2fa5f26a89c09f3ecf3325439b57d (patch) | |
| tree | 658e6924bdc1563955e6a857cbb57094c753be46 /clang/lib/AST/ASTContext.cpp | |
| parent | 83c64ee8de0842433aeaf52ed3750ae8495366e1 (diff) | |
| download | bcm5719-llvm-1fc3d66da4c2fa5f26a89c09f3ecf3325439b57d.tar.gz bcm5719-llvm-1fc3d66da4c2fa5f26a89c09f3ecf3325439b57d.zip | |
Tweak our handling of the notion of a standard conversion sequence
being a subsequence of another standard conversion sequence. Instead
of requiring exact type equality for the second conversion step,
require type *similarity*, which is type equality with cv-qualifiers
removed at all levels. This appears to match the behavior of EDG and
VC++ (albeit not GCC), and feels more intuitive. Big thanks to John
for the line of reasoning that supports this change: since
cv-qualifiers are orthogonal to the second conversion step, we should
ignore them in the type comparison.
llvm-svn: 105678
Diffstat (limited to 'clang/lib/AST/ASTContext.cpp')
| -rw-r--r-- | clang/lib/AST/ASTContext.cpp | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 75af89ee96a..2e724495756 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -2339,6 +2339,48 @@ QualType ASTContext::getUnqualifiedArrayType(QualType T, SourceRange()); } +/// UnwrapSimilarPointerTypes - If T1 and T2 are pointer types that +/// may be similar (C++ 4.4), replaces T1 and T2 with the type that +/// they point to and return true. If T1 and T2 aren't pointer types +/// or pointer-to-member types, or if they are not similar at this +/// level, returns false and leaves T1 and T2 unchanged. Top-level +/// qualifiers on T1 and T2 are ignored. This function will typically +/// be called in a loop that successively "unwraps" pointer and +/// pointer-to-member types to compare them at each level. +bool ASTContext::UnwrapSimilarPointerTypes(QualType &T1, QualType &T2) { + const PointerType *T1PtrType = T1->getAs<PointerType>(), + *T2PtrType = T2->getAs<PointerType>(); + if (T1PtrType && T2PtrType) { + T1 = T1PtrType->getPointeeType(); + T2 = T2PtrType->getPointeeType(); + return true; + } + + const MemberPointerType *T1MPType = T1->getAs<MemberPointerType>(), + *T2MPType = T2->getAs<MemberPointerType>(); + if (T1MPType && T2MPType && + hasSameUnqualifiedType(QualType(T1MPType->getClass(), 0), + QualType(T2MPType->getClass(), 0))) { + T1 = T1MPType->getPointeeType(); + T2 = T2MPType->getPointeeType(); + return true; + } + + if (getLangOptions().ObjC1) { + const ObjCObjectPointerType *T1OPType = T1->getAs<ObjCObjectPointerType>(), + *T2OPType = T2->getAs<ObjCObjectPointerType>(); + if (T1OPType && T2OPType) { + T1 = T1OPType->getPointeeType(); + T2 = T2OPType->getPointeeType(); + return true; + } + } + + // FIXME: Block pointers, too? + + return false; +} + DeclarationName ASTContext::getNameForTemplate(TemplateName Name) { if (TemplateDecl *TD = Name.getAsTemplateDecl()) return TD->getDeclName(); |

