2017-02-16 09:35:30 +00:00
|
|
|
#include "Cursor.h"
|
|
|
|
#include "Utility.h"
|
|
|
|
#include <algorithm>
|
|
|
|
|
|
|
|
namespace clang {
|
|
|
|
|
2017-02-17 09:57:44 +00:00
|
|
|
static_assert(sizeof(Cursor) == sizeof(CXCursor), "Cursor must be the same size as CXCursor");
|
|
|
|
|
|
|
|
std::string Type::get_spelling() const {
|
|
|
|
return ToString(clang_getTypeSpelling(cx_type));
|
|
|
|
}
|
|
|
|
|
|
|
|
Type Cursor::get_type() const {
|
|
|
|
return Type(clang_getCursorType(cx_cursor));
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Type::operator==(const Type& rhs) const {
|
|
|
|
return clang_equalTypes(cx_type, rhs.cx_type);
|
2017-02-16 09:35:30 +00:00
|
|
|
}
|
|
|
|
|
2017-02-17 09:57:44 +00:00
|
|
|
Type Type::get_result() const {
|
2017-02-16 09:35:30 +00:00
|
|
|
return Type(clang_getResultType(cx_type));
|
|
|
|
}
|
|
|
|
|
2017-02-17 09:57:44 +00:00
|
|
|
Cursor::Cursor() : cx_cursor(clang_getNullCursor()) {}
|
2017-02-16 09:35:30 +00:00
|
|
|
|
2017-02-17 09:57:44 +00:00
|
|
|
Cursor::Cursor(const CXCursor& other) : cx_cursor(other) {}
|
2017-02-16 09:35:30 +00:00
|
|
|
|
2017-02-17 09:57:44 +00:00
|
|
|
Cursor::operator bool() const {
|
|
|
|
return !clang_Cursor_isNull(cx_cursor);
|
2017-02-16 09:35:30 +00:00
|
|
|
}
|
|
|
|
|
2017-02-17 09:57:44 +00:00
|
|
|
bool Cursor::operator==(const Cursor& rhs) const {
|
|
|
|
return clang_equalCursors(cx_cursor, rhs.cx_cursor);
|
2017-02-16 09:35:30 +00:00
|
|
|
}
|
|
|
|
|
2017-02-17 09:57:44 +00:00
|
|
|
CXCursorKind Cursor::get_kind() const {
|
|
|
|
return cx_cursor.kind;
|
2017-02-16 09:35:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
SourceLocation Cursor::get_source_location() const {
|
|
|
|
return SourceLocation(clang_getCursorLocation(cx_cursor));
|
|
|
|
}
|
|
|
|
|
|
|
|
SourceRange Cursor::get_source_range() const {
|
|
|
|
return SourceRange(clang_getCursorExtent(cx_cursor));
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string Cursor::get_spelling() const {
|
2017-02-17 09:57:44 +00:00
|
|
|
return ToString(clang_getCursorSpelling(cx_cursor));
|
2017-02-16 09:35:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
std::string Cursor::get_display_name() const {
|
2017-02-17 09:57:44 +00:00
|
|
|
return ToString(clang_getCursorDisplayName(cx_cursor));
|
2017-02-16 09:35:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
std::string Cursor::get_usr() const {
|
2017-02-17 09:57:44 +00:00
|
|
|
return ToString(clang_getCursorUSR(cx_cursor));
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Cursor::is_definition() const {
|
|
|
|
return clang_isCursorDefinition(cx_cursor);
|
2017-02-16 09:35:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Cursor Cursor::get_referenced() const {
|
|
|
|
return Cursor(clang_getCursorReferenced(cx_cursor));
|
|
|
|
}
|
|
|
|
|
|
|
|
Cursor Cursor::get_canonical() const {
|
|
|
|
return Cursor(clang_getCanonicalCursor(cx_cursor));
|
|
|
|
}
|
|
|
|
|
|
|
|
Cursor Cursor::get_definition() const {
|
|
|
|
return Cursor(clang_getCursorDefinition(cx_cursor));
|
|
|
|
}
|
|
|
|
|
|
|
|
Cursor Cursor::get_semantic_parent() const {
|
|
|
|
return Cursor(clang_getCursorSemanticParent(cx_cursor));
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<Cursor> Cursor::get_arguments() const {
|
|
|
|
auto size = clang_Cursor_getNumArguments(cx_cursor);
|
|
|
|
std::vector<Cursor> cursors(size);
|
|
|
|
for (int c = 0; c < size; ++c)
|
|
|
|
cursors.emplace_back(clang_Cursor_getArgument(cx_cursor, c));
|
|
|
|
return cursors;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Cursor::is_valid_kind() const {
|
|
|
|
CXCursor referenced = clang_getCursorReferenced(cx_cursor);
|
|
|
|
if (clang_Cursor_isNull(referenced))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
CXCursorKind kind = get_kind();
|
|
|
|
return kind > CXCursor_UnexposedDecl &&
|
|
|
|
(kind < CXCursor_FirstInvalid || kind > CXCursor_LastInvalid);
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string Cursor::get_type_description() const {
|
|
|
|
std::string spelling;
|
|
|
|
|
|
|
|
auto referenced = clang_getCursorReferenced(cx_cursor);
|
|
|
|
if (!clang_Cursor_isNull(referenced)) {
|
|
|
|
auto type = clang_getCursorType(referenced);
|
2017-02-17 09:57:44 +00:00
|
|
|
spelling = ToString(clang_getTypeSpelling(type));
|
2017-02-16 09:35:30 +00:00
|
|
|
|
|
|
|
#if CINDEX_VERSION_MAJOR==0 && CINDEX_VERSION_MINOR<32
|
|
|
|
const std::string auto_str = "auto";
|
|
|
|
if (spelling.size() >= 4 && std::equal(auto_str.begin(), auto_str.end(), spelling.begin())) {
|
|
|
|
auto canonical_type = clang_getCanonicalType(clang_getCursorType(cx_cursor));
|
2017-02-17 09:57:44 +00:00
|
|
|
auto canonical_spelling = ToString(clang_getTypeSpelling(canonical_type));
|
2017-02-16 09:35:30 +00:00
|
|
|
if (spelling.size() > 5 && spelling[4] == ' ' && spelling[5] == '&' && spelling != canonical_spelling)
|
|
|
|
return canonical_spelling + " &";
|
|
|
|
else
|
|
|
|
return canonical_spelling;
|
|
|
|
}
|
|
|
|
|
|
|
|
const std::string const_auto_str = "const auto";
|
|
|
|
if (spelling.size() >= 10 && std::equal(const_auto_str.begin(), const_auto_str.end(), spelling.begin())) {
|
|
|
|
auto canonical_type = clang_getCanonicalType(clang_getCursorType(cx_cursor));
|
2017-02-17 09:57:44 +00:00
|
|
|
auto canonical_spelling = ToString(clang_getTypeSpelling(canonical_type));
|
2017-02-16 09:35:30 +00:00
|
|
|
if (spelling.size() > 11 && spelling[10] == ' ' && spelling[11] == '&' && spelling != canonical_spelling)
|
|
|
|
return canonical_spelling + " &";
|
|
|
|
else
|
|
|
|
return canonical_spelling;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
if (spelling.empty())
|
|
|
|
return get_spelling();
|
|
|
|
|
|
|
|
return spelling;
|
|
|
|
}
|
|
|
|
|
2017-02-17 09:57:44 +00:00
|
|
|
std::string Cursor::get_comments() const {
|
2017-02-16 09:35:30 +00:00
|
|
|
Cursor referenced = get_referenced();
|
|
|
|
if (referenced)
|
2017-02-17 09:57:44 +00:00
|
|
|
return ToString(clang_Cursor_getRawCommentText(referenced.cx_cursor));
|
2017-02-16 09:35:30 +00:00
|
|
|
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace clang
|