Coverage Report

Created: 2019-07-24 05:18

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