From 041ce8e00afd1185549a25d5c2b97d219ae032d9 Mon Sep 17 00:00:00 2001 From: Jordan Rose Date: Wed, 3 Oct 2012 01:08:28 +0000 Subject: [PATCH] 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 --- include/clang/AST/Type.h | 8 +++++++- lib/AST/Type.cpp | 14 +++++++++++--- lib/CodeGen/CGExprScalar.cpp | 15 +++++++-------- lib/StaticAnalyzer/Core/RegionStore.cpp | 25 +++++-------------------- 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()) - if (const RecordType *RT = PT->getPointeeType()->getAs()) - return dyn_cast(RT->getDecl()); + PointeeType = PT->getPointeeType(); + else if (const ReferenceType *RT = getAs()) + PointeeType = RT->getPointeeType(); + else + return 0; + + if (const RecordType *RT = PointeeType->getAs()) + return dyn_cast(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(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()->getPointeeType()->getAs(); - CXXRecordDecl *DerivedClassDecl = - cast(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()) - if (const RecordType *RCT = RT->getPointeeType()->getAs()) - return dyn_cast(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(&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()); -- 2.40.0