From 348b4a2e4e0d7b0f6d06be3c38bb41271195dfec Mon Sep 17 00:00:00 2001 From: Jacob Dufault Date: Sat, 11 Nov 2017 11:31:05 -0800 Subject: [PATCH] Move libclangmm/Cursor.* to clang_cursor.* --- src/.vscode/settings.json | 4 +- src/clang_cursor.cc | 195 +++++++++++++++++ src/clang_cursor.h | 87 ++++++++ src/indexer.cc | 143 +++++++------ src/libclangmm/Cursor.cc | 349 ------------------------------- src/libclangmm/Cursor.h | 99 --------- src/libclangmm/TranslationUnit.h | 2 +- src/query.cc | 24 +-- 8 files changed, 368 insertions(+), 535 deletions(-) create mode 100644 src/clang_cursor.cc create mode 100644 src/clang_cursor.h delete mode 100644 src/libclangmm/Cursor.cc delete mode 100644 src/libclangmm/Cursor.h diff --git a/src/.vscode/settings.json b/src/.vscode/settings.json index 4a157f4e..25e33e40 100644 --- a/src/.vscode/settings.json +++ b/src/.vscode/settings.json @@ -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/" } \ No newline at end of file diff --git a/src/clang_cursor.cc b/src/clang_cursor.cc new file mode 100644 index 00000000..ccb48bbe --- /dev/null +++ b/src/clang_cursor.cc @@ -0,0 +1,195 @@ +#include "clang_cursor.h" + +#include "clang_utils.h" + +#include +#include + +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::get_arguments() const { + int size = clang_getNumArgTypes(cx_type); + assert(size >= 0); + if (size < 0) + return std::vector(); + + std::vector types(size); + for (int i = 0; i < size; ++i) + types.emplace_back(clang_getArgType(cx_type, i)); + return types; +} + +std::vector ClangType::get_template_arguments() const { + int size = clang_Type_getNumTemplateArguments(cx_type); + assert(size >= 0); + if (size < 0) + return std::vector(); + + std::vector 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::get_arguments() const { + int size = clang_Cursor_getNumArguments(cx_cursor); + if (size < 0) + return std::vector(); + + std::vector 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(); +} diff --git a/src/clang_cursor.h b/src/clang_cursor.h new file mode 100644 index 00000000..ccb4138b --- /dev/null +++ b/src/clang_cursor.h @@ -0,0 +1,87 @@ +#pragma once + +#include + +#include +#include + +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 get_arguments() const; + std::vector 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 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 + using Visitor = VisitResult (*)(ClangCursor cursor, + ClangCursor parent, + TClientData* client_data); + + template + void VisitChildren(Visitor visitor, + TClientData* client_data) const { + clang_visitChildren(cx_cursor, reinterpret_cast(visitor), + client_data); + } + + CXCursor cx_cursor; +}; diff --git a/src/indexer.cc b/src/indexer.cc index ff81c4eb..c9a4368e 100644 --- a/src/indexer.cc +++ b/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> 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 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 result; + optional 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 FindChildOfKind(clang::Cursor cursor, - CXCursorKind kind) { +optional 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* result) { +ClangCursor::VisitResult FindTypeVisitor(ClangCursor cursor, + ClangCursor parent, + optional* 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 FindType(clang::Cursor cursor) { - optional result; +optional FindType(ClangCursor cursor) { + optional 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 previous_cursor; + optional previous_cursor; optional 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 => Foo<*,*>). optional 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 ResolveToDeclarationType(IndexFile* db, // ResolveToDeclarationType, which works in more scenarios. optional 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 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 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::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 opt_found_type = FindType(ref->cursor); + optional 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 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> 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(); diff --git a/src/libclangmm/Cursor.cc b/src/libclangmm/Cursor.cc deleted file mode 100644 index 3b7e3848..00000000 --- a/src/libclangmm/Cursor.cc +++ /dev/null @@ -1,349 +0,0 @@ -#include -#include - -#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::get_arguments() const { - int size = clang_getNumArgTypes(cx_type); - assert(size >= 0); - if (size < 0) - return std::vector(); - - std::vector types(size); - for (int i = 0; i < size; ++i) - types.emplace_back(clang_getArgType(cx_type, i)); - return types; -} - -std::vector 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(); - - std::vector 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::get_arguments() const { - int size = clang_Cursor_getNumArguments(cx_cursor); - if (size < 0) - return std::vector(); - - std::vector 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 \ No newline at end of file diff --git a/src/libclangmm/Cursor.h b/src/libclangmm/Cursor.h deleted file mode 100644 index e1862705..00000000 --- a/src/libclangmm/Cursor.h +++ /dev/null @@ -1,99 +0,0 @@ -#ifndef CURSOR_H_ -#define CURSOR_H_ - -#include -#include -#include - -#include - -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 get_arguments() const; - std::vector 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 get_arguments() const; - bool is_valid_kind() const; - - std::string get_type_description() const; - std::string get_comments() const; - - std::string ToString() const; - - template - using Visitor = VisiterResult (*)(Cursor cursor, - Cursor parent, - TClientData* client_data); - - enum class VisitResult { Completed, EndedEarly }; - - template - VisitResult VisitChildren(Visitor visitor, - TClientData* client_data) const { - if (clang_visitChildren(cx_cursor, - reinterpret_cast(visitor), - client_data) == 0) - return VisitResult::Completed; - return VisitResult::EndedEarly; - } - - CXCursor cx_cursor; -}; -} // namespace clang - -#endif // CURSOR_H_ diff --git a/src/libclangmm/TranslationUnit.h b/src/libclangmm/TranslationUnit.h index cb64c550..9c202ff2 100644 --- a/src/libclangmm/TranslationUnit.h +++ b/src/libclangmm/TranslationUnit.h @@ -1,6 +1,6 @@ #pragma once -#include "Cursor.h" +#include "../clang_cursor.h" #include "Index.h" #include diff --git a/src/query.cc b/src/query.cc index 09283542..94491ace 100644 --- a/src/query.cc +++ b/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 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( \ - 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 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( \ + current_id_map.ToQuery(current_def->id), added, removed)); \ + } \ } // File files_def_update.push_back(BuildFileDef(current_id_map, current_file));