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