[cfe-commits] r77554 - in /cfe/trunk: lib/CodeGen/CGCXX.cpp test/CodeGenCXX/nested-base-member-access.cpp

Fariborz Jahanian fjahanian at apple.com
Wed Jul 29 17:10:25 PDT 2009


Author: fjahanian
Date: Wed Jul 29 19:10:25 2009
New Revision: 77554

URL: http://llvm.org/viewvc/llvm-project?rev=77554&view=rev
Log:
ir-gen for nested non-virtual base member access
in current class.

Added:
    cfe/trunk/test/CodeGenCXX/nested-base-member-access.cpp
Modified:
    cfe/trunk/lib/CodeGen/CGCXX.cpp

Modified: cfe/trunk/lib/CodeGen/CGCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXX.cpp?rev=77554&r1=77553&r2=77554&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCXX.cpp Wed Jul 29 19:10:25 2009
@@ -155,19 +155,61 @@
   return Builder.CreateLoad(LocalDeclMap[CXXThisDecl], "this");
 }
 
+static bool
+GetNestedPaths(llvm::SmallVectorImpl<const CXXRecordDecl *> &NestedBasePaths,
+               const CXXRecordDecl *ClassDecl,
+               const CXXRecordDecl *BaseClassDecl) {
+  assert(!ClassDecl->isPolymorphic() && 
+         "FIXME: We don't support polymorphic classes yet!");
+  for (CXXRecordDecl::base_class_const_iterator i = ClassDecl->bases_begin(),
+      e = ClassDecl->bases_end(); i != e; ++i) {
+    if (i->isVirtual())
+      continue;
+    const CXXRecordDecl *Base = 
+        cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
+    if (Base == BaseClassDecl) {
+      NestedBasePaths.push_back(BaseClassDecl);
+      return true;
+    }
+  }
+  // BaseClassDecl not an immediate base of ClassDecl.
+  for (CXXRecordDecl::base_class_const_iterator i = ClassDecl->bases_begin(),
+       e = ClassDecl->bases_end(); i != e; ++i) {
+    if (i->isVirtual())
+      continue;
+    const CXXRecordDecl *Base = 
+      cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
+    if (GetNestedPaths(NestedBasePaths, Base, BaseClassDecl)) {
+      NestedBasePaths.push_back(Base);
+      return true;
+    }
+  }
+  return false;
+}
+
 llvm::Value *CodeGenFunction::AddressCXXOfBaseClass(llvm::Value *BaseValue,
                                           const CXXRecordDecl *ClassDecl, 
                                           const CXXRecordDecl *BaseClassDecl) {
   if (ClassDecl == BaseClassDecl)
     return BaseValue;
   
+  llvm::Type *I8Ptr = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
+  llvm::SmallVector<const CXXRecordDecl *, 16> NestedBasePaths;
+  GetNestedPaths(NestedBasePaths, ClassDecl, BaseClassDecl);
+  assert(NestedBasePaths.size() > 0 && 
+         "AddressCXXOfBaseClass - inheritence path failed");
+  NestedBasePaths.push_back(ClassDecl);
+  uint64_t Offset = 0;
+  
   // 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 = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
-  uint64_t Offset = Layout.getBaseClassOffset(BaseClassDecl) / 8;
+  for (unsigned i = NestedBasePaths.size()-1; i > 0; i--) {
+    const CXXRecordDecl *DerivedClass = NestedBasePaths[i];
+    const CXXRecordDecl *BaseClass = NestedBasePaths[i-1];
+    const ASTRecordLayout &Layout = 
+      getContext().getASTRecordLayout(DerivedClass);
+    Offset += Layout.getBaseClassOffset(BaseClass) / 8;
+  }
   llvm::Value *OffsetVal = 
     llvm::ConstantInt::get(
                   CGM.getTypes().ConvertType(CGM.getContext().LongTy), Offset);

Added: cfe/trunk/test/CodeGenCXX/nested-base-member-access.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/nested-base-member-access.cpp?rev=77554&view=auto

==============================================================================
--- cfe/trunk/test/CodeGenCXX/nested-base-member-access.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/nested-base-member-access.cpp Wed Jul 29 19:10:25 2009
@@ -0,0 +1,51 @@
+// RUN: clang-cc %s -emit-llvm -o %t
+
+extern "C" int printf(...);
+
+struct M {
+  M(int i){ iM = i; }
+  int iM;
+  void MPR() { printf("iM = %d\n", iM); }
+
+};
+
+struct Q {
+  Q(int i){ iQ = i; }
+  int iQ;
+  void QPR() { printf("iQ = %d\n", iQ); }
+};
+
+struct IQ {
+  IQ(int i) { iIQ = i; }
+  void IQPR() { printf("iIQ = %d\n", iIQ); }
+  int iIQ;
+};
+
+struct L : IQ {
+  L(int i) : IQ(i+100) { iL = i; }
+  int iL;
+};
+
+struct P : Q, L  {
+  P(int i) : Q(i+100), L(i+200) { iP = i; }
+  int iP;
+  void PPR() { printf("iP = %d\n", iP); }
+};
+
+
+struct N : M,P {
+  N() : M(100), P(200) {}
+  void PR() { this->MPR(); this->PPR(); this->QPR(); 
+	      IQPR();
+	      printf("iM = %d\n", iM); 
+	      printf("iP = %d\n", iP);
+ 	      printf("iQ = %d\n", iQ);
+ 	      printf("iL = %d\n", iL);
+ 	      printf("iIQ = %d\n", iIQ);
+	      }
+};
+
+int main() {
+  N n1;
+  n1.PR();
+}





More information about the cfe-commits mailing list