summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST/ASTContext.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-06-09 03:53:18 +0000
committerDouglas Gregor <dgregor@apple.com>2010-06-09 03:53:18 +0000
commit1fc3d66da4c2fa5f26a89c09f3ecf3325439b57d (patch)
tree658e6924bdc1563955e6a857cbb57094c753be46 /clang/lib/AST/ASTContext.cpp
parent83c64ee8de0842433aeaf52ed3750ae8495366e1 (diff)
downloadbcm5719-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.cpp42
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();
OpenPOWER on IntegriCloud