]> granicus.if.org Git - clang/commitdiff
More work toward data member access ir-gen.
authorFariborz Jahanian <fjahanian@apple.com>
Tue, 28 Jul 2009 17:38:28 +0000 (17:38 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Tue, 28 Jul 2009 17:38:28 +0000 (17:38 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@77332 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGCXX.cpp
lib/CodeGen/CGExpr.cpp
lib/CodeGen/CodeGenFunction.h
test/CodeGenCXX/constructor-init.cpp

index dd32cad21b88261d5e1705d252a55d9408039cc6..a0aaa82b4b169d5b360d038bdc0bf3746810af90 100644 (file)
@@ -155,6 +155,42 @@ llvm::Value *CodeGenFunction::LoadCXXThis() {
   return Builder.CreateLoad(LocalDeclMap[CXXThisDecl], "this");
 }
 
+llvm::Value *CodeGenFunction::AddressCXXOfBaseClass(llvm::Value *BaseValue,
+                                                CXXRecordDecl *ClassDecl, 
+                                                CXXRecordDecl *BaseClassDecl) {
+  if (ClassDecl == BaseClassDecl)
+    return BaseValue;
+  
+  // Accessing a member of the base class. Must add delata to
+  // the load of 'this'.
+  // FIXME. Once type layout is complete, this will probably change.
+  const ASTRecordLayout &Layout = 
+  getContext().getASTRecordLayout(ClassDecl);
+  llvm::Type *I8Ptr = VMContext.getPointerTypeUnqual(llvm::Type::Int8Ty);
+  unsigned Idx = 0;
+  for (CXXRecordDecl::base_class_const_iterator i = 
+         ClassDecl->bases_begin(),
+         e = ClassDecl->bases_end(); i != e; ++i, ++Idx) {
+    if (!i->isVirtual()) {
+        const CXXRecordDecl *Base =
+        cast<CXXRecordDecl>(i->getType()->getAsRecordType()->getDecl());
+        if (Base == BaseClassDecl)
+          break;
+    }
+  }
+  uint64_t Offset = Layout.getFieldOffset(Idx) / 8;
+  llvm::Value *OffsetVal = llvm::ConstantInt::get(llvm::Type::Int32Ty, Offset);
+  BaseValue = Builder.CreateBitCast(BaseValue, I8Ptr);
+  BaseValue = Builder.CreateGEP(BaseValue, OffsetVal, "add.ptr");
+  QualType BTy = 
+    getContext().getCanonicalType(
+                                  getContext().getTypeDeclType(BaseClassDecl));
+  const llvm::Type *BasePtr = ConvertType(BTy);
+  BasePtr = VMContext.getPointerTypeUnqual(BasePtr);
+  BaseValue = Builder.CreateBitCast(BaseValue, BasePtr);
+  return BaseValue;
+}
+
 void
 CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D, 
                                         CXXCtorType Type, 
index 48f69e4ca4d35f8d1dc7a445e8ccd91763f37055..b0e091bd0aa8885269e3eb5c1267f47a43cd9ad1 100644 (file)
@@ -993,6 +993,16 @@ LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) {
     if (PTy->getPointeeType()->isUnionType())
       isUnion = true;
     CVRQualifiers = PTy->getPointeeType().getCVRQualifiers();
+    if (CXXThisExpr *ThisExpr = dyn_cast<CXXThisExpr>(BaseExpr)) {
+      QualType ClassTy = ThisExpr->getType();
+      ClassTy = ClassTy->getPointeeType();
+      CXXRecordDecl *ClassDecl =
+        cast<CXXRecordDecl>(ClassTy->getAsRecordType()->getDecl());
+      FieldDecl *Field = dyn_cast<FieldDecl>(E->getMemberDecl());
+      CXXRecordDecl *BaseClassDecl = 
+        cast<CXXRecordDecl>(Field->getDeclContext());
+      BaseValue = AddressCXXOfBaseClass(BaseValue, ClassDecl, BaseClassDecl);
+    }
   } else if (isa<ObjCPropertyRefExpr>(BaseExpr) ||
              isa<ObjCKVCRefExpr>(BaseExpr)) {
     RValue RV = EmitObjCPropertyGet(BaseExpr);
index 6e905e48ac01bc2df4efbc81f4c95e16a93860a6..06265196f94961a346490657cc035a4e9626650d 100644 (file)
@@ -528,6 +528,14 @@ public:
   /// generating code for an C++ member function.
   llvm::Value *LoadCXXThis();
   
+  /// AddressCXXOfBaseClass - This function will add the necessary delta
+  /// to the load of 'this' and returns address of the base class.
+  // FIXME. This currently only does a derived to non-virtual base conversion. 
+  // Other kinds of conversions will come later.
+  llvm::Value *AddressCXXOfBaseClass(llvm::Value *ThisValue,
+                                     CXXRecordDecl *ClassDecl, 
+                                     CXXRecordDecl *BaseClassDecl);
+  
   void EmitCXXConstructorCall(const CXXConstructorDecl *D, CXXCtorType Type, 
                               llvm::Value *This,
                               CallExpr::const_arg_iterator ArgBeg,
index d2c33aef547ffe67915c0227e14b905d7a25e19a..4f7f8ee8c5aad1b5b4a8d8a5676a9c7638a1eeab 100644 (file)
@@ -35,6 +35,9 @@ struct N : M , P, Q {
              MPR();
              PPR();
               QPR();
+             printf("iQ = %d\n", iQ);
+             printf("iP = %d\n", iP);
+              printf("iM = %d\n", iM);
             }
   float ld;
   float ff;