aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2012-10-03 01:08:28 +0000
committerJordan Rose <jordan_rose@apple.com>2012-10-03 01:08:28 +0000
commit041ce8e00afd1185549a25d5c2b97d219ae032d9 (patch)
tree2822099dd1b8e0266c4aa27d3ca543290fa1022c
parent6b2cc42f1504db6577fd67fa55ef023254744e2c (diff)
Teach getCXXRecordDeclForPointerType about references.
Then, rename it getPointeeCXXRecordDecl and give it a nice doc comment, and actually use it. No intended functionality change. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@165077 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/AST/Type.h8
-rw-r--r--lib/AST/Type.cpp14
-rw-r--r--lib/CodeGen/CGExprScalar.cpp15
-rw-r--r--lib/StaticAnalyzer/Core/RegionStore.cpp25
4 files changed, 30 insertions, 32 deletions
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
index 7b903b315c..1950751ace 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -1675,13 +1675,19 @@ public:
const ObjCObjectPointerType *getAsObjCQualifiedIdType() const;
const ObjCObjectPointerType *getAsObjCQualifiedClassType() const;
const ObjCObjectType *getAsObjCQualifiedInterfaceType() const;
- const CXXRecordDecl *getCXXRecordDeclForPointerType() const;
/// \brief Retrieves the CXXRecordDecl that this type refers to, either
/// because the type is a RecordType or because it is the injected-class-name
/// type of a class template or class template partial specialization.
CXXRecordDecl *getAsCXXRecordDecl() const;
+ /// If this is a pointer or reference to a RecordType, return the
+ /// CXXRecordDecl that that type refers to.
+ ///
+ /// If this is not a pointer or reference, or the type being pointed to does
+ /// not refer to a CXXRecordDecl, returns NULL.
+ const CXXRecordDecl *getPointeeCXXRecordDecl() const;
+
/// \brief Get the AutoType whose type will be deduced for a variable with
/// an initializer of this type. This looks through declarators like pointer
/// types, but not through decltype or typedefs.
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index 9db41c4b1e..218e6e9a4d 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -512,10 +512,18 @@ const ObjCObjectPointerType *Type::getAsObjCInterfacePointerType() const {
return 0;
}
-const CXXRecordDecl *Type::getCXXRecordDeclForPointerType() const {
+const CXXRecordDecl *Type::getPointeeCXXRecordDecl() const {
+ QualType PointeeType;
if (const PointerType *PT = getAs<PointerType>())
- if (const RecordType *RT = PT->getPointeeType()->getAs<RecordType>())
- return dyn_cast<CXXRecordDecl>(RT->getDecl());
+ PointeeType = PT->getPointeeType();
+ else if (const ReferenceType *RT = getAs<ReferenceType>())
+ PointeeType = RT->getPointeeType();
+ else
+ return 0;
+
+ if (const RecordType *RT = PointeeType->getAs<RecordType>())
+ return dyn_cast<CXXRecordDecl>(RT->getDecl());
+
return 0;
}
diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp
index 28062456cc..6d25642d02 100644
--- a/lib/CodeGen/CGExprScalar.cpp
+++ b/lib/CodeGen/CGExprScalar.cpp
@@ -1056,19 +1056,18 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {
return Visit(const_cast<Expr*>(E));
case CK_BaseToDerived: {
- const CXXRecordDecl *DerivedClassDecl =
- DestTy->getCXXRecordDeclForPointerType();
-
- return CGF.GetAddressOfDerivedClass(Visit(E), DerivedClassDecl,
+ const CXXRecordDecl *DerivedClassDecl = DestTy->getPointeeCXXRecordDecl();
+ assert(DerivedClassDecl && "BaseToDerived arg isn't a C++ object pointer!");
+
+ return CGF.GetAddressOfDerivedClass(Visit(E), DerivedClassDecl,
CE->path_begin(), CE->path_end(),
ShouldNullCheckClassCastValue(CE));
}
case CK_UncheckedDerivedToBase:
case CK_DerivedToBase: {
- const RecordType *DerivedClassTy =
- E->getType()->getAs<PointerType>()->getPointeeType()->getAs<RecordType>();
- CXXRecordDecl *DerivedClassDecl =
- cast<CXXRecordDecl>(DerivedClassTy->getDecl());
+ const CXXRecordDecl *DerivedClassDecl =
+ E->getType()->getPointeeCXXRecordDecl();
+ assert(DerivedClassDecl && "DerivedToBase arg isn't a C++ object pointer!");
return CGF.GetAddressOfBaseClass(Visit(E), DerivedClassDecl,
CE->path_begin(), CE->path_end(),
diff --git a/lib/StaticAnalyzer/Core/RegionStore.cpp b/lib/StaticAnalyzer/Core/RegionStore.cpp
index aadb963e50..4902f246ec 100644
--- a/lib/StaticAnalyzer/Core/RegionStore.cpp
+++ b/lib/StaticAnalyzer/Core/RegionStore.cpp
@@ -900,31 +900,16 @@ SVal RegionStoreManager::ArrayToPointer(Loc Array) {
return loc::MemRegionVal(MRMgr.getElementRegion(T, ZeroIdx, ArrayR, Ctx));
}
-// This mirrors Type::getCXXRecordDeclForPointerType(), but there doesn't
-// appear to be another need for this in the rest of the codebase.
-static const CXXRecordDecl *GetCXXRecordDeclForReferenceType(QualType Ty) {
- if (const ReferenceType *RT = Ty->getAs<ReferenceType>())
- if (const RecordType *RCT = RT->getPointeeType()->getAs<RecordType>())
- return dyn_cast<CXXRecordDecl>(RCT->getDecl());
- return 0;
-}
-
SVal RegionStoreManager::evalDerivedToBase(SVal derived, QualType baseType) {
- const CXXRecordDecl *baseDecl;
-
- if (baseType->isPointerType())
- baseDecl = baseType->getCXXRecordDeclForPointerType();
- else if (baseType->isReferenceType())
- baseDecl = GetCXXRecordDeclForReferenceType(baseType);
- else
- baseDecl = baseType->getAsCXXRecordDecl();
-
- assert(baseDecl && "not a CXXRecordDecl?");
-
loc::MemRegionVal *derivedRegVal = dyn_cast<loc::MemRegionVal>(&derived);
if (!derivedRegVal)
return derived;
+ const CXXRecordDecl *baseDecl = baseType->getPointeeCXXRecordDecl();
+ if (!baseDecl)
+ baseDecl = baseType->getAsCXXRecordDecl();
+ assert(baseDecl && "not a C++ object?");
+
const MemRegion *baseReg =
MRMgr.getCXXBaseObjectRegion(baseDecl, derivedRegVal->getRegion());