]> granicus.if.org Git - clang/commitdiff
More work on thunks.
authorAnders Carlsson <andersca@mac.com>
Tue, 23 Mar 2010 16:36:50 +0000 (16:36 +0000)
committerAnders Carlsson <andersca@mac.com>
Tue, 23 Mar 2010 16:36:50 +0000 (16:36 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@99287 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGVtable.cpp
lib/CodeGen/CGVtable.h

index 736fb047c99d2cfe4e485704f97514ae31d233c2..279fcaac7d7c4e287e4b14d54f0199ab1afa159f 100644 (file)
@@ -1291,6 +1291,14 @@ public:
     LayoutVtable();
   }
 
+  ThunksMapTy::const_iterator thunks_begin() const {
+    return Thunks.begin();
+  }
+
+  ThunksMapTy::const_iterator thunks_end() const {
+    return Thunks.end();
+  }
+
   /// dumpLayout - Dump the vtable layout.
   void dumpLayout(llvm::raw_ostream&);
 };
@@ -3642,9 +3650,55 @@ CodeGenVTables::GenerateVtable(llvm::GlobalVariable::LinkageTypes Linkage,
   return GV;
 }
 
+void CodeGenVTables::EmitThunk(GlobalDecl GD, const ThunkInfo &Thunk)
+{
+  // FIXME: Implement this!
+}
+
 void CodeGenVTables::EmitThunks(GlobalDecl GD)
 {
-  CGM.BuildThunksForVirtual(GD);
+  // FIXME: We use the -fdump-vtable-layouts flag to trigger the new thunk
+  // building code for now.
+  if (!CGM.getLangOptions().DumpVtableLayouts) {
+    CGM.BuildThunksForVirtual(GD);
+    return;
+  }
+
+  const CXXMethodDecl *MD = 
+    cast<CXXMethodDecl>(GD.getDecl())->getCanonicalDecl();
+
+  // We don't need to generate thunks for the base destructor.
+  if (isa<CXXDestructorDecl>(MD) && GD.getDtorType() == Dtor_Base)
+    return;
+
+  const CXXRecordDecl *RD = MD->getParent();
+  
+  ThunksMapTy::const_iterator I = Thunks.find(MD);
+  if (I == Thunks.end()) {
+    // We did not find a thunk for this method. Check if we've collected thunks
+    // for this record.
+    if (!ClassesWithKnownThunkStatus.insert(RD).second) {
+      // This member function doesn't have any associated thunks.
+      return;
+    }
+    
+    // Use the vtable builder to build thunks for this class.
+    VtableBuilder Builder(*this, RD, 0, /*MostDerivedClassIsVirtual=*/0, RD);
+
+    // Add the known thunks.
+    Thunks.insert(Builder.thunks_begin(), Builder.thunks_end());
+  
+    // Look for the thunk again.
+    I = Thunks.find(MD);
+    if (I == Thunks.end()) {
+      // Looks like this function doesn't have any associated thunks after all.
+      return;
+    }
+  }
+  
+  const ThunkInfoVectorTy &ThunkInfoVector = I->second;
+  for (unsigned I = 0, E = ThunkInfoVector.size(); I != E; ++I)
+    EmitThunk(GD, ThunkInfoVector[I]);
 }
 
 void 
index 93aff61af4bf74bf0743f49b05465271e395e571..450fa9382f2e61bc6adac17f13c98c3097865fef 100644 (file)
@@ -255,6 +255,16 @@ private:
   SavedAdjustmentsTy SavedAdjustments;
   llvm::DenseSet<const CXXRecordDecl*> SavedAdjustmentRecords;
 
+  typedef llvm::SmallVector<ThunkInfo, 1> ThunkInfoVectorTy;
+  typedef llvm::DenseMap<const CXXMethodDecl *, ThunkInfoVectorTy> ThunksMapTy;
+  
+  /// Thunks - Contains all thunks that a given method decl will need.
+  ThunksMapTy Thunks;
+
+  /// ClassesWithKnownThunkStatus - Contains all the classes for which we know
+  /// whether their virtual member functions have thunks or not.
+  llvm::DenseSet<const CXXRecordDecl *> ClassesWithKnownThunkStatus;
+  
   typedef llvm::DenseMap<ClassPairTy, uint64_t> SubVTTIndiciesTy;
   SubVTTIndiciesTy SubVTTIndicies;
 
@@ -274,6 +284,9 @@ private:
                                     bool GenerateDefinition,
                                     const CXXRecordDecl *RD);
 
+  /// EmitThunk - Emit a single thunk.
+  void EmitThunk(GlobalDecl GD, const ThunkInfo &Thunk);
+  
   /// EmitThunks - Emit the associated thunks for the given global decl.
   void EmitThunks(GlobalDecl GD);