Home | History | Annotate | Download | only in libclang
      1 //===- CXTypes.cpp - Implements 'CXTypes' aspect of libclang ------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===--------------------------------------------------------------------===//
      9 //
     10 // This file implements the 'CXTypes' API hooks in the Clang-C library.
     11 //
     12 //===--------------------------------------------------------------------===//
     13 
     14 #include "CIndexer.h"
     15 #include "CXCursor.h"
     16 #include "CXString.h"
     17 #include "CXTranslationUnit.h"
     18 #include "CXType.h"
     19 #include "clang/AST/Decl.h"
     20 #include "clang/AST/DeclObjC.h"
     21 #include "clang/AST/DeclTemplate.h"
     22 #include "clang/AST/Expr.h"
     23 #include "clang/AST/Type.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(Float);
     52     BTCASE(Double);
     53     BTCASE(LongDouble);
     54     BTCASE(NullPtr);
     55     BTCASE(Overload);
     56     BTCASE(Dependent);
     57     BTCASE(ObjCId);
     58     BTCASE(ObjCClass);
     59     BTCASE(ObjCSel);
     60   default:
     61     return CXType_Unexposed;
     62   }
     63 #undef BTCASE
     64 }
     65 
     66 static CXTypeKind GetTypeKind(QualType T) {
     67   const Type *TP = T.getTypePtrOrNull();
     68   if (!TP)
     69     return CXType_Invalid;
     70 
     71 #define TKCASE(K) case Type::K: return CXType_##K
     72   switch (TP->getTypeClass()) {
     73     case Type::Builtin:
     74       return GetBuiltinTypeKind(cast<BuiltinType>(TP));
     75     TKCASE(Complex);
     76     TKCASE(Pointer);
     77     TKCASE(BlockPointer);
     78     TKCASE(LValueReference);
     79     TKCASE(RValueReference);
     80     TKCASE(Record);
     81     TKCASE(Enum);
     82     TKCASE(Typedef);
     83     TKCASE(ObjCInterface);
     84     TKCASE(ObjCObjectPointer);
     85     TKCASE(FunctionNoProto);
     86     TKCASE(FunctionProto);
     87     TKCASE(ConstantArray);
     88     TKCASE(IncompleteArray);
     89     TKCASE(VariableArray);
     90     TKCASE(DependentSizedArray);
     91     TKCASE(Vector);
     92     default:
     93       return CXType_Unexposed;
     94   }
     95 #undef TKCASE
     96 }
     97 
     98 
     99 CXType cxtype::MakeCXType(QualType T, CXTranslationUnit TU) {
    100   CXTypeKind TK = CXType_Invalid;
    101 
    102   if (TU && !T.isNull()) {
    103     ASTContext &Ctx = cxtu::getASTUnit(TU)->getASTContext();
    104     if (Ctx.getLangOpts().ObjC1) {
    105       QualType UnqualT = T.getUnqualifiedType();
    106       if (Ctx.isObjCIdType(UnqualT))
    107         TK = CXType_ObjCId;
    108       else if (Ctx.isObjCClassType(UnqualT))
    109         TK = CXType_ObjCClass;
    110       else if (Ctx.isObjCSelType(UnqualT))
    111         TK = CXType_ObjCSel;
    112     }
    113   }
    114   if (TK == CXType_Invalid)
    115     TK = GetTypeKind(T);
    116 
    117   CXType CT = { TK, { TK == CXType_Invalid ? 0 : T.getAsOpaquePtr(), TU }};
    118   return CT;
    119 }
    120 
    121 using cxtype::MakeCXType;
    122 
    123 static inline QualType GetQualType(CXType CT) {
    124   return QualType::getFromOpaquePtr(CT.data[0]);
    125 }
    126 
    127 static inline CXTranslationUnit GetTU(CXType CT) {
    128   return static_cast<CXTranslationUnit>(CT.data[1]);
    129 }
    130 
    131 extern "C" {
    132 
    133 CXType clang_getCursorType(CXCursor C) {
    134   using namespace cxcursor;
    135 
    136   CXTranslationUnit TU = cxcursor::getCursorTU(C);
    137   if (!TU)
    138     return MakeCXType(QualType(), TU);
    139 
    140   ASTContext &Context = cxtu::getASTUnit(TU)->getASTContext();
    141   if (clang_isExpression(C.kind)) {
    142     QualType T = cxcursor::getCursorExpr(C)->getType();
    143     return MakeCXType(T, TU);
    144   }
    145 
    146   if (clang_isDeclaration(C.kind)) {
    147     const Decl *D = cxcursor::getCursorDecl(C);
    148     if (!D)
    149       return MakeCXType(QualType(), TU);
    150 
    151     if (const TypeDecl *TD = dyn_cast<TypeDecl>(D))
    152       return MakeCXType(Context.getTypeDeclType(TD), TU);
    153     if (const ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D))
    154       return MakeCXType(Context.getObjCInterfaceType(ID), TU);
    155     if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
    156       if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
    157         return MakeCXType(TSInfo->getType(), TU);
    158       return MakeCXType(DD->getType(), TU);
    159     }
    160     if (const ValueDecl *VD = dyn_cast<ValueDecl>(D))
    161       return MakeCXType(VD->getType(), TU);
    162     if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
    163       return MakeCXType(PD->getType(), TU);
    164     if (const FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(D)) {
    165       if (TypeSourceInfo *TSInfo = FTD->getTemplatedDecl()->getTypeSourceInfo())
    166         return MakeCXType(TSInfo->getType(), TU);
    167       return MakeCXType(FTD->getTemplatedDecl()->getType(), TU);
    168     }
    169     return MakeCXType(QualType(), TU);
    170   }
    171 
    172   if (clang_isReference(C.kind)) {
    173     switch (C.kind) {
    174     case CXCursor_ObjCSuperClassRef: {
    175       QualType T
    176         = Context.getObjCInterfaceType(getCursorObjCSuperClassRef(C).first);
    177       return MakeCXType(T, TU);
    178     }
    179 
    180     case CXCursor_ObjCClassRef: {
    181       QualType T = Context.getObjCInterfaceType(getCursorObjCClassRef(C).first);
    182       return MakeCXType(T, TU);
    183     }
    184 
    185     case CXCursor_TypeRef: {
    186       QualType T = Context.getTypeDeclType(getCursorTypeRef(C).first);
    187       return MakeCXType(T, TU);
    188 
    189     }
    190 
    191     case CXCursor_CXXBaseSpecifier:
    192       return cxtype::MakeCXType(getCursorCXXBaseSpecifier(C)->getType(), TU);
    193 
    194     case CXCursor_MemberRef:
    195       return cxtype::MakeCXType(getCursorMemberRef(C).first->getType(), TU);
    196 
    197     case CXCursor_VariableRef:
    198       return cxtype::MakeCXType(getCursorVariableRef(C).first->getType(), TU);
    199 
    200     case CXCursor_ObjCProtocolRef:
    201     case CXCursor_TemplateRef:
    202     case CXCursor_NamespaceRef:
    203     case CXCursor_OverloadedDeclRef:
    204     default:
    205       break;
    206     }
    207 
    208     return MakeCXType(QualType(), TU);
    209   }
    210 
    211   return MakeCXType(QualType(), TU);
    212 }
    213 
    214 CXString clang_getTypeSpelling(CXType CT) {
    215   QualType T = GetQualType(CT);
    216   if (T.isNull())
    217     return cxstring::createEmpty();
    218 
    219   CXTranslationUnit TU = GetTU(CT);
    220   SmallString<64> Str;
    221   llvm::raw_svector_ostream OS(Str);
    222   PrintingPolicy PP(cxtu::getASTUnit(TU)->getASTContext().getLangOpts());
    223 
    224   T.print(OS, PP);
    225 
    226   return cxstring::createDup(OS.str());
    227 }
    228 
    229 CXType clang_getTypedefDeclUnderlyingType(CXCursor C) {
    230   using namespace cxcursor;
    231   CXTranslationUnit TU = cxcursor::getCursorTU(C);
    232 
    233   if (clang_isDeclaration(C.kind)) {
    234     const Decl *D = cxcursor::getCursorDecl(C);
    235 
    236     if (const TypedefNameDecl *TD = dyn_cast_or_null<TypedefNameDecl>(D)) {
    237       QualType T = TD->getUnderlyingType();
    238       return MakeCXType(T, TU);
    239     }
    240 
    241     return MakeCXType(QualType(), TU);
    242   }
    243 
    244   return MakeCXType(QualType(), TU);
    245 }
    246 
    247 CXType clang_getEnumDeclIntegerType(CXCursor C) {
    248   using namespace cxcursor;
    249   CXTranslationUnit TU = cxcursor::getCursorTU(C);
    250 
    251   if (clang_isDeclaration(C.kind)) {
    252     const Decl *D = cxcursor::getCursorDecl(C);
    253 
    254     if (const EnumDecl *TD = dyn_cast_or_null<EnumDecl>(D)) {
    255       QualType T = TD->getIntegerType();
    256       return MakeCXType(T, TU);
    257     }
    258 
    259     return MakeCXType(QualType(), TU);
    260   }
    261 
    262   return MakeCXType(QualType(), TU);
    263 }
    264 
    265 long long clang_getEnumConstantDeclValue(CXCursor C) {
    266   using namespace cxcursor;
    267 
    268   if (clang_isDeclaration(C.kind)) {
    269     const Decl *D = cxcursor::getCursorDecl(C);
    270 
    271     if (const EnumConstantDecl *TD = dyn_cast_or_null<EnumConstantDecl>(D)) {
    272       return TD->getInitVal().getSExtValue();
    273     }
    274 
    275     return LLONG_MIN;
    276   }
    277 
    278   return LLONG_MIN;
    279 }
    280 
    281 unsigned long long clang_getEnumConstantDeclUnsignedValue(CXCursor C) {
    282   using namespace cxcursor;
    283 
    284   if (clang_isDeclaration(C.kind)) {
    285     const Decl *D = cxcursor::getCursorDecl(C);
    286 
    287     if (const EnumConstantDecl *TD = dyn_cast_or_null<EnumConstantDecl>(D)) {
    288       return TD->getInitVal().getZExtValue();
    289     }
    290 
    291     return ULLONG_MAX;
    292   }
    293 
    294   return ULLONG_MAX;
    295 }
    296 
    297 int clang_getFieldDeclBitWidth(CXCursor C) {
    298   using namespace cxcursor;
    299 
    300   if (clang_isDeclaration(C.kind)) {
    301     const Decl *D = getCursorDecl(C);
    302 
    303     if (const FieldDecl *FD = dyn_cast_or_null<FieldDecl>(D)) {
    304       if (FD->isBitField())
    305         return FD->getBitWidthValue(getCursorContext(C));
    306     }
    307   }
    308 
    309   return -1;
    310 }
    311 
    312 CXType clang_getCanonicalType(CXType CT) {
    313   if (CT.kind == CXType_Invalid)
    314     return CT;
    315 
    316   QualType T = GetQualType(CT);
    317   CXTranslationUnit TU = GetTU(CT);
    318 
    319   if (T.isNull())
    320     return MakeCXType(QualType(), GetTU(CT));
    321 
    322   return MakeCXType(cxtu::getASTUnit(TU)->getASTContext()
    323                         .getCanonicalType(T),
    324                     TU);
    325 }
    326 
    327 unsigned clang_isConstQualifiedType(CXType CT) {
    328   QualType T = GetQualType(CT);
    329   return T.isLocalConstQualified();
    330 }
    331 
    332 unsigned clang_isVolatileQualifiedType(CXType CT) {
    333   QualType T = GetQualType(CT);
    334   return T.isLocalVolatileQualified();
    335 }
    336 
    337 unsigned clang_isRestrictQualifiedType(CXType CT) {
    338   QualType T = GetQualType(CT);
    339   return T.isLocalRestrictQualified();
    340 }
    341 
    342 CXType clang_getPointeeType(CXType CT) {
    343   QualType T = GetQualType(CT);
    344   const Type *TP = T.getTypePtrOrNull();
    345 
    346   if (!TP)
    347     return MakeCXType(QualType(), GetTU(CT));
    348 
    349   switch (TP->getTypeClass()) {
    350     case Type::Pointer:
    351       T = cast<PointerType>(TP)->getPointeeType();
    352       break;
    353     case Type::BlockPointer:
    354       T = cast<BlockPointerType>(TP)->getPointeeType();
    355       break;
    356     case Type::LValueReference:
    357     case Type::RValueReference:
    358       T = cast<ReferenceType>(TP)->getPointeeType();
    359       break;
    360     case Type::ObjCObjectPointer:
    361       T = cast<ObjCObjectPointerType>(TP)->getPointeeType();
    362       break;
    363     default:
    364       T = QualType();
    365       break;
    366   }
    367   return MakeCXType(T, GetTU(CT));
    368 }
    369 
    370 CXCursor clang_getTypeDeclaration(CXType CT) {
    371   if (CT.kind == CXType_Invalid)
    372     return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
    373 
    374   QualType T = GetQualType(CT);
    375   const Type *TP = T.getTypePtrOrNull();
    376 
    377   if (!TP)
    378     return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
    379 
    380   Decl *D = 0;
    381 
    382 try_again:
    383   switch (TP->getTypeClass()) {
    384   case Type::Typedef:
    385     D = cast<TypedefType>(TP)->getDecl();
    386     break;
    387   case Type::ObjCObject:
    388     D = cast<ObjCObjectType>(TP)->getInterface();
    389     break;
    390   case Type::ObjCInterface:
    391     D = cast<ObjCInterfaceType>(TP)->getDecl();
    392     break;
    393   case Type::Record:
    394   case Type::Enum:
    395     D = cast<TagType>(TP)->getDecl();
    396     break;
    397   case Type::TemplateSpecialization:
    398     if (const RecordType *Record = TP->getAs<RecordType>())
    399       D = Record->getDecl();
    400     else
    401       D = cast<TemplateSpecializationType>(TP)->getTemplateName()
    402                                                          .getAsTemplateDecl();
    403     break;
    404 
    405   case Type::InjectedClassName:
    406     D = cast<InjectedClassNameType>(TP)->getDecl();
    407     break;
    408 
    409   // FIXME: Template type parameters!
    410 
    411   case Type::Elaborated:
    412     TP = cast<ElaboratedType>(TP)->getNamedType().getTypePtrOrNull();
    413     goto try_again;
    414 
    415   default:
    416     break;
    417   }
    418 
    419   if (!D)
    420     return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
    421 
    422   return cxcursor::MakeCXCursor(D, GetTU(CT));
    423 }
    424 
    425 CXString clang_getTypeKindSpelling(enum CXTypeKind K) {
    426   const char *s = 0;
    427 #define TKIND(X) case CXType_##X: s = ""  #X  ""; break
    428   switch (K) {
    429     TKIND(Invalid);
    430     TKIND(Unexposed);
    431     TKIND(Void);
    432     TKIND(Bool);
    433     TKIND(Char_U);
    434     TKIND(UChar);
    435     TKIND(Char16);
    436     TKIND(Char32);
    437     TKIND(UShort);
    438     TKIND(UInt);
    439     TKIND(ULong);
    440     TKIND(ULongLong);
    441     TKIND(UInt128);
    442     TKIND(Char_S);
    443     TKIND(SChar);
    444     case CXType_WChar: s = "WChar"; break;
    445     TKIND(Short);
    446     TKIND(Int);
    447     TKIND(Long);
    448     TKIND(LongLong);
    449     TKIND(Int128);
    450     TKIND(Float);
    451     TKIND(Double);
    452     TKIND(LongDouble);
    453     TKIND(NullPtr);
    454     TKIND(Overload);
    455     TKIND(Dependent);
    456     TKIND(ObjCId);
    457     TKIND(ObjCClass);
    458     TKIND(ObjCSel);
    459     TKIND(Complex);
    460     TKIND(Pointer);
    461     TKIND(BlockPointer);
    462     TKIND(LValueReference);
    463     TKIND(RValueReference);
    464     TKIND(Record);
    465     TKIND(Enum);
    466     TKIND(Typedef);
    467     TKIND(ObjCInterface);
    468     TKIND(ObjCObjectPointer);
    469     TKIND(FunctionNoProto);
    470     TKIND(FunctionProto);
    471     TKIND(ConstantArray);
    472     TKIND(IncompleteArray);
    473     TKIND(VariableArray);
    474     TKIND(DependentSizedArray);
    475     TKIND(Vector);
    476   }
    477 #undef TKIND
    478   return cxstring::createRef(s);
    479 }
    480 
    481 unsigned clang_equalTypes(CXType A, CXType B) {
    482   return A.data[0] == B.data[0] && A.data[1] == B.data[1];;
    483 }
    484 
    485 unsigned clang_isFunctionTypeVariadic(CXType X) {
    486   QualType T = GetQualType(X);
    487   if (T.isNull())
    488     return 0;
    489 
    490   if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>())
    491     return (unsigned)FD->isVariadic();
    492 
    493   if (T->getAs<FunctionNoProtoType>())
    494     return 1;
    495 
    496   return 0;
    497 }
    498 
    499 CXCallingConv clang_getFunctionTypeCallingConv(CXType X) {
    500   QualType T = GetQualType(X);
    501   if (T.isNull())
    502     return CXCallingConv_Invalid;
    503 
    504   if (const FunctionType *FD = T->getAs<FunctionType>()) {
    505 #define TCALLINGCONV(X) case CC_##X: return CXCallingConv_##X
    506     switch (FD->getCallConv()) {
    507       TCALLINGCONV(Default);
    508       TCALLINGCONV(C);
    509       TCALLINGCONV(X86StdCall);
    510       TCALLINGCONV(X86FastCall);
    511       TCALLINGCONV(X86ThisCall);
    512       TCALLINGCONV(X86Pascal);
    513       TCALLINGCONV(AAPCS);
    514       TCALLINGCONV(AAPCS_VFP);
    515       TCALLINGCONV(PnaclCall);
    516       TCALLINGCONV(IntelOclBicc);
    517     }
    518 #undef TCALLINGCONV
    519   }
    520 
    521   return CXCallingConv_Invalid;
    522 }
    523 
    524 int clang_getNumArgTypes(CXType X) {
    525   QualType T = GetQualType(X);
    526   if (T.isNull())
    527     return -1;
    528 
    529   if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) {
    530     return FD->getNumArgs();
    531   }
    532 
    533   if (T->getAs<FunctionNoProtoType>()) {
    534     return 0;
    535   }
    536 
    537   return -1;
    538 }
    539 
    540 CXType clang_getArgType(CXType X, unsigned i) {
    541   QualType T = GetQualType(X);
    542   if (T.isNull())
    543     return MakeCXType(QualType(), GetTU(X));
    544 
    545   if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) {
    546     unsigned numArgs = FD->getNumArgs();
    547     if (i >= numArgs)
    548       return MakeCXType(QualType(), GetTU(X));
    549 
    550     return MakeCXType(FD->getArgType(i), GetTU(X));
    551   }
    552 
    553   return MakeCXType(QualType(), GetTU(X));
    554 }
    555 
    556 CXType clang_getResultType(CXType X) {
    557   QualType T = GetQualType(X);
    558   if (T.isNull())
    559     return MakeCXType(QualType(), GetTU(X));
    560 
    561   if (const FunctionType *FD = T->getAs<FunctionType>())
    562     return MakeCXType(FD->getResultType(), GetTU(X));
    563 
    564   return MakeCXType(QualType(), GetTU(X));
    565 }
    566 
    567 CXType clang_getCursorResultType(CXCursor C) {
    568   if (clang_isDeclaration(C.kind)) {
    569     const Decl *D = cxcursor::getCursorDecl(C);
    570     if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
    571       return MakeCXType(MD->getResultType(), cxcursor::getCursorTU(C));
    572 
    573     return clang_getResultType(clang_getCursorType(C));
    574   }
    575 
    576   return MakeCXType(QualType(), cxcursor::getCursorTU(C));
    577 }
    578 
    579 unsigned clang_isPODType(CXType X) {
    580   QualType T = GetQualType(X);
    581   if (T.isNull())
    582     return 0;
    583 
    584   CXTranslationUnit TU = GetTU(X);
    585 
    586   return T.isPODType(cxtu::getASTUnit(TU)->getASTContext()) ? 1 : 0;
    587 }
    588 
    589 CXType clang_getElementType(CXType CT) {
    590   QualType ET = QualType();
    591   QualType T = GetQualType(CT);
    592   const Type *TP = T.getTypePtrOrNull();
    593 
    594   if (TP) {
    595     switch (TP->getTypeClass()) {
    596     case Type::ConstantArray:
    597       ET = cast<ConstantArrayType> (TP)->getElementType();
    598       break;
    599     case Type::IncompleteArray:
    600       ET = cast<IncompleteArrayType> (TP)->getElementType();
    601       break;
    602     case Type::VariableArray:
    603       ET = cast<VariableArrayType> (TP)->getElementType();
    604       break;
    605     case Type::DependentSizedArray:
    606       ET = cast<DependentSizedArrayType> (TP)->getElementType();
    607       break;
    608     case Type::Vector:
    609       ET = cast<VectorType> (TP)->getElementType();
    610       break;
    611     case Type::Complex:
    612       ET = cast<ComplexType> (TP)->getElementType();
    613       break;
    614     default:
    615       break;
    616     }
    617   }
    618   return MakeCXType(ET, GetTU(CT));
    619 }
    620 
    621 long long clang_getNumElements(CXType CT) {
    622   long long result = -1;
    623   QualType T = GetQualType(CT);
    624   const Type *TP = T.getTypePtrOrNull();
    625 
    626   if (TP) {
    627     switch (TP->getTypeClass()) {
    628     case Type::ConstantArray:
    629       result = cast<ConstantArrayType> (TP)->getSize().getSExtValue();
    630       break;
    631     case Type::Vector:
    632       result = cast<VectorType> (TP)->getNumElements();
    633       break;
    634     default:
    635       break;
    636     }
    637   }
    638   return result;
    639 }
    640 
    641 CXType clang_getArrayElementType(CXType CT) {
    642   QualType ET = QualType();
    643   QualType T = GetQualType(CT);
    644   const Type *TP = T.getTypePtrOrNull();
    645 
    646   if (TP) {
    647     switch (TP->getTypeClass()) {
    648     case Type::ConstantArray:
    649       ET = cast<ConstantArrayType> (TP)->getElementType();
    650       break;
    651     case Type::IncompleteArray:
    652       ET = cast<IncompleteArrayType> (TP)->getElementType();
    653       break;
    654     case Type::VariableArray:
    655       ET = cast<VariableArrayType> (TP)->getElementType();
    656       break;
    657     case Type::DependentSizedArray:
    658       ET = cast<DependentSizedArrayType> (TP)->getElementType();
    659       break;
    660     default:
    661       break;
    662     }
    663   }
    664   return MakeCXType(ET, GetTU(CT));
    665 }
    666 
    667 long long clang_getArraySize(CXType CT) {
    668   long long result = -1;
    669   QualType T = GetQualType(CT);
    670   const Type *TP = T.getTypePtrOrNull();
    671 
    672   if (TP) {
    673     switch (TP->getTypeClass()) {
    674     case Type::ConstantArray:
    675       result = cast<ConstantArrayType> (TP)->getSize().getSExtValue();
    676       break;
    677     default:
    678       break;
    679     }
    680   }
    681   return result;
    682 }
    683 
    684 long long clang_Type_getAlignOf(CXType T) {
    685   if (T.kind == CXType_Invalid)
    686     return CXTypeLayoutError_Invalid;
    687   ASTContext &Ctx = cxtu::getASTUnit(GetTU(T))->getASTContext();
    688   QualType QT = GetQualType(T);
    689   // [expr.alignof] p1: return size_t value for complete object type, reference
    690   //                    or array.
    691   // [expr.alignof] p3: if reference type, return size of referenced type
    692   if (QT->isReferenceType())
    693     QT = QT.getNonReferenceType();
    694   if (QT->isIncompleteType())
    695     return CXTypeLayoutError_Incomplete;
    696   if (QT->isDependentType())
    697     return CXTypeLayoutError_Dependent;
    698   // Exceptions by GCC extension - see ASTContext.cpp:1313 getTypeInfoImpl
    699   // if (QT->isFunctionType()) return 4; // Bug #15511 - should be 1
    700   // if (QT->isVoidType()) return 1;
    701   return Ctx.getTypeAlignInChars(QT).getQuantity();
    702 }
    703 
    704 long long clang_Type_getSizeOf(CXType T) {
    705   if (T.kind == CXType_Invalid)
    706     return CXTypeLayoutError_Invalid;
    707   ASTContext &Ctx = cxtu::getASTUnit(GetTU(T))->getASTContext();
    708   QualType QT = GetQualType(T);
    709   // [expr.sizeof] p2: if reference type, return size of referenced type
    710   if (QT->isReferenceType())
    711     QT = QT.getNonReferenceType();
    712   // [expr.sizeof] p1: return -1 on: func, incomplete, bitfield, incomplete
    713   //                   enumeration
    714   // Note: We get the cxtype, not the cxcursor, so we can't call
    715   //       FieldDecl->isBitField()
    716   // [expr.sizeof] p3: pointer ok, function not ok.
    717   // [gcc extension] lib/AST/ExprConstant.cpp:1372 HandleSizeof : vla == error
    718   if (QT->isIncompleteType())
    719     return CXTypeLayoutError_Incomplete;
    720   if (QT->isDependentType())
    721     return CXTypeLayoutError_Dependent;
    722   if (!QT->isConstantSizeType())
    723     return CXTypeLayoutError_NotConstantSize;
    724   // [gcc extension] lib/AST/ExprConstant.cpp:1372
    725   //                 HandleSizeof : {voidtype,functype} == 1
    726   // not handled by ASTContext.cpp:1313 getTypeInfoImpl
    727   if (QT->isVoidType() || QT->isFunctionType())
    728     return 1;
    729   return Ctx.getTypeSizeInChars(QT).getQuantity();
    730 }
    731 
    732 static long long visitRecordForValidation(const RecordDecl *RD) {
    733   for (RecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
    734        I != E; ++I){
    735     QualType FQT = (*I)->getType();
    736     if (FQT->isIncompleteType())
    737       return CXTypeLayoutError_Incomplete;
    738     if (FQT->isDependentType())
    739       return CXTypeLayoutError_Dependent;
    740     // recurse
    741     if (const RecordType *ChildType = (*I)->getType()->getAs<RecordType>()) {
    742       if (const RecordDecl *Child = ChildType->getDecl()) {
    743         long long ret = visitRecordForValidation(Child);
    744         if (ret < 0)
    745           return ret;
    746       }
    747     }
    748     // else try next field
    749   }
    750   return 0;
    751 }
    752 
    753 long long clang_Type_getOffsetOf(CXType PT, const char *S) {
    754   // check that PT is not incomplete/dependent
    755   CXCursor PC = clang_getTypeDeclaration(PT);
    756   if (clang_isInvalid(PC.kind))
    757     return CXTypeLayoutError_Invalid;
    758   const RecordDecl *RD =
    759         dyn_cast_or_null<RecordDecl>(cxcursor::getCursorDecl(PC));
    760   if (!RD || RD->isInvalidDecl())
    761     return CXTypeLayoutError_Invalid;
    762   RD = RD->getDefinition();
    763   if (!RD)
    764     return CXTypeLayoutError_Incomplete;
    765   if (RD->isInvalidDecl())
    766     return CXTypeLayoutError_Invalid;
    767   QualType RT = GetQualType(PT);
    768   if (RT->isIncompleteType())
    769     return CXTypeLayoutError_Incomplete;
    770   if (RT->isDependentType())
    771     return CXTypeLayoutError_Dependent;
    772   // We recurse into all record fields to detect incomplete and dependent types.
    773   long long Error = visitRecordForValidation(RD);
    774   if (Error < 0)
    775     return Error;
    776   if (!S)
    777     return CXTypeLayoutError_InvalidFieldName;
    778   // lookup field
    779   ASTContext &Ctx = cxtu::getASTUnit(GetTU(PT))->getASTContext();
    780   IdentifierInfo *II = &Ctx.Idents.get(S);
    781   DeclarationName FieldName(II);
    782   RecordDecl::lookup_const_result Res = RD->lookup(FieldName);
    783   // If a field of the parent record is incomplete, lookup will fail.
    784   // and we would return InvalidFieldName instead of Incomplete.
    785   // But this erroneous results does protects again a hidden assertion failure
    786   // in the RecordLayoutBuilder
    787   if (Res.size() != 1)
    788     return CXTypeLayoutError_InvalidFieldName;
    789   if (const FieldDecl *FD = dyn_cast<FieldDecl>(Res.front()))
    790     return Ctx.getFieldOffset(FD);
    791   if (const IndirectFieldDecl *IFD = dyn_cast<IndirectFieldDecl>(Res.front()))
    792     return Ctx.getFieldOffset(IFD);
    793   // we don't want any other Decl Type.
    794   return CXTypeLayoutError_InvalidFieldName;
    795 }
    796 
    797 unsigned clang_Cursor_isBitField(CXCursor C) {
    798   if (!clang_isDeclaration(C.kind))
    799     return 0;
    800   const FieldDecl *FD = dyn_cast_or_null<FieldDecl>(cxcursor::getCursorDecl(C));
    801   if (!FD)
    802     return 0;
    803   return FD->isBitField();
    804 }
    805 
    806 CXString clang_getDeclObjCTypeEncoding(CXCursor C) {
    807   if (!clang_isDeclaration(C.kind))
    808     return cxstring::createEmpty();
    809 
    810   const Decl *D = cxcursor::getCursorDecl(C);
    811   ASTContext &Ctx = cxcursor::getCursorContext(C);
    812   std::string encoding;
    813 
    814   if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D))  {
    815     if (Ctx.getObjCEncodingForMethodDecl(OMD, encoding))
    816       return cxstring::createRef("?");
    817   } else if (const ObjCPropertyDecl *OPD = dyn_cast<ObjCPropertyDecl>(D))
    818     Ctx.getObjCEncodingForPropertyDecl(OPD, NULL, encoding);
    819   else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
    820     Ctx.getObjCEncodingForFunctionDecl(FD, encoding);
    821   else {
    822     QualType Ty;
    823     if (const TypeDecl *TD = dyn_cast<TypeDecl>(D))
    824       Ty = Ctx.getTypeDeclType(TD);
    825     if (const ValueDecl *VD = dyn_cast<ValueDecl>(D))
    826       Ty = VD->getType();
    827     else return cxstring::createRef("?");
    828     Ctx.getObjCEncodingForType(Ty, encoding);
    829   }
    830 
    831   return cxstring::createDup(encoding);
    832 }
    833 
    834 } // end: extern "C"
    835