Coverage Report

Created: 2017-10-03 07:32

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/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
//                     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 provides C++ AST support targeting the Microsoft Visual C++
11
// ABI.
12
//
13
//===----------------------------------------------------------------------===//
14
15
#include "CXXABI.h"
16
#include "clang/AST/ASTContext.h"
17
#include "clang/AST/Attr.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
/// \brief 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
241
        StaticLocalNumber(0), StaticThreadlocalNumber(0) {}
40
41
30
  unsigned getManglingNumber(const CXXMethodDecl *CallOperator) override {
42
30
    return ++LambdaManglingNumber;
43
30
  }
44
45
22
  unsigned getManglingNumber(const BlockDecl *BD) override {
46
22
    const Type *Ty = nullptr;
47
22
    return ++ManglingNumbers[Ty];
48
22
  }
49
50
61
  unsigned getStaticLocalNumber(const VarDecl *VD) override {
51
61
    if (VD->getTLSKind())
52
9
      return ++StaticThreadlocalNumber;
53
52
    return ++StaticLocalNumber;
54
52
  }
55
56
  unsigned getManglingNumber(const VarDecl *VD,
57
61
                             unsigned MSLocalManglingNumber) override {
58
61
    return MSLocalManglingNumber;
59
61
  }
60
61
  unsigned getManglingNumber(const TagDecl *TD,
62
155
                             unsigned MSLocalManglingNumber) override {
63
155
    return MSLocalManglingNumber;
64
155
  }
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
409
  MicrosoftCXXABI(ASTContext &Ctx) : Context(Ctx) { }
78
79
  std::pair<uint64_t, unsigned>
80
  getMemberPointerWidthAndAlign(const MemberPointerType *MPT) const override;
81
82
22.4k
  CallingConv getDefaultMethodCallConv(bool isVariadic) const override {
83
22.4k
    if (!isVariadic &&
84
22.3k
        Context.getTargetInfo().getTriple().getArch() == llvm::Triple::x86)
85
13.0k
      return CC_X86ThisCall;
86
9.37k
    return CC_C;
87
9.37k
  }
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
26
  getCopyConstructorForExceptionObject(CXXRecordDecl *RD) override {
95
26
    return RecordToCopyCtor[RD];
96
26
  }
97
98
  void
99
  addCopyConstructorForExceptionObject(CXXRecordDecl *RD,
100
14
                                       CXXConstructorDecl *CD) override {
101
14
    assert(CD != nullptr);
102
14
    assert(RecordToCopyCtor[RD] == nullptr || RecordToCopyCtor[RD] == CD);
103
14
    RecordToCopyCtor[RD] = CD;
104
14
  }
105
106
  void addTypedefNameForUnnamedTagDecl(TagDecl *TD,
107
7
                                       TypedefNameDecl *DD) override {
108
7
    TD = TD->getCanonicalDecl();
109
7
    DD = cast<TypedefNameDecl>(DD->getCanonicalDecl());
110
7
    TypedefNameDecl *&I = UnnamedTagDeclToTypedefNameDecl[TD];
111
7
    if (!I)
112
7
      I = DD;
113
7
  }
114
115
804
  TypedefNameDecl *getTypedefNameForUnnamedTagDecl(const TagDecl *TD) override {
116
804
    return UnnamedTagDeclToTypedefNameDecl.lookup(
117
804
        const_cast<TagDecl *>(TD->getCanonicalDecl()));
118
804
  }
119
120
  void addDeclaratorForUnnamedTagDecl(TagDecl *TD,
121
30
                                      DeclaratorDecl *DD) override {
122
30
    TD = TD->getCanonicalDecl();
123
30
    DD = cast<DeclaratorDecl>(DD->getCanonicalDecl());
124
30
    DeclaratorDecl *&I = UnnamedTagDeclToDeclaratorDecl[TD];
125
30
    if (!I)
126
30
      I = DD;
127
30
  }
128
129
840
  DeclaratorDecl *getDeclaratorForUnnamedTagDecl(const TagDecl *TD) override {
130
840
    return UnnamedTagDeclToDeclaratorDecl.lookup(
131
840
        const_cast<TagDecl *>(TD->getCanonicalDecl()));
132
840
  }
133
134
  std::unique_ptr<MangleNumberingContext>
