Function return type and namespace qualifiers in libclang

Hello!

  1. When traversing AST (with clang_visitChildren) parsed from this code:

namespace foo {

struct bar {};

struct baz {

bar qux();

};

}

foo::bar foo::baz::qux() {}

…following nodes are visited for qux() definition (last line):

±-------------±--------±-------±----------------+

kind | parent | text | spelling |

±-------------±--------±-------±----------------+

NamespaceRef | qux() | foo | foo |

TypeRef | qux() | bar | struct foo::bar |

NamespaceRef | qux() | foo | foo |

TypeRef | qux() | baz | struct foo::baz |

±-------------±--------±-------±----------------+

First two nodes are function return type and second two nodes are function namespace qualifiers.

Is it possible to determine, if visited node (cursor) belongs to return type or to qualifier?

If not, what is a preferred way to implement such mechanism in libclang?

  1. When traversing AST parsed from this code:

foo::bar var1;

::foo::bar var2;

where foo is top-level namespace, is it possible to determine, was foo referenced as ‘foo’ or as ‘::foo’?

For both var1 and var2 NamespaceRef spelling and substring pointed by cursor extent are just ‘foo’.

Thanks.

PS.

I’m working on experimental back-end for emacs’s semantic that will implement C++ parser using libclang. It will be plugin for irony-mode written by Guillaume Papin.

https://github.com/Sarcasm/irony-mode

https://github.com/Sarcasm/irony-mode/issues/5

– Victor

In these matters the only certainty is that there is nothing certain.

– Pliny the Elder

Victor Gaydov (Sunday 03 February 2013 00:49:16):

Hello!

  1. When traversing AST (with clang_visitChildren) parsed from this code:

namespace foo {

struct bar {};

struct baz {

bar qux();

};

}

foo::bar foo::baz::qux() {}

…following nodes are visited for qux() definition (last line):

±-------------±--------±-------±----------------+

kind | parent | text | spelling |

±-------------±--------±-------±----------------+

NamespaceRef | qux() | foo | foo |

TypeRef | qux() | bar | struct foo::bar |

NamespaceRef | qux() | foo | foo |

TypeRef | qux() | baz | struct foo::baz |

±-------------±--------±-------±----------------+

First two nodes are function return type and second two nodes are function

namespace qualifiers.

Is it possible to determine, if visited node (cursor) belongs to return

type or to qualifier?

[…]

Update: I also was unable to get namespace qualifiers of FunctionDecl with clang_getCursorReferenceNameRange() and didn’t find anything helpful in clang/tools/c-index-test.c.

So is it impossible to get qualified name of function and its return type (when both are qualified) with current API?

If this is so, I would like to write a patch. One possible approach is to transform AST for this code:

foo::bar foo::baz::qux() {}

from:

qux ← FunctionDecl

/ \

/ \

/| |\

/ | | \

/ | | \

/ | | \

foo bar foo baz

to:

qux ← FunctionDecl

/ \

/ \

/ \ \

/ foo baz

/

o ← FunctionReturnType (new cursor type)

/ \

/ \

foo bar

But I guess this can break backward compatibility? I’m new to libclang, so I need some advice about preferred way to implement such patch.

Thanks, sorry for self-replying.

– Victor

Victor Gaydov (Sunday 03 February 2013 00:49:16):

Hello!

  1. When traversing AST (with clang_visitChildren) parsed from this code:

namespace foo {
struct bar {};
struct baz {
bar qux();
};
}

foo::bar foo::baz::qux() {}

…following nodes are visited for qux() definition (last line):

±-------------±--------±-------±----------------+

kind | parent | text | spelling |
±-------------±--------±-------±----------------+
NamespaceRef | qux() | foo | foo |
TypeRef | qux() | bar | struct foo::bar |
NamespaceRef | qux() | foo | foo |
TypeRef | qux() | baz | struct foo::baz |
±-------------±--------±-------±----------------+

First two nodes are function return type and second two nodes are function
namespace qualifiers.

Is it possible to determine, if visited node (cursor) belongs to return
type or to qualifier?

[…]

Update: I also was unable to get namespace qualifiers of FunctionDecl with clang_getCursorReferenceNameRange() and didn’t find anything helpful in clang/tools/c-index-test.c.

So is it impossible to get qualified name of function and its return type (when both are qualified) with current API?

If this is so, I would like to write a patch. One possible approach is to transform AST for this code:

foo::bar foo::baz::qux() {}

from:

qux ← FunctionDecl
/
/
/| |
/ | |
/ | |
/ | |
foo bar foo baz

to:

qux ← FunctionDecl
/
/
/ \
/ foo baz
/
o ← FunctionReturnType (new cursor type)
/
/
foo bar

But I guess this can break backward compatibility? I’m new to libclang, so I need some advice about preferred way to implement such patch.

I suggest enhancing “clang_Cursor_getSpellingNameRange()” to work similar as “clang_getCursorReferenceNameRange()” and have it accept the same options (e.g. CXNameRange_WantQualifier).
Then you can pass it the cursor for the function and compare the CXSourceRanges that it gives you with the ones for the NamespaceRef/TypeRef cursors.