File: | tools/clang/lib/AST/ASTContext.cpp |
Warning: | line 2874, column 7 Called C++ object pointer is null |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | //===- ASTContext.cpp - Context to hold long-lived AST nodes --------------===// | ||||
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 ASTContext interface. | ||||
10 | // | ||||
11 | //===----------------------------------------------------------------------===// | ||||
12 | |||||
13 | #include "clang/AST/ASTContext.h" | ||||
14 | #include "CXXABI.h" | ||||
15 | #include "Interp/Context.h" | ||||
16 | #include "clang/AST/APValue.h" | ||||
17 | #include "clang/AST/ASTMutationListener.h" | ||||
18 | #include "clang/AST/ASTTypeTraits.h" | ||||
19 | #include "clang/AST/Attr.h" | ||||
20 | #include "clang/AST/AttrIterator.h" | ||||
21 | #include "clang/AST/CharUnits.h" | ||||
22 | #include "clang/AST/Comment.h" | ||||
23 | #include "clang/AST/Decl.h" | ||||
24 | #include "clang/AST/DeclBase.h" | ||||
25 | #include "clang/AST/DeclCXX.h" | ||||
26 | #include "clang/AST/DeclContextInternals.h" | ||||
27 | #include "clang/AST/DeclObjC.h" | ||||
28 | #include "clang/AST/DeclOpenMP.h" | ||||
29 | #include "clang/AST/DeclTemplate.h" | ||||
30 | #include "clang/AST/DeclarationName.h" | ||||
31 | #include "clang/AST/Expr.h" | ||||
32 | #include "clang/AST/ExprCXX.h" | ||||
33 | #include "clang/AST/ExternalASTSource.h" | ||||
34 | #include "clang/AST/Mangle.h" | ||||
35 | #include "clang/AST/MangleNumberingContext.h" | ||||
36 | #include "clang/AST/NestedNameSpecifier.h" | ||||
37 | #include "clang/AST/RawCommentList.h" | ||||
38 | #include "clang/AST/RecordLayout.h" | ||||
39 | #include "clang/AST/RecursiveASTVisitor.h" | ||||
40 | #include "clang/AST/Stmt.h" | ||||
41 | #include "clang/AST/TemplateBase.h" | ||||
42 | #include "clang/AST/TemplateName.h" | ||||
43 | #include "clang/AST/Type.h" | ||||
44 | #include "clang/AST/TypeLoc.h" | ||||
45 | #include "clang/AST/UnresolvedSet.h" | ||||
46 | #include "clang/AST/VTableBuilder.h" | ||||
47 | #include "clang/Basic/AddressSpaces.h" | ||||
48 | #include "clang/Basic/Builtins.h" | ||||
49 | #include "clang/Basic/CommentOptions.h" | ||||
50 | #include "clang/Basic/ExceptionSpecificationType.h" | ||||
51 | #include "clang/Basic/FixedPoint.h" | ||||
52 | #include "clang/Basic/IdentifierTable.h" | ||||
53 | #include "clang/Basic/LLVM.h" | ||||
54 | #include "clang/Basic/LangOptions.h" | ||||
55 | #include "clang/Basic/Linkage.h" | ||||
56 | #include "clang/Basic/ObjCRuntime.h" | ||||
57 | #include "clang/Basic/SanitizerBlacklist.h" | ||||
58 | #include "clang/Basic/SourceLocation.h" | ||||
59 | #include "clang/Basic/SourceManager.h" | ||||
60 | #include "clang/Basic/Specifiers.h" | ||||
61 | #include "clang/Basic/TargetCXXABI.h" | ||||
62 | #include "clang/Basic/TargetInfo.h" | ||||
63 | #include "clang/Basic/XRayLists.h" | ||||
64 | #include "llvm/ADT/APInt.h" | ||||
65 | #include "llvm/ADT/APSInt.h" | ||||
66 | #include "llvm/ADT/ArrayRef.h" | ||||
67 | #include "llvm/ADT/DenseMap.h" | ||||
68 | #include "llvm/ADT/DenseSet.h" | ||||
69 | #include "llvm/ADT/FoldingSet.h" | ||||
70 | #include "llvm/ADT/None.h" | ||||
71 | #include "llvm/ADT/Optional.h" | ||||
72 | #include "llvm/ADT/PointerUnion.h" | ||||
73 | #include "llvm/ADT/STLExtras.h" | ||||
74 | #include "llvm/ADT/SmallPtrSet.h" | ||||
75 | #include "llvm/ADT/SmallVector.h" | ||||
76 | #include "llvm/ADT/StringExtras.h" | ||||
77 | #include "llvm/ADT/StringRef.h" | ||||
78 | #include "llvm/ADT/Triple.h" | ||||
79 | #include "llvm/Support/Capacity.h" | ||||
80 | #include "llvm/Support/Casting.h" | ||||
81 | #include "llvm/Support/Compiler.h" | ||||
82 | #include "llvm/Support/ErrorHandling.h" | ||||
83 | #include "llvm/Support/MathExtras.h" | ||||
84 | #include "llvm/Support/raw_ostream.h" | ||||
85 | #include <algorithm> | ||||
86 | #include <cassert> | ||||
87 | #include <cstddef> | ||||
88 | #include <cstdint> | ||||
89 | #include <cstdlib> | ||||
90 | #include <map> | ||||
91 | #include <memory> | ||||
92 | #include <string> | ||||
93 | #include <tuple> | ||||
94 | #include <utility> | ||||
95 | |||||
96 | using namespace clang; | ||||
97 | |||||
98 | enum FloatingRank { | ||||
99 | Float16Rank, HalfRank, FloatRank, DoubleRank, LongDoubleRank, Float128Rank | ||||
100 | }; | ||||
101 | |||||
102 | /// \returns location that is relevant when searching for Doc comments related | ||||
103 | /// to \p D. | ||||
104 | static SourceLocation getDeclLocForCommentSearch(const Decl *D, | ||||
105 | SourceManager &SourceMgr) { | ||||
106 | assert(D)((D) ? static_cast<void> (0) : __assert_fail ("D", "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 106, __PRETTY_FUNCTION__)); | ||||
107 | |||||
108 | // User can not attach documentation to implicit declarations. | ||||
109 | if (D->isImplicit()) | ||||
110 | return {}; | ||||
111 | |||||
112 | // User can not attach documentation to implicit instantiations. | ||||
113 | if (const auto *FD = dyn_cast<FunctionDecl>(D)) { | ||||
114 | if (FD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation) | ||||
115 | return {}; | ||||
116 | } | ||||
117 | |||||
118 | if (const auto *VD = dyn_cast<VarDecl>(D)) { | ||||
119 | if (VD->isStaticDataMember() && | ||||
120 | VD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation) | ||||
121 | return {}; | ||||
122 | } | ||||
123 | |||||
124 | if (const auto *CRD = dyn_cast<CXXRecordDecl>(D)) { | ||||
125 | if (CRD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation) | ||||
126 | return {}; | ||||
127 | } | ||||
128 | |||||
129 | if (const auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(D)) { | ||||
130 | TemplateSpecializationKind TSK = CTSD->getSpecializationKind(); | ||||
131 | if (TSK == TSK_ImplicitInstantiation || | ||||
132 | TSK == TSK_Undeclared) | ||||
133 | return {}; | ||||
134 | } | ||||
135 | |||||
136 | if (const auto *ED = dyn_cast<EnumDecl>(D)) { | ||||
137 | if (ED->getTemplateSpecializationKind() == TSK_ImplicitInstantiation) | ||||
138 | return {}; | ||||
139 | } | ||||
140 | if (const auto *TD = dyn_cast<TagDecl>(D)) { | ||||
141 | // When tag declaration (but not definition!) is part of the | ||||
142 | // decl-specifier-seq of some other declaration, it doesn't get comment | ||||
143 | if (TD->isEmbeddedInDeclarator() && !TD->isCompleteDefinition()) | ||||
144 | return {}; | ||||
145 | } | ||||
146 | // TODO: handle comments for function parameters properly. | ||||
147 | if (isa<ParmVarDecl>(D)) | ||||
148 | return {}; | ||||
149 | |||||
150 | // TODO: we could look up template parameter documentation in the template | ||||
151 | // documentation. | ||||
152 | if (isa<TemplateTypeParmDecl>(D) || | ||||
153 | isa<NonTypeTemplateParmDecl>(D) || | ||||
154 | isa<TemplateTemplateParmDecl>(D)) | ||||
155 | return {}; | ||||
156 | |||||
157 | // Find declaration location. | ||||
158 | // For Objective-C declarations we generally don't expect to have multiple | ||||
159 | // declarators, thus use declaration starting location as the "declaration | ||||
160 | // location". | ||||
161 | // For all other declarations multiple declarators are used quite frequently, | ||||
162 | // so we use the location of the identifier as the "declaration location". | ||||
163 | if (isa<ObjCMethodDecl>(D) || isa<ObjCContainerDecl>(D) || | ||||
164 | isa<ObjCPropertyDecl>(D) || | ||||
165 | isa<RedeclarableTemplateDecl>(D) || | ||||
166 | isa<ClassTemplateSpecializationDecl>(D)) | ||||
167 | return D->getBeginLoc(); | ||||
168 | else { | ||||
169 | const SourceLocation DeclLoc = D->getLocation(); | ||||
170 | if (DeclLoc.isMacroID()) { | ||||
171 | if (isa<TypedefDecl>(D)) { | ||||
172 | // If location of the typedef name is in a macro, it is because being | ||||
173 | // declared via a macro. Try using declaration's starting location as | ||||
174 | // the "declaration location". | ||||
175 | return D->getBeginLoc(); | ||||
176 | } else if (const auto *TD = dyn_cast<TagDecl>(D)) { | ||||
177 | // If location of the tag decl is inside a macro, but the spelling of | ||||
178 | // the tag name comes from a macro argument, it looks like a special | ||||
179 | // macro like NS_ENUM is being used to define the tag decl. In that | ||||
180 | // case, adjust the source location to the expansion loc so that we can | ||||
181 | // attach the comment to the tag decl. | ||||
182 | if (SourceMgr.isMacroArgExpansion(DeclLoc) && | ||||
183 | TD->isCompleteDefinition()) | ||||
184 | return SourceMgr.getExpansionLoc(DeclLoc); | ||||
185 | } | ||||
186 | } | ||||
187 | return DeclLoc; | ||||
188 | } | ||||
189 | |||||
190 | return {}; | ||||
191 | } | ||||
192 | |||||
193 | RawComment *ASTContext::getRawCommentForDeclNoCacheImpl( | ||||
194 | const Decl *D, const SourceLocation RepresentativeLocForDecl, | ||||
195 | const std::map<unsigned, RawComment *> &CommentsInTheFile) const { | ||||
196 | // If the declaration doesn't map directly to a location in a file, we | ||||
197 | // can't find the comment. | ||||
198 | if (RepresentativeLocForDecl.isInvalid() || | ||||
199 | !RepresentativeLocForDecl.isFileID()) | ||||
200 | return nullptr; | ||||
201 | |||||
202 | // If there are no comments anywhere, we won't find anything. | ||||
203 | if (CommentsInTheFile.empty()) | ||||
204 | return nullptr; | ||||
205 | |||||
206 | // Decompose the location for the declaration and find the beginning of the | ||||
207 | // file buffer. | ||||
208 | const std::pair<FileID, unsigned> DeclLocDecomp = | ||||
209 | SourceMgr.getDecomposedLoc(RepresentativeLocForDecl); | ||||
210 | |||||
211 | // Slow path. | ||||
212 | auto OffsetCommentBehindDecl = | ||||
213 | CommentsInTheFile.lower_bound(DeclLocDecomp.second); | ||||
214 | |||||
215 | // First check whether we have a trailing comment. | ||||
216 | if (OffsetCommentBehindDecl != CommentsInTheFile.end()) { | ||||
217 | RawComment *CommentBehindDecl = OffsetCommentBehindDecl->second; | ||||
218 | if ((CommentBehindDecl->isDocumentation() || | ||||
219 | LangOpts.CommentOpts.ParseAllComments) && | ||||
220 | CommentBehindDecl->isTrailingComment() && | ||||
221 | (isa<FieldDecl>(D) || isa<EnumConstantDecl>(D) || isa<VarDecl>(D) || | ||||
222 | isa<ObjCMethodDecl>(D) || isa<ObjCPropertyDecl>(D))) { | ||||
223 | |||||
224 | // Check that Doxygen trailing comment comes after the declaration, starts | ||||
225 | // on the same line and in the same file as the declaration. | ||||
226 | if (SourceMgr.getLineNumber(DeclLocDecomp.first, DeclLocDecomp.second) == | ||||
227 | Comments.getCommentBeginLine(CommentBehindDecl, DeclLocDecomp.first, | ||||
228 | OffsetCommentBehindDecl->first)) { | ||||
229 | return CommentBehindDecl; | ||||
230 | } | ||||
231 | } | ||||
232 | } | ||||
233 | |||||
234 | // The comment just after the declaration was not a trailing comment. | ||||
235 | // Let's look at the previous comment. | ||||
236 | if (OffsetCommentBehindDecl == CommentsInTheFile.begin()) | ||||
237 | return nullptr; | ||||
238 | |||||
239 | auto OffsetCommentBeforeDecl = --OffsetCommentBehindDecl; | ||||
240 | RawComment *CommentBeforeDecl = OffsetCommentBeforeDecl->second; | ||||
241 | |||||
242 | // Check that we actually have a non-member Doxygen comment. | ||||
243 | if (!(CommentBeforeDecl->isDocumentation() || | ||||
244 | LangOpts.CommentOpts.ParseAllComments) || | ||||
245 | CommentBeforeDecl->isTrailingComment()) | ||||
246 | return nullptr; | ||||
247 | |||||
248 | // Decompose the end of the comment. | ||||
249 | const unsigned CommentEndOffset = | ||||
250 | Comments.getCommentEndOffset(CommentBeforeDecl); | ||||
251 | |||||
252 | // Get the corresponding buffer. | ||||
253 | bool Invalid = false; | ||||
254 | const char *Buffer = SourceMgr.getBufferData(DeclLocDecomp.first, | ||||
255 | &Invalid).data(); | ||||
256 | if (Invalid) | ||||
257 | return nullptr; | ||||
258 | |||||
259 | // Extract text between the comment and declaration. | ||||
260 | StringRef Text(Buffer + CommentEndOffset, | ||||
261 | DeclLocDecomp.second - CommentEndOffset); | ||||
262 | |||||
263 | // There should be no other declarations or preprocessor directives between | ||||
264 | // comment and declaration. | ||||
265 | if (Text.find_first_of(";{}#@") != StringRef::npos) | ||||
266 | return nullptr; | ||||
267 | |||||
268 | return CommentBeforeDecl; | ||||
269 | } | ||||
270 | |||||
271 | RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const { | ||||
272 | const SourceLocation DeclLoc = getDeclLocForCommentSearch(D, SourceMgr); | ||||
273 | |||||
274 | // If the declaration doesn't map directly to a location in a file, we | ||||
275 | // can't find the comment. | ||||
276 | if (DeclLoc.isInvalid() || !DeclLoc.isFileID()) | ||||
277 | return nullptr; | ||||
278 | |||||
279 | if (ExternalSource && !CommentsLoaded) { | ||||
280 | ExternalSource->ReadComments(); | ||||
281 | CommentsLoaded = true; | ||||
282 | } | ||||
283 | |||||
284 | if (Comments.empty()) | ||||
285 | return nullptr; | ||||
286 | |||||
287 | const FileID File = SourceMgr.getDecomposedLoc(DeclLoc).first; | ||||
288 | const auto CommentsInThisFile = Comments.getCommentsInFile(File); | ||||
289 | if (!CommentsInThisFile || CommentsInThisFile->empty()) | ||||
290 | return nullptr; | ||||
291 | |||||
292 | return getRawCommentForDeclNoCacheImpl(D, DeclLoc, *CommentsInThisFile); | ||||
293 | } | ||||
294 | |||||
295 | /// If we have a 'templated' declaration for a template, adjust 'D' to | ||||
296 | /// refer to the actual template. | ||||
297 | /// If we have an implicit instantiation, adjust 'D' to refer to template. | ||||
298 | static const Decl &adjustDeclToTemplate(const Decl &D) { | ||||
299 | if (const auto *FD = dyn_cast<FunctionDecl>(&D)) { | ||||
300 | // Is this function declaration part of a function template? | ||||
301 | if (const FunctionTemplateDecl *FTD = FD->getDescribedFunctionTemplate()) | ||||
302 | return *FTD; | ||||
303 | |||||
304 | // Nothing to do if function is not an implicit instantiation. | ||||
305 | if (FD->getTemplateSpecializationKind() != TSK_ImplicitInstantiation) | ||||
306 | return D; | ||||
307 | |||||
308 | // Function is an implicit instantiation of a function template? | ||||
309 | if (const FunctionTemplateDecl *FTD = FD->getPrimaryTemplate()) | ||||
310 | return *FTD; | ||||
311 | |||||
312 | // Function is instantiated from a member definition of a class template? | ||||
313 | if (const FunctionDecl *MemberDecl = | ||||
314 | FD->getInstantiatedFromMemberFunction()) | ||||
315 | return *MemberDecl; | ||||
316 | |||||
317 | return D; | ||||
318 | } | ||||
319 | if (const auto *VD = dyn_cast<VarDecl>(&D)) { | ||||
320 | // Static data member is instantiated from a member definition of a class | ||||
321 | // template? | ||||
322 | if (VD->isStaticDataMember()) | ||||
323 | if (const VarDecl *MemberDecl = VD->getInstantiatedFromStaticDataMember()) | ||||
324 | return *MemberDecl; | ||||
325 | |||||
326 | return D; | ||||
327 | } | ||||
328 | if (const auto *CRD = dyn_cast<CXXRecordDecl>(&D)) { | ||||
329 | // Is this class declaration part of a class template? | ||||
330 | if (const ClassTemplateDecl *CTD = CRD->getDescribedClassTemplate()) | ||||
331 | return *CTD; | ||||
332 | |||||
333 | // Class is an implicit instantiation of a class template or partial | ||||
334 | // specialization? | ||||
335 | if (const auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(CRD)) { | ||||
336 | if (CTSD->getSpecializationKind() != TSK_ImplicitInstantiation) | ||||
337 | return D; | ||||
338 | llvm::PointerUnion<ClassTemplateDecl *, | ||||
339 | ClassTemplatePartialSpecializationDecl *> | ||||
340 | PU = CTSD->getSpecializedTemplateOrPartial(); | ||||
341 | return PU.is<ClassTemplateDecl *>() | ||||
342 | ? *static_cast<const Decl *>(PU.get<ClassTemplateDecl *>()) | ||||
343 | : *static_cast<const Decl *>( | ||||
344 | PU.get<ClassTemplatePartialSpecializationDecl *>()); | ||||
345 | } | ||||
346 | |||||
347 | // Class is instantiated from a member definition of a class template? | ||||
348 | if (const MemberSpecializationInfo *Info = | ||||
349 | CRD->getMemberSpecializationInfo()) | ||||
350 | return *Info->getInstantiatedFrom(); | ||||
351 | |||||
352 | return D; | ||||
353 | } | ||||
354 | if (const auto *ED = dyn_cast<EnumDecl>(&D)) { | ||||
355 | // Enum is instantiated from a member definition of a class template? | ||||
356 | if (const EnumDecl *MemberDecl = ED->getInstantiatedFromMemberEnum()) | ||||
357 | return *MemberDecl; | ||||
358 | |||||
359 | return D; | ||||
360 | } | ||||
361 | // FIXME: Adjust alias templates? | ||||
362 | return D; | ||||
363 | } | ||||
364 | |||||
365 | const RawComment *ASTContext::getRawCommentForAnyRedecl( | ||||
366 | const Decl *D, | ||||
367 | const Decl **OriginalDecl) const { | ||||
368 | if (!D) { | ||||
369 | if (OriginalDecl) | ||||
370 | OriginalDecl = nullptr; | ||||
371 | return nullptr; | ||||
372 | } | ||||
373 | |||||
374 | D = &adjustDeclToTemplate(*D); | ||||
375 | |||||
376 | // Any comment directly attached to D? | ||||
377 | { | ||||
378 | auto DeclComment = DeclRawComments.find(D); | ||||
379 | if (DeclComment != DeclRawComments.end()) { | ||||
380 | if (OriginalDecl) | ||||
381 | *OriginalDecl = D; | ||||
382 | return DeclComment->second; | ||||
383 | } | ||||
384 | } | ||||
385 | |||||
386 | // Any comment attached to any redeclaration of D? | ||||
387 | const Decl *CanonicalD = D->getCanonicalDecl(); | ||||
388 | if (!CanonicalD) | ||||
389 | return nullptr; | ||||
390 | |||||
391 | { | ||||
392 | auto RedeclComment = RedeclChainComments.find(CanonicalD); | ||||
393 | if (RedeclComment != RedeclChainComments.end()) { | ||||
394 | if (OriginalDecl) | ||||
395 | *OriginalDecl = RedeclComment->second; | ||||
396 | auto CommentAtRedecl = DeclRawComments.find(RedeclComment->second); | ||||
397 | assert(CommentAtRedecl != DeclRawComments.end() &&((CommentAtRedecl != DeclRawComments.end() && "This decl is supposed to have comment attached." ) ? static_cast<void> (0) : __assert_fail ("CommentAtRedecl != DeclRawComments.end() && \"This decl is supposed to have comment attached.\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 398, __PRETTY_FUNCTION__)) | ||||
398 | "This decl is supposed to have comment attached.")((CommentAtRedecl != DeclRawComments.end() && "This decl is supposed to have comment attached." ) ? static_cast<void> (0) : __assert_fail ("CommentAtRedecl != DeclRawComments.end() && \"This decl is supposed to have comment attached.\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 398, __PRETTY_FUNCTION__)); | ||||
399 | return CommentAtRedecl->second; | ||||
400 | } | ||||
401 | } | ||||
402 | |||||
403 | // Any redeclarations of D that we haven't checked for comments yet? | ||||
404 | // We can't use DenseMap::iterator directly since it'd get invalid. | ||||
405 | auto LastCheckedRedecl = [this, CanonicalD]() -> const Decl * { | ||||
406 | auto LookupRes = CommentlessRedeclChains.find(CanonicalD); | ||||
407 | if (LookupRes != CommentlessRedeclChains.end()) | ||||
408 | return LookupRes->second; | ||||
409 | return nullptr; | ||||
410 | }(); | ||||
411 | |||||
412 | for (const auto Redecl : D->redecls()) { | ||||
413 | assert(Redecl)((Redecl) ? static_cast<void> (0) : __assert_fail ("Redecl" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 413, __PRETTY_FUNCTION__)); | ||||
414 | // Skip all redeclarations that have been checked previously. | ||||
415 | if (LastCheckedRedecl) { | ||||
416 | if (LastCheckedRedecl == Redecl) { | ||||
417 | LastCheckedRedecl = nullptr; | ||||
418 | } | ||||
419 | continue; | ||||
420 | } | ||||
421 | const RawComment *RedeclComment = getRawCommentForDeclNoCache(Redecl); | ||||
422 | if (RedeclComment) { | ||||
423 | cacheRawCommentForDecl(*Redecl, *RedeclComment); | ||||
424 | if (OriginalDecl) | ||||
425 | *OriginalDecl = Redecl; | ||||
426 | return RedeclComment; | ||||
427 | } | ||||
428 | CommentlessRedeclChains[CanonicalD] = Redecl; | ||||
429 | } | ||||
430 | |||||
431 | if (OriginalDecl) | ||||
432 | *OriginalDecl = nullptr; | ||||
433 | return nullptr; | ||||
434 | } | ||||
435 | |||||
436 | void ASTContext::cacheRawCommentForDecl(const Decl &OriginalD, | ||||
437 | const RawComment &Comment) const { | ||||
438 | assert(Comment.isDocumentation() || LangOpts.CommentOpts.ParseAllComments)((Comment.isDocumentation() || LangOpts.CommentOpts.ParseAllComments ) ? static_cast<void> (0) : __assert_fail ("Comment.isDocumentation() || LangOpts.CommentOpts.ParseAllComments" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 438, __PRETTY_FUNCTION__)); | ||||
439 | DeclRawComments.try_emplace(&OriginalD, &Comment); | ||||
440 | const Decl *const CanonicalDecl = OriginalD.getCanonicalDecl(); | ||||
441 | RedeclChainComments.try_emplace(CanonicalDecl, &OriginalD); | ||||
442 | CommentlessRedeclChains.erase(CanonicalDecl); | ||||
443 | } | ||||
444 | |||||
445 | static void addRedeclaredMethods(const ObjCMethodDecl *ObjCMethod, | ||||
446 | SmallVectorImpl<const NamedDecl *> &Redeclared) { | ||||
447 | const DeclContext *DC = ObjCMethod->getDeclContext(); | ||||
448 | if (const auto *IMD = dyn_cast<ObjCImplDecl>(DC)) { | ||||
449 | const ObjCInterfaceDecl *ID = IMD->getClassInterface(); | ||||
450 | if (!ID) | ||||
451 | return; | ||||
452 | // Add redeclared method here. | ||||
453 | for (const auto *Ext : ID->known_extensions()) { | ||||
454 | if (ObjCMethodDecl *RedeclaredMethod = | ||||
455 | Ext->getMethod(ObjCMethod->getSelector(), | ||||
456 | ObjCMethod->isInstanceMethod())) | ||||
457 | Redeclared.push_back(RedeclaredMethod); | ||||
458 | } | ||||
459 | } | ||||
460 | } | ||||
461 | |||||
462 | void ASTContext::attachCommentsToJustParsedDecls(ArrayRef<Decl *> Decls, | ||||
463 | const Preprocessor *PP) { | ||||
464 | if (Comments.empty() || Decls.empty()) | ||||
465 | return; | ||||
466 | |||||
467 | // See if there are any new comments that are not attached to a decl. | ||||
468 | // The location doesn't have to be precise - we care only about the file. | ||||
469 | const FileID File = | ||||
470 | SourceMgr.getDecomposedLoc((*Decls.begin())->getLocation()).first; | ||||
471 | auto CommentsInThisFile = Comments.getCommentsInFile(File); | ||||
472 | if (!CommentsInThisFile || CommentsInThisFile->empty() || | ||||
473 | CommentsInThisFile->rbegin()->second->isAttached()) | ||||
474 | return; | ||||
475 | |||||
476 | // There is at least one comment not attached to a decl. | ||||
477 | // Maybe it should be attached to one of Decls? | ||||
478 | // | ||||
479 | // Note that this way we pick up not only comments that precede the | ||||
480 | // declaration, but also comments that *follow* the declaration -- thanks to | ||||
481 | // the lookahead in the lexer: we've consumed the semicolon and looked | ||||
482 | // ahead through comments. | ||||
483 | |||||
484 | for (const Decl *D : Decls) { | ||||
485 | assert(D)((D) ? static_cast<void> (0) : __assert_fail ("D", "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 485, __PRETTY_FUNCTION__)); | ||||
486 | if (D->isInvalidDecl()) | ||||
487 | continue; | ||||
488 | |||||
489 | D = &adjustDeclToTemplate(*D); | ||||
490 | |||||
491 | const SourceLocation DeclLoc = getDeclLocForCommentSearch(D, SourceMgr); | ||||
492 | |||||
493 | if (DeclLoc.isInvalid() || !DeclLoc.isFileID()) | ||||
494 | continue; | ||||
495 | |||||
496 | if (DeclRawComments.count(D) > 0) | ||||
497 | continue; | ||||
498 | |||||
499 | if (RawComment *const DocComment = | ||||
500 | getRawCommentForDeclNoCacheImpl(D, DeclLoc, *CommentsInThisFile)) { | ||||
501 | cacheRawCommentForDecl(*D, *DocComment); | ||||
502 | comments::FullComment *FC = DocComment->parse(*this, PP, D); | ||||
503 | ParsedComments[D->getCanonicalDecl()] = FC; | ||||
504 | } | ||||
505 | } | ||||
506 | } | ||||
507 | |||||
508 | comments::FullComment *ASTContext::cloneFullComment(comments::FullComment *FC, | ||||
509 | const Decl *D) const { | ||||
510 | auto *ThisDeclInfo = new (*this) comments::DeclInfo; | ||||
511 | ThisDeclInfo->CommentDecl = D; | ||||
512 | ThisDeclInfo->IsFilled = false; | ||||
513 | ThisDeclInfo->fill(); | ||||
514 | ThisDeclInfo->CommentDecl = FC->getDecl(); | ||||
515 | if (!ThisDeclInfo->TemplateParameters) | ||||
516 | ThisDeclInfo->TemplateParameters = FC->getDeclInfo()->TemplateParameters; | ||||
517 | comments::FullComment *CFC = | ||||
518 | new (*this) comments::FullComment(FC->getBlocks(), | ||||
519 | ThisDeclInfo); | ||||
520 | return CFC; | ||||
521 | } | ||||
522 | |||||
523 | comments::FullComment *ASTContext::getLocalCommentForDeclUncached(const Decl *D) const { | ||||
524 | const RawComment *RC = getRawCommentForDeclNoCache(D); | ||||
525 | return RC ? RC->parse(*this, nullptr, D) : nullptr; | ||||
526 | } | ||||
527 | |||||
528 | comments::FullComment *ASTContext::getCommentForDecl( | ||||
529 | const Decl *D, | ||||
530 | const Preprocessor *PP) const { | ||||
531 | if (!D || D->isInvalidDecl()) | ||||
532 | return nullptr; | ||||
533 | D = &adjustDeclToTemplate(*D); | ||||
534 | |||||
535 | const Decl *Canonical = D->getCanonicalDecl(); | ||||
536 | llvm::DenseMap<const Decl *, comments::FullComment *>::iterator Pos = | ||||
537 | ParsedComments.find(Canonical); | ||||
538 | |||||
539 | if (Pos != ParsedComments.end()) { | ||||
540 | if (Canonical != D) { | ||||
541 | comments::FullComment *FC = Pos->second; | ||||
542 | comments::FullComment *CFC = cloneFullComment(FC, D); | ||||
543 | return CFC; | ||||
544 | } | ||||
545 | return Pos->second; | ||||
546 | } | ||||
547 | |||||
548 | const Decl *OriginalDecl = nullptr; | ||||
549 | |||||
550 | const RawComment *RC = getRawCommentForAnyRedecl(D, &OriginalDecl); | ||||
551 | if (!RC) { | ||||
552 | if (isa<ObjCMethodDecl>(D) || isa<FunctionDecl>(D)) { | ||||
553 | SmallVector<const NamedDecl*, 8> Overridden; | ||||
554 | const auto *OMD = dyn_cast<ObjCMethodDecl>(D); | ||||
555 | if (OMD && OMD->isPropertyAccessor()) | ||||
556 | if (const ObjCPropertyDecl *PDecl = OMD->findPropertyDecl()) | ||||
557 | if (comments::FullComment *FC = getCommentForDecl(PDecl, PP)) | ||||
558 | return cloneFullComment(FC, D); | ||||
559 | if (OMD) | ||||
560 | addRedeclaredMethods(OMD, Overridden); | ||||
561 | getOverriddenMethods(dyn_cast<NamedDecl>(D), Overridden); | ||||
562 | for (unsigned i = 0, e = Overridden.size(); i < e; i++) | ||||
563 | if (comments::FullComment *FC = getCommentForDecl(Overridden[i], PP)) | ||||
564 | return cloneFullComment(FC, D); | ||||
565 | } | ||||
566 | else if (const auto *TD = dyn_cast<TypedefNameDecl>(D)) { | ||||
567 | // Attach any tag type's documentation to its typedef if latter | ||||
568 | // does not have one of its own. | ||||
569 | QualType QT = TD->getUnderlyingType(); | ||||
570 | if (const auto *TT = QT->getAs<TagType>()) | ||||
571 | if (const Decl *TD = TT->getDecl()) | ||||
572 | if (comments::FullComment *FC = getCommentForDecl(TD, PP)) | ||||
573 | return cloneFullComment(FC, D); | ||||
574 | } | ||||
575 | else if (const auto *IC = dyn_cast<ObjCInterfaceDecl>(D)) { | ||||
576 | while (IC->getSuperClass()) { | ||||
577 | IC = IC->getSuperClass(); | ||||
578 | if (comments::FullComment *FC = getCommentForDecl(IC, PP)) | ||||
579 | return cloneFullComment(FC, D); | ||||
580 | } | ||||
581 | } | ||||
582 | else if (const auto *CD = dyn_cast<ObjCCategoryDecl>(D)) { | ||||
583 | if (const ObjCInterfaceDecl *IC = CD->getClassInterface()) | ||||
584 | if (comments::FullComment *FC = getCommentForDecl(IC, PP)) | ||||
585 | return cloneFullComment(FC, D); | ||||
586 | } | ||||
587 | else if (const auto *RD = dyn_cast<CXXRecordDecl>(D)) { | ||||
588 | if (!(RD = RD->getDefinition())) | ||||
589 | return nullptr; | ||||
590 | // Check non-virtual bases. | ||||
591 | for (const auto &I : RD->bases()) { | ||||
592 | if (I.isVirtual() || (I.getAccessSpecifier() != AS_public)) | ||||
593 | continue; | ||||
594 | QualType Ty = I.getType(); | ||||
595 | if (Ty.isNull()) | ||||
596 | continue; | ||||
597 | if (const CXXRecordDecl *NonVirtualBase = Ty->getAsCXXRecordDecl()) { | ||||
598 | if (!(NonVirtualBase= NonVirtualBase->getDefinition())) | ||||
599 | continue; | ||||
600 | |||||
601 | if (comments::FullComment *FC = getCommentForDecl((NonVirtualBase), PP)) | ||||
602 | return cloneFullComment(FC, D); | ||||
603 | } | ||||
604 | } | ||||
605 | // Check virtual bases. | ||||
606 | for (const auto &I : RD->vbases()) { | ||||
607 | if (I.getAccessSpecifier() != AS_public) | ||||
608 | continue; | ||||
609 | QualType Ty = I.getType(); | ||||
610 | if (Ty.isNull()) | ||||
611 | continue; | ||||
612 | if (const CXXRecordDecl *VirtualBase = Ty->getAsCXXRecordDecl()) { | ||||
613 | if (!(VirtualBase= VirtualBase->getDefinition())) | ||||
614 | continue; | ||||
615 | if (comments::FullComment *FC = getCommentForDecl((VirtualBase), PP)) | ||||
616 | return cloneFullComment(FC, D); | ||||
617 | } | ||||
618 | } | ||||
619 | } | ||||
620 | return nullptr; | ||||
621 | } | ||||
622 | |||||
623 | // If the RawComment was attached to other redeclaration of this Decl, we | ||||
624 | // should parse the comment in context of that other Decl. This is important | ||||
625 | // because comments can contain references to parameter names which can be | ||||
626 | // different across redeclarations. | ||||
627 | if (D != OriginalDecl && OriginalDecl) | ||||
628 | return getCommentForDecl(OriginalDecl, PP); | ||||
629 | |||||
630 | comments::FullComment *FC = RC->parse(*this, PP, D); | ||||
631 | ParsedComments[Canonical] = FC; | ||||
632 | return FC; | ||||
633 | } | ||||
634 | |||||
635 | void | ||||
636 | ASTContext::CanonicalTemplateTemplateParm::Profile(llvm::FoldingSetNodeID &ID, | ||||
637 | TemplateTemplateParmDecl *Parm) { | ||||
638 | ID.AddInteger(Parm->getDepth()); | ||||
639 | ID.AddInteger(Parm->getPosition()); | ||||
640 | ID.AddBoolean(Parm->isParameterPack()); | ||||
641 | |||||
642 | TemplateParameterList *Params = Parm->getTemplateParameters(); | ||||
643 | ID.AddInteger(Params->size()); | ||||
644 | for (TemplateParameterList::const_iterator P = Params->begin(), | ||||
645 | PEnd = Params->end(); | ||||
646 | P != PEnd; ++P) { | ||||
647 | if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) { | ||||
648 | ID.AddInteger(0); | ||||
649 | ID.AddBoolean(TTP->isParameterPack()); | ||||
650 | continue; | ||||
651 | } | ||||
652 | |||||
653 | if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P)) { | ||||
654 | ID.AddInteger(1); | ||||
655 | ID.AddBoolean(NTTP->isParameterPack()); | ||||
656 | ID.AddPointer(NTTP->getType().getCanonicalType().getAsOpaquePtr()); | ||||
657 | if (NTTP->isExpandedParameterPack()) { | ||||
658 | ID.AddBoolean(true); | ||||
659 | ID.AddInteger(NTTP->getNumExpansionTypes()); | ||||
660 | for (unsigned I = 0, N = NTTP->getNumExpansionTypes(); I != N; ++I) { | ||||
661 | QualType T = NTTP->getExpansionType(I); | ||||
662 | ID.AddPointer(T.getCanonicalType().getAsOpaquePtr()); | ||||
663 | } | ||||
664 | } else | ||||
665 | ID.AddBoolean(false); | ||||
666 | continue; | ||||
667 | } | ||||
668 | |||||
669 | auto *TTP = cast<TemplateTemplateParmDecl>(*P); | ||||
670 | ID.AddInteger(2); | ||||
671 | Profile(ID, TTP); | ||||
672 | } | ||||
673 | } | ||||
674 | |||||
675 | TemplateTemplateParmDecl * | ||||
676 | ASTContext::getCanonicalTemplateTemplateParmDecl( | ||||
677 | TemplateTemplateParmDecl *TTP) const { | ||||
678 | // Check if we already have a canonical template template parameter. | ||||
679 | llvm::FoldingSetNodeID ID; | ||||
680 | CanonicalTemplateTemplateParm::Profile(ID, TTP); | ||||
681 | void *InsertPos = nullptr; | ||||
682 | CanonicalTemplateTemplateParm *Canonical | ||||
683 | = CanonTemplateTemplateParms.FindNodeOrInsertPos(ID, InsertPos); | ||||
684 | if (Canonical) | ||||
685 | return Canonical->getParam(); | ||||
686 | |||||
687 | // Build a canonical template parameter list. | ||||
688 | TemplateParameterList *Params = TTP->getTemplateParameters(); | ||||
689 | SmallVector<NamedDecl *, 4> CanonParams; | ||||
690 | CanonParams.reserve(Params->size()); | ||||
691 | for (TemplateParameterList::const_iterator P = Params->begin(), | ||||
692 | PEnd = Params->end(); | ||||
693 | P != PEnd; ++P) { | ||||
694 | if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) | ||||
695 | CanonParams.push_back( | ||||
696 | TemplateTypeParmDecl::Create(*this, getTranslationUnitDecl(), | ||||
697 | SourceLocation(), | ||||
698 | SourceLocation(), | ||||
699 | TTP->getDepth(), | ||||
700 | TTP->getIndex(), nullptr, false, | ||||
701 | TTP->isParameterPack())); | ||||
702 | else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P)) { | ||||
703 | QualType T = getCanonicalType(NTTP->getType()); | ||||
704 | TypeSourceInfo *TInfo = getTrivialTypeSourceInfo(T); | ||||
705 | NonTypeTemplateParmDecl *Param; | ||||
706 | if (NTTP->isExpandedParameterPack()) { | ||||
707 | SmallVector<QualType, 2> ExpandedTypes; | ||||
708 | SmallVector<TypeSourceInfo *, 2> ExpandedTInfos; | ||||
709 | for (unsigned I = 0, N = NTTP->getNumExpansionTypes(); I != N; ++I) { | ||||
710 | ExpandedTypes.push_back(getCanonicalType(NTTP->getExpansionType(I))); | ||||
711 | ExpandedTInfos.push_back( | ||||
712 | getTrivialTypeSourceInfo(ExpandedTypes.back())); | ||||
713 | } | ||||
714 | |||||
715 | Param = NonTypeTemplateParmDecl::Create(*this, getTranslationUnitDecl(), | ||||
716 | SourceLocation(), | ||||
717 | SourceLocation(), | ||||
718 | NTTP->getDepth(), | ||||
719 | NTTP->getPosition(), nullptr, | ||||
720 | T, | ||||
721 | TInfo, | ||||
722 | ExpandedTypes, | ||||
723 | ExpandedTInfos); | ||||
724 | } else { | ||||
725 | Param = NonTypeTemplateParmDecl::Create(*this, getTranslationUnitDecl(), | ||||
726 | SourceLocation(), | ||||
727 | SourceLocation(), | ||||
728 | NTTP->getDepth(), | ||||
729 | NTTP->getPosition(), nullptr, | ||||
730 | T, | ||||
731 | NTTP->isParameterPack(), | ||||
732 | TInfo); | ||||
733 | } | ||||
734 | CanonParams.push_back(Param); | ||||
735 | |||||
736 | } else | ||||
737 | CanonParams.push_back(getCanonicalTemplateTemplateParmDecl( | ||||
738 | cast<TemplateTemplateParmDecl>(*P))); | ||||
739 | } | ||||
740 | |||||
741 | assert(!TTP->getRequiresClause() &&((!TTP->getRequiresClause() && "Unexpected requires-clause on template template-parameter" ) ? static_cast<void> (0) : __assert_fail ("!TTP->getRequiresClause() && \"Unexpected requires-clause on template template-parameter\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 742, __PRETTY_FUNCTION__)) | ||||
742 | "Unexpected requires-clause on template template-parameter")((!TTP->getRequiresClause() && "Unexpected requires-clause on template template-parameter" ) ? static_cast<void> (0) : __assert_fail ("!TTP->getRequiresClause() && \"Unexpected requires-clause on template template-parameter\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 742, __PRETTY_FUNCTION__)); | ||||
743 | Expr *const CanonRequiresClause = nullptr; | ||||
744 | |||||
745 | TemplateTemplateParmDecl *CanonTTP | ||||
746 | = TemplateTemplateParmDecl::Create(*this, getTranslationUnitDecl(), | ||||
747 | SourceLocation(), TTP->getDepth(), | ||||
748 | TTP->getPosition(), | ||||
749 | TTP->isParameterPack(), | ||||
750 | nullptr, | ||||
751 | TemplateParameterList::Create(*this, SourceLocation(), | ||||
752 | SourceLocation(), | ||||
753 | CanonParams, | ||||
754 | SourceLocation(), | ||||
755 | CanonRequiresClause)); | ||||
756 | |||||
757 | // Get the new insert position for the node we care about. | ||||
758 | Canonical = CanonTemplateTemplateParms.FindNodeOrInsertPos(ID, InsertPos); | ||||
759 | assert(!Canonical && "Shouldn't be in the map!")((!Canonical && "Shouldn't be in the map!") ? static_cast <void> (0) : __assert_fail ("!Canonical && \"Shouldn't be in the map!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 759, __PRETTY_FUNCTION__)); | ||||
760 | (void)Canonical; | ||||
761 | |||||
762 | // Create the canonical template template parameter entry. | ||||
763 | Canonical = new (*this) CanonicalTemplateTemplateParm(CanonTTP); | ||||
764 | CanonTemplateTemplateParms.InsertNode(Canonical, InsertPos); | ||||
765 | return CanonTTP; | ||||
766 | } | ||||
767 | |||||
768 | CXXABI *ASTContext::createCXXABI(const TargetInfo &T) { | ||||
769 | if (!LangOpts.CPlusPlus) return nullptr; | ||||
770 | |||||
771 | switch (T.getCXXABI().getKind()) { | ||||
772 | case TargetCXXABI::GenericARM: // Same as Itanium at this level | ||||
773 | case TargetCXXABI::iOS: | ||||
774 | case TargetCXXABI::iOS64: | ||||
775 | case TargetCXXABI::WatchOS: | ||||
776 | case TargetCXXABI::GenericAArch64: | ||||
777 | case TargetCXXABI::GenericMIPS: | ||||
778 | case TargetCXXABI::GenericItanium: | ||||
779 | case TargetCXXABI::WebAssembly: | ||||
780 | return CreateItaniumCXXABI(*this); | ||||
781 | case TargetCXXABI::Microsoft: | ||||
782 | return CreateMicrosoftCXXABI(*this); | ||||
783 | } | ||||
784 | llvm_unreachable("Invalid CXXABI type!")::llvm::llvm_unreachable_internal("Invalid CXXABI type!", "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 784); | ||||
785 | } | ||||
786 | |||||
787 | interp::Context &ASTContext::getInterpContext() { | ||||
788 | if (!InterpContext) { | ||||
789 | InterpContext.reset(new interp::Context(*this)); | ||||
790 | } | ||||
791 | return *InterpContext.get(); | ||||
792 | } | ||||
793 | |||||
794 | static const LangASMap *getAddressSpaceMap(const TargetInfo &T, | ||||
795 | const LangOptions &LOpts) { | ||||
796 | if (LOpts.FakeAddressSpaceMap) { | ||||
797 | // The fake address space map must have a distinct entry for each | ||||
798 | // language-specific address space. | ||||
799 | static const unsigned FakeAddrSpaceMap[] = { | ||||
800 | 0, // Default | ||||
801 | 1, // opencl_global | ||||
802 | 3, // opencl_local | ||||
803 | 2, // opencl_constant | ||||
804 | 0, // opencl_private | ||||
805 | 4, // opencl_generic | ||||
806 | 5, // cuda_device | ||||
807 | 6, // cuda_constant | ||||
808 | 7 // cuda_shared | ||||
809 | }; | ||||
810 | return &FakeAddrSpaceMap; | ||||
811 | } else { | ||||
812 | return &T.getAddressSpaceMap(); | ||||
813 | } | ||||
814 | } | ||||
815 | |||||
816 | static bool isAddrSpaceMapManglingEnabled(const TargetInfo &TI, | ||||
817 | const LangOptions &LangOpts) { | ||||
818 | switch (LangOpts.getAddressSpaceMapMangling()) { | ||||
819 | case LangOptions::ASMM_Target: | ||||
820 | return TI.useAddressSpaceMapMangling(); | ||||
821 | case LangOptions::ASMM_On: | ||||
822 | return true; | ||||
823 | case LangOptions::ASMM_Off: | ||||
824 | return false; | ||||
825 | } | ||||
826 | llvm_unreachable("getAddressSpaceMapMangling() doesn't cover anything.")::llvm::llvm_unreachable_internal("getAddressSpaceMapMangling() doesn't cover anything." , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 826); | ||||
827 | } | ||||
828 | |||||
829 | ASTContext::ASTContext(LangOptions &LOpts, SourceManager &SM, | ||||
830 | IdentifierTable &idents, SelectorTable &sels, | ||||
831 | Builtin::Context &builtins) | ||||
832 | : FunctionProtoTypes(this_()), TemplateSpecializationTypes(this_()), | ||||
833 | DependentTemplateSpecializationTypes(this_()), | ||||
834 | SubstTemplateTemplateParmPacks(this_()), SourceMgr(SM), LangOpts(LOpts), | ||||
835 | SanitizerBL(new SanitizerBlacklist(LangOpts.SanitizerBlacklistFiles, SM)), | ||||
836 | XRayFilter(new XRayFunctionFilter(LangOpts.XRayAlwaysInstrumentFiles, | ||||
837 | LangOpts.XRayNeverInstrumentFiles, | ||||
838 | LangOpts.XRayAttrListFiles, SM)), | ||||
839 | PrintingPolicy(LOpts), Idents(idents), Selectors(sels), | ||||
840 | BuiltinInfo(builtins), DeclarationNames(*this), Comments(SM), | ||||
841 | CommentCommandTraits(BumpAlloc, LOpts.CommentOpts), | ||||
842 | CompCategories(this_()), LastSDM(nullptr, 0) { | ||||
843 | TUDecl = TranslationUnitDecl::Create(*this); | ||||
844 | TraversalScope = {TUDecl}; | ||||
845 | } | ||||
846 | |||||
847 | ASTContext::~ASTContext() { | ||||
848 | // Release the DenseMaps associated with DeclContext objects. | ||||
849 | // FIXME: Is this the ideal solution? | ||||
850 | ReleaseDeclContextMaps(); | ||||
851 | |||||
852 | // Call all of the deallocation functions on all of their targets. | ||||
853 | for (auto &Pair : Deallocations) | ||||
854 | (Pair.first)(Pair.second); | ||||
855 | |||||
856 | // ASTRecordLayout objects in ASTRecordLayouts must always be destroyed | ||||
857 | // because they can contain DenseMaps. | ||||
858 | for (llvm::DenseMap<const ObjCContainerDecl*, | ||||
859 | const ASTRecordLayout*>::iterator | ||||
860 | I = ObjCLayouts.begin(), E = ObjCLayouts.end(); I != E; ) | ||||
861 | // Increment in loop to prevent using deallocated memory. | ||||
862 | if (auto *R = const_cast<ASTRecordLayout *>((I++)->second)) | ||||
863 | R->Destroy(*this); | ||||
864 | |||||
865 | for (llvm::DenseMap<const RecordDecl*, const ASTRecordLayout*>::iterator | ||||
866 | I = ASTRecordLayouts.begin(), E = ASTRecordLayouts.end(); I != E; ) { | ||||
867 | // Increment in loop to prevent using deallocated memory. | ||||
868 | if (auto *R = const_cast<ASTRecordLayout *>((I++)->second)) | ||||
869 | R->Destroy(*this); | ||||
870 | } | ||||
871 | |||||
872 | for (llvm::DenseMap<const Decl*, AttrVec*>::iterator A = DeclAttrs.begin(), | ||||
873 | AEnd = DeclAttrs.end(); | ||||
874 | A != AEnd; ++A) | ||||
875 | A->second->~AttrVec(); | ||||
876 | |||||
877 | for (std::pair<const MaterializeTemporaryExpr *, APValue *> &MTVPair : | ||||
878 | MaterializedTemporaryValues) | ||||
879 | MTVPair.second->~APValue(); | ||||
880 | |||||
881 | for (const auto &Value : ModuleInitializers) | ||||
882 | Value.second->~PerModuleInitializers(); | ||||
883 | |||||
884 | for (APValue *Value : APValueCleanups) | ||||
885 | Value->~APValue(); | ||||
886 | } | ||||
887 | |||||
888 | class ASTContext::ParentMap { | ||||
889 | /// Contains parents of a node. | ||||
890 | using ParentVector = llvm::SmallVector<ast_type_traits::DynTypedNode, 2>; | ||||
891 | |||||
892 | /// Maps from a node to its parents. This is used for nodes that have | ||||
893 | /// pointer identity only, which are more common and we can save space by | ||||
894 | /// only storing a unique pointer to them. | ||||
895 | using ParentMapPointers = llvm::DenseMap< | ||||
896 | const void *, | ||||
897 | llvm::PointerUnion4<const Decl *, const Stmt *, | ||||
898 | ast_type_traits::DynTypedNode *, ParentVector *>>; | ||||
899 | |||||
900 | /// Parent map for nodes without pointer identity. We store a full | ||||
901 | /// DynTypedNode for all keys. | ||||
902 | using ParentMapOtherNodes = llvm::DenseMap< | ||||
903 | ast_type_traits::DynTypedNode, | ||||
904 | llvm::PointerUnion4<const Decl *, const Stmt *, | ||||
905 | ast_type_traits::DynTypedNode *, ParentVector *>>; | ||||
906 | |||||
907 | ParentMapPointers PointerParents; | ||||
908 | ParentMapOtherNodes OtherParents; | ||||
909 | class ASTVisitor; | ||||
910 | |||||
911 | static ast_type_traits::DynTypedNode | ||||
912 | getSingleDynTypedNodeFromParentMap(ParentMapPointers::mapped_type U) { | ||||
913 | if (const auto *D = U.dyn_cast<const Decl *>()) | ||||
914 | return ast_type_traits::DynTypedNode::create(*D); | ||||
915 | if (const auto *S = U.dyn_cast<const Stmt *>()) | ||||
916 | return ast_type_traits::DynTypedNode::create(*S); | ||||
917 | return *U.get<ast_type_traits::DynTypedNode *>(); | ||||
918 | } | ||||
919 | |||||
920 | template <typename NodeTy, typename MapTy> | ||||
921 | static ASTContext::DynTypedNodeList getDynNodeFromMap(const NodeTy &Node, | ||||
922 | const MapTy &Map) { | ||||
923 | auto I = Map.find(Node); | ||||
924 | if (I == Map.end()) { | ||||
925 | return llvm::ArrayRef<ast_type_traits::DynTypedNode>(); | ||||
926 | } | ||||
927 | if (const auto *V = I->second.template dyn_cast<ParentVector *>()) { | ||||
928 | return llvm::makeArrayRef(*V); | ||||
929 | } | ||||
930 | return getSingleDynTypedNodeFromParentMap(I->second); | ||||
931 | } | ||||
932 | |||||
933 | public: | ||||
934 | ParentMap(ASTContext &Ctx); | ||||
935 | ~ParentMap() { | ||||
936 | for (const auto &Entry : PointerParents) { | ||||
937 | if (Entry.second.is<ast_type_traits::DynTypedNode *>()) { | ||||
938 | delete Entry.second.get<ast_type_traits::DynTypedNode *>(); | ||||
939 | } else if (Entry.second.is<ParentVector *>()) { | ||||
940 | delete Entry.second.get<ParentVector *>(); | ||||
941 | } | ||||
942 | } | ||||
943 | for (const auto &Entry : OtherParents) { | ||||
944 | if (Entry.second.is<ast_type_traits::DynTypedNode *>()) { | ||||
945 | delete Entry.second.get<ast_type_traits::DynTypedNode *>(); | ||||
946 | } else if (Entry.second.is<ParentVector *>()) { | ||||
947 | delete Entry.second.get<ParentVector *>(); | ||||
948 | } | ||||
949 | } | ||||
950 | } | ||||
951 | |||||
952 | DynTypedNodeList getParents(const ast_type_traits::DynTypedNode &Node) { | ||||
953 | if (Node.getNodeKind().hasPointerIdentity()) | ||||
954 | return getDynNodeFromMap(Node.getMemoizationData(), PointerParents); | ||||
955 | return getDynNodeFromMap(Node, OtherParents); | ||||
956 | } | ||||
957 | }; | ||||
958 | |||||
959 | void ASTContext::setTraversalScope(const std::vector<Decl *> &TopLevelDecls) { | ||||
960 | TraversalScope = TopLevelDecls; | ||||
961 | Parents.reset(); | ||||
962 | } | ||||
963 | |||||
964 | void ASTContext::AddDeallocation(void (*Callback)(void *), void *Data) const { | ||||
965 | Deallocations.push_back({Callback, Data}); | ||||
966 | } | ||||
967 | |||||
968 | void | ||||
969 | ASTContext::setExternalSource(IntrusiveRefCntPtr<ExternalASTSource> Source) { | ||||
970 | ExternalSource = std::move(Source); | ||||
971 | } | ||||
972 | |||||
973 | void ASTContext::PrintStats() const { | ||||
974 | llvm::errs() << "\n*** AST Context Stats:\n"; | ||||
975 | llvm::errs() << " " << Types.size() << " types total.\n"; | ||||
976 | |||||
977 | unsigned counts[] = { | ||||
978 | #define TYPE(Name, Parent) 0, | ||||
979 | #define ABSTRACT_TYPE(Name, Parent) | ||||
980 | #include "clang/AST/TypeNodes.inc" | ||||
981 | 0 // Extra | ||||
982 | }; | ||||
983 | |||||
984 | for (unsigned i = 0, e = Types.size(); i != e; ++i) { | ||||
985 | Type *T = Types[i]; | ||||
986 | counts[(unsigned)T->getTypeClass()]++; | ||||
987 | } | ||||
988 | |||||
989 | unsigned Idx = 0; | ||||
990 | unsigned TotalBytes = 0; | ||||
991 | #define TYPE(Name, Parent) \ | ||||
992 | if (counts[Idx]) \ | ||||
993 | llvm::errs() << " " << counts[Idx] << " " << #Name \ | ||||
994 | << " types, " << sizeof(Name##Type) << " each " \ | ||||
995 | << "(" << counts[Idx] * sizeof(Name##Type) \ | ||||
996 | << " bytes)\n"; \ | ||||
997 | TotalBytes += counts[Idx] * sizeof(Name##Type); \ | ||||
998 | ++Idx; | ||||
999 | #define ABSTRACT_TYPE(Name, Parent) | ||||
1000 | #include "clang/AST/TypeNodes.inc" | ||||
1001 | |||||
1002 | llvm::errs() << "Total bytes = " << TotalBytes << "\n"; | ||||
1003 | |||||
1004 | // Implicit special member functions. | ||||
1005 | llvm::errs() << NumImplicitDefaultConstructorsDeclared << "/" | ||||
1006 | << NumImplicitDefaultConstructors | ||||
1007 | << " implicit default constructors created\n"; | ||||
1008 | llvm::errs() << NumImplicitCopyConstructorsDeclared << "/" | ||||
1009 | << NumImplicitCopyConstructors | ||||
1010 | << " implicit copy constructors created\n"; | ||||
1011 | if (getLangOpts().CPlusPlus) | ||||
1012 | llvm::errs() << NumImplicitMoveConstructorsDeclared << "/" | ||||
1013 | << NumImplicitMoveConstructors | ||||
1014 | << " implicit move constructors created\n"; | ||||
1015 | llvm::errs() << NumImplicitCopyAssignmentOperatorsDeclared << "/" | ||||
1016 | << NumImplicitCopyAssignmentOperators | ||||
1017 | << " implicit copy assignment operators created\n"; | ||||
1018 | if (getLangOpts().CPlusPlus) | ||||
1019 | llvm::errs() << NumImplicitMoveAssignmentOperatorsDeclared << "/" | ||||
1020 | << NumImplicitMoveAssignmentOperators | ||||
1021 | << " implicit move assignment operators created\n"; | ||||
1022 | llvm::errs() << NumImplicitDestructorsDeclared << "/" | ||||
1023 | << NumImplicitDestructors | ||||
1024 | << " implicit destructors created\n"; | ||||
1025 | |||||
1026 | if (ExternalSource) { | ||||
1027 | llvm::errs() << "\n"; | ||||
1028 | ExternalSource->PrintStats(); | ||||
1029 | } | ||||
1030 | |||||
1031 | BumpAlloc.PrintStats(); | ||||
1032 | } | ||||
1033 | |||||
1034 | void ASTContext::mergeDefinitionIntoModule(NamedDecl *ND, Module *M, | ||||
1035 | bool NotifyListeners) { | ||||
1036 | if (NotifyListeners) | ||||
1037 | if (auto *Listener = getASTMutationListener()) | ||||
1038 | Listener->RedefinedHiddenDefinition(ND, M); | ||||
1039 | |||||
1040 | MergedDefModules[cast<NamedDecl>(ND->getCanonicalDecl())].push_back(M); | ||||
1041 | } | ||||
1042 | |||||
1043 | void ASTContext::deduplicateMergedDefinitonsFor(NamedDecl *ND) { | ||||
1044 | auto It = MergedDefModules.find(cast<NamedDecl>(ND->getCanonicalDecl())); | ||||
1045 | if (It == MergedDefModules.end()) | ||||
1046 | return; | ||||
1047 | |||||
1048 | auto &Merged = It->second; | ||||
1049 | llvm::DenseSet<Module*> Found; | ||||
1050 | for (Module *&M : Merged) | ||||
1051 | if (!Found.insert(M).second) | ||||
1052 | M = nullptr; | ||||
1053 | Merged.erase(std::remove(Merged.begin(), Merged.end(), nullptr), Merged.end()); | ||||
1054 | } | ||||
1055 | |||||
1056 | void ASTContext::PerModuleInitializers::resolve(ASTContext &Ctx) { | ||||
1057 | if (LazyInitializers.empty()) | ||||
1058 | return; | ||||
1059 | |||||
1060 | auto *Source = Ctx.getExternalSource(); | ||||
1061 | assert(Source && "lazy initializers but no external source")((Source && "lazy initializers but no external source" ) ? static_cast<void> (0) : __assert_fail ("Source && \"lazy initializers but no external source\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 1061, __PRETTY_FUNCTION__)); | ||||
1062 | |||||
1063 | auto LazyInits = std::move(LazyInitializers); | ||||
1064 | LazyInitializers.clear(); | ||||
1065 | |||||
1066 | for (auto ID : LazyInits) | ||||
1067 | Initializers.push_back(Source->GetExternalDecl(ID)); | ||||
1068 | |||||
1069 | assert(LazyInitializers.empty() &&((LazyInitializers.empty() && "GetExternalDecl for lazy module initializer added more inits" ) ? static_cast<void> (0) : __assert_fail ("LazyInitializers.empty() && \"GetExternalDecl for lazy module initializer added more inits\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 1070, __PRETTY_FUNCTION__)) | ||||
1070 | "GetExternalDecl for lazy module initializer added more inits")((LazyInitializers.empty() && "GetExternalDecl for lazy module initializer added more inits" ) ? static_cast<void> (0) : __assert_fail ("LazyInitializers.empty() && \"GetExternalDecl for lazy module initializer added more inits\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 1070, __PRETTY_FUNCTION__)); | ||||
1071 | } | ||||
1072 | |||||
1073 | void ASTContext::addModuleInitializer(Module *M, Decl *D) { | ||||
1074 | // One special case: if we add a module initializer that imports another | ||||
1075 | // module, and that module's only initializer is an ImportDecl, simplify. | ||||
1076 | if (const auto *ID = dyn_cast<ImportDecl>(D)) { | ||||
1077 | auto It = ModuleInitializers.find(ID->getImportedModule()); | ||||
1078 | |||||
1079 | // Maybe the ImportDecl does nothing at all. (Common case.) | ||||
1080 | if (It == ModuleInitializers.end()) | ||||
1081 | return; | ||||
1082 | |||||
1083 | // Maybe the ImportDecl only imports another ImportDecl. | ||||
1084 | auto &Imported = *It->second; | ||||
1085 | if (Imported.Initializers.size() + Imported.LazyInitializers.size() == 1) { | ||||
1086 | Imported.resolve(*this); | ||||
1087 | auto *OnlyDecl = Imported.Initializers.front(); | ||||
1088 | if (isa<ImportDecl>(OnlyDecl)) | ||||
1089 | D = OnlyDecl; | ||||
1090 | } | ||||
1091 | } | ||||
1092 | |||||
1093 | auto *&Inits = ModuleInitializers[M]; | ||||
1094 | if (!Inits) | ||||
1095 | Inits = new (*this) PerModuleInitializers; | ||||
1096 | Inits->Initializers.push_back(D); | ||||
1097 | } | ||||
1098 | |||||
1099 | void ASTContext::addLazyModuleInitializers(Module *M, ArrayRef<uint32_t> IDs) { | ||||
1100 | auto *&Inits = ModuleInitializers[M]; | ||||
1101 | if (!Inits) | ||||
1102 | Inits = new (*this) PerModuleInitializers; | ||||
1103 | Inits->LazyInitializers.insert(Inits->LazyInitializers.end(), | ||||
1104 | IDs.begin(), IDs.end()); | ||||
1105 | } | ||||
1106 | |||||
1107 | ArrayRef<Decl *> ASTContext::getModuleInitializers(Module *M) { | ||||
1108 | auto It = ModuleInitializers.find(M); | ||||
1109 | if (It == ModuleInitializers.end()) | ||||
1110 | return None; | ||||
1111 | |||||
1112 | auto *Inits = It->second; | ||||
1113 | Inits->resolve(*this); | ||||
1114 | return Inits->Initializers; | ||||
1115 | } | ||||
1116 | |||||
1117 | ExternCContextDecl *ASTContext::getExternCContextDecl() const { | ||||
1118 | if (!ExternCContext) | ||||
1119 | ExternCContext = ExternCContextDecl::Create(*this, getTranslationUnitDecl()); | ||||
1120 | |||||
1121 | return ExternCContext; | ||||
1122 | } | ||||
1123 | |||||
1124 | BuiltinTemplateDecl * | ||||
1125 | ASTContext::buildBuiltinTemplateDecl(BuiltinTemplateKind BTK, | ||||
1126 | const IdentifierInfo *II) const { | ||||
1127 | auto *BuiltinTemplate = BuiltinTemplateDecl::Create(*this, TUDecl, II, BTK); | ||||
1128 | BuiltinTemplate->setImplicit(); | ||||
1129 | TUDecl->addDecl(BuiltinTemplate); | ||||
1130 | |||||
1131 | return BuiltinTemplate; | ||||
1132 | } | ||||
1133 | |||||
1134 | BuiltinTemplateDecl * | ||||
1135 | ASTContext::getMakeIntegerSeqDecl() const { | ||||
1136 | if (!MakeIntegerSeqDecl) | ||||
1137 | MakeIntegerSeqDecl = buildBuiltinTemplateDecl(BTK__make_integer_seq, | ||||
1138 | getMakeIntegerSeqName()); | ||||
1139 | return MakeIntegerSeqDecl; | ||||
1140 | } | ||||
1141 | |||||
1142 | BuiltinTemplateDecl * | ||||
1143 | ASTContext::getTypePackElementDecl() const { | ||||
1144 | if (!TypePackElementDecl) | ||||
1145 | TypePackElementDecl = buildBuiltinTemplateDecl(BTK__type_pack_element, | ||||
1146 | getTypePackElementName()); | ||||
1147 | return TypePackElementDecl; | ||||
1148 | } | ||||
1149 | |||||
1150 | RecordDecl *ASTContext::buildImplicitRecord(StringRef Name, | ||||
1151 | RecordDecl::TagKind TK) const { | ||||
1152 | SourceLocation Loc; | ||||
1153 | RecordDecl *NewDecl; | ||||
1154 | if (getLangOpts().CPlusPlus) | ||||
1155 | NewDecl = CXXRecordDecl::Create(*this, TK, getTranslationUnitDecl(), Loc, | ||||
1156 | Loc, &Idents.get(Name)); | ||||
1157 | else | ||||
1158 | NewDecl = RecordDecl::Create(*this, TK, getTranslationUnitDecl(), Loc, Loc, | ||||
1159 | &Idents.get(Name)); | ||||
1160 | NewDecl->setImplicit(); | ||||
1161 | NewDecl->addAttr(TypeVisibilityAttr::CreateImplicit( | ||||
1162 | const_cast<ASTContext &>(*this), TypeVisibilityAttr::Default)); | ||||
1163 | return NewDecl; | ||||
1164 | } | ||||
1165 | |||||
1166 | TypedefDecl *ASTContext::buildImplicitTypedef(QualType T, | ||||
1167 | StringRef Name) const { | ||||
1168 | TypeSourceInfo *TInfo = getTrivialTypeSourceInfo(T); | ||||
1169 | TypedefDecl *NewDecl = TypedefDecl::Create( | ||||
1170 | const_cast<ASTContext &>(*this), getTranslationUnitDecl(), | ||||
1171 | SourceLocation(), SourceLocation(), &Idents.get(Name), TInfo); | ||||
1172 | NewDecl->setImplicit(); | ||||
1173 | return NewDecl; | ||||
1174 | } | ||||
1175 | |||||
1176 | TypedefDecl *ASTContext::getInt128Decl() const { | ||||
1177 | if (!Int128Decl) | ||||
1178 | Int128Decl = buildImplicitTypedef(Int128Ty, "__int128_t"); | ||||
1179 | return Int128Decl; | ||||
1180 | } | ||||
1181 | |||||
1182 | TypedefDecl *ASTContext::getUInt128Decl() const { | ||||
1183 | if (!UInt128Decl) | ||||
1184 | UInt128Decl = buildImplicitTypedef(UnsignedInt128Ty, "__uint128_t"); | ||||
1185 | return UInt128Decl; | ||||
1186 | } | ||||
1187 | |||||
1188 | void ASTContext::InitBuiltinType(CanQualType &R, BuiltinType::Kind K) { | ||||
1189 | auto *Ty = new (*this, TypeAlignment) BuiltinType(K); | ||||
1190 | R = CanQualType::CreateUnsafe(QualType(Ty, 0)); | ||||
1191 | Types.push_back(Ty); | ||||
1192 | } | ||||
1193 | |||||
1194 | void ASTContext::InitBuiltinTypes(const TargetInfo &Target, | ||||
1195 | const TargetInfo *AuxTarget) { | ||||
1196 | assert((!this->Target || this->Target == &Target) &&(((!this->Target || this->Target == &Target) && "Incorrect target reinitialization") ? static_cast<void> (0) : __assert_fail ("(!this->Target || this->Target == &Target) && \"Incorrect target reinitialization\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 1197, __PRETTY_FUNCTION__)) | ||||
1197 | "Incorrect target reinitialization")(((!this->Target || this->Target == &Target) && "Incorrect target reinitialization") ? static_cast<void> (0) : __assert_fail ("(!this->Target || this->Target == &Target) && \"Incorrect target reinitialization\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 1197, __PRETTY_FUNCTION__)); | ||||
1198 | assert(VoidTy.isNull() && "Context reinitialized?")((VoidTy.isNull() && "Context reinitialized?") ? static_cast <void> (0) : __assert_fail ("VoidTy.isNull() && \"Context reinitialized?\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 1198, __PRETTY_FUNCTION__)); | ||||
1199 | |||||
1200 | this->Target = &Target; | ||||
1201 | this->AuxTarget = AuxTarget; | ||||
1202 | |||||
1203 | ABI.reset(createCXXABI(Target)); | ||||
1204 | AddrSpaceMap = getAddressSpaceMap(Target, LangOpts); | ||||
1205 | AddrSpaceMapMangling = isAddrSpaceMapManglingEnabled(Target, LangOpts); | ||||
1206 | |||||
1207 | // C99 6.2.5p19. | ||||
1208 | InitBuiltinType(VoidTy, BuiltinType::Void); | ||||
1209 | |||||
1210 | // C99 6.2.5p2. | ||||
1211 | InitBuiltinType(BoolTy, BuiltinType::Bool); | ||||
1212 | // C99 6.2.5p3. | ||||
1213 | if (LangOpts.CharIsSigned) | ||||
1214 | InitBuiltinType(CharTy, BuiltinType::Char_S); | ||||
1215 | else | ||||
1216 | InitBuiltinType(CharTy, BuiltinType::Char_U); | ||||
1217 | // C99 6.2.5p4. | ||||
1218 | InitBuiltinType(SignedCharTy, BuiltinType::SChar); | ||||
1219 | InitBuiltinType(ShortTy, BuiltinType::Short); | ||||
1220 | InitBuiltinType(IntTy, BuiltinType::Int); | ||||
1221 | InitBuiltinType(LongTy, BuiltinType::Long); | ||||
1222 | InitBuiltinType(LongLongTy, BuiltinType::LongLong); | ||||
1223 | |||||
1224 | // C99 6.2.5p6. | ||||
1225 | InitBuiltinType(UnsignedCharTy, BuiltinType::UChar); | ||||
1226 | InitBuiltinType(UnsignedShortTy, BuiltinType::UShort); | ||||
1227 | InitBuiltinType(UnsignedIntTy, BuiltinType::UInt); | ||||
1228 | InitBuiltinType(UnsignedLongTy, BuiltinType::ULong); | ||||
1229 | InitBuiltinType(UnsignedLongLongTy, BuiltinType::ULongLong); | ||||
1230 | |||||
1231 | // C99 6.2.5p10. | ||||
1232 | InitBuiltinType(FloatTy, BuiltinType::Float); | ||||
1233 | InitBuiltinType(DoubleTy, BuiltinType::Double); | ||||
1234 | InitBuiltinType(LongDoubleTy, BuiltinType::LongDouble); | ||||
1235 | |||||
1236 | // GNU extension, __float128 for IEEE quadruple precision | ||||
1237 | InitBuiltinType(Float128Ty, BuiltinType::Float128); | ||||
1238 | |||||
1239 | // C11 extension ISO/IEC TS 18661-3 | ||||
1240 | InitBuiltinType(Float16Ty, BuiltinType::Float16); | ||||
1241 | |||||
1242 | // ISO/IEC JTC1 SC22 WG14 N1169 Extension | ||||
1243 | InitBuiltinType(ShortAccumTy, BuiltinType::ShortAccum); | ||||
1244 | InitBuiltinType(AccumTy, BuiltinType::Accum); | ||||
1245 | InitBuiltinType(LongAccumTy, BuiltinType::LongAccum); | ||||
1246 | InitBuiltinType(UnsignedShortAccumTy, BuiltinType::UShortAccum); | ||||
1247 | InitBuiltinType(UnsignedAccumTy, BuiltinType::UAccum); | ||||
1248 | InitBuiltinType(UnsignedLongAccumTy, BuiltinType::ULongAccum); | ||||
1249 | InitBuiltinType(ShortFractTy, BuiltinType::ShortFract); | ||||
1250 | InitBuiltinType(FractTy, BuiltinType::Fract); | ||||
1251 | InitBuiltinType(LongFractTy, BuiltinType::LongFract); | ||||
1252 | InitBuiltinType(UnsignedShortFractTy, BuiltinType::UShortFract); | ||||
1253 | InitBuiltinType(UnsignedFractTy, BuiltinType::UFract); | ||||
1254 | InitBuiltinType(UnsignedLongFractTy, BuiltinType::ULongFract); | ||||
1255 | InitBuiltinType(SatShortAccumTy, BuiltinType::SatShortAccum); | ||||
1256 | InitBuiltinType(SatAccumTy, BuiltinType::SatAccum); | ||||
1257 | InitBuiltinType(SatLongAccumTy, BuiltinType::SatLongAccum); | ||||
1258 | InitBuiltinType(SatUnsignedShortAccumTy, BuiltinType::SatUShortAccum); | ||||
1259 | InitBuiltinType(SatUnsignedAccumTy, BuiltinType::SatUAccum); | ||||
1260 | InitBuiltinType(SatUnsignedLongAccumTy, BuiltinType::SatULongAccum); | ||||
1261 | InitBuiltinType(SatShortFractTy, BuiltinType::SatShortFract); | ||||
1262 | InitBuiltinType(SatFractTy, BuiltinType::SatFract); | ||||
1263 | InitBuiltinType(SatLongFractTy, BuiltinType::SatLongFract); | ||||
1264 | InitBuiltinType(SatUnsignedShortFractTy, BuiltinType::SatUShortFract); | ||||
1265 | InitBuiltinType(SatUnsignedFractTy, BuiltinType::SatUFract); | ||||
1266 | InitBuiltinType(SatUnsignedLongFractTy, BuiltinType::SatULongFract); | ||||
1267 | |||||
1268 | // GNU extension, 128-bit integers. | ||||
1269 | InitBuiltinType(Int128Ty, BuiltinType::Int128); | ||||
1270 | InitBuiltinType(UnsignedInt128Ty, BuiltinType::UInt128); | ||||
1271 | |||||
1272 | // C++ 3.9.1p5 | ||||
1273 | if (TargetInfo::isTypeSigned(Target.getWCharType())) | ||||
1274 | InitBuiltinType(WCharTy, BuiltinType::WChar_S); | ||||
1275 | else // -fshort-wchar makes wchar_t be unsigned. | ||||
1276 | InitBuiltinType(WCharTy, BuiltinType::WChar_U); | ||||
1277 | if (LangOpts.CPlusPlus && LangOpts.WChar) | ||||
1278 | WideCharTy = WCharTy; | ||||
1279 | else { | ||||
1280 | // C99 (or C++ using -fno-wchar). | ||||
1281 | WideCharTy = getFromTargetType(Target.getWCharType()); | ||||
1282 | } | ||||
1283 | |||||
1284 | WIntTy = getFromTargetType(Target.getWIntType()); | ||||
1285 | |||||
1286 | // C++20 (proposed) | ||||
1287 | InitBuiltinType(Char8Ty, BuiltinType::Char8); | ||||
1288 | |||||
1289 | if (LangOpts.CPlusPlus) // C++0x 3.9.1p5, extension for C++ | ||||
1290 | InitBuiltinType(Char16Ty, BuiltinType::Char16); | ||||
1291 | else // C99 | ||||
1292 | Char16Ty = getFromTargetType(Target.getChar16Type()); | ||||
1293 | |||||
1294 | if (LangOpts.CPlusPlus) // C++0x 3.9.1p5, extension for C++ | ||||
1295 | InitBuiltinType(Char32Ty, BuiltinType::Char32); | ||||
1296 | else // C99 | ||||
1297 | Char32Ty = getFromTargetType(Target.getChar32Type()); | ||||
1298 | |||||
1299 | // Placeholder type for type-dependent expressions whose type is | ||||
1300 | // completely unknown. No code should ever check a type against | ||||
1301 | // DependentTy and users should never see it; however, it is here to | ||||
1302 | // help diagnose failures to properly check for type-dependent | ||||
1303 | // expressions. | ||||
1304 | InitBuiltinType(DependentTy, BuiltinType::Dependent); | ||||
1305 | |||||
1306 | // Placeholder type for functions. | ||||
1307 | InitBuiltinType(OverloadTy, BuiltinType::Overload); | ||||
1308 | |||||
1309 | // Placeholder type for bound members. | ||||
1310 | InitBuiltinType(BoundMemberTy, BuiltinType::BoundMember); | ||||
1311 | |||||
1312 | // Placeholder type for pseudo-objects. | ||||
1313 | InitBuiltinType(PseudoObjectTy, BuiltinType::PseudoObject); | ||||
1314 | |||||
1315 | // "any" type; useful for debugger-like clients. | ||||
1316 | InitBuiltinType(UnknownAnyTy, BuiltinType::UnknownAny); | ||||
1317 | |||||
1318 | // Placeholder type for unbridged ARC casts. | ||||
1319 | InitBuiltinType(ARCUnbridgedCastTy, BuiltinType::ARCUnbridgedCast); | ||||
1320 | |||||
1321 | // Placeholder type for builtin functions. | ||||
1322 | InitBuiltinType(BuiltinFnTy, BuiltinType::BuiltinFn); | ||||
1323 | |||||
1324 | // Placeholder type for OMP array sections. | ||||
1325 | if (LangOpts.OpenMP) | ||||
1326 | InitBuiltinType(OMPArraySectionTy, BuiltinType::OMPArraySection); | ||||
1327 | |||||
1328 | // C99 6.2.5p11. | ||||
1329 | FloatComplexTy = getComplexType(FloatTy); | ||||
1330 | DoubleComplexTy = getComplexType(DoubleTy); | ||||
1331 | LongDoubleComplexTy = getComplexType(LongDoubleTy); | ||||
1332 | Float128ComplexTy = getComplexType(Float128Ty); | ||||
1333 | |||||
1334 | // Builtin types for 'id', 'Class', and 'SEL'. | ||||
1335 | InitBuiltinType(ObjCBuiltinIdTy, BuiltinType::ObjCId); | ||||
1336 | InitBuiltinType(ObjCBuiltinClassTy, BuiltinType::ObjCClass); | ||||
1337 | InitBuiltinType(ObjCBuiltinSelTy, BuiltinType::ObjCSel); | ||||
1338 | |||||
1339 | if (LangOpts.OpenCL) { | ||||
1340 | #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ | ||||
1341 | InitBuiltinType(SingletonId, BuiltinType::Id); | ||||
1342 | #include "clang/Basic/OpenCLImageTypes.def" | ||||
1343 | |||||
1344 | InitBuiltinType(OCLSamplerTy, BuiltinType::OCLSampler); | ||||
1345 | InitBuiltinType(OCLEventTy, BuiltinType::OCLEvent); | ||||
1346 | InitBuiltinType(OCLClkEventTy, BuiltinType::OCLClkEvent); | ||||
1347 | InitBuiltinType(OCLQueueTy, BuiltinType::OCLQueue); | ||||
1348 | InitBuiltinType(OCLReserveIDTy, BuiltinType::OCLReserveID); | ||||
1349 | |||||
1350 | #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \ | ||||
1351 | InitBuiltinType(Id##Ty, BuiltinType::Id); | ||||
1352 | #include "clang/Basic/OpenCLExtensionTypes.def" | ||||
1353 | } | ||||
1354 | |||||
1355 | if (Target.hasAArch64SVETypes()) { | ||||
1356 | #define SVE_TYPE(Name, Id, SingletonId) \ | ||||
1357 | InitBuiltinType(SingletonId, BuiltinType::Id); | ||||
1358 | #include "clang/Basic/AArch64SVEACLETypes.def" | ||||
1359 | } | ||||
1360 | |||||
1361 | // Builtin type for __objc_yes and __objc_no | ||||
1362 | ObjCBuiltinBoolTy = (Target.useSignedCharForObjCBool() ? | ||||
1363 | SignedCharTy : BoolTy); | ||||
1364 | |||||
1365 | ObjCConstantStringType = QualType(); | ||||
1366 | |||||
1367 | ObjCSuperType = QualType(); | ||||
1368 | |||||
1369 | // void * type | ||||
1370 | if (LangOpts.OpenCLVersion >= 200) { | ||||
1371 | auto Q = VoidTy.getQualifiers(); | ||||
1372 | Q.setAddressSpace(LangAS::opencl_generic); | ||||
1373 | VoidPtrTy = getPointerType(getCanonicalType( | ||||
1374 | getQualifiedType(VoidTy.getUnqualifiedType(), Q))); | ||||
1375 | } else { | ||||
1376 | VoidPtrTy = getPointerType(VoidTy); | ||||
1377 | } | ||||
1378 | |||||
1379 | // nullptr type (C++0x 2.14.7) | ||||
1380 | InitBuiltinType(NullPtrTy, BuiltinType::NullPtr); | ||||
1381 | |||||
1382 | // half type (OpenCL 6.1.1.1) / ARM NEON __fp16 | ||||
1383 | InitBuiltinType(HalfTy, BuiltinType::Half); | ||||
1384 | |||||
1385 | // Builtin type used to help define __builtin_va_list. | ||||
1386 | VaListTagDecl = nullptr; | ||||
1387 | } | ||||
1388 | |||||
1389 | DiagnosticsEngine &ASTContext::getDiagnostics() const { | ||||
1390 | return SourceMgr.getDiagnostics(); | ||||
1391 | } | ||||
1392 | |||||
1393 | AttrVec& ASTContext::getDeclAttrs(const Decl *D) { | ||||
1394 | AttrVec *&Result = DeclAttrs[D]; | ||||
1395 | if (!Result) { | ||||
1396 | void *Mem = Allocate(sizeof(AttrVec)); | ||||
1397 | Result = new (Mem) AttrVec; | ||||
1398 | } | ||||
1399 | |||||
1400 | return *Result; | ||||
1401 | } | ||||
1402 | |||||
1403 | /// Erase the attributes corresponding to the given declaration. | ||||
1404 | void ASTContext::eraseDeclAttrs(const Decl *D) { | ||||
1405 | llvm::DenseMap<const Decl*, AttrVec*>::iterator Pos = DeclAttrs.find(D); | ||||
1406 | if (Pos != DeclAttrs.end()) { | ||||
1407 | Pos->second->~AttrVec(); | ||||
1408 | DeclAttrs.erase(Pos); | ||||
1409 | } | ||||
1410 | } | ||||
1411 | |||||
1412 | // FIXME: Remove ? | ||||
1413 | MemberSpecializationInfo * | ||||
1414 | ASTContext::getInstantiatedFromStaticDataMember(const VarDecl *Var) { | ||||
1415 | assert(Var->isStaticDataMember() && "Not a static data member")((Var->isStaticDataMember() && "Not a static data member" ) ? static_cast<void> (0) : __assert_fail ("Var->isStaticDataMember() && \"Not a static data member\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 1415, __PRETTY_FUNCTION__)); | ||||
1416 | return getTemplateOrSpecializationInfo(Var) | ||||
1417 | .dyn_cast<MemberSpecializationInfo *>(); | ||||
1418 | } | ||||
1419 | |||||
1420 | ASTContext::TemplateOrSpecializationInfo | ||||
1421 | ASTContext::getTemplateOrSpecializationInfo(const VarDecl *Var) { | ||||
1422 | llvm::DenseMap<const VarDecl *, TemplateOrSpecializationInfo>::iterator Pos = | ||||
1423 | TemplateOrInstantiation.find(Var); | ||||
1424 | if (Pos == TemplateOrInstantiation.end()) | ||||
1425 | return {}; | ||||
1426 | |||||
1427 | return Pos->second; | ||||
1428 | } | ||||
1429 | |||||
1430 | void | ||||
1431 | ASTContext::setInstantiatedFromStaticDataMember(VarDecl *Inst, VarDecl *Tmpl, | ||||
1432 | TemplateSpecializationKind TSK, | ||||
1433 | SourceLocation PointOfInstantiation) { | ||||
1434 | assert(Inst->isStaticDataMember() && "Not a static data member")((Inst->isStaticDataMember() && "Not a static data member" ) ? static_cast<void> (0) : __assert_fail ("Inst->isStaticDataMember() && \"Not a static data member\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 1434, __PRETTY_FUNCTION__)); | ||||
1435 | assert(Tmpl->isStaticDataMember() && "Not a static data member")((Tmpl->isStaticDataMember() && "Not a static data member" ) ? static_cast<void> (0) : __assert_fail ("Tmpl->isStaticDataMember() && \"Not a static data member\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 1435, __PRETTY_FUNCTION__)); | ||||
1436 | setTemplateOrSpecializationInfo(Inst, new (*this) MemberSpecializationInfo( | ||||
1437 | Tmpl, TSK, PointOfInstantiation)); | ||||
1438 | } | ||||
1439 | |||||
1440 | void | ||||
1441 | ASTContext::setTemplateOrSpecializationInfo(VarDecl *Inst, | ||||
1442 | TemplateOrSpecializationInfo TSI) { | ||||
1443 | assert(!TemplateOrInstantiation[Inst] &&((!TemplateOrInstantiation[Inst] && "Already noted what the variable was instantiated from" ) ? static_cast<void> (0) : __assert_fail ("!TemplateOrInstantiation[Inst] && \"Already noted what the variable was instantiated from\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 1444, __PRETTY_FUNCTION__)) | ||||
1444 | "Already noted what the variable was instantiated from")((!TemplateOrInstantiation[Inst] && "Already noted what the variable was instantiated from" ) ? static_cast<void> (0) : __assert_fail ("!TemplateOrInstantiation[Inst] && \"Already noted what the variable was instantiated from\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 1444, __PRETTY_FUNCTION__)); | ||||
1445 | TemplateOrInstantiation[Inst] = TSI; | ||||
1446 | } | ||||
1447 | |||||
1448 | NamedDecl * | ||||
1449 | ASTContext::getInstantiatedFromUsingDecl(NamedDecl *UUD) { | ||||
1450 | auto Pos = InstantiatedFromUsingDecl.find(UUD); | ||||
1451 | if (Pos == InstantiatedFromUsingDecl.end()) | ||||
1452 | return nullptr; | ||||
1453 | |||||
1454 | return Pos->second; | ||||
1455 | } | ||||
1456 | |||||
1457 | void | ||||
1458 | ASTContext::setInstantiatedFromUsingDecl(NamedDecl *Inst, NamedDecl *Pattern) { | ||||
1459 | assert((isa<UsingDecl>(Pattern) ||(((isa<UsingDecl>(Pattern) || isa<UnresolvedUsingValueDecl >(Pattern) || isa<UnresolvedUsingTypenameDecl>(Pattern )) && "pattern decl is not a using decl") ? static_cast <void> (0) : __assert_fail ("(isa<UsingDecl>(Pattern) || isa<UnresolvedUsingValueDecl>(Pattern) || isa<UnresolvedUsingTypenameDecl>(Pattern)) && \"pattern decl is not a using decl\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 1462, __PRETTY_FUNCTION__)) | ||||
1460 | isa<UnresolvedUsingValueDecl>(Pattern) ||(((isa<UsingDecl>(Pattern) || isa<UnresolvedUsingValueDecl >(Pattern) || isa<UnresolvedUsingTypenameDecl>(Pattern )) && "pattern decl is not a using decl") ? static_cast <void> (0) : __assert_fail ("(isa<UsingDecl>(Pattern) || isa<UnresolvedUsingValueDecl>(Pattern) || isa<UnresolvedUsingTypenameDecl>(Pattern)) && \"pattern decl is not a using decl\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 1462, __PRETTY_FUNCTION__)) | ||||
1461 | isa<UnresolvedUsingTypenameDecl>(Pattern)) &&(((isa<UsingDecl>(Pattern) || isa<UnresolvedUsingValueDecl >(Pattern) || isa<UnresolvedUsingTypenameDecl>(Pattern )) && "pattern decl is not a using decl") ? static_cast <void> (0) : __assert_fail ("(isa<UsingDecl>(Pattern) || isa<UnresolvedUsingValueDecl>(Pattern) || isa<UnresolvedUsingTypenameDecl>(Pattern)) && \"pattern decl is not a using decl\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 1462, __PRETTY_FUNCTION__)) | ||||
1462 | "pattern decl is not a using decl")(((isa<UsingDecl>(Pattern) || isa<UnresolvedUsingValueDecl >(Pattern) || isa<UnresolvedUsingTypenameDecl>(Pattern )) && "pattern decl is not a using decl") ? static_cast <void> (0) : __assert_fail ("(isa<UsingDecl>(Pattern) || isa<UnresolvedUsingValueDecl>(Pattern) || isa<UnresolvedUsingTypenameDecl>(Pattern)) && \"pattern decl is not a using decl\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 1462, __PRETTY_FUNCTION__)); | ||||
1463 | assert((isa<UsingDecl>(Inst) ||(((isa<UsingDecl>(Inst) || isa<UnresolvedUsingValueDecl >(Inst) || isa<UnresolvedUsingTypenameDecl>(Inst)) && "instantiation did not produce a using decl") ? static_cast< void> (0) : __assert_fail ("(isa<UsingDecl>(Inst) || isa<UnresolvedUsingValueDecl>(Inst) || isa<UnresolvedUsingTypenameDecl>(Inst)) && \"instantiation did not produce a using decl\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 1466, __PRETTY_FUNCTION__)) | ||||
1464 | isa<UnresolvedUsingValueDecl>(Inst) ||(((isa<UsingDecl>(Inst) || isa<UnresolvedUsingValueDecl >(Inst) || isa<UnresolvedUsingTypenameDecl>(Inst)) && "instantiation did not produce a using decl") ? static_cast< void> (0) : __assert_fail ("(isa<UsingDecl>(Inst) || isa<UnresolvedUsingValueDecl>(Inst) || isa<UnresolvedUsingTypenameDecl>(Inst)) && \"instantiation did not produce a using decl\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 1466, __PRETTY_FUNCTION__)) | ||||
1465 | isa<UnresolvedUsingTypenameDecl>(Inst)) &&(((isa<UsingDecl>(Inst) || isa<UnresolvedUsingValueDecl >(Inst) || isa<UnresolvedUsingTypenameDecl>(Inst)) && "instantiation did not produce a using decl") ? static_cast< void> (0) : __assert_fail ("(isa<UsingDecl>(Inst) || isa<UnresolvedUsingValueDecl>(Inst) || isa<UnresolvedUsingTypenameDecl>(Inst)) && \"instantiation did not produce a using decl\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 1466, __PRETTY_FUNCTION__)) | ||||
1466 | "instantiation did not produce a using decl")(((isa<UsingDecl>(Inst) || isa<UnresolvedUsingValueDecl >(Inst) || isa<UnresolvedUsingTypenameDecl>(Inst)) && "instantiation did not produce a using decl") ? static_cast< void> (0) : __assert_fail ("(isa<UsingDecl>(Inst) || isa<UnresolvedUsingValueDecl>(Inst) || isa<UnresolvedUsingTypenameDecl>(Inst)) && \"instantiation did not produce a using decl\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 1466, __PRETTY_FUNCTION__)); | ||||
1467 | assert(!InstantiatedFromUsingDecl[Inst] && "pattern already exists")((!InstantiatedFromUsingDecl[Inst] && "pattern already exists" ) ? static_cast<void> (0) : __assert_fail ("!InstantiatedFromUsingDecl[Inst] && \"pattern already exists\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 1467, __PRETTY_FUNCTION__)); | ||||
1468 | InstantiatedFromUsingDecl[Inst] = Pattern; | ||||
1469 | } | ||||
1470 | |||||
1471 | UsingShadowDecl * | ||||
1472 | ASTContext::getInstantiatedFromUsingShadowDecl(UsingShadowDecl *Inst) { | ||||
1473 | llvm::DenseMap<UsingShadowDecl*, UsingShadowDecl*>::const_iterator Pos | ||||
1474 | = InstantiatedFromUsingShadowDecl.find(Inst); | ||||
1475 | if (Pos == InstantiatedFromUsingShadowDecl.end()) | ||||
1476 | return nullptr; | ||||
1477 | |||||
1478 | return Pos->second; | ||||
1479 | } | ||||
1480 | |||||
1481 | void | ||||
1482 | ASTContext::setInstantiatedFromUsingShadowDecl(UsingShadowDecl *Inst, | ||||
1483 | UsingShadowDecl *Pattern) { | ||||
1484 | assert(!InstantiatedFromUsingShadowDecl[Inst] && "pattern already exists")((!InstantiatedFromUsingShadowDecl[Inst] && "pattern already exists" ) ? static_cast<void> (0) : __assert_fail ("!InstantiatedFromUsingShadowDecl[Inst] && \"pattern already exists\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 1484, __PRETTY_FUNCTION__)); | ||||
1485 | InstantiatedFromUsingShadowDecl[Inst] = Pattern; | ||||
1486 | } | ||||
1487 | |||||
1488 | FieldDecl *ASTContext::getInstantiatedFromUnnamedFieldDecl(FieldDecl *Field) { | ||||
1489 | llvm::DenseMap<FieldDecl *, FieldDecl *>::iterator Pos | ||||
1490 | = InstantiatedFromUnnamedFieldDecl.find(Field); | ||||
1491 | if (Pos == InstantiatedFromUnnamedFieldDecl.end()) | ||||
1492 | return nullptr; | ||||
1493 | |||||
1494 | return Pos->second; | ||||
1495 | } | ||||
1496 | |||||
1497 | void ASTContext::setInstantiatedFromUnnamedFieldDecl(FieldDecl *Inst, | ||||
1498 | FieldDecl *Tmpl) { | ||||
1499 | assert(!Inst->getDeclName() && "Instantiated field decl is not unnamed")((!Inst->getDeclName() && "Instantiated field decl is not unnamed" ) ? static_cast<void> (0) : __assert_fail ("!Inst->getDeclName() && \"Instantiated field decl is not unnamed\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 1499, __PRETTY_FUNCTION__)); | ||||
1500 | assert(!Tmpl->getDeclName() && "Template field decl is not unnamed")((!Tmpl->getDeclName() && "Template field decl is not unnamed" ) ? static_cast<void> (0) : __assert_fail ("!Tmpl->getDeclName() && \"Template field decl is not unnamed\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 1500, __PRETTY_FUNCTION__)); | ||||
1501 | assert(!InstantiatedFromUnnamedFieldDecl[Inst] &&((!InstantiatedFromUnnamedFieldDecl[Inst] && "Already noted what unnamed field was instantiated from" ) ? static_cast<void> (0) : __assert_fail ("!InstantiatedFromUnnamedFieldDecl[Inst] && \"Already noted what unnamed field was instantiated from\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 1502, __PRETTY_FUNCTION__)) | ||||
1502 | "Already noted what unnamed field was instantiated from")((!InstantiatedFromUnnamedFieldDecl[Inst] && "Already noted what unnamed field was instantiated from" ) ? static_cast<void> (0) : __assert_fail ("!InstantiatedFromUnnamedFieldDecl[Inst] && \"Already noted what unnamed field was instantiated from\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 1502, __PRETTY_FUNCTION__)); | ||||
1503 | |||||
1504 | InstantiatedFromUnnamedFieldDecl[Inst] = Tmpl; | ||||
1505 | } | ||||
1506 | |||||
1507 | ASTContext::overridden_cxx_method_iterator | ||||
1508 | ASTContext::overridden_methods_begin(const CXXMethodDecl *Method) const { | ||||
1509 | return overridden_methods(Method).begin(); | ||||
1510 | } | ||||
1511 | |||||
1512 | ASTContext::overridden_cxx_method_iterator | ||||
1513 | ASTContext::overridden_methods_end(const CXXMethodDecl *Method) const { | ||||
1514 | return overridden_methods(Method).end(); | ||||
1515 | } | ||||
1516 | |||||
1517 | unsigned | ||||
1518 | ASTContext::overridden_methods_size(const CXXMethodDecl *Method) const { | ||||
1519 | auto Range = overridden_methods(Method); | ||||
1520 | return Range.end() - Range.begin(); | ||||
1521 | } | ||||
1522 | |||||
1523 | ASTContext::overridden_method_range | ||||
1524 | ASTContext::overridden_methods(const CXXMethodDecl *Method) const { | ||||
1525 | llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector>::const_iterator Pos = | ||||
1526 | OverriddenMethods.find(Method->getCanonicalDecl()); | ||||
1527 | if (Pos == OverriddenMethods.end()) | ||||
1528 | return overridden_method_range(nullptr, nullptr); | ||||
1529 | return overridden_method_range(Pos->second.begin(), Pos->second.end()); | ||||
1530 | } | ||||
1531 | |||||
1532 | void ASTContext::addOverriddenMethod(const CXXMethodDecl *Method, | ||||
1533 | const CXXMethodDecl *Overridden) { | ||||
1534 | assert(Method->isCanonicalDecl() && Overridden->isCanonicalDecl())((Method->isCanonicalDecl() && Overridden->isCanonicalDecl ()) ? static_cast<void> (0) : __assert_fail ("Method->isCanonicalDecl() && Overridden->isCanonicalDecl()" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 1534, __PRETTY_FUNCTION__)); | ||||
1535 | OverriddenMethods[Method].push_back(Overridden); | ||||
1536 | } | ||||
1537 | |||||
1538 | void ASTContext::getOverriddenMethods( | ||||
1539 | const NamedDecl *D, | ||||
1540 | SmallVectorImpl<const NamedDecl *> &Overridden) const { | ||||
1541 | assert(D)((D) ? static_cast<void> (0) : __assert_fail ("D", "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 1541, __PRETTY_FUNCTION__)); | ||||
1542 | |||||
1543 | if (const auto *CXXMethod = dyn_cast<CXXMethodDecl>(D)) { | ||||
1544 | Overridden.append(overridden_methods_begin(CXXMethod), | ||||
1545 | overridden_methods_end(CXXMethod)); | ||||
1546 | return; | ||||
1547 | } | ||||
1548 | |||||
1549 | const auto *Method = dyn_cast<ObjCMethodDecl>(D); | ||||
1550 | if (!Method) | ||||
1551 | return; | ||||
1552 | |||||
1553 | SmallVector<const ObjCMethodDecl *, 8> OverDecls; | ||||
1554 | Method->getOverriddenMethods(OverDecls); | ||||
1555 | Overridden.append(OverDecls.begin(), OverDecls.end()); | ||||
1556 | } | ||||
1557 | |||||
1558 | void ASTContext::addedLocalImportDecl(ImportDecl *Import) { | ||||
1559 | assert(!Import->NextLocalImport && "Import declaration already in the chain")((!Import->NextLocalImport && "Import declaration already in the chain" ) ? static_cast<void> (0) : __assert_fail ("!Import->NextLocalImport && \"Import declaration already in the chain\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 1559, __PRETTY_FUNCTION__)); | ||||
1560 | assert(!Import->isFromASTFile() && "Non-local import declaration")((!Import->isFromASTFile() && "Non-local import declaration" ) ? static_cast<void> (0) : __assert_fail ("!Import->isFromASTFile() && \"Non-local import declaration\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 1560, __PRETTY_FUNCTION__)); | ||||
1561 | if (!FirstLocalImport) { | ||||
1562 | FirstLocalImport = Import; | ||||
1563 | LastLocalImport = Import; | ||||
1564 | return; | ||||
1565 | } | ||||
1566 | |||||
1567 | LastLocalImport->NextLocalImport = Import; | ||||
1568 | LastLocalImport = Import; | ||||
1569 | } | ||||
1570 | |||||
1571 | //===----------------------------------------------------------------------===// | ||||
1572 | // Type Sizing and Analysis | ||||
1573 | //===----------------------------------------------------------------------===// | ||||
1574 | |||||
1575 | /// getFloatTypeSemantics - Return the APFloat 'semantics' for the specified | ||||
1576 | /// scalar floating point type. | ||||
1577 | const llvm::fltSemantics &ASTContext::getFloatTypeSemantics(QualType T) const { | ||||
1578 | const auto *BT = T->getAs<BuiltinType>(); | ||||
1579 | assert(BT && "Not a floating point type!")((BT && "Not a floating point type!") ? static_cast< void> (0) : __assert_fail ("BT && \"Not a floating point type!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 1579, __PRETTY_FUNCTION__)); | ||||
1580 | switch (BT->getKind()) { | ||||
1581 | default: llvm_unreachable("Not a floating point type!")::llvm::llvm_unreachable_internal("Not a floating point type!" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 1581); | ||||
1582 | case BuiltinType::Float16: | ||||
1583 | case BuiltinType::Half: | ||||
1584 | return Target->getHalfFormat(); | ||||
1585 | case BuiltinType::Float: return Target->getFloatFormat(); | ||||
1586 | case BuiltinType::Double: return Target->getDoubleFormat(); | ||||
1587 | case BuiltinType::LongDouble: | ||||
1588 | if (getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice) | ||||
1589 | return AuxTarget->getLongDoubleFormat(); | ||||
1590 | return Target->getLongDoubleFormat(); | ||||
1591 | case BuiltinType::Float128: | ||||
1592 | if (getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice) | ||||
1593 | return AuxTarget->getFloat128Format(); | ||||
1594 | return Target->getFloat128Format(); | ||||
1595 | } | ||||
1596 | } | ||||
1597 | |||||
1598 | CharUnits ASTContext::getDeclAlign(const Decl *D, bool ForAlignof) const { | ||||
1599 | unsigned Align = Target->getCharWidth(); | ||||
1600 | |||||
1601 | bool UseAlignAttrOnly = false; | ||||
1602 | if (unsigned AlignFromAttr = D->getMaxAlignment()) { | ||||
1603 | Align = AlignFromAttr; | ||||
1604 | |||||
1605 | // __attribute__((aligned)) can increase or decrease alignment | ||||
1606 | // *except* on a struct or struct member, where it only increases | ||||
1607 | // alignment unless 'packed' is also specified. | ||||
1608 | // | ||||
1609 | // It is an error for alignas to decrease alignment, so we can | ||||
1610 | // ignore that possibility; Sema should diagnose it. | ||||
1611 | if (isa<FieldDecl>(D)) { | ||||
1612 | UseAlignAttrOnly = D->hasAttr<PackedAttr>() || | ||||
1613 | cast<FieldDecl>(D)->getParent()->hasAttr<PackedAttr>(); | ||||
1614 | } else { | ||||
1615 | UseAlignAttrOnly = true; | ||||
1616 | } | ||||
1617 | } | ||||
1618 | else if (isa<FieldDecl>(D)) | ||||
1619 | UseAlignAttrOnly = | ||||
1620 | D->hasAttr<PackedAttr>() || | ||||
1621 | cast<FieldDecl>(D)->getParent()->hasAttr<PackedAttr>(); | ||||
1622 | |||||
1623 | // If we're using the align attribute only, just ignore everything | ||||
1624 | // else about the declaration and its type. | ||||
1625 | if (UseAlignAttrOnly) { | ||||
1626 | // do nothing | ||||
1627 | } else if (const auto *VD = dyn_cast<ValueDecl>(D)) { | ||||
1628 | QualType T = VD->getType(); | ||||
1629 | if (const auto *RT = T->getAs<ReferenceType>()) { | ||||
1630 | if (ForAlignof) | ||||
1631 | T = RT->getPointeeType(); | ||||
1632 | else | ||||
1633 | T = getPointerType(RT->getPointeeType()); | ||||
1634 | } | ||||
1635 | QualType BaseT = getBaseElementType(T); | ||||
1636 | if (T->isFunctionType()) | ||||
1637 | Align = getTypeInfoImpl(T.getTypePtr()).Align; | ||||
1638 | else if (!BaseT->isIncompleteType()) { | ||||
1639 | // Adjust alignments of declarations with array type by the | ||||
1640 | // large-array alignment on the target. | ||||
1641 | if (const ArrayType *arrayType = getAsArrayType(T)) { | ||||
1642 | unsigned MinWidth = Target->getLargeArrayMinWidth(); | ||||
1643 | if (!ForAlignof && MinWidth) { | ||||
1644 | if (isa<VariableArrayType>(arrayType)) | ||||
1645 | Align = std::max(Align, Target->getLargeArrayAlign()); | ||||
1646 | else if (isa<ConstantArrayType>(arrayType) && | ||||
1647 | MinWidth <= getTypeSize(cast<ConstantArrayType>(arrayType))) | ||||
1648 | Align = std::max(Align, Target->getLargeArrayAlign()); | ||||
1649 | } | ||||
1650 | } | ||||
1651 | Align = std::max(Align, getPreferredTypeAlign(T.getTypePtr())); | ||||
1652 | if (BaseT.getQualifiers().hasUnaligned()) | ||||
1653 | Align = Target->getCharWidth(); | ||||
1654 | if (const auto *VD = dyn_cast<VarDecl>(D)) { | ||||
1655 | if (VD->hasGlobalStorage() && !ForAlignof) { | ||||
1656 | uint64_t TypeSize = getTypeSize(T.getTypePtr()); | ||||
1657 | Align = std::max(Align, getTargetInfo().getMinGlobalAlign(TypeSize)); | ||||
1658 | } | ||||
1659 | } | ||||
1660 | } | ||||
1661 | |||||
1662 | // Fields can be subject to extra alignment constraints, like if | ||||
1663 | // the field is packed, the struct is packed, or the struct has a | ||||
1664 | // a max-field-alignment constraint (#pragma pack). So calculate | ||||
1665 | // the actual alignment of the field within the struct, and then | ||||
1666 | // (as we're expected to) constrain that by the alignment of the type. | ||||
1667 | if (const auto *Field = dyn_cast<FieldDecl>(VD)) { | ||||
1668 | const RecordDecl *Parent = Field->getParent(); | ||||
1669 | // We can only produce a sensible answer if the record is valid. | ||||
1670 | if (!Parent->isInvalidDecl()) { | ||||
1671 | const ASTRecordLayout &Layout = getASTRecordLayout(Parent); | ||||
1672 | |||||
1673 | // Start with the record's overall alignment. | ||||
1674 | unsigned FieldAlign = toBits(Layout.getAlignment()); | ||||
1675 | |||||
1676 | // Use the GCD of that and the offset within the record. | ||||
1677 | uint64_t Offset = Layout.getFieldOffset(Field->getFieldIndex()); | ||||
1678 | if (Offset > 0) { | ||||
1679 | // Alignment is always a power of 2, so the GCD will be a power of 2, | ||||
1680 | // which means we get to do this crazy thing instead of Euclid's. | ||||
1681 | uint64_t LowBitOfOffset = Offset & (~Offset + 1); | ||||
1682 | if (LowBitOfOffset < FieldAlign) | ||||
1683 | FieldAlign = static_cast<unsigned>(LowBitOfOffset); | ||||
1684 | } | ||||
1685 | |||||
1686 | Align = std::min(Align, FieldAlign); | ||||
1687 | } | ||||
1688 | } | ||||
1689 | } | ||||
1690 | |||||
1691 | return toCharUnitsFromBits(Align); | ||||
1692 | } | ||||
1693 | |||||
1694 | // getTypeInfoDataSizeInChars - Return the size of a type, in | ||||
1695 | // chars. If the type is a record, its data size is returned. This is | ||||
1696 | // the size of the memcpy that's performed when assigning this type | ||||
1697 | // using a trivial copy/move assignment operator. | ||||
1698 | std::pair<CharUnits, CharUnits> | ||||
1699 | ASTContext::getTypeInfoDataSizeInChars(QualType T) const { | ||||
1700 | std::pair<CharUnits, CharUnits> sizeAndAlign = getTypeInfoInChars(T); | ||||
1701 | |||||
1702 | // In C++, objects can sometimes be allocated into the tail padding | ||||
1703 | // of a base-class subobject. We decide whether that's possible | ||||
1704 | // during class layout, so here we can just trust the layout results. | ||||
1705 | if (getLangOpts().CPlusPlus) { | ||||
1706 | if (const auto *RT = T->getAs<RecordType>()) { | ||||
1707 | const ASTRecordLayout &layout = getASTRecordLayout(RT->getDecl()); | ||||
1708 | sizeAndAlign.first = layout.getDataSize(); | ||||
1709 | } | ||||
1710 | } | ||||
1711 | |||||
1712 | return sizeAndAlign; | ||||
1713 | } | ||||
1714 | |||||
1715 | /// getConstantArrayInfoInChars - Performing the computation in CharUnits | ||||
1716 | /// instead of in bits prevents overflowing the uint64_t for some large arrays. | ||||
1717 | std::pair<CharUnits, CharUnits> | ||||
1718 | static getConstantArrayInfoInChars(const ASTContext &Context, | ||||
1719 | const ConstantArrayType *CAT) { | ||||
1720 | std::pair<CharUnits, CharUnits> EltInfo = | ||||
1721 | Context.getTypeInfoInChars(CAT->getElementType()); | ||||
1722 | uint64_t Size = CAT->getSize().getZExtValue(); | ||||
1723 | assert((Size == 0 || static_cast<uint64_t>(EltInfo.first.getQuantity()) <=(((Size == 0 || static_cast<uint64_t>(EltInfo.first.getQuantity ()) <= (uint64_t)(-1)/Size) && "Overflow in array type char size evaluation" ) ? static_cast<void> (0) : __assert_fail ("(Size == 0 || static_cast<uint64_t>(EltInfo.first.getQuantity()) <= (uint64_t)(-1)/Size) && \"Overflow in array type char size evaluation\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 1725, __PRETTY_FUNCTION__)) | ||||
1724 | (uint64_t)(-1)/Size) &&(((Size == 0 || static_cast<uint64_t>(EltInfo.first.getQuantity ()) <= (uint64_t)(-1)/Size) && "Overflow in array type char size evaluation" ) ? static_cast<void> (0) : __assert_fail ("(Size == 0 || static_cast<uint64_t>(EltInfo.first.getQuantity()) <= (uint64_t)(-1)/Size) && \"Overflow in array type char size evaluation\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 1725, __PRETTY_FUNCTION__)) | ||||
1725 | "Overflow in array type char size evaluation")(((Size == 0 || static_cast<uint64_t>(EltInfo.first.getQuantity ()) <= (uint64_t)(-1)/Size) && "Overflow in array type char size evaluation" ) ? static_cast<void> (0) : __assert_fail ("(Size == 0 || static_cast<uint64_t>(EltInfo.first.getQuantity()) <= (uint64_t)(-1)/Size) && \"Overflow in array type char size evaluation\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 1725, __PRETTY_FUNCTION__)); | ||||
1726 | uint64_t Width = EltInfo.first.getQuantity() * Size; | ||||
1727 | unsigned Align = EltInfo.second.getQuantity(); | ||||
1728 | if (!Context.getTargetInfo().getCXXABI().isMicrosoft() || | ||||
1729 | Context.getTargetInfo().getPointerWidth(0) == 64) | ||||
1730 | Width = llvm::alignTo(Width, Align); | ||||
1731 | return std::make_pair(CharUnits::fromQuantity(Width), | ||||
1732 | CharUnits::fromQuantity(Align)); | ||||
1733 | } | ||||
1734 | |||||
1735 | std::pair<CharUnits, CharUnits> | ||||
1736 | ASTContext::getTypeInfoInChars(const Type *T) const { | ||||
1737 | if (const auto *CAT = dyn_cast<ConstantArrayType>(T)) | ||||
1738 | return getConstantArrayInfoInChars(*this, CAT); | ||||
1739 | TypeInfo Info = getTypeInfo(T); | ||||
1740 | return std::make_pair(toCharUnitsFromBits(Info.Width), | ||||
1741 | toCharUnitsFromBits(Info.Align)); | ||||
1742 | } | ||||
1743 | |||||
1744 | std::pair<CharUnits, CharUnits> | ||||
1745 | ASTContext::getTypeInfoInChars(QualType T) const { | ||||
1746 | return getTypeInfoInChars(T.getTypePtr()); | ||||
1747 | } | ||||
1748 | |||||
1749 | bool ASTContext::isAlignmentRequired(const Type *T) const { | ||||
1750 | return getTypeInfo(T).AlignIsRequired; | ||||
1751 | } | ||||
1752 | |||||
1753 | bool ASTContext::isAlignmentRequired(QualType T) const { | ||||
1754 | return isAlignmentRequired(T.getTypePtr()); | ||||
1755 | } | ||||
1756 | |||||
1757 | unsigned ASTContext::getTypeAlignIfKnown(QualType T) const { | ||||
1758 | // An alignment on a typedef overrides anything else. | ||||
1759 | if (const auto *TT = T->getAs<TypedefType>()) | ||||
1760 | if (unsigned Align = TT->getDecl()->getMaxAlignment()) | ||||
1761 | return Align; | ||||
1762 | |||||
1763 | // If we have an (array of) complete type, we're done. | ||||
1764 | T = getBaseElementType(T); | ||||
1765 | if (!T->isIncompleteType()) | ||||
1766 | return getTypeAlign(T); | ||||
1767 | |||||
1768 | // If we had an array type, its element type might be a typedef | ||||
1769 | // type with an alignment attribute. | ||||
1770 | if (const auto *TT = T->getAs<TypedefType>()) | ||||
1771 | if (unsigned Align = TT->getDecl()->getMaxAlignment()) | ||||
1772 | return Align; | ||||
1773 | |||||
1774 | // Otherwise, see if the declaration of the type had an attribute. | ||||
1775 | if (const auto *TT = T->getAs<TagType>()) | ||||
1776 | return TT->getDecl()->getMaxAlignment(); | ||||
1777 | |||||
1778 | return 0; | ||||
1779 | } | ||||
1780 | |||||
1781 | TypeInfo ASTContext::getTypeInfo(const Type *T) const { | ||||
1782 | TypeInfoMap::iterator I = MemoizedTypeInfo.find(T); | ||||
1783 | if (I != MemoizedTypeInfo.end()) | ||||
1784 | return I->second; | ||||
1785 | |||||
1786 | // This call can invalidate MemoizedTypeInfo[T], so we need a second lookup. | ||||
1787 | TypeInfo TI = getTypeInfoImpl(T); | ||||
1788 | MemoizedTypeInfo[T] = TI; | ||||
1789 | return TI; | ||||
1790 | } | ||||
1791 | |||||
1792 | /// getTypeInfoImpl - Return the size of the specified type, in bits. This | ||||
1793 | /// method does not work on incomplete types. | ||||
1794 | /// | ||||
1795 | /// FIXME: Pointers into different addr spaces could have different sizes and | ||||
1796 | /// alignment requirements: getPointerInfo should take an AddrSpace, this | ||||
1797 | /// should take a QualType, &c. | ||||
1798 | TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const { | ||||
1799 | uint64_t Width = 0; | ||||
1800 | unsigned Align = 8; | ||||
1801 | bool AlignIsRequired = false; | ||||
1802 | unsigned AS = 0; | ||||
1803 | switch (T->getTypeClass()) { | ||||
1804 | #define TYPE(Class, Base) | ||||
1805 | #define ABSTRACT_TYPE(Class, Base) | ||||
1806 | #define NON_CANONICAL_TYPE(Class, Base) | ||||
1807 | #define DEPENDENT_TYPE(Class, Base) case Type::Class: | ||||
1808 | #define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) \ | ||||
1809 | case Type::Class: \ | ||||
1810 | assert(!T->isDependentType() && "should not see dependent types here")((!T->isDependentType() && "should not see dependent types here" ) ? static_cast<void> (0) : __assert_fail ("!T->isDependentType() && \"should not see dependent types here\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 1810, __PRETTY_FUNCTION__)); \ | ||||
1811 | return getTypeInfo(cast<Class##Type>(T)->desugar().getTypePtr()); | ||||
1812 | #include "clang/AST/TypeNodes.inc" | ||||
1813 | llvm_unreachable("Should not see dependent types")::llvm::llvm_unreachable_internal("Should not see dependent types" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 1813); | ||||
1814 | |||||
1815 | case Type::FunctionNoProto: | ||||
1816 | case Type::FunctionProto: | ||||
1817 | // GCC extension: alignof(function) = 32 bits | ||||
1818 | Width = 0; | ||||
1819 | Align = 32; | ||||
1820 | break; | ||||
1821 | |||||
1822 | case Type::IncompleteArray: | ||||
1823 | case Type::VariableArray: | ||||
1824 | Width = 0; | ||||
1825 | Align = getTypeAlign(cast<ArrayType>(T)->getElementType()); | ||||
1826 | break; | ||||
1827 | |||||
1828 | case Type::ConstantArray: { | ||||
1829 | const auto *CAT = cast<ConstantArrayType>(T); | ||||
1830 | |||||
1831 | TypeInfo EltInfo = getTypeInfo(CAT->getElementType()); | ||||
1832 | uint64_t Size = CAT->getSize().getZExtValue(); | ||||
1833 | assert((Size == 0 || EltInfo.Width <= (uint64_t)(-1) / Size) &&(((Size == 0 || EltInfo.Width <= (uint64_t)(-1) / Size) && "Overflow in array type bit size evaluation") ? static_cast< void> (0) : __assert_fail ("(Size == 0 || EltInfo.Width <= (uint64_t)(-1) / Size) && \"Overflow in array type bit size evaluation\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 1834, __PRETTY_FUNCTION__)) | ||||
1834 | "Overflow in array type bit size evaluation")(((Size == 0 || EltInfo.Width <= (uint64_t)(-1) / Size) && "Overflow in array type bit size evaluation") ? static_cast< void> (0) : __assert_fail ("(Size == 0 || EltInfo.Width <= (uint64_t)(-1) / Size) && \"Overflow in array type bit size evaluation\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 1834, __PRETTY_FUNCTION__)); | ||||
1835 | Width = EltInfo.Width * Size; | ||||
1836 | Align = EltInfo.Align; | ||||
1837 | if (!getTargetInfo().getCXXABI().isMicrosoft() || | ||||
1838 | getTargetInfo().getPointerWidth(0) == 64) | ||||
1839 | Width = llvm::alignTo(Width, Align); | ||||
1840 | break; | ||||
1841 | } | ||||
1842 | case Type::ExtVector: | ||||
1843 | case Type::Vector: { | ||||
1844 | const auto *VT = cast<VectorType>(T); | ||||
1845 | TypeInfo EltInfo = getTypeInfo(VT->getElementType()); | ||||
1846 | Width = EltInfo.Width * VT->getNumElements(); | ||||
1847 | Align = Width; | ||||
1848 | // If the alignment is not a power of 2, round up to the next power of 2. | ||||
1849 | // This happens for non-power-of-2 length vectors. | ||||
1850 | if (Align & (Align-1)) { | ||||
1851 | Align = llvm::NextPowerOf2(Align); | ||||
1852 | Width = llvm::alignTo(Width, Align); | ||||
1853 | } | ||||
1854 | // Adjust the alignment based on the target max. | ||||
1855 | uint64_t TargetVectorAlign = Target->getMaxVectorAlign(); | ||||
1856 | if (TargetVectorAlign && TargetVectorAlign < Align) | ||||
1857 | Align = TargetVectorAlign; | ||||
1858 | break; | ||||
1859 | } | ||||
1860 | |||||
1861 | case Type::Builtin: | ||||
1862 | switch (cast<BuiltinType>(T)->getKind()) { | ||||
1863 | default: llvm_unreachable("Unknown builtin type!")::llvm::llvm_unreachable_internal("Unknown builtin type!", "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 1863); | ||||
1864 | case BuiltinType::Void: | ||||
1865 | // GCC extension: alignof(void) = 8 bits. | ||||
1866 | Width = 0; | ||||
1867 | Align = 8; | ||||
1868 | break; | ||||
1869 | case BuiltinType::Bool: | ||||
1870 | Width = Target->getBoolWidth(); | ||||
1871 | Align = Target->getBoolAlign(); | ||||
1872 | break; | ||||
1873 | case BuiltinType::Char_S: | ||||
1874 | case BuiltinType::Char_U: | ||||
1875 | case BuiltinType::UChar: | ||||
1876 | case BuiltinType::SChar: | ||||
1877 | case BuiltinType::Char8: | ||||
1878 | Width = Target->getCharWidth(); | ||||
1879 | Align = Target->getCharAlign(); | ||||
1880 | break; | ||||
1881 | case BuiltinType::WChar_S: | ||||
1882 | case BuiltinType::WChar_U: | ||||
1883 | Width = Target->getWCharWidth(); | ||||
1884 | Align = Target->getWCharAlign(); | ||||
1885 | break; | ||||
1886 | case BuiltinType::Char16: | ||||
1887 | Width = Target->getChar16Width(); | ||||
1888 | Align = Target->getChar16Align(); | ||||
1889 | break; | ||||
1890 | case BuiltinType::Char32: | ||||
1891 | Width = Target->getChar32Width(); | ||||
1892 | Align = Target->getChar32Align(); | ||||
1893 | break; | ||||
1894 | case BuiltinType::UShort: | ||||
1895 | case BuiltinType::Short: | ||||
1896 | Width = Target->getShortWidth(); | ||||
1897 | Align = Target->getShortAlign(); | ||||
1898 | break; | ||||
1899 | case BuiltinType::UInt: | ||||
1900 | case BuiltinType::Int: | ||||
1901 | Width = Target->getIntWidth(); | ||||
1902 | Align = Target->getIntAlign(); | ||||
1903 | break; | ||||
1904 | case BuiltinType::ULong: | ||||
1905 | case BuiltinType::Long: | ||||
1906 | Width = Target->getLongWidth(); | ||||
1907 | Align = Target->getLongAlign(); | ||||
1908 | break; | ||||
1909 | case BuiltinType::ULongLong: | ||||
1910 | case BuiltinType::LongLong: | ||||
1911 | Width = Target->getLongLongWidth(); | ||||
1912 | Align = Target->getLongLongAlign(); | ||||
1913 | break; | ||||
1914 | case BuiltinType::Int128: | ||||
1915 | case BuiltinType::UInt128: | ||||
1916 | Width = 128; | ||||
1917 | Align = 128; // int128_t is 128-bit aligned on all targets. | ||||
1918 | break; | ||||
1919 | case BuiltinType::ShortAccum: | ||||
1920 | case BuiltinType::UShortAccum: | ||||
1921 | case BuiltinType::SatShortAccum: | ||||
1922 | case BuiltinType::SatUShortAccum: | ||||
1923 | Width = Target->getShortAccumWidth(); | ||||
1924 | Align = Target->getShortAccumAlign(); | ||||
1925 | break; | ||||
1926 | case BuiltinType::Accum: | ||||
1927 | case BuiltinType::UAccum: | ||||
1928 | case BuiltinType::SatAccum: | ||||
1929 | case BuiltinType::SatUAccum: | ||||
1930 | Width = Target->getAccumWidth(); | ||||
1931 | Align = Target->getAccumAlign(); | ||||
1932 | break; | ||||
1933 | case BuiltinType::LongAccum: | ||||
1934 | case BuiltinType::ULongAccum: | ||||
1935 | case BuiltinType::SatLongAccum: | ||||
1936 | case BuiltinType::SatULongAccum: | ||||
1937 | Width = Target->getLongAccumWidth(); | ||||
1938 | Align = Target->getLongAccumAlign(); | ||||
1939 | break; | ||||
1940 | case BuiltinType::ShortFract: | ||||
1941 | case BuiltinType::UShortFract: | ||||
1942 | case BuiltinType::SatShortFract: | ||||
1943 | case BuiltinType::SatUShortFract: | ||||
1944 | Width = Target->getShortFractWidth(); | ||||
1945 | Align = Target->getShortFractAlign(); | ||||
1946 | break; | ||||
1947 | case BuiltinType::Fract: | ||||
1948 | case BuiltinType::UFract: | ||||
1949 | case BuiltinType::SatFract: | ||||
1950 | case BuiltinType::SatUFract: | ||||
1951 | Width = Target->getFractWidth(); | ||||
1952 | Align = Target->getFractAlign(); | ||||
1953 | break; | ||||
1954 | case BuiltinType::LongFract: | ||||
1955 | case BuiltinType::ULongFract: | ||||
1956 | case BuiltinType::SatLongFract: | ||||
1957 | case BuiltinType::SatULongFract: | ||||
1958 | Width = Target->getLongFractWidth(); | ||||
1959 | Align = Target->getLongFractAlign(); | ||||
1960 | break; | ||||
1961 | case BuiltinType::Float16: | ||||
1962 | case BuiltinType::Half: | ||||
1963 | if (Target->hasFloat16Type() || !getLangOpts().OpenMP || | ||||
1964 | !getLangOpts().OpenMPIsDevice) { | ||||
1965 | Width = Target->getHalfWidth(); | ||||
1966 | Align = Target->getHalfAlign(); | ||||
1967 | } else { | ||||
1968 | assert(getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice &&((getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && "Expected OpenMP device compilation.") ? static_cast <void> (0) : __assert_fail ("getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && \"Expected OpenMP device compilation.\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 1969, __PRETTY_FUNCTION__)) | ||||
1969 | "Expected OpenMP device compilation.")((getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && "Expected OpenMP device compilation.") ? static_cast <void> (0) : __assert_fail ("getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && \"Expected OpenMP device compilation.\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 1969, __PRETTY_FUNCTION__)); | ||||
1970 | Width = AuxTarget->getHalfWidth(); | ||||
1971 | Align = AuxTarget->getHalfAlign(); | ||||
1972 | } | ||||
1973 | break; | ||||
1974 | case BuiltinType::Float: | ||||
1975 | Width = Target->getFloatWidth(); | ||||
1976 | Align = Target->getFloatAlign(); | ||||
1977 | break; | ||||
1978 | case BuiltinType::Double: | ||||
1979 | Width = Target->getDoubleWidth(); | ||||
1980 | Align = Target->getDoubleAlign(); | ||||
1981 | break; | ||||
1982 | case BuiltinType::LongDouble: | ||||
1983 | if (getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && | ||||
1984 | (Target->getLongDoubleWidth() != AuxTarget->getLongDoubleWidth() || | ||||
1985 | Target->getLongDoubleAlign() != AuxTarget->getLongDoubleAlign())) { | ||||
1986 | Width = AuxTarget->getLongDoubleWidth(); | ||||
1987 | Align = AuxTarget->getLongDoubleAlign(); | ||||
1988 | } else { | ||||
1989 | Width = Target->getLongDoubleWidth(); | ||||
1990 | Align = Target->getLongDoubleAlign(); | ||||
1991 | } | ||||
1992 | break; | ||||
1993 | case BuiltinType::Float128: | ||||
1994 | if (Target->hasFloat128Type() || !getLangOpts().OpenMP || | ||||
1995 | !getLangOpts().OpenMPIsDevice) { | ||||
1996 | Width = Target->getFloat128Width(); | ||||
1997 | Align = Target->getFloat128Align(); | ||||
1998 | } else { | ||||
1999 | assert(getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice &&((getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && "Expected OpenMP device compilation.") ? static_cast <void> (0) : __assert_fail ("getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && \"Expected OpenMP device compilation.\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 2000, __PRETTY_FUNCTION__)) | ||||
2000 | "Expected OpenMP device compilation.")((getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && "Expected OpenMP device compilation.") ? static_cast <void> (0) : __assert_fail ("getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && \"Expected OpenMP device compilation.\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 2000, __PRETTY_FUNCTION__)); | ||||
2001 | Width = AuxTarget->getFloat128Width(); | ||||
2002 | Align = AuxTarget->getFloat128Align(); | ||||
2003 | } | ||||
2004 | break; | ||||
2005 | case BuiltinType::NullPtr: | ||||
2006 | Width = Target->getPointerWidth(0); // C++ 3.9.1p11: sizeof(nullptr_t) | ||||
2007 | Align = Target->getPointerAlign(0); // == sizeof(void*) | ||||
2008 | break; | ||||
2009 | case BuiltinType::ObjCId: | ||||
2010 | case BuiltinType::ObjCClass: | ||||
2011 | case BuiltinType::ObjCSel: | ||||
2012 | Width = Target->getPointerWidth(0); | ||||
2013 | Align = Target->getPointerAlign(0); | ||||
2014 | break; | ||||
2015 | case BuiltinType::OCLSampler: | ||||
2016 | case BuiltinType::OCLEvent: | ||||
2017 | case BuiltinType::OCLClkEvent: | ||||
2018 | case BuiltinType::OCLQueue: | ||||
2019 | case BuiltinType::OCLReserveID: | ||||
2020 | #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ | ||||
2021 | case BuiltinType::Id: | ||||
2022 | #include "clang/Basic/OpenCLImageTypes.def" | ||||
2023 | #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \ | ||||
2024 | case BuiltinType::Id: | ||||
2025 | #include "clang/Basic/OpenCLExtensionTypes.def" | ||||
2026 | AS = getTargetAddressSpace( | ||||
2027 | Target->getOpenCLTypeAddrSpace(getOpenCLTypeKind(T))); | ||||
2028 | Width = Target->getPointerWidth(AS); | ||||
2029 | Align = Target->getPointerAlign(AS); | ||||
2030 | break; | ||||
2031 | // The SVE types are effectively target-specific. The length of an | ||||
2032 | // SVE_VECTOR_TYPE is only known at runtime, but it is always a multiple | ||||
2033 | // of 128 bits. There is one predicate bit for each vector byte, so the | ||||
2034 | // length of an SVE_PREDICATE_TYPE is always a multiple of 16 bits. | ||||
2035 | // | ||||
2036 | // Because the length is only known at runtime, we use a dummy value | ||||
2037 | // of 0 for the static length. The alignment values are those defined | ||||
2038 | // by the Procedure Call Standard for the Arm Architecture. | ||||
2039 | #define SVE_VECTOR_TYPE(Name, Id, SingletonId, ElKind, ElBits, IsSigned, IsFP)\ | ||||
2040 | case BuiltinType::Id: \ | ||||
2041 | Width = 0; \ | ||||
2042 | Align = 128; \ | ||||
2043 | break; | ||||
2044 | #define SVE_PREDICATE_TYPE(Name, Id, SingletonId, ElKind) \ | ||||
2045 | case BuiltinType::Id: \ | ||||
2046 | Width = 0; \ | ||||
2047 | Align = 16; \ | ||||
2048 | break; | ||||
2049 | #include "clang/Basic/AArch64SVEACLETypes.def" | ||||
2050 | } | ||||
2051 | break; | ||||
2052 | case Type::ObjCObjectPointer: | ||||
2053 | Width = Target->getPointerWidth(0); | ||||
2054 | Align = Target->getPointerAlign(0); | ||||
2055 | break; | ||||
2056 | case Type::BlockPointer: | ||||
2057 | AS = getTargetAddressSpace(cast<BlockPointerType>(T)->getPointeeType()); | ||||
2058 | Width = Target->getPointerWidth(AS); | ||||
2059 | Align = Target->getPointerAlign(AS); | ||||
2060 | break; | ||||
2061 | case Type::LValueReference: | ||||
2062 | case Type::RValueReference: | ||||
2063 | // alignof and sizeof should never enter this code path here, so we go | ||||
2064 | // the pointer route. | ||||
2065 | AS = getTargetAddressSpace(cast<ReferenceType>(T)->getPointeeType()); | ||||
2066 | Width = Target->getPointerWidth(AS); | ||||
2067 | Align = Target->getPointerAlign(AS); | ||||
2068 | break; | ||||
2069 | case Type::Pointer: | ||||
2070 | AS = getTargetAddressSpace(cast<PointerType>(T)->getPointeeType()); | ||||
2071 | Width = Target->getPointerWidth(AS); | ||||
2072 | Align = Target->getPointerAlign(AS); | ||||
2073 | break; | ||||
2074 | case Type::MemberPointer: { | ||||
2075 | const auto *MPT = cast<MemberPointerType>(T); | ||||
2076 | CXXABI::MemberPointerInfo MPI = ABI->getMemberPointerInfo(MPT); | ||||
2077 | Width = MPI.Width; | ||||
2078 | Align = MPI.Align; | ||||
2079 | break; | ||||
2080 | } | ||||
2081 | case Type::Complex: { | ||||
2082 | // Complex types have the same alignment as their elements, but twice the | ||||
2083 | // size. | ||||
2084 | TypeInfo EltInfo = getTypeInfo(cast<ComplexType>(T)->getElementType()); | ||||
2085 | Width = EltInfo.Width * 2; | ||||
2086 | Align = EltInfo.Align; | ||||
2087 | break; | ||||
2088 | } | ||||
2089 | case Type::ObjCObject: | ||||
2090 | return getTypeInfo(cast<ObjCObjectType>(T)->getBaseType().getTypePtr()); | ||||
2091 | case Type::Adjusted: | ||||
2092 | case Type::Decayed: | ||||
2093 | return getTypeInfo(cast<AdjustedType>(T)->getAdjustedType().getTypePtr()); | ||||
2094 | case Type::ObjCInterface: { | ||||
2095 | const auto *ObjCI = cast<ObjCInterfaceType>(T); | ||||
2096 | const ASTRecordLayout &Layout = getASTObjCInterfaceLayout(ObjCI->getDecl()); | ||||
2097 | Width = toBits(Layout.getSize()); | ||||
2098 | Align = toBits(Layout.getAlignment()); | ||||
2099 | break; | ||||
2100 | } | ||||
2101 | case Type::Record: | ||||
2102 | case Type::Enum: { | ||||
2103 | const auto *TT = cast<TagType>(T); | ||||
2104 | |||||
2105 | if (TT->getDecl()->isInvalidDecl()) { | ||||
2106 | Width = 8; | ||||
2107 | Align = 8; | ||||
2108 | break; | ||||
2109 | } | ||||
2110 | |||||
2111 | if (const auto *ET = dyn_cast<EnumType>(TT)) { | ||||
2112 | const EnumDecl *ED = ET->getDecl(); | ||||
2113 | TypeInfo Info = | ||||
2114 | getTypeInfo(ED->getIntegerType()->getUnqualifiedDesugaredType()); | ||||
2115 | if (unsigned AttrAlign = ED->getMaxAlignment()) { | ||||
2116 | Info.Align = AttrAlign; | ||||
2117 | Info.AlignIsRequired = true; | ||||
2118 | } | ||||
2119 | return Info; | ||||
2120 | } | ||||
2121 | |||||
2122 | const auto *RT = cast<RecordType>(TT); | ||||
2123 | const RecordDecl *RD = RT->getDecl(); | ||||
2124 | const ASTRecordLayout &Layout = getASTRecordLayout(RD); | ||||
2125 | Width = toBits(Layout.getSize()); | ||||
2126 | Align = toBits(Layout.getAlignment()); | ||||
2127 | AlignIsRequired = RD->hasAttr<AlignedAttr>(); | ||||
2128 | break; | ||||
2129 | } | ||||
2130 | |||||
2131 | case Type::SubstTemplateTypeParm: | ||||
2132 | return getTypeInfo(cast<SubstTemplateTypeParmType>(T)-> | ||||
2133 | getReplacementType().getTypePtr()); | ||||
2134 | |||||
2135 | case Type::Auto: | ||||
2136 | case Type::DeducedTemplateSpecialization: { | ||||
2137 | const auto *A = cast<DeducedType>(T); | ||||
2138 | assert(!A->getDeducedType().isNull() &&((!A->getDeducedType().isNull() && "cannot request the size of an undeduced or dependent auto type" ) ? static_cast<void> (0) : __assert_fail ("!A->getDeducedType().isNull() && \"cannot request the size of an undeduced or dependent auto type\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 2139, __PRETTY_FUNCTION__)) | ||||
2139 | "cannot request the size of an undeduced or dependent auto type")((!A->getDeducedType().isNull() && "cannot request the size of an undeduced or dependent auto type" ) ? static_cast<void> (0) : __assert_fail ("!A->getDeducedType().isNull() && \"cannot request the size of an undeduced or dependent auto type\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 2139, __PRETTY_FUNCTION__)); | ||||
2140 | return getTypeInfo(A->getDeducedType().getTypePtr()); | ||||
2141 | } | ||||
2142 | |||||
2143 | case Type::Paren: | ||||
2144 | return getTypeInfo(cast<ParenType>(T)->getInnerType().getTypePtr()); | ||||
2145 | |||||
2146 | case Type::MacroQualified: | ||||
2147 | return getTypeInfo( | ||||
2148 | cast<MacroQualifiedType>(T)->getUnderlyingType().getTypePtr()); | ||||
2149 | |||||
2150 | case Type::ObjCTypeParam: | ||||
2151 | return getTypeInfo(cast<ObjCTypeParamType>(T)->desugar().getTypePtr()); | ||||
2152 | |||||
2153 | case Type::Typedef: { | ||||
2154 | const TypedefNameDecl *Typedef = cast<TypedefType>(T)->getDecl(); | ||||
2155 | TypeInfo Info = getTypeInfo(Typedef->getUnderlyingType().getTypePtr()); | ||||
2156 | // If the typedef has an aligned attribute on it, it overrides any computed | ||||
2157 | // alignment we have. This violates the GCC documentation (which says that | ||||
2158 | // attribute(aligned) can only round up) but matches its implementation. | ||||
2159 | if (unsigned AttrAlign = Typedef->getMaxAlignment()) { | ||||
2160 | Align = AttrAlign; | ||||
2161 | AlignIsRequired = true; | ||||
2162 | } else { | ||||
2163 | Align = Info.Align; | ||||
2164 | AlignIsRequired = Info.AlignIsRequired; | ||||
2165 | } | ||||
2166 | Width = Info.Width; | ||||
2167 | break; | ||||
2168 | } | ||||
2169 | |||||
2170 | case Type::Elaborated: | ||||
2171 | return getTypeInfo(cast<ElaboratedType>(T)->getNamedType().getTypePtr()); | ||||
2172 | |||||
2173 | case Type::Attributed: | ||||
2174 | return getTypeInfo( | ||||
2175 | cast<AttributedType>(T)->getEquivalentType().getTypePtr()); | ||||
2176 | |||||
2177 | case Type::Atomic: { | ||||
2178 | // Start with the base type information. | ||||
2179 | TypeInfo Info = getTypeInfo(cast<AtomicType>(T)->getValueType()); | ||||
2180 | Width = Info.Width; | ||||
2181 | Align = Info.Align; | ||||
2182 | |||||
2183 | if (!Width) { | ||||
2184 | // An otherwise zero-sized type should still generate an | ||||
2185 | // atomic operation. | ||||
2186 | Width = Target->getCharWidth(); | ||||
2187 | assert(Align)((Align) ? static_cast<void> (0) : __assert_fail ("Align" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 2187, __PRETTY_FUNCTION__)); | ||||
2188 | } else if (Width <= Target->getMaxAtomicPromoteWidth()) { | ||||
2189 | // If the size of the type doesn't exceed the platform's max | ||||
2190 | // atomic promotion width, make the size and alignment more | ||||
2191 | // favorable to atomic operations: | ||||
2192 | |||||
2193 | // Round the size up to a power of 2. | ||||
2194 | if (!llvm::isPowerOf2_64(Width)) | ||||
2195 | Width = llvm::NextPowerOf2(Width); | ||||
2196 | |||||
2197 | // Set the alignment equal to the size. | ||||
2198 | Align = static_cast<unsigned>(Width); | ||||
2199 | } | ||||
2200 | } | ||||
2201 | break; | ||||
2202 | |||||
2203 | case Type::Pipe: | ||||
2204 | Width = Target->getPointerWidth(getTargetAddressSpace(LangAS::opencl_global)); | ||||
2205 | Align = Target->getPointerAlign(getTargetAddressSpace(LangAS::opencl_global)); | ||||
2206 | break; | ||||
2207 | } | ||||
2208 | |||||
2209 | assert(llvm::isPowerOf2_32(Align) && "Alignment must be power of 2")((llvm::isPowerOf2_32(Align) && "Alignment must be power of 2" ) ? static_cast<void> (0) : __assert_fail ("llvm::isPowerOf2_32(Align) && \"Alignment must be power of 2\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 2209, __PRETTY_FUNCTION__)); | ||||
2210 | return TypeInfo(Width, Align, AlignIsRequired); | ||||
2211 | } | ||||
2212 | |||||
2213 | unsigned ASTContext::getTypeUnadjustedAlign(const Type *T) const { | ||||
2214 | UnadjustedAlignMap::iterator I = MemoizedUnadjustedAlign.find(T); | ||||
2215 | if (I != MemoizedUnadjustedAlign.end()) | ||||
2216 | return I->second; | ||||
2217 | |||||
2218 | unsigned UnadjustedAlign; | ||||
2219 | if (const auto *RT = T->getAs<RecordType>()) { | ||||
2220 | const RecordDecl *RD = RT->getDecl(); | ||||
2221 | const ASTRecordLayout &Layout = getASTRecordLayout(RD); | ||||
2222 | UnadjustedAlign = toBits(Layout.getUnadjustedAlignment()); | ||||
2223 | } else if (const auto *ObjCI = T->getAs<ObjCInterfaceType>()) { | ||||
2224 | const ASTRecordLayout &Layout = getASTObjCInterfaceLayout(ObjCI->getDecl()); | ||||
2225 | UnadjustedAlign = toBits(Layout.getUnadjustedAlignment()); | ||||
2226 | } else { | ||||
2227 | UnadjustedAlign = getTypeAlign(T->getUnqualifiedDesugaredType()); | ||||
2228 | } | ||||
2229 | |||||
2230 | MemoizedUnadjustedAlign[T] = UnadjustedAlign; | ||||
2231 | return UnadjustedAlign; | ||||
2232 | } | ||||
2233 | |||||
2234 | unsigned ASTContext::getOpenMPDefaultSimdAlign(QualType T) const { | ||||
2235 | unsigned SimdAlign = getTargetInfo().getSimdDefaultAlign(); | ||||
2236 | // Target ppc64 with QPX: simd default alignment for pointer to double is 32. | ||||
2237 | if ((getTargetInfo().getTriple().getArch() == llvm::Triple::ppc64 || | ||||
2238 | getTargetInfo().getTriple().getArch() == llvm::Triple::ppc64le) && | ||||
2239 | getTargetInfo().getABI() == "elfv1-qpx" && | ||||
2240 | T->isSpecificBuiltinType(BuiltinType::Double)) | ||||
2241 | SimdAlign = 256; | ||||
2242 | return SimdAlign; | ||||
2243 | } | ||||
2244 | |||||
2245 | /// toCharUnitsFromBits - Convert a size in bits to a size in characters. | ||||
2246 | CharUnits ASTContext::toCharUnitsFromBits(int64_t BitSize) const { | ||||
2247 | return CharUnits::fromQuantity(BitSize / getCharWidth()); | ||||
2248 | } | ||||
2249 | |||||
2250 | /// toBits - Convert a size in characters to a size in characters. | ||||
2251 | int64_t ASTContext::toBits(CharUnits CharSize) const { | ||||
2252 | return CharSize.getQuantity() * getCharWidth(); | ||||
2253 | } | ||||
2254 | |||||
2255 | /// getTypeSizeInChars - Return the size of the specified type, in characters. | ||||
2256 | /// This method does not work on incomplete types. | ||||
2257 | CharUnits ASTContext::getTypeSizeInChars(QualType T) const { | ||||
2258 | return getTypeInfoInChars(T).first; | ||||
2259 | } | ||||
2260 | CharUnits ASTContext::getTypeSizeInChars(const Type *T) const { | ||||
2261 | return getTypeInfoInChars(T).first; | ||||
2262 | } | ||||
2263 | |||||
2264 | /// getTypeAlignInChars - Return the ABI-specified alignment of a type, in | ||||
2265 | /// characters. This method does not work on incomplete types. | ||||
2266 | CharUnits ASTContext::getTypeAlignInChars(QualType T) const { | ||||
2267 | return toCharUnitsFromBits(getTypeAlign(T)); | ||||
2268 | } | ||||
2269 | CharUnits ASTContext::getTypeAlignInChars(const Type *T) const { | ||||
2270 | return toCharUnitsFromBits(getTypeAlign(T)); | ||||
2271 | } | ||||
2272 | |||||
2273 | /// getTypeUnadjustedAlignInChars - Return the ABI-specified alignment of a | ||||
2274 | /// type, in characters, before alignment adustments. This method does | ||||
2275 | /// not work on incomplete types. | ||||
2276 | CharUnits ASTContext::getTypeUnadjustedAlignInChars(QualType T) const { | ||||
2277 | return toCharUnitsFromBits(getTypeUnadjustedAlign(T)); | ||||
2278 | } | ||||
2279 | CharUnits ASTContext::getTypeUnadjustedAlignInChars(const Type *T) const { | ||||
2280 | return toCharUnitsFromBits(getTypeUnadjustedAlign(T)); | ||||
2281 | } | ||||
2282 | |||||
2283 | /// getPreferredTypeAlign - Return the "preferred" alignment of the specified | ||||
2284 | /// type for the current target in bits. This can be different than the ABI | ||||
2285 | /// alignment in cases where it is beneficial for performance to overalign | ||||
2286 | /// a data type. | ||||
2287 | unsigned ASTContext::getPreferredTypeAlign(const Type *T) const { | ||||
2288 | TypeInfo TI = getTypeInfo(T); | ||||
2289 | unsigned ABIAlign = TI.Align; | ||||
2290 | |||||
2291 | T = T->getBaseElementTypeUnsafe(); | ||||
2292 | |||||
2293 | // The preferred alignment of member pointers is that of a pointer. | ||||
2294 | if (T->isMemberPointerType()) | ||||
2295 | return getPreferredTypeAlign(getPointerDiffType().getTypePtr()); | ||||
2296 | |||||
2297 | if (!Target->allowsLargerPreferedTypeAlignment()) | ||||
2298 | return ABIAlign; | ||||
2299 | |||||
2300 | // Double and long long should be naturally aligned if possible. | ||||
2301 | if (const auto *CT = T->getAs<ComplexType>()) | ||||
2302 | T = CT->getElementType().getTypePtr(); | ||||
2303 | if (const auto *ET = T->getAs<EnumType>()) | ||||
2304 | T = ET->getDecl()->getIntegerType().getTypePtr(); | ||||
2305 | if (T->isSpecificBuiltinType(BuiltinType::Double) || | ||||
2306 | T->isSpecificBuiltinType(BuiltinType::LongLong) || | ||||
2307 | T->isSpecificBuiltinType(BuiltinType::ULongLong)) | ||||
2308 | // Don't increase the alignment if an alignment attribute was specified on a | ||||
2309 | // typedef declaration. | ||||
2310 | if (!TI.AlignIsRequired) | ||||
2311 | return std::max(ABIAlign, (unsigned)getTypeSize(T)); | ||||
2312 | |||||
2313 | return ABIAlign; | ||||
2314 | } | ||||
2315 | |||||
2316 | /// getTargetDefaultAlignForAttributeAligned - Return the default alignment | ||||
2317 | /// for __attribute__((aligned)) on this target, to be used if no alignment | ||||
2318 | /// value is specified. | ||||
2319 | unsigned ASTContext::getTargetDefaultAlignForAttributeAligned() const { | ||||
2320 | return getTargetInfo().getDefaultAlignForAttributeAligned(); | ||||
2321 | } | ||||
2322 | |||||
2323 | /// getAlignOfGlobalVar - Return the alignment in bits that should be given | ||||
2324 | /// to a global variable of the specified type. | ||||
2325 | unsigned ASTContext::getAlignOfGlobalVar(QualType T) const { | ||||
2326 | uint64_t TypeSize = getTypeSize(T.getTypePtr()); | ||||
2327 | return std::max(getTypeAlign(T), getTargetInfo().getMinGlobalAlign(TypeSize)); | ||||
2328 | } | ||||
2329 | |||||
2330 | /// getAlignOfGlobalVarInChars - Return the alignment in characters that | ||||
2331 | /// should be given to a global variable of the specified type. | ||||
2332 | CharUnits ASTContext::getAlignOfGlobalVarInChars(QualType T) const { | ||||
2333 | return toCharUnitsFromBits(getAlignOfGlobalVar(T)); | ||||
2334 | } | ||||
2335 | |||||
2336 | CharUnits ASTContext::getOffsetOfBaseWithVBPtr(const CXXRecordDecl *RD) const { | ||||
2337 | CharUnits Offset = CharUnits::Zero(); | ||||
2338 | const ASTRecordLayout *Layout = &getASTRecordLayout(RD); | ||||
2339 | while (const CXXRecordDecl *Base = Layout->getBaseSharingVBPtr()) { | ||||
2340 | Offset += Layout->getBaseClassOffset(Base); | ||||
2341 | Layout = &getASTRecordLayout(Base); | ||||
2342 | } | ||||
2343 | return Offset; | ||||
2344 | } | ||||
2345 | |||||
2346 | /// DeepCollectObjCIvars - | ||||
2347 | /// This routine first collects all declared, but not synthesized, ivars in | ||||
2348 | /// super class and then collects all ivars, including those synthesized for | ||||
2349 | /// current class. This routine is used for implementation of current class | ||||
2350 | /// when all ivars, declared and synthesized are known. | ||||
2351 | void ASTContext::DeepCollectObjCIvars(const ObjCInterfaceDecl *OI, | ||||
2352 | bool leafClass, | ||||
2353 | SmallVectorImpl<const ObjCIvarDecl*> &Ivars) const { | ||||
2354 | if (const ObjCInterfaceDecl *SuperClass = OI->getSuperClass()) | ||||
2355 | DeepCollectObjCIvars(SuperClass, false, Ivars); | ||||
2356 | if (!leafClass) { | ||||
2357 | for (const auto *I : OI->ivars()) | ||||
2358 | Ivars.push_back(I); | ||||
2359 | } else { | ||||
2360 | auto *IDecl = const_cast<ObjCInterfaceDecl *>(OI); | ||||
2361 | for (const ObjCIvarDecl *Iv = IDecl->all_declared_ivar_begin(); Iv; | ||||
2362 | Iv= Iv->getNextIvar()) | ||||
2363 | Ivars.push_back(Iv); | ||||
2364 | } | ||||
2365 | } | ||||
2366 | |||||
2367 | /// CollectInheritedProtocols - Collect all protocols in current class and | ||||
2368 | /// those inherited by it. | ||||
2369 | void ASTContext::CollectInheritedProtocols(const Decl *CDecl, | ||||
2370 | llvm::SmallPtrSet<ObjCProtocolDecl*, 8> &Protocols) { | ||||
2371 | if (const auto *OI = dyn_cast<ObjCInterfaceDecl>(CDecl)) { | ||||
2372 | // We can use protocol_iterator here instead of | ||||
2373 | // all_referenced_protocol_iterator since we are walking all categories. | ||||
2374 | for (auto *Proto : OI->all_referenced_protocols()) { | ||||
2375 | CollectInheritedProtocols(Proto, Protocols); | ||||
2376 | } | ||||
2377 | |||||
2378 | // Categories of this Interface. | ||||
2379 | for (const auto *Cat : OI->visible_categories()) | ||||
2380 | CollectInheritedProtocols(Cat, Protocols); | ||||
2381 | |||||
2382 | if (ObjCInterfaceDecl *SD = OI->getSuperClass()) | ||||
2383 | while (SD) { | ||||
2384 | CollectInheritedProtocols(SD, Protocols); | ||||
2385 | SD = SD->getSuperClass(); | ||||
2386 | } | ||||
2387 | } else if (const auto *OC = dyn_cast<ObjCCategoryDecl>(CDecl)) { | ||||
2388 | for (auto *Proto : OC->protocols()) { | ||||
2389 | CollectInheritedProtocols(Proto, Protocols); | ||||
2390 | } | ||||
2391 | } else if (const auto *OP = dyn_cast<ObjCProtocolDecl>(CDecl)) { | ||||
2392 | // Insert the protocol. | ||||
2393 | if (!Protocols.insert( | ||||
2394 | const_cast<ObjCProtocolDecl *>(OP->getCanonicalDecl())).second) | ||||
2395 | return; | ||||
2396 | |||||
2397 | for (auto *Proto : OP->protocols()) | ||||
2398 | CollectInheritedProtocols(Proto, Protocols); | ||||
2399 | } | ||||
2400 | } | ||||
2401 | |||||
2402 | static bool unionHasUniqueObjectRepresentations(const ASTContext &Context, | ||||
2403 | const RecordDecl *RD) { | ||||
2404 | assert(RD->isUnion() && "Must be union type")((RD->isUnion() && "Must be union type") ? static_cast <void> (0) : __assert_fail ("RD->isUnion() && \"Must be union type\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 2404, __PRETTY_FUNCTION__)); | ||||
2405 | CharUnits UnionSize = Context.getTypeSizeInChars(RD->getTypeForDecl()); | ||||
2406 | |||||
2407 | for (const auto *Field : RD->fields()) { | ||||
2408 | if (!Context.hasUniqueObjectRepresentations(Field->getType())) | ||||
2409 | return false; | ||||
2410 | CharUnits FieldSize = Context.getTypeSizeInChars(Field->getType()); | ||||
2411 | if (FieldSize != UnionSize) | ||||
2412 | return false; | ||||
2413 | } | ||||
2414 | return !RD->field_empty(); | ||||
2415 | } | ||||
2416 | |||||
2417 | static bool isStructEmpty(QualType Ty) { | ||||
2418 | const RecordDecl *RD = Ty->castAs<RecordType>()->getDecl(); | ||||
2419 | |||||
2420 | if (!RD->field_empty()) | ||||
2421 | return false; | ||||
2422 | |||||
2423 | if (const auto *ClassDecl = dyn_cast<CXXRecordDecl>(RD)) | ||||
2424 | return ClassDecl->isEmpty(); | ||||
2425 | |||||
2426 | return true; | ||||
2427 | } | ||||
2428 | |||||
2429 | static llvm::Optional<int64_t> | ||||
2430 | structHasUniqueObjectRepresentations(const ASTContext &Context, | ||||
2431 | const RecordDecl *RD) { | ||||
2432 | assert(!RD->isUnion() && "Must be struct/class type")((!RD->isUnion() && "Must be struct/class type") ? static_cast<void> (0) : __assert_fail ("!RD->isUnion() && \"Must be struct/class type\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 2432, __PRETTY_FUNCTION__)); | ||||
2433 | const auto &Layout = Context.getASTRecordLayout(RD); | ||||
2434 | |||||
2435 | int64_t CurOffsetInBits = 0; | ||||
2436 | if (const auto *ClassDecl = dyn_cast<CXXRecordDecl>(RD)) { | ||||
2437 | if (ClassDecl->isDynamicClass()) | ||||
2438 | return llvm::None; | ||||
2439 | |||||
2440 | SmallVector<std::pair<QualType, int64_t>, 4> Bases; | ||||
2441 | for (const auto Base : ClassDecl->bases()) { | ||||
2442 | // Empty types can be inherited from, and non-empty types can potentially | ||||
2443 | // have tail padding, so just make sure there isn't an error. | ||||
2444 | if (!isStructEmpty(Base.getType())) { | ||||
2445 | llvm::Optional<int64_t> Size = structHasUniqueObjectRepresentations( | ||||
2446 | Context, Base.getType()->castAs<RecordType>()->getDecl()); | ||||
2447 | if (!Size) | ||||
2448 | return llvm::None; | ||||
2449 | Bases.emplace_back(Base.getType(), Size.getValue()); | ||||
2450 | } | ||||
2451 | } | ||||
2452 | |||||
2453 | llvm::sort(Bases, [&](const std::pair<QualType, int64_t> &L, | ||||
2454 | const std::pair<QualType, int64_t> &R) { | ||||
2455 | return Layout.getBaseClassOffset(L.first->getAsCXXRecordDecl()) < | ||||
2456 | Layout.getBaseClassOffset(R.first->getAsCXXRecordDecl()); | ||||
2457 | }); | ||||
2458 | |||||
2459 | for (const auto Base : Bases) { | ||||
2460 | int64_t BaseOffset = Context.toBits( | ||||
2461 | Layout.getBaseClassOffset(Base.first->getAsCXXRecordDecl())); | ||||
2462 | int64_t BaseSize = Base.second; | ||||
2463 | if (BaseOffset != CurOffsetInBits) | ||||
2464 | return llvm::None; | ||||
2465 | CurOffsetInBits = BaseOffset + BaseSize; | ||||
2466 | } | ||||
2467 | } | ||||
2468 | |||||
2469 | for (const auto *Field : RD->fields()) { | ||||
2470 | if (!Field->getType()->isReferenceType() && | ||||
2471 | !Context.hasUniqueObjectRepresentations(Field->getType())) | ||||
2472 | return llvm::None; | ||||
2473 | |||||
2474 | int64_t FieldSizeInBits = | ||||
2475 | Context.toBits(Context.getTypeSizeInChars(Field->getType())); | ||||
2476 | if (Field->isBitField()) { | ||||
2477 | int64_t BitfieldSize = Field->getBitWidthValue(Context); | ||||
2478 | |||||
2479 | if (BitfieldSize > FieldSizeInBits) | ||||
2480 | return llvm::None; | ||||
2481 | FieldSizeInBits = BitfieldSize; | ||||
2482 | } | ||||
2483 | |||||
2484 | int64_t FieldOffsetInBits = Context.getFieldOffset(Field); | ||||
2485 | |||||
2486 | if (FieldOffsetInBits != CurOffsetInBits) | ||||
2487 | return llvm::None; | ||||
2488 | |||||
2489 | CurOffsetInBits = FieldSizeInBits + FieldOffsetInBits; | ||||
2490 | } | ||||
2491 | |||||
2492 | return CurOffsetInBits; | ||||
2493 | } | ||||
2494 | |||||
2495 | bool ASTContext::hasUniqueObjectRepresentations(QualType Ty) const { | ||||
2496 | // C++17 [meta.unary.prop]: | ||||
2497 | // The predicate condition for a template specialization | ||||
2498 | // has_unique_object_representations<T> shall be | ||||
2499 | // satisfied if and only if: | ||||
2500 | // (9.1) - T is trivially copyable, and | ||||
2501 | // (9.2) - any two objects of type T with the same value have the same | ||||
2502 | // object representation, where two objects | ||||
2503 | // of array or non-union class type are considered to have the same value | ||||
2504 | // if their respective sequences of | ||||
2505 | // direct subobjects have the same values, and two objects of union type | ||||
2506 | // are considered to have the same | ||||
2507 | // value if they have the same active member and the corresponding members | ||||
2508 | // have the same value. | ||||
2509 | // The set of scalar types for which this condition holds is | ||||
2510 | // implementation-defined. [ Note: If a type has padding | ||||
2511 | // bits, the condition does not hold; otherwise, the condition holds true | ||||
2512 | // for unsigned integral types. -- end note ] | ||||
2513 | assert(!Ty.isNull() && "Null QualType sent to unique object rep check")((!Ty.isNull() && "Null QualType sent to unique object rep check" ) ? static_cast<void> (0) : __assert_fail ("!Ty.isNull() && \"Null QualType sent to unique object rep check\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 2513, __PRETTY_FUNCTION__)); | ||||
2514 | |||||
2515 | // Arrays are unique only if their element type is unique. | ||||
2516 | if (Ty->isArrayType()) | ||||
2517 | return hasUniqueObjectRepresentations(getBaseElementType(Ty)); | ||||
2518 | |||||
2519 | // (9.1) - T is trivially copyable... | ||||
2520 | if (!Ty.isTriviallyCopyableType(*this)) | ||||
2521 | return false; | ||||
2522 | |||||
2523 | // All integrals and enums are unique. | ||||
2524 | if (Ty->isIntegralOrEnumerationType()) | ||||
2525 | return true; | ||||
2526 | |||||
2527 | // All other pointers are unique. | ||||
2528 | if (Ty->isPointerType()) | ||||
2529 | return true; | ||||
2530 | |||||
2531 | if (Ty->isMemberPointerType()) { | ||||
2532 | const auto *MPT = Ty->getAs<MemberPointerType>(); | ||||
2533 | return !ABI->getMemberPointerInfo(MPT).HasPadding; | ||||
2534 | } | ||||
2535 | |||||
2536 | if (Ty->isRecordType()) { | ||||
2537 | const RecordDecl *Record = Ty->castAs<RecordType>()->getDecl(); | ||||
2538 | |||||
2539 | if (Record->isInvalidDecl()) | ||||
2540 | return false; | ||||
2541 | |||||
2542 | if (Record->isUnion()) | ||||
2543 | return unionHasUniqueObjectRepresentations(*this, Record); | ||||
2544 | |||||
2545 | Optional<int64_t> StructSize = | ||||
2546 | structHasUniqueObjectRepresentations(*this, Record); | ||||
2547 | |||||
2548 | return StructSize && | ||||
2549 | StructSize.getValue() == static_cast<int64_t>(getTypeSize(Ty)); | ||||
2550 | } | ||||
2551 | |||||
2552 | // FIXME: More cases to handle here (list by rsmith): | ||||
2553 | // vectors (careful about, eg, vector of 3 foo) | ||||
2554 | // _Complex int and friends | ||||
2555 | // _Atomic T | ||||
2556 | // Obj-C block pointers | ||||
2557 | // Obj-C object pointers | ||||
2558 | // and perhaps OpenCL's various builtin types (pipe, sampler_t, event_t, | ||||
2559 | // clk_event_t, queue_t, reserve_id_t) | ||||
2560 | // There're also Obj-C class types and the Obj-C selector type, but I think it | ||||
2561 | // makes sense for those to return false here. | ||||
2562 | |||||
2563 | return false; | ||||
2564 | } | ||||
2565 | |||||
2566 | unsigned ASTContext::CountNonClassIvars(const ObjCInterfaceDecl *OI) const { | ||||
2567 | unsigned count = 0; | ||||
2568 | // Count ivars declared in class extension. | ||||
2569 | for (const auto *Ext : OI->known_extensions()) | ||||
2570 | count += Ext->ivar_size(); | ||||
2571 | |||||
2572 | // Count ivar defined in this class's implementation. This | ||||
2573 | // includes synthesized ivars. | ||||
2574 | if (ObjCImplementationDecl *ImplDecl = OI->getImplementation()) | ||||
2575 | count += ImplDecl->ivar_size(); | ||||
2576 | |||||
2577 | return count; | ||||
2578 | } | ||||
2579 | |||||
2580 | bool ASTContext::isSentinelNullExpr(const Expr *E) { | ||||
2581 | if (!E) | ||||
2582 | return false; | ||||
2583 | |||||
2584 | // nullptr_t is always treated as null. | ||||
2585 | if (E->getType()->isNullPtrType()) return true; | ||||
2586 | |||||
2587 | if (E->getType()->isAnyPointerType() && | ||||
2588 | E->IgnoreParenCasts()->isNullPointerConstant(*this, | ||||
2589 | Expr::NPC_ValueDependentIsNull)) | ||||
2590 | return true; | ||||
2591 | |||||
2592 | // Unfortunately, __null has type 'int'. | ||||
2593 | if (isa<GNUNullExpr>(E)) return true; | ||||
2594 | |||||
2595 | return false; | ||||
2596 | } | ||||
2597 | |||||
2598 | /// Get the implementation of ObjCInterfaceDecl, or nullptr if none | ||||
2599 | /// exists. | ||||
2600 | ObjCImplementationDecl *ASTContext::getObjCImplementation(ObjCInterfaceDecl *D) { | ||||
2601 | llvm::DenseMap<ObjCContainerDecl*, ObjCImplDecl*>::iterator | ||||
2602 | I = ObjCImpls.find(D); | ||||
2603 | if (I != ObjCImpls.end()) | ||||
2604 | return cast<ObjCImplementationDecl>(I->second); | ||||
2605 | return nullptr; | ||||
2606 | } | ||||
2607 | |||||
2608 | /// Get the implementation of ObjCCategoryDecl, or nullptr if none | ||||
2609 | /// exists. | ||||
2610 | ObjCCategoryImplDecl *ASTContext::getObjCImplementation(ObjCCategoryDecl *D) { | ||||
2611 | llvm::DenseMap<ObjCContainerDecl*, ObjCImplDecl*>::iterator | ||||
2612 | I = ObjCImpls.find(D); | ||||
2613 | if (I != ObjCImpls.end()) | ||||
2614 | return cast<ObjCCategoryImplDecl>(I->second); | ||||
2615 | return nullptr; | ||||
2616 | } | ||||
2617 | |||||
2618 | /// Set the implementation of ObjCInterfaceDecl. | ||||
2619 | void ASTContext::setObjCImplementation(ObjCInterfaceDecl *IFaceD, | ||||
2620 | ObjCImplementationDecl *ImplD) { | ||||
2621 | assert(IFaceD && ImplD && "Passed null params")((IFaceD && ImplD && "Passed null params") ? static_cast <void> (0) : __assert_fail ("IFaceD && ImplD && \"Passed null params\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 2621, __PRETTY_FUNCTION__)); | ||||
2622 | ObjCImpls[IFaceD] = ImplD; | ||||
2623 | } | ||||
2624 | |||||
2625 | /// Set the implementation of ObjCCategoryDecl. | ||||
2626 | void ASTContext::setObjCImplementation(ObjCCategoryDecl *CatD, | ||||
2627 | ObjCCategoryImplDecl *ImplD) { | ||||
2628 | assert(CatD && ImplD && "Passed null params")((CatD && ImplD && "Passed null params") ? static_cast <void> (0) : __assert_fail ("CatD && ImplD && \"Passed null params\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 2628, __PRETTY_FUNCTION__)); | ||||
2629 | ObjCImpls[CatD] = ImplD; | ||||
2630 | } | ||||
2631 | |||||
2632 | const ObjCMethodDecl * | ||||
2633 | ASTContext::getObjCMethodRedeclaration(const ObjCMethodDecl *MD) const { | ||||
2634 | return ObjCMethodRedecls.lookup(MD); | ||||
2635 | } | ||||
2636 | |||||
2637 | void ASTContext::setObjCMethodRedeclaration(const ObjCMethodDecl *MD, | ||||
2638 | const ObjCMethodDecl *Redecl) { | ||||
2639 | assert(!getObjCMethodRedeclaration(MD) && "MD already has a redeclaration")((!getObjCMethodRedeclaration(MD) && "MD already has a redeclaration" ) ? static_cast<void> (0) : __assert_fail ("!getObjCMethodRedeclaration(MD) && \"MD already has a redeclaration\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 2639, __PRETTY_FUNCTION__)); | ||||
2640 | ObjCMethodRedecls[MD] = Redecl; | ||||
2641 | } | ||||
2642 | |||||
2643 | const ObjCInterfaceDecl *ASTContext::getObjContainingInterface( | ||||
2644 | const NamedDecl *ND) const { | ||||
2645 | if (const auto *ID = dyn_cast<ObjCInterfaceDecl>(ND->getDeclContext())) | ||||
2646 | return ID; | ||||
2647 | if (const auto *CD = dyn_cast<ObjCCategoryDecl>(ND->getDeclContext())) | ||||
2648 | return CD->getClassInterface(); | ||||
2649 | if (const auto *IMD = dyn_cast<ObjCImplDecl>(ND->getDeclContext())) | ||||
2650 | return IMD->getClassInterface(); | ||||
2651 | |||||
2652 | return nullptr; | ||||
2653 | } | ||||
2654 | |||||
2655 | /// Get the copy initialization expression of VarDecl, or nullptr if | ||||
2656 | /// none exists. | ||||
2657 | ASTContext::BlockVarCopyInit | ||||
2658 | ASTContext::getBlockVarCopyInit(const VarDecl*VD) const { | ||||
2659 | assert(VD && "Passed null params")((VD && "Passed null params") ? static_cast<void> (0) : __assert_fail ("VD && \"Passed null params\"", "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 2659, __PRETTY_FUNCTION__)); | ||||
2660 | assert(VD->hasAttr<BlocksAttr>() &&((VD->hasAttr<BlocksAttr>() && "getBlockVarCopyInits - not __block var" ) ? static_cast<void> (0) : __assert_fail ("VD->hasAttr<BlocksAttr>() && \"getBlockVarCopyInits - not __block var\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 2661, __PRETTY_FUNCTION__)) | ||||
2661 | "getBlockVarCopyInits - not __block var")((VD->hasAttr<BlocksAttr>() && "getBlockVarCopyInits - not __block var" ) ? static_cast<void> (0) : __assert_fail ("VD->hasAttr<BlocksAttr>() && \"getBlockVarCopyInits - not __block var\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 2661, __PRETTY_FUNCTION__)); | ||||
2662 | auto I = BlockVarCopyInits.find(VD); | ||||
2663 | if (I != BlockVarCopyInits.end()) | ||||
2664 | return I->second; | ||||
2665 | return {nullptr, false}; | ||||
2666 | } | ||||
2667 | |||||
2668 | /// Set the copy initialization expression of a block var decl. | ||||
2669 | void ASTContext::setBlockVarCopyInit(const VarDecl*VD, Expr *CopyExpr, | ||||
2670 | bool CanThrow) { | ||||
2671 | assert(VD && CopyExpr && "Passed null params")((VD && CopyExpr && "Passed null params") ? static_cast <void> (0) : __assert_fail ("VD && CopyExpr && \"Passed null params\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 2671, __PRETTY_FUNCTION__)); | ||||
2672 | assert(VD->hasAttr<BlocksAttr>() &&((VD->hasAttr<BlocksAttr>() && "setBlockVarCopyInits - not __block var" ) ? static_cast<void> (0) : __assert_fail ("VD->hasAttr<BlocksAttr>() && \"setBlockVarCopyInits - not __block var\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 2673, __PRETTY_FUNCTION__)) | ||||
2673 | "setBlockVarCopyInits - not __block var")((VD->hasAttr<BlocksAttr>() && "setBlockVarCopyInits - not __block var" ) ? static_cast<void> (0) : __assert_fail ("VD->hasAttr<BlocksAttr>() && \"setBlockVarCopyInits - not __block var\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 2673, __PRETTY_FUNCTION__)); | ||||
2674 | BlockVarCopyInits[VD].setExprAndFlag(CopyExpr, CanThrow); | ||||
2675 | } | ||||
2676 | |||||
2677 | TypeSourceInfo *ASTContext::CreateTypeSourceInfo(QualType T, | ||||
2678 | unsigned DataSize) const { | ||||
2679 | if (!DataSize) | ||||
2680 | DataSize = TypeLoc::getFullDataSizeForType(T); | ||||
2681 | else | ||||
2682 | assert(DataSize == TypeLoc::getFullDataSizeForType(T) &&((DataSize == TypeLoc::getFullDataSizeForType(T) && "incorrect data size provided to CreateTypeSourceInfo!" ) ? static_cast<void> (0) : __assert_fail ("DataSize == TypeLoc::getFullDataSizeForType(T) && \"incorrect data size provided to CreateTypeSourceInfo!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 2683, __PRETTY_FUNCTION__)) | ||||
2683 | "incorrect data size provided to CreateTypeSourceInfo!")((DataSize == TypeLoc::getFullDataSizeForType(T) && "incorrect data size provided to CreateTypeSourceInfo!" ) ? static_cast<void> (0) : __assert_fail ("DataSize == TypeLoc::getFullDataSizeForType(T) && \"incorrect data size provided to CreateTypeSourceInfo!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 2683, __PRETTY_FUNCTION__)); | ||||
2684 | |||||
2685 | auto *TInfo = | ||||
2686 | (TypeSourceInfo*)BumpAlloc.Allocate(sizeof(TypeSourceInfo) + DataSize, 8); | ||||
2687 | new (TInfo) TypeSourceInfo(T); | ||||
2688 | return TInfo; | ||||
2689 | } | ||||
2690 | |||||
2691 | TypeSourceInfo *ASTContext::getTrivialTypeSourceInfo(QualType T, | ||||
2692 | SourceLocation L) const { | ||||
2693 | TypeSourceInfo *DI = CreateTypeSourceInfo(T); | ||||
2694 | DI->getTypeLoc().initialize(const_cast<ASTContext &>(*this), L); | ||||
2695 | return DI; | ||||
2696 | } | ||||
2697 | |||||
2698 | const ASTRecordLayout & | ||||
2699 | ASTContext::getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D) const { | ||||
2700 | return getObjCLayout(D, nullptr); | ||||
2701 | } | ||||
2702 | |||||
2703 | const ASTRecordLayout & | ||||
2704 | ASTContext::getASTObjCImplementationLayout( | ||||
2705 | const ObjCImplementationDecl *D) const { | ||||
2706 | return getObjCLayout(D->getClassInterface(), D); | ||||
2707 | } | ||||
2708 | |||||
2709 | //===----------------------------------------------------------------------===// | ||||
2710 | // Type creation/memoization methods | ||||
2711 | //===----------------------------------------------------------------------===// | ||||
2712 | |||||
2713 | QualType | ||||
2714 | ASTContext::getExtQualType(const Type *baseType, Qualifiers quals) const { | ||||
2715 | unsigned fastQuals = quals.getFastQualifiers(); | ||||
2716 | quals.removeFastQualifiers(); | ||||
2717 | |||||
2718 | // Check if we've already instantiated this type. | ||||
2719 | llvm::FoldingSetNodeID ID; | ||||
2720 | ExtQuals::Profile(ID, baseType, quals); | ||||
2721 | void *insertPos = nullptr; | ||||
2722 | if (ExtQuals *eq = ExtQualNodes.FindNodeOrInsertPos(ID, insertPos)) { | ||||
2723 | assert(eq->getQualifiers() == quals)((eq->getQualifiers() == quals) ? static_cast<void> ( 0) : __assert_fail ("eq->getQualifiers() == quals", "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 2723, __PRETTY_FUNCTION__)); | ||||
2724 | return QualType(eq, fastQuals); | ||||
2725 | } | ||||
2726 | |||||
2727 | // If the base type is not canonical, make the appropriate canonical type. | ||||
2728 | QualType canon; | ||||
2729 | if (!baseType->isCanonicalUnqualified()) { | ||||
2730 | SplitQualType canonSplit = baseType->getCanonicalTypeInternal().split(); | ||||
2731 | canonSplit.Quals.addConsistentQualifiers(quals); | ||||
2732 | canon = getExtQualType(canonSplit.Ty, canonSplit.Quals); | ||||
2733 | |||||
2734 | // Re-find the insert position. | ||||
2735 | (void) ExtQualNodes.FindNodeOrInsertPos(ID, insertPos); | ||||
2736 | } | ||||
2737 | |||||
2738 | auto *eq = new (*this, TypeAlignment) ExtQuals(baseType, canon, quals); | ||||
2739 | ExtQualNodes.InsertNode(eq, insertPos); | ||||
2740 | return QualType(eq, fastQuals); | ||||
2741 | } | ||||
2742 | |||||
2743 | QualType ASTContext::getAddrSpaceQualType(QualType T, | ||||
2744 | LangAS AddressSpace) const { | ||||
2745 | QualType CanT = getCanonicalType(T); | ||||
2746 | if (CanT.getAddressSpace() == AddressSpace) | ||||
2747 | return T; | ||||
2748 | |||||
2749 | // If we are composing extended qualifiers together, merge together | ||||
2750 | // into one ExtQuals node. | ||||
2751 | QualifierCollector Quals; | ||||
2752 | const Type *TypeNode = Quals.strip(T); | ||||
2753 | |||||
2754 | // If this type already has an address space specified, it cannot get | ||||
2755 | // another one. | ||||
2756 | assert(!Quals.hasAddressSpace() &&((!Quals.hasAddressSpace() && "Type cannot be in multiple addr spaces!" ) ? static_cast<void> (0) : __assert_fail ("!Quals.hasAddressSpace() && \"Type cannot be in multiple addr spaces!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 2757, __PRETTY_FUNCTION__)) | ||||
2757 | "Type cannot be in multiple addr spaces!")((!Quals.hasAddressSpace() && "Type cannot be in multiple addr spaces!" ) ? static_cast<void> (0) : __assert_fail ("!Quals.hasAddressSpace() && \"Type cannot be in multiple addr spaces!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 2757, __PRETTY_FUNCTION__)); | ||||
2758 | Quals.addAddressSpace(AddressSpace); | ||||
2759 | |||||
2760 | return getExtQualType(TypeNode, Quals); | ||||
2761 | } | ||||
2762 | |||||
2763 | QualType ASTContext::removeAddrSpaceQualType(QualType T) const { | ||||
2764 | // If we are composing extended qualifiers together, merge together | ||||
2765 | // into one ExtQuals node. | ||||
2766 | QualifierCollector Quals; | ||||
2767 | const Type *TypeNode = Quals.strip(T); | ||||
2768 | |||||
2769 | // If the qualifier doesn't have an address space just return it. | ||||
2770 | if (!Quals.hasAddressSpace()) | ||||
2771 | return T; | ||||
2772 | |||||
2773 | Quals.removeAddressSpace(); | ||||
2774 | |||||
2775 | // Removal of the address space can mean there are no longer any | ||||
2776 | // non-fast qualifiers, so creating an ExtQualType isn't possible (asserts) | ||||
2777 | // or required. | ||||
2778 | if (Quals.hasNonFastQualifiers()) | ||||
2779 | return getExtQualType(TypeNode, Quals); | ||||
2780 | else | ||||
2781 | return QualType(TypeNode, Quals.getFastQualifiers()); | ||||
2782 | } | ||||
2783 | |||||
2784 | QualType ASTContext::getObjCGCQualType(QualType T, | ||||
2785 | Qualifiers::GC GCAttr) const { | ||||
2786 | QualType CanT = getCanonicalType(T); | ||||
2787 | if (CanT.getObjCGCAttr() == GCAttr) | ||||
2788 | return T; | ||||
2789 | |||||
2790 | if (const auto *ptr = T->getAs<PointerType>()) { | ||||
2791 | QualType Pointee = ptr->getPointeeType(); | ||||
2792 | if (Pointee->isAnyPointerType()) { | ||||
2793 | QualType ResultType = getObjCGCQualType(Pointee, GCAttr); | ||||
2794 | return getPointerType(ResultType); | ||||
2795 | } | ||||
2796 | } | ||||
2797 | |||||
2798 | // If we are composing extended qualifiers together, merge together | ||||
2799 | // into one ExtQuals node. | ||||
2800 | QualifierCollector Quals; | ||||
2801 | const Type *TypeNode = Quals.strip(T); | ||||
2802 | |||||
2803 | // If this type already has an ObjCGC specified, it cannot get | ||||
2804 | // another one. | ||||
2805 | assert(!Quals.hasObjCGCAttr() &&((!Quals.hasObjCGCAttr() && "Type cannot have multiple ObjCGCs!" ) ? static_cast<void> (0) : __assert_fail ("!Quals.hasObjCGCAttr() && \"Type cannot have multiple ObjCGCs!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 2806, __PRETTY_FUNCTION__)) | ||||
2806 | "Type cannot have multiple ObjCGCs!")((!Quals.hasObjCGCAttr() && "Type cannot have multiple ObjCGCs!" ) ? static_cast<void> (0) : __assert_fail ("!Quals.hasObjCGCAttr() && \"Type cannot have multiple ObjCGCs!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 2806, __PRETTY_FUNCTION__)); | ||||
2807 | Quals.addObjCGCAttr(GCAttr); | ||||
2808 | |||||
2809 | return getExtQualType(TypeNode, Quals); | ||||
2810 | } | ||||
2811 | |||||
2812 | const FunctionType *ASTContext::adjustFunctionType(const FunctionType *T, | ||||
2813 | FunctionType::ExtInfo Info) { | ||||
2814 | if (T->getExtInfo() == Info) | ||||
2815 | return T; | ||||
2816 | |||||
2817 | QualType Result; | ||||
2818 | if (const auto *FNPT = dyn_cast<FunctionNoProtoType>(T)) { | ||||
2819 | Result = getFunctionNoProtoType(FNPT->getReturnType(), Info); | ||||
2820 | } else { | ||||
2821 | const auto *FPT = cast<FunctionProtoType>(T); | ||||
2822 | FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo(); | ||||
2823 | EPI.ExtInfo = Info; | ||||
2824 | Result = getFunctionType(FPT->getReturnType(), FPT->getParamTypes(), EPI); | ||||
2825 | } | ||||
2826 | |||||
2827 | return cast<FunctionType>(Result.getTypePtr()); | ||||
2828 | } | ||||
2829 | |||||
2830 | void ASTContext::adjustDeducedFunctionResultType(FunctionDecl *FD, | ||||
2831 | QualType ResultType) { | ||||
2832 | FD = FD->getMostRecentDecl(); | ||||
2833 | while (true) { | ||||
2834 | const auto *FPT = FD->getType()->castAs<FunctionProtoType>(); | ||||
2835 | FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo(); | ||||
2836 | FD->setType(getFunctionType(ResultType, FPT->getParamTypes(), EPI)); | ||||
2837 | if (FunctionDecl *Next = FD->getPreviousDecl()) | ||||
2838 | FD = Next; | ||||
2839 | else | ||||
2840 | break; | ||||
2841 | } | ||||
2842 | if (ASTMutationListener *L = getASTMutationListener()) | ||||
2843 | L->DeducedReturnType(FD, ResultType); | ||||
2844 | } | ||||
2845 | |||||
2846 | /// Get a function type and produce the equivalent function type with the | ||||
2847 | /// specified exception specification. Type sugar that can be present on a | ||||
2848 | /// declaration of a function with an exception specification is permitted | ||||
2849 | /// and preserved. Other type sugar (for instance, typedefs) is not. | ||||
2850 | QualType ASTContext::getFunctionTypeWithExceptionSpec( | ||||
2851 | QualType Orig, const FunctionProtoType::ExceptionSpecInfo &ESI) { | ||||
2852 | // Might have some parens. | ||||
2853 | if (const auto *PT
| ||||
2854 | return getParenType( | ||||
2855 | getFunctionTypeWithExceptionSpec(PT->getInnerType(), ESI)); | ||||
2856 | |||||
2857 | // Might be wrapped in a macro qualified type. | ||||
2858 | if (const auto *MQT
| ||||
2859 | return getMacroQualifiedType( | ||||
2860 | getFunctionTypeWithExceptionSpec(MQT->getUnderlyingType(), ESI), | ||||
2861 | MQT->getMacroIdentifier()); | ||||
2862 | |||||
2863 | // Might have a calling-convention attribute. | ||||
2864 | if (const auto *AT
| ||||
2865 | return getAttributedType( | ||||
2866 | AT->getAttrKind(), | ||||
2867 | getFunctionTypeWithExceptionSpec(AT->getModifiedType(), ESI), | ||||
2868 | getFunctionTypeWithExceptionSpec(AT->getEquivalentType(), ESI)); | ||||
2869 | |||||
2870 | // Anything else must be a function type. Rebuild it with the new exception | ||||
2871 | // specification. | ||||
2872 | const auto *Proto = Orig->getAs<FunctionProtoType>(); | ||||
2873 | return getFunctionType( | ||||
2874 | Proto->getReturnType(), Proto->getParamTypes(), | ||||
| |||||
2875 | Proto->getExtProtoInfo().withExceptionSpec(ESI)); | ||||
2876 | } | ||||
2877 | |||||
2878 | bool ASTContext::hasSameFunctionTypeIgnoringExceptionSpec(QualType T, | ||||
2879 | QualType U) { | ||||
2880 | return hasSameType(T, U) || | ||||
2881 | (getLangOpts().CPlusPlus17 && | ||||
2882 | hasSameType(getFunctionTypeWithExceptionSpec(T, EST_None), | ||||
2883 | getFunctionTypeWithExceptionSpec(U, EST_None))); | ||||
2884 | } | ||||
2885 | |||||
2886 | void ASTContext::adjustExceptionSpec( | ||||
2887 | FunctionDecl *FD, const FunctionProtoType::ExceptionSpecInfo &ESI, | ||||
2888 | bool AsWritten) { | ||||
2889 | // Update the type. | ||||
2890 | QualType Updated = | ||||
2891 | getFunctionTypeWithExceptionSpec(FD->getType(), ESI); | ||||
| |||||
2892 | FD->setType(Updated); | ||||
2893 | |||||
2894 | if (!AsWritten) | ||||
2895 | return; | ||||
2896 | |||||
2897 | // Update the type in the type source information too. | ||||
2898 | if (TypeSourceInfo *TSInfo = FD->getTypeSourceInfo()) { | ||||
2899 | // If the type and the type-as-written differ, we may need to update | ||||
2900 | // the type-as-written too. | ||||
2901 | if (TSInfo->getType() != FD->getType()) | ||||
2902 | Updated = getFunctionTypeWithExceptionSpec(TSInfo->getType(), ESI); | ||||
2903 | |||||
2904 | // FIXME: When we get proper type location information for exceptions, | ||||
2905 | // we'll also have to rebuild the TypeSourceInfo. For now, we just patch | ||||
2906 | // up the TypeSourceInfo; | ||||
2907 | assert(TypeLoc::getFullDataSizeForType(Updated) ==((TypeLoc::getFullDataSizeForType(Updated) == TypeLoc::getFullDataSizeForType (TSInfo->getType()) && "TypeLoc size mismatch from updating exception specification" ) ? static_cast<void> (0) : __assert_fail ("TypeLoc::getFullDataSizeForType(Updated) == TypeLoc::getFullDataSizeForType(TSInfo->getType()) && \"TypeLoc size mismatch from updating exception specification\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 2909, __PRETTY_FUNCTION__)) | ||||
2908 | TypeLoc::getFullDataSizeForType(TSInfo->getType()) &&((TypeLoc::getFullDataSizeForType(Updated) == TypeLoc::getFullDataSizeForType (TSInfo->getType()) && "TypeLoc size mismatch from updating exception specification" ) ? static_cast<void> (0) : __assert_fail ("TypeLoc::getFullDataSizeForType(Updated) == TypeLoc::getFullDataSizeForType(TSInfo->getType()) && \"TypeLoc size mismatch from updating exception specification\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 2909, __PRETTY_FUNCTION__)) | ||||
2909 | "TypeLoc size mismatch from updating exception specification")((TypeLoc::getFullDataSizeForType(Updated) == TypeLoc::getFullDataSizeForType (TSInfo->getType()) && "TypeLoc size mismatch from updating exception specification" ) ? static_cast<void> (0) : __assert_fail ("TypeLoc::getFullDataSizeForType(Updated) == TypeLoc::getFullDataSizeForType(TSInfo->getType()) && \"TypeLoc size mismatch from updating exception specification\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 2909, __PRETTY_FUNCTION__)); | ||||
2910 | TSInfo->overrideType(Updated); | ||||
2911 | } | ||||
2912 | } | ||||
2913 | |||||
2914 | /// getComplexType - Return the uniqued reference to the type for a complex | ||||
2915 | /// number with the specified element type. | ||||
2916 | QualType ASTContext::getComplexType(QualType T) const { | ||||
2917 | // Unique pointers, to guarantee there is only one pointer of a particular | ||||
2918 | // structure. | ||||
2919 | llvm::FoldingSetNodeID ID; | ||||
2920 | ComplexType::Profile(ID, T); | ||||
2921 | |||||
2922 | void *InsertPos = nullptr; | ||||
2923 | if (ComplexType *CT = ComplexTypes.FindNodeOrInsertPos(ID, InsertPos)) | ||||
2924 | return QualType(CT, 0); | ||||
2925 | |||||
2926 | // If the pointee type isn't canonical, this won't be a canonical type either, | ||||
2927 | // so fill in the canonical type field. | ||||
2928 | QualType Canonical; | ||||
2929 | if (!T.isCanonical()) { | ||||
2930 | Canonical = getComplexType(getCanonicalType(T)); | ||||
2931 | |||||
2932 | // Get the new insert position for the node we care about. | ||||
2933 | ComplexType *NewIP = ComplexTypes.FindNodeOrInsertPos(ID, InsertPos); | ||||
2934 | assert(!NewIP && "Shouldn't be in the map!")((!NewIP && "Shouldn't be in the map!") ? static_cast <void> (0) : __assert_fail ("!NewIP && \"Shouldn't be in the map!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 2934, __PRETTY_FUNCTION__)); (void)NewIP; | ||||
2935 | } | ||||
2936 | auto *New = new (*this, TypeAlignment) ComplexType(T, Canonical); | ||||
2937 | Types.push_back(New); | ||||
2938 | ComplexTypes.InsertNode(New, InsertPos); | ||||
2939 | return QualType(New, 0); | ||||
2940 | } | ||||
2941 | |||||
2942 | /// getPointerType - Return the uniqued reference to the type for a pointer to | ||||
2943 | /// the specified type. | ||||
2944 | QualType ASTContext::getPointerType(QualType T) const { | ||||
2945 | // Unique pointers, to guarantee there is only one pointer of a particular | ||||
2946 | // structure. | ||||
2947 | llvm::FoldingSetNodeID ID; | ||||
2948 | PointerType::Profile(ID, T); | ||||
2949 | |||||
2950 | void *InsertPos = nullptr; | ||||
2951 | if (PointerType *PT = PointerTypes.FindNodeOrInsertPos(ID, InsertPos)) | ||||
2952 | return QualType(PT, 0); | ||||
2953 | |||||
2954 | // If the pointee type isn't canonical, this won't be a canonical type either, | ||||
2955 | // so fill in the canonical type field. | ||||
2956 | QualType Canonical; | ||||
2957 | if (!T.isCanonical()) { | ||||
2958 | Canonical = getPointerType(getCanonicalType(T)); | ||||
2959 | |||||
2960 | // Get the new insert position for the node we care about. | ||||
2961 | PointerType *NewIP = PointerTypes.FindNodeOrInsertPos(ID, InsertPos); | ||||
2962 | assert(!NewIP && "Shouldn't be in the map!")((!NewIP && "Shouldn't be in the map!") ? static_cast <void> (0) : __assert_fail ("!NewIP && \"Shouldn't be in the map!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 2962, __PRETTY_FUNCTION__)); (void)NewIP; | ||||
2963 | } | ||||
2964 | auto *New = new (*this, TypeAlignment) PointerType(T, Canonical); | ||||
2965 | Types.push_back(New); | ||||
2966 | PointerTypes.InsertNode(New, InsertPos); | ||||
2967 | return QualType(New, 0); | ||||
2968 | } | ||||
2969 | |||||
2970 | QualType ASTContext::getAdjustedType(QualType Orig, QualType New) const { | ||||
2971 | llvm::FoldingSetNodeID ID; | ||||
2972 | AdjustedType::Profile(ID, Orig, New); | ||||
2973 | void *InsertPos = nullptr; | ||||
2974 | AdjustedType *AT = AdjustedTypes.FindNodeOrInsertPos(ID, InsertPos); | ||||
2975 | if (AT) | ||||
2976 | return QualType(AT, 0); | ||||
2977 | |||||
2978 | QualType Canonical = getCanonicalType(New); | ||||
2979 | |||||
2980 | // Get the new insert position for the node we care about. | ||||
2981 | AT = AdjustedTypes.FindNodeOrInsertPos(ID, InsertPos); | ||||
2982 | assert(!AT && "Shouldn't be in the map!")((!AT && "Shouldn't be in the map!") ? static_cast< void> (0) : __assert_fail ("!AT && \"Shouldn't be in the map!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 2982, __PRETTY_FUNCTION__)); | ||||
2983 | |||||
2984 | AT = new (*this, TypeAlignment) | ||||
2985 | AdjustedType(Type::Adjusted, Orig, New, Canonical); | ||||
2986 | Types.push_back(AT); | ||||
2987 | AdjustedTypes.InsertNode(AT, InsertPos); | ||||
2988 | return QualType(AT, 0); | ||||
2989 | } | ||||
2990 | |||||
2991 | QualType ASTContext::getDecayedType(QualType T) const { | ||||
2992 | assert((T->isArrayType() || T->isFunctionType()) && "T does not decay")(((T->isArrayType() || T->isFunctionType()) && "T does not decay" ) ? static_cast<void> (0) : __assert_fail ("(T->isArrayType() || T->isFunctionType()) && \"T does not decay\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 2992, __PRETTY_FUNCTION__)); | ||||
2993 | |||||
2994 | QualType Decayed; | ||||
2995 | |||||
2996 | // C99 6.7.5.3p7: | ||||
2997 | // A declaration of a parameter as "array of type" shall be | ||||
2998 | // adjusted to "qualified pointer to type", where the type | ||||
2999 | // qualifiers (if any) are those specified within the [ and ] of | ||||
3000 | // the array type derivation. | ||||
3001 | if (T->isArrayType()) | ||||
3002 | Decayed = getArrayDecayedType(T); | ||||
3003 | |||||
3004 | // C99 6.7.5.3p8: | ||||
3005 | // A declaration of a parameter as "function returning type" | ||||
3006 | // shall be adjusted to "pointer to function returning type", as | ||||
3007 | // in 6.3.2.1. | ||||
3008 | if (T->isFunctionType()) | ||||
3009 | Decayed = getPointerType(T); | ||||
3010 | |||||
3011 | llvm::FoldingSetNodeID ID; | ||||
3012 | AdjustedType::Profile(ID, T, Decayed); | ||||
3013 | void *InsertPos = nullptr; | ||||
3014 | AdjustedType *AT = AdjustedTypes.FindNodeOrInsertPos(ID, InsertPos); | ||||
3015 | if (AT) | ||||
3016 | return QualType(AT, 0); | ||||
3017 | |||||
3018 | QualType Canonical = getCanonicalType(Decayed); | ||||
3019 | |||||
3020 | // Get the new insert position for the node we care about. | ||||
3021 | AT = AdjustedTypes.FindNodeOrInsertPos(ID, InsertPos); | ||||
3022 | assert(!AT && "Shouldn't be in the map!")((!AT && "Shouldn't be in the map!") ? static_cast< void> (0) : __assert_fail ("!AT && \"Shouldn't be in the map!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 3022, __PRETTY_FUNCTION__)); | ||||
3023 | |||||
3024 | AT = new (*this, TypeAlignment) DecayedType(T, Decayed, Canonical); | ||||
3025 | Types.push_back(AT); | ||||
3026 | AdjustedTypes.InsertNode(AT, InsertPos); | ||||
3027 | return QualType(AT, 0); | ||||
3028 | } | ||||
3029 | |||||
3030 | /// getBlockPointerType - Return the uniqued reference to the type for | ||||
3031 | /// a pointer to the specified block. | ||||
3032 | QualType ASTContext::getBlockPointerType(QualType T) const { | ||||
3033 | assert(T->isFunctionType() && "block of function types only")((T->isFunctionType() && "block of function types only" ) ? static_cast<void> (0) : __assert_fail ("T->isFunctionType() && \"block of function types only\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 3033, __PRETTY_FUNCTION__)); | ||||
3034 | // Unique pointers, to guarantee there is only one block of a particular | ||||
3035 | // structure. | ||||
3036 | llvm::FoldingSetNodeID ID; | ||||
3037 | BlockPointerType::Profile(ID, T); | ||||
3038 | |||||
3039 | void *InsertPos = nullptr; | ||||
3040 | if (BlockPointerType *PT = | ||||
3041 | BlockPointerTypes.FindNodeOrInsertPos(ID, InsertPos)) | ||||
3042 | return QualType(PT, 0); | ||||
3043 | |||||
3044 | // If the block pointee type isn't canonical, this won't be a canonical | ||||
3045 | // type either so fill in the canonical type field. | ||||
3046 | QualType Canonical; | ||||
3047 | if (!T.isCanonical()) { | ||||
3048 | Canonical = getBlockPointerType(getCanonicalType(T)); | ||||
3049 | |||||
3050 | // Get the new insert position for the node we care about. | ||||
3051 | BlockPointerType *NewIP = | ||||
3052 | BlockPointerTypes.FindNodeOrInsertPos(ID, InsertPos); | ||||
3053 | assert(!NewIP && "Shouldn't be in the map!")((!NewIP && "Shouldn't be in the map!") ? static_cast <void> (0) : __assert_fail ("!NewIP && \"Shouldn't be in the map!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 3053, __PRETTY_FUNCTION__)); (void)NewIP; | ||||
3054 | } | ||||
3055 | auto *New = new (*this, TypeAlignment) BlockPointerType(T, Canonical); | ||||
3056 | Types.push_back(New); | ||||
3057 | BlockPointerTypes.InsertNode(New, InsertPos); | ||||
3058 | return QualType(New, 0); | ||||
3059 | } | ||||
3060 | |||||
3061 | /// getLValueReferenceType - Return the uniqued reference to the type for an | ||||
3062 | /// lvalue reference to the specified type. | ||||
3063 | QualType | ||||
3064 | ASTContext::getLValueReferenceType(QualType T, bool SpelledAsLValue) const { | ||||
3065 | assert(getCanonicalType(T) != OverloadTy &&((getCanonicalType(T) != OverloadTy && "Unresolved overloaded function type" ) ? static_cast<void> (0) : __assert_fail ("getCanonicalType(T) != OverloadTy && \"Unresolved overloaded function type\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 3066, __PRETTY_FUNCTION__)) | ||||
3066 | "Unresolved overloaded function type")((getCanonicalType(T) != OverloadTy && "Unresolved overloaded function type" ) ? static_cast<void> (0) : __assert_fail ("getCanonicalType(T) != OverloadTy && \"Unresolved overloaded function type\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 3066, __PRETTY_FUNCTION__)); | ||||
3067 | |||||
3068 | // Unique pointers, to guarantee there is only one pointer of a particular | ||||
3069 | // structure. | ||||
3070 | llvm::FoldingSetNodeID ID; | ||||
3071 | ReferenceType::Profile(ID, T, SpelledAsLValue); | ||||
3072 | |||||
3073 | void *InsertPos = nullptr; | ||||
3074 | if (LValueReferenceType *RT = | ||||
3075 | LValueReferenceTypes.FindNodeOrInsertPos(ID, InsertPos)) | ||||
3076 | return QualType(RT, 0); | ||||
3077 | |||||
3078 | const auto *InnerRef = T->getAs<ReferenceType>(); | ||||
3079 | |||||
3080 | // If the referencee type isn't canonical, this won't be a canonical type | ||||
3081 | // either, so fill in the canonical type field. | ||||
3082 | QualType Canonical; | ||||
3083 | if (!SpelledAsLValue || InnerRef || !T.isCanonical()) { | ||||
3084 | QualType PointeeType = (InnerRef ? InnerRef->getPointeeType() : T); | ||||
3085 | Canonical = getLValueReferenceType(getCanonicalType(PointeeType)); | ||||
3086 | |||||
3087 | // Get the new insert position for the node we care about. | ||||
3088 | LValueReferenceType *NewIP = | ||||
3089 | LValueReferenceTypes.FindNodeOrInsertPos(ID, InsertPos); | ||||
3090 | assert(!NewIP && "Shouldn't be in the map!")((!NewIP && "Shouldn't be in the map!") ? static_cast <void> (0) : __assert_fail ("!NewIP && \"Shouldn't be in the map!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 3090, __PRETTY_FUNCTION__)); (void)NewIP; | ||||
3091 | } | ||||
3092 | |||||
3093 | auto *New = new (*this, TypeAlignment) LValueReferenceType(T, Canonical, | ||||
3094 | SpelledAsLValue); | ||||
3095 | Types.push_back(New); | ||||
3096 | LValueReferenceTypes.InsertNode(New, InsertPos); | ||||
3097 | |||||
3098 | return QualType(New, 0); | ||||
3099 | } | ||||
3100 | |||||
3101 | /// getRValueReferenceType - Return the uniqued reference to the type for an | ||||
3102 | /// rvalue reference to the specified type. | ||||
3103 | QualType ASTContext::getRValueReferenceType(QualType T) const { | ||||
3104 | // Unique pointers, to guarantee there is only one pointer of a particular | ||||
3105 | // structure. | ||||
3106 | llvm::FoldingSetNodeID ID; | ||||
3107 | ReferenceType::Profile(ID, T, false); | ||||
3108 | |||||
3109 | void *InsertPos = nullptr; | ||||
3110 | if (RValueReferenceType *RT = | ||||
3111 | RValueReferenceTypes.FindNodeOrInsertPos(ID, InsertPos)) | ||||
3112 | return QualType(RT, 0); | ||||
3113 | |||||
3114 | const auto *InnerRef = T->getAs<ReferenceType>(); | ||||
3115 | |||||
3116 | // If the referencee type isn't canonical, this won't be a canonical type | ||||
3117 | // either, so fill in the canonical type field. | ||||
3118 | QualType Canonical; | ||||
3119 | if (InnerRef || !T.isCanonical()) { | ||||
3120 | QualType PointeeType = (InnerRef ? InnerRef->getPointeeType() : T); | ||||
3121 | Canonical = getRValueReferenceType(getCanonicalType(PointeeType)); | ||||
3122 | |||||
3123 | // Get the new insert position for the node we care about. | ||||
3124 | RValueReferenceType *NewIP = | ||||
3125 | RValueReferenceTypes.FindNodeOrInsertPos(ID, InsertPos); | ||||
3126 | assert(!NewIP && "Shouldn't be in the map!")((!NewIP && "Shouldn't be in the map!") ? static_cast <void> (0) : __assert_fail ("!NewIP && \"Shouldn't be in the map!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 3126, __PRETTY_FUNCTION__)); (void)NewIP; | ||||
3127 | } | ||||
3128 | |||||
3129 | auto *New = new (*this, TypeAlignment) RValueReferenceType(T, Canonical); | ||||
3130 | Types.push_back(New); | ||||
3131 | RValueReferenceTypes.InsertNode(New, InsertPos); | ||||
3132 | return QualType(New, 0); | ||||
3133 | } | ||||
3134 | |||||
3135 | /// getMemberPointerType - Return the uniqued reference to the type for a | ||||
3136 | /// member pointer to the specified type, in the specified class. | ||||
3137 | QualType ASTContext::getMemberPointerType(QualType T, const Type *Cls) const { | ||||
3138 | // Unique pointers, to guarantee there is only one pointer of a particular | ||||
3139 | // structure. | ||||
3140 | llvm::FoldingSetNodeID ID; | ||||
3141 | MemberPointerType::Profile(ID, T, Cls); | ||||
3142 | |||||
3143 | void *InsertPos = nullptr; | ||||
3144 | if (MemberPointerType *PT = | ||||
3145 | MemberPointerTypes.FindNodeOrInsertPos(ID, InsertPos)) | ||||
3146 | return QualType(PT, 0); | ||||
3147 | |||||
3148 | // If the pointee or class type isn't canonical, this won't be a canonical | ||||
3149 | // type either, so fill in the canonical type field. | ||||
3150 | QualType Canonical; | ||||
3151 | if (!T.isCanonical() || !Cls->isCanonicalUnqualified()) { | ||||
3152 | Canonical = getMemberPointerType(getCanonicalType(T),getCanonicalType(Cls)); | ||||
3153 | |||||
3154 | // Get the new insert position for the node we care about. | ||||
3155 | MemberPointerType *NewIP = | ||||
3156 | MemberPointerTypes.FindNodeOrInsertPos(ID, InsertPos); | ||||
3157 | assert(!NewIP && "Shouldn't be in the map!")((!NewIP && "Shouldn't be in the map!") ? static_cast <void> (0) : __assert_fail ("!NewIP && \"Shouldn't be in the map!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 3157, __PRETTY_FUNCTION__)); (void)NewIP; | ||||
3158 | } | ||||
3159 | auto *New = new (*this, TypeAlignment) MemberPointerType(T, Cls, Canonical); | ||||
3160 | Types.push_back(New); | ||||
3161 | MemberPointerTypes.InsertNode(New, InsertPos); | ||||
3162 | return QualType(New, 0); | ||||
3163 | } | ||||
3164 | |||||
3165 | /// getConstantArrayType - Return the unique reference to the type for an | ||||
3166 | /// array of the specified element type. | ||||
3167 | QualType ASTContext::getConstantArrayType(QualType EltTy, | ||||
3168 | const llvm::APInt &ArySizeIn, | ||||
3169 | ArrayType::ArraySizeModifier ASM, | ||||
3170 | unsigned IndexTypeQuals) const { | ||||
3171 | assert((EltTy->isDependentType() ||(((EltTy->isDependentType() || EltTy->isIncompleteType( ) || EltTy->isConstantSizeType()) && "Constant array of VLAs is illegal!" ) ? static_cast<void> (0) : __assert_fail ("(EltTy->isDependentType() || EltTy->isIncompleteType() || EltTy->isConstantSizeType()) && \"Constant array of VLAs is illegal!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 3173, __PRETTY_FUNCTION__)) | ||||
3172 | EltTy->isIncompleteType() || EltTy->isConstantSizeType()) &&(((EltTy->isDependentType() || EltTy->isIncompleteType( ) || EltTy->isConstantSizeType()) && "Constant array of VLAs is illegal!" ) ? static_cast<void> (0) : __assert_fail ("(EltTy->isDependentType() || EltTy->isIncompleteType() || EltTy->isConstantSizeType()) && \"Constant array of VLAs is illegal!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 3173, __PRETTY_FUNCTION__)) | ||||
3173 | "Constant array of VLAs is illegal!")(((EltTy->isDependentType() || EltTy->isIncompleteType( ) || EltTy->isConstantSizeType()) && "Constant array of VLAs is illegal!" ) ? static_cast<void> (0) : __assert_fail ("(EltTy->isDependentType() || EltTy->isIncompleteType() || EltTy->isConstantSizeType()) && \"Constant array of VLAs is illegal!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 3173, __PRETTY_FUNCTION__)); | ||||
3174 | |||||
3175 | // Convert the array size into a canonical width matching the pointer size for | ||||
3176 | // the target. | ||||
3177 | llvm::APInt ArySize(ArySizeIn); | ||||
3178 | ArySize = ArySize.zextOrTrunc(Target->getMaxPointerWidth()); | ||||
3179 | |||||
3180 | llvm::FoldingSetNodeID ID; | ||||
3181 | ConstantArrayType::Profile(ID, EltTy, ArySize, ASM, IndexTypeQuals); | ||||
3182 | |||||
3183 | void *InsertPos = nullptr; | ||||
3184 | if (ConstantArrayType *ATP = | ||||
3185 | ConstantArrayTypes.FindNodeOrInsertPos(ID, InsertPos)) | ||||
3186 | return QualType(ATP, 0); | ||||
3187 | |||||
3188 | // If the element type isn't canonical or has qualifiers, this won't | ||||
3189 | // be a canonical type either, so fill in the canonical type field. | ||||
3190 | QualType Canon; | ||||
3191 | if (!EltTy.isCanonical() || EltTy.hasLocalQualifiers()) { | ||||
3192 | SplitQualType canonSplit = getCanonicalType(EltTy).split(); | ||||
3193 | Canon = getConstantArrayType(QualType(canonSplit.Ty, 0), ArySize, | ||||
3194 | ASM, IndexTypeQuals); | ||||
3195 | Canon = getQualifiedType(Canon, canonSplit.Quals); | ||||
3196 | |||||
3197 | // Get the new insert position for the node we care about. | ||||
3198 | ConstantArrayType *NewIP = | ||||
3199 | ConstantArrayTypes.FindNodeOrInsertPos(ID, InsertPos); | ||||
3200 | assert(!NewIP && "Shouldn't be in the map!")((!NewIP && "Shouldn't be in the map!") ? static_cast <void> (0) : __assert_fail ("!NewIP && \"Shouldn't be in the map!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 3200, __PRETTY_FUNCTION__)); (void)NewIP; | ||||
3201 | } | ||||
3202 | |||||
3203 | auto *New = new (*this,TypeAlignment) | ||||
3204 | ConstantArrayType(EltTy, Canon, ArySize, ASM, IndexTypeQuals); | ||||
3205 | ConstantArrayTypes.InsertNode(New, InsertPos); | ||||
3206 | Types.push_back(New); | ||||
3207 | return QualType(New, 0); | ||||
3208 | } | ||||
3209 | |||||
3210 | /// getVariableArrayDecayedType - Turns the given type, which may be | ||||
3211 | /// variably-modified, into the corresponding type with all the known | ||||
3212 | /// sizes replaced with [*]. | ||||
3213 | QualType ASTContext::getVariableArrayDecayedType(QualType type) const { | ||||
3214 | // Vastly most common case. | ||||
3215 | if (!type->isVariablyModifiedType()) return type; | ||||
3216 | |||||
3217 | QualType result; | ||||
3218 | |||||
3219 | SplitQualType split = type.getSplitDesugaredType(); | ||||
3220 | const Type *ty = split.Ty; | ||||
3221 | switch (ty->getTypeClass()) { | ||||
3222 | #define TYPE(Class, Base) | ||||
3223 | #define ABSTRACT_TYPE(Class, Base) | ||||
3224 | #define NON_CANONICAL_TYPE(Class, Base) case Type::Class: | ||||
3225 | #include "clang/AST/TypeNodes.inc" | ||||
3226 | llvm_unreachable("didn't desugar past all non-canonical types?")::llvm::llvm_unreachable_internal("didn't desugar past all non-canonical types?" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 3226); | ||||
3227 | |||||
3228 | // These types should never be variably-modified. | ||||
3229 | case Type::Builtin: | ||||
3230 | case Type::Complex: | ||||
3231 | case Type::Vector: | ||||
3232 | case Type::DependentVector: | ||||
3233 | case Type::ExtVector: | ||||
3234 | case Type::DependentSizedExtVector: | ||||
3235 | case Type::DependentAddressSpace: | ||||
3236 | case Type::ObjCObject: | ||||
3237 | case Type::ObjCInterface: | ||||
3238 | case Type::ObjCObjectPointer: | ||||
3239 | case Type::Record: | ||||
3240 | case Type::Enum: | ||||
3241 | case Type::UnresolvedUsing: | ||||
3242 | case Type::TypeOfExpr: | ||||
3243 | case Type::TypeOf: | ||||
3244 | case Type::Decltype: | ||||
3245 | case Type::UnaryTransform: | ||||
3246 | case Type::DependentName: | ||||
3247 | case Type::InjectedClassName: | ||||
3248 | case Type::TemplateSpecialization: | ||||
3249 | case Type::DependentTemplateSpecialization: | ||||
3250 | case Type::TemplateTypeParm: | ||||
3251 | case Type::SubstTemplateTypeParmPack: | ||||
3252 | case Type::Auto: | ||||
3253 | case Type::DeducedTemplateSpecialization: | ||||
3254 | case Type::PackExpansion: | ||||
3255 | llvm_unreachable("type should never be variably-modified")::llvm::llvm_unreachable_internal("type should never be variably-modified" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 3255); | ||||
3256 | |||||
3257 | // These types can be variably-modified but should never need to | ||||
3258 | // further decay. | ||||
3259 | case Type::FunctionNoProto: | ||||
3260 | case Type::FunctionProto: | ||||
3261 | case Type::BlockPointer: | ||||
3262 | case Type::MemberPointer: | ||||
3263 | case Type::Pipe: | ||||
3264 | return type; | ||||
3265 | |||||
3266 | // These types can be variably-modified. All these modifications | ||||
3267 | // preserve structure except as noted by comments. | ||||
3268 | // TODO: if we ever care about optimizing VLAs, there are no-op | ||||
3269 | // optimizations available here. | ||||
3270 | case Type::Pointer: | ||||
3271 | result = getPointerType(getVariableArrayDecayedType( | ||||
3272 | cast<PointerType>(ty)->getPointeeType())); | ||||
3273 | break; | ||||
3274 | |||||
3275 | case Type::LValueReference: { | ||||
3276 | const auto *lv = cast<LValueReferenceType>(ty); | ||||
3277 | result = getLValueReferenceType( | ||||
3278 | getVariableArrayDecayedType(lv->getPointeeType()), | ||||
3279 | lv->isSpelledAsLValue()); | ||||
3280 | break; | ||||
3281 | } | ||||
3282 | |||||
3283 | case Type::RValueReference: { | ||||
3284 | const auto *lv = cast<RValueReferenceType>(ty); | ||||
3285 | result = getRValueReferenceType( | ||||
3286 | getVariableArrayDecayedType(lv->getPointeeType())); | ||||
3287 | break; | ||||
3288 | } | ||||
3289 | |||||
3290 | case Type::Atomic: { | ||||
3291 | const auto *at = cast<AtomicType>(ty); | ||||
3292 | result = getAtomicType(getVariableArrayDecayedType(at->getValueType())); | ||||
3293 | break; | ||||
3294 | } | ||||
3295 | |||||
3296 | case Type::ConstantArray: { | ||||
3297 | const auto *cat = cast<ConstantArrayType>(ty); | ||||
3298 | result = getConstantArrayType( | ||||
3299 | getVariableArrayDecayedType(cat->getElementType()), | ||||
3300 | cat->getSize(), | ||||
3301 | cat->getSizeModifier(), | ||||
3302 | cat->getIndexTypeCVRQualifiers()); | ||||
3303 | break; | ||||
3304 | } | ||||
3305 | |||||
3306 | case Type::DependentSizedArray: { | ||||
3307 | const auto *dat = cast<DependentSizedArrayType>(ty); | ||||
3308 | result = getDependentSizedArrayType( | ||||
3309 | getVariableArrayDecayedType(dat->getElementType()), | ||||
3310 | dat->getSizeExpr(), | ||||
3311 | dat->getSizeModifier(), | ||||
3312 | dat->getIndexTypeCVRQualifiers(), | ||||
3313 | dat->getBracketsRange()); | ||||
3314 | break; | ||||
3315 | } | ||||
3316 | |||||
3317 | // Turn incomplete types into [*] types. | ||||
3318 | case Type::IncompleteArray: { | ||||
3319 | const auto *iat = cast<IncompleteArrayType>(ty); | ||||
3320 | result = getVariableArrayType( | ||||
3321 | getVariableArrayDecayedType(iat->getElementType()), | ||||
3322 | /*size*/ nullptr, | ||||
3323 | ArrayType::Normal, | ||||
3324 | iat->getIndexTypeCVRQualifiers(), | ||||
3325 | SourceRange()); | ||||
3326 | break; | ||||
3327 | } | ||||
3328 | |||||
3329 | // Turn VLA types into [*] types. | ||||
3330 | case Type::VariableArray: { | ||||
3331 | const auto *vat = cast<VariableArrayType>(ty); | ||||
3332 | result = getVariableArrayType( | ||||
3333 | getVariableArrayDecayedType(vat->getElementType()), | ||||
3334 | /*size*/ nullptr, | ||||
3335 | ArrayType::Star, | ||||
3336 | vat->getIndexTypeCVRQualifiers(), | ||||
3337 | vat->getBracketsRange()); | ||||
3338 | break; | ||||
3339 | } | ||||
3340 | } | ||||
3341 | |||||
3342 | // Apply the top-level qualifiers from the original. | ||||
3343 | return getQualifiedType(result, split.Quals); | ||||
3344 | } | ||||
3345 | |||||
3346 | /// getVariableArrayType - Returns a non-unique reference to the type for a | ||||
3347 | /// variable array of the specified element type. | ||||
3348 | QualType ASTContext::getVariableArrayType(QualType EltTy, | ||||
3349 | Expr *NumElts, | ||||
3350 | ArrayType::ArraySizeModifier ASM, | ||||
3351 | unsigned IndexTypeQuals, | ||||
3352 | SourceRange Brackets) const { | ||||
3353 | // Since we don't unique expressions, it isn't possible to unique VLA's | ||||
3354 | // that have an expression provided for their size. | ||||
3355 | QualType Canon; | ||||
3356 | |||||
3357 | // Be sure to pull qualifiers off the element type. | ||||
3358 | if (!EltTy.isCanonical() || EltTy.hasLocalQualifiers()) { | ||||
3359 | SplitQualType canonSplit = getCanonicalType(EltTy).split(); | ||||
3360 | Canon = getVariableArrayType(QualType(canonSplit.Ty, 0), NumElts, ASM, | ||||
3361 | IndexTypeQuals, Brackets); | ||||
3362 | Canon = getQualifiedType(Canon, canonSplit.Quals); | ||||
3363 | } | ||||
3364 | |||||
3365 | auto *New = new (*this, TypeAlignment) | ||||
3366 | VariableArrayType(EltTy, Canon, NumElts, ASM, IndexTypeQuals, Brackets); | ||||
3367 | |||||
3368 | VariableArrayTypes.push_back(New); | ||||
3369 | Types.push_back(New); | ||||
3370 | return QualType(New, 0); | ||||
3371 | } | ||||
3372 | |||||
3373 | /// getDependentSizedArrayType - Returns a non-unique reference to | ||||
3374 | /// the type for a dependently-sized array of the specified element | ||||
3375 | /// type. | ||||
3376 | QualType ASTContext::getDependentSizedArrayType(QualType elementType, | ||||
3377 | Expr *numElements, | ||||
3378 | ArrayType::ArraySizeModifier ASM, | ||||
3379 | unsigned elementTypeQuals, | ||||
3380 | SourceRange brackets) const { | ||||
3381 | assert((!numElements || numElements->isTypeDependent() ||(((!numElements || numElements->isTypeDependent() || numElements ->isValueDependent()) && "Size must be type- or value-dependent!" ) ? static_cast<void> (0) : __assert_fail ("(!numElements || numElements->isTypeDependent() || numElements->isValueDependent()) && \"Size must be type- or value-dependent!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 3383, __PRETTY_FUNCTION__)) | ||||
3382 | numElements->isValueDependent()) &&(((!numElements || numElements->isTypeDependent() || numElements ->isValueDependent()) && "Size must be type- or value-dependent!" ) ? static_cast<void> (0) : __assert_fail ("(!numElements || numElements->isTypeDependent() || numElements->isValueDependent()) && \"Size must be type- or value-dependent!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 3383, __PRETTY_FUNCTION__)) | ||||
3383 | "Size must be type- or value-dependent!")(((!numElements || numElements->isTypeDependent() || numElements ->isValueDependent()) && "Size must be type- or value-dependent!" ) ? static_cast<void> (0) : __assert_fail ("(!numElements || numElements->isTypeDependent() || numElements->isValueDependent()) && \"Size must be type- or value-dependent!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 3383, __PRETTY_FUNCTION__)); | ||||
3384 | |||||
3385 | // Dependently-sized array types that do not have a specified number | ||||
3386 | // of elements will have their sizes deduced from a dependent | ||||
3387 | // initializer. We do no canonicalization here at all, which is okay | ||||
3388 | // because they can't be used in most locations. | ||||
3389 | if (!numElements) { | ||||
3390 | auto *newType | ||||
3391 | = new (*this, TypeAlignment) | ||||
3392 | DependentSizedArrayType(*this, elementType, QualType(), | ||||
3393 | numElements, ASM, elementTypeQuals, | ||||
3394 | brackets); | ||||
3395 | Types.push_back(newType); | ||||
3396 | return QualType(newType, 0); | ||||
3397 | } | ||||
3398 | |||||
3399 | // Otherwise, we actually build a new type every time, but we | ||||
3400 | // also build a canonical type. | ||||
3401 | |||||
3402 | SplitQualType canonElementType = getCanonicalType(elementType).split(); | ||||
3403 | |||||
3404 | void *insertPos = nullptr; | ||||
3405 | llvm::FoldingSetNodeID ID; | ||||
3406 | DependentSizedArrayType::Profile(ID, *this, | ||||
3407 | QualType(canonElementType.Ty, 0), | ||||
3408 | ASM, elementTypeQuals, numElements); | ||||
3409 | |||||
3410 | // Look for an existing type with these properties. | ||||
3411 | DependentSizedArrayType *canonTy = | ||||
3412 | DependentSizedArrayTypes.FindNodeOrInsertPos(ID, insertPos); | ||||
3413 | |||||
3414 | // If we don't have one, build one. | ||||
3415 | if (!canonTy) { | ||||
3416 | canonTy = new (*this, TypeAlignment) | ||||
3417 | DependentSizedArrayType(*this, QualType(canonElementType.Ty, 0), | ||||
3418 | QualType(), numElements, ASM, elementTypeQuals, | ||||
3419 | brackets); | ||||
3420 | DependentSizedArrayTypes.InsertNode(canonTy, insertPos); | ||||
3421 | Types.push_back(canonTy); | ||||
3422 | } | ||||
3423 | |||||
3424 | // Apply qualifiers from the element type to the array. | ||||
3425 | QualType canon = getQualifiedType(QualType(canonTy,0), | ||||
3426 | canonElementType.Quals); | ||||
3427 | |||||
3428 | // If we didn't need extra canonicalization for the element type or the size | ||||
3429 | // expression, then just use that as our result. | ||||
3430 | if (QualType(canonElementType.Ty, 0) == elementType && | ||||
3431 | canonTy->getSizeExpr() == numElements) | ||||
3432 | return canon; | ||||
3433 | |||||
3434 | // Otherwise, we need to build a type which follows the spelling | ||||
3435 | // of the element type. | ||||
3436 | auto *sugaredType | ||||
3437 | = new (*this, TypeAlignment) | ||||
3438 | DependentSizedArrayType(*this, elementType, canon, numElements, | ||||
3439 | ASM, elementTypeQuals, brackets); | ||||
3440 | Types.push_back(sugaredType); | ||||
3441 | return QualType(sugaredType, 0); | ||||
3442 | } | ||||
3443 | |||||
3444 | QualType ASTContext::getIncompleteArrayType(QualType elementType, | ||||
3445 | ArrayType::ArraySizeModifier ASM, | ||||
3446 | unsigned elementTypeQuals) const { | ||||
3447 | llvm::FoldingSetNodeID ID; | ||||
3448 | IncompleteArrayType::Profile(ID, elementType, ASM, elementTypeQuals); | ||||
3449 | |||||
3450 | void *insertPos = nullptr; | ||||
3451 | if (IncompleteArrayType *iat = | ||||
3452 | IncompleteArrayTypes.FindNodeOrInsertPos(ID, insertPos)) | ||||
3453 | return QualType(iat, 0); | ||||
3454 | |||||
3455 | // If the element type isn't canonical, this won't be a canonical type | ||||
3456 | // either, so fill in the canonical type field. We also have to pull | ||||
3457 | // qualifiers off the element type. | ||||
3458 | QualType canon; | ||||
3459 | |||||
3460 | if (!elementType.isCanonical() || elementType.hasLocalQualifiers()) { | ||||
3461 | SplitQualType canonSplit = getCanonicalType(elementType).split(); | ||||
3462 | canon = getIncompleteArrayType(QualType(canonSplit.Ty, 0), | ||||
3463 | ASM, elementTypeQuals); | ||||
3464 | canon = getQualifiedType(canon, canonSplit.Quals); | ||||
3465 | |||||
3466 | // Get the new insert position for the node we care about. | ||||
3467 | IncompleteArrayType *existing = | ||||
3468 | IncompleteArrayTypes.FindNodeOrInsertPos(ID, insertPos); | ||||
3469 | assert(!existing && "Shouldn't be in the map!")((!existing && "Shouldn't be in the map!") ? static_cast <void> (0) : __assert_fail ("!existing && \"Shouldn't be in the map!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 3469, __PRETTY_FUNCTION__)); (void) existing; | ||||
3470 | } | ||||
3471 | |||||
3472 | auto *newType = new (*this, TypeAlignment) | ||||
3473 | IncompleteArrayType(elementType, canon, ASM, elementTypeQuals); | ||||
3474 | |||||
3475 | IncompleteArrayTypes.InsertNode(newType, insertPos); | ||||
3476 | Types.push_back(newType); | ||||
3477 | return QualType(newType, 0); | ||||
3478 | } | ||||
3479 | |||||
3480 | /// getVectorType - Return the unique reference to a vector type of | ||||
3481 | /// the specified element type and size. VectorType must be a built-in type. | ||||
3482 | QualType ASTContext::getVectorType(QualType vecType, unsigned NumElts, | ||||
3483 | VectorType::VectorKind VecKind) const { | ||||
3484 | assert(vecType->isBuiltinType())((vecType->isBuiltinType()) ? static_cast<void> (0) : __assert_fail ("vecType->isBuiltinType()", "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 3484, __PRETTY_FUNCTION__)); | ||||
3485 | |||||
3486 | // Check if we've already instantiated a vector of this type. | ||||
3487 | llvm::FoldingSetNodeID ID; | ||||
3488 | VectorType::Profile(ID, vecType, NumElts, Type::Vector, VecKind); | ||||
3489 | |||||
3490 | void *InsertPos = nullptr; | ||||
3491 | if (VectorType *VTP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos)) | ||||
3492 | return QualType(VTP, 0); | ||||
3493 | |||||
3494 | // If the element type isn't canonical, this won't be a canonical type either, | ||||
3495 | // so fill in the canonical type field. | ||||
3496 | QualType Canonical; | ||||
3497 | if (!vecType.isCanonical()) { | ||||
3498 | Canonical = getVectorType(getCanonicalType(vecType), NumElts, VecKind); | ||||
3499 | |||||
3500 | // Get the new insert position for the node we care about. | ||||
3501 | VectorType *NewIP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos); | ||||
3502 | assert(!NewIP && "Shouldn't be in the map!")((!NewIP && "Shouldn't be in the map!") ? static_cast <void> (0) : __assert_fail ("!NewIP && \"Shouldn't be in the map!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 3502, __PRETTY_FUNCTION__)); (void)NewIP; | ||||
3503 | } | ||||
3504 | auto *New = new (*this, TypeAlignment) | ||||
3505 | VectorType(vecType, NumElts, Canonical, VecKind); | ||||
3506 | VectorTypes.InsertNode(New, InsertPos); | ||||
3507 | Types.push_back(New); | ||||
3508 | return QualType(New, 0); | ||||
3509 | } | ||||
3510 | |||||
3511 | QualType | ||||
3512 | ASTContext::getDependentVectorType(QualType VecType, Expr *SizeExpr, | ||||
3513 | SourceLocation AttrLoc, | ||||
3514 | VectorType::VectorKind VecKind) const { | ||||
3515 | llvm::FoldingSetNodeID ID; | ||||
3516 | DependentVectorType::Profile(ID, *this, getCanonicalType(VecType), SizeExpr, | ||||
3517 | VecKind); | ||||
3518 | void *InsertPos = nullptr; | ||||
3519 | DependentVectorType *Canon = | ||||
3520 | DependentVectorTypes.FindNodeOrInsertPos(ID, InsertPos); | ||||
3521 | DependentVectorType *New; | ||||
3522 | |||||
3523 | if (Canon) { | ||||
3524 | New = new (*this, TypeAlignment) DependentVectorType( | ||||
3525 | *this, VecType, QualType(Canon, 0), SizeExpr, AttrLoc, VecKind); | ||||
3526 | } else { | ||||
3527 | QualType CanonVecTy = getCanonicalType(VecType); | ||||
3528 | if (CanonVecTy == VecType) { | ||||
3529 | New = new (*this, TypeAlignment) DependentVectorType( | ||||
3530 | *this, VecType, QualType(), SizeExpr, AttrLoc, VecKind); | ||||
3531 | |||||
3532 | DependentVectorType *CanonCheck = | ||||
3533 | DependentVectorTypes.FindNodeOrInsertPos(ID, InsertPos); | ||||
3534 | assert(!CanonCheck &&((!CanonCheck && "Dependent-sized vector_size canonical type broken" ) ? static_cast<void> (0) : __assert_fail ("!CanonCheck && \"Dependent-sized vector_size canonical type broken\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 3535, __PRETTY_FUNCTION__)) | ||||
3535 | "Dependent-sized vector_size canonical type broken")((!CanonCheck && "Dependent-sized vector_size canonical type broken" ) ? static_cast<void> (0) : __assert_fail ("!CanonCheck && \"Dependent-sized vector_size canonical type broken\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 3535, __PRETTY_FUNCTION__)); | ||||
3536 | (void)CanonCheck; | ||||
3537 | DependentVectorTypes.InsertNode(New, InsertPos); | ||||
3538 | } else { | ||||
3539 | QualType Canon = getDependentSizedExtVectorType(CanonVecTy, SizeExpr, | ||||
3540 | SourceLocation()); | ||||
3541 | New = new (*this, TypeAlignment) DependentVectorType( | ||||
3542 | *this, VecType, Canon, SizeExpr, AttrLoc, VecKind); | ||||
3543 | } | ||||
3544 | } | ||||
3545 | |||||
3546 | Types.push_back(New); | ||||
3547 | return QualType(New, 0); | ||||
3548 | } | ||||
3549 | |||||
3550 | /// getExtVectorType - Return the unique reference to an extended vector type of | ||||
3551 | /// the specified element type and size. VectorType must be a built-in type. | ||||
3552 | QualType | ||||
3553 | ASTContext::getExtVectorType(QualType vecType, unsigned NumElts) const { | ||||
3554 | assert(vecType->isBuiltinType() || vecType->isDependentType())((vecType->isBuiltinType() || vecType->isDependentType( )) ? static_cast<void> (0) : __assert_fail ("vecType->isBuiltinType() || vecType->isDependentType()" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 3554, __PRETTY_FUNCTION__)); | ||||
3555 | |||||
3556 | // Check if we've already instantiated a vector of this type. | ||||
3557 | llvm::FoldingSetNodeID ID; | ||||
3558 | VectorType::Profile(ID, vecType, NumElts, Type::ExtVector, | ||||
3559 | VectorType::GenericVector); | ||||
3560 | void *InsertPos = nullptr; | ||||
3561 | if (VectorType *VTP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos)) | ||||
3562 | return QualType(VTP, 0); | ||||
3563 | |||||
3564 | // If the element type isn't canonical, this won't be a canonical type either, | ||||
3565 | // so fill in the canonical type field. | ||||
3566 | QualType Canonical; | ||||
3567 | if (!vecType.isCanonical()) { | ||||
3568 | Canonical = getExtVectorType(getCanonicalType(vecType), NumElts); | ||||
3569 | |||||
3570 | // Get the new insert position for the node we care about. | ||||
3571 | VectorType *NewIP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos); | ||||
3572 | assert(!NewIP && "Shouldn't be in the map!")((!NewIP && "Shouldn't be in the map!") ? static_cast <void> (0) : __assert_fail ("!NewIP && \"Shouldn't be in the map!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 3572, __PRETTY_FUNCTION__)); (void)NewIP; | ||||
3573 | } | ||||
3574 | auto *New = new (*this, TypeAlignment) | ||||
3575 | ExtVectorType(vecType, NumElts, Canonical); | ||||
3576 | VectorTypes.InsertNode(New, InsertPos); | ||||
3577 | Types.push_back(New); | ||||
3578 | return QualType(New, 0); | ||||
3579 | } | ||||
3580 | |||||
3581 | QualType | ||||
3582 | ASTContext::getDependentSizedExtVectorType(QualType vecType, | ||||
3583 | Expr *SizeExpr, | ||||
3584 | SourceLocation AttrLoc) const { | ||||
3585 | llvm::FoldingSetNodeID ID; | ||||
3586 | DependentSizedExtVectorType::Profile(ID, *this, getCanonicalType(vecType), | ||||
3587 | SizeExpr); | ||||
3588 | |||||
3589 | void *InsertPos = nullptr; | ||||
3590 | DependentSizedExtVectorType *Canon | ||||
3591 | = DependentSizedExtVectorTypes.FindNodeOrInsertPos(ID, InsertPos); | ||||
3592 | DependentSizedExtVectorType *New; | ||||
3593 | if (Canon) { | ||||
3594 | // We already have a canonical version of this array type; use it as | ||||
3595 | // the canonical type for a newly-built type. | ||||
3596 | New = new (*this, TypeAlignment) | ||||
3597 | DependentSizedExtVectorType(*this, vecType, QualType(Canon, 0), | ||||
3598 | SizeExpr, AttrLoc); | ||||
3599 | } else { | ||||
3600 | QualType CanonVecTy = getCanonicalType(vecType); | ||||
3601 | if (CanonVecTy == vecType) { | ||||
3602 | New = new (*this, TypeAlignment) | ||||
3603 | DependentSizedExtVectorType(*this, vecType, QualType(), SizeExpr, | ||||
3604 | AttrLoc); | ||||
3605 | |||||
3606 | DependentSizedExtVectorType *CanonCheck | ||||
3607 | = DependentSizedExtVectorTypes.FindNodeOrInsertPos(ID, InsertPos); | ||||
3608 | assert(!CanonCheck && "Dependent-sized ext_vector canonical type broken")((!CanonCheck && "Dependent-sized ext_vector canonical type broken" ) ? static_cast<void> (0) : __assert_fail ("!CanonCheck && \"Dependent-sized ext_vector canonical type broken\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 3608, __PRETTY_FUNCTION__)); | ||||
3609 | (void)CanonCheck; | ||||
3610 | DependentSizedExtVectorTypes.InsertNode(New, InsertPos); | ||||
3611 | } else { | ||||
3612 | QualType Canon = getDependentSizedExtVectorType(CanonVecTy, SizeExpr, | ||||
3613 | SourceLocation()); | ||||
3614 | New = new (*this, TypeAlignment) | ||||
3615 | DependentSizedExtVectorType(*this, vecType, Canon, SizeExpr, AttrLoc); | ||||
3616 | } | ||||
3617 | } | ||||
3618 | |||||
3619 | Types.push_back(New); | ||||
3620 | return QualType(New, 0); | ||||
3621 | } | ||||
3622 | |||||
3623 | QualType ASTContext::getDependentAddressSpaceType(QualType PointeeType, | ||||
3624 | Expr *AddrSpaceExpr, | ||||
3625 | SourceLocation AttrLoc) const { | ||||
3626 | assert(AddrSpaceExpr->isInstantiationDependent())((AddrSpaceExpr->isInstantiationDependent()) ? static_cast <void> (0) : __assert_fail ("AddrSpaceExpr->isInstantiationDependent()" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 3626, __PRETTY_FUNCTION__)); | ||||
3627 | |||||
3628 | QualType canonPointeeType = getCanonicalType(PointeeType); | ||||
3629 | |||||
3630 | void *insertPos = nullptr; | ||||
3631 | llvm::FoldingSetNodeID ID; | ||||
3632 | DependentAddressSpaceType::Profile(ID, *this, canonPointeeType, | ||||
3633 | AddrSpaceExpr); | ||||
3634 | |||||
3635 | DependentAddressSpaceType *canonTy = | ||||
3636 | DependentAddressSpaceTypes.FindNodeOrInsertPos(ID, insertPos); | ||||
3637 | |||||
3638 | if (!canonTy) { | ||||
3639 | canonTy = new (*this, TypeAlignment) | ||||
3640 | DependentAddressSpaceType(*this, canonPointeeType, | ||||
3641 | QualType(), AddrSpaceExpr, AttrLoc); | ||||
3642 | DependentAddressSpaceTypes.InsertNode(canonTy, insertPos); | ||||
3643 | Types.push_back(canonTy); | ||||
3644 | } | ||||
3645 | |||||
3646 | if (canonPointeeType == PointeeType && | ||||
3647 | canonTy->getAddrSpaceExpr() == AddrSpaceExpr) | ||||
3648 | return QualType(canonTy, 0); | ||||
3649 | |||||
3650 | auto *sugaredType | ||||
3651 | = new (*this, TypeAlignment) | ||||
3652 | DependentAddressSpaceType(*this, PointeeType, QualType(canonTy, 0), | ||||
3653 | AddrSpaceExpr, AttrLoc); | ||||
3654 | Types.push_back(sugaredType); | ||||
3655 | return QualType(sugaredType, 0); | ||||
3656 | } | ||||
3657 | |||||
3658 | /// Determine whether \p T is canonical as the result type of a function. | ||||
3659 | static bool isCanonicalResultType(QualType T) { | ||||
3660 | return T.isCanonical() && | ||||
3661 | (T.getObjCLifetime() == Qualifiers::OCL_None || | ||||
3662 | T.getObjCLifetime() == Qualifiers::OCL_ExplicitNone); | ||||
3663 | } | ||||
3664 | |||||
3665 | /// getFunctionNoProtoType - Return a K&R style C function type like 'int()'. | ||||
3666 | QualType | ||||
3667 | ASTContext::getFunctionNoProtoType(QualType ResultTy, | ||||
3668 | const FunctionType::ExtInfo &Info) const { | ||||
3669 | // Unique functions, to guarantee there is only one function of a particular | ||||
3670 | // structure. | ||||
3671 | llvm::FoldingSetNodeID ID; | ||||
3672 | FunctionNoProtoType::Profile(ID, ResultTy, Info); | ||||
3673 | |||||
3674 | void *InsertPos = nullptr; | ||||
3675 | if (FunctionNoProtoType *FT = | ||||
3676 | FunctionNoProtoTypes.FindNodeOrInsertPos(ID, InsertPos)) | ||||
3677 | return QualType(FT, 0); | ||||
3678 | |||||
3679 | QualType Canonical; | ||||
3680 | if (!isCanonicalResultType(ResultTy)) { | ||||
3681 | Canonical = | ||||
3682 | getFunctionNoProtoType(getCanonicalFunctionResultType(ResultTy), Info); | ||||
3683 | |||||
3684 | // Get the new insert position for the node we care about. | ||||
3685 | FunctionNoProtoType *NewIP = | ||||
3686 | FunctionNoProtoTypes.FindNodeOrInsertPos(ID, InsertPos); | ||||
3687 | assert(!NewIP && "Shouldn't be in the map!")((!NewIP && "Shouldn't be in the map!") ? static_cast <void> (0) : __assert_fail ("!NewIP && \"Shouldn't be in the map!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 3687, __PRETTY_FUNCTION__)); (void)NewIP; | ||||
3688 | } | ||||
3689 | |||||
3690 | auto *New = new (*this, TypeAlignment) | ||||
3691 | FunctionNoProtoType(ResultTy, Canonical, Info); | ||||
3692 | Types.push_back(New); | ||||
3693 | FunctionNoProtoTypes.InsertNode(New, InsertPos); | ||||
3694 | return QualType(New, 0); | ||||
3695 | } | ||||
3696 | |||||
3697 | CanQualType | ||||
3698 | ASTContext::getCanonicalFunctionResultType(QualType ResultType) const { | ||||
3699 | CanQualType CanResultType = getCanonicalType(ResultType); | ||||
3700 | |||||
3701 | // Canonical result types do not have ARC lifetime qualifiers. | ||||
3702 | if (CanResultType.getQualifiers().hasObjCLifetime()) { | ||||
3703 | Qualifiers Qs = CanResultType.getQualifiers(); | ||||
3704 | Qs.removeObjCLifetime(); | ||||
3705 | return CanQualType::CreateUnsafe( | ||||
3706 | getQualifiedType(CanResultType.getUnqualifiedType(), Qs)); | ||||
3707 | } | ||||
3708 | |||||
3709 | return CanResultType; | ||||
3710 | } | ||||
3711 | |||||
3712 | static bool isCanonicalExceptionSpecification( | ||||
3713 | const FunctionProtoType::ExceptionSpecInfo &ESI, bool NoexceptInType) { | ||||
3714 | if (ESI.Type == EST_None) | ||||
3715 | return true; | ||||
3716 | if (!NoexceptInType) | ||||
3717 | return false; | ||||
3718 | |||||
3719 | // C++17 onwards: exception specification is part of the type, as a simple | ||||
3720 | // boolean "can this function type throw". | ||||
3721 | if (ESI.Type == EST_BasicNoexcept) | ||||
3722 | return true; | ||||
3723 | |||||
3724 | // A noexcept(expr) specification is (possibly) canonical if expr is | ||||
3725 | // value-dependent. | ||||
3726 | if (ESI.Type == EST_DependentNoexcept) | ||||
3727 | return true; | ||||
3728 | |||||
3729 | // A dynamic exception specification is canonical if it only contains pack | ||||
3730 | // expansions (so we can't tell whether it's non-throwing) and all its | ||||
3731 | // contained types are canonical. | ||||
3732 | if (ESI.Type == EST_Dynamic) { | ||||
3733 | bool AnyPackExpansions = false; | ||||
3734 | for (QualType ET : ESI.Exceptions) { | ||||
3735 | if (!ET.isCanonical()) | ||||
3736 | return false; | ||||
3737 | if (ET->getAs<PackExpansionType>()) | ||||
3738 | AnyPackExpansions = true; | ||||
3739 | } | ||||
3740 | return AnyPackExpansions; | ||||
3741 | } | ||||
3742 | |||||
3743 | return false; | ||||
3744 | } | ||||
3745 | |||||
3746 | QualType ASTContext::getFunctionTypeInternal( | ||||
3747 | QualType ResultTy, ArrayRef<QualType> ArgArray, | ||||
3748 | const FunctionProtoType::ExtProtoInfo &EPI, bool OnlyWantCanonical) const { | ||||
3749 | size_t NumArgs = ArgArray.size(); | ||||
3750 | |||||
3751 | // Unique functions, to guarantee there is only one function of a particular | ||||
3752 | // structure. | ||||
3753 | llvm::FoldingSetNodeID ID; | ||||
3754 | FunctionProtoType::Profile(ID, ResultTy, ArgArray.begin(), NumArgs, EPI, | ||||
3755 | *this, true); | ||||
3756 | |||||
3757 | QualType Canonical; | ||||
3758 | bool Unique = false; | ||||
3759 | |||||
3760 | void *InsertPos = nullptr; | ||||
3761 | if (FunctionProtoType *FPT = | ||||
3762 | FunctionProtoTypes.FindNodeOrInsertPos(ID, InsertPos)) { | ||||
3763 | QualType Existing = QualType(FPT, 0); | ||||
3764 | |||||
3765 | // If we find a pre-existing equivalent FunctionProtoType, we can just reuse | ||||
3766 | // it so long as our exception specification doesn't contain a dependent | ||||
3767 | // noexcept expression, or we're just looking for a canonical type. | ||||
3768 | // Otherwise, we're going to need to create a type | ||||
3769 | // sugar node to hold the concrete expression. | ||||
3770 | if (OnlyWantCanonical || !isComputedNoexcept(EPI.ExceptionSpec.Type) || | ||||
3771 | EPI.ExceptionSpec.NoexceptExpr == FPT->getNoexceptExpr()) | ||||
3772 | return Existing; | ||||
3773 | |||||
3774 | // We need a new type sugar node for this one, to hold the new noexcept | ||||
3775 | // expression. We do no canonicalization here, but that's OK since we don't | ||||
3776 | // expect to see the same noexcept expression much more than once. | ||||
3777 | Canonical = getCanonicalType(Existing); | ||||
3778 | Unique = true; | ||||
3779 | } | ||||
3780 | |||||
3781 | bool NoexceptInType = getLangOpts().CPlusPlus17; | ||||
3782 | bool IsCanonicalExceptionSpec = | ||||
3783 | isCanonicalExceptionSpecification(EPI.ExceptionSpec, NoexceptInType); | ||||
3784 | |||||
3785 | // Determine whether the type being created is already canonical or not. | ||||
3786 | bool isCanonical = !Unique && IsCanonicalExceptionSpec && | ||||
3787 | isCanonicalResultType(ResultTy) && !EPI.HasTrailingReturn; | ||||
3788 | for (unsigned i = 0; i != NumArgs && isCanonical; ++i) | ||||
3789 | if (!ArgArray[i].isCanonicalAsParam()) | ||||
3790 | isCanonical = false; | ||||
3791 | |||||
3792 | if (OnlyWantCanonical) | ||||
3793 | assert(isCanonical &&((isCanonical && "given non-canonical parameters constructing canonical type" ) ? static_cast<void> (0) : __assert_fail ("isCanonical && \"given non-canonical parameters constructing canonical type\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 3794, __PRETTY_FUNCTION__)) | ||||
3794 | "given non-canonical parameters constructing canonical type")((isCanonical && "given non-canonical parameters constructing canonical type" ) ? static_cast<void> (0) : __assert_fail ("isCanonical && \"given non-canonical parameters constructing canonical type\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 3794, __PRETTY_FUNCTION__)); | ||||
3795 | |||||
3796 | // If this type isn't canonical, get the canonical version of it if we don't | ||||
3797 | // already have it. The exception spec is only partially part of the | ||||
3798 | // canonical type, and only in C++17 onwards. | ||||
3799 | if (!isCanonical && Canonical.isNull()) { | ||||
3800 | SmallVector<QualType, 16> CanonicalArgs; | ||||
3801 | CanonicalArgs.reserve(NumArgs); | ||||
3802 | for (unsigned i = 0; i != NumArgs; ++i) | ||||
3803 | CanonicalArgs.push_back(getCanonicalParamType(ArgArray[i])); | ||||
3804 | |||||
3805 | llvm::SmallVector<QualType, 8> ExceptionTypeStorage; | ||||
3806 | FunctionProtoType::ExtProtoInfo CanonicalEPI = EPI; | ||||
3807 | CanonicalEPI.HasTrailingReturn = false; | ||||
3808 | |||||
3809 | if (IsCanonicalExceptionSpec) { | ||||
3810 | // Exception spec is already OK. | ||||
3811 | } else if (NoexceptInType) { | ||||
3812 | switch (EPI.ExceptionSpec.Type) { | ||||
3813 | case EST_Unparsed: case EST_Unevaluated: case EST_Uninstantiated: | ||||
3814 | // We don't know yet. It shouldn't matter what we pick here; no-one | ||||
3815 | // should ever look at this. | ||||
3816 | LLVM_FALLTHROUGH[[gnu::fallthrough]]; | ||||
3817 | case EST_None: case EST_MSAny: case EST_NoexceptFalse: | ||||
3818 | CanonicalEPI.ExceptionSpec.Type = EST_None; | ||||
3819 | break; | ||||
3820 | |||||
3821 | // A dynamic exception specification is almost always "not noexcept", | ||||
3822 | // with the exception that a pack expansion might expand to no types. | ||||
3823 | case EST_Dynamic: { | ||||
3824 | bool AnyPacks = false; | ||||
3825 | for (QualType ET : EPI.ExceptionSpec.Exceptions) { | ||||
3826 | if (ET->getAs<PackExpansionType>()) | ||||
3827 | AnyPacks = true; | ||||
3828 | ExceptionTypeStorage.push_back(getCanonicalType(ET)); | ||||
3829 | } | ||||
3830 | if (!AnyPacks) | ||||
3831 | CanonicalEPI.ExceptionSpec.Type = EST_None; | ||||
3832 | else { | ||||
3833 | CanonicalEPI.ExceptionSpec.Type = EST_Dynamic; | ||||
3834 | CanonicalEPI.ExceptionSpec.Exceptions = ExceptionTypeStorage; | ||||
3835 | } | ||||
3836 | break; | ||||
3837 | } | ||||
3838 | |||||
3839 | case EST_DynamicNone: | ||||
3840 | case EST_BasicNoexcept: | ||||
3841 | case EST_NoexceptTrue: | ||||
3842 | case EST_NoThrow: | ||||
3843 | CanonicalEPI.ExceptionSpec.Type = EST_BasicNoexcept; | ||||
3844 | break; | ||||
3845 | |||||
3846 | case EST_DependentNoexcept: | ||||
3847 | llvm_unreachable("dependent noexcept is already canonical")::llvm::llvm_unreachable_internal("dependent noexcept is already canonical" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 3847); | ||||
3848 | } | ||||
3849 | } else { | ||||
3850 | CanonicalEPI.ExceptionSpec = FunctionProtoType::ExceptionSpecInfo(); | ||||
3851 | } | ||||
3852 | |||||
3853 | // Adjust the canonical function result type. | ||||
3854 | CanQualType CanResultTy = getCanonicalFunctionResultType(ResultTy); | ||||
3855 | Canonical = | ||||
3856 | getFunctionTypeInternal(CanResultTy, CanonicalArgs, CanonicalEPI, true); | ||||
3857 | |||||
3858 | // Get the new insert position for the node we care about. | ||||
3859 | FunctionProtoType *NewIP = | ||||
3860 | FunctionProtoTypes.FindNodeOrInsertPos(ID, InsertPos); | ||||
3861 | assert(!NewIP && "Shouldn't be in the map!")((!NewIP && "Shouldn't be in the map!") ? static_cast <void> (0) : __assert_fail ("!NewIP && \"Shouldn't be in the map!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 3861, __PRETTY_FUNCTION__)); (void)NewIP; | ||||
3862 | } | ||||
3863 | |||||
3864 | // Compute the needed size to hold this FunctionProtoType and the | ||||
3865 | // various trailing objects. | ||||
3866 | auto ESH = FunctionProtoType::getExceptionSpecSize( | ||||
3867 | EPI.ExceptionSpec.Type, EPI.ExceptionSpec.Exceptions.size()); | ||||
3868 | size_t Size = FunctionProtoType::totalSizeToAlloc< | ||||
3869 | QualType, FunctionType::FunctionTypeExtraBitfields, | ||||
3870 | FunctionType::ExceptionType, Expr *, FunctionDecl *, | ||||
3871 | FunctionProtoType::ExtParameterInfo, Qualifiers>( | ||||
3872 | NumArgs, FunctionProtoType::hasExtraBitfields(EPI.ExceptionSpec.Type), | ||||
3873 | ESH.NumExceptionType, ESH.NumExprPtr, ESH.NumFunctionDeclPtr, | ||||
3874 | EPI.ExtParameterInfos ? NumArgs : 0, | ||||
3875 | EPI.TypeQuals.hasNonFastQualifiers() ? 1 : 0); | ||||
3876 | |||||
3877 | auto *FTP = (FunctionProtoType *)Allocate(Size, TypeAlignment); | ||||
3878 | FunctionProtoType::ExtProtoInfo newEPI = EPI; | ||||
3879 | new (FTP) FunctionProtoType(ResultTy, ArgArray, Canonical, newEPI); | ||||
3880 | Types.push_back(FTP); | ||||
3881 | if (!Unique) | ||||
3882 | FunctionProtoTypes.InsertNode(FTP, InsertPos); | ||||
3883 | return QualType(FTP, 0); | ||||
3884 | } | ||||
3885 | |||||
3886 | QualType ASTContext::getPipeType(QualType T, bool ReadOnly) const { | ||||
3887 | llvm::FoldingSetNodeID ID; | ||||
3888 | PipeType::Profile(ID, T, ReadOnly); | ||||
3889 | |||||
3890 | void *InsertPos = nullptr; | ||||
3891 | if (PipeType *PT = PipeTypes.FindNodeOrInsertPos(ID, InsertPos)) | ||||
3892 | return QualType(PT, 0); | ||||
3893 | |||||
3894 | // If the pipe element type isn't canonical, this won't be a canonical type | ||||
3895 | // either, so fill in the canonical type field. | ||||
3896 | QualType Canonical; | ||||
3897 | if (!T.isCanonical()) { | ||||
3898 | Canonical = getPipeType(getCanonicalType(T), ReadOnly); | ||||
3899 | |||||
3900 | // Get the new insert position for the node we care about. | ||||
3901 | PipeType *NewIP = PipeTypes.FindNodeOrInsertPos(ID, InsertPos); | ||||
3902 | assert(!NewIP && "Shouldn't be in the map!")((!NewIP && "Shouldn't be in the map!") ? static_cast <void> (0) : __assert_fail ("!NewIP && \"Shouldn't be in the map!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 3902, __PRETTY_FUNCTION__)); | ||||
3903 | (void)NewIP; | ||||
3904 | } | ||||
3905 | auto *New = new (*this, TypeAlignment) PipeType(T, Canonical, ReadOnly); | ||||
3906 | Types.push_back(New); | ||||
3907 | PipeTypes.InsertNode(New, InsertPos); | ||||
3908 | return QualType(New, 0); | ||||
3909 | } | ||||
3910 | |||||
3911 | QualType ASTContext::adjustStringLiteralBaseType(QualType Ty) const { | ||||
3912 | // OpenCL v1.1 s6.5.3: a string literal is in the constant address space. | ||||
3913 | return LangOpts.OpenCL ? getAddrSpaceQualType(Ty, LangAS::opencl_constant) | ||||
3914 | : Ty; | ||||
3915 | } | ||||
3916 | |||||
3917 | QualType ASTContext::getReadPipeType(QualType T) const { | ||||
3918 | return getPipeType(T, true); | ||||
3919 | } | ||||
3920 | |||||
3921 | QualType ASTContext::getWritePipeType(QualType T) const { | ||||
3922 | return getPipeType(T, false); | ||||
3923 | } | ||||
3924 | |||||
3925 | #ifndef NDEBUG | ||||
3926 | static bool NeedsInjectedClassNameType(const RecordDecl *D) { | ||||
3927 | if (!isa<CXXRecordDecl>(D)) return false; | ||||
3928 | const auto *RD = cast<CXXRecordDecl>(D); | ||||
3929 | if (isa<ClassTemplatePartialSpecializationDecl>(RD)) | ||||
3930 | return true; | ||||
3931 | if (RD->getDescribedClassTemplate() && | ||||
3932 | !isa<ClassTemplateSpecializationDecl>(RD)) | ||||
3933 | return true; | ||||
3934 | return false; | ||||
3935 | } | ||||
3936 | #endif | ||||
3937 | |||||
3938 | /// getInjectedClassNameType - Return the unique reference to the | ||||
3939 | /// injected class name type for the specified templated declaration. | ||||
3940 | QualType ASTContext::getInjectedClassNameType(CXXRecordDecl *Decl, | ||||
3941 | QualType TST) const { | ||||
3942 | assert(NeedsInjectedClassNameType(Decl))((NeedsInjectedClassNameType(Decl)) ? static_cast<void> (0) : __assert_fail ("NeedsInjectedClassNameType(Decl)", "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 3942, __PRETTY_FUNCTION__)); | ||||
3943 | if (Decl->TypeForDecl) { | ||||
3944 | assert(isa<InjectedClassNameType>(Decl->TypeForDecl))((isa<InjectedClassNameType>(Decl->TypeForDecl)) ? static_cast <void> (0) : __assert_fail ("isa<InjectedClassNameType>(Decl->TypeForDecl)" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 3944, __PRETTY_FUNCTION__)); | ||||
3945 | } else if (CXXRecordDecl *PrevDecl = Decl->getPreviousDecl()) { | ||||
3946 | assert(PrevDecl->TypeForDecl && "previous declaration has no type")((PrevDecl->TypeForDecl && "previous declaration has no type" ) ? static_cast<void> (0) : __assert_fail ("PrevDecl->TypeForDecl && \"previous declaration has no type\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 3946, __PRETTY_FUNCTION__)); | ||||
3947 | Decl->TypeForDecl = PrevDecl->TypeForDecl; | ||||
3948 | assert(isa<InjectedClassNameType>(Decl->TypeForDecl))((isa<InjectedClassNameType>(Decl->TypeForDecl)) ? static_cast <void> (0) : __assert_fail ("isa<InjectedClassNameType>(Decl->TypeForDecl)" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 3948, __PRETTY_FUNCTION__)); | ||||
3949 | } else { | ||||
3950 | Type *newType = | ||||
3951 | new (*this, TypeAlignment) InjectedClassNameType(Decl, TST); | ||||
3952 | Decl->TypeForDecl = newType; | ||||
3953 | Types.push_back(newType); | ||||
3954 | } | ||||
3955 | return QualType(Decl->TypeForDecl, 0); | ||||
3956 | } | ||||
3957 | |||||
3958 | /// getTypeDeclType - Return the unique reference to the type for the | ||||
3959 | /// specified type declaration. | ||||
3960 | QualType ASTContext::getTypeDeclTypeSlow(const TypeDecl *Decl) const { | ||||
3961 | assert(Decl && "Passed null for Decl param")((Decl && "Passed null for Decl param") ? static_cast <void> (0) : __assert_fail ("Decl && \"Passed null for Decl param\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 3961, __PRETTY_FUNCTION__)); | ||||
3962 | assert(!Decl->TypeForDecl && "TypeForDecl present in slow case")((!Decl->TypeForDecl && "TypeForDecl present in slow case" ) ? static_cast<void> (0) : __assert_fail ("!Decl->TypeForDecl && \"TypeForDecl present in slow case\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 3962, __PRETTY_FUNCTION__)); | ||||
3963 | |||||
3964 | if (const auto *Typedef = dyn_cast<TypedefNameDecl>(Decl)) | ||||
3965 | return getTypedefType(Typedef); | ||||
3966 | |||||
3967 | assert(!isa<TemplateTypeParmDecl>(Decl) &&((!isa<TemplateTypeParmDecl>(Decl) && "Template type parameter types are always available." ) ? static_cast<void> (0) : __assert_fail ("!isa<TemplateTypeParmDecl>(Decl) && \"Template type parameter types are always available.\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 3968, __PRETTY_FUNCTION__)) | ||||
3968 | "Template type parameter types are always available.")((!isa<TemplateTypeParmDecl>(Decl) && "Template type parameter types are always available." ) ? static_cast<void> (0) : __assert_fail ("!isa<TemplateTypeParmDecl>(Decl) && \"Template type parameter types are always available.\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 3968, __PRETTY_FUNCTION__)); | ||||
3969 | |||||
3970 | if (const auto *Record = dyn_cast<RecordDecl>(Decl)) { | ||||
3971 | assert(Record->isFirstDecl() && "struct/union has previous declaration")((Record->isFirstDecl() && "struct/union has previous declaration" ) ? static_cast<void> (0) : __assert_fail ("Record->isFirstDecl() && \"struct/union has previous declaration\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 3971, __PRETTY_FUNCTION__)); | ||||
3972 | assert(!NeedsInjectedClassNameType(Record))((!NeedsInjectedClassNameType(Record)) ? static_cast<void> (0) : __assert_fail ("!NeedsInjectedClassNameType(Record)", "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 3972, __PRETTY_FUNCTION__)); | ||||
3973 | return getRecordType(Record); | ||||
3974 | } else if (const auto *Enum = dyn_cast<EnumDecl>(Decl)) { | ||||
3975 | assert(Enum->isFirstDecl() && "enum has previous declaration")((Enum->isFirstDecl() && "enum has previous declaration" ) ? static_cast<void> (0) : __assert_fail ("Enum->isFirstDecl() && \"enum has previous declaration\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 3975, __PRETTY_FUNCTION__)); | ||||
3976 | return getEnumType(Enum); | ||||
3977 | } else if (const auto *Using = dyn_cast<UnresolvedUsingTypenameDecl>(Decl)) { | ||||
3978 | Type *newType = new (*this, TypeAlignment) UnresolvedUsingType(Using); | ||||
3979 | Decl->TypeForDecl = newType; | ||||
3980 | Types.push_back(newType); | ||||
3981 | } else | ||||
3982 | llvm_unreachable("TypeDecl without a type?")::llvm::llvm_unreachable_internal("TypeDecl without a type?", "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 3982); | ||||
3983 | |||||
3984 | return QualType(Decl->TypeForDecl, 0); | ||||
3985 | } | ||||
3986 | |||||
3987 | /// getTypedefType - Return the unique reference to the type for the | ||||
3988 | /// specified typedef name decl. | ||||
3989 | QualType | ||||
3990 | ASTContext::getTypedefType(const TypedefNameDecl *Decl, | ||||
3991 | QualType Canonical) const { | ||||
3992 | if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0); | ||||
3993 | |||||
3994 | if (Canonical.isNull()) | ||||
3995 | Canonical = getCanonicalType(Decl->getUnderlyingType()); | ||||
3996 | auto *newType = new (*this, TypeAlignment) | ||||
3997 | TypedefType(Type::Typedef, Decl, Canonical); | ||||
3998 | Decl->TypeForDecl = newType; | ||||
3999 | Types.push_back(newType); | ||||
4000 | return QualType(newType, 0); | ||||
4001 | } | ||||
4002 | |||||
4003 | QualType ASTContext::getRecordType(const RecordDecl *Decl) const { | ||||
4004 | if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0); | ||||
4005 | |||||
4006 | if (const RecordDecl *PrevDecl = Decl->getPreviousDecl()) | ||||
4007 | if (PrevDecl->TypeForDecl) | ||||
4008 | return QualType(Decl->TypeForDecl = PrevDecl->TypeForDecl, 0); | ||||
4009 | |||||
4010 | auto *newType = new (*this, TypeAlignment) RecordType(Decl); | ||||
4011 | Decl->TypeForDecl = newType; | ||||
4012 | Types.push_back(newType); | ||||
4013 | return QualType(newType, 0); | ||||
4014 | } | ||||
4015 | |||||
4016 | QualType ASTContext::getEnumType(const EnumDecl *Decl) const { | ||||
4017 | if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0); | ||||
4018 | |||||
4019 | if (const EnumDecl *PrevDecl = Decl->getPreviousDecl()) | ||||
4020 | if (PrevDecl->TypeForDecl) | ||||
4021 | return QualType(Decl->TypeForDecl = PrevDecl->TypeForDecl, 0); | ||||
4022 | |||||
4023 | auto *newType = new (*this, TypeAlignment) EnumType(Decl); | ||||
4024 | Decl->TypeForDecl = newType; | ||||
4025 | Types.push_back(newType); | ||||
4026 | return QualType(newType, 0); | ||||
4027 | } | ||||
4028 | |||||
4029 | QualType ASTContext::getAttributedType(attr::Kind attrKind, | ||||
4030 | QualType modifiedType, | ||||
4031 | QualType equivalentType) { | ||||
4032 | llvm::FoldingSetNodeID id; | ||||
4033 | AttributedType::Profile(id, attrKind, modifiedType, equivalentType); | ||||
4034 | |||||
4035 | void *insertPos = nullptr; | ||||
4036 | AttributedType *type = AttributedTypes.FindNodeOrInsertPos(id, insertPos); | ||||
4037 | if (type) return QualType(type, 0); | ||||
4038 | |||||
4039 | QualType canon = getCanonicalType(equivalentType); | ||||
4040 | type = new (*this, TypeAlignment) | ||||
4041 | AttributedType(canon, attrKind, modifiedType, equivalentType); | ||||
4042 | |||||
4043 | Types.push_back(type); | ||||
4044 | AttributedTypes.InsertNode(type, insertPos); | ||||
4045 | |||||
4046 | return QualType(type, 0); | ||||
4047 | } | ||||
4048 | |||||
4049 | /// Retrieve a substitution-result type. | ||||
4050 | QualType | ||||
4051 | ASTContext::getSubstTemplateTypeParmType(const TemplateTypeParmType *Parm, | ||||
4052 | QualType Replacement) const { | ||||
4053 | assert(Replacement.isCanonical()((Replacement.isCanonical() && "replacement types must always be canonical" ) ? static_cast<void> (0) : __assert_fail ("Replacement.isCanonical() && \"replacement types must always be canonical\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 4054, __PRETTY_FUNCTION__)) | ||||
4054 | && "replacement types must always be canonical")((Replacement.isCanonical() && "replacement types must always be canonical" ) ? static_cast<void> (0) : __assert_fail ("Replacement.isCanonical() && \"replacement types must always be canonical\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 4054, __PRETTY_FUNCTION__)); | ||||
4055 | |||||
4056 | llvm::FoldingSetNodeID ID; | ||||
4057 | SubstTemplateTypeParmType::Profile(ID, Parm, Replacement); | ||||
4058 | void *InsertPos = nullptr; | ||||
4059 | SubstTemplateTypeParmType *SubstParm | ||||
4060 | = SubstTemplateTypeParmTypes.FindNodeOrInsertPos(ID, InsertPos); | ||||
4061 | |||||
4062 | if (!SubstParm) { | ||||
4063 | SubstParm = new (*this, TypeAlignment) | ||||
4064 | SubstTemplateTypeParmType(Parm, Replacement); | ||||
4065 | Types.push_back(SubstParm); | ||||
4066 | SubstTemplateTypeParmTypes.InsertNode(SubstParm, InsertPos); | ||||
4067 | } | ||||
4068 | |||||
4069 | return QualType(SubstParm, 0); | ||||
4070 | } | ||||
4071 | |||||
4072 | /// Retrieve a | ||||
4073 | QualType ASTContext::getSubstTemplateTypeParmPackType( | ||||
4074 | const TemplateTypeParmType *Parm, | ||||
4075 | const TemplateArgument &ArgPack) { | ||||
4076 | #ifndef NDEBUG | ||||
4077 | for (const auto &P : ArgPack.pack_elements()) { | ||||
4078 | assert(P.getKind() == TemplateArgument::Type &&"Pack contains a non-type")((P.getKind() == TemplateArgument::Type &&"Pack contains a non-type" ) ? static_cast<void> (0) : __assert_fail ("P.getKind() == TemplateArgument::Type &&\"Pack contains a non-type\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 4078, __PRETTY_FUNCTION__)); | ||||
4079 | assert(P.getAsType().isCanonical() && "Pack contains non-canonical type")((P.getAsType().isCanonical() && "Pack contains non-canonical type" ) ? static_cast<void> (0) : __assert_fail ("P.getAsType().isCanonical() && \"Pack contains non-canonical type\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 4079, __PRETTY_FUNCTION__)); | ||||
4080 | } | ||||
4081 | #endif | ||||
4082 | |||||
4083 | llvm::FoldingSetNodeID ID; | ||||
4084 | SubstTemplateTypeParmPackType::Profile(ID, Parm, ArgPack); | ||||
4085 | void *InsertPos = nullptr; | ||||
4086 | if (SubstTemplateTypeParmPackType *SubstParm | ||||
4087 | = SubstTemplateTypeParmPackTypes.FindNodeOrInsertPos(ID, InsertPos)) | ||||
4088 | return QualType(SubstParm, 0); | ||||
4089 | |||||
4090 | QualType Canon; | ||||
4091 | if (!Parm->isCanonicalUnqualified()) { | ||||
4092 | Canon = getCanonicalType(QualType(Parm, 0)); | ||||
4093 | Canon = getSubstTemplateTypeParmPackType(cast<TemplateTypeParmType>(Canon), | ||||
4094 | ArgPack); | ||||
4095 | SubstTemplateTypeParmPackTypes.FindNodeOrInsertPos(ID, InsertPos); | ||||
4096 | } | ||||
4097 | |||||
4098 | auto *SubstParm | ||||
4099 | = new (*this, TypeAlignment) SubstTemplateTypeParmPackType(Parm, Canon, | ||||
4100 | ArgPack); | ||||
4101 | Types.push_back(SubstParm); | ||||
4102 | SubstTemplateTypeParmPackTypes.InsertNode(SubstParm, InsertPos); | ||||
4103 | return QualType(SubstParm, 0); | ||||
4104 | } | ||||
4105 | |||||
4106 | /// Retrieve the template type parameter type for a template | ||||
4107 | /// parameter or parameter pack with the given depth, index, and (optionally) | ||||
4108 | /// name. | ||||
4109 | QualType ASTContext::getTemplateTypeParmType(unsigned Depth, unsigned Index, | ||||
4110 | bool ParameterPack, | ||||
4111 | TemplateTypeParmDecl *TTPDecl) const { | ||||
4112 | llvm::FoldingSetNodeID ID; | ||||
4113 | TemplateTypeParmType::Profile(ID, Depth, Index, ParameterPack, TTPDecl); | ||||
4114 | void *InsertPos = nullptr; | ||||
4115 | TemplateTypeParmType *TypeParm | ||||
4116 | = TemplateTypeParmTypes.FindNodeOrInsertPos(ID, InsertPos); | ||||
4117 | |||||
4118 | if (TypeParm) | ||||
4119 | return QualType(TypeParm, 0); | ||||
4120 | |||||
4121 | if (TTPDecl) { | ||||
4122 | QualType Canon = getTemplateTypeParmType(Depth, Index, ParameterPack); | ||||
4123 | TypeParm = new (*this, TypeAlignment) TemplateTypeParmType(TTPDecl, Canon); | ||||
4124 | |||||
4125 | TemplateTypeParmType *TypeCheck | ||||
4126 | = TemplateTypeParmTypes.FindNodeOrInsertPos(ID, InsertPos); | ||||
4127 | assert(!TypeCheck && "Template type parameter canonical type broken")((!TypeCheck && "Template type parameter canonical type broken" ) ? static_cast<void> (0) : __assert_fail ("!TypeCheck && \"Template type parameter canonical type broken\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 4127, __PRETTY_FUNCTION__)); | ||||
4128 | (void)TypeCheck; | ||||
4129 | } else | ||||
4130 | TypeParm = new (*this, TypeAlignment) | ||||
4131 | TemplateTypeParmType(Depth, Index, ParameterPack); | ||||
4132 | |||||
4133 | Types.push_back(TypeParm); | ||||
4134 | TemplateTypeParmTypes.InsertNode(TypeParm, InsertPos); | ||||
4135 | |||||
4136 | return QualType(TypeParm, 0); | ||||
4137 | } | ||||
4138 | |||||
4139 | TypeSourceInfo * | ||||
4140 | ASTContext::getTemplateSpecializationTypeInfo(TemplateName Name, | ||||
4141 | SourceLocation NameLoc, | ||||
4142 | const TemplateArgumentListInfo &Args, | ||||
4143 | QualType Underlying) const { | ||||
4144 | assert(!Name.getAsDependentTemplateName() &&((!Name.getAsDependentTemplateName() && "No dependent template names here!" ) ? static_cast<void> (0) : __assert_fail ("!Name.getAsDependentTemplateName() && \"No dependent template names here!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 4145, __PRETTY_FUNCTION__)) | ||||
4145 | "No dependent template names here!")((!Name.getAsDependentTemplateName() && "No dependent template names here!" ) ? static_cast<void> (0) : __assert_fail ("!Name.getAsDependentTemplateName() && \"No dependent template names here!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 4145, __PRETTY_FUNCTION__)); | ||||
4146 | QualType TST = getTemplateSpecializationType(Name, Args, Underlying); | ||||
4147 | |||||
4148 | TypeSourceInfo *DI = CreateTypeSourceInfo(TST); | ||||
4149 | TemplateSpecializationTypeLoc TL = | ||||
4150 | DI->getTypeLoc().castAs<TemplateSpecializationTypeLoc>(); | ||||
4151 | TL.setTemplateKeywordLoc(SourceLocation()); | ||||
4152 | TL.setTemplateNameLoc(NameLoc); | ||||
4153 | TL.setLAngleLoc(Args.getLAngleLoc()); | ||||
4154 | TL.setRAngleLoc(Args.getRAngleLoc()); | ||||
4155 | for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) | ||||
4156 | TL.setArgLocInfo(i, Args[i].getLocInfo()); | ||||
4157 | return DI; | ||||
4158 | } | ||||
4159 | |||||
4160 | QualType | ||||
4161 | ASTContext::getTemplateSpecializationType(TemplateName Template, | ||||
4162 | const TemplateArgumentListInfo &Args, | ||||
4163 | QualType Underlying) const { | ||||
4164 | assert(!Template.getAsDependentTemplateName() &&((!Template.getAsDependentTemplateName() && "No dependent template names here!" ) ? static_cast<void> (0) : __assert_fail ("!Template.getAsDependentTemplateName() && \"No dependent template names here!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 4165, __PRETTY_FUNCTION__)) | ||||
4165 | "No dependent template names here!")((!Template.getAsDependentTemplateName() && "No dependent template names here!" ) ? static_cast<void> (0) : __assert_fail ("!Template.getAsDependentTemplateName() && \"No dependent template names here!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 4165, __PRETTY_FUNCTION__)); | ||||
4166 | |||||
4167 | SmallVector<TemplateArgument, 4> ArgVec; | ||||
4168 | ArgVec.reserve(Args.size()); | ||||
4169 | for (const TemplateArgumentLoc &Arg : Args.arguments()) | ||||
4170 | ArgVec.push_back(Arg.getArgument()); | ||||
4171 | |||||
4172 | return getTemplateSpecializationType(Template, ArgVec, Underlying); | ||||
4173 | } | ||||
4174 | |||||
4175 | #ifndef NDEBUG | ||||
4176 | static bool hasAnyPackExpansions(ArrayRef<TemplateArgument> Args) { | ||||
4177 | for (const TemplateArgument &Arg : Args) | ||||
4178 | if (Arg.isPackExpansion()) | ||||
4179 | return true; | ||||
4180 | |||||
4181 | return true; | ||||
4182 | } | ||||
4183 | #endif | ||||
4184 | |||||
4185 | QualType | ||||
4186 | ASTContext::getTemplateSpecializationType(TemplateName Template, | ||||
4187 | ArrayRef<TemplateArgument> Args, | ||||
4188 | QualType Underlying) const { | ||||
4189 | assert(!Template.getAsDependentTemplateName() &&((!Template.getAsDependentTemplateName() && "No dependent template names here!" ) ? static_cast<void> (0) : __assert_fail ("!Template.getAsDependentTemplateName() && \"No dependent template names here!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 4190, __PRETTY_FUNCTION__)) | ||||
4190 | "No dependent template names here!")((!Template.getAsDependentTemplateName() && "No dependent template names here!" ) ? static_cast<void> (0) : __assert_fail ("!Template.getAsDependentTemplateName() && \"No dependent template names here!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 4190, __PRETTY_FUNCTION__)); | ||||
4191 | // Look through qualified template names. | ||||
4192 | if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName()) | ||||
4193 | Template = TemplateName(QTN->getTemplateDecl()); | ||||
4194 | |||||
4195 | bool IsTypeAlias = | ||||
4196 | Template.getAsTemplateDecl() && | ||||
4197 | isa<TypeAliasTemplateDecl>(Template.getAsTemplateDecl()); | ||||
4198 | QualType CanonType; | ||||
4199 | if (!Underlying.isNull()) | ||||
4200 | CanonType = getCanonicalType(Underlying); | ||||
4201 | else { | ||||
4202 | // We can get here with an alias template when the specialization contains | ||||
4203 | // a pack expansion that does not match up with a parameter pack. | ||||
4204 | assert((!IsTypeAlias || hasAnyPackExpansions(Args)) &&(((!IsTypeAlias || hasAnyPackExpansions(Args)) && "Caller must compute aliased type" ) ? static_cast<void> (0) : __assert_fail ("(!IsTypeAlias || hasAnyPackExpansions(Args)) && \"Caller must compute aliased type\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 4205, __PRETTY_FUNCTION__)) | ||||
4205 | "Caller must compute aliased type")(((!IsTypeAlias || hasAnyPackExpansions(Args)) && "Caller must compute aliased type" ) ? static_cast<void> (0) : __assert_fail ("(!IsTypeAlias || hasAnyPackExpansions(Args)) && \"Caller must compute aliased type\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 4205, __PRETTY_FUNCTION__)); | ||||
4206 | IsTypeAlias = false; | ||||
4207 | CanonType = getCanonicalTemplateSpecializationType(Template, Args); | ||||
4208 | } | ||||
4209 | |||||
4210 | // Allocate the (non-canonical) template specialization type, but don't | ||||
4211 | // try to unique it: these types typically have location information that | ||||
4212 | // we don't unique and don't want to lose. | ||||
4213 | void *Mem = Allocate(sizeof(TemplateSpecializationType) + | ||||
4214 | sizeof(TemplateArgument) * Args.size() + | ||||
4215 | (IsTypeAlias? sizeof(QualType) : 0), | ||||
4216 | TypeAlignment); | ||||
4217 | auto *Spec | ||||
4218 | = new (Mem) TemplateSpecializationType(Template, Args, CanonType, | ||||
4219 | IsTypeAlias ? Underlying : QualType()); | ||||
4220 | |||||
4221 | Types.push_back(Spec); | ||||
4222 | return QualType(Spec, 0); | ||||
4223 | } | ||||
4224 | |||||
4225 | QualType ASTContext::getCanonicalTemplateSpecializationType( | ||||
4226 | TemplateName Template, ArrayRef<TemplateArgument> Args) const { | ||||
4227 | assert(!Template.getAsDependentTemplateName() &&((!Template.getAsDependentTemplateName() && "No dependent template names here!" ) ? static_cast<void> (0) : __assert_fail ("!Template.getAsDependentTemplateName() && \"No dependent template names here!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 4228, __PRETTY_FUNCTION__)) | ||||
4228 | "No dependent template names here!")((!Template.getAsDependentTemplateName() && "No dependent template names here!" ) ? static_cast<void> (0) : __assert_fail ("!Template.getAsDependentTemplateName() && \"No dependent template names here!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 4228, __PRETTY_FUNCTION__)); | ||||
4229 | |||||
4230 | // Look through qualified template names. | ||||
4231 | if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName()) | ||||
4232 | Template = TemplateName(QTN->getTemplateDecl()); | ||||
4233 | |||||
4234 | // Build the canonical template specialization type. | ||||
4235 | TemplateName CanonTemplate = getCanonicalTemplateName(Template); | ||||
4236 | SmallVector<TemplateArgument, 4> CanonArgs; | ||||
4237 | unsigned NumArgs = Args.size(); | ||||
4238 | CanonArgs.reserve(NumArgs); | ||||
4239 | for (const TemplateArgument &Arg : Args) | ||||
4240 | CanonArgs.push_back(getCanonicalTemplateArgument(Arg)); | ||||
4241 | |||||
4242 | // Determine whether this canonical template specialization type already | ||||
4243 | // exists. | ||||
4244 | llvm::FoldingSetNodeID ID; | ||||
4245 | TemplateSpecializationType::Profile(ID, CanonTemplate, | ||||
4246 | CanonArgs, *this); | ||||
4247 | |||||
4248 | void *InsertPos = nullptr; | ||||
4249 | TemplateSpecializationType *Spec | ||||
4250 | = TemplateSpecializationTypes.FindNodeOrInsertPos(ID, InsertPos); | ||||
4251 | |||||
4252 | if (!Spec) { | ||||
4253 | // Allocate a new canonical template specialization type. | ||||
4254 | void *Mem = Allocate((sizeof(TemplateSpecializationType) + | ||||
4255 | sizeof(TemplateArgument) * NumArgs), | ||||
4256 | TypeAlignment); | ||||
4257 | Spec = new (Mem) TemplateSpecializationType(CanonTemplate, | ||||
4258 | CanonArgs, | ||||
4259 | QualType(), QualType()); | ||||
4260 | Types.push_back(Spec); | ||||
4261 | TemplateSpecializationTypes.InsertNode(Spec, InsertPos); | ||||
4262 | } | ||||
4263 | |||||
4264 | assert(Spec->isDependentType() &&((Spec->isDependentType() && "Non-dependent template-id type must have a canonical type" ) ? static_cast<void> (0) : __assert_fail ("Spec->isDependentType() && \"Non-dependent template-id type must have a canonical type\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 4265, __PRETTY_FUNCTION__)) | ||||
4265 | "Non-dependent template-id type must have a canonical type")((Spec->isDependentType() && "Non-dependent template-id type must have a canonical type" ) ? static_cast<void> (0) : __assert_fail ("Spec->isDependentType() && \"Non-dependent template-id type must have a canonical type\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 4265, __PRETTY_FUNCTION__)); | ||||
4266 | return QualType(Spec, 0); | ||||
4267 | } | ||||
4268 | |||||
4269 | QualType ASTContext::getElaboratedType(ElaboratedTypeKeyword Keyword, | ||||
4270 | NestedNameSpecifier *NNS, | ||||
4271 | QualType NamedType, | ||||
4272 | TagDecl *OwnedTagDecl) const { | ||||
4273 | llvm::FoldingSetNodeID ID; | ||||
4274 | ElaboratedType::Profile(ID, Keyword, NNS, NamedType, OwnedTagDecl); | ||||
4275 | |||||
4276 | void *InsertPos = nullptr; | ||||
4277 | ElaboratedType *T = ElaboratedTypes.FindNodeOrInsertPos(ID, InsertPos); | ||||
4278 | if (T) | ||||
4279 | return QualType(T, 0); | ||||
4280 | |||||
4281 | QualType Canon = NamedType; | ||||
4282 | if (!Canon.isCanonical()) { | ||||
4283 | Canon = getCanonicalType(NamedType); | ||||
4284 | ElaboratedType *CheckT = ElaboratedTypes.FindNodeOrInsertPos(ID, InsertPos); | ||||
4285 | assert(!CheckT && "Elaborated canonical type broken")((!CheckT && "Elaborated canonical type broken") ? static_cast <void> (0) : __assert_fail ("!CheckT && \"Elaborated canonical type broken\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 4285, __PRETTY_FUNCTION__)); | ||||
4286 | (void)CheckT; | ||||
4287 | } | ||||
4288 | |||||
4289 | void *Mem = Allocate(ElaboratedType::totalSizeToAlloc<TagDecl *>(!!OwnedTagDecl), | ||||
4290 | TypeAlignment); | ||||
4291 | T = new (Mem) ElaboratedType(Keyword, NNS, NamedType, Canon, OwnedTagDecl); | ||||
4292 | |||||
4293 | Types.push_back(T); | ||||
4294 | ElaboratedTypes.InsertNode(T, InsertPos); | ||||
4295 | return QualType(T, 0); | ||||
4296 | } | ||||
4297 | |||||
4298 | QualType | ||||
4299 | ASTContext::getParenType(QualType InnerType) const { | ||||
4300 | llvm::FoldingSetNodeID ID; | ||||
4301 | ParenType::Profile(ID, InnerType); | ||||
4302 | |||||
4303 | void *InsertPos = nullptr; | ||||
4304 | ParenType *T = ParenTypes.FindNodeOrInsertPos(ID, InsertPos); | ||||
4305 | if (T) | ||||
4306 | return QualType(T, 0); | ||||
4307 | |||||
4308 | QualType Canon = InnerType; | ||||
4309 | if (!Canon.isCanonical()) { | ||||
4310 | Canon = getCanonicalType(InnerType); | ||||
4311 | ParenType *CheckT = ParenTypes.FindNodeOrInsertPos(ID, InsertPos); | ||||
4312 | assert(!CheckT && "Paren canonical type broken")((!CheckT && "Paren canonical type broken") ? static_cast <void> (0) : __assert_fail ("!CheckT && \"Paren canonical type broken\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 4312, __PRETTY_FUNCTION__)); | ||||
4313 | (void)CheckT; | ||||
4314 | } | ||||
4315 | |||||
4316 | T = new (*this, TypeAlignment) ParenType(InnerType, Canon); | ||||
4317 | Types.push_back(T); | ||||
4318 | ParenTypes.InsertNode(T, InsertPos); | ||||
4319 | return QualType(T, 0); | ||||
4320 | } | ||||
4321 | |||||
4322 | QualType | ||||
4323 | ASTContext::getMacroQualifiedType(QualType UnderlyingTy, | ||||
4324 | const IdentifierInfo *MacroII) const { | ||||
4325 | QualType Canon = UnderlyingTy; | ||||
4326 | if (!Canon.isCanonical()) | ||||
4327 | Canon = getCanonicalType(UnderlyingTy); | ||||
4328 | |||||
4329 | auto *newType = new (*this, TypeAlignment) | ||||
4330 | MacroQualifiedType(UnderlyingTy, Canon, MacroII); | ||||
4331 | Types.push_back(newType); | ||||
4332 | return QualType(newType, 0); | ||||
4333 | } | ||||
4334 | |||||
4335 | QualType ASTContext::getDependentNameType(ElaboratedTypeKeyword Keyword, | ||||
4336 | NestedNameSpecifier *NNS, | ||||
4337 | const IdentifierInfo *Name, | ||||
4338 | QualType Canon) const { | ||||
4339 | if (Canon.isNull()) { | ||||
4340 | NestedNameSpecifier *CanonNNS = getCanonicalNestedNameSpecifier(NNS); | ||||
4341 | if (CanonNNS != NNS) | ||||
4342 | Canon = getDependentNameType(Keyword, CanonNNS, Name); | ||||
4343 | } | ||||
4344 | |||||
4345 | llvm::FoldingSetNodeID ID; | ||||
4346 | DependentNameType::Profile(ID, Keyword, NNS, Name); | ||||
4347 | |||||
4348 | void *InsertPos = nullptr; | ||||
4349 | DependentNameType *T | ||||
4350 | = DependentNameTypes.FindNodeOrInsertPos(ID, InsertPos); | ||||
4351 | if (T) | ||||
4352 | return QualType(T, 0); | ||||
4353 | |||||
4354 | T = new (*this, TypeAlignment) DependentNameType(Keyword, NNS, Name, Canon); | ||||
4355 | Types.push_back(T); | ||||
4356 | DependentNameTypes.InsertNode(T, InsertPos); | ||||
4357 | return QualType(T, 0); | ||||
4358 | } | ||||
4359 | |||||
4360 | QualType | ||||
4361 | ASTContext::getDependentTemplateSpecializationType( | ||||
4362 | ElaboratedTypeKeyword Keyword, | ||||
4363 | NestedNameSpecifier *NNS, | ||||
4364 | const IdentifierInfo *Name, | ||||
4365 | const TemplateArgumentListInfo &Args) const { | ||||
4366 | // TODO: avoid this copy | ||||
4367 | SmallVector<TemplateArgument, 16> ArgCopy; | ||||
4368 | for (unsigned I = 0, E = Args.size(); I != E; ++I) | ||||
4369 | ArgCopy.push_back(Args[I].getArgument()); | ||||
4370 | return getDependentTemplateSpecializationType(Keyword, NNS, Name, ArgCopy); | ||||
4371 | } | ||||
4372 | |||||
4373 | QualType | ||||
4374 | ASTContext::getDependentTemplateSpecializationType( | ||||
4375 | ElaboratedTypeKeyword Keyword, | ||||
4376 | NestedNameSpecifier *NNS, | ||||
4377 | const IdentifierInfo *Name, | ||||
4378 | ArrayRef<TemplateArgument> Args) const { | ||||
4379 | assert((!NNS || NNS->isDependent()) &&(((!NNS || NNS->isDependent()) && "nested-name-specifier must be dependent" ) ? static_cast<void> (0) : __assert_fail ("(!NNS || NNS->isDependent()) && \"nested-name-specifier must be dependent\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 4380, __PRETTY_FUNCTION__)) | ||||
4380 | "nested-name-specifier must be dependent")(((!NNS || NNS->isDependent()) && "nested-name-specifier must be dependent" ) ? static_cast<void> (0) : __assert_fail ("(!NNS || NNS->isDependent()) && \"nested-name-specifier must be dependent\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 4380, __PRETTY_FUNCTION__)); | ||||
4381 | |||||
4382 | llvm::FoldingSetNodeID ID; | ||||
4383 | DependentTemplateSpecializationType::Profile(ID, *this, Keyword, NNS, | ||||
4384 | Name, Args); | ||||
4385 | |||||
4386 | void *InsertPos = nullptr; | ||||
4387 | DependentTemplateSpecializationType *T | ||||
4388 | = DependentTemplateSpecializationTypes.FindNodeOrInsertPos(ID, InsertPos); | ||||
4389 | if (T) | ||||
4390 | return QualType(T, 0); | ||||
4391 | |||||
4392 | NestedNameSpecifier *CanonNNS = getCanonicalNestedNameSpecifier(NNS); | ||||
4393 | |||||
4394 | ElaboratedTypeKeyword CanonKeyword = Keyword; | ||||
4395 | if (Keyword == ETK_None) CanonKeyword = ETK_Typename; | ||||
4396 | |||||
4397 | bool AnyNonCanonArgs = false; | ||||
4398 | unsigned NumArgs = Args.size(); | ||||
4399 | SmallVector<TemplateArgument, 16> CanonArgs(NumArgs); | ||||
4400 | for (unsigned I = 0; I != NumArgs; ++I) { | ||||
4401 | CanonArgs[I] = getCanonicalTemplateArgument(Args[I]); | ||||
4402 | if (!CanonArgs[I].structurallyEquals(Args[I])) | ||||
4403 | AnyNonCanonArgs = true; | ||||
4404 | } | ||||
4405 | |||||
4406 | QualType Canon; | ||||
4407 | if (AnyNonCanonArgs || CanonNNS != NNS || CanonKeyword != Keyword) { | ||||
4408 | Canon = getDependentTemplateSpecializationType(CanonKeyword, CanonNNS, | ||||
4409 | Name, | ||||
4410 | CanonArgs); | ||||
4411 | |||||
4412 | // Find the insert position again. | ||||
4413 | DependentTemplateSpecializationTypes.FindNodeOrInsertPos(ID, InsertPos); | ||||
4414 | } | ||||
4415 | |||||
4416 | void *Mem = Allocate((sizeof(DependentTemplateSpecializationType) + | ||||
4417 | sizeof(TemplateArgument) * NumArgs), | ||||
4418 | TypeAlignment); | ||||
4419 | T = new (Mem) DependentTemplateSpecializationType(Keyword, NNS, | ||||
4420 | Name, Args, Canon); | ||||
4421 | Types.push_back(T); | ||||
4422 | DependentTemplateSpecializationTypes.InsertNode(T, InsertPos); | ||||
4423 | return QualType(T, 0); | ||||
4424 | } | ||||
4425 | |||||
4426 | TemplateArgument ASTContext::getInjectedTemplateArg(NamedDecl *Param) { | ||||
4427 | TemplateArgument Arg; | ||||
4428 | if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) { | ||||
4429 | QualType ArgType = getTypeDeclType(TTP); | ||||
4430 | if (TTP->isParameterPack()) | ||||
4431 | ArgType = getPackExpansionType(ArgType, None); | ||||
4432 | |||||
4433 | Arg = TemplateArgument(ArgType); | ||||
4434 | } else if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) { | ||||
4435 | Expr *E = new (*this) DeclRefExpr( | ||||
4436 | *this, NTTP, /*enclosing*/ false, | ||||
4437 | NTTP->getType().getNonLValueExprType(*this), | ||||
4438 | Expr::getValueKindForType(NTTP->getType()), NTTP->getLocation()); | ||||
4439 | |||||
4440 | if (NTTP->isParameterPack()) | ||||
4441 | E = new (*this) PackExpansionExpr(DependentTy, E, NTTP->getLocation(), | ||||
4442 | None); | ||||
4443 | Arg = TemplateArgument(E); | ||||
4444 | } else { | ||||
4445 | auto *TTP = cast<TemplateTemplateParmDecl>(Param); | ||||
4446 | if (TTP->isParameterPack()) | ||||
4447 | Arg = TemplateArgument(TemplateName(TTP), Optional<unsigned>()); | ||||
4448 | else | ||||
4449 | Arg = TemplateArgument(TemplateName(TTP)); | ||||
4450 | } | ||||
4451 | |||||
4452 | if (Param->isTemplateParameterPack()) | ||||
4453 | Arg = TemplateArgument::CreatePackCopy(*this, Arg); | ||||
4454 | |||||
4455 | return Arg; | ||||
4456 | } | ||||
4457 | |||||
4458 | void | ||||
4459 | ASTContext::getInjectedTemplateArgs(const TemplateParameterList *Params, | ||||
4460 | SmallVectorImpl<TemplateArgument> &Args) { | ||||
4461 | Args.reserve(Args.size() + Params->size()); | ||||
4462 | |||||
4463 | for (NamedDecl *Param : *Params) | ||||
4464 | Args.push_back(getInjectedTemplateArg(Param)); | ||||
4465 | } | ||||
4466 | |||||
4467 | QualType ASTContext::getPackExpansionType(QualType Pattern, | ||||
4468 | Optional<unsigned> NumExpansions) { | ||||
4469 | llvm::FoldingSetNodeID ID; | ||||
4470 | PackExpansionType::Profile(ID, Pattern, NumExpansions); | ||||
4471 | |||||
4472 | // A deduced type can deduce to a pack, eg | ||||
4473 | // auto ...x = some_pack; | ||||
4474 | // That declaration isn't (yet) valid, but is created as part of building an | ||||
4475 | // init-capture pack: | ||||
4476 | // [...x = some_pack] {} | ||||
4477 | assert((Pattern->containsUnexpandedParameterPack() ||(((Pattern->containsUnexpandedParameterPack() || Pattern-> getContainedDeducedType()) && "Pack expansions must expand one or more parameter packs" ) ? static_cast<void> (0) : __assert_fail ("(Pattern->containsUnexpandedParameterPack() || Pattern->getContainedDeducedType()) && \"Pack expansions must expand one or more parameter packs\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 4479, __PRETTY_FUNCTION__)) | ||||
4478 | Pattern->getContainedDeducedType()) &&(((Pattern->containsUnexpandedParameterPack() || Pattern-> getContainedDeducedType()) && "Pack expansions must expand one or more parameter packs" ) ? static_cast<void> (0) : __assert_fail ("(Pattern->containsUnexpandedParameterPack() || Pattern->getContainedDeducedType()) && \"Pack expansions must expand one or more parameter packs\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 4479, __PRETTY_FUNCTION__)) | ||||
4479 | "Pack expansions must expand one or more parameter packs")(((Pattern->containsUnexpandedParameterPack() || Pattern-> getContainedDeducedType()) && "Pack expansions must expand one or more parameter packs" ) ? static_cast<void> (0) : __assert_fail ("(Pattern->containsUnexpandedParameterPack() || Pattern->getContainedDeducedType()) && \"Pack expansions must expand one or more parameter packs\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 4479, __PRETTY_FUNCTION__)); | ||||
4480 | void *InsertPos = nullptr; | ||||
4481 | PackExpansionType *T | ||||
4482 | = PackExpansionTypes.FindNodeOrInsertPos(ID, InsertPos); | ||||
4483 | if (T) | ||||
4484 | return QualType(T, 0); | ||||
4485 | |||||
4486 | QualType Canon; | ||||
4487 | if (!Pattern.isCanonical()) { | ||||
4488 | Canon = getCanonicalType(Pattern); | ||||
4489 | // The canonical type might not contain an unexpanded parameter pack, if it | ||||
4490 | // contains an alias template specialization which ignores one of its | ||||
4491 | // parameters. | ||||
4492 | if (Canon->containsUnexpandedParameterPack()) { | ||||
4493 | Canon = getPackExpansionType(Canon, NumExpansions); | ||||
4494 | |||||
4495 | // Find the insert position again, in case we inserted an element into | ||||
4496 | // PackExpansionTypes and invalidated our insert position. | ||||
4497 | PackExpansionTypes.FindNodeOrInsertPos(ID, InsertPos); | ||||
4498 | } | ||||
4499 | } | ||||
4500 | |||||
4501 | T = new (*this, TypeAlignment) | ||||
4502 | PackExpansionType(Pattern, Canon, NumExpansions); | ||||
4503 | Types.push_back(T); | ||||
4504 | PackExpansionTypes.InsertNode(T, InsertPos); | ||||
4505 | return QualType(T, 0); | ||||
4506 | } | ||||
4507 | |||||
4508 | /// CmpProtocolNames - Comparison predicate for sorting protocols | ||||
4509 | /// alphabetically. | ||||
4510 | static int CmpProtocolNames(ObjCProtocolDecl *const *LHS, | ||||
4511 | ObjCProtocolDecl *const *RHS) { | ||||
4512 | return DeclarationName::compare((*LHS)->getDeclName(), (*RHS)->getDeclName()); | ||||
4513 | } | ||||
4514 | |||||
4515 | static bool areSortedAndUniqued(ArrayRef<ObjCProtocolDecl *> Protocols) { | ||||
4516 | if (Protocols.empty()) return true; | ||||
4517 | |||||
4518 | if (Protocols[0]->getCanonicalDecl() != Protocols[0]) | ||||
4519 | return false; | ||||
4520 | |||||
4521 | for (unsigned i = 1; i != Protocols.size(); ++i) | ||||
4522 | if (CmpProtocolNames(&Protocols[i - 1], &Protocols[i]) >= 0 || | ||||
4523 | Protocols[i]->getCanonicalDecl() != Protocols[i]) | ||||
4524 | return false; | ||||
4525 | return true; | ||||
4526 | } | ||||
4527 | |||||
4528 | static void | ||||
4529 | SortAndUniqueProtocols(SmallVectorImpl<ObjCProtocolDecl *> &Protocols) { | ||||
4530 | // Sort protocols, keyed by name. | ||||
4531 | llvm::array_pod_sort(Protocols.begin(), Protocols.end(), CmpProtocolNames); | ||||
4532 | |||||
4533 | // Canonicalize. | ||||
4534 | for (ObjCProtocolDecl *&P : Protocols) | ||||
4535 | P = P->getCanonicalDecl(); | ||||
4536 | |||||
4537 | // Remove duplicates. | ||||
4538 | auto ProtocolsEnd = std::unique(Protocols.begin(), Protocols.end()); | ||||
4539 | Protocols.erase(ProtocolsEnd, Protocols.end()); | ||||
4540 | } | ||||
4541 | |||||
4542 | QualType ASTContext::getObjCObjectType(QualType BaseType, | ||||
4543 | ObjCProtocolDecl * const *Protocols, | ||||
4544 | unsigned NumProtocols) const { | ||||
4545 | return getObjCObjectType(BaseType, {}, | ||||
4546 | llvm::makeArrayRef(Protocols, NumProtocols), | ||||
4547 | /*isKindOf=*/false); | ||||
4548 | } | ||||
4549 | |||||
4550 | QualType ASTContext::getObjCObjectType( | ||||
4551 | QualType baseType, | ||||
4552 | ArrayRef<QualType> typeArgs, | ||||
4553 | ArrayRef<ObjCProtocolDecl *> protocols, | ||||
4554 | bool isKindOf) const { | ||||
4555 | // If the base type is an interface and there aren't any protocols or | ||||
4556 | // type arguments to add, then the interface type will do just fine. | ||||
4557 | if (typeArgs.empty() && protocols.empty() && !isKindOf && | ||||
4558 | isa<ObjCInterfaceType>(baseType)) | ||||
4559 | return baseType; | ||||
4560 | |||||
4561 | // Look in the folding set for an existing type. | ||||
4562 | llvm::FoldingSetNodeID ID; | ||||
4563 | ObjCObjectTypeImpl::Profile(ID, baseType, typeArgs, protocols, isKindOf); | ||||
4564 | void *InsertPos = nullptr; | ||||
4565 | if (ObjCObjectType *QT = ObjCObjectTypes.FindNodeOrInsertPos(ID, InsertPos)) | ||||
4566 | return QualType(QT, 0); | ||||
4567 | |||||
4568 | // Determine the type arguments to be used for canonicalization, | ||||
4569 | // which may be explicitly specified here or written on the base | ||||
4570 | // type. | ||||
4571 | ArrayRef<QualType> effectiveTypeArgs = typeArgs; | ||||
4572 | if (effectiveTypeArgs.empty()) { | ||||
4573 | if (const auto *baseObject = baseType->getAs<ObjCObjectType>()) | ||||
4574 | effectiveTypeArgs = baseObject->getTypeArgs(); | ||||
4575 | } | ||||
4576 | |||||
4577 | // Build the canonical type, which has the canonical base type and a | ||||
4578 | // sorted-and-uniqued list of protocols and the type arguments | ||||
4579 | // canonicalized. | ||||
4580 | QualType canonical; | ||||
4581 | bool typeArgsAreCanonical = std::all_of(effectiveTypeArgs.begin(), | ||||
4582 | effectiveTypeArgs.end(), | ||||
4583 | [&](QualType type) { | ||||
4584 | return type.isCanonical(); | ||||
4585 | }); | ||||
4586 | bool protocolsSorted = areSortedAndUniqued(protocols); | ||||
4587 | if (!typeArgsAreCanonical || !protocolsSorted || !baseType.isCanonical()) { | ||||
4588 | // Determine the canonical type arguments. | ||||
4589 | ArrayRef<QualType> canonTypeArgs; | ||||
4590 | SmallVector<QualType, 4> canonTypeArgsVec; | ||||
4591 | if (!typeArgsAreCanonical) { | ||||
4592 | canonTypeArgsVec.reserve(effectiveTypeArgs.size()); | ||||
4593 | for (auto typeArg : effectiveTypeArgs) | ||||
4594 | canonTypeArgsVec.push_back(getCanonicalType(typeArg)); | ||||
4595 | canonTypeArgs = canonTypeArgsVec; | ||||
4596 | } else { | ||||
4597 | canonTypeArgs = effectiveTypeArgs; | ||||
4598 | } | ||||
4599 | |||||
4600 | ArrayRef<ObjCProtocolDecl *> canonProtocols; | ||||
4601 | SmallVector<ObjCProtocolDecl*, 8> canonProtocolsVec; | ||||
4602 | if (!protocolsSorted) { | ||||
4603 | canonProtocolsVec.append(protocols.begin(), protocols.end()); | ||||
4604 | SortAndUniqueProtocols(canonProtocolsVec); | ||||
4605 | canonProtocols = canonProtocolsVec; | ||||
4606 | } else { | ||||
4607 | canonProtocols = protocols; | ||||
4608 | } | ||||
4609 | |||||
4610 | canonical = getObjCObjectType(getCanonicalType(baseType), canonTypeArgs, | ||||
4611 | canonProtocols, isKindOf); | ||||
4612 | |||||
4613 | // Regenerate InsertPos. | ||||
4614 | ObjCObjectTypes.FindNodeOrInsertPos(ID, InsertPos); | ||||
4615 | } | ||||
4616 | |||||
4617 | unsigned size = sizeof(ObjCObjectTypeImpl); | ||||
4618 | size += typeArgs.size() * sizeof(QualType); | ||||
4619 | size += protocols.size() * sizeof(ObjCProtocolDecl *); | ||||
4620 | void *mem = Allocate(size, TypeAlignment); | ||||
4621 | auto *T = | ||||
4622 | new (mem) ObjCObjectTypeImpl(canonical, baseType, typeArgs, protocols, | ||||
4623 | isKindOf); | ||||
4624 | |||||
4625 | Types.push_back(T); | ||||
4626 | ObjCObjectTypes.InsertNode(T, InsertPos); | ||||
4627 | return QualType(T, 0); | ||||
4628 | } | ||||
4629 | |||||
4630 | /// Apply Objective-C protocol qualifiers to the given type. | ||||
4631 | /// If this is for the canonical type of a type parameter, we can apply | ||||
4632 | /// protocol qualifiers on the ObjCObjectPointerType. | ||||
4633 | QualType | ||||
4634 | ASTContext::applyObjCProtocolQualifiers(QualType type, | ||||
4635 | ArrayRef<ObjCProtocolDecl *> protocols, bool &hasError, | ||||
4636 | bool allowOnPointerType) const { | ||||
4637 | hasError = false; | ||||
4638 | |||||
4639 | if (const auto *objT = dyn_cast<ObjCTypeParamType>(type.getTypePtr())) { | ||||
4640 | return getObjCTypeParamType(objT->getDecl(), protocols); | ||||
4641 | } | ||||
4642 | |||||
4643 | // Apply protocol qualifiers to ObjCObjectPointerType. | ||||
4644 | if (allowOnPointerType) { | ||||
4645 | if (const auto *objPtr = | ||||
4646 | dyn_cast<ObjCObjectPointerType>(type.getTypePtr())) { | ||||
4647 | const ObjCObjectType *objT = objPtr->getObjectType(); | ||||
4648 | // Merge protocol lists and construct ObjCObjectType. | ||||
4649 | SmallVector<ObjCProtocolDecl*, 8> protocolsVec; | ||||
4650 | protocolsVec.append(objT->qual_begin(), | ||||
4651 | objT->qual_end()); | ||||
4652 | protocolsVec.append(protocols.begin(), protocols.end()); | ||||
4653 | ArrayRef<ObjCProtocolDecl *> protocols = protocolsVec; | ||||
4654 | type = getObjCObjectType( | ||||
4655 | objT->getBaseType(), | ||||
4656 | objT->getTypeArgsAsWritten(), | ||||
4657 | protocols, | ||||
4658 | objT->isKindOfTypeAsWritten()); | ||||
4659 | return getObjCObjectPointerType(type); | ||||
4660 | } | ||||
4661 | } | ||||
4662 | |||||
4663 | // Apply protocol qualifiers to ObjCObjectType. | ||||
4664 | if (const auto *objT = dyn_cast<ObjCObjectType>(type.getTypePtr())){ | ||||
4665 | // FIXME: Check for protocols to which the class type is already | ||||
4666 | // known to conform. | ||||
4667 | |||||
4668 | return getObjCObjectType(objT->getBaseType(), | ||||
4669 | objT->getTypeArgsAsWritten(), | ||||
4670 | protocols, | ||||
4671 | objT->isKindOfTypeAsWritten()); | ||||
4672 | } | ||||
4673 | |||||
4674 | // If the canonical type is ObjCObjectType, ... | ||||
4675 | if (type->isObjCObjectType()) { | ||||
4676 | // Silently overwrite any existing protocol qualifiers. | ||||
4677 | // TODO: determine whether that's the right thing to do. | ||||
4678 | |||||
4679 | // FIXME: Check for protocols to which the class type is already | ||||
4680 | // known to conform. | ||||
4681 | return getObjCObjectType(type, {}, protocols, false); | ||||
4682 | } | ||||
4683 | |||||
4684 | // id<protocol-list> | ||||
4685 | if (type->isObjCIdType()) { | ||||
4686 | const auto *objPtr = type->castAs<ObjCObjectPointerType>(); | ||||
4687 | type = getObjCObjectType(ObjCBuiltinIdTy, {}, protocols, | ||||
4688 | objPtr->isKindOfType()); | ||||
4689 | return getObjCObjectPointerType(type); | ||||
4690 | } | ||||
4691 | |||||
4692 | // Class<protocol-list> | ||||
4693 | if (type->isObjCClassType()) { | ||||
4694 | const auto *objPtr = type->castAs<ObjCObjectPointerType>(); | ||||
4695 | type = getObjCObjectType(ObjCBuiltinClassTy, {}, protocols, | ||||
4696 | objPtr->isKindOfType()); | ||||
4697 | return getObjCObjectPointerType(type); | ||||
4698 | } | ||||
4699 | |||||
4700 | hasError = true; | ||||
4701 | return type; | ||||
4702 | } | ||||
4703 | |||||
4704 | QualType | ||||
4705 | ASTContext::getObjCTypeParamType(const ObjCTypeParamDecl *Decl, | ||||
4706 | ArrayRef<ObjCProtocolDecl *> protocols, | ||||
4707 | QualType Canonical) const { | ||||
4708 | // Look in the folding set for an existing type. | ||||
4709 | llvm::FoldingSetNodeID ID; | ||||
4710 | ObjCTypeParamType::Profile(ID, Decl, protocols); | ||||
4711 | void *InsertPos = nullptr; | ||||
4712 | if (ObjCTypeParamType *TypeParam = | ||||
4713 | ObjCTypeParamTypes.FindNodeOrInsertPos(ID, InsertPos)) | ||||
4714 | return QualType(TypeParam, 0); | ||||
4715 | |||||
4716 | if (Canonical.isNull()) { | ||||
4717 | // We canonicalize to the underlying type. | ||||
4718 | Canonical = getCanonicalType(Decl->getUnderlyingType()); | ||||
4719 | if (!protocols.empty()) { | ||||
4720 | // Apply the protocol qualifers. | ||||
4721 | bool hasError; | ||||
4722 | Canonical = getCanonicalType(applyObjCProtocolQualifiers( | ||||
4723 | Canonical, protocols, hasError, true /*allowOnPointerType*/)); | ||||
4724 | assert(!hasError && "Error when apply protocol qualifier to bound type")((!hasError && "Error when apply protocol qualifier to bound type" ) ? static_cast<void> (0) : __assert_fail ("!hasError && \"Error when apply protocol qualifier to bound type\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 4724, __PRETTY_FUNCTION__)); | ||||
4725 | } | ||||
4726 | } | ||||
4727 | |||||
4728 | unsigned size = sizeof(ObjCTypeParamType); | ||||
4729 | size += protocols.size() * sizeof(ObjCProtocolDecl *); | ||||
4730 | void *mem = Allocate(size, TypeAlignment); | ||||
4731 | auto *newType = new (mem) ObjCTypeParamType(Decl, Canonical, protocols); | ||||
4732 | |||||
4733 | Types.push_back(newType); | ||||
4734 | ObjCTypeParamTypes.InsertNode(newType, InsertPos); | ||||
4735 | return QualType(newType, 0); | ||||
4736 | } | ||||
4737 | |||||
4738 | /// ObjCObjectAdoptsQTypeProtocols - Checks that protocols in IC's | ||||
4739 | /// protocol list adopt all protocols in QT's qualified-id protocol | ||||
4740 | /// list. | ||||
4741 | bool ASTContext::ObjCObjectAdoptsQTypeProtocols(QualType QT, | ||||
4742 | ObjCInterfaceDecl *IC) { | ||||
4743 | if (!QT->isObjCQualifiedIdType()) | ||||
4744 | return false; | ||||
4745 | |||||
4746 | if (const auto *OPT = QT->getAs<ObjCObjectPointerType>()) { | ||||
4747 | // If both the right and left sides have qualifiers. | ||||
4748 | for (auto *Proto : OPT->quals()) { | ||||
4749 | if (!IC->ClassImplementsProtocol(Proto, false)) | ||||
4750 | return false; | ||||
4751 | } | ||||
4752 | return true; | ||||
4753 | } | ||||
4754 | return false; | ||||
4755 | } | ||||
4756 | |||||
4757 | /// QIdProtocolsAdoptObjCObjectProtocols - Checks that protocols in | ||||
4758 | /// QT's qualified-id protocol list adopt all protocols in IDecl's list | ||||
4759 | /// of protocols. | ||||
4760 | bool ASTContext::QIdProtocolsAdoptObjCObjectProtocols(QualType QT, | ||||
4761 | ObjCInterfaceDecl *IDecl) { | ||||
4762 | if (!QT->isObjCQualifiedIdType()) | ||||
4763 | return false; | ||||
4764 | const auto *OPT = QT->getAs<ObjCObjectPointerType>(); | ||||
4765 | if (!OPT) | ||||
4766 | return false; | ||||
4767 | if (!IDecl->hasDefinition()) | ||||
4768 | return false; | ||||
4769 | llvm::SmallPtrSet<ObjCProtocolDecl *, 8> InheritedProtocols; | ||||
4770 | CollectInheritedProtocols(IDecl, InheritedProtocols); | ||||
4771 | if (InheritedProtocols.empty()) | ||||
4772 | return false; | ||||
4773 | // Check that if every protocol in list of id<plist> conforms to a protocol | ||||
4774 | // of IDecl's, then bridge casting is ok. | ||||
4775 | bool Conforms = false; | ||||
4776 | for (auto *Proto : OPT->quals()) { | ||||
4777 | Conforms = false; | ||||
4778 | for (auto *PI : InheritedProtocols) { | ||||
4779 | if (ProtocolCompatibleWithProtocol(Proto, PI)) { | ||||
4780 | Conforms = true; | ||||
4781 | break; | ||||
4782 | } | ||||
4783 | } | ||||
4784 | if (!Conforms) | ||||
4785 | break; | ||||
4786 | } | ||||
4787 | if (Conforms) | ||||
4788 | return true; | ||||
4789 | |||||
4790 | for (auto *PI : InheritedProtocols) { | ||||
4791 | // If both the right and left sides have qualifiers. | ||||
4792 | bool Adopts = false; | ||||
4793 | for (auto *Proto : OPT->quals()) { | ||||
4794 | // return 'true' if 'PI' is in the inheritance hierarchy of Proto | ||||
4795 | if ((Adopts = ProtocolCompatibleWithProtocol(PI, Proto))) | ||||
4796 | break; | ||||
4797 | } | ||||
4798 | if (!Adopts) | ||||
4799 | return false; | ||||
4800 | } | ||||
4801 | return true; | ||||
4802 | } | ||||
4803 | |||||
4804 | /// getObjCObjectPointerType - Return a ObjCObjectPointerType type for | ||||
4805 | /// the given object type. | ||||
4806 | QualType ASTContext::getObjCObjectPointerType(QualType ObjectT) const { | ||||
4807 | llvm::FoldingSetNodeID ID; | ||||
4808 | ObjCObjectPointerType::Profile(ID, ObjectT); | ||||
4809 | |||||
4810 | void *InsertPos = nullptr; | ||||
4811 | if (ObjCObjectPointerType *QT = | ||||
4812 | ObjCObjectPointerTypes.FindNodeOrInsertPos(ID, InsertPos)) | ||||
4813 | return QualType(QT, 0); | ||||
4814 | |||||
4815 | // Find the canonical object type. | ||||
4816 | QualType Canonical; | ||||
4817 | if (!ObjectT.isCanonical()) { | ||||
4818 | Canonical = getObjCObjectPointerType(getCanonicalType(ObjectT)); | ||||
4819 | |||||
4820 | // Regenerate InsertPos. | ||||
4821 | ObjCObjectPointerTypes.FindNodeOrInsertPos(ID, InsertPos); | ||||
4822 | } | ||||
4823 | |||||
4824 | // No match. | ||||
4825 | void *Mem = Allocate(sizeof(ObjCObjectPointerType), TypeAlignment); | ||||
4826 | auto *QType = | ||||
4827 | new (Mem) ObjCObjectPointerType(Canonical, ObjectT); | ||||
4828 | |||||
4829 | Types.push_back(QType); | ||||
4830 | ObjCObjectPointerTypes.InsertNode(QType, InsertPos); | ||||
4831 | return QualType(QType, 0); | ||||
4832 | } | ||||
4833 | |||||
4834 | /// getObjCInterfaceType - Return the unique reference to the type for the | ||||
4835 | /// specified ObjC interface decl. The list of protocols is optional. | ||||
4836 | QualType ASTContext::getObjCInterfaceType(const ObjCInterfaceDecl *Decl, | ||||
4837 | ObjCInterfaceDecl *PrevDecl) const { | ||||
4838 | if (Decl->TypeForDecl) | ||||
4839 | return QualType(Decl->TypeForDecl, 0); | ||||
4840 | |||||
4841 | if (PrevDecl) { | ||||
4842 | assert(PrevDecl->TypeForDecl && "previous decl has no TypeForDecl")((PrevDecl->TypeForDecl && "previous decl has no TypeForDecl" ) ? static_cast<void> (0) : __assert_fail ("PrevDecl->TypeForDecl && \"previous decl has no TypeForDecl\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 4842, __PRETTY_FUNCTION__)); | ||||
4843 | Decl->TypeForDecl = PrevDecl->TypeForDecl; | ||||
4844 | return QualType(PrevDecl->TypeForDecl, 0); | ||||
4845 | } | ||||
4846 | |||||
4847 | // Prefer the definition, if there is one. | ||||
4848 | if (const ObjCInterfaceDecl *Def = Decl->getDefinition()) | ||||
4849 | Decl = Def; | ||||
4850 | |||||
4851 | void *Mem = Allocate(sizeof(ObjCInterfaceType), TypeAlignment); | ||||
4852 | auto *T = new (Mem) ObjCInterfaceType(Decl); | ||||
4853 | Decl->TypeForDecl = T; | ||||
4854 | Types.push_back(T); | ||||
4855 | return QualType(T, 0); | ||||
4856 | } | ||||
4857 | |||||
4858 | /// getTypeOfExprType - Unlike many "get<Type>" functions, we can't unique | ||||
4859 | /// TypeOfExprType AST's (since expression's are never shared). For example, | ||||
4860 | /// multiple declarations that refer to "typeof(x)" all contain different | ||||
4861 | /// DeclRefExpr's. This doesn't effect the type checker, since it operates | ||||
4862 | /// on canonical type's (which are always unique). | ||||
4863 | QualType ASTContext::getTypeOfExprType(Expr *tofExpr) const { | ||||
4864 | TypeOfExprType *toe; | ||||
4865 | if (tofExpr->isTypeDependent()) { | ||||
4866 | llvm::FoldingSetNodeID ID; | ||||
4867 | DependentTypeOfExprType::Profile(ID, *this, tofExpr); | ||||
4868 | |||||
4869 | void *InsertPos = nullptr; | ||||
4870 | DependentTypeOfExprType *Canon | ||||
4871 | = DependentTypeOfExprTypes.FindNodeOrInsertPos(ID, InsertPos); | ||||
4872 | if (Canon) { | ||||
4873 | // We already have a "canonical" version of an identical, dependent | ||||
4874 | // typeof(expr) type. Use that as our canonical type. | ||||
4875 | toe = new (*this, TypeAlignment) TypeOfExprType(tofExpr, | ||||
4876 | QualType((TypeOfExprType*)Canon, 0)); | ||||
4877 | } else { | ||||
4878 | // Build a new, canonical typeof(expr) type. | ||||
4879 | Canon | ||||
4880 | = new (*this, TypeAlignment) DependentTypeOfExprType(*this, tofExpr); | ||||
4881 | DependentTypeOfExprTypes.InsertNode(Canon, InsertPos); | ||||
4882 | toe = Canon; | ||||
4883 | } | ||||
4884 | } else { | ||||
4885 | QualType Canonical = getCanonicalType(tofExpr->getType()); | ||||
4886 | toe = new (*this, TypeAlignment) TypeOfExprType(tofExpr, Canonical); | ||||
4887 | } | ||||
4888 | Types.push_back(toe); | ||||
4889 | return QualType(toe, 0); | ||||
4890 | } | ||||
4891 | |||||
4892 | /// getTypeOfType - Unlike many "get<Type>" functions, we don't unique | ||||
4893 | /// TypeOfType nodes. The only motivation to unique these nodes would be | ||||
4894 | /// memory savings. Since typeof(t) is fairly uncommon, space shouldn't be | ||||
4895 | /// an issue. This doesn't affect the type checker, since it operates | ||||
4896 | /// on canonical types (which are always unique). | ||||
4897 | QualType ASTContext::getTypeOfType(QualType tofType) const { | ||||
4898 | QualType Canonical = getCanonicalType(tofType); | ||||
4899 | auto *tot = new (*this, TypeAlignment) TypeOfType(tofType, Canonical); | ||||
4900 | Types.push_back(tot); | ||||
4901 | return QualType(tot, 0); | ||||
4902 | } | ||||
4903 | |||||
4904 | /// Unlike many "get<Type>" functions, we don't unique DecltypeType | ||||
4905 | /// nodes. This would never be helpful, since each such type has its own | ||||
4906 | /// expression, and would not give a significant memory saving, since there | ||||
4907 | /// is an Expr tree under each such type. | ||||
4908 | QualType ASTContext::getDecltypeType(Expr *e, QualType UnderlyingType) const { | ||||
4909 | DecltypeType *dt; | ||||
4910 | |||||
4911 | // C++11 [temp.type]p2: | ||||
4912 | // If an expression e involves a template parameter, decltype(e) denotes a | ||||
4913 | // unique dependent type. Two such decltype-specifiers refer to the same | ||||
4914 | // type only if their expressions are equivalent (14.5.6.1). | ||||
4915 | if (e->isInstantiationDependent()) { | ||||
4916 | llvm::FoldingSetNodeID ID; | ||||
4917 | DependentDecltypeType::Profile(ID, *this, e); | ||||
4918 | |||||
4919 | void *InsertPos = nullptr; | ||||
4920 | DependentDecltypeType *Canon | ||||
4921 | = DependentDecltypeTypes.FindNodeOrInsertPos(ID, InsertPos); | ||||
4922 | if (!Canon) { | ||||
4923 | // Build a new, canonical decltype(expr) type. | ||||
4924 | Canon = new (*this, TypeAlignment) DependentDecltypeType(*this, e); | ||||
4925 | DependentDecltypeTypes.InsertNode(Canon, InsertPos); | ||||
4926 | } | ||||
4927 | dt = new (*this, TypeAlignment) | ||||
4928 | DecltypeType(e, UnderlyingType, QualType((DecltypeType *)Canon, 0)); | ||||
4929 | } else { | ||||
4930 | dt = new (*this, TypeAlignment) | ||||
4931 | DecltypeType(e, UnderlyingType, getCanonicalType(UnderlyingType)); | ||||
4932 | } | ||||
4933 | Types.push_back(dt); | ||||
4934 | return QualType(dt, 0); | ||||
4935 | } | ||||
4936 | |||||
4937 | /// getUnaryTransformationType - We don't unique these, since the memory | ||||
4938 | /// savings are minimal and these are rare. | ||||
4939 | QualType ASTContext::getUnaryTransformType(QualType BaseType, | ||||
4940 | QualType UnderlyingType, | ||||
4941 | UnaryTransformType::UTTKind Kind) | ||||
4942 | const { | ||||
4943 | UnaryTransformType *ut = nullptr; | ||||
4944 | |||||
4945 | if (BaseType->isDependentType()) { | ||||
4946 | // Look in the folding set for an existing type. | ||||
4947 | llvm::FoldingSetNodeID ID; | ||||
4948 | DependentUnaryTransformType::Profile(ID, getCanonicalType(BaseType), Kind); | ||||
4949 | |||||
4950 | void *InsertPos = nullptr; | ||||
4951 | DependentUnaryTransformType *Canon | ||||
4952 | = DependentUnaryTransformTypes.FindNodeOrInsertPos(ID, InsertPos); | ||||
4953 | |||||
4954 | if (!Canon) { | ||||
4955 | // Build a new, canonical __underlying_type(type) type. | ||||
4956 | Canon = new (*this, TypeAlignment) | ||||
4957 | DependentUnaryTransformType(*this, getCanonicalType(BaseType), | ||||
4958 | Kind); | ||||
4959 | DependentUnaryTransformTypes.InsertNode(Canon, InsertPos); | ||||
4960 | } | ||||
4961 | ut = new (*this, TypeAlignment) UnaryTransformType (BaseType, | ||||
4962 | QualType(), Kind, | ||||
4963 | QualType(Canon, 0)); | ||||
4964 | } else { | ||||
4965 | QualType CanonType = getCanonicalType(UnderlyingType); | ||||
4966 | ut = new (*this, TypeAlignment) UnaryTransformType (BaseType, | ||||
4967 | UnderlyingType, Kind, | ||||
4968 | CanonType); | ||||
4969 | } | ||||
4970 | Types.push_back(ut); | ||||
4971 | return QualType(ut, 0); | ||||
4972 | } | ||||
4973 | |||||
4974 | /// getAutoType - Return the uniqued reference to the 'auto' type which has been | ||||
4975 | /// deduced to the given type, or to the canonical undeduced 'auto' type, or the | ||||
4976 | /// canonical deduced-but-dependent 'auto' type. | ||||
4977 | QualType ASTContext::getAutoType(QualType DeducedType, AutoTypeKeyword Keyword, | ||||
4978 | bool IsDependent, bool IsPack) const { | ||||
4979 | assert((!IsPack || IsDependent) && "only use IsPack for a dependent pack")(((!IsPack || IsDependent) && "only use IsPack for a dependent pack" ) ? static_cast<void> (0) : __assert_fail ("(!IsPack || IsDependent) && \"only use IsPack for a dependent pack\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 4979, __PRETTY_FUNCTION__)); | ||||
4980 | if (DeducedType.isNull() && Keyword == AutoTypeKeyword::Auto && !IsDependent) | ||||
4981 | return getAutoDeductType(); | ||||
4982 | |||||
4983 | // Look in the folding set for an existing type. | ||||
4984 | void *InsertPos = nullptr; | ||||
4985 | llvm::FoldingSetNodeID ID; | ||||
4986 | AutoType::Profile(ID, DeducedType, Keyword, IsDependent, IsPack); | ||||
4987 | if (AutoType *AT = AutoTypes.FindNodeOrInsertPos(ID, InsertPos)) | ||||
4988 | return QualType(AT, 0); | ||||
4989 | |||||
4990 | auto *AT = new (*this, TypeAlignment) | ||||
4991 | AutoType(DeducedType, Keyword, IsDependent, IsPack); | ||||
4992 | Types.push_back(AT); | ||||
4993 | if (InsertPos) | ||||
4994 | AutoTypes.InsertNode(AT, InsertPos); | ||||
4995 | return QualType(AT, 0); | ||||
4996 | } | ||||
4997 | |||||
4998 | /// Return the uniqued reference to the deduced template specialization type | ||||
4999 | /// which has been deduced to the given type, or to the canonical undeduced | ||||
5000 | /// such type, or the canonical deduced-but-dependent such type. | ||||
5001 | QualType ASTContext::getDeducedTemplateSpecializationType( | ||||
5002 | TemplateName Template, QualType DeducedType, bool IsDependent) const { | ||||
5003 | // Look in the folding set for an existing type. | ||||
5004 | void *InsertPos = nullptr; | ||||
5005 | llvm::FoldingSetNodeID ID; | ||||
5006 | DeducedTemplateSpecializationType::Profile(ID, Template, DeducedType, | ||||
5007 | IsDependent); | ||||
5008 | if (DeducedTemplateSpecializationType *DTST = | ||||
5009 | DeducedTemplateSpecializationTypes.FindNodeOrInsertPos(ID, InsertPos)) | ||||
5010 | return QualType(DTST, 0); | ||||
5011 | |||||
5012 | auto *DTST = new (*this, TypeAlignment) | ||||
5013 | DeducedTemplateSpecializationType(Template, DeducedType, IsDependent); | ||||
5014 | Types.push_back(DTST); | ||||
5015 | if (InsertPos) | ||||
5016 | DeducedTemplateSpecializationTypes.InsertNode(DTST, InsertPos); | ||||
5017 | return QualType(DTST, 0); | ||||
5018 | } | ||||
5019 | |||||
5020 | /// getAtomicType - Return the uniqued reference to the atomic type for | ||||
5021 | /// the given value type. | ||||
5022 | QualType ASTContext::getAtomicType(QualType T) const { | ||||
5023 | // Unique pointers, to guarantee there is only one pointer of a particular | ||||
5024 | // structure. | ||||
5025 | llvm::FoldingSetNodeID ID; | ||||
5026 | AtomicType::Profile(ID, T); | ||||
5027 | |||||
5028 | void *InsertPos = nullptr; | ||||
5029 | if (AtomicType *AT = AtomicTypes.FindNodeOrInsertPos(ID, InsertPos)) | ||||
5030 | return QualType(AT, 0); | ||||
5031 | |||||
5032 | // If the atomic value type isn't canonical, this won't be a canonical type | ||||
5033 | // either, so fill in the canonical type field. | ||||
5034 | QualType Canonical; | ||||
5035 | if (!T.isCanonical()) { | ||||
5036 | Canonical = getAtomicType(getCanonicalType(T)); | ||||
5037 | |||||
5038 | // Get the new insert position for the node we care about. | ||||
5039 | AtomicType *NewIP = AtomicTypes.FindNodeOrInsertPos(ID, InsertPos); | ||||
5040 | assert(!NewIP && "Shouldn't be in the map!")((!NewIP && "Shouldn't be in the map!") ? static_cast <void> (0) : __assert_fail ("!NewIP && \"Shouldn't be in the map!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 5040, __PRETTY_FUNCTION__)); (void)NewIP; | ||||
5041 | } | ||||
5042 | auto *New = new (*this, TypeAlignment) AtomicType(T, Canonical); | ||||
5043 | Types.push_back(New); | ||||
5044 | AtomicTypes.InsertNode(New, InsertPos); | ||||
5045 | return QualType(New, 0); | ||||
5046 | } | ||||
5047 | |||||
5048 | /// getAutoDeductType - Get type pattern for deducing against 'auto'. | ||||
5049 | QualType ASTContext::getAutoDeductType() const { | ||||
5050 | if (AutoDeductTy.isNull()) | ||||
5051 | AutoDeductTy = QualType( | ||||
5052 | new (*this, TypeAlignment) AutoType(QualType(), AutoTypeKeyword::Auto, | ||||
5053 | /*dependent*/false, /*pack*/false), | ||||
5054 | 0); | ||||
5055 | return AutoDeductTy; | ||||
5056 | } | ||||
5057 | |||||
5058 | /// getAutoRRefDeductType - Get type pattern for deducing against 'auto &&'. | ||||
5059 | QualType ASTContext::getAutoRRefDeductType() const { | ||||
5060 | if (AutoRRefDeductTy.isNull()) | ||||
5061 | AutoRRefDeductTy = getRValueReferenceType(getAutoDeductType()); | ||||
5062 | assert(!AutoRRefDeductTy.isNull() && "can't build 'auto &&' pattern")((!AutoRRefDeductTy.isNull() && "can't build 'auto &&' pattern" ) ? static_cast<void> (0) : __assert_fail ("!AutoRRefDeductTy.isNull() && \"can't build 'auto &&' pattern\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 5062, __PRETTY_FUNCTION__)); | ||||
5063 | return AutoRRefDeductTy; | ||||
5064 | } | ||||
5065 | |||||
5066 | /// getTagDeclType - Return the unique reference to the type for the | ||||
5067 | /// specified TagDecl (struct/union/class/enum) decl. | ||||
5068 | QualType ASTContext::getTagDeclType(const TagDecl *Decl) const { | ||||
5069 | assert(Decl)((Decl) ? static_cast<void> (0) : __assert_fail ("Decl" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 5069, __PRETTY_FUNCTION__)); | ||||
5070 | // FIXME: What is the design on getTagDeclType when it requires casting | ||||
5071 | // away const? mutable? | ||||
5072 | return getTypeDeclType(const_cast<TagDecl*>(Decl)); | ||||
5073 | } | ||||
5074 | |||||
5075 | /// getSizeType - Return the unique type for "size_t" (C99 7.17), the result | ||||
5076 | /// of the sizeof operator (C99 6.5.3.4p4). The value is target dependent and | ||||
5077 | /// needs to agree with the definition in <stddef.h>. | ||||
5078 | CanQualType ASTContext::getSizeType() const { | ||||
5079 | return getFromTargetType(Target->getSizeType()); | ||||
5080 | } | ||||
5081 | |||||
5082 | /// Return the unique signed counterpart of the integer type | ||||
5083 | /// corresponding to size_t. | ||||
5084 | CanQualType ASTContext::getSignedSizeType() const { | ||||
5085 | return getFromTargetType(Target->getSignedSizeType()); | ||||
5086 | } | ||||
5087 | |||||
5088 | /// getIntMaxType - Return the unique type for "intmax_t" (C99 7.18.1.5). | ||||
5089 | CanQualType ASTContext::getIntMaxType() const { | ||||
5090 | return getFromTargetType(Target->getIntMaxType()); | ||||
5091 | } | ||||
5092 | |||||
5093 | /// getUIntMaxType - Return the unique type for "uintmax_t" (C99 7.18.1.5). | ||||
5094 | CanQualType ASTContext::getUIntMaxType() const { | ||||
5095 | return getFromTargetType(Target->getUIntMaxType()); | ||||
5096 | } | ||||
5097 | |||||
5098 | /// getSignedWCharType - Return the type of "signed wchar_t". | ||||
5099 | /// Used when in C++, as a GCC extension. | ||||
5100 | QualType ASTContext::getSignedWCharType() const { | ||||
5101 | // FIXME: derive from "Target" ? | ||||
5102 | return WCharTy; | ||||
5103 | } | ||||
5104 | |||||
5105 | /// getUnsignedWCharType - Return the type of "unsigned wchar_t". | ||||
5106 | /// Used when in C++, as a GCC extension. | ||||
5107 | QualType ASTContext::getUnsignedWCharType() const { | ||||
5108 | // FIXME: derive from "Target" ? | ||||
5109 | return UnsignedIntTy; | ||||
5110 | } | ||||
5111 | |||||
5112 | QualType ASTContext::getIntPtrType() const { | ||||
5113 | return getFromTargetType(Target->getIntPtrType()); | ||||
5114 | } | ||||
5115 | |||||
5116 | QualType ASTContext::getUIntPtrType() const { | ||||
5117 | return getCorrespondingUnsignedType(getIntPtrType()); | ||||
5118 | } | ||||
5119 | |||||
5120 | /// getPointerDiffType - Return the unique type for "ptrdiff_t" (C99 7.17) | ||||
5121 | /// defined in <stddef.h>. Pointer - pointer requires this (C99 6.5.6p9). | ||||
5122 | QualType ASTContext::getPointerDiffType() const { | ||||
5123 | return getFromTargetType(Target->getPtrDiffType(0)); | ||||
5124 | } | ||||
5125 | |||||
5126 | /// Return the unique unsigned counterpart of "ptrdiff_t" | ||||
5127 | /// integer type. The standard (C11 7.21.6.1p7) refers to this type | ||||
5128 | /// in the definition of %tu format specifier. | ||||
5129 | QualType ASTContext::getUnsignedPointerDiffType() const { | ||||
5130 | return getFromTargetType(Target->getUnsignedPtrDiffType(0)); | ||||
5131 | } | ||||
5132 | |||||
5133 | /// Return the unique type for "pid_t" defined in | ||||
5134 | /// <sys/types.h>. We need this to compute the correct type for vfork(). | ||||
5135 | QualType ASTContext::getProcessIDType() const { | ||||
5136 | return getFromTargetType(Target->getProcessIDType()); | ||||
5137 | } | ||||
5138 | |||||
5139 | //===----------------------------------------------------------------------===// | ||||
5140 | // Type Operators | ||||
5141 | //===----------------------------------------------------------------------===// | ||||
5142 | |||||
5143 | CanQualType ASTContext::getCanonicalParamType(QualType T) const { | ||||
5144 | // Push qualifiers into arrays, and then discard any remaining | ||||
5145 | // qualifiers. | ||||
5146 | T = getCanonicalType(T); | ||||
5147 | T = getVariableArrayDecayedType(T); | ||||
5148 | const Type *Ty = T.getTypePtr(); | ||||
5149 | QualType Result; | ||||
5150 | if (isa<ArrayType>(Ty)) { | ||||
5151 | Result = getArrayDecayedType(QualType(Ty,0)); | ||||
5152 | } else if (isa<FunctionType>(Ty)) { | ||||
5153 | Result = getPointerType(QualType(Ty, 0)); | ||||
5154 | } else { | ||||
5155 | Result = QualType(Ty, 0); | ||||
5156 | } | ||||
5157 | |||||
5158 | return CanQualType::CreateUnsafe(Result); | ||||
5159 | } | ||||
5160 | |||||
5161 | QualType ASTContext::getUnqualifiedArrayType(QualType type, | ||||
5162 | Qualifiers &quals) { | ||||
5163 | SplitQualType splitType = type.getSplitUnqualifiedType(); | ||||
5164 | |||||
5165 | // FIXME: getSplitUnqualifiedType() actually walks all the way to | ||||
5166 | // the unqualified desugared type and then drops it on the floor. | ||||
5167 | // We then have to strip that sugar back off with | ||||
5168 | // getUnqualifiedDesugaredType(), which is silly. | ||||
5169 | const auto *AT = | ||||
5170 | dyn_cast<ArrayType>(splitType.Ty->getUnqualifiedDesugaredType()); | ||||
5171 | |||||
5172 | // If we don't have an array, just use the results in splitType. | ||||
5173 | if (!AT) { | ||||
5174 | quals = splitType.Quals; | ||||
5175 | return QualType(splitType.Ty, 0); | ||||
5176 | } | ||||
5177 | |||||
5178 | // Otherwise, recurse on the array's element type. | ||||
5179 | QualType elementType = AT->getElementType(); | ||||
5180 | QualType unqualElementType = getUnqualifiedArrayType(elementType, quals); | ||||
5181 | |||||
5182 | // If that didn't change the element type, AT has no qualifiers, so we | ||||
5183 | // can just use the results in splitType. | ||||
5184 | if (elementType == unqualElementType) { | ||||
5185 | assert(quals.empty())((quals.empty()) ? static_cast<void> (0) : __assert_fail ("quals.empty()", "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 5185, __PRETTY_FUNCTION__)); // from the recursive call | ||||
5186 | quals = splitType.Quals; | ||||
5187 | return QualType(splitType.Ty, 0); | ||||
5188 | } | ||||
5189 | |||||
5190 | // Otherwise, add in the qualifiers from the outermost type, then | ||||
5191 | // build the type back up. | ||||
5192 | quals.addConsistentQualifiers(splitType.Quals); | ||||
5193 | |||||
5194 | if (const auto *CAT = dyn_cast<ConstantArrayType>(AT)) { | ||||
5195 | return getConstantArrayType(unqualElementType, CAT->getSize(), | ||||
5196 | CAT->getSizeModifier(), 0); | ||||
5197 | } | ||||
5198 | |||||
5199 | if (const auto *IAT = dyn_cast<IncompleteArrayType>(AT)) { | ||||
5200 | return getIncompleteArrayType(unqualElementType, IAT->getSizeModifier(), 0); | ||||
5201 | } | ||||
5202 | |||||
5203 | if (const auto *VAT = dyn_cast<VariableArrayType>(AT)) { | ||||
5204 | return getVariableArrayType(unqualElementType, | ||||
5205 | VAT->getSizeExpr(), | ||||
5206 | VAT->getSizeModifier(), | ||||
5207 | VAT->getIndexTypeCVRQualifiers(), | ||||
5208 | VAT->getBracketsRange()); | ||||
5209 | } | ||||
5210 | |||||
5211 | const auto *DSAT = cast<DependentSizedArrayType>(AT); | ||||
5212 | return getDependentSizedArrayType(unqualElementType, DSAT->getSizeExpr(), | ||||
5213 | DSAT->getSizeModifier(), 0, | ||||
5214 | SourceRange()); | ||||
5215 | } | ||||
5216 | |||||
5217 | /// Attempt to unwrap two types that may both be array types with the same bound | ||||
5218 | /// (or both be array types of unknown bound) for the purpose of comparing the | ||||
5219 | /// cv-decomposition of two types per C++ [conv.qual]. | ||||
5220 | bool ASTContext::UnwrapSimilarArrayTypes(QualType &T1, QualType &T2) { | ||||
5221 | bool UnwrappedAny = false; | ||||
5222 | while (true) { | ||||
5223 | auto *AT1 = getAsArrayType(T1); | ||||
5224 | if (!AT1) return UnwrappedAny; | ||||
5225 | |||||
5226 | auto *AT2 = getAsArrayType(T2); | ||||
5227 | if (!AT2) return UnwrappedAny; | ||||
5228 | |||||
5229 | // If we don't have two array types with the same constant bound nor two | ||||
5230 | // incomplete array types, we've unwrapped everything we can. | ||||
5231 | if (auto *CAT1 = dyn_cast<ConstantArrayType>(AT1)) { | ||||
5232 | auto *CAT2 = dyn_cast<ConstantArrayType>(AT2); | ||||
5233 | if (!CAT2 || CAT1->getSize() != CAT2->getSize()) | ||||
5234 | return UnwrappedAny; | ||||
5235 | } else if (!isa<IncompleteArrayType>(AT1) || | ||||
5236 | !isa<IncompleteArrayType>(AT2)) { | ||||
5237 | return UnwrappedAny; | ||||
5238 | } | ||||
5239 | |||||
5240 | T1 = AT1->getElementType(); | ||||
5241 | T2 = AT2->getElementType(); | ||||
5242 | UnwrappedAny = true; | ||||
5243 | } | ||||
5244 | } | ||||
5245 | |||||
5246 | /// Attempt to unwrap two types that may be similar (C++ [conv.qual]). | ||||
5247 | /// | ||||
5248 | /// If T1 and T2 are both pointer types of the same kind, or both array types | ||||
5249 | /// with the same bound, unwraps layers from T1 and T2 until a pointer type is | ||||
5250 | /// unwrapped. Top-level qualifiers on T1 and T2 are ignored. | ||||
5251 | /// | ||||
5252 | /// This function will typically be called in a loop that successively | ||||
5253 | /// "unwraps" pointer and pointer-to-member types to compare them at each | ||||
5254 | /// level. | ||||
5255 | /// | ||||
5256 | /// \return \c true if a pointer type was unwrapped, \c false if we reached a | ||||
5257 | /// pair of types that can't be unwrapped further. | ||||
5258 | bool ASTContext::UnwrapSimilarTypes(QualType &T1, QualType &T2) { | ||||
5259 | UnwrapSimilarArrayTypes(T1, T2); | ||||
5260 | |||||
5261 | const auto *T1PtrType = T1->getAs<PointerType>(); | ||||
5262 | const auto *T2PtrType = T2->getAs<PointerType>(); | ||||
5263 | if (T1PtrType && T2PtrType) { | ||||
5264 | T1 = T1PtrType->getPointeeType(); | ||||
5265 | T2 = T2PtrType->getPointeeType(); | ||||
5266 | return true; | ||||
5267 | } | ||||
5268 | |||||
5269 | const auto *T1MPType = T1->getAs<MemberPointerType>(); | ||||
5270 | const auto *T2MPType = T2->getAs<MemberPointerType>(); | ||||
5271 | if (T1MPType && T2MPType && | ||||
5272 | hasSameUnqualifiedType(QualType(T1MPType->getClass(), 0), | ||||
5273 | QualType(T2MPType->getClass(), 0))) { | ||||
5274 | T1 = T1MPType->getPointeeType(); | ||||
5275 | T2 = T2MPType->getPointeeType(); | ||||
5276 | return true; | ||||
5277 | } | ||||
5278 | |||||
5279 | if (getLangOpts().ObjC) { | ||||
5280 | const auto *T1OPType = T1->getAs<ObjCObjectPointerType>(); | ||||
5281 | const auto *T2OPType = T2->getAs<ObjCObjectPointerType>(); | ||||
5282 | if (T1OPType && T2OPType) { | ||||
5283 | T1 = T1OPType->getPointeeType(); | ||||
5284 | T2 = T2OPType->getPointeeType(); | ||||
5285 | return true; | ||||
5286 | } | ||||
5287 | } | ||||
5288 | |||||
5289 | // FIXME: Block pointers, too? | ||||
5290 | |||||
5291 | return false; | ||||
5292 | } | ||||
5293 | |||||
5294 | bool ASTContext::hasSimilarType(QualType T1, QualType T2) { | ||||
5295 | while (true) { | ||||
5296 | Qualifiers Quals; | ||||
5297 | T1 = getUnqualifiedArrayType(T1, Quals); | ||||
5298 | T2 = getUnqualifiedArrayType(T2, Quals); | ||||
5299 | if (hasSameType(T1, T2)) | ||||
5300 | return true; | ||||
5301 | if (!UnwrapSimilarTypes(T1, T2)) | ||||
5302 | return false; | ||||
5303 | } | ||||
5304 | } | ||||
5305 | |||||
5306 | bool ASTContext::hasCvrSimilarType(QualType T1, QualType T2) { | ||||
5307 | while (true) { | ||||
5308 | Qualifiers Quals1, Quals2; | ||||
5309 | T1 = getUnqualifiedArrayType(T1, Quals1); | ||||
5310 | T2 = getUnqualifiedArrayType(T2, Quals2); | ||||
5311 | |||||
5312 | Quals1.removeCVRQualifiers(); | ||||
5313 | Quals2.removeCVRQualifiers(); | ||||
5314 | if (Quals1 != Quals2) | ||||
5315 | return false; | ||||
5316 | |||||
5317 | if (hasSameType(T1, T2)) | ||||
5318 | return true; | ||||
5319 | |||||
5320 | if (!UnwrapSimilarTypes(T1, T2)) | ||||
5321 | return false; | ||||
5322 | } | ||||
5323 | } | ||||
5324 | |||||
5325 | DeclarationNameInfo | ||||
5326 | ASTContext::getNameForTemplate(TemplateName Name, | ||||
5327 | SourceLocation NameLoc) const { | ||||
5328 | switch (Name.getKind()) { | ||||
5329 | case TemplateName::QualifiedTemplate: | ||||
5330 | case TemplateName::Template: | ||||
5331 | // DNInfo work in progress: CHECKME: what about DNLoc? | ||||
5332 | return DeclarationNameInfo(Name.getAsTemplateDecl()->getDeclName(), | ||||
5333 | NameLoc); | ||||
5334 | |||||
5335 | case TemplateName::OverloadedTemplate: { | ||||
5336 | OverloadedTemplateStorage *Storage = Name.getAsOverloadedTemplate(); | ||||
5337 | // DNInfo work in progress: CHECKME: what about DNLoc? | ||||
5338 | return DeclarationNameInfo((*Storage->begin())->getDeclName(), NameLoc); | ||||
5339 | } | ||||
5340 | |||||
5341 | case TemplateName::AssumedTemplate: { | ||||
5342 | AssumedTemplateStorage *Storage = Name.getAsAssumedTemplateName(); | ||||
5343 | return DeclarationNameInfo(Storage->getDeclName(), NameLoc); | ||||
5344 | } | ||||
5345 | |||||
5346 | case TemplateName::DependentTemplate: { | ||||
5347 | DependentTemplateName *DTN = Name.getAsDependentTemplateName(); | ||||
5348 | DeclarationName DName; | ||||
5349 | if (DTN->isIdentifier()) { | ||||
5350 | DName = DeclarationNames.getIdentifier(DTN->getIdentifier()); | ||||
5351 | return DeclarationNameInfo(DName, NameLoc); | ||||
5352 | } else { | ||||
5353 | DName = DeclarationNames.getCXXOperatorName(DTN->getOperator()); | ||||
5354 | // DNInfo work in progress: FIXME: source locations? | ||||
5355 | DeclarationNameLoc DNLoc; | ||||
5356 | DNLoc.CXXOperatorName.BeginOpNameLoc = SourceLocation().getRawEncoding(); | ||||
5357 | DNLoc.CXXOperatorName.EndOpNameLoc = SourceLocation().getRawEncoding(); | ||||
5358 | return DeclarationNameInfo(DName, NameLoc, DNLoc); | ||||
5359 | } | ||||
5360 | } | ||||
5361 | |||||
5362 | case TemplateName::SubstTemplateTemplateParm: { | ||||
5363 | SubstTemplateTemplateParmStorage *subst | ||||
5364 | = Name.getAsSubstTemplateTemplateParm(); | ||||
5365 | return DeclarationNameInfo(subst->getParameter()->getDeclName(), | ||||
5366 | NameLoc); | ||||
5367 | } | ||||
5368 | |||||
5369 | case TemplateName::SubstTemplateTemplateParmPack: { | ||||
5370 | SubstTemplateTemplateParmPackStorage *subst | ||||
5371 | = Name.getAsSubstTemplateTemplateParmPack(); | ||||
5372 | return DeclarationNameInfo(subst->getParameterPack()->getDeclName(), | ||||
5373 | NameLoc); | ||||
5374 | } | ||||
5375 | } | ||||
5376 | |||||
5377 | llvm_unreachable("bad template name kind!")::llvm::llvm_unreachable_internal("bad template name kind!", "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 5377); | ||||
5378 | } | ||||
5379 | |||||
5380 | TemplateName ASTContext::getCanonicalTemplateName(TemplateName Name) const { | ||||
5381 | switch (Name.getKind()) { | ||||
5382 | case TemplateName::QualifiedTemplate: | ||||
5383 | case TemplateName::Template: { | ||||
5384 | TemplateDecl *Template = Name.getAsTemplateDecl(); | ||||
5385 | if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(Template)) | ||||
5386 | Template = getCanonicalTemplateTemplateParmDecl(TTP); | ||||
5387 | |||||
5388 | // The canonical template name is the canonical template declaration. | ||||
5389 | return TemplateName(cast<TemplateDecl>(Template->getCanonicalDecl())); | ||||
5390 | } | ||||
5391 | |||||
5392 | case TemplateName::OverloadedTemplate: | ||||
5393 | case TemplateName::AssumedTemplate: | ||||
5394 | llvm_unreachable("cannot canonicalize unresolved template")::llvm::llvm_unreachable_internal("cannot canonicalize unresolved template" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 5394); | ||||
5395 | |||||
5396 | case TemplateName::DependentTemplate: { | ||||
5397 | DependentTemplateName *DTN = Name.getAsDependentTemplateName(); | ||||
5398 | assert(DTN && "Non-dependent template names must refer to template decls.")((DTN && "Non-dependent template names must refer to template decls." ) ? static_cast<void> (0) : __assert_fail ("DTN && \"Non-dependent template names must refer to template decls.\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 5398, __PRETTY_FUNCTION__)); | ||||
5399 | return DTN->CanonicalTemplateName; | ||||
5400 | } | ||||
5401 | |||||
5402 | case TemplateName::SubstTemplateTemplateParm: { | ||||
5403 | SubstTemplateTemplateParmStorage *subst | ||||
5404 | = Name.getAsSubstTemplateTemplateParm(); | ||||
5405 | return getCanonicalTemplateName(subst->getReplacement()); | ||||
5406 | } | ||||
5407 | |||||
5408 | case TemplateName::SubstTemplateTemplateParmPack: { | ||||
5409 | SubstTemplateTemplateParmPackStorage *subst | ||||
5410 | = Name.getAsSubstTemplateTemplateParmPack(); | ||||
5411 | TemplateTemplateParmDecl *canonParameter | ||||
5412 | = getCanonicalTemplateTemplateParmDecl(subst->getParameterPack()); | ||||
5413 | TemplateArgument canonArgPack | ||||
5414 | = getCanonicalTemplateArgument(subst->getArgumentPack()); | ||||
5415 | return getSubstTemplateTemplateParmPack(canonParameter, canonArgPack); | ||||
5416 | } | ||||
5417 | } | ||||
5418 | |||||
5419 | llvm_unreachable("bad template name!")::llvm::llvm_unreachable_internal("bad template name!", "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 5419); | ||||
5420 | } | ||||
5421 | |||||
5422 | bool ASTContext::hasSameTemplateName(TemplateName X, TemplateName Y) { | ||||
5423 | X = getCanonicalTemplateName(X); | ||||
5424 | Y = getCanonicalTemplateName(Y); | ||||
5425 | return X.getAsVoidPointer() == Y.getAsVoidPointer(); | ||||
5426 | } | ||||
5427 | |||||
5428 | TemplateArgument | ||||
5429 | ASTContext::getCanonicalTemplateArgument(const TemplateArgument &Arg) const { | ||||
5430 | switch (Arg.getKind()) { | ||||
5431 | case TemplateArgument::Null: | ||||
5432 | return Arg; | ||||
5433 | |||||
5434 | case TemplateArgument::Expression: | ||||
5435 | return Arg; | ||||
5436 | |||||
5437 | case TemplateArgument::Declaration: { | ||||
5438 | auto *D = cast<ValueDecl>(Arg.getAsDecl()->getCanonicalDecl()); | ||||
5439 | return TemplateArgument(D, Arg.getParamTypeForDecl()); | ||||
5440 | } | ||||
5441 | |||||
5442 | case TemplateArgument::NullPtr: | ||||
5443 | return TemplateArgument(getCanonicalType(Arg.getNullPtrType()), | ||||
5444 | /*isNullPtr*/true); | ||||
5445 | |||||
5446 | case TemplateArgument::Template: | ||||
5447 | return TemplateArgument(getCanonicalTemplateName(Arg.getAsTemplate())); | ||||
5448 | |||||
5449 | case TemplateArgument::TemplateExpansion: | ||||
5450 | return TemplateArgument(getCanonicalTemplateName( | ||||
5451 | Arg.getAsTemplateOrTemplatePattern()), | ||||
5452 | Arg.getNumTemplateExpansions()); | ||||
5453 | |||||
5454 | case TemplateArgument::Integral: | ||||
5455 | return TemplateArgument(Arg, getCanonicalType(Arg.getIntegralType())); | ||||
5456 | |||||
5457 | case TemplateArgument::Type: | ||||
5458 | return TemplateArgument(getCanonicalType(Arg.getAsType())); | ||||
5459 | |||||
5460 | case TemplateArgument::Pack: { | ||||
5461 | if (Arg.pack_size() == 0) | ||||
5462 | return Arg; | ||||
5463 | |||||
5464 | auto *CanonArgs = new (*this) TemplateArgument[Arg.pack_size()]; | ||||
5465 | unsigned Idx = 0; | ||||
5466 | for (TemplateArgument::pack_iterator A = Arg.pack_begin(), | ||||
5467 | AEnd = Arg.pack_end(); | ||||
5468 | A != AEnd; (void)++A, ++Idx) | ||||
5469 | CanonArgs[Idx] = getCanonicalTemplateArgument(*A); | ||||
5470 | |||||
5471 | return TemplateArgument(llvm::makeArrayRef(CanonArgs, Arg.pack_size())); | ||||
5472 | } | ||||
5473 | } | ||||
5474 | |||||
5475 | // Silence GCC warning | ||||
5476 | llvm_unreachable("Unhandled template argument kind")::llvm::llvm_unreachable_internal("Unhandled template argument kind" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 5476); | ||||
5477 | } | ||||
5478 | |||||
5479 | NestedNameSpecifier * | ||||
5480 | ASTContext::getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS) const { | ||||
5481 | if (!NNS) | ||||
5482 | return nullptr; | ||||
5483 | |||||
5484 | switch (NNS->getKind()) { | ||||
5485 | case NestedNameSpecifier::Identifier: | ||||
5486 | // Canonicalize the prefix but keep the identifier the same. | ||||
5487 | return NestedNameSpecifier::Create(*this, | ||||
5488 | getCanonicalNestedNameSpecifier(NNS->getPrefix()), | ||||
5489 | NNS->getAsIdentifier()); | ||||
5490 | |||||
5491 | case NestedNameSpecifier::Namespace: | ||||
5492 | // A namespace is canonical; build a nested-name-specifier with | ||||
5493 | // this namespace and no prefix. | ||||
5494 | return NestedNameSpecifier::Create(*this, nullptr, | ||||
5495 | NNS->getAsNamespace()->getOriginalNamespace()); | ||||
5496 | |||||
5497 | case NestedNameSpecifier::NamespaceAlias: | ||||
5498 | // A namespace is canonical; build a nested-name-specifier with | ||||
5499 | // this namespace and no prefix. | ||||
5500 | return NestedNameSpecifier::Create(*this, nullptr, | ||||
5501 | NNS->getAsNamespaceAlias()->getNamespace() | ||||
5502 | ->getOriginalNamespace()); | ||||
5503 | |||||
5504 | case NestedNameSpecifier::TypeSpec: | ||||
5505 | case NestedNameSpecifier::TypeSpecWithTemplate: { | ||||
5506 | QualType T = getCanonicalType(QualType(NNS->getAsType(), 0)); | ||||
5507 | |||||
5508 | // If we have some kind of dependent-named type (e.g., "typename T::type"), | ||||
5509 | // break it apart into its prefix and identifier, then reconsititute those | ||||
5510 | // as the canonical nested-name-specifier. This is required to canonicalize | ||||
5511 | // a dependent nested-name-specifier involving typedefs of dependent-name | ||||
5512 | // types, e.g., | ||||
5513 | // typedef typename T::type T1; | ||||
5514 | // typedef typename T1::type T2; | ||||
5515 | if (const auto *DNT = T->getAs<DependentNameType>()) | ||||
5516 | return NestedNameSpecifier::Create(*this, DNT->getQualifier(), | ||||
5517 | const_cast<IdentifierInfo *>(DNT->getIdentifier())); | ||||
5518 | |||||
5519 | // Otherwise, just canonicalize the type, and force it to be a TypeSpec. | ||||
5520 | // FIXME: Why are TypeSpec and TypeSpecWithTemplate distinct in the | ||||
5521 | // first place? | ||||
5522 | return NestedNameSpecifier::Create(*this, nullptr, false, | ||||
5523 | const_cast<Type *>(T.getTypePtr())); | ||||
5524 | } | ||||
5525 | |||||
5526 | case NestedNameSpecifier::Global: | ||||
5527 | case NestedNameSpecifier::Super: | ||||
5528 | // The global specifier and __super specifer are canonical and unique. | ||||
5529 | return NNS; | ||||
5530 | } | ||||
5531 | |||||
5532 | llvm_unreachable("Invalid NestedNameSpecifier::Kind!")::llvm::llvm_unreachable_internal("Invalid NestedNameSpecifier::Kind!" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 5532); | ||||
5533 | } | ||||
5534 | |||||
5535 | const ArrayType *ASTContext::getAsArrayType(QualType T) const { | ||||
5536 | // Handle the non-qualified case efficiently. | ||||
5537 | if (!T.hasLocalQualifiers()) { | ||||
5538 | // Handle the common positive case fast. | ||||
5539 | if (const auto *AT = dyn_cast<ArrayType>(T)) | ||||
5540 | return AT; | ||||
5541 | } | ||||
5542 | |||||
5543 | // Handle the common negative case fast. | ||||
5544 | if (!isa<ArrayType>(T.getCanonicalType())) | ||||
5545 | return nullptr; | ||||
5546 | |||||
5547 | // Apply any qualifiers from the array type to the element type. This | ||||
5548 | // implements C99 6.7.3p8: "If the specification of an array type includes | ||||
5549 | // any type qualifiers, the element type is so qualified, not the array type." | ||||
5550 | |||||
5551 | // If we get here, we either have type qualifiers on the type, or we have | ||||
5552 | // sugar such as a typedef in the way. If we have type qualifiers on the type | ||||
5553 | // we must propagate them down into the element type. | ||||
5554 | |||||
5555 | SplitQualType split = T.getSplitDesugaredType(); | ||||
5556 | Qualifiers qs = split.Quals; | ||||
5557 | |||||
5558 | // If we have a simple case, just return now. | ||||
5559 | const auto *ATy = dyn_cast<ArrayType>(split.Ty); | ||||
5560 | if (!ATy || qs.empty()) | ||||
5561 | return ATy; | ||||
5562 | |||||
5563 | // Otherwise, we have an array and we have qualifiers on it. Push the | ||||
5564 | // qualifiers into the array element type and return a new array type. | ||||
5565 | QualType NewEltTy = getQualifiedType(ATy->getElementType(), qs); | ||||
5566 | |||||
5567 | if (const auto *CAT = dyn_cast<ConstantArrayType>(ATy)) | ||||
5568 | return cast<ArrayType>(getConstantArrayType(NewEltTy, CAT->getSize(), | ||||
5569 | CAT->getSizeModifier(), | ||||
5570 | CAT->getIndexTypeCVRQualifiers())); | ||||
5571 | if (const auto *IAT = dyn_cast<IncompleteArrayType>(ATy)) | ||||
5572 | return cast<ArrayType>(getIncompleteArrayType(NewEltTy, | ||||
5573 | IAT->getSizeModifier(), | ||||
5574 | IAT->getIndexTypeCVRQualifiers())); | ||||
5575 | |||||
5576 | if (const auto *DSAT = dyn_cast<DependentSizedArrayType>(ATy)) | ||||
5577 | return cast<ArrayType>( | ||||
5578 | getDependentSizedArrayType(NewEltTy, | ||||
5579 | DSAT->getSizeExpr(), | ||||
5580 | DSAT->getSizeModifier(), | ||||
5581 | DSAT->getIndexTypeCVRQualifiers(), | ||||
5582 | DSAT->getBracketsRange())); | ||||
5583 | |||||
5584 | const auto *VAT = cast<VariableArrayType>(ATy); | ||||
5585 | return cast<ArrayType>(getVariableArrayType(NewEltTy, | ||||
5586 | VAT->getSizeExpr(), | ||||
5587 | VAT->getSizeModifier(), | ||||
5588 | VAT->getIndexTypeCVRQualifiers(), | ||||
5589 | VAT->getBracketsRange())); | ||||
5590 | } | ||||
5591 | |||||
5592 | QualType ASTContext::getAdjustedParameterType(QualType T) const { | ||||
5593 | if (T->isArrayType() || T->isFunctionType()) | ||||
5594 | return getDecayedType(T); | ||||
5595 | return T; | ||||
5596 | } | ||||
5597 | |||||
5598 | QualType ASTContext::getSignatureParameterType(QualType T) const { | ||||
5599 | T = getVariableArrayDecayedType(T); | ||||
5600 | T = getAdjustedParameterType(T); | ||||
5601 | return T.getUnqualifiedType(); | ||||
5602 | } | ||||
5603 | |||||
5604 | QualType ASTContext::getExceptionObjectType(QualType T) const { | ||||
5605 | // C++ [except.throw]p3: | ||||
5606 | // A throw-expression initializes a temporary object, called the exception | ||||
5607 | // object, the type of which is determined by removing any top-level | ||||
5608 | // cv-qualifiers from the static type of the operand of throw and adjusting | ||||
5609 | // the type from "array of T" or "function returning T" to "pointer to T" | ||||
5610 | // or "pointer to function returning T", [...] | ||||
5611 | T = getVariableArrayDecayedType(T); | ||||
5612 | if (T->isArrayType() || T->isFunctionType()) | ||||
5613 | T = getDecayedType(T); | ||||
5614 | return T.getUnqualifiedType(); | ||||
5615 | } | ||||
5616 | |||||
5617 | /// getArrayDecayedType - Return the properly qualified result of decaying the | ||||
5618 | /// specified array type to a pointer. This operation is non-trivial when | ||||
5619 | /// handling typedefs etc. The canonical type of "T" must be an array type, | ||||
5620 | /// this returns a pointer to a properly qualified element of the array. | ||||
5621 | /// | ||||
5622 | /// See C99 6.7.5.3p7 and C99 6.3.2.1p3. | ||||
5623 | QualType ASTContext::getArrayDecayedType(QualType Ty) const { | ||||
5624 | // Get the element type with 'getAsArrayType' so that we don't lose any | ||||
5625 | // typedefs in the element type of the array. This also handles propagation | ||||
5626 | // of type qualifiers from the array type into the element type if present | ||||
5627 | // (C99 6.7.3p8). | ||||
5628 | const ArrayType *PrettyArrayType = getAsArrayType(Ty); | ||||
5629 | assert(PrettyArrayType && "Not an array type!")((PrettyArrayType && "Not an array type!") ? static_cast <void> (0) : __assert_fail ("PrettyArrayType && \"Not an array type!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 5629, __PRETTY_FUNCTION__)); | ||||
5630 | |||||
5631 | QualType PtrTy = getPointerType(PrettyArrayType->getElementType()); | ||||
5632 | |||||
5633 | // int x[restrict 4] -> int *restrict | ||||
5634 | QualType Result = getQualifiedType(PtrTy, | ||||
5635 | PrettyArrayType->getIndexTypeQualifiers()); | ||||
5636 | |||||
5637 | // int x[_Nullable] -> int * _Nullable | ||||
5638 | if (auto Nullability = Ty->getNullability(*this)) { | ||||
5639 | Result = const_cast<ASTContext *>(this)->getAttributedType( | ||||
5640 | AttributedType::getNullabilityAttrKind(*Nullability), Result, Result); | ||||
5641 | } | ||||
5642 | return Result; | ||||
5643 | } | ||||
5644 | |||||
5645 | QualType ASTContext::getBaseElementType(const ArrayType *array) const { | ||||
5646 | return getBaseElementType(array->getElementType()); | ||||
5647 | } | ||||
5648 | |||||
5649 | QualType ASTContext::getBaseElementType(QualType type) const { | ||||
5650 | Qualifiers qs; | ||||
5651 | while (true) { | ||||
5652 | SplitQualType split = type.getSplitDesugaredType(); | ||||
5653 | const ArrayType *array = split.Ty->getAsArrayTypeUnsafe(); | ||||
5654 | if (!array) break; | ||||
5655 | |||||
5656 | type = array->getElementType(); | ||||
5657 | qs.addConsistentQualifiers(split.Quals); | ||||
5658 | } | ||||
5659 | |||||
5660 | return getQualifiedType(type, qs); | ||||
5661 | } | ||||
5662 | |||||
5663 | /// getConstantArrayElementCount - Returns number of constant array elements. | ||||
5664 | uint64_t | ||||
5665 | ASTContext::getConstantArrayElementCount(const ConstantArrayType *CA) const { | ||||
5666 | uint64_t ElementCount = 1; | ||||
5667 | do { | ||||
5668 | ElementCount *= CA->getSize().getZExtValue(); | ||||
5669 | CA = dyn_cast_or_null<ConstantArrayType>( | ||||
5670 | CA->getElementType()->getAsArrayTypeUnsafe()); | ||||
5671 | } while (CA); | ||||
5672 | return ElementCount; | ||||
5673 | } | ||||
5674 | |||||
5675 | /// getFloatingRank - Return a relative rank for floating point types. | ||||
5676 | /// This routine will assert if passed a built-in type that isn't a float. | ||||
5677 | static FloatingRank getFloatingRank(QualType T) { | ||||
5678 | if (const auto *CT = T->getAs<ComplexType>()) | ||||
5679 | return getFloatingRank(CT->getElementType()); | ||||
5680 | |||||
5681 | assert(T->getAs<BuiltinType>() && "getFloatingRank(): not a floating type")((T->getAs<BuiltinType>() && "getFloatingRank(): not a floating type" ) ? static_cast<void> (0) : __assert_fail ("T->getAs<BuiltinType>() && \"getFloatingRank(): not a floating type\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 5681, __PRETTY_FUNCTION__)); | ||||
5682 | switch (T->castAs<BuiltinType>()->getKind()) { | ||||
5683 | default: llvm_unreachable("getFloatingRank(): not a floating type")::llvm::llvm_unreachable_internal("getFloatingRank(): not a floating type" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 5683); | ||||
5684 | case BuiltinType::Float16: return Float16Rank; | ||||
5685 | case BuiltinType::Half: return HalfRank; | ||||
5686 | case BuiltinType::Float: return FloatRank; | ||||
5687 | case BuiltinType::Double: return DoubleRank; | ||||
5688 | case BuiltinType::LongDouble: return LongDoubleRank; | ||||
5689 | case BuiltinType::Float128: return Float128Rank; | ||||
5690 | } | ||||
5691 | } | ||||
5692 | |||||
5693 | /// getFloatingTypeOfSizeWithinDomain - Returns a real floating | ||||
5694 | /// point or a complex type (based on typeDomain/typeSize). | ||||
5695 | /// 'typeDomain' is a real floating point or complex type. | ||||
5696 | /// 'typeSize' is a real floating point or complex type. | ||||
5697 | QualType ASTContext::getFloatingTypeOfSizeWithinDomain(QualType Size, | ||||
5698 | QualType Domain) const { | ||||
5699 | FloatingRank EltRank = getFloatingRank(Size); | ||||
5700 | if (Domain->isComplexType()) { | ||||
5701 | switch (EltRank) { | ||||
5702 | case Float16Rank: | ||||
5703 | case HalfRank: llvm_unreachable("Complex half is not supported")::llvm::llvm_unreachable_internal("Complex half is not supported" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 5703); | ||||
5704 | case FloatRank: return FloatComplexTy; | ||||
5705 | case DoubleRank: return DoubleComplexTy; | ||||
5706 | case LongDoubleRank: return LongDoubleComplexTy; | ||||
5707 | case Float128Rank: return Float128ComplexTy; | ||||
5708 | } | ||||
5709 | } | ||||
5710 | |||||
5711 | assert(Domain->isRealFloatingType() && "Unknown domain!")((Domain->isRealFloatingType() && "Unknown domain!" ) ? static_cast<void> (0) : __assert_fail ("Domain->isRealFloatingType() && \"Unknown domain!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 5711, __PRETTY_FUNCTION__)); | ||||
5712 | switch (EltRank) { | ||||
5713 | case Float16Rank: return HalfTy; | ||||
5714 | case HalfRank: return HalfTy; | ||||
5715 | case FloatRank: return FloatTy; | ||||
5716 | case DoubleRank: return DoubleTy; | ||||
5717 | case LongDoubleRank: return LongDoubleTy; | ||||
5718 | case Float128Rank: return Float128Ty; | ||||
5719 | } | ||||
5720 | llvm_unreachable("getFloatingRank(): illegal value for rank")::llvm::llvm_unreachable_internal("getFloatingRank(): illegal value for rank" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 5720); | ||||
5721 | } | ||||
5722 | |||||
5723 | /// getFloatingTypeOrder - Compare the rank of the two specified floating | ||||
5724 | /// point types, ignoring the domain of the type (i.e. 'double' == | ||||
5725 | /// '_Complex double'). If LHS > RHS, return 1. If LHS == RHS, return 0. If | ||||
5726 | /// LHS < RHS, return -1. | ||||
5727 | int ASTContext::getFloatingTypeOrder(QualType LHS, QualType RHS) const { | ||||
5728 | FloatingRank LHSR = getFloatingRank(LHS); | ||||
5729 | FloatingRank RHSR = getFloatingRank(RHS); | ||||
5730 | |||||
5731 | if (LHSR == RHSR) | ||||
5732 | return 0; | ||||
5733 | if (LHSR > RHSR) | ||||
5734 | return 1; | ||||
5735 | return -1; | ||||
5736 | } | ||||
5737 | |||||
5738 | int ASTContext::getFloatingTypeSemanticOrder(QualType LHS, QualType RHS) const { | ||||
5739 | if (&getFloatTypeSemantics(LHS) == &getFloatTypeSemantics(RHS)) | ||||
5740 | return 0; | ||||
5741 | return getFloatingTypeOrder(LHS, RHS); | ||||
5742 | } | ||||
5743 | |||||
5744 | /// getIntegerRank - Return an integer conversion rank (C99 6.3.1.1p1). This | ||||
5745 | /// routine will assert if passed a built-in type that isn't an integer or enum, | ||||
5746 | /// or if it is not canonicalized. | ||||
5747 | unsigned ASTContext::getIntegerRank(const Type *T) const { | ||||
5748 | assert(T->isCanonicalUnqualified() && "T should be canonicalized")((T->isCanonicalUnqualified() && "T should be canonicalized" ) ? static_cast<void> (0) : __assert_fail ("T->isCanonicalUnqualified() && \"T should be canonicalized\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 5748, __PRETTY_FUNCTION__)); | ||||
5749 | |||||
5750 | switch (cast<BuiltinType>(T)->getKind()) { | ||||
5751 | default: llvm_unreachable("getIntegerRank(): not a built-in integer")::llvm::llvm_unreachable_internal("getIntegerRank(): not a built-in integer" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 5751); | ||||
5752 | case BuiltinType::Bool: | ||||
5753 | return 1 + (getIntWidth(BoolTy) << 3); | ||||
5754 | case BuiltinType::Char_S: | ||||
5755 | case BuiltinType::Char_U: | ||||
5756 | case BuiltinType::SChar: | ||||
5757 | case BuiltinType::UChar: | ||||
5758 | return 2 + (getIntWidth(CharTy) << 3); | ||||
5759 | case BuiltinType::Short: | ||||
5760 | case BuiltinType::UShort: | ||||
5761 | return 3 + (getIntWidth(ShortTy) << 3); | ||||
5762 | case BuiltinType::Int: | ||||
5763 | case BuiltinType::UInt: | ||||
5764 | return 4 + (getIntWidth(IntTy) << 3); | ||||
5765 | case BuiltinType::Long: | ||||
5766 | case BuiltinType::ULong: | ||||
5767 | return 5 + (getIntWidth(LongTy) << 3); | ||||
5768 | case BuiltinType::LongLong: | ||||
5769 | case BuiltinType::ULongLong: | ||||
5770 | return 6 + (getIntWidth(LongLongTy) << 3); | ||||
5771 | case BuiltinType::Int128: | ||||
5772 | case BuiltinType::UInt128: | ||||
5773 | return 7 + (getIntWidth(Int128Ty) << 3); | ||||
5774 | } | ||||
5775 | } | ||||
5776 | |||||
5777 | /// Whether this is a promotable bitfield reference according | ||||
5778 | /// to C99 6.3.1.1p2, bullet 2 (and GCC extensions). | ||||
5779 | /// | ||||
5780 | /// \returns the type this bit-field will promote to, or NULL if no | ||||
5781 | /// promotion occurs. | ||||
5782 | QualType ASTContext::isPromotableBitField(Expr *E) const { | ||||
5783 | if (E->isTypeDependent() || E->isValueDependent()) | ||||
5784 | return {}; | ||||
5785 | |||||
5786 | // C++ [conv.prom]p5: | ||||
5787 | // If the bit-field has an enumerated type, it is treated as any other | ||||
5788 | // value of that type for promotion purposes. | ||||
5789 | if (getLangOpts().CPlusPlus && E->getType()->isEnumeralType()) | ||||
5790 | return {}; | ||||
5791 | |||||
5792 | // FIXME: We should not do this unless E->refersToBitField() is true. This | ||||
5793 | // matters in C where getSourceBitField() will find bit-fields for various | ||||
5794 | // cases where the source expression is not a bit-field designator. | ||||
5795 | |||||
5796 | FieldDecl *Field = E->getSourceBitField(); // FIXME: conditional bit-fields? | ||||
5797 | if (!Field) | ||||
5798 | return {}; | ||||
5799 | |||||
5800 | QualType FT = Field->getType(); | ||||
5801 | |||||
5802 | uint64_t BitWidth = Field->getBitWidthValue(*this); | ||||
5803 | uint64_t IntSize = getTypeSize(IntTy); | ||||
5804 | // C++ [conv.prom]p5: | ||||
5805 | // A prvalue for an integral bit-field can be converted to a prvalue of type | ||||
5806 | // int if int can represent all the values of the bit-field; otherwise, it | ||||
5807 | // can be converted to unsigned int if unsigned int can represent all the | ||||
5808 | // values of the bit-field. If the bit-field is larger yet, no integral | ||||
5809 | // promotion applies to it. | ||||
5810 | // C11 6.3.1.1/2: | ||||
5811 | // [For a bit-field of type _Bool, int, signed int, or unsigned int:] | ||||
5812 | // If an int can represent all values of the original type (as restricted by | ||||
5813 | // the width, for a bit-field), the value is converted to an int; otherwise, | ||||
5814 | // it is converted to an unsigned int. | ||||
5815 | // | ||||
5816 | // FIXME: C does not permit promotion of a 'long : 3' bitfield to int. | ||||
5817 | // We perform that promotion here to match GCC and C++. | ||||
5818 | // FIXME: C does not permit promotion of an enum bit-field whose rank is | ||||
5819 | // greater than that of 'int'. We perform that promotion to match GCC. | ||||
5820 | if (BitWidth < IntSize) | ||||
5821 | return IntTy; | ||||
5822 | |||||
5823 | if (BitWidth == IntSize) | ||||
5824 | return FT->isSignedIntegerType() ? IntTy : UnsignedIntTy; | ||||
5825 | |||||
5826 | // Bit-fields wider than int are not subject to promotions, and therefore act | ||||
5827 | // like the base type. GCC has some weird bugs in this area that we | ||||
5828 | // deliberately do not follow (GCC follows a pre-standard resolution to | ||||
5829 | // C's DR315 which treats bit-width as being part of the type, and this leaks | ||||
5830 | // into their semantics in some cases). | ||||
5831 | return {}; | ||||
5832 | } | ||||
5833 | |||||
5834 | /// getPromotedIntegerType - Returns the type that Promotable will | ||||
5835 | /// promote to: C99 6.3.1.1p2, assuming that Promotable is a promotable | ||||
5836 | /// integer type. | ||||
5837 | QualType ASTContext::getPromotedIntegerType(QualType Promotable) const { | ||||
5838 | assert(!Promotable.isNull())((!Promotable.isNull()) ? static_cast<void> (0) : __assert_fail ("!Promotable.isNull()", "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 5838, __PRETTY_FUNCTION__)); | ||||
5839 | assert(Promotable->isPromotableIntegerType())((Promotable->isPromotableIntegerType()) ? static_cast< void> (0) : __assert_fail ("Promotable->isPromotableIntegerType()" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 5839, __PRETTY_FUNCTION__)); | ||||
5840 | if (const auto *ET = Promotable->getAs<EnumType>()) | ||||
5841 | return ET->getDecl()->getPromotionType(); | ||||
5842 | |||||
5843 | if (const auto *BT = Promotable->getAs<BuiltinType>()) { | ||||
5844 | // C++ [conv.prom]: A prvalue of type char16_t, char32_t, or wchar_t | ||||
5845 | // (3.9.1) can be converted to a prvalue of the first of the following | ||||
5846 | // types that can represent all the values of its underlying type: | ||||
5847 | // int, unsigned int, long int, unsigned long int, long long int, or | ||||
5848 | // unsigned long long int [...] | ||||
5849 | // FIXME: Is there some better way to compute this? | ||||
5850 | if (BT->getKind() == BuiltinType::WChar_S || | ||||
5851 | BT->getKind() == BuiltinType::WChar_U || | ||||
5852 | BT->getKind() == BuiltinType::Char8 || | ||||
5853 | BT->getKind() == BuiltinType::Char16 || | ||||
5854 | BT->getKind() == BuiltinType::Char32) { | ||||
5855 | bool FromIsSigned = BT->getKind() == BuiltinType::WChar_S; | ||||
5856 | uint64_t FromSize = getTypeSize(BT); | ||||
5857 | QualType PromoteTypes[] = { IntTy, UnsignedIntTy, LongTy, UnsignedLongTy, | ||||
5858 | LongLongTy, UnsignedLongLongTy }; | ||||
5859 | for (size_t Idx = 0; Idx < llvm::array_lengthof(PromoteTypes); ++Idx) { | ||||
5860 | uint64_t ToSize = getTypeSize(PromoteTypes[Idx]); | ||||
5861 | if (FromSize < ToSize || | ||||
5862 | (FromSize == ToSize && | ||||
5863 | FromIsSigned == PromoteTypes[Idx]->isSignedIntegerType())) | ||||
5864 | return PromoteTypes[Idx]; | ||||
5865 | } | ||||
5866 | llvm_unreachable("char type should fit into long long")::llvm::llvm_unreachable_internal("char type should fit into long long" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 5866); | ||||
5867 | } | ||||
5868 | } | ||||
5869 | |||||
5870 | // At this point, we should have a signed or unsigned integer type. | ||||
5871 | if (Promotable->isSignedIntegerType()) | ||||
5872 | return IntTy; | ||||
5873 | uint64_t PromotableSize = getIntWidth(Promotable); | ||||
5874 | uint64_t IntSize = getIntWidth(IntTy); | ||||
5875 | assert(Promotable->isUnsignedIntegerType() && PromotableSize <= IntSize)((Promotable->isUnsignedIntegerType() && PromotableSize <= IntSize) ? static_cast<void> (0) : __assert_fail ("Promotable->isUnsignedIntegerType() && PromotableSize <= IntSize" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 5875, __PRETTY_FUNCTION__)); | ||||
5876 | return (PromotableSize != IntSize) ? IntTy : UnsignedIntTy; | ||||
5877 | } | ||||
5878 | |||||
5879 | /// Recurses in pointer/array types until it finds an objc retainable | ||||
5880 | /// type and returns its ownership. | ||||
5881 | Qualifiers::ObjCLifetime ASTContext::getInnerObjCOwnership(QualType T) const { | ||||
5882 | while (!T.isNull()) { | ||||
5883 | if (T.getObjCLifetime() != Qualifiers::OCL_None) | ||||
5884 | return T.getObjCLifetime(); | ||||
5885 | if (T->isArrayType()) | ||||
5886 | T = getBaseElementType(T); | ||||
5887 | else if (const auto *PT = T->getAs<PointerType>()) | ||||
5888 | T = PT->getPointeeType(); | ||||
5889 | else if (const auto *RT = T->getAs<ReferenceType>()) | ||||
5890 | T = RT->getPointeeType(); | ||||
5891 | else | ||||
5892 | break; | ||||
5893 | } | ||||
5894 | |||||
5895 | return Qualifiers::OCL_None; | ||||
5896 | } | ||||
5897 | |||||
5898 | static const Type *getIntegerTypeForEnum(const EnumType *ET) { | ||||
5899 | // Incomplete enum types are not treated as integer types. | ||||
5900 | // FIXME: In C++, enum types are never integer types. | ||||
5901 | if (ET->getDecl()->isComplete() && !ET->getDecl()->isScoped()) | ||||
5902 | return ET->getDecl()->getIntegerType().getTypePtr(); | ||||
5903 | return nullptr; | ||||
5904 | } | ||||
5905 | |||||
5906 | /// getIntegerTypeOrder - Returns the highest ranked integer type: | ||||
5907 | /// C99 6.3.1.8p1. If LHS > RHS, return 1. If LHS == RHS, return 0. If | ||||
5908 | /// LHS < RHS, return -1. | ||||
5909 | int ASTContext::getIntegerTypeOrder(QualType LHS, QualType RHS) const { | ||||
5910 | const Type *LHSC = getCanonicalType(LHS).getTypePtr(); | ||||
5911 | const Type *RHSC = getCanonicalType(RHS).getTypePtr(); | ||||
5912 | |||||
5913 | // Unwrap enums to their underlying type. | ||||
5914 | if (const auto *ET = dyn_cast<EnumType>(LHSC)) | ||||
5915 | LHSC = getIntegerTypeForEnum(ET); | ||||
5916 | if (const auto *ET = dyn_cast<EnumType>(RHSC)) | ||||
5917 | RHSC = getIntegerTypeForEnum(ET); | ||||
5918 | |||||
5919 | if (LHSC == RHSC) return 0; | ||||
5920 | |||||
5921 | bool LHSUnsigned = LHSC->isUnsignedIntegerType(); | ||||
5922 | bool RHSUnsigned = RHSC->isUnsignedIntegerType(); | ||||
5923 | |||||
5924 | unsigned LHSRank = getIntegerRank(LHSC); | ||||
5925 | unsigned RHSRank = getIntegerRank(RHSC); | ||||
5926 | |||||
5927 | if (LHSUnsigned == RHSUnsigned) { // Both signed or both unsigned. | ||||
5928 | if (LHSRank == RHSRank) return 0; | ||||
5929 | return LHSRank > RHSRank ? 1 : -1; | ||||
5930 | } | ||||
5931 | |||||
5932 | // Otherwise, the LHS is signed and the RHS is unsigned or visa versa. | ||||
5933 | if (LHSUnsigned) { | ||||
5934 | // If the unsigned [LHS] type is larger, return it. | ||||
5935 | if (LHSRank >= RHSRank) | ||||
5936 | return 1; | ||||
5937 | |||||
5938 | // If the signed type can represent all values of the unsigned type, it | ||||
5939 | // wins. Because we are dealing with 2's complement and types that are | ||||
5940 | // powers of two larger than each other, this is always safe. | ||||
5941 | return -1; | ||||
5942 | } | ||||
5943 | |||||
5944 | // If the unsigned [RHS] type is larger, return it. | ||||
5945 | if (RHSRank >= LHSRank) | ||||
5946 | return -1; | ||||
5947 | |||||
5948 | // If the signed type can represent all values of the unsigned type, it | ||||
5949 | // wins. Because we are dealing with 2's complement and types that are | ||||
5950 | // powers of two larger than each other, this is always safe. | ||||
5951 | return 1; | ||||
5952 | } | ||||
5953 | |||||
5954 | TypedefDecl *ASTContext::getCFConstantStringDecl() const { | ||||
5955 | if (CFConstantStringTypeDecl) | ||||
5956 | return CFConstantStringTypeDecl; | ||||
5957 | |||||
5958 | assert(!CFConstantStringTagDecl &&((!CFConstantStringTagDecl && "tag and typedef should be initialized together" ) ? static_cast<void> (0) : __assert_fail ("!CFConstantStringTagDecl && \"tag and typedef should be initialized together\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 5959, __PRETTY_FUNCTION__)) | ||||
5959 | "tag and typedef should be initialized together")((!CFConstantStringTagDecl && "tag and typedef should be initialized together" ) ? static_cast<void> (0) : __assert_fail ("!CFConstantStringTagDecl && \"tag and typedef should be initialized together\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 5959, __PRETTY_FUNCTION__)); | ||||
5960 | CFConstantStringTagDecl = buildImplicitRecord("__NSConstantString_tag"); | ||||
5961 | CFConstantStringTagDecl->startDefinition(); | ||||
5962 | |||||
5963 | struct { | ||||
5964 | QualType Type; | ||||
5965 | const char *Name; | ||||
5966 | } Fields[5]; | ||||
5967 | unsigned Count = 0; | ||||
5968 | |||||
5969 | /// Objective-C ABI | ||||
5970 | /// | ||||
5971 | /// typedef struct __NSConstantString_tag { | ||||
5972 | /// const int *isa; | ||||
5973 | /// int flags; | ||||
5974 | /// const char *str; | ||||
5975 | /// long length; | ||||
5976 | /// } __NSConstantString; | ||||
5977 | /// | ||||
5978 | /// Swift ABI (4.1, 4.2) | ||||
5979 | /// | ||||
5980 | /// typedef struct __NSConstantString_tag { | ||||
5981 | /// uintptr_t _cfisa; | ||||
5982 | /// uintptr_t _swift_rc; | ||||
5983 | /// _Atomic(uint64_t) _cfinfoa; | ||||
5984 | /// const char *_ptr; | ||||
5985 | /// uint32_t _length; | ||||
5986 | /// } __NSConstantString; | ||||
5987 | /// | ||||
5988 | /// Swift ABI (5.0) | ||||
5989 | /// | ||||
5990 | /// typedef struct __NSConstantString_tag { | ||||
5991 | /// uintptr_t _cfisa; | ||||
5992 | /// uintptr_t _swift_rc; | ||||
5993 | /// _Atomic(uint64_t) _cfinfoa; | ||||
5994 | /// const char *_ptr; | ||||
5995 | /// uintptr_t _length; | ||||
5996 | /// } __NSConstantString; | ||||
5997 | |||||
5998 | const auto CFRuntime = getLangOpts().CFRuntime; | ||||
5999 | if (static_cast<unsigned>(CFRuntime) < | ||||
6000 | static_cast<unsigned>(LangOptions::CoreFoundationABI::Swift)) { | ||||
6001 | Fields[Count++] = { getPointerType(IntTy.withConst()), "isa" }; | ||||
6002 | Fields[Count++] = { IntTy, "flags" }; | ||||
6003 | Fields[Count++] = { getPointerType(CharTy.withConst()), "str" }; | ||||
6004 | Fields[Count++] = { LongTy, "length" }; | ||||
6005 | } else { | ||||
6006 | Fields[Count++] = { getUIntPtrType(), "_cfisa" }; | ||||
6007 | Fields[Count++] = { getUIntPtrType(), "_swift_rc" }; | ||||
6008 | Fields[Count++] = { getFromTargetType(Target->getUInt64Type()), "_swift_rc" }; | ||||
6009 | Fields[Count++] = { getPointerType(CharTy.withConst()), "_ptr" }; | ||||
6010 | if (CFRuntime == LangOptions::CoreFoundationABI::Swift4_1 || | ||||
6011 | CFRuntime == LangOptions::CoreFoundationABI::Swift4_2) | ||||
6012 | Fields[Count++] = { IntTy, "_ptr" }; | ||||
6013 | else | ||||
6014 | Fields[Count++] = { getUIntPtrType(), "_ptr" }; | ||||
6015 | } | ||||
6016 | |||||
6017 | // Create fields | ||||
6018 | for (unsigned i = 0; i < Count; ++i) { | ||||
6019 | FieldDecl *Field = | ||||
6020 | FieldDecl::Create(*this, CFConstantStringTagDecl, SourceLocation(), | ||||
6021 | SourceLocation(), &Idents.get(Fields[i].Name), | ||||
6022 | Fields[i].Type, /*TInfo=*/nullptr, | ||||
6023 | /*BitWidth=*/nullptr, /*Mutable=*/false, ICIS_NoInit); | ||||
6024 | Field->setAccess(AS_public); | ||||
6025 | CFConstantStringTagDecl->addDecl(Field); | ||||
6026 | } | ||||
6027 | |||||
6028 | CFConstantStringTagDecl->completeDefinition(); | ||||
6029 | // This type is designed to be compatible with NSConstantString, but cannot | ||||
6030 | // use the same name, since NSConstantString is an interface. | ||||
6031 | auto tagType = getTagDeclType(CFConstantStringTagDecl); | ||||
6032 | CFConstantStringTypeDecl = | ||||
6033 | buildImplicitTypedef(tagType, "__NSConstantString"); | ||||
6034 | |||||
6035 | return CFConstantStringTypeDecl; | ||||
6036 | } | ||||
6037 | |||||
6038 | RecordDecl *ASTContext::getCFConstantStringTagDecl() const { | ||||
6039 | if (!CFConstantStringTagDecl) | ||||
6040 | getCFConstantStringDecl(); // Build the tag and the typedef. | ||||
6041 | return CFConstantStringTagDecl; | ||||
6042 | } | ||||
6043 | |||||
6044 | // getCFConstantStringType - Return the type used for constant CFStrings. | ||||
6045 | QualType ASTContext::getCFConstantStringType() const { | ||||
6046 | return getTypedefType(getCFConstantStringDecl()); | ||||
6047 | } | ||||
6048 | |||||
6049 | QualType ASTContext::getObjCSuperType() const { | ||||
6050 | if (ObjCSuperType.isNull()) { | ||||
6051 | RecordDecl *ObjCSuperTypeDecl = buildImplicitRecord("objc_super"); | ||||
6052 | TUDecl->addDecl(ObjCSuperTypeDecl); | ||||
6053 | ObjCSuperType = getTagDeclType(ObjCSuperTypeDecl); | ||||
6054 | } | ||||
6055 | return ObjCSuperType; | ||||
6056 | } | ||||
6057 | |||||
6058 | void ASTContext::setCFConstantStringType(QualType T) { | ||||
6059 | const auto *TD = T->getAs<TypedefType>(); | ||||
6060 | assert(TD && "Invalid CFConstantStringType")((TD && "Invalid CFConstantStringType") ? static_cast <void> (0) : __assert_fail ("TD && \"Invalid CFConstantStringType\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 6060, __PRETTY_FUNCTION__)); | ||||
6061 | CFConstantStringTypeDecl = cast<TypedefDecl>(TD->getDecl()); | ||||
6062 | const auto *TagType = | ||||
6063 | CFConstantStringTypeDecl->getUnderlyingType()->getAs<RecordType>(); | ||||
6064 | assert(TagType && "Invalid CFConstantStringType")((TagType && "Invalid CFConstantStringType") ? static_cast <void> (0) : __assert_fail ("TagType && \"Invalid CFConstantStringType\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 6064, __PRETTY_FUNCTION__)); | ||||
6065 | CFConstantStringTagDecl = TagType->getDecl(); | ||||
6066 | } | ||||
6067 | |||||
6068 | QualType ASTContext::getBlockDescriptorType() const { | ||||
6069 | if (BlockDescriptorType) | ||||
6070 | return getTagDeclType(BlockDescriptorType); | ||||
6071 | |||||
6072 | RecordDecl *RD; | ||||
6073 | // FIXME: Needs the FlagAppleBlock bit. | ||||
6074 | RD = buildImplicitRecord("__block_descriptor"); | ||||
6075 | RD->startDefinition(); | ||||
6076 | |||||
6077 | QualType FieldTypes[] = { | ||||
6078 | UnsignedLongTy, | ||||
6079 | UnsignedLongTy, | ||||
6080 | }; | ||||
6081 | |||||
6082 | static const char *const FieldNames[] = { | ||||
6083 | "reserved", | ||||
6084 | "Size" | ||||
6085 | }; | ||||
6086 | |||||
6087 | for (size_t i = 0; i < 2; ++i) { | ||||
6088 | FieldDecl *Field = FieldDecl::Create( | ||||
6089 | *this, RD, SourceLocation(), SourceLocation(), | ||||
6090 | &Idents.get(FieldNames[i]), FieldTypes[i], /*TInfo=*/nullptr, | ||||
6091 | /*BitWidth=*/nullptr, /*Mutable=*/false, ICIS_NoInit); | ||||
6092 | Field->setAccess(AS_public); | ||||
6093 | RD->addDecl(Field); | ||||
6094 | } | ||||
6095 | |||||
6096 | RD->completeDefinition(); | ||||
6097 | |||||
6098 | BlockDescriptorType = RD; | ||||
6099 | |||||
6100 | return getTagDeclType(BlockDescriptorType); | ||||
6101 | } | ||||
6102 | |||||
6103 | QualType ASTContext::getBlockDescriptorExtendedType() const { | ||||
6104 | if (BlockDescriptorExtendedType) | ||||
6105 | return getTagDeclType(BlockDescriptorExtendedType); | ||||
6106 | |||||
6107 | RecordDecl *RD; | ||||
6108 | // FIXME: Needs the FlagAppleBlock bit. | ||||
6109 | RD = buildImplicitRecord("__block_descriptor_withcopydispose"); | ||||
6110 | RD->startDefinition(); | ||||
6111 | |||||
6112 | QualType FieldTypes[] = { | ||||
6113 | UnsignedLongTy, | ||||
6114 | UnsignedLongTy, | ||||
6115 | getPointerType(VoidPtrTy), | ||||
6116 | getPointerType(VoidPtrTy) | ||||
6117 | }; | ||||
6118 | |||||
6119 | static const char *const FieldNames[] = { | ||||
6120 | "reserved", | ||||
6121 | "Size", | ||||
6122 | "CopyFuncPtr", | ||||
6123 | "DestroyFuncPtr" | ||||
6124 | }; | ||||
6125 | |||||
6126 | for (size_t i = 0; i < 4; ++i) { | ||||
6127 | FieldDecl *Field = FieldDecl::Create( | ||||
6128 | *this, RD, SourceLocation(), SourceLocation(), | ||||
6129 | &Idents.get(FieldNames[i]), FieldTypes[i], /*TInfo=*/nullptr, | ||||
6130 | /*BitWidth=*/nullptr, | ||||
6131 | /*Mutable=*/false, ICIS_NoInit); | ||||
6132 | Field->setAccess(AS_public); | ||||
6133 | RD->addDecl(Field); | ||||
6134 | } | ||||
6135 | |||||
6136 | RD->completeDefinition(); | ||||
6137 | |||||
6138 | BlockDescriptorExtendedType = RD; | ||||
6139 | return getTagDeclType(BlockDescriptorExtendedType); | ||||
6140 | } | ||||
6141 | |||||
6142 | TargetInfo::OpenCLTypeKind ASTContext::getOpenCLTypeKind(const Type *T) const { | ||||
6143 | const auto *BT = dyn_cast<BuiltinType>(T); | ||||
6144 | |||||
6145 | if (!BT) { | ||||
6146 | if (isa<PipeType>(T)) | ||||
6147 | return TargetInfo::OCLTK_Pipe; | ||||
6148 | |||||
6149 | return TargetInfo::OCLTK_Default; | ||||
6150 | } | ||||
6151 | |||||
6152 | switch (BT->getKind()) { | ||||
6153 | #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ | ||||
6154 | case BuiltinType::Id: \ | ||||
6155 | return TargetInfo::OCLTK_Image; | ||||
6156 | #include "clang/Basic/OpenCLImageTypes.def" | ||||
6157 | |||||
6158 | case BuiltinType::OCLClkEvent: | ||||
6159 | return TargetInfo::OCLTK_ClkEvent; | ||||
6160 | |||||
6161 | case BuiltinType::OCLEvent: | ||||
6162 | return TargetInfo::OCLTK_Event; | ||||
6163 | |||||
6164 | case BuiltinType::OCLQueue: | ||||
6165 | return TargetInfo::OCLTK_Queue; | ||||
6166 | |||||
6167 | case BuiltinType::OCLReserveID: | ||||
6168 | return TargetInfo::OCLTK_ReserveID; | ||||
6169 | |||||
6170 | case BuiltinType::OCLSampler: | ||||
6171 | return TargetInfo::OCLTK_Sampler; | ||||
6172 | |||||
6173 | default: | ||||
6174 | return TargetInfo::OCLTK_Default; | ||||
6175 | } | ||||
6176 | } | ||||
6177 | |||||
6178 | LangAS ASTContext::getOpenCLTypeAddrSpace(const Type *T) const { | ||||
6179 | return Target->getOpenCLTypeAddrSpace(getOpenCLTypeKind(T)); | ||||
6180 | } | ||||
6181 | |||||
6182 | /// BlockRequiresCopying - Returns true if byref variable "D" of type "Ty" | ||||
6183 | /// requires copy/dispose. Note that this must match the logic | ||||
6184 | /// in buildByrefHelpers. | ||||
6185 | bool ASTContext::BlockRequiresCopying(QualType Ty, | ||||
6186 | const VarDecl *D) { | ||||
6187 | if (const CXXRecordDecl *record = Ty->getAsCXXRecordDecl()) { | ||||
6188 | const Expr *copyExpr = getBlockVarCopyInit(D).getCopyExpr(); | ||||
6189 | if (!copyExpr && record->hasTrivialDestructor()) return false; | ||||
6190 | |||||
6191 | return true; | ||||
6192 | } | ||||
6193 | |||||
6194 | // The block needs copy/destroy helpers if Ty is non-trivial to destructively | ||||
6195 | // move or destroy. | ||||
6196 | if (Ty.isNonTrivialToPrimitiveDestructiveMove() || Ty.isDestructedType()) | ||||
6197 | return true; | ||||
6198 | |||||
6199 | if (!Ty->isObjCRetainableType()) return false; | ||||
6200 | |||||
6201 | Qualifiers qs = Ty.getQualifiers(); | ||||
6202 | |||||
6203 | // If we have lifetime, that dominates. | ||||
6204 | if (Qualifiers::ObjCLifetime lifetime = qs.getObjCLifetime()) { | ||||
6205 | switch (lifetime) { | ||||
6206 | case Qualifiers::OCL_None: llvm_unreachable("impossible")::llvm::llvm_unreachable_internal("impossible", "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 6206); | ||||
6207 | |||||
6208 | // These are just bits as far as the runtime is concerned. | ||||
6209 | case Qualifiers::OCL_ExplicitNone: | ||||
6210 | case Qualifiers::OCL_Autoreleasing: | ||||
6211 | return false; | ||||
6212 | |||||
6213 | // These cases should have been taken care of when checking the type's | ||||
6214 | // non-triviality. | ||||
6215 | case Qualifiers::OCL_Weak: | ||||
6216 | case Qualifiers::OCL_Strong: | ||||
6217 | llvm_unreachable("impossible")::llvm::llvm_unreachable_internal("impossible", "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 6217); | ||||
6218 | } | ||||
6219 | llvm_unreachable("fell out of lifetime switch!")::llvm::llvm_unreachable_internal("fell out of lifetime switch!" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 6219); | ||||
6220 | } | ||||
6221 | return (Ty->isBlockPointerType() || isObjCNSObjectType(Ty) || | ||||
6222 | Ty->isObjCObjectPointerType()); | ||||
6223 | } | ||||
6224 | |||||
6225 | bool ASTContext::getByrefLifetime(QualType Ty, | ||||
6226 | Qualifiers::ObjCLifetime &LifeTime, | ||||
6227 | bool &HasByrefExtendedLayout) const { | ||||
6228 | if (!getLangOpts().ObjC || | ||||
6229 | getLangOpts().getGC() != LangOptions::NonGC) | ||||
6230 | return false; | ||||
6231 | |||||
6232 | HasByrefExtendedLayout = false; | ||||
6233 | if (Ty->isRecordType()) { | ||||
6234 | HasByrefExtendedLayout = true; | ||||
6235 | LifeTime = Qualifiers::OCL_None; | ||||
6236 | } else if ((LifeTime = Ty.getObjCLifetime())) { | ||||
6237 | // Honor the ARC qualifiers. | ||||
6238 | } else if (Ty->isObjCObjectPointerType() || Ty->isBlockPointerType()) { | ||||
6239 | // The MRR rule. | ||||
6240 | LifeTime = Qualifiers::OCL_ExplicitNone; | ||||
6241 | } else { | ||||
6242 | LifeTime = Qualifiers::OCL_None; | ||||
6243 | } | ||||
6244 | return true; | ||||
6245 | } | ||||
6246 | |||||
6247 | TypedefDecl *ASTContext::getObjCInstanceTypeDecl() { | ||||
6248 | if (!ObjCInstanceTypeDecl) | ||||
6249 | ObjCInstanceTypeDecl = | ||||
6250 | buildImplicitTypedef(getObjCIdType(), "instancetype"); | ||||
6251 | return ObjCInstanceTypeDecl; | ||||
6252 | } | ||||
6253 | |||||
6254 | // This returns true if a type has been typedefed to BOOL: | ||||
6255 | // typedef <type> BOOL; | ||||
6256 | static bool isTypeTypedefedAsBOOL(QualType T) { | ||||
6257 | if (const auto *TT = dyn_cast<TypedefType>(T)) | ||||
6258 | if (IdentifierInfo *II = TT->getDecl()->getIdentifier()) | ||||
6259 | return II->isStr("BOOL"); | ||||
6260 | |||||
6261 | return false; | ||||
6262 | } | ||||
6263 | |||||
6264 | /// getObjCEncodingTypeSize returns size of type for objective-c encoding | ||||
6265 | /// purpose. | ||||
6266 | CharUnits ASTContext::getObjCEncodingTypeSize(QualType type) const { | ||||
6267 | if (!type->isIncompleteArrayType() && type->isIncompleteType()) | ||||
6268 | return CharUnits::Zero(); | ||||
6269 | |||||
6270 | CharUnits sz = getTypeSizeInChars(type); | ||||
6271 | |||||
6272 | // Make all integer and enum types at least as large as an int | ||||
6273 | if (sz.isPositive() && type->isIntegralOrEnumerationType()) | ||||
6274 | sz = std::max(sz, getTypeSizeInChars(IntTy)); | ||||
6275 | // Treat arrays as pointers, since that's how they're passed in. | ||||
6276 | else if (type->isArrayType()) | ||||
6277 | sz = getTypeSizeInChars(VoidPtrTy); | ||||
6278 | return sz; | ||||
6279 | } | ||||
6280 | |||||
6281 | bool ASTContext::isMSStaticDataMemberInlineDefinition(const VarDecl *VD) const { | ||||
6282 | return getTargetInfo().getCXXABI().isMicrosoft() && | ||||
6283 | VD->isStaticDataMember() && | ||||
6284 | VD->getType()->isIntegralOrEnumerationType() && | ||||
6285 | !VD->getFirstDecl()->isOutOfLine() && VD->getFirstDecl()->hasInit(); | ||||
6286 | } | ||||
6287 | |||||
6288 | ASTContext::InlineVariableDefinitionKind | ||||
6289 | ASTContext::getInlineVariableDefinitionKind(const VarDecl *VD) const { | ||||
6290 | if (!VD->isInline()) | ||||
6291 | return InlineVariableDefinitionKind::None; | ||||
6292 | |||||
6293 | // In almost all cases, it's a weak definition. | ||||
6294 | auto *First = VD->getFirstDecl(); | ||||
6295 | if (First->isInlineSpecified() || !First->isStaticDataMember()) | ||||
6296 | return InlineVariableDefinitionKind::Weak; | ||||
6297 | |||||
6298 | // If there's a file-context declaration in this translation unit, it's a | ||||
6299 | // non-discardable definition. | ||||
6300 | for (auto *D : VD->redecls()) | ||||
6301 | if (D->getLexicalDeclContext()->isFileContext() && | ||||
6302 | !D->isInlineSpecified() && (D->isConstexpr() || First->isConstexpr())) | ||||
6303 | return InlineVariableDefinitionKind::Strong; | ||||
6304 | |||||
6305 | // If we've not seen one yet, we don't know. | ||||
6306 | return InlineVariableDefinitionKind::WeakUnknown; | ||||
6307 | } | ||||
6308 | |||||
6309 | static std::string charUnitsToString(const CharUnits &CU) { | ||||
6310 | return llvm::itostr(CU.getQuantity()); | ||||
6311 | } | ||||
6312 | |||||
6313 | /// getObjCEncodingForBlock - Return the encoded type for this block | ||||
6314 | /// declaration. | ||||
6315 | std::string ASTContext::getObjCEncodingForBlock(const BlockExpr *Expr) const { | ||||
6316 | std::string S; | ||||
6317 | |||||
6318 | const BlockDecl *Decl = Expr->getBlockDecl(); | ||||
6319 | QualType BlockTy = | ||||
6320 | Expr->getType()->castAs<BlockPointerType>()->getPointeeType(); | ||||
6321 | QualType BlockReturnTy = BlockTy->castAs<FunctionType>()->getReturnType(); | ||||
6322 | // Encode result type. | ||||
6323 | if (getLangOpts().EncodeExtendedBlockSig) | ||||
6324 | getObjCEncodingForMethodParameter(Decl::OBJC_TQ_None, BlockReturnTy, S, | ||||
6325 | true /*Extended*/); | ||||
6326 | else | ||||
6327 | getObjCEncodingForType(BlockReturnTy, S); | ||||
6328 | // Compute size of all parameters. | ||||
6329 | // Start with computing size of a pointer in number of bytes. | ||||
6330 | // FIXME: There might(should) be a better way of doing this computation! | ||||
6331 | CharUnits PtrSize = getTypeSizeInChars(VoidPtrTy); | ||||
6332 | CharUnits ParmOffset = PtrSize; | ||||
6333 | for (auto PI : Decl->parameters()) { | ||||
6334 | QualType PType = PI->getType(); | ||||
6335 | CharUnits sz = getObjCEncodingTypeSize(PType); | ||||
6336 | if (sz.isZero()) | ||||
6337 | continue; | ||||
6338 | assert(sz.isPositive() && "BlockExpr - Incomplete param type")((sz.isPositive() && "BlockExpr - Incomplete param type" ) ? static_cast<void> (0) : __assert_fail ("sz.isPositive() && \"BlockExpr - Incomplete param type\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 6338, __PRETTY_FUNCTION__)); | ||||
6339 | ParmOffset += sz; | ||||
6340 | } | ||||
6341 | // Size of the argument frame | ||||
6342 | S += charUnitsToString(ParmOffset); | ||||
6343 | // Block pointer and offset. | ||||
6344 | S += "@?0"; | ||||
6345 | |||||
6346 | // Argument types. | ||||
6347 | ParmOffset = PtrSize; | ||||
6348 | for (auto PVDecl : Decl->parameters()) { | ||||
6349 | QualType PType = PVDecl->getOriginalType(); | ||||
6350 | if (const auto *AT = | ||||
6351 | dyn_cast<ArrayType>(PType->getCanonicalTypeInternal())) { | ||||
6352 | // Use array's original type only if it has known number of | ||||
6353 | // elements. | ||||
6354 | if (!isa<ConstantArrayType>(AT)) | ||||
6355 | PType = PVDecl->getType(); | ||||
6356 | } else if (PType->isFunctionType()) | ||||
6357 | PType = PVDecl->getType(); | ||||
6358 | if (getLangOpts().EncodeExtendedBlockSig) | ||||
6359 | getObjCEncodingForMethodParameter(Decl::OBJC_TQ_None, PType, | ||||
6360 | S, true /*Extended*/); | ||||
6361 | else | ||||
6362 | getObjCEncodingForType(PType, S); | ||||
6363 | S += charUnitsToString(ParmOffset); | ||||
6364 | ParmOffset += getObjCEncodingTypeSize(PType); | ||||
6365 | } | ||||
6366 | |||||
6367 | return S; | ||||
6368 | } | ||||
6369 | |||||
6370 | std::string | ||||
6371 | ASTContext::getObjCEncodingForFunctionDecl(const FunctionDecl *Decl) const { | ||||
6372 | std::string S; | ||||
6373 | // Encode result type. | ||||
6374 | getObjCEncodingForType(Decl->getReturnType(), S); | ||||
6375 | CharUnits ParmOffset; | ||||
6376 | // Compute size of all parameters. | ||||
6377 | for (auto PI : Decl->parameters()) { | ||||
6378 | QualType PType = PI->getType(); | ||||
6379 | CharUnits sz = getObjCEncodingTypeSize(PType); | ||||
6380 | if (sz.isZero()) | ||||
6381 | continue; | ||||
6382 | |||||
6383 | assert(sz.isPositive() &&((sz.isPositive() && "getObjCEncodingForFunctionDecl - Incomplete param type" ) ? static_cast<void> (0) : __assert_fail ("sz.isPositive() && \"getObjCEncodingForFunctionDecl - Incomplete param type\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 6384, __PRETTY_FUNCTION__)) | ||||
6384 | "getObjCEncodingForFunctionDecl - Incomplete param type")((sz.isPositive() && "getObjCEncodingForFunctionDecl - Incomplete param type" ) ? static_cast<void> (0) : __assert_fail ("sz.isPositive() && \"getObjCEncodingForFunctionDecl - Incomplete param type\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 6384, __PRETTY_FUNCTION__)); | ||||
6385 | ParmOffset += sz; | ||||
6386 | } | ||||
6387 | S += charUnitsToString(ParmOffset); | ||||
6388 | ParmOffset = CharUnits::Zero(); | ||||
6389 | |||||
6390 | // Argument types. | ||||
6391 | for (auto PVDecl : Decl->parameters()) { | ||||
6392 | QualType PType = PVDecl->getOriginalType(); | ||||
6393 | if (const auto *AT = | ||||
6394 | dyn_cast<ArrayType>(PType->getCanonicalTypeInternal())) { | ||||
6395 | // Use array's original type only if it has known number of | ||||
6396 | // elements. | ||||
6397 | if (!isa<ConstantArrayType>(AT)) | ||||
6398 | PType = PVDecl->getType(); | ||||
6399 | } else if (PType->isFunctionType()) | ||||
6400 | PType = PVDecl->getType(); | ||||
6401 | getObjCEncodingForType(PType, S); | ||||
6402 | S += charUnitsToString(ParmOffset); | ||||
6403 | ParmOffset += getObjCEncodingTypeSize(PType); | ||||
6404 | } | ||||
6405 | |||||
6406 | return S; | ||||
6407 | } | ||||
6408 | |||||
6409 | /// getObjCEncodingForMethodParameter - Return the encoded type for a single | ||||
6410 | /// method parameter or return type. If Extended, include class names and | ||||
6411 | /// block object types. | ||||
6412 | void ASTContext::getObjCEncodingForMethodParameter(Decl::ObjCDeclQualifier QT, | ||||
6413 | QualType T, std::string& S, | ||||
6414 | bool Extended) const { | ||||
6415 | // Encode type qualifer, 'in', 'inout', etc. for the parameter. | ||||
6416 | getObjCEncodingForTypeQualifier(QT, S); | ||||
6417 | // Encode parameter type. | ||||
6418 | ObjCEncOptions Options = ObjCEncOptions() | ||||
6419 | .setExpandPointedToStructures() | ||||
6420 | .setExpandStructures() | ||||
6421 | .setIsOutermostType(); | ||||
6422 | if (Extended) | ||||
6423 | Options.setEncodeBlockParameters().setEncodeClassNames(); | ||||
6424 | getObjCEncodingForTypeImpl(T, S, Options, /*Field=*/nullptr); | ||||
6425 | } | ||||
6426 | |||||
6427 | /// getObjCEncodingForMethodDecl - Return the encoded type for this method | ||||
6428 | /// declaration. | ||||
6429 | std::string ASTContext::getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl, | ||||
6430 | bool Extended) const { | ||||
6431 | // FIXME: This is not very efficient. | ||||
6432 | // Encode return type. | ||||
6433 | std::string S; | ||||
6434 | getObjCEncodingForMethodParameter(Decl->getObjCDeclQualifier(), | ||||
6435 | Decl->getReturnType(), S, Extended); | ||||
6436 | // Compute size of all parameters. | ||||
6437 | // Start with computing size of a pointer in number of bytes. | ||||
6438 | // FIXME: There might(should) be a better way of doing this computation! | ||||
6439 | CharUnits PtrSize = getTypeSizeInChars(VoidPtrTy); | ||||
6440 | // The first two arguments (self and _cmd) are pointers; account for | ||||
6441 | // their size. | ||||
6442 | CharUnits ParmOffset = 2 * PtrSize; | ||||
6443 | for (ObjCMethodDecl::param_const_iterator PI = Decl->param_begin(), | ||||
6444 | E = Decl->sel_param_end(); PI != E; ++PI) { | ||||
6445 | QualType PType = (*PI)->getType(); | ||||
6446 | CharUnits sz = getObjCEncodingTypeSize(PType); | ||||
6447 | if (sz.isZero()) | ||||
6448 | continue; | ||||
6449 | |||||
6450 | assert(sz.isPositive() &&((sz.isPositive() && "getObjCEncodingForMethodDecl - Incomplete param type" ) ? static_cast<void> (0) : __assert_fail ("sz.isPositive() && \"getObjCEncodingForMethodDecl - Incomplete param type\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 6451, __PRETTY_FUNCTION__)) | ||||
6451 | "getObjCEncodingForMethodDecl - Incomplete param type")((sz.isPositive() && "getObjCEncodingForMethodDecl - Incomplete param type" ) ? static_cast<void> (0) : __assert_fail ("sz.isPositive() && \"getObjCEncodingForMethodDecl - Incomplete param type\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 6451, __PRETTY_FUNCTION__)); | ||||
6452 | ParmOffset += sz; | ||||
6453 | } | ||||
6454 | S += charUnitsToString(ParmOffset); | ||||
6455 | S += "@0:"; | ||||
6456 | S += charUnitsToString(PtrSize); | ||||
6457 | |||||
6458 | // Argument types. | ||||
6459 | ParmOffset = 2 * PtrSize; | ||||
6460 | for (ObjCMethodDecl::param_const_iterator PI = Decl->param_begin(), | ||||
6461 | E = Decl->sel_param_end(); PI != E; ++PI) { | ||||
6462 | const ParmVarDecl *PVDecl = *PI; | ||||
6463 | QualType PType = PVDecl->getOriginalType(); | ||||
6464 | if (const auto *AT = | ||||
6465 | dyn_cast<ArrayType>(PType->getCanonicalTypeInternal())) { | ||||
6466 | // Use array's original type only if it has known number of | ||||
6467 | // elements. | ||||
6468 | if (!isa<ConstantArrayType>(AT)) | ||||
6469 | PType = PVDecl->getType(); | ||||
6470 | } else if (PType->isFunctionType()) | ||||
6471 | PType = PVDecl->getType(); | ||||
6472 | getObjCEncodingForMethodParameter(PVDecl->getObjCDeclQualifier(), | ||||
6473 | PType, S, Extended); | ||||
6474 | S += charUnitsToString(ParmOffset); | ||||
6475 | ParmOffset += getObjCEncodingTypeSize(PType); | ||||
6476 | } | ||||
6477 | |||||
6478 | return S; | ||||
6479 | } | ||||
6480 | |||||
6481 | ObjCPropertyImplDecl * | ||||
6482 | ASTContext::getObjCPropertyImplDeclForPropertyDecl( | ||||
6483 | const ObjCPropertyDecl *PD, | ||||
6484 | const Decl *Container) const { | ||||
6485 | if (!Container) | ||||
6486 | return nullptr; | ||||
6487 | if (const auto *CID = dyn_cast<ObjCCategoryImplDecl>(Container)) { | ||||
6488 | for (auto *PID : CID->property_impls()) | ||||
6489 | if (PID->getPropertyDecl() == PD) | ||||
6490 | return PID; | ||||
6491 | } else { | ||||
6492 | const auto *OID = cast<ObjCImplementationDecl>(Container); | ||||
6493 | for (auto *PID : OID->property_impls()) | ||||
6494 | if (PID->getPropertyDecl() == PD) | ||||
6495 | return PID; | ||||
6496 | } | ||||
6497 | return nullptr; | ||||
6498 | } | ||||
6499 | |||||
6500 | /// getObjCEncodingForPropertyDecl - Return the encoded type for this | ||||
6501 | /// property declaration. If non-NULL, Container must be either an | ||||
6502 | /// ObjCCategoryImplDecl or ObjCImplementationDecl; it should only be | ||||
6503 | /// NULL when getting encodings for protocol properties. | ||||
6504 | /// Property attributes are stored as a comma-delimited C string. The simple | ||||
6505 | /// attributes readonly and bycopy are encoded as single characters. The | ||||
6506 | /// parametrized attributes, getter=name, setter=name, and ivar=name, are | ||||
6507 | /// encoded as single characters, followed by an identifier. Property types | ||||
6508 | /// are also encoded as a parametrized attribute. The characters used to encode | ||||
6509 | /// these attributes are defined by the following enumeration: | ||||
6510 | /// @code | ||||
6511 | /// enum PropertyAttributes { | ||||
6512 | /// kPropertyReadOnly = 'R', // property is read-only. | ||||
6513 | /// kPropertyBycopy = 'C', // property is a copy of the value last assigned | ||||
6514 | /// kPropertyByref = '&', // property is a reference to the value last assigned | ||||
6515 | /// kPropertyDynamic = 'D', // property is dynamic | ||||
6516 | /// kPropertyGetter = 'G', // followed by getter selector name | ||||
6517 | /// kPropertySetter = 'S', // followed by setter selector name | ||||
6518 | /// kPropertyInstanceVariable = 'V' // followed by instance variable name | ||||
6519 | /// kPropertyType = 'T' // followed by old-style type encoding. | ||||
6520 | /// kPropertyWeak = 'W' // 'weak' property | ||||
6521 | /// kPropertyStrong = 'P' // property GC'able | ||||
6522 | /// kPropertyNonAtomic = 'N' // property non-atomic | ||||
6523 | /// }; | ||||
6524 | /// @endcode | ||||
6525 | std::string | ||||
6526 | ASTContext::getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD, | ||||
6527 | const Decl *Container) const { | ||||
6528 | // Collect information from the property implementation decl(s). | ||||
6529 | bool Dynamic = false; | ||||
6530 | ObjCPropertyImplDecl *SynthesizePID = nullptr; | ||||
6531 | |||||
6532 | if (ObjCPropertyImplDecl *PropertyImpDecl = | ||||
6533 | getObjCPropertyImplDeclForPropertyDecl(PD, Container)) { | ||||
6534 | if (PropertyImpDecl->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic) | ||||
6535 | Dynamic = true; | ||||
6536 | else | ||||
6537 | SynthesizePID = PropertyImpDecl; | ||||
6538 | } | ||||
6539 | |||||
6540 | // FIXME: This is not very efficient. | ||||
6541 | std::string S = "T"; | ||||
6542 | |||||
6543 | // Encode result type. | ||||
6544 | // GCC has some special rules regarding encoding of properties which | ||||
6545 | // closely resembles encoding of ivars. | ||||
6546 | getObjCEncodingForPropertyType(PD->getType(), S); | ||||
6547 | |||||
6548 | if (PD->isReadOnly()) { | ||||
6549 | S += ",R"; | ||||
6550 | if (PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_copy) | ||||
6551 | S += ",C"; | ||||
6552 | if (PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_retain) | ||||
6553 | S += ",&"; | ||||
6554 | if (PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_weak) | ||||
6555 | S += ",W"; | ||||
6556 | } else { | ||||
6557 | switch (PD->getSetterKind()) { | ||||
6558 | case ObjCPropertyDecl::Assign: break; | ||||
6559 | case ObjCPropertyDecl::Copy: S += ",C"; break; | ||||
6560 | case ObjCPropertyDecl::Retain: S += ",&"; break; | ||||
6561 | case ObjCPropertyDecl::Weak: S += ",W"; break; | ||||
6562 | } | ||||
6563 | } | ||||
6564 | |||||
6565 | // It really isn't clear at all what this means, since properties | ||||
6566 | // are "dynamic by default". | ||||
6567 | if (Dynamic) | ||||
6568 | S += ",D"; | ||||
6569 | |||||
6570 | if (PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_nonatomic) | ||||
6571 | S += ",N"; | ||||
6572 | |||||
6573 | if (PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_getter) { | ||||
6574 | S += ",G"; | ||||
6575 | S += PD->getGetterName().getAsString(); | ||||
6576 | } | ||||
6577 | |||||
6578 | if (PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_setter) { | ||||
6579 | S += ",S"; | ||||
6580 | S += PD->getSetterName().getAsString(); | ||||
6581 | } | ||||
6582 | |||||
6583 | if (SynthesizePID) { | ||||
6584 | const ObjCIvarDecl *OID = SynthesizePID->getPropertyIvarDecl(); | ||||
6585 | S += ",V"; | ||||
6586 | S += OID->getNameAsString(); | ||||
6587 | } | ||||
6588 | |||||
6589 | // FIXME: OBJCGC: weak & strong | ||||
6590 | return S; | ||||
6591 | } | ||||
6592 | |||||
6593 | /// getLegacyIntegralTypeEncoding - | ||||
6594 | /// Another legacy compatibility encoding: 32-bit longs are encoded as | ||||
6595 | /// 'l' or 'L' , but not always. For typedefs, we need to use | ||||
6596 | /// 'i' or 'I' instead if encoding a struct field, or a pointer! | ||||
6597 | void ASTContext::getLegacyIntegralTypeEncoding (QualType &PointeeTy) const { | ||||
6598 | if (isa<TypedefType>(PointeeTy.getTypePtr())) { | ||||
6599 | if (const auto *BT = PointeeTy->getAs<BuiltinType>()) { | ||||
6600 | if (BT->getKind() == BuiltinType::ULong && getIntWidth(PointeeTy) == 32) | ||||
6601 | PointeeTy = UnsignedIntTy; | ||||
6602 | else | ||||
6603 | if (BT->getKind() == BuiltinType::Long && getIntWidth(PointeeTy) == 32) | ||||
6604 | PointeeTy = IntTy; | ||||
6605 | } | ||||
6606 | } | ||||
6607 | } | ||||
6608 | |||||
6609 | void ASTContext::getObjCEncodingForType(QualType T, std::string& S, | ||||
6610 | const FieldDecl *Field, | ||||
6611 | QualType *NotEncodedT) const { | ||||
6612 | // We follow the behavior of gcc, expanding structures which are | ||||
6613 | // directly pointed to, and expanding embedded structures. Note that | ||||
6614 | // these rules are sufficient to prevent recursive encoding of the | ||||
6615 | // same type. | ||||
6616 | getObjCEncodingForTypeImpl(T, S, | ||||
6617 | ObjCEncOptions() | ||||
6618 | .setExpandPointedToStructures() | ||||
6619 | .setExpandStructures() | ||||
6620 | .setIsOutermostType(), | ||||
6621 | Field, NotEncodedT); | ||||
6622 | } | ||||
6623 | |||||
6624 | void ASTContext::getObjCEncodingForPropertyType(QualType T, | ||||
6625 | std::string& S) const { | ||||
6626 | // Encode result type. | ||||
6627 | // GCC has some special rules regarding encoding of properties which | ||||
6628 | // closely resembles encoding of ivars. | ||||
6629 | getObjCEncodingForTypeImpl(T, S, | ||||
6630 | ObjCEncOptions() | ||||
6631 | .setExpandPointedToStructures() | ||||
6632 | .setExpandStructures() | ||||
6633 | .setIsOutermostType() | ||||
6634 | .setEncodingProperty(), | ||||
6635 | /*Field=*/nullptr); | ||||
6636 | } | ||||
6637 | |||||
6638 | static char getObjCEncodingForPrimitiveType(const ASTContext *C, | ||||
6639 | const BuiltinType *BT) { | ||||
6640 | BuiltinType::Kind kind = BT->getKind(); | ||||
6641 | switch (kind) { | ||||
6642 | case BuiltinType::Void: return 'v'; | ||||
6643 | case BuiltinType::Bool: return 'B'; | ||||
6644 | case BuiltinType::Char8: | ||||
6645 | case BuiltinType::Char_U: | ||||
6646 | case BuiltinType::UChar: return 'C'; | ||||
6647 | case BuiltinType::Char16: | ||||
6648 | case BuiltinType::UShort: return 'S'; | ||||
6649 | case BuiltinType::Char32: | ||||
6650 | case BuiltinType::UInt: return 'I'; | ||||
6651 | case BuiltinType::ULong: | ||||
6652 | return C->getTargetInfo().getLongWidth() == 32 ? 'L' : 'Q'; | ||||
6653 | case BuiltinType::UInt128: return 'T'; | ||||
6654 | case BuiltinType::ULongLong: return 'Q'; | ||||
6655 | case BuiltinType::Char_S: | ||||
6656 | case BuiltinType::SChar: return 'c'; | ||||
6657 | case BuiltinType::Short: return 's'; | ||||
6658 | case BuiltinType::WChar_S: | ||||
6659 | case BuiltinType::WChar_U: | ||||
6660 | case BuiltinType::Int: return 'i'; | ||||
6661 | case BuiltinType::Long: | ||||
6662 | return C->getTargetInfo().getLongWidth() == 32 ? 'l' : 'q'; | ||||
6663 | case BuiltinType::LongLong: return 'q'; | ||||
6664 | case BuiltinType::Int128: return 't'; | ||||
6665 | case BuiltinType::Float: return 'f'; | ||||
6666 | case BuiltinType::Double: return 'd'; | ||||
6667 | case BuiltinType::LongDouble: return 'D'; | ||||
6668 | case BuiltinType::NullPtr: return '*'; // like char* | ||||
6669 | |||||
6670 | case BuiltinType::Float16: | ||||
6671 | case BuiltinType::Float128: | ||||
6672 | case BuiltinType::Half: | ||||
6673 | case BuiltinType::ShortAccum: | ||||
6674 | case BuiltinType::Accum: | ||||
6675 | case BuiltinType::LongAccum: | ||||
6676 | case BuiltinType::UShortAccum: | ||||
6677 | case BuiltinType::UAccum: | ||||
6678 | case BuiltinType::ULongAccum: | ||||
6679 | case BuiltinType::ShortFract: | ||||
6680 | case BuiltinType::Fract: | ||||
6681 | case BuiltinType::LongFract: | ||||
6682 | case BuiltinType::UShortFract: | ||||
6683 | case BuiltinType::UFract: | ||||
6684 | case BuiltinType::ULongFract: | ||||
6685 | case BuiltinType::SatShortAccum: | ||||
6686 | case BuiltinType::SatAccum: | ||||
6687 | case BuiltinType::SatLongAccum: | ||||
6688 | case BuiltinType::SatUShortAccum: | ||||
6689 | case BuiltinType::SatUAccum: | ||||
6690 | case BuiltinType::SatULongAccum: | ||||
6691 | case BuiltinType::SatShortFract: | ||||
6692 | case BuiltinType::SatFract: | ||||
6693 | case BuiltinType::SatLongFract: | ||||
6694 | case BuiltinType::SatUShortFract: | ||||
6695 | case BuiltinType::SatUFract: | ||||
6696 | case BuiltinType::SatULongFract: | ||||
6697 | // FIXME: potentially need @encodes for these! | ||||
6698 | return ' '; | ||||
6699 | |||||
6700 | #define SVE_TYPE(Name, Id, SingletonId) \ | ||||
6701 | case BuiltinType::Id: | ||||
6702 | #include "clang/Basic/AArch64SVEACLETypes.def" | ||||
6703 | { | ||||
6704 | DiagnosticsEngine &Diags = C->getDiagnostics(); | ||||
6705 | unsigned DiagID = Diags.getCustomDiagID( | ||||
6706 | DiagnosticsEngine::Error, "cannot yet @encode type %0"); | ||||
6707 | Diags.Report(DiagID) << BT->getName(C->getPrintingPolicy()); | ||||
6708 | return ' '; | ||||
6709 | } | ||||
6710 | |||||
6711 | case BuiltinType::ObjCId: | ||||
6712 | case BuiltinType::ObjCClass: | ||||
6713 | case BuiltinType::ObjCSel: | ||||
6714 | llvm_unreachable("@encoding ObjC primitive type")::llvm::llvm_unreachable_internal("@encoding ObjC primitive type" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 6714); | ||||
6715 | |||||
6716 | // OpenCL and placeholder types don't need @encodings. | ||||
6717 | #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ | ||||
6718 | case BuiltinType::Id: | ||||
6719 | #include "clang/Basic/OpenCLImageTypes.def" | ||||
6720 | #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \ | ||||
6721 | case BuiltinType::Id: | ||||
6722 | #include "clang/Basic/OpenCLExtensionTypes.def" | ||||
6723 | case BuiltinType::OCLEvent: | ||||
6724 | case BuiltinType::OCLClkEvent: | ||||
6725 | case BuiltinType::OCLQueue: | ||||
6726 | case BuiltinType::OCLReserveID: | ||||
6727 | case BuiltinType::OCLSampler: | ||||
6728 | case BuiltinType::Dependent: | ||||
6729 | #define BUILTIN_TYPE(KIND, ID) | ||||
6730 | #define PLACEHOLDER_TYPE(KIND, ID) \ | ||||
6731 | case BuiltinType::KIND: | ||||
6732 | #include "clang/AST/BuiltinTypes.def" | ||||
6733 | llvm_unreachable("invalid builtin type for @encode")::llvm::llvm_unreachable_internal("invalid builtin type for @encode" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 6733); | ||||
6734 | } | ||||
6735 | llvm_unreachable("invalid BuiltinType::Kind value")::llvm::llvm_unreachable_internal("invalid BuiltinType::Kind value" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 6735); | ||||
6736 | } | ||||
6737 | |||||
6738 | static char ObjCEncodingForEnumType(const ASTContext *C, const EnumType *ET) { | ||||
6739 | EnumDecl *Enum = ET->getDecl(); | ||||
6740 | |||||
6741 | // The encoding of an non-fixed enum type is always 'i', regardless of size. | ||||
6742 | if (!Enum->isFixed()) | ||||
6743 | return 'i'; | ||||
6744 | |||||
6745 | // The encoding of a fixed enum type matches its fixed underlying type. | ||||
6746 | const auto *BT = Enum->getIntegerType()->castAs<BuiltinType>(); | ||||
6747 | return getObjCEncodingForPrimitiveType(C, BT); | ||||
6748 | } | ||||
6749 | |||||
6750 | static void EncodeBitField(const ASTContext *Ctx, std::string& S, | ||||
6751 | QualType T, const FieldDecl *FD) { | ||||
6752 | assert(FD->isBitField() && "not a bitfield - getObjCEncodingForTypeImpl")((FD->isBitField() && "not a bitfield - getObjCEncodingForTypeImpl" ) ? static_cast<void> (0) : __assert_fail ("FD->isBitField() && \"not a bitfield - getObjCEncodingForTypeImpl\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 6752, __PRETTY_FUNCTION__)); | ||||
6753 | S += 'b'; | ||||
6754 | // The NeXT runtime encodes bit fields as b followed by the number of bits. | ||||
6755 | // The GNU runtime requires more information; bitfields are encoded as b, | ||||
6756 | // then the offset (in bits) of the first element, then the type of the | ||||
6757 | // bitfield, then the size in bits. For example, in this structure: | ||||
6758 | // | ||||
6759 | // struct | ||||
6760 | // { | ||||
6761 | // int integer; | ||||
6762 | // int flags:2; | ||||
6763 | // }; | ||||
6764 | // On a 32-bit system, the encoding for flags would be b2 for the NeXT | ||||
6765 | // runtime, but b32i2 for the GNU runtime. The reason for this extra | ||||
6766 | // information is not especially sensible, but we're stuck with it for | ||||
6767 | // compatibility with GCC, although providing it breaks anything that | ||||
6768 | // actually uses runtime introspection and wants to work on both runtimes... | ||||
6769 | if (Ctx->getLangOpts().ObjCRuntime.isGNUFamily()) { | ||||
6770 | uint64_t Offset; | ||||
6771 | |||||
6772 | if (const auto *IVD = dyn_cast<ObjCIvarDecl>(FD)) { | ||||
6773 | Offset = Ctx->lookupFieldBitOffset(IVD->getContainingInterface(), nullptr, | ||||
6774 | IVD); | ||||
6775 | } else { | ||||
6776 | const RecordDecl *RD = FD->getParent(); | ||||
6777 | const ASTRecordLayout &RL = Ctx->getASTRecordLayout(RD); | ||||
6778 | Offset = RL.getFieldOffset(FD->getFieldIndex()); | ||||
6779 | } | ||||
6780 | |||||
6781 | S += llvm::utostr(Offset); | ||||
6782 | |||||
6783 | if (const auto *ET = T->getAs<EnumType>()) | ||||
6784 | S += ObjCEncodingForEnumType(Ctx, ET); | ||||
6785 | else { | ||||
6786 | const auto *BT = T->castAs<BuiltinType>(); | ||||
6787 | S += getObjCEncodingForPrimitiveType(Ctx, BT); | ||||
6788 | } | ||||
6789 | } | ||||
6790 | S += llvm::utostr(FD->getBitWidthValue(*Ctx)); | ||||
6791 | } | ||||
6792 | |||||
6793 | // FIXME: Use SmallString for accumulating string. | ||||
6794 | void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string &S, | ||||
6795 | const ObjCEncOptions Options, | ||||
6796 | const FieldDecl *FD, | ||||
6797 | QualType *NotEncodedT) const { | ||||
6798 | CanQualType CT = getCanonicalType(T); | ||||
6799 | switch (CT->getTypeClass()) { | ||||
6800 | case Type::Builtin: | ||||
6801 | case Type::Enum: | ||||
6802 | if (FD && FD->isBitField()) | ||||
6803 | return EncodeBitField(this, S, T, FD); | ||||
6804 | if (const auto *BT = dyn_cast<BuiltinType>(CT)) | ||||
6805 | S += getObjCEncodingForPrimitiveType(this, BT); | ||||
6806 | else | ||||
6807 | S += ObjCEncodingForEnumType(this, cast<EnumType>(CT)); | ||||
6808 | return; | ||||
6809 | |||||
6810 | case Type::Complex: { | ||||
6811 | const auto *CT = T->castAs<ComplexType>(); | ||||
6812 | S += 'j'; | ||||
6813 | getObjCEncodingForTypeImpl(CT->getElementType(), S, ObjCEncOptions(), | ||||
6814 | /*Field=*/nullptr); | ||||
6815 | return; | ||||
6816 | } | ||||
6817 | |||||
6818 | case Type::Atomic: { | ||||
6819 | const auto *AT = T->castAs<AtomicType>(); | ||||
6820 | S += 'A'; | ||||
6821 | getObjCEncodingForTypeImpl(AT->getValueType(), S, ObjCEncOptions(), | ||||
6822 | /*Field=*/nullptr); | ||||
6823 | return; | ||||
6824 | } | ||||
6825 | |||||
6826 | // encoding for pointer or reference types. | ||||
6827 | case Type::Pointer: | ||||
6828 | case Type::LValueReference: | ||||
6829 | case Type::RValueReference: { | ||||
6830 | QualType PointeeTy; | ||||
6831 | if (isa<PointerType>(CT)) { | ||||
6832 | const auto *PT = T->castAs<PointerType>(); | ||||
6833 | if (PT->isObjCSelType()) { | ||||
6834 | S += ':'; | ||||
6835 | return; | ||||
6836 | } | ||||
6837 | PointeeTy = PT->getPointeeType(); | ||||
6838 | } else { | ||||
6839 | PointeeTy = T->castAs<ReferenceType>()->getPointeeType(); | ||||
6840 | } | ||||
6841 | |||||
6842 | bool isReadOnly = false; | ||||
6843 | // For historical/compatibility reasons, the read-only qualifier of the | ||||
6844 | // pointee gets emitted _before_ the '^'. The read-only qualifier of | ||||
6845 | // the pointer itself gets ignored, _unless_ we are looking at a typedef! | ||||
6846 | // Also, do not emit the 'r' for anything but the outermost type! | ||||
6847 | if (isa<TypedefType>(T.getTypePtr())) { | ||||
6848 | if (Options.IsOutermostType() && T.isConstQualified()) { | ||||
6849 | isReadOnly = true; | ||||
6850 | S += 'r'; | ||||
6851 | } | ||||
6852 | } else if (Options.IsOutermostType()) { | ||||
6853 | QualType P = PointeeTy; | ||||
6854 | while (P->getAs<PointerType>()) | ||||
6855 | P = P->getAs<PointerType>()->getPointeeType(); | ||||
6856 | if (P.isConstQualified()) { | ||||
6857 | isReadOnly = true; | ||||
6858 | S += 'r'; | ||||
6859 | } | ||||
6860 | } | ||||
6861 | if (isReadOnly) { | ||||
6862 | // Another legacy compatibility encoding. Some ObjC qualifier and type | ||||
6863 | // combinations need to be rearranged. | ||||
6864 | // Rewrite "in const" from "nr" to "rn" | ||||
6865 | if (StringRef(S).endswith("nr")) | ||||
6866 | S.replace(S.end()-2, S.end(), "rn"); | ||||
6867 | } | ||||
6868 | |||||
6869 | if (PointeeTy->isCharType()) { | ||||
6870 | // char pointer types should be encoded as '*' unless it is a | ||||
6871 | // type that has been typedef'd to 'BOOL'. | ||||
6872 | if (!isTypeTypedefedAsBOOL(PointeeTy)) { | ||||
6873 | S += '*'; | ||||
6874 | return; | ||||
6875 | } | ||||
6876 | } else if (const auto *RTy = PointeeTy->getAs<RecordType>()) { | ||||
6877 | // GCC binary compat: Need to convert "struct objc_class *" to "#". | ||||
6878 | if (RTy->getDecl()->getIdentifier() == &Idents.get("objc_class")) { | ||||
6879 | S += '#'; | ||||
6880 | return; | ||||
6881 | } | ||||
6882 | // GCC binary compat: Need to convert "struct objc_object *" to "@". | ||||
6883 | if (RTy->getDecl()->getIdentifier() == &Idents.get("objc_object")) { | ||||
6884 | S += '@'; | ||||
6885 | return; | ||||
6886 | } | ||||
6887 | // fall through... | ||||
6888 | } | ||||
6889 | S += '^'; | ||||
6890 | getLegacyIntegralTypeEncoding(PointeeTy); | ||||
6891 | |||||
6892 | ObjCEncOptions NewOptions; | ||||
6893 | if (Options.ExpandPointedToStructures()) | ||||
6894 | NewOptions.setExpandStructures(); | ||||
6895 | getObjCEncodingForTypeImpl(PointeeTy, S, NewOptions, | ||||
6896 | /*Field=*/nullptr, NotEncodedT); | ||||
6897 | return; | ||||
6898 | } | ||||
6899 | |||||
6900 | case Type::ConstantArray: | ||||
6901 | case Type::IncompleteArray: | ||||
6902 | case Type::VariableArray: { | ||||
6903 | const auto *AT = cast<ArrayType>(CT); | ||||
6904 | |||||
6905 | if (isa<IncompleteArrayType>(AT) && !Options.IsStructField()) { | ||||
6906 | // Incomplete arrays are encoded as a pointer to the array element. | ||||
6907 | S += '^'; | ||||
6908 | |||||
6909 | getObjCEncodingForTypeImpl( | ||||
6910 | AT->getElementType(), S, | ||||
6911 | Options.keepingOnly(ObjCEncOptions().setExpandStructures()), FD); | ||||
6912 | } else { | ||||
6913 | S += '['; | ||||
6914 | |||||
6915 | if (const auto *CAT = dyn_cast<ConstantArrayType>(AT)) | ||||
6916 | S += llvm::utostr(CAT->getSize().getZExtValue()); | ||||
6917 | else { | ||||
6918 | //Variable length arrays are encoded as a regular array with 0 elements. | ||||
6919 | assert((isa<VariableArrayType>(AT) || isa<IncompleteArrayType>(AT)) &&(((isa<VariableArrayType>(AT) || isa<IncompleteArrayType >(AT)) && "Unknown array type!") ? static_cast< void> (0) : __assert_fail ("(isa<VariableArrayType>(AT) || isa<IncompleteArrayType>(AT)) && \"Unknown array type!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 6920, __PRETTY_FUNCTION__)) | ||||
6920 | "Unknown array type!")(((isa<VariableArrayType>(AT) || isa<IncompleteArrayType >(AT)) && "Unknown array type!") ? static_cast< void> (0) : __assert_fail ("(isa<VariableArrayType>(AT) || isa<IncompleteArrayType>(AT)) && \"Unknown array type!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 6920, __PRETTY_FUNCTION__)); | ||||
6921 | S += '0'; | ||||
6922 | } | ||||
6923 | |||||
6924 | getObjCEncodingForTypeImpl( | ||||
6925 | AT->getElementType(), S, | ||||
6926 | Options.keepingOnly(ObjCEncOptions().setExpandStructures()), FD, | ||||
6927 | NotEncodedT); | ||||
6928 | S += ']'; | ||||
6929 | } | ||||
6930 | return; | ||||
6931 | } | ||||
6932 | |||||
6933 | case Type::FunctionNoProto: | ||||
6934 | case Type::FunctionProto: | ||||
6935 | S += '?'; | ||||
6936 | return; | ||||
6937 | |||||
6938 | case Type::Record: { | ||||
6939 | RecordDecl *RDecl = cast<RecordType>(CT)->getDecl(); | ||||
6940 | S += RDecl->isUnion() ? '(' : '{'; | ||||
6941 | // Anonymous structures print as '?' | ||||
6942 | if (const IdentifierInfo *II = RDecl->getIdentifier()) { | ||||
6943 | S += II->getName(); | ||||
6944 | if (const auto *Spec = dyn_cast<ClassTemplateSpecializationDecl>(RDecl)) { | ||||
6945 | const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs(); | ||||
6946 | llvm::raw_string_ostream OS(S); | ||||
6947 | printTemplateArgumentList(OS, TemplateArgs.asArray(), | ||||
6948 | getPrintingPolicy()); | ||||
6949 | } | ||||
6950 | } else { | ||||
6951 | S += '?'; | ||||
6952 | } | ||||
6953 | if (Options.ExpandStructures()) { | ||||
6954 | S += '='; | ||||
6955 | if (!RDecl->isUnion()) { | ||||
6956 | getObjCEncodingForStructureImpl(RDecl, S, FD, true, NotEncodedT); | ||||
6957 | } else { | ||||
6958 | for (const auto *Field : RDecl->fields()) { | ||||
6959 | if (FD) { | ||||
6960 | S += '"'; | ||||
6961 | S += Field->getNameAsString(); | ||||
6962 | S += '"'; | ||||
6963 | } | ||||
6964 | |||||
6965 | // Special case bit-fields. | ||||
6966 | if (Field->isBitField()) { | ||||
6967 | getObjCEncodingForTypeImpl(Field->getType(), S, | ||||
6968 | ObjCEncOptions().setExpandStructures(), | ||||
6969 | Field); | ||||
6970 | } else { | ||||
6971 | QualType qt = Field->getType(); | ||||
6972 | getLegacyIntegralTypeEncoding(qt); | ||||
6973 | getObjCEncodingForTypeImpl( | ||||
6974 | qt, S, | ||||
6975 | ObjCEncOptions().setExpandStructures().setIsStructField(), FD, | ||||
6976 | NotEncodedT); | ||||
6977 | } | ||||
6978 | } | ||||
6979 | } | ||||
6980 | } | ||||
6981 | S += RDecl->isUnion() ? ')' : '}'; | ||||
6982 | return; | ||||
6983 | } | ||||
6984 | |||||
6985 | case Type::BlockPointer: { | ||||
6986 | const auto *BT = T->castAs<BlockPointerType>(); | ||||
6987 | S += "@?"; // Unlike a pointer-to-function, which is "^?". | ||||
6988 | if (Options.EncodeBlockParameters()) { | ||||
6989 | const auto *FT = BT->getPointeeType()->castAs<FunctionType>(); | ||||
6990 | |||||
6991 | S += '<'; | ||||
6992 | // Block return type | ||||
6993 | getObjCEncodingForTypeImpl(FT->getReturnType(), S, | ||||
6994 | Options.forComponentType(), FD, NotEncodedT); | ||||
6995 | // Block self | ||||
6996 | S += "@?"; | ||||
6997 | // Block parameters | ||||
6998 | if (const auto *FPT = dyn_cast<FunctionProtoType>(FT)) { | ||||
6999 | for (const auto &I : FPT->param_types()) | ||||
7000 | getObjCEncodingForTypeImpl(I, S, Options.forComponentType(), FD, | ||||
7001 | NotEncodedT); | ||||
7002 | } | ||||
7003 | S += '>'; | ||||
7004 | } | ||||
7005 | return; | ||||
7006 | } | ||||
7007 | |||||
7008 | case Type::ObjCObject: { | ||||
7009 | // hack to match legacy encoding of *id and *Class | ||||
7010 | QualType Ty = getObjCObjectPointerType(CT); | ||||
7011 | if (Ty->isObjCIdType()) { | ||||
7012 | S += "{objc_object=}"; | ||||
7013 | return; | ||||
7014 | } | ||||
7015 | else if (Ty->isObjCClassType()) { | ||||
7016 | S += "{objc_class=}"; | ||||
7017 | return; | ||||
7018 | } | ||||
7019 | // TODO: Double check to make sure this intentionally falls through. | ||||
7020 | LLVM_FALLTHROUGH[[gnu::fallthrough]]; | ||||
7021 | } | ||||
7022 | |||||
7023 | case Type::ObjCInterface: { | ||||
7024 | // Ignore protocol qualifiers when mangling at this level. | ||||
7025 | // @encode(class_name) | ||||
7026 | ObjCInterfaceDecl *OI = T->castAs<ObjCObjectType>()->getInterface(); | ||||
7027 | S += '{'; | ||||
7028 | S += OI->getObjCRuntimeNameAsString(); | ||||
7029 | if (Options.ExpandStructures()) { | ||||
7030 | S += '='; | ||||
7031 | SmallVector<const ObjCIvarDecl*, 32> Ivars; | ||||
7032 | DeepCollectObjCIvars(OI, true, Ivars); | ||||
7033 | for (unsigned i = 0, e = Ivars.size(); i != e; ++i) { | ||||
7034 | const FieldDecl *Field = Ivars[i]; | ||||
7035 | if (Field->isBitField()) | ||||
7036 | getObjCEncodingForTypeImpl(Field->getType(), S, | ||||
7037 | ObjCEncOptions().setExpandStructures(), | ||||
7038 | Field); | ||||
7039 | else | ||||
7040 | getObjCEncodingForTypeImpl(Field->getType(), S, | ||||
7041 | ObjCEncOptions().setExpandStructures(), FD, | ||||
7042 | NotEncodedT); | ||||
7043 | } | ||||
7044 | } | ||||
7045 | S += '}'; | ||||
7046 | return; | ||||
7047 | } | ||||
7048 | |||||
7049 | case Type::ObjCObjectPointer: { | ||||
7050 | const auto *OPT = T->castAs<ObjCObjectPointerType>(); | ||||
7051 | if (OPT->isObjCIdType()) { | ||||
7052 | S += '@'; | ||||
7053 | return; | ||||
7054 | } | ||||
7055 | |||||
7056 | if (OPT->isObjCClassType() || OPT->isObjCQualifiedClassType()) { | ||||
7057 | // FIXME: Consider if we need to output qualifiers for 'Class<p>'. | ||||
7058 | // Since this is a binary compatibility issue, need to consult with | ||||
7059 | // runtime folks. Fortunately, this is a *very* obscure construct. | ||||
7060 | S += '#'; | ||||
7061 | return; | ||||
7062 | } | ||||
7063 | |||||
7064 | if (OPT->isObjCQualifiedIdType()) { | ||||
7065 | getObjCEncodingForTypeImpl( | ||||
7066 | getObjCIdType(), S, | ||||
7067 | Options.keepingOnly(ObjCEncOptions() | ||||
7068 | .setExpandPointedToStructures() | ||||
7069 | .setExpandStructures()), | ||||
7070 | FD); | ||||
7071 | if (FD || Options.EncodingProperty() || Options.EncodeClassNames()) { | ||||
7072 | // Note that we do extended encoding of protocol qualifer list | ||||
7073 | // Only when doing ivar or property encoding. | ||||
7074 | S += '"'; | ||||
7075 | for (const auto *I : OPT->quals()) { | ||||
7076 | S += '<'; | ||||
7077 | S += I->getObjCRuntimeNameAsString(); | ||||
7078 | S += '>'; | ||||
7079 | } | ||||
7080 | S += '"'; | ||||
7081 | } | ||||
7082 | return; | ||||
7083 | } | ||||
7084 | |||||
7085 | S += '@'; | ||||
7086 | if (OPT->getInterfaceDecl() && | ||||
7087 | (FD || Options.EncodingProperty() || Options.EncodeClassNames())) { | ||||
7088 | S += '"'; | ||||
7089 | S += OPT->getInterfaceDecl()->getObjCRuntimeNameAsString(); | ||||
7090 | for (const auto *I : OPT->quals()) { | ||||
7091 | S += '<'; | ||||
7092 | S += I->getObjCRuntimeNameAsString(); | ||||
7093 | S += '>'; | ||||
7094 | } | ||||
7095 | S += '"'; | ||||
7096 | } | ||||
7097 | return; | ||||
7098 | } | ||||
7099 | |||||
7100 | // gcc just blithely ignores member pointers. | ||||
7101 | // FIXME: we should do better than that. 'M' is available. | ||||
7102 | case Type::MemberPointer: | ||||
7103 | // This matches gcc's encoding, even though technically it is insufficient. | ||||
7104 | //FIXME. We should do a better job than gcc. | ||||
7105 | case Type::Vector: | ||||
7106 | case Type::ExtVector: | ||||
7107 | // Until we have a coherent encoding of these three types, issue warning. | ||||
7108 | if (NotEncodedT) | ||||
7109 | *NotEncodedT = T; | ||||
7110 | return; | ||||
7111 | |||||
7112 | // We could see an undeduced auto type here during error recovery. | ||||
7113 | // Just ignore it. | ||||
7114 | case Type::Auto: | ||||
7115 | case Type::DeducedTemplateSpecialization: | ||||
7116 | return; | ||||
7117 | |||||
7118 | case Type::Pipe: | ||||
7119 | #define ABSTRACT_TYPE(KIND, BASE) | ||||
7120 | #define TYPE(KIND, BASE) | ||||
7121 | #define DEPENDENT_TYPE(KIND, BASE) \ | ||||
7122 | case Type::KIND: | ||||
7123 | #define NON_CANONICAL_TYPE(KIND, BASE) \ | ||||
7124 | case Type::KIND: | ||||
7125 | #define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(KIND, BASE) \ | ||||
7126 | case Type::KIND: | ||||
7127 | #include "clang/AST/TypeNodes.inc" | ||||
7128 | llvm_unreachable("@encode for dependent type!")::llvm::llvm_unreachable_internal("@encode for dependent type!" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 7128); | ||||
7129 | } | ||||
7130 | llvm_unreachable("bad type kind!")::llvm::llvm_unreachable_internal("bad type kind!", "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 7130); | ||||
7131 | } | ||||
7132 | |||||
7133 | void ASTContext::getObjCEncodingForStructureImpl(RecordDecl *RDecl, | ||||
7134 | std::string &S, | ||||
7135 | const FieldDecl *FD, | ||||
7136 | bool includeVBases, | ||||
7137 | QualType *NotEncodedT) const { | ||||
7138 | assert(RDecl && "Expected non-null RecordDecl")((RDecl && "Expected non-null RecordDecl") ? static_cast <void> (0) : __assert_fail ("RDecl && \"Expected non-null RecordDecl\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 7138, __PRETTY_FUNCTION__)); | ||||
7139 | assert(!RDecl->isUnion() && "Should not be called for unions")((!RDecl->isUnion() && "Should not be called for unions" ) ? static_cast<void> (0) : __assert_fail ("!RDecl->isUnion() && \"Should not be called for unions\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 7139, __PRETTY_FUNCTION__)); | ||||
7140 | if (!RDecl->getDefinition() || RDecl->getDefinition()->isInvalidDecl()) | ||||
7141 | return; | ||||
7142 | |||||
7143 | const auto *CXXRec = dyn_cast<CXXRecordDecl>(RDecl); | ||||
7144 | std::multimap<uint64_t, NamedDecl *> FieldOrBaseOffsets; | ||||
7145 | const ASTRecordLayout &layout = getASTRecordLayout(RDecl); | ||||
7146 | |||||
7147 | if (CXXRec) { | ||||
7148 | for (const auto &BI : CXXRec->bases()) { | ||||
7149 | if (!BI.isVirtual()) { | ||||
7150 | CXXRecordDecl *base = BI.getType()->getAsCXXRecordDecl(); | ||||
7151 | if (base->isEmpty()) | ||||
7152 | continue; | ||||
7153 | uint64_t offs = toBits(layout.getBaseClassOffset(base)); | ||||
7154 | FieldOrBaseOffsets.insert(FieldOrBaseOffsets.upper_bound(offs), | ||||
7155 | std::make_pair(offs, base)); | ||||
7156 | } | ||||
7157 | } | ||||
7158 | } | ||||
7159 | |||||
7160 | unsigned i = 0; | ||||
7161 | for (auto *Field : RDecl->fields()) { | ||||
7162 | uint64_t offs = layout.getFieldOffset(i); | ||||
7163 | FieldOrBaseOffsets.insert(FieldOrBaseOffsets.upper_bound(offs), | ||||
7164 | std::make_pair(offs, Field)); | ||||
7165 | ++i; | ||||
7166 | } | ||||
7167 | |||||
7168 | if (CXXRec && includeVBases) { | ||||
7169 | for (const auto &BI : CXXRec->vbases()) { | ||||
7170 | CXXRecordDecl *base = BI.getType()->getAsCXXRecordDecl(); | ||||
7171 | if (base->isEmpty()) | ||||
7172 | continue; | ||||
7173 | uint64_t offs = toBits(layout.getVBaseClassOffset(base)); | ||||
7174 | if (offs >= uint64_t(toBits(layout.getNonVirtualSize())) && | ||||
7175 | FieldOrBaseOffsets.find(offs) == FieldOrBaseOffsets.end()) | ||||
7176 | FieldOrBaseOffsets.insert(FieldOrBaseOffsets.end(), | ||||
7177 | std::make_pair(offs, base)); | ||||
7178 | } | ||||
7179 | } | ||||
7180 | |||||
7181 | CharUnits size; | ||||
7182 | if (CXXRec) { | ||||
7183 | size = includeVBases ? layout.getSize() : layout.getNonVirtualSize(); | ||||
7184 | } else { | ||||
7185 | size = layout.getSize(); | ||||
7186 | } | ||||
7187 | |||||
7188 | #ifndef NDEBUG | ||||
7189 | uint64_t CurOffs = 0; | ||||
7190 | #endif | ||||
7191 | std::multimap<uint64_t, NamedDecl *>::iterator | ||||
7192 | CurLayObj = FieldOrBaseOffsets.begin(); | ||||
7193 | |||||
7194 | if (CXXRec && CXXRec->isDynamicClass() && | ||||
7195 | (CurLayObj == FieldOrBaseOffsets.end() || CurLayObj->first != 0)) { | ||||
7196 | if (FD) { | ||||
7197 | S += "\"_vptr$"; | ||||
7198 | std::string recname = CXXRec->getNameAsString(); | ||||
7199 | if (recname.empty()) recname = "?"; | ||||
7200 | S += recname; | ||||
7201 | S += '"'; | ||||
7202 | } | ||||
7203 | S += "^^?"; | ||||
7204 | #ifndef NDEBUG | ||||
7205 | CurOffs += getTypeSize(VoidPtrTy); | ||||
7206 | #endif | ||||
7207 | } | ||||
7208 | |||||
7209 | if (!RDecl->hasFlexibleArrayMember()) { | ||||
7210 | // Mark the end of the structure. | ||||
7211 | uint64_t offs = toBits(size); | ||||
7212 | FieldOrBaseOffsets.insert(FieldOrBaseOffsets.upper_bound(offs), | ||||
7213 | std::make_pair(offs, nullptr)); | ||||
7214 | } | ||||
7215 | |||||
7216 | for (; CurLayObj != FieldOrBaseOffsets.end(); ++CurLayObj) { | ||||
7217 | #ifndef NDEBUG | ||||
7218 | assert(CurOffs <= CurLayObj->first)((CurOffs <= CurLayObj->first) ? static_cast<void> (0) : __assert_fail ("CurOffs <= CurLayObj->first", "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 7218, __PRETTY_FUNCTION__)); | ||||
7219 | if (CurOffs < CurLayObj->first) { | ||||
7220 | uint64_t padding = CurLayObj->first - CurOffs; | ||||
7221 | // FIXME: There doesn't seem to be a way to indicate in the encoding that | ||||
7222 | // packing/alignment of members is different that normal, in which case | ||||
7223 | // the encoding will be out-of-sync with the real layout. | ||||
7224 | // If the runtime switches to just consider the size of types without | ||||
7225 | // taking into account alignment, we could make padding explicit in the | ||||
7226 | // encoding (e.g. using arrays of chars). The encoding strings would be | ||||
7227 | // longer then though. | ||||
7228 | CurOffs += padding; | ||||
7229 | } | ||||
7230 | #endif | ||||
7231 | |||||
7232 | NamedDecl *dcl = CurLayObj->second; | ||||
7233 | if (!dcl) | ||||
7234 | break; // reached end of structure. | ||||
7235 | |||||
7236 | if (auto *base = dyn_cast<CXXRecordDecl>(dcl)) { | ||||
7237 | // We expand the bases without their virtual bases since those are going | ||||
7238 | // in the initial structure. Note that this differs from gcc which | ||||
7239 | // expands virtual bases each time one is encountered in the hierarchy, | ||||
7240 | // making the encoding type bigger than it really is. | ||||
7241 | getObjCEncodingForStructureImpl(base, S, FD, /*includeVBases*/false, | ||||
7242 | NotEncodedT); | ||||
7243 | assert(!base->isEmpty())((!base->isEmpty()) ? static_cast<void> (0) : __assert_fail ("!base->isEmpty()", "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 7243, __PRETTY_FUNCTION__)); | ||||
7244 | #ifndef NDEBUG | ||||
7245 | CurOffs += toBits(getASTRecordLayout(base).getNonVirtualSize()); | ||||
7246 | #endif | ||||
7247 | } else { | ||||
7248 | const auto *field = cast<FieldDecl>(dcl); | ||||
7249 | if (FD) { | ||||
7250 | S += '"'; | ||||
7251 | S += field->getNameAsString(); | ||||
7252 | S += '"'; | ||||
7253 | } | ||||
7254 | |||||
7255 | if (field->isBitField()) { | ||||
7256 | EncodeBitField(this, S, field->getType(), field); | ||||
7257 | #ifndef NDEBUG | ||||
7258 | CurOffs += field->getBitWidthValue(*this); | ||||
7259 | #endif | ||||
7260 | } else { | ||||
7261 | QualType qt = field->getType(); | ||||
7262 | getLegacyIntegralTypeEncoding(qt); | ||||
7263 | getObjCEncodingForTypeImpl( | ||||
7264 | qt, S, ObjCEncOptions().setExpandStructures().setIsStructField(), | ||||
7265 | FD, NotEncodedT); | ||||
7266 | #ifndef NDEBUG | ||||
7267 | CurOffs += getTypeSize(field->getType()); | ||||
7268 | #endif | ||||
7269 | } | ||||
7270 | } | ||||
7271 | } | ||||
7272 | } | ||||
7273 | |||||
7274 | void ASTContext::getObjCEncodingForTypeQualifier(Decl::ObjCDeclQualifier QT, | ||||
7275 | std::string& S) const { | ||||
7276 | if (QT & Decl::OBJC_TQ_In) | ||||
7277 | S += 'n'; | ||||
7278 | if (QT & Decl::OBJC_TQ_Inout) | ||||
7279 | S += 'N'; | ||||
7280 | if (QT & Decl::OBJC_TQ_Out) | ||||
7281 | S += 'o'; | ||||
7282 | if (QT & Decl::OBJC_TQ_Bycopy) | ||||
7283 | S += 'O'; | ||||
7284 | if (QT & Decl::OBJC_TQ_Byref) | ||||
7285 | S += 'R'; | ||||
7286 | if (QT & Decl::OBJC_TQ_Oneway) | ||||
7287 | S += 'V'; | ||||
7288 | } | ||||
7289 | |||||
7290 | TypedefDecl *ASTContext::getObjCIdDecl() const { | ||||
7291 | if (!ObjCIdDecl) { | ||||
7292 | QualType T = getObjCObjectType(ObjCBuiltinIdTy, {}, {}); | ||||
7293 | T = getObjCObjectPointerType(T); | ||||
7294 | ObjCIdDecl = buildImplicitTypedef(T, "id"); | ||||
7295 | } | ||||
7296 | return ObjCIdDecl; | ||||
7297 | } | ||||
7298 | |||||
7299 | TypedefDecl *ASTContext::getObjCSelDecl() const { | ||||
7300 | if (!ObjCSelDecl) { | ||||
7301 | QualType T = getPointerType(ObjCBuiltinSelTy); | ||||
7302 | ObjCSelDecl = buildImplicitTypedef(T, "SEL"); | ||||
7303 | } | ||||
7304 | return ObjCSelDecl; | ||||
7305 | } | ||||
7306 | |||||
7307 | TypedefDecl *ASTContext::getObjCClassDecl() const { | ||||
7308 | if (!ObjCClassDecl) { | ||||
7309 | QualType T = getObjCObjectType(ObjCBuiltinClassTy, {}, {}); | ||||
7310 | T = getObjCObjectPointerType(T); | ||||
7311 | ObjCClassDecl = buildImplicitTypedef(T, "Class"); | ||||
7312 | } | ||||
7313 | return ObjCClassDecl; | ||||
7314 | } | ||||
7315 | |||||
7316 | ObjCInterfaceDecl *ASTContext::getObjCProtocolDecl() const { | ||||
7317 | if (!ObjCProtocolClassDecl) { | ||||
7318 | ObjCProtocolClassDecl | ||||
7319 | = ObjCInterfaceDecl::Create(*this, getTranslationUnitDecl(), | ||||
7320 | SourceLocation(), | ||||
7321 | &Idents.get("Protocol"), | ||||
7322 | /*typeParamList=*/nullptr, | ||||
7323 | /*PrevDecl=*/nullptr, | ||||
7324 | SourceLocation(), true); | ||||
7325 | } | ||||
7326 | |||||
7327 | return ObjCProtocolClassDecl; | ||||
7328 | } | ||||
7329 | |||||
7330 | //===----------------------------------------------------------------------===// | ||||
7331 | // __builtin_va_list Construction Functions | ||||
7332 | //===----------------------------------------------------------------------===// | ||||
7333 | |||||
7334 | static TypedefDecl *CreateCharPtrNamedVaListDecl(const ASTContext *Context, | ||||
7335 | StringRef Name) { | ||||
7336 | // typedef char* __builtin[_ms]_va_list; | ||||
7337 | QualType T = Context->getPointerType(Context->CharTy); | ||||
7338 | return Context->buildImplicitTypedef(T, Name); | ||||
7339 | } | ||||
7340 | |||||
7341 | static TypedefDecl *CreateMSVaListDecl(const ASTContext *Context) { | ||||
7342 | return CreateCharPtrNamedVaListDecl(Context, "__builtin_ms_va_list"); | ||||
7343 | } | ||||
7344 | |||||
7345 | static TypedefDecl *CreateCharPtrBuiltinVaListDecl(const ASTContext *Context) { | ||||
7346 | return CreateCharPtrNamedVaListDecl(Context, "__builtin_va_list"); | ||||
7347 | } | ||||
7348 | |||||
7349 | static TypedefDecl *CreateVoidPtrBuiltinVaListDecl(const ASTContext *Context) { | ||||
7350 | // typedef void* __builtin_va_list; | ||||
7351 | QualType T = Context->getPointerType(Context->VoidTy); | ||||
7352 | return Context->buildImplicitTypedef(T, "__builtin_va_list"); | ||||
7353 | } | ||||
7354 | |||||
7355 | static TypedefDecl * | ||||
7356 | CreateAArch64ABIBuiltinVaListDecl(const ASTContext *Context) { | ||||
7357 | // struct __va_list | ||||
7358 | RecordDecl *VaListTagDecl = Context->buildImplicitRecord("__va_list"); | ||||
7359 | if (Context->getLangOpts().CPlusPlus) { | ||||
7360 | // namespace std { struct __va_list { | ||||
7361 | NamespaceDecl *NS; | ||||
7362 | NS = NamespaceDecl::Create(const_cast<ASTContext &>(*Context), | ||||
7363 | Context->getTranslationUnitDecl(), | ||||
7364 | /*Inline*/ false, SourceLocation(), | ||||
7365 | SourceLocation(), &Context->Idents.get("std"), | ||||
7366 | /*PrevDecl*/ nullptr); | ||||
7367 | NS->setImplicit(); | ||||
7368 | VaListTagDecl->setDeclContext(NS); | ||||
7369 | } | ||||
7370 | |||||
7371 | VaListTagDecl->startDefinition(); | ||||
7372 | |||||
7373 | const size_t NumFields = 5; | ||||
7374 | QualType FieldTypes[NumFields]; | ||||
7375 | const char *FieldNames[NumFields]; | ||||
7376 | |||||
7377 | // void *__stack; | ||||
7378 | FieldTypes[0] = Context->getPointerType(Context->VoidTy); | ||||
7379 | FieldNames[0] = "__stack"; | ||||
7380 | |||||
7381 | // void *__gr_top; | ||||
7382 | FieldTypes[1] = Context->getPointerType(Context->VoidTy); | ||||
7383 | FieldNames[1] = "__gr_top"; | ||||
7384 | |||||
7385 | // void *__vr_top; | ||||
7386 | FieldTypes[2] = Context->getPointerType(Context->VoidTy); | ||||
7387 | FieldNames[2] = "__vr_top"; | ||||
7388 | |||||
7389 | // int __gr_offs; | ||||
7390 | FieldTypes[3] = Context->IntTy; | ||||
7391 | FieldNames[3] = "__gr_offs"; | ||||
7392 | |||||
7393 | // int __vr_offs; | ||||
7394 | FieldTypes[4] = Context->IntTy; | ||||
7395 | FieldNames[4] = "__vr_offs"; | ||||
7396 | |||||
7397 | // Create fields | ||||
7398 | for (unsigned i = 0; i < NumFields; ++i) { | ||||
7399 | FieldDecl *Field = FieldDecl::Create(const_cast<ASTContext &>(*Context), | ||||
7400 | VaListTagDecl, | ||||
7401 | SourceLocation(), | ||||
7402 | SourceLocation(), | ||||
7403 | &Context->Idents.get(FieldNames[i]), | ||||
7404 | FieldTypes[i], /*TInfo=*/nullptr, | ||||
7405 | /*BitWidth=*/nullptr, | ||||
7406 | /*Mutable=*/false, | ||||
7407 | ICIS_NoInit); | ||||
7408 | Field->setAccess(AS_public); | ||||
7409 | VaListTagDecl->addDecl(Field); | ||||
7410 | } | ||||
7411 | VaListTagDecl->completeDefinition(); | ||||
7412 | Context->VaListTagDecl = VaListTagDecl; | ||||
7413 | QualType VaListTagType = Context->getRecordType(VaListTagDecl); | ||||
7414 | |||||
7415 | // } __builtin_va_list; | ||||
7416 | return Context->buildImplicitTypedef(VaListTagType, "__builtin_va_list"); | ||||
7417 | } | ||||
7418 | |||||
7419 | static TypedefDecl *CreatePowerABIBuiltinVaListDecl(const ASTContext *Context) { | ||||
7420 | // typedef struct __va_list_tag { | ||||
7421 | RecordDecl *VaListTagDecl; | ||||
7422 | |||||
7423 | VaListTagDecl = Context->buildImplicitRecord("__va_list_tag"); | ||||
7424 | VaListTagDecl->startDefinition(); | ||||
7425 | |||||
7426 | const size_t NumFields = 5; | ||||
7427 | QualType FieldTypes[NumFields]; | ||||
7428 | const char *FieldNames[NumFields]; | ||||
7429 | |||||
7430 | // unsigned char gpr; | ||||
7431 | FieldTypes[0] = Context->UnsignedCharTy; | ||||
7432 | FieldNames[0] = "gpr"; | ||||
7433 | |||||
7434 | // unsigned char fpr; | ||||
7435 | FieldTypes[1] = Context->UnsignedCharTy; | ||||
7436 | FieldNames[1] = "fpr"; | ||||
7437 | |||||
7438 | // unsigned short reserved; | ||||
7439 | FieldTypes[2] = Context->UnsignedShortTy; | ||||
7440 | FieldNames[2] = "reserved"; | ||||
7441 | |||||
7442 | // void* overflow_arg_area; | ||||
7443 | FieldTypes[3] = Context->getPointerType(Context->VoidTy); | ||||
7444 | FieldNames[3] = "overflow_arg_area"; | ||||
7445 | |||||
7446 | // void* reg_save_area; | ||||
7447 | FieldTypes[4] = Context->getPointerType(Context->VoidTy); | ||||
7448 | FieldNames[4] = "reg_save_area"; | ||||
7449 | |||||
7450 | // Create fields | ||||
7451 | for (unsigned i = 0; i < NumFields; ++i) { | ||||
7452 | FieldDecl *Field = FieldDecl::Create(*Context, VaListTagDecl, | ||||
7453 | SourceLocation(), | ||||
7454 | SourceLocation(), | ||||
7455 | &Context->Idents.get(FieldNames[i]), | ||||
7456 | FieldTypes[i], /*TInfo=*/nullptr, | ||||
7457 | /*BitWidth=*/nullptr, | ||||
7458 | /*Mutable=*/false, | ||||
7459 | ICIS_NoInit); | ||||
7460 | Field->setAccess(AS_public); | ||||
7461 | VaListTagDecl->addDecl(Field); | ||||
7462 | } | ||||
7463 | VaListTagDecl->completeDefinition(); | ||||
7464 | Context->VaListTagDecl = VaListTagDecl; | ||||
7465 | QualType VaListTagType = Context->getRecordType(VaListTagDecl); | ||||
7466 | |||||
7467 | // } __va_list_tag; | ||||
7468 | TypedefDecl *VaListTagTypedefDecl = | ||||
7469 | Context->buildImplicitTypedef(VaListTagType, "__va_list_tag"); | ||||
7470 | |||||
7471 | QualType VaListTagTypedefType = | ||||
7472 | Context->getTypedefType(VaListTagTypedefDecl); | ||||
7473 | |||||
7474 | // typedef __va_list_tag __builtin_va_list[1]; | ||||
7475 | llvm::APInt Size(Context->getTypeSize(Context->getSizeType()), 1); | ||||
7476 | QualType VaListTagArrayType | ||||
7477 | = Context->getConstantArrayType(VaListTagTypedefType, | ||||
7478 | Size, ArrayType::Normal, 0); | ||||
7479 | return Context->buildImplicitTypedef(VaListTagArrayType, "__builtin_va_list"); | ||||
7480 | } | ||||
7481 | |||||
7482 | static TypedefDecl * | ||||
7483 | CreateX86_64ABIBuiltinVaListDecl(const ASTContext *Context) { | ||||
7484 | // struct __va_list_tag { | ||||
7485 | RecordDecl *VaListTagDecl; | ||||
7486 | VaListTagDecl = Context->buildImplicitRecord("__va_list_tag"); | ||||
7487 | VaListTagDecl->startDefinition(); | ||||
7488 | |||||
7489 | const size_t NumFields = 4; | ||||
7490 | QualType FieldTypes[NumFields]; | ||||
7491 | const char *FieldNames[NumFields]; | ||||
7492 | |||||
7493 | // unsigned gp_offset; | ||||
7494 | FieldTypes[0] = Context->UnsignedIntTy; | ||||
7495 | FieldNames[0] = "gp_offset"; | ||||
7496 | |||||
7497 | // unsigned fp_offset; | ||||
7498 | FieldTypes[1] = Context->UnsignedIntTy; | ||||
7499 | FieldNames[1] = "fp_offset"; | ||||
7500 | |||||
7501 | // void* overflow_arg_area; | ||||
7502 | FieldTypes[2] = Context->getPointerType(Context->VoidTy); | ||||
7503 | FieldNames[2] = "overflow_arg_area"; | ||||
7504 | |||||
7505 | // void* reg_save_area; | ||||
7506 | FieldTypes[3] = Context->getPointerType(Context->VoidTy); | ||||
7507 | FieldNames[3] = "reg_save_area"; | ||||
7508 | |||||
7509 | // Create fields | ||||
7510 | for (unsigned i = 0; i < NumFields; ++i) { | ||||
7511 | FieldDecl *Field = FieldDecl::Create(const_cast<ASTContext &>(*Context), | ||||
7512 | VaListTagDecl, | ||||
7513 | SourceLocation(), | ||||
7514 | SourceLocation(), | ||||
7515 | &Context->Idents.get(FieldNames[i]), | ||||
7516 | FieldTypes[i], /*TInfo=*/nullptr, | ||||
7517 | /*BitWidth=*/nullptr, | ||||
7518 | /*Mutable=*/false, | ||||
7519 | ICIS_NoInit); | ||||
7520 | Field->setAccess(AS_public); | ||||
7521 | VaListTagDecl->addDecl(Field); | ||||
7522 | } | ||||
7523 | VaListTagDecl->completeDefinition(); | ||||
7524 | Context->VaListTagDecl = VaListTagDecl; | ||||
7525 | QualType VaListTagType = Context->getRecordType(VaListTagDecl); | ||||
7526 | |||||
7527 | // }; | ||||
7528 | |||||
7529 | // typedef struct __va_list_tag __builtin_va_list[1]; | ||||
7530 | llvm::APInt Size(Context->getTypeSize(Context->getSizeType()), 1); | ||||
7531 | QualType VaListTagArrayType = | ||||
7532 | Context->getConstantArrayType(VaListTagType, Size, ArrayType::Normal, 0); | ||||
7533 | return Context->buildImplicitTypedef(VaListTagArrayType, "__builtin_va_list"); | ||||
7534 | } | ||||
7535 | |||||
7536 | static TypedefDecl *CreatePNaClABIBuiltinVaListDecl(const ASTContext *Context) { | ||||
7537 | // typedef int __builtin_va_list[4]; | ||||
7538 | llvm::APInt Size(Context->getTypeSize(Context->getSizeType()), 4); | ||||
7539 | QualType IntArrayType = | ||||
7540 | Context->getConstantArrayType(Context->IntTy, Size, ArrayType::Normal, 0); | ||||
7541 | return Context->buildImplicitTypedef(IntArrayType, "__builtin_va_list"); | ||||
7542 | } | ||||
7543 | |||||
7544 | static TypedefDecl * | ||||
7545 | CreateAAPCSABIBuiltinVaListDecl(const ASTContext *Context) { | ||||
7546 | // struct __va_list | ||||
7547 | RecordDecl *VaListDecl = Context->buildImplicitRecord("__va_list"); | ||||
7548 | if (Context->getLangOpts().CPlusPlus) { | ||||
7549 | // namespace std { struct __va_list { | ||||
7550 | NamespaceDecl *NS; | ||||
7551 | NS = NamespaceDecl::Create(const_cast<ASTContext &>(*Context), | ||||
7552 | Context->getTranslationUnitDecl(), | ||||
7553 | /*Inline*/false, SourceLocation(), | ||||
7554 | SourceLocation(), &Context->Idents.get("std"), | ||||
7555 | /*PrevDecl*/ nullptr); | ||||
7556 | NS->setImplicit(); | ||||
7557 | VaListDecl->setDeclContext(NS); | ||||
7558 | } | ||||
7559 | |||||
7560 | VaListDecl->startDefinition(); | ||||
7561 | |||||
7562 | // void * __ap; | ||||
7563 | FieldDecl *Field = FieldDecl::Create(const_cast<ASTContext &>(*Context), | ||||
7564 | VaListDecl, | ||||
7565 | SourceLocation(), | ||||
7566 | SourceLocation(), | ||||
7567 | &Context->Idents.get("__ap"), | ||||
7568 | Context->getPointerType(Context->VoidTy), | ||||
7569 | /*TInfo=*/nullptr, | ||||
7570 | /*BitWidth=*/nullptr, | ||||
7571 | /*Mutable=*/false, | ||||
7572 | ICIS_NoInit); | ||||
7573 | Field->setAccess(AS_public); | ||||
7574 | VaListDecl->addDecl(Field); | ||||
7575 | |||||
7576 | // }; | ||||
7577 | VaListDecl->completeDefinition(); | ||||
7578 | Context->VaListTagDecl = VaListDecl; | ||||
7579 | |||||
7580 | // typedef struct __va_list __builtin_va_list; | ||||
7581 | QualType T = Context->getRecordType(VaListDecl); | ||||
7582 | return Context->buildImplicitTypedef(T, "__builtin_va_list"); | ||||
7583 | } | ||||
7584 | |||||
7585 | static TypedefDecl * | ||||
7586 | CreateSystemZBuiltinVaListDecl(const ASTContext *Context) { | ||||
7587 | // struct __va_list_tag { | ||||
7588 | RecordDecl *VaListTagDecl; | ||||
7589 | VaListTagDecl = Context->buildImplicitRecord("__va_list_tag"); | ||||
7590 | VaListTagDecl->startDefinition(); | ||||
7591 | |||||
7592 | const size_t NumFields = 4; | ||||
7593 | QualType FieldTypes[NumFields]; | ||||
7594 | const char *FieldNames[NumFields]; | ||||
7595 | |||||
7596 | // long __gpr; | ||||
7597 | FieldTypes[0] = Context->LongTy; | ||||
7598 | FieldNames[0] = "__gpr"; | ||||
7599 | |||||
7600 | // long __fpr; | ||||
7601 | FieldTypes[1] = Context->LongTy; | ||||
7602 | FieldNames[1] = "__fpr"; | ||||
7603 | |||||
7604 | // void *__overflow_arg_area; | ||||
7605 | FieldTypes[2] = Context->getPointerType(Context->VoidTy); | ||||
7606 | FieldNames[2] = "__overflow_arg_area"; | ||||
7607 | |||||
7608 | // void *__reg_save_area; | ||||
7609 | FieldTypes[3] = Context->getPointerType(Context->VoidTy); | ||||
7610 | FieldNames[3] = "__reg_save_area"; | ||||
7611 | |||||
7612 | // Create fields | ||||
7613 | for (unsigned i = 0; i < NumFields; ++i) { | ||||
7614 | FieldDecl *Field = FieldDecl::Create(const_cast<ASTContext &>(*Context), | ||||
7615 | VaListTagDecl, | ||||
7616 | SourceLocation(), | ||||
7617 | SourceLocation(), | ||||
7618 | &Context->Idents.get(FieldNames[i]), | ||||
7619 | FieldTypes[i], /*TInfo=*/nullptr, | ||||
7620 | /*BitWidth=*/nullptr, | ||||
7621 | /*Mutable=*/false, | ||||
7622 | ICIS_NoInit); | ||||
7623 | Field->setAccess(AS_public); | ||||
7624 | VaListTagDecl->addDecl(Field); | ||||
7625 | } | ||||
7626 | VaListTagDecl->completeDefinition(); | ||||
7627 | Context->VaListTagDecl = VaListTagDecl; | ||||
7628 | QualType VaListTagType = Context->getRecordType(VaListTagDecl); | ||||
7629 | |||||
7630 | // }; | ||||
7631 | |||||
7632 | // typedef __va_list_tag __builtin_va_list[1]; | ||||
7633 | llvm::APInt Size(Context->getTypeSize(Context->getSizeType()), 1); | ||||
7634 | QualType VaListTagArrayType = | ||||
7635 | Context->getConstantArrayType(VaListTagType, Size, ArrayType::Normal, 0); | ||||
7636 | |||||
7637 | return Context->buildImplicitTypedef(VaListTagArrayType, "__builtin_va_list"); | ||||
7638 | } | ||||
7639 | |||||
7640 | static TypedefDecl *CreateVaListDecl(const ASTContext *Context, | ||||
7641 | TargetInfo::BuiltinVaListKind Kind) { | ||||
7642 | switch (Kind) { | ||||
7643 | case TargetInfo::CharPtrBuiltinVaList: | ||||
7644 | return CreateCharPtrBuiltinVaListDecl(Context); | ||||
7645 | case TargetInfo::VoidPtrBuiltinVaList: | ||||
7646 | return CreateVoidPtrBuiltinVaListDecl(Context); | ||||
7647 | case TargetInfo::AArch64ABIBuiltinVaList: | ||||
7648 | return CreateAArch64ABIBuiltinVaListDecl(Context); | ||||
7649 | case TargetInfo::PowerABIBuiltinVaList: | ||||
7650 | return CreatePowerABIBuiltinVaListDecl(Context); | ||||
7651 | case TargetInfo::X86_64ABIBuiltinVaList: | ||||
7652 | return CreateX86_64ABIBuiltinVaListDecl(Context); | ||||
7653 | case TargetInfo::PNaClABIBuiltinVaList: | ||||
7654 | return CreatePNaClABIBuiltinVaListDecl(Context); | ||||
7655 | case TargetInfo::AAPCSABIBuiltinVaList: | ||||
7656 | return CreateAAPCSABIBuiltinVaListDecl(Context); | ||||
7657 | case TargetInfo::SystemZBuiltinVaList: | ||||
7658 | return CreateSystemZBuiltinVaListDecl(Context); | ||||
7659 | } | ||||
7660 | |||||
7661 | llvm_unreachable("Unhandled __builtin_va_list type kind")::llvm::llvm_unreachable_internal("Unhandled __builtin_va_list type kind" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 7661); | ||||
7662 | } | ||||
7663 | |||||
7664 | TypedefDecl *ASTContext::getBuiltinVaListDecl() const { | ||||
7665 | if (!BuiltinVaListDecl) { | ||||
7666 | BuiltinVaListDecl = CreateVaListDecl(this, Target->getBuiltinVaListKind()); | ||||
7667 | assert(BuiltinVaListDecl->isImplicit())((BuiltinVaListDecl->isImplicit()) ? static_cast<void> (0) : __assert_fail ("BuiltinVaListDecl->isImplicit()", "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 7667, __PRETTY_FUNCTION__)); | ||||
7668 | } | ||||
7669 | |||||
7670 | return BuiltinVaListDecl; | ||||
7671 | } | ||||
7672 | |||||
7673 | Decl *ASTContext::getVaListTagDecl() const { | ||||
7674 | // Force the creation of VaListTagDecl by building the __builtin_va_list | ||||
7675 | // declaration. | ||||
7676 | if (!VaListTagDecl) | ||||
7677 | (void)getBuiltinVaListDecl(); | ||||
7678 | |||||
7679 | return VaListTagDecl; | ||||
7680 | } | ||||
7681 | |||||
7682 | TypedefDecl *ASTContext::getBuiltinMSVaListDecl() const { | ||||
7683 | if (!BuiltinMSVaListDecl) | ||||
7684 | BuiltinMSVaListDecl = CreateMSVaListDecl(this); | ||||
7685 | |||||
7686 | return BuiltinMSVaListDecl; | ||||
7687 | } | ||||
7688 | |||||
7689 | bool ASTContext::canBuiltinBeRedeclared(const FunctionDecl *FD) const { | ||||
7690 | return BuiltinInfo.canBeRedeclared(FD->getBuiltinID()); | ||||
7691 | } | ||||
7692 | |||||
7693 | void ASTContext::setObjCConstantStringInterface(ObjCInterfaceDecl *Decl) { | ||||
7694 | assert(ObjCConstantStringType.isNull() &&((ObjCConstantStringType.isNull() && "'NSConstantString' type already set!" ) ? static_cast<void> (0) : __assert_fail ("ObjCConstantStringType.isNull() && \"'NSConstantString' type already set!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 7695, __PRETTY_FUNCTION__)) | ||||
7695 | "'NSConstantString' type already set!")((ObjCConstantStringType.isNull() && "'NSConstantString' type already set!" ) ? static_cast<void> (0) : __assert_fail ("ObjCConstantStringType.isNull() && \"'NSConstantString' type already set!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 7695, __PRETTY_FUNCTION__)); | ||||
7696 | |||||
7697 | ObjCConstantStringType = getObjCInterfaceType(Decl); | ||||
7698 | } | ||||
7699 | |||||
7700 | /// Retrieve the template name that corresponds to a non-empty | ||||
7701 | /// lookup. | ||||
7702 | TemplateName | ||||
7703 | ASTContext::getOverloadedTemplateName(UnresolvedSetIterator Begin, | ||||
7704 | UnresolvedSetIterator End) const { | ||||
7705 | unsigned size = End - Begin; | ||||
7706 | assert(size > 1 && "set is not overloaded!")((size > 1 && "set is not overloaded!") ? static_cast <void> (0) : __assert_fail ("size > 1 && \"set is not overloaded!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 7706, __PRETTY_FUNCTION__)); | ||||
7707 | |||||
7708 | void *memory = Allocate(sizeof(OverloadedTemplateStorage) + | ||||
7709 | size * sizeof(FunctionTemplateDecl*)); | ||||
7710 | auto *OT = new (memory) OverloadedTemplateStorage(size); | ||||
7711 | |||||
7712 | NamedDecl **Storage = OT->getStorage(); | ||||
7713 | for (UnresolvedSetIterator I = Begin; I != End; ++I) { | ||||
7714 | NamedDecl *D = *I; | ||||
7715 | assert(isa<FunctionTemplateDecl>(D) ||((isa<FunctionTemplateDecl>(D) || isa<UnresolvedUsingValueDecl >(D) || (isa<UsingShadowDecl>(D) && isa<FunctionTemplateDecl >(D->getUnderlyingDecl()))) ? static_cast<void> ( 0) : __assert_fail ("isa<FunctionTemplateDecl>(D) || isa<UnresolvedUsingValueDecl>(D) || (isa<UsingShadowDecl>(D) && isa<FunctionTemplateDecl>(D->getUnderlyingDecl()))" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 7718, __PRETTY_FUNCTION__)) | ||||
7716 | isa<UnresolvedUsingValueDecl>(D) ||((isa<FunctionTemplateDecl>(D) || isa<UnresolvedUsingValueDecl >(D) || (isa<UsingShadowDecl>(D) && isa<FunctionTemplateDecl >(D->getUnderlyingDecl()))) ? static_cast<void> ( 0) : __assert_fail ("isa<FunctionTemplateDecl>(D) || isa<UnresolvedUsingValueDecl>(D) || (isa<UsingShadowDecl>(D) && isa<FunctionTemplateDecl>(D->getUnderlyingDecl()))" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 7718, __PRETTY_FUNCTION__)) | ||||
7717 | (isa<UsingShadowDecl>(D) &&((isa<FunctionTemplateDecl>(D) || isa<UnresolvedUsingValueDecl >(D) || (isa<UsingShadowDecl>(D) && isa<FunctionTemplateDecl >(D->getUnderlyingDecl()))) ? static_cast<void> ( 0) : __assert_fail ("isa<FunctionTemplateDecl>(D) || isa<UnresolvedUsingValueDecl>(D) || (isa<UsingShadowDecl>(D) && isa<FunctionTemplateDecl>(D->getUnderlyingDecl()))" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 7718, __PRETTY_FUNCTION__)) | ||||
7718 | isa<FunctionTemplateDecl>(D->getUnderlyingDecl())))((isa<FunctionTemplateDecl>(D) || isa<UnresolvedUsingValueDecl >(D) || (isa<UsingShadowDecl>(D) && isa<FunctionTemplateDecl >(D->getUnderlyingDecl()))) ? static_cast<void> ( 0) : __assert_fail ("isa<FunctionTemplateDecl>(D) || isa<UnresolvedUsingValueDecl>(D) || (isa<UsingShadowDecl>(D) && isa<FunctionTemplateDecl>(D->getUnderlyingDecl()))" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 7718, __PRETTY_FUNCTION__)); | ||||
7719 | *Storage++ = D; | ||||
7720 | } | ||||
7721 | |||||
7722 | return TemplateName(OT); | ||||
7723 | } | ||||
7724 | |||||
7725 | /// Retrieve a template name representing an unqualified-id that has been | ||||
7726 | /// assumed to name a template for ADL purposes. | ||||
7727 | TemplateName ASTContext::getAssumedTemplateName(DeclarationName Name) const { | ||||
7728 | auto *OT = new (*this) AssumedTemplateStorage(Name); | ||||
7729 | return TemplateName(OT); | ||||
7730 | } | ||||
7731 | |||||
7732 | /// Retrieve the template name that represents a qualified | ||||
7733 | /// template name such as \c std::vector. | ||||
7734 | TemplateName | ||||
7735 | ASTContext::getQualifiedTemplateName(NestedNameSpecifier *NNS, | ||||
7736 | bool TemplateKeyword, | ||||
7737 | TemplateDecl *Template) const { | ||||
7738 | assert(NNS && "Missing nested-name-specifier in qualified template name")((NNS && "Missing nested-name-specifier in qualified template name" ) ? static_cast<void> (0) : __assert_fail ("NNS && \"Missing nested-name-specifier in qualified template name\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 7738, __PRETTY_FUNCTION__)); | ||||
7739 | |||||
7740 | // FIXME: Canonicalization? | ||||
7741 | llvm::FoldingSetNodeID ID; | ||||
7742 | QualifiedTemplateName::Profile(ID, NNS, TemplateKeyword, Template); | ||||
7743 | |||||
7744 | void *InsertPos = nullptr; | ||||
7745 | QualifiedTemplateName *QTN = | ||||
7746 | QualifiedTemplateNames.FindNodeOrInsertPos(ID, InsertPos); | ||||
7747 | if (!QTN) { | ||||
7748 | QTN = new (*this, alignof(QualifiedTemplateName)) | ||||
7749 | QualifiedTemplateName(NNS, TemplateKeyword, Template); | ||||
7750 | QualifiedTemplateNames.InsertNode(QTN, InsertPos); | ||||
7751 | } | ||||
7752 | |||||
7753 | return TemplateName(QTN); | ||||
7754 | } | ||||
7755 | |||||
7756 | /// Retrieve the template name that represents a dependent | ||||
7757 | /// template name such as \c MetaFun::template apply. | ||||
7758 | TemplateName | ||||
7759 | ASTContext::getDependentTemplateName(NestedNameSpecifier *NNS, | ||||
7760 | const IdentifierInfo *Name) const { | ||||
7761 | assert((!NNS || NNS->isDependent()) &&(((!NNS || NNS->isDependent()) && "Nested name specifier must be dependent" ) ? static_cast<void> (0) : __assert_fail ("(!NNS || NNS->isDependent()) && \"Nested name specifier must be dependent\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 7762, __PRETTY_FUNCTION__)) | ||||
7762 | "Nested name specifier must be dependent")(((!NNS || NNS->isDependent()) && "Nested name specifier must be dependent" ) ? static_cast<void> (0) : __assert_fail ("(!NNS || NNS->isDependent()) && \"Nested name specifier must be dependent\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 7762, __PRETTY_FUNCTION__)); | ||||
7763 | |||||
7764 | llvm::FoldingSetNodeID ID; | ||||
7765 | DependentTemplateName::Profile(ID, NNS, Name); | ||||
7766 | |||||
7767 | void *InsertPos = nullptr; | ||||
7768 | DependentTemplateName *QTN = | ||||
7769 | DependentTemplateNames.FindNodeOrInsertPos(ID, InsertPos); | ||||
7770 | |||||
7771 | if (QTN) | ||||
7772 | return TemplateName(QTN); | ||||
7773 | |||||
7774 | NestedNameSpecifier *CanonNNS = getCanonicalNestedNameSpecifier(NNS); | ||||
7775 | if (CanonNNS == NNS) { | ||||
7776 | QTN = new (*this, alignof(DependentTemplateName)) | ||||
7777 | DependentTemplateName(NNS, Name); | ||||
7778 | } else { | ||||
7779 | TemplateName Canon = getDependentTemplateName(CanonNNS, Name); | ||||
7780 | QTN = new (*this, alignof(DependentTemplateName)) | ||||
7781 | DependentTemplateName(NNS, Name, Canon); | ||||
7782 | DependentTemplateName *CheckQTN = | ||||
7783 | DependentTemplateNames.FindNodeOrInsertPos(ID, InsertPos); | ||||
7784 | assert(!CheckQTN && "Dependent type name canonicalization broken")((!CheckQTN && "Dependent type name canonicalization broken" ) ? static_cast<void> (0) : __assert_fail ("!CheckQTN && \"Dependent type name canonicalization broken\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 7784, __PRETTY_FUNCTION__)); | ||||
7785 | (void)CheckQTN; | ||||
7786 | } | ||||
7787 | |||||
7788 | DependentTemplateNames.InsertNode(QTN, InsertPos); | ||||
7789 | return TemplateName(QTN); | ||||
7790 | } | ||||
7791 | |||||
7792 | /// Retrieve the template name that represents a dependent | ||||
7793 | /// template name such as \c MetaFun::template operator+. | ||||
7794 | TemplateName | ||||
7795 | ASTContext::getDependentTemplateName(NestedNameSpecifier *NNS, | ||||
7796 | OverloadedOperatorKind Operator) const { | ||||
7797 | assert((!NNS || NNS->isDependent()) &&(((!NNS || NNS->isDependent()) && "Nested name specifier must be dependent" ) ? static_cast<void> (0) : __assert_fail ("(!NNS || NNS->isDependent()) && \"Nested name specifier must be dependent\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 7798, __PRETTY_FUNCTION__)) | ||||
7798 | "Nested name specifier must be dependent")(((!NNS || NNS->isDependent()) && "Nested name specifier must be dependent" ) ? static_cast<void> (0) : __assert_fail ("(!NNS || NNS->isDependent()) && \"Nested name specifier must be dependent\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 7798, __PRETTY_FUNCTION__)); | ||||
7799 | |||||
7800 | llvm::FoldingSetNodeID ID; | ||||
7801 | DependentTemplateName::Profile(ID, NNS, Operator); | ||||
7802 | |||||
7803 | void *InsertPos = nullptr; | ||||
7804 | DependentTemplateName *QTN | ||||
7805 | = DependentTemplateNames.FindNodeOrInsertPos(ID, InsertPos); | ||||
7806 | |||||
7807 | if (QTN) | ||||
7808 | return TemplateName(QTN); | ||||
7809 | |||||
7810 | NestedNameSpecifier *CanonNNS = getCanonicalNestedNameSpecifier(NNS); | ||||
7811 | if (CanonNNS == NNS) { | ||||
7812 | QTN = new (*this, alignof(DependentTemplateName)) | ||||
7813 | DependentTemplateName(NNS, Operator); | ||||
7814 | } else { | ||||
7815 | TemplateName Canon = getDependentTemplateName(CanonNNS, Operator); | ||||
7816 | QTN = new (*this, alignof(DependentTemplateName)) | ||||
7817 | DependentTemplateName(NNS, Operator, Canon); | ||||
7818 | |||||
7819 | DependentTemplateName *CheckQTN | ||||
7820 | = DependentTemplateNames.FindNodeOrInsertPos(ID, InsertPos); | ||||
7821 | assert(!CheckQTN && "Dependent template name canonicalization broken")((!CheckQTN && "Dependent template name canonicalization broken" ) ? static_cast<void> (0) : __assert_fail ("!CheckQTN && \"Dependent template name canonicalization broken\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 7821, __PRETTY_FUNCTION__)); | ||||
7822 | (void)CheckQTN; | ||||
7823 | } | ||||
7824 | |||||
7825 | DependentTemplateNames.InsertNode(QTN, InsertPos); | ||||
7826 | return TemplateName(QTN); | ||||
7827 | } | ||||
7828 | |||||
7829 | TemplateName | ||||
7830 | ASTContext::getSubstTemplateTemplateParm(TemplateTemplateParmDecl *param, | ||||
7831 | TemplateName replacement) const { | ||||
7832 | llvm::FoldingSetNodeID ID; | ||||
7833 | SubstTemplateTemplateParmStorage::Profile(ID, param, replacement); | ||||
7834 | |||||
7835 | void *insertPos = nullptr; | ||||
7836 | SubstTemplateTemplateParmStorage *subst | ||||
7837 | = SubstTemplateTemplateParms.FindNodeOrInsertPos(ID, insertPos); | ||||
7838 | |||||
7839 | if (!subst) { | ||||
7840 | subst = new (*this) SubstTemplateTemplateParmStorage(param, replacement); | ||||
7841 | SubstTemplateTemplateParms.InsertNode(subst, insertPos); | ||||
7842 | } | ||||
7843 | |||||
7844 | return TemplateName(subst); | ||||
7845 | } | ||||
7846 | |||||
7847 | TemplateName | ||||
7848 | ASTContext::getSubstTemplateTemplateParmPack(TemplateTemplateParmDecl *Param, | ||||
7849 | const TemplateArgument &ArgPack) const { | ||||
7850 | auto &Self = const_cast<ASTContext &>(*this); | ||||
7851 | llvm::FoldingSetNodeID ID; | ||||
7852 | SubstTemplateTemplateParmPackStorage::Profile(ID, Self, Param, ArgPack); | ||||
7853 | |||||
7854 | void *InsertPos = nullptr; | ||||
7855 | SubstTemplateTemplateParmPackStorage *Subst | ||||
7856 | = SubstTemplateTemplateParmPacks.FindNodeOrInsertPos(ID, InsertPos); | ||||
7857 | |||||
7858 | if (!Subst) { | ||||
7859 | Subst = new (*this) SubstTemplateTemplateParmPackStorage(Param, | ||||
7860 | ArgPack.pack_size(), | ||||
7861 | ArgPack.pack_begin()); | ||||
7862 | SubstTemplateTemplateParmPacks.InsertNode(Subst, InsertPos); | ||||
7863 | } | ||||
7864 | |||||
7865 | return TemplateName(Subst); | ||||
7866 | } | ||||
7867 | |||||
7868 | /// getFromTargetType - Given one of the integer types provided by | ||||
7869 | /// TargetInfo, produce the corresponding type. The unsigned @p Type | ||||
7870 | /// is actually a value of type @c TargetInfo::IntType. | ||||
7871 | CanQualType ASTContext::getFromTargetType(unsigned Type) const { | ||||
7872 | switch (Type) { | ||||
7873 | case TargetInfo::NoInt: return {}; | ||||
7874 | case TargetInfo::SignedChar: return SignedCharTy; | ||||
7875 | case TargetInfo::UnsignedChar: return UnsignedCharTy; | ||||
7876 | case TargetInfo::SignedShort: return ShortTy; | ||||
7877 | case TargetInfo::UnsignedShort: return UnsignedShortTy; | ||||
7878 | case TargetInfo::SignedInt: return IntTy; | ||||
7879 | case TargetInfo::UnsignedInt: return UnsignedIntTy; | ||||
7880 | case TargetInfo::SignedLong: return LongTy; | ||||
7881 | case TargetInfo::UnsignedLong: return UnsignedLongTy; | ||||
7882 | case TargetInfo::SignedLongLong: return LongLongTy; | ||||
7883 | case TargetInfo::UnsignedLongLong: return UnsignedLongLongTy; | ||||
7884 | } | ||||
7885 | |||||
7886 | llvm_unreachable("Unhandled TargetInfo::IntType value")::llvm::llvm_unreachable_internal("Unhandled TargetInfo::IntType value" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 7886); | ||||
7887 | } | ||||
7888 | |||||
7889 | //===----------------------------------------------------------------------===// | ||||
7890 | // Type Predicates. | ||||
7891 | //===----------------------------------------------------------------------===// | ||||
7892 | |||||
7893 | /// getObjCGCAttr - Returns one of GCNone, Weak or Strong objc's | ||||
7894 | /// garbage collection attribute. | ||||
7895 | /// | ||||
7896 | Qualifiers::GC ASTContext::getObjCGCAttrKind(QualType Ty) const { | ||||
7897 | if (getLangOpts().getGC() == LangOptions::NonGC) | ||||
7898 | return Qualifiers::GCNone; | ||||
7899 | |||||
7900 | assert(getLangOpts().ObjC)((getLangOpts().ObjC) ? static_cast<void> (0) : __assert_fail ("getLangOpts().ObjC", "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 7900, __PRETTY_FUNCTION__)); | ||||
7901 | Qualifiers::GC GCAttrs = Ty.getObjCGCAttr(); | ||||
7902 | |||||
7903 | // Default behaviour under objective-C's gc is for ObjC pointers | ||||
7904 | // (or pointers to them) be treated as though they were declared | ||||
7905 | // as __strong. | ||||
7906 | if (GCAttrs == Qualifiers::GCNone) { | ||||
7907 | if (Ty->isObjCObjectPointerType() || Ty->isBlockPointerType()) | ||||
7908 | return Qualifiers::Strong; | ||||
7909 | else if (Ty->isPointerType()) | ||||
7910 | return getObjCGCAttrKind(Ty->castAs<PointerType>()->getPointeeType()); | ||||
7911 | } else { | ||||
7912 | // It's not valid to set GC attributes on anything that isn't a | ||||
7913 | // pointer. | ||||
7914 | #ifndef NDEBUG | ||||
7915 | QualType CT = Ty->getCanonicalTypeInternal(); | ||||
7916 | while (const auto *AT = dyn_cast<ArrayType>(CT)) | ||||
7917 | CT = AT->getElementType(); | ||||
7918 | assert(CT->isAnyPointerType() || CT->isBlockPointerType())((CT->isAnyPointerType() || CT->isBlockPointerType()) ? static_cast<void> (0) : __assert_fail ("CT->isAnyPointerType() || CT->isBlockPointerType()" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 7918, __PRETTY_FUNCTION__)); | ||||
7919 | #endif | ||||
7920 | } | ||||
7921 | return GCAttrs; | ||||
7922 | } | ||||
7923 | |||||
7924 | //===----------------------------------------------------------------------===// | ||||
7925 | // Type Compatibility Testing | ||||
7926 | //===----------------------------------------------------------------------===// | ||||
7927 | |||||
7928 | /// areCompatVectorTypes - Return true if the two specified vector types are | ||||
7929 | /// compatible. | ||||
7930 | static bool areCompatVectorTypes(const VectorType *LHS, | ||||
7931 | const VectorType *RHS) { | ||||
7932 | assert(LHS->isCanonicalUnqualified() && RHS->isCanonicalUnqualified())((LHS->isCanonicalUnqualified() && RHS->isCanonicalUnqualified ()) ? static_cast<void> (0) : __assert_fail ("LHS->isCanonicalUnqualified() && RHS->isCanonicalUnqualified()" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 7932, __PRETTY_FUNCTION__)); | ||||
7933 | return LHS->getElementType() == RHS->getElementType() && | ||||
7934 | LHS->getNumElements() == RHS->getNumElements(); | ||||
7935 | } | ||||
7936 | |||||
7937 | bool ASTContext::areCompatibleVectorTypes(QualType FirstVec, | ||||
7938 | QualType SecondVec) { | ||||
7939 | assert(FirstVec->isVectorType() && "FirstVec should be a vector type")((FirstVec->isVectorType() && "FirstVec should be a vector type" ) ? static_cast<void> (0) : __assert_fail ("FirstVec->isVectorType() && \"FirstVec should be a vector type\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 7939, __PRETTY_FUNCTION__)); | ||||
7940 | assert(SecondVec->isVectorType() && "SecondVec should be a vector type")((SecondVec->isVectorType() && "SecondVec should be a vector type" ) ? static_cast<void> (0) : __assert_fail ("SecondVec->isVectorType() && \"SecondVec should be a vector type\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 7940, __PRETTY_FUNCTION__)); | ||||
7941 | |||||
7942 | if (hasSameUnqualifiedType(FirstVec, SecondVec)) | ||||
7943 | return true; | ||||
7944 | |||||
7945 | // Treat Neon vector types and most AltiVec vector types as if they are the | ||||
7946 | // equivalent GCC vector types. | ||||
7947 | const auto *First = FirstVec->castAs<VectorType>(); | ||||
7948 | const auto *Second = SecondVec->castAs<VectorType>(); | ||||
7949 | if (First->getNumElements() == Second->getNumElements() && | ||||
7950 | hasSameType(First->getElementType(), Second->getElementType()) && | ||||
7951 | First->getVectorKind() != VectorType::AltiVecPixel && | ||||
7952 | First->getVectorKind() != VectorType::AltiVecBool && | ||||
7953 | Second->getVectorKind() != VectorType::AltiVecPixel && | ||||
7954 | Second->getVectorKind() != VectorType::AltiVecBool) | ||||
7955 | return true; | ||||
7956 | |||||
7957 | return false; | ||||
7958 | } | ||||
7959 | |||||
7960 | bool ASTContext::hasDirectOwnershipQualifier(QualType Ty) const { | ||||
7961 | while (true) { | ||||
7962 | // __strong id | ||||
7963 | if (const AttributedType *Attr = dyn_cast<AttributedType>(Ty)) { | ||||
7964 | if (Attr->getAttrKind() == attr::ObjCOwnership) | ||||
7965 | return true; | ||||
7966 | |||||
7967 | Ty = Attr->getModifiedType(); | ||||
7968 | |||||
7969 | // X *__strong (...) | ||||
7970 | } else if (const ParenType *Paren = dyn_cast<ParenType>(Ty)) { | ||||
7971 | Ty = Paren->getInnerType(); | ||||
7972 | |||||
7973 | // We do not want to look through typedefs, typeof(expr), | ||||
7974 | // typeof(type), or any other way that the type is somehow | ||||
7975 | // abstracted. | ||||
7976 | } else { | ||||
7977 | return false; | ||||
7978 | } | ||||
7979 | } | ||||
7980 | } | ||||
7981 | |||||
7982 | //===----------------------------------------------------------------------===// | ||||
7983 | // ObjCQualifiedIdTypesAreCompatible - Compatibility testing for qualified id's. | ||||
7984 | //===----------------------------------------------------------------------===// | ||||
7985 | |||||
7986 | /// ProtocolCompatibleWithProtocol - return 'true' if 'lProto' is in the | ||||
7987 | /// inheritance hierarchy of 'rProto'. | ||||
7988 | bool | ||||
7989 | ASTContext::ProtocolCompatibleWithProtocol(ObjCProtocolDecl *lProto, | ||||
7990 | ObjCProtocolDecl *rProto) const { | ||||
7991 | if (declaresSameEntity(lProto, rProto)) | ||||
7992 | return true; | ||||
7993 | for (auto *PI : rProto->protocols()) | ||||
7994 | if (ProtocolCompatibleWithProtocol(lProto, PI)) | ||||
7995 | return true; | ||||
7996 | return false; | ||||
7997 | } | ||||
7998 | |||||
7999 | /// ObjCQualifiedClassTypesAreCompatible - compare Class<pr,...> and | ||||
8000 | /// Class<pr1, ...>. | ||||
8001 | bool ASTContext::ObjCQualifiedClassTypesAreCompatible( | ||||
8002 | const ObjCObjectPointerType *lhs, const ObjCObjectPointerType *rhs) { | ||||
8003 | for (auto *lhsProto : lhs->quals()) { | ||||
8004 | bool match = false; | ||||
8005 | for (auto *rhsProto : rhs->quals()) { | ||||
8006 | if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto)) { | ||||
8007 | match = true; | ||||
8008 | break; | ||||
8009 | } | ||||
8010 | } | ||||
8011 | if (!match) | ||||
8012 | return false; | ||||
8013 | } | ||||
8014 | return true; | ||||
8015 | } | ||||
8016 | |||||
8017 | /// ObjCQualifiedIdTypesAreCompatible - We know that one of lhs/rhs is an | ||||
8018 | /// ObjCQualifiedIDType. | ||||
8019 | bool ASTContext::ObjCQualifiedIdTypesAreCompatible( | ||||
8020 | const ObjCObjectPointerType *lhs, const ObjCObjectPointerType *rhs, | ||||
8021 | bool compare) { | ||||
8022 | // Allow id<P..> and an 'id' or void* type in all cases. | ||||
8023 | if (lhs->isVoidPointerType() || | ||||
8024 | lhs->isObjCIdType() || lhs->isObjCClassType()) | ||||
8025 | return true; | ||||
8026 | else if (rhs->isVoidPointerType() || | ||||
8027 | rhs->isObjCIdType() || rhs->isObjCClassType()) | ||||
8028 | return true; | ||||
8029 | |||||
8030 | if (lhs->isObjCQualifiedIdType()) { | ||||
8031 | if (rhs->qual_empty()) { | ||||
8032 | // If the RHS is a unqualified interface pointer "NSString*", | ||||
8033 | // make sure we check the class hierarchy. | ||||
8034 | if (ObjCInterfaceDecl *rhsID = rhs->getInterfaceDecl()) { | ||||
8035 | for (auto *I : lhs->quals()) { | ||||
8036 | // when comparing an id<P> on lhs with a static type on rhs, | ||||
8037 | // see if static class implements all of id's protocols, directly or | ||||
8038 | // through its super class and categories. | ||||
8039 | if (!rhsID->ClassImplementsProtocol(I, true)) | ||||
8040 | return false; | ||||
8041 | } | ||||
8042 | } | ||||
8043 | // If there are no qualifiers and no interface, we have an 'id'. | ||||
8044 | return true; | ||||
8045 | } | ||||
8046 | // Both the right and left sides have qualifiers. | ||||
8047 | for (auto *lhsProto : lhs->quals()) { | ||||
8048 | bool match = false; | ||||
8049 | |||||
8050 | // when comparing an id<P> on lhs with a static type on rhs, | ||||
8051 | // see if static class implements all of id's protocols, directly or | ||||
8052 | // through its super class and categories. | ||||
8053 | for (auto *rhsProto : rhs->quals()) { | ||||
8054 | if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto) || | ||||
8055 | (compare && ProtocolCompatibleWithProtocol(rhsProto, lhsProto))) { | ||||
8056 | match = true; | ||||
8057 | break; | ||||
8058 | } | ||||
8059 | } | ||||
8060 | // If the RHS is a qualified interface pointer "NSString<P>*", | ||||
8061 | // make sure we check the class hierarchy. | ||||
8062 | if (ObjCInterfaceDecl *rhsID = rhs->getInterfaceDecl()) { | ||||
8063 | for (auto *I : lhs->quals()) { | ||||
8064 | // when comparing an id<P> on lhs with a static type on rhs, | ||||
8065 | // see if static class implements all of id's protocols, directly or | ||||
8066 | // through its super class and categories. | ||||
8067 | if (rhsID->ClassImplementsProtocol(I, true)) { | ||||
8068 | match = true; | ||||
8069 | break; | ||||
8070 | } | ||||
8071 | } | ||||
8072 | } | ||||
8073 | if (!match) | ||||
8074 | return false; | ||||
8075 | } | ||||
8076 | |||||
8077 | return true; | ||||
8078 | } | ||||
8079 | |||||
8080 | assert(rhs->isObjCQualifiedIdType() && "One of the LHS/RHS should be id<x>")((rhs->isObjCQualifiedIdType() && "One of the LHS/RHS should be id<x>" ) ? static_cast<void> (0) : __assert_fail ("rhs->isObjCQualifiedIdType() && \"One of the LHS/RHS should be id<x>\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 8080, __PRETTY_FUNCTION__)); | ||||
8081 | |||||
8082 | if (lhs->getInterfaceType()) { | ||||
8083 | // If both the right and left sides have qualifiers. | ||||
8084 | for (auto *lhsProto : lhs->quals()) { | ||||
8085 | bool match = false; | ||||
8086 | |||||
8087 | // when comparing an id<P> on rhs with a static type on lhs, | ||||
8088 | // see if static class implements all of id's protocols, directly or | ||||
8089 | // through its super class and categories. | ||||
8090 | // First, lhs protocols in the qualifier list must be found, direct | ||||
8091 | // or indirect in rhs's qualifier list or it is a mismatch. | ||||
8092 | for (auto *rhsProto : rhs->quals()) { | ||||
8093 | if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto) || | ||||
8094 | (compare && ProtocolCompatibleWithProtocol(rhsProto, lhsProto))) { | ||||
8095 | match = true; | ||||
8096 | break; | ||||
8097 | } | ||||
8098 | } | ||||
8099 | if (!match) | ||||
8100 | return false; | ||||
8101 | } | ||||
8102 | |||||
8103 | // Static class's protocols, or its super class or category protocols | ||||
8104 | // must be found, direct or indirect in rhs's qualifier list or it is a mismatch. | ||||
8105 | if (ObjCInterfaceDecl *lhsID = lhs->getInterfaceDecl()) { | ||||
8106 | llvm::SmallPtrSet<ObjCProtocolDecl *, 8> LHSInheritedProtocols; | ||||
8107 | CollectInheritedProtocols(lhsID, LHSInheritedProtocols); | ||||
8108 | // This is rather dubious but matches gcc's behavior. If lhs has | ||||
8109 | // no type qualifier and its class has no static protocol(s) | ||||
8110 | // assume that it is mismatch. | ||||
8111 | if (LHSInheritedProtocols.empty() && lhs->qual_empty()) | ||||
8112 | return false; | ||||
8113 | for (auto *lhsProto : LHSInheritedProtocols) { | ||||
8114 | bool match = false; | ||||
8115 | for (auto *rhsProto : rhs->quals()) { | ||||
8116 | if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto) || | ||||
8117 | (compare && ProtocolCompatibleWithProtocol(rhsProto, lhsProto))) { | ||||
8118 | match = true; | ||||
8119 | break; | ||||
8120 | } | ||||
8121 | } | ||||
8122 | if (!match) | ||||
8123 | return false; | ||||
8124 | } | ||||
8125 | } | ||||
8126 | return true; | ||||
8127 | } | ||||
8128 | return false; | ||||
8129 | } | ||||
8130 | |||||
8131 | /// canAssignObjCInterfaces - Return true if the two interface types are | ||||
8132 | /// compatible for assignment from RHS to LHS. This handles validation of any | ||||
8133 | /// protocol qualifiers on the LHS or RHS. | ||||
8134 | bool ASTContext::canAssignObjCInterfaces(const ObjCObjectPointerType *LHSOPT, | ||||
8135 | const ObjCObjectPointerType *RHSOPT) { | ||||
8136 | const ObjCObjectType* LHS = LHSOPT->getObjectType(); | ||||
8137 | const ObjCObjectType* RHS = RHSOPT->getObjectType(); | ||||
8138 | |||||
8139 | // If either type represents the built-in 'id' or 'Class' types, return true. | ||||
8140 | if (LHS->isObjCUnqualifiedIdOrClass() || | ||||
8141 | RHS->isObjCUnqualifiedIdOrClass()) | ||||
8142 | return true; | ||||
8143 | |||||
8144 | // Function object that propagates a successful result or handles | ||||
8145 | // __kindof types. | ||||
8146 | auto finish = [&](bool succeeded) -> bool { | ||||
8147 | if (succeeded) | ||||
8148 | return true; | ||||
8149 | |||||
8150 | if (!RHS->isKindOfType()) | ||||
8151 | return false; | ||||
8152 | |||||
8153 | // Strip off __kindof and protocol qualifiers, then check whether | ||||
8154 | // we can assign the other way. | ||||
8155 | return canAssignObjCInterfaces(RHSOPT->stripObjCKindOfTypeAndQuals(*this), | ||||
8156 | LHSOPT->stripObjCKindOfTypeAndQuals(*this)); | ||||
8157 | }; | ||||
8158 | |||||
8159 | if (LHS->isObjCQualifiedId() || RHS->isObjCQualifiedId()) { | ||||
8160 | return finish(ObjCQualifiedIdTypesAreCompatible(LHSOPT, RHSOPT, false)); | ||||
8161 | } | ||||
8162 | |||||
8163 | if (LHS->isObjCQualifiedClass() && RHS->isObjCQualifiedClass()) { | ||||
8164 | return finish(ObjCQualifiedClassTypesAreCompatible(LHSOPT, RHSOPT)); | ||||
8165 | } | ||||
8166 | |||||
8167 | // If we have 2 user-defined types, fall into that path. | ||||
8168 | if (LHS->getInterface() && RHS->getInterface()) { | ||||
8169 | return finish(canAssignObjCInterfaces(LHS, RHS)); | ||||
8170 | } | ||||
8171 | |||||
8172 | return false; | ||||
8173 | } | ||||
8174 | |||||
8175 | /// canAssignObjCInterfacesInBlockPointer - This routine is specifically written | ||||
8176 | /// for providing type-safety for objective-c pointers used to pass/return | ||||
8177 | /// arguments in block literals. When passed as arguments, passing 'A*' where | ||||
8178 | /// 'id' is expected is not OK. Passing 'Sub *" where 'Super *" is expected is | ||||
8179 | /// not OK. For the return type, the opposite is not OK. | ||||
8180 | bool ASTContext::canAssignObjCInterfacesInBlockPointer( | ||||
8181 | const ObjCObjectPointerType *LHSOPT, | ||||
8182 | const ObjCObjectPointerType *RHSOPT, | ||||
8183 | bool BlockReturnType) { | ||||
8184 | |||||
8185 | // Function object that propagates a successful result or handles | ||||
8186 | // __kindof types. | ||||
8187 | auto finish = [&](bool succeeded) -> bool { | ||||
8188 | if (succeeded) | ||||
8189 | return true; | ||||
8190 | |||||
8191 | const ObjCObjectPointerType *Expected = BlockReturnType ? RHSOPT : LHSOPT; | ||||
8192 | if (!Expected->isKindOfType()) | ||||
8193 | return false; | ||||
8194 | |||||
8195 | // Strip off __kindof and protocol qualifiers, then check whether | ||||
8196 | // we can assign the other way. | ||||
8197 | return canAssignObjCInterfacesInBlockPointer( | ||||
8198 | RHSOPT->stripObjCKindOfTypeAndQuals(*this), | ||||
8199 | LHSOPT->stripObjCKindOfTypeAndQuals(*this), | ||||
8200 | BlockReturnType); | ||||
8201 | }; | ||||
8202 | |||||
8203 | if (RHSOPT->isObjCBuiltinType() || LHSOPT->isObjCIdType()) | ||||
8204 | return true; | ||||
8205 | |||||
8206 | if (LHSOPT->isObjCBuiltinType()) { | ||||
8207 | return finish(RHSOPT->isObjCBuiltinType() || | ||||
8208 | RHSOPT->isObjCQualifiedIdType()); | ||||
8209 | } | ||||
8210 | |||||
8211 | if (LHSOPT->isObjCQualifiedIdType() || RHSOPT->isObjCQualifiedIdType()) | ||||
8212 | return finish(ObjCQualifiedIdTypesAreCompatible( | ||||
8213 | (BlockReturnType ? LHSOPT : RHSOPT), | ||||
8214 | (BlockReturnType ? RHSOPT : LHSOPT), false)); | ||||
8215 | |||||
8216 | const ObjCInterfaceType* LHS = LHSOPT->getInterfaceType(); | ||||
8217 | const ObjCInterfaceType* RHS = RHSOPT->getInterfaceType(); | ||||
8218 | if (LHS && RHS) { // We have 2 user-defined types. | ||||
8219 | if (LHS != RHS) { | ||||
8220 | if (LHS->getDecl()->isSuperClassOf(RHS->getDecl())) | ||||
8221 | return finish(BlockReturnType); | ||||
8222 | if (RHS->getDecl()->isSuperClassOf(LHS->getDecl())) | ||||
8223 | return finish(!BlockReturnType); | ||||
8224 | } | ||||
8225 | else | ||||
8226 | return true; | ||||
8227 | } | ||||
8228 | return false; | ||||
8229 | } | ||||
8230 | |||||
8231 | /// Comparison routine for Objective-C protocols to be used with | ||||
8232 | /// llvm::array_pod_sort. | ||||
8233 | static int compareObjCProtocolsByName(ObjCProtocolDecl * const *lhs, | ||||
8234 | ObjCProtocolDecl * const *rhs) { | ||||
8235 | return (*lhs)->getName().compare((*rhs)->getName()); | ||||
8236 | } | ||||
8237 | |||||
8238 | /// getIntersectionOfProtocols - This routine finds the intersection of set | ||||
8239 | /// of protocols inherited from two distinct objective-c pointer objects with | ||||
8240 | /// the given common base. | ||||
8241 | /// It is used to build composite qualifier list of the composite type of | ||||
8242 | /// the conditional expression involving two objective-c pointer objects. | ||||
8243 | static | ||||
8244 | void getIntersectionOfProtocols(ASTContext &Context, | ||||
8245 | const ObjCInterfaceDecl *CommonBase, | ||||
8246 | const ObjCObjectPointerType *LHSOPT, | ||||
8247 | const ObjCObjectPointerType *RHSOPT, | ||||
8248 | SmallVectorImpl<ObjCProtocolDecl *> &IntersectionSet) { | ||||
8249 | |||||
8250 | const ObjCObjectType* LHS = LHSOPT->getObjectType(); | ||||
8251 | const ObjCObjectType* RHS = RHSOPT->getObjectType(); | ||||
8252 | assert(LHS->getInterface() && "LHS must have an interface base")((LHS->getInterface() && "LHS must have an interface base" ) ? static_cast<void> (0) : __assert_fail ("LHS->getInterface() && \"LHS must have an interface base\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 8252, __PRETTY_FUNCTION__)); | ||||
8253 | assert(RHS->getInterface() && "RHS must have an interface base")((RHS->getInterface() && "RHS must have an interface base" ) ? static_cast<void> (0) : __assert_fail ("RHS->getInterface() && \"RHS must have an interface base\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 8253, __PRETTY_FUNCTION__)); | ||||
8254 | |||||
8255 | // Add all of the protocols for the LHS. | ||||
8256 | llvm::SmallPtrSet<ObjCProtocolDecl *, 8> LHSProtocolSet; | ||||
8257 | |||||
8258 | // Start with the protocol qualifiers. | ||||
8259 | for (auto proto : LHS->quals()) { | ||||
8260 | Context.CollectInheritedProtocols(proto, LHSProtocolSet); | ||||
8261 | } | ||||
8262 | |||||
8263 | // Also add the protocols associated with the LHS interface. | ||||
8264 | Context.CollectInheritedProtocols(LHS->getInterface(), LHSProtocolSet); | ||||
8265 | |||||
8266 | // Add all of the protocols for the RHS. | ||||
8267 | llvm::SmallPtrSet<ObjCProtocolDecl *, 8> RHSProtocolSet; | ||||
8268 | |||||
8269 | // Start with the protocol qualifiers. | ||||
8270 | for (auto proto : RHS->quals()) { | ||||
8271 | Context.CollectInheritedProtocols(proto, RHSProtocolSet); | ||||
8272 | } | ||||
8273 | |||||
8274 | // Also add the protocols associated with the RHS interface. | ||||
8275 | Context.CollectInheritedProtocols(RHS->getInterface(), RHSProtocolSet); | ||||
8276 | |||||
8277 | // Compute the intersection of the collected protocol sets. | ||||
8278 | for (auto proto : LHSProtocolSet) { | ||||
8279 | if (RHSProtocolSet.count(proto)) | ||||
8280 | IntersectionSet.push_back(proto); | ||||
8281 | } | ||||
8282 | |||||
8283 | // Compute the set of protocols that is implied by either the common type or | ||||
8284 | // the protocols within the intersection. | ||||
8285 | llvm::SmallPtrSet<ObjCProtocolDecl *, 8> ImpliedProtocols; | ||||
8286 | Context.CollectInheritedProtocols(CommonBase, ImpliedProtocols); | ||||
8287 | |||||
8288 | // Remove any implied protocols from the list of inherited protocols. | ||||
8289 | if (!ImpliedProtocols.empty()) { | ||||
8290 | IntersectionSet.erase( | ||||
8291 | std::remove_if(IntersectionSet.begin(), | ||||
8292 | IntersectionSet.end(), | ||||
8293 | [&](ObjCProtocolDecl *proto) -> bool { | ||||
8294 | return ImpliedProtocols.count(proto) > 0; | ||||
8295 | }), | ||||
8296 | IntersectionSet.end()); | ||||
8297 | } | ||||
8298 | |||||
8299 | // Sort the remaining protocols by name. | ||||
8300 | llvm::array_pod_sort(IntersectionSet.begin(), IntersectionSet.end(), | ||||
8301 | compareObjCProtocolsByName); | ||||
8302 | } | ||||
8303 | |||||
8304 | /// Determine whether the first type is a subtype of the second. | ||||
8305 | static bool canAssignObjCObjectTypes(ASTContext &ctx, QualType lhs, | ||||
8306 | QualType rhs) { | ||||
8307 | // Common case: two object pointers. | ||||
8308 | const auto *lhsOPT = lhs->getAs<ObjCObjectPointerType>(); | ||||
8309 | const auto *rhsOPT = rhs->getAs<ObjCObjectPointerType>(); | ||||
8310 | if (lhsOPT && rhsOPT) | ||||
8311 | return ctx.canAssignObjCInterfaces(lhsOPT, rhsOPT); | ||||
8312 | |||||
8313 | // Two block pointers. | ||||
8314 | const auto *lhsBlock = lhs->getAs<BlockPointerType>(); | ||||
8315 | const auto *rhsBlock = rhs->getAs<BlockPointerType>(); | ||||
8316 | if (lhsBlock && rhsBlock) | ||||
8317 | return ctx.typesAreBlockPointerCompatible(lhs, rhs); | ||||
8318 | |||||
8319 | // If either is an unqualified 'id' and the other is a block, it's | ||||
8320 | // acceptable. | ||||
8321 | if ((lhsOPT && lhsOPT->isObjCIdType() && rhsBlock) || | ||||
8322 | (rhsOPT && rhsOPT->isObjCIdType() && lhsBlock)) | ||||
8323 | return true; | ||||
8324 | |||||
8325 | return false; | ||||
8326 | } | ||||
8327 | |||||
8328 | // Check that the given Objective-C type argument lists are equivalent. | ||||
8329 | static bool sameObjCTypeArgs(ASTContext &ctx, | ||||
8330 | const ObjCInterfaceDecl *iface, | ||||
8331 | ArrayRef<QualType> lhsArgs, | ||||
8332 | ArrayRef<QualType> rhsArgs, | ||||
8333 | bool stripKindOf) { | ||||
8334 | if (lhsArgs.size() != rhsArgs.size()) | ||||
8335 | return false; | ||||
8336 | |||||
8337 | ObjCTypeParamList *typeParams = iface->getTypeParamList(); | ||||
8338 | for (unsigned i = 0, n = lhsArgs.size(); i != n; ++i) { | ||||
8339 | if (ctx.hasSameType(lhsArgs[i], rhsArgs[i])) | ||||
8340 | continue; | ||||
8341 | |||||
8342 | switch (typeParams->begin()[i]->getVariance()) { | ||||
8343 | case ObjCTypeParamVariance::Invariant: | ||||
8344 | if (!stripKindOf || | ||||
8345 | !ctx.hasSameType(lhsArgs[i].stripObjCKindOfType(ctx), | ||||
8346 | rhsArgs[i].stripObjCKindOfType(ctx))) { | ||||
8347 | return false; | ||||
8348 | } | ||||
8349 | break; | ||||
8350 | |||||
8351 | case ObjCTypeParamVariance::Covariant: | ||||
8352 | if (!canAssignObjCObjectTypes(ctx, lhsArgs[i], rhsArgs[i])) | ||||
8353 | return false; | ||||
8354 | break; | ||||
8355 | |||||
8356 | case ObjCTypeParamVariance::Contravariant: | ||||
8357 | if (!canAssignObjCObjectTypes(ctx, rhsArgs[i], lhsArgs[i])) | ||||
8358 | return false; | ||||
8359 | break; | ||||
8360 | } | ||||
8361 | } | ||||
8362 | |||||
8363 | return true; | ||||
8364 | } | ||||
8365 | |||||
8366 | QualType ASTContext::areCommonBaseCompatible( | ||||
8367 | const ObjCObjectPointerType *Lptr, | ||||
8368 | const ObjCObjectPointerType *Rptr) { | ||||
8369 | const ObjCObjectType *LHS = Lptr->getObjectType(); | ||||
8370 | const ObjCObjectType *RHS = Rptr->getObjectType(); | ||||
8371 | const ObjCInterfaceDecl* LDecl = LHS->getInterface(); | ||||
8372 | const ObjCInterfaceDecl* RDecl = RHS->getInterface(); | ||||
8373 | |||||
8374 | if (!LDecl || !RDecl) | ||||
8375 | return {}; | ||||
8376 | |||||
8377 | // When either LHS or RHS is a kindof type, we should return a kindof type. | ||||
8378 | // For example, for common base of kindof(ASub1) and kindof(ASub2), we return | ||||
8379 | // kindof(A). | ||||
8380 | bool anyKindOf = LHS->isKindOfType() || RHS->isKindOfType(); | ||||
8381 | |||||
8382 | // Follow the left-hand side up the class hierarchy until we either hit a | ||||
8383 | // root or find the RHS. Record the ancestors in case we don't find it. | ||||
8384 | llvm::SmallDenseMap<const ObjCInterfaceDecl *, const ObjCObjectType *, 4> | ||||
8385 | LHSAncestors; | ||||
8386 | while (true) { | ||||
8387 | // Record this ancestor. We'll need this if the common type isn't in the | ||||
8388 | // path from the LHS to the root. | ||||
8389 | LHSAncestors[LHS->getInterface()->getCanonicalDecl()] = LHS; | ||||
8390 | |||||
8391 | if (declaresSameEntity(LHS->getInterface(), RDecl)) { | ||||
8392 | // Get the type arguments. | ||||
8393 | ArrayRef<QualType> LHSTypeArgs = LHS->getTypeArgsAsWritten(); | ||||
8394 | bool anyChanges = false; | ||||
8395 | if (LHS->isSpecialized() && RHS->isSpecialized()) { | ||||
8396 | // Both have type arguments, compare them. | ||||
8397 | if (!sameObjCTypeArgs(*this, LHS->getInterface(), | ||||
8398 | LHS->getTypeArgs(), RHS->getTypeArgs(), | ||||
8399 | /*stripKindOf=*/true)) | ||||
8400 | return {}; | ||||
8401 | } else if (LHS->isSpecialized() != RHS->isSpecialized()) { | ||||
8402 | // If only one has type arguments, the result will not have type | ||||
8403 | // arguments. | ||||
8404 | LHSTypeArgs = {}; | ||||
8405 | anyChanges = true; | ||||
8406 | } | ||||
8407 | |||||
8408 | // Compute the intersection of protocols. | ||||
8409 | SmallVector<ObjCProtocolDecl *, 8> Protocols; | ||||
8410 | getIntersectionOfProtocols(*this, LHS->getInterface(), Lptr, Rptr, | ||||
8411 | Protocols); | ||||
8412 | if (!Protocols.empty()) | ||||
8413 | anyChanges = true; | ||||
8414 | |||||
8415 | // If anything in the LHS will have changed, build a new result type. | ||||
8416 | // If we need to return a kindof type but LHS is not a kindof type, we | ||||
8417 | // build a new result type. | ||||
8418 | if (anyChanges || LHS->isKindOfType() != anyKindOf) { | ||||
8419 | QualType Result = getObjCInterfaceType(LHS->getInterface()); | ||||
8420 | Result = getObjCObjectType(Result, LHSTypeArgs, Protocols, | ||||
8421 | anyKindOf || LHS->isKindOfType()); | ||||
8422 | return getObjCObjectPointerType(Result); | ||||
8423 | } | ||||
8424 | |||||
8425 | return getObjCObjectPointerType(QualType(LHS, 0)); | ||||
8426 | } | ||||
8427 | |||||
8428 | // Find the superclass. | ||||
8429 | QualType LHSSuperType = LHS->getSuperClassType(); | ||||
8430 | if (LHSSuperType.isNull()) | ||||
8431 | break; | ||||
8432 | |||||
8433 | LHS = LHSSuperType->castAs<ObjCObjectType>(); | ||||
8434 | } | ||||
8435 | |||||
8436 | // We didn't find anything by following the LHS to its root; now check | ||||
8437 | // the RHS against the cached set of ancestors. | ||||
8438 | while (true) { | ||||
8439 | auto KnownLHS = LHSAncestors.find(RHS->getInterface()->getCanonicalDecl()); | ||||
8440 | if (KnownLHS != LHSAncestors.end()) { | ||||
8441 | LHS = KnownLHS->second; | ||||
8442 | |||||
8443 | // Get the type arguments. | ||||
8444 | ArrayRef<QualType> RHSTypeArgs = RHS->getTypeArgsAsWritten(); | ||||
8445 | bool anyChanges = false; | ||||
8446 | if (LHS->isSpecialized() && RHS->isSpecialized()) { | ||||
8447 | // Both have type arguments, compare them. | ||||
8448 | if (!sameObjCTypeArgs(*this, LHS->getInterface(), | ||||
8449 | LHS->getTypeArgs(), RHS->getTypeArgs(), | ||||
8450 | /*stripKindOf=*/true)) | ||||
8451 | return {}; | ||||
8452 | } else if (LHS->isSpecialized() != RHS->isSpecialized()) { | ||||
8453 | // If only one has type arguments, the result will not have type | ||||
8454 | // arguments. | ||||
8455 | RHSTypeArgs = {}; | ||||
8456 | anyChanges = true; | ||||
8457 | } | ||||
8458 | |||||
8459 | // Compute the intersection of protocols. | ||||
8460 | SmallVector<ObjCProtocolDecl *, 8> Protocols; | ||||
8461 | getIntersectionOfProtocols(*this, RHS->getInterface(), Lptr, Rptr, | ||||
8462 | Protocols); | ||||
8463 | if (!Protocols.empty()) | ||||
8464 | anyChanges = true; | ||||
8465 | |||||
8466 | // If we need to return a kindof type but RHS is not a kindof type, we | ||||
8467 | // build a new result type. | ||||
8468 | if (anyChanges || RHS->isKindOfType() != anyKindOf) { | ||||
8469 | QualType Result = getObjCInterfaceType(RHS->getInterface()); | ||||
8470 | Result = getObjCObjectType(Result, RHSTypeArgs, Protocols, | ||||
8471 | anyKindOf || RHS->isKindOfType()); | ||||
8472 | return getObjCObjectPointerType(Result); | ||||
8473 | } | ||||
8474 | |||||
8475 | return getObjCObjectPointerType(QualType(RHS, 0)); | ||||
8476 | } | ||||
8477 | |||||
8478 | // Find the superclass of the RHS. | ||||
8479 | QualType RHSSuperType = RHS->getSuperClassType(); | ||||
8480 | if (RHSSuperType.isNull()) | ||||
8481 | break; | ||||
8482 | |||||
8483 | RHS = RHSSuperType->castAs<ObjCObjectType>(); | ||||
8484 | } | ||||
8485 | |||||
8486 | return {}; | ||||
8487 | } | ||||
8488 | |||||
8489 | bool ASTContext::canAssignObjCInterfaces(const ObjCObjectType *LHS, | ||||
8490 | const ObjCObjectType *RHS) { | ||||
8491 | assert(LHS->getInterface() && "LHS is not an interface type")((LHS->getInterface() && "LHS is not an interface type" ) ? static_cast<void> (0) : __assert_fail ("LHS->getInterface() && \"LHS is not an interface type\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 8491, __PRETTY_FUNCTION__)); | ||||
8492 | assert(RHS->getInterface() && "RHS is not an interface type")((RHS->getInterface() && "RHS is not an interface type" ) ? static_cast<void> (0) : __assert_fail ("RHS->getInterface() && \"RHS is not an interface type\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 8492, __PRETTY_FUNCTION__)); | ||||
8493 | |||||
8494 | // Verify that the base decls are compatible: the RHS must be a subclass of | ||||
8495 | // the LHS. | ||||
8496 | ObjCInterfaceDecl *LHSInterface = LHS->getInterface(); | ||||
8497 | bool IsSuperClass = LHSInterface->isSuperClassOf(RHS->getInterface()); | ||||
8498 | if (!IsSuperClass) | ||||
8499 | return false; | ||||
8500 | |||||
8501 | // If the LHS has protocol qualifiers, determine whether all of them are | ||||
8502 | // satisfied by the RHS (i.e., the RHS has a superset of the protocols in the | ||||
8503 | // LHS). | ||||
8504 | if (LHS->getNumProtocols() > 0) { | ||||
8505 | // OK if conversion of LHS to SuperClass results in narrowing of types | ||||
8506 | // ; i.e., SuperClass may implement at least one of the protocols | ||||
8507 | // in LHS's protocol list. Example, SuperObj<P1> = lhs<P1,P2> is ok. | ||||
8508 | // But not SuperObj<P1,P2,P3> = lhs<P1,P2>. | ||||
8509 | llvm::SmallPtrSet<ObjCProtocolDecl *, 8> SuperClassInheritedProtocols; | ||||
8510 | CollectInheritedProtocols(RHS->getInterface(), SuperClassInheritedProtocols); | ||||
8511 | // Also, if RHS has explicit quelifiers, include them for comparing with LHS's | ||||
8512 | // qualifiers. | ||||
8513 | for (auto *RHSPI : RHS->quals()) | ||||
8514 | CollectInheritedProtocols(RHSPI, SuperClassInheritedProtocols); | ||||
8515 | // If there is no protocols associated with RHS, it is not a match. | ||||
8516 | if (SuperClassInheritedProtocols.empty()) | ||||
8517 | return false; | ||||
8518 | |||||
8519 | for (const auto *LHSProto : LHS->quals()) { | ||||
8520 | bool SuperImplementsProtocol = false; | ||||
8521 | for (auto *SuperClassProto : SuperClassInheritedProtocols) | ||||
8522 | if (SuperClassProto->lookupProtocolNamed(LHSProto->getIdentifier())) { | ||||
8523 | SuperImplementsProtocol = true; | ||||
8524 | break; | ||||
8525 | } | ||||
8526 | if (!SuperImplementsProtocol) | ||||
8527 | return false; | ||||
8528 | } | ||||
8529 | } | ||||
8530 | |||||
8531 | // If the LHS is specialized, we may need to check type arguments. | ||||
8532 | if (LHS->isSpecialized()) { | ||||
8533 | // Follow the superclass chain until we've matched the LHS class in the | ||||
8534 | // hierarchy. This substitutes type arguments through. | ||||
8535 | const ObjCObjectType *RHSSuper = RHS; | ||||
8536 | while (!declaresSameEntity(RHSSuper->getInterface(), LHSInterface)) | ||||
8537 | RHSSuper = RHSSuper->getSuperClassType()->castAs<ObjCObjectType>(); | ||||
8538 | |||||
8539 | // If the RHS is specializd, compare type arguments. | ||||
8540 | if (RHSSuper->isSpecialized() && | ||||
8541 | !sameObjCTypeArgs(*this, LHS->getInterface(), | ||||
8542 | LHS->getTypeArgs(), RHSSuper->getTypeArgs(), | ||||
8543 | /*stripKindOf=*/true)) { | ||||
8544 | return false; | ||||
8545 | } | ||||
8546 | } | ||||
8547 | |||||
8548 | return true; | ||||
8549 | } | ||||
8550 | |||||
8551 | bool ASTContext::areComparableObjCPointerTypes(QualType LHS, QualType RHS) { | ||||
8552 | // get the "pointed to" types | ||||
8553 | const auto *LHSOPT = LHS->getAs<ObjCObjectPointerType>(); | ||||
8554 | const auto *RHSOPT = RHS->getAs<ObjCObjectPointerType>(); | ||||
8555 | |||||
8556 | if (!LHSOPT || !RHSOPT) | ||||
8557 | return false; | ||||
8558 | |||||
8559 | return canAssignObjCInterfaces(LHSOPT, RHSOPT) || | ||||
8560 | canAssignObjCInterfaces(RHSOPT, LHSOPT); | ||||
8561 | } | ||||
8562 | |||||
8563 | bool ASTContext::canBindObjCObjectType(QualType To, QualType From) { | ||||
8564 | return canAssignObjCInterfaces( | ||||
8565 | getObjCObjectPointerType(To)->getAs<ObjCObjectPointerType>(), | ||||
8566 | getObjCObjectPointerType(From)->getAs<ObjCObjectPointerType>()); | ||||
8567 | } | ||||
8568 | |||||
8569 | /// typesAreCompatible - C99 6.7.3p9: For two qualified types to be compatible, | ||||
8570 | /// both shall have the identically qualified version of a compatible type. | ||||
8571 | /// C99 6.2.7p1: Two types have compatible types if their types are the | ||||
8572 | /// same. See 6.7.[2,3,5] for additional rules. | ||||
8573 | bool ASTContext::typesAreCompatible(QualType LHS, QualType RHS, | ||||
8574 | bool CompareUnqualified) { | ||||
8575 | if (getLangOpts().CPlusPlus) | ||||
8576 | return hasSameType(LHS, RHS); | ||||
8577 | |||||
8578 | return !mergeTypes(LHS, RHS, false, CompareUnqualified).isNull(); | ||||
8579 | } | ||||
8580 | |||||
8581 | bool ASTContext::propertyTypesAreCompatible(QualType LHS, QualType RHS) { | ||||
8582 | return typesAreCompatible(LHS, RHS); | ||||
8583 | } | ||||
8584 | |||||
8585 | bool ASTContext::typesAreBlockPointerCompatible(QualType LHS, QualType RHS) { | ||||
8586 | return !mergeTypes(LHS, RHS, true).isNull(); | ||||
8587 | } | ||||
8588 | |||||
8589 | /// mergeTransparentUnionType - if T is a transparent union type and a member | ||||
8590 | /// of T is compatible with SubType, return the merged type, else return | ||||
8591 | /// QualType() | ||||
8592 | QualType ASTContext::mergeTransparentUnionType(QualType T, QualType SubType, | ||||
8593 | bool OfBlockPointer, | ||||
8594 | bool Unqualified) { | ||||
8595 | if (const RecordType *UT = T->getAsUnionType()) { | ||||
8596 | RecordDecl *UD = UT->getDecl(); | ||||
8597 | if (UD->hasAttr<TransparentUnionAttr>()) { | ||||
8598 | for (const auto *I : UD->fields()) { | ||||
8599 | QualType ET = I->getType().getUnqualifiedType(); | ||||
8600 | QualType MT = mergeTypes(ET, SubType, OfBlockPointer, Unqualified); | ||||
8601 | if (!MT.isNull()) | ||||
8602 | return MT; | ||||
8603 | } | ||||
8604 | } | ||||
8605 | } | ||||
8606 | |||||
8607 | return {}; | ||||
8608 | } | ||||
8609 | |||||
8610 | /// mergeFunctionParameterTypes - merge two types which appear as function | ||||
8611 | /// parameter types | ||||
8612 | QualType ASTContext::mergeFunctionParameterTypes(QualType lhs, QualType rhs, | ||||
8613 | bool OfBlockPointer, | ||||
8614 | bool Unqualified) { | ||||
8615 | // GNU extension: two types are compatible if they appear as a function | ||||
8616 | // argument, one of the types is a transparent union type and the other | ||||
8617 | // type is compatible with a union member | ||||
8618 | QualType lmerge = mergeTransparentUnionType(lhs, rhs, OfBlockPointer, | ||||
8619 | Unqualified); | ||||
8620 | if (!lmerge.isNull()) | ||||
8621 | return lmerge; | ||||
8622 | |||||
8623 | QualType rmerge = mergeTransparentUnionType(rhs, lhs, OfBlockPointer, | ||||
8624 | Unqualified); | ||||
8625 | if (!rmerge.isNull()) | ||||
8626 | return rmerge; | ||||
8627 | |||||
8628 | return mergeTypes(lhs, rhs, OfBlockPointer, Unqualified); | ||||
8629 | } | ||||
8630 | |||||
8631 | QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs, | ||||
8632 | bool OfBlockPointer, | ||||
8633 | bool Unqualified) { | ||||
8634 | const auto *lbase = lhs->getAs<FunctionType>(); | ||||
8635 | const auto *rbase = rhs->getAs<FunctionType>(); | ||||
8636 | const auto *lproto = dyn_cast<FunctionProtoType>(lbase); | ||||
8637 | const auto *rproto = dyn_cast<FunctionProtoType>(rbase); | ||||
8638 | bool allLTypes = true; | ||||
8639 | bool allRTypes = true; | ||||
8640 | |||||
8641 | // Check return type | ||||
8642 | QualType retType; | ||||
8643 | if (OfBlockPointer) { | ||||
8644 | QualType RHS = rbase->getReturnType(); | ||||
8645 | QualType LHS = lbase->getReturnType(); | ||||
8646 | bool UnqualifiedResult = Unqualified; | ||||
8647 | if (!UnqualifiedResult) | ||||
8648 | UnqualifiedResult = (!RHS.hasQualifiers() && LHS.hasQualifiers()); | ||||
8649 | retType = mergeTypes(LHS, RHS, true, UnqualifiedResult, true); | ||||
8650 | } | ||||
8651 | else | ||||
8652 | retType = mergeTypes(lbase->getReturnType(), rbase->getReturnType(), false, | ||||
8653 | Unqualified); | ||||
8654 | if (retType.isNull()) | ||||
8655 | return {}; | ||||
8656 | |||||
8657 | if (Unqualified) | ||||
8658 | retType = retType.getUnqualifiedType(); | ||||
8659 | |||||
8660 | CanQualType LRetType = getCanonicalType(lbase->getReturnType()); | ||||
8661 | CanQualType RRetType = getCanonicalType(rbase->getReturnType()); | ||||
8662 | if (Unqualified) { | ||||
8663 | LRetType = LRetType.getUnqualifiedType(); | ||||
8664 | RRetType = RRetType.getUnqualifiedType(); | ||||
8665 | } | ||||
8666 | |||||
8667 | if (getCanonicalType(retType) != LRetType) | ||||
8668 | allLTypes = false; | ||||
8669 | if (getCanonicalType(retType) != RRetType) | ||||
8670 | allRTypes = false; | ||||
8671 | |||||
8672 | // FIXME: double check this | ||||
8673 | // FIXME: should we error if lbase->getRegParmAttr() != 0 && | ||||
8674 | // rbase->getRegParmAttr() != 0 && | ||||
8675 | // lbase->getRegParmAttr() != rbase->getRegParmAttr()? | ||||
8676 | FunctionType::ExtInfo lbaseInfo = lbase->getExtInfo(); | ||||
8677 | FunctionType::ExtInfo rbaseInfo = rbase->getExtInfo(); | ||||
8678 | |||||
8679 | // Compatible functions must have compatible calling conventions | ||||
8680 | if (lbaseInfo.getCC() != rbaseInfo.getCC()) | ||||
8681 | return {}; | ||||
8682 | |||||
8683 | // Regparm is part of the calling convention. | ||||
8684 | if (lbaseInfo.getHasRegParm() != rbaseInfo.getHasRegParm()) | ||||
8685 | return {}; | ||||
8686 | if (lbaseInfo.getRegParm() != rbaseInfo.getRegParm()) | ||||
8687 | return {}; | ||||
8688 | |||||
8689 | if (lbaseInfo.getProducesResult() != rbaseInfo.getProducesResult()) | ||||
8690 | return {}; | ||||
8691 | if (lbaseInfo.getNoCallerSavedRegs() != rbaseInfo.getNoCallerSavedRegs()) | ||||
8692 | return {}; | ||||
8693 | if (lbaseInfo.getNoCfCheck() != rbaseInfo.getNoCfCheck()) | ||||
8694 | return {}; | ||||
8695 | |||||
8696 | // FIXME: some uses, e.g. conditional exprs, really want this to be 'both'. | ||||
8697 | bool NoReturn = lbaseInfo.getNoReturn() || rbaseInfo.getNoReturn(); | ||||
8698 | |||||
8699 | if (lbaseInfo.getNoReturn() != NoReturn) | ||||
8700 | allLTypes = false; | ||||
8701 | if (rbaseInfo.getNoReturn() != NoReturn) | ||||
8702 | allRTypes = false; | ||||
8703 | |||||
8704 | FunctionType::ExtInfo einfo = lbaseInfo.withNoReturn(NoReturn); | ||||
8705 | |||||
8706 | if (lproto && rproto) { // two C99 style function prototypes | ||||
8707 | assert(!lproto->hasExceptionSpec() && !rproto->hasExceptionSpec() &&((!lproto->hasExceptionSpec() && !rproto->hasExceptionSpec () && "C++ shouldn't be here") ? static_cast<void> (0) : __assert_fail ("!lproto->hasExceptionSpec() && !rproto->hasExceptionSpec() && \"C++ shouldn't be here\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 8708, __PRETTY_FUNCTION__)) | ||||
8708 | "C++ shouldn't be here")((!lproto->hasExceptionSpec() && !rproto->hasExceptionSpec () && "C++ shouldn't be here") ? static_cast<void> (0) : __assert_fail ("!lproto->hasExceptionSpec() && !rproto->hasExceptionSpec() && \"C++ shouldn't be here\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 8708, __PRETTY_FUNCTION__)); | ||||
8709 | // Compatible functions must have the same number of parameters | ||||
8710 | if (lproto->getNumParams() != rproto->getNumParams()) | ||||
8711 | return {}; | ||||
8712 | |||||
8713 | // Variadic and non-variadic functions aren't compatible | ||||
8714 | if (lproto->isVariadic() != rproto->isVariadic()) | ||||
8715 | return {}; | ||||
8716 | |||||
8717 | if (lproto->getMethodQuals() != rproto->getMethodQuals()) | ||||
8718 | return {}; | ||||
8719 | |||||
8720 | SmallVector<FunctionProtoType::ExtParameterInfo, 4> newParamInfos; | ||||
8721 | bool canUseLeft, canUseRight; | ||||
8722 | if (!mergeExtParameterInfo(lproto, rproto, canUseLeft, canUseRight, | ||||
8723 | newParamInfos)) | ||||
8724 | return {}; | ||||
8725 | |||||
8726 | if (!canUseLeft) | ||||
8727 | allLTypes = false; | ||||
8728 | if (!canUseRight) | ||||
8729 | allRTypes = false; | ||||
8730 | |||||
8731 | // Check parameter type compatibility | ||||
8732 | SmallVector<QualType, 10> types; | ||||
8733 | for (unsigned i = 0, n = lproto->getNumParams(); i < n; i++) { | ||||
8734 | QualType lParamType = lproto->getParamType(i).getUnqualifiedType(); | ||||
8735 | QualType rParamType = rproto->getParamType(i).getUnqualifiedType(); | ||||
8736 | QualType paramType = mergeFunctionParameterTypes( | ||||
8737 | lParamType, rParamType, OfBlockPointer, Unqualified); | ||||
8738 | if (paramType.isNull()) | ||||
8739 | return {}; | ||||
8740 | |||||
8741 | if (Unqualified) | ||||
8742 | paramType = paramType.getUnqualifiedType(); | ||||
8743 | |||||
8744 | types.push_back(paramType); | ||||
8745 | if (Unqualified) { | ||||
8746 | lParamType = lParamType.getUnqualifiedType(); | ||||
8747 | rParamType = rParamType.getUnqualifiedType(); | ||||
8748 | } | ||||
8749 | |||||
8750 | if (getCanonicalType(paramType) != getCanonicalType(lParamType)) | ||||
8751 | allLTypes = false; | ||||
8752 | if (getCanonicalType(paramType) != getCanonicalType(rParamType)) | ||||
8753 | allRTypes = false; | ||||
8754 | } | ||||
8755 | |||||
8756 | if (allLTypes) return lhs; | ||||
8757 | if (allRTypes) return rhs; | ||||
8758 | |||||
8759 | FunctionProtoType::ExtProtoInfo EPI = lproto->getExtProtoInfo(); | ||||
8760 | EPI.ExtInfo = einfo; | ||||
8761 | EPI.ExtParameterInfos = | ||||
8762 | newParamInfos.empty() ? nullptr : newParamInfos.data(); | ||||
8763 | return getFunctionType(retType, types, EPI); | ||||
8764 | } | ||||
8765 | |||||
8766 | if (lproto) allRTypes = false; | ||||
8767 | if (rproto) allLTypes = false; | ||||
8768 | |||||
8769 | const FunctionProtoType *proto = lproto ? lproto : rproto; | ||||
8770 | if (proto) { | ||||
8771 | assert(!proto->hasExceptionSpec() && "C++ shouldn't be here")((!proto->hasExceptionSpec() && "C++ shouldn't be here" ) ? static_cast<void> (0) : __assert_fail ("!proto->hasExceptionSpec() && \"C++ shouldn't be here\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 8771, __PRETTY_FUNCTION__)); | ||||
8772 | if (proto->isVariadic()) | ||||
8773 | return {}; | ||||
8774 | // Check that the types are compatible with the types that | ||||
8775 | // would result from default argument promotions (C99 6.7.5.3p15). | ||||
8776 | // The only types actually affected are promotable integer | ||||
8777 | // types and floats, which would be passed as a different | ||||
8778 | // type depending on whether the prototype is visible. | ||||
8779 | for (unsigned i = 0, n = proto->getNumParams(); i < n; ++i) { | ||||
8780 | QualType paramTy = proto->getParamType(i); | ||||
8781 | |||||
8782 | // Look at the converted type of enum types, since that is the type used | ||||
8783 | // to pass enum values. | ||||
8784 | if (const auto *Enum = paramTy->getAs<EnumType>()) { | ||||
8785 | paramTy = Enum->getDecl()->getIntegerType(); | ||||
8786 | if (paramTy.isNull()) | ||||
8787 | return {}; | ||||
8788 | } | ||||
8789 | |||||
8790 | if (paramTy->isPromotableIntegerType() || | ||||
8791 | getCanonicalType(paramTy).getUnqualifiedType() == FloatTy) | ||||
8792 | return {}; | ||||
8793 | } | ||||
8794 | |||||
8795 | if (allLTypes) return lhs; | ||||
8796 | if (allRTypes) return rhs; | ||||
8797 | |||||
8798 | FunctionProtoType::ExtProtoInfo EPI = proto->getExtProtoInfo(); | ||||
8799 | EPI.ExtInfo = einfo; | ||||
8800 | return getFunctionType(retType, proto->getParamTypes(), EPI); | ||||
8801 | } | ||||
8802 | |||||
8803 | if (allLTypes) return lhs; | ||||
8804 | if (allRTypes) return rhs; | ||||
8805 | return getFunctionNoProtoType(retType, einfo); | ||||
8806 | } | ||||
8807 | |||||
8808 | /// Given that we have an enum type and a non-enum type, try to merge them. | ||||
8809 | static QualType mergeEnumWithInteger(ASTContext &Context, const EnumType *ET, | ||||
8810 | QualType other, bool isBlockReturnType) { | ||||
8811 | // C99 6.7.2.2p4: Each enumerated type shall be compatible with char, | ||||
8812 | // a signed integer type, or an unsigned integer type. | ||||
8813 | // Compatibility is based on the underlying type, not the promotion | ||||
8814 | // type. | ||||
8815 | QualType underlyingType = ET->getDecl()->getIntegerType(); | ||||
8816 | if (underlyingType.isNull()) | ||||
8817 | return {}; | ||||
8818 | if (Context.hasSameType(underlyingType, other)) | ||||
8819 | return other; | ||||
8820 | |||||
8821 | // In block return types, we're more permissive and accept any | ||||
8822 | // integral type of the same size. | ||||
8823 | if (isBlockReturnType && other->isIntegerType() && | ||||
8824 | Context.getTypeSize(underlyingType) == Context.getTypeSize(other)) | ||||
8825 | return other; | ||||
8826 | |||||
8827 | return {}; | ||||
8828 | } | ||||
8829 | |||||
8830 | QualType ASTContext::mergeTypes(QualType LHS, QualType RHS, | ||||
8831 | bool OfBlockPointer, | ||||
8832 | bool Unqualified, bool BlockReturnType) { | ||||
8833 | // C++ [expr]: If an expression initially has the type "reference to T", the | ||||
8834 | // type is adjusted to "T" prior to any further analysis, the expression | ||||
8835 | // designates the object or function denoted by the reference, and the | ||||
8836 | // expression is an lvalue unless the reference is an rvalue reference and | ||||
8837 | // the expression is a function call (possibly inside parentheses). | ||||
8838 | assert(!LHS->getAs<ReferenceType>() && "LHS is a reference type?")((!LHS->getAs<ReferenceType>() && "LHS is a reference type?" ) ? static_cast<void> (0) : __assert_fail ("!LHS->getAs<ReferenceType>() && \"LHS is a reference type?\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 8838, __PRETTY_FUNCTION__)); | ||||
8839 | assert(!RHS->getAs<ReferenceType>() && "RHS is a reference type?")((!RHS->getAs<ReferenceType>() && "RHS is a reference type?" ) ? static_cast<void> (0) : __assert_fail ("!RHS->getAs<ReferenceType>() && \"RHS is a reference type?\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 8839, __PRETTY_FUNCTION__)); | ||||
8840 | |||||
8841 | if (Unqualified) { | ||||
8842 | LHS = LHS.getUnqualifiedType(); | ||||
8843 | RHS = RHS.getUnqualifiedType(); | ||||
8844 | } | ||||
8845 | |||||
8846 | QualType LHSCan = getCanonicalType(LHS), | ||||
8847 | RHSCan = getCanonicalType(RHS); | ||||
8848 | |||||
8849 | // If two types are identical, they are compatible. | ||||
8850 | if (LHSCan == RHSCan) | ||||
8851 | return LHS; | ||||
8852 | |||||
8853 | // If the qualifiers are different, the types aren't compatible... mostly. | ||||
8854 | Qualifiers LQuals = LHSCan.getLocalQualifiers(); | ||||
8855 | Qualifiers RQuals = RHSCan.getLocalQualifiers(); | ||||
8856 | if (LQuals != RQuals) { | ||||
8857 | // If any of these qualifiers are different, we have a type | ||||
8858 | // mismatch. | ||||
8859 | if (LQuals.getCVRQualifiers() != RQuals.getCVRQualifiers() || | ||||
8860 | LQuals.getAddressSpace() != RQuals.getAddressSpace() || | ||||
8861 | LQuals.getObjCLifetime() != RQuals.getObjCLifetime() || | ||||
8862 | LQuals.hasUnaligned() != RQuals.hasUnaligned()) | ||||
8863 | return {}; | ||||
8864 | |||||
8865 | // Exactly one GC qualifier difference is allowed: __strong is | ||||
8866 | // okay if the other type has no GC qualifier but is an Objective | ||||
8867 | // C object pointer (i.e. implicitly strong by default). We fix | ||||
8868 | // this by pretending that the unqualified type was actually | ||||
8869 | // qualified __strong. | ||||
8870 | Qualifiers::GC GC_L = LQuals.getObjCGCAttr(); | ||||
8871 | Qualifiers::GC GC_R = RQuals.getObjCGCAttr(); | ||||
8872 | assert((GC_L != GC_R) && "unequal qualifier sets had only equal elements")(((GC_L != GC_R) && "unequal qualifier sets had only equal elements" ) ? static_cast<void> (0) : __assert_fail ("(GC_L != GC_R) && \"unequal qualifier sets had only equal elements\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 8872, __PRETTY_FUNCTION__)); | ||||
8873 | |||||
8874 | if (GC_L == Qualifiers::Weak || GC_R == Qualifiers::Weak) | ||||
8875 | return {}; | ||||
8876 | |||||
8877 | if (GC_L == Qualifiers::Strong && RHSCan->isObjCObjectPointerType()) { | ||||
8878 | return mergeTypes(LHS, getObjCGCQualType(RHS, Qualifiers::Strong)); | ||||
8879 | } | ||||
8880 | if (GC_R == Qualifiers::Strong && LHSCan->isObjCObjectPointerType()) { | ||||
8881 | return mergeTypes(getObjCGCQualType(LHS, Qualifiers::Strong), RHS); | ||||
8882 | } | ||||
8883 | return {}; | ||||
8884 | } | ||||
8885 | |||||
8886 | // Okay, qualifiers are equal. | ||||
8887 | |||||
8888 | Type::TypeClass LHSClass = LHSCan->getTypeClass(); | ||||
8889 | Type::TypeClass RHSClass = RHSCan->getTypeClass(); | ||||
8890 | |||||
8891 | // We want to consider the two function types to be the same for these | ||||
8892 | // comparisons, just force one to the other. | ||||
8893 | if (LHSClass == Type::FunctionProto) LHSClass = Type::FunctionNoProto; | ||||
8894 | if (RHSClass == Type::FunctionProto) RHSClass = Type::FunctionNoProto; | ||||
8895 | |||||
8896 | // Same as above for arrays | ||||
8897 | if (LHSClass == Type::VariableArray || LHSClass == Type::IncompleteArray) | ||||
8898 | LHSClass = Type::ConstantArray; | ||||
8899 | if (RHSClass == Type::VariableArray || RHSClass == Type::IncompleteArray) | ||||
8900 | RHSClass = Type::ConstantArray; | ||||
8901 | |||||
8902 | // ObjCInterfaces are just specialized ObjCObjects. | ||||
8903 | if (LHSClass == Type::ObjCInterface) LHSClass = Type::ObjCObject; | ||||
8904 | if (RHSClass == Type::ObjCInterface) RHSClass = Type::ObjCObject; | ||||
8905 | |||||
8906 | // Canonicalize ExtVector -> Vector. | ||||
8907 | if (LHSClass == Type::ExtVector) LHSClass = Type::Vector; | ||||
8908 | if (RHSClass == Type::ExtVector) RHSClass = Type::Vector; | ||||
8909 | |||||
8910 | // If the canonical type classes don't match. | ||||
8911 | if (LHSClass != RHSClass) { | ||||
8912 | // Note that we only have special rules for turning block enum | ||||
8913 | // returns into block int returns, not vice-versa. | ||||
8914 | if (const auto *ETy = LHS->getAs<EnumType>()) { | ||||
8915 | return mergeEnumWithInteger(*this, ETy, RHS, false); | ||||
8916 | } | ||||
8917 | if (const EnumType* ETy = RHS->getAs<EnumType>()) { | ||||
8918 | return mergeEnumWithInteger(*this, ETy, LHS, BlockReturnType); | ||||
8919 | } | ||||
8920 | // allow block pointer type to match an 'id' type. | ||||
8921 | if (OfBlockPointer && !BlockReturnType) { | ||||
8922 | if (LHS->isObjCIdType() && RHS->isBlockPointerType()) | ||||
8923 | return LHS; | ||||
8924 | if (RHS->isObjCIdType() && LHS->isBlockPointerType()) | ||||
8925 | return RHS; | ||||
8926 | } | ||||
8927 | |||||
8928 | return {}; | ||||
8929 | } | ||||
8930 | |||||
8931 | // The canonical type classes match. | ||||
8932 | switch (LHSClass) { | ||||
8933 | #define TYPE(Class, Base) | ||||
8934 | #define ABSTRACT_TYPE(Class, Base) | ||||
8935 | #define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class: | ||||
8936 | #define NON_CANONICAL_TYPE(Class, Base) case Type::Class: | ||||
8937 | #define DEPENDENT_TYPE(Class, Base) case Type::Class: | ||||
8938 | #include "clang/AST/TypeNodes.inc" | ||||
8939 | llvm_unreachable("Non-canonical and dependent types shouldn't get here")::llvm::llvm_unreachable_internal("Non-canonical and dependent types shouldn't get here" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 8939); | ||||
8940 | |||||
8941 | case Type::Auto: | ||||
8942 | case Type::DeducedTemplateSpecialization: | ||||
8943 | case Type::LValueReference: | ||||
8944 | case Type::RValueReference: | ||||
8945 | case Type::MemberPointer: | ||||
8946 | llvm_unreachable("C++ should never be in mergeTypes")::llvm::llvm_unreachable_internal("C++ should never be in mergeTypes" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 8946); | ||||
8947 | |||||
8948 | case Type::ObjCInterface: | ||||
8949 | case Type::IncompleteArray: | ||||
8950 | case Type::VariableArray: | ||||
8951 | case Type::FunctionProto: | ||||
8952 | case Type::ExtVector: | ||||
8953 | llvm_unreachable("Types are eliminated above")::llvm::llvm_unreachable_internal("Types are eliminated above" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 8953); | ||||
8954 | |||||
8955 | case Type::Pointer: | ||||
8956 | { | ||||
8957 | // Merge two pointer types, while trying to preserve typedef info | ||||
8958 | QualType LHSPointee = LHS->castAs<PointerType>()->getPointeeType(); | ||||
8959 | QualType RHSPointee = RHS->castAs<PointerType>()->getPointeeType(); | ||||
8960 | if (Unqualified) { | ||||
8961 | LHSPointee = LHSPointee.getUnqualifiedType(); | ||||
8962 | RHSPointee = RHSPointee.getUnqualifiedType(); | ||||
8963 | } | ||||
8964 | QualType ResultType = mergeTypes(LHSPointee, RHSPointee, false, | ||||
8965 | Unqualified); | ||||
8966 | if (ResultType.isNull()) | ||||
8967 | return {}; | ||||
8968 | if (getCanonicalType(LHSPointee) == getCanonicalType(ResultType)) | ||||
8969 | return LHS; | ||||
8970 | if (getCanonicalType(RHSPointee) == getCanonicalType(ResultType)) | ||||
8971 | return RHS; | ||||
8972 | return getPointerType(ResultType); | ||||
8973 | } | ||||
8974 | case Type::BlockPointer: | ||||
8975 | { | ||||
8976 | // Merge two block pointer types, while trying to preserve typedef info | ||||
8977 | QualType LHSPointee = LHS->castAs<BlockPointerType>()->getPointeeType(); | ||||
8978 | QualType RHSPointee = RHS->castAs<BlockPointerType>()->getPointeeType(); | ||||
8979 | if (Unqualified) { | ||||
8980 | LHSPointee = LHSPointee.getUnqualifiedType(); | ||||
8981 | RHSPointee = RHSPointee.getUnqualifiedType(); | ||||
8982 | } | ||||
8983 | if (getLangOpts().OpenCL) { | ||||
8984 | Qualifiers LHSPteeQual = LHSPointee.getQualifiers(); | ||||
8985 | Qualifiers RHSPteeQual = RHSPointee.getQualifiers(); | ||||
8986 | // Blocks can't be an expression in a ternary operator (OpenCL v2.0 | ||||
8987 | // 6.12.5) thus the following check is asymmetric. | ||||
8988 | if (!LHSPteeQual.isAddressSpaceSupersetOf(RHSPteeQual)) | ||||
8989 | return {}; | ||||
8990 | LHSPteeQual.removeAddressSpace(); | ||||
8991 | RHSPteeQual.removeAddressSpace(); | ||||
8992 | LHSPointee = | ||||
8993 | QualType(LHSPointee.getTypePtr(), LHSPteeQual.getAsOpaqueValue()); | ||||
8994 | RHSPointee = | ||||
8995 | QualType(RHSPointee.getTypePtr(), RHSPteeQual.getAsOpaqueValue()); | ||||
8996 | } | ||||
8997 | QualType ResultType = mergeTypes(LHSPointee, RHSPointee, OfBlockPointer, | ||||
8998 | Unqualified); | ||||
8999 | if (ResultType.isNull()) | ||||
9000 | return {}; | ||||
9001 | if (getCanonicalType(LHSPointee) == getCanonicalType(ResultType)) | ||||
9002 | return LHS; | ||||
9003 | if (getCanonicalType(RHSPointee) == getCanonicalType(ResultType)) | ||||
9004 | return RHS; | ||||
9005 | return getBlockPointerType(ResultType); | ||||
9006 | } | ||||
9007 | case Type::Atomic: | ||||
9008 | { | ||||
9009 | // Merge two pointer types, while trying to preserve typedef info | ||||
9010 | QualType LHSValue = LHS->castAs<AtomicType>()->getValueType(); | ||||
9011 | QualType RHSValue = RHS->castAs<AtomicType>()->getValueType(); | ||||
9012 | if (Unqualified) { | ||||
9013 | LHSValue = LHSValue.getUnqualifiedType(); | ||||
9014 | RHSValue = RHSValue.getUnqualifiedType(); | ||||
9015 | } | ||||
9016 | QualType ResultType = mergeTypes(LHSValue, RHSValue, false, | ||||
9017 | Unqualified); | ||||
9018 | if (ResultType.isNull()) | ||||
9019 | return {}; | ||||
9020 | if (getCanonicalType(LHSValue) == getCanonicalType(ResultType)) | ||||
9021 | return LHS; | ||||
9022 | if (getCanonicalType(RHSValue) == getCanonicalType(ResultType)) | ||||
9023 | return RHS; | ||||
9024 | return getAtomicType(ResultType); | ||||
9025 | } | ||||
9026 | case Type::ConstantArray: | ||||
9027 | { | ||||
9028 | const ConstantArrayType* LCAT = getAsConstantArrayType(LHS); | ||||
9029 | const ConstantArrayType* RCAT = getAsConstantArrayType(RHS); | ||||
9030 | if (LCAT && RCAT && RCAT->getSize() != LCAT->getSize()) | ||||
9031 | return {}; | ||||
9032 | |||||
9033 | QualType LHSElem = getAsArrayType(LHS)->getElementType(); | ||||
9034 | QualType RHSElem = getAsArrayType(RHS)->getElementType(); | ||||
9035 | if (Unqualified) { | ||||
9036 | LHSElem = LHSElem.getUnqualifiedType(); | ||||
9037 | RHSElem = RHSElem.getUnqualifiedType(); | ||||
9038 | } | ||||
9039 | |||||
9040 | QualType ResultType = mergeTypes(LHSElem, RHSElem, false, Unqualified); | ||||
9041 | if (ResultType.isNull()) | ||||
9042 | return {}; | ||||
9043 | |||||
9044 | const VariableArrayType* LVAT = getAsVariableArrayType(LHS); | ||||
9045 | const VariableArrayType* RVAT = getAsVariableArrayType(RHS); | ||||
9046 | |||||
9047 | // If either side is a variable array, and both are complete, check whether | ||||
9048 | // the current dimension is definite. | ||||
9049 | if (LVAT || RVAT) { | ||||
9050 | auto SizeFetch = [this](const VariableArrayType* VAT, | ||||
9051 | const ConstantArrayType* CAT) | ||||
9052 | -> std::pair<bool,llvm::APInt> { | ||||
9053 | if (VAT) { | ||||
9054 | llvm::APSInt TheInt; | ||||
9055 | Expr *E = VAT->getSizeExpr(); | ||||
9056 | if (E && E->isIntegerConstantExpr(TheInt, *this)) | ||||
9057 | return std::make_pair(true, TheInt); | ||||
9058 | else | ||||
9059 | return std::make_pair(false, TheInt); | ||||
9060 | } else if (CAT) { | ||||
9061 | return std::make_pair(true, CAT->getSize()); | ||||
9062 | } else { | ||||
9063 | return std::make_pair(false, llvm::APInt()); | ||||
9064 | } | ||||
9065 | }; | ||||
9066 | |||||
9067 | bool HaveLSize, HaveRSize; | ||||
9068 | llvm::APInt LSize, RSize; | ||||
9069 | std::tie(HaveLSize, LSize) = SizeFetch(LVAT, LCAT); | ||||
9070 | std::tie(HaveRSize, RSize) = SizeFetch(RVAT, RCAT); | ||||
9071 | if (HaveLSize && HaveRSize && !llvm::APInt::isSameValue(LSize, RSize)) | ||||
9072 | return {}; // Definite, but unequal, array dimension | ||||
9073 | } | ||||
9074 | |||||
9075 | if (LCAT && getCanonicalType(LHSElem) == getCanonicalType(ResultType)) | ||||
9076 | return LHS; | ||||
9077 | if (RCAT && getCanonicalType(RHSElem) == getCanonicalType(ResultType)) | ||||
9078 | return RHS; | ||||
9079 | if (LCAT) return getConstantArrayType(ResultType, LCAT->getSize(), | ||||
9080 | ArrayType::ArraySizeModifier(), 0); | ||||
9081 | if (RCAT) return getConstantArrayType(ResultType, RCAT->getSize(), | ||||
9082 | ArrayType::ArraySizeModifier(), 0); | ||||
9083 | if (LVAT && getCanonicalType(LHSElem) == getCanonicalType(ResultType)) | ||||
9084 | return LHS; | ||||
9085 | if (RVAT && getCanonicalType(RHSElem) == getCanonicalType(ResultType)) | ||||
9086 | return RHS; | ||||
9087 | if (LVAT) { | ||||
9088 | // FIXME: This isn't correct! But tricky to implement because | ||||
9089 | // the array's size has to be the size of LHS, but the type | ||||
9090 | // has to be different. | ||||
9091 | return LHS; | ||||
9092 | } | ||||
9093 | if (RVAT) { | ||||
9094 | // FIXME: This isn't correct! But tricky to implement because | ||||
9095 | // the array's size has to be the size of RHS, but the type | ||||
9096 | // has to be different. | ||||
9097 | return RHS; | ||||
9098 | } | ||||
9099 | if (getCanonicalType(LHSElem) == getCanonicalType(ResultType)) return LHS; | ||||
9100 | if (getCanonicalType(RHSElem) == getCanonicalType(ResultType)) return RHS; | ||||
9101 | return getIncompleteArrayType(ResultType, | ||||
9102 | ArrayType::ArraySizeModifier(), 0); | ||||
9103 | } | ||||
9104 | case Type::FunctionNoProto: | ||||
9105 | return mergeFunctionTypes(LHS, RHS, OfBlockPointer, Unqualified); | ||||
9106 | case Type::Record: | ||||
9107 | case Type::Enum: | ||||
9108 | return {}; | ||||
9109 | case Type::Builtin: | ||||
9110 | // Only exactly equal builtin types are compatible, which is tested above. | ||||
9111 | return {}; | ||||
9112 | case Type::Complex: | ||||
9113 | // Distinct complex types are incompatible. | ||||
9114 | return {}; | ||||
9115 | case Type::Vector: | ||||
9116 | // FIXME: The merged type should be an ExtVector! | ||||
9117 | if (areCompatVectorTypes(LHSCan->getAs<VectorType>(), | ||||
9118 | RHSCan->getAs<VectorType>())) | ||||
9119 | return LHS; | ||||
9120 | return {}; | ||||
9121 | case Type::ObjCObject: { | ||||
9122 | // Check if the types are assignment compatible. | ||||
9123 | // FIXME: This should be type compatibility, e.g. whether | ||||
9124 | // "LHS x; RHS x;" at global scope is legal. | ||||
9125 | const auto *LHSIface = LHS->getAs<ObjCObjectType>(); | ||||
9126 | const auto *RHSIface = RHS->getAs<ObjCObjectType>(); | ||||
9127 | if (canAssignObjCInterfaces(LHSIface, RHSIface)) | ||||
9128 | return LHS; | ||||
9129 | |||||
9130 | return {}; | ||||
9131 | } | ||||
9132 | case Type::ObjCObjectPointer: | ||||
9133 | if (OfBlockPointer) { | ||||
9134 | if (canAssignObjCInterfacesInBlockPointer( | ||||
9135 | LHS->getAs<ObjCObjectPointerType>(), | ||||
9136 | RHS->getAs<ObjCObjectPointerType>(), | ||||
9137 | BlockReturnType)) | ||||
9138 | return LHS; | ||||
9139 | return {}; | ||||
9140 | } | ||||
9141 | if (canAssignObjCInterfaces(LHS->getAs<ObjCObjectPointerType>(), | ||||
9142 | RHS->getAs<ObjCObjectPointerType>())) | ||||
9143 | return LHS; | ||||
9144 | |||||
9145 | return {}; | ||||
9146 | case Type::Pipe: | ||||
9147 | assert(LHS != RHS &&((LHS != RHS && "Equivalent pipe types should have already been handled!" ) ? static_cast<void> (0) : __assert_fail ("LHS != RHS && \"Equivalent pipe types should have already been handled!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 9148, __PRETTY_FUNCTION__)) | ||||
9148 | "Equivalent pipe types should have already been handled!")((LHS != RHS && "Equivalent pipe types should have already been handled!" ) ? static_cast<void> (0) : __assert_fail ("LHS != RHS && \"Equivalent pipe types should have already been handled!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 9148, __PRETTY_FUNCTION__)); | ||||
9149 | return {}; | ||||
9150 | } | ||||
9151 | |||||
9152 | llvm_unreachable("Invalid Type::Class!")::llvm::llvm_unreachable_internal("Invalid Type::Class!", "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 9152); | ||||
9153 | } | ||||
9154 | |||||
9155 | bool ASTContext::mergeExtParameterInfo( | ||||
9156 | const FunctionProtoType *FirstFnType, const FunctionProtoType *SecondFnType, | ||||
9157 | bool &CanUseFirst, bool &CanUseSecond, | ||||
9158 | SmallVectorImpl<FunctionProtoType::ExtParameterInfo> &NewParamInfos) { | ||||
9159 | assert(NewParamInfos.empty() && "param info list not empty")((NewParamInfos.empty() && "param info list not empty" ) ? static_cast<void> (0) : __assert_fail ("NewParamInfos.empty() && \"param info list not empty\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 9159, __PRETTY_FUNCTION__)); | ||||
9160 | CanUseFirst = CanUseSecond = true; | ||||
9161 | bool FirstHasInfo = FirstFnType->hasExtParameterInfos(); | ||||
9162 | bool SecondHasInfo = SecondFnType->hasExtParameterInfos(); | ||||
9163 | |||||
9164 | // Fast path: if the first type doesn't have ext parameter infos, | ||||
9165 | // we match if and only if the second type also doesn't have them. | ||||
9166 | if (!FirstHasInfo && !SecondHasInfo) | ||||
9167 | return true; | ||||
9168 | |||||
9169 | bool NeedParamInfo = false; | ||||
9170 | size_t E = FirstHasInfo ? FirstFnType->getExtParameterInfos().size() | ||||
9171 | : SecondFnType->getExtParameterInfos().size(); | ||||
9172 | |||||
9173 | for (size_t I = 0; I < E; ++I) { | ||||
9174 | FunctionProtoType::ExtParameterInfo FirstParam, SecondParam; | ||||
9175 | if (FirstHasInfo) | ||||
9176 | FirstParam = FirstFnType->getExtParameterInfo(I); | ||||
9177 | if (SecondHasInfo) | ||||
9178 | SecondParam = SecondFnType->getExtParameterInfo(I); | ||||
9179 | |||||
9180 | // Cannot merge unless everything except the noescape flag matches. | ||||
9181 | if (FirstParam.withIsNoEscape(false) != SecondParam.withIsNoEscape(false)) | ||||
9182 | return false; | ||||
9183 | |||||
9184 | bool FirstNoEscape = FirstParam.isNoEscape(); | ||||
9185 | bool SecondNoEscape = SecondParam.isNoEscape(); | ||||
9186 | bool IsNoEscape = FirstNoEscape && SecondNoEscape; | ||||
9187 | NewParamInfos.push_back(FirstParam.withIsNoEscape(IsNoEscape)); | ||||
9188 | if (NewParamInfos.back().getOpaqueValue()) | ||||
9189 | NeedParamInfo = true; | ||||
9190 | if (FirstNoEscape != IsNoEscape) | ||||
9191 | CanUseFirst = false; | ||||
9192 | if (SecondNoEscape != IsNoEscape) | ||||
9193 | CanUseSecond = false; | ||||
9194 | } | ||||
9195 | |||||
9196 | if (!NeedParamInfo) | ||||
9197 | NewParamInfos.clear(); | ||||
9198 | |||||
9199 | return true; | ||||
9200 | } | ||||
9201 | |||||
9202 | void ASTContext::ResetObjCLayout(const ObjCContainerDecl *CD) { | ||||
9203 | ObjCLayouts[CD] = nullptr; | ||||
9204 | } | ||||
9205 | |||||
9206 | /// mergeObjCGCQualifiers - This routine merges ObjC's GC attribute of 'LHS' and | ||||
9207 | /// 'RHS' attributes and returns the merged version; including for function | ||||
9208 | /// return types. | ||||
9209 | QualType ASTContext::mergeObjCGCQualifiers(QualType LHS, QualType RHS) { | ||||
9210 | QualType LHSCan = getCanonicalType(LHS), | ||||
9211 | RHSCan = getCanonicalType(RHS); | ||||
9212 | // If two types are identical, they are compatible. | ||||
9213 | if (LHSCan == RHSCan) | ||||
9214 | return LHS; | ||||
9215 | if (RHSCan->isFunctionType()) { | ||||
9216 | if (!LHSCan->isFunctionType()) | ||||
9217 | return {}; | ||||
9218 | QualType OldReturnType = | ||||
9219 | cast<FunctionType>(RHSCan.getTypePtr())->getReturnType(); | ||||
9220 | QualType NewReturnType = | ||||
9221 | cast<FunctionType>(LHSCan.getTypePtr())->getReturnType(); | ||||
9222 | QualType ResReturnType = | ||||
9223 | mergeObjCGCQualifiers(NewReturnType, OldReturnType); | ||||
9224 | if (ResReturnType.isNull()) | ||||
9225 | return {}; | ||||
9226 | if (ResReturnType == NewReturnType || ResReturnType == OldReturnType) { | ||||
9227 | // id foo(); ... __strong id foo(); or: __strong id foo(); ... id foo(); | ||||
9228 | // In either case, use OldReturnType to build the new function type. | ||||
9229 | const auto *F = LHS->getAs<FunctionType>(); | ||||
9230 | if (const auto *FPT = cast<FunctionProtoType>(F)) { | ||||
9231 | FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo(); | ||||
9232 | EPI.ExtInfo = getFunctionExtInfo(LHS); | ||||
9233 | QualType ResultType = | ||||
9234 | getFunctionType(OldReturnType, FPT->getParamTypes(), EPI); | ||||
9235 | return ResultType; | ||||
9236 | } | ||||
9237 | } | ||||
9238 | return {}; | ||||
9239 | } | ||||
9240 | |||||
9241 | // If the qualifiers are different, the types can still be merged. | ||||
9242 | Qualifiers LQuals = LHSCan.getLocalQualifiers(); | ||||
9243 | Qualifiers RQuals = RHSCan.getLocalQualifiers(); | ||||
9244 | if (LQuals != RQuals) { | ||||
9245 | // If any of these qualifiers are different, we have a type mismatch. | ||||
9246 | if (LQuals.getCVRQualifiers() != RQuals.getCVRQualifiers() || | ||||
9247 | LQuals.getAddressSpace() != RQuals.getAddressSpace()) | ||||
9248 | return {}; | ||||
9249 | |||||
9250 | // Exactly one GC qualifier difference is allowed: __strong is | ||||
9251 | // okay if the other type has no GC qualifier but is an Objective | ||||
9252 | // C object pointer (i.e. implicitly strong by default). We fix | ||||
9253 | // this by pretending that the unqualified type was actually | ||||
9254 | // qualified __strong. | ||||
9255 | Qualifiers::GC GC_L = LQuals.getObjCGCAttr(); | ||||
9256 | Qualifiers::GC GC_R = RQuals.getObjCGCAttr(); | ||||
9257 | assert((GC_L != GC_R) && "unequal qualifier sets had only equal elements")(((GC_L != GC_R) && "unequal qualifier sets had only equal elements" ) ? static_cast<void> (0) : __assert_fail ("(GC_L != GC_R) && \"unequal qualifier sets had only equal elements\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 9257, __PRETTY_FUNCTION__)); | ||||
9258 | |||||
9259 | if (GC_L == Qualifiers::Weak || GC_R == Qualifiers::Weak) | ||||
9260 | return {}; | ||||
9261 | |||||
9262 | if (GC_L == Qualifiers::Strong) | ||||
9263 | return LHS; | ||||
9264 | if (GC_R == Qualifiers::Strong) | ||||
9265 | return RHS; | ||||
9266 | return {}; | ||||
9267 | } | ||||
9268 | |||||
9269 | if (LHSCan->isObjCObjectPointerType() && RHSCan->isObjCObjectPointerType()) { | ||||
9270 | QualType LHSBaseQT = LHS->castAs<ObjCObjectPointerType>()->getPointeeType(); | ||||
9271 | QualType RHSBaseQT = RHS->castAs<ObjCObjectPointerType>()->getPointeeType(); | ||||
9272 | QualType ResQT = mergeObjCGCQualifiers(LHSBaseQT, RHSBaseQT); | ||||
9273 | if (ResQT == LHSBaseQT) | ||||
9274 | return LHS; | ||||
9275 | if (ResQT == RHSBaseQT) | ||||
9276 | return RHS; | ||||
9277 | } | ||||
9278 | return {}; | ||||
9279 | } | ||||
9280 | |||||
9281 | //===----------------------------------------------------------------------===// | ||||
9282 | // Integer Predicates | ||||
9283 | //===----------------------------------------------------------------------===// | ||||
9284 | |||||
9285 | unsigned ASTContext::getIntWidth(QualType T) const { | ||||
9286 | if (const auto *ET = T->getAs<EnumType>()) | ||||
9287 | T = ET->getDecl()->getIntegerType(); | ||||
9288 | if (T->isBooleanType()) | ||||
9289 | return 1; | ||||
9290 | // For builtin types, just use the standard type sizing method | ||||
9291 | return (unsigned)getTypeSize(T); | ||||
9292 | } | ||||
9293 | |||||
9294 | QualType ASTContext::getCorrespondingUnsignedType(QualType T) const { | ||||
9295 | assert((T->hasSignedIntegerRepresentation() || T->isSignedFixedPointType()) &&(((T->hasSignedIntegerRepresentation() || T->isSignedFixedPointType ()) && "Unexpected type") ? static_cast<void> ( 0) : __assert_fail ("(T->hasSignedIntegerRepresentation() || T->isSignedFixedPointType()) && \"Unexpected type\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 9296, __PRETTY_FUNCTION__)) | ||||
9296 | "Unexpected type")(((T->hasSignedIntegerRepresentation() || T->isSignedFixedPointType ()) && "Unexpected type") ? static_cast<void> ( 0) : __assert_fail ("(T->hasSignedIntegerRepresentation() || T->isSignedFixedPointType()) && \"Unexpected type\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 9296, __PRETTY_FUNCTION__)); | ||||
9297 | |||||
9298 | // Turn <4 x signed int> -> <4 x unsigned int> | ||||
9299 | if (const auto *VTy = T->getAs<VectorType>()) | ||||
9300 | return getVectorType(getCorrespondingUnsignedType(VTy->getElementType()), | ||||
9301 | VTy->getNumElements(), VTy->getVectorKind()); | ||||
9302 | |||||
9303 | // For enums, we return the unsigned version of the base type. | ||||
9304 | if (const auto *ETy = T->getAs<EnumType>()) | ||||
9305 | T = ETy->getDecl()->getIntegerType(); | ||||
9306 | |||||
9307 | const auto *BTy = T->getAs<BuiltinType>(); | ||||
9308 | assert(BTy && "Unexpected signed integer or fixed point type")((BTy && "Unexpected signed integer or fixed point type" ) ? static_cast<void> (0) : __assert_fail ("BTy && \"Unexpected signed integer or fixed point type\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 9308, __PRETTY_FUNCTION__)); | ||||
9309 | switch (BTy->getKind()) { | ||||
9310 | case BuiltinType::Char_S: | ||||
9311 | case BuiltinType::SChar: | ||||
9312 | return UnsignedCharTy; | ||||
9313 | case BuiltinType::Short: | ||||
9314 | return UnsignedShortTy; | ||||
9315 | case BuiltinType::Int: | ||||
9316 | return UnsignedIntTy; | ||||
9317 | case BuiltinType::Long: | ||||
9318 | return UnsignedLongTy; | ||||
9319 | case BuiltinType::LongLong: | ||||
9320 | return UnsignedLongLongTy; | ||||
9321 | case BuiltinType::Int128: | ||||
9322 | return UnsignedInt128Ty; | ||||
9323 | |||||
9324 | case BuiltinType::ShortAccum: | ||||
9325 | return UnsignedShortAccumTy; | ||||
9326 | case BuiltinType::Accum: | ||||
9327 | return UnsignedAccumTy; | ||||
9328 | case BuiltinType::LongAccum: | ||||
9329 | return UnsignedLongAccumTy; | ||||
9330 | case BuiltinType::SatShortAccum: | ||||
9331 | return SatUnsignedShortAccumTy; | ||||
9332 | case BuiltinType::SatAccum: | ||||
9333 | return SatUnsignedAccumTy; | ||||
9334 | case BuiltinType::SatLongAccum: | ||||
9335 | return SatUnsignedLongAccumTy; | ||||
9336 | case BuiltinType::ShortFract: | ||||
9337 | return UnsignedShortFractTy; | ||||
9338 | case BuiltinType::Fract: | ||||
9339 | return UnsignedFractTy; | ||||
9340 | case BuiltinType::LongFract: | ||||
9341 | return UnsignedLongFractTy; | ||||
9342 | case BuiltinType::SatShortFract: | ||||
9343 | return SatUnsignedShortFractTy; | ||||
9344 | case BuiltinType::SatFract: | ||||
9345 | return SatUnsignedFractTy; | ||||
9346 | case BuiltinType::SatLongFract: | ||||
9347 | return SatUnsignedLongFractTy; | ||||
9348 | default: | ||||
9349 | llvm_unreachable("Unexpected signed integer or fixed point type")::llvm::llvm_unreachable_internal("Unexpected signed integer or fixed point type" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 9349); | ||||
9350 | } | ||||
9351 | } | ||||
9352 | |||||
9353 | ASTMutationListener::~ASTMutationListener() = default; | ||||
9354 | |||||
9355 | void ASTMutationListener::DeducedReturnType(const FunctionDecl *FD, | ||||
9356 | QualType ReturnType) {} | ||||
9357 | |||||
9358 | //===----------------------------------------------------------------------===// | ||||
9359 | // Builtin Type Computation | ||||
9360 | //===----------------------------------------------------------------------===// | ||||
9361 | |||||
9362 | /// DecodeTypeFromStr - This decodes one type descriptor from Str, advancing the | ||||
9363 | /// pointer over the consumed characters. This returns the resultant type. If | ||||
9364 | /// AllowTypeModifiers is false then modifier like * are not parsed, just basic | ||||
9365 | /// types. This allows "v2i*" to be parsed as a pointer to a v2i instead of | ||||
9366 | /// a vector of "i*". | ||||
9367 | /// | ||||
9368 | /// RequiresICE is filled in on return to indicate whether the value is required | ||||
9369 | /// to be an Integer Constant Expression. | ||||
9370 | static QualType DecodeTypeFromStr(const char *&Str, const ASTContext &Context, | ||||
9371 | ASTContext::GetBuiltinTypeError &Error, | ||||
9372 | bool &RequiresICE, | ||||
9373 | bool AllowTypeModifiers) { | ||||
9374 | // Modifiers. | ||||
9375 | int HowLong = 0; | ||||
9376 | bool Signed = false, Unsigned = false; | ||||
9377 | RequiresICE = false; | ||||
9378 | |||||
9379 | // Read the prefixed modifiers first. | ||||
9380 | bool Done = false; | ||||
9381 | #ifndef NDEBUG | ||||
9382 | bool IsSpecial = false; | ||||
9383 | #endif | ||||
9384 | while (!Done) { | ||||
9385 | switch (*Str++) { | ||||
9386 | default: Done = true; --Str; break; | ||||
9387 | case 'I': | ||||
9388 | RequiresICE = true; | ||||
9389 | break; | ||||
9390 | case 'S': | ||||
9391 | assert(!Unsigned && "Can't use both 'S' and 'U' modifiers!")((!Unsigned && "Can't use both 'S' and 'U' modifiers!" ) ? static_cast<void> (0) : __assert_fail ("!Unsigned && \"Can't use both 'S' and 'U' modifiers!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 9391, __PRETTY_FUNCTION__)); | ||||
9392 | assert(!Signed && "Can't use 'S' modifier multiple times!")((!Signed && "Can't use 'S' modifier multiple times!" ) ? static_cast<void> (0) : __assert_fail ("!Signed && \"Can't use 'S' modifier multiple times!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 9392, __PRETTY_FUNCTION__)); | ||||
9393 | Signed = true; | ||||
9394 | break; | ||||
9395 | case 'U': | ||||
9396 | assert(!Signed && "Can't use both 'S' and 'U' modifiers!")((!Signed && "Can't use both 'S' and 'U' modifiers!") ? static_cast<void> (0) : __assert_fail ("!Signed && \"Can't use both 'S' and 'U' modifiers!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 9396, __PRETTY_FUNCTION__)); | ||||
9397 | assert(!Unsigned && "Can't use 'U' modifier multiple times!")((!Unsigned && "Can't use 'U' modifier multiple times!" ) ? static_cast<void> (0) : __assert_fail ("!Unsigned && \"Can't use 'U' modifier multiple times!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 9397, __PRETTY_FUNCTION__)); | ||||
9398 | Unsigned = true; | ||||
9399 | break; | ||||
9400 | case 'L': | ||||
9401 | assert(!IsSpecial && "Can't use 'L' with 'W', 'N', 'Z' or 'O' modifiers")((!IsSpecial && "Can't use 'L' with 'W', 'N', 'Z' or 'O' modifiers" ) ? static_cast<void> (0) : __assert_fail ("!IsSpecial && \"Can't use 'L' with 'W', 'N', 'Z' or 'O' modifiers\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 9401, __PRETTY_FUNCTION__)); | ||||
9402 | assert(HowLong <= 2 && "Can't have LLLL modifier")((HowLong <= 2 && "Can't have LLLL modifier") ? static_cast <void> (0) : __assert_fail ("HowLong <= 2 && \"Can't have LLLL modifier\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 9402, __PRETTY_FUNCTION__)); | ||||
9403 | ++HowLong; | ||||
9404 | break; | ||||
9405 | case 'N': | ||||
9406 | // 'N' behaves like 'L' for all non LP64 targets and 'int' otherwise. | ||||
9407 | assert(!IsSpecial && "Can't use two 'N', 'W', 'Z' or 'O' modifiers!")((!IsSpecial && "Can't use two 'N', 'W', 'Z' or 'O' modifiers!" ) ? static_cast<void> (0) : __assert_fail ("!IsSpecial && \"Can't use two 'N', 'W', 'Z' or 'O' modifiers!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 9407, __PRETTY_FUNCTION__)); | ||||
9408 | assert(HowLong == 0 && "Can't use both 'L' and 'N' modifiers!")((HowLong == 0 && "Can't use both 'L' and 'N' modifiers!" ) ? static_cast<void> (0) : __assert_fail ("HowLong == 0 && \"Can't use both 'L' and 'N' modifiers!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 9408, __PRETTY_FUNCTION__)); | ||||
9409 | #ifndef NDEBUG | ||||
9410 | IsSpecial = true; | ||||
9411 | #endif | ||||
9412 | if (Context.getTargetInfo().getLongWidth() == 32) | ||||
9413 | ++HowLong; | ||||
9414 | break; | ||||
9415 | case 'W': | ||||
9416 | // This modifier represents int64 type. | ||||
9417 | assert(!IsSpecial && "Can't use two 'N', 'W', 'Z' or 'O' modifiers!")((!IsSpecial && "Can't use two 'N', 'W', 'Z' or 'O' modifiers!" ) ? static_cast<void> (0) : __assert_fail ("!IsSpecial && \"Can't use two 'N', 'W', 'Z' or 'O' modifiers!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 9417, __PRETTY_FUNCTION__)); | ||||
9418 | assert(HowLong == 0 && "Can't use both 'L' and 'W' modifiers!")((HowLong == 0 && "Can't use both 'L' and 'W' modifiers!" ) ? static_cast<void> (0) : __assert_fail ("HowLong == 0 && \"Can't use both 'L' and 'W' modifiers!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 9418, __PRETTY_FUNCTION__)); | ||||
9419 | #ifndef NDEBUG | ||||
9420 | IsSpecial = true; | ||||
9421 | #endif | ||||
9422 | switch (Context.getTargetInfo().getInt64Type()) { | ||||
9423 | default: | ||||
9424 | llvm_unreachable("Unexpected integer type")::llvm::llvm_unreachable_internal("Unexpected integer type", "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 9424); | ||||
9425 | case TargetInfo::SignedLong: | ||||
9426 | HowLong = 1; | ||||
9427 | break; | ||||
9428 | case TargetInfo::SignedLongLong: | ||||
9429 | HowLong = 2; | ||||
9430 | break; | ||||
9431 | } | ||||
9432 | break; | ||||
9433 | case 'Z': | ||||
9434 | // This modifier represents int32 type. | ||||
9435 | assert(!IsSpecial && "Can't use two 'N', 'W', 'Z' or 'O' modifiers!")((!IsSpecial && "Can't use two 'N', 'W', 'Z' or 'O' modifiers!" ) ? static_cast<void> (0) : __assert_fail ("!IsSpecial && \"Can't use two 'N', 'W', 'Z' or 'O' modifiers!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 9435, __PRETTY_FUNCTION__)); | ||||
9436 | assert(HowLong == 0 && "Can't use both 'L' and 'Z' modifiers!")((HowLong == 0 && "Can't use both 'L' and 'Z' modifiers!" ) ? static_cast<void> (0) : __assert_fail ("HowLong == 0 && \"Can't use both 'L' and 'Z' modifiers!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 9436, __PRETTY_FUNCTION__)); | ||||
9437 | #ifndef NDEBUG | ||||
9438 | IsSpecial = true; | ||||
9439 | #endif | ||||
9440 | switch (Context.getTargetInfo().getIntTypeByWidth(32, true)) { | ||||
9441 | default: | ||||
9442 | llvm_unreachable("Unexpected integer type")::llvm::llvm_unreachable_internal("Unexpected integer type", "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 9442); | ||||
9443 | case TargetInfo::SignedInt: | ||||
9444 | HowLong = 0; | ||||
9445 | break; | ||||
9446 | case TargetInfo::SignedLong: | ||||
9447 | HowLong = 1; | ||||
9448 | break; | ||||
9449 | case TargetInfo::SignedLongLong: | ||||
9450 | HowLong = 2; | ||||
9451 | break; | ||||
9452 | } | ||||
9453 | break; | ||||
9454 | case 'O': | ||||
9455 | assert(!IsSpecial && "Can't use two 'N', 'W', 'Z' or 'O' modifiers!")((!IsSpecial && "Can't use two 'N', 'W', 'Z' or 'O' modifiers!" ) ? static_cast<void> (0) : __assert_fail ("!IsSpecial && \"Can't use two 'N', 'W', 'Z' or 'O' modifiers!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 9455, __PRETTY_FUNCTION__)); | ||||
9456 | assert(HowLong == 0 && "Can't use both 'L' and 'O' modifiers!")((HowLong == 0 && "Can't use both 'L' and 'O' modifiers!" ) ? static_cast<void> (0) : __assert_fail ("HowLong == 0 && \"Can't use both 'L' and 'O' modifiers!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 9456, __PRETTY_FUNCTION__)); | ||||
9457 | #ifndef NDEBUG | ||||
9458 | IsSpecial = true; | ||||
9459 | #endif | ||||
9460 | if (Context.getLangOpts().OpenCL) | ||||
9461 | HowLong = 1; | ||||
9462 | else | ||||
9463 | HowLong = 2; | ||||
9464 | break; | ||||
9465 | } | ||||
9466 | } | ||||
9467 | |||||
9468 | QualType Type; | ||||
9469 | |||||
9470 | // Read the base type. | ||||
9471 | switch (*Str++) { | ||||
9472 | default: llvm_unreachable("Unknown builtin type letter!")::llvm::llvm_unreachable_internal("Unknown builtin type letter!" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 9472); | ||||
9473 | case 'v': | ||||
9474 | assert(HowLong == 0 && !Signed && !Unsigned &&((HowLong == 0 && !Signed && !Unsigned && "Bad modifiers used with 'v'!") ? static_cast<void> (0 ) : __assert_fail ("HowLong == 0 && !Signed && !Unsigned && \"Bad modifiers used with 'v'!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 9475, __PRETTY_FUNCTION__)) | ||||
9475 | "Bad modifiers used with 'v'!")((HowLong == 0 && !Signed && !Unsigned && "Bad modifiers used with 'v'!") ? static_cast<void> (0 ) : __assert_fail ("HowLong == 0 && !Signed && !Unsigned && \"Bad modifiers used with 'v'!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 9475, __PRETTY_FUNCTION__)); | ||||
9476 | Type = Context.VoidTy; | ||||
9477 | break; | ||||
9478 | case 'h': | ||||
9479 | assert(HowLong == 0 && !Signed && !Unsigned &&((HowLong == 0 && !Signed && !Unsigned && "Bad modifiers used with 'h'!") ? static_cast<void> (0 ) : __assert_fail ("HowLong == 0 && !Signed && !Unsigned && \"Bad modifiers used with 'h'!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 9480, __PRETTY_FUNCTION__)) | ||||
9480 | "Bad modifiers used with 'h'!")((HowLong == 0 && !Signed && !Unsigned && "Bad modifiers used with 'h'!") ? static_cast<void> (0 ) : __assert_fail ("HowLong == 0 && !Signed && !Unsigned && \"Bad modifiers used with 'h'!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 9480, __PRETTY_FUNCTION__)); | ||||
9481 | Type = Context.HalfTy; | ||||
9482 | break; | ||||
9483 | case 'f': | ||||
9484 | assert(HowLong == 0 && !Signed && !Unsigned &&((HowLong == 0 && !Signed && !Unsigned && "Bad modifiers used with 'f'!") ? static_cast<void> (0 ) : __assert_fail ("HowLong == 0 && !Signed && !Unsigned && \"Bad modifiers used with 'f'!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 9485, __PRETTY_FUNCTION__)) | ||||
9485 | "Bad modifiers used with 'f'!")((HowLong == 0 && !Signed && !Unsigned && "Bad modifiers used with 'f'!") ? static_cast<void> (0 ) : __assert_fail ("HowLong == 0 && !Signed && !Unsigned && \"Bad modifiers used with 'f'!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 9485, __PRETTY_FUNCTION__)); | ||||
9486 | Type = Context.FloatTy; | ||||
9487 | break; | ||||
9488 | case 'd': | ||||
9489 | assert(HowLong < 3 && !Signed && !Unsigned &&((HowLong < 3 && !Signed && !Unsigned && "Bad modifiers used with 'd'!") ? static_cast<void> (0 ) : __assert_fail ("HowLong < 3 && !Signed && !Unsigned && \"Bad modifiers used with 'd'!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 9490, __PRETTY_FUNCTION__)) | ||||
9490 | "Bad modifiers used with 'd'!")((HowLong < 3 && !Signed && !Unsigned && "Bad modifiers used with 'd'!") ? static_cast<void> (0 ) : __assert_fail ("HowLong < 3 && !Signed && !Unsigned && \"Bad modifiers used with 'd'!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 9490, __PRETTY_FUNCTION__)); | ||||
9491 | if (HowLong == 1) | ||||
9492 | Type = Context.LongDoubleTy; | ||||
9493 | else if (HowLong == 2) | ||||
9494 | Type = Context.Float128Ty; | ||||
9495 | else | ||||
9496 | Type = Context.DoubleTy; | ||||
9497 | break; | ||||
9498 | case 's': | ||||
9499 | assert(HowLong == 0 && "Bad modifiers used with 's'!")((HowLong == 0 && "Bad modifiers used with 's'!") ? static_cast <void> (0) : __assert_fail ("HowLong == 0 && \"Bad modifiers used with 's'!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 9499, __PRETTY_FUNCTION__)); | ||||
9500 | if (Unsigned) | ||||
9501 | Type = Context.UnsignedShortTy; | ||||
9502 | else | ||||
9503 | Type = Context.ShortTy; | ||||
9504 | break; | ||||
9505 | case 'i': | ||||
9506 | if (HowLong == 3) | ||||
9507 | Type = Unsigned ? Context.UnsignedInt128Ty : Context.Int128Ty; | ||||
9508 | else if (HowLong == 2) | ||||
9509 | Type = Unsigned ? Context.UnsignedLongLongTy : Context.LongLongTy; | ||||
9510 | else if (HowLong == 1) | ||||
9511 | Type = Unsigned ? Context.UnsignedLongTy : Context.LongTy; | ||||
9512 | else | ||||
9513 | Type = Unsigned ? Context.UnsignedIntTy : Context.IntTy; | ||||
9514 | break; | ||||
9515 | case 'c': | ||||
9516 | assert(HowLong == 0 && "Bad modifiers used with 'c'!")((HowLong == 0 && "Bad modifiers used with 'c'!") ? static_cast <void> (0) : __assert_fail ("HowLong == 0 && \"Bad modifiers used with 'c'!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 9516, __PRETTY_FUNCTION__)); | ||||
9517 | if (Signed) | ||||
9518 | Type = Context.SignedCharTy; | ||||
9519 | else if (Unsigned) | ||||
9520 | Type = Context.UnsignedCharTy; | ||||
9521 | else | ||||
9522 | Type = Context.CharTy; | ||||
9523 | break; | ||||
9524 | case 'b': // boolean | ||||
9525 | assert(HowLong == 0 && !Signed && !Unsigned && "Bad modifiers for 'b'!")((HowLong == 0 && !Signed && !Unsigned && "Bad modifiers for 'b'!") ? static_cast<void> (0) : __assert_fail ("HowLong == 0 && !Signed && !Unsigned && \"Bad modifiers for 'b'!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 9525, __PRETTY_FUNCTION__)); | ||||
9526 | Type = Context.BoolTy; | ||||
9527 | break; | ||||
9528 | case 'z': // size_t. | ||||
9529 | assert(HowLong == 0 && !Signed && !Unsigned && "Bad modifiers for 'z'!")((HowLong == 0 && !Signed && !Unsigned && "Bad modifiers for 'z'!") ? static_cast<void> (0) : __assert_fail ("HowLong == 0 && !Signed && !Unsigned && \"Bad modifiers for 'z'!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 9529, __PRETTY_FUNCTION__)); | ||||
9530 | Type = Context.getSizeType(); | ||||
9531 | break; | ||||
9532 | case 'w': // wchar_t. | ||||
9533 | assert(HowLong == 0 && !Signed && !Unsigned && "Bad modifiers for 'w'!")((HowLong == 0 && !Signed && !Unsigned && "Bad modifiers for 'w'!") ? static_cast<void> (0) : __assert_fail ("HowLong == 0 && !Signed && !Unsigned && \"Bad modifiers for 'w'!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 9533, __PRETTY_FUNCTION__)); | ||||
9534 | Type = Context.getWideCharType(); | ||||
9535 | break; | ||||
9536 | case 'F': | ||||
9537 | Type = Context.getCFConstantStringType(); | ||||
9538 | break; | ||||
9539 | case 'G': | ||||
9540 | Type = Context.getObjCIdType(); | ||||
9541 | break; | ||||
9542 | case 'H': | ||||
9543 | Type = Context.getObjCSelType(); | ||||
9544 | break; | ||||
9545 | case 'M': | ||||
9546 | Type = Context.getObjCSuperType(); | ||||
9547 | break; | ||||
9548 | case 'a': | ||||
9549 | Type = Context.getBuiltinVaListType(); | ||||
9550 | assert(!Type.isNull() && "builtin va list type not initialized!")((!Type.isNull() && "builtin va list type not initialized!" ) ? static_cast<void> (0) : __assert_fail ("!Type.isNull() && \"builtin va list type not initialized!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 9550, __PRETTY_FUNCTION__)); | ||||
9551 | break; | ||||
9552 | case 'A': | ||||
9553 | // This is a "reference" to a va_list; however, what exactly | ||||
9554 | // this means depends on how va_list is defined. There are two | ||||
9555 | // different kinds of va_list: ones passed by value, and ones | ||||
9556 | // passed by reference. An example of a by-value va_list is | ||||
9557 | // x86, where va_list is a char*. An example of by-ref va_list | ||||
9558 | // is x86-64, where va_list is a __va_list_tag[1]. For x86, | ||||
9559 | // we want this argument to be a char*&; for x86-64, we want | ||||
9560 | // it to be a __va_list_tag*. | ||||
9561 | Type = Context.getBuiltinVaListType(); | ||||
9562 | assert(!Type.isNull() && "builtin va list type not initialized!")((!Type.isNull() && "builtin va list type not initialized!" ) ? static_cast<void> (0) : __assert_fail ("!Type.isNull() && \"builtin va list type not initialized!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 9562, __PRETTY_FUNCTION__)); | ||||
9563 | if (Type->isArrayType()) | ||||
9564 | Type = Context.getArrayDecayedType(Type); | ||||
9565 | else | ||||
9566 | Type = Context.getLValueReferenceType(Type); | ||||
9567 | break; | ||||
9568 | case 'V': { | ||||
9569 | char *End; | ||||
9570 | unsigned NumElements = strtoul(Str, &End, 10); | ||||
9571 | assert(End != Str && "Missing vector size")((End != Str && "Missing vector size") ? static_cast< void> (0) : __assert_fail ("End != Str && \"Missing vector size\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 9571, __PRETTY_FUNCTION__)); | ||||
9572 | Str = End; | ||||
9573 | |||||
9574 | QualType ElementType = DecodeTypeFromStr(Str, Context, Error, | ||||
9575 | RequiresICE, false); | ||||
9576 | assert(!RequiresICE && "Can't require vector ICE")((!RequiresICE && "Can't require vector ICE") ? static_cast <void> (0) : __assert_fail ("!RequiresICE && \"Can't require vector ICE\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 9576, __PRETTY_FUNCTION__)); | ||||
9577 | |||||
9578 | // TODO: No way to make AltiVec vectors in builtins yet. | ||||
9579 | Type = Context.getVectorType(ElementType, NumElements, | ||||
9580 | VectorType::GenericVector); | ||||
9581 | break; | ||||
9582 | } | ||||
9583 | case 'E': { | ||||
9584 | char *End; | ||||
9585 | |||||
9586 | unsigned NumElements = strtoul(Str, &End, 10); | ||||
9587 | assert(End != Str && "Missing vector size")((End != Str && "Missing vector size") ? static_cast< void> (0) : __assert_fail ("End != Str && \"Missing vector size\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 9587, __PRETTY_FUNCTION__)); | ||||
9588 | |||||
9589 | Str = End; | ||||
9590 | |||||
9591 | QualType ElementType = DecodeTypeFromStr(Str, Context, Error, RequiresICE, | ||||
9592 | false); | ||||
9593 | Type = Context.getExtVectorType(ElementType, NumElements); | ||||
9594 | break; | ||||
9595 | } | ||||
9596 | case 'X': { | ||||
9597 | QualType ElementType = DecodeTypeFromStr(Str, Context, Error, RequiresICE, | ||||
9598 | false); | ||||
9599 | assert(!RequiresICE && "Can't require complex ICE")((!RequiresICE && "Can't require complex ICE") ? static_cast <void> (0) : __assert_fail ("!RequiresICE && \"Can't require complex ICE\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 9599, __PRETTY_FUNCTION__)); | ||||
9600 | Type = Context.getComplexType(ElementType); | ||||
9601 | break; | ||||
9602 | } | ||||
9603 | case 'Y': | ||||
9604 | Type = Context.getPointerDiffType(); | ||||
9605 | break; | ||||
9606 | case 'P': | ||||
9607 | Type = Context.getFILEType(); | ||||
9608 | if (Type.isNull()) { | ||||
9609 | Error = ASTContext::GE_Missing_stdio; | ||||
9610 | return {}; | ||||
9611 | } | ||||
9612 | break; | ||||
9613 | case 'J': | ||||
9614 | if (Signed) | ||||
9615 | Type = Context.getsigjmp_bufType(); | ||||
9616 | else | ||||
9617 | Type = Context.getjmp_bufType(); | ||||
9618 | |||||
9619 | if (Type.isNull()) { | ||||
9620 | Error = ASTContext::GE_Missing_setjmp; | ||||
9621 | return {}; | ||||
9622 | } | ||||
9623 | break; | ||||
9624 | case 'K': | ||||
9625 | assert(HowLong == 0 && !Signed && !Unsigned && "Bad modifiers for 'K'!")((HowLong == 0 && !Signed && !Unsigned && "Bad modifiers for 'K'!") ? static_cast<void> (0) : __assert_fail ("HowLong == 0 && !Signed && !Unsigned && \"Bad modifiers for 'K'!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 9625, __PRETTY_FUNCTION__)); | ||||
9626 | Type = Context.getucontext_tType(); | ||||
9627 | |||||
9628 | if (Type.isNull()) { | ||||
9629 | Error = ASTContext::GE_Missing_ucontext; | ||||
9630 | return {}; | ||||
9631 | } | ||||
9632 | break; | ||||
9633 | case 'p': | ||||
9634 | Type = Context.getProcessIDType(); | ||||
9635 | break; | ||||
9636 | } | ||||
9637 | |||||
9638 | // If there are modifiers and if we're allowed to parse them, go for it. | ||||
9639 | Done = !AllowTypeModifiers; | ||||
9640 | while (!Done) { | ||||
9641 | switch (char c = *Str++) { | ||||
9642 | default: Done = true; --Str; break; | ||||
9643 | case '*': | ||||
9644 | case '&': { | ||||
9645 | // Both pointers and references can have their pointee types | ||||
9646 | // qualified with an address space. | ||||
9647 | char *End; | ||||
9648 | unsigned AddrSpace = strtoul(Str, &End, 10); | ||||
9649 | if (End != Str) { | ||||
9650 | // Note AddrSpace == 0 is not the same as an unspecified address space. | ||||
9651 | Type = Context.getAddrSpaceQualType( | ||||
9652 | Type, | ||||
9653 | Context.getLangASForBuiltinAddressSpace(AddrSpace)); | ||||
9654 | Str = End; | ||||
9655 | } | ||||
9656 | if (c == '*') | ||||
9657 | Type = Context.getPointerType(Type); | ||||
9658 | else | ||||
9659 | Type = Context.getLValueReferenceType(Type); | ||||
9660 | break; | ||||
9661 | } | ||||
9662 | // FIXME: There's no way to have a built-in with an rvalue ref arg. | ||||
9663 | case 'C': | ||||
9664 | Type = Type.withConst(); | ||||
9665 | break; | ||||
9666 | case 'D': | ||||
9667 | Type = Context.getVolatileType(Type); | ||||
9668 | break; | ||||
9669 | case 'R': | ||||
9670 | Type = Type.withRestrict(); | ||||
9671 | break; | ||||
9672 | } | ||||
9673 | } | ||||
9674 | |||||
9675 | assert((!RequiresICE || Type->isIntegralOrEnumerationType()) &&(((!RequiresICE || Type->isIntegralOrEnumerationType()) && "Integer constant 'I' type must be an integer") ? static_cast <void> (0) : __assert_fail ("(!RequiresICE || Type->isIntegralOrEnumerationType()) && \"Integer constant 'I' type must be an integer\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 9676, __PRETTY_FUNCTION__)) | ||||
9676 | "Integer constant 'I' type must be an integer")(((!RequiresICE || Type->isIntegralOrEnumerationType()) && "Integer constant 'I' type must be an integer") ? static_cast <void> (0) : __assert_fail ("(!RequiresICE || Type->isIntegralOrEnumerationType()) && \"Integer constant 'I' type must be an integer\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 9676, __PRETTY_FUNCTION__)); | ||||
9677 | |||||
9678 | return Type; | ||||
9679 | } | ||||
9680 | |||||
9681 | /// GetBuiltinType - Return the type for the specified builtin. | ||||
9682 | QualType ASTContext::GetBuiltinType(unsigned Id, | ||||
9683 | GetBuiltinTypeError &Error, | ||||
9684 | unsigned *IntegerConstantArgs) const { | ||||
9685 | const char *TypeStr = BuiltinInfo.getTypeString(Id); | ||||
9686 | if (TypeStr[0] == '\0') { | ||||
9687 | Error = GE_Missing_type; | ||||
9688 | return {}; | ||||
9689 | } | ||||
9690 | |||||
9691 | SmallVector<QualType, 8> ArgTypes; | ||||
9692 | |||||
9693 | bool RequiresICE = false; | ||||
9694 | Error = GE_None; | ||||
9695 | QualType ResType = DecodeTypeFromStr(TypeStr, *this, Error, | ||||
9696 | RequiresICE, true); | ||||
9697 | if (Error != GE_None) | ||||
9698 | return {}; | ||||
9699 | |||||
9700 | assert(!RequiresICE && "Result of intrinsic cannot be required to be an ICE")((!RequiresICE && "Result of intrinsic cannot be required to be an ICE" ) ? static_cast<void> (0) : __assert_fail ("!RequiresICE && \"Result of intrinsic cannot be required to be an ICE\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 9700, __PRETTY_FUNCTION__)); | ||||
9701 | |||||
9702 | while (TypeStr[0] && TypeStr[0] != '.') { | ||||
9703 | QualType Ty = DecodeTypeFromStr(TypeStr, *this, Error, RequiresICE, true); | ||||
9704 | if (Error != GE_None) | ||||
9705 | return {}; | ||||
9706 | |||||
9707 | // If this argument is required to be an IntegerConstantExpression and the | ||||
9708 | // caller cares, fill in the bitmask we return. | ||||
9709 | if (RequiresICE && IntegerConstantArgs) | ||||
9710 | *IntegerConstantArgs |= 1 << ArgTypes.size(); | ||||
9711 | |||||
9712 | // Do array -> pointer decay. The builtin should use the decayed type. | ||||
9713 | if (Ty->isArrayType()) | ||||
9714 | Ty = getArrayDecayedType(Ty); | ||||
9715 | |||||
9716 | ArgTypes.push_back(Ty); | ||||
9717 | } | ||||
9718 | |||||
9719 | if (Id == Builtin::BI__GetExceptionInfo) | ||||
9720 | return {}; | ||||
9721 | |||||
9722 | assert((TypeStr[0] != '.' || TypeStr[1] == 0) &&(((TypeStr[0] != '.' || TypeStr[1] == 0) && "'.' should only occur at end of builtin type list!" ) ? static_cast<void> (0) : __assert_fail ("(TypeStr[0] != '.' || TypeStr[1] == 0) && \"'.' should only occur at end of builtin type list!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 9723, __PRETTY_FUNCTION__)) | ||||
9723 | "'.' should only occur at end of builtin type list!")(((TypeStr[0] != '.' || TypeStr[1] == 0) && "'.' should only occur at end of builtin type list!" ) ? static_cast<void> (0) : __assert_fail ("(TypeStr[0] != '.' || TypeStr[1] == 0) && \"'.' should only occur at end of builtin type list!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 9723, __PRETTY_FUNCTION__)); | ||||
9724 | |||||
9725 | bool Variadic = (TypeStr[0] == '.'); | ||||
9726 | |||||
9727 | FunctionType::ExtInfo EI(getDefaultCallingConvention( | ||||
9728 | Variadic, /*IsCXXMethod=*/false, /*IsBuiltin=*/true)); | ||||
9729 | if (BuiltinInfo.isNoReturn(Id)) EI = EI.withNoReturn(true); | ||||
9730 | |||||
9731 | |||||
9732 | // We really shouldn't be making a no-proto type here. | ||||
9733 | if (ArgTypes.empty() && Variadic && !getLangOpts().CPlusPlus) | ||||
9734 | return getFunctionNoProtoType(ResType, EI); | ||||
9735 | |||||
9736 | FunctionProtoType::ExtProtoInfo EPI; | ||||
9737 | EPI.ExtInfo = EI; | ||||
9738 | EPI.Variadic = Variadic; | ||||
9739 | if (getLangOpts().CPlusPlus && BuiltinInfo.isNoThrow(Id)) | ||||
9740 | EPI.ExceptionSpec.Type = | ||||
9741 | getLangOpts().CPlusPlus11 ? EST_BasicNoexcept : EST_DynamicNone; | ||||
9742 | |||||
9743 | return getFunctionType(ResType, ArgTypes, EPI); | ||||
9744 | } | ||||
9745 | |||||
9746 | static GVALinkage basicGVALinkageForFunction(const ASTContext &Context, | ||||
9747 | const FunctionDecl *FD) { | ||||
9748 | if (!FD->isExternallyVisible()) | ||||
9749 | return GVA_Internal; | ||||
9750 | |||||
9751 | // Non-user-provided functions get emitted as weak definitions with every | ||||
9752 | // use, no matter whether they've been explicitly instantiated etc. | ||||
9753 | if (const auto *MD = dyn_cast<CXXMethodDecl>(FD)) | ||||
9754 | if (!MD->isUserProvided()) | ||||
9755 | return GVA_DiscardableODR; | ||||
9756 | |||||
9757 | GVALinkage External; | ||||
9758 | switch (FD->getTemplateSpecializationKind()) { | ||||
9759 | case TSK_Undeclared: | ||||
9760 | case TSK_ExplicitSpecialization: | ||||
9761 | External = GVA_StrongExternal; | ||||
9762 | break; | ||||
9763 | |||||
9764 | case TSK_ExplicitInstantiationDefinition: | ||||
9765 | return GVA_StrongODR; | ||||
9766 | |||||
9767 | // C++11 [temp.explicit]p10: | ||||
9768 | // [ Note: The intent is that an inline function that is the subject of | ||||
9769 | // an explicit instantiation declaration will still be implicitly | ||||
9770 | // instantiated when used so that the body can be considered for | ||||
9771 | // inlining, but that no out-of-line copy of the inline function would be | ||||
9772 | // generated in the translation unit. -- end note ] | ||||
9773 | case TSK_ExplicitInstantiationDeclaration: | ||||
9774 | return GVA_AvailableExternally; | ||||
9775 | |||||
9776 | case TSK_ImplicitInstantiation: | ||||
9777 | External = GVA_DiscardableODR; | ||||
9778 | break; | ||||
9779 | } | ||||
9780 | |||||
9781 | if (!FD->isInlined()) | ||||
9782 | return External; | ||||
9783 | |||||
9784 | if ((!Context.getLangOpts().CPlusPlus && | ||||
9785 | !Context.getTargetInfo().getCXXABI().isMicrosoft() && | ||||
9786 | !FD->hasAttr<DLLExportAttr>()) || | ||||
9787 | FD->hasAttr<GNUInlineAttr>()) { | ||||
9788 | // FIXME: This doesn't match gcc's behavior for dllexport inline functions. | ||||
9789 | |||||
9790 | // GNU or C99 inline semantics. Determine whether this symbol should be | ||||
9791 | // externally visible. | ||||
9792 | if (FD->isInlineDefinitionExternallyVisible()) | ||||
9793 | return External; | ||||
9794 | |||||
9795 | // C99 inline semantics, where the symbol is not externally visible. | ||||
9796 | return GVA_AvailableExternally; | ||||
9797 | } | ||||
9798 | |||||
9799 | // Functions specified with extern and inline in -fms-compatibility mode | ||||
9800 | // forcibly get emitted. While the body of the function cannot be later | ||||
9801 | // replaced, the function definition cannot be discarded. | ||||
9802 | if (FD->isMSExternInline()) | ||||
9803 | return GVA_StrongODR; | ||||
9804 | |||||
9805 | return GVA_DiscardableODR; | ||||
9806 | } | ||||
9807 | |||||
9808 | static GVALinkage adjustGVALinkageForAttributes(const ASTContext &Context, | ||||
9809 | const Decl *D, GVALinkage L) { | ||||
9810 | // See http://msdn.microsoft.com/en-us/library/xa0d9ste.aspx | ||||
9811 | // dllexport/dllimport on inline functions. | ||||
9812 | if (D->hasAttr<DLLImportAttr>()) { | ||||
9813 | if (L == GVA_DiscardableODR || L == GVA_StrongODR) | ||||
9814 | return GVA_AvailableExternally; | ||||
9815 | } else if (D->hasAttr<DLLExportAttr>()) { | ||||
9816 | if (L == GVA_DiscardableODR) | ||||
9817 | return GVA_StrongODR; | ||||
9818 | } else if (Context.getLangOpts().CUDA && Context.getLangOpts().CUDAIsDevice && | ||||
9819 | D->hasAttr<CUDAGlobalAttr>()) { | ||||
9820 | // Device-side functions with __global__ attribute must always be | ||||
9821 | // visible externally so they can be launched from host. | ||||
9822 | if (L == GVA_DiscardableODR || L == GVA_Internal) | ||||
9823 | return GVA_StrongODR; | ||||
9824 | } | ||||
9825 | return L; | ||||
9826 | } | ||||
9827 | |||||
9828 | /// Adjust the GVALinkage for a declaration based on what an external AST source | ||||
9829 | /// knows about whether there can be other definitions of this declaration. | ||||
9830 | static GVALinkage | ||||
9831 | adjustGVALinkageForExternalDefinitionKind(const ASTContext &Ctx, const Decl *D, | ||||
9832 | GVALinkage L) { | ||||
9833 | ExternalASTSource *Source = Ctx.getExternalSource(); | ||||
9834 | if (!Source) | ||||
9835 | return L; | ||||
9836 | |||||
9837 | switch (Source->hasExternalDefinitions(D)) { | ||||
9838 | case ExternalASTSource::EK_Never: | ||||
9839 | // Other translation units rely on us to provide the definition. | ||||
9840 | if (L == GVA_DiscardableODR) | ||||
9841 | return GVA_StrongODR; | ||||
9842 | break; | ||||
9843 | |||||
9844 | case ExternalASTSource::EK_Always: | ||||
9845 | return GVA_AvailableExternally; | ||||
9846 | |||||
9847 | case ExternalASTSource::EK_ReplyHazy: | ||||
9848 | break; | ||||
9849 | } | ||||
9850 | return L; | ||||
9851 | } | ||||
9852 | |||||
9853 | GVALinkage ASTContext::GetGVALinkageForFunction(const FunctionDecl *FD) const { | ||||
9854 | return adjustGVALinkageForExternalDefinitionKind(*this, FD, | ||||
9855 | adjustGVALinkageForAttributes(*this, FD, | ||||
9856 | basicGVALinkageForFunction(*this, FD))); | ||||
9857 | } | ||||
9858 | |||||
9859 | static GVALinkage basicGVALinkageForVariable(const ASTContext &Context, | ||||
9860 | const VarDecl *VD) { | ||||
9861 | if (!VD->isExternallyVisible()) | ||||
9862 | return GVA_Internal; | ||||
9863 | |||||
9864 | if (VD->isStaticLocal()) { | ||||
9865 | const DeclContext *LexicalContext = VD->getParentFunctionOrMethod(); | ||||
9866 | while (LexicalContext && !isa<FunctionDecl>(LexicalContext)) | ||||
9867 | LexicalContext = LexicalContext->getLexicalParent(); | ||||
9868 | |||||
9869 | // ObjC Blocks can create local variables that don't have a FunctionDecl | ||||
9870 | // LexicalContext. | ||||
9871 | if (!LexicalContext) | ||||
9872 | return GVA_DiscardableODR; | ||||
9873 | |||||
9874 | // Otherwise, let the static local variable inherit its linkage from the | ||||
9875 | // nearest enclosing function. | ||||
9876 | auto StaticLocalLinkage = | ||||
9877 | Context.GetGVALinkageForFunction(cast<FunctionDecl>(LexicalContext)); | ||||
9878 | |||||
9879 | // Itanium ABI 5.2.2: "Each COMDAT group [for a static local variable] must | ||||
9880 | // be emitted in any object with references to the symbol for the object it | ||||
9881 | // contains, whether inline or out-of-line." | ||||
9882 | // Similar behavior is observed with MSVC. An alternative ABI could use | ||||
9883 | // StrongODR/AvailableExternally to match the function, but none are | ||||
9884 | // known/supported currently. | ||||
9885 | if (StaticLocalLinkage == GVA_StrongODR || | ||||
9886 | StaticLocalLinkage == GVA_AvailableExternally) | ||||
9887 | return GVA_DiscardableODR; | ||||
9888 | return StaticLocalLinkage; | ||||
9889 | } | ||||
9890 | |||||
9891 | // MSVC treats in-class initialized static data members as definitions. | ||||
9892 | // By giving them non-strong linkage, out-of-line definitions won't | ||||
9893 | // cause link errors. | ||||
9894 | if (Context.isMSStaticDataMemberInlineDefinition(VD)) | ||||
9895 | return GVA_DiscardableODR; | ||||
9896 | |||||
9897 | // Most non-template variables have strong linkage; inline variables are | ||||
9898 | // linkonce_odr or (occasionally, for compatibility) weak_odr. | ||||
9899 | GVALinkage StrongLinkage; | ||||
9900 | switch (Context.getInlineVariableDefinitionKind(VD)) { | ||||
9901 | case ASTContext::InlineVariableDefinitionKind::None: | ||||
9902 | StrongLinkage = GVA_StrongExternal; | ||||
9903 | break; | ||||
9904 | case ASTContext::InlineVariableDefinitionKind::Weak: | ||||
9905 | case ASTContext::InlineVariableDefinitionKind::WeakUnknown: | ||||
9906 | StrongLinkage = GVA_DiscardableODR; | ||||
9907 | break; | ||||
9908 | case ASTContext::InlineVariableDefinitionKind::Strong: | ||||
9909 | StrongLinkage = GVA_StrongODR; | ||||
9910 | break; | ||||
9911 | } | ||||
9912 | |||||
9913 | switch (VD->getTemplateSpecializationKind()) { | ||||
9914 | case TSK_Undeclared: | ||||
9915 | return StrongLinkage; | ||||
9916 | |||||
9917 | case TSK_ExplicitSpecialization: | ||||
9918 | return Context.getTargetInfo().getCXXABI().isMicrosoft() && | ||||
9919 | VD->isStaticDataMember() | ||||
9920 | ? GVA_StrongODR | ||||
9921 | : StrongLinkage; | ||||
9922 | |||||
9923 | case TSK_ExplicitInstantiationDefinition: | ||||
9924 | return GVA_StrongODR; | ||||
9925 | |||||
9926 | case TSK_ExplicitInstantiationDeclaration: | ||||
9927 | return GVA_AvailableExternally; | ||||
9928 | |||||
9929 | case TSK_ImplicitInstantiation: | ||||
9930 | return GVA_DiscardableODR; | ||||
9931 | } | ||||
9932 | |||||
9933 | llvm_unreachable("Invalid Linkage!")::llvm::llvm_unreachable_internal("Invalid Linkage!", "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 9933); | ||||
9934 | } | ||||
9935 | |||||
9936 | GVALinkage ASTContext::GetGVALinkageForVariable(const VarDecl *VD) { | ||||
9937 | return adjustGVALinkageForExternalDefinitionKind(*this, VD, | ||||
9938 | adjustGVALinkageForAttributes(*this, VD, | ||||
9939 | basicGVALinkageForVariable(*this, VD))); | ||||
9940 | } | ||||
9941 | |||||
9942 | bool ASTContext::DeclMustBeEmitted(const Decl *D) { | ||||
9943 | if (const auto *VD = dyn_cast<VarDecl>(D)) { | ||||
9944 | if (!VD->isFileVarDecl()) | ||||
9945 | return false; | ||||
9946 | // Global named register variables (GNU extension) are never emitted. | ||||
9947 | if (VD->getStorageClass() == SC_Register) | ||||
9948 | return false; | ||||
9949 | if (VD->getDescribedVarTemplate() || | ||||
9950 | isa<VarTemplatePartialSpecializationDecl>(VD)) | ||||
9951 | return false; | ||||
9952 | } else if (const auto *FD = dyn_cast<FunctionDecl>(D)) { | ||||
9953 | // We never need to emit an uninstantiated function template. | ||||
9954 | if (FD->getTemplatedKind() == FunctionDecl::TK_FunctionTemplate) | ||||
9955 | return false; | ||||
9956 | } else if (isa<PragmaCommentDecl>(D)) | ||||
9957 | return true; | ||||
9958 | else if (isa<PragmaDetectMismatchDecl>(D)) | ||||
9959 | return true; | ||||
9960 | else if (isa<OMPThreadPrivateDecl>(D)) | ||||
9961 | return !D->getDeclContext()->isDependentContext(); | ||||
9962 | else if (isa<OMPAllocateDecl>(D)) | ||||
9963 | return !D->getDeclContext()->isDependentContext(); | ||||
9964 | else if (isa<OMPDeclareReductionDecl>(D) || isa<OMPDeclareMapperDecl>(D)) | ||||
9965 | return !D->getDeclContext()->isDependentContext(); | ||||
9966 | else if (isa<ImportDecl>(D)) | ||||
9967 | return true; | ||||
9968 | else | ||||
9969 | return false; | ||||
9970 | |||||
9971 | if (D->isFromASTFile() && !LangOpts.BuildingPCHWithObjectFile) { | ||||
9972 | assert(getExternalSource() && "It's from an AST file; must have a source.")((getExternalSource() && "It's from an AST file; must have a source." ) ? static_cast<void> (0) : __assert_fail ("getExternalSource() && \"It's from an AST file; must have a source.\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 9972, __PRETTY_FUNCTION__)); | ||||
9973 | // On Windows, PCH files are built together with an object file. If this | ||||
9974 | // declaration comes from such a PCH and DeclMustBeEmitted would return | ||||
9975 | // true, it would have returned true and the decl would have been emitted | ||||
9976 | // into that object file, so it doesn't need to be emitted here. | ||||
9977 | // Note that decls are still emitted if they're referenced, as usual; | ||||
9978 | // DeclMustBeEmitted is used to decide whether a decl must be emitted even | ||||
9979 | // if it's not referenced. | ||||
9980 | // | ||||
9981 | // Explicit template instantiation definitions are tricky. If there was an | ||||
9982 | // explicit template instantiation decl in the PCH before, it will look like | ||||
9983 | // the definition comes from there, even if that was just the declaration. | ||||
9984 | // (Explicit instantiation defs of variable templates always get emitted.) | ||||
9985 | bool IsExpInstDef = | ||||
9986 | isa<FunctionDecl>(D) && | ||||
9987 | cast<FunctionDecl>(D)->getTemplateSpecializationKind() == | ||||
9988 | TSK_ExplicitInstantiationDefinition; | ||||
9989 | |||||
9990 | // Implicit member function definitions, such as operator= might not be | ||||
9991 | // marked as template specializations, since they're not coming from a | ||||
9992 | // template but synthesized directly on the class. | ||||
9993 | IsExpInstDef |= | ||||
9994 | isa<CXXMethodDecl>(D) && | ||||
9995 | cast<CXXMethodDecl>(D)->getParent()->getTemplateSpecializationKind() == | ||||
9996 | TSK_ExplicitInstantiationDefinition; | ||||
9997 | |||||
9998 | if (getExternalSource()->DeclIsFromPCHWithObjectFile(D) && !IsExpInstDef) | ||||
9999 | return false; | ||||
10000 | } | ||||
10001 | |||||
10002 | // If this is a member of a class template, we do not need to emit it. | ||||
10003 | if (D->getDeclContext()->isDependentContext()) | ||||
10004 | return false; | ||||
10005 | |||||
10006 | // Weak references don't produce any output by themselves. | ||||
10007 | if (D->hasAttr<WeakRefAttr>()) | ||||
10008 | return false; | ||||
10009 | |||||
10010 | // Aliases and used decls are required. | ||||
10011 | if (D->hasAttr<AliasAttr>() || D->hasAttr<UsedAttr>()) | ||||
10012 | return true; | ||||
10013 | |||||
10014 | if (const auto *FD = dyn_cast<FunctionDecl>(D)) { | ||||
10015 | // Forward declarations aren't required. | ||||
10016 | if (!FD->doesThisDeclarationHaveABody()) | ||||
10017 | return FD->doesDeclarationForceExternallyVisibleDefinition(); | ||||
10018 | |||||
10019 | // Constructors and destructors are required. | ||||
10020 | if (FD->hasAttr<ConstructorAttr>() || FD->hasAttr<DestructorAttr>()) | ||||
10021 | return true; | ||||
10022 | |||||
10023 | // The key function for a class is required. This rule only comes | ||||
10024 | // into play when inline functions can be key functions, though. | ||||
10025 | if (getTargetInfo().getCXXABI().canKeyFunctionBeInline()) { | ||||
10026 | if (const auto *MD = dyn_cast<CXXMethodDecl>(FD)) { | ||||
10027 | const CXXRecordDecl *RD = MD->getParent(); | ||||
10028 | if (MD->isOutOfLine() && RD->isDynamicClass()) { | ||||
10029 | const CXXMethodDecl *KeyFunc = getCurrentKeyFunction(RD); | ||||
10030 | if (KeyFunc && KeyFunc->getCanonicalDecl() == MD->getCanonicalDecl()) | ||||
10031 | return true; | ||||
10032 | } | ||||
10033 | } | ||||
10034 | } | ||||
10035 | |||||
10036 | GVALinkage Linkage = GetGVALinkageForFunction(FD); | ||||
10037 | |||||
10038 | // static, static inline, always_inline, and extern inline functions can | ||||
10039 | // always be deferred. Normal inline functions can be deferred in C99/C++. | ||||
10040 | // Implicit template instantiations can also be deferred in C++. | ||||
10041 | return !isDiscardableGVALinkage(Linkage); | ||||
10042 | } | ||||
10043 | |||||
10044 | const auto *VD = cast<VarDecl>(D); | ||||
10045 | assert(VD->isFileVarDecl() && "Expected file scoped var")((VD->isFileVarDecl() && "Expected file scoped var" ) ? static_cast<void> (0) : __assert_fail ("VD->isFileVarDecl() && \"Expected file scoped var\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 10045, __PRETTY_FUNCTION__)); | ||||
10046 | |||||
10047 | // If the decl is marked as `declare target to`, it should be emitted for the | ||||
10048 | // host and for the device. | ||||
10049 | if (LangOpts.OpenMP && | ||||
10050 | OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) | ||||
10051 | return true; | ||||
10052 | |||||
10053 | if (VD->isThisDeclarationADefinition() == VarDecl::DeclarationOnly && | ||||
10054 | !isMSStaticDataMemberInlineDefinition(VD)) | ||||
10055 | return false; | ||||
10056 | |||||
10057 | // Variables that can be needed in other TUs are required. | ||||
10058 | auto Linkage = GetGVALinkageForVariable(VD); | ||||
10059 | if (!isDiscardableGVALinkage(Linkage)) | ||||
10060 | return true; | ||||
10061 | |||||
10062 | // We never need to emit a variable that is available in another TU. | ||||
10063 | if (Linkage == GVA_AvailableExternally) | ||||
10064 | return false; | ||||
10065 | |||||
10066 | // Variables that have destruction with side-effects are required. | ||||
10067 | if (VD->needsDestruction(*this)) | ||||
10068 | return true; | ||||
10069 | |||||
10070 | // Variables that have initialization with side-effects are required. | ||||
10071 | if (VD->getInit() && VD->getInit()->HasSideEffects(*this) && | ||||
10072 | // We can get a value-dependent initializer during error recovery. | ||||
10073 | (VD->getInit()->isValueDependent() || !VD->evaluateValue())) | ||||
10074 | return true; | ||||
10075 | |||||
10076 | // Likewise, variables with tuple-like bindings are required if their | ||||
10077 | // bindings have side-effects. | ||||
10078 | if (const auto *DD = dyn_cast<DecompositionDecl>(VD)) | ||||
10079 | for (const auto *BD : DD->bindings()) | ||||
10080 | if (const auto *BindingVD = BD->getHoldingVar()) | ||||
10081 | if (DeclMustBeEmitted(BindingVD)) | ||||
10082 | return true; | ||||
10083 | |||||
10084 | return false; | ||||
10085 | } | ||||
10086 | |||||
10087 | void ASTContext::forEachMultiversionedFunctionVersion( | ||||
10088 | const FunctionDecl *FD, | ||||
10089 | llvm::function_ref<void(FunctionDecl *)> Pred) const { | ||||
10090 | assert(FD->isMultiVersion() && "Only valid for multiversioned functions")((FD->isMultiVersion() && "Only valid for multiversioned functions" ) ? static_cast<void> (0) : __assert_fail ("FD->isMultiVersion() && \"Only valid for multiversioned functions\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 10090, __PRETTY_FUNCTION__)); | ||||
10091 | llvm::SmallDenseSet<const FunctionDecl*, 4> SeenDecls; | ||||
10092 | FD = FD->getMostRecentDecl(); | ||||
10093 | for (auto *CurDecl : | ||||
10094 | FD->getDeclContext()->getRedeclContext()->lookup(FD->getDeclName())) { | ||||
10095 | FunctionDecl *CurFD = CurDecl->getAsFunction()->getMostRecentDecl(); | ||||
10096 | if (CurFD && hasSameType(CurFD->getType(), FD->getType()) && | ||||
10097 | std::end(SeenDecls) == llvm::find(SeenDecls, CurFD)) { | ||||
10098 | SeenDecls.insert(CurFD); | ||||
10099 | Pred(CurFD); | ||||
10100 | } | ||||
10101 | } | ||||
10102 | } | ||||
10103 | |||||
10104 | CallingConv ASTContext::getDefaultCallingConvention(bool IsVariadic, | ||||
10105 | bool IsCXXMethod, | ||||
10106 | bool IsBuiltin) const { | ||||
10107 | // Pass through to the C++ ABI object | ||||
10108 | if (IsCXXMethod) | ||||
10109 | return ABI->getDefaultMethodCallConv(IsVariadic); | ||||
10110 | |||||
10111 | // Builtins ignore user-specified default calling convention and remain the | ||||
10112 | // Target's default calling convention. | ||||
10113 | if (!IsBuiltin) { | ||||
10114 | switch (LangOpts.getDefaultCallingConv()) { | ||||
10115 | case LangOptions::DCC_None: | ||||
10116 | break; | ||||
10117 | case LangOptions::DCC_CDecl: | ||||
10118 | return CC_C; | ||||
10119 | case LangOptions::DCC_FastCall: | ||||
10120 | if (getTargetInfo().hasFeature("sse2") && !IsVariadic) | ||||
10121 | return CC_X86FastCall; | ||||
10122 | break; | ||||
10123 | case LangOptions::DCC_StdCall: | ||||
10124 | if (!IsVariadic) | ||||
10125 | return CC_X86StdCall; | ||||
10126 | break; | ||||
10127 | case LangOptions::DCC_VectorCall: | ||||
10128 | // __vectorcall cannot be applied to variadic functions. | ||||
10129 | if (!IsVariadic) | ||||
10130 | return CC_X86VectorCall; | ||||
10131 | break; | ||||
10132 | case LangOptions::DCC_RegCall: | ||||
10133 | // __regcall cannot be applied to variadic functions. | ||||
10134 | if (!IsVariadic) | ||||
10135 | return CC_X86RegCall; | ||||
10136 | break; | ||||
10137 | } | ||||
10138 | } | ||||
10139 | return Target->getDefaultCallingConv(); | ||||
10140 | } | ||||
10141 | |||||
10142 | bool ASTContext::isNearlyEmpty(const CXXRecordDecl *RD) const { | ||||
10143 | // Pass through to the C++ ABI object | ||||
10144 | return ABI->isNearlyEmpty(RD); | ||||
10145 | } | ||||
10146 | |||||
10147 | VTableContextBase *ASTContext::getVTableContext() { | ||||
10148 | if (!VTContext.get()) { | ||||
10149 | if (Target->getCXXABI().isMicrosoft()) | ||||
10150 | VTContext.reset(new MicrosoftVTableContext(*this)); | ||||
10151 | else | ||||
10152 | VTContext.reset(new ItaniumVTableContext(*this)); | ||||
10153 | } | ||||
10154 | return VTContext.get(); | ||||
10155 | } | ||||
10156 | |||||
10157 | MangleContext *ASTContext::createMangleContext(const TargetInfo *T) { | ||||
10158 | if (!T) | ||||
10159 | T = Target; | ||||
10160 | switch (T->getCXXABI().getKind()) { | ||||
10161 | case TargetCXXABI::GenericAArch64: | ||||
10162 | case TargetCXXABI::GenericItanium: | ||||
10163 | case TargetCXXABI::GenericARM: | ||||
10164 | case TargetCXXABI::GenericMIPS: | ||||
10165 | case TargetCXXABI::iOS: | ||||
10166 | case TargetCXXABI::iOS64: | ||||
10167 | case TargetCXXABI::WebAssembly: | ||||
10168 | case TargetCXXABI::WatchOS: | ||||
10169 | return ItaniumMangleContext::create(*this, getDiagnostics()); | ||||
10170 | case TargetCXXABI::Microsoft: | ||||
10171 | return MicrosoftMangleContext::create(*this, getDiagnostics()); | ||||
10172 | } | ||||
10173 | llvm_unreachable("Unsupported ABI")::llvm::llvm_unreachable_internal("Unsupported ABI", "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 10173); | ||||
10174 | } | ||||
10175 | |||||
10176 | CXXABI::~CXXABI() = default; | ||||
10177 | |||||
10178 | size_t ASTContext::getSideTableAllocatedMemory() const { | ||||
10179 | return ASTRecordLayouts.getMemorySize() + | ||||
10180 | llvm::capacity_in_bytes(ObjCLayouts) + | ||||
10181 | llvm::capacity_in_bytes(KeyFunctions) + | ||||
10182 | llvm::capacity_in_bytes(ObjCImpls) + | ||||
10183 | llvm::capacity_in_bytes(BlockVarCopyInits) + | ||||
10184 | llvm::capacity_in_bytes(DeclAttrs) + | ||||
10185 | llvm::capacity_in_bytes(TemplateOrInstantiation) + | ||||
10186 | llvm::capacity_in_bytes(InstantiatedFromUsingDecl) + | ||||
10187 | llvm::capacity_in_bytes(InstantiatedFromUsingShadowDecl) + | ||||
10188 | llvm::capacity_in_bytes(InstantiatedFromUnnamedFieldDecl) + | ||||
10189 | llvm::capacity_in_bytes(OverriddenMethods) + | ||||
10190 | llvm::capacity_in_bytes(Types) + | ||||
10191 | llvm::capacity_in_bytes(VariableArrayTypes); | ||||
10192 | } | ||||
10193 | |||||
10194 | /// getIntTypeForBitwidth - | ||||
10195 | /// sets integer QualTy according to specified details: | ||||
10196 | /// bitwidth, signed/unsigned. | ||||
10197 | /// Returns empty type if there is no appropriate target types. | ||||
10198 | QualType ASTContext::getIntTypeForBitwidth(unsigned DestWidth, | ||||
10199 | unsigned Signed) const { | ||||
10200 | TargetInfo::IntType Ty = getTargetInfo().getIntTypeByWidth(DestWidth, Signed); | ||||
10201 | CanQualType QualTy = getFromTargetType(Ty); | ||||
10202 | if (!QualTy && DestWidth == 128) | ||||
10203 | return Signed ? Int128Ty : UnsignedInt128Ty; | ||||
10204 | return QualTy; | ||||
10205 | } | ||||
10206 | |||||
10207 | /// getRealTypeForBitwidth - | ||||
10208 | /// sets floating point QualTy according to specified bitwidth. | ||||
10209 | /// Returns empty type if there is no appropriate target types. | ||||
10210 | QualType ASTContext::getRealTypeForBitwidth(unsigned DestWidth) const { | ||||
10211 | TargetInfo::RealType Ty = getTargetInfo().getRealTypeByWidth(DestWidth); | ||||
10212 | switch (Ty) { | ||||
10213 | case TargetInfo::Float: | ||||
10214 | return FloatTy; | ||||
10215 | case TargetInfo::Double: | ||||
10216 | return DoubleTy; | ||||
10217 | case TargetInfo::LongDouble: | ||||
10218 | return LongDoubleTy; | ||||
10219 | case TargetInfo::Float128: | ||||
10220 | return Float128Ty; | ||||
10221 | case TargetInfo::NoFloat: | ||||
10222 | return {}; | ||||
10223 | } | ||||
10224 | |||||
10225 | llvm_unreachable("Unhandled TargetInfo::RealType value")::llvm::llvm_unreachable_internal("Unhandled TargetInfo::RealType value" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 10225); | ||||
10226 | } | ||||
10227 | |||||
10228 | void ASTContext::setManglingNumber(const NamedDecl *ND, unsigned Number) { | ||||
10229 | if (Number > 1) | ||||
10230 | MangleNumbers[ND] = Number; | ||||
10231 | } | ||||
10232 | |||||
10233 | unsigned ASTContext::getManglingNumber(const NamedDecl *ND) const { | ||||
10234 | auto I = MangleNumbers.find(ND); | ||||
10235 | return I != MangleNumbers.end() ? I->second : 1; | ||||
10236 | } | ||||
10237 | |||||
10238 | void ASTContext::setStaticLocalNumber(const VarDecl *VD, unsigned Number) { | ||||
10239 | if (Number > 1) | ||||
10240 | StaticLocalNumbers[VD] = Number; | ||||
10241 | } | ||||
10242 | |||||
10243 | unsigned ASTContext::getStaticLocalNumber(const VarDecl *VD) const { | ||||
10244 | auto I = StaticLocalNumbers.find(VD); | ||||
10245 | return I != StaticLocalNumbers.end() ? I->second : 1; | ||||
10246 | } | ||||
10247 | |||||
10248 | MangleNumberingContext & | ||||
10249 | ASTContext::getManglingNumberContext(const DeclContext *DC) { | ||||
10250 | assert(LangOpts.CPlusPlus)((LangOpts.CPlusPlus) ? static_cast<void> (0) : __assert_fail ("LangOpts.CPlusPlus", "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 10250, __PRETTY_FUNCTION__)); // We don't need mangling numbers for plain C. | ||||
10251 | std::unique_ptr<MangleNumberingContext> &MCtx = MangleNumberingContexts[DC]; | ||||
10252 | if (!MCtx) | ||||
10253 | MCtx = createMangleNumberingContext(); | ||||
10254 | return *MCtx; | ||||
10255 | } | ||||
10256 | |||||
10257 | std::unique_ptr<MangleNumberingContext> | ||||
10258 | ASTContext::createMangleNumberingContext() const { | ||||
10259 | return ABI->createMangleNumberingContext(); | ||||
10260 | } | ||||
10261 | |||||
10262 | const CXXConstructorDecl * | ||||
10263 | ASTContext::getCopyConstructorForExceptionObject(CXXRecordDecl *RD) { | ||||
10264 | return ABI->getCopyConstructorForExceptionObject( | ||||
10265 | cast<CXXRecordDecl>(RD->getFirstDecl())); | ||||
10266 | } | ||||
10267 | |||||
10268 | void ASTContext::addCopyConstructorForExceptionObject(CXXRecordDecl *RD, | ||||
10269 | CXXConstructorDecl *CD) { | ||||
10270 | return ABI->addCopyConstructorForExceptionObject( | ||||
10271 | cast<CXXRecordDecl>(RD->getFirstDecl()), | ||||
10272 | cast<CXXConstructorDecl>(CD->getFirstDecl())); | ||||
10273 | } | ||||
10274 | |||||
10275 | void ASTContext::addTypedefNameForUnnamedTagDecl(TagDecl *TD, | ||||
10276 | TypedefNameDecl *DD) { | ||||
10277 | return ABI->addTypedefNameForUnnamedTagDecl(TD, DD); | ||||
10278 | } | ||||
10279 | |||||
10280 | TypedefNameDecl * | ||||
10281 | ASTContext::getTypedefNameForUnnamedTagDecl(const TagDecl *TD) { | ||||
10282 | return ABI->getTypedefNameForUnnamedTagDecl(TD); | ||||
10283 | } | ||||
10284 | |||||
10285 | void ASTContext::addDeclaratorForUnnamedTagDecl(TagDecl *TD, | ||||
10286 | DeclaratorDecl *DD) { | ||||
10287 | return ABI->addDeclaratorForUnnamedTagDecl(TD, DD); | ||||
10288 | } | ||||
10289 | |||||
10290 | DeclaratorDecl *ASTContext::getDeclaratorForUnnamedTagDecl(const TagDecl *TD) { | ||||
10291 | return ABI->getDeclaratorForUnnamedTagDecl(TD); | ||||
10292 | } | ||||
10293 | |||||
10294 | void ASTContext::setParameterIndex(const ParmVarDecl *D, unsigned int index) { | ||||
10295 | ParamIndices[D] = index; | ||||
10296 | } | ||||
10297 | |||||
10298 | unsigned ASTContext::getParameterIndex(const ParmVarDecl *D) const { | ||||
10299 | ParameterIndexTable::const_iterator I = ParamIndices.find(D); | ||||
10300 | assert(I != ParamIndices.end() &&((I != ParamIndices.end() && "ParmIndices lacks entry set by ParmVarDecl" ) ? static_cast<void> (0) : __assert_fail ("I != ParamIndices.end() && \"ParmIndices lacks entry set by ParmVarDecl\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 10301, __PRETTY_FUNCTION__)) | ||||
10301 | "ParmIndices lacks entry set by ParmVarDecl")((I != ParamIndices.end() && "ParmIndices lacks entry set by ParmVarDecl" ) ? static_cast<void> (0) : __assert_fail ("I != ParamIndices.end() && \"ParmIndices lacks entry set by ParmVarDecl\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 10301, __PRETTY_FUNCTION__)); | ||||
10302 | return I->second; | ||||
10303 | } | ||||
10304 | |||||
10305 | APValue * | ||||
10306 | ASTContext::getMaterializedTemporaryValue(const MaterializeTemporaryExpr *E, | ||||
10307 | bool MayCreate) { | ||||
10308 | assert(E && E->getStorageDuration() == SD_Static &&((E && E->getStorageDuration() == SD_Static && "don't need to cache the computed value for this temporary") ? static_cast<void> (0) : __assert_fail ("E && E->getStorageDuration() == SD_Static && \"don't need to cache the computed value for this temporary\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 10309, __PRETTY_FUNCTION__)) | ||||
10309 | "don't need to cache the computed value for this temporary")((E && E->getStorageDuration() == SD_Static && "don't need to cache the computed value for this temporary") ? static_cast<void> (0) : __assert_fail ("E && E->getStorageDuration() == SD_Static && \"don't need to cache the computed value for this temporary\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 10309, __PRETTY_FUNCTION__)); | ||||
10310 | if (MayCreate) { | ||||
10311 | APValue *&MTVI = MaterializedTemporaryValues[E]; | ||||
10312 | if (!MTVI) | ||||
10313 | MTVI = new (*this) APValue; | ||||
10314 | return MTVI; | ||||
10315 | } | ||||
10316 | |||||
10317 | return MaterializedTemporaryValues.lookup(E); | ||||
10318 | } | ||||
10319 | |||||
10320 | QualType ASTContext::getStringLiteralArrayType(QualType EltTy, | ||||
10321 | unsigned Length) const { | ||||
10322 | // A C++ string literal has a const-qualified element type (C++ 2.13.4p1). | ||||
10323 | if (getLangOpts().CPlusPlus || getLangOpts().ConstStrings) | ||||
10324 | EltTy = EltTy.withConst(); | ||||
10325 | |||||
10326 | EltTy = adjustStringLiteralBaseType(EltTy); | ||||
10327 | |||||
10328 | // Get an array type for the string, according to C99 6.4.5. This includes | ||||
10329 | // the null terminator character. | ||||
10330 | return getConstantArrayType(EltTy, llvm::APInt(32, Length + 1), | ||||
10331 | ArrayType::Normal, /*IndexTypeQuals*/ 0); | ||||
10332 | } | ||||
10333 | |||||
10334 | StringLiteral * | ||||
10335 | ASTContext::getPredefinedStringLiteralFromCache(StringRef Key) const { | ||||
10336 | StringLiteral *&Result = StringLiteralCache[Key]; | ||||
10337 | if (!Result) | ||||
10338 | Result = StringLiteral::Create( | ||||
10339 | *this, Key, StringLiteral::Ascii, | ||||
10340 | /*Pascal*/ false, getStringLiteralArrayType(CharTy, Key.size()), | ||||
10341 | SourceLocation()); | ||||
10342 | return Result; | ||||
10343 | } | ||||
10344 | |||||
10345 | bool ASTContext::AtomicUsesUnsupportedLibcall(const AtomicExpr *E) const { | ||||
10346 | const llvm::Triple &T = getTargetInfo().getTriple(); | ||||
10347 | if (!T.isOSDarwin()) | ||||
10348 | return false; | ||||
10349 | |||||
10350 | if (!(T.isiOS() && T.isOSVersionLT(7)) && | ||||
10351 | !(T.isMacOSX() && T.isOSVersionLT(10, 9))) | ||||
10352 | return false; | ||||
10353 | |||||
10354 | QualType AtomicTy = E->getPtr()->getType()->getPointeeType(); | ||||
10355 | CharUnits sizeChars = getTypeSizeInChars(AtomicTy); | ||||
10356 | uint64_t Size = sizeChars.getQuantity(); | ||||
10357 | CharUnits alignChars = getTypeAlignInChars(AtomicTy); | ||||
10358 | unsigned Align = alignChars.getQuantity(); | ||||
10359 | unsigned MaxInlineWidthInBits = getTargetInfo().getMaxAtomicInlineWidth(); | ||||
10360 | return (Size != Align || toBits(sizeChars) > MaxInlineWidthInBits); | ||||
10361 | } | ||||
10362 | |||||
10363 | /// Template specializations to abstract away from pointers and TypeLocs. | ||||
10364 | /// @{ | ||||
10365 | template <typename T> | ||||
10366 | static ast_type_traits::DynTypedNode createDynTypedNode(const T &Node) { | ||||
10367 | return ast_type_traits::DynTypedNode::create(*Node); | ||||
10368 | } | ||||
10369 | template <> | ||||
10370 | ast_type_traits::DynTypedNode createDynTypedNode(const TypeLoc &Node) { | ||||
10371 | return ast_type_traits::DynTypedNode::create(Node); | ||||
10372 | } | ||||
10373 | template <> | ||||
10374 | ast_type_traits::DynTypedNode | ||||
10375 | createDynTypedNode(const NestedNameSpecifierLoc &Node) { | ||||
10376 | return ast_type_traits::DynTypedNode::create(Node); | ||||
10377 | } | ||||
10378 | /// @} | ||||
10379 | |||||
10380 | /// A \c RecursiveASTVisitor that builds a map from nodes to their | ||||
10381 | /// parents as defined by the \c RecursiveASTVisitor. | ||||
10382 | /// | ||||
10383 | /// Note that the relationship described here is purely in terms of AST | ||||
10384 | /// traversal - there are other relationships (for example declaration context) | ||||
10385 | /// in the AST that are better modeled by special matchers. | ||||
10386 | /// | ||||
10387 | /// FIXME: Currently only builds up the map using \c Stmt and \c Decl nodes. | ||||
10388 | class ASTContext::ParentMap::ASTVisitor | ||||
10389 | : public RecursiveASTVisitor<ASTVisitor> { | ||||
10390 | public: | ||||
10391 | ASTVisitor(ParentMap &Map) : Map(Map) {} | ||||
10392 | |||||
10393 | private: | ||||
10394 | friend class RecursiveASTVisitor<ASTVisitor>; | ||||
10395 | |||||
10396 | using VisitorBase = RecursiveASTVisitor<ASTVisitor>; | ||||
10397 | |||||
10398 | bool shouldVisitTemplateInstantiations() const { return true; } | ||||
10399 | |||||
10400 | bool shouldVisitImplicitCode() const { return true; } | ||||
10401 | |||||
10402 | template <typename T, typename MapNodeTy, typename BaseTraverseFn, | ||||
10403 | typename MapTy> | ||||
10404 | bool TraverseNode(T Node, MapNodeTy MapNode, BaseTraverseFn BaseTraverse, | ||||
10405 | MapTy *Parents) { | ||||
10406 | if (!Node) | ||||
10407 | return true; | ||||
10408 | if (ParentStack.size() > 0) { | ||||
10409 | // FIXME: Currently we add the same parent multiple times, but only | ||||
10410 | // when no memoization data is available for the type. | ||||
10411 | // For example when we visit all subexpressions of template | ||||
10412 | // instantiations; this is suboptimal, but benign: the only way to | ||||
10413 | // visit those is with hasAncestor / hasParent, and those do not create | ||||
10414 | // new matches. | ||||
10415 | // The plan is to enable DynTypedNode to be storable in a map or hash | ||||
10416 | // map. The main problem there is to implement hash functions / | ||||
10417 | // comparison operators for all types that DynTypedNode supports that | ||||
10418 | // do not have pointer identity. | ||||
10419 | auto &NodeOrVector = (*Parents)[MapNode]; | ||||
10420 | if (NodeOrVector.isNull()) { | ||||
10421 | if (const auto *D = ParentStack.back().get<Decl>()) | ||||
10422 | NodeOrVector = D; | ||||
10423 | else if (const auto *S = ParentStack.back().get<Stmt>()) | ||||
10424 | NodeOrVector = S; | ||||
10425 | else | ||||
10426 | NodeOrVector = new ast_type_traits::DynTypedNode(ParentStack.back()); | ||||
10427 | } else { | ||||
10428 | if (!NodeOrVector.template is<ParentVector *>()) { | ||||
10429 | auto *Vector = new ParentVector( | ||||
10430 | 1, getSingleDynTypedNodeFromParentMap(NodeOrVector)); | ||||
10431 | delete NodeOrVector | ||||
10432 | .template dyn_cast<ast_type_traits::DynTypedNode *>(); | ||||
10433 | NodeOrVector = Vector; | ||||
10434 | } | ||||
10435 | |||||
10436 | auto *Vector = NodeOrVector.template get<ParentVector *>(); | ||||
10437 | // Skip duplicates for types that have memoization data. | ||||
10438 | // We must check that the type has memoization data before calling | ||||
10439 | // std::find() because DynTypedNode::operator== can't compare all | ||||
10440 | // types. | ||||
10441 | bool Found = ParentStack.back().getMemoizationData() && | ||||
10442 | std::find(Vector->begin(), Vector->end(), | ||||
10443 | ParentStack.back()) != Vector->end(); | ||||
10444 | if (!Found) | ||||
10445 | Vector->push_back(ParentStack.back()); | ||||
10446 | } | ||||
10447 | } | ||||
10448 | ParentStack.push_back(createDynTypedNode(Node)); | ||||
10449 | bool Result = BaseTraverse(); | ||||
10450 | ParentStack.pop_back(); | ||||
10451 | return Result; | ||||
10452 | } | ||||
10453 | |||||
10454 | bool TraverseDecl(Decl *DeclNode) { | ||||
10455 | return TraverseNode( | ||||
10456 | DeclNode, DeclNode, [&] { return VisitorBase::TraverseDecl(DeclNode); }, | ||||
10457 | &Map.PointerParents); | ||||
10458 | } | ||||
10459 | |||||
10460 | bool TraverseStmt(Stmt *StmtNode) { | ||||
10461 | return TraverseNode( | ||||
10462 | StmtNode, StmtNode, [&] { return VisitorBase::TraverseStmt(StmtNode); }, | ||||
10463 | &Map.PointerParents); | ||||
10464 | } | ||||
10465 | |||||
10466 | bool TraverseTypeLoc(TypeLoc TypeLocNode) { | ||||
10467 | return TraverseNode( | ||||
10468 | TypeLocNode, ast_type_traits::DynTypedNode::create(TypeLocNode), | ||||
10469 | [&] { return VisitorBase::TraverseTypeLoc(TypeLocNode); }, | ||||
10470 | &Map.OtherParents); | ||||
10471 | } | ||||
10472 | |||||
10473 | bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNSLocNode) { | ||||
10474 | return TraverseNode( | ||||
10475 | NNSLocNode, ast_type_traits::DynTypedNode::create(NNSLocNode), | ||||
10476 | [&] { return VisitorBase::TraverseNestedNameSpecifierLoc(NNSLocNode); }, | ||||
10477 | &Map.OtherParents); | ||||
10478 | } | ||||
10479 | |||||
10480 | ParentMap ⤅ | ||||
10481 | llvm::SmallVector<ast_type_traits::DynTypedNode, 16> ParentStack; | ||||
10482 | }; | ||||
10483 | |||||
10484 | ASTContext::ParentMap::ParentMap(ASTContext &Ctx) { | ||||
10485 | ASTVisitor(*this).TraverseAST(Ctx); | ||||
10486 | } | ||||
10487 | |||||
10488 | ASTContext::DynTypedNodeList | ||||
10489 | ASTContext::getParents(const ast_type_traits::DynTypedNode &Node) { | ||||
10490 | if (!Parents) | ||||
10491 | // We build the parent map for the traversal scope (usually whole TU), as | ||||
10492 | // hasAncestor can escape any subtree. | ||||
10493 | Parents = std::make_unique<ParentMap>(*this); | ||||
10494 | return Parents->getParents(Node); | ||||
10495 | } | ||||
10496 | |||||
10497 | bool | ||||
10498 | ASTContext::ObjCMethodsAreEqual(const ObjCMethodDecl *MethodDecl, | ||||
10499 | const ObjCMethodDecl *MethodImpl) { | ||||
10500 | // No point trying to match an unavailable/deprecated mothod. | ||||
10501 | if (MethodDecl->hasAttr<UnavailableAttr>() | ||||
10502 | || MethodDecl->hasAttr<DeprecatedAttr>()) | ||||
10503 | return false; | ||||
10504 | if (MethodDecl->getObjCDeclQualifier() != | ||||
10505 | MethodImpl->getObjCDeclQualifier()) | ||||
10506 | return false; | ||||
10507 | if (!hasSameType(MethodDecl->getReturnType(), MethodImpl->getReturnType())) | ||||
10508 | return false; | ||||
10509 | |||||
10510 | if (MethodDecl->param_size() != MethodImpl->param_size()) | ||||
10511 | return false; | ||||
10512 | |||||
10513 | for (ObjCMethodDecl::param_const_iterator IM = MethodImpl->param_begin(), | ||||
10514 | IF = MethodDecl->param_begin(), EM = MethodImpl->param_end(), | ||||
10515 | EF = MethodDecl->param_end(); | ||||
10516 | IM != EM && IF != EF; ++IM, ++IF) { | ||||
10517 | const ParmVarDecl *DeclVar = (*IF); | ||||
10518 | const ParmVarDecl *ImplVar = (*IM); | ||||
10519 | if (ImplVar->getObjCDeclQualifier() != DeclVar->getObjCDeclQualifier()) | ||||
10520 | return false; | ||||
10521 | if (!hasSameType(DeclVar->getType(), ImplVar->getType())) | ||||
10522 | return false; | ||||
10523 | } | ||||
10524 | |||||
10525 | return (MethodDecl->isVariadic() == MethodImpl->isVariadic()); | ||||
10526 | } | ||||
10527 | |||||
10528 | uint64_t ASTContext::getTargetNullPointerValue(QualType QT) const { | ||||
10529 | LangAS AS; | ||||
10530 | if (QT->getUnqualifiedDesugaredType()->isNullPtrType()) | ||||
10531 | AS = LangAS::Default; | ||||
10532 | else | ||||
10533 | AS = QT->getPointeeType().getAddressSpace(); | ||||
10534 | |||||
10535 | return getTargetInfo().getNullPointerValue(AS); | ||||
10536 | } | ||||
10537 | |||||
10538 | unsigned ASTContext::getTargetAddressSpace(LangAS AS) const { | ||||
10539 | if (isTargetAddressSpace(AS)) | ||||
10540 | return toTargetAddressSpace(AS); | ||||
10541 | else | ||||
10542 | return (*AddrSpaceMap)[(unsigned)AS]; | ||||
10543 | } | ||||
10544 | |||||
10545 | QualType ASTContext::getCorrespondingSaturatedType(QualType Ty) const { | ||||
10546 | assert(Ty->isFixedPointType())((Ty->isFixedPointType()) ? static_cast<void> (0) : __assert_fail ("Ty->isFixedPointType()", "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 10546, __PRETTY_FUNCTION__)); | ||||
10547 | |||||
10548 | if (Ty->isSaturatedFixedPointType()) return Ty; | ||||
10549 | |||||
10550 | switch (Ty->castAs<BuiltinType>()->getKind()) { | ||||
10551 | default: | ||||
10552 | llvm_unreachable("Not a fixed point type!")::llvm::llvm_unreachable_internal("Not a fixed point type!", "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 10552); | ||||
10553 | case BuiltinType::ShortAccum: | ||||
10554 | return SatShortAccumTy; | ||||
10555 | case BuiltinType::Accum: | ||||
10556 | return SatAccumTy; | ||||
10557 | case BuiltinType::LongAccum: | ||||
10558 | return SatLongAccumTy; | ||||
10559 | case BuiltinType::UShortAccum: | ||||
10560 | return SatUnsignedShortAccumTy; | ||||
10561 | case BuiltinType::UAccum: | ||||
10562 | return SatUnsignedAccumTy; | ||||
10563 | case BuiltinType::ULongAccum: | ||||
10564 | return SatUnsignedLongAccumTy; | ||||
10565 | case BuiltinType::ShortFract: | ||||
10566 | return SatShortFractTy; | ||||
10567 | case BuiltinType::Fract: | ||||
10568 | return SatFractTy; | ||||
10569 | case BuiltinType::LongFract: | ||||
10570 | return SatLongFractTy; | ||||
10571 | case BuiltinType::UShortFract: | ||||
10572 | return SatUnsignedShortFractTy; | ||||
10573 | case BuiltinType::UFract: | ||||
10574 | return SatUnsignedFractTy; | ||||
10575 | case BuiltinType::ULongFract: | ||||
10576 | return SatUnsignedLongFractTy; | ||||
10577 | } | ||||
10578 | } | ||||
10579 | |||||
10580 | LangAS ASTContext::getLangASForBuiltinAddressSpace(unsigned AS) const { | ||||
10581 | if (LangOpts.OpenCL) | ||||
10582 | return getTargetInfo().getOpenCLBuiltinAddressSpace(AS); | ||||
10583 | |||||
10584 | if (LangOpts.CUDA) | ||||
10585 | return getTargetInfo().getCUDABuiltinAddressSpace(AS); | ||||
10586 | |||||
10587 | return getLangASFromTargetAS(AS); | ||||
10588 | } | ||||
10589 | |||||
10590 | // Explicitly instantiate this in case a Redeclarable<T> is used from a TU that | ||||
10591 | // doesn't include ASTContext.h | ||||
10592 | template | ||||
10593 | clang::LazyGenerationalUpdatePtr< | ||||
10594 | const Decl *, Decl *, &ExternalASTSource::CompleteRedeclChain>::ValueType | ||||
10595 | clang::LazyGenerationalUpdatePtr< | ||||
10596 | const Decl *, Decl *, &ExternalASTSource::CompleteRedeclChain>::makeValue( | ||||
10597 | const clang::ASTContext &Ctx, Decl *Value); | ||||
10598 | |||||
10599 | unsigned char ASTContext::getFixedPointScale(QualType Ty) const { | ||||
10600 | assert(Ty->isFixedPointType())((Ty->isFixedPointType()) ? static_cast<void> (0) : __assert_fail ("Ty->isFixedPointType()", "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 10600, __PRETTY_FUNCTION__)); | ||||
10601 | |||||
10602 | const auto *BT = Ty->getAs<BuiltinType>(); | ||||
10603 | const TargetInfo &Target = getTargetInfo(); | ||||
10604 | switch (BT->getKind()) { | ||||
10605 | default: | ||||
10606 | llvm_unreachable("Not a fixed point type!")::llvm::llvm_unreachable_internal("Not a fixed point type!", "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 10606); | ||||
10607 | case BuiltinType::ShortAccum: | ||||
10608 | case BuiltinType::SatShortAccum: | ||||
10609 | return Target.getShortAccumScale(); | ||||
10610 | case BuiltinType::Accum: | ||||
10611 | case BuiltinType::SatAccum: | ||||
10612 | return Target.getAccumScale(); | ||||
10613 | case BuiltinType::LongAccum: | ||||
10614 | case BuiltinType::SatLongAccum: | ||||
10615 | return Target.getLongAccumScale(); | ||||
10616 | case BuiltinType::UShortAccum: | ||||
10617 | case BuiltinType::SatUShortAccum: | ||||
10618 | return Target.getUnsignedShortAccumScale(); | ||||
10619 | case BuiltinType::UAccum: | ||||
10620 | case BuiltinType::SatUAccum: | ||||
10621 | return Target.getUnsignedAccumScale(); | ||||
10622 | case BuiltinType::ULongAccum: | ||||
10623 | case BuiltinType::SatULongAccum: | ||||
10624 | return Target.getUnsignedLongAccumScale(); | ||||
10625 | case BuiltinType::ShortFract: | ||||
10626 | case BuiltinType::SatShortFract: | ||||
10627 | return Target.getShortFractScale(); | ||||
10628 | case BuiltinType::Fract: | ||||
10629 | case BuiltinType::SatFract: | ||||
10630 | return Target.getFractScale(); | ||||
10631 | case BuiltinType::LongFract: | ||||
10632 | case BuiltinType::SatLongFract: | ||||
10633 | return Target.getLongFractScale(); | ||||
10634 | case BuiltinType::UShortFract: | ||||
10635 | case BuiltinType::SatUShortFract: | ||||
10636 | return Target.getUnsignedShortFractScale(); | ||||
10637 | case BuiltinType::UFract: | ||||
10638 | case BuiltinType::SatUFract: | ||||
10639 | return Target.getUnsignedFractScale(); | ||||
10640 | case BuiltinType::ULongFract: | ||||
10641 | case BuiltinType::SatULongFract: | ||||
10642 | return Target.getUnsignedLongFractScale(); | ||||
10643 | } | ||||
10644 | } | ||||
10645 | |||||
10646 | unsigned char ASTContext::getFixedPointIBits(QualType Ty) const { | ||||
10647 | assert(Ty->isFixedPointType())((Ty->isFixedPointType()) ? static_cast<void> (0) : __assert_fail ("Ty->isFixedPointType()", "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 10647, __PRETTY_FUNCTION__)); | ||||
10648 | |||||
10649 | const auto *BT = Ty->getAs<BuiltinType>(); | ||||
10650 | const TargetInfo &Target = getTargetInfo(); | ||||
10651 | switch (BT->getKind()) { | ||||
10652 | default: | ||||
10653 | llvm_unreachable("Not a fixed point type!")::llvm::llvm_unreachable_internal("Not a fixed point type!", "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 10653); | ||||
10654 | case BuiltinType::ShortAccum: | ||||
10655 | case BuiltinType::SatShortAccum: | ||||
10656 | return Target.getShortAccumIBits(); | ||||
10657 | case BuiltinType::Accum: | ||||
10658 | case BuiltinType::SatAccum: | ||||
10659 | return Target.getAccumIBits(); | ||||
10660 | case BuiltinType::LongAccum: | ||||
10661 | case BuiltinType::SatLongAccum: | ||||
10662 | return Target.getLongAccumIBits(); | ||||
10663 | case BuiltinType::UShortAccum: | ||||
10664 | case BuiltinType::SatUShortAccum: | ||||
10665 | return Target.getUnsignedShortAccumIBits(); | ||||
10666 | case BuiltinType::UAccum: | ||||
10667 | case BuiltinType::SatUAccum: | ||||
10668 | return Target.getUnsignedAccumIBits(); | ||||
10669 | case BuiltinType::ULongAccum: | ||||
10670 | case BuiltinType::SatULongAccum: | ||||
10671 | return Target.getUnsignedLongAccumIBits(); | ||||
10672 | case BuiltinType::ShortFract: | ||||
10673 | case BuiltinType::SatShortFract: | ||||
10674 | case BuiltinType::Fract: | ||||
10675 | case BuiltinType::SatFract: | ||||
10676 | case BuiltinType::LongFract: | ||||
10677 | case BuiltinType::SatLongFract: | ||||
10678 | case BuiltinType::UShortFract: | ||||
10679 | case BuiltinType::SatUShortFract: | ||||
10680 | case BuiltinType::UFract: | ||||
10681 | case BuiltinType::SatUFract: | ||||
10682 | case BuiltinType::ULongFract: | ||||
10683 | case BuiltinType::SatULongFract: | ||||
10684 | return 0; | ||||
10685 | } | ||||
10686 | } | ||||
10687 | |||||
10688 | FixedPointSemantics ASTContext::getFixedPointSemantics(QualType Ty) const { | ||||
10689 | assert((Ty->isFixedPointType() || Ty->isIntegerType()) &&(((Ty->isFixedPointType() || Ty->isIntegerType()) && "Can only get the fixed point semantics for a " "fixed point or integer type." ) ? static_cast<void> (0) : __assert_fail ("(Ty->isFixedPointType() || Ty->isIntegerType()) && \"Can only get the fixed point semantics for a \" \"fixed point or integer type.\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 10691, __PRETTY_FUNCTION__)) | ||||
10690 | "Can only get the fixed point semantics for a "(((Ty->isFixedPointType() || Ty->isIntegerType()) && "Can only get the fixed point semantics for a " "fixed point or integer type." ) ? static_cast<void> (0) : __assert_fail ("(Ty->isFixedPointType() || Ty->isIntegerType()) && \"Can only get the fixed point semantics for a \" \"fixed point or integer type.\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 10691, __PRETTY_FUNCTION__)) | ||||
10691 | "fixed point or integer type.")(((Ty->isFixedPointType() || Ty->isIntegerType()) && "Can only get the fixed point semantics for a " "fixed point or integer type." ) ? static_cast<void> (0) : __assert_fail ("(Ty->isFixedPointType() || Ty->isIntegerType()) && \"Can only get the fixed point semantics for a \" \"fixed point or integer type.\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 10691, __PRETTY_FUNCTION__)); | ||||
10692 | if (Ty->isIntegerType()) | ||||
10693 | return FixedPointSemantics::GetIntegerSemantics(getIntWidth(Ty), | ||||
10694 | Ty->isSignedIntegerType()); | ||||
10695 | |||||
10696 | bool isSigned = Ty->isSignedFixedPointType(); | ||||
10697 | return FixedPointSemantics( | ||||
10698 | static_cast<unsigned>(getTypeSize(Ty)), getFixedPointScale(Ty), isSigned, | ||||
10699 | Ty->isSaturatedFixedPointType(), | ||||
10700 | !isSigned && getTargetInfo().doUnsignedFixedPointTypesHavePadding()); | ||||
10701 | } | ||||
10702 | |||||
10703 | APFixedPoint ASTContext::getFixedPointMax(QualType Ty) const { | ||||
10704 | assert(Ty->isFixedPointType())((Ty->isFixedPointType()) ? static_cast<void> (0) : __assert_fail ("Ty->isFixedPointType()", "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 10704, __PRETTY_FUNCTION__)); | ||||
10705 | return APFixedPoint::getMax(getFixedPointSemantics(Ty)); | ||||
10706 | } | ||||
10707 | |||||
10708 | APFixedPoint ASTContext::getFixedPointMin(QualType Ty) const { | ||||
10709 | assert(Ty->isFixedPointType())((Ty->isFixedPointType()) ? static_cast<void> (0) : __assert_fail ("Ty->isFixedPointType()", "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 10709, __PRETTY_FUNCTION__)); | ||||
10710 | return APFixedPoint::getMin(getFixedPointSemantics(Ty)); | ||||
10711 | } | ||||
10712 | |||||
10713 | QualType ASTContext::getCorrespondingSignedFixedPointType(QualType Ty) const { | ||||
10714 | assert(Ty->isUnsignedFixedPointType() &&((Ty->isUnsignedFixedPointType() && "Expected unsigned fixed point type" ) ? static_cast<void> (0) : __assert_fail ("Ty->isUnsignedFixedPointType() && \"Expected unsigned fixed point type\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 10715, __PRETTY_FUNCTION__)) | ||||
10715 | "Expected unsigned fixed point type")((Ty->isUnsignedFixedPointType() && "Expected unsigned fixed point type" ) ? static_cast<void> (0) : __assert_fail ("Ty->isUnsignedFixedPointType() && \"Expected unsigned fixed point type\"" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 10715, __PRETTY_FUNCTION__)); | ||||
10716 | const auto *BTy = Ty->getAs<BuiltinType>(); | ||||
10717 | |||||
10718 | switch (BTy->getKind()) { | ||||
10719 | case BuiltinType::UShortAccum: | ||||
10720 | return ShortAccumTy; | ||||
10721 | case BuiltinType::UAccum: | ||||
10722 | return AccumTy; | ||||
10723 | case BuiltinType::ULongAccum: | ||||
10724 | return LongAccumTy; | ||||
10725 | case BuiltinType::SatUShortAccum: | ||||
10726 | return SatShortAccumTy; | ||||
10727 | case BuiltinType::SatUAccum: | ||||
10728 | return SatAccumTy; | ||||
10729 | case BuiltinType::SatULongAccum: | ||||
10730 | return SatLongAccumTy; | ||||
10731 | case BuiltinType::UShortFract: | ||||
10732 | return ShortFractTy; | ||||
10733 | case BuiltinType::UFract: | ||||
10734 | return FractTy; | ||||
10735 | case BuiltinType::ULongFract: | ||||
10736 | return LongFractTy; | ||||
10737 | case BuiltinType::SatUShortFract: | ||||
10738 | return SatShortFractTy; | ||||
10739 | case BuiltinType::SatUFract: | ||||
10740 | return SatFractTy; | ||||
10741 | case BuiltinType::SatULongFract: | ||||
10742 | return SatLongFractTy; | ||||
10743 | default: | ||||
10744 | llvm_unreachable("Unexpected unsigned fixed point type")::llvm::llvm_unreachable_internal("Unexpected unsigned fixed point type" , "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/ASTContext.cpp" , 10744); | ||||
10745 | } | ||||
10746 | } |
1 | //===- llvm/Support/Casting.h - Allow flexible, checked, casts --*- C++ -*-===// |
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 defines the isa<X>(), cast<X>(), dyn_cast<X>(), cast_or_null<X>(), |
10 | // and dyn_cast_or_null<X>() templates. |
11 | // |
12 | //===----------------------------------------------------------------------===// |
13 | |
14 | #ifndef LLVM_SUPPORT_CASTING_H |
15 | #define LLVM_SUPPORT_CASTING_H |
16 | |
17 | #include "llvm/Support/Compiler.h" |
18 | #include "llvm/Support/type_traits.h" |
19 | #include <cassert> |
20 | #include <memory> |
21 | #include <type_traits> |
22 | |
23 | namespace llvm { |
24 | |
25 | //===----------------------------------------------------------------------===// |
26 | // isa<x> Support Templates |
27 | //===----------------------------------------------------------------------===// |
28 | |
29 | // Define a template that can be specialized by smart pointers to reflect the |
30 | // fact that they are automatically dereferenced, and are not involved with the |
31 | // template selection process... the default implementation is a noop. |
32 | // |
33 | template<typename From> struct simplify_type { |
34 | using SimpleType = From; // The real type this represents... |
35 | |
36 | // An accessor to get the real value... |
37 | static SimpleType &getSimplifiedValue(From &Val) { return Val; } |
38 | }; |
39 | |
40 | template<typename From> struct simplify_type<const From> { |
41 | using NonConstSimpleType = typename simplify_type<From>::SimpleType; |
42 | using SimpleType = |
43 | typename add_const_past_pointer<NonConstSimpleType>::type; |
44 | using RetType = |
45 | typename add_lvalue_reference_if_not_pointer<SimpleType>::type; |
46 | |
47 | static RetType getSimplifiedValue(const From& Val) { |
48 | return simplify_type<From>::getSimplifiedValue(const_cast<From&>(Val)); |
49 | } |
50 | }; |
51 | |
52 | // The core of the implementation of isa<X> is here; To and From should be |
53 | // the names of classes. This template can be specialized to customize the |
54 | // implementation of isa<> without rewriting it from scratch. |
55 | template <typename To, typename From, typename Enabler = void> |
56 | struct isa_impl { |
57 | static inline bool doit(const From &Val) { |
58 | return To::classof(&Val); |
59 | } |
60 | }; |
61 | |
62 | /// Always allow upcasts, and perform no dynamic check for them. |
63 | template <typename To, typename From> |
64 | struct isa_impl< |
65 | To, From, typename std::enable_if<std::is_base_of<To, From>::value>::type> { |
66 | static inline bool doit(const From &) { return true; } |
67 | }; |
68 | |
69 | template <typename To, typename From> struct isa_impl_cl { |
70 | static inline bool doit(const From &Val) { |
71 | return isa_impl<To, From>::doit(Val); |
72 | } |
73 | }; |
74 | |
75 | template <typename To, typename From> struct isa_impl_cl<To, const From> { |
76 | static inline bool doit(const From &Val) { |
77 | return isa_impl<To, From>::doit(Val); |
78 | } |
79 | }; |
80 | |
81 | template <typename To, typename From> |
82 | struct isa_impl_cl<To, const std::unique_ptr<From>> { |
83 | static inline bool doit(const std::unique_ptr<From> &Val) { |
84 | assert(Val && "isa<> used on a null pointer")((Val && "isa<> used on a null pointer") ? static_cast <void> (0) : __assert_fail ("Val && \"isa<> used on a null pointer\"" , "/build/llvm-toolchain-snapshot-10~svn373517/include/llvm/Support/Casting.h" , 84, __PRETTY_FUNCTION__)); |
85 | return isa_impl_cl<To, From>::doit(*Val); |
86 | } |
87 | }; |
88 | |
89 | template <typename To, typename From> struct isa_impl_cl<To, From*> { |
90 | static inline bool doit(const From *Val) { |
91 | assert(Val && "isa<> used on a null pointer")((Val && "isa<> used on a null pointer") ? static_cast <void> (0) : __assert_fail ("Val && \"isa<> used on a null pointer\"" , "/build/llvm-toolchain-snapshot-10~svn373517/include/llvm/Support/Casting.h" , 91, __PRETTY_FUNCTION__)); |
92 | return isa_impl<To, From>::doit(*Val); |
93 | } |
94 | }; |
95 | |
96 | template <typename To, typename From> struct isa_impl_cl<To, From*const> { |
97 | static inline bool doit(const From *Val) { |
98 | assert(Val && "isa<> used on a null pointer")((Val && "isa<> used on a null pointer") ? static_cast <void> (0) : __assert_fail ("Val && \"isa<> used on a null pointer\"" , "/build/llvm-toolchain-snapshot-10~svn373517/include/llvm/Support/Casting.h" , 98, __PRETTY_FUNCTION__)); |
99 | return isa_impl<To, From>::doit(*Val); |
100 | } |
101 | }; |
102 | |
103 | template <typename To, typename From> struct isa_impl_cl<To, const From*> { |
104 | static inline bool doit(const From *Val) { |
105 | assert(Val && "isa<> used on a null pointer")((Val && "isa<> used on a null pointer") ? static_cast <void> (0) : __assert_fail ("Val && \"isa<> used on a null pointer\"" , "/build/llvm-toolchain-snapshot-10~svn373517/include/llvm/Support/Casting.h" , 105, __PRETTY_FUNCTION__)); |
106 | return isa_impl<To, From>::doit(*Val); |
107 | } |
108 | }; |
109 | |
110 | template <typename To, typename From> struct isa_impl_cl<To, const From*const> { |
111 | static inline bool doit(const From *Val) { |
112 | assert(Val && "isa<> used on a null pointer")((Val && "isa<> used on a null pointer") ? static_cast <void> (0) : __assert_fail ("Val && \"isa<> used on a null pointer\"" , "/build/llvm-toolchain-snapshot-10~svn373517/include/llvm/Support/Casting.h" , 112, __PRETTY_FUNCTION__)); |
113 | return isa_impl<To, From>::doit(*Val); |
114 | } |
115 | }; |
116 | |
117 | template<typename To, typename From, typename SimpleFrom> |
118 | struct isa_impl_wrap { |
119 | // When From != SimplifiedType, we can simplify the type some more by using |
120 | // the simplify_type template. |
121 | static bool doit(const From &Val) { |
122 | return isa_impl_wrap<To, SimpleFrom, |
123 | typename simplify_type<SimpleFrom>::SimpleType>::doit( |
124 | simplify_type<const From>::getSimplifiedValue(Val)); |
125 | } |
126 | }; |
127 | |
128 | template<typename To, typename FromTy> |
129 | struct isa_impl_wrap<To, FromTy, FromTy> { |
130 | // When From == SimpleType, we are as simple as we are going to get. |
131 | static bool doit(const FromTy &Val) { |
132 | return isa_impl_cl<To,FromTy>::doit(Val); |
133 | } |
134 | }; |
135 | |
136 | // isa<X> - Return true if the parameter to the template is an instance of the |
137 | // template type argument. Used like this: |
138 | // |
139 | // if (isa<Type>(myVal)) { ... } |
140 | // |
141 | template <class X, class Y> LLVM_NODISCARD[[clang::warn_unused_result]] inline bool isa(const Y &Val) { |
142 | return isa_impl_wrap<X, const Y, |
143 | typename simplify_type<const Y>::SimpleType>::doit(Val); |
144 | } |
145 | |
146 | // isa_and_nonnull<X> - Functionally identical to isa, except that a null value |
147 | // is accepted. |
148 | // |
149 | template <class X, class Y> |
150 | LLVM_NODISCARD[[clang::warn_unused_result]] inline bool isa_and_nonnull(const Y &Val) { |
151 | if (!Val) |
152 | return false; |
153 | return isa<X>(Val); |
154 | } |
155 | |
156 | //===----------------------------------------------------------------------===// |
157 | // cast<x> Support Templates |
158 | //===----------------------------------------------------------------------===// |
159 | |
160 | template<class To, class From> struct cast_retty; |
161 | |
162 | // Calculate what type the 'cast' function should return, based on a requested |
163 | // type of To and a source type of From. |
164 | template<class To, class From> struct cast_retty_impl { |
165 | using ret_type = To &; // Normal case, return Ty& |
166 | }; |
167 | template<class To, class From> struct cast_retty_impl<To, const From> { |
168 | using ret_type = const To &; // Normal case, return Ty& |
169 | }; |
170 | |
171 | template<class To, class From> struct cast_retty_impl<To, From*> { |
172 | using ret_type = To *; // Pointer arg case, return Ty* |
173 | }; |
174 | |
175 | template<class To, class From> struct cast_retty_impl<To, const From*> { |
176 | using ret_type = const To *; // Constant pointer arg case, return const Ty* |
177 | }; |
178 | |
179 | template<class To, class From> struct cast_retty_impl<To, const From*const> { |
180 | using ret_type = const To *; // Constant pointer arg case, return const Ty* |
181 | }; |
182 | |
183 | template <class To, class From> |
184 | struct cast_retty_impl<To, std::unique_ptr<From>> { |
185 | private: |
186 | using PointerType = typename cast_retty_impl<To, From *>::ret_type; |
187 | using ResultType = typename std::remove_pointer<PointerType>::type; |
188 | |
189 | public: |
190 | using ret_type = std::unique_ptr<ResultType>; |
191 | }; |
192 | |
193 | template<class To, class From, class SimpleFrom> |
194 | struct cast_retty_wrap { |
195 | // When the simplified type and the from type are not the same, use the type |
196 | // simplifier to reduce the type, then reuse cast_retty_impl to get the |
197 | // resultant type. |
198 | using ret_type = typename cast_retty<To, SimpleFrom>::ret_type; |
199 | }; |
200 | |
201 | template<class To, class FromTy> |
202 | struct cast_retty_wrap<To, FromTy, FromTy> { |
203 | // When the simplified type is equal to the from type, use it directly. |
204 | using ret_type = typename cast_retty_impl<To,FromTy>::ret_type; |
205 | }; |
206 | |
207 | template<class To, class From> |
208 | struct cast_retty { |
209 | using ret_type = typename cast_retty_wrap< |
210 | To, From, typename simplify_type<From>::SimpleType>::ret_type; |
211 | }; |
212 | |
213 | // Ensure the non-simple values are converted using the simplify_type template |
214 | // that may be specialized by smart pointers... |
215 | // |
216 | template<class To, class From, class SimpleFrom> struct cast_convert_val { |
217 | // This is not a simple type, use the template to simplify it... |
218 | static typename cast_retty<To, From>::ret_type doit(From &Val) { |
219 | return cast_convert_val<To, SimpleFrom, |
220 | typename simplify_type<SimpleFrom>::SimpleType>::doit( |
221 | simplify_type<From>::getSimplifiedValue(Val)); |
222 | } |
223 | }; |
224 | |
225 | template<class To, class FromTy> struct cast_convert_val<To,FromTy,FromTy> { |
226 | // This _is_ a simple type, just cast it. |
227 | static typename cast_retty<To, FromTy>::ret_type doit(const FromTy &Val) { |
228 | typename cast_retty<To, FromTy>::ret_type Res2 |
229 | = (typename cast_retty<To, FromTy>::ret_type)const_cast<FromTy&>(Val); |
230 | return Res2; |
231 | } |
232 | }; |
233 | |
234 | template <class X> struct is_simple_type { |
235 | static const bool value = |
236 | std::is_same<X, typename simplify_type<X>::SimpleType>::value; |
237 | }; |
238 | |
239 | // cast<X> - Return the argument parameter cast to the specified type. This |
240 | // casting operator asserts that the type is correct, so it does not return null |
241 | // on failure. It does not allow a null argument (use cast_or_null for that). |
242 | // It is typically used like this: |
243 | // |
244 | // cast<Instruction>(myVal)->getParent() |
245 | // |
246 | template <class X, class Y> |
247 | inline typename std::enable_if<!is_simple_type<Y>::value, |
248 | typename cast_retty<X, const Y>::ret_type>::type |
249 | cast(const Y &Val) { |
250 | assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!")((isa<X>(Val) && "cast<Ty>() argument of incompatible type!" ) ? static_cast<void> (0) : __assert_fail ("isa<X>(Val) && \"cast<Ty>() argument of incompatible type!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/include/llvm/Support/Casting.h" , 250, __PRETTY_FUNCTION__)); |
251 | return cast_convert_val< |
252 | X, const Y, typename simplify_type<const Y>::SimpleType>::doit(Val); |
253 | } |
254 | |
255 | template <class X, class Y> |
256 | inline typename cast_retty<X, Y>::ret_type cast(Y &Val) { |
257 | assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!")((isa<X>(Val) && "cast<Ty>() argument of incompatible type!" ) ? static_cast<void> (0) : __assert_fail ("isa<X>(Val) && \"cast<Ty>() argument of incompatible type!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/include/llvm/Support/Casting.h" , 257, __PRETTY_FUNCTION__)); |
258 | return cast_convert_val<X, Y, |
259 | typename simplify_type<Y>::SimpleType>::doit(Val); |
260 | } |
261 | |
262 | template <class X, class Y> |
263 | inline typename cast_retty<X, Y *>::ret_type cast(Y *Val) { |
264 | assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!")((isa<X>(Val) && "cast<Ty>() argument of incompatible type!" ) ? static_cast<void> (0) : __assert_fail ("isa<X>(Val) && \"cast<Ty>() argument of incompatible type!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/include/llvm/Support/Casting.h" , 264, __PRETTY_FUNCTION__)); |
265 | return cast_convert_val<X, Y*, |
266 | typename simplify_type<Y*>::SimpleType>::doit(Val); |
267 | } |
268 | |
269 | template <class X, class Y> |
270 | inline typename cast_retty<X, std::unique_ptr<Y>>::ret_type |
271 | cast(std::unique_ptr<Y> &&Val) { |
272 | assert(isa<X>(Val.get()) && "cast<Ty>() argument of incompatible type!")((isa<X>(Val.get()) && "cast<Ty>() argument of incompatible type!" ) ? static_cast<void> (0) : __assert_fail ("isa<X>(Val.get()) && \"cast<Ty>() argument of incompatible type!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/include/llvm/Support/Casting.h" , 272, __PRETTY_FUNCTION__)); |
273 | using ret_type = typename cast_retty<X, std::unique_ptr<Y>>::ret_type; |
274 | return ret_type( |
275 | cast_convert_val<X, Y *, typename simplify_type<Y *>::SimpleType>::doit( |
276 | Val.release())); |
277 | } |
278 | |
279 | // cast_or_null<X> - Functionally identical to cast, except that a null value is |
280 | // accepted. |
281 | // |
282 | template <class X, class Y> |
283 | LLVM_NODISCARD[[clang::warn_unused_result]] inline |
284 | typename std::enable_if<!is_simple_type<Y>::value, |
285 | typename cast_retty<X, const Y>::ret_type>::type |
286 | cast_or_null(const Y &Val) { |
287 | if (!Val) |
288 | return nullptr; |
289 | assert(isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!")((isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!" ) ? static_cast<void> (0) : __assert_fail ("isa<X>(Val) && \"cast_or_null<Ty>() argument of incompatible type!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/include/llvm/Support/Casting.h" , 289, __PRETTY_FUNCTION__)); |
290 | return cast<X>(Val); |
291 | } |
292 | |
293 | template <class X, class Y> |
294 | LLVM_NODISCARD[[clang::warn_unused_result]] inline |
295 | typename std::enable_if<!is_simple_type<Y>::value, |
296 | typename cast_retty<X, Y>::ret_type>::type |
297 | cast_or_null(Y &Val) { |
298 | if (!Val) |
299 | return nullptr; |
300 | assert(isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!")((isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!" ) ? static_cast<void> (0) : __assert_fail ("isa<X>(Val) && \"cast_or_null<Ty>() argument of incompatible type!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/include/llvm/Support/Casting.h" , 300, __PRETTY_FUNCTION__)); |
301 | return cast<X>(Val); |
302 | } |
303 | |
304 | template <class X, class Y> |
305 | LLVM_NODISCARD[[clang::warn_unused_result]] inline typename cast_retty<X, Y *>::ret_type |
306 | cast_or_null(Y *Val) { |
307 | if (!Val) return nullptr; |
308 | assert(isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!")((isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!" ) ? static_cast<void> (0) : __assert_fail ("isa<X>(Val) && \"cast_or_null<Ty>() argument of incompatible type!\"" , "/build/llvm-toolchain-snapshot-10~svn373517/include/llvm/Support/Casting.h" , 308, __PRETTY_FUNCTION__)); |
309 | return cast<X>(Val); |
310 | } |
311 | |
312 | template <class X, class Y> |
313 | inline typename cast_retty<X, std::unique_ptr<Y>>::ret_type |
314 | cast_or_null(std::unique_ptr<Y> &&Val) { |
315 | if (!Val) |
316 | return nullptr; |
317 | return cast<X>(std::move(Val)); |
318 | } |
319 | |
320 | // dyn_cast<X> - Return the argument parameter cast to the specified type. This |
321 | // casting operator returns null if the argument is of the wrong type, so it can |
322 | // be used to test for a type as well as cast if successful. This should be |
323 | // used in the context of an if statement like this: |
324 | // |
325 | // if (const Instruction *I = dyn_cast<Instruction>(myVal)) { ... } |
326 | // |
327 | |
328 | template <class X, class Y> |
329 | LLVM_NODISCARD[[clang::warn_unused_result]] inline |
330 | typename std::enable_if<!is_simple_type<Y>::value, |
331 | typename cast_retty<X, const Y>::ret_type>::type |
332 | dyn_cast(const Y &Val) { |
333 | return isa<X>(Val) ? cast<X>(Val) : nullptr; |
334 | } |
335 | |
336 | template <class X, class Y> |
337 | LLVM_NODISCARD[[clang::warn_unused_result]] inline typename cast_retty<X, Y>::ret_type dyn_cast(Y &Val) { |
338 | return isa<X>(Val) ? cast<X>(Val) : nullptr; |
339 | } |
340 | |
341 | template <class X, class Y> |
342 | LLVM_NODISCARD[[clang::warn_unused_result]] inline typename cast_retty<X, Y *>::ret_type dyn_cast(Y *Val) { |
343 | return isa<X>(Val) ? cast<X>(Val) : nullptr; |
344 | } |
345 | |
346 | // dyn_cast_or_null<X> - Functionally identical to dyn_cast, except that a null |
347 | // value is accepted. |
348 | // |
349 | template <class X, class Y> |
350 | LLVM_NODISCARD[[clang::warn_unused_result]] inline |
351 | typename std::enable_if<!is_simple_type<Y>::value, |
352 | typename cast_retty<X, const Y>::ret_type>::type |
353 | dyn_cast_or_null(const Y &Val) { |
354 | return (Val && isa<X>(Val)) ? cast<X>(Val) : nullptr; |
355 | } |
356 | |
357 | template <class X, class Y> |
358 | LLVM_NODISCARD[[clang::warn_unused_result]] inline |
359 | typename std::enable_if<!is_simple_type<Y>::value, |
360 | typename cast_retty<X, Y>::ret_type>::type |
361 | dyn_cast_or_null(Y &Val) { |
362 | return (Val && isa<X>(Val)) ? cast<X>(Val) : nullptr; |
363 | } |
364 | |
365 | template <class X, class Y> |
366 | LLVM_NODISCARD[[clang::warn_unused_result]] inline typename cast_retty<X, Y *>::ret_type |
367 | dyn_cast_or_null(Y *Val) { |
368 | return (Val && isa<X>(Val)) ? cast<X>(Val) : nullptr; |
369 | } |
370 | |
371 | // unique_dyn_cast<X> - Given a unique_ptr<Y>, try to return a unique_ptr<X>, |
372 | // taking ownership of the input pointer iff isa<X>(Val) is true. If the |
373 | // cast is successful, From refers to nullptr on exit and the casted value |
374 | // is returned. If the cast is unsuccessful, the function returns nullptr |
375 | // and From is unchanged. |
376 | template <class X, class Y> |
377 | LLVM_NODISCARD[[clang::warn_unused_result]] inline auto unique_dyn_cast(std::unique_ptr<Y> &Val) |
378 | -> decltype(cast<X>(Val)) { |
379 | if (!isa<X>(Val)) |
380 | return nullptr; |
381 | return cast<X>(std::move(Val)); |
382 | } |
383 | |
384 | template <class X, class Y> |
385 | LLVM_NODISCARD[[clang::warn_unused_result]] inline auto unique_dyn_cast(std::unique_ptr<Y> &&Val) |
386 | -> decltype(cast<X>(Val)) { |
387 | return unique_dyn_cast<X, Y>(Val); |
388 | } |
389 | |
390 | // dyn_cast_or_null<X> - Functionally identical to unique_dyn_cast, except that |
391 | // a null value is accepted. |
392 | template <class X, class Y> |
393 | LLVM_NODISCARD[[clang::warn_unused_result]] inline auto unique_dyn_cast_or_null(std::unique_ptr<Y> &Val) |
394 | -> decltype(cast<X>(Val)) { |
395 | if (!Val) |
396 | return nullptr; |
397 | return unique_dyn_cast<X, Y>(Val); |
398 | } |
399 | |
400 | template <class X, class Y> |
401 | LLVM_NODISCARD[[clang::warn_unused_result]] inline auto unique_dyn_cast_or_null(std::unique_ptr<Y> &&Val) |
402 | -> decltype(cast<X>(Val)) { |
403 | return unique_dyn_cast_or_null<X, Y>(Val); |
404 | } |
405 | |
406 | } // end namespace llvm |
407 | |
408 | #endif // LLVM_SUPPORT_CASTING_H |