]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/include/clang/Tooling/Refactoring/ASTSelection.h
Merge clang trunk r321017 to contrib/llvm/tools/clang.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / clang / include / clang / Tooling / Refactoring / ASTSelection.h
1 //===--- ASTSelection.h - Clang refactoring library -----------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #ifndef LLVM_CLANG_TOOLING_REFACTOR_AST_SELECTION_H
11 #define LLVM_CLANG_TOOLING_REFACTOR_AST_SELECTION_H
12
13 #include "clang/AST/ASTTypeTraits.h"
14 #include "clang/Basic/LLVM.h"
15 #include "clang/Basic/SourceLocation.h"
16 #include <vector>
17
18 namespace clang {
19
20 class ASTContext;
21
22 namespace tooling {
23
24 enum class SourceSelectionKind {
25   /// A node that's not selected.
26   None,
27
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
38   /// A node that's considered to be selected because the node is entirely in
39   /// the selection range.
40   InsideSelection,
41 };
42
43 /// Represents a selected AST node.
44 ///
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
49 /// argument.
50 struct SelectedASTNode {
51   ast_type_traits::DynTypedNode Node;
52   SourceSelectionKind SelectionKind;
53   std::vector<SelectedASTNode> Children;
54
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;
60
61   void dump(llvm::raw_ostream &OS = llvm::errs()) const;
62
63   using ReferenceType = std::reference_wrapper<const SelectedASTNode>;
64 };
65
66 /// Traverses the given ASTContext and creates a tree of selected AST nodes.
67 ///
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);
72
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).
75 ///
76 /// For example, the following selection in the source.
77 ///
78 /// \code
79 /// void function() {
80 ///  // selection begin:
81 ///  int x = 0;
82 ///  {
83 ///     // selection end
84 ///     x = 1;
85 ///  }
86 ///  x = 2;
87 /// }
88 /// \endcode
89 ///
90 /// Would correspond to a code range selection of statements "int x = 0"
91 /// and the entire compound statement that follows it.
92 ///
93 /// A \c CodeRangeASTSelection value stores references to the full
94 /// \c SelectedASTNode tree and should not outlive it.
95 class CodeRangeASTSelection {
96 public:
97   CodeRangeASTSelection(CodeRangeASTSelection &&) = default;
98   CodeRangeASTSelection &operator=(CodeRangeASTSelection &&) = default;
99
100   /// Returns the parent hierarchy (top to bottom) for the selected nodes.
101   ArrayRef<SelectedASTNode::ReferenceType> getParents() { return Parents; }
102
103   /// Returns the number of selected statements.
104   size_t size() const {
105     if (!AreChildrenSelected)
106       return 1;
107     return SelectedNode.get().Children.size();
108   }
109
110   const Stmt *operator[](size_t I) const {
111     if (!AreChildrenSelected) {
112       assert(I == 0 && "Invalid index");
113       return SelectedNode.get().Node.get<Stmt>();
114     }
115     return SelectedNode.get().Children[I].Node.get<Stmt>();
116   }
117
118   /// Returns true when a selected code range is in a function-like body
119   /// of code, like a function, method or a block.
120   ///
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.
124   ///
125   /// Use the \c getFunctionLikeNearestParent to get the function-like parent
126   /// declaration.
127   bool isInFunctionLikeBodyOfCode() const;
128
129   /// Returns the nearest function-like parent declaration or null if such
130   /// declaration doesn't exist.
131   const Decl *getFunctionLikeNearestParent() const;
132
133   static Optional<CodeRangeASTSelection>
134   create(SourceRange SelectionRange, const SelectedASTNode &ASTSelection);
135
136 private:
137   CodeRangeASTSelection(SelectedASTNode::ReferenceType SelectedNode,
138                         ArrayRef<SelectedASTNode::ReferenceType> Parents,
139                         bool AreChildrenSelected)
140       : SelectedNode(SelectedNode), Parents(Parents.begin(), Parents.end()),
141         AreChildrenSelected(AreChildrenSelected) {}
142
143   /// The reference to the selected node (or reference to the selected
144   /// child nodes).
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;
150 };
151
152 } // end namespace tooling
153 } // end namespace clang
154
155 #endif // LLVM_CLANG_TOOLING_REFACTOR_AST_SELECTION_H