File: | clang/lib/AST/DeclCXX.cpp |
Warning: | line 2344, column 38 Called C++ object pointer is null |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | //===- DeclCXX.cpp - C++ Declaration AST Node Implementation --------------===// | |||
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 file implements the C++ related Decl classes. | |||
10 | // | |||
11 | //===----------------------------------------------------------------------===// | |||
12 | ||||
13 | #include "clang/AST/DeclCXX.h" | |||
14 | #include "clang/AST/ASTContext.h" | |||
15 | #include "clang/AST/ASTLambda.h" | |||
16 | #include "clang/AST/ASTMutationListener.h" | |||
17 | #include "clang/AST/ASTUnresolvedSet.h" | |||
18 | #include "clang/AST/Attr.h" | |||
19 | #include "clang/AST/CXXInheritance.h" | |||
20 | #include "clang/AST/DeclBase.h" | |||
21 | #include "clang/AST/DeclTemplate.h" | |||
22 | #include "clang/AST/DeclarationName.h" | |||
23 | #include "clang/AST/Expr.h" | |||
24 | #include "clang/AST/ExprCXX.h" | |||
25 | #include "clang/AST/LambdaCapture.h" | |||
26 | #include "clang/AST/NestedNameSpecifier.h" | |||
27 | #include "clang/AST/ODRHash.h" | |||
28 | #include "clang/AST/Type.h" | |||
29 | #include "clang/AST/TypeLoc.h" | |||
30 | #include "clang/AST/UnresolvedSet.h" | |||
31 | #include "clang/Basic/Diagnostic.h" | |||
32 | #include "clang/Basic/IdentifierTable.h" | |||
33 | #include "clang/Basic/LLVM.h" | |||
34 | #include "clang/Basic/LangOptions.h" | |||
35 | #include "clang/Basic/OperatorKinds.h" | |||
36 | #include "clang/Basic/PartialDiagnostic.h" | |||
37 | #include "clang/Basic/SourceLocation.h" | |||
38 | #include "clang/Basic/Specifiers.h" | |||
39 | #include "llvm/ADT/None.h" | |||
40 | #include "llvm/ADT/SmallPtrSet.h" | |||
41 | #include "llvm/ADT/SmallVector.h" | |||
42 | #include "llvm/ADT/iterator_range.h" | |||
43 | #include "llvm/Support/Casting.h" | |||
44 | #include "llvm/Support/ErrorHandling.h" | |||
45 | #include "llvm/Support/raw_ostream.h" | |||
46 | #include <algorithm> | |||
47 | #include <cassert> | |||
48 | #include <cstddef> | |||
49 | #include <cstdint> | |||
50 | ||||
51 | using namespace clang; | |||
52 | ||||
53 | //===----------------------------------------------------------------------===// | |||
54 | // Decl Allocation/Deallocation Method Implementations | |||
55 | //===----------------------------------------------------------------------===// | |||
56 | ||||
57 | void AccessSpecDecl::anchor() {} | |||
58 | ||||
59 | AccessSpecDecl *AccessSpecDecl::CreateDeserialized(ASTContext &C, unsigned ID) { | |||
60 | return new (C, ID) AccessSpecDecl(EmptyShell()); | |||
61 | } | |||
62 | ||||
63 | void LazyASTUnresolvedSet::getFromExternalSource(ASTContext &C) const { | |||
64 | ExternalASTSource *Source = C.getExternalSource(); | |||
65 | assert(Impl.Decls.isLazy() && "getFromExternalSource for non-lazy set")((Impl.Decls.isLazy() && "getFromExternalSource for non-lazy set" ) ? static_cast<void> (0) : __assert_fail ("Impl.Decls.isLazy() && \"getFromExternalSource for non-lazy set\"" , "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/AST/DeclCXX.cpp" , 65, __PRETTY_FUNCTION__)); | |||
66 | assert(Source && "getFromExternalSource with no external source")((Source && "getFromExternalSource with no external source" ) ? static_cast<void> (0) : __assert_fail ("Source && \"getFromExternalSource with no external source\"" , "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/AST/DeclCXX.cpp" , 66, __PRETTY_FUNCTION__)); | |||
67 | ||||
68 | for (ASTUnresolvedSet::iterator I = Impl.begin(); I != Impl.end(); ++I) | |||
69 | I.setDecl(cast<NamedDecl>(Source->GetExternalDecl( | |||
70 | reinterpret_cast<uintptr_t>(I.getDecl()) >> 2))); | |||
71 | Impl.Decls.setLazy(false); | |||
72 | } | |||
73 | ||||
74 | CXXRecordDecl::DefinitionData::DefinitionData(CXXRecordDecl *D) | |||
75 | : UserDeclaredConstructor(false), UserDeclaredSpecialMembers(0), | |||
76 | Aggregate(true), PlainOldData(true), Empty(true), Polymorphic(false), | |||
77 | Abstract(false), IsStandardLayout(true), IsCXX11StandardLayout(true), | |||
78 | HasBasesWithFields(false), HasBasesWithNonStaticDataMembers(false), | |||
79 | HasPrivateFields(false), HasProtectedFields(false), | |||
80 | HasPublicFields(false), HasMutableFields(false), HasVariantMembers(false), | |||
81 | HasOnlyCMembers(true), HasInClassInitializer(false), | |||
82 | HasUninitializedReferenceMember(false), HasUninitializedFields(false), | |||
83 | HasInheritedConstructor(false), HasInheritedAssignment(false), | |||
84 | NeedOverloadResolutionForCopyConstructor(false), | |||
85 | NeedOverloadResolutionForMoveConstructor(false), | |||
86 | NeedOverloadResolutionForMoveAssignment(false), | |||
87 | NeedOverloadResolutionForDestructor(false), | |||
88 | DefaultedCopyConstructorIsDeleted(false), | |||
89 | DefaultedMoveConstructorIsDeleted(false), | |||
90 | DefaultedMoveAssignmentIsDeleted(false), | |||
91 | DefaultedDestructorIsDeleted(false), HasTrivialSpecialMembers(SMF_All), | |||
92 | HasTrivialSpecialMembersForCall(SMF_All), | |||
93 | DeclaredNonTrivialSpecialMembers(0), | |||
94 | DeclaredNonTrivialSpecialMembersForCall(0), HasIrrelevantDestructor(true), | |||
95 | HasConstexprNonCopyMoveConstructor(false), | |||
96 | HasDefaultedDefaultConstructor(false), | |||
97 | DefaultedDefaultConstructorIsConstexpr(true), | |||
98 | HasConstexprDefaultConstructor(false), | |||
99 | DefaultedDestructorIsConstexpr(true), | |||
100 | HasNonLiteralTypeFieldsOrBases(false), | |||
101 | UserProvidedDefaultConstructor(false), DeclaredSpecialMembers(0), | |||
102 | ImplicitCopyConstructorCanHaveConstParamForVBase(true), | |||
103 | ImplicitCopyConstructorCanHaveConstParamForNonVBase(true), | |||
104 | ImplicitCopyAssignmentHasConstParam(true), | |||
105 | HasDeclaredCopyConstructorWithConstParam(false), | |||
106 | HasDeclaredCopyAssignmentWithConstParam(false), IsLambda(false), | |||
107 | IsParsingBaseSpecifiers(false), ComputedVisibleConversions(false), | |||
108 | HasODRHash(false), Definition(D) {} | |||
109 | ||||
110 | CXXBaseSpecifier *CXXRecordDecl::DefinitionData::getBasesSlowCase() const { | |||
111 | return Bases.get(Definition->getASTContext().getExternalSource()); | |||
112 | } | |||
113 | ||||
114 | CXXBaseSpecifier *CXXRecordDecl::DefinitionData::getVBasesSlowCase() const { | |||
115 | return VBases.get(Definition->getASTContext().getExternalSource()); | |||
116 | } | |||
117 | ||||
118 | CXXRecordDecl::CXXRecordDecl(Kind K, TagKind TK, const ASTContext &C, | |||
119 | DeclContext *DC, SourceLocation StartLoc, | |||
120 | SourceLocation IdLoc, IdentifierInfo *Id, | |||
121 | CXXRecordDecl *PrevDecl) | |||
122 | : RecordDecl(K, TK, C, DC, StartLoc, IdLoc, Id, PrevDecl), | |||
123 | DefinitionData(PrevDecl ? PrevDecl->DefinitionData | |||
124 | : nullptr) {} | |||
125 | ||||
126 | CXXRecordDecl *CXXRecordDecl::Create(const ASTContext &C, TagKind TK, | |||
127 | DeclContext *DC, SourceLocation StartLoc, | |||
128 | SourceLocation IdLoc, IdentifierInfo *Id, | |||
129 | CXXRecordDecl *PrevDecl, | |||
130 | bool DelayTypeCreation) { | |||
131 | auto *R = new (C, DC) CXXRecordDecl(CXXRecord, TK, C, DC, StartLoc, IdLoc, Id, | |||
132 | PrevDecl); | |||
133 | R->setMayHaveOutOfDateDef(C.getLangOpts().Modules); | |||
134 | ||||
135 | // FIXME: DelayTypeCreation seems like such a hack | |||
136 | if (!DelayTypeCreation) | |||
137 | C.getTypeDeclType(R, PrevDecl); | |||
138 | return R; | |||
139 | } | |||
140 | ||||
141 | CXXRecordDecl * | |||
142 | CXXRecordDecl::CreateLambda(const ASTContext &C, DeclContext *DC, | |||
143 | TypeSourceInfo *Info, SourceLocation Loc, | |||
144 | bool Dependent, bool IsGeneric, | |||
145 | LambdaCaptureDefault CaptureDefault) { | |||
146 | auto *R = new (C, DC) CXXRecordDecl(CXXRecord, TTK_Class, C, DC, Loc, Loc, | |||
147 | nullptr, nullptr); | |||
148 | R->setBeingDefined(true); | |||
149 | R->DefinitionData = | |||
150 | new (C) struct LambdaDefinitionData(R, Info, Dependent, IsGeneric, | |||
151 | CaptureDefault); | |||
152 | R->setMayHaveOutOfDateDef(false); | |||
153 | R->setImplicit(true); | |||
154 | C.getTypeDeclType(R, /*PrevDecl=*/nullptr); | |||
155 | return R; | |||
156 | } | |||
157 | ||||
158 | CXXRecordDecl * | |||
159 | CXXRecordDecl::CreateDeserialized(const ASTContext &C, unsigned ID) { | |||
160 | auto *R = new (C, ID) CXXRecordDecl( | |||
161 | CXXRecord, TTK_Struct, C, nullptr, SourceLocation(), SourceLocation(), | |||
162 | nullptr, nullptr); | |||
163 | R->setMayHaveOutOfDateDef(false); | |||
164 | return R; | |||
165 | } | |||
166 | ||||
167 | /// Determine whether a class has a repeated base class. This is intended for | |||
168 | /// use when determining if a class is standard-layout, so makes no attempt to | |||
169 | /// handle virtual bases. | |||
170 | static bool hasRepeatedBaseClass(const CXXRecordDecl *StartRD) { | |||
171 | llvm::SmallPtrSet<const CXXRecordDecl*, 8> SeenBaseTypes; | |||
172 | SmallVector<const CXXRecordDecl*, 8> WorkList = {StartRD}; | |||
173 | while (!WorkList.empty()) { | |||
174 | const CXXRecordDecl *RD = WorkList.pop_back_val(); | |||
175 | for (const CXXBaseSpecifier &BaseSpec : RD->bases()) { | |||
176 | if (const CXXRecordDecl *B = BaseSpec.getType()->getAsCXXRecordDecl()) { | |||
177 | if (!SeenBaseTypes.insert(B).second) | |||
178 | return true; | |||
179 | WorkList.push_back(B); | |||
180 | } | |||
181 | } | |||
182 | } | |||
183 | return false; | |||
184 | } | |||
185 | ||||
186 | void | |||
187 | CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases, | |||
188 | unsigned NumBases) { | |||
189 | ASTContext &C = getASTContext(); | |||
190 | ||||
191 | if (!data().Bases.isOffset() && data().NumBases > 0) | |||
192 | C.Deallocate(data().getBases()); | |||
193 | ||||
194 | if (NumBases) { | |||
195 | if (!C.getLangOpts().CPlusPlus17) { | |||
196 | // C++ [dcl.init.aggr]p1: | |||
197 | // An aggregate is [...] a class with [...] no base classes [...]. | |||
198 | data().Aggregate = false; | |||
199 | } | |||
200 | ||||
201 | // C++ [class]p4: | |||
202 | // A POD-struct is an aggregate class... | |||
203 | data().PlainOldData = false; | |||
204 | } | |||
205 | ||||
206 | // The set of seen virtual base types. | |||
207 | llvm::SmallPtrSet<CanQualType, 8> SeenVBaseTypes; | |||
208 | ||||
209 | // The virtual bases of this class. | |||
210 | SmallVector<const CXXBaseSpecifier *, 8> VBases; | |||
211 | ||||
212 | data().Bases = new(C) CXXBaseSpecifier [NumBases]; | |||
213 | data().NumBases = NumBases; | |||
214 | for (unsigned i = 0; i < NumBases; ++i) { | |||
215 | data().getBases()[i] = *Bases[i]; | |||
216 | // Keep track of inherited vbases for this base class. | |||
217 | const CXXBaseSpecifier *Base = Bases[i]; | |||
218 | QualType BaseType = Base->getType(); | |||
219 | // Skip dependent types; we can't do any checking on them now. | |||
220 | if (BaseType->isDependentType()) | |||
221 | continue; | |||
222 | auto *BaseClassDecl = | |||
223 | cast<CXXRecordDecl>(BaseType->castAs<RecordType>()->getDecl()); | |||
224 | ||||
225 | // C++2a [class]p7: | |||
226 | // A standard-layout class is a class that: | |||
227 | // [...] | |||
228 | // -- has all non-static data members and bit-fields in the class and | |||
229 | // its base classes first declared in the same class | |||
230 | if (BaseClassDecl->data().HasBasesWithFields || | |||
231 | !BaseClassDecl->field_empty()) { | |||
232 | if (data().HasBasesWithFields) | |||
233 | // Two bases have members or bit-fields: not standard-layout. | |||
234 | data().IsStandardLayout = false; | |||
235 | data().HasBasesWithFields = true; | |||
236 | } | |||
237 | ||||
238 | // C++11 [class]p7: | |||
239 | // A standard-layout class is a class that: | |||
240 | // -- [...] has [...] at most one base class with non-static data | |||
241 | // members | |||
242 | if (BaseClassDecl->data().HasBasesWithNonStaticDataMembers || | |||
243 | BaseClassDecl->hasDirectFields()) { | |||
244 | if (data().HasBasesWithNonStaticDataMembers) | |||
245 | data().IsCXX11StandardLayout = false; | |||
246 | data().HasBasesWithNonStaticDataMembers = true; | |||
247 | } | |||
248 | ||||
249 | if (!BaseClassDecl->isEmpty()) { | |||
250 | // C++14 [meta.unary.prop]p4: | |||
251 | // T is a class type [...] with [...] no base class B for which | |||
252 | // is_empty<B>::value is false. | |||
253 | data().Empty = false; | |||
254 | } | |||
255 | ||||
256 | // C++1z [dcl.init.agg]p1: | |||
257 | // An aggregate is a class with [...] no private or protected base classes | |||
258 | if (Base->getAccessSpecifier() != AS_public) | |||
259 | data().Aggregate = false; | |||
260 | ||||
261 | // C++ [class.virtual]p1: | |||
262 | // A class that declares or inherits a virtual function is called a | |||
263 | // polymorphic class. | |||
264 | if (BaseClassDecl->isPolymorphic()) { | |||
265 | data().Polymorphic = true; | |||
266 | ||||
267 | // An aggregate is a class with [...] no virtual functions. | |||
268 | data().Aggregate = false; | |||
269 | } | |||
270 | ||||
271 | // C++0x [class]p7: | |||
272 | // A standard-layout class is a class that: [...] | |||
273 | // -- has no non-standard-layout base classes | |||
274 | if (!BaseClassDecl->isStandardLayout()) | |||
275 | data().IsStandardLayout = false; | |||
276 | if (!BaseClassDecl->isCXX11StandardLayout()) | |||
277 | data().IsCXX11StandardLayout = false; | |||
278 | ||||
279 | // Record if this base is the first non-literal field or base. | |||
280 | if (!hasNonLiteralTypeFieldsOrBases() && !BaseType->isLiteralType(C)) | |||
281 | data().HasNonLiteralTypeFieldsOrBases = true; | |||
282 | ||||
283 | // Now go through all virtual bases of this base and add them. | |||
284 | for (const auto &VBase : BaseClassDecl->vbases()) { | |||
285 | // Add this base if it's not already in the list. | |||
286 | if (SeenVBaseTypes.insert(C.getCanonicalType(VBase.getType())).second) { | |||
287 | VBases.push_back(&VBase); | |||
288 | ||||
289 | // C++11 [class.copy]p8: | |||
290 | // The implicitly-declared copy constructor for a class X will have | |||
291 | // the form 'X::X(const X&)' if each [...] virtual base class B of X | |||
292 | // has a copy constructor whose first parameter is of type | |||
293 | // 'const B&' or 'const volatile B&' [...] | |||
294 | if (CXXRecordDecl *VBaseDecl = VBase.getType()->getAsCXXRecordDecl()) | |||
295 | if (!VBaseDecl->hasCopyConstructorWithConstParam()) | |||
296 | data().ImplicitCopyConstructorCanHaveConstParamForVBase = false; | |||
297 | ||||
298 | // C++1z [dcl.init.agg]p1: | |||
299 | // An aggregate is a class with [...] no virtual base classes | |||
300 | data().Aggregate = false; | |||
301 | } | |||
302 | } | |||
303 | ||||
304 | if (Base->isVirtual()) { | |||
305 | // Add this base if it's not already in the list. | |||
306 | if (SeenVBaseTypes.insert(C.getCanonicalType(BaseType)).second) | |||
307 | VBases.push_back(Base); | |||
308 | ||||
309 | // C++14 [meta.unary.prop] is_empty: | |||
310 | // T is a class type, but not a union type, with ... no virtual base | |||
311 | // classes | |||
312 | data().Empty = false; | |||
313 | ||||
314 | // C++1z [dcl.init.agg]p1: | |||
315 | // An aggregate is a class with [...] no virtual base classes | |||
316 | data().Aggregate = false; | |||
317 | ||||
318 | // C++11 [class.ctor]p5, C++11 [class.copy]p12, C++11 [class.copy]p25: | |||
319 | // A [default constructor, copy/move constructor, or copy/move assignment | |||
320 | // operator for a class X] is trivial [...] if: | |||
321 | // -- class X has [...] no virtual base classes | |||
322 | data().HasTrivialSpecialMembers &= SMF_Destructor; | |||
323 | data().HasTrivialSpecialMembersForCall &= SMF_Destructor; | |||
324 | ||||
325 | // C++0x [class]p7: | |||
326 | // A standard-layout class is a class that: [...] | |||
327 | // -- has [...] no virtual base classes | |||
328 | data().IsStandardLayout = false; | |||
329 | data().IsCXX11StandardLayout = false; | |||
330 | ||||
331 | // C++20 [dcl.constexpr]p3: | |||
332 | // In the definition of a constexpr function [...] | |||
333 | // -- if the function is a constructor or destructor, | |||
334 | // its class shall not have any virtual base classes | |||
335 | data().DefaultedDefaultConstructorIsConstexpr = false; | |||
336 | data().DefaultedDestructorIsConstexpr = false; | |||
337 | ||||
338 | // C++1z [class.copy]p8: | |||
339 | // The implicitly-declared copy constructor for a class X will have | |||
340 | // the form 'X::X(const X&)' if each potentially constructed subobject | |||
341 | // has a copy constructor whose first parameter is of type | |||
342 | // 'const B&' or 'const volatile B&' [...] | |||
343 | if (!BaseClassDecl->hasCopyConstructorWithConstParam()) | |||
344 | data().ImplicitCopyConstructorCanHaveConstParamForVBase = false; | |||
345 | } else { | |||
346 | // C++ [class.ctor]p5: | |||
347 | // A default constructor is trivial [...] if: | |||
348 | // -- all the direct base classes of its class have trivial default | |||
349 | // constructors. | |||
350 | if (!BaseClassDecl->hasTrivialDefaultConstructor()) | |||
351 | data().HasTrivialSpecialMembers &= ~SMF_DefaultConstructor; | |||
352 | ||||
353 | // C++0x [class.copy]p13: | |||
354 | // A copy/move constructor for class X is trivial if [...] | |||
355 | // [...] | |||
356 | // -- the constructor selected to copy/move each direct base class | |||
357 | // subobject is trivial, and | |||
358 | if (!BaseClassDecl->hasTrivialCopyConstructor()) | |||
359 | data().HasTrivialSpecialMembers &= ~SMF_CopyConstructor; | |||
360 | ||||
361 | if (!BaseClassDecl->hasTrivialCopyConstructorForCall()) | |||
362 | data().HasTrivialSpecialMembersForCall &= ~SMF_CopyConstructor; | |||
363 | ||||
364 | // If the base class doesn't have a simple move constructor, we'll eagerly | |||
365 | // declare it and perform overload resolution to determine which function | |||
366 | // it actually calls. If it does have a simple move constructor, this | |||
367 | // check is correct. | |||
368 | if (!BaseClassDecl->hasTrivialMoveConstructor()) | |||
369 | data().HasTrivialSpecialMembers &= ~SMF_MoveConstructor; | |||
370 | ||||
371 | if (!BaseClassDecl->hasTrivialMoveConstructorForCall()) | |||
372 | data().HasTrivialSpecialMembersForCall &= ~SMF_MoveConstructor; | |||
373 | ||||
374 | // C++0x [class.copy]p27: | |||
375 | // A copy/move assignment operator for class X is trivial if [...] | |||
376 | // [...] | |||
377 | // -- the assignment operator selected to copy/move each direct base | |||
378 | // class subobject is trivial, and | |||
379 | if (!BaseClassDecl->hasTrivialCopyAssignment()) | |||
380 | data().HasTrivialSpecialMembers &= ~SMF_CopyAssignment; | |||
381 | // If the base class doesn't have a simple move assignment, we'll eagerly | |||
382 | // declare it and perform overload resolution to determine which function | |||
383 | // it actually calls. If it does have a simple move assignment, this | |||
384 | // check is correct. | |||
385 | if (!BaseClassDecl->hasTrivialMoveAssignment()) | |||
386 | data().HasTrivialSpecialMembers &= ~SMF_MoveAssignment; | |||
387 | ||||
388 | // C++11 [class.ctor]p6: | |||
389 | // If that user-written default constructor would satisfy the | |||
390 | // requirements of a constexpr constructor, the implicitly-defined | |||
391 | // default constructor is constexpr. | |||
392 | if (!BaseClassDecl->hasConstexprDefaultConstructor()) | |||
393 | data().DefaultedDefaultConstructorIsConstexpr = false; | |||
394 | ||||
395 | // C++1z [class.copy]p8: | |||
396 | // The implicitly-declared copy constructor for a class X will have | |||
397 | // the form 'X::X(const X&)' if each potentially constructed subobject | |||
398 | // has a copy constructor whose first parameter is of type | |||
399 | // 'const B&' or 'const volatile B&' [...] | |||
400 | if (!BaseClassDecl->hasCopyConstructorWithConstParam()) | |||
401 | data().ImplicitCopyConstructorCanHaveConstParamForNonVBase = false; | |||
402 | } | |||
403 | ||||
404 | // C++ [class.ctor]p3: | |||
405 | // A destructor is trivial if all the direct base classes of its class | |||
406 | // have trivial destructors. | |||
407 | if (!BaseClassDecl->hasTrivialDestructor()) | |||
408 | data().HasTrivialSpecialMembers &= ~SMF_Destructor; | |||
409 | ||||
410 | if (!BaseClassDecl->hasTrivialDestructorForCall()) | |||
411 | data().HasTrivialSpecialMembersForCall &= ~SMF_Destructor; | |||
412 | ||||
413 | if (!BaseClassDecl->hasIrrelevantDestructor()) | |||
414 | data().HasIrrelevantDestructor = false; | |||
415 | ||||
416 | // C++11 [class.copy]p18: | |||
417 | // The implicitly-declared copy assignment operator for a class X will | |||
418 | // have the form 'X& X::operator=(const X&)' if each direct base class B | |||
419 | // of X has a copy assignment operator whose parameter is of type 'const | |||
420 | // B&', 'const volatile B&', or 'B' [...] | |||
421 | if (!BaseClassDecl->hasCopyAssignmentWithConstParam()) | |||
422 | data().ImplicitCopyAssignmentHasConstParam = false; | |||
423 | ||||
424 | // A class has an Objective-C object member if... or any of its bases | |||
425 | // has an Objective-C object member. | |||
426 | if (BaseClassDecl->hasObjectMember()) | |||
427 | setHasObjectMember(true); | |||
428 | ||||
429 | if (BaseClassDecl->hasVolatileMember()) | |||
430 | setHasVolatileMember(true); | |||
431 | ||||
432 | if (BaseClassDecl->getArgPassingRestrictions() == | |||
433 | RecordDecl::APK_CanNeverPassInRegs) | |||
434 | setArgPassingRestrictions(RecordDecl::APK_CanNeverPassInRegs); | |||
435 | ||||
436 | // Keep track of the presence of mutable fields. | |||
437 | if (BaseClassDecl->hasMutableFields()) { | |||
438 | data().HasMutableFields = true; | |||
439 | data().NeedOverloadResolutionForCopyConstructor = true; | |||
440 | } | |||
441 | ||||
442 | if (BaseClassDecl->hasUninitializedReferenceMember()) | |||
443 | data().HasUninitializedReferenceMember = true; | |||
444 | ||||
445 | if (!BaseClassDecl->allowConstDefaultInit()) | |||
446 | data().HasUninitializedFields = true; | |||
447 | ||||
448 | addedClassSubobject(BaseClassDecl); | |||
449 | } | |||
450 | ||||
451 | // C++2a [class]p7: | |||
452 | // A class S is a standard-layout class if it: | |||
453 | // -- has at most one base class subobject of any given type | |||
454 | // | |||
455 | // Note that we only need to check this for classes with more than one base | |||
456 | // class. If there's only one base class, and it's standard layout, then | |||
457 | // we know there are no repeated base classes. | |||
458 | if (data().IsStandardLayout && NumBases > 1 && hasRepeatedBaseClass(this)) | |||
459 | data().IsStandardLayout = false; | |||
460 | ||||
461 | if (VBases.empty()) { | |||
462 | data().IsParsingBaseSpecifiers = false; | |||
463 | return; | |||
464 | } | |||
465 | ||||
466 | // Create base specifier for any direct or indirect virtual bases. | |||
467 | data().VBases = new (C) CXXBaseSpecifier[VBases.size()]; | |||
468 | data().NumVBases = VBases.size(); | |||
469 | for (int I = 0, E = VBases.size(); I != E; ++I) { | |||
470 | QualType Type = VBases[I]->getType(); | |||
471 | if (!Type->isDependentType()) | |||
472 | addedClassSubobject(Type->getAsCXXRecordDecl()); | |||
473 | data().getVBases()[I] = *VBases[I]; | |||
474 | } | |||
475 | ||||
476 | data().IsParsingBaseSpecifiers = false; | |||
477 | } | |||
478 | ||||
479 | unsigned CXXRecordDecl::getODRHash() const { | |||
480 | assert(hasDefinition() && "ODRHash only for records with definitions")((hasDefinition() && "ODRHash only for records with definitions" ) ? static_cast<void> (0) : __assert_fail ("hasDefinition() && \"ODRHash only for records with definitions\"" , "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/AST/DeclCXX.cpp" , 480, __PRETTY_FUNCTION__)); | |||
481 | ||||
482 | // Previously calculated hash is stored in DefinitionData. | |||
483 | if (DefinitionData->HasODRHash) | |||
484 | return DefinitionData->ODRHash; | |||
485 | ||||
486 | // Only calculate hash on first call of getODRHash per record. | |||
487 | ODRHash Hash; | |||
488 | Hash.AddCXXRecordDecl(getDefinition()); | |||
489 | DefinitionData->HasODRHash = true; | |||
490 | DefinitionData->ODRHash = Hash.CalculateHash(); | |||
491 | ||||
492 | return DefinitionData->ODRHash; | |||
493 | } | |||
494 | ||||
495 | void CXXRecordDecl::addedClassSubobject(CXXRecordDecl *Subobj) { | |||
496 | // C++11 [class.copy]p11: | |||
497 | // A defaulted copy/move constructor for a class X is defined as | |||
498 | // deleted if X has: | |||
499 | // -- a direct or virtual base class B that cannot be copied/moved [...] | |||
500 | // -- a non-static data member of class type M (or array thereof) | |||
501 | // that cannot be copied or moved [...] | |||
502 | if (!Subobj->hasSimpleCopyConstructor()) | |||
503 | data().NeedOverloadResolutionForCopyConstructor = true; | |||
504 | if (!Subobj->hasSimpleMoveConstructor()) | |||
505 | data().NeedOverloadResolutionForMoveConstructor = true; | |||
506 | ||||
507 | // C++11 [class.copy]p23: | |||
508 | // A defaulted copy/move assignment operator for a class X is defined as | |||
509 | // deleted if X has: | |||
510 | // -- a direct or virtual base class B that cannot be copied/moved [...] | |||
511 | // -- a non-static data member of class type M (or array thereof) | |||
512 | // that cannot be copied or moved [...] | |||
513 | if (!Subobj->hasSimpleMoveAssignment()) | |||
514 | data().NeedOverloadResolutionForMoveAssignment = true; | |||
515 | ||||
516 | // C++11 [class.ctor]p5, C++11 [class.copy]p11, C++11 [class.dtor]p5: | |||
517 | // A defaulted [ctor or dtor] for a class X is defined as | |||
518 | // deleted if X has: | |||
519 | // -- any direct or virtual base class [...] has a type with a destructor | |||
520 | // that is deleted or inaccessible from the defaulted [ctor or dtor]. | |||
521 | // -- any non-static data member has a type with a destructor | |||
522 | // that is deleted or inaccessible from the defaulted [ctor or dtor]. | |||
523 | if (!Subobj->hasSimpleDestructor()) { | |||
524 | data().NeedOverloadResolutionForCopyConstructor = true; | |||
525 | data().NeedOverloadResolutionForMoveConstructor = true; | |||
526 | data().NeedOverloadResolutionForDestructor = true; | |||
527 | } | |||
528 | ||||
529 | // C++2a [dcl.constexpr]p4: | |||
530 | // The definition of a constexpr destructor [shall] satisfy the | |||
531 | // following requirement: | |||
532 | // -- for every subobject of class type or (possibly multi-dimensional) | |||
533 | // array thereof, that class type shall have a constexpr destructor | |||
534 | if (!Subobj->hasConstexprDestructor()) | |||
535 | data().DefaultedDestructorIsConstexpr = false; | |||
536 | } | |||
537 | ||||
538 | bool CXXRecordDecl::hasConstexprDestructor() const { | |||
539 | auto *Dtor = getDestructor(); | |||
540 | return Dtor ? Dtor->isConstexpr() : defaultedDestructorIsConstexpr(); | |||
541 | } | |||
542 | ||||
543 | bool CXXRecordDecl::hasAnyDependentBases() const { | |||
544 | if (!isDependentContext()) | |||
545 | return false; | |||
546 | ||||
547 | return !forallBases([](const CXXRecordDecl *) { return true; }); | |||
548 | } | |||
549 | ||||
550 | bool CXXRecordDecl::isTriviallyCopyable() const { | |||
551 | // C++0x [class]p5: | |||
552 | // A trivially copyable class is a class that: | |||
553 | // -- has no non-trivial copy constructors, | |||
554 | if (hasNonTrivialCopyConstructor()) return false; | |||
555 | // -- has no non-trivial move constructors, | |||
556 | if (hasNonTrivialMoveConstructor()) return false; | |||
557 | // -- has no non-trivial copy assignment operators, | |||
558 | if (hasNonTrivialCopyAssignment()) return false; | |||
559 | // -- has no non-trivial move assignment operators, and | |||
560 | if (hasNonTrivialMoveAssignment()) return false; | |||
561 | // -- has a trivial destructor. | |||
562 | if (!hasTrivialDestructor()) return false; | |||
563 | ||||
564 | return true; | |||
565 | } | |||
566 | ||||
567 | void CXXRecordDecl::markedVirtualFunctionPure() { | |||
568 | // C++ [class.abstract]p2: | |||
569 | // A class is abstract if it has at least one pure virtual function. | |||
570 | data().Abstract = true; | |||
571 | } | |||
572 | ||||
573 | bool CXXRecordDecl::hasSubobjectAtOffsetZeroOfEmptyBaseType( | |||
574 | ASTContext &Ctx, const CXXRecordDecl *XFirst) { | |||
575 | if (!getNumBases()) | |||
576 | return false; | |||
577 | ||||
578 | llvm::SmallPtrSet<const CXXRecordDecl*, 8> Bases; | |||
579 | llvm::SmallPtrSet<const CXXRecordDecl*, 8> M; | |||
580 | SmallVector<const CXXRecordDecl*, 8> WorkList; | |||
581 | ||||
582 | // Visit a type that we have determined is an element of M(S). | |||
583 | auto Visit = [&](const CXXRecordDecl *RD) -> bool { | |||
584 | RD = RD->getCanonicalDecl(); | |||
585 | ||||
586 | // C++2a [class]p8: | |||
587 | // A class S is a standard-layout class if it [...] has no element of the | |||
588 | // set M(S) of types as a base class. | |||
589 | // | |||
590 | // If we find a subobject of an empty type, it might also be a base class, | |||
591 | // so we'll need to walk the base classes to check. | |||
592 | if (!RD->data().HasBasesWithFields) { | |||
593 | // Walk the bases the first time, stopping if we find the type. Build a | |||
594 | // set of them so we don't need to walk them again. | |||
595 | if (Bases.empty()) { | |||
596 | bool RDIsBase = !forallBases([&](const CXXRecordDecl *Base) -> bool { | |||
597 | Base = Base->getCanonicalDecl(); | |||
598 | if (RD == Base) | |||
599 | return false; | |||
600 | Bases.insert(Base); | |||
601 | return true; | |||
602 | }); | |||
603 | if (RDIsBase) | |||
604 | return true; | |||
605 | } else { | |||
606 | if (Bases.count(RD)) | |||
607 | return true; | |||
608 | } | |||
609 | } | |||
610 | ||||
611 | if (M.insert(RD).second) | |||
612 | WorkList.push_back(RD); | |||
613 | return false; | |||
614 | }; | |||
615 | ||||
616 | if (Visit(XFirst)) | |||
617 | return true; | |||
618 | ||||
619 | while (!WorkList.empty()) { | |||
620 | const CXXRecordDecl *X = WorkList.pop_back_val(); | |||
621 | ||||
622 | // FIXME: We don't check the bases of X. That matches the standard, but | |||
623 | // that sure looks like a wording bug. | |||
624 | ||||
625 | // -- If X is a non-union class type with a non-static data member | |||
626 | // [recurse to each field] that is either of zero size or is the | |||
627 | // first non-static data member of X | |||
628 | // -- If X is a union type, [recurse to union members] | |||
629 | bool IsFirstField = true; | |||
630 | for (auto *FD : X->fields()) { | |||
631 | // FIXME: Should we really care about the type of the first non-static | |||
632 | // data member of a non-union if there are preceding unnamed bit-fields? | |||
633 | if (FD->isUnnamedBitfield()) | |||
634 | continue; | |||
635 | ||||
636 | if (!IsFirstField && !FD->isZeroSize(Ctx)) | |||
637 | continue; | |||
638 | ||||
639 | // -- If X is n array type, [visit the element type] | |||
640 | QualType T = Ctx.getBaseElementType(FD->getType()); | |||
641 | if (auto *RD = T->getAsCXXRecordDecl()) | |||
642 | if (Visit(RD)) | |||
643 | return true; | |||
644 | ||||
645 | if (!X->isUnion()) | |||
646 | IsFirstField = false; | |||
647 | } | |||
648 | } | |||
649 | ||||
650 | return false; | |||
651 | } | |||
652 | ||||
653 | bool CXXRecordDecl::lambdaIsDefaultConstructibleAndAssignable() const { | |||
654 | assert(isLambda() && "not a lambda")((isLambda() && "not a lambda") ? static_cast<void > (0) : __assert_fail ("isLambda() && \"not a lambda\"" , "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/AST/DeclCXX.cpp" , 654, __PRETTY_FUNCTION__)); | |||
655 | ||||
656 | // C++2a [expr.prim.lambda.capture]p11: | |||
657 | // The closure type associated with a lambda-expression has no default | |||
658 | // constructor if the lambda-expression has a lambda-capture and a | |||
659 | // defaulted default constructor otherwise. It has a deleted copy | |||
660 | // assignment operator if the lambda-expression has a lambda-capture and | |||
661 | // defaulted copy and move assignment operators otherwise. | |||
662 | // | |||
663 | // C++17 [expr.prim.lambda]p21: | |||
664 | // The closure type associated with a lambda-expression has no default | |||
665 | // constructor and a deleted copy assignment operator. | |||
666 | if (getLambdaCaptureDefault() != LCD_None || | |||
667 | getLambdaData().NumCaptures != 0) | |||
668 | return false; | |||
669 | return getASTContext().getLangOpts().CPlusPlus2a; | |||
670 | } | |||
671 | ||||
672 | void CXXRecordDecl::addedMember(Decl *D) { | |||
673 | if (!D->isImplicit() && | |||
674 | !isa<FieldDecl>(D) && | |||
675 | !isa<IndirectFieldDecl>(D) && | |||
676 | (!isa<TagDecl>(D) || cast<TagDecl>(D)->getTagKind() == TTK_Class || | |||
677 | cast<TagDecl>(D)->getTagKind() == TTK_Interface)) | |||
678 | data().HasOnlyCMembers = false; | |||
679 | ||||
680 | // Ignore friends and invalid declarations. | |||
681 | if (D->getFriendObjectKind() || D->isInvalidDecl()) | |||
682 | return; | |||
683 | ||||
684 | auto *FunTmpl = dyn_cast<FunctionTemplateDecl>(D); | |||
685 | if (FunTmpl) | |||
686 | D = FunTmpl->getTemplatedDecl(); | |||
687 | ||||
688 | // FIXME: Pass NamedDecl* to addedMember? | |||
689 | Decl *DUnderlying = D; | |||
690 | if (auto *ND = dyn_cast<NamedDecl>(DUnderlying)) { | |||
691 | DUnderlying = ND->getUnderlyingDecl(); | |||
692 | if (auto *UnderlyingFunTmpl = dyn_cast<FunctionTemplateDecl>(DUnderlying)) | |||
693 | DUnderlying = UnderlyingFunTmpl->getTemplatedDecl(); | |||
694 | } | |||
695 | ||||
696 | if (const auto *Method = dyn_cast<CXXMethodDecl>(D)) { | |||
697 | if (Method->isVirtual()) { | |||
698 | // C++ [dcl.init.aggr]p1: | |||
699 | // An aggregate is an array or a class with [...] no virtual functions. | |||
700 | data().Aggregate = false; | |||
701 | ||||
702 | // C++ [class]p4: | |||
703 | // A POD-struct is an aggregate class... | |||
704 | data().PlainOldData = false; | |||
705 | ||||
706 | // C++14 [meta.unary.prop]p4: | |||
707 | // T is a class type [...] with [...] no virtual member functions... | |||
708 | data().Empty = false; | |||
709 | ||||
710 | // C++ [class.virtual]p1: | |||
711 | // A class that declares or inherits a virtual function is called a | |||
712 | // polymorphic class. | |||
713 | data().Polymorphic = true; | |||
714 | ||||
715 | // C++11 [class.ctor]p5, C++11 [class.copy]p12, C++11 [class.copy]p25: | |||
716 | // A [default constructor, copy/move constructor, or copy/move | |||
717 | // assignment operator for a class X] is trivial [...] if: | |||
718 | // -- class X has no virtual functions [...] | |||
719 | data().HasTrivialSpecialMembers &= SMF_Destructor; | |||
720 | data().HasTrivialSpecialMembersForCall &= SMF_Destructor; | |||
721 | ||||
722 | // C++0x [class]p7: | |||
723 | // A standard-layout class is a class that: [...] | |||
724 | // -- has no virtual functions | |||
725 | data().IsStandardLayout = false; | |||
726 | data().IsCXX11StandardLayout = false; | |||
727 | } | |||
728 | } | |||
729 | ||||
730 | // Notify the listener if an implicit member was added after the definition | |||
731 | // was completed. | |||
732 | if (!isBeingDefined() && D->isImplicit()) | |||
733 | if (ASTMutationListener *L = getASTMutationListener()) | |||
734 | L->AddedCXXImplicitMember(data().Definition, D); | |||
735 | ||||
736 | // The kind of special member this declaration is, if any. | |||
737 | unsigned SMKind = 0; | |||
738 | ||||
739 | // Handle constructors. | |||
740 | if (const auto *Constructor = dyn_cast<CXXConstructorDecl>(D)) { | |||
741 | if (Constructor->isInheritingConstructor()) { | |||
742 | // Ignore constructor shadow declarations. They are lazily created and | |||
743 | // so shouldn't affect any properties of the class. | |||
744 | } else { | |||
745 | if (!Constructor->isImplicit()) { | |||
746 | // Note that we have a user-declared constructor. | |||
747 | data().UserDeclaredConstructor = true; | |||
748 | ||||
749 | // C++ [class]p4: | |||
750 | // A POD-struct is an aggregate class [...] | |||
751 | // Since the POD bit is meant to be C++03 POD-ness, clear it even if | |||
752 | // the type is technically an aggregate in C++0x since it wouldn't be | |||
753 | // in 03. | |||
754 | data().PlainOldData = false; | |||
755 | } | |||
756 | ||||
757 | if (Constructor->isDefaultConstructor()) { | |||
758 | SMKind |= SMF_DefaultConstructor; | |||
759 | ||||
760 | if (Constructor->isUserProvided()) | |||
761 | data().UserProvidedDefaultConstructor = true; | |||
762 | if (Constructor->isConstexpr()) | |||
763 | data().HasConstexprDefaultConstructor = true; | |||
764 | if (Constructor->isDefaulted()) | |||
765 | data().HasDefaultedDefaultConstructor = true; | |||
766 | } | |||
767 | ||||
768 | if (!FunTmpl) { | |||
769 | unsigned Quals; | |||
770 | if (Constructor->isCopyConstructor(Quals)) { | |||
771 | SMKind |= SMF_CopyConstructor; | |||
772 | ||||
773 | if (Quals & Qualifiers::Const) | |||
774 | data().HasDeclaredCopyConstructorWithConstParam = true; | |||
775 | } else if (Constructor->isMoveConstructor()) | |||
776 | SMKind |= SMF_MoveConstructor; | |||
777 | } | |||
778 | ||||
779 | // C++11 [dcl.init.aggr]p1: DR1518 | |||
780 | // An aggregate is an array or a class with no user-provided [or] | |||
781 | // explicit [...] constructors | |||
782 | // C++20 [dcl.init.aggr]p1: | |||
783 | // An aggregate is an array or a class with no user-declared [...] | |||
784 | // constructors | |||
785 | if (getASTContext().getLangOpts().CPlusPlus2a | |||
786 | ? !Constructor->isImplicit() | |||
787 | : (Constructor->isUserProvided() || Constructor->isExplicit())) | |||
788 | data().Aggregate = false; | |||
789 | } | |||
790 | } | |||
791 | ||||
792 | // Handle constructors, including those inherited from base classes. | |||
793 | if (const auto *Constructor = dyn_cast<CXXConstructorDecl>(DUnderlying)) { | |||
794 | // Record if we see any constexpr constructors which are neither copy | |||
795 | // nor move constructors. | |||
796 | // C++1z [basic.types]p10: | |||
797 | // [...] has at least one constexpr constructor or constructor template | |||
798 | // (possibly inherited from a base class) that is not a copy or move | |||
799 | // constructor [...] | |||
800 | if (Constructor->isConstexpr() && !Constructor->isCopyOrMoveConstructor()) | |||
801 | data().HasConstexprNonCopyMoveConstructor = true; | |||
802 | } | |||
803 | ||||
804 | // Handle destructors. | |||
805 | if (const auto *DD = dyn_cast<CXXDestructorDecl>(D)) { | |||
806 | SMKind |= SMF_Destructor; | |||
807 | ||||
808 | if (DD->isUserProvided()) | |||
809 | data().HasIrrelevantDestructor = false; | |||
810 | // If the destructor is explicitly defaulted and not trivial or not public | |||
811 | // or if the destructor is deleted, we clear HasIrrelevantDestructor in | |||
812 | // finishedDefaultedOrDeletedMember. | |||
813 | ||||
814 | // C++11 [class.dtor]p5: | |||
815 | // A destructor is trivial if [...] the destructor is not virtual. | |||
816 | if (DD->isVirtual()) { | |||
817 | data().HasTrivialSpecialMembers &= ~SMF_Destructor; | |||
818 | data().HasTrivialSpecialMembersForCall &= ~SMF_Destructor; | |||
819 | } | |||
820 | } | |||
821 | ||||
822 | // Handle member functions. | |||
823 | if (const auto *Method = dyn_cast<CXXMethodDecl>(D)) { | |||
824 | if (Method->isCopyAssignmentOperator()) { | |||
825 | SMKind |= SMF_CopyAssignment; | |||
826 | ||||
827 | const auto *ParamTy = | |||
828 | Method->getParamDecl(0)->getType()->getAs<ReferenceType>(); | |||
829 | if (!ParamTy || ParamTy->getPointeeType().isConstQualified()) | |||
830 | data().HasDeclaredCopyAssignmentWithConstParam = true; | |||
831 | } | |||
832 | ||||
833 | if (Method->isMoveAssignmentOperator()) | |||
834 | SMKind |= SMF_MoveAssignment; | |||
835 | ||||
836 | // Keep the list of conversion functions up-to-date. | |||
837 | if (auto *Conversion = dyn_cast<CXXConversionDecl>(D)) { | |||
838 | // FIXME: We use the 'unsafe' accessor for the access specifier here, | |||
839 | // because Sema may not have set it yet. That's really just a misdesign | |||
840 | // in Sema. However, LLDB *will* have set the access specifier correctly, | |||
841 | // and adds declarations after the class is technically completed, | |||
842 | // so completeDefinition()'s overriding of the access specifiers doesn't | |||
843 | // work. | |||
844 | AccessSpecifier AS = Conversion->getAccessUnsafe(); | |||
845 | ||||
846 | if (Conversion->getPrimaryTemplate()) { | |||
847 | // We don't record specializations. | |||
848 | } else { | |||
849 | ASTContext &Ctx = getASTContext(); | |||
850 | ASTUnresolvedSet &Conversions = data().Conversions.get(Ctx); | |||
851 | NamedDecl *Primary = | |||
852 | FunTmpl ? cast<NamedDecl>(FunTmpl) : cast<NamedDecl>(Conversion); | |||
853 | if (Primary->getPreviousDecl()) | |||
854 | Conversions.replace(cast<NamedDecl>(Primary->getPreviousDecl()), | |||
855 | Primary, AS); | |||
856 | else | |||
857 | Conversions.addDecl(Ctx, Primary, AS); | |||
858 | } | |||
859 | } | |||
860 | ||||
861 | if (SMKind) { | |||
862 | // If this is the first declaration of a special member, we no longer have | |||
863 | // an implicit trivial special member. | |||
864 | data().HasTrivialSpecialMembers &= | |||
865 | data().DeclaredSpecialMembers | ~SMKind; | |||
866 | data().HasTrivialSpecialMembersForCall &= | |||
867 | data().DeclaredSpecialMembers | ~SMKind; | |||
868 | ||||
869 | if (!Method->isImplicit() && !Method->isUserProvided()) { | |||
870 | // This method is user-declared but not user-provided. We can't work out | |||
871 | // whether it's trivial yet (not until we get to the end of the class). | |||
872 | // We'll handle this method in finishedDefaultedOrDeletedMember. | |||
873 | } else if (Method->isTrivial()) { | |||
874 | data().HasTrivialSpecialMembers |= SMKind; | |||
875 | data().HasTrivialSpecialMembersForCall |= SMKind; | |||
876 | } else if (Method->isTrivialForCall()) { | |||
877 | data().HasTrivialSpecialMembersForCall |= SMKind; | |||
878 | data().DeclaredNonTrivialSpecialMembers |= SMKind; | |||
879 | } else { | |||
880 | data().DeclaredNonTrivialSpecialMembers |= SMKind; | |||
881 | // If this is a user-provided function, do not set | |||
882 | // DeclaredNonTrivialSpecialMembersForCall here since we don't know | |||
883 | // yet whether the method would be considered non-trivial for the | |||
884 | // purpose of calls (attribute "trivial_abi" can be dropped from the | |||
885 | // class later, which can change the special method's triviality). | |||
886 | if (!Method->isUserProvided()) | |||
887 | data().DeclaredNonTrivialSpecialMembersForCall |= SMKind; | |||
888 | } | |||
889 | ||||
890 | // Note when we have declared a declared special member, and suppress the | |||
891 | // implicit declaration of this special member. | |||
892 | data().DeclaredSpecialMembers |= SMKind; | |||
893 | ||||
894 | if (!Method->isImplicit()) { | |||
895 | data().UserDeclaredSpecialMembers |= SMKind; | |||
896 | ||||
897 | // C++03 [class]p4: | |||
898 | // A POD-struct is an aggregate class that has [...] no user-defined | |||
899 | // copy assignment operator and no user-defined destructor. | |||
900 | // | |||
901 | // Since the POD bit is meant to be C++03 POD-ness, and in C++03, | |||
902 | // aggregates could not have any constructors, clear it even for an | |||
903 | // explicitly defaulted or deleted constructor. | |||
904 | // type is technically an aggregate in C++0x since it wouldn't be in 03. | |||
905 | // | |||
906 | // Also, a user-declared move assignment operator makes a class non-POD. | |||
907 | // This is an extension in C++03. | |||
908 | data().PlainOldData = false; | |||
909 | } | |||
910 | } | |||
911 | ||||
912 | return; | |||
913 | } | |||
914 | ||||
915 | // Handle non-static data members. | |||
916 | if (const auto *Field = dyn_cast<FieldDecl>(D)) { | |||
917 | ASTContext &Context = getASTContext(); | |||
918 | ||||
919 | // C++2a [class]p7: | |||
920 | // A standard-layout class is a class that: | |||
921 | // [...] | |||
922 | // -- has all non-static data members and bit-fields in the class and | |||
923 | // its base classes first declared in the same class | |||
924 | if (data().HasBasesWithFields) | |||
925 | data().IsStandardLayout = false; | |||
926 | ||||
927 | // C++ [class.bit]p2: | |||
928 | // A declaration for a bit-field that omits the identifier declares an | |||
929 | // unnamed bit-field. Unnamed bit-fields are not members and cannot be | |||
930 | // initialized. | |||
931 | if (Field->isUnnamedBitfield()) { | |||
932 | // C++ [meta.unary.prop]p4: [LWG2358] | |||
933 | // T is a class type [...] with [...] no unnamed bit-fields of non-zero | |||
934 | // length | |||
935 | if (data().Empty && !Field->isZeroLengthBitField(Context) && | |||
936 | Context.getLangOpts().getClangABICompat() > | |||
937 | LangOptions::ClangABI::Ver6) | |||
938 | data().Empty = false; | |||
939 | return; | |||
940 | } | |||
941 | ||||
942 | // C++11 [class]p7: | |||
943 | // A standard-layout class is a class that: | |||
944 | // -- either has no non-static data members in the most derived class | |||
945 | // [...] or has no base classes with non-static data members | |||
946 | if (data().HasBasesWithNonStaticDataMembers) | |||
947 | data().IsCXX11StandardLayout = false; | |||
948 | ||||
949 | // C++ [dcl.init.aggr]p1: | |||
950 | // An aggregate is an array or a class (clause 9) with [...] no | |||
951 | // private or protected non-static data members (clause 11). | |||
952 | // | |||
953 | // A POD must be an aggregate. | |||
954 | if (D->getAccess() == AS_private || D->getAccess() == AS_protected) { | |||
955 | data().Aggregate = false; | |||
956 | data().PlainOldData = false; | |||
957 | } | |||
958 | ||||
959 | // Track whether this is the first field. We use this when checking | |||
960 | // whether the class is standard-layout below. | |||
961 | bool IsFirstField = !data().HasPrivateFields && | |||
962 | !data().HasProtectedFields && !data().HasPublicFields; | |||
963 | ||||
964 | // C++0x [class]p7: | |||
965 | // A standard-layout class is a class that: | |||
966 | // [...] | |||
967 | // -- has the same access control for all non-static data members, | |||
968 | switch (D->getAccess()) { | |||
969 | case AS_private: data().HasPrivateFields = true; break; | |||
970 | case AS_protected: data().HasProtectedFields = true; break; | |||
971 | case AS_public: data().HasPublicFields = true; break; | |||
972 | case AS_none: llvm_unreachable("Invalid access specifier")::llvm::llvm_unreachable_internal("Invalid access specifier", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/AST/DeclCXX.cpp" , 972); | |||
973 | }; | |||
974 | if ((data().HasPrivateFields + data().HasProtectedFields + | |||
975 | data().HasPublicFields) > 1) { | |||
976 | data().IsStandardLayout = false; | |||
977 | data().IsCXX11StandardLayout = false; | |||
978 | } | |||
979 | ||||
980 | // Keep track of the presence of mutable fields. | |||
981 | if (Field->isMutable()) { | |||
982 | data().HasMutableFields = true; | |||
983 | data().NeedOverloadResolutionForCopyConstructor = true; | |||
984 | } | |||
985 | ||||
986 | // C++11 [class.union]p8, DR1460: | |||
987 | // If X is a union, a non-static data member of X that is not an anonymous | |||
988 | // union is a variant member of X. | |||
989 | if (isUnion() && !Field->isAnonymousStructOrUnion()) | |||
990 | data().HasVariantMembers = true; | |||
991 | ||||
992 | // C++0x [class]p9: | |||
993 | // A POD struct is a class that is both a trivial class and a | |||
994 | // standard-layout class, and has no non-static data members of type | |||
995 | // non-POD struct, non-POD union (or array of such types). | |||
996 | // | |||
997 | // Automatic Reference Counting: the presence of a member of Objective-C pointer type | |||
998 | // that does not explicitly have no lifetime makes the class a non-POD. | |||
999 | QualType T = Context.getBaseElementType(Field->getType()); | |||
1000 | if (T->isObjCRetainableType() || T.isObjCGCStrong()) { | |||
1001 | if (T.hasNonTrivialObjCLifetime()) { | |||
1002 | // Objective-C Automatic Reference Counting: | |||
1003 | // If a class has a non-static data member of Objective-C pointer | |||
1004 | // type (or array thereof), it is a non-POD type and its | |||
1005 | // default constructor (if any), copy constructor, move constructor, | |||
1006 | // copy assignment operator, move assignment operator, and destructor are | |||
1007 | // non-trivial. | |||
1008 | setHasObjectMember(true); | |||
1009 | struct DefinitionData &Data = data(); | |||
1010 | Data.PlainOldData = false; | |||
1011 | Data.HasTrivialSpecialMembers = 0; | |||
1012 | ||||
1013 | // __strong or __weak fields do not make special functions non-trivial | |||
1014 | // for the purpose of calls. | |||
1015 | Qualifiers::ObjCLifetime LT = T.getQualifiers().getObjCLifetime(); | |||
1016 | if (LT != Qualifiers::OCL_Strong && LT != Qualifiers::OCL_Weak) | |||
1017 | data().HasTrivialSpecialMembersForCall = 0; | |||
1018 | ||||
1019 | // Structs with __weak fields should never be passed directly. | |||
1020 | if (LT == Qualifiers::OCL_Weak) | |||
1021 | setArgPassingRestrictions(RecordDecl::APK_CanNeverPassInRegs); | |||
1022 | ||||
1023 | Data.HasIrrelevantDestructor = false; | |||
1024 | ||||
1025 | if (isUnion()) { | |||
1026 | data().DefaultedCopyConstructorIsDeleted = true; | |||
1027 | data().DefaultedMoveConstructorIsDeleted = true; | |||
1028 | data().DefaultedMoveAssignmentIsDeleted = true; | |||
1029 | data().DefaultedDestructorIsDeleted = true; | |||
1030 | data().NeedOverloadResolutionForCopyConstructor = true; | |||
1031 | data().NeedOverloadResolutionForMoveConstructor = true; | |||
1032 | data().NeedOverloadResolutionForMoveAssignment = true; | |||
1033 | data().NeedOverloadResolutionForDestructor = true; | |||
1034 | } | |||
1035 | } else if (!Context.getLangOpts().ObjCAutoRefCount) { | |||
1036 | setHasObjectMember(true); | |||
1037 | } | |||
1038 | } else if (!T.isCXX98PODType(Context)) | |||
1039 | data().PlainOldData = false; | |||
1040 | ||||
1041 | if (T->isReferenceType()) { | |||
1042 | if (!Field->hasInClassInitializer()) | |||
1043 | data().HasUninitializedReferenceMember = true; | |||
1044 | ||||
1045 | // C++0x [class]p7: | |||
1046 | // A standard-layout class is a class that: | |||
1047 | // -- has no non-static data members of type [...] reference, | |||
1048 | data().IsStandardLayout = false; | |||
1049 | data().IsCXX11StandardLayout = false; | |||
1050 | ||||
1051 | // C++1z [class.copy.ctor]p10: | |||
1052 | // A defaulted copy constructor for a class X is defined as deleted if X has: | |||
1053 | // -- a non-static data member of rvalue reference type | |||
1054 | if (T->isRValueReferenceType()) | |||
1055 | data().DefaultedCopyConstructorIsDeleted = true; | |||
1056 | } | |||
1057 | ||||
1058 | if (!Field->hasInClassInitializer() && !Field->isMutable()) { | |||
1059 | if (CXXRecordDecl *FieldType = T->getAsCXXRecordDecl()) { | |||
1060 | if (FieldType->hasDefinition() && !FieldType->allowConstDefaultInit()) | |||
1061 | data().HasUninitializedFields = true; | |||
1062 | } else { | |||
1063 | data().HasUninitializedFields = true; | |||
1064 | } | |||
1065 | } | |||
1066 | ||||
1067 | // Record if this field is the first non-literal or volatile field or base. | |||
1068 | if (!T->isLiteralType(Context) || T.isVolatileQualified()) | |||
1069 | data().HasNonLiteralTypeFieldsOrBases = true; | |||
1070 | ||||
1071 | if (Field->hasInClassInitializer() || | |||
1072 | (Field->isAnonymousStructOrUnion() && | |||
1073 | Field->getType()->getAsCXXRecordDecl()->hasInClassInitializer())) { | |||
1074 | data().HasInClassInitializer = true; | |||
1075 | ||||
1076 | // C++11 [class]p5: | |||
1077 | // A default constructor is trivial if [...] no non-static data member | |||
1078 | // of its class has a brace-or-equal-initializer. | |||
1079 | data().HasTrivialSpecialMembers &= ~SMF_DefaultConstructor; | |||
1080 | ||||
1081 | // C++11 [dcl.init.aggr]p1: | |||
1082 | // An aggregate is a [...] class with [...] no | |||
1083 | // brace-or-equal-initializers for non-static data members. | |||
1084 | // | |||
1085 | // This rule was removed in C++14. | |||
1086 | if (!getASTContext().getLangOpts().CPlusPlus14) | |||
1087 | data().Aggregate = false; | |||
1088 | ||||
1089 | // C++11 [class]p10: | |||
1090 | // A POD struct is [...] a trivial class. | |||
1091 | data().PlainOldData = false; | |||
1092 | } | |||
1093 | ||||
1094 | // C++11 [class.copy]p23: | |||
1095 | // A defaulted copy/move assignment operator for a class X is defined | |||
1096 | // as deleted if X has: | |||
1097 | // -- a non-static data member of reference type | |||
1098 | if (T->isReferenceType()) | |||
1099 | data().DefaultedMoveAssignmentIsDeleted = true; | |||
1100 | ||||
1101 | // Bitfields of length 0 are also zero-sized, but we already bailed out for | |||
1102 | // those because they are always unnamed. | |||
1103 | bool IsZeroSize = Field->isZeroSize(Context); | |||
1104 | ||||
1105 | if (const auto *RecordTy = T->getAs<RecordType>()) { | |||
1106 | auto *FieldRec = cast<CXXRecordDecl>(RecordTy->getDecl()); | |||
1107 | if (FieldRec->getDefinition()) { | |||
1108 | addedClassSubobject(FieldRec); | |||
1109 | ||||
1110 | // We may need to perform overload resolution to determine whether a | |||
1111 | // field can be moved if it's const or volatile qualified. | |||
1112 | if (T.getCVRQualifiers() & (Qualifiers::Const | Qualifiers::Volatile)) { | |||
1113 | // We need to care about 'const' for the copy constructor because an | |||
1114 | // implicit copy constructor might be declared with a non-const | |||
1115 | // parameter. | |||
1116 | data().NeedOverloadResolutionForCopyConstructor = true; | |||
1117 | data().NeedOverloadResolutionForMoveConstructor = true; | |||
1118 | data().NeedOverloadResolutionForMoveAssignment = true; | |||
1119 | } | |||
1120 | ||||
1121 | // C++11 [class.ctor]p5, C++11 [class.copy]p11: | |||
1122 | // A defaulted [special member] for a class X is defined as | |||
1123 | // deleted if: | |||
1124 | // -- X is a union-like class that has a variant member with a | |||
1125 | // non-trivial [corresponding special member] | |||
1126 | if (isUnion()) { | |||
1127 | if (FieldRec->hasNonTrivialCopyConstructor()) | |||
1128 | data().DefaultedCopyConstructorIsDeleted = true; | |||
1129 | if (FieldRec->hasNonTrivialMoveConstructor()) | |||
1130 | data().DefaultedMoveConstructorIsDeleted = true; | |||
1131 | if (FieldRec->hasNonTrivialMoveAssignment()) | |||
1132 | data().DefaultedMoveAssignmentIsDeleted = true; | |||
1133 | if (FieldRec->hasNonTrivialDestructor()) | |||
1134 | data().DefaultedDestructorIsDeleted = true; | |||
1135 | } | |||
1136 | ||||
1137 | // For an anonymous union member, our overload resolution will perform | |||
1138 | // overload resolution for its members. | |||
1139 | if (Field->isAnonymousStructOrUnion()) { | |||
1140 | data().NeedOverloadResolutionForCopyConstructor |= | |||
1141 | FieldRec->data().NeedOverloadResolutionForCopyConstructor; | |||
1142 | data().NeedOverloadResolutionForMoveConstructor |= | |||
1143 | FieldRec->data().NeedOverloadResolutionForMoveConstructor; | |||
1144 | data().NeedOverloadResolutionForMoveAssignment |= | |||
1145 | FieldRec->data().NeedOverloadResolutionForMoveAssignment; | |||
1146 | data().NeedOverloadResolutionForDestructor |= | |||
1147 | FieldRec->data().NeedOverloadResolutionForDestructor; | |||
1148 | } | |||
1149 | ||||
1150 | // C++0x [class.ctor]p5: | |||
1151 | // A default constructor is trivial [...] if: | |||
1152 | // -- for all the non-static data members of its class that are of | |||
1153 | // class type (or array thereof), each such class has a trivial | |||
1154 | // default constructor. | |||
1155 | if (!FieldRec->hasTrivialDefaultConstructor()) | |||
1156 | data().HasTrivialSpecialMembers &= ~SMF_DefaultConstructor; | |||
1157 | ||||
1158 | // C++0x [class.copy]p13: | |||
1159 | // A copy/move constructor for class X is trivial if [...] | |||
1160 | // [...] | |||
1161 | // -- for each non-static data member of X that is of class type (or | |||
1162 | // an array thereof), the constructor selected to copy/move that | |||
1163 | // member is trivial; | |||
1164 | if (!FieldRec->hasTrivialCopyConstructor()) | |||
1165 | data().HasTrivialSpecialMembers &= ~SMF_CopyConstructor; | |||
1166 | ||||
1167 | if (!FieldRec->hasTrivialCopyConstructorForCall()) | |||
1168 | data().HasTrivialSpecialMembersForCall &= ~SMF_CopyConstructor; | |||
1169 | ||||
1170 | // If the field doesn't have a simple move constructor, we'll eagerly | |||
1171 | // declare the move constructor for this class and we'll decide whether | |||
1172 | // it's trivial then. | |||
1173 | if (!FieldRec->hasTrivialMoveConstructor()) | |||
1174 | data().HasTrivialSpecialMembers &= ~SMF_MoveConstructor; | |||
1175 | ||||
1176 | if (!FieldRec->hasTrivialMoveConstructorForCall()) | |||
1177 | data().HasTrivialSpecialMembersForCall &= ~SMF_MoveConstructor; | |||
1178 | ||||
1179 | // C++0x [class.copy]p27: | |||
1180 | // A copy/move assignment operator for class X is trivial if [...] | |||
1181 | // [...] | |||
1182 | // -- for each non-static data member of X that is of class type (or | |||
1183 | // an array thereof), the assignment operator selected to | |||
1184 | // copy/move that member is trivial; | |||
1185 | if (!FieldRec->hasTrivialCopyAssignment()) | |||
1186 | data().HasTrivialSpecialMembers &= ~SMF_CopyAssignment; | |||
1187 | // If the field doesn't have a simple move assignment, we'll eagerly | |||
1188 | // declare the move assignment for this class and we'll decide whether | |||
1189 | // it's trivial then. | |||
1190 | if (!FieldRec->hasTrivialMoveAssignment()) | |||
1191 | data().HasTrivialSpecialMembers &= ~SMF_MoveAssignment; | |||
1192 | ||||
1193 | if (!FieldRec->hasTrivialDestructor()) | |||
1194 | data().HasTrivialSpecialMembers &= ~SMF_Destructor; | |||
1195 | if (!FieldRec->hasTrivialDestructorForCall()) | |||
1196 | data().HasTrivialSpecialMembersForCall &= ~SMF_Destructor; | |||
1197 | if (!FieldRec->hasIrrelevantDestructor()) | |||
1198 | data().HasIrrelevantDestructor = false; | |||
1199 | if (FieldRec->hasObjectMember()) | |||
1200 | setHasObjectMember(true); | |||
1201 | if (FieldRec->hasVolatileMember()) | |||
1202 | setHasVolatileMember(true); | |||
1203 | if (FieldRec->getArgPassingRestrictions() == | |||
1204 | RecordDecl::APK_CanNeverPassInRegs) | |||
1205 | setArgPassingRestrictions(RecordDecl::APK_CanNeverPassInRegs); | |||
1206 | ||||
1207 | // C++0x [class]p7: | |||
1208 | // A standard-layout class is a class that: | |||
1209 | // -- has no non-static data members of type non-standard-layout | |||
1210 | // class (or array of such types) [...] | |||
1211 | if (!FieldRec->isStandardLayout()) | |||
1212 | data().IsStandardLayout = false; | |||
1213 | if (!FieldRec->isCXX11StandardLayout()) | |||
1214 | data().IsCXX11StandardLayout = false; | |||
1215 | ||||
1216 | // C++2a [class]p7: | |||
1217 | // A standard-layout class is a class that: | |||
1218 | // [...] | |||
1219 | // -- has no element of the set M(S) of types as a base class. | |||
1220 | if (data().IsStandardLayout && | |||
1221 | (isUnion() || IsFirstField || IsZeroSize) && | |||
1222 | hasSubobjectAtOffsetZeroOfEmptyBaseType(Context, FieldRec)) | |||
1223 | data().IsStandardLayout = false; | |||
1224 | ||||
1225 | // C++11 [class]p7: | |||
1226 | // A standard-layout class is a class that: | |||
1227 | // -- has no base classes of the same type as the first non-static | |||
1228 | // data member | |||
1229 | if (data().IsCXX11StandardLayout && IsFirstField) { | |||
1230 | // FIXME: We should check all base classes here, not just direct | |||
1231 | // base classes. | |||
1232 | for (const auto &BI : bases()) { | |||
1233 | if (Context.hasSameUnqualifiedType(BI.getType(), T)) { | |||
1234 | data().IsCXX11StandardLayout = false; | |||
1235 | break; | |||
1236 | } | |||
1237 | } | |||
1238 | } | |||
1239 | ||||
1240 | // Keep track of the presence of mutable fields. | |||
1241 | if (FieldRec->hasMutableFields()) { | |||
1242 | data().HasMutableFields = true; | |||
1243 | data().NeedOverloadResolutionForCopyConstructor = true; | |||
1244 | } | |||
1245 | ||||
1246 | // C++11 [class.copy]p13: | |||
1247 | // If the implicitly-defined constructor would satisfy the | |||
1248 | // requirements of a constexpr constructor, the implicitly-defined | |||
1249 | // constructor is constexpr. | |||
1250 | // C++11 [dcl.constexpr]p4: | |||
1251 | // -- every constructor involved in initializing non-static data | |||
1252 | // members [...] shall be a constexpr constructor | |||
1253 | if (!Field->hasInClassInitializer() && | |||
1254 | !FieldRec->hasConstexprDefaultConstructor() && !isUnion()) | |||
1255 | // The standard requires any in-class initializer to be a constant | |||
1256 | // expression. We consider this to be a defect. | |||
1257 | data().DefaultedDefaultConstructorIsConstexpr = false; | |||
1258 | ||||
1259 | // C++11 [class.copy]p8: | |||
1260 | // The implicitly-declared copy constructor for a class X will have | |||
1261 | // the form 'X::X(const X&)' if each potentially constructed subobject | |||
1262 | // of a class type M (or array thereof) has a copy constructor whose | |||
1263 | // first parameter is of type 'const M&' or 'const volatile M&'. | |||
1264 | if (!FieldRec->hasCopyConstructorWithConstParam()) | |||
1265 | data().ImplicitCopyConstructorCanHaveConstParamForNonVBase = false; | |||
1266 | ||||
1267 | // C++11 [class.copy]p18: | |||
1268 | // The implicitly-declared copy assignment oeprator for a class X will | |||
1269 | // have the form 'X& X::operator=(const X&)' if [...] for all the | |||
1270 | // non-static data members of X that are of a class type M (or array | |||
1271 | // thereof), each such class type has a copy assignment operator whose | |||
1272 | // parameter is of type 'const M&', 'const volatile M&' or 'M'. | |||
1273 | if (!FieldRec->hasCopyAssignmentWithConstParam()) | |||
1274 | data().ImplicitCopyAssignmentHasConstParam = false; | |||
1275 | ||||
1276 | if (FieldRec->hasUninitializedReferenceMember() && | |||
1277 | !Field->hasInClassInitializer()) | |||
1278 | data().HasUninitializedReferenceMember = true; | |||
1279 | ||||
1280 | // C++11 [class.union]p8, DR1460: | |||
1281 | // a non-static data member of an anonymous union that is a member of | |||
1282 | // X is also a variant member of X. | |||
1283 | if (FieldRec->hasVariantMembers() && | |||
1284 | Field->isAnonymousStructOrUnion()) | |||
1285 | data().HasVariantMembers = true; | |||
1286 | } | |||
1287 | } else { | |||
1288 | // Base element type of field is a non-class type. | |||
1289 | if (!T->isLiteralType(Context) || | |||
1290 | (!Field->hasInClassInitializer() && !isUnion() && | |||
1291 | !Context.getLangOpts().CPlusPlus2a)) | |||
1292 | data().DefaultedDefaultConstructorIsConstexpr = false; | |||
1293 | ||||
1294 | // C++11 [class.copy]p23: | |||
1295 | // A defaulted copy/move assignment operator for a class X is defined | |||
1296 | // as deleted if X has: | |||
1297 | // -- a non-static data member of const non-class type (or array | |||
1298 | // thereof) | |||
1299 | if (T.isConstQualified()) | |||
1300 | data().DefaultedMoveAssignmentIsDeleted = true; | |||
1301 | } | |||
1302 | ||||
1303 | // C++14 [meta.unary.prop]p4: | |||
1304 | // T is a class type [...] with [...] no non-static data members other | |||
1305 | // than subobjects of zero size | |||
1306 | if (data().Empty && !IsZeroSize) | |||
1307 | data().Empty = false; | |||
1308 | } | |||
1309 | ||||
1310 | // Handle using declarations of conversion functions. | |||
1311 | if (auto *Shadow = dyn_cast<UsingShadowDecl>(D)) { | |||
1312 | if (Shadow->getDeclName().getNameKind() | |||
1313 | == DeclarationName::CXXConversionFunctionName) { | |||
1314 | ASTContext &Ctx = getASTContext(); | |||
1315 | data().Conversions.get(Ctx).addDecl(Ctx, Shadow, Shadow->getAccess()); | |||
1316 | } | |||
1317 | } | |||
1318 | ||||
1319 | if (const auto *Using = dyn_cast<UsingDecl>(D)) { | |||
1320 | if (Using->getDeclName().getNameKind() == | |||
1321 | DeclarationName::CXXConstructorName) { | |||
1322 | data().HasInheritedConstructor = true; | |||
1323 | // C++1z [dcl.init.aggr]p1: | |||
1324 | // An aggregate is [...] a class [...] with no inherited constructors | |||
1325 | data().Aggregate = false; | |||
1326 | } | |||
1327 | ||||
1328 | if (Using->getDeclName().getCXXOverloadedOperator() == OO_Equal) | |||
1329 | data().HasInheritedAssignment = true; | |||
1330 | } | |||
1331 | } | |||
1332 | ||||
1333 | void CXXRecordDecl::finishedDefaultedOrDeletedMember(CXXMethodDecl *D) { | |||
1334 | assert(!D->isImplicit() && !D->isUserProvided())((!D->isImplicit() && !D->isUserProvided()) ? static_cast <void> (0) : __assert_fail ("!D->isImplicit() && !D->isUserProvided()" , "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/AST/DeclCXX.cpp" , 1334, __PRETTY_FUNCTION__)); | |||
1335 | ||||
1336 | // The kind of special member this declaration is, if any. | |||
1337 | unsigned SMKind = 0; | |||
1338 | ||||
1339 | if (const auto *Constructor = dyn_cast<CXXConstructorDecl>(D)) { | |||
1340 | if (Constructor->isDefaultConstructor()) { | |||
1341 | SMKind |= SMF_DefaultConstructor; | |||
1342 | if (Constructor->isConstexpr()) | |||
1343 | data().HasConstexprDefaultConstructor = true; | |||
1344 | } | |||
1345 | if (Constructor->isCopyConstructor()) | |||
1346 | SMKind |= SMF_CopyConstructor; | |||
1347 | else if (Constructor->isMoveConstructor()) | |||
1348 | SMKind |= SMF_MoveConstructor; | |||
1349 | else if (Constructor->isConstexpr()) | |||
1350 | // We may now know that the constructor is constexpr. | |||
1351 | data().HasConstexprNonCopyMoveConstructor = true; | |||
1352 | } else if (isa<CXXDestructorDecl>(D)) { | |||
1353 | SMKind |= SMF_Destructor; | |||
1354 | if (!D->isTrivial() || D->getAccess() != AS_public || D->isDeleted()) | |||
1355 | data().HasIrrelevantDestructor = false; | |||
1356 | } else if (D->isCopyAssignmentOperator()) | |||
1357 | SMKind |= SMF_CopyAssignment; | |||
1358 | else if (D->isMoveAssignmentOperator()) | |||
1359 | SMKind |= SMF_MoveAssignment; | |||
1360 | ||||
1361 | // Update which trivial / non-trivial special members we have. | |||
1362 | // addedMember will have skipped this step for this member. | |||
1363 | if (D->isTrivial()) | |||
1364 | data().HasTrivialSpecialMembers |= SMKind; | |||
1365 | else | |||
1366 | data().DeclaredNonTrivialSpecialMembers |= SMKind; | |||
1367 | } | |||
1368 | ||||
1369 | void CXXRecordDecl::setTrivialForCallFlags(CXXMethodDecl *D) { | |||
1370 | unsigned SMKind = 0; | |||
1371 | ||||
1372 | if (const auto *Constructor = dyn_cast<CXXConstructorDecl>(D)) { | |||
1373 | if (Constructor->isCopyConstructor()) | |||
1374 | SMKind = SMF_CopyConstructor; | |||
1375 | else if (Constructor->isMoveConstructor()) | |||
1376 | SMKind = SMF_MoveConstructor; | |||
1377 | } else if (isa<CXXDestructorDecl>(D)) | |||
1378 | SMKind = SMF_Destructor; | |||
1379 | ||||
1380 | if (D->isTrivialForCall()) | |||
1381 | data().HasTrivialSpecialMembersForCall |= SMKind; | |||
1382 | else | |||
1383 | data().DeclaredNonTrivialSpecialMembersForCall |= SMKind; | |||
1384 | } | |||
1385 | ||||
1386 | bool CXXRecordDecl::isCLike() const { | |||
1387 | if (getTagKind() == TTK_Class || getTagKind() == TTK_Interface || | |||
1388 | !TemplateOrInstantiation.isNull()) | |||
1389 | return false; | |||
1390 | if (!hasDefinition()) | |||
1391 | return true; | |||
1392 | ||||
1393 | return isPOD() && data().HasOnlyCMembers; | |||
1394 | } | |||
1395 | ||||
1396 | bool CXXRecordDecl::isGenericLambda() const { | |||
1397 | if (!isLambda()) return false; | |||
1398 | return getLambdaData().IsGenericLambda; | |||
1399 | } | |||
1400 | ||||
1401 | #ifndef NDEBUG | |||
1402 | static bool allLookupResultsAreTheSame(const DeclContext::lookup_result &R) { | |||
1403 | for (auto *D : R) | |||
1404 | if (!declaresSameEntity(D, R.front())) | |||
1405 | return false; | |||
1406 | return true; | |||
1407 | } | |||
1408 | #endif | |||
1409 | ||||
1410 | static NamedDecl* getLambdaCallOperatorHelper(const CXXRecordDecl &RD) { | |||
1411 | if (!RD.isLambda()) return nullptr; | |||
1412 | DeclarationName Name = | |||
1413 | RD.getASTContext().DeclarationNames.getCXXOperatorName(OO_Call); | |||
1414 | DeclContext::lookup_result Calls = RD.lookup(Name); | |||
1415 | ||||
1416 | assert(!Calls.empty() && "Missing lambda call operator!")((!Calls.empty() && "Missing lambda call operator!") ? static_cast<void> (0) : __assert_fail ("!Calls.empty() && \"Missing lambda call operator!\"" , "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/AST/DeclCXX.cpp" , 1416, __PRETTY_FUNCTION__)); | |||
1417 | assert(allLookupResultsAreTheSame(Calls) &&((allLookupResultsAreTheSame(Calls) && "More than one lambda call operator!" ) ? static_cast<void> (0) : __assert_fail ("allLookupResultsAreTheSame(Calls) && \"More than one lambda call operator!\"" , "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/AST/DeclCXX.cpp" , 1418, __PRETTY_FUNCTION__)) | |||
1418 | "More than one lambda call operator!")((allLookupResultsAreTheSame(Calls) && "More than one lambda call operator!" ) ? static_cast<void> (0) : __assert_fail ("allLookupResultsAreTheSame(Calls) && \"More than one lambda call operator!\"" , "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/AST/DeclCXX.cpp" , 1418, __PRETTY_FUNCTION__)); | |||
1419 | return Calls.front(); | |||
1420 | } | |||
1421 | ||||
1422 | FunctionTemplateDecl* CXXRecordDecl::getDependentLambdaCallOperator() const { | |||
1423 | NamedDecl *CallOp = getLambdaCallOperatorHelper(*this); | |||
1424 | return dyn_cast_or_null<FunctionTemplateDecl>(CallOp); | |||
1425 | } | |||
1426 | ||||
1427 | CXXMethodDecl *CXXRecordDecl::getLambdaCallOperator() const { | |||
1428 | NamedDecl *CallOp = getLambdaCallOperatorHelper(*this); | |||
1429 | ||||
1430 | if (CallOp == nullptr) | |||
1431 | return nullptr; | |||
1432 | ||||
1433 | if (const auto *CallOpTmpl = dyn_cast<FunctionTemplateDecl>(CallOp)) | |||
1434 | return cast<CXXMethodDecl>(CallOpTmpl->getTemplatedDecl()); | |||
1435 | ||||
1436 | return cast<CXXMethodDecl>(CallOp); | |||
1437 | } | |||
1438 | ||||
1439 | CXXMethodDecl* CXXRecordDecl::getLambdaStaticInvoker() const { | |||
1440 | if (!isLambda()) return nullptr; | |||
1441 | DeclarationName Name = | |||
1442 | &getASTContext().Idents.get(getLambdaStaticInvokerName()); | |||
1443 | DeclContext::lookup_result Invoker = lookup(Name); | |||
1444 | if (Invoker.empty()) return nullptr; | |||
1445 | assert(allLookupResultsAreTheSame(Invoker) &&((allLookupResultsAreTheSame(Invoker) && "More than one static invoker operator!" ) ? static_cast<void> (0) : __assert_fail ("allLookupResultsAreTheSame(Invoker) && \"More than one static invoker operator!\"" , "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/AST/DeclCXX.cpp" , 1446, __PRETTY_FUNCTION__)) | |||
1446 | "More than one static invoker operator!")((allLookupResultsAreTheSame(Invoker) && "More than one static invoker operator!" ) ? static_cast<void> (0) : __assert_fail ("allLookupResultsAreTheSame(Invoker) && \"More than one static invoker operator!\"" , "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/AST/DeclCXX.cpp" , 1446, __PRETTY_FUNCTION__)); | |||
1447 | NamedDecl *InvokerFun = Invoker.front(); | |||
1448 | if (const auto *InvokerTemplate = dyn_cast<FunctionTemplateDecl>(InvokerFun)) | |||
1449 | return cast<CXXMethodDecl>(InvokerTemplate->getTemplatedDecl()); | |||
1450 | ||||
1451 | return cast<CXXMethodDecl>(InvokerFun); | |||
1452 | } | |||
1453 | ||||
1454 | void CXXRecordDecl::getCaptureFields( | |||
1455 | llvm::DenseMap<const VarDecl *, FieldDecl *> &Captures, | |||
1456 | FieldDecl *&ThisCapture) const { | |||
1457 | Captures.clear(); | |||
1458 | ThisCapture = nullptr; | |||
1459 | ||||
1460 | LambdaDefinitionData &Lambda = getLambdaData(); | |||
1461 | RecordDecl::field_iterator Field = field_begin(); | |||
1462 | for (const LambdaCapture *C = Lambda.Captures, *CEnd = C + Lambda.NumCaptures; | |||
1463 | C != CEnd; ++C, ++Field) { | |||
1464 | if (C->capturesThis()) | |||
1465 | ThisCapture = *Field; | |||
1466 | else if (C->capturesVariable()) | |||
1467 | Captures[C->getCapturedVar()] = *Field; | |||
1468 | } | |||
1469 | assert(Field == field_end())((Field == field_end()) ? static_cast<void> (0) : __assert_fail ("Field == field_end()", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/AST/DeclCXX.cpp" , 1469, __PRETTY_FUNCTION__)); | |||
1470 | } | |||
1471 | ||||
1472 | TemplateParameterList * | |||
1473 | CXXRecordDecl::getGenericLambdaTemplateParameterList() const { | |||
1474 | if (!isGenericLambda()) return nullptr; | |||
1475 | CXXMethodDecl *CallOp = getLambdaCallOperator(); | |||
1476 | if (FunctionTemplateDecl *Tmpl = CallOp->getDescribedFunctionTemplate()) | |||
1477 | return Tmpl->getTemplateParameters(); | |||
1478 | return nullptr; | |||
1479 | } | |||
1480 | ||||
1481 | ArrayRef<NamedDecl *> | |||
1482 | CXXRecordDecl::getLambdaExplicitTemplateParameters() const { | |||
1483 | TemplateParameterList *List = getGenericLambdaTemplateParameterList(); | |||
1484 | if (!List) | |||
1485 | return {}; | |||
1486 | ||||
1487 | assert(std::is_partitioned(List->begin(), List->end(),((std::is_partitioned(List->begin(), List->end(), [](const NamedDecl *D) { return !D->isImplicit(); }) && "Explicit template params should be ordered before implicit ones" ) ? static_cast<void> (0) : __assert_fail ("std::is_partitioned(List->begin(), List->end(), [](const NamedDecl *D) { return !D->isImplicit(); }) && \"Explicit template params should be ordered before implicit ones\"" , "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/AST/DeclCXX.cpp" , 1489, __PRETTY_FUNCTION__)) | |||
1488 | [](const NamedDecl *D) { return !D->isImplicit(); })((std::is_partitioned(List->begin(), List->end(), [](const NamedDecl *D) { return !D->isImplicit(); }) && "Explicit template params should be ordered before implicit ones" ) ? static_cast<void> (0) : __assert_fail ("std::is_partitioned(List->begin(), List->end(), [](const NamedDecl *D) { return !D->isImplicit(); }) && \"Explicit template params should be ordered before implicit ones\"" , "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/AST/DeclCXX.cpp" , 1489, __PRETTY_FUNCTION__)) | |||
1489 | && "Explicit template params should be ordered before implicit ones")((std::is_partitioned(List->begin(), List->end(), [](const NamedDecl *D) { return !D->isImplicit(); }) && "Explicit template params should be ordered before implicit ones" ) ? static_cast<void> (0) : __assert_fail ("std::is_partitioned(List->begin(), List->end(), [](const NamedDecl *D) { return !D->isImplicit(); }) && \"Explicit template params should be ordered before implicit ones\"" , "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/AST/DeclCXX.cpp" , 1489, __PRETTY_FUNCTION__)); | |||
1490 | ||||
1491 | const auto ExplicitEnd = llvm::partition_point( | |||
1492 | *List, [](const NamedDecl *D) { return !D->isImplicit(); }); | |||
1493 | return llvm::makeArrayRef(List->begin(), ExplicitEnd); | |||
1494 | } | |||
1495 | ||||
1496 | Decl *CXXRecordDecl::getLambdaContextDecl() const { | |||
1497 | assert(isLambda() && "Not a lambda closure type!")((isLambda() && "Not a lambda closure type!") ? static_cast <void> (0) : __assert_fail ("isLambda() && \"Not a lambda closure type!\"" , "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/AST/DeclCXX.cpp" , 1497, __PRETTY_FUNCTION__)); | |||
1498 | ExternalASTSource *Source = getParentASTContext().getExternalSource(); | |||
1499 | return getLambdaData().ContextDecl.get(Source); | |||
1500 | } | |||
1501 | ||||
1502 | static CanQualType GetConversionType(ASTContext &Context, NamedDecl *Conv) { | |||
1503 | QualType T = | |||
1504 | cast<CXXConversionDecl>(Conv->getUnderlyingDecl()->getAsFunction()) | |||
1505 | ->getConversionType(); | |||
1506 | return Context.getCanonicalType(T); | |||
1507 | } | |||
1508 | ||||
1509 | /// Collect the visible conversions of a base class. | |||
1510 | /// | |||
1511 | /// \param Record a base class of the class we're considering | |||
1512 | /// \param InVirtual whether this base class is a virtual base (or a base | |||
1513 | /// of a virtual base) | |||
1514 | /// \param Access the access along the inheritance path to this base | |||
1515 | /// \param ParentHiddenTypes the conversions provided by the inheritors | |||
1516 | /// of this base | |||
1517 | /// \param Output the set to which to add conversions from non-virtual bases | |||
1518 | /// \param VOutput the set to which to add conversions from virtual bases | |||
1519 | /// \param HiddenVBaseCs the set of conversions which were hidden in a | |||
1520 | /// virtual base along some inheritance path | |||
1521 | static void CollectVisibleConversions( | |||
1522 | ASTContext &Context, const CXXRecordDecl *Record, bool InVirtual, | |||
1523 | AccessSpecifier Access, | |||
1524 | const llvm::SmallPtrSet<CanQualType, 8> &ParentHiddenTypes, | |||
1525 | ASTUnresolvedSet &Output, UnresolvedSetImpl &VOutput, | |||
1526 | llvm::SmallPtrSet<NamedDecl *, 8> &HiddenVBaseCs) { | |||
1527 | // The set of types which have conversions in this class or its | |||
1528 | // subclasses. As an optimization, we don't copy the derived set | |||
1529 | // unless it might change. | |||
1530 | const llvm::SmallPtrSet<CanQualType, 8> *HiddenTypes = &ParentHiddenTypes; | |||
1531 | llvm::SmallPtrSet<CanQualType, 8> HiddenTypesBuffer; | |||
1532 | ||||
1533 | // Collect the direct conversions and figure out which conversions | |||
1534 | // will be hidden in the subclasses. | |||
1535 | CXXRecordDecl::conversion_iterator ConvI = Record->conversion_begin(); | |||
1536 | CXXRecordDecl::conversion_iterator ConvE = Record->conversion_end(); | |||
1537 | if (ConvI != ConvE) { | |||
1538 | HiddenTypesBuffer = ParentHiddenTypes; | |||
1539 | HiddenTypes = &HiddenTypesBuffer; | |||
1540 | ||||
1541 | for (CXXRecordDecl::conversion_iterator I = ConvI; I != ConvE; ++I) { | |||
1542 | CanQualType ConvType(GetConversionType(Context, I.getDecl())); | |||
1543 | bool Hidden = ParentHiddenTypes.count(ConvType); | |||
1544 | if (!Hidden) | |||
1545 | HiddenTypesBuffer.insert(ConvType); | |||
1546 | ||||
1547 | // If this conversion is hidden and we're in a virtual base, | |||
1548 | // remember that it's hidden along some inheritance path. | |||
1549 | if (Hidden && InVirtual) | |||
1550 | HiddenVBaseCs.insert(cast<NamedDecl>(I.getDecl()->getCanonicalDecl())); | |||
1551 | ||||
1552 | // If this conversion isn't hidden, add it to the appropriate output. | |||
1553 | else if (!Hidden) { | |||
1554 | AccessSpecifier IAccess | |||
1555 | = CXXRecordDecl::MergeAccess(Access, I.getAccess()); | |||
1556 | ||||
1557 | if (InVirtual) | |||
1558 | VOutput.addDecl(I.getDecl(), IAccess); | |||
1559 | else | |||
1560 | Output.addDecl(Context, I.getDecl(), IAccess); | |||
1561 | } | |||
1562 | } | |||
1563 | } | |||
1564 | ||||
1565 | // Collect information recursively from any base classes. | |||
1566 | for (const auto &I : Record->bases()) { | |||
1567 | const auto *RT = I.getType()->getAs<RecordType>(); | |||
1568 | if (!RT) continue; | |||
1569 | ||||
1570 | AccessSpecifier BaseAccess | |||
1571 | = CXXRecordDecl::MergeAccess(Access, I.getAccessSpecifier()); | |||
1572 | bool BaseInVirtual = InVirtual || I.isVirtual(); | |||
1573 | ||||
1574 | auto *Base = cast<CXXRecordDecl>(RT->getDecl()); | |||
1575 | CollectVisibleConversions(Context, Base, BaseInVirtual, BaseAccess, | |||
1576 | *HiddenTypes, Output, VOutput, HiddenVBaseCs); | |||
1577 | } | |||
1578 | } | |||
1579 | ||||
1580 | /// Collect the visible conversions of a class. | |||
1581 | /// | |||
1582 | /// This would be extremely straightforward if it weren't for virtual | |||
1583 | /// bases. It might be worth special-casing that, really. | |||
1584 | static void CollectVisibleConversions(ASTContext &Context, | |||
1585 | const CXXRecordDecl *Record, | |||
1586 | ASTUnresolvedSet &Output) { | |||
1587 | // The collection of all conversions in virtual bases that we've | |||
1588 | // found. These will be added to the output as long as they don't | |||
1589 | // appear in the hidden-conversions set. | |||
1590 | UnresolvedSet<8> VBaseCs; | |||
1591 | ||||
1592 | // The set of conversions in virtual bases that we've determined to | |||
1593 | // be hidden. | |||
1594 | llvm::SmallPtrSet<NamedDecl*, 8> HiddenVBaseCs; | |||
1595 | ||||
1596 | // The set of types hidden by classes derived from this one. | |||
1597 | llvm::SmallPtrSet<CanQualType, 8> HiddenTypes; | |||
1598 | ||||
1599 | // Go ahead and collect the direct conversions and add them to the | |||
1600 | // hidden-types set. | |||
1601 | CXXRecordDecl::conversion_iterator ConvI = Record->conversion_begin(); | |||
1602 | CXXRecordDecl::conversion_iterator ConvE = Record->conversion_end(); | |||
1603 | Output.append(Context, ConvI, ConvE); | |||
1604 | for (; ConvI != ConvE; ++ConvI) | |||
1605 | HiddenTypes.insert(GetConversionType(Context, ConvI.getDecl())); | |||
1606 | ||||
1607 | // Recursively collect conversions from base classes. | |||
1608 | for (const auto &I : Record->bases()) { | |||
1609 | const auto *RT = I.getType()->getAs<RecordType>(); | |||
1610 | if (!RT) continue; | |||
1611 | ||||
1612 | CollectVisibleConversions(Context, cast<CXXRecordDecl>(RT->getDecl()), | |||
1613 | I.isVirtual(), I.getAccessSpecifier(), | |||
1614 | HiddenTypes, Output, VBaseCs, HiddenVBaseCs); | |||
1615 | } | |||
1616 | ||||
1617 | // Add any unhidden conversions provided by virtual bases. | |||
1618 | for (UnresolvedSetIterator I = VBaseCs.begin(), E = VBaseCs.end(); | |||
1619 | I != E; ++I) { | |||
1620 | if (!HiddenVBaseCs.count(cast<NamedDecl>(I.getDecl()->getCanonicalDecl()))) | |||
1621 | Output.addDecl(Context, I.getDecl(), I.getAccess()); | |||
1622 | } | |||
1623 | } | |||
1624 | ||||
1625 | /// getVisibleConversionFunctions - get all conversion functions visible | |||
1626 | /// in current class; including conversion function templates. | |||
1627 | llvm::iterator_range<CXXRecordDecl::conversion_iterator> | |||
1628 | CXXRecordDecl::getVisibleConversionFunctions() const { | |||
1629 | ASTContext &Ctx = getASTContext(); | |||
1630 | ||||
1631 | ASTUnresolvedSet *Set; | |||
1632 | if (bases_begin() == bases_end()) { | |||
1633 | // If root class, all conversions are visible. | |||
1634 | Set = &data().Conversions.get(Ctx); | |||
1635 | } else { | |||
1636 | Set = &data().VisibleConversions.get(Ctx); | |||
1637 | // If visible conversion list is not evaluated, evaluate it. | |||
1638 | if (!data().ComputedVisibleConversions) { | |||
1639 | CollectVisibleConversions(Ctx, this, *Set); | |||
1640 | data().ComputedVisibleConversions = true; | |||
1641 | } | |||
1642 | } | |||
1643 | return llvm::make_range(Set->begin(), Set->end()); | |||
1644 | } | |||
1645 | ||||
1646 | void CXXRecordDecl::removeConversion(const NamedDecl *ConvDecl) { | |||
1647 | // This operation is O(N) but extremely rare. Sema only uses it to | |||
1648 | // remove UsingShadowDecls in a class that were followed by a direct | |||
1649 | // declaration, e.g.: | |||
1650 | // class A : B { | |||
1651 | // using B::operator int; | |||
1652 | // operator int(); | |||
1653 | // }; | |||
1654 | // This is uncommon by itself and even more uncommon in conjunction | |||
1655 | // with sufficiently large numbers of directly-declared conversions | |||
1656 | // that asymptotic behavior matters. | |||
1657 | ||||
1658 | ASTUnresolvedSet &Convs = data().Conversions.get(getASTContext()); | |||
1659 | for (unsigned I = 0, E = Convs.size(); I != E; ++I) { | |||
1660 | if (Convs[I].getDecl() == ConvDecl) { | |||
1661 | Convs.erase(I); | |||
1662 | assert(llvm::find(Convs, ConvDecl) == Convs.end() &&((llvm::find(Convs, ConvDecl) == Convs.end() && "conversion was found multiple times in unresolved set" ) ? static_cast<void> (0) : __assert_fail ("llvm::find(Convs, ConvDecl) == Convs.end() && \"conversion was found multiple times in unresolved set\"" , "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/AST/DeclCXX.cpp" , 1663, __PRETTY_FUNCTION__)) | |||
1663 | "conversion was found multiple times in unresolved set")((llvm::find(Convs, ConvDecl) == Convs.end() && "conversion was found multiple times in unresolved set" ) ? static_cast<void> (0) : __assert_fail ("llvm::find(Convs, ConvDecl) == Convs.end() && \"conversion was found multiple times in unresolved set\"" , "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/AST/DeclCXX.cpp" , 1663, __PRETTY_FUNCTION__)); | |||
1664 | return; | |||
1665 | } | |||
1666 | } | |||
1667 | ||||
1668 | llvm_unreachable("conversion not found in set!")::llvm::llvm_unreachable_internal("conversion not found in set!" , "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/AST/DeclCXX.cpp" , 1668); | |||
1669 | } | |||
1670 | ||||
1671 | CXXRecordDecl *CXXRecordDecl::getInstantiatedFromMemberClass() const { | |||
1672 | if (MemberSpecializationInfo *MSInfo = getMemberSpecializationInfo()) | |||
1673 | return cast<CXXRecordDecl>(MSInfo->getInstantiatedFrom()); | |||
1674 | ||||
1675 | return nullptr; | |||
1676 | } | |||
1677 | ||||
1678 | MemberSpecializationInfo *CXXRecordDecl::getMemberSpecializationInfo() const { | |||
1679 | return TemplateOrInstantiation.dyn_cast<MemberSpecializationInfo *>(); | |||
1680 | } | |||
1681 | ||||
1682 | void | |||
1683 | CXXRecordDecl::setInstantiationOfMemberClass(CXXRecordDecl *RD, | |||
1684 | TemplateSpecializationKind TSK) { | |||
1685 | assert(TemplateOrInstantiation.isNull() &&((TemplateOrInstantiation.isNull() && "Previous template or instantiation?" ) ? static_cast<void> (0) : __assert_fail ("TemplateOrInstantiation.isNull() && \"Previous template or instantiation?\"" , "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/AST/DeclCXX.cpp" , 1686, __PRETTY_FUNCTION__)) | |||
1686 | "Previous template or instantiation?")((TemplateOrInstantiation.isNull() && "Previous template or instantiation?" ) ? static_cast<void> (0) : __assert_fail ("TemplateOrInstantiation.isNull() && \"Previous template or instantiation?\"" , "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/AST/DeclCXX.cpp" , 1686, __PRETTY_FUNCTION__)); | |||
1687 | assert(!isa<ClassTemplatePartialSpecializationDecl>(this))((!isa<ClassTemplatePartialSpecializationDecl>(this)) ? static_cast<void> (0) : __assert_fail ("!isa<ClassTemplatePartialSpecializationDecl>(this)" , "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/AST/DeclCXX.cpp" , 1687, __PRETTY_FUNCTION__)); | |||
1688 | TemplateOrInstantiation | |||
1689 | = new (getASTContext()) MemberSpecializationInfo(RD, TSK); | |||
1690 | } | |||
1691 | ||||
1692 | ClassTemplateDecl *CXXRecordDecl::getDescribedClassTemplate() const { | |||
1693 | return TemplateOrInstantiation.dyn_cast<ClassTemplateDecl *>(); | |||
1694 | } | |||
1695 | ||||
1696 | void CXXRecordDecl::setDescribedClassTemplate(ClassTemplateDecl *Template) { | |||
1697 | TemplateOrInstantiation = Template; | |||
1698 | } | |||
1699 | ||||
1700 | TemplateSpecializationKind CXXRecordDecl::getTemplateSpecializationKind() const{ | |||
1701 | if (const auto *Spec = dyn_cast<ClassTemplateSpecializationDecl>(this)) | |||
1702 | return Spec->getSpecializationKind(); | |||
1703 | ||||
1704 | if (MemberSpecializationInfo *MSInfo = getMemberSpecializationInfo()) | |||
1705 | return MSInfo->getTemplateSpecializationKind(); | |||
1706 | ||||
1707 | return TSK_Undeclared; | |||
1708 | } | |||
1709 | ||||
1710 | void | |||
1711 | CXXRecordDecl::setTemplateSpecializationKind(TemplateSpecializationKind TSK) { | |||
1712 | if (auto *Spec = dyn_cast<ClassTemplateSpecializationDecl>(this)) { | |||
1713 | Spec->setSpecializationKind(TSK); | |||
1714 | return; | |||
1715 | } | |||
1716 | ||||
1717 | if (MemberSpecializationInfo *MSInfo = getMemberSpecializationInfo()) { | |||
1718 | MSInfo->setTemplateSpecializationKind(TSK); | |||
1719 | return; | |||
1720 | } | |||
1721 | ||||
1722 | llvm_unreachable("Not a class template or member class specialization")::llvm::llvm_unreachable_internal("Not a class template or member class specialization" , "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/AST/DeclCXX.cpp" , 1722); | |||
1723 | } | |||
1724 | ||||
1725 | const CXXRecordDecl *CXXRecordDecl::getTemplateInstantiationPattern() const { | |||
1726 | auto GetDefinitionOrSelf = | |||
1727 | [](const CXXRecordDecl *D) -> const CXXRecordDecl * { | |||
1728 | if (auto *Def = D->getDefinition()) | |||
1729 | return Def; | |||
1730 | return D; | |||
1731 | }; | |||
1732 | ||||
1733 | // If it's a class template specialization, find the template or partial | |||
1734 | // specialization from which it was instantiated. | |||
1735 | if (auto *TD = dyn_cast<ClassTemplateSpecializationDecl>(this)) { | |||
1736 | auto From = TD->getInstantiatedFrom(); | |||
1737 | if (auto *CTD = From.dyn_cast<ClassTemplateDecl *>()) { | |||
1738 | while (auto *NewCTD = CTD->getInstantiatedFromMemberTemplate()) { | |||
1739 | if (NewCTD->isMemberSpecialization()) | |||
1740 | break; | |||
1741 | CTD = NewCTD; | |||
1742 | } | |||
1743 | return GetDefinitionOrSelf(CTD->getTemplatedDecl()); | |||
1744 | } | |||
1745 | if (auto *CTPSD = | |||
1746 | From.dyn_cast<ClassTemplatePartialSpecializationDecl *>()) { | |||
1747 | while (auto *NewCTPSD = CTPSD->getInstantiatedFromMember()) { | |||
1748 | if (NewCTPSD->isMemberSpecialization()) | |||
1749 | break; | |||
1750 | CTPSD = NewCTPSD; | |||
1751 | } | |||
1752 | return GetDefinitionOrSelf(CTPSD); | |||
1753 | } | |||
1754 | } | |||
1755 | ||||
1756 | if (MemberSpecializationInfo *MSInfo = getMemberSpecializationInfo()) { | |||
1757 | if (isTemplateInstantiation(MSInfo->getTemplateSpecializationKind())) { | |||
1758 | const CXXRecordDecl *RD = this; | |||
1759 | while (auto *NewRD = RD->getInstantiatedFromMemberClass()) | |||
1760 | RD = NewRD; | |||
1761 | return GetDefinitionOrSelf(RD); | |||
1762 | } | |||
1763 | } | |||
1764 | ||||
1765 | assert(!isTemplateInstantiation(this->getTemplateSpecializationKind()) &&((!isTemplateInstantiation(this->getTemplateSpecializationKind ()) && "couldn't find pattern for class template instantiation" ) ? static_cast<void> (0) : __assert_fail ("!isTemplateInstantiation(this->getTemplateSpecializationKind()) && \"couldn't find pattern for class template instantiation\"" , "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/AST/DeclCXX.cpp" , 1766, __PRETTY_FUNCTION__)) | |||
1766 | "couldn't find pattern for class template instantiation")((!isTemplateInstantiation(this->getTemplateSpecializationKind ()) && "couldn't find pattern for class template instantiation" ) ? static_cast<void> (0) : __assert_fail ("!isTemplateInstantiation(this->getTemplateSpecializationKind()) && \"couldn't find pattern for class template instantiation\"" , "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/AST/DeclCXX.cpp" , 1766, __PRETTY_FUNCTION__)); | |||
1767 | return nullptr; | |||
1768 | } | |||
1769 | ||||
1770 | CXXDestructorDecl *CXXRecordDecl::getDestructor() const { | |||
1771 | ASTContext &Context = getASTContext(); | |||
1772 | QualType ClassType = Context.getTypeDeclType(this); | |||
1773 | ||||
1774 | DeclarationName Name | |||
1775 | = Context.DeclarationNames.getCXXDestructorName( | |||
1776 | Context.getCanonicalType(ClassType)); | |||
1777 | ||||
1778 | DeclContext::lookup_result R = lookup(Name); | |||
1779 | ||||
1780 | return R.empty() ? nullptr : dyn_cast<CXXDestructorDecl>(R.front()); | |||
1781 | } | |||
1782 | ||||
1783 | bool CXXRecordDecl::isAnyDestructorNoReturn() const { | |||
1784 | // Destructor is noreturn. | |||
1785 | if (const CXXDestructorDecl *Destructor = getDestructor()) | |||
1786 | if (Destructor->isNoReturn()) | |||
1787 | return true; | |||
1788 | ||||
1789 | // Check base classes destructor for noreturn. | |||
1790 | for (const auto &Base : bases()) | |||
1791 | if (const CXXRecordDecl *RD = Base.getType()->getAsCXXRecordDecl()) | |||
1792 | if (RD->isAnyDestructorNoReturn()) | |||
1793 | return true; | |||
1794 | ||||
1795 | // Check fields for noreturn. | |||
1796 | for (const auto *Field : fields()) | |||
1797 | if (const CXXRecordDecl *RD = | |||
1798 | Field->getType()->getBaseElementTypeUnsafe()->getAsCXXRecordDecl()) | |||
1799 | if (RD->isAnyDestructorNoReturn()) | |||
1800 | return true; | |||
1801 | ||||
1802 | // All destructors are not noreturn. | |||
1803 | return false; | |||
1804 | } | |||
1805 | ||||
1806 | static bool isDeclContextInNamespace(const DeclContext *DC) { | |||
1807 | while (!DC->isTranslationUnit()) { | |||
1808 | if (DC->isNamespace()) | |||
1809 | return true; | |||
1810 | DC = DC->getParent(); | |||
1811 | } | |||
1812 | return false; | |||
1813 | } | |||
1814 | ||||
1815 | bool CXXRecordDecl::isInterfaceLike() const { | |||
1816 | assert(hasDefinition() && "checking for interface-like without a definition")((hasDefinition() && "checking for interface-like without a definition" ) ? static_cast<void> (0) : __assert_fail ("hasDefinition() && \"checking for interface-like without a definition\"" , "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/AST/DeclCXX.cpp" , 1816, __PRETTY_FUNCTION__)); | |||
1817 | // All __interfaces are inheritently interface-like. | |||
1818 | if (isInterface()) | |||
1819 | return true; | |||
1820 | ||||
1821 | // Interface-like types cannot have a user declared constructor, destructor, | |||
1822 | // friends, VBases, conversion functions, or fields. Additionally, lambdas | |||
1823 | // cannot be interface types. | |||
1824 | if (isLambda() || hasUserDeclaredConstructor() || | |||
1825 | hasUserDeclaredDestructor() || !field_empty() || hasFriends() || | |||
1826 | getNumVBases() > 0 || conversion_end() - conversion_begin() > 0) | |||
1827 | return false; | |||
1828 | ||||
1829 | // No interface-like type can have a method with a definition. | |||
1830 | for (const auto *const Method : methods()) | |||
1831 | if (Method->isDefined() && !Method->isImplicit()) | |||
1832 | return false; | |||
1833 | ||||
1834 | // Check "Special" types. | |||
1835 | const auto *Uuid = getAttr<UuidAttr>(); | |||
1836 | // MS SDK declares IUnknown/IDispatch both in the root of a TU, or in an | |||
1837 | // extern C++ block directly in the TU. These are only valid if in one | |||
1838 | // of these two situations. | |||
1839 | if (Uuid && isStruct() && !getDeclContext()->isExternCContext() && | |||
1840 | !isDeclContextInNamespace(getDeclContext()) && | |||
1841 | ((getName() == "IUnknown" && | |||
1842 | Uuid->getGuid() == "00000000-0000-0000-C000-000000000046") || | |||
1843 | (getName() == "IDispatch" && | |||
1844 | Uuid->getGuid() == "00020400-0000-0000-C000-000000000046"))) { | |||
1845 | if (getNumBases() > 0) | |||
1846 | return false; | |||
1847 | return true; | |||
1848 | } | |||
1849 | ||||
1850 | // FIXME: Any access specifiers is supposed to make this no longer interface | |||
1851 | // like. | |||
1852 | ||||
1853 | // If this isn't a 'special' type, it must have a single interface-like base. | |||
1854 | if (getNumBases() != 1) | |||
1855 | return false; | |||
1856 | ||||
1857 | const auto BaseSpec = *bases_begin(); | |||
1858 | if (BaseSpec.isVirtual() || BaseSpec.getAccessSpecifier() != AS_public) | |||
1859 | return false; | |||
1860 | const auto *Base = BaseSpec.getType()->getAsCXXRecordDecl(); | |||
1861 | if (Base->isInterface() || !Base->isInterfaceLike()) | |||
1862 | return false; | |||
1863 | return true; | |||
1864 | } | |||
1865 | ||||
1866 | void CXXRecordDecl::completeDefinition() { | |||
1867 | completeDefinition(nullptr); | |||
1868 | } | |||
1869 | ||||
1870 | void CXXRecordDecl::completeDefinition(CXXFinalOverriderMap *FinalOverriders) { | |||
1871 | RecordDecl::completeDefinition(); | |||
1872 | ||||
1873 | // If the class may be abstract (but hasn't been marked as such), check for | |||
1874 | // any pure final overriders. | |||
1875 | if (mayBeAbstract()) { | |||
1876 | CXXFinalOverriderMap MyFinalOverriders; | |||
1877 | if (!FinalOverriders) { | |||
1878 | getFinalOverriders(MyFinalOverriders); | |||
1879 | FinalOverriders = &MyFinalOverriders; | |||
1880 | } | |||
1881 | ||||
1882 | bool Done = false; | |||
1883 | for (CXXFinalOverriderMap::iterator M = FinalOverriders->begin(), | |||
1884 | MEnd = FinalOverriders->end(); | |||
1885 | M != MEnd && !Done; ++M) { | |||
1886 | for (OverridingMethods::iterator SO = M->second.begin(), | |||
1887 | SOEnd = M->second.end(); | |||
1888 | SO != SOEnd && !Done; ++SO) { | |||
1889 | assert(SO->second.size() > 0 &&((SO->second.size() > 0 && "All virtual functions have overriding virtual functions" ) ? static_cast<void> (0) : __assert_fail ("SO->second.size() > 0 && \"All virtual functions have overriding virtual functions\"" , "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/AST/DeclCXX.cpp" , 1890, __PRETTY_FUNCTION__)) | |||
1890 | "All virtual functions have overriding virtual functions")((SO->second.size() > 0 && "All virtual functions have overriding virtual functions" ) ? static_cast<void> (0) : __assert_fail ("SO->second.size() > 0 && \"All virtual functions have overriding virtual functions\"" , "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/AST/DeclCXX.cpp" , 1890, __PRETTY_FUNCTION__)); | |||
1891 | ||||
1892 | // C++ [class.abstract]p4: | |||
1893 | // A class is abstract if it contains or inherits at least one | |||
1894 | // pure virtual function for which the final overrider is pure | |||
1895 | // virtual. | |||
1896 | if (SO->second.front().Method->isPure()) { | |||
1897 | data().Abstract = true; | |||
1898 | Done = true; | |||
1899 | break; | |||
1900 | } | |||
1901 | } | |||
1902 | } | |||
1903 | } | |||
1904 | ||||
1905 | // Set access bits correctly on the directly-declared conversions. | |||
1906 | for (conversion_iterator I = conversion_begin(), E = conversion_end(); | |||
1907 | I != E; ++I) | |||
1908 | I.setAccess((*I)->getAccess()); | |||
1909 | } | |||
1910 | ||||
1911 | bool CXXRecordDecl::mayBeAbstract() const { | |||
1912 | if (data().Abstract || isInvalidDecl() || !data().Polymorphic || | |||
1913 | isDependentContext()) | |||
1914 | return false; | |||
1915 | ||||
1916 | for (const auto &B : bases()) { | |||
1917 | const auto *BaseDecl = | |||
1918 | cast<CXXRecordDecl>(B.getType()->castAs<RecordType>()->getDecl()); | |||
1919 | if (BaseDecl->isAbstract()) | |||
1920 | return true; | |||
1921 | } | |||
1922 | ||||
1923 | return false; | |||
1924 | } | |||
1925 | ||||
1926 | bool CXXRecordDecl::isEffectivelyFinal() const { | |||
1927 | auto *Def = getDefinition(); | |||
1928 | if (!Def) | |||
1929 | return false; | |||
1930 | if (Def->hasAttr<FinalAttr>()) | |||
1931 | return true; | |||
1932 | if (const auto *Dtor = Def->getDestructor()) | |||
1933 | if (Dtor->hasAttr<FinalAttr>()) | |||
1934 | return true; | |||
1935 | return false; | |||
1936 | } | |||
1937 | ||||
1938 | void CXXDeductionGuideDecl::anchor() {} | |||
1939 | ||||
1940 | bool ExplicitSpecifier::isEquivalent(const ExplicitSpecifier Other) const { | |||
1941 | if ((getKind() != Other.getKind() || | |||
1942 | getKind() == ExplicitSpecKind::Unresolved)) { | |||
1943 | if (getKind() == ExplicitSpecKind::Unresolved && | |||
1944 | Other.getKind() == ExplicitSpecKind::Unresolved) { | |||
1945 | ODRHash SelfHash, OtherHash; | |||
1946 | SelfHash.AddStmt(getExpr()); | |||
1947 | OtherHash.AddStmt(Other.getExpr()); | |||
1948 | return SelfHash.CalculateHash() == OtherHash.CalculateHash(); | |||
1949 | } else | |||
1950 | return false; | |||
1951 | } | |||
1952 | return true; | |||
1953 | } | |||
1954 | ||||
1955 | ExplicitSpecifier ExplicitSpecifier::getFromDecl(FunctionDecl *Function) { | |||
1956 | switch (Function->getDeclKind()) { | |||
1957 | case Decl::Kind::CXXConstructor: | |||
1958 | return cast<CXXConstructorDecl>(Function)->getExplicitSpecifier(); | |||
1959 | case Decl::Kind::CXXConversion: | |||
1960 | return cast<CXXConversionDecl>(Function)->getExplicitSpecifier(); | |||
1961 | case Decl::Kind::CXXDeductionGuide: | |||
1962 | return cast<CXXDeductionGuideDecl>(Function)->getExplicitSpecifier(); | |||
1963 | default: | |||
1964 | return {}; | |||
1965 | } | |||
1966 | } | |||
1967 | ||||
1968 | CXXDeductionGuideDecl *CXXDeductionGuideDecl::Create( | |||
1969 | ASTContext &C, DeclContext *DC, SourceLocation StartLoc, | |||
1970 | ExplicitSpecifier ES, const DeclarationNameInfo &NameInfo, QualType T, | |||
1971 | TypeSourceInfo *TInfo, SourceLocation EndLocation) { | |||
1972 | return new (C, DC) CXXDeductionGuideDecl(C, DC, StartLoc, ES, NameInfo, T, | |||
1973 | TInfo, EndLocation); | |||
1974 | } | |||
1975 | ||||
1976 | CXXDeductionGuideDecl *CXXDeductionGuideDecl::CreateDeserialized(ASTContext &C, | |||
1977 | unsigned ID) { | |||
1978 | return new (C, ID) CXXDeductionGuideDecl( | |||
1979 | C, nullptr, SourceLocation(), ExplicitSpecifier(), DeclarationNameInfo(), | |||
1980 | QualType(), nullptr, SourceLocation()); | |||
1981 | } | |||
1982 | ||||
1983 | RequiresExprBodyDecl *RequiresExprBodyDecl::Create( | |||
1984 | ASTContext &C, DeclContext *DC, SourceLocation StartLoc) { | |||
1985 | return new (C, DC) RequiresExprBodyDecl(C, DC, StartLoc); | |||
1986 | } | |||
1987 | ||||
1988 | RequiresExprBodyDecl *RequiresExprBodyDecl::CreateDeserialized(ASTContext &C, | |||
1989 | unsigned ID) { | |||
1990 | return new (C, ID) RequiresExprBodyDecl(C, nullptr, SourceLocation()); | |||
1991 | } | |||
1992 | ||||
1993 | void CXXMethodDecl::anchor() {} | |||
1994 | ||||
1995 | bool CXXMethodDecl::isStatic() const { | |||
1996 | const CXXMethodDecl *MD = getCanonicalDecl(); | |||
1997 | ||||
1998 | if (MD->getStorageClass() == SC_Static) | |||
1999 | return true; | |||
2000 | ||||
2001 | OverloadedOperatorKind OOK = getDeclName().getCXXOverloadedOperator(); | |||
2002 | return isStaticOverloadedOperator(OOK); | |||
2003 | } | |||
2004 | ||||
2005 | static bool recursivelyOverrides(const CXXMethodDecl *DerivedMD, | |||
2006 | const CXXMethodDecl *BaseMD) { | |||
2007 | for (const CXXMethodDecl *MD : DerivedMD->overridden_methods()) { | |||
2008 | if (MD->getCanonicalDecl() == BaseMD->getCanonicalDecl()) | |||
2009 | return true; | |||
2010 | if (recursivelyOverrides(MD, BaseMD)) | |||
2011 | return true; | |||
2012 | } | |||
2013 | return false; | |||
2014 | } | |||
2015 | ||||
2016 | CXXMethodDecl * | |||
2017 | CXXMethodDecl::getCorrespondingMethodDeclaredInClass(const CXXRecordDecl *RD, | |||
2018 | bool MayBeBase) { | |||
2019 | if (this->getParent()->getCanonicalDecl() == RD->getCanonicalDecl()) | |||
2020 | return this; | |||
2021 | ||||
2022 | // Lookup doesn't work for destructors, so handle them separately. | |||
2023 | if (isa<CXXDestructorDecl>(this)) { | |||
2024 | CXXMethodDecl *MD = RD->getDestructor(); | |||
2025 | if (MD) { | |||
2026 | if (recursivelyOverrides(MD, this)) | |||
2027 | return MD; | |||
2028 | if (MayBeBase && recursivelyOverrides(this, MD)) | |||
2029 | return MD; | |||
2030 | } | |||
2031 | return nullptr; | |||
2032 | } | |||
2033 | ||||
2034 | for (auto *ND : RD->lookup(getDeclName())) { | |||
2035 | auto *MD = dyn_cast<CXXMethodDecl>(ND); | |||
2036 | if (!MD) | |||
2037 | continue; | |||
2038 | if (recursivelyOverrides(MD, this)) | |||
2039 | return MD; | |||
2040 | if (MayBeBase && recursivelyOverrides(this, MD)) | |||
2041 | return MD; | |||
2042 | } | |||
2043 | ||||
2044 | return nullptr; | |||
2045 | } | |||
2046 | ||||
2047 | CXXMethodDecl * | |||
2048 | CXXMethodDecl::getCorrespondingMethodInClass(const CXXRecordDecl *RD, | |||
2049 | bool MayBeBase) { | |||
2050 | if (auto *MD = getCorrespondingMethodDeclaredInClass(RD, MayBeBase)) | |||
2051 | return MD; | |||
2052 | ||||
2053 | llvm::SmallVector<CXXMethodDecl*, 4> FinalOverriders; | |||
2054 | auto AddFinalOverrider = [&](CXXMethodDecl *D) { | |||
2055 | // If this function is overridden by a candidate final overrider, it is not | |||
2056 | // a final overrider. | |||
2057 | for (CXXMethodDecl *OtherD : FinalOverriders) { | |||
2058 | if (declaresSameEntity(D, OtherD) || recursivelyOverrides(OtherD, D)) | |||
2059 | return; | |||
2060 | } | |||
2061 | ||||
2062 | // Other candidate final overriders might be overridden by this function. | |||
2063 | FinalOverriders.erase( | |||
2064 | std::remove_if(FinalOverriders.begin(), FinalOverriders.end(), | |||
2065 | [&](CXXMethodDecl *OtherD) { | |||
2066 | return recursivelyOverrides(D, OtherD); | |||
2067 | }), | |||
2068 | FinalOverriders.end()); | |||
2069 | ||||
2070 | FinalOverriders.push_back(D); | |||
2071 | }; | |||
2072 | ||||
2073 | for (const auto &I : RD->bases()) { | |||
2074 | const RecordType *RT = I.getType()->getAs<RecordType>(); | |||
2075 | if (!RT) | |||
2076 | continue; | |||
2077 | const auto *Base = cast<CXXRecordDecl>(RT->getDecl()); | |||
2078 | if (CXXMethodDecl *D = this->getCorrespondingMethodInClass(Base)) | |||
2079 | AddFinalOverrider(D); | |||
2080 | } | |||
2081 | ||||
2082 | return FinalOverriders.size() == 1 ? FinalOverriders.front() : nullptr; | |||
2083 | } | |||
2084 | ||||
2085 | CXXMethodDecl *CXXMethodDecl::Create(ASTContext &C, CXXRecordDecl *RD, | |||
2086 | SourceLocation StartLoc, | |||
2087 | const DeclarationNameInfo &NameInfo, | |||
2088 | QualType T, TypeSourceInfo *TInfo, | |||
2089 | StorageClass SC, bool isInline, | |||
2090 | ConstexprSpecKind ConstexprKind, | |||
2091 | SourceLocation EndLocation, | |||
2092 | Expr *TrailingRequiresClause) { | |||
2093 | return new (C, RD) | |||
2094 | CXXMethodDecl(CXXMethod, C, RD, StartLoc, NameInfo, T, TInfo, SC, | |||
2095 | isInline, ConstexprKind, EndLocation, | |||
2096 | TrailingRequiresClause); | |||
2097 | } | |||
2098 | ||||
2099 | CXXMethodDecl *CXXMethodDecl::CreateDeserialized(ASTContext &C, unsigned ID) { | |||
2100 | return new (C, ID) CXXMethodDecl( | |||
2101 | CXXMethod, C, nullptr, SourceLocation(), DeclarationNameInfo(), | |||
2102 | QualType(), nullptr, SC_None, false, CSK_unspecified, SourceLocation(), | |||
2103 | nullptr); | |||
2104 | } | |||
2105 | ||||
2106 | CXXMethodDecl *CXXMethodDecl::getDevirtualizedMethod(const Expr *Base, | |||
2107 | bool IsAppleKext) { | |||
2108 | assert(isVirtual() && "this method is expected to be virtual")((isVirtual() && "this method is expected to be virtual" ) ? static_cast<void> (0) : __assert_fail ("isVirtual() && \"this method is expected to be virtual\"" , "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/AST/DeclCXX.cpp" , 2108, __PRETTY_FUNCTION__)); | |||
2109 | ||||
2110 | // When building with -fapple-kext, all calls must go through the vtable since | |||
2111 | // the kernel linker can do runtime patching of vtables. | |||
2112 | if (IsAppleKext) | |||
2113 | return nullptr; | |||
2114 | ||||
2115 | // If the member function is marked 'final', we know that it can't be | |||
2116 | // overridden and can therefore devirtualize it unless it's pure virtual. | |||
2117 | if (hasAttr<FinalAttr>()) | |||
2118 | return isPure() ? nullptr : this; | |||
2119 | ||||
2120 | // If Base is unknown, we cannot devirtualize. | |||
2121 | if (!Base) | |||
2122 | return nullptr; | |||
2123 | ||||
2124 | // If the base expression (after skipping derived-to-base conversions) is a | |||
2125 | // class prvalue, then we can devirtualize. | |||
2126 | Base = Base->getBestDynamicClassTypeExpr(); | |||
2127 | if (Base->isRValue() && Base->getType()->isRecordType()) | |||
2128 | return this; | |||
2129 | ||||
2130 | // If we don't even know what we would call, we can't devirtualize. | |||
2131 | const CXXRecordDecl *BestDynamicDecl = Base->getBestDynamicClassType(); | |||
2132 | if (!BestDynamicDecl) | |||
2133 | return nullptr; | |||
2134 | ||||
2135 | // There may be a method corresponding to MD in a derived class. | |||
2136 | CXXMethodDecl *DevirtualizedMethod = | |||
2137 | getCorrespondingMethodInClass(BestDynamicDecl); | |||
2138 | ||||
2139 | // If there final overrider in the dynamic type is ambiguous, we can't | |||
2140 | // devirtualize this call. | |||
2141 | if (!DevirtualizedMethod) | |||
2142 | return nullptr; | |||
2143 | ||||
2144 | // If that method is pure virtual, we can't devirtualize. If this code is | |||
2145 | // reached, the result would be UB, not a direct call to the derived class | |||
2146 | // function, and we can't assume the derived class function is defined. | |||
2147 | if (DevirtualizedMethod->isPure()) | |||
2148 | return nullptr; | |||
2149 | ||||
2150 | // If that method is marked final, we can devirtualize it. | |||
2151 | if (DevirtualizedMethod->hasAttr<FinalAttr>()) | |||
2152 | return DevirtualizedMethod; | |||
2153 | ||||
2154 | // Similarly, if the class itself or its destructor is marked 'final', | |||
2155 | // the class can't be derived from and we can therefore devirtualize the | |||
2156 | // member function call. | |||
2157 | if (BestDynamicDecl->isEffectivelyFinal()) | |||
2158 | return DevirtualizedMethod; | |||
2159 | ||||
2160 | if (const auto *DRE = dyn_cast<DeclRefExpr>(Base)) { | |||
2161 | if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) | |||
2162 | if (VD->getType()->isRecordType()) | |||
2163 | // This is a record decl. We know the type and can devirtualize it. | |||
2164 | return DevirtualizedMethod; | |||
2165 | ||||
2166 | return nullptr; | |||
2167 | } | |||
2168 | ||||
2169 | // We can devirtualize calls on an object accessed by a class member access | |||
2170 | // expression, since by C++11 [basic.life]p6 we know that it can't refer to | |||
2171 | // a derived class object constructed in the same location. | |||
2172 | if (const auto *ME = dyn_cast<MemberExpr>(Base)) { | |||
2173 | const ValueDecl *VD = ME->getMemberDecl(); | |||
2174 | return VD->getType()->isRecordType() ? DevirtualizedMethod : nullptr; | |||
2175 | } | |||
2176 | ||||
2177 | // Likewise for calls on an object accessed by a (non-reference) pointer to | |||
2178 | // member access. | |||
2179 | if (auto *BO = dyn_cast<BinaryOperator>(Base)) { | |||
2180 | if (BO->isPtrMemOp()) { | |||
2181 | auto *MPT = BO->getRHS()->getType()->castAs<MemberPointerType>(); | |||
2182 | if (MPT->getPointeeType()->isRecordType()) | |||
2183 | return DevirtualizedMethod; | |||
2184 | } | |||
2185 | } | |||
2186 | ||||
2187 | // We can't devirtualize the call. | |||
2188 | return nullptr; | |||
2189 | } | |||
2190 | ||||
2191 | bool CXXMethodDecl::isUsualDeallocationFunction( | |||
2192 | SmallVectorImpl<const FunctionDecl *> &PreventedBy) const { | |||
2193 | assert(PreventedBy.empty() && "PreventedBy is expected to be empty")((PreventedBy.empty() && "PreventedBy is expected to be empty" ) ? static_cast<void> (0) : __assert_fail ("PreventedBy.empty() && \"PreventedBy is expected to be empty\"" , "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/AST/DeclCXX.cpp" , 2193, __PRETTY_FUNCTION__)); | |||
2194 | if (getOverloadedOperator() != OO_Delete && | |||
2195 | getOverloadedOperator() != OO_Array_Delete) | |||
2196 | return false; | |||
2197 | ||||
2198 | // C++ [basic.stc.dynamic.deallocation]p2: | |||
2199 | // A template instance is never a usual deallocation function, | |||
2200 | // regardless of its signature. | |||
2201 | if (getPrimaryTemplate()) | |||
2202 | return false; | |||
2203 | ||||
2204 | // C++ [basic.stc.dynamic.deallocation]p2: | |||
2205 | // If a class T has a member deallocation function named operator delete | |||
2206 | // with exactly one parameter, then that function is a usual (non-placement) | |||
2207 | // deallocation function. [...] | |||
2208 | if (getNumParams() == 1) | |||
2209 | return true; | |||
2210 | unsigned UsualParams = 1; | |||
2211 | ||||
2212 | // C++ P0722: | |||
2213 | // A destroying operator delete is a usual deallocation function if | |||
2214 | // removing the std::destroying_delete_t parameter and changing the | |||
2215 | // first parameter type from T* to void* results in the signature of | |||
2216 | // a usual deallocation function. | |||
2217 | if (isDestroyingOperatorDelete()) | |||
2218 | ++UsualParams; | |||
2219 | ||||
2220 | // C++ <=14 [basic.stc.dynamic.deallocation]p2: | |||
2221 | // [...] If class T does not declare such an operator delete but does | |||
2222 | // declare a member deallocation function named operator delete with | |||
2223 | // exactly two parameters, the second of which has type std::size_t (18.1), | |||
2224 | // then this function is a usual deallocation function. | |||
2225 | // | |||
2226 | // C++17 says a usual deallocation function is one with the signature | |||
2227 | // (void* [, size_t] [, std::align_val_t] [, ...]) | |||
2228 | // and all such functions are usual deallocation functions. It's not clear | |||
2229 | // that allowing varargs functions was intentional. | |||
2230 | ASTContext &Context = getASTContext(); | |||
2231 | if (UsualParams < getNumParams() && | |||
2232 | Context.hasSameUnqualifiedType(getParamDecl(UsualParams)->getType(), | |||
2233 | Context.getSizeType())) | |||
2234 | ++UsualParams; | |||
2235 | ||||
2236 | if (UsualParams < getNumParams() && | |||
2237 | getParamDecl(UsualParams)->getType()->isAlignValT()) | |||
2238 | ++UsualParams; | |||
2239 | ||||
2240 | if (UsualParams != getNumParams()) | |||
2241 | return false; | |||
2242 | ||||
2243 | // In C++17 onwards, all potential usual deallocation functions are actual | |||
2244 | // usual deallocation functions. Honor this behavior when post-C++14 | |||
2245 | // deallocation functions are offered as extensions too. | |||
2246 | // FIXME(EricWF): Destrying Delete should be a language option. How do we | |||
2247 | // handle when destroying delete is used prior to C++17? | |||
2248 | if (Context.getLangOpts().CPlusPlus17 || | |||
2249 | Context.getLangOpts().AlignedAllocation || | |||
2250 | isDestroyingOperatorDelete()) | |||
2251 | return true; | |||
2252 | ||||
2253 | // This function is a usual deallocation function if there are no | |||
2254 | // single-parameter deallocation functions of the same kind. | |||
2255 | DeclContext::lookup_result R = getDeclContext()->lookup(getDeclName()); | |||
2256 | bool Result = true; | |||
2257 | for (const auto *D : R) { | |||
2258 | if (const auto *FD = dyn_cast<FunctionDecl>(D)) { | |||
2259 | if (FD->getNumParams() == 1) { | |||
2260 | PreventedBy.push_back(FD); | |||
2261 | Result = false; | |||
2262 | } | |||
2263 | } | |||
2264 | } | |||
2265 | return Result; | |||
2266 | } | |||
2267 | ||||
2268 | bool CXXMethodDecl::isCopyAssignmentOperator() const { | |||
2269 | // C++0x [class.copy]p17: | |||
2270 | // A user-declared copy assignment operator X::operator= is a non-static | |||
2271 | // non-template member function of class X with exactly one parameter of | |||
2272 | // type X, X&, const X&, volatile X& or const volatile X&. | |||
2273 | if (/*operator=*/getOverloadedOperator() != OO_Equal || | |||
2274 | /*non-static*/ isStatic() || | |||
2275 | /*non-template*/getPrimaryTemplate() || getDescribedFunctionTemplate() || | |||
2276 | getNumParams() != 1) | |||
2277 | return false; | |||
2278 | ||||
2279 | QualType ParamType = getParamDecl(0)->getType(); | |||
2280 | if (const auto *Ref = ParamType->getAs<LValueReferenceType>()) | |||
2281 | ParamType = Ref->getPointeeType(); | |||
2282 | ||||
2283 | ASTContext &Context = getASTContext(); | |||
2284 | QualType ClassType | |||
2285 | = Context.getCanonicalType(Context.getTypeDeclType(getParent())); | |||
2286 | return Context.hasSameUnqualifiedType(ClassType, ParamType); | |||
2287 | } | |||
2288 | ||||
2289 | bool CXXMethodDecl::isMoveAssignmentOperator() const { | |||
2290 | // C++0x [class.copy]p19: | |||
2291 | // A user-declared move assignment operator X::operator= is a non-static | |||
2292 | // non-template member function of class X with exactly one parameter of type | |||
2293 | // X&&, const X&&, volatile X&&, or const volatile X&&. | |||
2294 | if (getOverloadedOperator() != OO_Equal || isStatic() || | |||
2295 | getPrimaryTemplate() || getDescribedFunctionTemplate() || | |||
2296 | getNumParams() != 1) | |||
2297 | return false; | |||
2298 | ||||
2299 | QualType ParamType = getParamDecl(0)->getType(); | |||
2300 | if (!isa<RValueReferenceType>(ParamType)) | |||
2301 | return false; | |||
2302 | ParamType = ParamType->getPointeeType(); | |||
2303 | ||||
2304 | ASTContext &Context = getASTContext(); | |||
2305 | QualType ClassType | |||
2306 | = Context.getCanonicalType(Context.getTypeDeclType(getParent())); | |||
2307 | return Context.hasSameUnqualifiedType(ClassType, ParamType); | |||
2308 | } | |||
2309 | ||||
2310 | void CXXMethodDecl::addOverriddenMethod(const CXXMethodDecl *MD) { | |||
2311 | assert(MD->isCanonicalDecl() && "Method is not canonical!")((MD->isCanonicalDecl() && "Method is not canonical!" ) ? static_cast<void> (0) : __assert_fail ("MD->isCanonicalDecl() && \"Method is not canonical!\"" , "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/AST/DeclCXX.cpp" , 2311, __PRETTY_FUNCTION__)); | |||
2312 | assert(!MD->getParent()->isDependentContext() &&((!MD->getParent()->isDependentContext() && "Can't add an overridden method to a class template!" ) ? static_cast<void> (0) : __assert_fail ("!MD->getParent()->isDependentContext() && \"Can't add an overridden method to a class template!\"" , "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/AST/DeclCXX.cpp" , 2313, __PRETTY_FUNCTION__)) | |||
2313 | "Can't add an overridden method to a class template!")((!MD->getParent()->isDependentContext() && "Can't add an overridden method to a class template!" ) ? static_cast<void> (0) : __assert_fail ("!MD->getParent()->isDependentContext() && \"Can't add an overridden method to a class template!\"" , "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/AST/DeclCXX.cpp" , 2313, __PRETTY_FUNCTION__)); | |||
2314 | assert(MD->isVirtual() && "Method is not virtual!")((MD->isVirtual() && "Method is not virtual!") ? static_cast <void> (0) : __assert_fail ("MD->isVirtual() && \"Method is not virtual!\"" , "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/AST/DeclCXX.cpp" , 2314, __PRETTY_FUNCTION__)); | |||
2315 | ||||
2316 | getASTContext().addOverriddenMethod(this, MD); | |||
2317 | } | |||
2318 | ||||
2319 | CXXMethodDecl::method_iterator CXXMethodDecl::begin_overridden_methods() const { | |||
2320 | if (isa<CXXConstructorDecl>(this)) return nullptr; | |||
2321 | return getASTContext().overridden_methods_begin(this); | |||
2322 | } | |||
2323 | ||||
2324 | CXXMethodDecl::method_iterator CXXMethodDecl::end_overridden_methods() const { | |||
2325 | if (isa<CXXConstructorDecl>(this)) return nullptr; | |||
2326 | return getASTContext().overridden_methods_end(this); | |||
2327 | } | |||
2328 | ||||
2329 | unsigned CXXMethodDecl::size_overridden_methods() const { | |||
2330 | if (isa<CXXConstructorDecl>(this)) return 0; | |||
2331 | return getASTContext().overridden_methods_size(this); | |||
2332 | } | |||
2333 | ||||
2334 | CXXMethodDecl::overridden_method_range | |||
2335 | CXXMethodDecl::overridden_methods() const { | |||
2336 | if (isa<CXXConstructorDecl>(this)) | |||
2337 | return overridden_method_range(nullptr, nullptr); | |||
2338 | return getASTContext().overridden_methods(this); | |||
2339 | } | |||
2340 | ||||
2341 | static QualType getThisObjectType(ASTContext &C, const FunctionProtoType *FPT, | |||
2342 | const CXXRecordDecl *Decl) { | |||
2343 | QualType ClassTy = C.getTypeDeclType(Decl); | |||
2344 | return C.getQualifiedType(ClassTy, FPT->getMethodQuals()); | |||
| ||||
2345 | } | |||
2346 | ||||
2347 | QualType CXXMethodDecl::getThisType(const FunctionProtoType *FPT, | |||
2348 | const CXXRecordDecl *Decl) { | |||
2349 | ASTContext &C = Decl->getASTContext(); | |||
2350 | QualType ObjectTy = ::getThisObjectType(C, FPT, Decl); | |||
2351 | return C.getPointerType(ObjectTy); | |||
2352 | } | |||
2353 | ||||
2354 | QualType CXXMethodDecl::getThisObjectType(const FunctionProtoType *FPT, | |||
2355 | const CXXRecordDecl *Decl) { | |||
2356 | ASTContext &C = Decl->getASTContext(); | |||
2357 | return ::getThisObjectType(C, FPT, Decl); | |||
2358 | } | |||
2359 | ||||
2360 | QualType CXXMethodDecl::getThisType() const { | |||
2361 | // C++ 9.3.2p1: The type of this in a member function of a class X is X*. | |||
2362 | // If the member function is declared const, the type of this is const X*, | |||
2363 | // if the member function is declared volatile, the type of this is | |||
2364 | // volatile X*, and if the member function is declared const volatile, | |||
2365 | // the type of this is const volatile X*. | |||
2366 | assert(isInstance() && "No 'this' for static methods!")((isInstance() && "No 'this' for static methods!") ? static_cast <void> (0) : __assert_fail ("isInstance() && \"No 'this' for static methods!\"" , "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/AST/DeclCXX.cpp" , 2366, __PRETTY_FUNCTION__)); | |||
2367 | ||||
2368 | return CXXMethodDecl::getThisType(getType()->getAs<FunctionProtoType>(), | |||
2369 | getParent()); | |||
2370 | } | |||
2371 | ||||
2372 | QualType CXXMethodDecl::getThisObjectType() const { | |||
2373 | // Ditto getThisType. | |||
2374 | assert(isInstance() && "No 'this' for static methods!")((isInstance() && "No 'this' for static methods!") ? static_cast <void> (0) : __assert_fail ("isInstance() && \"No 'this' for static methods!\"" , "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/AST/DeclCXX.cpp" , 2374, __PRETTY_FUNCTION__)); | |||
| ||||
2375 | ||||
2376 | return CXXMethodDecl::getThisObjectType(getType()->getAs<FunctionProtoType>(), | |||
2377 | getParent()); | |||
2378 | } | |||
2379 | ||||
2380 | bool CXXMethodDecl::hasInlineBody() const { | |||
2381 | // If this function is a template instantiation, look at the template from | |||
2382 | // which it was instantiated. | |||
2383 | const FunctionDecl *CheckFn = getTemplateInstantiationPattern(); | |||
2384 | if (!CheckFn) | |||
2385 | CheckFn = this; | |||
2386 | ||||
2387 | const FunctionDecl *fn; | |||
2388 | return CheckFn->isDefined(fn) && !fn->isOutOfLine() && | |||
2389 | (fn->doesThisDeclarationHaveABody() || fn->willHaveBody()); | |||
2390 | } | |||
2391 | ||||
2392 | bool CXXMethodDecl::isLambdaStaticInvoker() const { | |||
2393 | const CXXRecordDecl *P = getParent(); | |||
2394 | if (P->isLambda()) { | |||
2395 | if (const CXXMethodDecl *StaticInvoker = P->getLambdaStaticInvoker()) { | |||
2396 | if (StaticInvoker == this) return true; | |||
2397 | if (P->isGenericLambda() && this->isFunctionTemplateSpecialization()) | |||
2398 | return StaticInvoker == this->getPrimaryTemplate()->getTemplatedDecl(); | |||
2399 | } | |||
2400 | } | |||
2401 | return false; | |||
2402 | } | |||
2403 | ||||
2404 | CXXCtorInitializer::CXXCtorInitializer(ASTContext &Context, | |||
2405 | TypeSourceInfo *TInfo, bool IsVirtual, | |||
2406 | SourceLocation L, Expr *Init, | |||
2407 | SourceLocation R, | |||
2408 | SourceLocation EllipsisLoc) | |||
2409 | : Initializee(TInfo), MemberOrEllipsisLocation(EllipsisLoc), Init(Init), | |||
2410 | LParenLoc(L), RParenLoc(R), IsDelegating(false), IsVirtual(IsVirtual), | |||
2411 | IsWritten(false), SourceOrder(0) {} | |||
2412 | ||||
2413 | CXXCtorInitializer::CXXCtorInitializer(ASTContext &Context, | |||
2414 | FieldDecl *Member, | |||
2415 | SourceLocation MemberLoc, | |||
2416 | SourceLocation L, Expr *Init, | |||
2417 | SourceLocation R) | |||
2418 | : Initializee(Member), MemberOrEllipsisLocation(MemberLoc), Init(Init), | |||
2419 | LParenLoc(L), RParenLoc(R), IsDelegating(false), IsVirtual(false), | |||
2420 | IsWritten(false), SourceOrder(0) {} | |||
2421 | ||||
2422 | CXXCtorInitializer::CXXCtorInitializer(ASTContext &Context, | |||
2423 | IndirectFieldDecl *Member, | |||
2424 | SourceLocation MemberLoc, | |||
2425 | SourceLocation L, Expr *Init, | |||
2426 | SourceLocation R) | |||
2427 | : Initializee(Member), MemberOrEllipsisLocation(MemberLoc), Init(Init), | |||
2428 | LParenLoc(L), RParenLoc(R), IsDelegating(false), IsVirtual(false), | |||
2429 | IsWritten(false), SourceOrder(0) {} | |||
2430 | ||||
2431 | CXXCtorInitializer::CXXCtorInitializer(ASTContext &Context, | |||
2432 | TypeSourceInfo *TInfo, | |||
2433 | SourceLocation L, Expr *Init, | |||
2434 | SourceLocation R) | |||
2435 | : Initializee(TInfo), Init(Init), LParenLoc(L), RParenLoc(R), | |||
2436 | IsDelegating(true), IsVirtual(false), IsWritten(false), SourceOrder(0) {} | |||
2437 | ||||
2438 | int64_t CXXCtorInitializer::getID(const ASTContext &Context) const { | |||
2439 | return Context.getAllocator() | |||
2440 | .identifyKnownAlignedObject<CXXCtorInitializer>(this); | |||
2441 | } | |||
2442 | ||||
2443 | TypeLoc CXXCtorInitializer::getBaseClassLoc() const { | |||
2444 | if (isBaseInitializer()) | |||
2445 | return Initializee.get<TypeSourceInfo*>()->getTypeLoc(); | |||
2446 | else | |||
2447 | return {}; | |||
2448 | } | |||
2449 | ||||
2450 | const Type *CXXCtorInitializer::getBaseClass() const { | |||
2451 | if (isBaseInitializer()) | |||
2452 | return Initializee.get<TypeSourceInfo*>()->getType().getTypePtr(); | |||
2453 | else | |||
2454 | return nullptr; | |||
2455 | } | |||
2456 | ||||
2457 | SourceLocation CXXCtorInitializer::getSourceLocation() const { | |||
2458 | if (isInClassMemberInitializer()) | |||
2459 | return getAnyMember()->getLocation(); | |||
2460 | ||||
2461 | if (isAnyMemberInitializer()) | |||
2462 | return getMemberLocation(); | |||
2463 | ||||
2464 | if (const auto *TSInfo = Initializee.get<TypeSourceInfo *>()) | |||
2465 | return TSInfo->getTypeLoc().getLocalSourceRange().getBegin(); | |||
2466 | ||||
2467 | return {}; | |||
2468 | } | |||
2469 | ||||
2470 | SourceRange CXXCtorInitializer::getSourceRange() const { | |||
2471 | if (isInClassMemberInitializer()) { | |||
2472 | FieldDecl *D = getAnyMember(); | |||
2473 | if (Expr *I = D->getInClassInitializer()) | |||
2474 | return I->getSourceRange(); | |||
2475 | return {}; | |||
2476 | } | |||
2477 | ||||
2478 | return SourceRange(getSourceLocation(), getRParenLoc()); | |||
2479 | } | |||
2480 | ||||
2481 | CXXConstructorDecl::CXXConstructorDecl( | |||
2482 | ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, | |||
2483 | const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, | |||
2484 | ExplicitSpecifier ES, bool isInline, bool isImplicitlyDeclared, | |||
2485 | ConstexprSpecKind ConstexprKind, InheritedConstructor Inherited, | |||
2486 | Expr *TrailingRequiresClause) | |||
2487 | : CXXMethodDecl(CXXConstructor, C, RD, StartLoc, NameInfo, T, TInfo, | |||
2488 | SC_None, isInline, ConstexprKind, SourceLocation(), | |||
2489 | TrailingRequiresClause) { | |||
2490 | setNumCtorInitializers(0); | |||
2491 | setInheritingConstructor(static_cast<bool>(Inherited)); | |||
2492 | setImplicit(isImplicitlyDeclared); | |||
2493 | CXXConstructorDeclBits.HasTrailingExplicitSpecifier = ES.getExpr() ? 1 : 0; | |||
2494 | if (Inherited) | |||
2495 | *getTrailingObjects<InheritedConstructor>() = Inherited; | |||
2496 | setExplicitSpecifier(ES); | |||
2497 | } | |||
2498 | ||||
2499 | void CXXConstructorDecl::anchor() {} | |||
2500 | ||||
2501 | CXXConstructorDecl *CXXConstructorDecl::CreateDeserialized(ASTContext &C, | |||
2502 | unsigned ID, | |||
2503 | uint64_t AllocKind) { | |||
2504 | bool hasTraillingExplicit = static_cast<bool>(AllocKind & TAKHasTailExplicit); | |||
2505 | bool isInheritingConstructor = | |||
2506 | static_cast<bool>(AllocKind & TAKInheritsConstructor); | |||
2507 | unsigned Extra = | |||
2508 | additionalSizeToAlloc<InheritedConstructor, ExplicitSpecifier>( | |||
2509 | isInheritingConstructor, hasTraillingExplicit); | |||
2510 | auto *Result = new (C, ID, Extra) | |||
2511 | CXXConstructorDecl(C, nullptr, SourceLocation(), DeclarationNameInfo(), | |||
2512 | QualType(), nullptr, ExplicitSpecifier(), false, false, | |||
2513 | CSK_unspecified, InheritedConstructor(), nullptr); | |||
2514 | Result->setInheritingConstructor(isInheritingConstructor); | |||
2515 | Result->CXXConstructorDeclBits.HasTrailingExplicitSpecifier = | |||
2516 | hasTraillingExplicit; | |||
2517 | Result->setExplicitSpecifier(ExplicitSpecifier()); | |||
2518 | return Result; | |||
2519 | } | |||
2520 | ||||
2521 | CXXConstructorDecl *CXXConstructorDecl::Create( | |||
2522 | ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, | |||
2523 | const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, | |||
2524 | ExplicitSpecifier ES, bool isInline, bool isImplicitlyDeclared, | |||
2525 | ConstexprSpecKind ConstexprKind, InheritedConstructor Inherited, | |||
2526 | Expr *TrailingRequiresClause) { | |||
2527 | assert(NameInfo.getName().getNameKind()((NameInfo.getName().getNameKind() == DeclarationName::CXXConstructorName && "Name must refer to a constructor") ? static_cast <void> (0) : __assert_fail ("NameInfo.getName().getNameKind() == DeclarationName::CXXConstructorName && \"Name must refer to a constructor\"" , "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/AST/DeclCXX.cpp" , 2529, __PRETTY_FUNCTION__)) | |||
2528 | == DeclarationName::CXXConstructorName &&((NameInfo.getName().getNameKind() == DeclarationName::CXXConstructorName && "Name must refer to a constructor") ? static_cast <void> (0) : __assert_fail ("NameInfo.getName().getNameKind() == DeclarationName::CXXConstructorName && \"Name must refer to a constructor\"" , "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/AST/DeclCXX.cpp" , 2529, __PRETTY_FUNCTION__)) | |||
2529 | "Name must refer to a constructor")((NameInfo.getName().getNameKind() == DeclarationName::CXXConstructorName && "Name must refer to a constructor") ? static_cast <void> (0) : __assert_fail ("NameInfo.getName().getNameKind() == DeclarationName::CXXConstructorName && \"Name must refer to a constructor\"" , "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/AST/DeclCXX.cpp" , 2529, __PRETTY_FUNCTION__)); | |||
2530 | unsigned Extra = | |||
2531 | additionalSizeToAlloc<InheritedConstructor, ExplicitSpecifier>( | |||
2532 | Inherited ? 1 : 0, ES.getExpr() ? 1 : 0); | |||
2533 | return new (C, RD, Extra) | |||
2534 | CXXConstructorDecl(C, RD, StartLoc, NameInfo, T, TInfo, ES, isInline, | |||
2535 | isImplicitlyDeclared, ConstexprKind, Inherited, | |||
2536 | TrailingRequiresClause); | |||
2537 | } | |||
2538 | ||||
2539 | CXXConstructorDecl::init_const_iterator CXXConstructorDecl::init_begin() const { | |||
2540 | return CtorInitializers.get(getASTContext().getExternalSource()); | |||
2541 | } | |||
2542 | ||||
2543 | CXXConstructorDecl *CXXConstructorDecl::getTargetConstructor() const { | |||
2544 | assert(isDelegatingConstructor() && "Not a delegating constructor!")((isDelegatingConstructor() && "Not a delegating constructor!" ) ? static_cast<void> (0) : __assert_fail ("isDelegatingConstructor() && \"Not a delegating constructor!\"" , "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/AST/DeclCXX.cpp" , 2544, __PRETTY_FUNCTION__)); | |||
2545 | Expr *E = (*init_begin())->getInit()->IgnoreImplicit(); | |||
2546 | if (const auto *Construct = dyn_cast<CXXConstructExpr>(E)) | |||
2547 | return Construct->getConstructor(); | |||
2548 | ||||
2549 | return nullptr; | |||
2550 | } | |||
2551 | ||||
2552 | bool CXXConstructorDecl::isDefaultConstructor() const { | |||
2553 | // C++ [class.ctor]p5: | |||
2554 | // A default constructor for a class X is a constructor of class | |||
2555 | // X that can be called without an argument. | |||
2556 | return (getNumParams() == 0) || | |||
2557 | (getNumParams() > 0 && getParamDecl(0)->hasDefaultArg()); | |||
2558 | } | |||
2559 | ||||
2560 | bool | |||
2561 | CXXConstructorDecl::isCopyConstructor(unsigned &TypeQuals) const { | |||
2562 | return isCopyOrMoveConstructor(TypeQuals) && | |||
2563 | getParamDecl(0)->getType()->isLValueReferenceType(); | |||
2564 | } | |||
2565 | ||||
2566 | bool CXXConstructorDecl::isMoveConstructor(unsigned &TypeQuals) const { | |||
2567 | return isCopyOrMoveConstructor(TypeQuals) && | |||
2568 | getParamDecl(0)->getType()->isRValueReferenceType(); | |||
2569 | } | |||
2570 | ||||
2571 | /// Determine whether this is a copy or move constructor. | |||
2572 | bool CXXConstructorDecl::isCopyOrMoveConstructor(unsigned &TypeQuals) const { | |||
2573 | // C++ [class.copy]p2: | |||
2574 | // A non-template constructor for class X is a copy constructor | |||
2575 | // if its first parameter is of type X&, const X&, volatile X& or | |||
2576 | // const volatile X&, and either there are no other parameters | |||
2577 | // or else all other parameters have default arguments (8.3.6). | |||
2578 | // C++0x [class.copy]p3: | |||
2579 | // A non-template constructor for class X is a move constructor if its | |||
2580 | // first parameter is of type X&&, const X&&, volatile X&&, or | |||
2581 | // const volatile X&&, and either there are no other parameters or else | |||
2582 | // all other parameters have default arguments. | |||
2583 | if ((getNumParams() < 1) || | |||
2584 | (getNumParams() > 1 && !getParamDecl(1)->hasDefaultArg()) || | |||
2585 | (getPrimaryTemplate() != nullptr) || | |||
2586 | (getDescribedFunctionTemplate() != nullptr)) | |||
2587 | return false; | |||
2588 | ||||
2589 | const ParmVarDecl *Param = getParamDecl(0); | |||
2590 | ||||
2591 | // Do we have a reference type? | |||
2592 | const auto *ParamRefType = Param->getType()->getAs<ReferenceType>(); | |||
2593 | if (!ParamRefType) | |||
2594 | return false; | |||
2595 | ||||
2596 | // Is it a reference to our class type? | |||
2597 | ASTContext &Context = getASTContext(); | |||
2598 | ||||
2599 | CanQualType PointeeType | |||
2600 | = Context.getCanonicalType(ParamRefType->getPointeeType()); | |||
2601 | CanQualType ClassTy | |||
2602 | = Context.getCanonicalType(Context.getTagDeclType(getParent())); | |||
2603 | if (PointeeType.getUnqualifiedType() != ClassTy) | |||
2604 | return false; | |||
2605 | ||||
2606 | // FIXME: other qualifiers? | |||
2607 | ||||
2608 | // We have a copy or move constructor. | |||
2609 | TypeQuals = PointeeType.getCVRQualifiers(); | |||
2610 | return true; | |||
2611 | } | |||
2612 | ||||
2613 | bool CXXConstructorDecl::isConvertingConstructor(bool AllowExplicit) const { | |||
2614 | // C++ [class.conv.ctor]p1: | |||
2615 | // A constructor declared without the function-specifier explicit | |||
2616 | // that can be called with a single parameter specifies a | |||
2617 | // conversion from the type of its first parameter to the type of | |||
2618 | // its class. Such a constructor is called a converting | |||
2619 | // constructor. | |||
2620 | if (isExplicit() && !AllowExplicit) | |||
2621 | return false; | |||
2622 | ||||
2623 | return (getNumParams() == 0 && | |||
2624 | getType()->castAs<FunctionProtoType>()->isVariadic()) || | |||
2625 | (getNumParams() == 1) || | |||
2626 | (getNumParams() > 1 && | |||
2627 | (getParamDecl(1)->hasDefaultArg() || | |||
2628 | getParamDecl(1)->isParameterPack())); | |||
2629 | } | |||
2630 | ||||
2631 | bool CXXConstructorDecl::isSpecializationCopyingObject() const { | |||
2632 | if ((getNumParams() < 1) || | |||
2633 | (getNumParams() > 1 && !getParamDecl(1)->hasDefaultArg()) || | |||
2634 | (getDescribedFunctionTemplate() != nullptr)) | |||
2635 | return false; | |||
2636 | ||||
2637 | const ParmVarDecl *Param = getParamDecl(0); | |||
2638 | ||||
2639 | ASTContext &Context = getASTContext(); | |||
2640 | CanQualType ParamType = Context.getCanonicalType(Param->getType()); | |||
2641 | ||||
2642 | // Is it the same as our class type? | |||
2643 | CanQualType ClassTy | |||
2644 | = Context.getCanonicalType(Context.getTagDeclType(getParent())); | |||
2645 | if (ParamType.getUnqualifiedType() != ClassTy) | |||
2646 | return false; | |||
2647 | ||||
2648 | return true; | |||
2649 | } | |||
2650 | ||||
2651 | void CXXDestructorDecl::anchor() {} | |||
2652 | ||||
2653 | CXXDestructorDecl * | |||
2654 | CXXDestructorDecl::CreateDeserialized(ASTContext &C, unsigned ID) { | |||
2655 | return new (C, ID) | |||
2656 | CXXDestructorDecl(C, nullptr, SourceLocation(), DeclarationNameInfo(), | |||
2657 | QualType(), nullptr, false, false, CSK_unspecified, | |||
2658 | nullptr); | |||
2659 | } | |||
2660 | ||||
2661 | CXXDestructorDecl *CXXDestructorDecl::Create( | |||
2662 | ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, | |||
2663 | const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, | |||
2664 | bool isInline, bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind, | |||
2665 | Expr *TrailingRequiresClause) { | |||
2666 | assert(NameInfo.getName().getNameKind()((NameInfo.getName().getNameKind() == DeclarationName::CXXDestructorName && "Name must refer to a destructor") ? static_cast< void> (0) : __assert_fail ("NameInfo.getName().getNameKind() == DeclarationName::CXXDestructorName && \"Name must refer to a destructor\"" , "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/AST/DeclCXX.cpp" , 2668, __PRETTY_FUNCTION__)) | |||
2667 | == DeclarationName::CXXDestructorName &&((NameInfo.getName().getNameKind() == DeclarationName::CXXDestructorName && "Name must refer to a destructor") ? static_cast< void> (0) : __assert_fail ("NameInfo.getName().getNameKind() == DeclarationName::CXXDestructorName && \"Name must refer to a destructor\"" , "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/AST/DeclCXX.cpp" , 2668, __PRETTY_FUNCTION__)) | |||
2668 | "Name must refer to a destructor")((NameInfo.getName().getNameKind() == DeclarationName::CXXDestructorName && "Name must refer to a destructor") ? static_cast< void> (0) : __assert_fail ("NameInfo.getName().getNameKind() == DeclarationName::CXXDestructorName && \"Name must refer to a destructor\"" , "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/AST/DeclCXX.cpp" , 2668, __PRETTY_FUNCTION__)); | |||
2669 | return new (C, RD) | |||
2670 | CXXDestructorDecl(C, RD, StartLoc, NameInfo, T, TInfo, isInline, | |||
2671 | isImplicitlyDeclared, ConstexprKind, | |||
2672 | TrailingRequiresClause); | |||
2673 | } | |||
2674 | ||||
2675 | void CXXDestructorDecl::setOperatorDelete(FunctionDecl *OD, Expr *ThisArg) { | |||
2676 | auto *First = cast<CXXDestructorDecl>(getFirstDecl()); | |||
2677 | if (OD && !First->OperatorDelete) { | |||
2678 | First->OperatorDelete = OD; | |||
2679 | First->OperatorDeleteThisArg = ThisArg; | |||
2680 | if (auto *L = getASTMutationListener()) | |||
2681 | L->ResolvedOperatorDelete(First, OD, ThisArg); | |||
2682 | } | |||
2683 | } | |||
2684 | ||||
2685 | void CXXConversionDecl::anchor() {} | |||
2686 | ||||
2687 | CXXConversionDecl * | |||
2688 | CXXConversionDecl::CreateDeserialized(ASTContext &C, unsigned ID) { | |||
2689 | return new (C, ID) CXXConversionDecl( | |||
2690 | C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(), nullptr, | |||
2691 | false, ExplicitSpecifier(), CSK_unspecified, SourceLocation(), nullptr); | |||
2692 | } | |||
2693 | ||||
2694 | CXXConversionDecl *CXXConversionDecl::Create( | |||
2695 | ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, | |||
2696 | const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, | |||
2697 | bool isInline, ExplicitSpecifier ES, ConstexprSpecKind ConstexprKind, | |||
2698 | SourceLocation EndLocation, Expr *TrailingRequiresClause) { | |||
2699 | assert(NameInfo.getName().getNameKind()((NameInfo.getName().getNameKind() == DeclarationName::CXXConversionFunctionName && "Name must refer to a conversion function") ? static_cast <void> (0) : __assert_fail ("NameInfo.getName().getNameKind() == DeclarationName::CXXConversionFunctionName && \"Name must refer to a conversion function\"" , "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/AST/DeclCXX.cpp" , 2701, __PRETTY_FUNCTION__)) | |||
2700 | == DeclarationName::CXXConversionFunctionName &&((NameInfo.getName().getNameKind() == DeclarationName::CXXConversionFunctionName && "Name must refer to a conversion function") ? static_cast <void> (0) : __assert_fail ("NameInfo.getName().getNameKind() == DeclarationName::CXXConversionFunctionName && \"Name must refer to a conversion function\"" , "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/AST/DeclCXX.cpp" , 2701, __PRETTY_FUNCTION__)) | |||
2701 | "Name must refer to a conversion function")((NameInfo.getName().getNameKind() == DeclarationName::CXXConversionFunctionName && "Name must refer to a conversion function") ? static_cast <void> (0) : __assert_fail ("NameInfo.getName().getNameKind() == DeclarationName::CXXConversionFunctionName && \"Name must refer to a conversion function\"" , "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/AST/DeclCXX.cpp" , 2701, __PRETTY_FUNCTION__)); | |||
2702 | return new (C, RD) | |||
2703 | CXXConversionDecl(C, RD, StartLoc, NameInfo, T, TInfo, isInline, ES, | |||
2704 | ConstexprKind, EndLocation, TrailingRequiresClause); | |||
2705 | } | |||
2706 | ||||
2707 | bool CXXConversionDecl::isLambdaToBlockPointerConversion() const { | |||
2708 | return isImplicit() && getParent()->isLambda() && | |||
2709 | getConversionType()->isBlockPointerType(); | |||
2710 | } | |||
2711 | ||||
2712 | LinkageSpecDecl::LinkageSpecDecl(DeclContext *DC, SourceLocation ExternLoc, | |||
2713 | SourceLocation LangLoc, LanguageIDs lang, | |||
2714 | bool HasBraces) | |||
2715 | : Decl(LinkageSpec, DC, LangLoc), DeclContext(LinkageSpec), | |||
2716 | ExternLoc(ExternLoc), RBraceLoc(SourceLocation()) { | |||
2717 | setLanguage(lang); | |||
2718 | LinkageSpecDeclBits.HasBraces = HasBraces; | |||
2719 | } | |||
2720 | ||||
2721 | void LinkageSpecDecl::anchor() {} | |||
2722 | ||||
2723 | LinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C, | |||
2724 | DeclContext *DC, | |||
2725 | SourceLocation ExternLoc, | |||
2726 | SourceLocation LangLoc, | |||
2727 | LanguageIDs Lang, | |||
2728 | bool HasBraces) { | |||
2729 | return new (C, DC) LinkageSpecDecl(DC, ExternLoc, LangLoc, Lang, HasBraces); | |||
2730 | } | |||
2731 | ||||
2732 | LinkageSpecDecl *LinkageSpecDecl::CreateDeserialized(ASTContext &C, | |||
2733 | unsigned ID) { | |||
2734 | return new (C, ID) LinkageSpecDecl(nullptr, SourceLocation(), | |||
2735 | SourceLocation(), lang_c, false); | |||
2736 | } | |||
2737 | ||||
2738 | void UsingDirectiveDecl::anchor() {} | |||
2739 | ||||
2740 | UsingDirectiveDecl *UsingDirectiveDecl::Create(ASTContext &C, DeclContext *DC, | |||
2741 | SourceLocation L, | |||
2742 | SourceLocation NamespaceLoc, | |||
2743 | NestedNameSpecifierLoc QualifierLoc, | |||
2744 | SourceLocation IdentLoc, | |||
2745 | NamedDecl *Used, | |||
2746 | DeclContext *CommonAncestor) { | |||
2747 | if (auto *NS = dyn_cast_or_null<NamespaceDecl>(Used)) | |||
2748 | Used = NS->getOriginalNamespace(); | |||
2749 | return new (C, DC) UsingDirectiveDecl(DC, L, NamespaceLoc, QualifierLoc, | |||
2750 | IdentLoc, Used, CommonAncestor); | |||
2751 | } | |||
2752 | ||||
2753 | UsingDirectiveDecl *UsingDirectiveDecl::CreateDeserialized(ASTContext &C, | |||
2754 | unsigned ID) { | |||
2755 | return new (C, ID) UsingDirectiveDecl(nullptr, SourceLocation(), | |||
2756 | SourceLocation(), | |||
2757 | NestedNameSpecifierLoc(), | |||
2758 | SourceLocation(), nullptr, nullptr); | |||
2759 | } | |||
2760 | ||||
2761 | NamespaceDecl *UsingDirectiveDecl::getNominatedNamespace() { | |||
2762 | if (auto *NA = dyn_cast_or_null<NamespaceAliasDecl>(NominatedNamespace)) | |||
2763 | return NA->getNamespace(); | |||
2764 | return cast_or_null<NamespaceDecl>(NominatedNamespace); | |||
2765 | } | |||
2766 | ||||
2767 | NamespaceDecl::NamespaceDecl(ASTContext &C, DeclContext *DC, bool Inline, | |||
2768 | SourceLocation StartLoc, SourceLocation IdLoc, | |||
2769 | IdentifierInfo *Id, NamespaceDecl *PrevDecl) | |||
2770 | : NamedDecl(Namespace, DC, IdLoc, Id), DeclContext(Namespace), | |||
2771 | redeclarable_base(C), LocStart(StartLoc), | |||
2772 | AnonOrFirstNamespaceAndInline(nullptr, Inline) { | |||
2773 | setPreviousDecl(PrevDecl); | |||
2774 | ||||
2775 | if (PrevDecl) | |||
2776 | AnonOrFirstNamespaceAndInline.setPointer(PrevDecl->getOriginalNamespace()); | |||
2777 | } | |||
2778 | ||||
2779 | NamespaceDecl *NamespaceDecl::Create(ASTContext &C, DeclContext *DC, | |||
2780 | bool Inline, SourceLocation StartLoc, | |||
2781 | SourceLocation IdLoc, IdentifierInfo *Id, | |||
2782 | NamespaceDecl *PrevDecl) { | |||
2783 | return new (C, DC) NamespaceDecl(C, DC, Inline, StartLoc, IdLoc, Id, | |||
2784 | PrevDecl); | |||
2785 | } | |||
2786 | ||||
2787 | NamespaceDecl *NamespaceDecl::CreateDeserialized(ASTContext &C, unsigned ID) { | |||
2788 | return new (C, ID) NamespaceDecl(C, nullptr, false, SourceLocation(), | |||
2789 | SourceLocation(), nullptr, nullptr); | |||
2790 | } | |||
2791 | ||||
2792 | NamespaceDecl *NamespaceDecl::getOriginalNamespace() { | |||
2793 | if (isFirstDecl()) | |||
2794 | return this; | |||
2795 | ||||
2796 | return AnonOrFirstNamespaceAndInline.getPointer(); | |||
2797 | } | |||
2798 | ||||
2799 | const NamespaceDecl *NamespaceDecl::getOriginalNamespace() const { | |||
2800 | if (isFirstDecl()) | |||
2801 | return this; | |||
2802 | ||||
2803 | return AnonOrFirstNamespaceAndInline.getPointer(); | |||
2804 | } | |||
2805 | ||||
2806 | bool NamespaceDecl::isOriginalNamespace() const { return isFirstDecl(); } | |||
2807 | ||||
2808 | NamespaceDecl *NamespaceDecl::getNextRedeclarationImpl() { | |||
2809 | return getNextRedeclaration(); | |||
2810 | } | |||
2811 | ||||
2812 | NamespaceDecl *NamespaceDecl::getPreviousDeclImpl() { | |||
2813 | return getPreviousDecl(); | |||
2814 | } | |||
2815 | ||||
2816 | NamespaceDecl *NamespaceDecl::getMostRecentDeclImpl() { | |||
2817 | return getMostRecentDecl(); | |||
2818 | } | |||
2819 | ||||
2820 | void NamespaceAliasDecl::anchor() {} | |||
2821 | ||||
2822 | NamespaceAliasDecl *NamespaceAliasDecl::getNextRedeclarationImpl() { | |||
2823 | return getNextRedeclaration(); | |||
2824 | } | |||
2825 | ||||
2826 | NamespaceAliasDecl *NamespaceAliasDecl::getPreviousDeclImpl() { | |||
2827 | return getPreviousDecl(); | |||
2828 | } | |||
2829 | ||||
2830 | NamespaceAliasDecl *NamespaceAliasDecl::getMostRecentDeclImpl() { | |||
2831 | return getMostRecentDecl(); | |||
2832 | } | |||
2833 | ||||
2834 | NamespaceAliasDecl *NamespaceAliasDecl::Create(ASTContext &C, DeclContext *DC, | |||
2835 | SourceLocation UsingLoc, | |||
2836 | SourceLocation AliasLoc, | |||
2837 | IdentifierInfo *Alias, | |||
2838 | NestedNameSpecifierLoc QualifierLoc, | |||
2839 | SourceLocation IdentLoc, | |||
2840 | NamedDecl *Namespace) { | |||
2841 | // FIXME: Preserve the aliased namespace as written. | |||
2842 | if (auto *NS = dyn_cast_or_null<NamespaceDecl>(Namespace)) | |||
2843 | Namespace = NS->getOriginalNamespace(); | |||
2844 | return new (C, DC) NamespaceAliasDecl(C, DC, UsingLoc, AliasLoc, Alias, | |||
2845 | QualifierLoc, IdentLoc, Namespace); | |||
2846 | } | |||
2847 | ||||
2848 | NamespaceAliasDecl * | |||
2849 | NamespaceAliasDecl::CreateDeserialized(ASTContext &C, unsigned ID) { | |||
2850 | return new (C, ID) NamespaceAliasDecl(C, nullptr, SourceLocation(), | |||
2851 | SourceLocation(), nullptr, | |||
2852 | NestedNameSpecifierLoc(), | |||
2853 | SourceLocation(), nullptr); | |||
2854 | } | |||
2855 | ||||
2856 | void LifetimeExtendedTemporaryDecl::anchor() {} | |||
2857 | ||||
2858 | /// Retrieve the storage duration for the materialized temporary. | |||
2859 | StorageDuration LifetimeExtendedTemporaryDecl::getStorageDuration() const { | |||
2860 | const ValueDecl *ExtendingDecl = getExtendingDecl(); | |||
2861 | if (!ExtendingDecl) | |||
2862 | return SD_FullExpression; | |||
2863 | // FIXME: This is not necessarily correct for a temporary materialized | |||
2864 | // within a default initializer. | |||
2865 | if (isa<FieldDecl>(ExtendingDecl)) | |||
2866 | return SD_Automatic; | |||
2867 | // FIXME: This only works because storage class specifiers are not allowed | |||
2868 | // on decomposition declarations. | |||
2869 | if (isa<BindingDecl>(ExtendingDecl)) | |||
2870 | return ExtendingDecl->getDeclContext()->isFunctionOrMethod() ? SD_Automatic | |||
2871 | : SD_Static; | |||
2872 | return cast<VarDecl>(ExtendingDecl)->getStorageDuration(); | |||
2873 | } | |||
2874 | ||||
2875 | APValue *LifetimeExtendedTemporaryDecl::getOrCreateValue(bool MayCreate) const { | |||
2876 | assert(getStorageDuration() == SD_Static &&((getStorageDuration() == SD_Static && "don't need to cache the computed value for this temporary" ) ? static_cast<void> (0) : __assert_fail ("getStorageDuration() == SD_Static && \"don't need to cache the computed value for this temporary\"" , "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/AST/DeclCXX.cpp" , 2877, __PRETTY_FUNCTION__)) | |||
2877 | "don't need to cache the computed value for this temporary")((getStorageDuration() == SD_Static && "don't need to cache the computed value for this temporary" ) ? static_cast<void> (0) : __assert_fail ("getStorageDuration() == SD_Static && \"don't need to cache the computed value for this temporary\"" , "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/AST/DeclCXX.cpp" , 2877, __PRETTY_FUNCTION__)); | |||
2878 | if (MayCreate && !Value) { | |||
2879 | Value = (new (getASTContext()) APValue); | |||
2880 | getASTContext().addDestruction(Value); | |||
2881 | } | |||
2882 | assert(Value && "may not be null")((Value && "may not be null") ? static_cast<void> (0) : __assert_fail ("Value && \"may not be null\"", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/AST/DeclCXX.cpp" , 2882, __PRETTY_FUNCTION__)); | |||
2883 | return Value; | |||
2884 | } | |||
2885 | ||||
2886 | void UsingShadowDecl::anchor() {} | |||
2887 | ||||
2888 | UsingShadowDecl::UsingShadowDecl(Kind K, ASTContext &C, DeclContext *DC, | |||
2889 | SourceLocation Loc, UsingDecl *Using, | |||
2890 | NamedDecl *Target) | |||
2891 | : NamedDecl(K, DC, Loc, Using ? Using->getDeclName() : DeclarationName()), | |||
2892 | redeclarable_base(C), UsingOrNextShadow(cast<NamedDecl>(Using)) { | |||
2893 | if (Target) | |||
2894 | setTargetDecl(Target); | |||
2895 | setImplicit(); | |||
2896 | } | |||
2897 | ||||
2898 | UsingShadowDecl::UsingShadowDecl(Kind K, ASTContext &C, EmptyShell Empty) | |||
2899 | : NamedDecl(K, nullptr, SourceLocation(), DeclarationName()), | |||
2900 | redeclarable_base(C) {} | |||
2901 | ||||
2902 | UsingShadowDecl * | |||
2903 | UsingShadowDecl::CreateDeserialized(ASTContext &C, unsigned ID) { | |||
2904 | return new (C, ID) UsingShadowDecl(UsingShadow, C, EmptyShell()); | |||
2905 | } | |||
2906 | ||||
2907 | UsingDecl *UsingShadowDecl::getUsingDecl() const { | |||
2908 | const UsingShadowDecl *Shadow = this; | |||
2909 | while (const auto *NextShadow = | |||
2910 | dyn_cast<UsingShadowDecl>(Shadow->UsingOrNextShadow)) | |||
2911 | Shadow = NextShadow; | |||
2912 | return cast<UsingDecl>(Shadow->UsingOrNextShadow); | |||
2913 | } | |||
2914 | ||||
2915 | void ConstructorUsingShadowDecl::anchor() {} | |||
2916 | ||||
2917 | ConstructorUsingShadowDecl * | |||
2918 | ConstructorUsingShadowDecl::Create(ASTContext &C, DeclContext *DC, | |||
2919 | SourceLocation Loc, UsingDecl *Using, | |||
2920 | NamedDecl *Target, bool IsVirtual) { | |||
2921 | return new (C, DC) ConstructorUsingShadowDecl(C, DC, Loc, Using, Target, | |||
2922 | IsVirtual); | |||
2923 | } | |||
2924 | ||||
2925 | ConstructorUsingShadowDecl * | |||
2926 | ConstructorUsingShadowDecl::CreateDeserialized(ASTContext &C, unsigned ID) { | |||
2927 | return new (C, ID) ConstructorUsingShadowDecl(C, EmptyShell()); | |||
2928 | } | |||
2929 | ||||
2930 | CXXRecordDecl *ConstructorUsingShadowDecl::getNominatedBaseClass() const { | |||
2931 | return getUsingDecl()->getQualifier()->getAsRecordDecl(); | |||
2932 | } | |||
2933 | ||||
2934 | void UsingDecl::anchor() {} | |||
2935 | ||||
2936 | void UsingDecl::addShadowDecl(UsingShadowDecl *S) { | |||
2937 | assert(std::find(shadow_begin(), shadow_end(), S) == shadow_end() &&((std::find(shadow_begin(), shadow_end(), S) == shadow_end() && "declaration already in set") ? static_cast<void> (0) : __assert_fail ("std::find(shadow_begin(), shadow_end(), S) == shadow_end() && \"declaration already in set\"" , "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/AST/DeclCXX.cpp" , 2938, __PRETTY_FUNCTION__)) | |||
2938 | "declaration already in set")((std::find(shadow_begin(), shadow_end(), S) == shadow_end() && "declaration already in set") ? static_cast<void> (0) : __assert_fail ("std::find(shadow_begin(), shadow_end(), S) == shadow_end() && \"declaration already in set\"" , "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/AST/DeclCXX.cpp" , 2938, __PRETTY_FUNCTION__)); | |||
2939 | assert(S->getUsingDecl() == this)((S->getUsingDecl() == this) ? static_cast<void> (0) : __assert_fail ("S->getUsingDecl() == this", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/AST/DeclCXX.cpp" , 2939, __PRETTY_FUNCTION__)); | |||
2940 | ||||
2941 | if (FirstUsingShadow.getPointer()) | |||
2942 | S->UsingOrNextShadow = FirstUsingShadow.getPointer(); | |||
2943 | FirstUsingShadow.setPointer(S); | |||
2944 | } | |||
2945 | ||||
2946 | void UsingDecl::removeShadowDecl(UsingShadowDecl *S) { | |||
2947 | assert(std::find(shadow_begin(), shadow_end(), S) != shadow_end() &&((std::find(shadow_begin(), shadow_end(), S) != shadow_end() && "declaration not in set") ? static_cast<void> (0) : __assert_fail ("std::find(shadow_begin(), shadow_end(), S) != shadow_end() && \"declaration not in set\"" , "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/AST/DeclCXX.cpp" , 2948, __PRETTY_FUNCTION__)) | |||
2948 | "declaration not in set")((std::find(shadow_begin(), shadow_end(), S) != shadow_end() && "declaration not in set") ? static_cast<void> (0) : __assert_fail ("std::find(shadow_begin(), shadow_end(), S) != shadow_end() && \"declaration not in set\"" , "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/AST/DeclCXX.cpp" , 2948, __PRETTY_FUNCTION__)); | |||
2949 | assert(S->getUsingDecl() == this)((S->getUsingDecl() == this) ? static_cast<void> (0) : __assert_fail ("S->getUsingDecl() == this", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/AST/DeclCXX.cpp" , 2949, __PRETTY_FUNCTION__)); | |||
2950 | ||||
2951 | // Remove S from the shadow decl chain. This is O(n) but hopefully rare. | |||
2952 | ||||
2953 | if (FirstUsingShadow.getPointer() == S) { | |||
2954 | FirstUsingShadow.setPointer( | |||
2955 | dyn_cast<UsingShadowDecl>(S->UsingOrNextShadow)); | |||
2956 | S->UsingOrNextShadow = this; | |||
2957 | return; | |||
2958 | } | |||
2959 | ||||
2960 | UsingShadowDecl *Prev = FirstUsingShadow.getPointer(); | |||
2961 | while (Prev->UsingOrNextShadow != S) | |||
2962 | Prev = cast<UsingShadowDecl>(Prev->UsingOrNextShadow); | |||
2963 | Prev->UsingOrNextShadow = S->UsingOrNextShadow; | |||
2964 | S->UsingOrNextShadow = this; | |||
2965 | } | |||
2966 | ||||
2967 | UsingDecl *UsingDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation UL, | |||
2968 | NestedNameSpecifierLoc QualifierLoc, | |||
2969 | const DeclarationNameInfo &NameInfo, | |||
2970 | bool HasTypename) { | |||
2971 | return new (C, DC) UsingDecl(DC, UL, QualifierLoc, NameInfo, HasTypename); | |||
2972 | } | |||
2973 | ||||
2974 | UsingDecl *UsingDecl::CreateDeserialized(ASTContext &C, unsigned ID) { | |||
2975 | return new (C, ID) UsingDecl(nullptr, SourceLocation(), | |||
2976 | NestedNameSpecifierLoc(), DeclarationNameInfo(), | |||
2977 | false); | |||
2978 | } | |||
2979 | ||||
2980 | SourceRange UsingDecl::getSourceRange() const { | |||
2981 | SourceLocation Begin = isAccessDeclaration() | |||
2982 | ? getQualifierLoc().getBeginLoc() : UsingLocation; | |||
2983 | return SourceRange(Begin, getNameInfo().getEndLoc()); | |||
2984 | } | |||
2985 | ||||
2986 | void UsingPackDecl::anchor() {} | |||
2987 | ||||
2988 | UsingPackDecl *UsingPackDecl::Create(ASTContext &C, DeclContext *DC, | |||
2989 | NamedDecl *InstantiatedFrom, | |||
2990 | ArrayRef<NamedDecl *> UsingDecls) { | |||
2991 | size_t Extra = additionalSizeToAlloc<NamedDecl *>(UsingDecls.size()); | |||
2992 | return new (C, DC, Extra) UsingPackDecl(DC, InstantiatedFrom, UsingDecls); | |||
2993 | } | |||
2994 | ||||
2995 | UsingPackDecl *UsingPackDecl::CreateDeserialized(ASTContext &C, unsigned ID, | |||
2996 | unsigned NumExpansions) { | |||
2997 | size_t Extra = additionalSizeToAlloc<NamedDecl *>(NumExpansions); | |||
2998 | auto *Result = new (C, ID, Extra) UsingPackDecl(nullptr, nullptr, None); | |||
2999 | Result->NumExpansions = NumExpansions; | |||
3000 | auto *Trail = Result->getTrailingObjects<NamedDecl *>(); | |||
3001 | for (unsigned I = 0; I != NumExpansions; ++I) | |||
3002 | new (Trail + I) NamedDecl*(nullptr); | |||
3003 | return Result; | |||
3004 | } | |||
3005 | ||||
3006 | void UnresolvedUsingValueDecl::anchor() {} | |||
3007 | ||||
3008 | UnresolvedUsingValueDecl * | |||
3009 | UnresolvedUsingValueDecl::Create(ASTContext &C, DeclContext *DC, | |||
3010 | SourceLocation UsingLoc, | |||
3011 | NestedNameSpecifierLoc QualifierLoc, | |||
3012 | const DeclarationNameInfo &NameInfo, | |||
3013 | SourceLocation EllipsisLoc) { | |||
3014 | return new (C, DC) UnresolvedUsingValueDecl(DC, C.DependentTy, UsingLoc, | |||
3015 | QualifierLoc, NameInfo, | |||
3016 | EllipsisLoc); | |||
3017 | } | |||
3018 | ||||
3019 | UnresolvedUsingValueDecl * | |||
3020 | UnresolvedUsingValueDecl::CreateDeserialized(ASTContext &C, unsigned ID) { | |||
3021 | return new (C, ID) UnresolvedUsingValueDecl(nullptr, QualType(), | |||
3022 | SourceLocation(), | |||
3023 | NestedNameSpecifierLoc(), | |||
3024 | DeclarationNameInfo(), | |||
3025 | SourceLocation()); | |||
3026 | } | |||
3027 | ||||
3028 | SourceRange UnresolvedUsingValueDecl::getSourceRange() const { | |||
3029 | SourceLocation Begin = isAccessDeclaration() | |||
3030 | ? getQualifierLoc().getBeginLoc() : UsingLocation; | |||
3031 | return SourceRange(Begin, getNameInfo().getEndLoc()); | |||
3032 | } | |||
3033 | ||||
3034 | void UnresolvedUsingTypenameDecl::anchor() {} | |||
3035 | ||||
3036 | UnresolvedUsingTypenameDecl * | |||
3037 | UnresolvedUsingTypenameDecl::Create(ASTContext &C, DeclContext *DC, | |||
3038 | SourceLocation UsingLoc, | |||
3039 | SourceLocation TypenameLoc, | |||
3040 | NestedNameSpecifierLoc QualifierLoc, | |||
3041 | SourceLocation TargetNameLoc, | |||
3042 | DeclarationName TargetName, | |||
3043 | SourceLocation EllipsisLoc) { | |||
3044 | return new (C, DC) UnresolvedUsingTypenameDecl( | |||
3045 | DC, UsingLoc, TypenameLoc, QualifierLoc, TargetNameLoc, | |||
3046 | TargetName.getAsIdentifierInfo(), EllipsisLoc); | |||
3047 | } | |||
3048 | ||||
3049 | UnresolvedUsingTypenameDecl * | |||
3050 | UnresolvedUsingTypenameDecl::CreateDeserialized(ASTContext &C, unsigned ID) { | |||
3051 | return new (C, ID) UnresolvedUsingTypenameDecl( | |||
3052 | nullptr, SourceLocation(), SourceLocation(), NestedNameSpecifierLoc(), | |||
3053 | SourceLocation(), nullptr, SourceLocation()); | |||
3054 | } | |||
3055 | ||||
3056 | void StaticAssertDecl::anchor() {} | |||
3057 | ||||
3058 | StaticAssertDecl *StaticAssertDecl::Create(ASTContext &C, DeclContext *DC, | |||
3059 | SourceLocation StaticAssertLoc, | |||
3060 | Expr *AssertExpr, | |||
3061 | StringLiteral *Message, | |||
3062 | SourceLocation RParenLoc, | |||
3063 | bool Failed) { | |||
3064 | return new (C, DC) StaticAssertDecl(DC, StaticAssertLoc, AssertExpr, Message, | |||
3065 | RParenLoc, Failed); | |||
3066 | } | |||
3067 | ||||
3068 | StaticAssertDecl *StaticAssertDecl::CreateDeserialized(ASTContext &C, | |||
3069 | unsigned ID) { | |||
3070 | return new (C, ID) StaticAssertDecl(nullptr, SourceLocation(), nullptr, | |||
3071 | nullptr, SourceLocation(), false); | |||
3072 | } | |||
3073 | ||||
3074 | void BindingDecl::anchor() {} | |||
3075 | ||||
3076 | BindingDecl *BindingDecl::Create(ASTContext &C, DeclContext *DC, | |||
3077 | SourceLocation IdLoc, IdentifierInfo *Id) { | |||
3078 | return new (C, DC) BindingDecl(DC, IdLoc, Id); | |||
3079 | } | |||
3080 | ||||
3081 | BindingDecl *BindingDecl::CreateDeserialized(ASTContext &C, unsigned ID) { | |||
3082 | return new (C, ID) BindingDecl(nullptr, SourceLocation(), nullptr); | |||
3083 | } | |||
3084 | ||||
3085 | ValueDecl *BindingDecl::getDecomposedDecl() const { | |||
3086 | ExternalASTSource *Source = | |||
3087 | Decomp.isOffset() ? getASTContext().getExternalSource() : nullptr; | |||
3088 | return cast_or_null<ValueDecl>(Decomp.get(Source)); | |||
3089 | } | |||
3090 | ||||
3091 | VarDecl *BindingDecl::getHoldingVar() const { | |||
3092 | Expr *B = getBinding(); | |||
3093 | if (!B) | |||
3094 | return nullptr; | |||
3095 | auto *DRE = dyn_cast<DeclRefExpr>(B->IgnoreImplicit()); | |||
3096 | if (!DRE) | |||
3097 | return nullptr; | |||
3098 | ||||
3099 | auto *VD = dyn_cast<VarDecl>(DRE->getDecl()); | |||
3100 | assert(VD->isImplicit() && "holding var for binding decl not implicit")((VD->isImplicit() && "holding var for binding decl not implicit" ) ? static_cast<void> (0) : __assert_fail ("VD->isImplicit() && \"holding var for binding decl not implicit\"" , "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/AST/DeclCXX.cpp" , 3100, __PRETTY_FUNCTION__)); | |||
3101 | return VD; | |||
3102 | } | |||
3103 | ||||
3104 | void DecompositionDecl::anchor() {} | |||
3105 | ||||
3106 | DecompositionDecl *DecompositionDecl::Create(ASTContext &C, DeclContext *DC, | |||
3107 | SourceLocation StartLoc, | |||
3108 | SourceLocation LSquareLoc, | |||
3109 | QualType T, TypeSourceInfo *TInfo, | |||
3110 | StorageClass SC, | |||
3111 | ArrayRef<BindingDecl *> Bindings) { | |||
3112 | size_t Extra = additionalSizeToAlloc<BindingDecl *>(Bindings.size()); | |||
3113 | return new (C, DC, Extra) | |||
3114 | DecompositionDecl(C, DC, StartLoc, LSquareLoc, T, TInfo, SC, Bindings); | |||
3115 | } | |||
3116 | ||||
3117 | DecompositionDecl *DecompositionDecl::CreateDeserialized(ASTContext &C, | |||
3118 | unsigned ID, | |||
3119 | unsigned NumBindings) { | |||
3120 | size_t Extra = additionalSizeToAlloc<BindingDecl *>(NumBindings); | |||
3121 | auto *Result = new (C, ID, Extra) | |||
3122 | DecompositionDecl(C, nullptr, SourceLocation(), SourceLocation(), | |||
3123 | QualType(), nullptr, StorageClass(), None); | |||
3124 | // Set up and clean out the bindings array. | |||
3125 | Result->NumBindings = NumBindings; | |||
3126 | auto *Trail = Result->getTrailingObjects<BindingDecl *>(); | |||
3127 | for (unsigned I = 0; I != NumBindings; ++I) | |||
3128 | new (Trail + I) BindingDecl*(nullptr); | |||
3129 | return Result; | |||
3130 | } | |||
3131 | ||||
3132 | void DecompositionDecl::printName(llvm::raw_ostream &os) const { | |||
3133 | os << '['; | |||
3134 | bool Comma = false; | |||
3135 | for (const auto *B : bindings()) { | |||
3136 | if (Comma) | |||
3137 | os << ", "; | |||
3138 | B->printName(os); | |||
3139 | Comma = true; | |||
3140 | } | |||
3141 | os << ']'; | |||
3142 | } | |||
3143 | ||||
3144 | void MSPropertyDecl::anchor() {} | |||
3145 | ||||
3146 | MSPropertyDecl *MSPropertyDecl::Create(ASTContext &C, DeclContext *DC, | |||
3147 | SourceLocation L, DeclarationName N, | |||
3148 | QualType T, TypeSourceInfo *TInfo, | |||
3149 | SourceLocation StartL, | |||
3150 | IdentifierInfo *Getter, | |||
3151 | IdentifierInfo *Setter) { | |||
3152 | return new (C, DC) MSPropertyDecl(DC, L, N, T, TInfo, StartL, Getter, Setter); | |||
3153 | } | |||
3154 | ||||
3155 | MSPropertyDecl *MSPropertyDecl::CreateDeserialized(ASTContext &C, | |||
3156 | unsigned ID) { | |||
3157 | return new (C, ID) MSPropertyDecl(nullptr, SourceLocation(), | |||
3158 | DeclarationName(), QualType(), nullptr, | |||
3159 | SourceLocation(), nullptr, nullptr); | |||
3160 | } | |||
3161 | ||||
3162 | static const char *getAccessName(AccessSpecifier AS) { | |||
3163 | switch (AS) { | |||
3164 | case AS_none: | |||
3165 | llvm_unreachable("Invalid access specifier!")::llvm::llvm_unreachable_internal("Invalid access specifier!" , "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/AST/DeclCXX.cpp" , 3165); | |||
3166 | case AS_public: | |||
3167 | return "public"; | |||
3168 | case AS_private: | |||
3169 | return "private"; | |||
3170 | case AS_protected: | |||
3171 | return "protected"; | |||
3172 | } | |||
3173 | llvm_unreachable("Invalid access specifier!")::llvm::llvm_unreachable_internal("Invalid access specifier!" , "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/AST/DeclCXX.cpp" , 3173); | |||
3174 | } | |||
3175 | ||||
3176 | const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB, | |||
3177 | AccessSpecifier AS) { | |||
3178 | return DB << getAccessName(AS); | |||
3179 | } | |||
3180 | ||||
3181 | const PartialDiagnostic &clang::operator<<(const PartialDiagnostic &DB, | |||
3182 | AccessSpecifier AS) { | |||
3183 | return DB << getAccessName(AS); | |||
3184 | } |