1 //===--- Relation.h ----------------------------------------------*- C++-*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_RELATION_H 10 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_RELATION_H 11 12 #include "SymbolID.h" 13 #include "SymbolLocation.h" 14 #include "clang/Index/IndexSymbol.h" 15 #include "llvm/ADT/iterator_range.h" 16 #include <cstdint> 17 #include <utility> 18 19 namespace clang { 20 namespace clangd { 21 22 enum class RelationKind : uint8_t { 23 BaseOf, 24 OverriddenBy, 25 }; 26 27 /// Represents a relation between two symbols. 28 /// For an example: 29 /// - "A is a base class of B" is represented as 30 /// { Subject = A, Predicate = BaseOf, Object = B }. 31 /// - "Derived::Foo overrides Base::Foo" is represented as 32 /// { Subject = Base::Foo, Predicate = OverriddenBy, Object = Derived::Foo 33 /// }. 34 struct Relation { 35 SymbolID Subject; 36 RelationKind Predicate; 37 SymbolID Object; 38 39 bool operator==(const Relation &Other) const { 40 return std::tie(Subject, Predicate, Object) == 41 std::tie(Other.Subject, Other.Predicate, Other.Object); 42 } 43 // SPO order 44 bool operator<(const Relation &Other) const { 45 return std::tie(Subject, Predicate, Object) < 46 std::tie(Other.Subject, Other.Predicate, Other.Object); 47 } 48 }; 49 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const RelationKind R); 50 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Relation &R); 51 52 class RelationSlab { 53 public: 54 using value_type = Relation; 55 using const_iterator = std::vector<value_type>::const_iterator; 56 using iterator = const_iterator; 57 58 RelationSlab() = default; 59 RelationSlab(RelationSlab &&Slab) = default; 60 RelationSlab &operator=(RelationSlab &&RHS) = default; 61 begin()62 const_iterator begin() const { return Relations.begin(); } end()63 const_iterator end() const { return Relations.end(); } size()64 size_t size() const { return Relations.size(); } empty()65 bool empty() const { return Relations.empty(); } 66 bytes()67 size_t bytes() const { 68 return sizeof(*this) + sizeof(value_type) * Relations.capacity(); 69 } 70 71 /// Lookup all relations matching the given subject and predicate. 72 llvm::iterator_range<iterator> lookup(const SymbolID &Subject, 73 RelationKind Predicate) const; 74 75 /// RelationSlab::Builder is a mutable container that can 'freeze' to 76 /// RelationSlab. 77 class Builder { 78 public: 79 /// Adds a relation to the slab. insert(const Relation & R)80 void insert(const Relation &R) { Relations.push_back(R); } 81 82 /// Consumes the builder to finalize the slab. 83 RelationSlab build() &&; 84 85 private: 86 std::vector<Relation> Relations; 87 }; 88 89 private: RelationSlab(std::vector<Relation> Relations)90 RelationSlab(std::vector<Relation> Relations) 91 : Relations(std::move(Relations)) {} 92 93 std::vector<Relation> Relations; 94 }; 95 96 } // namespace clangd 97 } // namespace clang 98 99 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_RELATION_H 100