[cfe-commits] r88823 - in /cfe/trunk/lib/CodeGen: CGRtti.cpp CGVtable.cpp CodeGenModule.h

Mike Stump mrs at apple.com
Sat Nov 14 15:32:22 PST 2009


Author: mrs
Date: Sat Nov 14 17:32:21 2009
New Revision: 88823

URL: http://llvm.org/viewvc/llvm-project?rev=88823&view=rev
Log:
Finisgh off rest of class_type_info rtti generation.

Modified:
    cfe/trunk/lib/CodeGen/CGRtti.cpp
    cfe/trunk/lib/CodeGen/CGVtable.cpp
    cfe/trunk/lib/CodeGen/CodeGenModule.h

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

==============================================================================
--- cfe/trunk/lib/CodeGen/CGRtti.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGRtti.cpp Sat Nov 14 17:32:21 2009
@@ -12,6 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "CodeGenModule.h"
+#include "clang/AST/RecordLayout.h"
 using namespace clang;
 using namespace CodeGen;
 
@@ -24,9 +25,9 @@
     : CGM(cgm), VMContext(cgm.getModule().getContext()),
       Int8PtrTy(llvm::Type::getInt8PtrTy(VMContext)) { }
 
-  llvm::Constant *Buildclass_type_infoDesc() {
-    // Build a descriptor for class_type_info.
-    llvm::StringRef Name = "_ZTVN10__cxxabiv121__vmi_class_type_infoE";
+  /// BuildVtableRef - Build a reference to a vtable.
+  llvm::Constant *BuildVtableRef(const char *Name) {
+    // Build a descriptor for Name
     llvm::Constant *GV = CGM.getModule().getGlobalVariable(Name);
     if (GV)
       GV = llvm::ConstantExpr::getBitCast(GV,
@@ -36,25 +37,25 @@
       linktype = llvm::GlobalValue::ExternalLinkage;
       GV = new llvm::GlobalVariable(CGM.getModule(), Int8PtrTy,
                                     true, linktype, 0, Name);
-    }  
+    }
     llvm::Constant *C;
     C = llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), 2);
     C = llvm::ConstantExpr::getInBoundsGetElementPtr(GV, &C, 1);
     return llvm::ConstantExpr::getBitCast(C, Int8PtrTy);
   }
-  
+
   llvm::Constant *BuildName(const CXXRecordDecl *RD) {
     llvm::SmallString<256> OutName;
     llvm::raw_svector_ostream Out(OutName);
     mangleCXXRttiName(CGM.getMangleContext(),
                       CGM.getContext().getTagDeclType(RD), Out);
-  
+
     llvm::GlobalVariable::LinkageTypes linktype;
     linktype = llvm::GlobalValue::LinkOnceODRLinkage;
 
     llvm::Constant *C;
     C = llvm::ConstantArray::get(VMContext, Out.str().substr(4));
-    
+
     llvm::Constant *s = new llvm::GlobalVariable(CGM.getModule(), C->getType(),
                                                  true, linktype, C,
                                                  Out.str());
@@ -62,8 +63,44 @@
     return s;
   };
 
+  /// - BuildFlags - Build a psABI __flags value for __vmi_class_type_info.
+  llvm::Constant *BuildFlags(int f) {
+    return llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), f);
+  }
+
+  /// BuildBaseCount - Build a psABI __base_count value for
+  /// __vmi_class_type_info.
+  llvm::Constant *BuildBaseCount(unsigned c) {
+    return llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), c);
+  }
+
+  llvm::Constant *Buildclass_type_infoRef(const CXXRecordDecl *RD) {
+    const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext);
+    llvm::Constant *C;
+
+    if (!CGM.getContext().getLangOptions().Rtti)
+      return llvm::Constant::getNullValue(Int8PtrTy);
+
+    llvm::SmallString<256> OutName;
+    llvm::raw_svector_ostream Out(OutName);
+    mangleCXXRtti(CGM.getMangleContext(), CGM.getContext().getTagDeclType(RD),
+                  Out);
+
+    C = CGM.getModule().getGlobalVariable(Out.str());
+    if (C)
+      return llvm::ConstantExpr::getBitCast(C, Int8PtrTy);
+
+    llvm::GlobalVariable::LinkageTypes linktype;
+    linktype = llvm::GlobalValue::ExternalLinkage;;
+
+    C = new llvm::GlobalVariable(CGM.getModule(), Int8PtrTy, true, linktype,
+                                 0, Out.str());
+    return llvm::ConstantExpr::getBitCast(C, Int8PtrTy);
+  }
+
   llvm::Constant *Buildclass_type_info(const CXXRecordDecl *RD) {
     const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext);
+    llvm::Constant *C;
 
     if (!CGM.getContext().getLangOptions().Rtti)
       return llvm::Constant::getNullValue(Int8PtrTy);
@@ -72,29 +109,94 @@
     llvm::raw_svector_ostream Out(OutName);
     mangleCXXRtti(CGM.getMangleContext(), CGM.getContext().getTagDeclType(RD),
                   Out);
-  
+
+    llvm::GlobalVariable *GV;
+    GV = CGM.getModule().getGlobalVariable(Out.str());
+    if (GV && !GV->isDeclaration())
+      return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
+
     llvm::GlobalVariable::LinkageTypes linktype;
     linktype = llvm::GlobalValue::LinkOnceODRLinkage;
     std::vector<llvm::Constant *> info;
 
