Index: bindings/python/clang/cindex.py =================================================================== --- bindings/python/clang/cindex.py +++ bindings/python/clang/cindex.py @@ -1217,6 +1217,17 @@ return self._extent @property + def storage_class(self): + """ + Retrieves the storage class (if any) of the entity pointed at by the + cursor. + """ + if not hasattr(self, '_storage_class'): + self._storage_class = conf.lib.clang_getStorageClass(self) + + return StorageClass.from_id(self._storage_class) + + @property def access_specifier(self): """ Retrieves the access specifier (if any) of the entity pointed at by the @@ -1459,6 +1470,56 @@ res._tu = args[0]._tu return res +class StorageClass(object): + """ + Describes the storage class of a declaration + """ + + # The unique kind objects, index by id. + _kinds = [] + _name_map = None + + def __init__(self, value): + if value >= len(StorageClass._kinds): + StorageClass._kinds += [None] * (value - len(StorageClass._kinds) + 1) + if StorageClass._kinds[value] is not None: + raise ValueError,'StorageClass already loaded' + self.value = value + StorageClass._kinds[value] = self + StorageClass._name_map = None + + def from_param(self): + return self.value + + @property + def name(self): + """Get the enumeration name of this storage class.""" + if self._name_map is None: + self._name_map = {} + for key,value in StorageClass.__dict__.items(): + if isinstance(value,StorageClass): + self._name_map[value] = key + return self._name_map[self] + + @staticmethod + def from_id(id): + if id >= len(StorageClass._kinds) or not StorageClass._kinds[id]: + raise ValueError,'Unknown storage class %d' % id + return StorageClass._kinds[id] + + def __repr__(self): + return 'StorageClass.%s' % (self.name,) + +StorageClass.INVALID = StorageClass(0) +StorageClass.NONE = StorageClass(1) +StorageClass.EXTERN = StorageClass(2) +StorageClass.STATIC = StorageClass(3) +StorageClass.PRIVATEEXTERN = StorageClass(4) +StorageClass.OPENCLWORKGROUPLOCAL = StorageClass(5) +StorageClass.AUTO = StorageClass(6) +StorageClass.REGISTER = StorageClass(7) + + ### C++ access specifiers ### class AccessSpecifier(object): Index: include/clang-c/Index.h =================================================================== --- include/clang-c/Index.h +++ include/clang-c/Index.h @@ -1716,6 +1716,12 @@ CXCursor_LastRef = CXCursor_VariableRef, + /** + * \brief The storage class for functions and variables. + * + */ + CXCursor_StorageClass = 51, + /* Error conditions */ CXCursor_FirstInvalid = 70, CXCursor_InvalidFile = 70, @@ -3220,6 +3226,19 @@ */ CINDEX_LINKAGE enum CX_CXXAccessSpecifier clang_getCXXAccessSpecifier(CXCursor); +enum CX_StorageClass { + CX_SC_Invalid, + CX_SC_None, + CX_SC_Extern, + CX_SC_Static, + CX_SC_PrivateExtern, + CX_SC_OpenCLWorkGroupLocal, + CX_SC_Auto, + CX_SC_Register +}; + +CINDEX_LINKAGE enum CX_StorageClass clang_getStorageClass(CXCursor); + /** * \brief Determine the number of overloaded declarations referenced by a * \c CXCursor_OverloadedDeclRef cursor. Index: tools/libclang/CIndex.cpp =================================================================== --- tools/libclang/CIndex.cpp +++ tools/libclang/CIndex.cpp @@ -4145,6 +4145,8 @@ return cxstring::createRef("ObjCSynthesizeDecl"); case CXCursor_ObjCDynamicDecl: return cxstring::createRef("ObjCDynamicDecl"); + case CXCursor_StorageClass: + return cxstring::createRef("StorageClass"); case CXCursor_CXXAccessSpecifier: return cxstring::createRef("CXXAccessSpecifier"); case CXCursor_ModuleImportDecl: @@ -6410,6 +6412,41 @@ return D; } + +enum CX_StorageClass clang_getStorageClass(CXCursor C){ + StorageClass sc = SC_None; + Decl const * D = getCursorDecl(C); + if(D){ + if(FunctionDecl const * FD = dyn_cast(D)){ + sc = FD->getStorageClass(); + }else if(VarDecl const * VD = dyn_cast(D)){ + sc = VD->getStorageClass(); + }else{ + return CX_SC_Invalid; + } + }else{ + return CX_SC_Invalid; + } + switch(sc){ + case SC_None : + return CX_SC_None; + case SC_Extern : + return CX_SC_Extern; + case SC_Static : + return CX_SC_Static; + case SC_PrivateExtern : + return CX_SC_PrivateExtern; + case SC_OpenCLWorkGroupLocal : + return CX_SC_OpenCLWorkGroupLocal; + case SC_Auto : + return CX_SC_Auto; + case SC_Register : + return CX_SC_Register; + default: + return CX_SC_Invalid; + } +} + CXCursor clang_getCursorSemanticParent(CXCursor cursor) { if (clang_isDeclaration(cursor.kind)) { if (const Decl *D = getCursorDecl(cursor)) { Index: tools/libclang/libclang.exports =================================================================== --- tools/libclang/libclang.exports +++ tools/libclang/libclang.exports @@ -129,6 +129,7 @@ clang_getBuildSessionTimestamp clang_getCString clang_getCXTUResourceUsage +clang_getStorageClass clang_getCXXAccessSpecifier clang_getCanonicalCursor clang_getCanonicalType