Bug Summary

File:build/source/clang/lib/AST/ASTContext.cpp
Warning:line 3207, column 12
1st function call argument is an uninitialized value

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name ASTContext.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mframe-pointer=none -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/build/source/build-llvm -resource-dir /usr/lib/llvm-17/lib/clang/17 -D _DEBUG -D _GLIBCXX_ASSERTIONS -D _GNU_SOURCE -D _LIBCPP_ENABLE_ASSERTIONS -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I tools/clang/lib/AST -I /build/source/clang/lib/AST -I /build/source/clang/include -I tools/clang/include -I include -I /build/source/llvm/include -D _FORTIFY_SOURCE=2 -D NDEBUG -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/x86_64-linux-gnu/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/backward -internal-isystem /usr/lib/llvm-17/lib/clang/17/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/build/source/build-llvm=build-llvm -fmacro-prefix-map=/build/source/= -fcoverage-prefix-map=/build/source/build-llvm=build-llvm -fcoverage-prefix-map=/build/source/= -source-date-epoch 1679915782 -O3 -Wno-unused-command-line-argument -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-class-memaccess -Wno-redundant-move -Wno-pessimizing-move -Wno-noexcept-type -Wno-comment -Wno-misleading-indentation -std=c++17 -fdeprecated-macro -fdebug-compilation-dir=/build/source/build-llvm -fdebug-prefix-map=/build/source/build-llvm=build-llvm -fdebug-prefix-map=/build/source/= -fdebug-prefix-map=/build/source/build-llvm=build-llvm -fdebug-prefix-map=/build/source/= -ferror-limit 19 -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcolor-diagnostics -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2023-03-27-130437-16335-1 -x c++ /build/source/clang/lib/AST/ASTContext.cpp
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/ASTConcept.h"
18#include "clang/AST/ASTMutationListener.h"
19#include "clang/AST/ASTTypeTraits.h"
20#include "clang/AST/Attr.h"
21#include "clang/AST/AttrIterator.h"
22#include "clang/AST/CharUnits.h"
23#include "clang/AST/Comment.h"
24#include "clang/AST/Decl.h"
25#include "clang/AST/DeclBase.h"
26#include "clang/AST/DeclCXX.h"
27#include "clang/AST/DeclContextInternals.h"
28#include "clang/AST/DeclObjC.h"
29#include "clang/AST/DeclOpenMP.h"
30#include "clang/AST/DeclTemplate.h"
31#include "clang/AST/DeclarationName.h"
32#include "clang/AST/DependenceFlags.h"
33#include "clang/AST/Expr.h"
34#include "clang/AST/ExprCXX.h"
35#include "clang/AST/ExprConcepts.h"
36#include "clang/AST/ExternalASTSource.h"
37#include "clang/AST/Mangle.h"
38#include "clang/AST/MangleNumberingContext.h"
39#include "clang/AST/NestedNameSpecifier.h"
40#include "clang/AST/ParentMapContext.h"
41#include "clang/AST/RawCommentList.h"
42#include "clang/AST/RecordLayout.h"
43#include "clang/AST/Stmt.h"
44#include "clang/AST/TemplateBase.h"
45#include "clang/AST/TemplateName.h"
46#include "clang/AST/Type.h"
47#include "clang/AST/TypeLoc.h"
48#include "clang/AST/UnresolvedSet.h"
49#include "clang/AST/VTableBuilder.h"
50#include "clang/Basic/AddressSpaces.h"
51#include "clang/Basic/Builtins.h"
52#include "clang/Basic/CommentOptions.h"
53#include "clang/Basic/ExceptionSpecificationType.h"
54#include "clang/Basic/IdentifierTable.h"
55#include "clang/Basic/LLVM.h"
56#include "clang/Basic/LangOptions.h"
57#include "clang/Basic/Linkage.h"
58#include "clang/Basic/Module.h"
59#include "clang/Basic/NoSanitizeList.h"
60#include "clang/Basic/ObjCRuntime.h"
61#include "clang/Basic/SourceLocation.h"
62#include "clang/Basic/SourceManager.h"
63#include "clang/Basic/Specifiers.h"
64#include "clang/Basic/TargetCXXABI.h"
65#include "clang/Basic/TargetInfo.h"
66#include "clang/Basic/XRayLists.h"
67#include "llvm/ADT/APFixedPoint.h"
68#include "llvm/ADT/APInt.h"
69#include "llvm/ADT/APSInt.h"
70#include "llvm/ADT/ArrayRef.h"
71#include "llvm/ADT/DenseMap.h"
72#include "llvm/ADT/DenseSet.h"
73#include "llvm/ADT/FoldingSet.h"
74#include "llvm/ADT/PointerUnion.h"
75#include "llvm/ADT/STLExtras.h"
76#include "llvm/ADT/SmallPtrSet.h"
77#include "llvm/ADT/SmallVector.h"
78#include "llvm/ADT/StringExtras.h"
79#include "llvm/ADT/StringRef.h"
80#include "llvm/Frontend/OpenMP/OMPIRBuilder.h"
81#include "llvm/Support/Capacity.h"
82#include "llvm/Support/Casting.h"
83#include "llvm/Support/Compiler.h"
84#include "llvm/Support/ErrorHandling.h"
85#include "llvm/Support/MD5.h"
86#include "llvm/Support/MathExtras.h"
87#include "llvm/Support/raw_ostream.h"
88#include "llvm/TargetParser/Triple.h"
89#include <algorithm>
90#include <cassert>
91#include <cstddef>
92#include <cstdint>
93#include <cstdlib>
94#include <map>
95#include <memory>
96#include <optional>
97#include <string>
98#include <tuple>
99#include <utility>
100
101using namespace clang;
102
103enum FloatingRank {
104 BFloat16Rank,
105 Float16Rank,
106 HalfRank,
107 FloatRank,
108 DoubleRank,
109 LongDoubleRank,
110 Float128Rank,
111 Ibm128Rank
112};
113
114/// \returns location that is relevant when searching for Doc comments related
115/// to \p D.
116static SourceLocation getDeclLocForCommentSearch(const Decl *D,
117 SourceManager &SourceMgr) {
118 assert(D)(static_cast <bool> (D) ? void (0) : __assert_fail ("D"
, "clang/lib/AST/ASTContext.cpp", 118, __extension__ __PRETTY_FUNCTION__
))
;
119
120 // User can not attach documentation to implicit declarations.
121 if (D->isImplicit())
122 return {};
123
124 // User can not attach documentation to implicit instantiations.
125 if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
126 if (FD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)
127 return {};
128 }
129
130 if (const auto *VD = dyn_cast<VarDecl>(D)) {
131 if (VD->isStaticDataMember() &&
132 VD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)
133 return {};
134 }
135
136 if (const auto *CRD = dyn_cast<CXXRecordDecl>(D)) {
137 if (CRD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)
138 return {};
139 }
140
141 if (const auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
142 TemplateSpecializationKind TSK = CTSD->getSpecializationKind();
143 if (TSK == TSK_ImplicitInstantiation ||
144 TSK == TSK_Undeclared)
145 return {};
146 }
147
148 if (const auto *ED = dyn_cast<EnumDecl>(D)) {
149 if (ED->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)
150 return {};
151 }
152 if (const auto *TD = dyn_cast<TagDecl>(D)) {
153 // When tag declaration (but not definition!) is part of the
154 // decl-specifier-seq of some other declaration, it doesn't get comment
155 if (TD->isEmbeddedInDeclarator() && !TD->isCompleteDefinition())
156 return {};
157 }
158 // TODO: handle comments for function parameters properly.
159 if (isa<ParmVarDecl>(D))
160 return {};
161
162 // TODO: we could look up template parameter documentation in the template
163 // documentation.
164 if (isa<TemplateTypeParmDecl>(D) ||
165 isa<NonTypeTemplateParmDecl>(D) ||
166 isa<TemplateTemplateParmDecl>(D))
167 return {};
168
169 // Find declaration location.
170 // For Objective-C declarations we generally don't expect to have multiple
171 // declarators, thus use declaration starting location as the "declaration
172 // location".
173 // For all other declarations multiple declarators are used quite frequently,
174 // so we use the location of the identifier as the "declaration location".
175 if (isa<ObjCMethodDecl>(D) || isa<ObjCContainerDecl>(D) ||
176 isa<ObjCPropertyDecl>(D) ||
177 isa<RedeclarableTemplateDecl>(D) ||
178 isa<ClassTemplateSpecializationDecl>(D) ||
179 // Allow association with Y across {} in `typedef struct X {} Y`.
180 isa<TypedefDecl>(D))
181 return D->getBeginLoc();
182
183 const SourceLocation DeclLoc = D->getLocation();
184 if (DeclLoc.isMacroID()) {
185 // There are (at least) three types of macros we care about here.
186 //
187 // 1. Macros that are used in the definition of a type outside the macro,
188 // with a comment attached at the macro call site.
189 // ```
190 // #define MAKE_NAME(Foo) Name##Foo
191 //
192 // /// Comment is here, where we use the macro.
193 // struct MAKE_NAME(Foo) {
194 // int a;
195 // int b;
196 // };
197 // ```
198 // 2. Macros that define whole things along with the comment.
199 // ```
200 // #define MAKE_METHOD(name) \
201 // /** Comment is here, inside the macro. */ \
202 // void name() {}
203 //
204 // struct S {
205 // MAKE_METHOD(f)
206 // }
207 // ```
208 // 3. Macros that both declare a type and name a decl outside the macro.
209 // ```
210 // /// Comment is here, where we use the macro.
211 // typedef NS_ENUM(NSInteger, Size) {
212 // SizeWidth,
213 // SizeHeight
214 // };
215 // ```
216 // In this case NS_ENUM declares am enum type, and uses the same name for
217 // the typedef declaration that appears outside the macro. The comment
218 // here should be applied to both declarations inside and outside the
219 // macro.
220 //
221 // We have found a Decl name that comes from inside a macro, but
222 // Decl::getLocation() returns the place where the macro is being called.
223 // If the declaration (and not just the name) resides inside the macro,
224 // then we want to map Decl::getLocation() into the macro to where the
225 // declaration and its attached comment (if any) were written.
226 //
227 // This mapping into the macro is done by mapping the location to its
228 // spelling location, however even if the declaration is inside a macro,
229 // the name's spelling can come from a macro argument (case 2 above). In
230 // this case mapping the location to the spelling location finds the
231 // argument's position (at `f` in MAKE_METHOD(`f`) above), which is not
232 // where the declaration and its comment are located.
233 //
234 // To avoid this issue, we make use of Decl::getBeginLocation() instead.
235 // While the declaration's position is where the name is written, the
236 // comment is always attached to the begining of the declaration, not to
237 // the name.
238 //
239 // In the first case, the begin location of the decl is outside the macro,
240 // at the location of `typedef`. This is where the comment is found as
241 // well. The begin location is not inside a macro, so it's spelling
242 // location is the same.
243 //
244 // In the second case, the begin location of the decl is the call to the
245 // macro, at `MAKE_METHOD`. However its spelling location is inside the
246 // the macro at the location of `void`. This is where the comment is found
247 // again.
248 //
249 // In the third case, there's no correct single behaviour. We want to use
250 // the comment outside the macro for the definition that's inside the macro.
251 // There is also a definition outside the macro, and we want the comment to
252 // apply to both. The cases we care about here is NS_ENUM() and
253 // NS_OPTIONS(). In general, if an enum is defined inside a macro, we should
254 // try to find the comment there.
255
256 // This is handling case 3 for NS_ENUM() and NS_OPTIONS(), which define
257 // enum types inside the macro.
258 if (isa<EnumDecl>(D)) {
259 SourceLocation MacroCallLoc = SourceMgr.getExpansionLoc(DeclLoc);
260 if (auto BufferRef =
261 SourceMgr.getBufferOrNone(SourceMgr.getFileID(MacroCallLoc));
262 BufferRef.has_value()) {
263 llvm::StringRef buffer = BufferRef->getBuffer().substr(
264 SourceMgr.getFileOffset(MacroCallLoc));
265 if (buffer.starts_with("NS_ENUM(") ||
266 buffer.starts_with("NS_OPTIONS(")) {
267 // We want to use the comment on the call to NS_ENUM and NS_OPTIONS
268 // macros for the types defined inside the macros, which is at the
269 // expansion location.
270 return MacroCallLoc;
271 }
272 }
273 }
274 return SourceMgr.getSpellingLoc(D->getBeginLoc());
275 }
276
277 return DeclLoc;
278}
279
280RawComment *ASTContext::getRawCommentForDeclNoCacheImpl(
281 const Decl *D, const SourceLocation RepresentativeLocForDecl,
282 const std::map<unsigned, RawComment *> &CommentsInTheFile) const {
283 // If the declaration doesn't map directly to a location in a file, we
284 // can't find the comment.
285 if (RepresentativeLocForDecl.isInvalid() ||
286 !RepresentativeLocForDecl.isFileID())
287 return nullptr;
288
289 // If there are no comments anywhere, we won't find anything.
290 if (CommentsInTheFile.empty())
291 return nullptr;
292
293 // Decompose the location for the declaration and find the beginning of the
294 // file buffer.
295 const std::pair<FileID, unsigned> DeclLocDecomp =
296 SourceMgr.getDecomposedLoc(RepresentativeLocForDecl);
297
298 // Slow path.
299 auto OffsetCommentBehindDecl =
300 CommentsInTheFile.lower_bound(DeclLocDecomp.second);
301
302 // First check whether we have a trailing comment.
303 if (OffsetCommentBehindDecl != CommentsInTheFile.end()) {
304 RawComment *CommentBehindDecl = OffsetCommentBehindDecl->second;
305 if ((CommentBehindDecl->isDocumentation() ||
306 LangOpts.CommentOpts.ParseAllComments) &&
307 CommentBehindDecl->isTrailingComment() &&
308 (isa<FieldDecl>(D) || isa<EnumConstantDecl>(D) || isa<VarDecl>(D) ||
309 isa<ObjCMethodDecl>(D) || isa<ObjCPropertyDecl>(D))) {
310
311 // Check that Doxygen trailing comment comes after the declaration, starts
312 // on the same line and in the same file as the declaration.
313 if (SourceMgr.getLineNumber(DeclLocDecomp.first, DeclLocDecomp.second) ==
314 Comments.getCommentBeginLine(CommentBehindDecl, DeclLocDecomp.first,
315 OffsetCommentBehindDecl->first)) {
316 return CommentBehindDecl;
317 }
318 }
319 }
320
321 // The comment just after the declaration was not a trailing comment.
322 // Let's look at the previous comment.
323 if (OffsetCommentBehindDecl == CommentsInTheFile.begin())
324 return nullptr;
325
326 auto OffsetCommentBeforeDecl = --OffsetCommentBehindDecl;
327 RawComment *CommentBeforeDecl = OffsetCommentBeforeDecl->second;
328
329 // Check that we actually have a non-member Doxygen comment.
330 if (!(CommentBeforeDecl->isDocumentation() ||
331 LangOpts.CommentOpts.ParseAllComments) ||
332 CommentBeforeDecl->isTrailingComment())
333 return nullptr;
334
335 // Decompose the end of the comment.
336 const unsigned CommentEndOffset =
337 Comments.getCommentEndOffset(CommentBeforeDecl);
338
339 // Get the corresponding buffer.
340 bool Invalid = false;
341 const char *Buffer = SourceMgr.getBufferData(DeclLocDecomp.first,
342 &Invalid).data();
343 if (Invalid)
344 return nullptr;
345
346 // Extract text between the comment and declaration.
347 StringRef Text(Buffer + CommentEndOffset,
348 DeclLocDecomp.second - CommentEndOffset);
349
350 // There should be no other declarations or preprocessor directives between
351 // comment and declaration.
352 if (Text.find_last_of(";{}#@") != StringRef::npos)
353 return nullptr;
354
355 return CommentBeforeDecl;
356}
357
358RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const {
359 const SourceLocation DeclLoc = getDeclLocForCommentSearch(D, SourceMgr);
360
361 // If the declaration doesn't map directly to a location in a file, we
362 // can't find the comment.
363 if (DeclLoc.isInvalid() || !DeclLoc.isFileID())
364 return nullptr;
365
366 if (ExternalSource && !CommentsLoaded) {
367 ExternalSource->ReadComments();
368 CommentsLoaded = true;
369 }
370
371 if (Comments.empty())
372 return nullptr;
373
374 const FileID File = SourceMgr.getDecomposedLoc(DeclLoc).first;
375 if (!File.isValid()) {
376 return nullptr;
377 }
378 const auto CommentsInThisFile = Comments.getCommentsInFile(File);
379 if (!CommentsInThisFile || CommentsInThisFile->empty())
380 return nullptr;
381
382 return getRawCommentForDeclNoCacheImpl(D, DeclLoc, *CommentsInThisFile);
383}
384
385void ASTContext::addComment(const RawComment &RC) {
386 assert(LangOpts.RetainCommentsFromSystemHeaders ||(static_cast <bool> (LangOpts.RetainCommentsFromSystemHeaders
|| !SourceMgr.isInSystemHeader(RC.getSourceRange().getBegin(
))) ? void (0) : __assert_fail ("LangOpts.RetainCommentsFromSystemHeaders || !SourceMgr.isInSystemHeader(RC.getSourceRange().getBegin())"
, "clang/lib/AST/ASTContext.cpp", 387, __extension__ __PRETTY_FUNCTION__
))
387 !SourceMgr.isInSystemHeader(RC.getSourceRange().getBegin()))(static_cast <bool> (LangOpts.RetainCommentsFromSystemHeaders
|| !SourceMgr.isInSystemHeader(RC.getSourceRange().getBegin(
))) ? void (0) : __assert_fail ("LangOpts.RetainCommentsFromSystemHeaders || !SourceMgr.isInSystemHeader(RC.getSourceRange().getBegin())"
, "clang/lib/AST/ASTContext.cpp", 387, __extension__ __PRETTY_FUNCTION__
))
;
388 Comments.addComment(RC, LangOpts.CommentOpts, BumpAlloc);
389}
390
391/// If we have a 'templated' declaration for a template, adjust 'D' to
392/// refer to the actual template.
393/// If we have an implicit instantiation, adjust 'D' to refer to template.
394static const Decl &adjustDeclToTemplate(const Decl &D) {
395 if (const auto *FD = dyn_cast<FunctionDecl>(&D)) {
396 // Is this function declaration part of a function template?
397 if (const FunctionTemplateDecl *FTD = FD->getDescribedFunctionTemplate())
398 return *FTD;
399
400 // Nothing to do if function is not an implicit instantiation.
401 if (FD->getTemplateSpecializationKind() != TSK_ImplicitInstantiation)
402 return D;
403
404 // Function is an implicit instantiation of a function template?
405 if (const FunctionTemplateDecl *FTD = FD->getPrimaryTemplate())
406 return *FTD;
407
408 // Function is instantiated from a member definition of a class template?
409 if (const FunctionDecl *MemberDecl =
410 FD->getInstantiatedFromMemberFunction())
411 return *MemberDecl;
412
413 return D;
414 }
415 if (const auto *VD = dyn_cast<VarDecl>(&D)) {
416 // Static data member is instantiated from a member definition of a class
417 // template?
418 if (VD->isStaticDataMember())
419 if (const VarDecl *MemberDecl = VD->getInstantiatedFromStaticDataMember())
420 return *MemberDecl;
421
422 return D;
423 }
424 if (const auto *CRD = dyn_cast<CXXRecordDecl>(&D)) {
425 // Is this class declaration part of a class template?
426 if (const ClassTemplateDecl *CTD = CRD->getDescribedClassTemplate())
427 return *CTD;
428
429 // Class is an implicit instantiation of a class template or partial
430 // specialization?
431 if (const auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(CRD)) {
432 if (CTSD->getSpecializationKind() != TSK_ImplicitInstantiation)
433 return D;
434 llvm::PointerUnion<ClassTemplateDecl *,
435 ClassTemplatePartialSpecializationDecl *>
436 PU = CTSD->getSpecializedTemplateOrPartial();
437 return PU.is<ClassTemplateDecl *>()
438 ? *static_cast<const Decl *>(PU.get<ClassTemplateDecl *>())
439 : *static_cast<const Decl *>(
440 PU.get<ClassTemplatePartialSpecializationDecl *>());
441 }
442
443 // Class is instantiated from a member definition of a class template?
444 if (const MemberSpecializationInfo *Info =
445 CRD->getMemberSpecializationInfo())
446 return *Info->getInstantiatedFrom();
447
448 return D;
449 }
450 if (const auto *ED = dyn_cast<EnumDecl>(&D)) {
451 // Enum is instantiated from a member definition of a class template?
452 if (const EnumDecl *MemberDecl = ED->getInstantiatedFromMemberEnum())
453 return *MemberDecl;
454
455 return D;
456 }
457 // FIXME: Adjust alias templates?
458 return D;
459}
460
461const RawComment *ASTContext::getRawCommentForAnyRedecl(
462 const Decl *D,
463 const Decl **OriginalDecl) const {
464 if (!D) {
465 if (OriginalDecl)
466 OriginalDecl = nullptr;
467 return nullptr;
468 }
469
470 D = &adjustDeclToTemplate(*D);
471
472 // Any comment directly attached to D?
473 {
474 auto DeclComment = DeclRawComments.find(D);
475 if (DeclComment != DeclRawComments.end()) {
476 if (OriginalDecl)
477 *OriginalDecl = D;
478 return DeclComment->second;
479 }
480 }
481
482 // Any comment attached to any redeclaration of D?
483 const Decl *CanonicalD = D->getCanonicalDecl();
484 if (!CanonicalD)
485 return nullptr;
486
487 {
488 auto RedeclComment = RedeclChainComments.find(CanonicalD);
489 if (RedeclComment != RedeclChainComments.end()) {
490 if (OriginalDecl)
491 *OriginalDecl = RedeclComment->second;
492 auto CommentAtRedecl = DeclRawComments.find(RedeclComment->second);
493 assert(CommentAtRedecl != DeclRawComments.end() &&(static_cast <bool> (CommentAtRedecl != DeclRawComments
.end() && "This decl is supposed to have comment attached."
) ? void (0) : __assert_fail ("CommentAtRedecl != DeclRawComments.end() && \"This decl is supposed to have comment attached.\""
, "clang/lib/AST/ASTContext.cpp", 494, __extension__ __PRETTY_FUNCTION__
))
494 "This decl is supposed to have comment attached.")(static_cast <bool> (CommentAtRedecl != DeclRawComments
.end() && "This decl is supposed to have comment attached."
) ? void (0) : __assert_fail ("CommentAtRedecl != DeclRawComments.end() && \"This decl is supposed to have comment attached.\""
, "clang/lib/AST/ASTContext.cpp", 494, __extension__ __PRETTY_FUNCTION__
))
;
495 return CommentAtRedecl->second;
496 }
497 }
498
499 // Any redeclarations of D that we haven't checked for comments yet?
500 // We can't use DenseMap::iterator directly since it'd get invalid.
501 auto LastCheckedRedecl = [this, CanonicalD]() -> const Decl * {
502 auto LookupRes = CommentlessRedeclChains.find(CanonicalD);
503 if (LookupRes != CommentlessRedeclChains.end())
504 return LookupRes->second;
505 return nullptr;
506 }();
507
508 for (const auto Redecl : D->redecls()) {
509 assert(Redecl)(static_cast <bool> (Redecl) ? void (0) : __assert_fail
("Redecl", "clang/lib/AST/ASTContext.cpp", 509, __extension__
__PRETTY_FUNCTION__))
;
510 // Skip all redeclarations that have been checked previously.
511 if (LastCheckedRedecl) {
512 if (LastCheckedRedecl == Redecl) {
513 LastCheckedRedecl = nullptr;
514 }
515 continue;
516 }
517 const RawComment *RedeclComment = getRawCommentForDeclNoCache(Redecl);
518 if (RedeclComment) {
519 cacheRawCommentForDecl(*Redecl, *RedeclComment);
520 if (OriginalDecl)
521 *OriginalDecl = Redecl;
522 return RedeclComment;
523 }
524 CommentlessRedeclChains[CanonicalD] = Redecl;
525 }
526
527 if (OriginalDecl)
528 *OriginalDecl = nullptr;
529 return nullptr;
530}
531
532void ASTContext::cacheRawCommentForDecl(const Decl &OriginalD,
533 const RawComment &Comment) const {
534 assert(Comment.isDocumentation() || LangOpts.CommentOpts.ParseAllComments)(static_cast <bool> (Comment.isDocumentation() || LangOpts
.CommentOpts.ParseAllComments) ? void (0) : __assert_fail ("Comment.isDocumentation() || LangOpts.CommentOpts.ParseAllComments"
, "clang/lib/AST/ASTContext.cpp", 534, __extension__ __PRETTY_FUNCTION__
))
;
535 DeclRawComments.try_emplace(&OriginalD, &Comment);
536 const Decl *const CanonicalDecl = OriginalD.getCanonicalDecl();
537 RedeclChainComments.try_emplace(CanonicalDecl, &OriginalD);
538 CommentlessRedeclChains.erase(CanonicalDecl);
539}
540
541static void addRedeclaredMethods(const ObjCMethodDecl *ObjCMethod,
542 SmallVectorImpl<const NamedDecl *> &Redeclared) {
543 const DeclContext *DC = ObjCMethod->getDeclContext();
544 if (const auto *IMD = dyn_cast<ObjCImplDecl>(DC)) {
545 const ObjCInterfaceDecl *ID = IMD->getClassInterface();
546 if (!ID)
547 return;
548 // Add redeclared method here.
549 for (const auto *Ext : ID->known_extensions()) {
550 if (ObjCMethodDecl *RedeclaredMethod =
551 Ext->getMethod(ObjCMethod->getSelector(),
552 ObjCMethod->isInstanceMethod()))
553 Redeclared.push_back(RedeclaredMethod);
554 }
555 }
556}
557
558void ASTContext::attachCommentsToJustParsedDecls(ArrayRef<Decl *> Decls,
559 const Preprocessor *PP) {
560 if (Comments.empty() || Decls.empty())
561 return;
562
563 FileID File;
564 for (Decl *D : Decls) {
565 SourceLocation Loc = D->getLocation();
566 if (Loc.isValid()) {
567 // See if there are any new comments that are not attached to a decl.
568 // The location doesn't have to be precise - we care only about the file.
569 File = SourceMgr.getDecomposedLoc(Loc).first;
570 break;
571 }
572 }
573
574 if (File.isInvalid())
575 return;
576
577 auto CommentsInThisFile = Comments.getCommentsInFile(File);
578 if (!CommentsInThisFile || CommentsInThisFile->empty() ||
579 CommentsInThisFile->rbegin()->second->isAttached())
580 return;
581
582 // There is at least one comment not attached to a decl.
583 // Maybe it should be attached to one of Decls?
584 //
585 // Note that this way we pick up not only comments that precede the
586 // declaration, but also comments that *follow* the declaration -- thanks to
587 // the lookahead in the lexer: we've consumed the semicolon and looked
588 // ahead through comments.
589
590 for (const Decl *D : Decls) {
591 assert(D)(static_cast <bool> (D) ? void (0) : __assert_fail ("D"
, "clang/lib/AST/ASTContext.cpp", 591, __extension__ __PRETTY_FUNCTION__
))
;
592 if (D->isInvalidDecl())
593 continue;
594
595 D = &adjustDeclToTemplate(*D);
596
597 const SourceLocation DeclLoc = getDeclLocForCommentSearch(D, SourceMgr);
598
599 if (DeclLoc.isInvalid() || !DeclLoc.isFileID())
600 continue;
601
602 if (DeclRawComments.count(D) > 0)
603 continue;
604
605 if (RawComment *const DocComment =
606 getRawCommentForDeclNoCacheImpl(D, DeclLoc, *CommentsInThisFile)) {
607 cacheRawCommentForDecl(*D, *DocComment);
608 comments::FullComment *FC = DocComment->parse(*this, PP, D);
609 ParsedComments[D->getCanonicalDecl()] = FC;
610 }
611 }
612}
613
614comments::FullComment *ASTContext::cloneFullComment(comments::FullComment *FC,
615 const Decl *D) const {
616 auto *ThisDeclInfo = new (*this) comments::DeclInfo;
617 ThisDeclInfo->CommentDecl = D;
618 ThisDeclInfo->IsFilled = false;
619 ThisDeclInfo->fill();
620 ThisDeclInfo->CommentDecl = FC->getDecl();
621 if (!ThisDeclInfo->TemplateParameters)
622 ThisDeclInfo->TemplateParameters = FC->getDeclInfo()->TemplateParameters;
623 comments::FullComment *CFC =
624 new (*this) comments::FullComment(FC->getBlocks(),
625 ThisDeclInfo);
626 return CFC;
627}
628
629comments::FullComment *ASTContext::getLocalCommentForDeclUncached(const Decl *D) const {
630 const RawComment *RC = getRawCommentForDeclNoCache(D);
631 return RC ? RC->parse(*this, nullptr, D) : nullptr;
632}
633
634comments::FullComment *ASTContext::getCommentForDecl(
635 const Decl *D,
636 const Preprocessor *PP) const {
637 if (!D || D->isInvalidDecl())
638 return nullptr;
639 D = &adjustDeclToTemplate(*D);
640
641 const Decl *Canonical = D->getCanonicalDecl();
642 llvm::DenseMap<const Decl *, comments::FullComment *>::iterator Pos =
643 ParsedComments.find(Canonical);
644
645 if (Pos != ParsedComments.end()) {
646 if (Canonical != D) {
647 comments::FullComment *FC = Pos->second;
648 comments::FullComment *CFC = cloneFullComment(FC, D);
649 return CFC;
650 }
651 return Pos->second;
652 }
653
654 const Decl *OriginalDecl = nullptr;
655
656 const RawComment *RC = getRawCommentForAnyRedecl(D, &OriginalDecl);
657 if (!RC) {
658 if (isa<ObjCMethodDecl>(D) || isa<FunctionDecl>(D)) {
659 SmallVector<const NamedDecl*, 8> Overridden;
660 const auto *OMD = dyn_cast<ObjCMethodDecl>(D);
661 if (OMD && OMD->isPropertyAccessor())
662 if (const ObjCPropertyDecl *PDecl = OMD->findPropertyDecl())
663 if (comments::FullComment *FC = getCommentForDecl(PDecl, PP))
664 return cloneFullComment(FC, D);
665 if (OMD)
666 addRedeclaredMethods(OMD, Overridden);
667 getOverriddenMethods(dyn_cast<NamedDecl>(D), Overridden);
668 for (unsigned i = 0, e = Overridden.size(); i < e; i++)
669 if (comments::FullComment *FC = getCommentForDecl(Overridden[i], PP))
670 return cloneFullComment(FC, D);
671 }
672 else if (const auto *TD = dyn_cast<TypedefNameDecl>(D)) {
673 // Attach any tag type's documentation to its typedef if latter
674 // does not have one of its own.
675 QualType QT = TD->getUnderlyingType();
676 if (const auto *TT = QT->getAs<TagType>())
677 if (const Decl *TD = TT->getDecl())
678 if (comments::FullComment *FC = getCommentForDecl(TD, PP))
679 return cloneFullComment(FC, D);
680 }
681 else if (const auto *IC = dyn_cast<ObjCInterfaceDecl>(D)) {
682 while (IC->getSuperClass()) {
683 IC = IC->getSuperClass();
684 if (comments::FullComment *FC = getCommentForDecl(IC, PP))
685 return cloneFullComment(FC, D);
686 }
687 }
688 else if (const auto *CD = dyn_cast<ObjCCategoryDecl>(D)) {
689 if (const ObjCInterfaceDecl *IC = CD->getClassInterface())
690 if (comments::FullComment *FC = getCommentForDecl(IC, PP))
691 return cloneFullComment(FC, D);
692 }
693 else if (const auto *RD = dyn_cast<CXXRecordDecl>(D)) {
694 if (!(RD = RD->getDefinition()))
695 return nullptr;
696 // Check non-virtual bases.
697 for (const auto &I : RD->bases()) {
698 if (I.isVirtual() || (I.getAccessSpecifier() != AS_public))
699 continue;
700 QualType Ty = I.getType();
701 if (Ty.isNull())
702 continue;
703 if (const CXXRecordDecl *NonVirtualBase = Ty->getAsCXXRecordDecl()) {
704 if (!(NonVirtualBase= NonVirtualBase->getDefinition()))
705 continue;
706
707 if (comments::FullComment *FC = getCommentForDecl((NonVirtualBase), PP))
708 return cloneFullComment(FC, D);
709 }
710 }
711 // Check virtual bases.
712 for (const auto &I : RD->vbases()) {
713 if (I.getAccessSpecifier() != AS_public)
714 continue;
715 QualType Ty = I.getType();
716 if (Ty.isNull())
717 continue;
718 if (const CXXRecordDecl *VirtualBase = Ty->getAsCXXRecordDecl()) {
719 if (!(VirtualBase= VirtualBase->getDefinition()))
720 continue;
721 if (comments::FullComment *FC = getCommentForDecl((VirtualBase), PP))
722 return cloneFullComment(FC, D);
723 }
724 }
725 }
726 return nullptr;
727 }
728
729 // If the RawComment was attached to other redeclaration of this Decl, we
730 // should parse the comment in context of that other Decl. This is important
731 // because comments can contain references to parameter names which can be
732 // different across redeclarations.
733 if (D != OriginalDecl && OriginalDecl)
734 return getCommentForDecl(OriginalDecl, PP);
735
736 comments::FullComment *FC = RC->parse(*this, PP, D);
737 ParsedComments[Canonical] = FC;
738 return FC;
739}
740
741void
742ASTContext::CanonicalTemplateTemplateParm::Profile(llvm::FoldingSetNodeID &ID,
743 const ASTContext &C,
744 TemplateTemplateParmDecl *Parm) {
745 ID.AddInteger(Parm->getDepth());
746 ID.AddInteger(Parm->getPosition());
747 ID.AddBoolean(Parm->isParameterPack());
748
749 TemplateParameterList *Params = Parm->getTemplateParameters();
750 ID.AddInteger(Params->size());
751 for (TemplateParameterList::const_iterator P = Params->begin(),
752 PEnd = Params->end();
753 P != PEnd; ++P) {
754 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
755 ID.AddInteger(0);
756 ID.AddBoolean(TTP->isParameterPack());
757 const TypeConstraint *TC = TTP->getTypeConstraint();
758 ID.AddBoolean(TC != nullptr);
759 if (TC)
760 TC->getImmediatelyDeclaredConstraint()->Profile(ID, C,
761 /*Canonical=*/true);
762 if (TTP->isExpandedParameterPack()) {
763 ID.AddBoolean(true);
764 ID.AddInteger(TTP->getNumExpansionParameters());
765 } else
766 ID.AddBoolean(false);
767 continue;
768 }
769
770 if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
771 ID.AddInteger(1);
772 ID.AddBoolean(NTTP->isParameterPack());
773 const Expr *TC = NTTP->getPlaceholderTypeConstraint();
774 ID.AddBoolean(TC != nullptr);
775 ID.AddPointer(NTTP->getType().getCanonicalType().getAsOpaquePtr());
776 if (TC)
777 TC->Profile(ID, C, /*Canonical=*/true);
778 if (NTTP->isExpandedParameterPack()) {
779 ID.AddBoolean(true);
780 ID.AddInteger(NTTP->getNumExpansionTypes());
781 for (unsigned I = 0, N = NTTP->getNumExpansionTypes(); I != N; ++I) {
782 QualType T = NTTP->getExpansionType(I);
783 ID.AddPointer(T.getCanonicalType().getAsOpaquePtr());
784 }
785 } else
786 ID.AddBoolean(false);
787 continue;
788 }
789
790 auto *TTP = cast<TemplateTemplateParmDecl>(*P);
791 ID.AddInteger(2);
792 Profile(ID, C, TTP);
793 }
794 Expr *RequiresClause = Parm->getTemplateParameters()->getRequiresClause();
795 ID.AddBoolean(RequiresClause != nullptr);
796 if (RequiresClause)
797 RequiresClause->Profile(ID, C, /*Canonical=*/true);
798}
799
800static Expr *
801canonicalizeImmediatelyDeclaredConstraint(const ASTContext &C, Expr *IDC,
802 QualType ConstrainedType) {
803 // This is a bit ugly - we need to form a new immediately-declared
804 // constraint that references the new parameter; this would ideally
805 // require semantic analysis (e.g. template<C T> struct S {}; - the
806 // converted arguments of C<T> could be an argument pack if C is
807 // declared as template<typename... T> concept C = ...).
808 // We don't have semantic analysis here so we dig deep into the
809 // ready-made constraint expr and change the thing manually.
810 ConceptSpecializationExpr *CSE;
811 if (const auto *Fold = dyn_cast<CXXFoldExpr>(IDC))
812 CSE = cast<ConceptSpecializationExpr>(Fold->getLHS());
813 else
814 CSE = cast<ConceptSpecializationExpr>(IDC);
815 ArrayRef<TemplateArgument> OldConverted = CSE->getTemplateArguments();
816 SmallVector<TemplateArgument, 3> NewConverted;
817 NewConverted.reserve(OldConverted.size());
818 if (OldConverted.front().getKind() == TemplateArgument::Pack) {
819 // The case:
820 // template<typename... T> concept C = true;
821 // template<C<int> T> struct S; -> constraint is C<{T, int}>
822 NewConverted.push_back(ConstrainedType);
823 llvm::append_range(NewConverted,
824 OldConverted.front().pack_elements().drop_front(1));
825 TemplateArgument NewPack(NewConverted);
826
827 NewConverted.clear();
828 NewConverted.push_back(NewPack);
829 assert(OldConverted.size() == 1 &&(static_cast <bool> (OldConverted.size() == 1 &&
"Template parameter pack should be the last parameter") ? void
(0) : __assert_fail ("OldConverted.size() == 1 && \"Template parameter pack should be the last parameter\""
, "clang/lib/AST/ASTContext.cpp", 830, __extension__ __PRETTY_FUNCTION__
))
830 "Template parameter pack should be the last parameter")(static_cast <bool> (OldConverted.size() == 1 &&
"Template parameter pack should be the last parameter") ? void
(0) : __assert_fail ("OldConverted.size() == 1 && \"Template parameter pack should be the last parameter\""
, "clang/lib/AST/ASTContext.cpp", 830, __extension__ __PRETTY_FUNCTION__
))
;
831 } else {
832 assert(OldConverted.front().getKind() == TemplateArgument::Type &&(static_cast <bool> (OldConverted.front().getKind() == TemplateArgument
::Type && "Unexpected first argument kind for immediately-declared "
"constraint") ? void (0) : __assert_fail ("OldConverted.front().getKind() == TemplateArgument::Type && \"Unexpected first argument kind for immediately-declared \" \"constraint\""
, "clang/lib/AST/ASTContext.cpp", 834, __extension__ __PRETTY_FUNCTION__
))
833 "Unexpected first argument kind for immediately-declared "(static_cast <bool> (OldConverted.front().getKind() == TemplateArgument
::Type && "Unexpected first argument kind for immediately-declared "
"constraint") ? void (0) : __assert_fail ("OldConverted.front().getKind() == TemplateArgument::Type && \"Unexpected first argument kind for immediately-declared \" \"constraint\""
, "clang/lib/AST/ASTContext.cpp", 834, __extension__ __PRETTY_FUNCTION__
))
834 "constraint")(static_cast <bool> (OldConverted.front().getKind() == TemplateArgument
::Type && "Unexpected first argument kind for immediately-declared "
"constraint") ? void (0) : __assert_fail ("OldConverted.front().getKind() == TemplateArgument::Type && \"Unexpected first argument kind for immediately-declared \" \"constraint\""
, "clang/lib/AST/ASTContext.cpp", 834, __extension__ __PRETTY_FUNCTION__
))
;
835 NewConverted.push_back(ConstrainedType);
836 llvm::append_range(NewConverted, OldConverted.drop_front(1));
837 }
838 auto *CSD = ImplicitConceptSpecializationDecl::Create(
839 C, CSE->getNamedConcept()->getDeclContext(),
840 CSE->getNamedConcept()->getLocation(), NewConverted);
841
842 Expr *NewIDC = ConceptSpecializationExpr::Create(
843 C, CSE->getNamedConcept(), CSD, nullptr, CSE->isInstantiationDependent(),
844 CSE->containsUnexpandedParameterPack());
845
846 if (auto *OrigFold = dyn_cast<CXXFoldExpr>(IDC))
847 NewIDC = new (C) CXXFoldExpr(
848 OrigFold->getType(), /*Callee*/ nullptr, SourceLocation(), NewIDC,
849 BinaryOperatorKind::BO_LAnd, SourceLocation(), /*RHS=*/nullptr,
850 SourceLocation(), /*NumExpansions=*/std::nullopt);
851 return NewIDC;
852}
853
854TemplateTemplateParmDecl *
855ASTContext::getCanonicalTemplateTemplateParmDecl(
856 TemplateTemplateParmDecl *TTP) const {
857 // Check if we already have a canonical template template parameter.
858 llvm::FoldingSetNodeID ID;
859 CanonicalTemplateTemplateParm::Profile(ID, *this, TTP);
860 void *InsertPos = nullptr;
861 CanonicalTemplateTemplateParm *Canonical
862 = CanonTemplateTemplateParms.FindNodeOrInsertPos(ID, InsertPos);
863 if (Canonical)
864 return Canonical->getParam();
865
866 // Build a canonical template parameter list.
867 TemplateParameterList *Params = TTP->getTemplateParameters();
868 SmallVector<NamedDecl *, 4> CanonParams;
869 CanonParams.reserve(Params->size());
870 for (TemplateParameterList::const_iterator P = Params->begin(),
871 PEnd = Params->end();
872 P != PEnd; ++P) {
873 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
874 TemplateTypeParmDecl *NewTTP = TemplateTypeParmDecl::Create(
875 *this, getTranslationUnitDecl(), SourceLocation(), SourceLocation(),
876 TTP->getDepth(), TTP->getIndex(), nullptr, false,
877 TTP->isParameterPack(), TTP->hasTypeConstraint(),
878 TTP->isExpandedParameterPack()
879 ? std::optional<unsigned>(TTP->getNumExpansionParameters())
880 : std::nullopt);
881 if (const auto *TC = TTP->getTypeConstraint()) {
882 QualType ParamAsArgument(NewTTP->getTypeForDecl(), 0);
883 Expr *NewIDC = canonicalizeImmediatelyDeclaredConstraint(
884 *this, TC->getImmediatelyDeclaredConstraint(),
885 ParamAsArgument);
886 NewTTP->setTypeConstraint(
887 NestedNameSpecifierLoc(),
888 DeclarationNameInfo(TC->getNamedConcept()->getDeclName(),
889 SourceLocation()), /*FoundDecl=*/nullptr,
890 // Actually canonicalizing a TemplateArgumentLoc is difficult so we
891 // simply omit the ArgsAsWritten
892 TC->getNamedConcept(), /*ArgsAsWritten=*/nullptr, NewIDC);
893 }
894 CanonParams.push_back(NewTTP);
895 } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
896 QualType T = getCanonicalType(NTTP->getType());
897 TypeSourceInfo *TInfo = getTrivialTypeSourceInfo(T);
898 NonTypeTemplateParmDecl *Param;
899 if (NTTP->isExpandedParameterPack()) {
900 SmallVector<QualType, 2> ExpandedTypes;
901 SmallVector<TypeSourceInfo *, 2> ExpandedTInfos;
902 for (unsigned I = 0, N = NTTP->getNumExpansionTypes(); I != N; ++I) {
903 ExpandedTypes.push_back(getCanonicalType(NTTP->getExpansionType(I)));
904 ExpandedTInfos.push_back(
905 getTrivialTypeSourceInfo(ExpandedTypes.back()));
906 }
907
908 Param = NonTypeTemplateParmDecl::Create(*this, getTranslationUnitDecl(),
909 SourceLocation(),
910 SourceLocation(),
911 NTTP->getDepth(),
912 NTTP->getPosition(), nullptr,
913 T,
914 TInfo,
915 ExpandedTypes,
916 ExpandedTInfos);
917 } else {
918 Param = NonTypeTemplateParmDecl::Create(*this, getTranslationUnitDecl(),
919 SourceLocation(),
920 SourceLocation(),
921 NTTP->getDepth(),
922 NTTP->getPosition(), nullptr,
923 T,
924 NTTP->isParameterPack(),
925 TInfo);
926 }
927 if (AutoType *AT = T->getContainedAutoType()) {
928 if (AT->isConstrained()) {
929 Param->setPlaceholderTypeConstraint(
930 canonicalizeImmediatelyDeclaredConstraint(
931 *this, NTTP->getPlaceholderTypeConstraint(), T));
932 }
933 }
934 CanonParams.push_back(Param);
935
936 } else
937 CanonParams.push_back(getCanonicalTemplateTemplateParmDecl(
938 cast<TemplateTemplateParmDecl>(*P)));
939 }
940
941 Expr *CanonRequiresClause = nullptr;
942 if (Expr *RequiresClause = TTP->getTemplateParameters()->getRequiresClause())
943 CanonRequiresClause = RequiresClause;
944
945 TemplateTemplateParmDecl *CanonTTP
946 = TemplateTemplateParmDecl::Create(*this, getTranslationUnitDecl(),
947 SourceLocation(), TTP->getDepth(),
948 TTP->getPosition(),
949 TTP->isParameterPack(),
950 nullptr,
951 TemplateParameterList::Create(*this, SourceLocation(),
952 SourceLocation(),
953 CanonParams,
954 SourceLocation(),
955 CanonRequiresClause));
956
957 // Get the new insert position for the node we care about.
958 Canonical = CanonTemplateTemplateParms.FindNodeOrInsertPos(ID, InsertPos);
959 assert(!Canonical && "Shouldn't be in the map!")(static_cast <bool> (!Canonical && "Shouldn't be in the map!"
) ? void (0) : __assert_fail ("!Canonical && \"Shouldn't be in the map!\""
, "clang/lib/AST/ASTContext.cpp", 959, __extension__ __PRETTY_FUNCTION__
))
;
960 (void)Canonical;
961
962 // Create the canonical template template parameter entry.
963 Canonical = new (*this) CanonicalTemplateTemplateParm(CanonTTP);
964 CanonTemplateTemplateParms.InsertNode(Canonical, InsertPos);
965 return CanonTTP;
966}
967
968TargetCXXABI::Kind ASTContext::getCXXABIKind() const {
969 auto Kind = getTargetInfo().getCXXABI().getKind();
970 return getLangOpts().CXXABI.value_or(Kind);
971}
972
973CXXABI *ASTContext::createCXXABI(const TargetInfo &T) {
974 if (!LangOpts.CPlusPlus) return nullptr;
975
976 switch (getCXXABIKind()) {
977 case TargetCXXABI::AppleARM64:
978 case TargetCXXABI::Fuchsia:
979 case TargetCXXABI::GenericARM: // Same as Itanium at this level
980 case TargetCXXABI::iOS:
981 case TargetCXXABI::WatchOS:
982 case TargetCXXABI::GenericAArch64:
983 case TargetCXXABI::GenericMIPS:
984 case TargetCXXABI::GenericItanium:
985 case TargetCXXABI::WebAssembly:
986 case TargetCXXABI::XL:
987 return CreateItaniumCXXABI(*this);
988 case TargetCXXABI::Microsoft:
989 return CreateMicrosoftCXXABI(*this);
990 }
991 llvm_unreachable("Invalid CXXABI type!")::llvm::llvm_unreachable_internal("Invalid CXXABI type!", "clang/lib/AST/ASTContext.cpp"
, 991)
;
992}
993
994interp::Context &ASTContext::getInterpContext() {
995 if (!InterpContext) {
996 InterpContext.reset(new interp::Context(*this));
997 }
998 return *InterpContext.get();
999}
1000
1001ParentMapContext &ASTContext::getParentMapContext() {
1002 if (!ParentMapCtx)
1003 ParentMapCtx.reset(new ParentMapContext(*this));
1004 return *ParentMapCtx.get();
1005}
1006
1007static bool isAddrSpaceMapManglingEnabled(const TargetInfo &TI,
1008 const LangOptions &LangOpts) {
1009 switch (LangOpts.getAddressSpaceMapMangling()) {
1010 case LangOptions::ASMM_Target:
1011 return TI.useAddressSpaceMapMangling();
1012 case LangOptions::ASMM_On:
1013 return true;
1014 case LangOptions::ASMM_Off:
1015 return false;
1016 }
1017 llvm_unreachable("getAddressSpaceMapMangling() doesn't cover anything.")::llvm::llvm_unreachable_internal("getAddressSpaceMapMangling() doesn't cover anything."
, "clang/lib/AST/ASTContext.cpp", 1017)
;
1018}
1019
1020ASTContext::ASTContext(LangOptions &LOpts, SourceManager &SM,
1021 IdentifierTable &idents, SelectorTable &sels,
1022 Builtin::Context &builtins, TranslationUnitKind TUKind)
1023 : ConstantArrayTypes(this_(), ConstantArrayTypesLog2InitSize),
1024 FunctionProtoTypes(this_(), FunctionProtoTypesLog2InitSize),
1025 TemplateSpecializationTypes(this_()),
1026 DependentTemplateSpecializationTypes(this_()), AutoTypes(this_()),
1027 SubstTemplateTemplateParmPacks(this_()),
1028 CanonTemplateTemplateParms(this_()), SourceMgr(SM), LangOpts(LOpts),
1029 NoSanitizeL(new NoSanitizeList(LangOpts.NoSanitizeFiles, SM)),
1030 XRayFilter(new XRayFunctionFilter(LangOpts.XRayAlwaysInstrumentFiles,
1031 LangOpts.XRayNeverInstrumentFiles,
1032 LangOpts.XRayAttrListFiles, SM)),
1033 ProfList(new ProfileList(LangOpts.ProfileListFiles, SM)),
1034 PrintingPolicy(LOpts), Idents(idents), Selectors(sels),
1035 BuiltinInfo(builtins), TUKind(TUKind), DeclarationNames(*this),
1036 Comments(SM), CommentCommandTraits(BumpAlloc, LOpts.CommentOpts),
1037 CompCategories(this_()), LastSDM(nullptr, 0) {
1038 addTranslationUnitDecl();
1039}
1040
1041void ASTContext::cleanup() {
1042 // Release the DenseMaps associated with DeclContext objects.
1043 // FIXME: Is this the ideal solution?
1044 ReleaseDeclContextMaps();
1045
1046 // Call all of the deallocation functions on all of their targets.
1047 for (auto &Pair : Deallocations)
1048 (Pair.first)(Pair.second);
1049 Deallocations.clear();
1050
1051 // ASTRecordLayout objects in ASTRecordLayouts must always be destroyed
1052 // because they can contain DenseMaps.
1053 for (llvm::DenseMap<const ObjCContainerDecl*,
1054 const ASTRecordLayout*>::iterator
1055 I = ObjCLayouts.begin(), E = ObjCLayouts.end(); I != E; )
1056 // Increment in loop to prevent using deallocated memory.
1057 if (auto *R = const_cast<ASTRecordLayout *>((I++)->second))
1058 R->Destroy(*this);
1059 ObjCLayouts.clear();
1060
1061 for (llvm::DenseMap<const RecordDecl*, const ASTRecordLayout*>::iterator
1062 I = ASTRecordLayouts.begin(), E = ASTRecordLayouts.end(); I != E; ) {
1063 // Increment in loop to prevent using deallocated memory.
1064 if (auto *R = const_cast<ASTRecordLayout *>((I++)->second))
1065 R->Destroy(*this);
1066 }
1067 ASTRecordLayouts.clear();
1068
1069 for (llvm::DenseMap<const Decl*, AttrVec*>::iterator A = DeclAttrs.begin(),
1070 AEnd = DeclAttrs.end();
1071 A != AEnd; ++A)
1072 A->second->~AttrVec();
1073 DeclAttrs.clear();
1074
1075 for (const auto &Value : ModuleInitializers)
1076 Value.second->~PerModuleInitializers();
1077 ModuleInitializers.clear();
1078}
1079
1080ASTContext::~ASTContext() { cleanup(); }
1081
1082void ASTContext::setTraversalScope(const std::vector<Decl *> &TopLevelDecls) {
1083 TraversalScope = TopLevelDecls;
1084 getParentMapContext().clear();
1085}
1086
1087void ASTContext::AddDeallocation(void (*Callback)(void *), void *Data) const {
1088 Deallocations.push_back({Callback, Data});
1089}
1090
1091void
1092ASTContext::setExternalSource(IntrusiveRefCntPtr<ExternalASTSource> Source) {
1093 ExternalSource = std::move(Source);
1094}
1095
1096void ASTContext::PrintStats() const {
1097 llvm::errs() << "\n*** AST Context Stats:\n";
1098 llvm::errs() << " " << Types.size() << " types total.\n";
1099
1100 unsigned counts[] = {
1101#define TYPE(Name, Parent) 0,
1102#define ABSTRACT_TYPE(Name, Parent)
1103#include "clang/AST/TypeNodes.inc"
1104 0 // Extra
1105 };
1106
1107 for (unsigned i = 0, e = Types.size(); i != e; ++i) {
1108 Type *T = Types[i];
1109 counts[(unsigned)T->getTypeClass()]++;
1110 }
1111
1112 unsigned Idx = 0;
1113 unsigned TotalBytes = 0;
1114#define TYPE(Name, Parent) \
1115 if (counts[Idx]) \
1116 llvm::errs() << " " << counts[Idx] << " " << #Name \
1117 << " types, " << sizeof(Name##Type) << " each " \
1118 << "(" << counts[Idx] * sizeof(Name##Type) \
1119 << " bytes)\n"; \
1120 TotalBytes += counts[Idx] * sizeof(Name##Type); \
1121 ++Idx;
1122#define ABSTRACT_TYPE(Name, Parent)
1123#include "clang/AST/TypeNodes.inc"
1124
1125 llvm::errs() << "Total bytes = " << TotalBytes << "\n";
1126
1127 // Implicit special member functions.
1128 llvm::errs() << NumImplicitDefaultConstructorsDeclared << "/"
1129 << NumImplicitDefaultConstructors
1130 << " implicit default constructors created\n";
1131 llvm::errs() << NumImplicitCopyConstructorsDeclared << "/"
1132 << NumImplicitCopyConstructors
1133 << " implicit copy constructors created\n";
1134 if (getLangOpts().CPlusPlus)
1135 llvm::errs() << NumImplicitMoveConstructorsDeclared << "/"
1136 << NumImplicitMoveConstructors
1137 << " implicit move constructors created\n";
1138 llvm::errs() << NumImplicitCopyAssignmentOperatorsDeclared << "/"
1139 << NumImplicitCopyAssignmentOperators
1140 << " implicit copy assignment operators created\n";
1141 if (getLangOpts().CPlusPlus)
1142 llvm::errs() << NumImplicitMoveAssignmentOperatorsDeclared << "/"
1143 << NumImplicitMoveAssignmentOperators
1144 << " implicit move assignment operators created\n";
1145 llvm::errs() << NumImplicitDestructorsDeclared << "/"
1146 << NumImplicitDestructors
1147 << " implicit destructors created\n";
1148
1149 if (ExternalSource) {
1150 llvm::errs() << "\n";
1151 ExternalSource->PrintStats();
1152 }
1153
1154 BumpAlloc.PrintStats();
1155}
1156
1157void ASTContext::mergeDefinitionIntoModule(NamedDecl *ND, Module *M,
1158 bool NotifyListeners) {
1159 if (NotifyListeners)
1160 if (auto *Listener = getASTMutationListener())
1161 Listener->RedefinedHiddenDefinition(ND, M);
1162
1163 MergedDefModules[cast<NamedDecl>(ND->getCanonicalDecl())].push_back(M);
1164}
1165
1166void ASTContext::deduplicateMergedDefinitonsFor(NamedDecl *ND) {
1167 auto It = MergedDefModules.find(cast<NamedDecl>(ND->getCanonicalDecl()));
1168 if (It == MergedDefModules.end())
1169 return;
1170
1171 auto &Merged = It->second;
1172 llvm::DenseSet<Module*> Found;
1173 for (Module *&M : Merged)
1174 if (!Found.insert(M).second)
1175 M = nullptr;
1176 llvm::erase_value(Merged, nullptr);
1177}
1178
1179ArrayRef<Module *>
1180ASTContext::getModulesWithMergedDefinition(const NamedDecl *Def) {
1181 auto MergedIt =
1182 MergedDefModules.find(cast<NamedDecl>(Def->getCanonicalDecl()));
1183 if (MergedIt == MergedDefModules.end())
1184 return std::nullopt;
1185 return MergedIt->second;
1186}
1187
1188void ASTContext::PerModuleInitializers::resolve(ASTContext &Ctx) {
1189 if (LazyInitializers.empty())
1190 return;
1191
1192 auto *Source = Ctx.getExternalSource();
1193 assert(Source && "lazy initializers but no external source")(static_cast <bool> (Source && "lazy initializers but no external source"
) ? void (0) : __assert_fail ("Source && \"lazy initializers but no external source\""
, "clang/lib/AST/ASTContext.cpp", 1193, __extension__ __PRETTY_FUNCTION__
))
;
1194
1195 auto LazyInits = std::move(LazyInitializers);
1196 LazyInitializers.clear();
1197
1198 for (auto ID : LazyInits)
1199 Initializers.push_back(Source->GetExternalDecl(ID));
1200
1201 assert(LazyInitializers.empty() &&(static_cast <bool> (LazyInitializers.empty() &&
"GetExternalDecl for lazy module initializer added more inits"
) ? void (0) : __assert_fail ("LazyInitializers.empty() && \"GetExternalDecl for lazy module initializer added more inits\""
, "clang/lib/AST/ASTContext.cpp", 1202, __extension__ __PRETTY_FUNCTION__
))
1202 "GetExternalDecl for lazy module initializer added more inits")(static_cast <bool> (LazyInitializers.empty() &&
"GetExternalDecl for lazy module initializer added more inits"
) ? void (0) : __assert_fail ("LazyInitializers.empty() && \"GetExternalDecl for lazy module initializer added more inits\""
, "clang/lib/AST/ASTContext.cpp", 1202, __extension__ __PRETTY_FUNCTION__
))
;
1203}
1204
1205void ASTContext::addModuleInitializer(Module *M, Decl *D) {
1206 // One special case: if we add a module initializer that imports another
1207 // module, and that module's only initializer is an ImportDecl, simplify.
1208 if (const auto *ID = dyn_cast<ImportDecl>(D)) {
1209 auto It = ModuleInitializers.find(ID->getImportedModule());
1210
1211 // Maybe the ImportDecl does nothing at all. (Common case.)
1212 if (It == ModuleInitializers.end())
1213 return;
1214
1215 // Maybe the ImportDecl only imports another ImportDecl.
1216 auto &Imported = *It->second;
1217 if (Imported.Initializers.size() + Imported.LazyInitializers.size() == 1) {
1218 Imported.resolve(*this);
1219 auto *OnlyDecl = Imported.Initializers.front();
1220 if (isa<ImportDecl>(OnlyDecl))
1221 D = OnlyDecl;
1222 }
1223 }
1224
1225 auto *&Inits = ModuleInitializers[M];
1226 if (!Inits)
1227 Inits = new (*this) PerModuleInitializers;
1228 Inits->Initializers.push_back(D);
1229}
1230
1231void ASTContext::addLazyModuleInitializers(Module *M, ArrayRef<uint32_t> IDs) {
1232 auto *&Inits = ModuleInitializers[M];
1233 if (!Inits)
1234 Inits = new (*this) PerModuleInitializers;
1235 Inits->LazyInitializers.insert(Inits->LazyInitializers.end(),
1236 IDs.begin(), IDs.end());
1237}
1238
1239ArrayRef<Decl *> ASTContext::getModuleInitializers(Module *M) {
1240 auto It = ModuleInitializers.find(M);
1241 if (It == ModuleInitializers.end())
1242 return std::nullopt;
1243
1244 auto *Inits = It->second;
1245 Inits->resolve(*this);
1246 return Inits->Initializers;
1247}
1248
1249ExternCContextDecl *ASTContext::getExternCContextDecl() const {
1250 if (!ExternCContext)
1251 ExternCContext = ExternCContextDecl::Create(*this, getTranslationUnitDecl());
1252
1253 return ExternCContext;
1254}
1255
1256BuiltinTemplateDecl *
1257ASTContext::buildBuiltinTemplateDecl(BuiltinTemplateKind BTK,
1258 const IdentifierInfo *II) const {
1259 auto *BuiltinTemplate =
1260 BuiltinTemplateDecl::Create(*this, getTranslationUnitDecl(), II, BTK);
1261 BuiltinTemplate->setImplicit();
1262 getTranslationUnitDecl()->addDecl(BuiltinTemplate);
1263
1264 return BuiltinTemplate;
1265}
1266
1267BuiltinTemplateDecl *
1268ASTContext::getMakeIntegerSeqDecl() const {
1269 if (!MakeIntegerSeqDecl)
1270 MakeIntegerSeqDecl = buildBuiltinTemplateDecl(BTK__make_integer_seq,
1271 getMakeIntegerSeqName());
1272 return MakeIntegerSeqDecl;
1273}
1274
1275BuiltinTemplateDecl *
1276ASTContext::getTypePackElementDecl() const {
1277 if (!TypePackElementDecl)
1278 TypePackElementDecl = buildBuiltinTemplateDecl(BTK__type_pack_element,
1279 getTypePackElementName());
1280 return TypePackElementDecl;
1281}
1282
1283RecordDecl *ASTContext::buildImplicitRecord(StringRef Name,
1284 RecordDecl::TagKind TK) const {
1285 SourceLocation Loc;
1286 RecordDecl *NewDecl;
1287 if (getLangOpts().CPlusPlus)
1288 NewDecl = CXXRecordDecl::Create(*this, TK, getTranslationUnitDecl(), Loc,
1289 Loc, &Idents.get(Name));
1290 else
1291 NewDecl = RecordDecl::Create(*this, TK, getTranslationUnitDecl(), Loc, Loc,
1292 &Idents.get(Name));
1293 NewDecl->setImplicit();
1294 NewDecl->addAttr(TypeVisibilityAttr::CreateImplicit(
1295 const_cast<ASTContext &>(*this), TypeVisibilityAttr::Default));
1296 return NewDecl;
1297}
1298
1299TypedefDecl *ASTContext::buildImplicitTypedef(QualType T,
1300 StringRef Name) const {
1301 TypeSourceInfo *TInfo = getTrivialTypeSourceInfo(T);
1302 TypedefDecl *NewDecl = TypedefDecl::Create(
1303 const_cast<ASTContext &>(*this), getTranslationUnitDecl(),
1304 SourceLocation(), SourceLocation(), &Idents.get(Name), TInfo);
1305 NewDecl->setImplicit();
1306 return NewDecl;
1307}
1308
1309TypedefDecl *ASTContext::getInt128Decl() const {
1310 if (!Int128Decl)
1311 Int128Decl = buildImplicitTypedef(Int128Ty, "__int128_t");
1312 return Int128Decl;
1313}
1314
1315TypedefDecl *ASTContext::getUInt128Decl() const {
1316 if (!UInt128Decl)
1317 UInt128Decl = buildImplicitTypedef(UnsignedInt128Ty, "__uint128_t");
1318 return UInt128Decl;
1319}
1320
1321void ASTContext::InitBuiltinType(CanQualType &R, BuiltinType::Kind K) {
1322 auto *Ty = new (*this, TypeAlignment) BuiltinType(K);
1323 R = CanQualType::CreateUnsafe(QualType(Ty, 0));
1324 Types.push_back(Ty);
1325}
1326
1327void ASTContext::InitBuiltinTypes(const TargetInfo &Target,
1328 const TargetInfo *AuxTarget) {
1329 assert((!this->Target || this->Target == &Target) &&(static_cast <bool> ((!this->Target || this->Target
== &Target) && "Incorrect target reinitialization"
) ? void (0) : __assert_fail ("(!this->Target || this->Target == &Target) && \"Incorrect target reinitialization\""
, "clang/lib/AST/ASTContext.cpp", 1330, __extension__ __PRETTY_FUNCTION__
))
1330 "Incorrect target reinitialization")(static_cast <bool> ((!this->Target || this->Target
== &Target) && "Incorrect target reinitialization"
) ? void (0) : __assert_fail ("(!this->Target || this->Target == &Target) && \"Incorrect target reinitialization\""
, "clang/lib/AST/ASTContext.cpp", 1330, __extension__ __PRETTY_FUNCTION__
))
;
1331 assert(VoidTy.isNull() && "Context reinitialized?")(static_cast <bool> (VoidTy.isNull() && "Context reinitialized?"
) ? void (0) : __assert_fail ("VoidTy.isNull() && \"Context reinitialized?\""
, "clang/lib/AST/ASTContext.cpp", 1331, __extension__ __PRETTY_FUNCTION__
))
;
1332
1333 this->Target = &Target;
1334 this->AuxTarget = AuxTarget;
1335
1336 ABI.reset(createCXXABI(Target));
1337 AddrSpaceMapMangling = isAddrSpaceMapManglingEnabled(Target, LangOpts);
1338
1339 // C99 6.2.5p19.
1340 InitBuiltinType(VoidTy, BuiltinType::Void);
1341
1342 // C99 6.2.5p2.
1343 InitBuiltinType(BoolTy, BuiltinType::Bool);
1344 // C99 6.2.5p3.
1345 if (LangOpts.CharIsSigned)
1346 InitBuiltinType(CharTy, BuiltinType::Char_S);
1347 else
1348 InitBuiltinType(CharTy, BuiltinType::Char_U);
1349 // C99 6.2.5p4.
1350 InitBuiltinType(SignedCharTy, BuiltinType::SChar);
1351 InitBuiltinType(ShortTy, BuiltinType::Short);
1352 InitBuiltinType(IntTy, BuiltinType::Int);
1353 InitBuiltinType(LongTy, BuiltinType::Long);
1354 InitBuiltinType(LongLongTy, BuiltinType::LongLong);
1355
1356 // C99 6.2.5p6.
1357 InitBuiltinType(UnsignedCharTy, BuiltinType::UChar);
1358 InitBuiltinType(UnsignedShortTy, BuiltinType::UShort);
1359 InitBuiltinType(UnsignedIntTy, BuiltinType::UInt);
1360 InitBuiltinType(UnsignedLongTy, BuiltinType::ULong);
1361 InitBuiltinType(UnsignedLongLongTy, BuiltinType::ULongLong);
1362
1363 // C99 6.2.5p10.
1364 InitBuiltinType(FloatTy, BuiltinType::Float);
1365 InitBuiltinType(DoubleTy, BuiltinType::Double);
1366 InitBuiltinType(LongDoubleTy, BuiltinType::LongDouble);
1367
1368 // GNU extension, __float128 for IEEE quadruple precision
1369 InitBuiltinType(Float128Ty, BuiltinType::Float128);
1370
1371 // __ibm128 for IBM extended precision
1372 InitBuiltinType(Ibm128Ty, BuiltinType::Ibm128);
1373
1374 // C11 extension ISO/IEC TS 18661-3
1375 InitBuiltinType(Float16Ty, BuiltinType::Float16);
1376
1377 // ISO/IEC JTC1 SC22 WG14 N1169 Extension
1378 InitBuiltinType(ShortAccumTy, BuiltinType::ShortAccum);
1379 InitBuiltinType(AccumTy, BuiltinType::Accum);
1380 InitBuiltinType(LongAccumTy, BuiltinType::LongAccum);
1381 InitBuiltinType(UnsignedShortAccumTy, BuiltinType::UShortAccum);
1382 InitBuiltinType(UnsignedAccumTy, BuiltinType::UAccum);
1383 InitBuiltinType(UnsignedLongAccumTy, BuiltinType::ULongAccum);
1384 InitBuiltinType(ShortFractTy, BuiltinType::ShortFract);
1385 InitBuiltinType(FractTy, BuiltinType::Fract);
1386 InitBuiltinType(LongFractTy, BuiltinType::LongFract);
1387 InitBuiltinType(UnsignedShortFractTy, BuiltinType::UShortFract);
1388 InitBuiltinType(UnsignedFractTy, BuiltinType::UFract);
1389 InitBuiltinType(UnsignedLongFractTy, BuiltinType::ULongFract);
1390 InitBuiltinType(SatShortAccumTy, BuiltinType::SatShortAccum);
1391 InitBuiltinType(SatAccumTy, BuiltinType::SatAccum);
1392 InitBuiltinType(SatLongAccumTy, BuiltinType::SatLongAccum);
1393 InitBuiltinType(SatUnsignedShortAccumTy, BuiltinType::SatUShortAccum);
1394 InitBuiltinType(SatUnsignedAccumTy, BuiltinType::SatUAccum);
1395 InitBuiltinType(SatUnsignedLongAccumTy, BuiltinType::SatULongAccum);
1396 InitBuiltinType(SatShortFractTy, BuiltinType::SatShortFract);
1397 InitBuiltinType(SatFractTy, BuiltinType::SatFract);
1398 InitBuiltinType(SatLongFractTy, BuiltinType::SatLongFract);
1399 InitBuiltinType(SatUnsignedShortFractTy, BuiltinType::SatUShortFract);
1400 InitBuiltinType(SatUnsignedFractTy, BuiltinType::SatUFract);
1401 InitBuiltinType(SatUnsignedLongFractTy, BuiltinType::SatULongFract);
1402
1403 // GNU extension, 128-bit integers.
1404 InitBuiltinType(Int128Ty, BuiltinType::Int128);
1405 InitBuiltinType(UnsignedInt128Ty, BuiltinType::UInt128);
1406
1407 // C++ 3.9.1p5
1408 if (TargetInfo::isTypeSigned(Target.getWCharType()))
1409 InitBuiltinType(WCharTy, BuiltinType::WChar_S);
1410 else // -fshort-wchar makes wchar_t be unsigned.
1411 InitBuiltinType(WCharTy, BuiltinType::WChar_U);
1412 if (LangOpts.CPlusPlus && LangOpts.WChar)
1413 WideCharTy = WCharTy;
1414 else {
1415 // C99 (or C++ using -fno-wchar).
1416 WideCharTy = getFromTargetType(Target.getWCharType());
1417 }
1418
1419 WIntTy = getFromTargetType(Target.getWIntType());
1420
1421 // C++20 (proposed)
1422 InitBuiltinType(Char8Ty, BuiltinType::Char8);
1423
1424 if (LangOpts.CPlusPlus) // C++0x 3.9.1p5, extension for C++
1425 InitBuiltinType(Char16Ty, BuiltinType::Char16);
1426 else // C99
1427 Char16Ty = getFromTargetType(Target.getChar16Type());
1428
1429 if (LangOpts.CPlusPlus) // C++0x 3.9.1p5, extension for C++
1430 InitBuiltinType(Char32Ty, BuiltinType::Char32);
1431 else // C99
1432 Char32Ty = getFromTargetType(Target.getChar32Type());
1433
1434 // Placeholder type for type-dependent expressions whose type is
1435 // completely unknown. No code should ever check a type against
1436 // DependentTy and users should never see it; however, it is here to
1437 // help diagnose failures to properly check for type-dependent
1438 // expressions.
1439 InitBuiltinType(DependentTy, BuiltinType::Dependent);
1440
1441 // Placeholder type for functions.
1442 InitBuiltinType(OverloadTy, BuiltinType::Overload);
1443
1444 // Placeholder type for bound members.
1445 InitBuiltinType(BoundMemberTy, BuiltinType::BoundMember);
1446
1447 // Placeholder type for pseudo-objects.
1448 InitBuiltinType(PseudoObjectTy, BuiltinType::PseudoObject);
1449
1450 // "any" type; useful for debugger-like clients.
1451 InitBuiltinType(UnknownAnyTy, BuiltinType::UnknownAny);
1452
1453 // Placeholder type for unbridged ARC casts.
1454 InitBuiltinType(ARCUnbridgedCastTy, BuiltinType::ARCUnbridgedCast);
1455
1456 // Placeholder type for builtin functions.
1457 InitBuiltinType(BuiltinFnTy, BuiltinType::BuiltinFn);
1458
1459 // Placeholder type for OMP array sections.
1460 if (LangOpts.OpenMP) {
1461 InitBuiltinType(OMPArraySectionTy, BuiltinType::OMPArraySection);
1462 InitBuiltinType(OMPArrayShapingTy, BuiltinType::OMPArrayShaping);
1463 InitBuiltinType(OMPIteratorTy, BuiltinType::OMPIterator);
1464 }
1465 if (LangOpts.MatrixTypes)
1466 InitBuiltinType(IncompleteMatrixIdxTy, BuiltinType::IncompleteMatrixIdx);
1467
1468 // Builtin types for 'id', 'Class', and 'SEL'.
1469 InitBuiltinType(ObjCBuiltinIdTy, BuiltinType::ObjCId);
1470 InitBuiltinType(ObjCBuiltinClassTy, BuiltinType::ObjCClass);
1471 InitBuiltinType(ObjCBuiltinSelTy, BuiltinType::ObjCSel);
1472
1473 if (LangOpts.OpenCL) {
1474#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
1475 InitBuiltinType(SingletonId, BuiltinType::Id);
1476#include "clang/Basic/OpenCLImageTypes.def"
1477
1478 InitBuiltinType(OCLSamplerTy, BuiltinType::OCLSampler);
1479 InitBuiltinType(OCLEventTy, BuiltinType::OCLEvent);
1480 InitBuiltinType(OCLClkEventTy, BuiltinType::OCLClkEvent);
1481 InitBuiltinType(OCLQueueTy, BuiltinType::OCLQueue);
1482 InitBuiltinType(OCLReserveIDTy, BuiltinType::OCLReserveID);
1483
1484#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
1485 InitBuiltinType(Id##Ty, BuiltinType::Id);
1486#include "clang/Basic/OpenCLExtensionTypes.def"
1487 }
1488
1489 if (Target.hasAArch64SVETypes()) {
1490#define SVE_TYPE(Name, Id, SingletonId) \
1491 InitBuiltinType(SingletonId, BuiltinType::Id);
1492#include "clang/Basic/AArch64SVEACLETypes.def"
1493 }
1494
1495 if (Target.getTriple().isPPC64()) {
1496#define PPC_VECTOR_MMA_TYPE(Name, Id, Size) \
1497 InitBuiltinType(Id##Ty, BuiltinType::Id);
1498#include "clang/Basic/PPCTypes.def"
1499#define PPC_VECTOR_VSX_TYPE(Name, Id, Size) \
1500 InitBuiltinType(Id##Ty, BuiltinType::Id);
1501#include "clang/Basic/PPCTypes.def"
1502 }
1503
1504 if (Target.hasRISCVVTypes()) {
1505#define RVV_TYPE(Name, Id, SingletonId) \
1506 InitBuiltinType(SingletonId, BuiltinType::Id);
1507#include "clang/Basic/RISCVVTypes.def"
1508 }
1509
1510 if (Target.getTriple().isWasm() && Target.hasFeature("reference-types")) {
1511#define WASM_TYPE(Name, Id, SingletonId) \
1512 InitBuiltinType(SingletonId, BuiltinType::Id);
1513#include "clang/Basic/WebAssemblyReferenceTypes.def"
1514 }
1515
1516 // Builtin type for __objc_yes and __objc_no
1517 ObjCBuiltinBoolTy = (Target.useSignedCharForObjCBool() ?
1518 SignedCharTy : BoolTy);
1519
1520 ObjCConstantStringType = QualType();
1521
1522 ObjCSuperType = QualType();
1523
1524 // void * type
1525 if (LangOpts.OpenCLGenericAddressSpace) {
1526 auto Q = VoidTy.getQualifiers();
1527 Q.setAddressSpace(LangAS::opencl_generic);
1528 VoidPtrTy = getPointerType(getCanonicalType(
1529 getQualifiedType(VoidTy.getUnqualifiedType(), Q)));
1530 } else {
1531 VoidPtrTy = getPointerType(VoidTy);
1532 }
1533
1534 // nullptr type (C++0x 2.14.7)
1535 InitBuiltinType(NullPtrTy, BuiltinType::NullPtr);
1536
1537 // half type (OpenCL 6.1.1.1) / ARM NEON __fp16
1538 InitBuiltinType(HalfTy, BuiltinType::Half);
1539
1540 InitBuiltinType(BFloat16Ty, BuiltinType::BFloat16);
1541
1542 // Builtin type used to help define __builtin_va_list.
1543 VaListTagDecl = nullptr;
1544
1545 // MSVC predeclares struct _GUID, and we need it to create MSGuidDecls.
1546 if (LangOpts.MicrosoftExt || LangOpts.Borland) {
1547 MSGuidTagDecl = buildImplicitRecord("_GUID");
1548 getTranslationUnitDecl()->addDecl(MSGuidTagDecl);
1549 }
1550}
1551
1552DiagnosticsEngine &ASTContext::getDiagnostics() const {
1553 return SourceMgr.getDiagnostics();
1554}
1555
1556AttrVec& ASTContext::getDeclAttrs(const Decl *D) {
1557 AttrVec *&Result = DeclAttrs[D];
1558 if (!Result) {
1559 void *Mem = Allocate(sizeof(AttrVec));
1560 Result = new (Mem) AttrVec;
1561 }
1562
1563 return *Result;
1564}
1565
1566/// Erase the attributes corresponding to the given declaration.
1567void ASTContext::eraseDeclAttrs(const Decl *D) {
1568 llvm::DenseMap<const Decl*, AttrVec*>::iterator Pos = DeclAttrs.find(D);
1569 if (Pos != DeclAttrs.end()) {
1570 Pos->second->~AttrVec();
1571 DeclAttrs.erase(Pos);
1572 }
1573}
1574
1575// FIXME: Remove ?
1576MemberSpecializationInfo *
1577ASTContext::getInstantiatedFromStaticDataMember(const VarDecl *Var) {
1578 assert(Var->isStaticDataMember() && "Not a static data member")(static_cast <bool> (Var->isStaticDataMember() &&
"Not a static data member") ? void (0) : __assert_fail ("Var->isStaticDataMember() && \"Not a static data member\""
, "clang/lib/AST/ASTContext.cpp", 1578, __extension__ __PRETTY_FUNCTION__
))
;
1579 return getTemplateOrSpecializationInfo(Var)
1580 .dyn_cast<MemberSpecializationInfo *>();
1581}
1582
1583ASTContext::TemplateOrSpecializationInfo
1584ASTContext::getTemplateOrSpecializationInfo(const VarDecl *Var) {
1585 llvm::DenseMap<const VarDecl *, TemplateOrSpecializationInfo>::iterator Pos =
1586 TemplateOrInstantiation.find(Var);
1587 if (Pos == TemplateOrInstantiation.end())
1588 return {};
1589
1590 return Pos->second;
1591}
1592
1593void
1594ASTContext::setInstantiatedFromStaticDataMember(VarDecl *Inst, VarDecl *Tmpl,
1595 TemplateSpecializationKind TSK,
1596 SourceLocation PointOfInstantiation) {
1597 assert(Inst->isStaticDataMember() && "Not a static data member")(static_cast <bool> (Inst->isStaticDataMember() &&
"Not a static data member") ? void (0) : __assert_fail ("Inst->isStaticDataMember() && \"Not a static data member\""
, "clang/lib/AST/ASTContext.cpp", 1597, __extension__ __PRETTY_FUNCTION__
))
;
1598 assert(Tmpl->isStaticDataMember() && "Not a static data member")(static_cast <bool> (Tmpl->isStaticDataMember() &&
"Not a static data member") ? void (0) : __assert_fail ("Tmpl->isStaticDataMember() && \"Not a static data member\""
, "clang/lib/AST/ASTContext.cpp", 1598, __extension__ __PRETTY_FUNCTION__
))
;
1599 setTemplateOrSpecializationInfo(Inst, new (*this) MemberSpecializationInfo(
1600 Tmpl, TSK, PointOfInstantiation));
1601}
1602
1603void
1604ASTContext::setTemplateOrSpecializationInfo(VarDecl *Inst,
1605 TemplateOrSpecializationInfo TSI) {
1606 assert(!TemplateOrInstantiation[Inst] &&(static_cast <bool> (!TemplateOrInstantiation[Inst] &&
"Already noted what the variable was instantiated from") ? void
(0) : __assert_fail ("!TemplateOrInstantiation[Inst] && \"Already noted what the variable was instantiated from\""
, "clang/lib/AST/ASTContext.cpp", 1607, __extension__ __PRETTY_FUNCTION__
))
1607 "Already noted what the variable was instantiated from")(static_cast <bool> (!TemplateOrInstantiation[Inst] &&
"Already noted what the variable was instantiated from") ? void
(0) : __assert_fail ("!TemplateOrInstantiation[Inst] && \"Already noted what the variable was instantiated from\""
, "clang/lib/AST/ASTContext.cpp", 1607, __extension__ __PRETTY_FUNCTION__
))
;
1608 TemplateOrInstantiation[Inst] = TSI;
1609}
1610
1611NamedDecl *
1612ASTContext::getInstantiatedFromUsingDecl(NamedDecl *UUD) {
1613 auto Pos = InstantiatedFromUsingDecl.find(UUD);
1614 if (Pos == InstantiatedFromUsingDecl.end())
1615 return nullptr;
1616
1617 return Pos->second;
1618}
1619
1620void
1621ASTContext::setInstantiatedFromUsingDecl(NamedDecl *Inst, NamedDecl *Pattern) {
1622 assert((isa<UsingDecl>(Pattern) ||(static_cast <bool> ((isa<UsingDecl>(Pattern) || isa
<UnresolvedUsingValueDecl>(Pattern) || isa<UnresolvedUsingTypenameDecl
>(Pattern)) && "pattern decl is not a using decl")
? void (0) : __assert_fail ("(isa<UsingDecl>(Pattern) || isa<UnresolvedUsingValueDecl>(Pattern) || isa<UnresolvedUsingTypenameDecl>(Pattern)) && \"pattern decl is not a using decl\""
, "clang/lib/AST/ASTContext.cpp", 1625, __extension__ __PRETTY_FUNCTION__
))
1623 isa<UnresolvedUsingValueDecl>(Pattern) ||(static_cast <bool> ((isa<UsingDecl>(Pattern) || isa
<UnresolvedUsingValueDecl>(Pattern) || isa<UnresolvedUsingTypenameDecl
>(Pattern)) && "pattern decl is not a using decl")
? void (0) : __assert_fail ("(isa<UsingDecl>(Pattern) || isa<UnresolvedUsingValueDecl>(Pattern) || isa<UnresolvedUsingTypenameDecl>(Pattern)) && \"pattern decl is not a using decl\""
, "clang/lib/AST/ASTContext.cpp", 1625, __extension__ __PRETTY_FUNCTION__
))
1624 isa<UnresolvedUsingTypenameDecl>(Pattern)) &&(static_cast <bool> ((isa<UsingDecl>(Pattern) || isa
<UnresolvedUsingValueDecl>(Pattern) || isa<UnresolvedUsingTypenameDecl
>(Pattern)) && "pattern decl is not a using decl")
? void (0) : __assert_fail ("(isa<UsingDecl>(Pattern) || isa<UnresolvedUsingValueDecl>(Pattern) || isa<UnresolvedUsingTypenameDecl>(Pattern)) && \"pattern decl is not a using decl\""
, "clang/lib/AST/ASTContext.cpp", 1625, __extension__ __PRETTY_FUNCTION__
))
1625 "pattern decl is not a using decl")(static_cast <bool> ((isa<UsingDecl>(Pattern) || isa
<UnresolvedUsingValueDecl>(Pattern) || isa<UnresolvedUsingTypenameDecl
>(Pattern)) && "pattern decl is not a using decl")
? void (0) : __assert_fail ("(isa<UsingDecl>(Pattern) || isa<UnresolvedUsingValueDecl>(Pattern) || isa<UnresolvedUsingTypenameDecl>(Pattern)) && \"pattern decl is not a using decl\""
, "clang/lib/AST/ASTContext.cpp", 1625, __extension__ __PRETTY_FUNCTION__
))
;
1626 assert((isa<UsingDecl>(Inst) ||(static_cast <bool> ((isa<UsingDecl>(Inst) || isa
<UnresolvedUsingValueDecl>(Inst) || isa<UnresolvedUsingTypenameDecl
>(Inst)) && "instantiation did not produce a using decl"
) ? void (0) : __assert_fail ("(isa<UsingDecl>(Inst) || isa<UnresolvedUsingValueDecl>(Inst) || isa<UnresolvedUsingTypenameDecl>(Inst)) && \"instantiation did not produce a using decl\""
, "clang/lib/AST/ASTContext.cpp", 1629, __extension__ __PRETTY_FUNCTION__
))
1627 isa<UnresolvedUsingValueDecl>(Inst) ||(static_cast <bool> ((isa<UsingDecl>(Inst) || isa
<UnresolvedUsingValueDecl>(Inst) || isa<UnresolvedUsingTypenameDecl
>(Inst)) && "instantiation did not produce a using decl"
) ? void (0) : __assert_fail ("(isa<UsingDecl>(Inst) || isa<UnresolvedUsingValueDecl>(Inst) || isa<UnresolvedUsingTypenameDecl>(Inst)) && \"instantiation did not produce a using decl\""
, "clang/lib/AST/ASTContext.cpp", 1629, __extension__ __PRETTY_FUNCTION__
))
1628 isa<UnresolvedUsingTypenameDecl>(Inst)) &&(static_cast <bool> ((isa<UsingDecl>(Inst) || isa
<UnresolvedUsingValueDecl>(Inst) || isa<UnresolvedUsingTypenameDecl
>(Inst)) && "instantiation did not produce a using decl"
) ? void (0) : __assert_fail ("(isa<UsingDecl>(Inst) || isa<UnresolvedUsingValueDecl>(Inst) || isa<UnresolvedUsingTypenameDecl>(Inst)) && \"instantiation did not produce a using decl\""
, "clang/lib/AST/ASTContext.cpp", 1629, __extension__ __PRETTY_FUNCTION__
))
1629 "instantiation did not produce a using decl")(static_cast <bool> ((isa<UsingDecl>(Inst) || isa
<UnresolvedUsingValueDecl>(Inst) || isa<UnresolvedUsingTypenameDecl
>(Inst)) && "instantiation did not produce a using decl"
) ? void (0) : __assert_fail ("(isa<UsingDecl>(Inst) || isa<UnresolvedUsingValueDecl>(Inst) || isa<UnresolvedUsingTypenameDecl>(Inst)) && \"instantiation did not produce a using decl\""
, "clang/lib/AST/ASTContext.cpp", 1629, __extension__ __PRETTY_FUNCTION__
))
;
1630 assert(!InstantiatedFromUsingDecl[Inst] && "pattern already exists")(static_cast <bool> (!InstantiatedFromUsingDecl[Inst] &&
"pattern already exists") ? void (0) : __assert_fail ("!InstantiatedFromUsingDecl[Inst] && \"pattern already exists\""
, "clang/lib/AST/ASTContext.cpp", 1630, __extension__ __PRETTY_FUNCTION__
))
;
1631 InstantiatedFromUsingDecl[Inst] = Pattern;
1632}
1633
1634UsingEnumDecl *
1635ASTContext::getInstantiatedFromUsingEnumDecl(UsingEnumDecl *UUD) {
1636 auto Pos = InstantiatedFromUsingEnumDecl.find(UUD);
1637 if (Pos == InstantiatedFromUsingEnumDecl.end())
1638 return nullptr;
1639
1640 return Pos->second;
1641}
1642
1643void ASTContext::setInstantiatedFromUsingEnumDecl(UsingEnumDecl *Inst,
1644 UsingEnumDecl *Pattern) {
1645 assert(!InstantiatedFromUsingEnumDecl[Inst] && "pattern already exists")(static_cast <bool> (!InstantiatedFromUsingEnumDecl[Inst
] && "pattern already exists") ? void (0) : __assert_fail
("!InstantiatedFromUsingEnumDecl[Inst] && \"pattern already exists\""
, "clang/lib/AST/ASTContext.cpp", 1645, __extension__ __PRETTY_FUNCTION__
))
;
1646 InstantiatedFromUsingEnumDecl[Inst] = Pattern;
1647}
1648
1649UsingShadowDecl *
1650ASTContext::getInstantiatedFromUsingShadowDecl(UsingShadowDecl *Inst) {
1651 llvm::DenseMap<UsingShadowDecl*, UsingShadowDecl*>::const_iterator Pos
1652 = InstantiatedFromUsingShadowDecl.find(Inst);
1653 if (Pos == InstantiatedFromUsingShadowDecl.end())
1654 return nullptr;
1655
1656 return Pos->second;
1657}
1658
1659void
1660ASTContext::setInstantiatedFromUsingShadowDecl(UsingShadowDecl *Inst,
1661 UsingShadowDecl *Pattern) {
1662 assert(!InstantiatedFromUsingShadowDecl[Inst] && "pattern already exists")(static_cast <bool> (!InstantiatedFromUsingShadowDecl[Inst
] && "pattern already exists") ? void (0) : __assert_fail
("!InstantiatedFromUsingShadowDecl[Inst] && \"pattern already exists\""
, "clang/lib/AST/ASTContext.cpp", 1662, __extension__ __PRETTY_FUNCTION__
))
;
1663 InstantiatedFromUsingShadowDecl[Inst] = Pattern;
1664}
1665
1666FieldDecl *ASTContext::getInstantiatedFromUnnamedFieldDecl(FieldDecl *Field) {
1667 llvm::DenseMap<FieldDecl *, FieldDecl *>::iterator Pos
1668 = InstantiatedFromUnnamedFieldDecl.find(Field);
1669 if (Pos == InstantiatedFromUnnamedFieldDecl.end())
1670 return nullptr;
1671
1672 return Pos->second;
1673}
1674
1675void ASTContext::setInstantiatedFromUnnamedFieldDecl(FieldDecl *Inst,
1676 FieldDecl *Tmpl) {
1677 assert(!Inst->getDeclName() && "Instantiated field decl is not unnamed")(static_cast <bool> (!Inst->getDeclName() &&
"Instantiated field decl is not unnamed") ? void (0) : __assert_fail
("!Inst->getDeclName() && \"Instantiated field decl is not unnamed\""
, "clang/lib/AST/ASTContext.cpp", 1677, __extension__ __PRETTY_FUNCTION__
))
;
1678 assert(!Tmpl->getDeclName() && "Template field decl is not unnamed")(static_cast <bool> (!Tmpl->getDeclName() &&
"Template field decl is not unnamed") ? void (0) : __assert_fail
("!Tmpl->getDeclName() && \"Template field decl is not unnamed\""
, "clang/lib/AST/ASTContext.cpp", 1678, __extension__ __PRETTY_FUNCTION__
))
;
1679 assert(!InstantiatedFromUnnamedFieldDecl[Inst] &&(static_cast <bool> (!InstantiatedFromUnnamedFieldDecl[
Inst] && "Already noted what unnamed field was instantiated from"
) ? void (0) : __assert_fail ("!InstantiatedFromUnnamedFieldDecl[Inst] && \"Already noted what unnamed field was instantiated from\""
, "clang/lib/AST/ASTContext.cpp", 1680, __extension__ __PRETTY_FUNCTION__
))
1680 "Already noted what unnamed field was instantiated from")(static_cast <bool> (!InstantiatedFromUnnamedFieldDecl[
Inst] && "Already noted what unnamed field was instantiated from"
) ? void (0) : __assert_fail ("!InstantiatedFromUnnamedFieldDecl[Inst] && \"Already noted what unnamed field was instantiated from\""
, "clang/lib/AST/ASTContext.cpp", 1680, __extension__ __PRETTY_FUNCTION__
))
;
1681
1682 InstantiatedFromUnnamedFieldDecl[Inst] = Tmpl;
1683}
1684
1685ASTContext::overridden_cxx_method_iterator
1686ASTContext::overridden_methods_begin(const CXXMethodDecl *Method) const {
1687 return overridden_methods(Method).begin();
1688}
1689
1690ASTContext::overridden_cxx_method_iterator
1691ASTContext::overridden_methods_end(const CXXMethodDecl *Method) const {
1692 return overridden_methods(Method).end();
1693}
1694
1695unsigned
1696ASTContext::overridden_methods_size(const CXXMethodDecl *Method) const {
1697 auto Range = overridden_methods(Method);
1698 return Range.end() - Range.begin();
1699}
1700
1701ASTContext::overridden_method_range
1702ASTContext::overridden_methods(const CXXMethodDecl *Method) const {
1703 llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector>::const_iterator Pos =
1704 OverriddenMethods.find(Method->getCanonicalDecl());
1705 if (Pos == OverriddenMethods.end())
1706 return overridden_method_range(nullptr, nullptr);
1707 return overridden_method_range(Pos->second.begin(), Pos->second.end());
1708}
1709
1710void ASTContext::addOverriddenMethod(const CXXMethodDecl *Method,
1711 const CXXMethodDecl *Overridden) {
1712 assert(Method->isCanonicalDecl() && Overridden->isCanonicalDecl())(static_cast <bool> (Method->isCanonicalDecl() &&
Overridden->isCanonicalDecl()) ? void (0) : __assert_fail
("Method->isCanonicalDecl() && Overridden->isCanonicalDecl()"
, "clang/lib/AST/ASTContext.cpp", 1712, __extension__ __PRETTY_FUNCTION__
))
;
1713 OverriddenMethods[Method].push_back(Overridden);
1714}
1715
1716void ASTContext::getOverriddenMethods(
1717 const NamedDecl *D,
1718 SmallVectorImpl<const NamedDecl *> &Overridden) const {
1719 assert(D)(static_cast <bool> (D) ? void (0) : __assert_fail ("D"
, "clang/lib/AST/ASTContext.cpp", 1719, __extension__ __PRETTY_FUNCTION__
))
;
1720
1721 if (const auto *CXXMethod = dyn_cast<CXXMethodDecl>(D)) {
1722 Overridden.append(overridden_methods_begin(CXXMethod),
1723 overridden_methods_end(CXXMethod));
1724 return;
1725 }
1726
1727 const auto *Method = dyn_cast<ObjCMethodDecl>(D);
1728 if (!Method)
1729 return;
1730
1731 SmallVector<const ObjCMethodDecl *, 8> OverDecls;
1732 Method->getOverriddenMethods(OverDecls);
1733 Overridden.append(OverDecls.begin(), OverDecls.end());
1734}
1735
1736void ASTContext::addedLocalImportDecl(ImportDecl *Import) {
1737 assert(!Import->getNextLocalImport() &&(static_cast <bool> (!Import->getNextLocalImport() &&
"Import declaration already in the chain") ? void (0) : __assert_fail
("!Import->getNextLocalImport() && \"Import declaration already in the chain\""
, "clang/lib/AST/ASTContext.cpp", 1738, __extension__ __PRETTY_FUNCTION__
))
1738 "Import declaration already in the chain")(static_cast <bool> (!Import->getNextLocalImport() &&
"Import declaration already in the chain") ? void (0) : __assert_fail
("!Import->getNextLocalImport() && \"Import declaration already in the chain\""
, "clang/lib/AST/ASTContext.cpp", 1738, __extension__ __PRETTY_FUNCTION__
))
;
1739 assert(!Import->isFromASTFile() && "Non-local import declaration")(static_cast <bool> (!Import->isFromASTFile() &&
"Non-local import declaration") ? void (0) : __assert_fail (
"!Import->isFromASTFile() && \"Non-local import declaration\""
, "clang/lib/AST/ASTContext.cpp", 1739, __extension__ __PRETTY_FUNCTION__
))
;
1740 if (!FirstLocalImport) {
1741 FirstLocalImport = Import;
1742 LastLocalImport = Import;
1743 return;
1744 }
1745
1746 LastLocalImport->setNextLocalImport(Import);
1747 LastLocalImport = Import;
1748}
1749
1750//===----------------------------------------------------------------------===//
1751// Type Sizing and Analysis
1752//===----------------------------------------------------------------------===//
1753
1754/// getFloatTypeSemantics - Return the APFloat 'semantics' for the specified
1755/// scalar floating point type.
1756const llvm::fltSemantics &ASTContext::getFloatTypeSemantics(QualType T) const {
1757 switch (T->castAs<BuiltinType>()->getKind()) {
1758 default:
1759 llvm_unreachable("Not a floating point type!")::llvm::llvm_unreachable_internal("Not a floating point type!"
, "clang/lib/AST/ASTContext.cpp", 1759)
;
1760 case BuiltinType::BFloat16:
1761 return Target->getBFloat16Format();
1762 case BuiltinType::Float16:
1763 return Target->getHalfFormat();
1764 case BuiltinType::Half:
1765 // For HLSL, when the native half type is disabled, half will be treat as
1766 // float.
1767 if (getLangOpts().HLSL)
1768 if (getLangOpts().NativeHalfType)
1769 return Target->getHalfFormat();
1770 else
1771 return Target->getFloatFormat();
1772 else
1773 return Target->getHalfFormat();
1774 case BuiltinType::Float: return Target->getFloatFormat();
1775 case BuiltinType::Double: return Target->getDoubleFormat();
1776 case BuiltinType::Ibm128:
1777 return Target->getIbm128Format();
1778 case BuiltinType::LongDouble:
1779 if (getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice)
1780 return AuxTarget->getLongDoubleFormat();
1781 return Target->getLongDoubleFormat();
1782 case BuiltinType::Float128:
1783 if (getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice)
1784 return AuxTarget->getFloat128Format();
1785 return Target->getFloat128Format();
1786 }
1787}
1788
1789CharUnits ASTContext::getDeclAlign(const Decl *D, bool ForAlignof) const {
1790 unsigned Align = Target->getCharWidth();
1791
1792 bool UseAlignAttrOnly = false;
1793 if (unsigned AlignFromAttr = D->getMaxAlignment()) {
1794 Align = AlignFromAttr;
1795
1796 // __attribute__((aligned)) can increase or decrease alignment
1797 // *except* on a struct or struct member, where it only increases
1798 // alignment unless 'packed' is also specified.
1799 //
1800 // It is an error for alignas to decrease alignment, so we can
1801 // ignore that possibility; Sema should diagnose it.
1802 if (isa<FieldDecl>(D)) {
1803 UseAlignAttrOnly = D->hasAttr<PackedAttr>() ||
1804 cast<FieldDecl>(D)->getParent()->hasAttr<PackedAttr>();
1805 } else {
1806 UseAlignAttrOnly = true;
1807 }
1808 }
1809 else if (isa<FieldDecl>(D))
1810 UseAlignAttrOnly =
1811 D->hasAttr<PackedAttr>() ||
1812 cast<FieldDecl>(D)->getParent()->hasAttr<PackedAttr>();
1813
1814 // If we're using the align attribute only, just ignore everything
1815 // else about the declaration and its type.
1816 if (UseAlignAttrOnly) {
1817 // do nothing
1818 } else if (const auto *VD = dyn_cast<ValueDecl>(D)) {
1819 QualType T = VD->getType();
1820 if (const auto *RT = T->getAs<ReferenceType>()) {
1821 if (ForAlignof)
1822 T = RT->getPointeeType();
1823 else
1824 T = getPointerType(RT->getPointeeType());
1825 }
1826 QualType BaseT = getBaseElementType(T);
1827 if (T->isFunctionType())
1828 Align = getTypeInfoImpl(T.getTypePtr()).Align;
1829 else if (!BaseT->isIncompleteType()) {
1830 // Adjust alignments of declarations with array type by the
1831 // large-array alignment on the target.
1832 if (const ArrayType *arrayType = getAsArrayType(T)) {
1833 unsigned MinWidth = Target->getLargeArrayMinWidth();
1834 if (!ForAlignof && MinWidth) {
1835 if (isa<VariableArrayType>(arrayType))
1836 Align = std::max(Align, Target->getLargeArrayAlign());
1837 else if (isa<ConstantArrayType>(arrayType) &&
1838 MinWidth <= getTypeSize(cast<ConstantArrayType>(arrayType)))
1839 Align = std::max(Align, Target->getLargeArrayAlign());
1840 }
1841 }
1842 Align = std::max(Align, getPreferredTypeAlign(T.getTypePtr()));
1843 if (BaseT.getQualifiers().hasUnaligned())
1844 Align = Target->getCharWidth();
1845 if (const auto *VD = dyn_cast<VarDecl>(D)) {
1846 if (VD->hasGlobalStorage() && !ForAlignof) {
1847 uint64_t TypeSize = getTypeSize(T.getTypePtr());
1848 Align = std::max(Align, getTargetInfo().getMinGlobalAlign(TypeSize));
1849 }
1850 }
1851 }
1852
1853 // Fields can be subject to extra alignment constraints, like if
1854 // the field is packed, the struct is packed, or the struct has a
1855 // a max-field-alignment constraint (#pragma pack). So calculate
1856 // the actual alignment of the field within the struct, and then
1857 // (as we're expected to) constrain that by the alignment of the type.
1858 if (const auto *Field = dyn_cast<FieldDecl>(VD)) {
1859 const RecordDecl *Parent = Field->getParent();
1860 // We can only produce a sensible answer if the record is valid.
1861 if (!Parent->isInvalidDecl()) {
1862 const ASTRecordLayout &Layout = getASTRecordLayout(Parent);
1863
1864 // Start with the record's overall alignment.
1865 unsigned FieldAlign = toBits(Layout.getAlignment());
1866
1867 // Use the GCD of that and the offset within the record.
1868 uint64_t Offset = Layout.getFieldOffset(Field->getFieldIndex());
1869 if (Offset > 0) {
1870 // Alignment is always a power of 2, so the GCD will be a power of 2,
1871 // which means we get to do this crazy thing instead of Euclid's.
1872 uint64_t LowBitOfOffset = Offset & (~Offset + 1);
1873 if (LowBitOfOffset < FieldAlign)
1874 FieldAlign = static_cast<unsigned>(LowBitOfOffset);
1875 }
1876
1877 Align = std::min(Align, FieldAlign);
1878 }
1879 }
1880 }
1881
1882 // Some targets have hard limitation on the maximum requestable alignment in
1883 // aligned attribute for static variables.
1884 const unsigned MaxAlignedAttr = getTargetInfo().getMaxAlignedAttribute();
1885 const auto *VD = dyn_cast<VarDecl>(D);
1886 if (MaxAlignedAttr && VD && VD->getStorageClass() == SC_Static)
1887 Align = std::min(Align, MaxAlignedAttr);
1888
1889 return toCharUnitsFromBits(Align);
1890}
1891
1892CharUnits ASTContext::getExnObjectAlignment() const {
1893 return toCharUnitsFromBits(Target->getExnObjectAlignment());
1894}
1895
1896// getTypeInfoDataSizeInChars - Return the size of a type, in
1897// chars. If the type is a record, its data size is returned. This is
1898// the size of the memcpy that's performed when assigning this type
1899// using a trivial copy/move assignment operator.
1900TypeInfoChars ASTContext::getTypeInfoDataSizeInChars(QualType T) const {
1901 TypeInfoChars Info = getTypeInfoInChars(T);
1902
1903 // In C++, objects can sometimes be allocated into the tail padding
1904 // of a base-class subobject. We decide whether that's possible
1905 // during class layout, so here we can just trust the layout results.
1906 if (getLangOpts().CPlusPlus) {
1907 if (const auto *RT = T->getAs<RecordType>()) {
1908 const ASTRecordLayout &layout = getASTRecordLayout(RT->getDecl());
1909 Info.Width = layout.getDataSize();
1910 }
1911 }
1912
1913 return Info;
1914}
1915
1916/// getConstantArrayInfoInChars - Performing the computation in CharUnits
1917/// instead of in bits prevents overflowing the uint64_t for some large arrays.
1918TypeInfoChars
1919static getConstantArrayInfoInChars(const ASTContext &Context,
1920 const ConstantArrayType *CAT) {
1921 TypeInfoChars EltInfo = Context.getTypeInfoInChars(CAT->getElementType());
1922 uint64_t Size = CAT->getSize().getZExtValue();
1923 assert((Size == 0 || static_cast<uint64_t>(EltInfo.Width.getQuantity()) <=(static_cast <bool> ((Size == 0 || static_cast<uint64_t
>(EltInfo.Width.getQuantity()) <= (uint64_t)(-1)/Size) &&
"Overflow in array type char size evaluation") ? void (0) : __assert_fail
("(Size == 0 || static_cast<uint64_t>(EltInfo.Width.getQuantity()) <= (uint64_t)(-1)/Size) && \"Overflow in array type char size evaluation\""
, "clang/lib/AST/ASTContext.cpp", 1925, __extension__ __PRETTY_FUNCTION__
))
1924 (uint64_t)(-1)/Size) &&(static_cast <bool> ((Size == 0 || static_cast<uint64_t
>(EltInfo.Width.getQuantity()) <= (uint64_t)(-1)/Size) &&
"Overflow in array type char size evaluation") ? void (0) : __assert_fail
("(Size == 0 || static_cast<uint64_t>(EltInfo.Width.getQuantity()) <= (uint64_t)(-1)/Size) && \"Overflow in array type char size evaluation\""
, "clang/lib/AST/ASTContext.cpp", 1925, __extension__ __PRETTY_FUNCTION__
))
1925 "Overflow in array type char size evaluation")(static_cast <bool> ((Size == 0 || static_cast<uint64_t
>(EltInfo.Width.getQuantity()) <= (uint64_t)(-1)/Size) &&
"Overflow in array type char size evaluation") ? void (0) : __assert_fail
("(Size == 0 || static_cast<uint64_t>(EltInfo.Width.getQuantity()) <= (uint64_t)(-1)/Size) && \"Overflow in array type char size evaluation\""
, "clang/lib/AST/ASTContext.cpp", 1925, __extension__ __PRETTY_FUNCTION__
))
;
1926 uint64_t Width = EltInfo.Width.getQuantity() * Size;
1927 unsigned Align = EltInfo.Align.getQuantity();
1928 if (!Context.getTargetInfo().getCXXABI().isMicrosoft() ||
1929 Context.getTargetInfo().getPointerWidth(LangAS::Default) == 64)
1930 Width = llvm::alignTo(Width, Align);
1931 return TypeInfoChars(CharUnits::fromQuantity(Width),
1932 CharUnits::fromQuantity(Align),
1933 EltInfo.AlignRequirement);
1934}
1935
1936TypeInfoChars ASTContext::getTypeInfoInChars(const Type *T) const {
1937 if (const auto *CAT = dyn_cast<ConstantArrayType>(T))
1938 return getConstantArrayInfoInChars(*this, CAT);
1939 TypeInfo Info = getTypeInfo(T);
1940 return TypeInfoChars(toCharUnitsFromBits(Info.Width),
1941 toCharUnitsFromBits(Info.Align), Info.AlignRequirement);
1942}
1943
1944TypeInfoChars ASTContext::getTypeInfoInChars(QualType T) const {
1945 return getTypeInfoInChars(T.getTypePtr());
1946}
1947
1948bool ASTContext::isPromotableIntegerType(QualType T) const {
1949 // HLSL doesn't promote all small integer types to int, it
1950 // just uses the rank-based promotion rules for all types.
1951 if (getLangOpts().HLSL)
1952 return false;
1953
1954 if (const auto *BT = T->getAs<BuiltinType>())
1955 switch (BT->getKind()) {
1956 case BuiltinType::Bool:
1957 case BuiltinType::Char_S:
1958 case BuiltinType::Char_U:
1959 case BuiltinType::SChar:
1960 case BuiltinType::UChar:
1961 case BuiltinType::Short:
1962 case BuiltinType::UShort:
1963 case BuiltinType::WChar_S:
1964 case BuiltinType::WChar_U:
1965 case BuiltinType::Char8:
1966 case BuiltinType::Char16:
1967 case BuiltinType::Char32:
1968 return true;
1969 default:
1970 return false;
1971 }
1972
1973 // Enumerated types are promotable to their compatible integer types
1974 // (C99 6.3.1.1) a.k.a. its underlying type (C++ [conv.prom]p2).
1975 if (const auto *ET = T->getAs<EnumType>()) {
1976 if (T->isDependentType() || ET->getDecl()->getPromotionType().isNull() ||
1977 ET->getDecl()->isScoped())
1978 return false;
1979
1980 return true;
1981 }
1982
1983 return false;
1984}
1985
1986bool ASTContext::isAlignmentRequired(const Type *T) const {
1987 return getTypeInfo(T).AlignRequirement != AlignRequirementKind::None;
1988}
1989
1990bool ASTContext::isAlignmentRequired(QualType T) const {
1991 return isAlignmentRequired(T.getTypePtr());
1992}
1993
1994unsigned ASTContext::getTypeAlignIfKnown(QualType T,
1995 bool NeedsPreferredAlignment) const {
1996 // An alignment on a typedef overrides anything else.
1997 if (const auto *TT = T->getAs<TypedefType>())
1998 if (unsigned Align = TT->getDecl()->getMaxAlignment())
1999 return Align;
2000
2001 // If we have an (array of) complete type, we're done.
2002 T = getBaseElementType(T);
2003 if (!T->isIncompleteType())
2004 return NeedsPreferredAlignment ? getPreferredTypeAlign(T) : getTypeAlign(T);
2005
2006 // If we had an array type, its element type might be a typedef
2007 // type with an alignment attribute.
2008 if (const auto *TT = T->getAs<TypedefType>())
2009 if (unsigned Align = TT->getDecl()->getMaxAlignment())
2010 return Align;
2011
2012 // Otherwise, see if the declaration of the type had an attribute.
2013 if (const auto *TT = T->getAs<TagType>())
2014 return TT->getDecl()->getMaxAlignment();
2015
2016 return 0;
2017}
2018
2019TypeInfo ASTContext::getTypeInfo(const Type *T) const {
2020 TypeInfoMap::iterator I = MemoizedTypeInfo.find(T);
2021 if (I != MemoizedTypeInfo.end())
2022 return I->second;
2023
2024 // This call can invalidate MemoizedTypeInfo[T], so we need a second lookup.
2025 TypeInfo TI = getTypeInfoImpl(T);
2026 MemoizedTypeInfo[T] = TI;
2027 return TI;
2028}
2029
2030/// getTypeInfoImpl - Return the size of the specified type, in bits. This
2031/// method does not work on incomplete types.
2032///
2033/// FIXME: Pointers into different addr spaces could have different sizes and
2034/// alignment requirements: getPointerInfo should take an AddrSpace, this
2035/// should take a QualType, &c.
2036TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
2037 uint64_t Width = 0;
2038 unsigned Align = 8;
2039 AlignRequirementKind AlignRequirement = AlignRequirementKind::None;
2040 LangAS AS = LangAS::Default;
2041 switch (T->getTypeClass()) {
2042#define TYPE(Class, Base)
2043#define ABSTRACT_TYPE(Class, Base)
2044#define NON_CANONICAL_TYPE(Class, Base)
2045#define DEPENDENT_TYPE(Class, Base) case Type::Class:
2046#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) \
2047 case Type::Class: \
2048 assert(!T->isDependentType() && "should not see dependent types here")(static_cast <bool> (!T->isDependentType() &&
"should not see dependent types here") ? void (0) : __assert_fail
("!T->isDependentType() && \"should not see dependent types here\""
, "clang/lib/AST/ASTContext.cpp", 2048, __extension__ __PRETTY_FUNCTION__
))
; \
2049 return getTypeInfo(cast<Class##Type>(T)->desugar().getTypePtr());
2050#include "clang/AST/TypeNodes.inc"
2051 llvm_unreachable("Should not see dependent types")::llvm::llvm_unreachable_internal("Should not see dependent types"
, "clang/lib/AST/ASTContext.cpp", 2051)
;
2052
2053 case Type::FunctionNoProto:
2054 case Type::FunctionProto:
2055 // GCC extension: alignof(function) = 32 bits
2056 Width = 0;
2057 Align = 32;
2058 break;
2059
2060 case Type::IncompleteArray:
2061 case Type::VariableArray:
2062 case Type::ConstantArray: {
2063 // Model non-constant sized arrays as size zero, but track the alignment.
2064 uint64_t Size = 0;
2065 if (const auto *CAT = dyn_cast<ConstantArrayType>(T))
2066 Size = CAT->getSize().getZExtValue();
2067
2068 TypeInfo EltInfo = getTypeInfo(cast<ArrayType>(T)->getElementType());
2069 assert((Size == 0 || EltInfo.Width <= (uint64_t)(-1) / Size) &&(static_cast <bool> ((Size == 0 || EltInfo.Width <= (
uint64_t)(-1) / Size) && "Overflow in array type bit size evaluation"
) ? void (0) : __assert_fail ("(Size == 0 || EltInfo.Width <= (uint64_t)(-1) / Size) && \"Overflow in array type bit size evaluation\""
, "clang/lib/AST/ASTContext.cpp", 2070, __extension__ __PRETTY_FUNCTION__
))
2070 "Overflow in array type bit size evaluation")(static_cast <bool> ((Size == 0 || EltInfo.Width <= (
uint64_t)(-1) / Size) && "Overflow in array type bit size evaluation"
) ? void (0) : __assert_fail ("(Size == 0 || EltInfo.Width <= (uint64_t)(-1) / Size) && \"Overflow in array type bit size evaluation\""
, "clang/lib/AST/ASTContext.cpp", 2070, __extension__ __PRETTY_FUNCTION__
))
;
2071 Width = EltInfo.Width * Size;
2072 Align = EltInfo.Align;
2073 AlignRequirement = EltInfo.AlignRequirement;
2074 if (!getTargetInfo().getCXXABI().isMicrosoft() ||
2075 getTargetInfo().getPointerWidth(LangAS::Default) == 64)
2076 Width = llvm::alignTo(Width, Align);
2077 break;
2078 }
2079
2080 case Type::ExtVector:
2081 case Type::Vector: {
2082 const auto *VT = cast<VectorType>(T);
2083 TypeInfo EltInfo = getTypeInfo(VT->getElementType());
2084 Width = VT->isExtVectorBoolType() ? VT->getNumElements()
2085 : EltInfo.Width * VT->getNumElements();
2086 // Enforce at least byte size and alignment.
2087 Width = std::max<unsigned>(8, Width);
2088 Align = std::max<unsigned>(8, Width);
2089
2090 // If the alignment is not a power of 2, round up to the next power of 2.
2091 // This happens for non-power-of-2 length vectors.
2092 if (Align & (Align-1)) {
2093 Align = llvm::bit_ceil(Align);
2094 Width = llvm::alignTo(Width, Align);
2095 }
2096 // Adjust the alignment based on the target max.
2097 uint64_t TargetVectorAlign = Target->getMaxVectorAlign();
2098 if (TargetVectorAlign && TargetVectorAlign < Align)
2099 Align = TargetVectorAlign;
2100 if (VT->getVectorKind() == VectorType::SveFixedLengthDataVector)
2101 // Adjust the alignment for fixed-length SVE vectors. This is important
2102 // for non-power-of-2 vector lengths.
2103 Align = 128;
2104 else if (VT->getVectorKind() == VectorType::SveFixedLengthPredicateVector)
2105 // Adjust the alignment for fixed-length SVE predicates.
2106 Align = 16;
2107 break;
2108 }
2109
2110 case Type::ConstantMatrix: {
2111 const auto *MT = cast<ConstantMatrixType>(T);
2112 TypeInfo ElementInfo = getTypeInfo(MT->getElementType());
2113 // The internal layout of a matrix value is implementation defined.
2114 // Initially be ABI compatible with arrays with respect to alignment and
2115 // size.
2116 Width = ElementInfo.Width * MT->getNumRows() * MT->getNumColumns();
2117 Align = ElementInfo.Align;
2118 break;
2119 }
2120
2121 case Type::Builtin:
2122 switch (cast<BuiltinType>(T)->getKind()) {
2123 default: llvm_unreachable("Unknown builtin type!")::llvm::llvm_unreachable_internal("Unknown builtin type!", "clang/lib/AST/ASTContext.cpp"
, 2123)
;
2124 case BuiltinType::Void:
2125 // GCC extension: alignof(void) = 8 bits.
2126 Width = 0;
2127 Align = 8;
2128 break;
2129 case BuiltinType::Bool:
2130 Width = Target->getBoolWidth();
2131 Align = Target->getBoolAlign();
2132 break;
2133 case BuiltinType::Char_S:
2134 case BuiltinType::Char_U:
2135 case BuiltinType::UChar:
2136 case BuiltinType::SChar:
2137 case BuiltinType::Char8:
2138 Width = Target->getCharWidth();
2139 Align = Target->getCharAlign();
2140 break;
2141 case BuiltinType::WChar_S:
2142 case BuiltinType::WChar_U:
2143 Width = Target->getWCharWidth();
2144 Align = Target->getWCharAlign();
2145 break;
2146 case BuiltinType::Char16:
2147 Width = Target->getChar16Width();
2148 Align = Target->getChar16Align();
2149 break;
2150 case BuiltinType::Char32:
2151 Width = Target->getChar32Width();
2152 Align = Target->getChar32Align();
2153 break;
2154 case BuiltinType::UShort:
2155 case BuiltinType::Short:
2156 Width = Target->getShortWidth();
2157 Align = Target->getShortAlign();
2158 break;
2159 case BuiltinType::UInt:
2160 case BuiltinType::Int:
2161 Width = Target->getIntWidth();
2162 Align = Target->getIntAlign();
2163 break;
2164 case BuiltinType::ULong:
2165 case BuiltinType::Long:
2166 Width = Target->getLongWidth();
2167 Align = Target->getLongAlign();
2168 break;
2169 case BuiltinType::ULongLong:
2170 case BuiltinType::LongLong:
2171 Width = Target->getLongLongWidth();
2172 Align = Target->getLongLongAlign();
2173 break;
2174 case BuiltinType::Int128:
2175 case BuiltinType::UInt128:
2176 Width = 128;
2177 Align = Target->getInt128Align();
2178 break;
2179 case BuiltinType::ShortAccum:
2180 case BuiltinType::UShortAccum:
2181 case BuiltinType::SatShortAccum:
2182 case BuiltinType::SatUShortAccum:
2183 Width = Target->getShortAccumWidth();
2184 Align = Target->getShortAccumAlign();
2185 break;
2186 case BuiltinType::Accum:
2187 case BuiltinType::UAccum:
2188 case BuiltinType::SatAccum:
2189 case BuiltinType::SatUAccum:
2190 Width = Target->getAccumWidth();
2191 Align = Target->getAccumAlign();
2192 break;
2193 case BuiltinType::LongAccum:
2194 case BuiltinType::ULongAccum:
2195 case BuiltinType::SatLongAccum:
2196 case BuiltinType::SatULongAccum:
2197 Width = Target->getLongAccumWidth();
2198 Align = Target->getLongAccumAlign();
2199 break;
2200 case BuiltinType::ShortFract:
2201 case BuiltinType::UShortFract:
2202 case BuiltinType::SatShortFract:
2203 case BuiltinType::SatUShortFract:
2204 Width = Target->getShortFractWidth();
2205 Align = Target->getShortFractAlign();
2206 break;
2207 case BuiltinType::Fract:
2208 case BuiltinType::UFract:
2209 case BuiltinType::SatFract:
2210 case BuiltinType::SatUFract:
2211 Width = Target->getFractWidth();
2212 Align = Target->getFractAlign();
2213 break;
2214 case BuiltinType::LongFract:
2215 case BuiltinType::ULongFract:
2216 case BuiltinType::SatLongFract:
2217 case BuiltinType::SatULongFract:
2218 Width = Target->getLongFractWidth();
2219 Align = Target->getLongFractAlign();
2220 break;
2221 case BuiltinType::BFloat16:
2222 if (Target->hasBFloat16Type()) {
2223 Width = Target->getBFloat16Width();
2224 Align = Target->getBFloat16Align();
2225 } else if ((getLangOpts().SYCLIsDevice ||
2226 (getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice)) &&
2227 AuxTarget->hasBFloat16Type()) {
2228 Width = AuxTarget->getBFloat16Width();
2229 Align = AuxTarget->getBFloat16Align();
2230 }
2231 break;
2232 case BuiltinType::Float16:
2233 case BuiltinType::Half:
2234 if (Target->hasFloat16Type() || !getLangOpts().OpenMP ||
2235 !getLangOpts().OpenMPIsDevice) {
2236 Width = Target->getHalfWidth();
2237 Align = Target->getHalfAlign();
2238 } else {
2239 assert(getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice &&(static_cast <bool> (getLangOpts().OpenMP && getLangOpts
().OpenMPIsDevice && "Expected OpenMP device compilation."
) ? void (0) : __assert_fail ("getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && \"Expected OpenMP device compilation.\""
, "clang/lib/AST/ASTContext.cpp", 2240, __extension__ __PRETTY_FUNCTION__
))
2240 "Expected OpenMP device compilation.")(static_cast <bool> (getLangOpts().OpenMP && getLangOpts
().OpenMPIsDevice && "Expected OpenMP device compilation."
) ? void (0) : __assert_fail ("getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && \"Expected OpenMP device compilation.\""
, "clang/lib/AST/ASTContext.cpp", 2240, __extension__ __PRETTY_FUNCTION__
))
;
2241 Width = AuxTarget->getHalfWidth();
2242 Align = AuxTarget->getHalfAlign();
2243 }
2244 break;
2245 case BuiltinType::Float:
2246 Width = Target->getFloatWidth();
2247 Align = Target->getFloatAlign();
2248 break;
2249 case BuiltinType::Double:
2250 Width = Target->getDoubleWidth();
2251 Align = Target->getDoubleAlign();
2252 break;
2253 case BuiltinType::Ibm128:
2254 Width = Target->getIbm128Width();
2255 Align = Target->getIbm128Align();
2256 break;
2257 case BuiltinType::LongDouble:
2258 if (getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice &&
2259 (Target->getLongDoubleWidth() != AuxTarget->getLongDoubleWidth() ||
2260 Target->getLongDoubleAlign() != AuxTarget->getLongDoubleAlign())) {
2261 Width = AuxTarget->getLongDoubleWidth();
2262 Align = AuxTarget->getLongDoubleAlign();
2263 } else {
2264 Width = Target->getLongDoubleWidth();
2265 Align = Target->getLongDoubleAlign();
2266 }
2267 break;
2268 case BuiltinType::Float128:
2269 if (Target->hasFloat128Type() || !getLangOpts().OpenMP ||
2270 !getLangOpts().OpenMPIsDevice) {
2271 Width = Target->getFloat128Width();
2272 Align = Target->getFloat128Align();
2273 } else {
2274 assert(getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice &&(static_cast <bool> (getLangOpts().OpenMP && getLangOpts
().OpenMPIsDevice && "Expected OpenMP device compilation."
) ? void (0) : __assert_fail ("getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && \"Expected OpenMP device compilation.\""
, "clang/lib/AST/ASTContext.cpp", 2275, __extension__ __PRETTY_FUNCTION__
))
2275 "Expected OpenMP device compilation.")(static_cast <bool> (getLangOpts().OpenMP && getLangOpts
().OpenMPIsDevice && "Expected OpenMP device compilation."
) ? void (0) : __assert_fail ("getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && \"Expected OpenMP device compilation.\""
, "clang/lib/AST/ASTContext.cpp", 2275, __extension__ __PRETTY_FUNCTION__
))
;
2276 Width = AuxTarget->getFloat128Width();
2277 Align = AuxTarget->getFloat128Align();
2278 }
2279 break;
2280 case BuiltinType::NullPtr:
2281 // C++ 3.9.1p11: sizeof(nullptr_t) == sizeof(void*)
2282 Width = Target->getPointerWidth(LangAS::Default);
2283 Align = Target->getPointerAlign(LangAS::Default);
2284 break;
2285 case BuiltinType::ObjCId:
2286 case BuiltinType::ObjCClass:
2287 case BuiltinType::ObjCSel:
2288 Width = Target->getPointerWidth(LangAS::Default);
2289 Align = Target->getPointerAlign(LangAS::Default);
2290 break;
2291 case BuiltinType::OCLSampler:
2292 case BuiltinType::OCLEvent:
2293 case BuiltinType::OCLClkEvent:
2294 case BuiltinType::OCLQueue:
2295 case BuiltinType::OCLReserveID:
2296#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
2297 case BuiltinType::Id:
2298#include "clang/Basic/OpenCLImageTypes.def"
2299#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
2300 case BuiltinType::Id:
2301#include "clang/Basic/OpenCLExtensionTypes.def"
2302 AS = Target->getOpenCLTypeAddrSpace(getOpenCLTypeKind(T));
2303 Width = Target->getPointerWidth(AS);
2304 Align = Target->getPointerAlign(AS);
2305 break;
2306 // The SVE types are effectively target-specific. The length of an
2307 // SVE_VECTOR_TYPE is only known at runtime, but it is always a multiple
2308 // of 128 bits. There is one predicate bit for each vector byte, so the
2309 // length of an SVE_PREDICATE_TYPE is always a multiple of 16 bits.
2310 //
2311 // Because the length is only known at runtime, we use a dummy value
2312 // of 0 for the static length. The alignment values are those defined
2313 // by the Procedure Call Standard for the Arm Architecture.
2314#define SVE_VECTOR_TYPE(Name, MangledName, Id, SingletonId, NumEls, ElBits, \
2315 IsSigned, IsFP, IsBF) \
2316 case BuiltinType::Id: \
2317 Width = 0; \
2318 Align = 128; \
2319 break;
2320#define SVE_PREDICATE_TYPE(Name, MangledName, Id, SingletonId, NumEls) \
2321 case BuiltinType::Id: \
2322 Width = 0; \
2323 Align = 16; \
2324 break;
2325#define SVE_OPAQUE_TYPE(Name, MangledName, Id, SingletonId) \
2326 case BuiltinType::Id: \
2327 Width = 0; \
2328 Align = 16; \
2329 break;
2330#include "clang/Basic/AArch64SVEACLETypes.def"
2331#define PPC_VECTOR_TYPE(Name, Id, Size) \
2332 case BuiltinType::Id: \
2333 Width = Size; \
2334 Align = Size; \
2335 break;
2336#include "clang/Basic/PPCTypes.def"
2337#define RVV_VECTOR_TYPE(Name, Id, SingletonId, ElKind, ElBits, NF, IsSigned, \
2338 IsFP) \
2339 case BuiltinType::Id: \
2340 Width = 0; \
2341 Align = ElBits; \
2342 break;
2343#define RVV_PREDICATE_TYPE(Name, Id, SingletonId, ElKind) \
2344 case BuiltinType::Id: \
2345 Width = 0; \
2346 Align = 8; \
2347 break;
2348#include "clang/Basic/RISCVVTypes.def"
2349#define WASM_TYPE(Name, Id, SingletonId) \
2350 case BuiltinType::Id: \
2351 Width = 0; \
2352 Align = 8; \
2353 break;
2354#include "clang/Basic/WebAssemblyReferenceTypes.def"
2355 }
2356 break;
2357 case Type::ObjCObjectPointer:
2358 Width = Target->getPointerWidth(LangAS::Default);
2359 Align = Target->getPointerAlign(LangAS::Default);
2360 break;
2361 case Type::BlockPointer:
2362 AS = cast<BlockPointerType>(T)->getPointeeType().getAddressSpace();
2363 Width = Target->getPointerWidth(AS);
2364 Align = Target->getPointerAlign(AS);
2365 break;
2366 case Type::LValueReference:
2367 case Type::RValueReference:
2368 // alignof and sizeof should never enter this code path here, so we go
2369 // the pointer route.
2370 AS = cast<ReferenceType>(T)->getPointeeType().getAddressSpace();
2371 Width = Target->getPointerWidth(AS);
2372 Align = Target->getPointerAlign(AS);
2373 break;
2374 case Type::Pointer:
2375 AS = cast<PointerType>(T)->getPointeeType().getAddressSpace();
2376 Width = Target->getPointerWidth(AS);
2377 Align = Target->getPointerAlign(AS);
2378 break;
2379 case Type::MemberPointer: {
2380 const auto *MPT = cast<MemberPointerType>(T);
2381 CXXABI::MemberPointerInfo MPI = ABI->getMemberPointerInfo(MPT);
2382 Width = MPI.Width;
2383 Align = MPI.Align;
2384 break;
2385 }
2386 case Type::Complex: {
2387 // Complex types have the same alignment as their elements, but twice the
2388 // size.
2389 TypeInfo EltInfo = getTypeInfo(cast<ComplexType>(T)->getElementType());
2390 Width = EltInfo.Width * 2;
2391 Align = EltInfo.Align;
2392 break;
2393 }
2394 case Type::ObjCObject:
2395 return getTypeInfo(cast<ObjCObjectType>(T)->getBaseType().getTypePtr());
2396 case Type::Adjusted:
2397 case Type::Decayed:
2398 return getTypeInfo(cast<AdjustedType>(T)->getAdjustedType().getTypePtr());
2399 case Type::ObjCInterface: {
2400 const auto *ObjCI = cast<ObjCInterfaceType>(T);
2401 if (ObjCI->getDecl()->isInvalidDecl()) {
2402 Width = 8;
2403 Align = 8;
2404 break;
2405 }
2406 const ASTRecordLayout &Layout = getASTObjCInterfaceLayout(ObjCI->getDecl());
2407 Width = toBits(Layout.getSize());
2408 Align = toBits(Layout.getAlignment());
2409 break;
2410 }
2411 case Type::BitInt: {
2412 const auto *EIT = cast<BitIntType>(T);
2413 Align = std::clamp<unsigned>(llvm::PowerOf2Ceil(EIT->getNumBits()),
2414 getCharWidth(), Target->getLongLongAlign());
2415 Width = llvm::alignTo(EIT->getNumBits(), Align);
2416 break;
2417 }
2418 case Type::Record:
2419 case Type::Enum: {
2420 const auto *TT = cast<TagType>(T);
2421
2422 if (TT->getDecl()->isInvalidDecl()) {
2423 Width = 8;
2424 Align = 8;
2425 break;
2426 }
2427
2428 if (const auto *ET = dyn_cast<EnumType>(TT)) {
2429 const EnumDecl *ED = ET->getDecl();
2430 TypeInfo Info =
2431 getTypeInfo(ED->getIntegerType()->getUnqualifiedDesugaredType());
2432 if (unsigned AttrAlign = ED->getMaxAlignment()) {
2433 Info.Align = AttrAlign;
2434 Info.AlignRequirement = AlignRequirementKind::RequiredByEnum;
2435 }
2436 return Info;
2437 }
2438
2439 const auto *RT = cast<RecordType>(TT);
2440 const RecordDecl *RD = RT->getDecl();
2441 const ASTRecordLayout &Layout = getASTRecordLayout(RD);
2442 Width = toBits(Layout.getSize());
2443 Align = toBits(Layout.getAlignment());
2444 AlignRequirement = RD->hasAttr<AlignedAttr>()
2445 ? AlignRequirementKind::RequiredByRecord
2446 : AlignRequirementKind::None;
2447 break;
2448 }
2449
2450 case Type::SubstTemplateTypeParm:
2451 return getTypeInfo(cast<SubstTemplateTypeParmType>(T)->
2452 getReplacementType().getTypePtr());
2453
2454 case Type::Auto:
2455 case Type::DeducedTemplateSpecialization: {
2456 const auto *A = cast<DeducedType>(T);
2457 assert(!A->getDeducedType().isNull() &&(static_cast <bool> (!A->getDeducedType().isNull() &&
"cannot request the size of an undeduced or dependent auto type"
) ? void (0) : __assert_fail ("!A->getDeducedType().isNull() && \"cannot request the size of an undeduced or dependent auto type\""
, "clang/lib/AST/ASTContext.cpp", 2458, __extension__ __PRETTY_FUNCTION__
))
2458 "cannot request the size of an undeduced or dependent auto type")(static_cast <bool> (!A->getDeducedType().isNull() &&
"cannot request the size of an undeduced or dependent auto type"
) ? void (0) : __assert_fail ("!A->getDeducedType().isNull() && \"cannot request the size of an undeduced or dependent auto type\""
, "clang/lib/AST/ASTContext.cpp", 2458, __extension__ __PRETTY_FUNCTION__
))
;
2459 return getTypeInfo(A->getDeducedType().getTypePtr());
2460 }
2461
2462 case Type::Paren:
2463 return getTypeInfo(cast<ParenType>(T)->getInnerType().getTypePtr());
2464
2465 case Type::MacroQualified:
2466 return getTypeInfo(
2467 cast<MacroQualifiedType>(T)->getUnderlyingType().getTypePtr());
2468
2469 case Type::ObjCTypeParam:
2470 return getTypeInfo(cast<ObjCTypeParamType>(T)->desugar().getTypePtr());
2471
2472 case Type::Using:
2473 return getTypeInfo(cast<UsingType>(T)->desugar().getTypePtr());
2474
2475 case Type::Typedef: {
2476 const auto *TT = cast<TypedefType>(T);
2477 TypeInfo Info = getTypeInfo(TT->desugar().getTypePtr());
2478 // If the typedef has an aligned attribute on it, it overrides any computed
2479 // alignment we have. This violates the GCC documentation (which says that
2480 // attribute(aligned) can only round up) but matches its implementation.
2481 if (unsigned AttrAlign = TT->getDecl()->getMaxAlignment()) {
2482 Align = AttrAlign;
2483 AlignRequirement = AlignRequirementKind::RequiredByTypedef;
2484 } else {
2485 Align = Info.Align;
2486 AlignRequirement = Info.AlignRequirement;
2487 }
2488 Width = Info.Width;
2489 break;
2490 }
2491
2492 case Type::Elaborated:
2493 return getTypeInfo(cast<ElaboratedType>(T)->getNamedType().getTypePtr());
2494
2495 case Type::Attributed:
2496 return getTypeInfo(
2497 cast<AttributedType>(T)->getEquivalentType().getTypePtr());
2498
2499 case Type::BTFTagAttributed:
2500 return getTypeInfo(
2501 cast<BTFTagAttributedType>(T)->getWrappedType().getTypePtr());
2502
2503 case Type::Atomic: {
2504 // Start with the base type information.
2505 TypeInfo Info = getTypeInfo(cast<AtomicType>(T)->getValueType());
2506 Width = Info.Width;
2507 Align = Info.Align;
2508
2509 if (!Width) {
2510 // An otherwise zero-sized type should still generate an
2511 // atomic operation.
2512 Width = Target->getCharWidth();
2513 assert(Align)(static_cast <bool> (Align) ? void (0) : __assert_fail (
"Align", "clang/lib/AST/ASTContext.cpp", 2513, __extension__ __PRETTY_FUNCTION__
))
;
2514 } else if (Width <= Target->getMaxAtomicPromoteWidth()) {
2515 // If the size of the type doesn't exceed the platform's max
2516 // atomic promotion width, make the size and alignment more
2517 // favorable to atomic operations:
2518
2519 // Round the size up to a power of 2.
2520 Width = llvm::bit_ceil(Width);
2521
2522 // Set the alignment equal to the size.
2523 Align = static_cast<unsigned>(Width);
2524 }
2525 }
2526 break;
2527
2528 case Type::Pipe:
2529 Width = Target->getPointerWidth(LangAS::opencl_global);
2530 Align = Target->getPointerAlign(LangAS::opencl_global);
2531 break;
2532 }
2533
2534 assert(llvm::isPowerOf2_32(Align) && "Alignment must be power of 2")(static_cast <bool> (llvm::isPowerOf2_32(Align) &&
"Alignment must be power of 2") ? void (0) : __assert_fail (
"llvm::isPowerOf2_32(Align) && \"Alignment must be power of 2\""
, "clang/lib/AST/ASTContext.cpp", 2534, __extension__ __PRETTY_FUNCTION__
))
;
2535 return TypeInfo(Width, Align, AlignRequirement);
2536}
2537
2538unsigned ASTContext::getTypeUnadjustedAlign(const Type *T) const {
2539 UnadjustedAlignMap::iterator I = MemoizedUnadjustedAlign.find(T);
2540 if (I != MemoizedUnadjustedAlign.end())
2541 return I->second;
2542
2543 unsigned UnadjustedAlign;
2544 if (const auto *RT = T->getAs<RecordType>()) {
2545 const RecordDecl *RD = RT->getDecl();
2546 const ASTRecordLayout &Layout = getASTRecordLayout(RD);
2547 UnadjustedAlign = toBits(Layout.getUnadjustedAlignment());
2548 } else if (const auto *ObjCI = T->getAs<ObjCInterfaceType>()) {
2549 const ASTRecordLayout &Layout = getASTObjCInterfaceLayout(ObjCI->getDecl());
2550 UnadjustedAlign = toBits(Layout.getUnadjustedAlignment());
2551 } else {
2552 UnadjustedAlign = getTypeAlign(T->getUnqualifiedDesugaredType());
2553 }
2554
2555 MemoizedUnadjustedAlign[T] = UnadjustedAlign;
2556 return UnadjustedAlign;
2557}
2558
2559unsigned ASTContext::getOpenMPDefaultSimdAlign(QualType T) const {
2560 unsigned SimdAlign = llvm::OpenMPIRBuilder::getOpenMPDefaultSimdAlign(
2561 getTargetInfo().getTriple(), Target->getTargetOpts().FeatureMap);
2562 return SimdAlign;
2563}
2564
2565/// toCharUnitsFromBits - Convert a size in bits to a size in characters.
2566CharUnits ASTContext::toCharUnitsFromBits(int64_t BitSize) const {
2567 return CharUnits::fromQuantity(BitSize / getCharWidth());
2568}
2569
2570/// toBits - Convert a size in characters to a size in characters.
2571int64_t ASTContext::toBits(CharUnits CharSize) const {
2572 return CharSize.getQuantity() * getCharWidth();
2573}
2574
2575/// getTypeSizeInChars - Return the size of the specified type, in characters.
2576/// This method does not work on incomplete types.
2577CharUnits ASTContext::getTypeSizeInChars(QualType T) const {
2578 return getTypeInfoInChars(T).Width;
2579}
2580CharUnits ASTContext::getTypeSizeInChars(const Type *T) const {
2581 return getTypeInfoInChars(T).Width;
2582}
2583
2584/// getTypeAlignInChars - Return the ABI-specified alignment of a type, in
2585/// characters. This method does not work on incomplete types.
2586CharUnits ASTContext::getTypeAlignInChars(QualType T) const {
2587 return toCharUnitsFromBits(getTypeAlign(T));
2588}
2589CharUnits ASTContext::getTypeAlignInChars(const Type *T) const {
2590 return toCharUnitsFromBits(getTypeAlign(T));
2591}
2592
2593/// getTypeUnadjustedAlignInChars - Return the ABI-specified alignment of a
2594/// type, in characters, before alignment adjustments. This method does
2595/// not work on incomplete types.
2596CharUnits ASTContext::getTypeUnadjustedAlignInChars(QualType T) const {
2597 return toCharUnitsFromBits(getTypeUnadjustedAlign(T));
2598}
2599CharUnits ASTContext::getTypeUnadjustedAlignInChars(const Type *T) const {
2600 return toCharUnitsFromBits(getTypeUnadjustedAlign(T));
2601}
2602
2603/// getPreferredTypeAlign - Return the "preferred" alignment of the specified
2604/// type for the current target in bits. This can be different than the ABI
2605/// alignment in cases where it is beneficial for performance or backwards
2606/// compatibility preserving to overalign a data type. (Note: despite the name,
2607/// the preferred alignment is ABI-impacting, and not an optimization.)
2608unsigned ASTContext::getPreferredTypeAlign(const Type *T) const {
2609 TypeInfo TI = getTypeInfo(T);
2610 unsigned ABIAlign = TI.Align;
2611
2612 T = T->getBaseElementTypeUnsafe();
2613
2614 // The preferred alignment of member pointers is that of a pointer.
2615 if (T->isMemberPointerType())
2616 return getPreferredTypeAlign(getPointerDiffType().getTypePtr());
2617
2618 if (!Target->allowsLargerPreferedTypeAlignment())
2619 return ABIAlign;
2620
2621 if (const auto *RT = T->getAs<RecordType>()) {
2622 const RecordDecl *RD = RT->getDecl();
2623
2624 // When used as part of a typedef, or together with a 'packed' attribute,
2625 // the 'aligned' attribute can be used to decrease alignment. Note that the
2626 // 'packed' case is already taken into consideration when computing the
2627 // alignment, we only need to handle the typedef case here.
2628 if (TI.AlignRequirement == AlignRequirementKind::RequiredByTypedef ||
2629 RD->isInvalidDecl())
2630 return ABIAlign;
2631
2632 unsigned PreferredAlign = static_cast<unsigned>(
2633 toBits(getASTRecordLayout(RD).PreferredAlignment));
2634 assert(PreferredAlign >= ABIAlign &&(static_cast <bool> (PreferredAlign >= ABIAlign &&
"PreferredAlign should be at least as large as ABIAlign.") ?
void (0) : __assert_fail ("PreferredAlign >= ABIAlign && \"PreferredAlign should be at least as large as ABIAlign.\""
, "clang/lib/AST/ASTContext.cpp", 2635, __extension__ __PRETTY_FUNCTION__
))
2635 "PreferredAlign should be at least as large as ABIAlign.")(static_cast <bool> (PreferredAlign >= ABIAlign &&
"PreferredAlign should be at least as large as ABIAlign.") ?
void (0) : __assert_fail ("PreferredAlign >= ABIAlign && \"PreferredAlign should be at least as large as ABIAlign.\""
, "clang/lib/AST/ASTContext.cpp", 2635, __extension__ __PRETTY_FUNCTION__
))
;
2636 return PreferredAlign;
2637 }
2638
2639 // Double (and, for targets supporting AIX `power` alignment, long double) and
2640 // long long should be naturally aligned (despite requiring less alignment) if
2641 // possible.
2642 if (const auto *CT = T->getAs<ComplexType>())
2643 T = CT->getElementType().getTypePtr();
2644 if (const auto *ET = T->getAs<EnumType>())
2645 T = ET->getDecl()->getIntegerType().getTypePtr();
2646 if (T->isSpecificBuiltinType(BuiltinType::Double) ||
2647 T->isSpecificBuiltinType(BuiltinType::LongLong) ||
2648 T->isSpecificBuiltinType(BuiltinType::ULongLong) ||
2649 (T->isSpecificBuiltinType(BuiltinType::LongDouble) &&
2650 Target->defaultsToAIXPowerAlignment()))
2651 // Don't increase the alignment if an alignment attribute was specified on a
2652 // typedef declaration.
2653 if (!TI.isAlignRequired())
2654 return std::max(ABIAlign, (unsigned)getTypeSize(T));
2655
2656 return ABIAlign;
2657}
2658
2659/// getTargetDefaultAlignForAttributeAligned - Return the default alignment
2660/// for __attribute__((aligned)) on this target, to be used if no alignment
2661/// value is specified.
2662unsigned ASTContext::getTargetDefaultAlignForAttributeAligned() const {
2663 return getTargetInfo().getDefaultAlignForAttributeAligned();
2664}
2665
2666/// getAlignOfGlobalVar - Return the alignment in bits that should be given
2667/// to a global variable of the specified type.
2668unsigned ASTContext::getAlignOfGlobalVar(QualType T) const {
2669 uint64_t TypeSize = getTypeSize(T.getTypePtr());
2670 return std::max(getPreferredTypeAlign(T),
2671 getTargetInfo().getMinGlobalAlign(TypeSize));
2672}
2673
2674/// getAlignOfGlobalVarInChars - Return the alignment in characters that
2675/// should be given to a global variable of the specified type.
2676CharUnits ASTContext::getAlignOfGlobalVarInChars(QualType T) const {
2677 return toCharUnitsFromBits(getAlignOfGlobalVar(T));
2678}
2679
2680CharUnits ASTContext::getOffsetOfBaseWithVBPtr(const CXXRecordDecl *RD) const {
2681 CharUnits Offset = CharUnits::Zero();
2682 const ASTRecordLayout *Layout = &getASTRecordLayout(RD);
2683 while (const CXXRecordDecl *Base = Layout->getBaseSharingVBPtr()) {
2684 Offset += Layout->getBaseClassOffset(Base);
2685 Layout = &getASTRecordLayout(Base);
2686 }
2687 return Offset;
2688}
2689
2690CharUnits ASTContext::getMemberPointerPathAdjustment(const APValue &MP) const {
2691 const ValueDecl *MPD = MP.getMemberPointerDecl();
2692 CharUnits ThisAdjustment = CharUnits::Zero();
2693 ArrayRef<const CXXRecordDecl*> Path = MP.getMemberPointerPath();
2694 bool DerivedMember = MP.isMemberPointerToDerivedMember();
2695 const CXXRecordDecl *RD = cast<CXXRecordDecl>(MPD->getDeclContext());
2696 for (unsigned I = 0, N = Path.size(); I != N; ++I) {
2697 const CXXRecordDecl *Base = RD;
2698 const CXXRecordDecl *Derived = Path[I];
2699 if (DerivedMember)
2700 std::swap(Base, Derived);
2701 ThisAdjustment += getASTRecordLayout(Derived).getBaseClassOffset(Base);
2702 RD = Path[I];
2703 }
2704 if (DerivedMember)
2705 ThisAdjustment = -ThisAdjustment;
2706 return ThisAdjustment;
2707}
2708
2709/// DeepCollectObjCIvars -
2710/// This routine first collects all declared, but not synthesized, ivars in
2711/// super class and then collects all ivars, including those synthesized for
2712/// current class. This routine is used for implementation of current class
2713/// when all ivars, declared and synthesized are known.
2714void ASTContext::DeepCollectObjCIvars(const ObjCInterfaceDecl *OI,
2715 bool leafClass,
2716 SmallVectorImpl<const ObjCIvarDecl*> &Ivars) const {
2717 if (const ObjCInterfaceDecl *SuperClass = OI->getSuperClass())
2718 DeepCollectObjCIvars(SuperClass, false, Ivars);
2719 if (!leafClass) {
2720 llvm::append_range(Ivars, OI->ivars());
2721 } else {
2722 auto *IDecl = const_cast<ObjCInterfaceDecl *>(OI);
2723 for (const ObjCIvarDecl *Iv = IDecl->all_declared_ivar_begin(); Iv;
2724 Iv= Iv->getNextIvar())
2725 Ivars.push_back(Iv);
2726 }
2727}
2728
2729/// CollectInheritedProtocols - Collect all protocols in current class and
2730/// those inherited by it.
2731void ASTContext::CollectInheritedProtocols(const Decl *CDecl,
2732 llvm::SmallPtrSet<ObjCProtocolDecl*, 8> &Protocols) {
2733 if (const auto *OI = dyn_cast<ObjCInterfaceDecl>(CDecl)) {
2734 // We can use protocol_iterator here instead of
2735 // all_referenced_protocol_iterator since we are walking all categories.
2736 for (auto *Proto : OI->all_referenced_protocols()) {
2737 CollectInheritedProtocols(Proto, Protocols);
2738 }
2739
2740 // Categories of this Interface.
2741 for (const auto *Cat : OI->visible_categories())
2742 CollectInheritedProtocols(Cat, Protocols);
2743
2744 if (ObjCInterfaceDecl *SD = OI->getSuperClass())
2745 while (SD) {
2746 CollectInheritedProtocols(SD, Protocols);
2747 SD = SD->getSuperClass();
2748 }
2749 } else if (const auto *OC = dyn_cast<ObjCCategoryDecl>(CDecl)) {
2750 for (auto *Proto : OC->protocols()) {
2751 CollectInheritedProtocols(Proto, Protocols);
2752 }
2753 } else if (const auto *OP = dyn_cast<ObjCProtocolDecl>(CDecl)) {
2754 // Insert the protocol.
2755 if (!Protocols.insert(
2756 const_cast<ObjCProtocolDecl *>(OP->getCanonicalDecl())).second)
2757 return;
2758
2759 for (auto *Proto : OP->protocols())
2760 CollectInheritedProtocols(Proto, Protocols);
2761 }
2762}
2763
2764static bool unionHasUniqueObjectRepresentations(const ASTContext &Context,
2765 const RecordDecl *RD) {
2766 assert(RD->isUnion() && "Must be union type")(static_cast <bool> (RD->isUnion() && "Must be union type"
) ? void (0) : __assert_fail ("RD->isUnion() && \"Must be union type\""
, "clang/lib/AST/ASTContext.cpp", 2766, __extension__ __PRETTY_FUNCTION__
))
;
2767 CharUnits UnionSize = Context.getTypeSizeInChars(RD->getTypeForDecl());
2768
2769 for (const auto *Field : RD->fields()) {
2770 if (!Context.hasUniqueObjectRepresentations(Field->getType()))
2771 return false;
2772 CharUnits FieldSize = Context.getTypeSizeInChars(Field->getType());
2773 if (FieldSize != UnionSize)
2774 return false;
2775 }
2776 return !RD->field_empty();
2777}
2778
2779static int64_t getSubobjectOffset(const FieldDecl *Field,
2780 const ASTContext &Context,
2781 const clang::ASTRecordLayout & /*Layout*/) {
2782 return Context.getFieldOffset(Field);
2783}
2784
2785static int64_t getSubobjectOffset(const CXXRecordDecl *RD,
2786 const ASTContext &Context,
2787 const clang::ASTRecordLayout &Layout) {
2788 return Context.toBits(Layout.getBaseClassOffset(RD));
2789}
2790
2791static std::optional<int64_t>
2792structHasUniqueObjectRepresentations(const ASTContext &Context,
2793 const RecordDecl *RD);
2794
2795static std::optional<int64_t>
2796getSubobjectSizeInBits(const FieldDecl *Field, const ASTContext &Context) {
2797 if (Field->getType()->isRecordType()) {
2798 const RecordDecl *RD = Field->getType()->getAsRecordDecl();
2799 if (!RD->isUnion())
2800 return structHasUniqueObjectRepresentations(Context, RD);
2801 }
2802
2803 // A _BitInt type may not be unique if it has padding bits
2804 // but if it is a bitfield the padding bits are not used.
2805 bool IsBitIntType = Field->getType()->isBitIntType();
2806 if (!Field->getType()->isReferenceType() && !IsBitIntType &&
2807 !Context.hasUniqueObjectRepresentations(Field->getType()))
2808 return std::nullopt;
2809
2810 int64_t FieldSizeInBits =
2811 Context.toBits(Context.getTypeSizeInChars(Field->getType()));
2812 if (Field->isBitField()) {
2813 int64_t BitfieldSize = Field->getBitWidthValue(Context);
2814 if (IsBitIntType) {
2815 if ((unsigned)BitfieldSize >
2816 cast<BitIntType>(Field->getType())->getNumBits())
2817 return std::nullopt;
2818 } else if (BitfieldSize > FieldSizeInBits) {
2819 return std::nullopt;
2820 }
2821 FieldSizeInBits = BitfieldSize;
2822 } else if (IsBitIntType &&
2823 !Context.hasUniqueObjectRepresentations(Field->getType())) {
2824 return std::nullopt;
2825 }
2826 return FieldSizeInBits;
2827}
2828
2829static std::optional<int64_t>
2830getSubobjectSizeInBits(const CXXRecordDecl *RD, const ASTContext &Context) {
2831 return structHasUniqueObjectRepresentations(Context, RD);
2832}
2833
2834template <typename RangeT>
2835static std::optional<int64_t> structSubobjectsHaveUniqueObjectRepresentations(
2836 const RangeT &Subobjects, int64_t CurOffsetInBits,
2837 const ASTContext &Context, const clang::ASTRecordLayout &Layout) {
2838 for (const auto *Subobject : Subobjects) {
2839 std::optional<int64_t> SizeInBits =
2840 getSubobjectSizeInBits(Subobject, Context);
2841 if (!SizeInBits)
2842 return std::nullopt;
2843 if (*SizeInBits != 0) {
2844 int64_t Offset = getSubobjectOffset(Subobject, Context, Layout);
2845 if (Offset != CurOffsetInBits)
2846 return std::nullopt;
2847 CurOffsetInBits += *SizeInBits;
2848 }
2849 }
2850 return CurOffsetInBits;
2851}
2852
2853static std::optional<int64_t>
2854structHasUniqueObjectRepresentations(const ASTContext &Context,
2855 const RecordDecl *RD) {
2856 assert(!RD->isUnion() && "Must be struct/class type")(static_cast <bool> (!RD->isUnion() && "Must be struct/class type"
) ? void (0) : __assert_fail ("!RD->isUnion() && \"Must be struct/class type\""
, "clang/lib/AST/ASTContext.cpp", 2856, __extension__ __PRETTY_FUNCTION__
))
;
2857 const auto &Layout = Context.getASTRecordLayout(RD);
2858
2859 int64_t CurOffsetInBits = 0;
2860 if (const auto *ClassDecl = dyn_cast<CXXRecordDecl>(RD)) {
2861 if (ClassDecl->isDynamicClass())
2862 return std::nullopt;
2863
2864 SmallVector<CXXRecordDecl *, 4> Bases;
2865 for (const auto &Base : ClassDecl->bases()) {
2866 // Empty types can be inherited from, and non-empty types can potentially
2867 // have tail padding, so just make sure there isn't an error.
2868 Bases.emplace_back(Base.getType()->getAsCXXRecordDecl());
2869 }
2870
2871 llvm::sort(Bases, [&](const CXXRecordDecl *L, const CXXRecordDecl *R) {
2872 return Layout.getBaseClassOffset(L) < Layout.getBaseClassOffset(R);
2873 });
2874
2875 std::optional<int64_t> OffsetAfterBases =
2876 structSubobjectsHaveUniqueObjectRepresentations(Bases, CurOffsetInBits,
2877 Context, Layout);
2878 if (!OffsetAfterBases)
2879 return std::nullopt;
2880 CurOffsetInBits = *OffsetAfterBases;
2881 }
2882
2883 std::optional<int64_t> OffsetAfterFields =
2884 structSubobjectsHaveUniqueObjectRepresentations(
2885 RD->fields(), CurOffsetInBits, Context, Layout);
2886 if (!OffsetAfterFields)
2887 return std::nullopt;
2888 CurOffsetInBits = *OffsetAfterFields;
2889
2890 return CurOffsetInBits;
2891}
2892
2893bool ASTContext::hasUniqueObjectRepresentations(QualType Ty) const {
2894 // C++17 [meta.unary.prop]:
2895 // The predicate condition for a template specialization
2896 // has_unique_object_representations<T> shall be
2897 // satisfied if and only if:
2898 // (9.1) - T is trivially copyable, and
2899 // (9.2) - any two objects of type T with the same value have the same
2900 // object representation, where two objects
2901 // of array or non-union class type are considered to have the same value
2902 // if their respective sequences of
2903 // direct subobjects have the same values, and two objects of union type
2904 // are considered to have the same
2905 // value if they have the same active member and the corresponding members
2906 // have the same value.
2907 // The set of scalar types for which this condition holds is
2908 // implementation-defined. [ Note: If a type has padding
2909 // bits, the condition does not hold; otherwise, the condition holds true
2910 // for unsigned integral types. -- end note ]
2911 assert(!Ty.isNull() && "Null QualType sent to unique object rep check")(static_cast <bool> (!Ty.isNull() && "Null QualType sent to unique object rep check"
) ? void (0) : __assert_fail ("!Ty.isNull() && \"Null QualType sent to unique object rep check\""
, "clang/lib/AST/ASTContext.cpp", 2911, __extension__ __PRETTY_FUNCTION__
))
;
2912
2913 // Arrays are unique only if their element type is unique.
2914 if (Ty->isArrayType())
2915 return hasUniqueObjectRepresentations(getBaseElementType(Ty));
2916
2917 // (9.1) - T is trivially copyable...
2918 if (!Ty.isTriviallyCopyableType(*this))
2919 return false;
2920
2921 // All integrals and enums are unique.
2922 if (Ty->isIntegralOrEnumerationType()) {
2923 // Except _BitInt types that have padding bits.
2924 if (const auto *BIT = dyn_cast<BitIntType>(Ty))
2925 return getTypeSize(BIT) == BIT->getNumBits();
2926
2927 return true;
2928 }
2929
2930 // All other pointers are unique.
2931 if (Ty->isPointerType())
2932 return true;
2933
2934 if (Ty->isMemberPointerType()) {
2935 const auto *MPT = Ty->getAs<MemberPointerType>();
2936 return !ABI->getMemberPointerInfo(MPT).HasPadding;
2937 }
2938
2939 if (Ty->isRecordType()) {
2940 const RecordDecl *Record = Ty->castAs<RecordType>()->getDecl();
2941
2942 if (Record->isInvalidDecl())
2943 return false;
2944
2945 if (Record->isUnion())
2946 return unionHasUniqueObjectRepresentations(*this, Record);
2947
2948 std::optional<int64_t> StructSize =
2949 structHasUniqueObjectRepresentations(*this, Record);
2950
2951 return StructSize && *StructSize == static_cast<int64_t>(getTypeSize(Ty));
2952 }
2953
2954 // FIXME: More cases to handle here (list by rsmith):
2955 // vectors (careful about, eg, vector of 3 foo)
2956 // _Complex int and friends
2957 // _Atomic T
2958 // Obj-C block pointers
2959 // Obj-C object pointers
2960 // and perhaps OpenCL's various builtin types (pipe, sampler_t, event_t,
2961 // clk_event_t, queue_t, reserve_id_t)
2962 // There're also Obj-C class types and the Obj-C selector type, but I think it
2963 // makes sense for those to return false here.
2964
2965 return false;
2966}
2967
2968unsigned ASTContext::CountNonClassIvars(const ObjCInterfaceDecl *OI) const {
2969 unsigned count = 0;
2970 // Count ivars declared in class extension.
2971 for (const auto *Ext : OI->known_extensions())
2972 count += Ext->ivar_size();
2973
2974 // Count ivar defined in this class's implementation. This
2975 // includes synthesized ivars.
2976 if (ObjCImplementationDecl *ImplDecl = OI->getImplementation())
2977 count += ImplDecl->ivar_size();
2978
2979 return count;
2980}
2981
2982bool ASTContext::isSentinelNullExpr(const Expr *E) {
2983 if (!E)
2984 return false;
2985
2986 // nullptr_t is always treated as null.
2987 if (E->getType()->isNullPtrType()) return true;
2988
2989 if (E->getType()->isAnyPointerType() &&
2990 E->IgnoreParenCasts()->isNullPointerConstant(*this,
2991 Expr::NPC_ValueDependentIsNull))
2992 return true;
2993
2994 // Unfortunately, __null has type 'int'.
2995 if (isa<GNUNullExpr>(E)) return true;
2996
2997 return false;
2998}
2999
3000/// Get the implementation of ObjCInterfaceDecl, or nullptr if none
3001/// exists.
3002ObjCImplementationDecl *ASTContext::getObjCImplementation(ObjCInterfaceDecl *D) {
3003 llvm::DenseMap<ObjCContainerDecl*, ObjCImplDecl*>::iterator
3004 I = ObjCImpls.find(D);
3005 if (I != ObjCImpls.end())
3006 return cast<ObjCImplementationDecl>(I->second);
3007 return nullptr;
3008}
3009
3010/// Get the implementation of ObjCCategoryDecl, or nullptr if none
3011/// exists.
3012ObjCCategoryImplDecl *ASTContext::getObjCImplementation(ObjCCategoryDecl *D) {
3013 llvm::DenseMap<ObjCContainerDecl*, ObjCImplDecl*>::iterator
3014 I = ObjCImpls.find(D);
3015 if (I != ObjCImpls.end())
3016 return cast<ObjCCategoryImplDecl>(I->second);
3017 return nullptr;
3018}
3019
3020/// Set the implementation of ObjCInterfaceDecl.
3021void ASTContext::setObjCImplementation(ObjCInterfaceDecl *IFaceD,
3022 ObjCImplementationDecl *ImplD) {
3023 assert(IFaceD && ImplD && "Passed null params")(static_cast <bool> (IFaceD && ImplD &&
"Passed null params") ? void (0) : __assert_fail ("IFaceD && ImplD && \"Passed null params\""
, "clang/lib/AST/ASTContext.cpp", 3023, __extension__ __PRETTY_FUNCTION__
))
;
3024 ObjCImpls[IFaceD] = ImplD;
3025}
3026
3027/// Set the implementation of ObjCCategoryDecl.
3028void ASTContext::setObjCImplementation(ObjCCategoryDecl *CatD,
3029 ObjCCategoryImplDecl *ImplD) {
3030 assert(CatD && ImplD && "Passed null params")(static_cast <bool> (CatD && ImplD && "Passed null params"
) ? void (0) : __assert_fail ("CatD && ImplD && \"Passed null params\""
, "clang/lib/AST/ASTContext.cpp", 3030, __extension__ __PRETTY_FUNCTION__
))
;
3031 ObjCImpls[CatD] = ImplD;
3032}
3033
3034const ObjCMethodDecl *
3035ASTContext::getObjCMethodRedeclaration(const ObjCMethodDecl *MD) const {
3036 return ObjCMethodRedecls.lookup(MD);
3037}
3038
3039void ASTContext::setObjCMethodRedeclaration(const ObjCMethodDecl *MD,
3040 const ObjCMethodDecl *Redecl) {
3041 assert(!getObjCMethodRedeclaration(MD) && "MD already has a redeclaration")(static_cast <bool> (!getObjCMethodRedeclaration(MD) &&
"MD already has a redeclaration") ? void (0) : __assert_fail
("!getObjCMethodRedeclaration(MD) && \"MD already has a redeclaration\""
, "clang/lib/AST/ASTContext.cpp", 3041, __extension__ __PRETTY_FUNCTION__
))
;
3042 ObjCMethodRedecls[MD] = Redecl;
3043}
3044
3045const ObjCInterfaceDecl *ASTContext::getObjContainingInterface(
3046 const NamedDecl *ND) const {
3047 if (const auto *ID = dyn_cast<ObjCInterfaceDecl>(ND->getDeclContext()))
3048 return ID;
3049 if (const auto *CD = dyn_cast<ObjCCategoryDecl>(ND->getDeclContext()))
3050 return CD->getClassInterface();
3051 if (const auto *IMD = dyn_cast<ObjCImplDecl>(ND->getDeclContext()))
3052 return IMD->getClassInterface();
3053
3054 return nullptr;
3055}
3056
3057/// Get the copy initialization expression of VarDecl, or nullptr if
3058/// none exists.
3059BlockVarCopyInit ASTContext::getBlockVarCopyInit(const VarDecl *VD) const {
3060 assert(VD && "Passed null params")(static_cast <bool> (VD && "Passed null params"
) ? void (0) : __assert_fail ("VD && \"Passed null params\""
, "clang/lib/AST/ASTContext.cpp", 3060, __extension__ __PRETTY_FUNCTION__
))
;
3061 assert(VD->hasAttr<BlocksAttr>() &&(static_cast <bool> (VD->hasAttr<BlocksAttr>()
&& "getBlockVarCopyInits - not __block var") ? void (
0) : __assert_fail ("VD->hasAttr<BlocksAttr>() && \"getBlockVarCopyInits - not __block var\""
, "clang/lib/AST/ASTContext.cpp", 3062, __extension__ __PRETTY_FUNCTION__
))
3062 "getBlockVarCopyInits - not __block var")(static_cast <bool> (VD->hasAttr<BlocksAttr>()
&& "getBlockVarCopyInits - not __block var") ? void (
0) : __assert_fail ("VD->hasAttr<BlocksAttr>() && \"getBlockVarCopyInits - not __block var\""
, "clang/lib/AST/ASTContext.cpp", 3062, __extension__ __PRETTY_FUNCTION__
))
;
3063 auto I = BlockVarCopyInits.find(VD);
3064 if (I != BlockVarCopyInits.end())
3065 return I->second;
3066 return {nullptr, false};
3067}
3068
3069/// Set the copy initialization expression of a block var decl.
3070void ASTContext::setBlockVarCopyInit(const VarDecl*VD, Expr *CopyExpr,
3071 bool CanThrow) {
3072 assert(VD && CopyExpr && "Passed null params")(static_cast <bool> (VD && CopyExpr && "Passed null params"
) ? void (0) : __assert_fail ("VD && CopyExpr && \"Passed null params\""
, "clang/lib/AST/ASTContext.cpp", 3072, __extension__ __PRETTY_FUNCTION__
))
;
3073 assert(VD->hasAttr<BlocksAttr>() &&(static_cast <bool> (VD->hasAttr<BlocksAttr>()
&& "setBlockVarCopyInits - not __block var") ? void (
0) : __assert_fail ("VD->hasAttr<BlocksAttr>() && \"setBlockVarCopyInits - not __block var\""
, "clang/lib/AST/ASTContext.cpp", 3074, __extension__ __PRETTY_FUNCTION__
))
3074 "setBlockVarCopyInits - not __block var")(static_cast <bool> (VD->hasAttr<BlocksAttr>()
&& "setBlockVarCopyInits - not __block var") ? void (
0) : __assert_fail ("VD->hasAttr<BlocksAttr>() && \"setBlockVarCopyInits - not __block var\""
, "clang/lib/AST/ASTContext.cpp", 3074, __extension__ __PRETTY_FUNCTION__
))
;
3075 BlockVarCopyInits[VD].setExprAndFlag(CopyExpr, CanThrow);
3076}
3077
3078TypeSourceInfo *ASTContext::CreateTypeSourceInfo(QualType T,
3079 unsigned DataSize) const {
3080 if (!DataSize)
3081 DataSize = TypeLoc::getFullDataSizeForType(T);
3082 else
3083 assert(DataSize == TypeLoc::getFullDataSizeForType(T) &&(static_cast <bool> (DataSize == TypeLoc::getFullDataSizeForType
(T) && "incorrect data size provided to CreateTypeSourceInfo!"
) ? void (0) : __assert_fail ("DataSize == TypeLoc::getFullDataSizeForType(T) && \"incorrect data size provided to CreateTypeSourceInfo!\""
, "clang/lib/AST/ASTContext.cpp", 3084, __extension__ __PRETTY_FUNCTION__
))
3084 "incorrect data size provided to CreateTypeSourceInfo!")(static_cast <bool> (DataSize == TypeLoc::getFullDataSizeForType
(T) && "incorrect data size provided to CreateTypeSourceInfo!"
) ? void (0) : __assert_fail ("DataSize == TypeLoc::getFullDataSizeForType(T) && \"incorrect data size provided to CreateTypeSourceInfo!\""
, "clang/lib/AST/ASTContext.cpp", 3084, __extension__ __PRETTY_FUNCTION__
))
;
3085
3086 auto *TInfo =
3087 (TypeSourceInfo*)BumpAlloc.Allocate(sizeof(TypeSourceInfo) + DataSize, 8);
3088 new (TInfo) TypeSourceInfo(T);
3089 return TInfo;
3090}
3091
3092TypeSourceInfo *ASTContext::getTrivialTypeSourceInfo(QualType T,
3093 SourceLocation L) const {
3094 TypeSourceInfo *DI = CreateTypeSourceInfo(T);
3095 DI->getTypeLoc().initialize(const_cast<ASTContext &>(*this), L);
3096 return DI;
3097}
3098
3099const ASTRecordLayout &
3100ASTContext::getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D) const {
3101 return getObjCLayout(D, nullptr);
3102}
3103
3104const ASTRecordLayout &
3105ASTContext::getASTObjCImplementationLayout(
3106 const ObjCImplementationDecl *D) const {
3107 return getObjCLayout(D->getClassInterface(), D);
3108}
3109
3110static auto getCanonicalTemplateArguments(const ASTContext &C,
3111 ArrayRef<TemplateArgument> Args,
3112 bool &AnyNonCanonArgs) {
3113 SmallVector<TemplateArgument, 16> CanonArgs(Args);
3114 for (auto &Arg : CanonArgs) {
3115 TemplateArgument OrigArg = Arg;
3116 Arg = C.getCanonicalTemplateArgument(Arg);
3117 AnyNonCanonArgs |= !Arg.structurallyEquals(OrigArg);
3118 }
3119 return CanonArgs;
3120}
3121
3122//===----------------------------------------------------------------------===//
3123// Type creation/memoization methods
3124//===----------------------------------------------------------------------===//
3125
3126QualType
3127ASTContext::getExtQualType(const Type *baseType, Qualifiers quals) const {
3128 unsigned fastQuals = quals.getFastQualifiers();
3129 quals.removeFastQualifiers();
3130
3131 // Check if we've already instantiated this type.
3132 llvm::FoldingSetNodeID ID;
3133 ExtQuals::Profile(ID, baseType, quals);
3134 void *insertPos = nullptr;
3135 if (ExtQuals *eq = ExtQualNodes.FindNodeOrInsertPos(ID, insertPos)) {
3136 assert(eq->getQualifiers() == quals)(static_cast <bool> (eq->getQualifiers() == quals) ?
void (0) : __assert_fail ("eq->getQualifiers() == quals",
"clang/lib/AST/ASTContext.cpp", 3136, __extension__ __PRETTY_FUNCTION__
))
;
3137 return QualType(eq, fastQuals);
3138 }
3139
3140 // If the base type is not canonical, make the appropriate canonical type.
3141 QualType canon;
3142 if (!baseType->isCanonicalUnqualified()) {
3143 SplitQualType canonSplit = baseType->getCanonicalTypeInternal().split();
3144 canonSplit.Quals.addConsistentQualifiers(quals);
3145 canon = getExtQualType(canonSplit.Ty, canonSplit.Quals);
3146
3147 // Re-find the insert position.
3148 (void) ExtQualNodes.FindNodeOrInsertPos(ID, insertPos);
3149 }
3150
3151 auto *eq = new (*this, TypeAlignment) ExtQuals(baseType, canon, quals);
3152 ExtQualNodes.InsertNode(eq, insertPos);
3153 return QualType(eq, fastQuals);
3154}
3155
3156QualType ASTContext::getAddrSpaceQualType(QualType T,
3157 LangAS AddressSpace) const {
3158 QualType CanT = getCanonicalType(T);
3159 if (CanT.getAddressSpace() == AddressSpace)
3160 return T;
3161
3162 // If we are composing extended qualifiers together, merge together
3163 // into one ExtQuals node.
3164 QualifierCollector Quals;
3165 const Type *TypeNode = Quals.strip(T);
3166
3167 // If this type already has an address space specified, it cannot get
3168 // another one.
3169 assert(!Quals.hasAddressSpace() &&(static_cast <bool> (!Quals.hasAddressSpace() &&
"Type cannot be in multiple addr spaces!") ? void (0) : __assert_fail
("!Quals.hasAddressSpace() && \"Type cannot be in multiple addr spaces!\""
, "clang/lib/AST/ASTContext.cpp", 3170, __extension__ __PRETTY_FUNCTION__
))
3170 "Type cannot be in multiple addr spaces!")(static_cast <bool> (!Quals.hasAddressSpace() &&
"Type cannot be in multiple addr spaces!") ? void (0) : __assert_fail
("!Quals.hasAddressSpace() && \"Type cannot be in multiple addr spaces!\""
, "clang/lib/AST/ASTContext.cpp", 3170, __extension__ __PRETTY_FUNCTION__
))
;
3171 Quals.addAddressSpace(AddressSpace);
3172
3173 return getExtQualType(TypeNode, Quals);
3174}
3175
3176QualType ASTContext::removeAddrSpaceQualType(QualType T) const {
3177 // If the type is not qualified with an address space, just return it
3178 // immediately.
3179 if (!T.hasAddressSpace())
12
Assuming the condition is false
13
Taking false branch
3180 return T;
3181
3182 // If we are composing extended qualifiers together, merge together
3183 // into one ExtQuals node.
3184 QualifierCollector Quals;
3185 const Type *TypeNode;
14
'TypeNode' declared without an initial value
3186
3187 while (T.hasAddressSpace()) {
15
Loop condition is false. Execution continues on line 3199
3188 TypeNode = Quals.strip(T);
3189
3190 // If the type no longer has an address space after stripping qualifiers,
3191 // jump out.
3192 if (!QualType(TypeNode, 0).hasAddressSpace())
3193 break;
3194
3195 // There might be sugar in the way. Strip it and try again.
3196 T = T.getSingleStepDesugaredType(*this);
3197 }
3198
3199 Quals.removeAddressSpace();
3200
3201 // Removal of the address space can mean there are no longer any
3202 // non-fast qualifiers, so creating an ExtQualType isn't possible (asserts)
3203 // or required.
3204 if (Quals.hasNonFastQualifiers())
16
Assuming the condition is false
17
Taking false branch
3205 return getExtQualType(TypeNode, Quals);
3206 else
3207 return QualType(TypeNode, Quals.getFastQualifiers());
18
1st function call argument is an uninitialized value
3208}
3209
3210QualType ASTContext::getObjCGCQualType(QualType T,
3211 Qualifiers::GC GCAttr) const {
3212 QualType CanT = getCanonicalType(T);
3213 if (CanT.getObjCGCAttr() == GCAttr)
3214 return T;
3215
3216 if (const auto *ptr = T->getAs<PointerType>()) {
3217 QualType Pointee = ptr->getPointeeType();
3218 if (Pointee->isAnyPointerType()) {
3219 QualType ResultType = getObjCGCQualType(Pointee, GCAttr);
3220 return getPointerType(ResultType);
3221 }
3222 }
3223
3224 // If we are composing extended qualifiers together, merge together
3225 // into one ExtQuals node.
3226 QualifierCollector Quals;
3227 const Type *TypeNode = Quals.strip(T);
3228
3229 // If this type already has an ObjCGC specified, it cannot get
3230 // another one.
3231 assert(!Quals.hasObjCGCAttr() &&(static_cast <bool> (!Quals.hasObjCGCAttr() && "Type cannot have multiple ObjCGCs!"
) ? void (0) : __assert_fail ("!Quals.hasObjCGCAttr() && \"Type cannot have multiple ObjCGCs!\""
, "clang/lib/AST/ASTContext.cpp", 3232, __extension__ __PRETTY_FUNCTION__
))
3232 "Type cannot have multiple ObjCGCs!")(static_cast <bool> (!Quals.hasObjCGCAttr() && "Type cannot have multiple ObjCGCs!"
) ? void (0) : __assert_fail ("!Quals.hasObjCGCAttr() && \"Type cannot have multiple ObjCGCs!\""
, "clang/lib/AST/ASTContext.cpp", 3232, __extension__ __PRETTY_FUNCTION__
))
;
3233 Quals.addObjCGCAttr(GCAttr);
3234
3235 return getExtQualType(TypeNode, Quals);
3236}
3237
3238QualType ASTContext::removePtrSizeAddrSpace(QualType T) const {
3239 if (const PointerType *Ptr = T->getAs<PointerType>()) {
7
Assuming the object is a 'const class clang::PointerType *'
8
Assuming 'Ptr' is non-null
9
Taking true branch
3240 QualType Pointee = Ptr->getPointeeType();
3241 if (isPtrSizeAddressSpace(Pointee.getAddressSpace())) {
10
Taking true branch
3242 return getPointerType(removeAddrSpaceQualType(Pointee));
11
Calling 'ASTContext::removeAddrSpaceQualType'
3243 }
3244 }
3245 return T;
3246}
3247
3248const FunctionType *ASTContext::adjustFunctionType(const FunctionType *T,
3249 FunctionType::ExtInfo Info) {
3250 if (T->getExtInfo() == Info)
3251 return T;
3252
3253 QualType Result;
3254 if (const auto *FNPT = dyn_cast<FunctionNoProtoType>(T)) {
3255 Result = getFunctionNoProtoType(FNPT->getReturnType(), Info);
3256 } else {
3257 const auto *FPT = cast<FunctionProtoType>(T);
3258 FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
3259 EPI.ExtInfo = Info;
3260 Result = getFunctionType(FPT->getReturnType(), FPT->getParamTypes(), EPI);
3261 }
3262
3263 return cast<FunctionType>(Result.getTypePtr());
3264}
3265
3266void ASTContext::adjustDeducedFunctionResultType(FunctionDecl *FD,
3267 QualType ResultType) {
3268 FD = FD->getMostRecentDecl();
3269 while (true) {
3270 const auto *FPT = FD->getType()->castAs<FunctionProtoType>();
3271 FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
3272 FD->setType(getFunctionType(ResultType, FPT->getParamTypes(), EPI));
3273 if (FunctionDecl *Next = FD->getPreviousDecl())
3274 FD = Next;
3275 else
3276 break;
3277 }
3278 if (ASTMutationListener *L = getASTMutationListener())
3279 L->DeducedReturnType(FD, ResultType);
3280}
3281
3282/// Get a function type and produce the equivalent function type with the
3283/// specified exception specification. Type sugar that can be present on a
3284/// declaration of a function with an exception specification is permitted
3285/// and preserved. Other type sugar (for instance, typedefs) is not.
3286QualType ASTContext::getFunctionTypeWithExceptionSpec(
3287 QualType Orig, const FunctionProtoType::ExceptionSpecInfo &ESI) const {
3288 // Might have some parens.
3289 if (const auto *PT = dyn_cast<ParenType>(Orig))
3290 return getParenType(
3291 getFunctionTypeWithExceptionSpec(PT->getInnerType(), ESI));
3292
3293 // Might be wrapped in a macro qualified type.
3294 if (const auto *MQT = dyn_cast<MacroQualifiedType>(Orig))
3295 return getMacroQualifiedType(
3296 getFunctionTypeWithExceptionSpec(MQT->getUnderlyingType(), ESI),
3297 MQT->getMacroIdentifier());
3298
3299 // Might have a calling-convention attribute.
3300 if (const auto *AT = dyn_cast<AttributedType>(Orig))
3301 return getAttributedType(
3302 AT->getAttrKind(),
3303 getFunctionTypeWithExceptionSpec(AT->getModifiedType(), ESI),
3304 getFunctionTypeWithExceptionSpec(AT->getEquivalentType(), ESI));
3305
3306 // Anything else must be a function type. Rebuild it with the new exception
3307 // specification.
3308 const auto *Proto = Orig->castAs<FunctionProtoType>();
3309 return getFunctionType(
3310 Proto->getReturnType(), Proto->getParamTypes(),
3311 Proto->getExtProtoInfo().withExceptionSpec(ESI));
3312}
3313
3314bool ASTContext::hasSameFunctionTypeIgnoringExceptionSpec(QualType T,
3315 QualType U) const {
3316 return hasSameType(T, U) ||
3317 (getLangOpts().CPlusPlus17 &&
3318 hasSameType(getFunctionTypeWithExceptionSpec(T, EST_None),
3319 getFunctionTypeWithExceptionSpec(U, EST_None)));
3320}
3321
3322QualType ASTContext::getFunctionTypeWithoutPtrSizes(QualType T) {
3323 if (const auto *Proto = T->getAs<FunctionProtoType>()) {
3
Assuming the object is a 'const class clang::FunctionProtoType *'
4
Assuming 'Proto' is non-null
5
Taking true branch
3324 QualType RetTy = removePtrSizeAddrSpace(Proto->getReturnType());
6
Calling 'ASTContext::removePtrSizeAddrSpace'
3325 SmallVector<QualType, 16> Args(Proto->param_types().size());
3326 for (unsigned i = 0, n = Args.size(); i != n; ++i)
3327 Args[i] = removePtrSizeAddrSpace(Proto->param_types()[i]);
3328 return getFunctionType(RetTy, Args, Proto->getExtProtoInfo());
3329 }
3330
3331 if (const FunctionNoProtoType *Proto = T->getAs<FunctionNoProtoType>()) {
3332 QualType RetTy = removePtrSizeAddrSpace(Proto->getReturnType());
3333 return getFunctionNoProtoType(RetTy, Proto->getExtInfo());
3334 }
3335
3336 return T;
3337}
3338
3339bool ASTContext::hasSameFunctionTypeIgnoringPtrSizes(QualType T, QualType U) {
3340 return hasSameType(T, U) ||
1
Assuming the condition is false
3341 hasSameType(getFunctionTypeWithoutPtrSizes(T),
2
Calling 'ASTContext::getFunctionTypeWithoutPtrSizes'
3342 getFunctionTypeWithoutPtrSizes(U));
3343}
3344
3345void ASTContext::adjustExceptionSpec(
3346 FunctionDecl *FD, const FunctionProtoType::ExceptionSpecInfo &ESI,
3347 bool AsWritten) {
3348 // Update the type.
3349 QualType Updated =
3350 getFunctionTypeWithExceptionSpec(FD->getType(), ESI);
3351 FD->setType(Updated);
3352
3353 if (!AsWritten)
3354 return;
3355
3356 // Update the type in the type source information too.
3357 if (TypeSourceInfo *TSInfo = FD->getTypeSourceInfo()) {
3358 // If the type and the type-as-written differ, we may need to update
3359 // the type-as-written too.
3360 if (TSInfo->getType() != FD->getType())
3361 Updated = getFunctionTypeWithExceptionSpec(TSInfo->getType(), ESI);
3362
3363 // FIXME: When we get proper type location information for exceptions,
3364 // we'll also have to rebuild the TypeSourceInfo. For now, we just patch
3365 // up the TypeSourceInfo;
3366 assert(TypeLoc::getFullDataSizeForType(Updated) ==(static_cast <bool> (TypeLoc::getFullDataSizeForType(Updated
) == TypeLoc::getFullDataSizeForType(TSInfo->getType()) &&
"TypeLoc size mismatch from updating exception specification"
) ? void (0) : __assert_fail ("TypeLoc::getFullDataSizeForType(Updated) == TypeLoc::getFullDataSizeForType(TSInfo->getType()) && \"TypeLoc size mismatch from updating exception specification\""
, "clang/lib/AST/ASTContext.cpp", 3368, __extension__ __PRETTY_FUNCTION__
))
3367 TypeLoc::getFullDataSizeForType(TSInfo->getType()) &&(static_cast <bool> (TypeLoc::getFullDataSizeForType(Updated
) == TypeLoc::getFullDataSizeForType(TSInfo->getType()) &&
"TypeLoc size mismatch from updating exception specification"
) ? void (0) : __assert_fail ("TypeLoc::getFullDataSizeForType(Updated) == TypeLoc::getFullDataSizeForType(TSInfo->getType()) && \"TypeLoc size mismatch from updating exception specification\""
, "clang/lib/AST/ASTContext.cpp", 3368, __extension__ __PRETTY_FUNCTION__
))
3368 "TypeLoc size mismatch from updating exception specification")(static_cast <bool> (TypeLoc::getFullDataSizeForType(Updated
) == TypeLoc::getFullDataSizeForType(TSInfo->getType()) &&
"TypeLoc size mismatch from updating exception specification"
) ? void (0) : __assert_fail ("TypeLoc::getFullDataSizeForType(Updated) == TypeLoc::getFullDataSizeForType(TSInfo->getType()) && \"TypeLoc size mismatch from updating exception specification\""
, "clang/lib/AST/ASTContext.cpp", 3368, __extension__ __PRETTY_FUNCTION__
))
;
3369 TSInfo->overrideType(Updated);
3370 }
3371}
3372
3373/// getComplexType - Return the uniqued reference to the type for a complex
3374/// number with the specified element type.
3375QualType ASTContext::getComplexType(QualType T) const {
3376 // Unique pointers, to guarantee there is only one pointer of a particular
3377 // structure.
3378 llvm::FoldingSetNodeID ID;
3379 ComplexType::Profile(ID, T);
3380
3381 void *InsertPos = nullptr;
3382 if (ComplexType *CT = ComplexTypes.FindNodeOrInsertPos(ID, InsertPos))
3383 return QualType(CT, 0);
3384
3385 // If the pointee type isn't canonical, this won't be a canonical type either,
3386 // so fill in the canonical type field.
3387 QualType Canonical;
3388 if (!T.isCanonical()) {
3389 Canonical = getComplexType(getCanonicalType(T));
3390
3391 // Get the new insert position for the node we care about.
3392 ComplexType *NewIP = ComplexTypes.FindNodeOrInsertPos(ID, InsertPos);
3393 assert(!NewIP && "Shouldn't be in the map!")(static_cast <bool> (!NewIP && "Shouldn't be in the map!"
) ? void (0) : __assert_fail ("!NewIP && \"Shouldn't be in the map!\""
, "clang/lib/AST/ASTContext.cpp", 3393, __extension__ __PRETTY_FUNCTION__
))
; (void)NewIP;
3394 }
3395 auto *New = new (*this, TypeAlignment) ComplexType(T, Canonical);
3396 Types.push_back(New);
3397 ComplexTypes.InsertNode(New, InsertPos);
3398 return QualType(New, 0);
3399}
3400
3401/// getPointerType - Return the uniqued reference to the type for a pointer to
3402/// the specified type.
3403QualType ASTContext::getPointerType(QualType T) const {
3404 // Unique pointers, to guarantee there is only one pointer of a particular
3405 // structure.
3406 llvm::FoldingSetNodeID ID;
3407 PointerType::Profile(ID, T);
3408
3409 void *InsertPos = nullptr;
3410 if (PointerType *PT = PointerTypes.FindNodeOrInsertPos(ID, InsertPos))
3411 return QualType(PT, 0);
3412
3413 // If the pointee type isn't canonical, this won't be a canonical type either,
3414 // so fill in the canonical type field.
3415 QualType Canonical;
3416 if (!T.isCanonical()) {
3417 Canonical = getPointerType(getCanonicalType(T));
3418
3419 // Get the new insert position for the node we care about.
3420 PointerType *NewIP = PointerTypes.FindNodeOrInsertPos(ID, InsertPos);
3421 assert(!NewIP && "Shouldn't be in the map!")(static_cast <bool> (!NewIP && "Shouldn't be in the map!"
) ? void (0) : __assert_fail ("!NewIP && \"Shouldn't be in the map!\""
, "clang/lib/AST/ASTContext.cpp", 3421, __extension__ __PRETTY_FUNCTION__
))
; (void)NewIP;
3422 }
3423 auto *New = new (*this, TypeAlignment) PointerType(T, Canonical);
3424 Types.push_back(New);
3425 PointerTypes.InsertNode(New, InsertPos);
3426 return QualType(New, 0);
3427}
3428
3429QualType ASTContext::getAdjustedType(QualType Orig, QualType New) const {
3430 llvm::FoldingSetNodeID ID;
3431 AdjustedType::Profile(ID, Orig, New);
3432 void *InsertPos = nullptr;
3433 AdjustedType *AT = AdjustedTypes.FindNodeOrInsertPos(ID, InsertPos);
3434 if (AT)
3435 return QualType(AT, 0);
3436
3437 QualType Canonical = getCanonicalType(New);
3438
3439 // Get the new insert position for the node we care about.
3440 AT = AdjustedTypes.FindNodeOrInsertPos(ID, InsertPos);
3441 assert(!AT && "Shouldn't be in the map!")(static_cast <bool> (!AT && "Shouldn't be in the map!"
) ? void (0) : __assert_fail ("!AT && \"Shouldn't be in the map!\""
, "clang/lib/AST/ASTContext.cpp", 3441, __extension__ __PRETTY_FUNCTION__
))
;
3442
3443 AT = new (*this, TypeAlignment)
3444 AdjustedType(Type::Adjusted, Orig, New, Canonical);
3445 Types.push_back(AT);
3446 AdjustedTypes.InsertNode(AT, InsertPos);
3447 return QualType(AT, 0);
3448}
3449
3450QualType ASTContext::getDecayedType(QualType Orig, QualType Decayed) const {
3451 llvm::FoldingSetNodeID ID;
3452 AdjustedType::Profile(ID, Orig, Decayed);
3453 void *InsertPos = nullptr;
3454 AdjustedType *AT = AdjustedTypes.FindNodeOrInsertPos(ID, InsertPos);
3455 if (AT)
3456 return QualType(AT, 0);
3457
3458 QualType Canonical = getCanonicalType(Decayed);
3459
3460 // Get the new insert position for the node we care about.
3461 AT = AdjustedTypes.FindNodeOrInsertPos(ID, InsertPos);
3462 assert(!AT && "Shouldn't be in the map!")(static_cast <bool> (!AT && "Shouldn't be in the map!"
) ? void (0) : __assert_fail ("!AT && \"Shouldn't be in the map!\""
, "clang/lib/AST/ASTContext.cpp", 3462, __extension__ __PRETTY_FUNCTION__
))
;
3463
3464 AT = new (*this, TypeAlignment) DecayedType(Orig, Decayed, Canonical);
3465 Types.push_back(AT);
3466 AdjustedTypes.InsertNode(AT, InsertPos);
3467 return QualType(AT, 0);
3468}
3469
3470QualType ASTContext::getDecayedType(QualType T) const {
3471 assert((T->isArrayType() || T->isFunctionType()) && "T does not decay")(static_cast <bool> ((T->isArrayType() || T->isFunctionType
()) && "T does not decay") ? void (0) : __assert_fail
("(T->isArrayType() || T->isFunctionType()) && \"T does not decay\""
, "clang/lib/AST/ASTContext.cpp", 3471, __extension__ __PRETTY_FUNCTION__
))
;
3472
3473 QualType Decayed;
3474
3475 // C99 6.7.5.3p7:
3476 // A declaration of a parameter as "array of type" shall be
3477 // adjusted to "qualified pointer to type", where the type
3478 // qualifiers (if any) are those specified within the [ and ] of
3479 // the array type derivation.
3480 if (T->isArrayType())
3481 Decayed = getArrayDecayedType(T);
3482
3483 // C99 6.7.5.3p8:
3484 // A declaration of a parameter as "function returning type"
3485 // shall be adjusted to "pointer to function returning type", as
3486 // in 6.3.2.1.
3487 if (T->isFunctionType())
3488 Decayed = getPointerType(T);
3489
3490 return getDecayedType(T, Decayed);
3491}
3492
3493/// getBlockPointerType - Return the uniqued reference to the type for
3494/// a pointer to the specified block.
3495QualType ASTContext::getBlockPointerType(QualType T) const {
3496 assert(T->isFunctionType() && "block of function types only")(static_cast <bool> (T->isFunctionType() && "block of function types only"
) ? void (0) : __assert_fail ("T->isFunctionType() && \"block of function types only\""
, "clang/lib/AST/ASTContext.cpp", 3496, __extension__ __PRETTY_FUNCTION__
))
;
3497 // Unique pointers, to guarantee there is only one block of a particular
3498 // structure.
3499 llvm::FoldingSetNodeID ID;
3500 BlockPointerType::Profile(ID, T);
3501
3502 void *InsertPos = nullptr;
3503 if (BlockPointerType *PT =
3504 BlockPointerTypes.FindNodeOrInsertPos(ID, InsertPos))
3505 return QualType(PT, 0);
3506
3507 // If the block pointee type isn't canonical, this won't be a canonical
3508 // type either so fill in the canonical type field.
3509 QualType Canonical;
3510 if (!T.isCanonical()) {
3511 Canonical = getBlockPointerType(getCanonicalType(T));
3512
3513 // Get the new insert position for the node we care about.
3514 BlockPointerType *NewIP =
3515 BlockPointerTypes.FindNodeOrInsertPos(ID, InsertPos);
3516 assert(!NewIP && "Shouldn't be in the map!")(static_cast <bool> (!NewIP && "Shouldn't be in the map!"
) ? void (0) : __assert_fail ("!NewIP && \"Shouldn't be in the map!\""
, "clang/lib/AST/ASTContext.cpp", 3516, __extension__ __PRETTY_FUNCTION__
))
; (void)NewIP;
3517 }
3518 auto *New = new (*this, TypeAlignment) BlockPointerType(T, Canonical);
3519 Types.push_back(New);
3520 BlockPointerTypes.InsertNode(New, InsertPos);
3521 return QualType(New, 0);
3522}
3523
3524/// getLValueReferenceType - Return the uniqued reference to the type for an
3525/// lvalue reference to the specified type.
3526QualType
3527ASTContext::getLValueReferenceType(QualType T, bool SpelledAsLValue) const {
3528 assert((!T->isPlaceholderType() ||(static_cast <bool> ((!T->isPlaceholderType() || T->
isSpecificPlaceholderType(BuiltinType::UnknownAny)) &&
"Unresolved placeholder type") ? void (0) : __assert_fail ("(!T->isPlaceholderType() || T->isSpecificPlaceholderType(BuiltinType::UnknownAny)) && \"Unresolved placeholder type\""
, "clang/lib/AST/ASTContext.cpp", 3530, __extension__ __PRETTY_FUNCTION__
))
3529 T->isSpecificPlaceholderType(BuiltinType::UnknownAny)) &&(static_cast <bool> ((!T->isPlaceholderType() || T->
isSpecificPlaceholderType(BuiltinType::UnknownAny)) &&
"Unresolved placeholder type") ? void (0) : __assert_fail ("(!T->isPlaceholderType() || T->isSpecificPlaceholderType(BuiltinType::UnknownAny)) && \"Unresolved placeholder type\""
, "clang/lib/AST/ASTContext.cpp", 3530, __extension__ __PRETTY_FUNCTION__
))
3530 "Unresolved placeholder type")(static_cast <bool> ((!T->isPlaceholderType() || T->
isSpecificPlaceholderType(BuiltinType::UnknownAny)) &&
"Unresolved placeholder type") ? void (0) : __assert_fail ("(!T->isPlaceholderType() || T->isSpecificPlaceholderType(BuiltinType::UnknownAny)) && \"Unresolved placeholder type\""
, "clang/lib/AST/ASTContext.cpp", 3530, __extension__ __PRETTY_FUNCTION__
))
;
3531
3532 // Unique pointers, to guarantee there is only one pointer of a particular
3533 // structure.
3534 llvm::FoldingSetNodeID ID;
3535 ReferenceType::Profile(ID, T, SpelledAsLValue);
3536
3537 void *InsertPos = nullptr;
3538 if (LValueReferenceType *RT =
3539 LValueReferenceTypes.FindNodeOrInsertPos(ID, InsertPos))
3540 return QualType(RT, 0);
3541
3542 const auto *InnerRef = T->getAs<ReferenceType>();
3543
3544 // If the referencee type isn't canonical, this won't be a canonical type
3545 // either, so fill in the canonical type field.
3546 QualType Canonical;
3547 if (!SpelledAsLValue || InnerRef || !T.isCanonical()) {
3548 QualType PointeeType = (InnerRef ? InnerRef->getPointeeType() : T);
3549 Canonical = getLValueReferenceType(getCanonicalType(PointeeType));
3550
3551 // Get the new insert position for the node we care about.
3552 LValueReferenceType *NewIP =
3553 LValueReferenceTypes.FindNodeOrInsertPos(ID, InsertPos);
3554 assert(!NewIP && "Shouldn't be in the map!")(static_cast <bool> (!NewIP && "Shouldn't be in the map!"
) ? void (0) : __assert_fail ("!NewIP && \"Shouldn't be in the map!\""
, "clang/lib/AST/ASTContext.cpp", 3554, __extension__ __PRETTY_FUNCTION__
))
; (void)NewIP;
3555 }
3556
3557 auto *New = new (*this, TypeAlignment) LValueReferenceType(T, Canonical,
3558 SpelledAsLValue);
3559 Types.push_back(New);
3560 LValueReferenceTypes.InsertNode(New, InsertPos);
3561
3562 return QualType(New, 0);
3563}
3564
3565/// getRValueReferenceType - Return the uniqued reference to the type for an
3566/// rvalue reference to the specified type.
3567QualType ASTContext::getRValueReferenceType(QualType T) const {
3568 assert((!T->isPlaceholderType() ||(static_cast <bool> ((!T->isPlaceholderType() || T->
isSpecificPlaceholderType(BuiltinType::UnknownAny)) &&
"Unresolved placeholder type") ? void (0) : __assert_fail ("(!T->isPlaceholderType() || T->isSpecificPlaceholderType(BuiltinType::UnknownAny)) && \"Unresolved placeholder type\""
, "clang/lib/AST/ASTContext.cpp", 3570, __extension__ __PRETTY_FUNCTION__
))
3569 T->isSpecificPlaceholderType(BuiltinType::UnknownAny)) &&(static_cast <bool> ((!T->isPlaceholderType() || T->
isSpecificPlaceholderType(BuiltinType::UnknownAny)) &&
"Unresolved placeholder type") ? void (0) : __assert_fail ("(!T->isPlaceholderType() || T->isSpecificPlaceholderType(BuiltinType::UnknownAny)) && \"Unresolved placeholder type\""
, "clang/lib/AST/ASTContext.cpp", 3570, __extension__ __PRETTY_FUNCTION__
))
3570 "Unresolved placeholder type")(static_cast <bool> ((!T->isPlaceholderType() || T->
isSpecificPlaceholderType(BuiltinType::UnknownAny)) &&
"Unresolved placeholder type") ? void (0) : __assert_fail ("(!T->isPlaceholderType() || T->isSpecificPlaceholderType(BuiltinType::UnknownAny)) && \"Unresolved placeholder type\""
, "clang/lib/AST/ASTContext.cpp", 3570, __extension__ __PRETTY_FUNCTION__
))
;
3571
3572 // Unique pointers, to guarantee there is only one pointer of a particular
3573 // structure.
3574 llvm::FoldingSetNodeID ID;
3575 ReferenceType::Profile(ID, T, false);
3576
3577 void *InsertPos = nullptr;
3578 if (RValueReferenceType *RT =
3579 RValueReferenceTypes.FindNodeOrInsertPos(ID, InsertPos))
3580 return QualType(RT, 0);
3581
3582 const auto *InnerRef = T->getAs<ReferenceType>();
3583
3584 // If the referencee type isn't canonical, this won't be a canonical type
3585 // either, so fill in the canonical type field.
3586 QualType Canonical;
3587 if (InnerRef || !T.isCanonical()) {
3588 QualType PointeeType = (InnerRef ? InnerRef->getPointeeType() : T);
3589 Canonical = getRValueReferenceType(getCanonicalType(PointeeType));
3590
3591 // Get the new insert position for the node we care about.
3592 RValueReferenceType *NewIP =
3593 RValueReferenceTypes.FindNodeOrInsertPos(ID, InsertPos);
3594 assert(!NewIP && "Shouldn't be in the map!")(static_cast <bool> (!NewIP && "Shouldn't be in the map!"
) ? void (0) : __assert_fail ("!NewIP && \"Shouldn't be in the map!\""
, "clang/lib/AST/ASTContext.cpp", 3594, __extension__ __PRETTY_FUNCTION__
))
; (void)NewIP;
3595 }
3596
3597 auto *New = new (*this, TypeAlignment) RValueReferenceType(T, Canonical);
3598 Types.push_back(New);
3599 RValueReferenceTypes.InsertNode(New, InsertPos);
3600 return QualType(New, 0);
3601}
3602
3603/// getMemberPointerType - Return the uniqued reference to the type for a
3604/// member pointer to the specified type, in the specified class.
3605QualType ASTContext::getMemberPointerType(QualType T, const Type *Cls) const {
3606 // Unique pointers, to guarantee there is only one pointer of a particular
3607 // structure.
3608 llvm::FoldingSetNodeID ID;
3609 MemberPointerType::Profile(ID, T, Cls);
3610
3611 void *InsertPos = nullptr;
3612 if (MemberPointerType *PT =
3613 MemberPointerTypes.FindNodeOrInsertPos(ID, InsertPos))
3614 return QualType(PT, 0);
3615
3616 // If the pointee or class type isn't canonical, this won't be a canonical
3617 // type either, so fill in the canonical type field.
3618 QualType Canonical;
3619 if (!T.isCanonical() || !Cls->isCanonicalUnqualified()) {
3620 Canonical = getMemberPointerType(getCanonicalType(T),getCanonicalType(Cls));
3621
3622 // Get the new insert position for the node we care about.
3623 MemberPointerType *NewIP =
3624 MemberPointerTypes.FindNodeOrInsertPos(ID, InsertPos);
3625 assert(!NewIP && "Shouldn't be in the map!")(static_cast <bool> (!NewIP && "Shouldn't be in the map!"
) ? void (0) : __assert_fail ("!NewIP && \"Shouldn't be in the map!\""
, "clang/lib/AST/ASTContext.cpp", 3625, __extension__ __PRETTY_FUNCTION__
))
; (void)NewIP;
3626 }
3627 auto *New = new (*this, TypeAlignment) MemberPointerType(T, Cls, Canonical);
3628 Types.push_back(New);
3629 MemberPointerTypes.InsertNode(New, InsertPos);
3630 return QualType(New, 0);
3631}
3632
3633/// getConstantArrayType - Return the unique reference to the type for an
3634/// array of the specified element type.
3635QualType ASTContext::getConstantArrayType(QualType EltTy,
3636 const llvm::APInt &ArySizeIn,
3637 const Expr *SizeExpr,
3638 ArrayType::ArraySizeModifier ASM,
3639 unsigned IndexTypeQuals) const {
3640 assert((EltTy->isDependentType() ||(static_cast <bool> ((EltTy->isDependentType() || EltTy
->isIncompleteType() || EltTy->isConstantSizeType()) &&
"Constant array of VLAs is illegal!") ? void (0) : __assert_fail
("(EltTy->isDependentType() || EltTy->isIncompleteType() || EltTy->isConstantSizeType()) && \"Constant array of VLAs is illegal!\""
, "clang/lib/AST/ASTContext.cpp", 3642, __extension__ __PRETTY_FUNCTION__
))
3641 EltTy->isIncompleteType() || EltTy->isConstantSizeType()) &&(static_cast <bool> ((EltTy->isDependentType() || EltTy
->isIncompleteType() || EltTy->isConstantSizeType()) &&
"Constant array of VLAs is illegal!") ? void (0) : __assert_fail
("(EltTy->isDependentType() || EltTy->isIncompleteType() || EltTy->isConstantSizeType()) && \"Constant array of VLAs is illegal!\""
, "clang/lib/AST/ASTContext.cpp", 3642, __extension__ __PRETTY_FUNCTION__
))
3642 "Constant array of VLAs is illegal!")(static_cast <bool> ((EltTy->isDependentType() || EltTy
->isIncompleteType() || EltTy->isConstantSizeType()) &&
"Constant array of VLAs is illegal!") ? void (0) : __assert_fail
("(EltTy->isDependentType() || EltTy->isIncompleteType() || EltTy->isConstantSizeType()) && \"Constant array of VLAs is illegal!\""
, "clang/lib/AST/ASTContext.cpp", 3642, __extension__ __PRETTY_FUNCTION__
))
;
3643
3644 // We only need the size as part of the type if it's instantiation-dependent.
3645 if (SizeExpr && !SizeExpr->isInstantiationDependent())
3646 SizeExpr = nullptr;
3647
3648 // Convert the array size into a canonical width matching the pointer size for
3649 // the target.
3650 llvm::APInt ArySize(ArySizeIn);
3651 ArySize = ArySize.zextOrTrunc(Target->getMaxPointerWidth());
3652
3653 llvm::FoldingSetNodeID ID;
3654 ConstantArrayType::Profile(ID, *this, EltTy, ArySize, SizeExpr, ASM,
3655 IndexTypeQuals);
3656
3657 void *InsertPos = nullptr;
3658 if (ConstantArrayType *ATP =
3659 ConstantArrayTypes.FindNodeOrInsertPos(ID, InsertPos))
3660 return QualType(ATP, 0);
3661
3662 // If the element type isn't canonical or has qualifiers, or the array bound
3663 // is instantiation-dependent, this won't be a canonical type either, so fill
3664 // in the canonical type field.
3665 QualType Canon;
3666 // FIXME: Check below should look for qualifiers behind sugar.
3667 if (!EltTy.isCanonical() || EltTy.hasLocalQualifiers() || SizeExpr) {
3668 SplitQualType canonSplit = getCanonicalType(EltTy).split();
3669 Canon = getConstantArrayType(QualType(canonSplit.Ty, 0), ArySize, nullptr,
3670 ASM, IndexTypeQuals);
3671 Canon = getQualifiedType(Canon, canonSplit.Quals);
3672
3673 // Get the new insert position for the node we care about.
3674 ConstantArrayType *NewIP =
3675 ConstantArrayTypes.FindNodeOrInsertPos(ID, InsertPos);
3676 assert(!NewIP && "Shouldn't be in the map!")(static_cast <bool> (!NewIP && "Shouldn't be in the map!"
) ? void (0) : __assert_fail ("!NewIP && \"Shouldn't be in the map!\""
, "clang/lib/AST/ASTContext.cpp", 3676, __extension__ __PRETTY_FUNCTION__
))
; (void)NewIP;
3677 }
3678
3679 void *Mem = Allocate(
3680 ConstantArrayType::totalSizeToAlloc<const Expr *>(SizeExpr ? 1 : 0),
3681 TypeAlignment);
3682 auto *New = new (Mem)
3683 ConstantArrayType(EltTy, Canon, ArySize, SizeExpr, ASM, IndexTypeQuals);
3684 ConstantArrayTypes.InsertNode(New, InsertPos);
3685 Types.push_back(New);
3686 return QualType(New, 0);
3687}
3688
3689/// getVariableArrayDecayedType - Turns the given type, which may be
3690/// variably-modified, into the corresponding type with all the known
3691/// sizes replaced with [*].
3692QualType ASTContext::getVariableArrayDecayedType(QualType type) const {
3693 // Vastly most common case.
3694 if (!type->isVariablyModifiedType()) return type;
3695
3696 QualType result;
3697
3698 SplitQualType split = type.getSplitDesugaredType();
3699 const Type *ty = split.Ty;
3700 switch (ty->getTypeClass()) {
3701#define TYPE(Class, Base)
3702#define ABSTRACT_TYPE(Class, Base)
3703#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
3704#include "clang/AST/TypeNodes.inc"
3705 llvm_unreachable("didn't desugar past all non-canonical types?")::llvm::llvm_unreachable_internal("didn't desugar past all non-canonical types?"
, "clang/lib/AST/ASTContext.cpp", 3705)
;
3706
3707 // These types should never be variably-modified.
3708 case Type::Builtin:
3709 case Type::Complex:
3710 case Type::Vector:
3711 case Type::DependentVector:
3712 case Type::ExtVector:
3713 case Type::DependentSizedExtVector:
3714 case Type::ConstantMatrix:
3715 case Type::DependentSizedMatrix:
3716 case Type::DependentAddressSpace:
3717 case Type::ObjCObject:
3718 case Type::ObjCInterface:
3719 case Type::ObjCObjectPointer:
3720 case Type::Record:
3721 case Type::Enum:
3722 case Type::UnresolvedUsing:
3723 case Type::TypeOfExpr:
3724 case Type::TypeOf:
3725 case Type::Decltype:
3726 case Type::UnaryTransform:
3727 case Type::DependentName:
3728 case Type::InjectedClassName:
3729 case Type::TemplateSpecialization:
3730 case Type::DependentTemplateSpecialization:
3731 case Type::TemplateTypeParm:
3732 case Type::SubstTemplateTypeParmPack:
3733 case Type::Auto:
3734 case Type::DeducedTemplateSpecialization:
3735 case Type::PackExpansion:
3736 case Type::BitInt:
3737 case Type::DependentBitInt:
3738 llvm_unreachable("type should never be variably-modified")::llvm::llvm_unreachable_internal("type should never be variably-modified"
, "clang/lib/AST/ASTContext.cpp", 3738)
;
3739
3740 // These types can be variably-modified but should never need to
3741 // further decay.
3742 case Type::FunctionNoProto:
3743 case Type::FunctionProto:
3744 case Type::BlockPointer:
3745 case Type::MemberPointer:
3746 case Type::Pipe:
3747 return type;
3748
3749 // These types can be variably-modified. All these modifications
3750 // preserve structure except as noted by comments.
3751 // TODO: if we ever care about optimizing VLAs, there are no-op
3752 // optimizations available here.
3753 case Type::Pointer:
3754 result = getPointerType(getVariableArrayDecayedType(
3755 cast<PointerType>(ty)->getPointeeType()));
3756 break;
3757
3758 case Type::LValueReference: {
3759 const auto *lv = cast<LValueReferenceType>(ty);
3760 result = getLValueReferenceType(
3761 getVariableArrayDecayedType(lv->getPointeeType()),
3762 lv->isSpelledAsLValue());
3763 break;
3764 }
3765
3766 case Type::RValueReference: {
3767 const auto *lv = cast<RValueReferenceType>(ty);
3768 result = getRValueReferenceType(
3769 getVariableArrayDecayedType(lv->getPointeeType()));
3770 break;
3771 }
3772
3773 case Type::Atomic: {
3774 const auto *at = cast<AtomicType>(ty);
3775 result = getAtomicType(getVariableArrayDecayedType(at->getValueType()));
3776 break;
3777 }
3778
3779 case Type::ConstantArray: {
3780 const auto *cat = cast<ConstantArrayType>(ty);
3781 result = getConstantArrayType(
3782 getVariableArrayDecayedType(cat->getElementType()),
3783 cat->getSize(),
3784 cat->getSizeExpr(),
3785 cat->getSizeModifier(),
3786 cat->getIndexTypeCVRQualifiers());
3787 break;
3788 }
3789
3790 case Type::DependentSizedArray: {
3791 const auto *dat = cast<DependentSizedArrayType>(ty);
3792 result = getDependentSizedArrayType(
3793 getVariableArrayDecayedType(dat->getElementType()),
3794 dat->getSizeExpr(),
3795 dat->getSizeModifier(),
3796 dat->getIndexTypeCVRQualifiers(),
3797 dat->getBracketsRange());
3798 break;
3799 }
3800
3801 // Turn incomplete types into [*] types.
3802 case Type::IncompleteArray: {
3803 const auto *iat = cast<IncompleteArrayType>(ty);
3804 result = getVariableArrayType(
3805 getVariableArrayDecayedType(iat->getElementType()),
3806 /*size*/ nullptr,
3807 ArrayType::Normal,
3808 iat->getIndexTypeCVRQualifiers(),
3809 SourceRange());
3810 break;
3811 }
3812
3813 // Turn VLA types into [*] types.
3814 case Type::VariableArray: {
3815 const auto *vat = cast<VariableArrayType>(ty);
3816 result = getVariableArrayType(
3817 getVariableArrayDecayedType(vat->getElementType()),
3818 /*size*/ nullptr,
3819 ArrayType::Star,
3820 vat->getIndexTypeCVRQualifiers(),
3821 vat->getBracketsRange());
3822 break;
3823 }
3824 }
3825
3826 // Apply the top-level qualifiers from the original.
3827 return getQualifiedType(result, split.Quals);
3828}
3829
3830/// getVariableArrayType - Returns a non-unique reference to the type for a
3831/// variable array of the specified element type.
3832QualType ASTContext::getVariableArrayType(QualType EltTy,
3833 Expr *NumElts,
3834 ArrayType::ArraySizeModifier ASM,
3835 unsigned IndexTypeQuals,
3836 SourceRange Brackets) const {
3837 // Since we don't unique expressions, it isn't possible to unique VLA's
3838 // that have an expression provided for their size.
3839 QualType Canon;
3840
3841 // Be sure to pull qualifiers off the element type.
3842 // FIXME: Check below should look for qualifiers behind sugar.
3843 if (!EltTy.isCanonical() || EltTy.hasLocalQualifiers()) {
3844 SplitQualType canonSplit = getCanonicalType(EltTy).split();
3845 Canon = getVariableArrayType(QualType(canonSplit.Ty, 0), NumElts, ASM,
3846 IndexTypeQuals, Brackets);
3847 Canon = getQualifiedType(Canon, canonSplit.Quals);
3848 }
3849
3850 auto *New = new (*this, TypeAlignment)
3851 VariableArrayType(EltTy, Canon, NumElts, ASM, IndexTypeQuals, Brackets);
3852
3853 VariableArrayTypes.push_back(New);
3854 Types.push_back(New);
3855 return QualType(New, 0);
3856}
3857
3858/// getDependentSizedArrayType - Returns a non-unique reference to
3859/// the type for a dependently-sized array of the specified element
3860/// type.
3861QualType ASTContext::getDependentSizedArrayType(QualType elementType,
3862 Expr *numElements,
3863 ArrayType::ArraySizeModifier ASM,
3864 unsigned elementTypeQuals,
3865 SourceRange brackets) const {
3866 assert((!numElements || numElements->isTypeDependent() ||(static_cast <bool> ((!numElements || numElements->isTypeDependent
() || numElements->isValueDependent()) && "Size must be type- or value-dependent!"
) ? void (0) : __assert_fail ("(!numElements || numElements->isTypeDependent() || numElements->isValueDependent()) && \"Size must be type- or value-dependent!\""
, "clang/lib/AST/ASTContext.cpp", 3868, __extension__ __PRETTY_FUNCTION__
))
3867 numElements->isValueDependent()) &&(static_cast <bool> ((!numElements || numElements->isTypeDependent
() || numElements->isValueDependent()) && "Size must be type- or value-dependent!"
) ? void (0) : __assert_fail ("(!numElements || numElements->isTypeDependent() || numElements->isValueDependent()) && \"Size must be type- or value-dependent!\""
, "clang/lib/AST/ASTContext.cpp", 3868, __extension__ __PRETTY_FUNCTION__
))
3868 "Size must be type- or value-dependent!")(static_cast <bool> ((!numElements || numElements->isTypeDependent
() || numElements->isValueDependent()) && "Size must be type- or value-dependent!"
) ? void (0) : __assert_fail ("(!numElements || numElements->isTypeDependent() || numElements->isValueDependent()) && \"Size must be type- or value-dependent!\""
, "clang/lib/AST/ASTContext.cpp", 3868, __extension__ __PRETTY_FUNCTION__
))
;
3869
3870 // Dependently-sized array types that do not have a specified number
3871 // of elements will have their sizes deduced from a dependent
3872 // initializer. We do no canonicalization here at all, which is okay
3873 // because they can't be used in most locations.
3874 if (!numElements) {
3875 auto *newType
3876 = new (*this, TypeAlignment)
3877 DependentSizedArrayType(*this, elementType, QualType(),
3878 numElements, ASM, elementTypeQuals,
3879 brackets);
3880 Types.push_back(newType);
3881 return QualType(newType, 0);
3882 }
3883
3884 // Otherwise, we actually build a new type every time, but we
3885 // also build a canonical type.
3886
3887 SplitQualType canonElementType = getCanonicalType(elementType).split();
3888
3889 void *insertPos = nullptr;
3890 llvm::FoldingSetNodeID ID;
3891 DependentSizedArrayType::Profile(ID, *this,
3892 QualType(canonElementType.Ty, 0),
3893 ASM, elementTypeQuals, numElements);
3894
3895 // Look for an existing type with these properties.
3896 DependentSizedArrayType *canonTy =
3897 DependentSizedArrayTypes.FindNodeOrInsertPos(ID, insertPos);
3898
3899 // If we don't have one, build one.
3900 if (!canonTy) {
3901 canonTy = new (*this, TypeAlignment)
3902 DependentSizedArrayType(*this, QualType(canonElementType.Ty, 0),
3903 QualType(), numElements, ASM, elementTypeQuals,
3904 brackets);
3905 DependentSizedArrayTypes.InsertNode(canonTy, insertPos);
3906 Types.push_back(canonTy);
3907 }
3908
3909 // Apply qualifiers from the element type to the array.
3910 QualType canon = getQualifiedType(QualType(canonTy,0),
3911 canonElementType.Quals);
3912
3913 // If we didn't need extra canonicalization for the element type or the size
3914 // expression, then just use that as our result.
3915 if (QualType(canonElementType.Ty, 0) == elementType &&
3916 canonTy->getSizeExpr() == numElements)
3917 return canon;
3918
3919 // Otherwise, we need to build a type which follows the spelling
3920 // of the element type.
3921 auto *sugaredType
3922 = new (*this, TypeAlignment)
3923 DependentSizedArrayType(*this, elementType, canon, numElements,
3924 ASM, elementTypeQuals, brackets);
3925 Types.push_back(sugaredType);
3926 return QualType(sugaredType, 0);
3927}
3928
3929QualType ASTContext::getIncompleteArrayType(QualType elementType,
3930 ArrayType::ArraySizeModifier ASM,
3931 unsigned elementTypeQuals) const {
3932 llvm::FoldingSetNodeID ID;
3933 IncompleteArrayType::Profile(ID, elementType, ASM, elementTypeQuals);
3934
3935 void *insertPos = nullptr;
3936 if (IncompleteArrayType *iat =
3937 IncompleteArrayTypes.FindNodeOrInsertPos(ID, insertPos))
3938 return QualType(iat, 0);
3939
3940 // If the element type isn't canonical, this won't be a canonical type
3941 // either, so fill in the canonical type field. We also have to pull
3942 // qualifiers off the element type.
3943 QualType canon;
3944
3945 // FIXME: Check below should look for qualifiers behind sugar.
3946 if (!elementType.isCanonical() || elementType.hasLocalQualifiers()) {
3947 SplitQualType canonSplit = getCanonicalType(elementType).split();
3948 canon = getIncompleteArrayType(QualType(canonSplit.Ty, 0),
3949 ASM, elementTypeQuals);
3950 canon = getQualifiedType(canon, canonSplit.Quals);
3951
3952 // Get the new insert position for the node we care about.
3953 IncompleteArrayType *existing =
3954 IncompleteArrayTypes.FindNodeOrInsertPos(ID, insertPos);
3955 assert(!existing && "Shouldn't be in the map!")(static_cast <bool> (!existing && "Shouldn't be in the map!"
) ? void (0) : __assert_fail ("!existing && \"Shouldn't be in the map!\""
, "clang/lib/AST/ASTContext.cpp", 3955, __extension__ __PRETTY_FUNCTION__
))
; (void) existing;
3956 }
3957
3958 auto *newType = new (*this, TypeAlignment)
3959 IncompleteArrayType(elementType, canon, ASM, elementTypeQuals);
3960
3961 IncompleteArrayTypes.InsertNode(newType, insertPos);
3962 Types.push_back(newType);
3963 return QualType(newType, 0);
3964}
3965
3966ASTContext::BuiltinVectorTypeInfo
3967ASTContext::getBuiltinVectorTypeInfo(const BuiltinType *Ty) const {
3968#define SVE_INT_ELTTY(BITS, ELTS, SIGNED, NUMVECTORS){getIntTypeForBitwidth(BITS, SIGNED), llvm::ElementCount::getScalable
(ELTS), NUMVECTORS};
\
3969 {getIntTypeForBitwidth(BITS, SIGNED), llvm::ElementCount::getScalable(ELTS), \
3970 NUMVECTORS};
3971
3972#define SVE_ELTTY(ELTTY, ELTS, NUMVECTORS){ELTTY, llvm::ElementCount::getScalable(ELTS), NUMVECTORS}; \
3973 {ELTTY, llvm::ElementCount::getScalable(ELTS), NUMVECTORS};
3974
3975 switch (Ty->getKind()) {
3976 default:
3977 llvm_unreachable("Unsupported builtin vector type")::llvm::llvm_unreachable_internal("Unsupported builtin vector type"
, "clang/lib/AST/ASTContext.cpp", 3977)
;
3978 case BuiltinType::SveInt8:
3979 return SVE_INT_ELTTY(8, 16, true, 1){getIntTypeForBitwidth(8, true), llvm::ElementCount::getScalable
(16), 1};
;
3980 case BuiltinType::SveUint8:
3981 return SVE_INT_ELTTY(8, 16, false, 1){getIntTypeForBitwidth(8, false), llvm::ElementCount::getScalable
(16), 1};
;
3982 case BuiltinType::SveInt8x2:
3983 return SVE_INT_ELTTY(8, 16, true, 2){getIntTypeForBitwidth(8, true), llvm::ElementCount::getScalable
(16), 2};
;
3984 case BuiltinType::SveUint8x2:
3985 return SVE_INT_ELTTY(8, 16, false, 2){getIntTypeForBitwidth(8, false), llvm::ElementCount::getScalable
(16), 2};
;
3986 case BuiltinType::SveInt8x3:
3987 return SVE_INT_ELTTY(8, 16, true, 3){getIntTypeForBitwidth(8, true), llvm::ElementCount::getScalable
(16), 3};
;
3988 case BuiltinType::SveUint8x3:
3989 return SVE_INT_ELTTY(8, 16, false, 3){getIntTypeForBitwidth(8, false), llvm::ElementCount::getScalable
(16), 3};
;
3990 case BuiltinType::SveInt8x4:
3991 return SVE_INT_ELTTY(8, 16, true, 4){getIntTypeForBitwidth(8, true), llvm::ElementCount::getScalable
(16), 4};
;
3992 case BuiltinType::SveUint8x4:
3993 return SVE_INT_ELTTY(8, 16, false, 4){getIntTypeForBitwidth(8, false), llvm::ElementCount::getScalable
(16), 4};
;
3994 case BuiltinType::SveInt16:
3995 return SVE_INT_ELTTY(16, 8, true, 1){getIntTypeForBitwidth(16, true), llvm::ElementCount::getScalable
(8), 1};
;
3996 case BuiltinType::SveUint16:
3997 return SVE_INT_ELTTY(16, 8, false, 1){getIntTypeForBitwidth(16, false), llvm::ElementCount::getScalable
(8), 1};
;
3998 case BuiltinType::SveInt16x2:
3999 return SVE_INT_ELTTY(16, 8, true, 2){getIntTypeForBitwidth(16, true), llvm::ElementCount::getScalable
(8), 2};
;
4000 case BuiltinType::SveUint16x2:
4001 return SVE_INT_ELTTY(16, 8, false, 2){getIntTypeForBitwidth(16, false), llvm::ElementCount::getScalable
(8), 2};
;
4002 case BuiltinType::SveInt16x3:
4003 return SVE_INT_ELTTY(16, 8, true, 3){getIntTypeForBitwidth(16, true), llvm::ElementCount::getScalable
(8), 3};
;
4004 case BuiltinType::SveUint16x3:
4005 return SVE_INT_ELTTY(16, 8, false, 3){getIntTypeForBitwidth(16, false), llvm::ElementCount::getScalable
(8), 3};
;
4006 case BuiltinType::SveInt16x4:
4007 return SVE_INT_ELTTY(16, 8, true, 4){getIntTypeForBitwidth(16, true), llvm::ElementCount::getScalable
(8), 4};
;
4008 case BuiltinType::SveUint16x4:
4009 return SVE_INT_ELTTY(16, 8, false, 4){getIntTypeForBitwidth(16, false), llvm::ElementCount::getScalable
(8), 4};
;
4010 case BuiltinType::SveInt32:
4011 return SVE_INT_ELTTY(32, 4, true, 1){getIntTypeForBitwidth(32, true), llvm::ElementCount::getScalable
(4), 1};
;
4012 case BuiltinType::SveUint32:
4013 return SVE_INT_ELTTY(32, 4, false, 1){getIntTypeForBitwidth(32, false), llvm::ElementCount::getScalable
(4), 1};
;
4014 case BuiltinType::SveInt32x2:
4015 return SVE_INT_ELTTY(32, 4, true, 2){getIntTypeForBitwidth(32, true), llvm::ElementCount::getScalable
(4), 2};
;
4016 case BuiltinType::SveUint32x2:
4017 return SVE_INT_ELTTY(32, 4, false, 2){getIntTypeForBitwidth(32, false), llvm::ElementCount::getScalable
(4), 2};
;
4018 case BuiltinType::SveInt32x3:
4019 return SVE_INT_ELTTY(32, 4, true, 3){getIntTypeForBitwidth(32, true), llvm::ElementCount::getScalable
(4), 3};
;
4020 case BuiltinType::SveUint32x3:
4021 return SVE_INT_ELTTY(32, 4, false, 3){getIntTypeForBitwidth(32, false), llvm::ElementCount::getScalable
(4), 3};
;
4022 case BuiltinType::SveInt32x4:
4023 return SVE_INT_ELTTY(32, 4, true, 4){getIntTypeForBitwidth(32, true), llvm::ElementCount::getScalable
(4), 4};
;
4024 case BuiltinType::SveUint32x4:
4025 return SVE_INT_ELTTY(32, 4, false, 4){getIntTypeForBitwidth(32, false), llvm::ElementCount::getScalable
(4), 4};
;
4026 case BuiltinType::SveInt64:
4027 return SVE_INT_ELTTY(64, 2, true, 1){getIntTypeForBitwidth(64, true), llvm::ElementCount::getScalable
(2), 1};
;
4028 case BuiltinType::SveUint64:
4029 return SVE_INT_ELTTY(64, 2, false, 1){getIntTypeForBitwidth(64, false), llvm::ElementCount::getScalable
(2), 1};
;
4030 case BuiltinType::SveInt64x2:
4031 return SVE_INT_ELTTY(64, 2, true, 2){getIntTypeForBitwidth(64, true), llvm::ElementCount::getScalable
(2), 2};
;
4032 case BuiltinType::SveUint64x2:
4033 return SVE_INT_ELTTY(64, 2, false, 2){getIntTypeForBitwidth(64, false), llvm::ElementCount::getScalable
(2), 2};
;
4034 case BuiltinType::SveInt64x3:
4035 return SVE_INT_ELTTY(64, 2, true, 3){getIntTypeForBitwidth(64, true), llvm::ElementCount::getScalable
(2), 3};
;
4036 case BuiltinType::SveUint64x3:
4037 return SVE_INT_ELTTY(64, 2, false, 3){getIntTypeForBitwidth(64, false), llvm::ElementCount::getScalable
(2), 3};
;
4038 case BuiltinType::SveInt64x4:
4039 return SVE_INT_ELTTY(64, 2, true, 4){getIntTypeForBitwidth(64, true), llvm::ElementCount::getScalable
(2), 4};
;
4040 case BuiltinType::SveUint64x4:
4041 return SVE_INT_ELTTY(64, 2, false, 4){getIntTypeForBitwidth(64, false), llvm::ElementCount::getScalable
(2), 4};
;
4042 case BuiltinType::SveBool:
4043 return SVE_ELTTY(BoolTy, 16, 1){BoolTy, llvm::ElementCount::getScalable(16), 1};;
4044 case BuiltinType::SveBoolx2:
4045 return SVE_ELTTY(BoolTy, 16, 2){BoolTy, llvm::ElementCount::getScalable(16), 2};;
4046 case BuiltinType::SveBoolx4:
4047 return SVE_ELTTY(BoolTy, 16, 4){BoolTy, llvm::ElementCount::getScalable(16), 4};;
4048 case BuiltinType::SveFloat16:
4049 return SVE_ELTTY(HalfTy, 8, 1){HalfTy, llvm::ElementCount::getScalable(8), 1};;
4050 case BuiltinType::SveFloat16x2:
4051 return SVE_ELTTY(HalfTy, 8, 2){HalfTy, llvm::ElementCount::getScalable(8), 2};;
4052 case BuiltinType::SveFloat16x3:
4053 return SVE_ELTTY(HalfTy, 8, 3){HalfTy, llvm::ElementCount::getScalable(8), 3};;
4054 case BuiltinType::SveFloat16x4:
4055 return SVE_ELTTY(HalfTy, 8, 4){HalfTy, llvm::ElementCount::getScalable(8), 4};;
4056 case BuiltinType::SveFloat32:
4057 return SVE_ELTTY(FloatTy, 4, 1){FloatTy, llvm::ElementCount::getScalable(4), 1};;
4058 case BuiltinType::SveFloat32x2:
4059 return SVE_ELTTY(FloatTy, 4, 2){FloatTy, llvm::ElementCount::getScalable(4), 2};;
4060 case BuiltinType::SveFloat32x3:
4061 return SVE_ELTTY(FloatTy, 4, 3){FloatTy, llvm::ElementCount::getScalable(4), 3};;
4062 case BuiltinType::SveFloat32x4:
4063 return SVE_ELTTY(FloatTy, 4, 4){FloatTy, llvm::ElementCount::getScalable(4), 4};;
4064 case BuiltinType::SveFloat64:
4065 return SVE_ELTTY(DoubleTy, 2, 1){DoubleTy, llvm::ElementCount::getScalable(2), 1};;
4066 case BuiltinType::SveFloat64x2:
4067 return SVE_ELTTY(DoubleTy, 2, 2){DoubleTy, llvm::ElementCount::getScalable(2), 2};;
4068 case BuiltinType::SveFloat64x3:
4069 return SVE_ELTTY(DoubleTy, 2, 3){DoubleTy, llvm::ElementCount::getScalable(2), 3};;
4070 case BuiltinType::SveFloat64x4:
4071 return SVE_ELTTY(DoubleTy, 2, 4){DoubleTy, llvm::ElementCount::getScalable(2), 4};;
4072 case BuiltinType::SveBFloat16:
4073 return SVE_ELTTY(BFloat16Ty, 8, 1){BFloat16Ty, llvm::ElementCount::getScalable(8), 1};;
4074 case BuiltinType::SveBFloat16x2:
4075 return SVE_ELTTY(BFloat16Ty, 8, 2){BFloat16Ty, llvm::ElementCount::getScalable(8), 2};;
4076 case BuiltinType::SveBFloat16x3:
4077 return SVE_ELTTY(BFloat16Ty, 8, 3){BFloat16Ty, llvm::ElementCount::getScalable(8), 3};;
4078 case BuiltinType::SveBFloat16x4:
4079 return SVE_ELTTY(BFloat16Ty, 8, 4){BFloat16Ty, llvm::ElementCount::getScalable(8), 4};;
4080#define RVV_VECTOR_TYPE_INT(Name, Id, SingletonId, NumEls, ElBits, NF, \
4081 IsSigned) \
4082 case BuiltinType::Id: \
4083 return {getIntTypeForBitwidth(ElBits, IsSigned), \
4084 llvm::ElementCount::getScalable(NumEls), NF};
4085#define RVV_VECTOR_TYPE_FLOAT(Name, Id, SingletonId, NumEls, ElBits, NF) \
4086 case BuiltinType::Id: \
4087 return {ElBits == 16 ? Float16Ty : (ElBits == 32 ? FloatTy : DoubleTy), \
4088 llvm::ElementCount::getScalable(NumEls), NF};
4089#define RVV_PREDICATE_TYPE(Name, Id, SingletonId, NumEls) \
4090 case BuiltinType::Id: \
4091 return {BoolTy, llvm::ElementCount::getScalable(NumEls), 1};
4092#include "clang/Basic/RISCVVTypes.def"
4093 }
4094}
4095
4096/// getExternrefType - Return a WebAssembly externref type, which represents an
4097/// opaque reference to a host value.
4098QualType ASTContext::getWebAssemblyExternrefType() const {
4099 if (Target->getTriple().isWasm() && Target->hasFeature("reference-types")) {
4100#define WASM_REF_TYPE(Name, MangledName, Id, SingletonId, AS) \
4101 if (BuiltinType::Id == BuiltinType::WasmExternRef) \
4102 return SingletonId;
4103#include "clang/Basic/WebAssemblyReferenceTypes.def"
4104 }
4105 llvm_unreachable(::llvm::llvm_unreachable_internal("shouldn't try to generate type externref outside WebAssembly target"
, "clang/lib/AST/ASTContext.cpp", 4106)
4106 "shouldn't try to generate type externref outside WebAssembly target")::llvm::llvm_unreachable_internal("shouldn't try to generate type externref outside WebAssembly target"
, "clang/lib/AST/ASTContext.cpp", 4106)
;
4107}
4108
4109/// getScalableVectorType - Return the unique reference to a scalable vector
4110/// type of the specified element type and size. VectorType must be a built-in
4111/// type.
4112QualType ASTContext::getScalableVectorType(QualType EltTy,
4113 unsigned NumElts) const {
4114 if (Target->hasAArch64SVETypes()) {
4115 uint64_t EltTySize = getTypeSize(EltTy);
4116#define SVE_VECTOR_TYPE(Name, MangledName, Id, SingletonId, NumEls, ElBits, \
4117 IsSigned, IsFP, IsBF) \
4118 if (!EltTy->isBooleanType() && \
4119 ((EltTy->hasIntegerRepresentation() && \
4120 EltTy->hasSignedIntegerRepresentation() == IsSigned) || \
4121 (EltTy->hasFloatingRepresentation() && !EltTy->isBFloat16Type() && \
4122 IsFP && !IsBF) || \
4123 (EltTy->hasFloatingRepresentation() && EltTy->isBFloat16Type() && \
4124 IsBF && !IsFP)) && \
4125 EltTySize == ElBits && NumElts == NumEls) { \
4126 return SingletonId; \
4127 }
4128#define SVE_PREDICATE_TYPE(Name, MangledName, Id, SingletonId, NumEls) \
4129 if (EltTy->isBooleanType() && NumElts == NumEls) \
4130 return SingletonId;
4131#define SVE_OPAQUE_TYPE(Name, MangledName, Id, SingleTonId)
4132#include "clang/Basic/AArch64SVEACLETypes.def"
4133 } else if (Target->hasRISCVVTypes()) {
4134 uint64_t EltTySize = getTypeSize(EltTy);
4135#define RVV_VECTOR_TYPE(Name, Id, SingletonId, NumEls, ElBits, NF, IsSigned, \
4136 IsFP) \
4137 if (!EltTy->isBooleanType() && \
4138 ((EltTy->hasIntegerRepresentation() && \
4139 EltTy->hasSignedIntegerRepresentation() == IsSigned) || \
4140 (EltTy->hasFloatingRepresentation() && IsFP)) && \
4141 EltTySize == ElBits && NumElts == NumEls) \
4142 return SingletonId;
4143#define RVV_PREDICATE_TYPE(Name, Id, SingletonId, NumEls) \
4144 if (EltTy->isBooleanType() && NumElts == NumEls) \
4145 return SingletonId;
4146#include "clang/Basic/RISCVVTypes.def"
4147 }
4148 return QualType();
4149}
4150
4151/// getVectorType - Return the unique reference to a vector type of
4152/// the specified element type and size. VectorType must be a built-in type.
4153QualType ASTContext::getVectorType(QualType vecType, unsigned NumElts,
4154 VectorType::VectorKind VecKind) const {
4155 assert(vecType->isBuiltinType() ||(static_cast <bool> (vecType->isBuiltinType() || (vecType
->isBitIntType() && llvm::isPowerOf2_32(vecType->
getAs<BitIntType>()->getNumBits()) && vecType
->getAs<BitIntType>()->getNumBits() >= 8)) ? void
(0) : __assert_fail ("vecType->isBuiltinType() || (vecType->isBitIntType() && llvm::isPowerOf2_32(vecType->getAs<BitIntType>()->getNumBits()) && vecType->getAs<BitIntType>()->getNumBits() >= 8)"
, "clang/lib/AST/ASTContext.cpp", 4159, __extension__ __PRETTY_FUNCTION__
))
4156 (vecType->isBitIntType() &&(static_cast <bool> (vecType->isBuiltinType() || (vecType
->isBitIntType() && llvm::isPowerOf2_32(vecType->
getAs<BitIntType>()->getNumBits()) && vecType
->getAs<BitIntType>()->getNumBits() >= 8)) ? void
(0) : __assert_fail ("vecType->isBuiltinType() || (vecType->isBitIntType() && llvm::isPowerOf2_32(vecType->getAs<BitIntType>()->getNumBits()) && vecType->getAs<BitIntType>()->getNumBits() >= 8)"
, "clang/lib/AST/ASTContext.cpp", 4159, __extension__ __PRETTY_FUNCTION__
))
4157 // Only support _BitInt elements with byte-sized power of 2 NumBits.(static_cast <bool> (vecType->isBuiltinType() || (vecType
->isBitIntType() && llvm::isPowerOf2_32(vecType->
getAs<BitIntType>()->getNumBits()) && vecType
->getAs<BitIntType>()->getNumBits() >= 8)) ? void
(0) : __assert_fail ("vecType->isBuiltinType() || (vecType->isBitIntType() && llvm::isPowerOf2_32(vecType->getAs<BitIntType>()->getNumBits()) && vecType->getAs<BitIntType>()->getNumBits() >= 8)"
, "clang/lib/AST/ASTContext.cpp", 4159, __extension__ __PRETTY_FUNCTION__
))
4158 llvm::isPowerOf2_32(vecType->getAs<BitIntType>()->getNumBits()) &&(static_cast <bool> (vecType->isBuiltinType() || (vecType
->isBitIntType() && llvm::isPowerOf2_32(vecType->
getAs<BitIntType>()->getNumBits()) && vecType
->getAs<BitIntType>()->getNumBits() >= 8)) ? void
(0) : __assert_fail ("vecType->isBuiltinType() || (vecType->isBitIntType() && llvm::isPowerOf2_32(vecType->getAs<BitIntType>()->getNumBits()) && vecType->getAs<BitIntType>()->getNumBits() >= 8)"
, "clang/lib/AST/ASTContext.cpp", 4159, __extension__ __PRETTY_FUNCTION__
))
4159 vecType->getAs<BitIntType>()->getNumBits() >= 8))(static_cast <bool> (vecType->isBuiltinType() || (vecType
->isBitIntType() && llvm::isPowerOf2_32(vecType->
getAs<BitIntType>()->getNumBits()) && vecType
->getAs<BitIntType>()->getNumBits() >= 8)) ? void
(0) : __assert_fail ("vecType->isBuiltinType() || (vecType->isBitIntType() && llvm::isPowerOf2_32(vecType->getAs<BitIntType>()->getNumBits()) && vecType->getAs<BitIntType>()->getNumBits() >= 8)"
, "clang/lib/AST/ASTContext.cpp", 4159, __extension__ __PRETTY_FUNCTION__
))
;
4160
4161 // Check if we've already instantiated a vector of this type.
4162 llvm::FoldingSetNodeID ID;
4163 VectorType::Profile(ID, vecType, NumElts, Type::Vector, VecKind);
4164
4165 void *InsertPos = nullptr;
4166 if (VectorType *VTP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos))
4167 return QualType(VTP, 0);
4168
4169 // If the element type isn't canonical, this won't be a canonical type either,
4170 // so fill in the canonical type field.
4171 QualType Canonical;
4172 if (!vecType.isCanonical()) {
4173 Canonical = getVectorType(getCanonicalType(vecType), NumElts, VecKind);
4174
4175 // Get the new insert position for the node we care about.
4176 VectorType *NewIP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos);
4177 assert(!NewIP && "Shouldn't be in the map!")(static_cast <bool> (!NewIP && "Shouldn't be in the map!"
) ? void (0) : __assert_fail ("!NewIP && \"Shouldn't be in the map!\""
, "clang/lib/AST/ASTContext.cpp", 4177, __extension__ __PRETTY_FUNCTION__
))
; (void)NewIP;
4178 }
4179 auto *New = new (*this, TypeAlignment)
4180 VectorType(vecType, NumElts, Canonical, VecKind);
4181 VectorTypes.InsertNode(New, InsertPos);
4182 Types.push_back(New);
4183 return QualType(New, 0);
4184}
4185
4186QualType
4187ASTContext::getDependentVectorType(QualType VecType, Expr *SizeExpr,
4188 SourceLocation AttrLoc,
4189 VectorType::VectorKind VecKind) const {
4190 llvm::FoldingSetNodeID ID;
4191 DependentVectorType::Profile(ID, *this, getCanonicalType(VecType), SizeExpr,
4192 VecKind);
4193 void *InsertPos = nullptr;
4194 DependentVectorType *Canon =
4195 DependentVectorTypes.FindNodeOrInsertPos(ID, InsertPos);
4196 DependentVectorType *New;
4197
4198 if (Canon) {
4199 New = new (*this, TypeAlignment) DependentVectorType(
4200 *this, VecType, QualType(Canon, 0), SizeExpr, AttrLoc, VecKind);
4201 } else {
4202 QualType CanonVecTy = getCanonicalType(VecType);
4203 if (CanonVecTy == VecType) {
4204 New = new (*this, TypeAlignment) DependentVectorType(
4205 *this, VecType, QualType(), SizeExpr, AttrLoc, VecKind);
4206
4207 DependentVectorType *CanonCheck =
4208 DependentVectorTypes.FindNodeOrInsertPos(ID, InsertPos);
4209 assert(!CanonCheck &&(static_cast <bool> (!CanonCheck && "Dependent-sized vector_size canonical type broken"
) ? void (0) : __assert_fail ("!CanonCheck && \"Dependent-sized vector_size canonical type broken\""
, "clang/lib/AST/ASTContext.cpp", 4210, __extension__ __PRETTY_FUNCTION__
))
4210 "Dependent-sized vector_size canonical type broken")(static_cast <bool> (!CanonCheck && "Dependent-sized vector_size canonical type broken"
) ? void (0) : __assert_fail ("!CanonCheck && \"Dependent-sized vector_size canonical type broken\""
, "clang/lib/AST/ASTContext.cpp", 4210, __extension__ __PRETTY_FUNCTION__
))
;
4211 (void)CanonCheck;
4212 DependentVectorTypes.InsertNode(New, InsertPos);
4213 } else {
4214 QualType CanonTy = getDependentVectorType(CanonVecTy, SizeExpr,
4215 SourceLocation(), VecKind);
4216 New = new (*this, TypeAlignment) DependentVectorType(
4217 *this, VecType, CanonTy, SizeExpr, AttrLoc, VecKind);
4218 }
4219 }
4220
4221 Types.push_back(New);
4222 return QualType(New, 0);
4223}
4224
4225/// getExtVectorType - Return the unique reference to an extended vector type of
4226/// the specified element type and size. VectorType must be a built-in type.
4227QualType ASTContext::getExtVectorType(QualType vecType,
4228 unsigned NumElts) const {
4229 assert(vecType->isBuiltinType() || vecType->isDependentType() ||(static_cast <bool> (vecType->isBuiltinType() || vecType
->isDependentType() || (vecType->isBitIntType() &&
llvm::isPowerOf2_32(vecType->getAs<BitIntType>()->
getNumBits()) && vecType->getAs<BitIntType>(
)->getNumBits() >= 8)) ? void (0) : __assert_fail ("vecType->isBuiltinType() || vecType->isDependentType() || (vecType->isBitIntType() && llvm::isPowerOf2_32(vecType->getAs<BitIntType>()->getNumBits()) && vecType->getAs<BitIntType>()->getNumBits() >= 8)"
, "clang/lib/AST/ASTContext.cpp", 4233, __extension__ __PRETTY_FUNCTION__
))
4230 (vecType->isBitIntType() &&(static_cast <bool> (vecType->isBuiltinType() || vecType
->isDependentType() || (vecType->isBitIntType() &&
llvm::isPowerOf2_32(vecType->getAs<BitIntType>()->
getNumBits()) && vecType->getAs<BitIntType>(
)->getNumBits() >= 8)) ? void (0) : __assert_fail ("vecType->isBuiltinType() || vecType->isDependentType() || (vecType->isBitIntType() && llvm::isPowerOf2_32(vecType->getAs<BitIntType>()->getNumBits()) && vecType->getAs<BitIntType>()->getNumBits() >= 8)"
, "clang/lib/AST/ASTContext.cpp", 4233, __extension__ __PRETTY_FUNCTION__
))
4231 // Only support _BitInt elements with byte-sized power of 2 NumBits.(static_cast <bool> (vecType->isBuiltinType() || vecType
->isDependentType() || (vecType->isBitIntType() &&
llvm::isPowerOf2_32(vecType->getAs<BitIntType>()->
getNumBits()) && vecType->getAs<BitIntType>(
)->getNumBits() >= 8)) ? void (0) : __assert_fail ("vecType->isBuiltinType() || vecType->isDependentType() || (vecType->isBitIntType() && llvm::isPowerOf2_32(vecType->getAs<BitIntType>()->getNumBits()) && vecType->getAs<BitIntType>()->getNumBits() >= 8)"
, "clang/lib/AST/ASTContext.cpp", 4233, __extension__ __PRETTY_FUNCTION__
))
4232 llvm::isPowerOf2_32(vecType->getAs<BitIntType>()->getNumBits()) &&(static_cast <bool> (vecType->isBuiltinType() || vecType
->isDependentType() || (vecType->isBitIntType() &&
llvm::isPowerOf2_32(vecType->getAs<BitIntType>()->
getNumBits()) && vecType->getAs<BitIntType>(
)->getNumBits() >= 8)) ? void (0) : __assert_fail ("vecType->isBuiltinType() || vecType->isDependentType() || (vecType->isBitIntType() && llvm::isPowerOf2_32(vecType->getAs<BitIntType>()->getNumBits()) && vecType->getAs<BitIntType>()->getNumBits() >= 8)"
, "clang/lib/AST/ASTContext.cpp", 4233, __extension__ __PRETTY_FUNCTION__
))
4233 vecType->getAs<BitIntType>()->getNumBits() >= 8))(static_cast <bool> (vecType->isBuiltinType() || vecType
->isDependentType() || (vecType->isBitIntType() &&
llvm::isPowerOf2_32(vecType->getAs<BitIntType>()->
getNumBits()) && vecType->getAs<BitIntType>(
)->getNumBits() >= 8)) ? void (0) : __assert_fail ("vecType->isBuiltinType() || vecType->isDependentType() || (vecType->isBitIntType() && llvm::isPowerOf2_32(vecType->getAs<BitIntType>()->getNumBits()) && vecType->getAs<BitIntType>()->getNumBits() >= 8)"
, "clang/lib/AST/ASTContext.cpp", 4233, __extension__ __PRETTY_FUNCTION__
))
;
4234
4235 // Check if we've already instantiated a vector of this type.
4236 llvm::FoldingSetNodeID ID;
4237 VectorType::Profile(ID, vecType, NumElts, Type::ExtVector,
4238 VectorType::GenericVector);
4239 void *InsertPos = nullptr;
4240 if (VectorType *VTP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos))
4241 return QualType(VTP, 0);
4242
4243 // If the element type isn't canonical, this won't be a canonical type either,
4244 // so fill in the canonical type field.
4245 QualType Canonical;
4246 if (!vecType.isCanonical()) {
4247 Canonical = getExtVectorType(getCanonicalType(vecType), NumElts);
4248
4249 // Get the new insert position for the node we care about.
4250 VectorType *NewIP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos);
4251 assert(!NewIP && "Shouldn't be in the map!")(static_cast <bool> (!NewIP && "Shouldn't be in the map!"
) ? void (0) : __assert_fail ("!NewIP && \"Shouldn't be in the map!\""
, "clang/lib/AST/ASTContext.cpp", 4251, __extension__ __PRETTY_FUNCTION__
))
; (void)NewIP;
4252 }
4253 auto *New = new (*this, TypeAlignment)
4254 ExtVectorType(vecType, NumElts, Canonical);
4255 VectorTypes.InsertNode(New, InsertPos);
4256 Types.push_back(New);
4257 return QualType(New, 0);
4258}
4259
4260QualType
4261ASTContext::getDependentSizedExtVectorType(QualType vecType,
4262 Expr *SizeExpr,
4263 SourceLocation AttrLoc) const {
4264 llvm::FoldingSetNodeID ID;
4265 DependentSizedExtVectorType::Profile(ID, *this, getCanonicalType(vecType),
4266 SizeExpr);
4267
4268 void *InsertPos = nullptr;
4269 DependentSizedExtVectorType *Canon
4270 = DependentSizedExtVectorTypes.FindNodeOrInsertPos(ID, InsertPos);
4271 DependentSizedExtVectorType *New;
4272 if (Canon) {
4273 // We already have a canonical version of this array type; use it as
4274 // the canonical type for a newly-built type.
4275 New = new (*this, TypeAlignment)
4276 DependentSizedExtVectorType(*this, vecType, QualType(Canon, 0),
4277 SizeExpr, AttrLoc);
4278 } else {
4279 QualType CanonVecTy = getCanonicalType(vecType);
4280 if (CanonVecTy == vecType) {
4281 New = new (*this, TypeAlignment)
4282 DependentSizedExtVectorType(*this, vecType, QualType(), SizeExpr,
4283 AttrLoc);
4284
4285 DependentSizedExtVectorType *CanonCheck
4286 = DependentSizedExtVectorTypes.FindNodeOrInsertPos(ID, InsertPos);
4287 assert(!CanonCheck && "Dependent-sized ext_vector canonical type broken")(static_cast <bool> (!CanonCheck && "Dependent-sized ext_vector canonical type broken"
) ? void (0) : __assert_fail ("!CanonCheck && \"Dependent-sized ext_vector canonical type broken\""
, "clang/lib/AST/ASTContext.cpp", 4287, __extension__ __PRETTY_FUNCTION__
))
;
4288 (void)CanonCheck;
4289 DependentSizedExtVectorTypes.InsertNode(New, InsertPos);
4290 } else {
4291 QualType CanonExtTy = getDependentSizedExtVectorType(CanonVecTy, SizeExpr,
4292 SourceLocation());
4293 New = new (*this, TypeAlignment) DependentSizedExtVectorType(
4294 *this, vecType, CanonExtTy, SizeExpr, AttrLoc);
4295 }
4296 }
4297
4298 Types.push_back(New);
4299 return QualType(New, 0);
4300}
4301
4302QualType ASTContext::getConstantMatrixType(QualType ElementTy, unsigned NumRows,
4303 unsigned NumColumns) const {
4304 llvm::FoldingSetNodeID ID;
4305 ConstantMatrixType::Profile(ID, ElementTy, NumRows, NumColumns,
4306 Type::ConstantMatrix);
4307
4308 assert(MatrixType::isValidElementType(ElementTy) &&(static_cast <bool> (MatrixType::isValidElementType(ElementTy
) && "need a valid element type") ? void (0) : __assert_fail
("MatrixType::isValidElementType(ElementTy) && \"need a valid element type\""
, "clang/lib/AST/ASTContext.cpp", 4309, __extension__ __PRETTY_FUNCTION__
))
4309 "need a valid element type")(static_cast <bool> (MatrixType::isValidElementType(ElementTy
) && "need a valid element type") ? void (0) : __assert_fail
("MatrixType::isValidElementType(ElementTy) && \"need a valid element type\""
, "clang/lib/AST/ASTContext.cpp", 4309, __extension__ __PRETTY_FUNCTION__
))
;
4310 assert(ConstantMatrixType::isDimensionValid(NumRows) &&(static_cast <bool> (ConstantMatrixType::isDimensionValid
(NumRows) && ConstantMatrixType::isDimensionValid(NumColumns
) && "need valid matrix dimensions") ? void (0) : __assert_fail
("ConstantMatrixType::isDimensionValid(NumRows) && ConstantMatrixType::isDimensionValid(NumColumns) && \"need valid matrix dimensions\""
, "clang/lib/AST/ASTContext.cpp", 4312, __extension__ __PRETTY_FUNCTION__
))
4311 ConstantMatrixType::isDimensionValid(NumColumns) &&(static_cast <bool> (ConstantMatrixType::isDimensionValid
(NumRows) && ConstantMatrixType::isDimensionValid(NumColumns
) && "need valid matrix dimensions") ? void (0) : __assert_fail
("ConstantMatrixType::isDimensionValid(NumRows) && ConstantMatrixType::isDimensionValid(NumColumns) && \"need valid matrix dimensions\""
, "clang/lib/AST/ASTContext.cpp", 4312, __extension__ __PRETTY_FUNCTION__
))
4312 "need valid matrix dimensions")(static_cast <bool> (ConstantMatrixType::isDimensionValid
(NumRows) && ConstantMatrixType::isDimensionValid(NumColumns
) && "need valid matrix dimensions") ? void (0) : __assert_fail
("ConstantMatrixType::isDimensionValid(NumRows) && ConstantMatrixType::isDimensionValid(NumColumns) && \"need valid matrix dimensions\""
, "clang/lib/AST/ASTContext.cpp", 4312, __extension__ __PRETTY_FUNCTION__
))
;
4313 void *InsertPos = nullptr;
4314 if (ConstantMatrixType *MTP = MatrixTypes.FindNodeOrInsertPos(ID, InsertPos))
4315 return QualType(MTP, 0);
4316
4317 QualType Canonical;
4318 if (!ElementTy.isCanonical()) {
4319 Canonical =
4320 getConstantMatrixType(getCanonicalType(ElementTy), NumRows, NumColumns);
4321
4322 ConstantMatrixType *NewIP = MatrixTypes.FindNodeOrInsertPos(ID, InsertPos);
4323 assert(!NewIP && "Matrix type shouldn't already exist in the map")(static_cast <bool> (!NewIP && "Matrix type shouldn't already exist in the map"
) ? void (0) : __assert_fail ("!NewIP && \"Matrix type shouldn't already exist in the map\""
, "clang/lib/AST/ASTContext.cpp", 4323, __extension__ __PRETTY_FUNCTION__
))
;
4324 (void)NewIP;
4325 }
4326
4327 auto *New = new (*this, TypeAlignment)
4328 ConstantMatrixType(ElementTy, NumRows, NumColumns, Canonical);
4329 MatrixTypes.InsertNode(New, InsertPos);
4330 Types.push_back(New);
4331 return QualType(New, 0);
4332}
4333
4334QualType ASTContext::getDependentSizedMatrixType(QualType ElementTy,
4335 Expr *RowExpr,
4336 Expr *ColumnExpr,
4337 SourceLocation AttrLoc) const {
4338 QualType CanonElementTy = getCanonicalType(ElementTy);
4339 llvm::FoldingSetNodeID ID;
4340 DependentSizedMatrixType::Profile(ID, *this, CanonElementTy, RowExpr,
4341 ColumnExpr);
4342
4343 void *InsertPos = nullptr;
4344 DependentSizedMatrixType *Canon =
4345 DependentSizedMatrixTypes.FindNodeOrInsertPos(ID, InsertPos);
4346
4347 if (!Canon) {
4348 Canon = new (*this, TypeAlignment) DependentSizedMatrixType(
4349 *this, CanonElementTy, QualType(), RowExpr, ColumnExpr, AttrLoc);
4350#ifndef NDEBUG
4351 DependentSizedMatrixType *CanonCheck =
4352 DependentSizedMatrixTypes.FindNodeOrInsertPos(ID, InsertPos);
4353 assert(!CanonCheck && "Dependent-sized matrix canonical type broken")(static_cast <bool> (!CanonCheck && "Dependent-sized matrix canonical type broken"
) ? void (0) : __assert_fail ("!CanonCheck && \"Dependent-sized matrix canonical type broken\""
, "clang/lib/AST/ASTContext.cpp", 4353, __extension__ __PRETTY_FUNCTION__
))
;
4354#endif
4355 DependentSizedMatrixTypes.InsertNode(Canon, InsertPos);
4356 Types.push_back(Canon);
4357 }
4358
4359 // Already have a canonical version of the matrix type
4360 //
4361 // If it exactly matches the requested type, use it directly.
4362 if (Canon->getElementType() == ElementTy && Canon->getRowExpr() == RowExpr &&
4363 Canon->getRowExpr() == ColumnExpr)
4364 return QualType(Canon, 0);
4365
4366 // Use Canon as the canonical type for newly-built type.
4367 DependentSizedMatrixType *New = new (*this, TypeAlignment)
4368 DependentSizedMatrixType(*this, ElementTy, QualType(Canon, 0), RowExpr,
4369 ColumnExpr, AttrLoc);
4370 Types.push_back(New);
4371 return QualType(New, 0);
4372}
4373
4374QualType ASTContext::getDependentAddressSpaceType(QualType PointeeType,
4375 Expr *AddrSpaceExpr,
4376 SourceLocation AttrLoc) const {
4377 assert(AddrSpaceExpr->isInstantiationDependent())(static_cast <bool> (AddrSpaceExpr->isInstantiationDependent
()) ? void (0) : __assert_fail ("AddrSpaceExpr->isInstantiationDependent()"
, "clang/lib/AST/ASTContext.cpp", 4377, __extension__ __PRETTY_FUNCTION__
))
;
4378
4379 QualType canonPointeeType = getCanonicalType(PointeeType);
4380
4381 void *insertPos = nullptr;
4382 llvm::FoldingSetNodeID ID;
4383 DependentAddressSpaceType::Profile(ID, *this, canonPointeeType,
4384 AddrSpaceExpr);
4385
4386 DependentAddressSpaceType *canonTy =
4387 DependentAddressSpaceTypes.FindNodeOrInsertPos(ID, insertPos);
4388
4389 if (!canonTy) {
4390 canonTy = new (*this, TypeAlignment)
4391 DependentAddressSpaceType(*this, canonPointeeType,
4392 QualType(), AddrSpaceExpr, AttrLoc);
4393 DependentAddressSpaceTypes.InsertNode(canonTy, insertPos);
4394 Types.push_back(canonTy);
4395 }
4396
4397 if (canonPointeeType == PointeeType &&
4398 canonTy->getAddrSpaceExpr() == AddrSpaceExpr)
4399 return QualType(canonTy, 0);
4400
4401 auto *sugaredType
4402 = new (*this, TypeAlignment)
4403 DependentAddressSpaceType(*this, PointeeType, QualType(canonTy, 0),
4404 AddrSpaceExpr, AttrLoc);
4405 Types.push_back(sugaredType);
4406 return QualType(sugaredType, 0);
4407}
4408
4409/// Determine whether \p T is canonical as the result type of a function.
4410static bool isCanonicalResultType(QualType T) {
4411 return T.isCanonical() &&
4412 (T.getObjCLifetime() == Qualifiers::OCL_None ||
4413 T.getObjCLifetime() == Qualifiers::OCL_ExplicitNone);
4414}
4415
4416/// getFunctionNoProtoType - Return a K&R style C function type like 'int()'.
4417QualType
4418ASTContext::getFunctionNoProtoType(QualType ResultTy,
4419 const FunctionType::ExtInfo &Info) const {
4420 // FIXME: This assertion cannot be enabled (yet) because the ObjC rewriter
4421 // functionality creates a function without a prototype regardless of
4422 // language mode (so it makes them even in C++). Once the rewriter has been
4423 // fixed, this assertion can be enabled again.
4424 //assert(!LangOpts.requiresStrictPrototypes() &&
4425 // "strict prototypes are disabled");
4426
4427 // Unique functions, to guarantee there is only one function of a particular
4428 // structure.
4429 llvm::FoldingSetNodeID ID;
4430 FunctionNoProtoType::Profile(ID, ResultTy, Info);
4431
4432 void *InsertPos = nullptr;
4433 if (FunctionNoProtoType *FT =
4434 FunctionNoProtoTypes.FindNodeOrInsertPos(ID, InsertPos))
4435 return QualType(FT, 0);
4436
4437 QualType Canonical;
4438 if (!isCanonicalResultType(ResultTy)) {
4439 Canonical =
4440 getFunctionNoProtoType(getCanonicalFunctionResultType(ResultTy), Info);
4441
4442 // Get the new insert position for the node we care about.
4443 FunctionNoProtoType *NewIP =
4444 FunctionNoProtoTypes.FindNodeOrInsertPos(ID, InsertPos);
4445 assert(!NewIP && "Shouldn't be in the map!")(static_cast <bool> (!NewIP && "Shouldn't be in the map!"
) ? void (0) : __assert_fail ("!NewIP && \"Shouldn't be in the map!\""
, "clang/lib/AST/ASTContext.cpp", 4445, __extension__ __PRETTY_FUNCTION__
))
; (void)NewIP;
4446 }
4447
4448 auto *New = new (*this, TypeAlignment)
4449 FunctionNoProtoType(ResultTy, Canonical, Info);
4450 Types.push_back(New);
4451 FunctionNoProtoTypes.InsertNode(New, InsertPos);
4452 return QualType(New, 0);
4453}
4454
4455CanQualType
4456ASTContext::getCanonicalFunctionResultType(QualType ResultType) const {
4457 CanQualType CanResultType = getCanonicalType(ResultType);
4458
4459 // Canonical result types do not have ARC lifetime qualifiers.
4460 if (CanResultType.getQualifiers().hasObjCLifetime()) {
4461 Qualifiers Qs = CanResultType.getQualifiers();
4462 Qs.removeObjCLifetime();
4463 return CanQualType::CreateUnsafe(
4464 getQualifiedType(CanResultType.getUnqualifiedType(), Qs));
4465 }
4466
4467 return CanResultType;
4468}
4469
4470static bool isCanonicalExceptionSpecification(
4471 const FunctionProtoType::ExceptionSpecInfo &ESI, bool NoexceptInType) {
4472 if (ESI.Type == EST_None)
4473 return true;
4474 if (!NoexceptInType)
4475 return false;
4476
4477 // C++17 onwards: exception specification is part of the type, as a simple
4478 // boolean "can this function type throw".
4479 if (ESI.Type == EST_BasicNoexcept)
4480 return true;
4481
4482 // A noexcept(expr) specification is (possibly) canonical if expr is
4483 // value-dependent.
4484 if (ESI.Type == EST_DependentNoexcept)
4485 return true;
4486
4487 // A dynamic exception specification is canonical if it only contains pack
4488 // expansions (so we can't tell whether it's non-throwing) and all its
4489 // contained types are canonical.
4490 if (ESI.Type == EST_Dynamic) {
4491 bool AnyPackExpansions = false;
4492 for (QualType ET : ESI.Exceptions) {
4493 if (!ET.isCanonical())
4494 return false;
4495 if (ET->getAs<PackExpansionType>())
4496 AnyPackExpansions = true;
4497 }
4498 return AnyPackExpansions;
4499 }
4500
4501 return false;
4502}
4503
4504QualType ASTContext::getFunctionTypeInternal(
4505 QualType ResultTy, ArrayRef<QualType> ArgArray,
4506 const FunctionProtoType::ExtProtoInfo &EPI, bool OnlyWantCanonical) const {
4507 size_t NumArgs = ArgArray.size();
4508
4509 // Unique functions, to guarantee there is only one function of a particular
4510 // structure.
4511 llvm::FoldingSetNodeID ID;
4512 FunctionProtoType::Profile(ID, ResultTy, ArgArray.begin(), NumArgs, EPI,
4513 *this, true);
4514
4515 QualType Canonical;
4516 bool Unique = false;
4517
4518 void *InsertPos = nullptr;
4519 if (FunctionProtoType *FPT =
4520 FunctionProtoTypes.FindNodeOrInsertPos(ID, InsertPos)) {
4521 QualType Existing = QualType(FPT, 0);
4522
4523 // If we find a pre-existing equivalent FunctionProtoType, we can just reuse
4524 // it so long as our exception specification doesn't contain a dependent
4525 // noexcept expression, or we're just looking for a canonical type.
4526 // Otherwise, we're going to need to create a type
4527 // sugar node to hold the concrete expression.
4528 if (OnlyWantCanonical || !isComputedNoexcept(EPI.ExceptionSpec.Type) ||
4529 EPI.ExceptionSpec.NoexceptExpr == FPT->getNoexceptExpr())
4530 return Existing;
4531
4532 // We need a new type sugar node for this one, to hold the new noexcept
4533 // expression. We do no canonicalization here, but that's OK since we don't
4534 // expect to see the same noexcept expression much more than once.
4535 Canonical = getCanonicalType(Existing);
4536 Unique = true;
4537 }
4538
4539 bool NoexceptInType = getLangOpts().CPlusPlus17;
4540 bool IsCanonicalExceptionSpec =
4541 isCanonicalExceptionSpecification(EPI.ExceptionSpec, NoexceptInType);
4542
4543 // Determine whether the type being created is already canonical or not.
4544 bool isCanonical = !Unique && IsCanonicalExceptionSpec &&
4545 isCanonicalResultType(ResultTy) && !EPI.HasTrailingReturn;
4546 for (unsigned i = 0; i != NumArgs && isCanonical; ++i)
4547 if (!ArgArray[i].isCanonicalAsParam())
4548 isCanonical = false;
4549
4550 if (OnlyWantCanonical)
4551 assert(isCanonical &&(static_cast <bool> (isCanonical && "given non-canonical parameters constructing canonical type"
) ? void (0) : __assert_fail ("isCanonical && \"given non-canonical parameters constructing canonical type\""
, "clang/lib/AST/ASTContext.cpp", 4552, __extension__ __PRETTY_FUNCTION__
))
4552 "given non-canonical parameters constructing canonical type")(static_cast <bool> (isCanonical && "given non-canonical parameters constructing canonical type"
) ? void (0) : __assert_fail ("isCanonical && \"given non-canonical parameters constructing canonical type\""
, "clang/lib/AST/ASTContext.cpp", 4552, __extension__ __PRETTY_FUNCTION__
))
;
4553
4554 // If this type isn't canonical, get the canonical version of it if we don't
4555 // already have it. The exception spec is only partially part of the
4556 // canonical type, and only in C++17 onwards.
4557 if (!isCanonical && Canonical.isNull()) {
4558 SmallVector<QualType, 16> CanonicalArgs;
4559 CanonicalArgs.reserve(NumArgs);
4560 for (unsigned i = 0; i != NumArgs; ++i)
4561 CanonicalArgs.push_back(getCanonicalParamType(ArgArray[i]));
4562
4563 llvm::SmallVector<QualType, 8> ExceptionTypeStorage;
4564 FunctionProtoType::ExtProtoInfo CanonicalEPI = EPI;
4565 CanonicalEPI.HasTrailingReturn = false;
4566
4567 if (IsCanonicalExceptionSpec) {
4568 // Exception spec is already OK.
4569 } else if (NoexceptInType) {
4570 switch (EPI.ExceptionSpec.Type) {
4571 case EST_Unparsed: case EST_Unevaluated: case EST_Uninstantiated:
4572 // We don't know yet. It shouldn't matter what we pick here; no-one
4573 // should ever look at this.
4574 [[fallthrough]];
4575 case EST_None: case EST_MSAny: case EST_NoexceptFalse:
4576 CanonicalEPI.ExceptionSpec.Type = EST_None;
4577 break;
4578
4579 // A dynamic exception specification is almost always "not noexcept",
4580 // with the exception that a pack expansion might expand to no types.
4581 case EST_Dynamic: {
4582 bool AnyPacks = false;
4583 for (QualType ET : EPI.ExceptionSpec.Exceptions) {
4584 if (ET->getAs<PackExpansionType>())
4585 AnyPacks = true;
4586 ExceptionTypeStorage.push_back(getCanonicalType(ET));
4587 }
4588 if (!AnyPacks)
4589 CanonicalEPI.ExceptionSpec.Type = EST_None;
4590 else {
4591 CanonicalEPI.ExceptionSpec.Type = EST_Dynamic;
4592 CanonicalEPI.ExceptionSpec.Exceptions = ExceptionTypeStorage;
4593 }
4594 break;
4595 }
4596
4597 case EST_DynamicNone:
4598 case EST_BasicNoexcept:
4599 case EST_NoexceptTrue:
4600 case EST_NoThrow:
4601 CanonicalEPI.ExceptionSpec.Type = EST_BasicNoexcept;
4602 break;
4603
4604 case EST_DependentNoexcept:
4605 llvm_unreachable("dependent noexcept is already canonical")::llvm::llvm_unreachable_internal("dependent noexcept is already canonical"
, "clang/lib/AST/ASTContext.cpp", 4605)
;
4606 }
4607 } else {
4608 CanonicalEPI.ExceptionSpec = FunctionProtoType::ExceptionSpecInfo();
4609 }
4610
4611 // Adjust the canonical function result type.
4612 CanQualType CanResultTy = getCanonicalFunctionResultType(ResultTy);
4613 Canonical =
4614 getFunctionTypeInternal(CanResultTy, CanonicalArgs, CanonicalEPI, true);
4615
4616 // Get the new insert position for the node we care about.
4617 FunctionProtoType *NewIP =
4618 FunctionProtoTypes.FindNodeOrInsertPos(ID, InsertPos);
4619 assert(!NewIP && "Shouldn't be in the map!")(static_cast <bool> (!NewIP && "Shouldn't be in the map!"
) ? void (0) : __assert_fail ("!NewIP && \"Shouldn't be in the map!\""
, "clang/lib/AST/ASTContext.cpp", 4619, __extension__ __PRETTY_FUNCTION__
))
; (void)NewIP;
4620 }
4621
4622 // Compute the needed size to hold this FunctionProtoType and the
4623 // various trailing objects.
4624 auto ESH = FunctionProtoType::getExceptionSpecSize(
4625 EPI.ExceptionSpec.Type, EPI.ExceptionSpec.Exceptions.size());
4626 size_t Size = FunctionProtoType::totalSizeToAlloc<
4627 QualType, SourceLocation, FunctionType::FunctionTypeExtraBitfields,
4628 FunctionType::ExceptionType, Expr *, FunctionDecl *,
4629 FunctionProtoType::ExtParameterInfo, Qualifiers>(
4630 NumArgs, EPI.Variadic, EPI.requiresFunctionProtoTypeExtraBitfields(),
4631 ESH.NumExceptionType, ESH.NumExprPtr, ESH.NumFunctionDeclPtr,
4632 EPI.ExtParameterInfos ? NumArgs : 0,
4633 EPI.TypeQuals.hasNonFastQualifiers() ? 1 : 0);
4634
4635 auto *FTP = (FunctionProtoType *)Allocate(Size, TypeAlignment);
4636 FunctionProtoType::ExtProtoInfo newEPI = EPI;
4637 new (FTP) FunctionProtoType(ResultTy, ArgArray, Canonical, newEPI);
4638 Types.push_back(FTP);
4639 if (!Unique)
4640 FunctionProtoTypes.InsertNode(FTP, InsertPos);
4641 return QualType(FTP, 0);
4642}
4643
4644QualType ASTContext::getPipeType(QualType T, bool ReadOnly) const {
4645 llvm::FoldingSetNodeID ID;
4646 PipeType::Profile(ID, T, ReadOnly);
4647
4648 void *InsertPos = nullptr;
4649 if (PipeType *PT = PipeTypes.FindNodeOrInsertPos(ID, InsertPos))
4650 return QualType(PT, 0);
4651
4652 // If the pipe element type isn't canonical, this won't be a canonical type
4653 // either, so fill in the canonical type field.
4654 QualType Canonical;
4655 if (!T.isCanonical()) {
4656 Canonical = getPipeType(getCanonicalType(T), ReadOnly);
4657
4658 // Get the new insert position for the node we care about.
4659 PipeType *NewIP = PipeTypes.FindNodeOrInsertPos(ID, InsertPos);
4660 assert(!NewIP && "Shouldn't be in the map!")(static_cast <bool> (!NewIP && "Shouldn't be in the map!"
) ? void (0) : __assert_fail ("!NewIP && \"Shouldn't be in the map!\""
, "clang/lib/AST/ASTContext.cpp", 4660, __extension__ __PRETTY_FUNCTION__
))
;
4661 (void)NewIP;
4662 }
4663 auto *New = new (*this, TypeAlignment) PipeType(T, Canonical, ReadOnly);
4664 Types.push_back(New);
4665 PipeTypes.InsertNode(New, InsertPos);
4666 return QualType(New, 0);
4667}
4668
4669QualType ASTContext::adjustStringLiteralBaseType(QualType Ty) const {
4670 // OpenCL v1.1 s6.5.3: a string literal is in the constant address space.
4671 return LangOpts.OpenCL ? getAddrSpaceQualType(Ty, LangAS::opencl_constant)
4672 : Ty;
4673}
4674
4675QualType ASTContext::getReadPipeType(QualType T) const {
4676 return getPipeType(T, true);
4677}
4678
4679QualType ASTContext::getWritePipeType(QualType T) const {
4680 return getPipeType(T, false);
4681}
4682
4683QualType ASTContext::getBitIntType(bool IsUnsigned, unsigned NumBits) const {
4684 llvm::FoldingSetNodeID ID;
4685 BitIntType::Profile(ID, IsUnsigned, NumBits);
4686
4687 void *InsertPos = nullptr;
4688 if (BitIntType *EIT = BitIntTypes.FindNodeOrInsertPos(ID, InsertPos))
4689 return QualType(EIT, 0);
4690
4691 auto *New = new (*this, TypeAlignment) BitIntType(IsUnsigned, NumBits);
4692 BitIntTypes.InsertNode(New, InsertPos);
4693 Types.push_back(New);
4694 return QualType(New, 0);
4695}
4696
4697QualType ASTContext::getDependentBitIntType(bool IsUnsigned,
4698 Expr *NumBitsExpr) const {
4699 assert(NumBitsExpr->isInstantiationDependent() && "Only good for dependent")(static_cast <bool> (NumBitsExpr->isInstantiationDependent
() && "Only good for dependent") ? void (0) : __assert_fail
("NumBitsExpr->isInstantiationDependent() && \"Only good for dependent\""
, "clang/lib/AST/ASTContext.cpp", 4699, __extension__ __PRETTY_FUNCTION__
))
;
4700 llvm::FoldingSetNodeID ID;
4701 DependentBitIntType::Profile(ID, *this, IsUnsigned, NumBitsExpr);
4702
4703 void *InsertPos = nullptr;
4704 if (DependentBitIntType *Existing =
4705 DependentBitIntTypes.FindNodeOrInsertPos(ID, InsertPos))
4706 return QualType(Existing, 0);
4707
4708 auto *New = new (*this, TypeAlignment)
4709 DependentBitIntType(*this, IsUnsigned, NumBitsExpr);
4710 DependentBitIntTypes.InsertNode(New, InsertPos);
4711
4712 Types.push_back(New);
4713 return QualType(New, 0);
4714}
4715
4716#ifndef NDEBUG
4717static bool NeedsInjectedClassNameType(const RecordDecl *D) {
4718 if (!isa<CXXRecordDecl>(D)) return false;
4719 const auto *RD = cast<CXXRecordDecl>(D);
4720 if (isa<ClassTemplatePartialSpecializationDecl>(RD))
4721 return true;
4722 if (RD->getDescribedClassTemplate() &&
4723 !isa<ClassTemplateSpecializationDecl>(RD))
4724 return true;
4725 return false;
4726}
4727#endif
4728
4729/// getInjectedClassNameType - Return the unique reference to the
4730/// injected class name type for the specified templated declaration.
4731QualType ASTContext::getInjectedClassNameType(CXXRecordDecl *Decl,
4732 QualType TST) const {
4733 assert(NeedsInjectedClassNameType(Decl))(static_cast <bool> (NeedsInjectedClassNameType(Decl)) ?
void (0) : __assert_fail ("NeedsInjectedClassNameType(Decl)"
, "clang/lib/AST/ASTContext.cpp", 4733, __extension__ __PRETTY_FUNCTION__
))
;
4734 if (Decl->TypeForDecl) {
4735 assert(isa<InjectedClassNameType>(Decl->TypeForDecl))(static_cast <bool> (isa<InjectedClassNameType>(Decl
->TypeForDecl)) ? void (0) : __assert_fail ("isa<InjectedClassNameType>(Decl->TypeForDecl)"
, "clang/lib/AST/ASTContext.cpp", 4735, __extension__ __PRETTY_FUNCTION__
))
;
4736 } else if (CXXRecordDecl *PrevDecl = Decl->getPreviousDecl()) {
4737 assert(PrevDecl->TypeForDecl && "previous declaration has no type")(static_cast <bool> (PrevDecl->TypeForDecl &&
"previous declaration has no type") ? void (0) : __assert_fail
("PrevDecl->TypeForDecl && \"previous declaration has no type\""
, "clang/lib/AST/ASTContext.cpp", 4737, __extension__ __PRETTY_FUNCTION__
))
;
4738 Decl->TypeForDecl = PrevDecl->TypeForDecl;
4739 assert(isa<InjectedClassNameType>(Decl->TypeForDecl))(static_cast <bool> (isa<InjectedClassNameType>(Decl
->TypeForDecl)) ? void (0) : __assert_fail ("isa<InjectedClassNameType>(Decl->TypeForDecl)"
, "clang/lib/AST/ASTContext.cpp", 4739, __extension__ __PRETTY_FUNCTION__
))
;
4740 } else {
4741 Type *newType =
4742 new (*this, TypeAlignment) InjectedClassNameType(Decl, TST);
4743 Decl->TypeForDecl = newType;
4744 Types.push_back(newType);
4745 }
4746 return QualType(Decl->TypeForDecl, 0);
4747}
4748
4749/// getTypeDeclType - Return the unique reference to the type for the
4750/// specified type declaration.
4751QualType ASTContext::getTypeDeclTypeSlow(const TypeDecl *Decl) const {
4752 assert(Decl && "Passed null for Decl param")(static_cast <bool> (Decl && "Passed null for Decl param"
) ? void (0) : __assert_fail ("Decl && \"Passed null for Decl param\""
, "clang/lib/AST/ASTContext.cpp", 4752, __extension__ __PRETTY_FUNCTION__
))
;
4753 assert(!Decl->TypeForDecl && "TypeForDecl present in slow case")(static_cast <bool> (!Decl->TypeForDecl && "TypeForDecl present in slow case"
) ? void (0) : __assert_fail ("!Decl->TypeForDecl && \"TypeForDecl present in slow case\""
, "clang/lib/AST/ASTContext.cpp", 4753, __extension__ __PRETTY_FUNCTION__
))
;
4754
4755 if (const auto *Typedef = dyn_cast<TypedefNameDecl>(Decl))
4756 return getTypedefType(Typedef);
4757
4758 assert(!isa<TemplateTypeParmDecl>(Decl) &&(static_cast <bool> (!isa<TemplateTypeParmDecl>(Decl
) && "Template type parameter types are always available."
) ? void (0) : __assert_fail ("!isa<TemplateTypeParmDecl>(Decl) && \"Template type parameter types are always available.\""
, "clang/lib/AST/ASTContext.cpp", 4759, __extension__ __PRETTY_FUNCTION__
))
4759 "Template type parameter types are always available.")(static_cast <bool> (!isa<TemplateTypeParmDecl>(Decl
) && "Template type parameter types are always available."
) ? void (0) : __assert_fail ("!isa<TemplateTypeParmDecl>(Decl) && \"Template type parameter types are always available.\""
, "clang/lib/AST/ASTContext.cpp", 4759, __extension__ __PRETTY_FUNCTION__
))
;
4760
4761 if (const auto *Record = dyn_cast<RecordDecl>(Decl)) {
4762 assert(Record->isFirstDecl() && "struct/union has previous declaration")(static_cast <bool> (Record->isFirstDecl() &&
"struct/union has previous declaration") ? void (0) : __assert_fail
("Record->isFirstDecl() && \"struct/union has previous declaration\""
, "clang/lib/AST/ASTContext.cpp", 4762, __extension__ __PRETTY_FUNCTION__
))
;
4763 assert(!NeedsInjectedClassNameType(Record))(static_cast <bool> (!NeedsInjectedClassNameType(Record
)) ? void (0) : __assert_fail ("!NeedsInjectedClassNameType(Record)"
, "clang/lib/AST/ASTContext.cpp", 4763, __extension__ __PRETTY_FUNCTION__
))
;
4764 return getRecordType(Record);
4765 } else if (const auto *Enum = dyn_cast<EnumDecl>(Decl)) {
4766 assert(Enum->isFirstDecl() && "enum has previous declaration")(static_cast <bool> (Enum->isFirstDecl() && "enum has previous declaration"
) ? void (0) : __assert_fail ("Enum->isFirstDecl() && \"enum has previous declaration\""
, "clang/lib/AST/ASTContext.cpp", 4766, __extension__ __PRETTY_FUNCTION__
))
;
4767 return getEnumType(Enum);
4768 } else if (const auto *Using = dyn_cast<UnresolvedUsingTypenameDecl>(Decl)) {
4769 return getUnresolvedUsingType(Using);
4770 } else
4771 llvm_unreachable("TypeDecl without a type?")::llvm::llvm_unreachable_internal("TypeDecl without a type?",
"clang/lib/AST/ASTContext.cpp", 4771)
;
4772
4773 return QualType(Decl->TypeForDecl, 0);
4774}
4775
4776/// getTypedefType - Return the unique reference to the type for the
4777/// specified typedef name decl.
4778QualType ASTContext::getTypedefType(const TypedefNameDecl *Decl,
4779 QualType Underlying) const {
4780 if (!Decl->TypeForDecl) {
4781 if (Underlying.isNull())
4782 Underlying = Decl->getUnderlyingType();
4783 auto *NewType = new (*this, TypeAlignment) TypedefType(
4784 Type::Typedef, Decl, QualType(), getCanonicalType(Underlying));
4785 Decl->TypeForDecl = NewType;
4786 Types.push_back(NewType);
4787 return QualType(NewType, 0);
4788 }
4789 if (Underlying.isNull() || Decl->getUnderlyingType() == Underlying)
4790 return QualType(Decl->TypeForDecl, 0);
4791 assert(hasSameType(Decl->getUnderlyingType(), Underlying))(static_cast <bool> (hasSameType(Decl->getUnderlyingType
(), Underlying)) ? void (0) : __assert_fail ("hasSameType(Decl->getUnderlyingType(), Underlying)"
, "clang/lib/AST/ASTContext.cpp", 4791, __extension__ __PRETTY_FUNCTION__
))
;
4792
4793 llvm::FoldingSetNodeID ID;
4794 TypedefType::Profile(ID, Decl, Underlying);
4795
4796 void *InsertPos = nullptr;
4797 if (TypedefType *T = TypedefTypes.FindNodeOrInsertPos(ID, InsertPos)) {
4798 assert(!T->typeMatchesDecl() &&(static_cast <bool> (!T->typeMatchesDecl() &&
"non-divergent case should be handled with TypeDecl") ? void
(0) : __assert_fail ("!T->typeMatchesDecl() && \"non-divergent case should be handled with TypeDecl\""
, "clang/lib/AST/ASTContext.cpp", 4799, __extension__ __PRETTY_FUNCTION__
))
4799 "non-divergent case should be handled with TypeDecl")(static_cast <bool> (!T->typeMatchesDecl() &&
"non-divergent case should be handled with TypeDecl") ? void
(0) : __assert_fail ("!T->typeMatchesDecl() && \"non-divergent case should be handled with TypeDecl\""
, "clang/lib/AST/ASTContext.cpp", 4799, __extension__ __PRETTY_FUNCTION__
))
;
4800 return QualType(T, 0);
4801 }
4802
4803 void *Mem =
4804 Allocate(TypedefType::totalSizeToAlloc<QualType>(true), TypeAlignment);
4805 auto *NewType = new (Mem) TypedefType(Type::Typedef, Decl, Underlying,
4806 getCanonicalType(Underlying));
4807 TypedefTypes.InsertNode(NewType, InsertPos);
4808 Types.push_back(NewType);
4809 return QualType(NewType, 0);
4810}
4811
4812QualType ASTContext::getUsingType(const UsingShadowDecl *Found,
4813 QualType Underlying) const {
4814 llvm::FoldingSetNodeID ID;
4815 UsingType::Profile(ID, Found, Underlying);
4816
4817 void *InsertPos = nullptr;
4818 if (UsingType *T = UsingTypes.FindNodeOrInsertPos(ID, InsertPos))
4819 return QualType(T, 0);
4820
4821 const Type *TypeForDecl =
4822 cast<TypeDecl>(Found->getTargetDecl())->getTypeForDecl();
4823
4824 assert(!Underlying.hasLocalQualifiers())(static_cast <bool> (!Underlying.hasLocalQualifiers()) ?
void (0) : __assert_fail ("!Underlying.hasLocalQualifiers()"
, "clang/lib/AST/ASTContext.cpp", 4824, __extension__ __PRETTY_FUNCTION__
))
;
4825 QualType Canon = Underlying->getCanonicalTypeInternal();
4826 assert(TypeForDecl->getCanonicalTypeInternal() == Canon)(static_cast <bool> (TypeForDecl->getCanonicalTypeInternal
() == Canon) ? void (0) : __assert_fail ("TypeForDecl->getCanonicalTypeInternal() == Canon"
, "clang/lib/AST/ASTContext.cpp", 4826, __extension__ __PRETTY_FUNCTION__
))
;
4827
4828 if (Underlying.getTypePtr() == TypeForDecl)
4829 Underlying = QualType();
4830 void *Mem =
4831 Allocate(UsingType::totalSizeToAlloc<QualType>(!Underlying.isNull()),
4832 TypeAlignment);
4833 UsingType *NewType = new (Mem) UsingType(Found, Underlying, Canon);
4834 Types.push_back(NewType);
4835 UsingTypes.InsertNode(NewType, InsertPos);
4836 return QualType(NewType, 0);
4837}
4838
4839QualType ASTContext::getRecordType(const RecordDecl *Decl) const {
4840 if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0);
4841
4842 if (const RecordDecl *PrevDecl = Decl->getPreviousDecl())
4843 if (PrevDecl->TypeForDecl)
4844 return QualType(Decl->TypeForDecl = PrevDecl->TypeForDecl, 0);
4845
4846 auto *newType = new (*this, TypeAlignment) RecordType(Decl);
4847 Decl->TypeForDecl = newType;
4848 Types.push_back(newType);
4849 return QualType(newType, 0);
4850}
4851
4852QualType ASTContext::getEnumType(const EnumDecl *Decl) const {
4853 if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0);
4854
4855 if (const EnumDecl *PrevDecl = Decl->getPreviousDecl())
4856 if (PrevDecl->TypeForDecl)
4857 return QualType(Decl->TypeForDecl = PrevDecl->TypeForDecl, 0);
4858
4859 auto *newType = new (*this, TypeAlignment) EnumType(Decl);
4860 Decl->TypeForDecl = newType;
4861 Types.push_back(newType);
4862 return QualType(newType, 0);
4863}
4864
4865QualType ASTContext::getUnresolvedUsingType(
4866 const UnresolvedUsingTypenameDecl *Decl) const {
4867 if (Decl->TypeForDecl)
4868 return QualType(Decl->TypeForDecl, 0);
4869
4870 if (const UnresolvedUsingTypenameDecl *CanonicalDecl =
4871 Decl->getCanonicalDecl())
4872 if (CanonicalDecl->TypeForDecl)
4873 return QualType(Decl->TypeForDecl = CanonicalDecl->TypeForDecl, 0);
4874
4875 Type *newType = new (*this, TypeAlignment) UnresolvedUsingType(Decl);
4876 Decl->TypeForDecl = newType;
4877 Types.push_back(newType);
4878 return QualType(newType, 0);
4879}
4880
4881QualType ASTContext::getAttributedType(attr::Kind attrKind,
4882 QualType modifiedType,
4883 QualType equivalentType) const {
4884 llvm::FoldingSetNodeID id;
4885 AttributedType::Profile(id, attrKind, modifiedType, equivalentType);
4886
4887 void *insertPos = nullptr;
4888 AttributedType *type = AttributedTypes.FindNodeOrInsertPos(id, insertPos);
4889 if (type) return QualType(type, 0);
4890
4891 QualType canon = getCanonicalType(equivalentType);
4892 type = new (*this, TypeAlignment)
4893 AttributedType(canon, attrKind, modifiedType, equivalentType);
4894
4895 Types.push_back(type);
4896 AttributedTypes.InsertNode(type, insertPos);
4897
4898 return QualType(type, 0);
4899}
4900
4901QualType ASTContext::getBTFTagAttributedType(const BTFTypeTagAttr *BTFAttr,
4902 QualType Wrapped) {
4903 llvm::FoldingSetNodeID ID;
4904 BTFTagAttributedType::Profile(ID, Wrapped, BTFAttr);
4905
4906 void *InsertPos = nullptr;
4907 BTFTagAttributedType *Ty =
4908 BTFTagAttributedTypes.FindNodeOrInsertPos(ID, InsertPos);
4909 if (Ty)
4910 return QualType(Ty, 0);
4911
4912 QualType Canon = getCanonicalType(Wrapped);
4913 Ty = new (*this, TypeAlignment) BTFTagAttributedType(Canon, Wrapped, BTFAttr);
4914
4915 Types.push_back(Ty);
4916 BTFTagAttributedTypes.InsertNode(Ty, InsertPos);
4917
4918 return QualType(Ty, 0);
4919}
4920
4921/// Retrieve a substitution-result type.
4922QualType ASTContext::getSubstTemplateTypeParmType(
4923 QualType Replacement, Decl *AssociatedDecl, unsigned Index,
4924 std::optional<unsigned> PackIndex) const {
4925 llvm::FoldingSetNodeID ID;
4926 SubstTemplateTypeParmType::Profile(ID, Replacement, AssociatedDecl, Index,
4927 PackIndex);
4928 void *InsertPos = nullptr;
4929 SubstTemplateTypeParmType *SubstParm =
4930 SubstTemplateTypeParmTypes.FindNodeOrInsertPos(ID, InsertPos);
4931
4932 if (!SubstParm) {
4933 void *Mem = Allocate(SubstTemplateTypeParmType::totalSizeToAlloc<QualType>(
4934 !Replacement.isCanonical()),
4935 TypeAlignment);
4936 SubstParm = new (Mem) SubstTemplateTypeParmType(Replacement, AssociatedDecl,
4937 Index, PackIndex);
4938 Types.push_back(SubstParm);
4939 SubstTemplateTypeParmTypes.InsertNode(SubstParm, InsertPos);
4940 }
4941
4942 return QualType(SubstParm, 0);
4943}
4944
4945/// Retrieve a
4946QualType
4947ASTContext::getSubstTemplateTypeParmPackType(Decl *AssociatedDecl,
4948 unsigned Index, bool Final,
4949 const TemplateArgument &ArgPack) {
4950#ifndef NDEBUG
4951 for (const auto &P : ArgPack.pack_elements())
4952 assert(P.getKind() == TemplateArgument::Type && "Pack contains a non-type")(static_cast <bool> (P.getKind() == TemplateArgument::Type
&& "Pack contains a non-type") ? void (0) : __assert_fail
("P.getKind() == TemplateArgument::Type && \"Pack contains a non-type\""
, "clang/lib/AST/ASTContext.cpp", 4952, __extension__ __PRETTY_FUNCTION__
))
;
4953#endif
4954
4955 llvm::FoldingSetNodeID ID;
4956 SubstTemplateTypeParmPackType::Profile(ID, AssociatedDecl, Index, Final,
4957 ArgPack);
4958 void *InsertPos = nullptr;
4959 if (SubstTemplateTypeParmPackType *SubstParm =
4960 SubstTemplateTypeParmPackTypes.FindNodeOrInsertPos(ID, InsertPos))
4961 return QualType(SubstParm, 0);
4962
4963 QualType Canon;
4964 {
4965 TemplateArgument CanonArgPack = getCanonicalTemplateArgument(ArgPack);
4966 if (!AssociatedDecl->isCanonicalDecl() ||
4967 !CanonArgPack.structurallyEquals(ArgPack)) {
4968 Canon = getSubstTemplateTypeParmPackType(
4969 AssociatedDecl->getCanonicalDecl(), Index, Final, CanonArgPack);
4970 [[maybe_unused]] const auto *Nothing =
4971 SubstTemplateTypeParmPackTypes.FindNodeOrInsertPos(ID, InsertPos);
4972 assert(!Nothing)(static_cast <bool> (!Nothing) ? void (0) : __assert_fail
("!Nothing", "clang/lib/AST/ASTContext.cpp", 4972, __extension__
__PRETTY_FUNCTION__))
;
4973 }
4974 }
4975
4976 auto *SubstParm = new (*this, TypeAlignment) SubstTemplateTypeParmPackType(
4977 Canon, AssociatedDecl, Index, Final, ArgPack);
4978 Types.push_back(SubstParm);
4979 SubstTemplateTypeParmPackTypes.InsertNode(SubstParm, InsertPos);
4980 return QualType(SubstParm, 0);
4981}
4982
4983/// Retrieve the template type parameter type for a template
4984/// parameter or parameter pack with the given depth, index, and (optionally)
4985/// name.
4986QualType ASTContext::getTemplateTypeParmType(unsigned Depth, unsigned Index,
4987 bool ParameterPack,
4988 TemplateTypeParmDecl *TTPDecl) const {
4989 llvm::FoldingSetNodeID ID;
4990 TemplateTypeParmType::Profile(ID, Depth, Index, ParameterPack, TTPDecl);
4991 void *InsertPos = nullptr;
4992 TemplateTypeParmType *TypeParm
4993 = TemplateTypeParmTypes.FindNodeOrInsertPos(ID, InsertPos);
4994
4995 if (TypeParm)
4996 return QualType(TypeParm, 0);
4997
4998 if (TTPDecl) {
4999 QualType Canon = getTemplateTypeParmType(Depth, Index, ParameterPack);
5000 TypeParm = new (*this, TypeAlignment) TemplateTypeParmType(TTPDecl, Canon);
5001
5002 TemplateTypeParmType *TypeCheck
5003 = TemplateTypeParmTypes.FindNodeOrInsertPos(ID, InsertPos);
5004 assert(!TypeCheck && "Template type parameter canonical type broken")(static_cast <bool> (!TypeCheck && "Template type parameter canonical type broken"
) ? void (0) : __assert_fail ("!TypeCheck && \"Template type parameter canonical type broken\""
, "clang/lib/AST/ASTContext.cpp", 5004, __extension__ __PRETTY_FUNCTION__
))
;
5005 (void)TypeCheck;
5006 } else
5007 TypeParm = new (*this, TypeAlignment)
5008 TemplateTypeParmType(Depth, Index, ParameterPack);
5009
5010 Types.push_back(TypeParm);
5011 TemplateTypeParmTypes.InsertNode(TypeParm, InsertPos);
5012
5013 return QualType(TypeParm, 0);
5014}
5015
5016TypeSourceInfo *
5017ASTContext::getTemplateSpecializationTypeInfo(TemplateName Name,
5018 SourceLocation NameLoc,
5019 const TemplateArgumentListInfo &Args,
5020 QualType Underlying) const {
5021 assert(!Name.getAsDependentTemplateName() &&(static_cast <bool> (!Name.getAsDependentTemplateName()
&& "No dependent template names here!") ? void (0) :
__assert_fail ("!Name.getAsDependentTemplateName() && \"No dependent template names here!\""
, "clang/lib/AST/ASTContext.cpp", 5022, __extension__ __PRETTY_FUNCTION__
))
5022 "No dependent template names here!")(static_cast <bool> (!Name.getAsDependentTemplateName()
&& "No dependent template names here!") ? void (0) :
__assert_fail ("!Name.getAsDependentTemplateName() && \"No dependent template names here!\""
, "clang/lib/AST/ASTContext.cpp", 5022, __extension__ __PRETTY_FUNCTION__
))
;
5023 QualType TST =
5024 getTemplateSpecializationType(Name, Args.arguments(), Underlying);
5025
5026 TypeSourceInfo *DI = CreateTypeSourceInfo(TST);
5027 TemplateSpecializationTypeLoc TL =
5028 DI->getTypeLoc().castAs<TemplateSpecializationTypeLoc>();
5029 TL.setTemplateKeywordLoc(SourceLocation());
5030 TL.setTemplateNameLoc(NameLoc);
5031 TL.setLAngleLoc(Args.getLAngleLoc());
5032 TL.setRAngleLoc(Args.getRAngleLoc());
5033 for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i)
5034 TL.setArgLocInfo(i, Args[i].getLocInfo());
5035 return DI;
5036}
5037
5038QualType
5039ASTContext::getTemplateSpecializationType(TemplateName Template,
5040 ArrayRef<TemplateArgumentLoc> Args,
5041 QualType Underlying) const {
5042 assert(!Template.getAsDependentTemplateName() &&(static_cast <bool> (!Template.getAsDependentTemplateName
() && "No dependent template names here!") ? void (0)
: __assert_fail ("!Template.getAsDependentTemplateName() && \"No dependent template names here!\""
, "clang/lib/AST/ASTContext.cpp", 5043, __extension__ __PRETTY_FUNCTION__
))
5043 "No dependent template names here!")(static_cast <bool> (!Template.getAsDependentTemplateName
() && "No dependent template names here!") ? void (0)
: __assert_fail ("!Template.getAsDependentTemplateName() && \"No dependent template names here!\""
, "clang/lib/AST/ASTContext.cpp", 5043, __extension__ __PRETTY_FUNCTION__
))
;
5044
5045 SmallVector<TemplateArgument, 4> ArgVec;
5046 ArgVec.reserve(Args.size());
5047 for (const TemplateArgumentLoc &Arg : Args)
5048 ArgVec.push_back(Arg.getArgument());
5049
5050 return getTemplateSpecializationType(Template, ArgVec, Underlying);
5051}
5052
5053#ifndef NDEBUG
5054static bool hasAnyPackExpansions(ArrayRef<TemplateArgument> Args) {
5055 for (const TemplateArgument &Arg : Args)
5056 if (Arg.isPackExpansion())
5057 return true;
5058
5059 return true;
5060}
5061#endif
5062
5063QualType
5064ASTContext::getTemplateSpecializationType(TemplateName Template,
5065 ArrayRef<TemplateArgument> Args,
5066 QualType Underlying) const {
5067 assert(!Template.getAsDependentTemplateName() &&(static_cast <bool> (!Template.getAsDependentTemplateName
() && "No dependent template names here!") ? void (0)
: __assert_fail ("!Template.getAsDependentTemplateName() && \"No dependent template names here!\""
, "clang/lib/AST/ASTContext.cpp", 5068, __extension__ __PRETTY_FUNCTION__
))
5068 "No dependent template names here!")(static_cast <bool> (!Template.getAsDependentTemplateName
() && "No dependent template names here!") ? void (0)
: __assert_fail ("!Template.getAsDependentTemplateName() && \"No dependent template names here!\""
, "clang/lib/AST/ASTContext.cpp", 5068, __extension__ __PRETTY_FUNCTION__
))
;
5069 // Look through qualified template names.
5070 if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName())
5071 Template = QTN->getUnderlyingTemplate();
5072
5073 const auto *TD = Template.getAsTemplateDecl();
5074 bool IsTypeAlias = TD && TD->isTypeAlias();
5075 QualType CanonType;
5076 if (!Underlying.isNull())
5077 CanonType = getCanonicalType(Underlying);
5078 else {
5079 // We can get here with an alias template when the specialization contains
5080 // a pack expansion that does not match up with a parameter pack.
5081 assert((!IsTypeAlias || hasAnyPackExpansions(Args)) &&(static_cast <bool> ((!IsTypeAlias || hasAnyPackExpansions
(Args)) && "Caller must compute aliased type") ? void
(0) : __assert_fail ("(!IsTypeAlias || hasAnyPackExpansions(Args)) && \"Caller must compute aliased type\""
, "clang/lib/AST/ASTContext.cpp", 5082, __extension__ __PRETTY_FUNCTION__
))
5082 "Caller must compute aliased type")(static_cast <bool> ((!IsTypeAlias || hasAnyPackExpansions
(Args)) && "Caller must compute aliased type") ? void
(0) : __assert_fail ("(!IsTypeAlias || hasAnyPackExpansions(Args)) && \"Caller must compute aliased type\""
, "clang/lib/AST/ASTContext.cpp", 5082, __extension__ __PRETTY_FUNCTION__
))
;
5083 IsTypeAlias = false;
5084 CanonType = getCanonicalTemplateSpecializationType(Template, Args);
5085 }
5086
5087 // Allocate the (non-canonical) template specialization type, but don't
5088 // try to unique it: these types typically have location information that
5089 // we don't unique and don't want to lose.
5090 void *Mem = Allocate(sizeof(TemplateSpecializationType) +
5091 sizeof(TemplateArgument) * Args.size() +
5092 (IsTypeAlias? sizeof(QualType) : 0),
5093 TypeAlignment);
5094 auto *Spec
5095 = new (Mem) TemplateSpecializationType(Template, Args, CanonType,
5096 IsTypeAlias ? Underlying : QualType());
5097
5098 Types.push_back(Spec);
5099 return QualType(Spec, 0);
5100}
5101
5102QualType ASTContext::getCanonicalTemplateSpecializationType(
5103 TemplateName Template, ArrayRef<TemplateArgument> Args) const {
5104 assert(!Template.getAsDependentTemplateName() &&(static_cast <bool> (!Template.getAsDependentTemplateName
() && "No dependent template names here!") ? void (0)
: __assert_fail ("!Template.getAsDependentTemplateName() && \"No dependent template names here!\""
, "clang/lib/AST/ASTContext.cpp", 5105, __extension__ __PRETTY_FUNCTION__
))
5105 "No dependent template names here!")(static_cast <bool> (!Template.getAsDependentTemplateName
() && "No dependent template names here!") ? void (0)
: __assert_fail ("!Template.getAsDependentTemplateName() && \"No dependent template names here!\""
, "clang/lib/AST/ASTContext.cpp", 5105, __extension__ __PRETTY_FUNCTION__
))
;
5106
5107 // Look through qualified template names.
5108 if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName())
5109 Template = TemplateName(QTN->getUnderlyingTemplate());
5110
5111 // Build the canonical template specialization type.
5112 TemplateName CanonTemplate = getCanonicalTemplateName(Template);
5113 bool AnyNonCanonArgs = false;
5114 auto CanonArgs =
5115 ::getCanonicalTemplateArguments(*this, Args, AnyNonCanonArgs);
5116
5117 // Determine whether this canonical template specialization type already
5118 // exists.
5119 llvm::FoldingSetNodeID ID;
5120 TemplateSpecializationType::Profile(ID, CanonTemplate,
5121 CanonArgs, *this);
5122
5123 void *InsertPos = nullptr;
5124 TemplateSpecializationType *Spec
5125 = TemplateSpecializationTypes.FindNodeOrInsertPos(ID, InsertPos);
5126
5127 if (!Spec) {
5128 // Allocate a new canonical template specialization type.
5129 void *Mem = Allocate((sizeof(TemplateSpecializationType) +
5130 sizeof(TemplateArgument) * CanonArgs.size()),
5131 TypeAlignment);
5132 Spec = new (Mem) TemplateSpecializationType(CanonTemplate,
5133 CanonArgs,
5134 QualType(), QualType());
5135 Types.push_back(Spec);
5136 TemplateSpecializationTypes.InsertNode(Spec, InsertPos);
5137 }
5138
5139 assert(Spec->isDependentType() &&(static_cast <bool> (Spec->isDependentType() &&
"Non-dependent template-id type must have a canonical type")
? void (0) : __assert_fail ("Spec->isDependentType() && \"Non-dependent template-id type must have a canonical type\""
, "clang/lib/AST/ASTContext.cpp", 5140, __extension__ __PRETTY_FUNCTION__
))
5140 "Non-dependent template-id type must have a canonical type")(static_cast <bool> (Spec->isDependentType() &&
"Non-dependent template-id type must have a canonical type")
? void (0) : __assert_fail ("Spec->isDependentType() && \"Non-dependent template-id type must have a canonical type\""
, "clang/lib/AST/ASTContext.cpp", 5140, __extension__ __PRETTY_FUNCTION__
))
;
5141 return QualType(Spec, 0);
5142}
5143
5144QualType ASTContext::getElaboratedType(ElaboratedTypeKeyword Keyword,
5145 NestedNameSpecifier *NNS,
5146 QualType NamedType,
5147 TagDecl *OwnedTagDecl) const {
5148 llvm::FoldingSetNodeID ID;
5149 ElaboratedType::Profile(ID, Keyword, NNS, NamedType, OwnedTagDecl);
5150
5151 void *InsertPos = nullptr;
5152 ElaboratedType *T = ElaboratedTypes.FindNodeOrInsertPos(ID, InsertPos);
5153 if (T)
5154 return QualType(T, 0);
5155
5156 QualType Canon = NamedType;
5157 if (!Canon.isCanonical()) {
5158 Canon = getCanonicalType(NamedType);
5159 ElaboratedType *CheckT = ElaboratedTypes.FindNodeOrInsertPos(ID, InsertPos);
5160 assert(!CheckT && "Elaborated canonical type broken")(static_cast <bool> (!CheckT && "Elaborated canonical type broken"
) ? void (0) : __assert_fail ("!CheckT && \"Elaborated canonical type broken\""
, "clang/lib/AST/ASTContext.cpp", 5160, __extension__ __PRETTY_FUNCTION__
))
;
5161 (void)CheckT;
5162 }
5163
5164 void *Mem = Allocate(ElaboratedType::totalSizeToAlloc<TagDecl *>(!!OwnedTagDecl),
5165 TypeAlignment);
5166 T = new (Mem) ElaboratedType(Keyword, NNS, NamedType, Canon, OwnedTagDecl);
5167
5168 Types.push_back(T);
5169 ElaboratedTypes.InsertNode(T, InsertPos);
5170 return QualType(T, 0);
5171}
5172
5173QualType
5174ASTContext::getParenType(QualType InnerType) const {
5175 llvm::FoldingSetNodeID ID;
5176 ParenType::Profile(ID, InnerType);
5177
5178 void *InsertPos = nullptr;
5179 ParenType *T = ParenTypes.FindNodeOrInsertPos(ID, InsertPos);
5180 if (T)
5181 return QualType(T, 0);
5182
5183 QualType Canon = InnerType;
5184 if (!Canon.isCanonical()) {
5185 Canon = getCanonicalType(InnerType);
5186 ParenType *CheckT = ParenTypes.FindNodeOrInsertPos(ID, InsertPos);
5187 assert(!CheckT && "Paren canonical type broken")(static_cast <bool> (!CheckT && "Paren canonical type broken"
) ? void (0) : __assert_fail ("!CheckT && \"Paren canonical type broken\""
, "clang/lib/AST/ASTContext.cpp", 5187, __extension__ __PRETTY_FUNCTION__
))
;
5188 (void)CheckT;
5189 }
5190
5191 T = new (*this, TypeAlignment) ParenType(InnerType, Canon);
5192 Types.push_back(T);
5193 ParenTypes.InsertNode(T, InsertPos);
5194 return QualType(T, 0);
5195}
5196
5197QualType
5198ASTContext::getMacroQualifiedType(QualType UnderlyingTy,
5199 const IdentifierInfo *MacroII) const {
5200 QualType Canon = UnderlyingTy;
5201 if (!Canon.isCanonical())
5202 Canon = getCanonicalType(UnderlyingTy);
5203
5204 auto *newType = new (*this, TypeAlignment)
5205 MacroQualifiedType(UnderlyingTy, Canon, MacroII);
5206 Types.push_back(newType);
5207 return QualType(newType, 0);
5208}
5209
5210QualType ASTContext::getDependentNameType(ElaboratedTypeKeyword Keyword,
5211 NestedNameSpecifier *NNS,
5212 const IdentifierInfo *Name,
5213 QualType Canon) const {
5214 if (Canon.isNull()) {
5215 NestedNameSpecifier *CanonNNS = getCanonicalNestedNameSpecifier(NNS);
5216 if (CanonNNS != NNS)
5217 Canon = getDependentNameType(Keyword, CanonNNS, Name);
5218 }
5219
5220 llvm::FoldingSetNodeID ID;
5221 DependentNameType::Profile(ID, Keyword, NNS, Name);
5222
5223 void *InsertPos = nullptr;
5224 DependentNameType *T
5225 = DependentNameTypes.FindNodeOrInsertPos(ID, InsertPos);
5226 if (T)
5227 return QualType(T, 0);
5228
5229 T = new (*this, TypeAlignment) DependentNameType(Keyword, NNS, Name, Canon);
5230 Types.push_back(T);
5231 DependentNameTypes.InsertNode(T, InsertPos);
5232 return QualType(T, 0);
5233}
5234
5235QualType ASTContext::getDependentTemplateSpecializationType(
5236 ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
5237 const IdentifierInfo *Name, ArrayRef<TemplateArgumentLoc> Args) const {
5238 // TODO: avoid this copy
5239 SmallVector<TemplateArgument, 16> ArgCopy;
5240 for (unsigned I = 0, E = Args.size(); I != E; ++I)
5241 ArgCopy.push_back(Args[I].getArgument());
5242 return getDependentTemplateSpecializationType(Keyword, NNS, Name, ArgCopy);
5243}
5244
5245QualType
5246ASTContext::getDependentTemplateSpecializationType(
5247 ElaboratedTypeKeyword Keyword,
5248 NestedNameSpecifier *NNS,
5249 const IdentifierInfo *Name,
5250 ArrayRef<TemplateArgument> Args) const {
5251 assert((!NNS || NNS->isDependent()) &&(static_cast <bool> ((!NNS || NNS->isDependent()) &&
"nested-name-specifier must be dependent") ? void (0) : __assert_fail
("(!NNS || NNS->isDependent()) && \"nested-name-specifier must be dependent\""
, "clang/lib/AST/ASTContext.cpp", 5252, __extension__ __PRETTY_FUNCTION__
))
5252 "nested-name-specifier must be dependent")(static_cast <bool> ((!NNS || NNS->isDependent()) &&
"nested-name-specifier must be dependent") ? void (0) : __assert_fail
("(!NNS || NNS->isDependent()) && \"nested-name-specifier must be dependent\""
, "clang/lib/AST/ASTContext.cpp", 5252, __extension__ __PRETTY_FUNCTION__
))
;
5253
5254 llvm::FoldingSetNodeID ID;
5255 DependentTemplateSpecializationType::Profile(ID, *this, Keyword, NNS,
5256 Name, Args);
5257
5258 void *InsertPos = nullptr;
5259 DependentTemplateSpecializationType *T
5260 = DependentTemplateSpecializationTypes.FindNodeOrInsertPos(ID, InsertPos);
5261 if (T)
5262 return QualType(T, 0);
5263
5264 NestedNameSpecifier *CanonNNS = getCanonicalNestedNameSpecifier(NNS);
5265
5266 ElaboratedTypeKeyword CanonKeyword = Keyword;
5267 if (Keyword == ETK_None) CanonKeyword = ETK_Typename;
5268
5269 bool AnyNonCanonArgs = false;
5270 auto CanonArgs =
5271 ::getCanonicalTemplateArguments(*this, Args, AnyNonCanonArgs);
5272
5273 QualType Canon;
5274 if (AnyNonCanonArgs || CanonNNS != NNS || CanonKeyword != Keyword) {
5275 Canon = getDependentTemplateSpecializationType(CanonKeyword, CanonNNS,
5276 Name,
5277 CanonArgs);
5278
5279 // Find the insert position again.
5280 [[maybe_unused]] auto *Nothing =
5281 DependentTemplateSpecializationTypes.FindNodeOrInsertPos(ID, InsertPos);
5282 assert(!Nothing && "canonical type broken")(static_cast <bool> (!Nothing && "canonical type broken"
) ? void (0) : __assert_fail ("!Nothing && \"canonical type broken\""
, "clang/lib/AST/ASTContext.cpp", 5282, __extension__ __PRETTY_FUNCTION__
))
;
5283 }
5284
5285 void *Mem = Allocate((sizeof(DependentTemplateSpecializationType) +
5286 sizeof(TemplateArgument) * Args.size()),
5287 TypeAlignment);
5288 T = new (Mem) DependentTemplateSpecializationType(Keyword, NNS,
5289 Name, Args, Canon);
5290 Types.push_back(T);
5291 DependentTemplateSpecializationTypes.InsertNode(T, InsertPos);
5292 return QualType(T, 0);
5293}
5294
5295TemplateArgument ASTContext::getInjectedTemplateArg(NamedDecl *Param) {
5296 TemplateArgument Arg;
5297 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
5298 QualType ArgType = getTypeDeclType(TTP);
5299 if (TTP->isParameterPack())
5300 ArgType = getPackExpansionType(ArgType, std::nullopt);
5301
5302 Arg = TemplateArgument(ArgType);
5303 } else if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
5304 QualType T =
5305 NTTP->getType().getNonPackExpansionType().getNonLValueExprType(*this);
5306 // For class NTTPs, ensure we include the 'const' so the type matches that
5307 // of a real template argument.
5308 // FIXME: It would be more faithful to model this as something like an
5309 // lvalue-to-rvalue conversion applied to a const-qualified lvalue.
5310 if (T->isRecordType())
5311 T.addConst();
5312 Expr *E = new (*this) DeclRefExpr(
5313 *this, NTTP, /*RefersToEnclosingVariableOrCapture*/ false, T,
5314 Expr::getValueKindForType(NTTP->getType()), NTTP->getLocation());
5315
5316 if (NTTP->isParameterPack())
5317 E = new (*this)
5318 PackExpansionExpr(DependentTy, E, NTTP->getLocation(), std::nullopt);
5319 Arg = TemplateArgument(E);
5320 } else {
5321 auto *TTP = cast<TemplateTemplateParmDecl>(Param);
5322 if (TTP->isParameterPack())
5323 Arg = TemplateArgument(TemplateName(TTP), std::optional<unsigned>());
5324 else
5325 Arg = TemplateArgument(TemplateName(TTP));
5326 }
5327
5328 if (Param->isTemplateParameterPack())
5329 Arg = TemplateArgument::CreatePackCopy(*this, Arg);
5330
5331 return Arg;
5332}
5333
5334void
5335ASTContext::getInjectedTemplateArgs(const TemplateParameterList *Params,
5336 SmallVectorImpl<TemplateArgument> &Args) {
5337 Args.reserve(Args.size() + Params->size());
5338
5339 for (NamedDecl *Param : *Params)
5340 Args.push_back(getInjectedTemplateArg(Param));
5341}
5342
5343QualType ASTContext::getPackExpansionType(QualType Pattern,
5344 std::optional<unsigned> NumExpansions,
5345 bool ExpectPackInType) {
5346 assert((!ExpectPackInType || Pattern->containsUnexpandedParameterPack()) &&(static_cast <bool> ((!ExpectPackInType || Pattern->
containsUnexpandedParameterPack()) && "Pack expansions must expand one or more parameter packs"
) ? void (0) : __assert_fail ("(!ExpectPackInType || Pattern->containsUnexpandedParameterPack()) && \"Pack expansions must expand one or more parameter packs\""
, "clang/lib/AST/ASTContext.cpp", 5347, __extension__ __PRETTY_FUNCTION__
))
5347 "Pack expansions must expand one or more parameter packs")(static_cast <bool> ((!ExpectPackInType || Pattern->
containsUnexpandedParameterPack()) && "Pack expansions must expand one or more parameter packs"
) ? void (0) : __assert_fail ("(!ExpectPackInType || Pattern->containsUnexpandedParameterPack()) && \"Pack expansions must expand one or more parameter packs\""
, "clang/lib/AST/ASTContext.cpp", 5347, __extension__ __PRETTY_FUNCTION__
))
;
5348
5349 llvm::FoldingSetNodeID ID;
5350 PackExpansionType::Profile(ID, Pattern, NumExpansions);
5351
5352 void *InsertPos = nullptr;
5353 PackExpansionType *T = PackExpansionTypes.FindNodeOrInsertPos(ID, InsertPos);
5354 if (T)
5355 return QualType(T, 0);
5356
5357 QualType Canon;
5358 if (!Pattern.isCanonical()) {
5359 Canon = getPackExpansionType(getCanonicalType(Pattern), NumExpansions,
5360 /*ExpectPackInType=*/false);
5361
5362 // Find the insert position again, in case we inserted an element into
5363 // PackExpansionTypes and invalidated our insert position.
5364 PackExpansionTypes.FindNodeOrInsertPos(ID, InsertPos);
5365 }
5366
5367 T = new (*this, TypeAlignment)
5368 PackExpansionType(Pattern, Canon, NumExpansions);
5369 Types.push_back(T);
5370 PackExpansionTypes.InsertNode(T, InsertPos);
5371 return QualType(T, 0);
5372}
5373
5374/// CmpProtocolNames - Comparison predicate for sorting protocols
5375/// alphabetically.
5376static int CmpProtocolNames(ObjCProtocolDecl *const *LHS,
5377 ObjCProtocolDecl *const *RHS) {
5378 return DeclarationName::compare((*LHS)->getDeclName(), (*RHS)->getDeclName());
5379}
5380
5381static bool areSortedAndUniqued(ArrayRef<ObjCProtocolDecl *> Protocols) {
5382 if (Protocols.empty()) return true;
5383
5384 if (Protocols[0]->getCanonicalDecl() != Protocols[0])
5385 return false;
5386
5387 for (unsigned i = 1; i != Protocols.size(); ++i)
5388 if (CmpProtocolNames(&Protocols[i - 1], &Protocols[i]) >= 0 ||
5389 Protocols[i]->getCanonicalDecl() != Protocols[i])
5390 return false;
5391 return true;
5392}
5393
5394static void
5395SortAndUniqueProtocols(SmallVectorImpl<ObjCProtocolDecl *> &Protocols) {
5396 // Sort protocols, keyed by name.
5397 llvm::array_pod_sort(Protocols.begin(), Protocols.end(), CmpProtocolNames);
5398
5399 // Canonicalize.
5400 for (ObjCProtocolDecl *&P : Protocols)
5401 P = P->getCanonicalDecl();
5402
5403 // Remove duplicates.
5404 auto ProtocolsEnd = std::unique(Protocols.begin(), Protocols.end());
5405 Protocols.erase(ProtocolsEnd, Protocols.end());
5406}
5407
5408QualType ASTContext::getObjCObjectType(QualType BaseType,
5409 ObjCProtocolDecl * const *Protocols,
5410 unsigned NumProtocols) const {
5411 return getObjCObjectType(BaseType, {},
5412 llvm::ArrayRef(Protocols, NumProtocols),
5413 /*isKindOf=*/false);
5414}
5415
5416QualType ASTContext::getObjCObjectType(
5417 QualType baseType,
5418 ArrayRef<QualType> typeArgs,
5419 ArrayRef<ObjCProtocolDecl *> protocols,
5420 bool isKindOf) const {
5421 // If the base type is an interface and there aren't any protocols or
5422 // type arguments to add, then the interface type will do just fine.
5423 if (typeArgs.empty() && protocols.empty() && !isKindOf &&
5424 isa<ObjCInterfaceType>(baseType))
5425 return baseType;
5426
5427 // Look in the folding set for an existing type.
5428 llvm::FoldingSetNodeID ID;
5429 ObjCObjectTypeImpl::Profile(ID, baseType, typeArgs, protocols, isKindOf);
5430 void *InsertPos = nullptr;
5431 if (ObjCObjectType *QT = ObjCObjectTypes.FindNodeOrInsertPos(ID, InsertPos))
5432 return QualType(QT, 0);
5433
5434 // Determine the type arguments to be used for canonicalization,
5435 // which may be explicitly specified here or written on the base
5436 // type.
5437 ArrayRef<QualType> effectiveTypeArgs = typeArgs;
5438 if (effectiveTypeArgs.empty()) {
5439 if (const auto *baseObject = baseType->getAs<ObjCObjectType>())
5440 effectiveTypeArgs = baseObject->getTypeArgs();
5441 }
5442
5443 // Build the canonical type, which has the canonical base type and a
5444 // sorted-and-uniqued list of protocols and the type arguments
5445 // canonicalized.
5446 QualType canonical;
5447 bool typeArgsAreCanonical = llvm::all_of(
5448 effectiveTypeArgs, [&](QualType type) { return type.isCanonical(); });
5449 bool protocolsSorted = areSortedAndUniqued(protocols);
5450 if (!typeArgsAreCanonical || !protocolsSorted || !baseType.isCanonical()) {
5451 // Determine the canonical type arguments.
5452 ArrayRef<QualType> canonTypeArgs;
5453 SmallVector<QualType, 4> canonTypeArgsVec;
5454 if (!typeArgsAreCanonical) {
5455 canonTypeArgsVec.reserve(effectiveTypeArgs.size());
5456 for (auto typeArg : effectiveTypeArgs)
5457 canonTypeArgsVec.push_back(getCanonicalType(typeArg));
5458 canonTypeArgs = canonTypeArgsVec;
5459 } else {
5460 canonTypeArgs = effectiveTypeArgs;
5461 }
5462
5463 ArrayRef<ObjCProtocolDecl *> canonProtocols;
5464 SmallVector<ObjCProtocolDecl*, 8> canonProtocolsVec;
5465 if (!protocolsSorted) {
5466 canonProtocolsVec.append(protocols.begin(), protocols.end());
5467 SortAndUniqueProtocols(canonProtocolsVec);
5468 canonProtocols = canonProtocolsVec;
5469 } else {
5470 canonProtocols = protocols;
5471 }
5472
5473 canonical = getObjCObjectType(getCanonicalType(baseType), canonTypeArgs,
5474 canonProtocols, isKindOf);
5475
5476 // Regenerate InsertPos.
5477 ObjCObjectTypes.FindNodeOrInsertPos(ID, InsertPos);
5478 }
5479
5480 unsigned size = sizeof(ObjCObjectTypeImpl);
5481 size += typeArgs.size() * sizeof(QualType);
5482 size += protocols.size() * sizeof(ObjCProtocolDecl *);
5483 void *mem = Allocate(size, TypeAlignment);
5484 auto *T =
5485 new (mem) ObjCObjectTypeImpl(canonical, baseType, typeArgs, protocols,
5486 isKindOf);
5487
5488 Types.push_back(T);
5489 ObjCObjectTypes.InsertNode(T, InsertPos);
5490 return QualType(T, 0);
5491}
5492
5493/// Apply Objective-C protocol qualifiers to the given type.
5494/// If this is for the canonical type of a type parameter, we can apply
5495/// protocol qualifiers on the ObjCObjectPointerType.
5496QualType
5497ASTContext::applyObjCProtocolQualifiers(QualType type,
5498 ArrayRef<ObjCProtocolDecl *> protocols, bool &hasError,
5499 bool allowOnPointerType) const {
5500 hasError = false;
5501
5502 if (const auto *objT = dyn_cast<ObjCTypeParamType>(type.getTypePtr())) {
5503 return getObjCTypeParamType(objT->getDecl(), protocols);
5504 }
5505
5506 // Apply protocol qualifiers to ObjCObjectPointerType.
5507 if (allowOnPointerType) {
5508 if (const auto *objPtr =
5509 dyn_cast<ObjCObjectPointerType>(type.getTypePtr())) {
5510 const ObjCObjectType *objT = objPtr->getObjectType();
5511 // Merge protocol lists and construct ObjCObjectType.
5512 SmallVector<ObjCProtocolDecl*, 8> protocolsVec;
5513 protocolsVec.append(objT->qual_begin(),
5514 objT->qual_end());
5515 protocolsVec.append(protocols.begin(), protocols.end());
5516 ArrayRef<ObjCProtocolDecl *> protocols = protocolsVec;
5517 type = getObjCObjectType(
5518 objT->getBaseType(),
5519 objT->getTypeArgsAsWritten(),
5520 protocols,
5521 objT->isKindOfTypeAsWritten());
5522 return getObjCObjectPointerType(type);
5523 }
5524 }
5525
5526 // Apply protocol qualifiers to ObjCObjectType.
5527 if (const auto *objT = dyn_cast<ObjCObjectType>(type.getTypePtr())){
5528 // FIXME: Check for protocols to which the class type is already
5529 // known to conform.
5530
5531 return getObjCObjectType(objT->getBaseType(),
5532 objT->getTypeArgsAsWritten(),
5533 protocols,
5534 objT->isKindOfTypeAsWritten());
5535 }
5536
5537 // If the canonical type is ObjCObjectType, ...
5538 if (type->isObjCObjectType()) {
5539 // Silently overwrite any existing protocol qualifiers.
5540 // TODO: determine whether that's the right thing to do.
5541
5542 // FIXME: Check for protocols to which the class type is already
5543 // known to conform.
5544 return getObjCObjectType(type, {}, protocols, false);
5545 }
5546
5547 // id<protocol-list>
5548 if (type->isObjCIdType()) {
5549 const auto *objPtr = type->castAs<ObjCObjectPointerType>();
5550 type = getObjCObjectType(ObjCBuiltinIdTy, {}, protocols,
5551 objPtr->isKindOfType());
5552 return getObjCObjectPointerType(type);
5553 }
5554
5555 // Class<protocol-list>
5556 if (type->isObjCClassType()) {
5557 const auto *objPtr = type->castAs<ObjCObjectPointerType>();
5558 type = getObjCObjectType(ObjCBuiltinClassTy, {}, protocols,
5559 objPtr->isKindOfType());
5560 return getObjCObjectPointerType(type);
5561 }
5562
5563 hasError = true;
5564 return type;
5565}
5566
5567QualType
5568ASTContext::getObjCTypeParamType(const ObjCTypeParamDecl *Decl,
5569 ArrayRef<ObjCProtocolDecl *> protocols) const {
5570 // Look in the folding set for an existing type.
5571 llvm::FoldingSetNodeID ID;
5572 ObjCTypeParamType::Profile(ID, Decl, Decl->getUnderlyingType(), protocols);
5573 void *InsertPos = nullptr;
5574 if (ObjCTypeParamType *TypeParam =
5575 ObjCTypeParamTypes.FindNodeOrInsertPos(ID, InsertPos))
5576 return QualType(TypeParam, 0);
5577
5578 // We canonicalize to the underlying type.
5579 QualType Canonical = getCanonicalType(Decl->getUnderlyingType());
5580 if (!protocols.empty()) {
5581 // Apply the protocol qualifers.
5582 bool hasError;
5583 Canonical = getCanonicalType(applyObjCProtocolQualifiers(
5584 Canonical, protocols, hasError, true /*allowOnPointerType*/));
5585 assert(!hasError && "Error when apply protocol qualifier to bound type")(static_cast <bool> (!hasError && "Error when apply protocol qualifier to bound type"
) ? void (0) : __assert_fail ("!hasError && \"Error when apply protocol qualifier to bound type\""
, "clang/lib/AST/ASTContext.cpp", 5585, __extension__ __PRETTY_FUNCTION__
))
;
5586 }
5587
5588 unsigned size = sizeof(ObjCTypeParamType);
5589 size += protocols.size() * sizeof(ObjCProtocolDecl *);
5590 void *mem = Allocate(size, TypeAlignment);
5591 auto *newType = new (mem) ObjCTypeParamType(Decl, Canonical, protocols);
5592
5593 Types.push_back(newType);
5594 ObjCTypeParamTypes.InsertNode(newType, InsertPos);
5595 return QualType(newType, 0);
5596}
5597
5598void ASTContext::adjustObjCTypeParamBoundType(const ObjCTypeParamDecl *Orig,
5599 ObjCTypeParamDecl *New) const {
5600 New->setTypeSourceInfo(getTrivialTypeSourceInfo(Orig->getUnderlyingType()));
5601 // Update TypeForDecl after updating TypeSourceInfo.
5602 auto NewTypeParamTy = cast<ObjCTypeParamType>(New->getTypeForDecl());
5603 SmallVector<ObjCProtocolDecl *, 8> protocols;
5604 protocols.append(NewTypeParamTy->qual_begin(), NewTypeParamTy->qual_end());
5605 QualType UpdatedTy = getObjCTypeParamType(New, protocols);
5606 New->setTypeForDecl(UpdatedTy.getTypePtr());
5607}
5608
5609