Coverage Report

Created: 2020-02-25 14:32

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/AST/MicrosoftCXXABI.cpp
Line
Count
Source (jump to first uncovered line)
1
//===------- MicrosoftCXXABI.cpp - AST support for the Microsoft C++ ABI --===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
// This provides C++ AST support targeting the Microsoft Visual C++
10
// ABI.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#include "CXXABI.h"
15
#include "clang/AST/ASTContext.h"
16
#include "clang/AST/Attr.h"
17
#include "clang/AST/CXXInheritance.h"
18
#include "clang/AST/DeclCXX.h"
19
#include "clang/AST/MangleNumberingContext.h"
20
#include "clang/AST/RecordLayout.h"
21
#include "clang/AST/Type.h"
22
#include "clang/Basic/TargetInfo.h"
23
24
using namespace clang;
25
26
namespace {
27
28
/// Numbers things which need to correspond across multiple TUs.
29
/// Typically these are things like static locals, lambdas, or blocks.
30
class MicrosoftNumberingContext : public MangleNumberingContext {
31
  llvm::DenseMap<const Type *, unsigned> ManglingNumbers;
32
  unsigned LambdaManglingNumber;
33
  unsigned StaticLocalNumber;
34
  unsigned StaticThreadlocalNumber;
35
36
public:
37
  MicrosoftNumberingContext()
38
      : MangleNumberingContext(), LambdaManglingNumber(0),
39
372
        StaticLocalNumber(0), StaticThreadlocalNumber(0) {}
40
41
42
  unsigned getManglingNumber(const CXXMethodDecl *CallOperator) override {
42
42
    return ++LambdaManglingNumber;
43
42
  }
44
45
22
  unsigned getManglingNumber(const BlockDecl *BD) override {
46
22
    const Type *Ty = nullptr;
47
22
    return ++ManglingNumbers[Ty];
48
22
  }
49
50
109
  unsigned getStaticLocalNumber(const VarDecl *VD) override {
51
109
    if (VD->getTLSKind())
52
11
      return ++StaticThreadlocalNumber;
53
98
    return ++StaticLocalNumber;
54
98
  }
55
56
  unsigned getManglingNumber(const VarDecl *VD,
57
109
                             unsigned MSLocalManglingNumber) override {
58
109
    return MSLocalManglingNumber;
59
109
  }
60
61
  unsigned getManglingNumber(const TagDecl *TD,
62
237
                             unsigned MSLocalManglingNumber) override {
63
237
    return MSLocalManglingNumber;
64
237
  }
65
};
66
67
class MicrosoftCXXABI : public CXXABI {
68
  ASTContext &Context;
69
  llvm::SmallDenseMap<CXXRecordDecl *, CXXConstructorDecl *> RecordToCopyCtor;
70
71
  llvm::SmallDenseMap<TagDecl *, DeclaratorDecl *>
72
      UnnamedTagDeclToDeclaratorDecl;
73
  llvm::SmallDenseMap<TagDecl *, TypedefNameDecl *>
74
      UnnamedTagDeclToTypedefNameDecl;
75
76
public:
77
597
  MicrosoftCXXABI(ASTContext &Ctx) : Context(Ctx) { }
78
79
  MemberPointerInfo
80
  getMemberPointerInfo(const MemberPointerType *MPT) const override;
81
82
29.2k
  CallingConv getDefaultMethodCallConv(bool isVariadic) const override {
83
29.2k
    if (!isVariadic &&
84
29.2k
        
Context.getTargetInfo().getTriple().getArch() == llvm::Triple::x8629.1k
)
85
16.1k
      return CC_X86ThisCall;
86
13.0k
    return Context.getTargetInfo().getDefaultCallingConv();
87
13.0k
  }
88
89
0
  bool isNearlyEmpty(const CXXRecordDecl *RD) const override {
90
0
    llvm_unreachable("unapplicable to the MS ABI");
91
0
  }
92
93
  const CXXConstructorDecl *
94
50
  getCopyConstructorForExceptionObject(CXXRecordDecl *RD) override {
95
50
    return RecordToCopyCtor[RD];
96
50
  }
97
98
  void
99
  addCopyConstructorForExceptionObject(CXXRecordDecl *RD,
100
20
                                       CXXConstructorDecl *CD) override {
101
20
    assert(CD != nullptr);
102
20
    assert(RecordToCopyCtor[RD] == nullptr || RecordToCopyCtor[RD] == CD);
103
20
    RecordToCopyCtor[RD] = CD;
104
20
  }
105
106
  void addTypedefNameForUnnamedTagDecl(TagDecl *TD,
107
10
                                       TypedefNameDecl *DD) override {
108
10
    TD = TD->getCanonicalDecl();
109
10
    DD = DD->getCanonicalDecl();
110
10
    TypedefNameDecl *&I = UnnamedTagDeclToTypedefNameDecl[TD];
111
10
    if (!I)
112
10
      I = DD;
113
10
  }
114
115
1.19k
  TypedefNameDecl *getTypedefNameForUnnamedTagDecl(const TagDecl *TD) override {
116
1.19k
    return UnnamedTagDeclToTypedefNameDecl.lookup(
117
1.19k
        const_cast<TagDecl *>(TD->getCanonicalDecl()));
118
1.19k
  }
119
120
  void addDeclaratorForUnnamedTagDecl(TagDecl *TD,
121
42
                                      DeclaratorDecl *DD) override {
122
42
    TD = TD->getCanonicalDecl();
123
42
    DD = cast<DeclaratorDecl>(DD->getCanonicalDecl());
124
42
    DeclaratorDecl *&I = UnnamedTagDeclToDeclaratorDecl[TD];
125
42
    if (!I)
126
42
      I = DD;
127
42
  }
128
129
1.27k
  DeclaratorDecl *getDeclaratorForUnnamedTagDecl(const TagDecl *TD) override {
130
1.27k
    return UnnamedTagDeclToDeclaratorDecl.lookup(
131
1.27k
        const_cast<TagDecl *>(TD->getCanonicalDecl()));
132
1.27k
  }
133
134
  std::unique_ptr<MangleNumberingContext>
135
372
  createMangleNumberingContext() const override {
136
372
    return std::make_unique<MicrosoftNumberingContext>();
137
372
  }
138
};
139
}
140
141
// getNumBases() seems to only give us the number of direct bases, and not the
142
// total.  This function tells us if we inherit from anybody that uses MI, or if
143
// we have a non-primary base class, which uses the multiple inheritance model.
144
455
static bool usesMultipleInheritanceModel(const CXXRecordDecl *RD) {
145
549
  while (RD->getNumBases() > 0) {
146
121
    if (RD->getNumBases() > 1)
147
19
      return true;
148
102
    assert(RD->getNumBases() == 1);
149
102
    const CXXRecordDecl *Base =
150
102
        RD->bases_begin()->getType()->getAsCXXRecordDecl();
151
102
    if (RD->isPolymorphic() && 
!Base->isPolymorphic()15
)
152
8
      return true;
153
94
    RD = Base;
154
94
  }
155
455
  
return false428
;
156
455
}
157
158
556
MSInheritanceModel CXXRecordDecl::calculateInheritanceModel() const {
159
556
  if (!hasDefinition() || 
isParsingBaseSpecifiers()488
)
160
70
    return MSInheritanceModel::Unspecified;
161
486
  if (getNumVBases() > 0)
162
31
    return MSInheritanceModel::Virtual;
163
455
  if (usesMultipleInheritanceModel(this))
164
27
    return MSInheritanceModel::Multiple;
165
428
  return MSInheritanceModel::Single;
166
428
}
167
168
2.66k
MSInheritanceModel CXXRecordDecl::getMSInheritanceModel() const {
169
2.66k
  MSInheritanceAttr *IA = getAttr<MSInheritanceAttr>();
170
2.66k
  assert(IA && "Expected MSInheritanceAttr on the CXXRecordDecl!");
171
2.66k
  return IA->getInheritanceModel();
172
2.66k
}
173
174
143
bool CXXRecordDecl::nullFieldOffsetIsZero() const {
175
143
  return !inheritanceModelHasOnlyOneField(/*IsMemberFunction=*/false,
176
143
                                          getMSInheritanceModel()) ||
177
143
         
(99
hasDefinition()99
&&
isPolymorphic()97
);
178
143
}
179
180
1.67k
MSVtorDispMode CXXRecordDecl::getMSVtorDispMode() const {
181
1.67k
  if (MSVtorDispAttr *VDA = getAttr<MSVtorDispAttr>())
182
26
    return VDA->getVtorDispMode();
183
1.64k
  return getASTContext().getLangOpts().getVtorDispMode();
184
1.64k
}
185
186
// Returns the number of pointer and integer slots used to represent a member
187
// pointer in the MS C++ ABI.
188
//
189
// Member function pointers have the following general form;  however, fields
190
// are dropped as permitted (under the MSVC interpretation) by the inheritance
191
// model of the actual class.
192
//
193
//   struct {
194
//     // A pointer to the member function to call.  If the member function is
195
//     // virtual, this will be a thunk that forwards to the appropriate vftable
196
//     // slot.
197
//     void *FunctionPointerOrVirtualThunk;
198
//
199
//     // An offset to add to the address of the vbtable pointer after
200
//     // (possibly) selecting the virtual base but before resolving and calling
201
//     // the function.
202
//     // Only needed if the class has any virtual bases or bases at a non-zero
203
//     // offset.
204
//     int NonVirtualBaseAdjustment;
205
//
206
//     // The offset of the vb-table pointer within the object.  Only needed for
207
//     // incomplete types.
208
//     int VBPtrOffset;
209
//
210
//     // An offset within the vb-table that selects the virtual base containing
211
//     // the member.  Loading from this offset produces a new offset that is
212
//     // added to the address of the vb-table pointer to produce the base.
213
//     int VirtualBaseAdjustmentOffset;
214
//   };
215
static std::pair<unsigned, unsigned>
216
844
getMSMemberPointerSlots(const MemberPointerType *MPT) {
217
844
  const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
218
844
  MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
219
844
  unsigned Ptrs = 0;
220
844
  unsigned Ints = 0;
221
844
  if (MPT->isMemberFunctionPointer())
222
673
    Ptrs = 1;
223
171
  else
224
171
    Ints = 1;
225
844
  if (inheritanceModelHasNVOffsetField(MPT->isMemberFunctionPointer(),
226
844
                                          Inheritance))
227
140
    Ints++;
228
844
  if (inheritanceModelHasVBPtrOffsetField(Inheritance))
229
159
    Ints++;
230
844
  if (inheritanceModelHasVBTableOffsetField(Inheritance))
231
208
    Ints++;
232
844
  return std::make_pair(Ptrs, Ints);
233
844
}
234
235
CXXABI::MemberPointerInfo MicrosoftCXXABI::getMemberPointerInfo(
236
844
    const MemberPointerType *MPT) const {
237
844
  // The nominal struct is laid out with pointers followed by ints and aligned
238
844
  // to a pointer width if any are present and an int width otherwise.
239
844
  const TargetInfo &Target = Context.getTargetInfo();
240
844
  unsigned PtrSize = Target.getPointerWidth(0);
241
844
  unsigned IntSize = Target.getIntWidth();
242
844
243
844
  unsigned Ptrs, Ints;
244
844
  std::tie(Ptrs, Ints) = getMSMemberPointerSlots(MPT);
245
844
  MemberPointerInfo MPI;
246
844
  MPI.HasPadding = false;
247
844
  MPI.Width = Ptrs * PtrSize + Ints * IntSize;
248
844
249
844
  // When MSVC does x86_32 record layout, it aligns aggregate member pointers to
250
844
  // 8 bytes.  However, __alignof usually returns 4 for data memptrs and 8 for
251
844
  // function memptrs.
252
844
  if (Ptrs + Ints > 1 && 
Target.getTriple().isArch32Bit()230
)
253
102
    MPI.Align = 64;
254
742
  else if (Ptrs)
255
608
    MPI.Align = Target.getPointerAlign(0);
256
134
  else
257
134
    MPI.Align = Target.getIntAlign();
258
844
259
844
  if (Target.getTriple().isArch64Bit()) {
260
355
    MPI.Width = llvm::alignTo(MPI.Width, MPI.Align);
261
355
    MPI.HasPadding = MPI.Width != (Ptrs * PtrSize + Ints * IntSize);
262
355
  }
263
844
  return MPI;
264
844
}
265
266
597
CXXABI *clang::CreateMicrosoftCXXABI(ASTContext &Ctx) {
267
597
  return new MicrosoftCXXABI(Ctx);
268
597
}
269