Bug Summary

File:build/llvm-toolchain-snapshot-16~++20220929111209+ac2e2d659819/clang/tools/libclang/CXType.cpp
Warning:line 1046, column 8
Called C++ object pointer is null

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 CXType.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/llvm-toolchain-snapshot-16~++20220929111209+ac2e2d659819/build-llvm/tools/clang/stage2-bins -resource-dir /usr/lib/llvm-16/lib/clang/16.0.0 -D _CINDEX_LIB_ -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I tools/clang/tools/libclang -I /build/llvm-toolchain-snapshot-16~++20220929111209+ac2e2d659819/clang/tools/libclang -I /build/llvm-toolchain-snapshot-16~++20220929111209+ac2e2d659819/clang/include -I tools/clang/include -I include -I /build/llvm-toolchain-snapshot-16~++20220929111209+ac2e2d659819/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-16/lib/clang/16.0.0/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/llvm-toolchain-snapshot-16~++20220929111209+ac2e2d659819/build-llvm/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -fmacro-prefix-map=/build/llvm-toolchain-snapshot-16~++20220929111209+ac2e2d659819/= -fcoverage-prefix-map=/build/llvm-toolchain-snapshot-16~++20220929111209+ac2e2d659819/build-llvm/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -fcoverage-prefix-map=/build/llvm-toolchain-snapshot-16~++20220929111209+ac2e2d659819/= -O2 -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/llvm-toolchain-snapshot-16~++20220929111209+ac2e2d659819/build-llvm/tools/clang/stage2-bins -fdebug-prefix-map=/build/llvm-toolchain-snapshot-16~++20220929111209+ac2e2d659819/build-llvm/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -fdebug-prefix-map=/build/llvm-toolchain-snapshot-16~++20220929111209+ac2e2d659819/= -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-2022-09-29-125212-15910-1 -x c++ /build/llvm-toolchain-snapshot-16~++20220929111209+ac2e2d659819/clang/tools/libclang/CXType.cpp
1//===- CXType.cpp - Implements 'CXTypes' aspect of libclang ---------------===//
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 'CXTypes' API hooks in the Clang-C library.
10//
11//===--------------------------------------------------------------------===//
12
13#include "CIndexer.h"
14#include "CXCursor.h"
15#include "CXString.h"
16#include "CXTranslationUnit.h"
17#include "CXType.h"
18#include "clang/AST/Decl.h"
19#include "clang/AST/DeclObjC.h"
20#include "clang/AST/DeclTemplate.h"
21#include "clang/AST/Expr.h"
22#include "clang/AST/Type.h"
23#include "clang/Basic/AddressSpaces.h"
24#include "clang/Frontend/ASTUnit.h"
25
26using namespace clang;
27
28static CXTypeKind GetBuiltinTypeKind(const BuiltinType *BT) {
29#define BTCASE(K) case BuiltinType::K: return CXType_##K
30 switch (BT->getKind()) {
31 BTCASE(Void);
32 BTCASE(Bool);
33 BTCASE(Char_U);
34 BTCASE(UChar);
35 BTCASE(Char16);
36 BTCASE(Char32);
37 BTCASE(UShort);
38 BTCASE(UInt);
39 BTCASE(ULong);
40 BTCASE(ULongLong);
41 BTCASE(UInt128);
42 BTCASE(Char_S);
43 BTCASE(SChar);
44 case BuiltinType::WChar_S: return CXType_WChar;
45 case BuiltinType::WChar_U: return CXType_WChar;
46 BTCASE(Short);
47 BTCASE(Int);
48 BTCASE(Long);
49 BTCASE(LongLong);
50 BTCASE(Int128);
51 BTCASE(Half);
52 BTCASE(Float);
53 BTCASE(Double);
54 BTCASE(LongDouble);
55 BTCASE(ShortAccum);
56 BTCASE(Accum);
57 BTCASE(LongAccum);
58 BTCASE(UShortAccum);
59 BTCASE(UAccum);
60 BTCASE(ULongAccum);
61 BTCASE(Float16);
62 BTCASE(Float128);
63 BTCASE(Ibm128);
64 BTCASE(NullPtr);
65 BTCASE(Overload);
66 BTCASE(Dependent);
67 BTCASE(ObjCId);
68 BTCASE(ObjCClass);
69 BTCASE(ObjCSel);
70#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) BTCASE(Id);
71#include "clang/Basic/OpenCLImageTypes.def"
72#undef IMAGE_TYPE
73#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) BTCASE(Id);
74#include "clang/Basic/OpenCLExtensionTypes.def"
75 BTCASE(OCLSampler);
76 BTCASE(OCLEvent);
77 BTCASE(OCLQueue);
78 BTCASE(OCLReserveID);
79 default:
80 return CXType_Unexposed;
81 }
82#undef BTCASE
83}
84
85static CXTypeKind GetTypeKind(QualType T) {
86 const Type *TP = T.getTypePtrOrNull();
87 if (!TP)
88 return CXType_Invalid;
89
90#define TKCASE(K) case Type::K: return CXType_##K
91 switch (TP->getTypeClass()) {
92 case Type::Builtin:
93 return GetBuiltinTypeKind(cast<BuiltinType>(TP));
94 TKCASE(Complex);
95 TKCASE(Pointer);
96 TKCASE(BlockPointer);
97 TKCASE(LValueReference);
98 TKCASE(RValueReference);
99 TKCASE(Record);
100 TKCASE(Enum);
101 TKCASE(Typedef);
102 TKCASE(ObjCInterface);
103 TKCASE(ObjCObject);
104 TKCASE(ObjCObjectPointer);
105 TKCASE(ObjCTypeParam);
106 TKCASE(FunctionNoProto);
107 TKCASE(FunctionProto);
108 TKCASE(ConstantArray);
109 TKCASE(IncompleteArray);
110 TKCASE(VariableArray);
111 TKCASE(DependentSizedArray);
112 TKCASE(Vector);
113 TKCASE(ExtVector);
114 TKCASE(MemberPointer);
115 TKCASE(Auto);
116 TKCASE(Elaborated);
117 TKCASE(Pipe);
118 TKCASE(Attributed);
119 TKCASE(BTFTagAttributed);
120 TKCASE(Atomic);
121 default:
122 return CXType_Unexposed;
123 }
124#undef TKCASE
125}
126
127
128CXType cxtype::MakeCXType(QualType T, CXTranslationUnit TU) {
129 CXTypeKind TK = CXType_Invalid;
130
131 if (TU && !T.isNull()) {
132 // Handle attributed types as the original type
133 if (auto *ATT = T->getAs<AttributedType>()) {
134 if (!(TU->ParsingOptions & CXTranslationUnit_IncludeAttributedTypes)) {
135 // Return the equivalent type which represents the canonically
136 // equivalent type.
137 return MakeCXType(ATT->getEquivalentType(), TU);
138 }
139 }
140 if (auto *ATT = T->getAs<BTFTagAttributedType>()) {
141 if (!(TU->ParsingOptions & CXTranslationUnit_IncludeAttributedTypes))
142 return MakeCXType(ATT->getWrappedType(), TU);
143 }
144 // Handle paren types as the original type
145 if (auto *PTT = T->getAs<ParenType>()) {
146 return MakeCXType(PTT->getInnerType(), TU);
147 }
148
149 ASTContext &Ctx = cxtu::getASTUnit(TU)->getASTContext();
150 if (Ctx.getLangOpts().ObjC) {
151 QualType UnqualT = T.getUnqualifiedType();
152 if (Ctx.isObjCIdType(UnqualT))
153 TK = CXType_ObjCId;
154 else if (Ctx.isObjCClassType(UnqualT))
155 TK = CXType_ObjCClass;
156 else if (Ctx.isObjCSelType(UnqualT))
157 TK = CXType_ObjCSel;
158 }
159
160 /* Handle decayed types as the original type */
161 if (const DecayedType *DT = T->getAs<DecayedType>()) {
162 return MakeCXType(DT->getOriginalType(), TU);
163 }
164 }
165 if (TK == CXType_Invalid)
166 TK = GetTypeKind(T);
167
168 CXType CT = { TK, { TK == CXType_Invalid ? nullptr
169 : T.getAsOpaquePtr(), TU } };
170 return CT;
171}
172
173using cxtype::MakeCXType;
174
175static inline QualType GetQualType(CXType CT) {
176 return QualType::getFromOpaquePtr(CT.data[0]);
177}
178
179static inline CXTranslationUnit GetTU(CXType CT) {
180 return static_cast<CXTranslationUnit>(CT.data[1]);
181}
182
183static Optional<ArrayRef<TemplateArgument>>
184GetTemplateArguments(QualType Type) {
185 assert(!Type.isNull())(static_cast <bool> (!Type.isNull()) ? void (0) : __assert_fail
("!Type.isNull()", "clang/tools/libclang/CXType.cpp", 185, __extension__
__PRETTY_FUNCTION__))
;
186 if (const auto *Specialization = Type->getAs<TemplateSpecializationType>())
187 return Specialization->template_arguments();
188
189 if (const auto *RecordDecl = Type->getAsCXXRecordDecl()) {
190 const auto *TemplateDecl =
191 dyn_cast<ClassTemplateSpecializationDecl>(RecordDecl);
192 if (TemplateDecl)
193 return TemplateDecl->getTemplateArgs().asArray();
194 }
195
196 return None;
197}
198
199static Optional<QualType> TemplateArgumentToQualType(const TemplateArgument &A) {
200 if (A.getKind() == TemplateArgument::Type)
201 return A.getAsType();
202 return None;
203}
204
205static Optional<QualType>
206FindTemplateArgumentTypeAt(ArrayRef<TemplateArgument> TA, unsigned index) {
207 unsigned current = 0;
208 for (const auto &A : TA) {
209 if (A.getKind() == TemplateArgument::Pack) {
210 if (index < current + A.pack_size())
211 return TemplateArgumentToQualType(A.getPackAsArray()[index - current]);
212 current += A.pack_size();
213 continue;
214 }
215 if (current == index)
216 return TemplateArgumentToQualType(A);
217 current++;
218 }
219 return None;
220}
221
222CXType clang_getCursorType(CXCursor C) {
223 using namespace cxcursor;
224
225 CXTranslationUnit TU = cxcursor::getCursorTU(C);
226 if (!TU)
227 return MakeCXType(QualType(), TU);
228
229 ASTContext &Context = cxtu::getASTUnit(TU)->getASTContext();
230 if (clang_isExpression(C.kind)) {
231 QualType T = cxcursor::getCursorExpr(C)->getType();
232 return MakeCXType(T, TU);
233 }
234
235 if (clang_isDeclaration(C.kind)) {
236 const Decl *D = cxcursor::getCursorDecl(C);
237 if (!D)
238 return MakeCXType(QualType(), TU);
239
240 if (const TypeDecl *TD = dyn_cast<TypeDecl>(D))
241 return MakeCXType(Context.getTypeDeclType(TD), TU);
242 if (const ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D))
243 return MakeCXType(Context.getObjCInterfaceType(ID), TU);
244 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D))
245 return MakeCXType(DD->getType(), TU);
246 if (const ValueDecl *VD = dyn_cast<ValueDecl>(D))
247 return MakeCXType(VD->getType(), TU);
248 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
249 return MakeCXType(PD->getType(), TU);
250 if (const FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(D))
251 return MakeCXType(FTD->getTemplatedDecl()->getType(), TU);
252 return MakeCXType(QualType(), TU);
253 }
254
255 if (clang_isReference(C.kind)) {
256 switch (C.kind) {
257 case CXCursor_ObjCSuperClassRef: {
258 QualType T
259 = Context.getObjCInterfaceType(getCursorObjCSuperClassRef(C).first);
260 return MakeCXType(T, TU);
261 }
262
263 case CXCursor_ObjCClassRef: {
264 QualType T = Context.getObjCInterfaceType(getCursorObjCClassRef(C).first);
265 return MakeCXType(T, TU);
266 }
267
268 case CXCursor_TypeRef: {
269 QualType T = Context.getTypeDeclType(getCursorTypeRef(C).first);
270 return MakeCXType(T, TU);
271
272 }
273
274 case CXCursor_CXXBaseSpecifier:
275 return cxtype::MakeCXType(getCursorCXXBaseSpecifier(C)->getType(), TU);
276
277 case CXCursor_MemberRef:
278 return cxtype::MakeCXType(getCursorMemberRef(C).first->getType(), TU);
279
280 case CXCursor_VariableRef:
281 return cxtype::MakeCXType(getCursorVariableRef(C).first->getType(), TU);
282
283 case CXCursor_ObjCProtocolRef:
284 case CXCursor_TemplateRef:
285 case CXCursor_NamespaceRef:
286 case CXCursor_OverloadedDeclRef:
287 default:
288 break;
289 }
290
291 return MakeCXType(QualType(), TU);
292 }
293
294 return MakeCXType(QualType(), TU);
295}
296
297CXString clang_getTypeSpelling(CXType CT) {
298 QualType T = GetQualType(CT);
299 if (T.isNull())
300 return cxstring::createEmpty();
301
302 CXTranslationUnit TU = GetTU(CT);
303 SmallString<64> Str;
304 llvm::raw_svector_ostream OS(Str);
305 PrintingPolicy PP(cxtu::getASTUnit(TU)->getASTContext().getLangOpts());
306
307 T.print(OS, PP);
308
309 return cxstring::createDup(OS.str());
310}
311
312CXType clang_getTypedefDeclUnderlyingType(CXCursor C) {
313 using namespace cxcursor;
314 CXTranslationUnit TU = cxcursor::getCursorTU(C);
315
316 if (clang_isDeclaration(C.kind)) {
317 const Decl *D = cxcursor::getCursorDecl(C);
318
319 if (const TypedefNameDecl *TD = dyn_cast_or_null<TypedefNameDecl>(D)) {
320 QualType T = TD->getUnderlyingType();
321 return MakeCXType(T, TU);
322 }
323
324 return MakeCXType(QualType(), TU);
325 }
326
327 return MakeCXType(QualType(), TU);
328}
329
330CXType clang_getEnumDeclIntegerType(CXCursor C) {
331 using namespace cxcursor;
332 CXTranslationUnit TU = cxcursor::getCursorTU(C);
333
334 if (clang_isDeclaration(C.kind)) {
335 const Decl *D = cxcursor::getCursorDecl(C);
336
337 if (const EnumDecl *TD = dyn_cast_or_null<EnumDecl>(D)) {
338 QualType T = TD->getIntegerType();
339 return MakeCXType(T, TU);
340 }
341
342 return MakeCXType(QualType(), TU);
343 }
344
345 return MakeCXType(QualType(), TU);
346}
347
348long long clang_getEnumConstantDeclValue(CXCursor C) {
349 using namespace cxcursor;
350
351 if (clang_isDeclaration(C.kind)) {
352 const Decl *D = cxcursor::getCursorDecl(C);
353
354 if (const EnumConstantDecl *TD = dyn_cast_or_null<EnumConstantDecl>(D)) {
355 return TD->getInitVal().getSExtValue();
356 }
357
358 return LLONG_MIN(-9223372036854775807LL -1LL);
359 }
360
361 return LLONG_MIN(-9223372036854775807LL -1LL);
362}
363
364unsigned long long clang_getEnumConstantDeclUnsignedValue(CXCursor C) {
365 using namespace cxcursor;
366
367 if (clang_isDeclaration(C.kind)) {
368 const Decl *D = cxcursor::getCursorDecl(C);
369
370 if (const EnumConstantDecl *TD = dyn_cast_or_null<EnumConstantDecl>(D)) {
371 return TD->getInitVal().getZExtValue();
372 }
373
374 return ULLONG_MAX(9223372036854775807LL*2ULL+1ULL);
375 }
376
377 return ULLONG_MAX(9223372036854775807LL*2ULL+1ULL);
378}
379
380int clang_getFieldDeclBitWidth(CXCursor C) {
381 using namespace cxcursor;
382
383 if (clang_isDeclaration(C.kind)) {
384 const Decl *D = getCursorDecl(C);
385
386 if (const FieldDecl *FD = dyn_cast_or_null<FieldDecl>(D)) {
387 if (FD->isBitField())
388 return FD->getBitWidthValue(getCursorContext(C));
389 }
390 }
391
392 return -1;
393}
394
395CXType clang_getCanonicalType(CXType CT) {
396 if (CT.kind == CXType_Invalid)
397 return CT;
398
399 QualType T = GetQualType(CT);
400 CXTranslationUnit TU = GetTU(CT);
401
402 if (T.isNull())
403 return MakeCXType(QualType(), GetTU(CT));
404
405 return MakeCXType(cxtu::getASTUnit(TU)->getASTContext()
406 .getCanonicalType(T),
407 TU);
408}
409
410unsigned clang_isConstQualifiedType(CXType CT) {
411 QualType T = GetQualType(CT);
412 return T.isLocalConstQualified();
413}
414
415unsigned clang_isVolatileQualifiedType(CXType CT) {
416 QualType T = GetQualType(CT);
417 return T.isLocalVolatileQualified();
418}
419
420unsigned clang_isRestrictQualifiedType(CXType CT) {
421 QualType T = GetQualType(CT);
422 return T.isLocalRestrictQualified();
423}
424
425unsigned clang_getAddressSpace(CXType CT) {
426 QualType T = GetQualType(CT);
427
428 // For non language-specific address space, use separate helper function.
429 if (T.getAddressSpace() >= LangAS::FirstTargetAddressSpace) {
430 return T.getQualifiers().getAddressSpaceAttributePrintValue();
431 }
432 // FIXME: this function returns either a LangAS or a target AS
433 // Those values can overlap which makes this function rather unpredictable
434 // for any caller
435 return (unsigned)T.getAddressSpace();
436}
437
438CXString clang_getTypedefName(CXType CT) {
439 QualType T = GetQualType(CT);
440 const TypedefType *TT = T->getAs<TypedefType>();
441 if (TT) {
442 TypedefNameDecl *TD = TT->getDecl();
443 if (TD)
444 return cxstring::createDup(TD->getNameAsString().c_str());
445 }
446 return cxstring::createEmpty();
447}
448
449CXType clang_getPointeeType(CXType CT) {
450 QualType T = GetQualType(CT);
451 const Type *TP = T.getTypePtrOrNull();
452
453 if (!TP)
454 return MakeCXType(QualType(), GetTU(CT));
455
456try_again:
457 switch (TP->getTypeClass()) {
458 case Type::Pointer:
459 T = cast<PointerType>(TP)->getPointeeType();
460 break;
461 case Type::BlockPointer:
462 T = cast<BlockPointerType>(TP)->getPointeeType();
463 break;
464 case Type::LValueReference:
465 case Type::RValueReference:
466 T = cast<ReferenceType>(TP)->getPointeeType();
467 break;
468 case Type::ObjCObjectPointer:
469 T = cast<ObjCObjectPointerType>(TP)->getPointeeType();
470 break;
471 case Type::MemberPointer:
472 T = cast<MemberPointerType>(TP)->getPointeeType();
473 break;
474 case Type::Auto:
475 case Type::DeducedTemplateSpecialization:
476 TP = cast<DeducedType>(TP)->getDeducedType().getTypePtrOrNull();
477 if (TP)
478 goto try_again;
479 break;
480 default:
481 T = QualType();
482 break;
483 }
484 return MakeCXType(T, GetTU(CT));
485}
486
487CXType clang_getUnqualifiedType(CXType CT) {
488 return MakeCXType(GetQualType(CT).getUnqualifiedType(), GetTU(CT));
489}
490
491CXType clang_getNonReferenceType(CXType CT) {
492 return MakeCXType(GetQualType(CT).getNonReferenceType(), GetTU(CT));
493}
494
495CXCursor clang_getTypeDeclaration(CXType CT) {
496 if (CT.kind == CXType_Invalid)
497 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
498
499 QualType T = GetQualType(CT);
500 const Type *TP = T.getTypePtrOrNull();
501
502 if (!TP)
503 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
504
505 Decl *D = nullptr;
506
507try_again:
508 switch (TP->getTypeClass()) {
509 case Type::Typedef:
510 D = cast<TypedefType>(TP)->getDecl();
511 break;
512 case Type::ObjCObject:
513 D = cast<ObjCObjectType>(TP)->getInterface();
514 break;
515 case Type::ObjCInterface:
516 D = cast<ObjCInterfaceType>(TP)->getDecl();
517 break;
518 case Type::Record:
519 case Type::Enum:
520 D = cast<TagType>(TP)->getDecl();
521 break;
522 case Type::TemplateSpecialization:
523 if (const RecordType *Record = TP->getAs<RecordType>())
524 D = Record->getDecl();
525 else
526 D = cast<TemplateSpecializationType>(TP)->getTemplateName()
527 .getAsTemplateDecl();
528 break;
529
530 case Type::Auto:
531 case Type::DeducedTemplateSpecialization:
532 TP = cast<DeducedType>(TP)->getDeducedType().getTypePtrOrNull();
533 if (TP)
534 goto try_again;
535 break;
536
537 case Type::InjectedClassName:
538 D = cast<InjectedClassNameType>(TP)->getDecl();
539 break;
540
541 // FIXME: Template type parameters!
542
543 case Type::Elaborated:
544 TP = cast<ElaboratedType>(TP)->getNamedType().getTypePtrOrNull();
545 goto try_again;
546
547 default:
548 break;
549 }
550
551 if (!D)
552 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
553
554 return cxcursor::MakeCXCursor(D, GetTU(CT));
555}
556
557CXString clang_getTypeKindSpelling(enum CXTypeKind K) {
558 const char *s = nullptr;
559#define TKIND(X) case CXType_##X: s = "" #X ""; break
560 switch (K) {
561 TKIND(Invalid);
562 TKIND(Unexposed);
563 TKIND(Void);
564 TKIND(Bool);
565 TKIND(Char_U);
566 TKIND(UChar);
567 TKIND(Char16);
568 TKIND(Char32);
569 TKIND(UShort);
570 TKIND(UInt);
571 TKIND(ULong);
572 TKIND(ULongLong);
573 TKIND(UInt128);
574 TKIND(Char_S);
575 TKIND(SChar);
576 case CXType_WChar: s = "WChar"; break;
577 TKIND(Short);
578 TKIND(Int);
579 TKIND(Long);
580 TKIND(LongLong);
581 TKIND(Int128);
582 TKIND(Half);
583 TKIND(Float);
584 TKIND(Double);
585 TKIND(LongDouble);
586 TKIND(ShortAccum);
587 TKIND(Accum);
588 TKIND(LongAccum);
589 TKIND(UShortAccum);
590 TKIND(UAccum);
591 TKIND(ULongAccum);
592 TKIND(Float16);
593 TKIND(Float128);
594 TKIND(Ibm128);
595 TKIND(NullPtr);
596 TKIND(Overload);
597 TKIND(Dependent);
598 TKIND(ObjCId);
599 TKIND(ObjCClass);
600 TKIND(ObjCSel);
601 TKIND(Complex);
602 TKIND(Pointer);
603 TKIND(BlockPointer);
604 TKIND(LValueReference);
605 TKIND(RValueReference);
606 TKIND(Record);
607 TKIND(Enum);
608 TKIND(Typedef);
609 TKIND(ObjCInterface);
610 TKIND(ObjCObject);
611 TKIND(ObjCObjectPointer);
612 TKIND(ObjCTypeParam);
613 TKIND(FunctionNoProto);
614 TKIND(FunctionProto);
615 TKIND(ConstantArray);
616 TKIND(IncompleteArray);
617 TKIND(VariableArray);
618 TKIND(DependentSizedArray);
619 TKIND(Vector);
620 TKIND(ExtVector);
621 TKIND(MemberPointer);
622 TKIND(Auto);
623 TKIND(Elaborated);
624 TKIND(Pipe);
625 TKIND(Attributed);
626 TKIND(BTFTagAttributed);
627 TKIND(BFloat16);
628#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) TKIND(Id);
629#include "clang/Basic/OpenCLImageTypes.def"
630#undef IMAGE_TYPE
631#define EXT_OPAQUE_TYPE(ExtTYpe, Id, Ext) TKIND(Id);
632#include "clang/Basic/OpenCLExtensionTypes.def"
633 TKIND(OCLSampler);
634 TKIND(OCLEvent);
635 TKIND(OCLQueue);
636 TKIND(OCLReserveID);
637 TKIND(Atomic);
638 }
639#undef TKIND
640 return cxstring::createRef(s);
641}
642
643unsigned clang_equalTypes(CXType A, CXType B) {
644 return A.data[0] == B.data[0] && A.data[1] == B.data[1];
645}
646
647unsigned clang_isFunctionTypeVariadic(CXType X) {
648 QualType T = GetQualType(X);
649 if (T.isNull())
650 return 0;
651
652 if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>())
653 return (unsigned)FD->isVariadic();
654
655 if (T->getAs<FunctionNoProtoType>())
656 return 1;
657
658 return 0;
659}
660
661CXCallingConv clang_getFunctionTypeCallingConv(CXType X) {
662 QualType T = GetQualType(X);
663 if (T.isNull())
664 return CXCallingConv_Invalid;
665
666 if (const FunctionType *FD = T->getAs<FunctionType>()) {
667#define TCALLINGCONV(X) case CC_##X: return CXCallingConv_##X
668 switch (FD->getCallConv()) {
669 TCALLINGCONV(C);
670 TCALLINGCONV(X86StdCall);
671 TCALLINGCONV(X86FastCall);
672 TCALLINGCONV(X86ThisCall);
673 TCALLINGCONV(X86Pascal);
674 TCALLINGCONV(X86RegCall);
675 TCALLINGCONV(X86VectorCall);
676 TCALLINGCONV(AArch64VectorCall);
677 TCALLINGCONV(AArch64SVEPCS);
678 TCALLINGCONV(Win64);
679 TCALLINGCONV(X86_64SysV);
680 TCALLINGCONV(AAPCS);
681 TCALLINGCONV(AAPCS_VFP);
682 TCALLINGCONV(IntelOclBicc);
683 TCALLINGCONV(Swift);
684 TCALLINGCONV(SwiftAsync);
685 TCALLINGCONV(PreserveMost);
686 TCALLINGCONV(PreserveAll);
687 case CC_SpirFunction: return CXCallingConv_Unexposed;
688 case CC_AMDGPUKernelCall: return CXCallingConv_Unexposed;
689 case CC_OpenCLKernel: return CXCallingConv_Unexposed;
690 break;
691 }
692#undef TCALLINGCONV
693 }
694
695 return CXCallingConv_Invalid;
696}
697
698int clang_getNumArgTypes(CXType X) {
699 QualType T = GetQualType(X);
700 if (T.isNull())
701 return -1;
702
703 if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) {
704 return FD->getNumParams();
705 }
706
707 if (T->getAs<FunctionNoProtoType>()) {
708 return 0;
709 }
710
711 return -1;
712}
713
714CXType clang_getArgType(CXType X, unsigned i) {
715 QualType T = GetQualType(X);
716 if (T.isNull())
717 return MakeCXType(QualType(), GetTU(X));
718
719 if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) {
720 unsigned numParams = FD->getNumParams();
721 if (i >= numParams)
722 return MakeCXType(QualType(), GetTU(X));
723
724 return MakeCXType(FD->getParamType(i), GetTU(X));
725 }
726
727 return MakeCXType(QualType(), GetTU(X));
728}
729
730CXType clang_getResultType(CXType X) {
731 QualType T = GetQualType(X);
732 if (T.isNull())
733 return MakeCXType(QualType(), GetTU(X));
734
735 if (const FunctionType *FD = T->getAs<FunctionType>())
736 return MakeCXType(FD->getReturnType(), GetTU(X));
737
738 return MakeCXType(QualType(), GetTU(X));
739}
740
741CXType clang_getCursorResultType(CXCursor C) {
742 if (clang_isDeclaration(C.kind)) {
743 const Decl *D = cxcursor::getCursorDecl(C);
744 if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
745 return MakeCXType(MD->getReturnType(), cxcursor::getCursorTU(C));
746
747 return clang_getResultType(clang_getCursorType(C));
748 }
749
750 return MakeCXType(QualType(), cxcursor::getCursorTU(C));
751}
752
753// FIXME: We should expose the canThrow(...) result instead of the EST.
754static CXCursor_ExceptionSpecificationKind
755getExternalExceptionSpecificationKind(ExceptionSpecificationType EST) {
756 switch (EST) {
757 case EST_None:
758 return CXCursor_ExceptionSpecificationKind_None;
759 case EST_DynamicNone:
760 return CXCursor_ExceptionSpecificationKind_DynamicNone;
761 case EST_Dynamic:
762 return CXCursor_ExceptionSpecificationKind_Dynamic;
763 case EST_MSAny:
764 return CXCursor_ExceptionSpecificationKind_MSAny;
765 case EST_BasicNoexcept:
766 return CXCursor_ExceptionSpecificationKind_BasicNoexcept;
767 case EST_NoThrow:
768 return CXCursor_ExceptionSpecificationKind_NoThrow;
769 case EST_NoexceptFalse:
770 case EST_NoexceptTrue:
771 case EST_DependentNoexcept:
772 return CXCursor_ExceptionSpecificationKind_ComputedNoexcept;
773 case EST_Unevaluated:
774 return CXCursor_ExceptionSpecificationKind_Unevaluated;
775 case EST_Uninstantiated:
776 return CXCursor_ExceptionSpecificationKind_Uninstantiated;
777 case EST_Unparsed:
778 return CXCursor_ExceptionSpecificationKind_Unparsed;
779 }
780 llvm_unreachable("invalid EST value")::llvm::llvm_unreachable_internal("invalid EST value", "clang/tools/libclang/CXType.cpp"
, 780)
;
781}
782
783int clang_getExceptionSpecificationType(CXType X) {
784 QualType T = GetQualType(X);
785 if (T.isNull())
786 return -1;
787
788 if (const auto *FD = T->getAs<FunctionProtoType>())
789 return getExternalExceptionSpecificationKind(FD->getExceptionSpecType());
790
791 return -1;
792}
793
794int clang_getCursorExceptionSpecificationType(CXCursor C) {
795 if (clang_isDeclaration(C.kind))
796 return clang_getExceptionSpecificationType(clang_getCursorType(C));
797
798 return -1;
799}
800
801unsigned clang_isPODType(CXType X) {
802 QualType T = GetQualType(X);
803 if (T.isNull())
804 return 0;
805
806 CXTranslationUnit TU = GetTU(X);
807
808 return T.isPODType(cxtu::getASTUnit(TU)->getASTContext()) ? 1 : 0;
809}
810
811CXType clang_getElementType(CXType CT) {
812 QualType ET = QualType();
813 QualType T = GetQualType(CT);
814 const Type *TP = T.getTypePtrOrNull();
815
816 if (TP) {
817 switch (TP->getTypeClass()) {
818 case Type::ConstantArray:
819 ET = cast<ConstantArrayType> (TP)->getElementType();
820 break;
821 case Type::IncompleteArray:
822 ET = cast<IncompleteArrayType> (TP)->getElementType();
823 break;
824 case Type::VariableArray:
825 ET = cast<VariableArrayType> (TP)->getElementType();
826 break;
827 case Type::DependentSizedArray:
828 ET = cast<DependentSizedArrayType> (TP)->getElementType();
829 break;
830 case Type::Vector:
831 ET = cast<VectorType> (TP)->getElementType();
832 break;
833 case Type::ExtVector:
834 ET = cast<ExtVectorType>(TP)->getElementType();
835 break;
836 case Type::Complex:
837 ET = cast<ComplexType> (TP)->getElementType();
838 break;
839 default:
840 break;
841 }
842 }
843 return MakeCXType(ET, GetTU(CT));
844}
845
846long long clang_getNumElements(CXType CT) {
847 long long result = -1;
848 QualType T = GetQualType(CT);
849 const Type *TP = T.getTypePtrOrNull();
850
851 if (TP) {
852 switch (TP->getTypeClass()) {
853 case Type::ConstantArray:
854 result = cast<ConstantArrayType> (TP)->getSize().getSExtValue();
855 break;
856 case Type::Vector:
857 result = cast<VectorType> (TP)->getNumElements();
858 break;
859 case Type::ExtVector:
860 result = cast<ExtVectorType>(TP)->getNumElements();
861 break;
862 default:
863 break;
864 }
865 }
866 return result;
867}
868
869CXType clang_getArrayElementType(CXType CT) {
870 QualType ET = QualType();
871 QualType T = GetQualType(CT);
872 const Type *TP = T.getTypePtrOrNull();
873
874 if (TP) {
875 switch (TP->getTypeClass()) {
876 case Type::ConstantArray:
877 ET = cast<ConstantArrayType> (TP)->getElementType();
878 break;
879 case Type::IncompleteArray:
880 ET = cast<IncompleteArrayType> (TP)->getElementType();
881 break;
882 case Type::VariableArray:
883 ET = cast<VariableArrayType> (TP)->getElementType();
884 break;
885 case Type::DependentSizedArray:
886 ET = cast<DependentSizedArrayType> (TP)->getElementType();
887 break;
888 default:
889 break;
890 }
891 }
892 return MakeCXType(ET, GetTU(CT));
893}
894
895long long clang_getArraySize(CXType CT) {
896 long long result = -1;
897 QualType T = GetQualType(CT);
898 const Type *TP = T.getTypePtrOrNull();
899
900 if (TP) {
901 switch (TP->getTypeClass()) {
902 case Type::ConstantArray:
903 result = cast<ConstantArrayType> (TP)->getSize().getSExtValue();
904 break;
905 default:
906 break;
907 }
908 }
909 return result;
910}
911
912static bool isIncompleteTypeWithAlignment(QualType QT) {
913 return QT->isIncompleteArrayType() || !QT->isIncompleteType();
914}
915
916long long clang_Type_getAlignOf(CXType T) {
917 if (T.kind == CXType_Invalid)
918 return CXTypeLayoutError_Invalid;
919 ASTContext &Ctx = cxtu::getASTUnit(GetTU(T))->getASTContext();
920 QualType QT = GetQualType(T);
921 // [expr.alignof] p1: return size_t value for complete object type, reference
922 // or array.
923 // [expr.alignof] p3: if reference type, return size of referenced type
924 if (QT->isReferenceType())
925 QT = QT.getNonReferenceType();
926 if (!isIncompleteTypeWithAlignment(QT))
927 return CXTypeLayoutError_Incomplete;
928 if (QT->isDependentType())
929 return CXTypeLayoutError_Dependent;
930 if (const auto *Deduced = dyn_cast<DeducedType>(QT))
931 if (Deduced->getDeducedType().isNull())
932 return CXTypeLayoutError_Undeduced;
933 // Exceptions by GCC extension - see ASTContext.cpp:1313 getTypeInfoImpl
934 // if (QT->isFunctionType()) return 4; // Bug #15511 - should be 1
935 // if (QT->isVoidType()) return 1;
936 return Ctx.getTypeAlignInChars(QT).getQuantity();
937}
938
939CXType clang_Type_getClassType(CXType CT) {
940 QualType ET = QualType();
941 QualType T = GetQualType(CT);
942 const Type *TP = T.getTypePtrOrNull();
943
944 if (TP && TP->getTypeClass() == Type::MemberPointer) {
945 ET = QualType(cast<MemberPointerType> (TP)->getClass(), 0);
946 }
947 return MakeCXType(ET, GetTU(CT));
948}
949
950long long clang_Type_getSizeOf(CXType T) {
951 if (T.kind == CXType_Invalid)
952 return CXTypeLayoutError_Invalid;
953 ASTContext &Ctx = cxtu::getASTUnit(GetTU(T))->getASTContext();
954 QualType QT = GetQualType(T);
955 // [expr.sizeof] p2: if reference type, return size of referenced type
956 if (QT->isReferenceType())
957 QT = QT.getNonReferenceType();
958 // [expr.sizeof] p1: return -1 on: func, incomplete, bitfield, incomplete
959 // enumeration
960 // Note: We get the cxtype, not the cxcursor, so we can't call
961 // FieldDecl->isBitField()
962 // [expr.sizeof] p3: pointer ok, function not ok.
963 // [gcc extension] lib/AST/ExprConstant.cpp:1372 HandleSizeof : vla == error
964 if (QT->isIncompleteType())
965 return CXTypeLayoutError_Incomplete;
966 if (QT->isDependentType())
967 return CXTypeLayoutError_Dependent;
968 if (!QT->isConstantSizeType())
969 return CXTypeLayoutError_NotConstantSize;
970 if (const auto *Deduced = dyn_cast<DeducedType>(QT))
971 if (Deduced->getDeducedType().isNull())
972 return CXTypeLayoutError_Undeduced;
973 // [gcc extension] lib/AST/ExprConstant.cpp:1372
974 // HandleSizeof : {voidtype,functype} == 1
975 // not handled by ASTContext.cpp:1313 getTypeInfoImpl
976 if (QT->isVoidType() || QT->isFunctionType())
977 return 1;
978 return Ctx.getTypeSizeInChars(QT).getQuantity();
979}
980
981static bool isTypeIncompleteForLayout(QualType QT) {
982 return QT->isIncompleteType() && !QT->isIncompleteArrayType();
983}
984
985static long long visitRecordForValidation(const RecordDecl *RD) {
986 for (const auto *I : RD->fields()){
987 QualType FQT = I->getType();
988 if (isTypeIncompleteForLayout(FQT))
989 return CXTypeLayoutError_Incomplete;
990 if (FQT->isDependentType())
991 return CXTypeLayoutError_Dependent;
992 // recurse
993 if (const RecordType *ChildType = I->getType()->getAs<RecordType>()) {
994 if (const RecordDecl *Child = ChildType->getDecl()) {
995 long long ret = visitRecordForValidation(Child);
996 if (ret < 0)
997 return ret;
998 }
999 }
1000 // else try next field
1001 }
1002 return 0;
1003}
1004
1005static long long validateFieldParentType(CXCursor PC, CXType PT){
1006 if (clang_isInvalid(PC.kind))
1007 return CXTypeLayoutError_Invalid;
1008 const RecordDecl *RD =
1009 dyn_cast_or_null<RecordDecl>(cxcursor::getCursorDecl(PC));
1010 // validate parent declaration
1011 if (!RD || RD->isInvalidDecl())
1012 return CXTypeLayoutError_Invalid;
1013 RD = RD->getDefinition();
1014 if (!RD)
1015 return CXTypeLayoutError_Incomplete;
1016 if (RD->isInvalidDecl())
1017 return CXTypeLayoutError_Invalid;
1018 // validate parent type
1019 QualType RT = GetQualType(PT);
1020 if (RT->isIncompleteType())
1021 return CXTypeLayoutError_Incomplete;
1022 if (RT->isDependentType())
1023 return CXTypeLayoutError_Dependent;
1024 // We recurse into all record fields to detect incomplete and dependent types.
1025 long long Error = visitRecordForValidation(RD);
1026 if (Error < 0)
1027 return Error;
1028 return 0;
1029}
1030
1031long long clang_Type_getOffsetOf(CXType PT, const char *S) {
1032 // check that PT is not incomplete/dependent
1033 CXCursor PC = clang_getTypeDeclaration(PT);
1034 long long Error = validateFieldParentType(PC,PT);
1035 if (Error
0.1
'Error' is >= 0
< 0)
1
Taking false branch
1036 return Error;
1037 if (!S)
2
Assuming 'S' is non-null
3
Taking false branch
1038 return CXTypeLayoutError_InvalidFieldName;
1039 // lookup field
1040 ASTContext &Ctx = cxtu::getASTUnit(GetTU(PT))->getASTContext();
1041 IdentifierInfo *II = &Ctx.Idents.get(S);
1042 DeclarationName FieldName(II);
1043 const RecordDecl *RD =
5
'RD' initialized to a null pointer value
1044 dyn_cast_or_null<RecordDecl>(cxcursor::getCursorDecl(PC));
4
Assuming null pointer is passed into cast
1045 // verified in validateFieldParentType
1046 RD = RD->getDefinition();
6
Called C++ object pointer is null
1047 RecordDecl::lookup_result Res = RD->lookup(FieldName);
1048 // If a field of the parent record is incomplete, lookup will fail.
1049 // and we would return InvalidFieldName instead of Incomplete.
1050 // But this erroneous results does protects again a hidden assertion failure
1051 // in the RecordLayoutBuilder
1052 if (!Res.isSingleResult())
1053 return CXTypeLayoutError_InvalidFieldName;
1054 if (const FieldDecl *FD = dyn_cast<FieldDecl>(Res.front()))
1055 return Ctx.getFieldOffset(FD);
1056 if (const IndirectFieldDecl *IFD = dyn_cast<IndirectFieldDecl>(Res.front()))
1057 return Ctx.getFieldOffset(IFD);
1058 // we don't want any other Decl Type.
1059 return CXTypeLayoutError_InvalidFieldName;
1060}
1061
1062CXType clang_Type_getModifiedType(CXType CT) {
1063 QualType T = GetQualType(CT);
1064 if (T.isNull())
1065 return MakeCXType(QualType(), GetTU(CT));
1066
1067 if (auto *ATT = T->getAs<AttributedType>())
1068 return MakeCXType(ATT->getModifiedType(), GetTU(CT));
1069
1070 if (auto *ATT = T->getAs<BTFTagAttributedType>())
1071 return MakeCXType(ATT->getWrappedType(), GetTU(CT));
1072
1073 return MakeCXType(QualType(), GetTU(CT));
1074}
1075
1076long long clang_Cursor_getOffsetOfField(CXCursor C) {
1077 if (clang_isDeclaration(C.kind)) {
1078 // we need to validate the parent type
1079 CXCursor PC = clang_getCursorSemanticParent(C);
1080 CXType PT = clang_getCursorType(PC);
1081 long long Error = validateFieldParentType(PC,PT);
1082 if (Error < 0)
1083 return Error;
1084 // proceed with the offset calculation
1085 const Decl *D = cxcursor::getCursorDecl(C);
1086 ASTContext &Ctx = cxcursor::getCursorContext(C);
1087 if (const FieldDecl *FD = dyn_cast_or_null<FieldDecl>(D))
1088 return Ctx.getFieldOffset(FD);
1089 if (const IndirectFieldDecl *IFD = dyn_cast_or_null<IndirectFieldDecl>(D))
1090 return Ctx.getFieldOffset(IFD);
1091 }
1092 return -1;
1093}
1094
1095enum CXRefQualifierKind clang_Type_getCXXRefQualifier(CXType T) {
1096 QualType QT = GetQualType(T);
1097 if (QT.isNull())
1098 return CXRefQualifier_None;
1099 const FunctionProtoType *FD = QT->getAs<FunctionProtoType>();
1100 if (!FD)
1101 return CXRefQualifier_None;
1102 switch (FD->getRefQualifier()) {
1103 case RQ_None:
1104 return CXRefQualifier_None;
1105 case RQ_LValue:
1106 return CXRefQualifier_LValue;
1107 case RQ_RValue:
1108 return CXRefQualifier_RValue;
1109 }
1110 return CXRefQualifier_None;
1111}
1112
1113unsigned clang_Cursor_isBitField(CXCursor C) {
1114 if (!clang_isDeclaration(C.kind))
1115 return 0;
1116 const FieldDecl *FD = dyn_cast_or_null<FieldDecl>(cxcursor::getCursorDecl(C));
1117 if (!FD)
1118 return 0;
1119 return FD->isBitField();
1120}
1121
1122CXString clang_getDeclObjCTypeEncoding(CXCursor C) {
1123 if (!clang_isDeclaration(C.kind))
1124 return cxstring::createEmpty();
1125
1126 const Decl *D = cxcursor::getCursorDecl(C);
1127 ASTContext &Ctx = cxcursor::getCursorContext(C);
1128 std::string encoding;
1129
1130 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D)) {
1131 encoding = Ctx.getObjCEncodingForMethodDecl(OMD);
1132 } else if (const ObjCPropertyDecl *OPD = dyn_cast<ObjCPropertyDecl>(D))
1133 encoding = Ctx.getObjCEncodingForPropertyDecl(OPD, nullptr);
1134 else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
1135 encoding = Ctx.getObjCEncodingForFunctionDecl(FD);
1136 else {
1137 QualType Ty;
1138 if (const TypeDecl *TD = dyn_cast<TypeDecl>(D))
1139 Ty = Ctx.getTypeDeclType(TD);
1140 if (const ValueDecl *VD = dyn_cast<ValueDecl>(D))
1141 Ty = VD->getType();
1142 else return cxstring::createRef("?");
1143 Ctx.getObjCEncodingForType(Ty, encoding);
1144 }
1145
1146 return cxstring::createDup(encoding);
1147}
1148
1149static unsigned GetTemplateArgumentArraySize(ArrayRef<TemplateArgument> TA) {
1150 unsigned size = TA.size();
1151 for (const auto &Arg : TA)
1152 if (Arg.getKind() == TemplateArgument::Pack)
1153 size += Arg.pack_size() - 1;
1154 return size;
1155}
1156
1157int clang_Type_getNumTemplateArguments(CXType CT) {
1158 QualType T = GetQualType(CT);
1159 if (T.isNull())
1160 return -1;
1161
1162 auto TA = GetTemplateArguments(T);
1163 if (!TA)
1164 return -1;
1165
1166 return GetTemplateArgumentArraySize(*TA);
1167}
1168
1169CXType clang_Type_getTemplateArgumentAsType(CXType CT, unsigned index) {
1170 QualType T = GetQualType(CT);
1171 if (T.isNull())
1172 return MakeCXType(QualType(), GetTU(CT));
1173
1174 auto TA = GetTemplateArguments(T);
1175 if (!TA)
1176 return MakeCXType(QualType(), GetTU(CT));
1177
1178 Optional<QualType> QT = FindTemplateArgumentTypeAt(*TA, index);
1179 return MakeCXType(QT.value_or(QualType()), GetTU(CT));
1180}
1181
1182CXType clang_Type_getObjCObjectBaseType(CXType CT) {
1183 QualType T = GetQualType(CT);
1184 if (T.isNull())
1185 return MakeCXType(QualType(), GetTU(CT));
1186
1187 const ObjCObjectType *OT = dyn_cast<ObjCObjectType>(T);
1188 if (!OT)
1189 return MakeCXType(QualType(), GetTU(CT));
1190
1191 return MakeCXType(OT->getBaseType(), GetTU(CT));
1192}
1193
1194unsigned clang_Type_getNumObjCProtocolRefs(CXType CT) {
1195 QualType T = GetQualType(CT);
1196 if (T.isNull())
1197 return 0;
1198
1199 const ObjCObjectType *OT = dyn_cast<ObjCObjectType>(T);
1200 if (!OT)
1201 return 0;
1202
1203 return OT->getNumProtocols();
1204}
1205
1206CXCursor clang_Type_getObjCProtocolDecl(CXType CT, unsigned i) {
1207 QualType T = GetQualType(CT);
1208 if (T.isNull())
1209 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
1210
1211 const ObjCObjectType *OT = dyn_cast<ObjCObjectType>(T);
1212 if (!OT)
1213 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
1214
1215 const ObjCProtocolDecl *PD = OT->getProtocol(i);
1216 if (!PD)
1217 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
1218
1219 return cxcursor::MakeCXCursor(PD, GetTU(CT));
1220}
1221
1222unsigned clang_Type_getNumObjCTypeArgs(CXType CT) {
1223 QualType T = GetQualType(CT);
1224 if (T.isNull())
1225 return 0;
1226
1227 const ObjCObjectType *OT = dyn_cast<ObjCObjectType>(T);
1228 if (!OT)
1229 return 0;
1230
1231 return OT->getTypeArgs().size();
1232}
1233
1234CXType clang_Type_getObjCTypeArg(CXType CT, unsigned i) {
1235 QualType T = GetQualType(CT);
1236 if (T.isNull())
1237 return MakeCXType(QualType(), GetTU(CT));
1238
1239 const ObjCObjectType *OT = dyn_cast<ObjCObjectType>(T);
1240 if (!OT)
1241 return MakeCXType(QualType(), GetTU(CT));
1242
1243 const ArrayRef<QualType> TA = OT->getTypeArgs();
1244 if ((size_t)i >= TA.size())
1245 return MakeCXType(QualType(), GetTU(CT));
1246
1247 return MakeCXType(TA[i], GetTU(CT));
1248}
1249
1250unsigned clang_Type_visitFields(CXType PT,
1251 CXFieldVisitor visitor,
1252 CXClientData client_data){
1253 CXCursor PC = clang_getTypeDeclaration(PT);
1254 if (clang_isInvalid(PC.kind))
1255 return false;
1256 const RecordDecl *RD =
1257 dyn_cast_or_null<RecordDecl>(cxcursor::getCursorDecl(PC));
1258 if (!RD || RD->isInvalidDecl())
1259 return false;
1260 RD = RD->getDefinition();
1261 if (!RD || RD->isInvalidDecl())
1262 return false;
1263
1264 for (RecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
1265 I != E; ++I){
1266 const FieldDecl *FD = dyn_cast_or_null<FieldDecl>((*I));
1267 // Callback to the client.
1268 switch (visitor(cxcursor::MakeCXCursor(FD, GetTU(PT)), client_data)){
1269 case CXVisit_Break:
1270 return true;
1271 case CXVisit_Continue:
1272 break;
1273 }
1274 }
1275 return true;
1276}
1277
1278unsigned clang_Cursor_isAnonymous(CXCursor C){
1279 if (!clang_isDeclaration(C.kind))
1280 return 0;
1281 const Decl *D = cxcursor::getCursorDecl(C);
1282 if (const NamespaceDecl *ND = dyn_cast_or_null<NamespaceDecl>(D)) {
1283 return ND->isAnonymousNamespace();
1284 } else if (const TagDecl *TD = dyn_cast_or_null<TagDecl>(D)) {
1285 return TD->getTypedefNameForAnonDecl() == nullptr &&
1286 TD->getIdentifier() == nullptr;
1287 }
1288
1289 return 0;
1290}
1291
1292unsigned clang_Cursor_isAnonymousRecordDecl(CXCursor C){
1293 if (!clang_isDeclaration(C.kind))
1294 return 0;
1295 const Decl *D = cxcursor::getCursorDecl(C);
1296 if (const RecordDecl *FD = dyn_cast_or_null<RecordDecl>(D))
1297 return FD->isAnonymousStructOrUnion();
1298 return 0;
1299}
1300
1301unsigned clang_Cursor_isInlineNamespace(CXCursor C) {
1302 if (!clang_isDeclaration(C.kind))
1303 return 0;
1304 const Decl *D = cxcursor::getCursorDecl(C);
1305 const NamespaceDecl *ND = dyn_cast_or_null<NamespaceDecl>(D);
1306 return ND ? ND->isInline() : 0;
1307}
1308
1309CXType clang_Type_getNamedType(CXType CT){
1310 QualType T = GetQualType(CT);
1311 const Type *TP = T.getTypePtrOrNull();
1312
1313 if (TP && TP->getTypeClass() == Type::Elaborated)
1314 return MakeCXType(cast<ElaboratedType>(TP)->getNamedType(), GetTU(CT));
1315
1316 return MakeCXType(QualType(), GetTU(CT));
1317}
1318
1319unsigned clang_Type_isTransparentTagTypedef(CXType TT){
1320 QualType T = GetQualType(TT);
1321 if (auto *TT = dyn_cast_or_null<TypedefType>(T.getTypePtrOrNull())) {
1322 if (auto *D = TT->getDecl())
1323 return D->isTransparentTag();
1324 }
1325 return false;
1326}
1327
1328enum CXTypeNullabilityKind clang_Type_getNullability(CXType CT) {
1329 QualType T = GetQualType(CT);
1330 if (T.isNull())
1331 return CXTypeNullability_Invalid;
1332
1333 ASTContext &Ctx = cxtu::getASTUnit(GetTU(CT))->getASTContext();
1334 if (auto nullability = T->getNullability(Ctx)) {
1335 switch (*nullability) {
1336 case NullabilityKind::NonNull:
1337 return CXTypeNullability_NonNull;
1338 case NullabilityKind::Nullable:
1339 return CXTypeNullability_Nullable;
1340 case NullabilityKind::NullableResult:
1341 return CXTypeNullability_NullableResult;
1342 case NullabilityKind::Unspecified:
1343 return CXTypeNullability_Unspecified;
1344 }
1345 }
1346 return CXTypeNullability_Invalid;
1347}
1348
1349CXType clang_Type_getValueType(CXType CT) {
1350 QualType T = GetQualType(CT);
1351
1352 if (T.isNull() || !T->isAtomicType())
1353 return MakeCXType(QualType(), GetTU(CT));
1354
1355 const auto *AT = T->castAs<AtomicType>();
1356 return MakeCXType(AT->getValueType(), GetTU(CT));
1357}