Coverage Report

Created: 2017-10-03 07:32

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/tools/clang/lib/CodeGen/CGVTT.cpp
Line
Count
Source
1
//===--- CGVTT.cpp - Emit LLVM Code for C++ VTTs --------------------------===//
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 VTTs (vtable tables).
11
//
12
//===----------------------------------------------------------------------===//
13
14
#include "CodeGenModule.h"
15
#include "CGCXXABI.h"
16
#include "clang/AST/RecordLayout.h"
17
#include "clang/AST/VTTBuilder.h"
18
using namespace clang;
19
using namespace CodeGen;
20
21
static llvm::GlobalVariable *
22
GetAddrOfVTTVTable(CodeGenVTables &CGVT, CodeGenModule &CGM,
23
                   const CXXRecordDecl *MostDerivedClass,
24
                   const VTTVTable &VTable,
25
                   llvm::GlobalVariable::LinkageTypes Linkage,
26
503
                   VTableLayout::AddressPointsMapTy &AddressPoints) {
27
503
  if (
VTable.getBase() == MostDerivedClass503
) {
28
253
    assert(VTable.getBaseOffset().isZero() &&
29
253
           "Most derived class vtable must have a zero offset!");
30
253
    // This is a regular vtable.
31
253
    return CGM.getCXXABI().getAddrOfVTable(MostDerivedClass, CharUnits());
32
253
  }
33
250
  
34
250
  return CGVT.GenerateConstructionVTable(MostDerivedClass, 
35
250
                                         VTable.getBaseSubobject(),
36
250
                                         VTable.isVirtual(),
37
250
                                         Linkage,
38
250
                                         AddressPoints);
39
250
}
40
41
void
42
CodeGenVTables::EmitVTTDefinition(llvm::GlobalVariable *VTT,
43
                                  llvm::GlobalVariable::LinkageTypes Linkage,
44
253
                                  const CXXRecordDecl *RD) {
45
253
  VTTBuilder Builder(CGM.getContext(), RD, /*GenerateDefinition=*/true);
46
253
47
253
  llvm::Type *Int8PtrTy = CGM.Int8PtrTy, *Int32Ty = CGM.Int32Ty;
48
253
  llvm::ArrayType *ArrayType = 
49
253
    llvm::ArrayType::get(Int8PtrTy, Builder.getVTTComponents().size());
50
253
51
253
  SmallVector<llvm::GlobalVariable *, 8> VTables;
52
253
  SmallVector<VTableAddressPointsMapTy, 8> VTableAddressPoints;
53
253
  for (const VTTVTable *i = Builder.getVTTVTables().begin(),
54
756
                       *e = Builder.getVTTVTables().end(); 
i != e756
;
++i503
) {
55
503
    VTableAddressPoints.push_back(VTableAddressPointsMapTy());
56
503
    VTables.push_back(GetAddrOfVTTVTable(*this, CGM, RD, *i, Linkage,
57
503
                                         VTableAddressPoints.back()));
58
503
  }
59
253
60
253
  SmallVector<llvm::Constant *, 8> VTTComponents;
61
253
  for (const VTTComponent *i = Builder.getVTTComponents().begin(),
62
1.41k
                          *e = Builder.getVTTComponents().end(); 
i != e1.41k
;
++i1.16k
) {
63
1.16k
    const VTTVTable &VTTVT = Builder.getVTTVTables()[i->VTableIndex];
64
1.16k
    llvm::GlobalVariable *VTable = VTables[i->VTableIndex];
65
1.16k
    VTableLayout::AddressPointLocation AddressPoint;
66
1.16k
    if (
VTTVT.getBase() == RD1.16k
) {
67
566
      // Just get the address point for the regular vtable.
68
566
      AddressPoint =
69
566
          getItaniumVTableContext().getVTableLayout(RD).getAddressPoint(
70
566
              i->VTableBase);
71
1.16k
    } else {
72
599
      AddressPoint = VTableAddressPoints[i->VTableIndex].lookup(i->VTableBase);
73
599
      assert(AddressPoint.AddressPointIndex != 0 &&
74
599
             "Did not find ctor vtable address point!");
75
599
    }
76
1.16k
77
1.16k
     llvm::Value *Idxs[] = {
78
1.16k
       llvm::ConstantInt::get(Int32Ty, 0),
79
1.16k
       llvm::ConstantInt::get(Int32Ty, AddressPoint.VTableIndex),
80
1.16k
       llvm::ConstantInt::get(Int32Ty, AddressPoint.AddressPointIndex),
81
1.16k
     };
82
1.16k
83
1.16k
     llvm::Constant *Init = llvm::ConstantExpr::getGetElementPtr(
84
1.16k
         VTable->getValueType(), VTable, Idxs, /*InBounds=*/true,
85
1.16k
         /*InRangeIndex=*/1);
86
1.16k
87
1.16k
     Init = llvm::ConstantExpr::getBitCast(Init, Int8PtrTy);
88
1.16k
89
1.16k
     VTTComponents.push_back(Init);
90
1.16k
  }
91
253
92
253
  llvm::Constant *Init = llvm::ConstantArray::get(ArrayType, VTTComponents);
93
253
94
253
  VTT->setInitializer(Init);
95
253
96
253
  // Set the correct linkage.
97
253
  VTT->setLinkage(Linkage);
98
253
99
253
  if (
CGM.supportsCOMDAT() && 253
VTT->isWeakForLinker()89
)
100
46
    VTT->setComdat(CGM.getModule().getOrInsertComdat(VTT->getName()));
101
253
102
253
  // Set the right visibility.
103
253
  CGM.setGlobalVisibility(VTT, RD);
104
253
}
105
106
383
llvm::GlobalVariable *CodeGenVTables::GetAddrOfVTT(const CXXRecordDecl *RD) {
107
383
  assert(RD->getNumVBases() && "Only classes with virtual bases need a VTT");
108
383
109
383
  SmallString<256> OutName;
110
383
  llvm::raw_svector_ostream Out(OutName);
111
383
  cast<ItaniumMangleContext>(CGM.getCXXABI().getMangleContext())
112
383
      .mangleCXXVTT(RD, Out);
113
383
  StringRef Name = OutName.str();
114
383
115
383
  // This will also defer the definition of the VTT.
116
383
  (void) CGM.getCXXABI().getAddrOfVTable(RD, CharUnits());
117
383
118
383
  VTTBuilder Builder(CGM.getContext(), RD, /*GenerateDefinition=*/false);
119
383
120
383
  llvm::ArrayType *ArrayType = 
121
383
    llvm::ArrayType::get(CGM.Int8PtrTy, Builder.getVTTComponents().size());
122
383
123
383
  llvm::GlobalVariable *GV =
124
383
    CGM.CreateOrReplaceCXXRuntimeVariable(Name, ArrayType, 
125
383
                                          llvm::GlobalValue::ExternalLinkage);
126
383
  GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
127
383
  return GV;
128
383
}
129
130
uint64_t CodeGenVTables::getSubVTTIndex(const CXXRecordDecl *RD, 
131
94
                                        BaseSubobject Base) {
132
94
  BaseSubobjectPairTy ClassSubobjectPair(RD, Base);
133
94
134
94
  SubVTTIndiciesMapTy::iterator I = SubVTTIndicies.find(ClassSubobjectPair);
135
94
  if (I != SubVTTIndicies.end())
136
40
    return I->second;
137
54
  
138
54
  VTTBuilder Builder(CGM.getContext(), RD, /*GenerateDefinition=*/false);
139
54
140
54
  for (llvm::DenseMap<BaseSubobject, uint64_t>::const_iterator I =
141
54
       Builder.getSubVTTIndicies().begin(), 
142
127
       E = Builder.getSubVTTIndicies().end(); 
I != E127
;
++I73
) {
143
73
    // Insert all indices.
144
73
    BaseSubobjectPairTy ClassSubobjectPair(RD, I->first);
145
73
    
146
73
    SubVTTIndicies.insert(std::make_pair(ClassSubobjectPair, I->second));
147
73
  }
148
94
    
149
94
  I = SubVTTIndicies.find(ClassSubobjectPair);
150
94
  assert(I != SubVTTIndicies.end() && "Did not find index!");
151
94
  
152
94
  return I->second;
153
94
}
154
155
uint64_t 
156
CodeGenVTables::getSecondaryVirtualPointerIndex(const CXXRecordDecl *RD,
157
180
                                                BaseSubobject Base) {
158
180
  SecondaryVirtualPointerIndicesMapTy::iterator I =
159
180
    SecondaryVirtualPointerIndices.find(std::make_pair(RD, Base));
160
180
161
180
  if (I != SecondaryVirtualPointerIndices.end())
162
76
    return I->second;
163
104
164
104
  VTTBuilder Builder(CGM.getContext(), RD, /*GenerateDefinition=*/false);
165
104
166
104
  // Insert all secondary vpointer indices.
167
104
  for (llvm::DenseMap<BaseSubobject, uint64_t>::const_iterator I = 
168
104
       Builder.getSecondaryVirtualPointerIndices().begin(),
169
268
       E = Builder.getSecondaryVirtualPointerIndices().end(); 
I != E268
;
++I164
) {
170
164
    std::pair<const CXXRecordDecl *, BaseSubobject> Pair =
171
164
      std::make_pair(RD, I->first);
172
164
    
173
164
    SecondaryVirtualPointerIndices.insert(std::make_pair(Pair, I->second));
174
164
  }
175
180
176
180
  I = SecondaryVirtualPointerIndices.find(std::make_pair(RD, Base));
177
180
  assert(I != SecondaryVirtualPointerIndices.end() && "Did not find index!");
178
180
  
179
180
  return I->second;
180
180
}