135
241
  createMangleNumberingContext() const override {
136
241
    return llvm::make_unique<MicrosoftNumberingContext>();
137
241
  }
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
422
static bool usesMultipleInheritanceModel(const CXXRecordDecl *RD) {
145
511
  while (
RD->getNumBases() > 0511
) {
146
116
    if (RD->getNumBases() > 1)
147
19
      return true;
148
116
    assert(RD->getNumBases() == 1);
149
97
    const CXXRecordDecl *Base =
150
97
        RD->bases_begin()->getType()->getAsCXXRecordDecl();
151
97
    if (
RD->isPolymorphic() && 97
!Base->isPolymorphic()15
)
152
8
      return true;
153
89
    RD = Base;
154
89
  }
155
395
  return false;
156
422
}
157
158
503
MSInheritanceAttr::Spelling CXXRecordDecl::calculateInheritanceModel() const {
159
503
  if (
!hasDefinition() || 503
isParsingBaseSpecifiers()453
)
160
52
    return MSInheritanceAttr::Keyword_unspecified_inheritance;
161
451
  
if (451
getNumVBases() > 0451
)
162
29
    return MSInheritanceAttr::Keyword_virtual_inheritance;
163
422
  
if (422
usesMultipleInheritanceModel(this)422
)
164
27
    return MSInheritanceAttr::Keyword_multiple_inheritance;
165
395
  return MSInheritanceAttr::Keyword_single_inheritance;
166
395
}
167
168
MSInheritanceAttr::Spelling
169
2.33k
CXXRecordDecl::getMSInheritanceModel() const {
170
2.33k
  MSInheritanceAttr *IA = getAttr<MSInheritanceAttr>();
171
2.33k
  assert(IA && "Expected MSInheritanceAttr on the CXXRecordDecl!");
172
2.33k
  return IA->getSemanticSpelling();
173
2.33k
}
174
175
1.20k
MSVtorDispAttr::Mode CXXRecordDecl::getMSVtorDispMode() const {
176
1.20k
  if (MSVtorDispAttr *VDA = getAttr<MSVtorDispAttr>())
177
26
    return VDA->getVtorDispMode();
178
1.18k
  return MSVtorDispAttr::Mode(getASTContext().getLangOpts().VtorDispMode);
179
1.18k
}
180
181
// Returns the number of pointer and integer slots used to represent a member
182
// pointer in the MS C++ ABI.
183
//
184
// Member function pointers have the following general form;  however, fields
185
// are dropped as permitted (under the MSVC interpretation) by the inheritance
186
// model of the actual class.
187
//
188
//   struct {
189
//     // A pointer to the member function to call.  If the member function is
190
//     // virtual, this will be a thunk that forwards to the appropriate vftable
191
//     // slot.
192
//     void *FunctionPointerOrVirtualThunk;
193
//
194
//     // An offset to add to the address of the vbtable pointer after
195
//     // (possibly) selecting the virtual base but before resolving and calling
196
//     // the function.
197
//     // Only needed if the class has any virtual bases or bases at a non-zero
198
//     // offset.
199
//     int NonVirtualBaseAdjustment;
200
//
201
//     // The offset of the vb-table pointer within the object.  Only needed for
202
//     // incomplete types.
203
//     int VBPtrOffset;
204
//
205
//     // An offset within the vb-table that selects the virtual base containing
206
//     // the member.  Loading from this offset produces a new offset that is
207
//     // added to the address of the vb-table pointer to produce the base.
208
//     int VirtualBaseAdjustmentOffset;
209
//   };
210
static std::pair<unsigned, unsigned>
211
799
getMSMemberPointerSlots(const MemberPointerType *MPT) {
212
799
  const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
213
799
  MSInheritanceAttr::Spelling Inheritance = RD->getMSInheritanceModel();
214
799
  unsigned Ptrs = 0;
215
799
  unsigned Ints = 0;
216
799
  if (MPT->isMemberFunctionPointer())
217
641
    Ptrs = 1;
218
799
  else
219
158
    Ints = 1;
220
799
  if (MSInheritanceAttr::hasNVOffsetField(MPT->isMemberFunctionPointer(),
221
799
                                          Inheritance))
222
116
    Ints++;
223
799
  if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance))
224
131
    Ints++;
225
799
  if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance))
226
176
    Ints++;
227
799
  return std::make_pair(Ptrs, Ints);
228
799
}
229
230
std::pair<uint64_t, unsigned> MicrosoftCXXABI::getMemberPointerWidthAndAlign(
231
799
    const MemberPointerType *MPT) const {
232
799
  // The nominal struct is laid out with pointers followed by ints and aligned
233
799
  // to a pointer width if any are present and an int width otherwise.
234
799
  const TargetInfo &Target = Context.getTargetInfo();
235
799
  unsigned PtrSize = Target.getPointerWidth(0);
236
799
  unsigned IntSize = Target.getIntWidth();
237
799
238
799
  unsigned Ptrs, Ints;
239
799
  std::tie(Ptrs, Ints) = getMSMemberPointerSlots(MPT);
240
799
  uint64_t Width = Ptrs * PtrSize + Ints * IntSize;
241
799
  unsigned Align;
242
799
243
799
  // When MSVC does x86_32 record layout, it aligns aggregate member pointers to
244
799
  // 8 bytes.  However, __alignof usually returns 4 for data memptrs and 8 for
245
799
  // function memptrs.
246
799
  if (
Ptrs + Ints > 1 && 799
Target.getTriple().isArch32Bit()199
)
247
88
    Align = 64;
248
711
  else 
if (711
Ptrs711
)
249
587
    Align = Target.getPointerAlign(0);
250
711
  else
251
124
    Align = Target.getIntAlign();
252
799
253
799
  if (Target.getTriple().isArch64Bit())
254
328
    Width = llvm::alignTo(Width, Align);
255
799
  return std::make_pair(Width, Align);
256
799
}
257
258
409
CXXABI *clang::CreateMicrosoftCXXABI(ASTContext &Ctx) {
259
409
  return new MicrosoftCXXABI(Ctx);
260
409
}
261