ASTSelection.h 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===--- ASTSelection.h - Clang refactoring library -----------------------===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #ifndef LLVM_CLANG_TOOLING_REFACTORING_ASTSELECTION_H
  14. #define LLVM_CLANG_TOOLING_REFACTORING_ASTSELECTION_H
  15. #include "clang/AST/ASTTypeTraits.h"
  16. #include "clang/AST/Stmt.h"
  17. #include "clang/Basic/LLVM.h"
  18. #include "clang/Basic/SourceLocation.h"
  19. #include "llvm/Support/raw_ostream.h"
  20. #include <optional>
  21. #include <vector>
  22. namespace clang {
  23. class ASTContext;
  24. namespace tooling {
  25. enum class SourceSelectionKind {
  26. /// A node that's not selected.
  27. None,
  28. /// A node that's considered to be selected because the whole selection range
  29. /// is inside of its source range.
  30. ContainsSelection,
  31. /// A node that's considered to be selected because the start of the selection
  32. /// range is inside its source range.
  33. ContainsSelectionStart,
  34. /// A node that's considered to be selected because the end of the selection
  35. /// range is inside its source range.
  36. ContainsSelectionEnd,
  37. /// A node that's considered to be selected because the node is entirely in
  38. /// the selection range.
  39. InsideSelection,
  40. };
  41. /// Represents a selected AST node.
  42. ///
  43. /// AST selection is represented using a tree of \c SelectedASTNode. The tree
  44. /// follows the top-down shape of the actual AST. Each selected node has
  45. /// a selection kind. The kind might be none as the node itself might not
  46. /// actually be selected, e.g. a statement in macro whose child is in a macro
  47. /// argument.
  48. struct SelectedASTNode {
  49. DynTypedNode Node;
  50. SourceSelectionKind SelectionKind;
  51. std::vector<SelectedASTNode> Children;
  52. SelectedASTNode(const DynTypedNode &Node, SourceSelectionKind SelectionKind)
  53. : Node(Node), SelectionKind(SelectionKind) {}
  54. SelectedASTNode(SelectedASTNode &&) = default;
  55. SelectedASTNode &operator=(SelectedASTNode &&) = default;
  56. void dump(llvm::raw_ostream &OS = llvm::errs()) const;
  57. using ReferenceType = std::reference_wrapper<const SelectedASTNode>;
  58. };
  59. /// Traverses the given ASTContext and creates a tree of selected AST nodes.
  60. ///
  61. /// \returns std::nullopt if no nodes are selected in the AST, or a selected AST
  62. /// node that corresponds to the TranslationUnitDecl otherwise.
  63. std::optional<SelectedASTNode> findSelectedASTNodes(const ASTContext &Context,
  64. SourceRange SelectionRange);
  65. /// An AST selection value that corresponds to a selection of a set of
  66. /// statements that belong to one body of code (like one function).
  67. ///
  68. /// For example, the following selection in the source.
  69. ///
  70. /// \code
  71. /// void function() {
  72. /// // selection begin:
  73. /// int x = 0;
  74. /// {
  75. /// // selection end
  76. /// x = 1;
  77. /// }
  78. /// x = 2;
  79. /// }
  80. /// \endcode
  81. ///
  82. /// Would correspond to a code range selection of statements "int x = 0"
  83. /// and the entire compound statement that follows it.
  84. ///
  85. /// A \c CodeRangeASTSelection value stores references to the full
  86. /// \c SelectedASTNode tree and should not outlive it.
  87. class CodeRangeASTSelection {
  88. public:
  89. CodeRangeASTSelection(CodeRangeASTSelection &&) = default;
  90. CodeRangeASTSelection &operator=(CodeRangeASTSelection &&) = default;
  91. /// Returns the parent hierarchy (top to bottom) for the selected nodes.
  92. ArrayRef<SelectedASTNode::ReferenceType> getParents() { return Parents; }
  93. /// Returns the number of selected statements.
  94. size_t size() const {
  95. if (!AreChildrenSelected)
  96. return 1;
  97. return SelectedNode.get().Children.size();
  98. }
  99. const Stmt *operator[](size_t I) const {
  100. if (!AreChildrenSelected) {
  101. assert(I == 0 && "Invalid index");
  102. return SelectedNode.get().Node.get<Stmt>();
  103. }
  104. return SelectedNode.get().Children[I].Node.get<Stmt>();
  105. }
  106. /// Returns true when a selected code range is in a function-like body
  107. /// of code, like a function, method or a block.
  108. ///
  109. /// This function can be used to test against selected expressions that are
  110. /// located outside of a function, e.g. global variable initializers, default
  111. /// argument values, or even template arguments.
  112. ///
  113. /// Use the \c getFunctionLikeNearestParent to get the function-like parent
  114. /// declaration.
  115. bool isInFunctionLikeBodyOfCode() const;
  116. /// Returns the nearest function-like parent declaration or null if such
  117. /// declaration doesn't exist.
  118. const Decl *getFunctionLikeNearestParent() const;
  119. static std::optional<CodeRangeASTSelection>
  120. create(SourceRange SelectionRange, const SelectedASTNode &ASTSelection);
  121. private:
  122. CodeRangeASTSelection(SelectedASTNode::ReferenceType SelectedNode,
  123. ArrayRef<SelectedASTNode::ReferenceType> Parents,
  124. bool AreChildrenSelected)
  125. : SelectedNode(SelectedNode), Parents(Parents.begin(), Parents.end()),
  126. AreChildrenSelected(AreChildrenSelected) {}
  127. /// The reference to the selected node (or reference to the selected
  128. /// child nodes).
  129. SelectedASTNode::ReferenceType SelectedNode;
  130. /// The parent hierarchy (top to bottom) for the selected noe.
  131. llvm::SmallVector<SelectedASTNode::ReferenceType, 8> Parents;
  132. /// True only when the children of the selected node are actually selected.
  133. bool AreChildrenSelected;
  134. };
  135. } // end namespace tooling
  136. } // end namespace clang
  137. #endif // LLVM_CLANG_TOOLING_REFACTORING_ASTSELECTION_H
  138. #ifdef __GNUC__
  139. #pragma GCC diagnostic pop
  140. #endif