I have the following code that uses the clang-c API.
#include <iostream>
#include <string>
#include <clang-c/Index.h>
CXChildVisitResult printVisitor(CXCursor cursor, CXCursor parent, CXClientData client_data)
{
CXCursor cursor1 = clang_getCursorReferenced(cursor);
CXType type = clang_getCursorType(cursor1);
CXCursorKind kind = clang_getCursorKind(cursor1);
CXString str = clang_getTypeSpelling(type);
CXString str1 = clang_getCursorSpelling(cursor1);
std::string cstr = clang_getCString(str);
std::string cstr1 = clang_getCString(str1);
if(type.kind != 0 && kind == CXCursorKind::CXCursor_FunctionDecl)
{
std::cout << "Declaration!\n" << "type is: " << cstr << std::endl;
std::cout << "name is: " << cstr1 << std::endl;
}
return CXChildVisit_Recurse;
}
int main (int argc, char** argv)
{
CXIndex index = clang_createIndex (
false, // excludeDeclarationFromPCH
true // displayDiagnostics
);
CXTranslationUnit unit = clang_parseTranslationUnit (
index, // CIdx
"main1.cpp", // source_filename
argv + 1 , // command_line_args
argc - 1 , // num_command_line_args
0, // unsave_files
0, // num_unsaved_files
CXTranslationUnit_None // options
);
if (unit != 0 )
std::cout << "Translation unit successfully created" << std::endl;
else
std::cout << "Translation unit was not created" << std::endl;
CXCursor rootCursor = clang_getTranslationUnitCursor(unit);
clang_visitChildren(rootCursor, printVisitor, NULL);
clang_disposeTranslationUnit(unit);
clang_disposeIndex(index);
}
This code parses the following.
double getSum(double a, float b)
{
return a + b;
}
int main(void)
{
int a = 5;
float b = 6;
double c = a + b;
return getSum(c, b);
}
When the program runs, I see the following.
Translation unit successfully created
Declaration!
type is: double (double, float)
name is: getSum
Declaration!
type is: int ()
name is: main
Declaration!
type is: double (double, float)
name is: getSum
Declaration!
type is: double (double, float)
name is: getSum
Declaration!
type is: double (double, float)
name is: getSum
Declaration!
type is: double (double, float)
name is: getSum
Why do I get so much declarations of getSum()
, when in the code I have a single declaration?
When you use clang_getCursorReferenced
, you get the CXCursor
which is referenced at the current location. For example, a function declaration references itself, and is referenced by the corresponding function call(s). In your example, you will thus get positive matches for every reference to a function declaration (either a function declaration itself or a function call).
Now the other thing is that each CXCursor
represents a part of the AST, either a leaf or a more complex part with subparts. For example, while traversing the AST, you'll find in turn the following cursors:
return getSum (c, b)
getSum (c, b)
getSum
All these cursors reference the getSum
function declaration, and my guess is that these are the cursors which trigger multiple references to getSum
.
You can check which part of the source code corresponds to the current cursor by calling clang_getCursorExtent
I've never used clang, but based on the documentation of CXCursor it seems that the CXCursorKind
will always be Declaration
whenever the cursor is somewhere in a function (main
may get special treatment I suppose). This may explain why you have multiple reports of a declaration of Sum
.
I base my conjecture on the definition of CXCursorKind
, found here:
enum CXCursorKind {
/* Declarations */
/**
* \brief A declaration whose specific kind is not exposed via this
* interface.
*
* Unexposed declarations have the same operations as any other kind
* of declaration; one can extract their location information,
* spelling, find their definitions, etc. However, the specific kind
* of the declaration is not reported.
*/
...
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With