zcov: / lib/CodeGen/CGVtable.cpp


Files: 1 Branches Taken: 75.3% 324 / 430
Generated: 2010-02-10 01:31 Branches Executed: 91.6% 394 / 430
Line Coverage: 91.5% 626 / 684


Programs: 1 Runs 2897


       1                 : //===--- CGVtable.cpp - Emit LLVM Code for C++ vtables --------------------===//
       2                 : //
       3                 : //                     The LLVM Compiler Infrastructure
       4                 : //
       5                 : // This file is distributed under the University of Illinois Open Source
       6                 : // License. See LICENSE.TXT for details.
       7                 : //
       8                 : //===----------------------------------------------------------------------===//
       9                 : //
      10                 : // This contains code dealing with C++ code generation of virtual tables.
      11                 : //
      12                 : //===----------------------------------------------------------------------===//
      13                 : 
      14                 : #include "CodeGenModule.h"
      15                 : #include "CodeGenFunction.h"
      16                 : #include "clang/AST/CXXInheritance.h"
      17                 : #include "clang/AST/RecordLayout.h"
      18                 : #include "llvm/ADT/DenseSet.h"
      19                 : #include <cstdio>
      20                 : 
      21                 : using namespace clang;
      22                 : using namespace CodeGen;
      23                 : 
      24                 : namespace {
      25              652: class VtableBuilder {
      26                 : public:
      27                 :   /// Index_t - Vtable index type.
      28                 :   typedef uint64_t Index_t;
      29                 :   typedef std::vector<std::pair<GlobalDecl,
      30                 :                                 std::pair<GlobalDecl, ThunkAdjustment> > >
      31                 :       SavedAdjustmentsVectorTy;
      32                 : private:
      33                 :   
      34                 :   // VtableComponents - The components of the vtable being built.
      35                 :   typedef llvm::SmallVector<llvm::Constant *, 64> VtableComponentsVectorTy;
      36                 :   VtableComponentsVectorTy VtableComponents;
      37                 :   
      38                 :   const bool BuildVtable;
      39                 : 
      40                 :   llvm::Type *Ptr8Ty;
      41                 :   
      42                 :   /// MostDerivedClass - The most derived class that this vtable is being 
      43                 :   /// built for.
      44                 :   const CXXRecordDecl *MostDerivedClass;
      45                 :   
      46                 :   /// LayoutClass - The most derived class used for virtual base layout
      47                 :   /// information.
      48                 :   const CXXRecordDecl *LayoutClass;
      49                 :   /// LayoutOffset - The offset for Class in LayoutClass.
      50                 :   uint64_t LayoutOffset;
      51                 :   /// BLayout - Layout for the most derived class that this vtable is being
      52                 :   /// built for.
      53                 :   const ASTRecordLayout &BLayout;
      54                 :   llvm::SmallSet<const CXXRecordDecl *, 32> IndirectPrimary;
      55                 :   llvm::SmallSet<const CXXRecordDecl *, 32> SeenVBase;
      56                 :   llvm::Constant *rtti;
      57                 :   llvm::LLVMContext &VMContext;
      58                 :   CodeGenModule &CGM;  // Per-module state.
      59                 :   
      60                 :   llvm::DenseMap<const CXXMethodDecl *, Index_t> VCall;
      61                 :   llvm::DenseMap<GlobalDecl, Index_t> VCallOffset;
      62                 :   llvm::DenseMap<GlobalDecl, Index_t> VCallOffsetForVCall;
      63                 :   // This is the offset to the nearest virtual base
      64                 :   llvm::DenseMap<const CXXMethodDecl *, Index_t> NonVirtualOffset;
      65                 :   llvm::DenseMap<const CXXRecordDecl *, Index_t> VBIndex;
      66                 : 
      67                 :   /// PureVirtualFunction - Points to __cxa_pure_virtual.
      68                 :   llvm::Constant *PureVirtualFn;
      69                 :   
      70                 :   /// VtableMethods - A data structure for keeping track of methods in a vtable.
      71                 :   /// Can add methods, override methods and iterate in vtable order.
      72             1304:   class VtableMethods {
      73                 :     // MethodToIndexMap - Maps from a global decl to the index it has in the
      74                 :     // Methods vector.
      75                 :     llvm::DenseMap<GlobalDecl, uint64_t> MethodToIndexMap;
      76                 : 
      77                 :     /// Methods - The methods, in vtable order.
      78                 :     typedef llvm::SmallVector<GlobalDecl, 16> MethodsVectorTy;
      79                 :     MethodsVectorTy Methods;
      80                 :     MethodsVectorTy OrigMethods;
      81                 : 
      82                 :   public:
      83                 :     /// AddMethod - Add a method to the vtable methods.
      84             2270:     void AddMethod(GlobalDecl GD) {
      85                 :       assert(!MethodToIndexMap.count(GD) && 
                     2270: branch 1 taken
                        0: branch 2 not taken
      86             2270:              "Method has already been added!");
      87                 :       
      88             2270:       MethodToIndexMap[GD] = Methods.size();
      89             2270:       Methods.push_back(GD);
      90             2270:       OrigMethods.push_back(GD);
      91             2270:     }
      92                 :     
      93                 :     /// OverrideMethod - Replace a method with another.
      94              596:     void OverrideMethod(GlobalDecl OverriddenGD, GlobalDecl GD) {
      95                 :       llvm::DenseMap<GlobalDecl, uint64_t>::iterator i 
      96              596:         = MethodToIndexMap.find(OverriddenGD);
                      596: branch 3 taken
                        0: branch 4 not taken
      97              596:       assert(i != MethodToIndexMap.end() && "Did not find entry!");
      98                 : 
      99                 :       // Get the index of the old decl.
     100              596:       uint64_t Index = i->second;
     101                 :       
     102                 :       // Replace the old decl with the new decl.
     103              596:       Methods[Index] = GD;
     104                 : 
     105                 :       // And add the new.
     106              596:       MethodToIndexMap[GD] = Index;
     107              596:     }
     108                 : 
     109                 :     /// getIndex - Gives the index of a passed in GlobalDecl. Returns false if
     110                 :     /// the index couldn't be found.
     111              856:     bool getIndex(GlobalDecl GD, uint64_t &Index) const {
     112                 :       llvm::DenseMap<GlobalDecl, uint64_t>::const_iterator i 
     113              856:         = MethodToIndexMap.find(GD);
     114                 : 
                      260: branch 2 taken
                      596: branch 3 taken
     115              856:       if (i == MethodToIndexMap.end())
     116              260:         return false;
     117                 :       
     118              596:       Index = i->second;
     119              596:       return true;
     120                 :     }
     121                 : 
     122              596:     GlobalDecl getOrigMethod(uint64_t Index) const {
     123              596:       return OrigMethods[Index];
     124                 :     }
     125                 : 
     126             1682:     MethodsVectorTy::size_type size() const {
     127             1682:       return Methods.size();
     128                 :     }
     129                 : 
     130             1125:     void clear() {
     131             1125:       MethodToIndexMap.clear();
     132             1125:       Methods.clear();
     133             1125:       OrigMethods.clear();
     134             1125:     }
     135                 :     
     136             1070:     GlobalDecl operator[](uint64_t Index) const {
     137             1070:       return Methods[Index];
     138                 :     }
     139                 :   };
     140                 :   
     141                 :   /// Methods - The vtable methods we're currently building.
     142                 :   VtableMethods Methods;
     143                 :   
     144                 :   /// ThisAdjustments - For a given index in the vtable, contains the 'this'
     145                 :   /// pointer adjustment needed for a method.
     146                 :   typedef llvm::DenseMap<uint64_t, ThunkAdjustment> ThisAdjustmentsMapTy;
     147                 :   ThisAdjustmentsMapTy ThisAdjustments;
     148                 : 
     149                 :   SavedAdjustmentsVectorTy SavedAdjustments;
     150                 : 
     151                 :   /// BaseReturnTypes - Contains the base return types of methods who have been
     152                 :   /// overridden with methods whose return types require adjustment. Used for
     153                 :   /// generating covariant thunk information.
     154                 :   typedef llvm::DenseMap<uint64_t, CanQualType> BaseReturnTypesMapTy;
     155                 :   BaseReturnTypesMapTy BaseReturnTypes;
     156                 :   
     157                 :   std::vector<Index_t> VCalls;
     158                 : 
     159                 :   typedef std::pair<const CXXRecordDecl *, uint64_t> CtorVtable_t;
     160                 :   // subAddressPoints - Used to hold the AddressPoints (offsets) into the built
     161                 :   // vtable for use in computing the initializers for the VTT.
     162                 :   llvm::DenseMap<CtorVtable_t, int64_t> &subAddressPoints;
     163                 : 
     164                 :   /// AddressPoints - Address points for this vtable.
     165                 :   CGVtableInfo::AddressPointsMapTy& AddressPoints;
     166                 :   
     167                 :   typedef CXXRecordDecl::method_iterator method_iter;
     168                 :   const uint32_t LLVMPointerWidth;
     169                 :   Index_t extra;
     170                 :   typedef std::vector<std::pair<const CXXRecordDecl *, int64_t> > Path_t;
     171                 :   static llvm::DenseMap<CtorVtable_t, int64_t>&
     172                 :   AllocAddressPoint(CodeGenModule &cgm, const CXXRecordDecl *l,
     173              652:                     const CXXRecordDecl *c) {
     174              652:     CGVtableInfo::AddrMap_t *&oref = cgm.getVtableInfo().AddressPoints[l];
                      298: branch 0 taken
                      354: branch 1 taken
     175              652:     if (oref == 0)
     176              298:       oref = new CGVtableInfo::AddrMap_t;
     177                 : 
     178              652:     llvm::DenseMap<CtorVtable_t, int64_t> *&ref = (*oref)[c];
                      409: branch 0 taken
                      243: branch 1 taken
     179              652:     if (ref == 0)
     180              409:       ref = new llvm::DenseMap<CtorVtable_t, int64_t>;
     181              652:     return *ref;
     182                 :   }
     183                 :   
     184                0:   bool DclIsSame(const FunctionDecl *New, const FunctionDecl *Old) {
     185                0:     FunctionTemplateDecl *OldTemplate = Old->getDescribedFunctionTemplate();
     186                0:     FunctionTemplateDecl *NewTemplate = New->getDescribedFunctionTemplate();
     187                 : 
     188                 :     // C++ [temp.fct]p2:
     189                 :     //   A function template can be overloaded with other function templates
     190                 :     //   and with normal (non-template) functions.
                        0: branch 0 not taken
                        0: branch 1 not taken
     191                0:     if ((OldTemplate == 0) != (NewTemplate == 0))
     192                0:       return false;
     193                 : 
     194                 :     // Is the function New an overload of the function Old?
     195                0:     QualType OldQType = CGM.getContext().getCanonicalType(Old->getType());
     196                0:     QualType NewQType = CGM.getContext().getCanonicalType(New->getType());
     197                 : 
     198                 :     // Compare the signatures (C++ 1.3.10) of the two functions to
     199                 :     // determine whether they are overloads. If we find any mismatch
     200                 :     // in the signature, they are overloads.
     201                 : 
     202                 :     // If either of these functions is a K&R-style function (no
     203                 :     // prototype), then we consider them to have matching signatures.
                        0: branch 2 not taken
                        0: branch 3 not taken
                        0: branch 6 not taken
                        0: branch 7 not taken
                        0: branch 8 not taken
                        0: branch 9 not taken
     204                0:     if (isa<FunctionNoProtoType>(OldQType.getTypePtr()) ||
     205                 :         isa<FunctionNoProtoType>(NewQType.getTypePtr()))
     206                0:       return true;
     207                 : 
     208                0:     FunctionProtoType* OldType = cast<FunctionProtoType>(OldQType);
     209                0:     FunctionProtoType* NewType = cast<FunctionProtoType>(NewQType);
     210                 : 
     211                 :     // The signature of a function includes the types of its
     212                 :     // parameters (C++ 1.3.10), which includes the presence or absence
     213                 :     // of the ellipsis; see C++ DR 357).
                        0: branch 1 not taken
                        0: branch 2 not taken
                        0: branch 5 not taken
                        0: branch 6 not taken
                        0: branch 9 not taken
                        0: branch 10 not taken
                        0: branch 15 not taken
                        0: branch 16 not taken
                        0: branch 17 not taken
                        0: branch 18 not taken
     214                0:     if (OldQType != NewQType &&
     215                 :         (OldType->getNumArgs() != NewType->getNumArgs() ||
     216                 :          OldType->isVariadic() != NewType->isVariadic() ||
     217                 :          !std::equal(OldType->arg_type_begin(), OldType->arg_type_end(),
     218                 :                      NewType->arg_type_begin())))
     219                0:       return false;
     220                 : 
     221                 : #if 0
     222                 :     // C++ [temp.over.link]p4:
     223                 :     //   The signature of a function template consists of its function
     224                 :     //   signature, its return type and its template parameter list. The names
     225                 :     //   of the template parameters are significant only for establishing the
     226                 :     //   relationship between the template parameters and the rest of the
     227                 :     //   signature.
     228                 :     //
     229                 :     // We check the return type and template parameter lists for function
     230                 :     // templates first; the remaining checks follow.
     231                 :     if (NewTemplate &&
     232                 :         (!TemplateParameterListsAreEqual(NewTemplate->getTemplateParameters(),
     233                 :                                          OldTemplate->getTemplateParameters(),
     234                 :                                          TPL_TemplateMatch) ||
     235                 :          OldType->getResultType() != NewType->getResultType()))
     236                 :       return false;
     237                 : #endif
     238                 : 
     239                 :     // If the function is a class member, its signature includes the
     240                 :     // cv-qualifiers (if any) on the function itself.
     241                 :     //
     242                 :     // As part of this, also check whether one of the member functions
     243                 :     // is static, in which case they are not overloads (C++
     244                 :     // 13.1p2). While not part of the definition of the signature,
     245                 :     // this check is important to determine whether these functions
     246                 :     // can be overloaded.
     247                0:     const CXXMethodDecl* OldMethod = dyn_cast<CXXMethodDecl>(Old);
     248                0:     const CXXMethodDecl* NewMethod = dyn_cast<CXXMethodDecl>(New);
                        0: branch 0 not taken
                        0: branch 1 not taken
                        0: branch 2 not taken
                        0: branch 3 not taken
                        0: branch 5 not taken
                        0: branch 6 not taken
                        0: branch 8 not taken
                        0: branch 9 not taken
                        0: branch 12 not taken
                        0: branch 13 not taken
                        0: branch 14 not taken
                        0: branch 15 not taken
     249                0:     if (OldMethod && NewMethod &&
     250                 :         !OldMethod->isStatic() && !NewMethod->isStatic() &&
     251                 :         OldMethod->getTypeQualifiers() != NewMethod->getTypeQualifiers())
     252                0:       return false;
     253                 :   
     254                 :     // The signatures match; this is not an overload.
     255                0:     return true;
     256                 :   }
     257                 : 
     258                 :   typedef llvm::DenseMap<const CXXMethodDecl *, const CXXMethodDecl*>
     259                 :     ForwardUnique_t;
     260                 :   ForwardUnique_t ForwardUnique;
     261                 :   llvm::DenseMap<const CXXMethodDecl*, const CXXMethodDecl*> UniqueOverrider;
     262                 : 
     263             2435:   void BuildUniqueOverrider(const CXXMethodDecl *U, const CXXMethodDecl *MD) {
     264             2435:     const CXXMethodDecl *PrevU = UniqueOverrider[MD];
                        0: branch 0 not taken
                     2435: branch 1 taken
     265             2435:     assert(U && "no unique overrider");
                        0: branch 0 not taken
                     2435: branch 1 taken
     266             2435:     if (PrevU == U)
     267                0:       return;
                     2435: branch 0 taken
                        0: branch 1 not taken
                        0: branch 2 not taken
                     2435: branch 3 taken
     268             2435:     if (PrevU != U && PrevU != 0) {
     269                 :       // If already set, note the two sets as the same
     270                 :       if (0)
     271                 :         printf("%s::%s same as %s::%s\n",
     272                 :                PrevU->getParent()->getNameAsCString(),
     273                 :                PrevU->getNameAsCString(),
     274                 :                U->getParent()->getNameAsCString(),
     275                 :                U->getNameAsCString());
     276                0:       ForwardUnique[PrevU] = U;
     277                0:       return;
     278                 :     }
     279                 : 
     280                 :     // Not set, set it now
     281                 :     if (0)
     282                 :       printf("marking %s::%s %p override as %s::%s\n",
     283                 :              MD->getParent()->getNameAsCString(),
     284                 :              MD->getNameAsCString(),
     285                 :              (void*)MD,
     286                 :              U->getParent()->getNameAsCString(),
     287                 :              U->getNameAsCString());
     288             2435:     UniqueOverrider[MD] = U;
     289                 : 
                      505: branch 1 taken
                     2435: branch 2 taken
     290             5375:     for (CXXMethodDecl::method_iterator mi = MD->begin_overridden_methods(),
     291             2435:            me = MD->end_overridden_methods(); mi != me; ++mi) {
     292              505:       BuildUniqueOverrider(U, *mi);
     293                 :     }
     294                 :   }
     295                 : 
     296             1931:   void BuildUniqueOverriders(const CXXRecordDecl *RD) {
     297                 :     if (0) printf("walking %s\n", RD->getNameAsCString());
                    10244: branch 3 taken
                     1931: branch 4 taken
     298            14106:     for (CXXRecordDecl::method_iterator i = RD->method_begin(),
     299             1931:            e = RD->method_end(); i != e; ++i) {
     300            10244:       const CXXMethodDecl *MD = *i;
                     7710: branch 1 taken
                     2534: branch 2 taken
     301            10244:       if (!MD->isVirtual())
     302             7710:         continue;
     303                 : 
                     1930: branch 1 taken
                      604: branch 2 taken
     304             2534:       if (UniqueOverrider[MD] == 0) {
     305                 :         // Only set this, if it hasn't been set yet.
     306             1930:         BuildUniqueOverrider(MD, MD);
     307                 :         if (0)
     308                 :           printf("top set is %s::%s %p\n",
     309                 :                   MD->getParent()->getNameAsCString(),
     310                 :                   MD->getNameAsCString(),
     311                 :                   (void*)MD);
     312             1930:         ForwardUnique[MD] = MD;
     313                 :       }
     314                 :     }
                     1279: branch 1 taken
                     1931: branch 2 taken
     315             5141:     for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
     316             1931:            e = RD->bases_end(); i != e; ++i) {
     317                 :       const CXXRecordDecl *Base =
     318             1279:         cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
     319             1279:       BuildUniqueOverriders(Base);
     320                 :     }
     321             1931:   }
     322                 : 
     323             3811:   static int DclCmp(const void *p1, const void *p2) {
     324             3811:     const CXXMethodDecl *MD1 = (const CXXMethodDecl *)p1;
     325             3811:     const CXXMethodDecl *MD2 = (const CXXMethodDecl *)p2;
     326             3811:     return (MD1->getIdentifier() - MD2->getIdentifier());
     327                 :   }
     328                 :   
     329              652:   void MergeForwarding() {
     330                 :     typedef llvm::SmallVector<const CXXMethodDecl *, 100>  A_t;
     331              652:     A_t A;
                     1930: branch 4 taken
                      652: branch 5 taken
     332             3234:     for (ForwardUnique_t::iterator I = ForwardUnique.begin(),
     333              652:            E = ForwardUnique.end(); I != E; ++I) {
                     1930: branch 2 taken
                        0: branch 3 not taken
     334             1930:       if (I->first == I->second)
     335                 :         // Only add the roots of all trees
     336             1930:         A.push_back(I->first);
     337                 :     }
     338              652:     llvm::array_pod_sort(A.begin(), A.end(), DclCmp);
                     1930: branch 1 taken
                      652: branch 2 taken
     339             3234:     for (A_t::iterator I = A.begin(),
     340              652:            E = A.end(); I != E; ++I) {
     341             1930:       A_t::iterator J = I;
                     1316: branch 0 taken
                      614: branch 1 taken
                        0: branch 3 not taken
                     1316: branch 4 taken
                        0: branch 5 not taken
                     1930: branch 6 taken
     342             3860:       while (++J != E  && DclCmp(*I, *J) == 0)
                        0: branch 1 not taken
                        0: branch 2 not taken
     343                0:         if (DclIsSame(*I, *J)) {
     344                0:           printf("connecting %s\n", (*I)->getNameAsCString());
     345                0:           ForwardUnique[*J] = *I;
     346                 :         }
     347              652:     }
     348              652:   }
     349                 : 
     350             2306:   const CXXMethodDecl *getUnique(const CXXMethodDecl *MD) {
     351             2306:     const CXXMethodDecl *U = UniqueOverrider[MD];
                        0: branch 0 not taken
                     2306: branch 1 taken
     352             2306:     assert(U && "unique overrider not found");
                     2306: branch 1 taken
                        0: branch 2 not taken
     353             4612:     while (ForwardUnique.count(U)) {
     354             2306:       const CXXMethodDecl *NU = ForwardUnique[U];
                        0: branch 0 not taken
                     2306: branch 1 taken
     355             2306:       if (NU == U) break;
     356                0:       U = NU;
     357                 :     }
     358             2306:     return U;
     359                 :   }
     360                 : 
     361             2306:   GlobalDecl getUnique(GlobalDecl GD) {
     362             2306:     const CXXMethodDecl *Unique = getUnique(cast<CXXMethodDecl>(GD.getDecl()));
     363                 :     
                        0: branch 1 not taken
                     2306: branch 2 taken
     364             2306:     if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(Unique))
     365                0:       return GlobalDecl(CD, GD.getCtorType());
     366                 :     
                       92: branch 1 taken
                     2214: branch 2 taken
     367             2306:     if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(Unique))
     368               92:       return GlobalDecl(DD, GD.getDtorType());
     369                 :     
     370             2214:     return Unique;
     371                 :   }
     372                 : 
     373                 :   /// getPureVirtualFn - Return the __cxa_pure_virtual function.
     374                4:   llvm::Constant* getPureVirtualFn() {
                        4: branch 0 taken
                        0: branch 1 not taken
     375                4:     if (!PureVirtualFn) {
     376                 :       const llvm::FunctionType *Ty = 
     377                 :         llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), 
     378                4:                                 /*isVarArg=*/false);
     379                4:       PureVirtualFn = wrap(CGM.CreateRuntimeFunction(Ty, "__cxa_pure_virtual"));
     380                 :     }
     381                 :     
     382                4:     return PureVirtualFn;
     383                 :   }
     384                 :   
     385                 : public:
     386                 :   VtableBuilder(const CXXRecordDecl *MostDerivedClass,
     387                 :                 const CXXRecordDecl *l, uint64_t lo, CodeGenModule &cgm,
     388              652:                 bool build, CGVtableInfo::AddressPointsMapTy& AddressPoints)
     389                 :     : BuildVtable(build), MostDerivedClass(MostDerivedClass), LayoutClass(l),
     390                 :       LayoutOffset(lo), BLayout(cgm.getContext().getASTRecordLayout(l)),
     391                 :       rtti(0), VMContext(cgm.getModule().getContext()),CGM(cgm),
     392                 :       PureVirtualFn(0),
     393                 :       subAddressPoints(AllocAddressPoint(cgm, l, MostDerivedClass)),
     394                 :       AddressPoints(AddressPoints),
     395              652:       LLVMPointerWidth(cgm.getContext().Target.getPointerWidth(0))
     396                 :       {
     397              652:     Ptr8Ty = llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext), 0);
                      322: branch 0 taken
                      330: branch 1 taken
     398              652:     if (BuildVtable) {
     399              322:       QualType ClassType = CGM.getContext().getTagDeclType(MostDerivedClass);
     400              322:       rtti = CGM.GetAddrOfRTTIDescriptor(ClassType);
     401                 :     }
     402              652:     BuildUniqueOverriders(MostDerivedClass);
     403              652:     MergeForwarding();
     404              652:   }
     405                 : 
     406                 :   // getVtableComponents - Returns a reference to the vtable components.
     407             1054:   const VtableComponentsVectorTy &getVtableComponents() const {
     408             1054:     return VtableComponents;
     409                 :   }
     410                 :   
     411              166:   llvm::DenseMap<const CXXRecordDecl *, uint64_t> &getVBIndex()
     412              166:     { return VBIndex; }
     413                 : 
     414              318:   SavedAdjustmentsVectorTy &getSavedAdjustments()
     415              318:     { return SavedAdjustments; }
     416                 : 
     417             1571:   llvm::Constant *wrap(Index_t i) {
     418                 :     llvm::Constant *m;
     419             1571:     m = llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), i);
     420             1571:     return llvm::ConstantExpr::getIntToPtr(m, Ptr8Ty);
     421                 :   }
     422                 : 
     423             1070:   llvm::Constant *wrap(llvm::Constant *m) {
     424             1070:     return llvm::ConstantExpr::getBitCast(m, Ptr8Ty);
     425                 :   }
     426                 : 
     427                 : //#define D1(x)
     428                 : #define D1(X) do { if (getenv("DEBUG")) { X; } } while (0)
     429                 : 
     430                 :   void GenerateVBaseOffsets(const CXXRecordDecl *RD, uint64_t Offset,
     431             3683:                             bool updateVBIndex, Index_t current_vbindex) {
                     2075: branch 1 taken
                     3683: branch 2 taken
     432             9441:     for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
     433             3683:            e = RD->bases_end(); i != e; ++i) {
     434                 :       const CXXRecordDecl *Base =
     435             2075:         cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
     436             2075:       Index_t next_vbindex = current_vbindex;
                     1373: branch 1 taken
                      702: branch 2 taken
                     1031: branch 4 taken
                      342: branch 5 taken
                     1031: branch 6 taken
                     1044: branch 7 taken
     437             2075:       if (i->isVirtual() && !SeenVBase.count(Base)) {
     438             1031:         SeenVBase.insert(Base);
                      808: branch 0 taken
                      223: branch 1 taken
     439             1031:         if (updateVBIndex) {
     440                 :           next_vbindex = (ssize_t)(-(VCalls.size()*LLVMPointerWidth/8)
     441              808:                                    - 3*LLVMPointerWidth/8);
     442              808:           VBIndex[Base] = next_vbindex;
     443                 :         }
     444             1031:         int64_t BaseOffset = -(Offset/8) + BLayout.getVBaseClassOffset(Base)/8;
     445             1031:         VCalls.push_back((0?700:0) + BaseOffset);
                        0: branch 1 not taken
                     1031: branch 2 taken
     446             1031:         D1(printf("  vbase for %s at %d delta %d most derived %s\n",
     447                 :                   Base->getNameAsCString(),
     448                 :                   (int)-VCalls.size()-3, (int)BaseOffset,
     449                 :                   MostDerivedClass->getNameAsCString()));
     450                 :       }
     451                 :       // We also record offsets for non-virtual bases to closest enclosing
     452                 :       // virtual base.  We do this so that we don't have to search
     453                 :       // for the nearst virtual base class when generating thunks.
                     1661: branch 0 taken
                      414: branch 1 taken
                      400: branch 3 taken
                     1261: branch 4 taken
                      400: branch 5 taken
                     1675: branch 6 taken
     454             2075:       if (updateVBIndex && VBIndex.count(Base) == 0)
     455              400:         VBIndex[Base] = next_vbindex;
     456             2075:       GenerateVBaseOffsets(Base, Offset, updateVBIndex, next_vbindex);
     457                 :     }
     458             3683:   }
     459                 : 
     460             2368:   void StartNewTable() {
     461             2368:     SeenVBase.clear();
     462             2368:   }
     463                 : 
     464                 :   Index_t getNVOffset_1(const CXXRecordDecl *D, const CXXRecordDecl *B,
     465             1900:     Index_t Offset = 0) {
     466                 : 
                      654: branch 0 taken
                     1246: branch 1 taken
     467             1900:     if (B == D)
     468              654:       return Offset;
     469                 : 
     470             1246:     const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(D);
                     1246: branch 1 taken
                      388: branch 2 taken
     471             2880:     for (CXXRecordDecl::base_class_const_iterator i = D->bases_begin(),
     472             1246:            e = D->bases_end(); i != e; ++i) {
     473                 :       const CXXRecordDecl *Base =
     474             1246:         cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
     475             1246:       int64_t BaseOffset = 0;
                      803: branch 1 taken
                      443: branch 2 taken
     476             1246:       if (!i->isVirtual())
     477              803:         BaseOffset = Offset + Layout.getBaseClassOffset(Base);
     478             1246:       int64_t o = getNVOffset_1(Base, B, BaseOffset);
                      858: branch 0 taken
                      388: branch 1 taken
     479             1246:       if (o >= 0)
     480              858:         return o;
     481                 :     }
     482                 : 
     483              388:     return -1;
     484                 :   }
     485                 : 
     486                 :   /// getNVOffset - Returns the non-virtual offset for the given (B) base of the
     487                 :   /// derived class D.
     488              654:   Index_t getNVOffset(QualType qB, QualType qD) {
     489              654:     qD = qD->getPointeeType();
     490              654:     qB = qB->getPointeeType();
     491              654:     CXXRecordDecl *D = cast<CXXRecordDecl>(qD->getAs<RecordType>()->getDecl());
     492              654:     CXXRecordDecl *B = cast<CXXRecordDecl>(qB->getAs<RecordType>()->getDecl());
     493              654:     int64_t o = getNVOffset_1(D, B);
                      654: branch 0 taken
                        0: branch 1 not taken
     494              654:     if (o >= 0)
     495              654:       return o;
     496                 : 
     497                0:     assert(false && "FIXME: non-virtual base not found");
     498                 :     return 0;
     499                 :   }
     500                 : 
     501                 :   /// getVbaseOffset - Returns the index into the vtable for the virtual base
     502                 :   /// offset for the given (B) virtual base of the derived class D.
     503               58:   Index_t getVbaseOffset(QualType qB, QualType qD) {
     504               58:     qD = qD->getPointeeType();
     505               58:     qB = qB->getPointeeType();
     506               58:     CXXRecordDecl *D = cast<CXXRecordDecl>(qD->getAs<RecordType>()->getDecl());
     507               58:     CXXRecordDecl *B = cast<CXXRecordDecl>(qB->getAs<RecordType>()->getDecl());
                        6: branch 0 taken
                       52: branch 1 taken
     508               58:     if (D != MostDerivedClass)
     509                6:       return CGM.getVtableInfo().getVirtualBaseOffsetIndex(D, B);
     510               52:     llvm::DenseMap<const CXXRecordDecl *, Index_t>::iterator i;
     511               52:     i = VBIndex.find(B);
                       52: branch 3 taken
                        0: branch 4 not taken
     512               52:     if (i != VBIndex.end())
     513               52:       return i->second;
     514                 : 
     515                0:     assert(false && "FIXME: Base not found");
     516                 :     return 0;
     517                 :   }
     518                 : 
     519                 :   bool OverrideMethod(GlobalDecl GD, bool MorallyVirtual,
     520                 :                       Index_t OverrideOffset, Index_t Offset,
     521                 :                       int64_t CurrentVBaseOffset);
     522                 : 
     523                 :   /// AppendMethods - Append the current methods to the vtable.
     524                 :   void AppendMethodsToVtable();
     525                 :   
     526              983:   llvm::Constant *WrapAddrOf(GlobalDecl GD) {
     527              983:     const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
     528                 : 
     529              983:     const llvm::Type *Ty = CGM.getTypes().GetFunctionTypeForVtable(MD);
     530                 : 
     531              983:     return wrap(CGM.GetAddrOfFunction(GD, Ty));
     532                 :   }
     533                 : 
     534                 :   void OverrideMethods(Path_t *Path, bool MorallyVirtual, int64_t Offset,
     535              473:                        int64_t CurrentVBaseOffset) {
                      734: branch 3 taken
                      473: branch 4 taken
     536             1680:     for (Path_t::reverse_iterator i = Path->rbegin(),
     537              473:            e = Path->rend(); i != e; ++i) {
     538              734:       const CXXRecordDecl *RD = i->first;
     539              734:       int64_t OverrideOffset = i->second;
                     3925: branch 4 taken
                      734: branch 5 taken
     540             4659:       for (method_iter mi = RD->method_begin(), me = RD->method_end(); mi != me;
     541                 :            ++mi) {
     542             3925:         const CXXMethodDecl *MD = *mi;
     543                 : 
                     2942: branch 1 taken
                      983: branch 2 taken
     544             3925:         if (!MD->isVirtual())
     545             2942:           continue;
     546                 : 
                        0: branch 1 not taken
                      983: branch 2 taken
     547              983:         if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {
     548                 :           // Override both the complete and the deleting destructor.
     549                0:           GlobalDecl CompDtor(DD, Dtor_Complete);
     550                 :           OverrideMethod(CompDtor, MorallyVirtual, OverrideOffset, Offset,
     551                0:                          CurrentVBaseOffset);
     552                 : 
     553                0:           GlobalDecl DeletingDtor(DD, Dtor_Deleting);
     554                 :           OverrideMethod(DeletingDtor, MorallyVirtual, OverrideOffset, Offset,
     555                0:                          CurrentVBaseOffset);
     556                 :         } else {
     557                 :           OverrideMethod(MD, MorallyVirtual, OverrideOffset, Offset,
     558              983:                          CurrentVBaseOffset);
     559                 :         }
     560                 :       }
     561                 :     }
     562              473:   }
     563                 : 
     564                 :   void AddMethod(const GlobalDecl GD, bool MorallyVirtual, Index_t Offset,
     565             2601:                  int64_t CurrentVBaseOffset) {
     566                 :     // If we can find a previously allocated slot for this, reuse it.
                      331: branch 1 taken
                     2270: branch 2 taken
     567             2601:     if (OverrideMethod(GD, MorallyVirtual, Offset, Offset,
     568                 :                        CurrentVBaseOffset))
     569              331:       return;
     570                 : 
                        0: branch 1 not taken
                     2270: branch 2 taken
     571             2270:     D1(printf("  vfn for %s at %d\n",
     572                 :               dyn_cast<CXXMethodDecl>(GD.getDecl())->getNameAsCString(),
     573                 :               (int)Methods.size()));
     574                 : 
     575                 :     // We didn't find an entry in the vtable that we could use, add a new
     576                 :     // entry.
     577             2270:     Methods.AddMethod(GD);
     578                 : 
     579             2270:     VCallOffset[GD] = Offset/8 - CurrentVBaseOffset/8;
     580                 : 
                     1114: branch 0 taken
                     1156: branch 1 taken
     581             2270:     if (MorallyVirtual) {
     582             1114:       GlobalDecl UGD = getUnique(GD);
     583             1114:       const CXXMethodDecl *UMD = cast<CXXMethodDecl>(UGD.getDecl());
     584                 :   
                        0: branch 0 not taken
                     1114: branch 1 taken
     585             1114:       assert(UMD && "final overrider not found");
     586                 : 
     587             1114:       Index_t &idx = VCall[UMD];
     588                 :       // Allocate the first one, after that, we reuse the previous one.
                     1085: branch 0 taken
                       29: branch 1 taken
     589             1114:       if (idx == 0) {
     590             1085:         VCallOffsetForVCall[UGD] = Offset/8;
     591             1085:         NonVirtualOffset[UMD] = Offset/8 - CurrentVBaseOffset/8;
     592             1085:         idx = VCalls.size()+1;
     593             1085:         VCalls.push_back(Offset/8 - CurrentVBaseOffset/8);
                        0: branch 1 not taken
                     1085: branch 2 taken
     594             1085:         D1(printf("  vcall for %s at %d with delta %d\n",
     595                 :                   dyn_cast<CXXMethodDecl>(GD.getDecl())->getNameAsCString(),
     596                 :                   (int)-VCalls.size()-3, (int)VCalls[idx-1]));
     597                 :       }
     598                 :     }
     599                 :   }
     600                 : 
     601                 :   void AddMethods(const CXXRecordDecl *RD, bool MorallyVirtual,
     602             1608:                   Index_t Offset, int64_t CurrentVBaseOffset) {
                     8945: branch 4 taken
                     1608: branch 5 taken
     603            10553:     for (method_iter mi = RD->method_begin(), me = RD->method_end(); mi != me;
     604                 :          ++mi) {
     605             8945:       const CXXMethodDecl *MD = *mi;
                     6418: branch 1 taken
                     2527: branch 2 taken
     606             8945:       if (!MD->isVirtual())
     607             6418:         continue;
     608                 :       
                       74: branch 1 taken
                     2453: branch 2 taken
     609             2527:       if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {
     610                 :         // For destructors, add both the complete and the deleting destructor
     611                 :         // to the vtable.
     612                 :         AddMethod(GlobalDecl(DD, Dtor_Complete), MorallyVirtual, Offset, 
     613               74:                   CurrentVBaseOffset);
     614                 :         AddMethod(GlobalDecl(DD, Dtor_Deleting), MorallyVirtual, Offset, 
     615               74:                   CurrentVBaseOffset);
     616                 :       } else
     617             2453:         AddMethod(MD, MorallyVirtual, Offset, CurrentVBaseOffset);
     618                 :     }
     619             1608:   }
     620                 : 
     621                 :   void NonVirtualBases(const CXXRecordDecl *RD, const ASTRecordLayout &Layout,
     622                 :                        const CXXRecordDecl *PrimaryBase,
     623                 :                        bool PrimaryBaseWasVirtual, bool MorallyVirtual,
     624                 :                        int64_t Offset, int64_t CurrentVBaseOffset,
     625             1370:                        Path_t *Path) {
     626             1370:     Path->push_back(std::make_pair(RD, Offset));
                     1127: branch 1 taken
                     1370: branch 2 taken
     627             3867:     for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
     628             1370:            e = RD->bases_end(); i != e; ++i) {
                      708: branch 1 taken
                      419: branch 2 taken
     629             1127:       if (i->isVirtual())
     630              708:         continue;
     631                 :       const CXXRecordDecl *Base =
     632              419:         cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
     633              419:       uint64_t o = Offset + Layout.getBaseClassOffset(Base);
     634              419:       StartNewTable();
     635                 :       GenerateVtableForBase(Base, o, MorallyVirtual, false,
     636                 :                             true, Base == PrimaryBase && !PrimaryBaseWasVirtual,
                      253: branch 0 taken
                      166: branch 1 taken
                      253: branch 2 taken
                        0: branch 3 not taken
     637              419:                             CurrentVBaseOffset, Path);
     638                 :     }
     639             1370:     Path->pop_back();
     640             1370:   }
     641                 : 
     642                 : // #define D(X) do { X; } while (0)
     643                 : #define D(X)
     644                 : 
     645             1090:   void insertVCalls(int InsertionPoint) {
                        0: branch 1 not taken
                     1090: branch 2 taken
     646             1090:     D1(printf("============= combining vbase/vcall\n"));
     647                 :     D(VCalls.insert(VCalls.begin(), 673));
     648                 :     D(VCalls.push_back(672));
     649                 : 
     650                 :     VtableComponents.insert(VtableComponents.begin() + InsertionPoint, 
     651             1090:                             VCalls.size(), 0);
                      543: branch 0 taken
                      547: branch 1 taken
     652             1090:     if (BuildVtable) {
     653                 :       // The vcalls come first...
                     1014: branch 3 taken
                      543: branch 4 taken
     654             2100:       for (std::vector<Index_t>::reverse_iterator i = VCalls.rbegin(),
     655              543:              e = VCalls.rend();
     656                 :            i != e; ++i)
     657             1014:         VtableComponents[InsertionPoint++] = wrap((0?600:0) + *i);
     658                 :     }
     659             1090:     VCalls.clear();
     660             1090:     VCall.clear();
     661             1090:     VCallOffsetForVCall.clear();
     662             1090:     VCallOffset.clear();
     663             1090:     NonVirtualOffset.clear();
     664             1090:   }
     665                 : 
     666                 :   void AddAddressPoints(const CXXRecordDecl *RD, uint64_t Offset,
     667             1125:                        Index_t AddressPoint) {
                        0: branch 1 not taken
                     1125: branch 2 taken
     668             1125:     D1(printf("XXX address point for %s in %s layout %s at offset %d is %d\n",
     669                 :               RD->getNameAsCString(), MostDerivedClass->getNameAsCString(),
     670                 :               LayoutClass->getNameAsCString(), (int)Offset, (int)AddressPoint));
     671             1125:     subAddressPoints[std::make_pair(RD, Offset)] = AddressPoint;
     672             1125:     AddressPoints[BaseSubobject(RD, Offset)] = AddressPoint;
     673                 : 
     674                 :     // Now also add the address point for all our primary bases.
     675              483:     while (1) {
     676             1608:       const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
     677             1608:       RD = Layout.getPrimaryBase();
     678             1608:       const bool PrimaryBaseWasVirtual = Layout.getPrimaryBaseWasVirtual();
     679                 :       // FIXME: Double check this.
                      483: branch 0 taken
                     1125: branch 1 taken
     680             1608:       if (RD == 0)
     681             1125:         break;
                      204: branch 0 taken
                      279: branch 1 taken
                        0: branch 3 not taken
                      204: branch 4 taken
                        0: branch 5 not taken
                      483: branch 6 taken
     682              483:       if (PrimaryBaseWasVirtual &&
     683                 :           BLayout.getVBaseClassOffset(RD) != Offset)
     684                0:         break;
                        0: branch 1 not taken
                      483: branch 2 taken
     685              483:       D1(printf("XXX address point for %s in %s layout %s at offset %d is %d\n",
     686                 :                 RD->getNameAsCString(), MostDerivedClass->getNameAsCString(),
     687                 :                 LayoutClass->getNameAsCString(), (int)Offset, (int)AddressPoint));
     688              483:       subAddressPoints[std::make_pair(RD, Offset)] = AddressPoint;
     689              483:       AddressPoints[BaseSubobject(RD, Offset)] = AddressPoint;
     690                 :     }
     691             1125:   }
     692                 : 
     693                 : 
     694                 :   void FinishGenerateVtable(const CXXRecordDecl *RD,
     695                 :                             const ASTRecordLayout &Layout,
     696                 :                             const CXXRecordDecl *PrimaryBase,
     697                 :                             bool ForNPNVBases, bool WasPrimaryBase,
     698                 :                             bool PrimaryBaseWasVirtual,
     699                 :                             bool MorallyVirtual, int64_t Offset,
     700                 :                             bool ForVirtualBase, int64_t CurrentVBaseOffset,
     701             1370:                             Path_t *Path) {
     702             1370:     bool alloc = false;
                      652: branch 0 taken
                      718: branch 1 taken
     703             1370:     if (Path == 0) {
     704              652:       alloc = true;
     705              652:       Path = new Path_t;
     706                 :     }
     707                 : 
     708             1370:     StartNewTable();
     709             1370:     extra = 0;
     710             1370:     Index_t AddressPoint = 0;
     711             1370:     int VCallInsertionPoint = 0;
                      329: branch 0 taken
                     1041: branch 1 taken
                       84: branch 2 taken
                      245: branch 3 taken
     712             1370:     if (!ForNPNVBases || !WasPrimaryBase) {
                      701: branch 0 taken
                      424: branch 1 taken
                        0: branch 2 not taken
                      701: branch 3 taken
     713             1125:       bool DeferVCalls = MorallyVirtual || ForVirtualBase;
     714             1125:       VCallInsertionPoint = VtableComponents.size();
                      701: branch 0 taken
                      424: branch 1 taken
     715             1125:       if (!DeferVCalls) {
     716              701:         insertVCalls(VCallInsertionPoint);
     717                 :       } else
     718                 :         // FIXME: just for extra, or for all uses of VCalls.size post this?
     719              424:         extra = -VCalls.size();
     720                 : 
     721                 :       // Add the offset to top.
                      557: branch 0 taken
                      568: branch 1 taken
     722             1125:       VtableComponents.push_back(BuildVtable ? wrap(-((Offset-LayoutOffset)/8)) : 0);
     723                 :     
     724                 :       // Add the RTTI information.
     725             1125:       VtableComponents.push_back(rtti);
     726                 :     
     727             1125:       AddressPoint = VtableComponents.size();
     728                 : 
     729             1125:       AppendMethodsToVtable();
     730                 :     }
     731                 : 
     732                 :     // and then the non-virtual bases.
     733                 :     NonVirtualBases(RD, Layout, PrimaryBase, PrimaryBaseWasVirtual,
     734             1370:                     MorallyVirtual, Offset, CurrentVBaseOffset, Path);
     735                 : 
                      389: branch 0 taken
                      981: branch 1 taken
     736             1370:     if (ForVirtualBase) {
     737                 :       // FIXME: We're adding to VCalls in callers, we need to do the overrides
     738                 :       // in the inner part, so that we know the complete set of vcalls during
     739                 :       // the build and don't have to insert into methods.  Saving out the
     740                 :       // AddressPoint here, would need to be fixed, if we didn't do that.  Also
     741                 :       // retroactively adding vcalls for overrides later wind up in the wrong
     742                 :       // place, the vcall slot has to be alloted during the walk of the base
     743                 :       // when the function is first introduces.
     744              389:       AddressPoint += VCalls.size();
     745              389:       insertVCalls(VCallInsertionPoint);
     746                 :     }
     747                 :     
                      329: branch 0 taken
                     1041: branch 1 taken
                       84: branch 2 taken
                      245: branch 3 taken
     748             1370:     if (!ForNPNVBases || !WasPrimaryBase)
     749             1125:       AddAddressPoints(RD, Offset, AddressPoint);
     750                 : 
                      652: branch 0 taken
                      718: branch 1 taken
     751             1370:     if (alloc) {
                      652: branch 0 taken
                        0: branch 1 not taken
     752              652:       delete Path;
     753                 :     }
     754             1370:   }
     755                 : 
     756                 :   void Primaries(const CXXRecordDecl *RD, bool MorallyVirtual, int64_t Offset,
     757                 :                  bool updateVBIndex, Index_t current_vbindex,
     758             1608:                  int64_t CurrentVBaseOffset) {
                        0: branch 1 not taken
                     1608: branch 2 taken
     759             1608:     if (!RD->isDynamicClass())
     760                0:       return;
     761                 : 
     762             1608:     const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
     763             1608:     const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
     764             1608:     const bool PrimaryBaseWasVirtual = Layout.getPrimaryBaseWasVirtual();
     765                 : 
     766                 :     // vtables are composed from the chain of primaries.
                      483: branch 0 taken
                     1125: branch 1 taken
                      279: branch 2 taken
                      204: branch 3 taken
     767             1608:     if (PrimaryBase && !PrimaryBaseWasVirtual) {
                        0: branch 1 not taken
                      279: branch 2 taken
     768              279:       D1(printf(" doing primaries for %s most derived %s\n",
     769                 :                 RD->getNameAsCString(), MostDerivedClass->getNameAsCString()));
     770                 :       Primaries(PrimaryBase, PrimaryBaseWasVirtual|MorallyVirtual, Offset,
     771              279:                 updateVBIndex, current_vbindex, CurrentVBaseOffset);
     772                 :     }
     773                 : 
                        0: branch 1 not taken
                     1608: branch 2 taken
     774             1608:     D1(printf(" doing vcall entries for %s most derived %s\n",
     775                 :               RD->getNameAsCString(), MostDerivedClass->getNameAsCString()));
     776                 : 
     777                 :     // And add the virtuals for the class to the primary vtable.
     778             1608:     AddMethods(RD, MorallyVirtual, Offset, CurrentVBaseOffset);
     779                 :   }
     780                 : 
     781                 :   void VBPrimaries(const CXXRecordDecl *RD, bool MorallyVirtual, int64_t Offset,
     782                 :                    bool updateVBIndex, Index_t current_vbindex,
     783                 :                    bool RDisVirtualBase, int64_t CurrentVBaseOffset,
     784             1608:                    bool bottom) {
                        0: branch 1 not taken
                     1608: branch 2 taken
     785             1608:     if (!RD->isDynamicClass())
     786                0:       return;
     787                 : 
     788             1608:     const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
     789             1608:     const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
     790             1608:     const bool PrimaryBaseWasVirtual = Layout.getPrimaryBaseWasVirtual();
     791                 : 
     792                 :     // vtables are composed from the chain of primaries.
                      483: branch 0 taken
                     1125: branch 1 taken
     793             1608:     if (PrimaryBase) {
     794              483:       int BaseCurrentVBaseOffset = CurrentVBaseOffset;
                      204: branch 0 taken
                      279: branch 1 taken
     795              483:       if (PrimaryBaseWasVirtual) {
     796              204:         IndirectPrimary.insert(PrimaryBase);
     797              204:         BaseCurrentVBaseOffset = BLayout.getVBaseClassOffset(PrimaryBase);
     798                 :       }
     799                 : 
                        0: branch 1 not taken
                      483: branch 2 taken
     800              483:       D1(printf(" doing primaries for %s most derived %s\n",
     801                 :                 RD->getNameAsCString(), MostDerivedClass->getNameAsCString()));
     802                 :       
     803                 :       VBPrimaries(PrimaryBase, PrimaryBaseWasVirtual|MorallyVirtual, Offset,
     804                 :                   updateVBIndex, current_vbindex, PrimaryBaseWasVirtual,
     805              483:                   BaseCurrentVBaseOffset, false);
     806                 :     }
     807                 : 
                        0: branch 1 not taken
                     1608: branch 2 taken
     808             1608:     D1(printf(" doing vbase entries for %s most derived %s\n",
     809                 :               RD->getNameAsCString(), MostDerivedClass->getNameAsCString()));
     810             1608:     GenerateVBaseOffsets(RD, Offset, updateVBIndex, current_vbindex);
     811                 : 
                     1015: branch 0 taken
                      593: branch 1 taken
                      736: branch 2 taken
                      279: branch 3 taken
     812             1608:     if (RDisVirtualBase || bottom) {
     813                 :       Primaries(RD, MorallyVirtual, Offset, updateVBIndex, current_vbindex,
     814             1329:                 CurrentVBaseOffset);
     815                 :     }
     816                 :   }
     817                 : 
     818                 :   void GenerateVtableForBase(const CXXRecordDecl *RD, int64_t Offset = 0,
     819                 :                              bool MorallyVirtual = false, 
     820                 :                              bool ForVirtualBase = false,
     821                 :                              bool ForNPNVBases = false,
     822                 :                              bool WasPrimaryBase = true,
     823                 :                              int CurrentVBaseOffset = 0,
     824             1650:                              Path_t *Path = 0) {
                      268: branch 1 taken
                     1382: branch 2 taken
     825             1650:     if (!RD->isDynamicClass())
     826              268:       return;
     827                 : 
     828                 :     // Construction vtable don't need parts that have no virtual bases and
     829                 :     // aren't morally virtual.
                      231: branch 0 taken
                     1151: branch 1 taken
                       84: branch 3 taken
                      147: branch 4 taken
                       12: branch 5 taken
                       72: branch 6 taken
                       12: branch 7 taken
                     1370: branch 8 taken
     830             1382:     if ((LayoutClass != MostDerivedClass) && 
     831                 :         RD->getNumVBases() == 0 && !MorallyVirtual)
     832               12:       return;
     833                 : 
     834             1370:     const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
     835             1370:     const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
     836             1370:     const bool PrimaryBaseWasVirtual = Layout.getPrimaryBaseWasVirtual();
     837                 : 
     838             1370:     extra = 0;
                        0: branch 1 not taken
                     1370: branch 2 taken
     839             1370:     D1(printf("building entries for base %s most derived %s\n",
     840                 :               RD->getNameAsCString(), MostDerivedClass->getNameAsCString()));
     841                 : 
                      389: branch 0 taken
                      981: branch 1 taken
     842             1370:     if (ForVirtualBase)
     843              389:       extra = VCalls.size();
     844                 : 
                      329: branch 0 taken
                     1041: branch 1 taken
                       84: branch 2 taken
                      245: branch 3 taken
     845             1370:     if (!ForNPNVBases || !WasPrimaryBase) {
     846                 :       VBPrimaries(RD, MorallyVirtual, Offset, !ForVirtualBase, 0,
     847             1125:                   ForVirtualBase, CurrentVBaseOffset, true);
     848                 : 
                      473: branch 0 taken
                      652: branch 1 taken
     849             1125:       if (Path)
     850              473:         OverrideMethods(Path, MorallyVirtual, Offset, CurrentVBaseOffset);
     851                 :     }
     852                 : 
     853                 :     FinishGenerateVtable(RD, Layout, PrimaryBase, ForNPNVBases, WasPrimaryBase,
     854                 :                          PrimaryBaseWasVirtual, MorallyVirtual, Offset,
     855             1370:                          ForVirtualBase, CurrentVBaseOffset, Path);
     856                 :   }
     857                 : 
     858                 :   void GenerateVtableForVBases(const CXXRecordDecl *RD,
     859                 :                                int64_t Offset = 0,
     860              978:                                Path_t *Path = 0) {
     861              978:     bool alloc = false;
                      652: branch 0 taken
                      326: branch 1 taken
     862              978:     if (Path == 0) {
     863              652:       alloc = true;
     864              652:       Path = new Path_t;
     865                 :     }
     866                 :     // FIXME: We also need to override using all paths to a virtual base,
     867                 :     // right now, we just process the first path
     868              978:     Path->push_back(std::make_pair(RD, Offset));
                     1181: branch 1 taken
                      978: branch 2 taken
     869             3137:     for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
     870              978:            e = RD->bases_end(); i != e; ++i) {
     871                 :       const CXXRecordDecl *Base =
     872             1181:         cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
                      827: branch 1 taken
                      354: branch 2 taken
                      579: branch 4 taken
                      248: branch 5 taken
                      579: branch 6 taken
                      602: branch 7 taken
     873             1181:       if (i->isVirtual() && !IndirectPrimary.count(Base)) {
     874                 :         // Mark it so we don't output it twice.
     875              579:         IndirectPrimary.insert(Base);
     876              579:         StartNewTable();
     877              579:         VCall.clear();
     878              579:         int64_t BaseOffset = BLayout.getVBaseClassOffset(Base);
     879              579:         int64_t CurrentVBaseOffset = BaseOffset;
                        0: branch 1 not taken
                      579: branch 2 taken
     880              579:         D1(printf("vtable %s virtual base %s\n",
     881                 :                   MostDerivedClass->getNameAsCString(), Base->getNameAsCString()));
     882                 :         GenerateVtableForBase(Base, BaseOffset, true, true, false,
     883              579:                               true, CurrentVBaseOffset, Path);
     884                 :       }
     885                 :       int64_t BaseOffset;
                      827: branch 1 taken
                      354: branch 2 taken
     886             1181:       if (i->isVirtual())
     887              827:         BaseOffset = BLayout.getVBaseClassOffset(Base);
     888                 :       else {
     889              354:         const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
     890              354:         BaseOffset = Offset + Layout.getBaseClassOffset(Base);
     891                 :       }
     892                 :         
                      326: branch 1 taken
                      855: branch 2 taken
     893             1181:       if (Base->getNumVBases()) {
     894              326:         GenerateVtableForVBases(Base, BaseOffset, Path);
     895                 :       }
     896                 :     }
     897              978:     Path->pop_back();
                      652: branch 0 taken
                      326: branch 1 taken
     898              978:     if (alloc)
                      652: branch 0 taken
                        0: branch 1 not taken
     899              652:       delete Path;
     900              978:   }
     901                 : };
     902                 : } // end anonymous namespace
     903                 : 
     904                 : /// TypeConversionRequiresAdjustment - Returns whether conversion from a 
     905                 : /// derived type to a base type requires adjustment.
     906                 : static bool
     907                 : TypeConversionRequiresAdjustment(ASTContext &Ctx,
     908                 :                                  const CXXRecordDecl *DerivedDecl,
     909              192:                                  const CXXRecordDecl *BaseDecl) {
     910                 :   CXXBasePaths Paths(/*FindAmbiguities=*/false,
     911              192:                      /*RecordPaths=*/true, /*DetectVirtual=*/true);
                        0: branch 1 not taken
                      192: branch 2 taken
     912              192:   if (!const_cast<CXXRecordDecl *>(DerivedDecl)->
     913                 :       isDerivedFrom(const_cast<CXXRecordDecl *>(BaseDecl), Paths)) {
     914                0:     assert(false && "Class must be derived from the passed in base class!");
     915                 :     return false;
     916                 :   }
     917                 :   
     918                 :   // If we found a virtual base we always want to require adjustment.
                      156: branch 1 taken
                       36: branch 2 taken
     919              192:   if (Paths.getDetectedVirtual())
     920              156:     return true;
     921                 :   
     922               36:   const CXXBasePath &Path = Paths.front();
     923                 :   
                       36: branch 1 taken
                        0: branch 2 not taken
     924               36:   for (size_t Start = 0, End = Path.size(); Start != End; ++Start) {
     925               36:     const CXXBasePathElement &Element = Path[Start];
     926                 :     
     927                 :     // Check the base class offset.
     928               36:     const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(Element.Class);
     929                 :     
     930               36:     const RecordType *BaseType = Element.Base->getType()->getAs<RecordType>();
     931               36:     const CXXRecordDecl *Base = cast<CXXRecordDecl>(BaseType->getDecl());
     932                 :     
                       36: branch 1 taken
                        0: branch 2 not taken
     933               36:     if (Layout.getBaseClassOffset(Base) != 0) {
     934                 :       // This requires an adjustment.
     935               36:       return true;
     936                 :     }
     937                 :   }
     938                 :   
     939                0:   return false;
     940                 : }
     941                 : 
     942                 : static bool 
     943                 : TypeConversionRequiresAdjustment(ASTContext &Ctx,
     944              600:                                  QualType DerivedType, QualType BaseType) {
     945                 :   // Canonicalize the types.
     946              600:   QualType CanDerivedType = Ctx.getCanonicalType(DerivedType);
     947              600:   QualType CanBaseType = Ctx.getCanonicalType(BaseType);
     948                 :   
     949                 :   assert(CanDerivedType->getTypeClass() == CanBaseType->getTypeClass() && 
                      600: branch 4 taken
                        0: branch 5 not taken
     950              600:          "Types must have same type class!");
     951                 :   
                      408: branch 1 taken
                      192: branch 2 taken
     952              600:   if (CanDerivedType == CanBaseType) {
     953                 :     // No adjustment needed.
     954              408:     return false;
     955                 :   }
     956                 :   
                       64: branch 1 taken
                      128: branch 2 taken
     957              192:   if (const ReferenceType *RT = dyn_cast<ReferenceType>(CanDerivedType)) {
     958               64:     CanDerivedType = RT->getPointeeType();
     959               64:     CanBaseType = cast<ReferenceType>(CanBaseType)->getPointeeType();
                      128: branch 1 taken
                        0: branch 2 not taken
     960              128:   } else if (const PointerType *PT = dyn_cast<PointerType>(CanDerivedType)) {
     961              128:     CanDerivedType = PT->getPointeeType();
     962              128:     CanBaseType = cast<PointerType>(CanBaseType)->getPointeeType();
     963                 :   } else {
     964                0:     assert(false && "Unexpected return type!");
     965                 :   }
     966                 :   
                        0: branch 1 not taken
                      192: branch 2 taken
     967              192:   if (CanDerivedType == CanBaseType) {
     968                 :     // No adjustment needed.
     969                0:     return false;
     970                 :   }
     971                 :   
     972                 :   const CXXRecordDecl *DerivedDecl = 
     973              192:     cast<CXXRecordDecl>(cast<RecordType>(CanDerivedType)->getDecl());
     974                 :   
     975                 :   const CXXRecordDecl *BaseDecl = 
     976              192:     cast<CXXRecordDecl>(cast<RecordType>(CanBaseType)->getDecl());
     977                 :   
     978              192:   return TypeConversionRequiresAdjustment(Ctx, DerivedDecl, BaseDecl);
     979                 : }
     980                 : 
     981                 : bool VtableBuilder::OverrideMethod(GlobalDecl GD, bool MorallyVirtual,
     982                 :                                    Index_t OverrideOffset, Index_t Offset,
     983             3584:                                    int64_t CurrentVBaseOffset) {
     984             3584:   const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
     985                 : 
     986             3584:   const bool isPure = MD->isPure();
     987                 :   
     988                 :   // FIXME: Should OverrideOffset's be Offset?
     989                 : 
                      856: branch 1 taken
                     2988: branch 2 taken
     990             7428:   for (CXXMethodDecl::method_iterator mi = MD->begin_overridden_methods(),
     991             3584:        e = MD->end_overridden_methods(); mi != e; ++mi) {
     992              856:     GlobalDecl OGD;
     993              856:     GlobalDecl OGD2;
     994                 :     
     995              856:     const CXXMethodDecl *OMD = *mi;
                       46: branch 1 taken
                      810: branch 2 taken
     996              856:     if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(OMD))
     997               46:       OGD = GlobalDecl(DD, GD.getDtorType());
     998                 :     else
     999              810:       OGD = OMD;
    1000                 : 
    1001                 :     // Check whether this is the method being overridden in this section of
    1002                 :     // the vtable.
    1003                 :     uint64_t Index;
                      596: branch 1 taken
                      260: branch 2 taken
    1004              856:     if (!Methods.getIndex(OGD, Index))
    1005              260:       continue;
    1006                 : 
    1007              596:     OGD2 = OGD;
    1008                 : 
    1009                 :     // Get the original method, which we should be computing thunks, etc,
    1010                 :     // against.
    1011              596:     OGD = Methods.getOrigMethod(Index);
    1012              596:     OMD = cast<CXXMethodDecl>(OGD.getDecl());
    1013                 : 
    1014                 :     QualType ReturnType = 
    1015              596:       MD->getType()->getAs<FunctionType>()->getResultType();
    1016                 :     QualType OverriddenReturnType = 
    1017              596:       OMD->getType()->getAs<FunctionType>()->getResultType();
    1018                 :     
    1019                 :     // Check if we need a return type adjustment.
                      192: branch 2 taken
                      404: branch 3 taken
    1020              596:     if (TypeConversionRequiresAdjustment(CGM.getContext(), ReturnType, 
    1021                 :                                           OverriddenReturnType)) {
    1022              192:       CanQualType &BaseReturnType = BaseReturnTypes[Index];
    1023                 : 
    1024                 :       // Insert the base return type.
                      134: branch 1 taken
                       58: branch 2 taken
    1025              192:       if (BaseReturnType.isNull())
    1026                 :         BaseReturnType =
    1027              134:           CGM.getContext().getCanonicalType(OverriddenReturnType);
    1028                 :     }
    1029                 : 
    1030              596:     Methods.OverrideMethod(OGD, GD);
    1031                 : 
    1032              596:     GlobalDecl UGD = getUnique(GD);
    1033              596:     const CXXMethodDecl *UMD = cast<CXXMethodDecl>(UGD.getDecl());
                      596: branch 1 taken
                        0: branch 2 not taken
    1034              596:     assert(UGD.getDecl() && "unique overrider not found");
                      596: branch 2 taken
                        0: branch 3 not taken
    1035              596:     assert(UGD == getUnique(OGD) && "unique overrider not unique");
    1036                 : 
    1037              596:     ThisAdjustments.erase(Index);
                      260: branch 0 taken
                      336: branch 1 taken
                       96: branch 3 taken
                      164: branch 4 taken
                      432: branch 5 taken
                      164: branch 6 taken
    1038              856:     if (MorallyVirtual || VCall.count(UMD)) {
    1039                 : 
    1040              432:       Index_t &idx = VCall[UMD];
                        0: branch 0 not taken
                      432: branch 1 taken
    1041              432:       if (idx == 0) {
    1042                0:         VCallOffset[GD] = VCallOffset[OGD];
    1043                 :         // NonVirtualOffset[UMD] = CurrentVBaseOffset/8 - OverrideOffset/8;
    1044                0:         NonVirtualOffset[UMD] = VCallOffset[OGD];
    1045                0:         VCallOffsetForVCall[UMD] = OverrideOffset/8;
    1046                0:         idx = VCalls.size()+1;
    1047                0:         VCalls.push_back(OverrideOffset/8 - CurrentVBaseOffset/8);
                        0: branch 1 not taken
                        0: branch 2 not taken
    1048                0:         D1(printf("  vcall for %s at %d with delta %d most derived %s\n",
    1049                 :                   MD->getNameAsString().c_str(), (int)-idx-3,
    1050                 :                   (int)VCalls[idx-1], MostDerivedClass->getNameAsCString()));
    1051                 :       } else {
    1052              432:         VCallOffset[GD] = NonVirtualOffset[UMD];
    1053              432:         VCalls[idx-1] = -VCallOffsetForVCall[UGD] + OverrideOffset/8;
                        0: branch 1 not taken
                      432: branch 2 taken
    1054              432:         D1(printf("  vcall patch for %s at %d with delta %d most derived %s\n",
    1055                 :                   MD->getNameAsString().c_str(), (int)-idx-3,
    1056                 :                   (int)VCalls[idx-1], MostDerivedClass->getNameAsCString()));
    1057                 :       }
    1058              432:       int64_t NonVirtualAdjustment = -VCallOffset[OGD];
    1059              432:       QualType DerivedType = MD->getThisType(CGM.getContext());
    1060              432:       QualType BaseType = cast<const CXXMethodDecl>(OGD.getDecl())->getThisType(CGM.getContext());
    1061              432:       int64_t NonVirtualAdjustment2 = -(getNVOffset(BaseType, DerivedType)/8);
                        0: branch 0 not taken
                      432: branch 1 taken
    1062              432:       if (NonVirtualAdjustment2 != NonVirtualAdjustment) {
    1063                0:         NonVirtualAdjustment = NonVirtualAdjustment2;
    1064                 :       }
    1065                 :       int64_t VirtualAdjustment = 
    1066              432:         -((idx + extra + 2) * LLVMPointerWidth / 8);
    1067                 :       
    1068                 :       // Optimize out virtual adjustments of 0.
                      216: branch 1 taken
                      216: branch 2 taken
    1069              432:       if (VCalls[idx-1] == 0)
    1070              216:         VirtualAdjustment = 0;
    1071                 :       
    1072                 :       ThunkAdjustment ThisAdjustment(NonVirtualAdjustment,
    1073              432:                                       VirtualAdjustment);
    1074                 : 
                      432: branch 0 taken
                        0: branch 1 not taken
                      245: branch 3 taken
                      187: branch 4 taken
                      245: branch 5 taken
                      187: branch 6 taken
    1075              432:       if (!isPure && !ThisAdjustment.isEmpty()) {
    1076              245:         ThisAdjustments[Index] = ThisAdjustment;
    1077                 :         SavedAdjustments.push_back(
    1078              245:             std::make_pair(GD, std::make_pair(OGD, ThisAdjustment)));
    1079                 :       }
    1080              432:       return true;
    1081                 :     }
    1082                 : 
    1083              164:     VCallOffset[GD] = VCallOffset[OGD2] - OverrideOffset/8;
    1084                 : 
    1085              164:     int64_t NonVirtualAdjustment = -VCallOffset[GD];
    1086              164:     QualType DerivedType = MD->getThisType(CGM.getContext());
    1087              164:     QualType BaseType = cast<const CXXMethodDecl>(OGD.getDecl())->getThisType(CGM.getContext());
    1088              164:     int64_t NonVirtualAdjustment2 = -(getNVOffset(BaseType, DerivedType)/8);
                        0: branch 0 not taken
                      164: branch 1 taken
    1089              164:     if (NonVirtualAdjustment2 != NonVirtualAdjustment) {
    1090                0:       NonVirtualAdjustment = NonVirtualAdjustment2;
    1091                 :     }
    1092                 :       
                       20: branch 0 taken
                      144: branch 1 taken
    1093              164:     if (NonVirtualAdjustment) {
    1094               20:       ThunkAdjustment ThisAdjustment(NonVirtualAdjustment, 0);
    1095                 :       
                       20: branch 0 taken
                        0: branch 1 not taken
    1096               20:       if (!isPure) {
    1097               20:         ThisAdjustments[Index] = ThisAdjustment;
    1098                 :         SavedAdjustments.push_back(
    1099               20:             std::make_pair(GD, std::make_pair(OGD, ThisAdjustment)));
    1100                 :       }
    1101                 :     }
    1102              164:     return true;
    1103                 :   }
    1104                 : 
    1105             2988:   return false;
    1106                 : }
    1107                 : 
    1108             1125: void VtableBuilder::AppendMethodsToVtable() {
                      568: branch 0 taken
                      557: branch 1 taken
    1109             1125:   if (!BuildVtable) {
    1110                 :     VtableComponents.insert(VtableComponents.end(), Methods.size(), 
    1111              568:                             (llvm::Constant *)0);
    1112              568:     ThisAdjustments.clear();
    1113              568:     BaseReturnTypes.clear();
    1114              568:     Methods.clear();
    1115              568:     return;
    1116                 :   }
    1117                 : 
    1118                 :   // Reserve room in the vtable for our new methods.
    1119              557:   VtableComponents.reserve(VtableComponents.size() + Methods.size());
    1120                 : 
                     1070: branch 1 taken
                      557: branch 2 taken
    1121             1627:   for (unsigned i = 0, e = Methods.size(); i != e; ++i) {
    1122             1070:     GlobalDecl GD = Methods[i];
    1123             1070:     const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
    1124                 :   
    1125                 :     // Get the 'this' pointer adjustment.
    1126             1070:     ThunkAdjustment ThisAdjustment = ThisAdjustments.lookup(i);
    1127                 :   
    1128                 :     // Construct the return type adjustment.
    1129             1070:     ThunkAdjustment ReturnAdjustment;
    1130                 : 
    1131             1070:     QualType BaseReturnType = BaseReturnTypes.lookup(i);
                       58: branch 1 taken
                     1012: branch 2 taken
                       58: branch 4 taken
                        0: branch 5 not taken
                       58: branch 6 taken
                     1012: branch 7 taken
    1132             1070:     if (!BaseReturnType.isNull() && !MD->isPure()) {
    1133                 :       QualType DerivedType = 
    1134               58:         MD->getType()->getAs<FunctionType>()->getResultType();
    1135                 :       
    1136                 :       int64_t NonVirtualAdjustment = 
    1137               58:       getNVOffset(BaseReturnType, DerivedType) / 8;
    1138                 :       
    1139                 :       int64_t VirtualAdjustment = 
    1140               58:       getVbaseOffset(BaseReturnType, DerivedType);
    1141                 :       
    1142                 :       ReturnAdjustment = ThunkAdjustment(NonVirtualAdjustment, 
    1143               58:                                          VirtualAdjustment);
    1144                 :     }
    1145                 : 
    1146             1070:     llvm::Constant *Method = 0;
                       58: branch 1 taken
                     1012: branch 2 taken
    1147             1070:     if (!ReturnAdjustment.isEmpty()) {
    1148                 :       // Build a covariant thunk.
    1149               58:       CovariantThunkAdjustment Adjustment(ThisAdjustment, ReturnAdjustment);
    1150               58:       Method = wrap(CGM.GetAddrOfCovariantThunk(GD, Adjustment));
                       25: branch 1 taken
                      987: branch 2 taken
    1151             1012:     } else if (!ThisAdjustment.isEmpty()) {
    1152                 :       // Build a "regular" thunk.
    1153               25:       Method = wrap(CGM.GetAddrOfThunk(GD, ThisAdjustment));
                        4: branch 1 taken
                      983: branch 2 taken
    1154              987:     } else if (MD->isPure()) {
    1155                 :       // We have a pure virtual method.
    1156                4:       Method = getPureVirtualFn();
    1157                 :     } else {
    1158                 :       // We have a good old regular method.
    1159              983:       Method = WrapAddrOf(GD);
    1160                 :     }
    1161                 : 
    1162                 :     // Add the method to the vtable.
    1163             1070:     VtableComponents.push_back(Method);
    1164                 :   }
    1165                 :   
    1166                 :   
    1167              557:   ThisAdjustments.clear();
    1168              557:   BaseReturnTypes.clear();
    1169                 :   
    1170              557:   Methods.clear();
    1171                 : }
    1172                 : 
    1173               21: void CGVtableInfo::ComputeMethodVtableIndices(const CXXRecordDecl *RD) {
    1174                 :   
    1175                 :   // Itanium C++ ABI 2.5.2:
    1176                 :   //   The order of the virtual function pointers in a virtual table is the 
    1177                 :   //   order of declaration of the corresponding member functions in the class.
    1178                 :   //
    1179                 :   //   There is an entry for any virtual function declared in a class, 
    1180                 :   //   whether it is a new function or overrides a base class function, 
    1181                 :   //   unless it overrides a function from the primary base, and conversion
    1182                 :   //   between their return types does not require an adjustment. 
    1183                 : 
    1184               21:   int64_t CurrentIndex = 0;
    1185                 :   
    1186               21:   const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
    1187               21:   const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
    1188                 :   
                        6: branch 0 taken
                       15: branch 1 taken
    1189               21:   if (PrimaryBase) {
    1190                 :     assert(PrimaryBase->isDefinition() && 
                        6: branch 1 taken
                        0: branch 2 not taken
    1191                6:            "Should have the definition decl of the primary base!");
    1192                 : 
    1193                 :     // Since the record decl shares its vtable pointer with the primary base
    1194                 :     // we need to start counting at the end of the primary base's vtable.
    1195                6:     CurrentIndex = getNumVirtualFunctionPointers(PrimaryBase);
    1196                 :   }
    1197                 : 
    1198                 :   // Collect all the primary bases, so we can check whether methods override
    1199                 :   // a method from the base.
    1200               21:   llvm::SmallPtrSet<const CXXRecordDecl *, 5> PrimaryBases;
                        7: branch 2 taken
                       21: branch 3 taken
    1201               28:   for (ASTRecordLayout::primary_base_info_iterator
    1202               21:        I = Layout.primary_base_begin(), E = Layout.primary_base_end();
    1203                 :        I != E; ++I)
    1204                7:     PrimaryBases.insert((*I).getBase());
    1205                 : 
    1206               21:   const CXXDestructorDecl *ImplicitVirtualDtor = 0;
    1207                 :   
                      111: branch 3 taken
                       21: branch 4 taken
    1208              153:   for (CXXRecordDecl::method_iterator i = RD->method_begin(),
    1209               21:        e = RD->method_end(); i != e; ++i) {
    1210              111:     const CXXMethodDecl *MD = *i;
    1211                 : 
    1212                 :     // We only want virtual methods.
                       87: branch 1 taken
                       24: branch 2 taken
    1213              111:     if (!MD->isVirtual())
    1214               87:       continue;
    1215                 : 
    1216               24:     bool ShouldAddEntryForMethod = true;
    1217                 :     
    1218                 :     // Check if this method overrides a method in the primary base.
                        4: branch 1 taken
                       20: branch 2 taken
    1219               48:     for (CXXMethodDecl::method_iterator i = MD->begin_overridden_methods(),
    1220               24:          e = MD->end_overridden_methods(); i != e; ++i) {
    1221                4:       const CXXMethodDecl *OverriddenMD = *i;
    1222                4:       const CXXRecordDecl *OverriddenRD = OverriddenMD->getParent();
    1223                 :       assert(OverriddenMD->isCanonicalDecl() &&
                        4: branch 1 taken
                        0: branch 2 not taken
    1224                4:              "Should have the canonical decl of the overridden RD!");
    1225                 :       
                        4: branch 1 taken
                        0: branch 2 not taken
    1226                4:       if (PrimaryBases.count(OverriddenRD)) {
    1227                 :         // Check if converting from the return type of the method to the 
    1228                 :         // return type of the overridden method requires conversion.
    1229                 :         QualType ReturnType = 
    1230                4:           MD->getType()->getAs<FunctionType>()->getResultType();
    1231                 :         QualType OverriddenReturnType =
    1232                4:           OverriddenMD->getType()->getAs<FunctionType>()->getResultType();
    1233                 :         
                        4: branch 2 taken
                        0: branch 3 not taken
    1234                4:         if (!TypeConversionRequiresAdjustment(CGM.getContext(), 
    1235                 :                                             ReturnType, OverriddenReturnType)) {
    1236                 :           // This index is shared between the index in the vtable of the primary
    1237                 :           // base class.
                        0: branch 1 not taken
                        4: branch 2 taken
    1238                4:           if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {
    1239                 :             const CXXDestructorDecl *OverriddenDD = 
    1240                0:               cast<CXXDestructorDecl>(OverriddenMD);
    1241                 :             
    1242                 :             // Add both the complete and deleting entries.
    1243                 :             MethodVtableIndices[GlobalDecl(DD, Dtor_Complete)] = 
    1244                0:               getMethodVtableIndex(GlobalDecl(OverriddenDD, Dtor_Complete));
    1245                 :             MethodVtableIndices[GlobalDecl(DD, Dtor_Deleting)] = 
    1246                0:               getMethodVtableIndex(GlobalDecl(OverriddenDD, Dtor_Deleting));
    1247                 :           } else {
    1248                4:             MethodVtableIndices[MD] = getMethodVtableIndex(OverriddenMD);
    1249                 :           }
    1250                 :           
    1251                 :           // We don't need to add an entry for this method.
    1252                4:           ShouldAddEntryForMethod = false;
    1253                4:           break;
    1254                 :         }        
    1255                 :       }
    1256                 :     }
    1257                 :     
                        4: branch 0 taken
                       20: branch 1 taken
    1258               24:     if (!ShouldAddEntryForMethod)
    1259                4:       continue;
    1260                 :     
                        1: branch 1 taken
                       19: branch 2 taken
    1261               20:     if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {
                        0: branch 1 not taken
                        1: branch 2 taken
    1262                1:       if (MD->isImplicit()) {
    1263                 :         assert(!ImplicitVirtualDtor && 
                        0: branch 0 not taken
                        0: branch 1 not taken
    1264                0:                "Did already see an implicit virtual dtor!");
    1265                0:         ImplicitVirtualDtor = DD;
    1266                0:         continue;
    1267                 :       } 
    1268                 : 
    1269                 :       // Add the complete dtor.
    1270                1:       MethodVtableIndices[GlobalDecl(DD, Dtor_Complete)] = CurrentIndex++;
    1271                 :       
    1272                 :       // Add the deleting dtor.
    1273                1:       MethodVtableIndices[GlobalDecl(DD, Dtor_Deleting)] = CurrentIndex++;
    1274                 :     } else {
    1275                 :       // Add the entry.
    1276               19:       MethodVtableIndices[MD] = CurrentIndex++;
    1277                 :     }
    1278                 :   }
    1279                 : 
                        0: branch 0 not taken
                       21: branch 1 taken
    1280               21:   if (ImplicitVirtualDtor) {
    1281                 :     // Itanium C++ ABI 2.5.2:
    1282                 :     // If a class has an implicitly-defined virtual destructor, 
    1283                 :     // its entries come after the declared virtual function pointers.
    1284                 : 
    1285                 :     // Add the complete dtor.
    1286                 :     MethodVtableIndices[GlobalDecl(ImplicitVirtualDtor, Dtor_Complete)] = 
    1287                0:       CurrentIndex++;
    1288                 :     
    1289                 :     // Add the deleting dtor.
    1290                 :     MethodVtableIndices[GlobalDecl(ImplicitVirtualDtor, Dtor_Deleting)] = 
    1291                0:       CurrentIndex++;
    1292                 :   }
    1293                 :   
    1294               21:   NumVirtualFunctionPointers[RD] = CurrentIndex;
    1295               21: }
    1296                 : 
    1297                6: uint64_t CGVtableInfo::getNumVirtualFunctionPointers(const CXXRecordDecl *RD) {
    1298                 :   llvm::DenseMap<const CXXRecordDecl *, uint64_t>::iterator I = 
    1299                6:     NumVirtualFunctionPointers.find(RD);
                        3: branch 3 taken
                        3: branch 4 taken
    1300                6:   if (I != NumVirtualFunctionPointers.end())
    1301                3:     return I->second;
    1302                 : 
    1303                3:   ComputeMethodVtableIndices(RD);
    1304                 : 
    1305                3:   I = NumVirtualFunctionPointers.find(RD);
                        3: branch 3 taken
                        0: branch 4 not taken
    1306                3:   assert(I != NumVirtualFunctionPointers.end() && "Did not find entry!");
    1307                3:   return I->second;
    1308                 : }
    1309                 :       
    1310               37: uint64_t CGVtableInfo::getMethodVtableIndex(GlobalDecl GD) {
    1311               37:   MethodVtableIndicesTy::iterator I = MethodVtableIndices.find(GD);
                       19: branch 3 taken
                       18: branch 4 taken
    1312               37:   if (I != MethodVtableIndices.end())
    1313               19:     return I->second;
    1314                 :   
    1315               18:   const CXXRecordDecl *RD = cast<CXXMethodDecl>(GD.getDecl())->getParent();
    1316                 : 
    1317               18:   ComputeMethodVtableIndices(RD);
    1318                 : 
    1319               18:   I = MethodVtableIndices.find(GD);
                       18: branch 3 taken
                        0: branch 4 not taken
    1320               18:   assert(I != MethodVtableIndices.end() && "Did not find index!");
    1321               18:   return I->second;
    1322                 : }
    1323                 : 
    1324                 : CGVtableInfo::AdjustmentVectorTy*
    1325              943: CGVtableInfo::getAdjustments(GlobalDecl GD) {
    1326              943:   SavedAdjustmentsTy::iterator I = SavedAdjustments.find(GD);
                      125: branch 3 taken
                      818: branch 4 taken
    1327              943:   if (I != SavedAdjustments.end())
    1328              125:     return &I->second;
    1329                 : 
    1330              818:   const CXXRecordDecl *RD = cast<CXXRecordDecl>(GD.getDecl()->getDeclContext());
                      659: branch 1 taken
                      159: branch 2 taken
    1331              818:   if (!SavedAdjustmentRecords.insert(RD).second)
    1332              659:     return 0;
    1333                 : 
    1334              159:   AddressPointsMapTy AddressPoints;
    1335              159:   VtableBuilder b(RD, RD, 0, CGM, false, AddressPoints);
                        0: branch 1 not taken
                      159: branch 2 taken
    1336              159:   D1(printf("vtable %s\n", RD->getNameAsCString()));
    1337              159:   b.GenerateVtableForBase(RD);
    1338              159:   b.GenerateVtableForVBases(RD);
    1339                 : 
                       77: branch 2 taken
                      159: branch 3 taken
    1340              236:   for (VtableBuilder::SavedAdjustmentsVectorTy::iterator
    1341              159:        i = b.getSavedAdjustments().begin(),
    1342              159:        e = b.getSavedAdjustments().end(); i != e; i++)
    1343               77:     SavedAdjustments[i->first].push_back(i->second);
    1344                 : 
    1345              159:   I = SavedAdjustments.find(GD);
                        8: branch 3 taken
                      151: branch 4 taken
    1346              159:   if (I != SavedAdjustments.end())
    1347                8:     return &I->second;
    1348                 : 
    1349              151:   return 0;
    1350                 : }
    1351                 : 
    1352                 : int64_t CGVtableInfo::getVirtualBaseOffsetIndex(const CXXRecordDecl *RD, 
    1353              255:                                                 const CXXRecordDecl *VBase) {
    1354              255:   ClassPairTy ClassPair(RD, VBase);
    1355                 :   
    1356                 :   VirtualBaseClassIndiciesTy::iterator I = 
    1357              255:     VirtualBaseClassIndicies.find(ClassPair);
                      172: branch 3 taken
                       83: branch 4 taken
    1358              255:   if (I != VirtualBaseClassIndicies.end())
    1359              172:     return I->second;
    1360                 :   
    1361                 :   // FIXME: This seems expensive.  Can we do a partial job to get
    1362                 :   // just this data.
    1363               83:   AddressPointsMapTy AddressPoints;
    1364               83:   VtableBuilder b(RD, RD, 0, CGM, false, AddressPoints);
                        0: branch 1 not taken
                       83: branch 2 taken
    1365               83:   D1(printf("vtable %s\n", RD->getNameAsCString()));
    1366               83:   b.GenerateVtableForBase(RD);
    1367               83:   b.GenerateVtableForVBases(RD);
    1368                 :   
                      256: branch 3 taken
                       83: branch 4 taken
    1369              339:   for (llvm::DenseMap<const CXXRecordDecl *, uint64_t>::iterator I =
    1370               83:        b.getVBIndex().begin(), E = b.getVBIndex().end(); I != E; ++I) {
    1371                 :     // Insert all types.
    1372              256:     ClassPairTy ClassPair(RD, I->first);
    1373                 :     
    1374              256:     VirtualBaseClassIndicies.insert(std::make_pair(ClassPair, I->second));
    1375                 :   }
    1376                 :   
    1377               83:   I = VirtualBaseClassIndicies.find(ClassPair);
                       83: branch 3 taken
                        0: branch 4 not taken
    1378               83:   assert(I != VirtualBaseClassIndicies.end() && "Did not find index!");
    1379                 :   
    1380               83:   return I->second;
    1381                 : }
    1382                 : 
    1383                0: uint64_t CGVtableInfo::getVtableAddressPoint(const CXXRecordDecl *RD) {
    1384                 :   uint64_t AddressPoint = 
    1385                0:     (*(*(CGM.getVtableInfo().AddressPoints[RD]))[RD])[std::make_pair(RD, 0)];
    1386                 :   
    1387                0:   return AddressPoint;
    1388                 : }
    1389                 : 
    1390                 : llvm::GlobalVariable *
    1391                 : CGVtableInfo::GenerateVtable(llvm::GlobalVariable::LinkageTypes Linkage,
    1392                 :                              bool GenerateDefinition,
    1393                 :                              const CXXRecordDecl *LayoutClass,
    1394                 :                              const CXXRecordDecl *RD, uint64_t Offset,
    1395              410:                              AddressPointsMapTy& AddressPoints) {
    1396              410:   llvm::SmallString<256> OutName;
                      111: branch 0 taken
                      299: branch 1 taken
    1397              410:   if (LayoutClass != RD)
    1398                 :     CGM.getMangleContext().mangleCXXCtorVtable(LayoutClass, Offset / 8, 
    1399              111:                                                RD, OutName);
    1400                 :   else
    1401              299:     CGM.getMangleContext().mangleCXXVtable(RD, OutName);
    1402              410:   llvm::StringRef Name = OutName.str();
    1403                 : 
    1404              410:   llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
                        7: branch 0 taken
                      403: branch 1 taken
                        7: branch 4 taken
                        0: branch 5 not taken
                        7: branch 7 taken
                        0: branch 8 not taken
                      410: branch 9 taken
                        0: branch 10 not taken
    1405              410:   if (GV == 0 || CGM.getVtableInfo().AddressPoints[LayoutClass] == 0 || 
    1406                 :       GV->isDeclaration()) {
    1407                 :     VtableBuilder b(RD, LayoutClass, Offset, CGM, GenerateDefinition,
    1408              410:                     AddressPoints);
    1409                 : 
                        0: branch 1 not taken
                      410: branch 2 taken
    1410              410:     D1(printf("vtable %s\n", RD->getNameAsCString()));
    1411                 :     // First comes the vtables for all the non-virtual bases...
    1412              410:     b.GenerateVtableForBase(RD, Offset);
    1413                 : 
    1414                 :     // then the vtables for all the virtual bases.
    1415              410:     b.GenerateVtableForVBases(RD, Offset);
    1416                 : 
    1417              410:     llvm::Constant *Init = 0;
    1418              410:     const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
    1419                 :     llvm::ArrayType *ArrayType = 
    1420              410:       llvm::ArrayType::get(Int8PtrTy, b.getVtableComponents().size());
    1421                 : 
                      322: branch 0 taken
                       88: branch 1 taken
    1422              410:     if (GenerateDefinition)
    1423                 :       Init = llvm::ConstantArray::get(ArrayType, &b.getVtableComponents()[0], 
    1424              322:                                       b.getVtableComponents().size());
    1425                 : 
    1426              410:     llvm::GlobalVariable *OGV = GV;
    1427                 :     
    1428                 :     GV = new llvm::GlobalVariable(CGM.getModule(), ArrayType, 
    1429              410:                                   /*isConstant=*/true, Linkage, Init, Name);
    1430              410:     CGM.setGlobalVisibility(GV, RD);
    1431                 :   
                        7: branch 0 taken
                      403: branch 1 taken
    1432              410:     if (OGV) {
    1433                7:       GV->takeName(OGV);
    1434                 :       llvm::Constant *NewPtr = 
    1435                7:         llvm::ConstantExpr::getBitCast(GV, OGV->getType());
    1436                7:       OGV->replaceAllUsesWith(NewPtr);
    1437                7:       OGV->eraseFromParent();
    1438              410:     }
    1439                 :   }
    1440                 :   
    1441              410:   return GV;
    1442                 : }
    1443                 : 
    1444                 : void CGVtableInfo::GenerateClassData(llvm::GlobalVariable::LinkageTypes Linkage,
    1445              485:                                      const CXXRecordDecl *RD) {
    1446              485:   llvm::GlobalVariable *&Vtable = Vtables[RD];
                      274: branch 0 taken
                      211: branch 1 taken
    1447              485:   if (Vtable) {
                      274: branch 1 taken
                        0: branch 2 not taken
    1448              274:     assert(Vtable->getInitializer() && "Vtable doesn't have a definition!");
    1449              274:     return;
    1450                 :   }
    1451                 :   
    1452              211:   AddressPointsMapTy AddressPoints;
    1453                 :   Vtable = GenerateVtable(Linkage, /*GenerateDefinition=*/true, RD, RD, 0,
    1454              211:                           AddressPoints);
    1455              211:   GenerateVTT(Linkage, /*GenerateDefinition=*/true, RD);  
    1456                 : }
    1457                 : 
    1458              434: llvm::GlobalVariable *CGVtableInfo::getVtable(const CXXRecordDecl *RD) {
    1459              434:   llvm::GlobalVariable *Vtable = Vtables.lookup(RD);
    1460                 :   
                       88: branch 0 taken
                      346: branch 1 taken
    1461              434:   if (!Vtable) {
    1462               88:     AddressPointsMapTy AddressPoints;
    1463                 :     Vtable = GenerateVtable(llvm::GlobalValue::ExternalLinkage, 
    1464                 :                             /*GenerateDefinition=*/false, RD, RD, 0,
    1465               88:                             AddressPoints);
    1466                 :   }
    1467                 : 
    1468              434:   return Vtable;
    1469                 : }
    1470                 : 
    1471              984: void CGVtableInfo::MaybeEmitVtable(GlobalDecl GD) {
    1472              984:   const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
    1473              984:   const CXXRecordDecl *RD = MD->getParent();
    1474                 : 
    1475                 :   // If the class doesn't have a vtable we don't need to emit one.
                      360: branch 1 taken
                      624: branch 2 taken
    1476              984:   if (!RD->isDynamicClass())
    1477              360:     return;
    1478                 :   
    1479                 :   // Get the key function.
    1480              624:   const CXXMethodDecl *KeyFunction = CGM.getContext().getKeyFunction(RD);
    1481                 :   
                      197: branch 0 taken
                      427: branch 1 taken
    1482              624:   if (KeyFunction) {
    1483                 :     // We don't have the right key function.
                      139: branch 2 taken
                       58: branch 3 taken
    1484              197:     if (KeyFunction->getCanonicalDecl() != MD->getCanonicalDecl())
    1485              139:       return;
    1486                 :   }
    1487                 : 
    1488                 :   // Emit the data.
    1489              485:   GenerateClassData(CGM.getVtableLinkage(RD), RD);
    1490                 : 
                     3030: branch 3 taken
                      485: branch 4 taken
    1491             4000:   for (CXXRecordDecl::method_iterator i = RD->method_begin(),
    1492              485:        e = RD->method_end(); i != e; ++i) {
                      938: branch 2 taken
                     2092: branch 3 taken
                      102: branch 6 taken
                      836: branch 7 taken
                       15: branch 10 taken
                       87: branch 11 taken
                      851: branch 12 taken
                     2179: branch 13 taken
    1493             3030:     if ((*i)->isVirtual() && ((*i)->hasInlineBody() || (*i)->isImplicit())) {
                       34: branch 2 taken
                      817: branch 3 taken
    1494              851:       if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(*i)) {
    1495               34:         CGM.BuildThunksForVirtual(GlobalDecl(DD, Dtor_Complete));
    1496               34:         CGM.BuildThunksForVirtual(GlobalDecl(DD, Dtor_Deleting));
    1497                 :       } else {
    1498              817:         CGM.BuildThunksForVirtual(GlobalDecl(*i));
    1499                 :       }
    1500                 :     }
    1501                 :   }
    1502                 : }
    1503                 : 

Generated: 2010-02-10 01:31 by zcov