From 5389f48b24937ad7b4093307128b3cbf25235654 Mon Sep 17 00:00:00 2001 From: David Chisnall Date: Thu, 30 Dec 2010 14:05:53 +0000 Subject: [PATCH] Expose Objective-C type encodings of declarations to libclang users. This also adds a method in ASTContext which encodes FunctionDecls using the same encoding format that is used for Objective-C methods. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@122639 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang-c/Index.h | 4 +++ include/clang/AST/ASTContext.h | 4 +++ lib/AST/ASTContext.cpp | 36 ++++++++++++++++++++++++++ tools/libclang/CXType.cpp | 29 +++++++++++++++++++++ tools/libclang/libclang.darwin.exports | 1 + tools/libclang/libclang.exports | 1 + 6 files changed, 75 insertions(+) diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h index 9bf492d5f8..46b429dda2 100644 --- a/include/clang-c/Index.h +++ b/include/clang-c/Index.h @@ -1792,6 +1792,10 @@ CINDEX_LINKAGE CXType clang_getPointeeType(CXType T); */ CINDEX_LINKAGE CXCursor clang_getTypeDeclaration(CXType T); +/** + * Returns the Objective-C type encoding for the specified declaration. + */ +CINDEX_LINKAGE CXString clang_getDeclObjCTypeEncoding(CXCursor C); /** * \brief Retrieve the spelling of a given CXTypeKind. diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index 757cddbfd2..beba66947e 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -828,6 +828,10 @@ public: void getObjCEncodingForTypeQualifier(Decl::ObjCDeclQualifier QT, std::string &S) const; + /// getObjCEncodingForFunctionDecl - Returns the encoded type for this + //function. This is in the same format as Objective-C method encodings. + void getObjCEncodingForFunctionDecl(const FunctionDecl *Decl, std::string& S); + /// getObjCEncodingForMethodDecl - Return the encoded type for this method /// declaration. void getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl, std::string &S); diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index b1fd16fb07..149ecbc599 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -3526,6 +3526,42 @@ void ASTContext::getObjCEncodingForBlock(const BlockExpr *Expr, } } +void ASTContext::getObjCEncodingForFunctionDecl(const FunctionDecl *Decl, + std::string& S) { + // Encode result type. + getObjCEncodingForType(Decl->getResultType(), S); + CharUnits ParmOffset; + // Compute size of all parameters. + for (FunctionDecl::param_const_iterator PI = Decl->param_begin(), + E = Decl->param_end(); PI != E; ++PI) { + QualType PType = (*PI)->getType(); + CharUnits sz = getObjCEncodingTypeSize(PType); + assert (sz.isPositive() && + "getObjCEncodingForMethodDecl - Incomplete param type"); + ParmOffset += sz; + } + S += charUnitsToString(ParmOffset); + ParmOffset = CharUnits::Zero(); + + // Argument types. + for (FunctionDecl::param_const_iterator PI = Decl->param_begin(), + E = Decl->param_end(); PI != E; ++PI) { + ParmVarDecl *PVDecl = *PI; + QualType PType = PVDecl->getOriginalType(); + if (const ArrayType *AT = + dyn_cast(PType->getCanonicalTypeInternal())) { + // Use array's original type only if it has known number of + // elements. + if (!isa(AT)) + PType = PVDecl->getType(); + } else if (PType->isFunctionType()) + PType = PVDecl->getType(); + getObjCEncodingForType(PType, S); + S += charUnitsToString(ParmOffset); + ParmOffset += getObjCEncodingTypeSize(PType); + } +} + /// getObjCEncodingForMethodDecl - Return the encoded type for this method /// declaration. void ASTContext::getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl, diff --git a/tools/libclang/CXType.cpp b/tools/libclang/CXType.cpp index e1297a4325..a72b02f045 100644 --- a/tools/libclang/CXType.cpp +++ b/tools/libclang/CXType.cpp @@ -353,4 +353,33 @@ unsigned clang_isPODType(CXType X) { return T->isPODType() ? 1 : 0; } +CXString clang_getDeclObjCTypeEncoding(CXCursor C) { + if ((C.kind < CXCursor_FirstDecl) || (C.kind > CXCursor_LastDecl)) + return cxstring::createCXString(""); + + Decl *D = static_cast(C.data[0]); + CXTranslationUnit TU = static_cast(C.data[2]); + ASTUnit *AU = static_cast(TU->TUData); + ASTContext &Ctx = AU->getASTContext(); + std::string encoding; + + if (ObjCMethodDecl *OMD = dyn_cast(D)) + Ctx.getObjCEncodingForMethodDecl(OMD, encoding); + else if (ObjCPropertyDecl *OPD = dyn_cast(D)) + Ctx.getObjCEncodingForPropertyDecl(OPD, NULL, encoding); + else if (FunctionDecl *FD = dyn_cast(D)) + Ctx.getObjCEncodingForFunctionDecl(FD, encoding); + else { + QualType Ty; + if (TypeDecl *TD = dyn_cast(D)) + Ty = QualType(TD->getTypeForDecl(), 0); + if (ValueDecl *VD = dyn_cast(D)) + Ty = VD->getType(); + else return cxstring::createCXString("?"); + Ctx.getObjCEncodingForType(Ty, encoding); + } + + return cxstring::createCXString(encoding); +} + } // end: extern "C" diff --git a/tools/libclang/libclang.darwin.exports b/tools/libclang/libclang.darwin.exports index 33a0f8382f..1792312de2 100644 --- a/tools/libclang/libclang.darwin.exports +++ b/tools/libclang/libclang.darwin.exports @@ -61,6 +61,7 @@ _clang_getCursorSemanticParent _clang_getCursorSpelling _clang_getCursorType _clang_getCursorUSR +_clang_getDeclObjCTypeEncoding _clang_getDefinitionSpellingAndExtent _clang_getDiagnostic _clang_getDiagnosticCategory diff --git a/tools/libclang/libclang.exports b/tools/libclang/libclang.exports index d966b6654e..c5415e3614 100644 --- a/tools/libclang/libclang.exports +++ b/tools/libclang/libclang.exports @@ -61,6 +61,7 @@ clang_getCursorSemanticParent clang_getCursorSpelling clang_getCursorType clang_getCursorUSR +clang_getDeclObjCTypeEncoding clang_getDefinitionSpellingAndExtent clang_getDiagnostic clang_getDiagnosticCategory -- 2.40.0