mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-26 01:21:57 +00:00
Move libclangmm/Cursor.* to clang_cursor.*
This commit is contained in:
parent
5fa7fbf0d2
commit
348b4a2e4e
4
src/.vscode/settings.json
vendored
4
src/.vscode/settings.json
vendored
@ -1,6 +1,5 @@
|
||||
// Place your settings in this file to overwrite default and user settings.
|
||||
{
|
||||
"cquery.cacheDirectory": "C:/Users/jacob/Desktop/cquery/CACHE",
|
||||
"cquery.blacklist": [
|
||||
// ".*libclangmm/.*"
|
||||
],
|
||||
@ -9,5 +8,6 @@
|
||||
],
|
||||
"cquery.launch.command": "cquery.exe",
|
||||
"cquery.launch.workingDirectory": "C:/Users/jacob/Desktop/cquery/x64/Release",
|
||||
"cquery.launch.autoRestart": false
|
||||
"cquery.launch.autoRestart": false,
|
||||
"cquery.cacheDirectory": "c:/Users/jacob/Desktop/cquery/src/.vscode/cquery_cached_index/"
|
||||
}
|
195
src/clang_cursor.cc
Normal file
195
src/clang_cursor.cc
Normal file
@ -0,0 +1,195 @@
|
||||
#include "clang_cursor.h"
|
||||
|
||||
#include "clang_utils.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
|
||||
ClangType::ClangType() : cx_type() {}
|
||||
|
||||
ClangType::ClangType(const CXType& other) : cx_type(other) {}
|
||||
|
||||
bool ClangType::operator==(const ClangType& rhs) const {
|
||||
return clang_equalTypes(cx_type, rhs.cx_type);
|
||||
}
|
||||
|
||||
bool ClangType::is_fundamental() const {
|
||||
// NOTE: This will return false for pointed types. Should we call
|
||||
// strip_qualifiers for the user?
|
||||
return cx_type.kind >= CXType_FirstBuiltin &&
|
||||
cx_type.kind <= CXType_LastBuiltin;
|
||||
}
|
||||
|
||||
CXCursor ClangType::get_declaration() const {
|
||||
return clang_getTypeDeclaration(cx_type);
|
||||
}
|
||||
|
||||
std::string ClangType::get_usr() const {
|
||||
return ClangCursor(clang_getTypeDeclaration(cx_type)).get_usr();
|
||||
}
|
||||
|
||||
ClangType ClangType::get_canonical() const {
|
||||
return clang_getCanonicalType(cx_type);
|
||||
}
|
||||
|
||||
ClangType ClangType::strip_qualifiers() const {
|
||||
// CXRefQualifierKind qualifiers = clang_Type_getCXXRefQualifier(cx_type)
|
||||
switch (cx_type.kind) {
|
||||
case CXType_LValueReference:
|
||||
case CXType_Pointer:
|
||||
return clang_getPointeeType(cx_type);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return cx_type;
|
||||
}
|
||||
|
||||
std::string ClangType::get_spelling() const {
|
||||
return ToString(clang_getTypeSpelling(cx_type));
|
||||
}
|
||||
|
||||
ClangType ClangType::get_return_type() const {
|
||||
return ClangType(clang_getResultType(cx_type));
|
||||
}
|
||||
|
||||
std::vector<ClangType> ClangType::get_arguments() const {
|
||||
int size = clang_getNumArgTypes(cx_type);
|
||||
assert(size >= 0);
|
||||
if (size < 0)
|
||||
return std::vector<ClangType>();
|
||||
|
||||
std::vector<ClangType> types(size);
|
||||
for (int i = 0; i < size; ++i)
|
||||
types.emplace_back(clang_getArgType(cx_type, i));
|
||||
return types;
|
||||
}
|
||||
|
||||
std::vector<ClangType> ClangType::get_template_arguments() const {
|
||||
int size = clang_Type_getNumTemplateArguments(cx_type);
|
||||
assert(size >= 0);
|
||||
if (size < 0)
|
||||
return std::vector<ClangType>();
|
||||
|
||||
std::vector<ClangType> types(size);
|
||||
for (int i = 0; i < size; ++i)
|
||||
types.emplace_back(clang_Type_getTemplateArgumentAsType(cx_type, i));
|
||||
return types;
|
||||
}
|
||||
|
||||
static_assert(sizeof(ClangCursor) == sizeof(CXCursor),
|
||||
"Cursor must be the same size as CXCursor");
|
||||
|
||||
ClangCursor::ClangCursor() : cx_cursor(clang_getNullCursor()) {}
|
||||
|
||||
ClangCursor::ClangCursor(const CXCursor& other) : cx_cursor(other) {}
|
||||
|
||||
ClangCursor::operator bool() const {
|
||||
return !clang_Cursor_isNull(cx_cursor);
|
||||
}
|
||||
|
||||
bool ClangCursor::operator==(const ClangCursor& rhs) const {
|
||||
return clang_equalCursors(cx_cursor, rhs.cx_cursor);
|
||||
}
|
||||
|
||||
bool ClangCursor::operator!=(const ClangCursor& rhs) const {
|
||||
return !(*this == rhs);
|
||||
}
|
||||
|
||||
CXCursorKind ClangCursor::get_kind() const {
|
||||
return cx_cursor.kind;
|
||||
}
|
||||
|
||||
ClangCursor ClangCursor::get_declaration() const {
|
||||
ClangType type = get_type();
|
||||
|
||||
// auto x = new Foo() will not be deduced to |Foo| if we do not use the
|
||||
// canonical type. However, a canonical type will look past typedefs so we
|
||||
// will not accurately report variables on typedefs if we always do this.
|
||||
if (type.cx_type.kind == CXType_Auto)
|
||||
type = type.get_canonical();
|
||||
|
||||
return type.strip_qualifiers().get_declaration();
|
||||
}
|
||||
|
||||
ClangType ClangCursor::get_type() const {
|
||||
return ClangType(clang_getCursorType(cx_cursor));
|
||||
}
|
||||
|
||||
std::string ClangCursor::get_spelling() const {
|
||||
return ::ToString(clang_getCursorSpelling(cx_cursor));
|
||||
}
|
||||
|
||||
std::string ClangCursor::get_display_name() const {
|
||||
return ::ToString(clang_getCursorDisplayName(cx_cursor));
|
||||
}
|
||||
|
||||
std::string ClangCursor::get_usr() const {
|
||||
return ::ToString(clang_getCursorUSR(cx_cursor));
|
||||
}
|
||||
|
||||
bool ClangCursor::is_definition() const {
|
||||
return clang_isCursorDefinition(cx_cursor);
|
||||
}
|
||||
|
||||
ClangCursor ClangCursor::template_specialization_to_template_definition()
|
||||
const {
|
||||
CXCursor definition = clang_getSpecializedCursorTemplate(cx_cursor);
|
||||
if (definition.kind == CXCursor_FirstInvalid)
|
||||
return cx_cursor;
|
||||
return definition;
|
||||
}
|
||||
|
||||
ClangCursor ClangCursor::get_referenced() const {
|
||||
return ClangCursor(clang_getCursorReferenced(cx_cursor));
|
||||
}
|
||||
|
||||
ClangCursor ClangCursor::get_canonical() const {
|
||||
return ClangCursor(clang_getCanonicalCursor(cx_cursor));
|
||||
}
|
||||
|
||||
ClangCursor ClangCursor::get_definition() const {
|
||||
return ClangCursor(clang_getCursorDefinition(cx_cursor));
|
||||
}
|
||||
|
||||
ClangCursor ClangCursor::get_semantic_parent() const {
|
||||
return ClangCursor(clang_getCursorSemanticParent(cx_cursor));
|
||||
}
|
||||
|
||||
std::vector<ClangCursor> ClangCursor::get_arguments() const {
|
||||
int size = clang_Cursor_getNumArguments(cx_cursor);
|
||||
if (size < 0)
|
||||
return std::vector<ClangCursor>();
|
||||
|
||||
std::vector<ClangCursor> cursors(size);
|
||||
for (int i = 0; i < size; ++i)
|
||||
cursors.emplace_back(clang_Cursor_getArgument(cx_cursor, i));
|
||||
return cursors;
|
||||
}
|
||||
|
||||
bool ClangCursor::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 ClangCursor::get_type_description() const {
|
||||
auto type = clang_getCursorType(cx_cursor);
|
||||
return ::ToString(clang_getTypeSpelling(type));
|
||||
}
|
||||
|
||||
std::string ClangCursor::get_comments() const {
|
||||
ClangCursor referenced = get_referenced();
|
||||
if (referenced)
|
||||
return ::ToString(clang_Cursor_getRawCommentText(referenced.cx_cursor));
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string ClangCursor::ToString() const {
|
||||
return ::ToString(get_kind()) + " " + get_spelling();
|
||||
}
|
87
src/clang_cursor.h
Normal file
87
src/clang_cursor.h
Normal file
@ -0,0 +1,87 @@
|
||||
#pragma once
|
||||
|
||||
#include <clang-c/Index.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class ClangType {
|
||||
public:
|
||||
ClangType();
|
||||
ClangType(const CXType& other);
|
||||
|
||||
bool operator==(const ClangType& rhs) const;
|
||||
|
||||
// Returns true if this is a fundamental type like int.
|
||||
bool is_fundamental() const;
|
||||
|
||||
// ClangCursor is not defined so we have to return CXCursor
|
||||
CXCursor get_declaration() const;
|
||||
std::string get_usr() const;
|
||||
std::string get_spelling() const;
|
||||
ClangType get_canonical() const;
|
||||
|
||||
// Try to resolve this type and remove qualifies, ie, Foo* will become Foo
|
||||
ClangType strip_qualifiers() const;
|
||||
|
||||
ClangType get_return_type() const;
|
||||
std::vector<ClangType> get_arguments() const;
|
||||
std::vector<ClangType> get_template_arguments() const;
|
||||
|
||||
CXType cx_type;
|
||||
};
|
||||
|
||||
class ClangCursor {
|
||||
public:
|
||||
ClangCursor();
|
||||
ClangCursor(const CXCursor& other);
|
||||
|
||||
explicit operator bool() const;
|
||||
bool operator==(const ClangCursor& rhs) const;
|
||||
bool operator!=(const ClangCursor& rhs) const;
|
||||
|
||||
CXCursorKind get_kind() const;
|
||||
ClangCursor get_declaration() const;
|
||||
ClangType get_type() const;
|
||||
std::string get_spelling() const;
|
||||
std::string get_display_name() const;
|
||||
std::string get_usr() const;
|
||||
|
||||
bool is_definition() const;
|
||||
|
||||
// If the given cursor points to a template specialization, this
|
||||
// will return the cursor pointing to the template definition.
|
||||
// If the given cursor is not a template specialization, this will
|
||||
// just return the same cursor.
|
||||
//
|
||||
// This means it is always safe to call this method.
|
||||
ClangCursor template_specialization_to_template_definition() const;
|
||||
|
||||
ClangCursor get_referenced() const;
|
||||
ClangCursor get_canonical() const;
|
||||
ClangCursor get_definition() const;
|
||||
ClangCursor get_semantic_parent() const;
|
||||
std::vector<ClangCursor> get_arguments() const;
|
||||
bool is_valid_kind() const;
|
||||
|
||||
std::string get_type_description() const;
|
||||
std::string get_comments() const;
|
||||
|
||||
std::string ToString() const;
|
||||
|
||||
enum class VisitResult { Break, Continue, Recurse };
|
||||
|
||||
template <typename TClientData>
|
||||
using Visitor = VisitResult (*)(ClangCursor cursor,
|
||||
ClangCursor parent,
|
||||
TClientData* client_data);
|
||||
|
||||
template <typename TClientData>
|
||||
void VisitChildren(Visitor<TClientData> visitor,
|
||||
TClientData* client_data) const {
|
||||
clang_visitChildren(cx_cursor, reinterpret_cast<CXCursorVisitor>(visitor),
|
||||
client_data);
|
||||
}
|
||||
|
||||
CXCursor cx_cursor;
|
||||
};
|
143
src/indexer.cc
143
src/indexer.cc
@ -1,7 +1,7 @@
|
||||
#include "indexer.h"
|
||||
|
||||
#include "clang_cursor.h"
|
||||
#include "clang_utils.h"
|
||||
#include "libclangmm/Cursor.h"
|
||||
#include "libclangmm/Index.h"
|
||||
#include "libclangmm/TranslationUnit.h"
|
||||
#include "platform.h"
|
||||
@ -58,7 +58,7 @@ struct NamespaceHelper {
|
||||
const CXIdxContainerInfo* container,
|
||||
std::string qualified_name) {
|
||||
if (container) {
|
||||
std::string container_usr = clang::Cursor(container->cursor).get_usr();
|
||||
std::string container_usr = ClangCursor(container->cursor).get_usr();
|
||||
auto it = container_usr_to_qualified_name.find(container_usr);
|
||||
if (it != container_usr_to_qualified_name.end()) {
|
||||
container_usr_to_qualified_name[usr] =
|
||||
@ -73,7 +73,7 @@ struct NamespaceHelper {
|
||||
std::string QualifiedName(const CXIdxContainerInfo* container,
|
||||
std::string unqualified_name) {
|
||||
if (container) {
|
||||
std::string container_usr = clang::Cursor(container->cursor).get_usr();
|
||||
std::string container_usr = ClangCursor(container->cursor).get_usr();
|
||||
auto it = container_usr_to_qualified_name.find(container_usr);
|
||||
if (it != container_usr_to_qualified_name.end())
|
||||
return it->second + unqualified_name;
|
||||
@ -81,7 +81,7 @@ struct NamespaceHelper {
|
||||
// Anonymous namespaces are not processed by indexDeclaration. If we
|
||||
// encounter one insert it into map.
|
||||
if (container->cursor.kind == CXCursor_Namespace) {
|
||||
// assert(clang::Cursor(container->cursor).get_spelling() == "");
|
||||
// assert(ClangCursor(container->cursor).get_spelling() == "");
|
||||
container_usr_to_qualified_name[container_usr] = "::";
|
||||
return "::" + unqualified_name;
|
||||
}
|
||||
@ -103,10 +103,10 @@ struct ConstructorCache {
|
||||
std::unordered_map<Usr, std::vector<Constructor>> constructors_;
|
||||
|
||||
// This should be called whenever there is a constructor declaration.
|
||||
void NotifyConstructor(clang::Cursor ctor_cursor) {
|
||||
auto build_type_desc = [](clang::Cursor cursor) {
|
||||
void NotifyConstructor(ClangCursor ctor_cursor) {
|
||||
auto build_type_desc = [](ClangCursor cursor) {
|
||||
std::vector<std::string> type_desc;
|
||||
for (clang::Cursor arg : cursor.get_arguments()) {
|
||||
for (ClangCursor arg : cursor.get_arguments()) {
|
||||
if (arg.get_kind() == CXCursor_ParmDecl)
|
||||
type_desc.push_back(arg.get_type_description());
|
||||
}
|
||||
@ -419,15 +419,15 @@ IndexVarId IndexFile::ToVarId(const std::string& usr) {
|
||||
}
|
||||
|
||||
IndexTypeId IndexFile::ToTypeId(const CXCursor& cursor) {
|
||||
return ToTypeId(clang::Cursor(cursor).get_usr());
|
||||
return ToTypeId(ClangCursor(cursor).get_usr());
|
||||
}
|
||||
|
||||
IndexFuncId IndexFile::ToFuncId(const CXCursor& cursor) {
|
||||
return ToFuncId(clang::Cursor(cursor).get_usr());
|
||||
return ToFuncId(ClangCursor(cursor).get_usr());
|
||||
}
|
||||
|
||||
IndexVarId IndexFile::ToVarId(const CXCursor& cursor) {
|
||||
return ToVarId(clang::Cursor(cursor).get_usr());
|
||||
return ToVarId(ClangCursor(cursor).get_usr());
|
||||
}
|
||||
|
||||
IndexType* IndexFile::Resolve(IndexTypeId id) {
|
||||
@ -546,9 +546,9 @@ CXIdxClientContainer startedTranslationUnit(CXClientData client_data,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
clang::VisiterResult DumpVisitor(clang::Cursor cursor,
|
||||
clang::Cursor parent,
|
||||
int* level) {
|
||||
ClangCursor::VisitResult DumpVisitor(ClangCursor cursor,
|
||||
ClangCursor parent,
|
||||
int* level) {
|
||||
for (int i = 0; i < *level; ++i)
|
||||
std::cerr << " ";
|
||||
std::cerr << ToString(cursor.get_kind()) << " " << cursor.get_spelling()
|
||||
@ -558,56 +558,55 @@ clang::VisiterResult DumpVisitor(clang::Cursor cursor,
|
||||
cursor.VisitChildren(&DumpVisitor, level);
|
||||
*level -= 1;
|
||||
|
||||
return clang::VisiterResult::Continue;
|
||||
return ClangCursor::VisitResult::Continue;
|
||||
}
|
||||
|
||||
void Dump(clang::Cursor cursor) {
|
||||
void Dump(ClangCursor cursor) {
|
||||
int level = 0;
|
||||
cursor.VisitChildren(&DumpVisitor, &level);
|
||||
}
|
||||
|
||||
struct FindChildOfKindParam {
|
||||
CXCursorKind target_kind;
|
||||
optional<clang::Cursor> result;
|
||||
optional<ClangCursor> result;
|
||||
|
||||
FindChildOfKindParam(CXCursorKind target_kind) : target_kind(target_kind) {}
|
||||
};
|
||||
|
||||
clang::VisiterResult FindChildOfKindVisitor(clang::Cursor cursor,
|
||||
clang::Cursor parent,
|
||||
FindChildOfKindParam* param) {
|
||||
ClangCursor::VisitResult FindChildOfKindVisitor(ClangCursor cursor,
|
||||
ClangCursor parent,
|
||||
FindChildOfKindParam* param) {
|
||||
if (cursor.get_kind() == param->target_kind) {
|
||||
param->result = cursor;
|
||||
return clang::VisiterResult::Break;
|
||||
return ClangCursor::VisitResult::Break;
|
||||
}
|
||||
|
||||
return clang::VisiterResult::Recurse;
|
||||
return ClangCursor::VisitResult::Recurse;
|
||||
}
|
||||
|
||||
optional<clang::Cursor> FindChildOfKind(clang::Cursor cursor,
|
||||
CXCursorKind kind) {
|
||||
optional<ClangCursor> FindChildOfKind(ClangCursor cursor, CXCursorKind kind) {
|
||||
FindChildOfKindParam param(kind);
|
||||
cursor.VisitChildren(&FindChildOfKindVisitor, ¶m);
|
||||
return param.result;
|
||||
}
|
||||
|
||||
clang::VisiterResult FindTypeVisitor(clang::Cursor cursor,
|
||||
clang::Cursor parent,
|
||||
optional<clang::Cursor>* result) {
|
||||
ClangCursor::VisitResult FindTypeVisitor(ClangCursor cursor,
|
||||
ClangCursor parent,
|
||||
optional<ClangCursor>* result) {
|
||||
switch (cursor.get_kind()) {
|
||||
case CXCursor_TypeRef:
|
||||
case CXCursor_TemplateRef:
|
||||
*result = cursor;
|
||||
return clang::VisiterResult::Break;
|
||||
return ClangCursor::VisitResult::Break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return clang::VisiterResult::Recurse;
|
||||
return ClangCursor::VisitResult::Recurse;
|
||||
}
|
||||
|
||||
optional<clang::Cursor> FindType(clang::Cursor cursor) {
|
||||
optional<clang::Cursor> result;
|
||||
optional<ClangCursor> FindType(ClangCursor cursor) {
|
||||
optional<ClangCursor> result;
|
||||
cursor.VisitChildren(&FindTypeVisitor, &result);
|
||||
return result;
|
||||
}
|
||||
@ -630,13 +629,13 @@ bool IsTypeDefinition(const CXIdxContainerInfo* container) {
|
||||
struct VisitDeclForTypeUsageParam {
|
||||
IndexFile* db;
|
||||
int has_processed_any = false;
|
||||
optional<clang::Cursor> previous_cursor;
|
||||
optional<ClangCursor> previous_cursor;
|
||||
optional<IndexTypeId> initial_type;
|
||||
|
||||
VisitDeclForTypeUsageParam(IndexFile* db) : db(db) {}
|
||||
};
|
||||
|
||||
void VisitDeclForTypeUsageVisitorHandler(clang::Cursor cursor,
|
||||
void VisitDeclForTypeUsageVisitorHandler(ClangCursor cursor,
|
||||
VisitDeclForTypeUsageParam* param) {
|
||||
param->has_processed_any = true;
|
||||
IndexFile* db = param->db;
|
||||
@ -661,9 +660,9 @@ void VisitDeclForTypeUsageVisitorHandler(clang::Cursor cursor,
|
||||
UniqueAdd(ref_type_def->uses, loc);
|
||||
}
|
||||
|
||||
clang::VisiterResult VisitDeclForTypeUsageVisitor(
|
||||
clang::Cursor cursor,
|
||||
clang::Cursor parent,
|
||||
ClangCursor::VisitResult VisitDeclForTypeUsageVisitor(
|
||||
ClangCursor cursor,
|
||||
ClangCursor parent,
|
||||
VisitDeclForTypeUsageParam* param) {
|
||||
switch (cursor.get_kind()) {
|
||||
case CXCursor_TemplateRef:
|
||||
@ -674,7 +673,7 @@ clang::VisiterResult VisitDeclForTypeUsageVisitor(
|
||||
}
|
||||
|
||||
param->previous_cursor = cursor;
|
||||
return clang::VisiterResult::Continue;
|
||||
return ClangCursor::VisitResult::Continue;
|
||||
|
||||
// We do not want to recurse for everything, since if we do that we will end
|
||||
// up visiting method definition bodies/etc. Instead, we only recurse for
|
||||
@ -689,13 +688,13 @@ clang::VisiterResult VisitDeclForTypeUsageVisitor(
|
||||
case CXCursor_CStyleCastExpr:
|
||||
case CXCursor_CXXStaticCastExpr:
|
||||
case CXCursor_CXXReinterpretCastExpr:
|
||||
return clang::VisiterResult::Recurse;
|
||||
return ClangCursor::VisitResult::Recurse;
|
||||
|
||||
default:
|
||||
return clang::VisiterResult::Continue;
|
||||
return ClangCursor::VisitResult::Continue;
|
||||
}
|
||||
|
||||
return clang::VisiterResult::Continue;
|
||||
return ClangCursor::VisitResult::Continue;
|
||||
}
|
||||
|
||||
// Finds the cursor associated with the declaration type of |cursor|. This
|
||||
@ -703,8 +702,8 @@ clang::VisiterResult VisitDeclForTypeUsageVisitor(
|
||||
// qualifies from |cursor| (ie, Foo* => Foo) and removes template arguments
|
||||
// (ie, Foo<A,B> => Foo<*,*>).
|
||||
optional<IndexTypeId> ResolveToDeclarationType(IndexFile* db,
|
||||
clang::Cursor cursor) {
|
||||
clang::Cursor declaration = cursor.get_declaration();
|
||||
ClangCursor cursor) {
|
||||
ClangCursor declaration = cursor.get_declaration();
|
||||
declaration = declaration.template_specialization_to_template_definition();
|
||||
std::string usr = declaration.get_usr();
|
||||
if (usr != "")
|
||||
@ -719,7 +718,7 @@ optional<IndexTypeId> ResolveToDeclarationType(IndexFile* db,
|
||||
// ResolveToDeclarationType, which works in more scenarios.
|
||||
optional<IndexTypeId> AddDeclTypeUsages(
|
||||
IndexFile* db,
|
||||
clang::Cursor decl_cursor,
|
||||
ClangCursor decl_cursor,
|
||||
const CXIdxContainerInfo* semantic_container,
|
||||
const CXIdxContainerInfo* lexical_container) {
|
||||
// std::cerr << std::endl << "AddDeclUsages " << decl_cursor.get_spelling() <<
|
||||
@ -817,7 +816,7 @@ optional<IndexTypeId> AddDeclTypeUsages(
|
||||
//
|
||||
if (!decl_cursor.is_definition()) {
|
||||
// TODO: I don't think this resolution ever works.
|
||||
clang::Cursor def = decl_cursor.get_definition();
|
||||
ClangCursor def = decl_cursor.get_definition();
|
||||
if (def.get_kind() != CXCursor_FirstInvalid) {
|
||||
std::cerr << "Successful resolution of decl usage to definition"
|
||||
<< std::endl;
|
||||
@ -851,9 +850,9 @@ optional<IndexTypeId> AddDeclTypeUsages(
|
||||
|
||||
// Various versions of LLVM (ie, 4.0) will not visit inline variable references
|
||||
// for template arguments.
|
||||
clang::VisiterResult AddDeclInitializerUsagesVisitor(clang::Cursor cursor,
|
||||
clang::Cursor parent,
|
||||
IndexFile* db) {
|
||||
ClangCursor::VisitResult AddDeclInitializerUsagesVisitor(ClangCursor cursor,
|
||||
ClangCursor parent,
|
||||
IndexFile* db) {
|
||||
/*
|
||||
We need to index the |DeclRefExpr| below (ie, |var| inside of
|
||||
Foo<int>::var).
|
||||
@ -882,7 +881,7 @@ clang::VisiterResult AddDeclInitializerUsagesVisitor(clang::Cursor cursor,
|
||||
// TODO: when we resolve the template type to the definition, we get a
|
||||
// different USR.
|
||||
|
||||
// clang::Cursor ref =
|
||||
// ClangCursor ref =
|
||||
// cursor.get_referenced().template_specialization_to_template_definition().get_type().strip_qualifiers().get_usr();
|
||||
// std::string ref_usr =
|
||||
// cursor.get_referenced().template_specialization_to_template_definition().get_type().strip_qualifiers().get_usr();
|
||||
@ -907,10 +906,10 @@ clang::VisiterResult AddDeclInitializerUsagesVisitor(clang::Cursor cursor,
|
||||
break;
|
||||
}
|
||||
|
||||
return clang::VisiterResult::Recurse;
|
||||
return ClangCursor::VisitResult::Recurse;
|
||||
}
|
||||
|
||||
void AddDeclInitializerUsages(IndexFile* db, clang::Cursor decl_cursor) {
|
||||
void AddDeclInitializerUsages(IndexFile* db, ClangCursor decl_cursor) {
|
||||
decl_cursor.VisitChildren(&AddDeclInitializerUsagesVisitor, db);
|
||||
}
|
||||
|
||||
@ -924,9 +923,9 @@ bool AreEqualLocations(CXIdxLoc loc, CXCursor cursor) {
|
||||
clang_getRangeStart(clang_Cursor_getSpellingNameRange(cursor, 0, 0)));
|
||||
}
|
||||
|
||||
clang::VisiterResult VisitMacroDefinitionAndExpansions(clang::Cursor cursor,
|
||||
clang::Cursor parent,
|
||||
IndexParam* param) {
|
||||
ClangCursor::VisitResult VisitMacroDefinitionAndExpansions(ClangCursor cursor,
|
||||
ClangCursor parent,
|
||||
IndexParam* param) {
|
||||
switch (cursor.get_kind()) {
|
||||
case CXCursor_MacroDefinition:
|
||||
case CXCursor_MacroExpansion: {
|
||||
@ -972,7 +971,7 @@ clang::VisiterResult VisitMacroDefinitionAndExpansions(clang::Cursor cursor,
|
||||
break;
|
||||
}
|
||||
|
||||
return clang::VisiterResult::Continue;
|
||||
return ClangCursor::VisitResult::Continue;
|
||||
}
|
||||
|
||||
void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
||||
@ -1017,7 +1016,7 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
||||
case CXIdxEntity_CXXStaticVariable: {
|
||||
Range decl_loc_spelling = ResolveSpelling(decl->cursor);
|
||||
|
||||
clang::Cursor decl_cursor = decl->cursor;
|
||||
ClangCursor decl_cursor = decl->cursor;
|
||||
|
||||
// Do not index implicit template instantiations.
|
||||
if (decl_cursor !=
|
||||
@ -1109,8 +1108,8 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
||||
Range decl_spelling = ResolveSpelling(decl->cursor);
|
||||
Range decl_extent = ResolveExtent(decl->cursor);
|
||||
|
||||
clang::Cursor decl_cursor = decl->cursor;
|
||||
clang::Cursor decl_cursor_resolved =
|
||||
ClangCursor decl_cursor = decl->cursor;
|
||||
ClangCursor decl_cursor_resolved =
|
||||
decl_cursor.template_specialization_to_template_definition();
|
||||
bool is_template_specialization = decl_cursor != decl_cursor_resolved;
|
||||
|
||||
@ -1140,7 +1139,7 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
||||
param->tu->cx_tu, clang_getCursorExtent(decl->cursor));
|
||||
|
||||
// Add parameters.
|
||||
for (clang::Cursor arg : decl_cursor.get_arguments()) {
|
||||
for (ClangCursor arg : decl_cursor.get_arguments()) {
|
||||
switch (arg.get_kind()) {
|
||||
case CXCursor_ParmDecl: {
|
||||
Range param_spelling = ResolveSpelling(arg.cx_cursor);
|
||||
@ -1217,7 +1216,7 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
||||
<< func->def.detailed_name << std::endl;
|
||||
|
||||
for (unsigned i = 0; i < num_overridden; ++i) {
|
||||
clang::Cursor parent = overridden[i];
|
||||
ClangCursor parent = overridden[i];
|
||||
IndexFuncId parent_id = db->ToFuncId(parent.get_usr());
|
||||
IndexFunc* parent_def = db->Resolve(parent_id);
|
||||
func = db->Resolve(func_id); // ToFuncId invalidated func_def
|
||||
@ -1325,7 +1324,7 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
||||
|
||||
default:
|
||||
std::cerr << "!! Unhandled indexDeclaration: "
|
||||
<< clang::Cursor(decl->cursor).ToString() << " at "
|
||||
<< ClangCursor(decl->cursor).ToString() << " at "
|
||||
<< ResolveSpelling(decl->cursor).start.ToString() << std::endl;
|
||||
std::cerr << " entityInfo->kind = " << decl->entityInfo->kind
|
||||
<< std::endl;
|
||||
@ -1333,15 +1332,15 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
||||
<< std::endl;
|
||||
if (decl->declAsContainer)
|
||||
std::cerr << " declAsContainer = "
|
||||
<< clang::Cursor(decl->declAsContainer->cursor).ToString()
|
||||
<< ClangCursor(decl->declAsContainer->cursor).ToString()
|
||||
<< std::endl;
|
||||
if (decl->semanticContainer)
|
||||
std::cerr << " semanticContainer = "
|
||||
<< clang::Cursor(decl->semanticContainer->cursor).ToString()
|
||||
<< ClangCursor(decl->semanticContainer->cursor).ToString()
|
||||
<< std::endl;
|
||||
if (decl->lexicalContainer)
|
||||
std::cerr << " lexicalContainer = "
|
||||
<< clang::Cursor(decl->lexicalContainer->cursor).get_usr()
|
||||
<< ClangCursor(decl->lexicalContainer->cursor).get_usr()
|
||||
<< std::endl;
|
||||
break;
|
||||
}
|
||||
@ -1409,7 +1408,7 @@ void indexEntityReference(CXClientData client_data,
|
||||
// if (!clang_Location_isFromMainFile(clang_getCursorLocation(ref->cursor)))
|
||||
// return;
|
||||
|
||||
clang::Cursor cursor(ref->cursor);
|
||||
ClangCursor cursor(ref->cursor);
|
||||
|
||||
switch (ref->referencedEntity->kind) {
|
||||
case CXIdxEntity_CXXNamespaceAlias:
|
||||
@ -1424,7 +1423,7 @@ void indexEntityReference(CXClientData client_data,
|
||||
case CXIdxEntity_Field: {
|
||||
Range loc_spelling = ResolveSpelling(ref->cursor);
|
||||
|
||||
clang::Cursor referenced = ref->referencedEntity->cursor;
|
||||
ClangCursor referenced = ref->referencedEntity->cursor;
|
||||
referenced = referenced.template_specialization_to_template_definition();
|
||||
|
||||
IndexVarId var_id = db->ToVarId(referenced.get_usr());
|
||||
@ -1494,16 +1493,16 @@ void indexEntityReference(CXClientData client_data,
|
||||
if (is_template && str_begin("make", ref->referencedEntity->name)) {
|
||||
// Try to find the return type of called function. That type will have
|
||||
// the constructor function we add a usage to.
|
||||
optional<clang::Cursor> opt_found_type = FindType(ref->cursor);
|
||||
optional<ClangCursor> opt_found_type = FindType(ref->cursor);
|
||||
if (opt_found_type) {
|
||||
std::string ctor_type_usr =
|
||||
opt_found_type->get_referenced().get_usr();
|
||||
clang::Cursor call_cursor = ref->cursor;
|
||||
ClangCursor call_cursor = ref->cursor;
|
||||
|
||||
// Build a type description from the parameters of the call, so we
|
||||
// can try to find a constructor with the same type description.
|
||||
std::vector<std::string> call_type_desc;
|
||||
for (clang::Type type : call_cursor.get_type().get_arguments()) {
|
||||
for (ClangType type : call_cursor.get_type().get_arguments()) {
|
||||
std::string type_desc = type.get_spelling();
|
||||
if (!type_desc.empty())
|
||||
call_type_desc.push_back(type_desc);
|
||||
@ -1529,7 +1528,7 @@ void indexEntityReference(CXClientData client_data,
|
||||
case CXIdxEntity_Union:
|
||||
case CXIdxEntity_Struct:
|
||||
case CXIdxEntity_CXXClass: {
|
||||
clang::Cursor referenced_cursor = ref->referencedEntity->cursor;
|
||||
ClangCursor referenced_cursor = ref->referencedEntity->cursor;
|
||||
referenced_cursor =
|
||||
referenced_cursor.template_specialization_to_template_definition();
|
||||
IndexTypeId referenced_id = db->ToTypeId(referenced_cursor.get_usr());
|
||||
@ -1569,15 +1568,15 @@ void indexEntityReference(CXClientData client_data,
|
||||
std::cerr << " ref->kind = " << ref->kind << std::endl;
|
||||
if (ref->parentEntity)
|
||||
std::cerr << " parentEntity = "
|
||||
<< clang::Cursor(ref->parentEntity->cursor).ToString()
|
||||
<< ClangCursor(ref->parentEntity->cursor).ToString()
|
||||
<< std::endl;
|
||||
if (ref->referencedEntity)
|
||||
std::cerr << " referencedEntity = "
|
||||
<< clang::Cursor(ref->referencedEntity->cursor).ToString()
|
||||
<< ClangCursor(ref->referencedEntity->cursor).ToString()
|
||||
<< std::endl;
|
||||
if (ref->container)
|
||||
std::cerr << " container = "
|
||||
<< clang::Cursor(ref->container->cursor).ToString()
|
||||
<< ClangCursor(ref->container->cursor).ToString()
|
||||
<< std::endl;
|
||||
break;
|
||||
}
|
||||
@ -1663,7 +1662,7 @@ std::vector<std::unique_ptr<IndexFile>> ParseWithTu(
|
||||
clang_IndexAction_dispose(index_action);
|
||||
// std::cerr << "!! [END] Indexing " << file << std::endl;
|
||||
|
||||
clang::Cursor(clang_getTranslationUnitCursor(tu->cx_tu))
|
||||
ClangCursor(clang_getTranslationUnitCursor(tu->cx_tu))
|
||||
.VisitChildren(&VisitMacroDefinitionAndExpansions, ¶m);
|
||||
|
||||
perf->index_build = timer.ElapsedMicrosecondsAndReset();
|
||||
|
@ -1,349 +0,0 @@
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
|
||||
#include "../clang_utils.h"
|
||||
#include "Cursor.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
Type::Type() : cx_type() {}
|
||||
|
||||
Type::Type(const CXType& other) : cx_type(other) {}
|
||||
|
||||
bool Type::operator==(const Type& rhs) const {
|
||||
return clang_equalTypes(cx_type, rhs.cx_type);
|
||||
}
|
||||
|
||||
bool Type::is_fundamental() const {
|
||||
// switch (cx_type.kind) {
|
||||
// case CXType_Auto:
|
||||
// return true;
|
||||
//}
|
||||
|
||||
// NOTE: This will return false for pointed types. Should we call
|
||||
// strip_qualifiers for the user?
|
||||
return cx_type.kind >= CXType_FirstBuiltin &&
|
||||
cx_type.kind <= CXType_LastBuiltin;
|
||||
}
|
||||
|
||||
CXCursor Type::get_declaration() const {
|
||||
return clang_getTypeDeclaration(cx_type);
|
||||
}
|
||||
|
||||
std::string Type::get_usr() const {
|
||||
return clang::Cursor(clang_getTypeDeclaration(cx_type)).get_usr();
|
||||
}
|
||||
|
||||
Type Type::get_canonical() const {
|
||||
return clang_getCanonicalType(cx_type);
|
||||
}
|
||||
|
||||
Type Type::strip_qualifiers() const {
|
||||
// CXRefQualifierKind qualifiers = clang_Type_getCXXRefQualifier(cx_type)
|
||||
switch (cx_type.kind) {
|
||||
case CXType_LValueReference:
|
||||
case CXType_Pointer:
|
||||
return clang_getPointeeType(cx_type);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return cx_type;
|
||||
}
|
||||
|
||||
std::string Type::get_spelling() const {
|
||||
return ToString(clang_getTypeSpelling(cx_type));
|
||||
}
|
||||
|
||||
/*
|
||||
SourceLocation Cursor::get_source_location() const {
|
||||
return SourceLocation(clang_getCursorLocation(cx_cursor));
|
||||
}
|
||||
*/
|
||||
|
||||
Type Type::get_return_type() const {
|
||||
return Type(clang_getResultType(cx_type));
|
||||
}
|
||||
|
||||
std::vector<Type> Type::get_arguments() const {
|
||||
int size = clang_getNumArgTypes(cx_type);
|
||||
assert(size >= 0);
|
||||
if (size < 0)
|
||||
return std::vector<Type>();
|
||||
|
||||
std::vector<Type> types(size);
|
||||
for (int i = 0; i < size; ++i)
|
||||
types.emplace_back(clang_getArgType(cx_type, i));
|
||||
return types;
|
||||
}
|
||||
|
||||
std::vector<Type> Type::get_template_arguments() const {
|
||||
/*
|
||||
CINDEX_LINKAGE int clang_Type_getNumTemplateArguments(CXType T);
|
||||
CINDEX_LINKAGE CXType clang_Type_getTemplateArgumentAsType(CXType T, unsigned
|
||||
i);
|
||||
*/
|
||||
|
||||
int size = clang_Type_getNumTemplateArguments(cx_type);
|
||||
assert(size >= 0);
|
||||
if (size < 0)
|
||||
return std::vector<Type>();
|
||||
|
||||
std::vector<Type> types(size);
|
||||
for (int i = 0; i < size; ++i)
|
||||
types.emplace_back(clang_Type_getTemplateArgumentAsType(cx_type, i));
|
||||
return types;
|
||||
}
|
||||
|
||||
static_assert(sizeof(Cursor) == sizeof(CXCursor),
|
||||
"Cursor must be the same size as CXCursor");
|
||||
|
||||
Cursor::Cursor() : cx_cursor(clang_getNullCursor()) {}
|
||||
|
||||
Cursor::Cursor(const CXCursor& other) : cx_cursor(other) {}
|
||||
|
||||
Cursor::operator bool() const {
|
||||
return !clang_Cursor_isNull(cx_cursor);
|
||||
}
|
||||
|
||||
bool Cursor::operator==(const Cursor& rhs) const {
|
||||
return clang_equalCursors(cx_cursor, rhs.cx_cursor);
|
||||
}
|
||||
|
||||
bool Cursor::operator!=(const Cursor& rhs) const {
|
||||
return !(*this == rhs);
|
||||
}
|
||||
|
||||
CXCursorKind Cursor::get_kind() const {
|
||||
return cx_cursor.kind;
|
||||
}
|
||||
|
||||
Cursor Cursor::get_declaration() const {
|
||||
Type type = get_type();
|
||||
|
||||
// auto x = new Foo() will not be deduced to |Foo| if we do not use the
|
||||
// canonical type. However, a canonical type will look past typedefs so we
|
||||
// will not accurately report variables on typedefs if we always do this.
|
||||
if (type.cx_type.kind == CXType_Auto)
|
||||
type = type.get_canonical();
|
||||
|
||||
return type.strip_qualifiers().get_declaration();
|
||||
}
|
||||
|
||||
Type Cursor::get_type() const {
|
||||
return Type(clang_getCursorType(cx_cursor));
|
||||
}
|
||||
|
||||
/*
|
||||
SourceRange Cursor::get_source_range() const {
|
||||
return SourceRange(clang_getCursorExtent(cx_cursor));
|
||||
}
|
||||
*/
|
||||
|
||||
std::string Cursor::get_spelling() const {
|
||||
return ::ToString(clang_getCursorSpelling(cx_cursor));
|
||||
}
|
||||
|
||||
std::string Cursor::get_display_name() const {
|
||||
return ::ToString(clang_getCursorDisplayName(cx_cursor));
|
||||
}
|
||||
|
||||
std::string Cursor::get_usr() const {
|
||||
return ::ToString(clang_getCursorUSR(cx_cursor));
|
||||
}
|
||||
|
||||
bool Cursor::is_definition() const {
|
||||
return clang_isCursorDefinition(cx_cursor);
|
||||
}
|
||||
|
||||
Cursor Cursor::template_specialization_to_template_definition() const {
|
||||
CXCursor definition = clang_getSpecializedCursorTemplate(cx_cursor);
|
||||
if (definition.kind == CXCursor_FirstInvalid)
|
||||
return cx_cursor;
|
||||
return definition;
|
||||
}
|
||||
|
||||
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 {
|
||||
int size = clang_Cursor_getNumArguments(cx_cursor);
|
||||
if (size < 0)
|
||||
return std::vector<Cursor>();
|
||||
|
||||
std::vector<Cursor> cursors(size);
|
||||
for (int i = 0; i < size; ++i)
|
||||
cursors.emplace_back(clang_Cursor_getArgument(cx_cursor, i));
|
||||
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 {
|
||||
auto type = clang_getCursorType(cx_cursor);
|
||||
return ::ToString(clang_getTypeSpelling(type));
|
||||
|
||||
#if false
|
||||
std::string spelling;
|
||||
|
||||
auto referenced = clang_getCursorReferenced(cx_cursor);
|
||||
if (!clang_Cursor_isNull(referenced)) {
|
||||
auto type = clang_getCursorType(referenced);
|
||||
spelling = clang::ToString(clang_getTypeSpelling(type));
|
||||
|
||||
#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));
|
||||
auto canonical_spelling = ToString(clang_getTypeSpelling(canonical_type));
|
||||
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));
|
||||
auto canonical_spelling = ToString(clang_getTypeSpelling(canonical_type));
|
||||
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;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if false
|
||||
std::string Cursor::evaluate() const {
|
||||
CXEvalResult eval = clang_Cursor_Evaluate(cx_cursor);
|
||||
|
||||
std::string result;
|
||||
auto kind = clang_EvalResult_getKind(eval);
|
||||
switch (clang_EvalResult_getKind(eval)) {
|
||||
case CXEval_Int:
|
||||
result = std::to_string(clang_EvalResult_getAsInt(eval));
|
||||
break;
|
||||
case CXEval_Float:
|
||||
result = std::to_string(clang_EvalResult_getAsDouble(eval));
|
||||
break;
|
||||
default:
|
||||
{
|
||||
const char* r = clang_EvalResult_getAsStr(eval);
|
||||
if (r)
|
||||
result = r;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
clang_EvalResult_dispose(eval);
|
||||
return result;
|
||||
|
||||
#if false
|
||||
typedef enum {
|
||||
CXEval_Int = 1,
|
||||
CXEval_Float = 2,
|
||||
CXEval_ObjCStrLiteral = 3,
|
||||
CXEval_StrLiteral = 4,
|
||||
CXEval_CFStr = 5,
|
||||
CXEval_Other = 6,
|
||||
|
||||
CXEval_UnExposed = 0
|
||||
|
||||
} CXEvalResultKind;
|
||||
|
||||
/**
|
||||
* \brief Evaluation result of a cursor
|
||||
*/
|
||||
typedef void * CXEvalResult;
|
||||
|
||||
/**
|
||||
* \brief If cursor is a statement declaration tries to evaluate the
|
||||
* statement and if its variable, tries to evaluate its initializer,
|
||||
* into its corresponding type.
|
||||
*/
|
||||
CINDEX_LINKAGE CXEvalResult clang_Cursor_Evaluate(CXCursor C);
|
||||
|
||||
/**
|
||||
* \brief Returns the kind of the evaluated result.
|
||||
*/
|
||||
CINDEX_LINKAGE CXEvalResultKind clang_EvalResult_getKind(CXEvalResult E);
|
||||
|
||||
/**
|
||||
* \brief Returns the evaluation result as integer if the
|
||||
* kind is Int.
|
||||
*/
|
||||
CINDEX_LINKAGE int clang_EvalResult_getAsInt(CXEvalResult E);
|
||||
|
||||
/**
|
||||
* \brief Returns the evaluation result as double if the
|
||||
* kind is double.
|
||||
*/
|
||||
CINDEX_LINKAGE double clang_EvalResult_getAsDouble(CXEvalResult E);
|
||||
|
||||
/**
|
||||
* \brief Returns the evaluation result as a constant string if the
|
||||
* kind is other than Int or float. User must not free this pointer,
|
||||
* instead call clang_EvalResult_dispose on the CXEvalResult returned
|
||||
* by clang_Cursor_Evaluate.
|
||||
*/
|
||||
CINDEX_LINKAGE const char* clang_EvalResult_getAsStr(CXEvalResult E);
|
||||
|
||||
/**
|
||||
* \brief Disposes the created Eval memory.
|
||||
*/
|
||||
CINDEX_LINKAGE void clang_EvalResult_dispose(CXEvalResult E);
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
std::string Cursor::get_comments() const {
|
||||
Cursor referenced = get_referenced();
|
||||
if (referenced)
|
||||
return ::ToString(clang_Cursor_getRawCommentText(referenced.cx_cursor));
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string Cursor::ToString() const {
|
||||
return ::ToString(get_kind()) + " " + get_spelling();
|
||||
}
|
||||
|
||||
} // namespace clang
|
@ -1,99 +0,0 @@
|
||||
#ifndef CURSOR_H_
|
||||
#define CURSOR_H_
|
||||
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include <clang-c/Index.h>
|
||||
|
||||
namespace clang {
|
||||
|
||||
class Type {
|
||||
public:
|
||||
Type();
|
||||
Type(const CXType& other);
|
||||
|
||||
bool operator==(const Type& rhs) const;
|
||||
|
||||
// Returns true if this is a fundamental type like int.
|
||||
bool is_fundamental() const;
|
||||
|
||||
// clang::Cursor is not defined so we have to return CXCursor
|
||||
CXCursor get_declaration() const;
|
||||
std::string get_usr() const;
|
||||
std::string get_spelling() const;
|
||||
Type get_canonical() const;
|
||||
|
||||
// Try to resolve this type and remove qualifies, ie, Foo* will become Foo
|
||||
Type strip_qualifiers() const;
|
||||
|
||||
Type get_return_type() const;
|
||||
std::vector<Type> get_arguments() const;
|
||||
std::vector<Type> get_template_arguments() const;
|
||||
|
||||
CXType cx_type;
|
||||
};
|
||||
|
||||
enum class VisiterResult { Break, Continue, Recurse };
|
||||
|
||||
class Cursor {
|
||||
public:
|
||||
Cursor();
|
||||
Cursor(const CXCursor& other);
|
||||
|
||||
explicit operator bool() const;
|
||||
bool operator==(const Cursor& rhs) const;
|
||||
bool operator!=(const Cursor& rhs) const;
|
||||
|
||||
CXCursorKind get_kind() const;
|
||||
Cursor get_declaration() const;
|
||||
Type get_type() const;
|
||||
std::string get_spelling() const;
|
||||
std::string get_display_name() const;
|
||||
std::string get_usr() const;
|
||||
|
||||
bool is_definition() const;
|
||||
|
||||
// If the given cursor points to a template specialization, this
|
||||
// will return the cursor pointing to the template definition.
|
||||
// If the given cursor is not a template specialization, this will
|
||||
// just return the same cursor.
|
||||
//
|
||||
// This means it is always safe to call this method.
|
||||
Cursor template_specialization_to_template_definition() const;
|
||||
|
||||
Cursor get_referenced() const;
|
||||
Cursor get_canonical() const;
|
||||
Cursor get_definition() const;
|
||||
Cursor get_semantic_parent() const;
|
||||
std::vector<Cursor> get_arguments() const;
|
||||
bool is_valid_kind() const;
|
||||
|
||||
std::string get_type_description() const;
|
||||
std::string get_comments() const;
|
||||
|
||||
std::string ToString() const;
|
||||
|
||||
template <typename TClientData>
|
||||
using Visitor = VisiterResult (*)(Cursor cursor,
|
||||
Cursor parent,
|
||||
TClientData* client_data);
|
||||
|
||||
enum class VisitResult { Completed, EndedEarly };
|
||||
|
||||
template <typename TClientData>
|
||||
VisitResult VisitChildren(Visitor<TClientData> visitor,
|
||||
TClientData* client_data) const {
|
||||
if (clang_visitChildren(cx_cursor,
|
||||
reinterpret_cast<CXCursorVisitor>(visitor),
|
||||
client_data) == 0)
|
||||
return VisitResult::Completed;
|
||||
return VisitResult::EndedEarly;
|
||||
}
|
||||
|
||||
CXCursor cx_cursor;
|
||||
};
|
||||
} // namespace clang
|
||||
|
||||
#endif // CURSOR_H_
|
@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "Cursor.h"
|
||||
#include "../clang_cursor.h"
|
||||
#include "Index.h"
|
||||
|
||||
#include <clang-c/Index.h>
|
||||
|
24
src/query.cc
24
src/query.cc
@ -420,18 +420,18 @@ IndexUpdate::IndexUpdate(const IdMap& previous_id_map,
|
||||
// |query_name| is the name of the variable on the query type.
|
||||
// |index_name| is the name of the variable on the index type.
|
||||
// |type| is the type of the variable.
|
||||
#define PROCESS_UPDATE_DIFF(type_id, query_name, index_name, type) \
|
||||
{ \
|
||||
/* Check for changes. */ \
|
||||
std::vector<type> removed, added; \
|
||||
auto previous = previous_id_map.ToQuery(previous_def->index_name); \
|
||||
auto current = current_id_map.ToQuery(current_def->index_name); \
|
||||
bool did_add = \
|
||||
ComputeDifferenceForUpdate(previous, current, &removed, &added); \
|
||||
if (did_add) { \
|
||||
query_name.push_back(MergeableUpdate<type_id, type>( \
|
||||
current_id_map.ToQuery(current_def->id), added, removed)); \
|
||||
} \
|
||||
#define PROCESS_UPDATE_DIFF(type_id, query_name, index_name, type) \
|
||||
{ \
|
||||
/* Check for changes. */ \
|
||||
std::vector<type> removed, added; \
|
||||
auto previous = previous_id_map.ToQuery(previous_def->index_name); \
|
||||
auto current = current_id_map.ToQuery(current_def->index_name); \
|
||||
bool did_add = \
|
||||
ComputeDifferenceForUpdate(previous, current, &removed, &added); \
|
||||
if (did_add) { \
|
||||
query_name.push_back(MergeableUpdate<type_id, type>( \
|
||||
current_id_map.ToQuery(current_def->id), added, removed)); \
|
||||
} \
|
||||
}
|
||||
// File
|
||||
files_def_update.push_back(BuildFileDef(current_id_map, current_file));
|
||||
|
Loading…
Reference in New Issue
Block a user