| /* |
| * Copyright 2018 The Kythe Authors. All rights reserved. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| #ifndef KYTHE_CXX_INDEXER_CXX_INDEXED_PARENT_MAP_H_ |
| #define KYTHE_CXX_INDEXER_CXX_INDEXED_PARENT_MAP_H_ |
| |
| #include "clang/AST/ASTTypeTraits.h" |
| #include "clang/AST/Decl.h" |
| #include "llvm/ADT/DenseMap.h" |
| #include "llvm/ADT/PointerIntPair.h" |
| |
| namespace kythe { |
| |
| /// For a given node in the AST, this class keeps track of the node's |
| /// parent (along some path from the AST root) and an integer index for that |
| /// node in some arbitrary but consistent order defined by the parent. |
| struct IndexedParent { |
| /// \brief The parent DynTypedNode associated with some key. |
| clang::ast_type_traits::DynTypedNode parent; |
| /// \brief The index at which some associated key appears in `Parent`. |
| size_t index; |
| |
| friend bool operator==(const IndexedParent& lhs, const IndexedParent& rhs) { |
| // We compare IndexedParents for deduplicating memoizable DynTypedNodes |
| // below; semantically, this means that we keep the first child index |
| // we saw when following every path through a particular memoizable |
| // IndexedParent. |
| return lhs.parent == rhs.parent; |
| } |
| |
| friend bool operator!=(const IndexedParent& lhs, const IndexedParent& rhs) { |
| return !(lhs == rhs); |
| } |
| }; |
| |
| class IndexedParentMap { |
| public: |
| /// \brief Builds and returns the translation unit's indexed parent map. |
| static IndexedParentMap Build(clang::TranslationUnitDecl* unit); |
| |
| // IndexedParentMap retains ownership of the contained IndexedParents and |
| // thus is move-only. |
| IndexedParentMap(IndexedParentMap&&) = default; |
| IndexedParentMap& operator=(IndexedParentMap&&) = default; |
| |
| bool empty() const { return parents_.empty(); } |
| |
| /// \brief Returns the parent of the given node, along with the index |
| /// at which the node appears underneath each parent. |
| const IndexedParent* GetIndexedParent( |
| const clang::ast_type_traits::DynTypedNode& node) const; |
| |
| /// \brief Returns the parent of the given node, along with the index |
| /// at which the node appears underneath each parent. |
| /// |
| /// 'NodeT' can be one of Decl, Stmt, Type, TypeLoc, |
| /// NestedNameSpecifier or NestedNameSpecifierLoc. |
| template <typename T> |
| const IndexedParent* GetIndexedParent(const T& node) const { |
| return GetIndexedParent(clang::ast_type_traits::DynTypedNode::create(node)); |
| } |
| |
| /// \return true if `Decl` and all of the nodes underneath it are prunable. |
| /// |
| /// A subtree is prunable if it's "the same" in all possible indexer runs. |
| /// This excludes, for example, certain template instantiations. |
| bool DeclDominatesPrunableSubtree(const clang::Decl* decl) const; |
| |
| private: |
| // An owned, move-only, PointerIntPair. |
| struct PointerPair : llvm::PointerIntPair<IndexedParent*, 1, bool> { |
| PointerPair() = default; |
| |
| PointerPair(PointerPair&& other) |
| : PointerIntPair(other.getPointer(), other.getInt()) { |
| other.setPointer(nullptr); |
| } |
| |
| PointerPair& operator=(PointerPair&& other) { |
| setPointerAndInt(other.getPointer(), other.getInt()); |
| other.setPointer(nullptr); |
| return *this; |
| } |
| |
| ~PointerPair() { delete PointerIntPair::getPointer(); } |
| }; |
| using MappingType = llvm::DenseMap<const void*, PointerPair>; |
| |
| explicit IndexedParentMap(MappingType parents) |
| : parents_(std::move(parents)) {} |
| |
| MappingType parents_; |
| }; |
| |
| } // namespace kythe |
| |
| #endif // KYTHE_CXX_INDEXER_CXX_INDEXED_PARENT_MAP_H_ |