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