[libclang] Introduce a couple of functions to make it convenient

to get at the parameters (and their types) of a function or objc method cursor.

int clang_Cursor_getNumArguments(CXCursor C);
CXCursor clang_Cursor_getArgument(CXCursor C, unsigned i);

rdar://11201527

llvm-svn: 154523
This commit is contained in:
Argyrios Kyrtzidis 2012-04-11 19:32:19 +00:00
parent cc899f3b6d
commit 0c27e4b36b
7 changed files with 71 additions and 8 deletions

View File

@ -2524,6 +2524,22 @@ CINDEX_LINKAGE long long clang_getEnumConstantDeclValue(CXCursor C);
*/
CINDEX_LINKAGE unsigned long long clang_getEnumConstantDeclUnsignedValue(CXCursor C);
/**
* \brief Retrieve the number of non-variadic arguments associated with a given
* cursor.
*
* If a cursor that is not a function or method is passed in, -1 is returned.
*/
CINDEX_LINKAGE int clang_Cursor_getNumArguments(CXCursor C);
/**
* \brief Retrieve the argument cursor of a function or method.
*
* If a cursor that is not a function or method is passed in or the index
* exceeds the number of arguments, an invalid cursor is returned.
*/
CINDEX_LINKAGE CXCursor clang_Cursor_getArgument(CXCursor C, unsigned i);
/**
* \determine Determine whether two CXTypes represent the same type.
*
@ -2598,9 +2614,9 @@ CINDEX_LINKAGE CXType clang_getResultType(CXType T);
/**
* \brief Retrieve the number of non-variadic arguments associated with a function type.
*
* If a non-function type is passed in, UINT_MAX is returned.
* If a non-function type is passed in, -1 is returned.
*/
CINDEX_LINKAGE unsigned clang_getNumArgTypes(CXType T);
CINDEX_LINKAGE int clang_getNumArgTypes(CXType T);
/**
* \brief Retrieve the type of an argument of a function type.

View File

@ -10,7 +10,7 @@ typedef int ArrayType[5];
// RUN: c-index-test -test-print-typekind %s | FileCheck %s
// CHECK: TypedefDecl=FooType:1:13 (Definition) typekind=Typedef [canonical=Int] [isPOD=1]
// CHECK: VarDecl=p:2:6 typekind=Pointer [isPOD=1]
// CHECK: FunctionDecl=f:3:6 (Definition) typekind=FunctionProto [canonical=FunctionProto] [result=Pointer] [isPOD=0]
// CHECK: FunctionDecl=f:3:6 (Definition) typekind=FunctionProto [canonical=FunctionProto] [result=Pointer] [args= Pointer Pointer Typedef] [isPOD=0]
// CHECK: ParmDecl=p:3:13 (Definition) typekind=Pointer [isPOD=1]
// CHECK: ParmDecl=x:3:22 (Definition) typekind=Pointer [isPOD=1]
// CHECK: ParmDecl=z:3:33 (Definition) typekind=Typedef [canonical=Int] [isPOD=1]

View File

@ -1,10 +1,10 @@
@interface Foo
@property (readonly) id x;
-(int) mymethod;
-(int) mymethod2:(int)x blah:(float)y;
@end
// RUN: c-index-test -test-print-typekind %s | FileCheck %s
// CHECK: ObjCPropertyDecl=x:2:25 typekind=Typedef [canonical=ObjCObjectPointer]
// CHECK: ObjCInstanceMethodDecl=mymethod:3:8 typekind=Invalid [result=Int]
// CHECK: ObjCInstanceMethodDecl=mymethod2:blah::4:8 typekind=Invalid [result=Int] [args= Int Float]

View File

@ -663,6 +663,22 @@ static enum CXChildVisitResult PrintTypeKind(CXCursor cursor, CXCursor p,
clang_disposeString(RS);
}
}
/* Print the argument types if they exist. */
{
int numArgs = clang_Cursor_getNumArguments(cursor);
if (numArgs != -1 && numArgs != 0) {
printf(" [args=");
for (int i = 0; i < numArgs; ++i) {
CXType T = clang_getCursorType(clang_Cursor_getArgument(cursor, i));
if (T.kind != CXType_Invalid) {
CXString S = clang_getTypeKindSpelling(T.kind);
printf(" %s", clang_getCString(S));
clang_disposeString(S);
}
}
printf("]");
}
}
/* Print if this is a non-POD type. */
printf(" [isPOD=%d]", clang_isPODType(T));

View File

@ -1024,6 +1024,35 @@ CXTranslationUnit clang_Cursor_getTranslationUnit(CXCursor cursor) {
return getCursorTU(cursor);
}
int clang_Cursor_getNumArguments(CXCursor C) {
if (clang_isDeclaration(C.kind)) {
Decl *D = cxcursor::getCursorDecl(C);
if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
return MD->param_size();
if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
return FD->param_size();
}
return -1;
}
CXCursor clang_Cursor_getArgument(CXCursor C, unsigned i) {
if (clang_isDeclaration(C.kind)) {
Decl *D = cxcursor::getCursorDecl(C);
if (ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D)) {
if (i < MD->param_size())
return cxcursor::MakeCXCursor(MD->param_begin()[i],
cxcursor::getCursorTU(C));
} else if (FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) {
if (i < FD->param_size())
return cxcursor::MakeCXCursor(FD->param_begin()[i],
cxcursor::getCursorTU(C));
}
}
return clang_getNullCursor();
}
} // end: extern "C"
//===----------------------------------------------------------------------===//

View File

@ -455,10 +455,10 @@ CXCallingConv clang_getFunctionTypeCallingConv(CXType X) {
return CXCallingConv_Invalid;
}
unsigned clang_getNumArgTypes(CXType X) {
int clang_getNumArgTypes(CXType X) {
QualType T = GetQualType(X);
if (T.isNull())
return UINT_MAX;
return -1;
if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) {
return FD->getNumArgs();
@ -468,7 +468,7 @@ unsigned clang_getNumArgTypes(CXType X) {
return 0;
}
return UINT_MAX;
return -1;
}
CXType clang_getArgType(CXType X, unsigned i) {

View File

@ -4,6 +4,8 @@ clang_CXIndex_getGlobalOptions
clang_CXIndex_setGlobalOptions
clang_CXXMethod_isStatic
clang_CXXMethod_isVirtual
clang_Cursor_getArgument
clang_Cursor_getNumArguments
clang_Cursor_getSpellingNameRange
clang_Cursor_getTranslationUnit
clang_Cursor_getObjCSelectorIndex