-    info.push_back(Buildclass_type_infoDesc());
+    if (RD->getNumBases() == 0)
+      C = BuildVtableRef("_ZTVN10__cxxabiv117__class_type_infoE");
+    // FIXME: Add si_class_type_info optimization
+    else
+      C = BuildVtableRef("_ZTVN10__cxxabiv121__vmi_class_type_infoE");
+    info.push_back(C);
     info.push_back(BuildName(RD));
 
-    // FIXME: rest of rtti bits
+    // If we have no bases, there are no more fields.
+    if (RD->getNumBases()) {
 
-    llvm::Constant *C;
+      // FIXME: Calculate is_diamond and non-diamond repeated inheritance, 3 is
+      // conservative.
+      info.push_back(BuildFlags(3));
+      info.push_back(BuildBaseCount(RD->getNumBases()));
+
+      const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
+      for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
+             e = RD->bases_end(); i != e; ++i) {
+        const CXXRecordDecl *Base =
+          cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
+        info.push_back(CGM.GenerateRtti(Base));
+        int64_t offset;
+        if (!i->isVirtual())
+          offset = Layout.getBaseClassOffset(Base);
+        else
+          offset = CGM.getVtableInfo().getVirtualBaseOffsetIndex(RD, Base);
+        offset <<= 8;
+        // Now set the flags.
+        offset += i->isVirtual() ? 1 : 0;;
+        offset += i->getAccessSpecifier() == AS_public ? 2 : 0;
+        const llvm::Type *LongTy =
+          CGM.getTypes().ConvertType(CGM.getContext().LongTy);
+        C = llvm::ConstantInt::get(LongTy, offset);
+        info.push_back(C);
+      }
+    }
+
+    std::vector<const llvm::Type *> Types(info.size());
+    for (unsigned i=0; i<info.size(); ++i)
+      Types[i] = info[i]->getType();
+    // llvm::StructType *Ty = llvm::StructType::get(VMContext, Types, true);
+    C = llvm::ConstantStruct::get(VMContext, &info[0], info.size(), false);
+
+    if (GV == 0)
+      GV = new llvm::GlobalVariable(CGM.getModule(), C->getType(), true, linktype,
+                                    C, Out.str());
+    else {
+      llvm::GlobalVariable *OGV = GV;
+      GV = new llvm::GlobalVariable(CGM.getModule(), C->getType(), true, linktype,
+                                    C, Out.str());
+      GV->takeName(OGV);
+      llvm::Constant *NewPtr = llvm::ConstantExpr::getBitCast(GV, OGV->getType());
+      OGV->replaceAllUsesWith(NewPtr);
+      OGV->eraseFromParent();
+    }
+    return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
+
+#if 0
     llvm::ArrayType *type = llvm::ArrayType::get(Int8PtrTy, info.size());
     C = llvm::ConstantArray::get(type, info);
-    llvm::Constant *Rtti = 
+    llvm::Constant *Rtti =
       new llvm::GlobalVariable(CGM.getModule(), type, true, linktype, C,
                                Out.str());
     Rtti = llvm::ConstantExpr::getBitCast(Rtti, Int8PtrTy);
     return Rtti;
+#endif
   }
 };
 
+llvm::Constant *CodeGenModule::GenerateRttiRef(const CXXRecordDecl *RD) {
+  RttiBuilder b(*this);
+
+  return b.Buildclass_type_infoRef(RD);
+}
+
 llvm::Constant *CodeGenModule::GenerateRtti(const CXXRecordDecl *RD) {
   RttiBuilder b(*this);
 
-  return  b.Buildclass_type_info(RD);
+  return b.Buildclass_type_info(RD);
 }

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

==============================================================================
--- cfe/trunk/lib/CodeGen/CGVtable.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGVtable.cpp Sat Nov 14 17:32:21 2009
@@ -80,7 +80,7 @@
                 const CXXRecordDecl *l, uint64_t lo, CodeGenModule &cgm)
     : methods(meth), Class(c), LayoutClass(l), LayoutOffset(lo),
       BLayout(cgm.getContext().getASTRecordLayout(l)),
-      rtti(cgm.GenerateRtti(c)), VMContext(cgm.getModule().getContext()),
+      rtti(cgm.GenerateRttiRef(c)), VMContext(cgm.getModule().getContext()),
       CGM(cgm), AddressPoints(*new llvm::DenseMap<CtorVtable_t, int64_t>),
       Extern(true),
       LLVMPointerWidth(cgm.getContext().Target.getPointerWidth(0)) {
@@ -1022,6 +1022,7 @@
   if (vtbl)
     return vtbl;
   vtbl = CGM.GenerateVtable(RD, RD);
+  CGM.GenerateRtti(RD);
   CGM.GenerateVTT(RD);
   return vtbl;
 }

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=88823&r1=88822&r2=88823&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Sat Nov 14 17:32:21 2009
@@ -226,6 +226,9 @@
 
   /// GenerateRtti - Generate the rtti information for the given type.
   llvm::Constant *GenerateRtti(const CXXRecordDecl *RD);
+  /// GenerateRttiRef - Generate a reference to the rtti information for the
+  /// given type.
+  llvm::Constant *GenerateRttiRef(const CXXRecordDecl *RD);
 
   /// BuildThunk - Build a thunk for the given method
   llvm::Constant *BuildThunk(const CXXMethodDecl *MD, bool Extern, int64_t nv,





More information about the cfe-commits mailing list