1 //===--- ASTSelection.h - Clang refactoring library -----------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #ifndef LLVM_CLANG_TOOLING_REFACTOR_AST_SELECTION_H
11 #define LLVM_CLANG_TOOLING_REFACTOR_AST_SELECTION_H
13 #include "clang/AST/ASTTypeTraits.h"
14 #include "clang/Basic/LLVM.h"
15 #include "clang/Basic/SourceLocation.h"
24 enum class SourceSelectionKind {
25 /// A node that's not selected.
28 /// A node that's considered to be selected because the whole selection range
29 /// is inside of its source range.
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.
38 /// A node that's considered to be selected because the node is entirely in
39 /// the selection range.
43 /// Represents a selected AST node.
45 /// AST selection is represented using a tree of \c SelectedASTNode. The tree
46 /// follows the top-down shape of the actual AST. Each selected node has
47 /// a selection kind. The kind might be none as the node itself might not
48 /// actually be selected, e.g. a statement in macro whose child is in a macro
50 struct SelectedASTNode {
51 ast_type_traits::DynTypedNode Node;
52 SourceSelectionKind SelectionKind;
53 std::vector<SelectedASTNode> Children;
55 SelectedASTNode(const ast_type_traits::DynTypedNode &Node,
56 SourceSelectionKind SelectionKind)
57 : Node(Node), SelectionKind(SelectionKind) {}
58 SelectedASTNode(SelectedASTNode &&) = default;
59 SelectedASTNode &operator=(SelectedASTNode &&) = default;
61 void dump(llvm::raw_ostream &OS = llvm::errs()) const;
63 using ReferenceType = std::reference_wrapper<const SelectedASTNode>;
66 /// Traverses the given ASTContext and creates a tree of selected AST nodes.
68 /// \returns None if no nodes are selected in the AST, or a selected AST node
69 /// that corresponds to the TranslationUnitDecl otherwise.
70 Optional<SelectedASTNode> findSelectedASTNodes(const ASTContext &Context,
71 SourceRange SelectionRange);
73 /// An AST selection value that corresponds to a selection of a set of
74 /// statements that belong to one body of code (like one function).
76 /// For example, the following selection in the source.
80 /// // selection begin:
90 /// Would correspond to a code range selection of statements "int x = 0"
91 /// and the entire compound statement that follows it.
93 /// A \c CodeRangeASTSelection value stores references to the full
94 /// \c SelectedASTNode tree and should not outlive it.
95 class CodeRangeASTSelection {
97 CodeRangeASTSelection(CodeRangeASTSelection &&) = default;
98 CodeRangeASTSelection &operator=(CodeRangeASTSelection &&) = default;
100 /// Returns the parent hierarchy (top to bottom) for the selected nodes.
101 ArrayRef<SelectedASTNode::ReferenceType> getParents() { return Parents; }
103 /// Returns the number of selected statements.
104 size_t size() const {
105 if (!AreChildrenSelected)
107 return SelectedNode.get().Children.size();
110 const Stmt *operator[](size_t I) const {
111 if (!AreChildrenSelected) {
112 assert(I == 0 && "Invalid index");
113 return SelectedNode.get().Node.get<Stmt>();
115 return SelectedNode.get().Children[I].Node.get<Stmt>();
118 /// Returns true when a selected code range is in a function-like body
119 /// of code, like a function, method or a block.
121 /// This function can be used to test against selected expressions that are
122 /// located outside of a function, e.g. global variable initializers, default
123 /// argument values, or even template arguments.
125 /// Use the \c getFunctionLikeNearestParent to get the function-like parent
127 bool isInFunctionLikeBodyOfCode() const;
129 /// Returns the nearest function-like parent declaration or null if such
130 /// declaration doesn't exist.
131 const Decl *getFunctionLikeNearestParent() const;
133 static Optional<CodeRangeASTSelection>
134 create(SourceRange SelectionRange, const SelectedASTNode &ASTSelection);
137 CodeRangeASTSelection(SelectedASTNode::ReferenceType SelectedNode,
138 ArrayRef<SelectedASTNode::ReferenceType> Parents,
139 bool AreChildrenSelected)
140 : SelectedNode(SelectedNode), Parents(Parents.begin(), Parents.end()),
141 AreChildrenSelected(AreChildrenSelected) {}
143 /// The reference to the selected node (or reference to the selected
145 SelectedASTNode::ReferenceType SelectedNode;
146 /// The parent hierarchy (top to bottom) for the selected noe.
147 llvm::SmallVector<SelectedASTNode::ReferenceType, 8> Parents;
148 /// True only when the children of the selected node are actually selected.
149 bool AreChildrenSelected;
152 } // end namespace tooling
153 } // end namespace clang
155 #endif // LLVM_CLANG_TOOLING_REFACTOR_AST_SELECTION_H