1 #pragma once 2 3 #include "position.h" 4 5 #include <clang-c/Index.h> 6 #include <optional.h> 7 8 #include <array> 9 #include <string> 10 #include <vector> 11 12 using Usr = uint64_t; 13 14 Range ResolveCXSourceRange(const CXSourceRange& range, 15 CXFile* cx_file = nullptr); 16 17 class ClangCursor; 18 19 class ClangType { 20 public: 21 ClangType(); 22 ClangType(const CXType& other); 23 24 bool operator==(const ClangType& rhs) const; 25 26 // Returns true if this is a fundamental type like int. is_builtin()27 bool is_builtin() const { 28 // NOTE: This will return false for pointed types. Should we call 29 // strip_qualifiers for the user? 30 return cx_type.kind >= CXType_FirstBuiltin && 31 cx_type.kind <= CXType_LastBuiltin; 32 } 33 34 ClangCursor get_declaration() const; 35 std::string get_usr() const; 36 Usr get_usr_hash() const; 37 std::string get_spell_name() const; 38 ClangType get_canonical() const; 39 40 // Try to resolve this type and remove qualifies, ie, Foo* will become Foo 41 ClangType strip_qualifiers() const; 42 43 ClangType get_return_type() const; 44 std::vector<ClangType> get_arguments() const; 45 std::vector<ClangType> get_template_arguments() const; 46 47 CXType cx_type; 48 }; 49 50 class ClangCursor { 51 public: 52 ClangCursor(); 53 ClangCursor(const CXCursor& other); 54 55 explicit operator bool() const; 56 bool operator==(const ClangCursor& rhs) const; 57 bool operator!=(const ClangCursor& rhs) const; 58 59 CXCursorKind get_kind() const; 60 ClangType get_type() const; 61 std::string get_spell_name() const; 62 Range get_spell(CXFile* cx_file = nullptr) const; 63 Range get_extent() const; 64 std::string get_display_name() const; 65 std::string get_usr() const; 66 Usr get_usr_hash() const; 67 optional<Usr> get_opt_usr_hash() const; 68 69 bool is_definition() const; 70 71 // If the given cursor points to a template specialization, this 72 // will return the cursor pointing to the template definition. 73 // If the given cursor is not a template specialization, this will 74 // just return the same cursor. 75 // 76 // This means it is always safe to call this method. 77 ClangCursor template_specialization_to_template_definition() const; 78 79 ClangCursor get_referenced() const; 80 ClangCursor get_canonical() const; 81 ClangCursor get_definition() const; 82 ClangCursor get_lexical_parent() const; 83 ClangCursor get_semantic_parent() const; 84 std::vector<ClangCursor> get_arguments() const; 85 bool is_valid_kind() const; 86 87 std::string get_type_description() const; 88 std::string get_comments() const; 89 90 std::string ToString() const; 91 92 enum class VisitResult { Break, Continue, Recurse }; 93 94 template <typename TClientData> 95 using Visitor = VisitResult (*)(ClangCursor cursor, 96 ClangCursor parent, 97 TClientData* client_data); 98 99 template <typename TClientData> VisitChildren(Visitor<TClientData> visitor,TClientData * client_data)100 void VisitChildren(Visitor<TClientData> visitor, 101 TClientData* client_data) const { 102 clang_visitChildren(cx_cursor, reinterpret_cast<CXCursorVisitor>(visitor), 103 client_data); 104 } 105 106 CXCursor cx_cursor; 107 }; 108 109 namespace std { 110 template <> 111 struct hash<ClangCursor> { 112 size_t operator()(const ClangCursor& x) const { 113 return clang_hashCursor(x.cx_cursor); 114 } 115 }; 116 } // namespace std 117