/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 | | |