[cfe-commits] r90745 - in /cfe/trunk: include/clang/AST/ASTContext.h include/clang/AST/RecordLayout.h lib/AST/ASTContext.cpp lib/AST/RecordLayoutBuilder.cpp lib/AST/RecordLayoutBuilder.h lib/CodeGen/CGVtable.cpp lib/Sema/SemaDeclCXX.cpp

Anders Carlsson andersca at mac.com
Sun Dec 6 20:35:15 PST 2009


Author: andersca
Date: Sun Dec  6 22:35:11 2009
New Revision: 90745

URL: http://llvm.org/viewvc/llvm-project?rev=90745&view=rev
Log:
Move key functions to a separate map.

Modified:
    cfe/trunk/include/clang/AST/ASTContext.h
    cfe/trunk/include/clang/AST/RecordLayout.h
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/AST/RecordLayoutBuilder.cpp
    cfe/trunk/lib/AST/RecordLayoutBuilder.h
    cfe/trunk/lib/CodeGen/CGVtable.cpp
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp

Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=90745&r1=90744&r2=90745&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Sun Dec  6 22:35:11 2009
@@ -45,6 +45,8 @@
   class SourceManager;
   class TargetInfo;
   // Decls
+  class CXXMethodDecl;
+  class CXXRecordDecl;
   class Decl;
   class FieldDecl;
   class ObjCIvarDecl;
@@ -106,6 +108,9 @@
   llvm::DenseMap<const RecordDecl*, const ASTRecordLayout*> ASTRecordLayouts;
   llvm::DenseMap<const ObjCContainerDecl*, const ASTRecordLayout*> ObjCLayouts;
 
+  /// KeyFunctions - A cache mapping from CXXRecordDecls to key functions.
+  llvm::DenseMap<const CXXRecordDecl*, const CXXMethodDecl*> KeyFunctions;
+  
   /// \brief Mapping from ObjCContainers to their ObjCImplementations.
   llvm::DenseMap<ObjCContainerDecl*, ObjCImplDecl*> ObjCImpls;
 
@@ -852,6 +857,13 @@
   const ASTRecordLayout &
   getASTObjCImplementationLayout(const ObjCImplementationDecl *D);
 
+  /// getKeyFunction - Get the key function for the given record decl. 
+  /// The key function is, according to the Itanium C++ ABI section 5.2.3:
+  ///
+  /// ...the first non-pure virtual function that is not inline at the point
+  /// of class definition.
+  const CXXMethodDecl *getKeyFunction(const CXXRecordDecl *RD);
+
   void CollectObjCIvars(const ObjCInterfaceDecl *OI,
                         llvm::SmallVectorImpl<FieldDecl*> &Fields);
 

Modified: cfe/trunk/include/clang/AST/RecordLayout.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecordLayout.h?rev=90745&r1=90744&r2=90745&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/RecordLayout.h (original)
+++ cfe/trunk/include/clang/AST/RecordLayout.h Sun Dec  6 22:35:11 2009
@@ -119,13 +119,6 @@
     /// VBaseOffsets - Contains a map from vbase classes to their offset.
     /// FIXME: This should really use a SmallPtrMap, once we have one in LLVM :)
     llvm::DenseMap<const CXXRecordDecl *, uint64_t> VBaseOffsets;
-    
-    /// KeyFunction - The key function, according to the Itanium C++ ABI,
-    /// section 5.2.3:
-    ///
-    /// ...the first non-pure virtual function that is not inline at the point
-    /// of class definition.
-    const CXXMethodDecl *KeyFunction;
   };
 
   /// CXXInfo - If the record layout is for a C++ record, this will have
@@ -154,8 +147,7 @@
                   const std::pair<const CXXRecordDecl *, uint64_t> *bases,
                   unsigned numbases,
                   const std::pair<const CXXRecordDecl *, uint64_t> *vbases,
-                  unsigned numvbases,
-                  const CXXMethodDecl *KeyFunction)
+                  unsigned numvbases)
   : Size(size), DataSize(datasize), FieldOffsets(0), Alignment(alignment),
   FieldCount(fieldcount), CXXInfo(new CXXRecordLayoutInfo) {
     if (FieldCount > 0)  {
@@ -171,7 +163,6 @@
       CXXInfo->BaseOffsets[bases[i].first] = bases[i].second;
     for (unsigned i = 0; i != numvbases; ++i)
       CXXInfo->VBaseOffsets[vbases[i].first] = vbases[i].second;
-    CXXInfo->KeyFunction = KeyFunction;
   }
 
   ~ASTRecordLayout() {
@@ -254,13 +245,6 @@
     return CXXInfo->VBaseOffsets[VBase];
   }
   
-  /// getKeyFunction - Get the key function.                  
-  const CXXMethodDecl *getKeyFunction() const {
-    assert(CXXInfo && "Record layout does not have C++ specific info!");
-
-    return CXXInfo->KeyFunction;
-  }
-  
   primary_base_info_iterator primary_base_begin() const {
     assert(CXXInfo && "Record layout does not have C++ specific info!");
   

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=90745&r1=90744&r2=90745&view=diff

==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Sun Dec  6 22:35:11 2009
@@ -1104,6 +1104,20 @@
   return *NewEntry;
 }
 
+const CXXMethodDecl *ASTContext::getKeyFunction(const CXXRecordDecl *RD) {
+  RD = cast<CXXRecordDecl>(RD->getDefinition(*this));
+  assert(RD && "Cannot get key function for forward declarations!");
+  
+  const CXXMethodDecl *&Entry = KeyFunctions[RD];
+  if (!Entry) 
+    Entry = ASTRecordLayoutBuilder::ComputeKeyFunction(RD);
+  else
+    assert(Entry == ASTRecordLayoutBuilder::ComputeKeyFunction(RD) &&
+           "Key function changed!");
+  
+  return Entry;
+}
+
 //===----------------------------------------------------------------------===//
 //                   Type creation/memoization methods
 //===----------------------------------------------------------------------===//

Modified: cfe/trunk/lib/AST/RecordLayoutBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/RecordLayoutBuilder.cpp?rev=90745&r1=90744&r2=90745&view=diff

==============================================================================
--- cfe/trunk/lib/AST/RecordLayoutBuilder.cpp (original)
+++ cfe/trunk/lib/AST/RecordLayoutBuilder.cpp Sun Dec  6 22:35:11 2009
@@ -663,35 +663,6 @@
   Alignment = NewAlignment;
 }
 
