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 "CXTranslationUnit.h"
     16 #include "CXCursor.h"
     17 #include "CXString.h"
     18 #include "CXType.h"
     19 #include "clang/AST/Expr.h"
     20 #include "clang/AST/Type.h"
     21 #include "clang/AST/Decl.h"
     22 #include "clang/AST/DeclObjC.h"
     23 #include "clang/AST/DeclTemplate.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(Vector);
     89     default:
     90       return CXType_Unexposed;
     91   }
     92 #undef TKCASE
     93 }
     94 
     95 
     96 CXType cxtype::MakeCXType(QualType T, CXTranslationUnit TU) {
     97   CXTypeKind TK = GetTypeKind(T);
     98   CXType CT = { TK, { TK == CXType_Invalid ? 0 : T.getAsOpaquePtr(), TU }};
     99   return CT;
    100 }
    101 
    102 using cxtype::MakeCXType;
    103 
    104 static inline QualType GetQualType(CXType CT) {
    105   return QualType::getFromOpaquePtr(CT.data[0]);
    106 }
    107 
    108 static inline CXTranslationUnit GetTU(CXType CT) {
    109   return static_cast<CXTranslationUnit>(CT.data[1]);
    110 }
    111 
    112 extern "C" {
    113 
    114 CXType clang_getCursorType(CXCursor C) {
    115   using namespace cxcursor;
    116 
    117   CXTranslationUnit TU = cxcursor::getCursorTU(C);
    118   ASTContext &Context = static_cast<ASTUnit *>(TU->TUData)->getASTContext();
    119   if (clang_isExpression(C.kind)) {
    120     QualType T = cxcursor::getCursorExpr(C)->getType();
    121     return MakeCXType(T, TU);
    122   }
    123 
    124   if (clang_isDeclaration(C.kind)) {
    125     Decl *D = cxcursor::getCursorDecl(C);
    126     if (!D)
    127       return MakeCXType(QualType(), TU);
    128 
    129     if (TypeDecl *TD = dyn_cast<TypeDecl>(D))
    130       return MakeCXType(Context.getTypeDeclType(TD), TU);
    131     if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D))
    132       return MakeCXType(Context.getObjCInterfaceType(ID), TU);
    133     if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
    134       return MakeCXType(VD->getType(), TU);
    135     if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
    136       return MakeCXType(PD->getType(), TU);
    137     if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
    138       return MakeCXType(FD->getType(), TU);
    139     return MakeCXType(QualType(), TU);
    140   }
    141 
    142   if (clang_isReference(C.kind)) {
    143     switch (C.kind) {
    144     case CXCursor_ObjCSuperClassRef: {
    145       QualType T
    146         = Context.getObjCInterfaceType(getCursorObjCSuperClassRef(C).first);
    147       return MakeCXType(T, TU);
    148     }
    149 
    150     case CXCursor_ObjCClassRef: {
    151       QualType T = Context.getObjCInterfaceType(getCursorObjCClassRef(C).first);
    152       return MakeCXType(T, TU);
    153     }
    154 
    155     case CXCursor_TypeRef: {
    156       QualType T = Context.getTypeDeclType(getCursorTypeRef(C).first);
    157       return MakeCXType(T, TU);
    158 
    159     }
    160 
    161     case CXCursor_CXXBaseSpecifier:
    162       return cxtype::MakeCXType(getCursorCXXBaseSpecifier(C)->getType(), TU);
    163 
    164     case CXCursor_MemberRef:
    165       return cxtype::MakeCXType(getCursorMemberRef(C).first->getType(), TU);
    166 
    167     case CXCursor_VariableRef:
    168       return cxtype::MakeCXType(getCursorVariableRef(C).first->getType(), TU);
    169 
    170     case CXCursor_ObjCProtocolRef:
    171     case CXCursor_TemplateRef:
    172     case CXCursor_NamespaceRef:
    173     case CXCursor_OverloadedDeclRef:
    174     default:
    175       break;
    176     }
    177 
    178     return MakeCXType(QualType(), TU);
    179   }
    180 
    181   return MakeCXType(QualType(), TU);
    182 }
    183 
    184 CXType clang_getTypedefDeclUnderlyingType(CXCursor C) {
    185   using namespace cxcursor;
    186   CXTranslationUnit TU = cxcursor::getCursorTU(C);
    187 
    188   if (clang_isDeclaration(C.kind)) {
    189     Decl *D = cxcursor::getCursorDecl(C);
    190 
    191     if (TypedefNameDecl *TD = dyn_cast_or_null<TypedefNameDecl>(D)) {
    192       QualType T = TD->getUnderlyingType();
    193       return MakeCXType(T, TU);
    194     }
    195 
    196     return MakeCXType(QualType(), TU);
    197   }
    198 
    199   return MakeCXType(QualType(), TU);
    200 }
    201 
    202 CXType clang_getEnumDeclIntegerType(CXCursor C) {
    203   using namespace cxcursor;
    204   CXTranslationUnit TU = cxcursor::getCursorTU(C);
    205 
    206   if (clang_isDeclaration(C.kind)) {
    207     Decl *D = cxcursor::getCursorDecl(C);
    208 
    209     if (EnumDecl *TD = dyn_cast_or_null<EnumDecl>(D)) {
    210       QualType T = TD->getIntegerType();
    211       return MakeCXType(T, TU);
    212     }
    213 
    214     return MakeCXType(QualType(), TU);
    215   }
    216 
    217   return MakeCXType(QualType(), TU);
    218 }
    219 
    220 long long clang_getEnumConstantDeclValue(CXCursor C) {
    221   using namespace cxcursor;
    222 
    223   if (clang_isDeclaration(C.kind)) {
    224     Decl *D = cxcursor::getCursorDecl(C);
    225 
    226     if (EnumConstantDecl *TD = dyn_cast_or_null<EnumConstantDecl>(D)) {
    227       return TD->getInitVal().getSExtValue();
    228     }
    229 
    230     return LLONG_MIN;
    231   }
    232 
    233   return LLONG_MIN;
    234 }
    235 
    236 unsigned long long clang_getEnumConstantDeclUnsignedValue(CXCursor C) {
    237   using namespace cxcursor;
    238 
    239   if (clang_isDeclaration(C.kind)) {
    240     Decl *D = cxcursor::getCursorDecl(C);
    241 
    242     if (EnumConstantDecl *TD = dyn_cast_or_null<EnumConstantDecl>(D)) {
    243       return TD->getInitVal().getZExtValue();
    244     }
    245 
    246     return ULLONG_MAX;
    247   }
    248 
    249   return ULLONG_MAX;
    250 }
    251 
    252 CXType clang_getCanonicalType(CXType CT) {
    253   if (CT.kind == CXType_Invalid)
    254     return CT;
    255 
    256   QualType T = GetQualType(CT);
    257   CXTranslationUnit TU = GetTU(CT);
    258 
    259   if (T.isNull())
    260     return MakeCXType(QualType(), GetTU(CT));
    261 
    262   ASTUnit *AU = static_cast<ASTUnit*>(TU->TUData);
    263   return MakeCXType(AU->getASTContext().getCanonicalType(T), TU);
    264 }
    265 
    266 unsigned clang_isConstQualifiedType(CXType CT) {
    267   QualType T = GetQualType(CT);
    268   return T.isLocalConstQualified();
    269 }
    270 
    271 unsigned clang_isVolatileQualifiedType(CXType CT) {
    272   QualType T = GetQualType(CT);
    273   return T.isLocalVolatileQualified();
    274 }
    275 
    276 unsigned clang_isRestrictQualifiedType(CXType CT) {
    277   QualType T = GetQualType(CT);
    278   return T.isLocalRestrictQualified();
    279 }
    280 
    281 CXType clang_getPointeeType(CXType CT) {
    282   QualType T = GetQualType(CT);
    283   const Type *TP = T.getTypePtrOrNull();
    284 
    285   if (!TP)
    286     return MakeCXType(QualType(), GetTU(CT));
    287 
    288   switch (TP->getTypeClass()) {
    289     case Type::Pointer:
    290       T = cast<PointerType>(TP)->getPointeeType();
    291       break;
    292     case Type::BlockPointer:
    293       T = cast<BlockPointerType>(TP)->getPointeeType();
    294       break;
    295     case Type::LValueReference:
    296     case Type::RValueReference:
    297       T = cast<ReferenceType>(TP)->getPointeeType();
    298       break;
    299     case Type::ObjCObjectPointer:
    300       T = cast<ObjCObjectPointerType>(TP)->getPointeeType();
    301       break;
    302     default:
    303       T = QualType();
    304       break;
    305   }
    306   return MakeCXType(T, GetTU(CT));
    307 }
    308 
    309 CXCursor clang_getTypeDeclaration(CXType CT) {
    310   if (CT.kind == CXType_Invalid)
    311     return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
    312 
    313   QualType T = GetQualType(CT);
    314   const Type *TP = T.getTypePtrOrNull();
    315 
    316   if (!TP)
    317     return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
    318 
    319   Decl *D = 0;
    320 
    321 try_again:
    322   switch (TP->getTypeClass()) {
    323   case Type::Typedef:
    324     D = cast<TypedefType>(TP)->getDecl();
    325     break;
    326   case Type::ObjCObject:
    327     D = cast<ObjCObjectType>(TP)->getInterface();
    328     break;
    329   case Type::ObjCInterface:
    330     D = cast<ObjCInterfaceType>(TP)->getDecl();
    331     break;
    332   case Type::Record:
    333   case Type::Enum:
    334     D = cast<TagType>(TP)->getDecl();
    335     break;
    336   case Type::TemplateSpecialization:
    337     if (const RecordType *Record = TP->getAs<RecordType>())
    338       D = Record->getDecl();
    339     else
    340       D = cast<TemplateSpecializationType>(TP)->getTemplateName()
    341                                                          .getAsTemplateDecl();
    342     break;
    343 
    344   case Type::InjectedClassName:
    345     D = cast<InjectedClassNameType>(TP)->getDecl();
    346     break;
    347 
    348   // FIXME: Template type parameters!
    349 
    350   case Type::Elaborated:
    351     TP = cast<ElaboratedType>(TP)->getNamedType().getTypePtrOrNull();
    352     goto try_again;
    353 
    354   default:
    355     break;
    356   }
    357 
    358   if (!D)
    359     return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
    360 
    361   return cxcursor::MakeCXCursor(D, GetTU(CT));
    362 }
    363 
    364 CXString clang_getTypeKindSpelling(enum CXTypeKind K) {
    365   const char *s = 0;
    366 #define TKIND(X) case CXType_##X: s = ""  #X  ""; break
    367   switch (K) {
    368     TKIND(Invalid);
    369     TKIND(Unexposed);
    370     TKIND(Void);
    371     TKIND(Bool);
    372     TKIND(Char_U);
    373     TKIND(UChar);
    374     TKIND(Char16);
    375     TKIND(Char32);
    376     TKIND(UShort);
    377     TKIND(UInt);
    378     TKIND(ULong);
    379     TKIND(ULongLong);
    380     TKIND(UInt128);
    381     TKIND(Char_S);
    382     TKIND(SChar);
    383     case CXType_WChar: s = "WChar"; break;
    384     TKIND(Short);
    385     TKIND(Int);
    386     TKIND(Long);
    387     TKIND(LongLong);
    388     TKIND(Int128);
    389     TKIND(Float);
    390     TKIND(Double);
    391     TKIND(LongDouble);
    392     TKIND(NullPtr);
    393     TKIND(Overload);
    394     TKIND(Dependent);
    395     TKIND(ObjCId);
    396     TKIND(ObjCClass);
    397     TKIND(ObjCSel);
    398     TKIND(Complex);
    399     TKIND(Pointer);
    400     TKIND(BlockPointer);
    401     TKIND(LValueReference);
    402     TKIND(RValueReference);
    403     TKIND(Record);
    404     TKIND(Enum);
    405     TKIND(Typedef);
    406     TKIND(ObjCInterface);
    407     TKIND(ObjCObjectPointer);
    408     TKIND(FunctionNoProto);
    409     TKIND(FunctionProto);
    410     TKIND(ConstantArray);
    411     TKIND(Vector);
    412   }
    413 #undef TKIND
    414   return cxstring::createCXString(s);
    415 }
    416 
    417 unsigned clang_equalTypes(CXType A, CXType B) {
    418   return A.data[0] == B.data[0] && A.data[1] == B.data[1];;
    419 }
    420 
    421 unsigned clang_isFunctionTypeVariadic(CXType X) {
    422   QualType T = GetQualType(X);
    423   if (T.isNull())
    424     return 0;
    425 
    426   if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>())
    427     return (unsigned)FD->isVariadic();
    428 
    429   if (T->getAs<FunctionNoProtoType>())
    430     return 1;
    431 
    432   return 0;
    433 }
    434 
    435 CXCallingConv clang_getFunctionTypeCallingConv(CXType X) {
    436   QualType T = GetQualType(X);
    437   if (T.isNull())
    438     return CXCallingConv_Invalid;
    439 
    440   if (const FunctionType *FD = T->getAs<FunctionType>()) {
    441 #define TCALLINGCONV(X) case CC_##X: return CXCallingConv_##X
    442     switch (FD->getCallConv()) {
    443       TCALLINGCONV(Default);
    444       TCALLINGCONV(C);
    445       TCALLINGCONV(X86StdCall);
    446       TCALLINGCONV(X86FastCall);
    447       TCALLINGCONV(X86ThisCall);
    448       TCALLINGCONV(X86Pascal);
    449       TCALLINGCONV(AAPCS);
    450       TCALLINGCONV(AAPCS_VFP);
    451     }
    452 #undef TCALLINGCONV
    453   }
    454 
    455   return CXCallingConv_Invalid;
    456 }
    457 
    458 int clang_getNumArgTypes(CXType X) {
    459   QualType T = GetQualType(X);
    460   if (T.isNull())
    461     return -1;
    462 
    463   if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) {
    464     return FD->getNumArgs();
    465   }
    466 
    467   if (T->getAs<FunctionNoProtoType>()) {
    468     return 0;
    469   }
    470 
    471   return -1;
    472 }
    473 
    474 CXType clang_getArgType(CXType X, unsigned i) {
    475   QualType T = GetQualType(X);
    476   if (T.isNull())
    477     return MakeCXType(QualType(), GetTU(X));
    478 
    479   if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) {
    480     unsigned numArgs = FD->getNumArgs();
    481     if (i >= numArgs)
    482       return MakeCXType(QualType(), GetTU(X));
    483 
    484     return MakeCXType(FD->getArgType(i), GetTU(X));
    485   }
    486 
    487   return MakeCXType(QualType(), GetTU(X));
    488 }
    489 
    490 CXType clang_getResultType(CXType X) {
    491   QualType T = GetQualType(X);
    492   if (T.isNull())
    493     return MakeCXType(QualType(), GetTU(X));
    494 
    495   if (const FunctionType *FD = T->getAs<FunctionType>())
    496     return MakeCXType(FD->getResultType(), GetTU(X));
    497 
    498   return MakeCXType(QualType(), GetTU(X));
    499 }
    500 
    501 CXType clang_getCursorResultType(CXCursor C) {
    502   if (clang_isDeclaration(C.kind)) {
    503     Decl *D = cxcursor::getCursorDecl(C);
    504     if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
    505       return MakeCXType(MD->getResultType(), cxcursor::getCursorTU(C));
    506 
    507     return clang_getResultType(clang_getCursorType(C));
    508   }
    509 
    510   return MakeCXType(QualType(), cxcursor::getCursorTU(C));
    511 }
    512 
    513 unsigned clang_isPODType(CXType X) {
    514   QualType T = GetQualType(X);
    515   if (T.isNull())
    516     return 0;
    517 
    518   CXTranslationUnit TU = GetTU(X);
    519   ASTUnit *AU = static_cast<ASTUnit*>(TU->TUData);
    520 
    521   return T.isPODType(AU->getASTContext()) ? 1 : 0;
    522 }
    523 
    524 CXType clang_getElementType(CXType CT) {
    525   QualType ET = QualType();
    526   QualType T = GetQualType(CT);
    527   const Type *TP = T.getTypePtrOrNull();
    528 
    529   if (TP) {
    530     switch (TP->getTypeClass()) {
    531     case Type::ConstantArray:
    532       ET = cast<ConstantArrayType> (TP)->getElementType();
    533       break;
    534     case Type::Vector:
    535       ET = cast<VectorType> (TP)->getElementType();
    536       break;
    537     case Type::Complex:
    538       ET = cast<ComplexType> (TP)->getElementType();
    539       break;
    540     default:
    541       break;
    542     }
    543   }
    544   return MakeCXType(ET, GetTU(CT));
    545 }
    546 
    547 long long clang_getNumElements(CXType CT) {
    548   long long result = -1;
    549   QualType T = GetQualType(CT);
    550   const Type *TP = T.getTypePtrOrNull();
    551 
    552   if (TP) {
    553     switch (TP->getTypeClass()) {
    554     case Type::ConstantArray:
    555       result = cast<ConstantArrayType> (TP)->getSize().getSExtValue();
    556       break;
    557     case Type::Vector:
    558       result = cast<VectorType> (TP)->getNumElements();
    559       break;
    560     default:
    561       break;
    562     }
    563   }
    564   return result;
    565 }
    566 
    567 CXType clang_getArrayElementType(CXType CT) {
    568   QualType ET = QualType();
    569   QualType T = GetQualType(CT);
    570   const Type *TP = T.getTypePtrOrNull();
    571 
    572   if (TP) {
    573     switch (TP->getTypeClass()) {
    574     case Type::ConstantArray:
    575       ET = cast<ConstantArrayType> (TP)->getElementType();
    576       break;
    577     default:
    578       break;
    579     }
    580   }
    581   return MakeCXType(ET, GetTU(CT));
    582 }
    583 
    584 long long clang_getArraySize(CXType CT) {
    585   long long result = -1;
    586   QualType T = GetQualType(CT);
    587   const Type *TP = T.getTypePtrOrNull();
    588 
    589   if (TP) {
    590     switch (TP->getTypeClass()) {
    591     case Type::ConstantArray:
    592       result = cast<ConstantArrayType> (TP)->getSize().getSExtValue();
    593       break;
    594     default:
    595       break;
    596     }
    597   }
    598   return result;
    599 }
    600 
    601 CXString clang_getDeclObjCTypeEncoding(CXCursor C) {
    602   if ((C.kind < CXCursor_FirstDecl) || (C.kind > CXCursor_LastDecl))
    603     return cxstring::createCXString("");
    604 
    605   Decl *D = static_cast<Decl*>(C.data[0]);
    606   CXTranslationUnit TU = static_cast<CXTranslationUnit>(C.data[2]);
    607   ASTUnit *AU = static_cast<ASTUnit*>(TU->TUData);
    608   ASTContext &Ctx = AU->getASTContext();
    609   std::string encoding;
    610 
    611   if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D))  {
    612     if (Ctx.getObjCEncodingForMethodDecl(OMD, encoding))
    613       return cxstring::createCXString("?");
    614   } else if (ObjCPropertyDecl *OPD = dyn_cast<ObjCPropertyDecl>(D))
    615     Ctx.getObjCEncodingForPropertyDecl(OPD, NULL, encoding);
    616   else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
    617     Ctx.getObjCEncodingForFunctionDecl(FD, encoding);
    618   else {
    619     QualType Ty;
    620     if (TypeDecl *TD = dyn_cast<TypeDecl>(D))
    621       Ty = Ctx.getTypeDeclType(TD);
    622     if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
    623       Ty = VD->getType();
    624     else return cxstring::createCXString("?");
    625     Ctx.getObjCEncodingForType(Ty, encoding);
    626   }
    627 
    628   return cxstring::createCXString(encoding);
    629 }
    630 
    631 } // end: extern "C"
    632