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