-static const CXXMethodDecl *GetKeyFunction(const CXXRecordDecl *RD) {
-  if (!RD->isDynamicClass())
-    return 0;
-  
-  for (CXXRecordDecl::method_iterator I = RD->method_begin(), 
-       E = RD->method_end(); I != E; ++I) {
-    const CXXMethodDecl *MD = *I;
-    
-    if (!MD->isVirtual())
-      continue;
-    
-    if (MD->isPure())
-      continue;
-    
-    // Ignore implicit member functions, they are always marked as inline, but
-    // they don't have a body until they're defined.
-    if (MD->isImplicit())
-      continue;
-
-    if (MD->hasInlineBody())
-      continue;
-    
-    // We found it.
-    return MD;
-  }
-  
-  return 0;
-}
-
 const ASTRecordLayout *
 ASTRecordLayoutBuilder::ComputeLayout(ASTContext &Ctx,
                                       const RecordDecl *D) {
@@ -715,8 +686,6 @@
   uint64_t NonVirtualSize =
     IsPODForThePurposeOfLayout ? DataSize : Builder.NonVirtualSize;
 
-  const CXXMethodDecl *KeyFunction = GetKeyFunction(cast<CXXRecordDecl>(D));
-  
   return new ASTRecordLayout(Builder.Size, Builder.Alignment, DataSize,
                              Builder.FieldOffsets.data(),
                              Builder.FieldOffsets.size(),
@@ -726,8 +695,7 @@
                              Builder.Bases.data(),
                              Builder.Bases.size(),
                              Builder.VBases.data(),
-                             Builder.VBases.size(),
-                             KeyFunction);
+                             Builder.VBases.size());
 }
 
 const ASTRecordLayout *
@@ -743,3 +711,37 @@
                              Builder.FieldOffsets.data(),
                              Builder.FieldOffsets.size());
 }
+
+const CXXMethodDecl *
+ASTRecordLayoutBuilder::ComputeKeyFunction(const CXXRecordDecl *RD) {
+  assert(RD->isDynamicClass() && "Class does not have any virtual methods!");
+
+  // If a class isnt' polymorphic it doesn't have a key function.
+  if (!RD->isPolymorphic())
+    return 0;
+  
+  for (CXXRecordDecl::method_iterator I = RD->method_begin(), 
+       E = RD->method_end(); I != E; ++I) {
+    const CXXMethodDecl *MD = *I;
+    
+    if (!MD->isVirtual())
+      continue;
+    
+    if (MD->isPure())
+      continue;
+    
+    // Ignore implicit member functions, they are always marked as inline, but
+    // they don't have a body until they're defined.
+    if (MD->isImplicit())
+      continue;
+
+    if (MD->hasInlineBody())
+      continue;
+    
+    // We found it.
+    return MD;
+  }
+  
+  return 0;
+}
+

Modified: cfe/trunk/lib/AST/RecordLayoutBuilder.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/RecordLayoutBuilder.h?rev=90745&r1=90744&r2=90745&view=diff

==============================================================================
--- cfe/trunk/lib/AST/RecordLayoutBuilder.h (original)
+++ cfe/trunk/lib/AST/RecordLayoutBuilder.h Sun Dec  6 22:35:11 2009
@@ -151,6 +151,7 @@
   static const ASTRecordLayout *ComputeLayout(ASTContext &Ctx,
                                               const ObjCInterfaceDecl *D,
                                             const ObjCImplementationDecl *Impl);
+  static const CXXMethodDecl *ComputeKeyFunction(const CXXRecordDecl *RD);
 };
 
 } // end namespace clang

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

==============================================================================
--- cfe/trunk/lib/CodeGen/CGVtable.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGVtable.cpp Sun Dec  6 22:35:11 2009
@@ -1433,10 +1433,8 @@
   if (!RD->isDynamicClass())
     return;
   
-  const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
-  
   // Get the key function.
-  const CXXMethodDecl *KeyFunction = Layout.getKeyFunction();
+  const CXXMethodDecl *KeyFunction = CGM.getContext().getKeyFunction(RD);
   
   if (KeyFunction) {
     // We don't have the right key function.

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=90745&r1=90744&r2=90745&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Sun Dec  6 22:35:11 2009
@@ -5090,8 +5090,12 @@
     return;
   
   CXXRecordDecl *RD = MD->getParent();
-  const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
-  const CXXMethodDecl *KeyFunction = Layout.getKeyFunction();
+  
+  // Ignore classes without a vtable.
+  if (!RD->isDynamicClass())
+    return;
+
+  const CXXMethodDecl *KeyFunction = Context.getKeyFunction(RD);
 
   if (!KeyFunction) {
     // This record does not have a key function, so we assume that the vtable





More information about the cfe-commits mailing list