mirror of
				https://github.com/MaskRay/ccls.git
				synced 2025-10-31 20:53:01 +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; | ||||
| }; | ||||
							
								
								
									
										135
									
								
								src/indexer.cc
									
									
									
									
									
								
							
							
						
						
									
										135
									
								
								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,8 +546,8 @@ CXIdxClientContainer startedTranslationUnit(CXClientData client_data, | ||||
|   return nullptr; | ||||
| } | ||||
| 
 | ||||
| clang::VisiterResult DumpVisitor(clang::Cursor cursor, | ||||
|                                  clang::Cursor parent, | ||||
| ClangCursor::VisitResult DumpVisitor(ClangCursor cursor, | ||||
|                                      ClangCursor parent, | ||||
|                                      int* level) { | ||||
|   for (int i = 0; i < *level; ++i) | ||||
|     std::cerr << "  "; | ||||
| @ -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, | ||||
| 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,8 +850,8 @@ 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, | ||||
| ClangCursor::VisitResult AddDeclInitializerUsagesVisitor(ClangCursor cursor, | ||||
|                                                          ClangCursor parent, | ||||
|                                                          IndexFile* db) { | ||||
|   /*
 | ||||
|     We need to index the |DeclRefExpr| below (ie, |var| inside of | ||||
| @ -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,8 +923,8 @@ bool AreEqualLocations(CXIdxLoc loc, CXCursor cursor) { | ||||
|       clang_getRangeStart(clang_Cursor_getSpellingNameRange(cursor, 0, 0))); | ||||
| } | ||||
| 
 | ||||
| clang::VisiterResult VisitMacroDefinitionAndExpansions(clang::Cursor cursor, | ||||
|                                                        clang::Cursor parent, | ||||
| ClangCursor::VisitResult VisitMacroDefinitionAndExpansions(ClangCursor cursor, | ||||
|                                                            ClangCursor parent, | ||||
|                                                            IndexParam* param) { | ||||
|   switch (cursor.get_kind()) { | ||||
|     case CXCursor_MacroDefinition: | ||||
| @ -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> | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user