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