]> granicus.if.org Git - clang/commitdiff
Teach getCXXRecordDeclForPointerType about references.
authorJordan Rose <jordan_rose@apple.com>
Wed, 3 Oct 2012 01:08:28 +0000 (01:08 +0000)
committerJordan Rose <jordan_rose@apple.com>
Wed, 3 Oct 2012 01:08:28 +0000 (01:08 +0000)
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
lib/AST/Type.cpp
lib/CodeGen/CGExprScalar.cpp
lib/StaticAnalyzer/Core/RegionStore.cpp

index 7b903b315ca94645a257e87568c7486603203c07..1950751acec7e8a5da5fd238239f8e3d688a8416 100644 (file)
@@ -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.
index 9db41c4b1e95f97c1fe877d05f4596a48e5915c8..218e6e9a4d1bca3073861470f0c084517c68de49 100644 (file)
@@ -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;
 }
 
index 28062456ccbe9d21f0b62fc5e6b3f1eef4bbba13..6d25642d02bebd89389135e6e995fefdde0fd6e3 100644 (file)
@@ -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(),
index aadb963e50f631e7aeb647bcde6bc1fc8db483df..4902f246ec4bd14ede8e21d6a0f8ef564d179c38 100644 (file)
@@ -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());