Coverage Report

Created: 2020-02-15 09:57

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/include/clang/Tooling/Refactoring/ASTSelection.h
Line
Count
Source
1
//===--- ASTSelection.h - Clang refactoring library -----------------------===//
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_TOOLING_REFACTOR_AST_SELECTION_H
10
#define LLVM_CLANG_TOOLING_REFACTOR_AST_SELECTION_H
11
12
#include "clang/AST/ASTTypeTraits.h"
13
#include "clang/AST/Stmt.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
  DynTypedNode Node;
52
  SourceSelectionKind SelectionKind;
53
  std::vector<SelectedASTNode> Children;
54
55
  SelectedASTNode(const DynTypedNode &Node, SourceSelectionKind SelectionKind)
56
3.29k
      : Node(Node), SelectionKind(SelectionKind) {}
57
8.46k
  SelectedASTNode(SelectedASTNode &&) = default;
58
  SelectedASTNode &operator=(SelectedASTNode &&) = default;
59
60
  void dump(llvm::raw_ostream &OS = llvm::errs()) const;
61
62
  using ReferenceType = std::reference_wrapper<const SelectedASTNode>;
63
};
64
65
/// Traverses the given ASTContext and creates a tree of selected AST nodes.
66
///
67
/// \returns None if no nodes are selected in the AST, or a selected AST node
68
/// that corresponds to the TranslationUnitDecl otherwise.
69
Optional<SelectedASTNode> findSelectedASTNodes(const ASTContext &Context,
70
                                               SourceRange SelectionRange);
71
72
/// An AST selection value that corresponds to a selection of a set of
73
/// statements that belong to one body of code (like one function).
74
///
75
/// For example, the following selection in the source.
76
///
77
/// \code
78
/// void function() {
79
///  // selection begin:
80
///  int x = 0;
81
///  {
82
///     // selection end
83
///     x = 1;
84
///  }
85
///  x = 2;
86
/// }
87
/// \endcode
88
///
89
/// Would correspond to a code range selection of statements "int x = 0"
90
/// and the entire compound statement that follows it.
91
///
92
/// A \c CodeRangeASTSelection value stores references to the full
93
/// \c SelectedASTNode tree and should not outlive it.
94
class CodeRangeASTSelection {
95
public:
96
258
  CodeRangeASTSelection(CodeRangeASTSelection &&) = default;
97
  CodeRangeASTSelection &operator=(CodeRangeASTSelection &&) = default;
98
99
  /// Returns the parent hierarchy (top to bottom) for the selected nodes.
100
  ArrayRef<SelectedASTNode::ReferenceType> getParents() { return Parents; }
101
102
  /// Returns the number of selected statements.
103
127
  size_t size() const {
104
127
    if (!AreChildrenSelected)
105
113
      return 1;
106
14
    return SelectedNode.get().Children.size();
107
14
  }
108
109
192
  const Stmt *operator[](size_t I) const {
110
192
    if (!AreChildrenSelected) {
111
170
      assert(I == 0 && "Invalid index");
112
170
      return SelectedNode.get().Node.get<Stmt>();
113
170
    }
114
22
    return SelectedNode.get().Children[I].Node.get<Stmt>();
115
22
  }
116
117
  /// Returns true when a selected code range is in a function-like body
118
  /// of code, like a function, method or a block.
119
  ///
120
  /// This function can be used to test against selected expressions that are
121
  /// located outside of a function, e.g. global variable initializers, default
122
  /// argument values, or even template arguments.
123
  ///
124
  /// Use the \c getFunctionLikeNearestParent to get the function-like parent
125
  /// declaration.
126
  bool isInFunctionLikeBodyOfCode() const;
127
128
  /// Returns the nearest function-like parent declaration or null if such
129
  /// declaration doesn't exist.
130
  const Decl *getFunctionLikeNearestParent() const;
131
132
  static Optional<CodeRangeASTSelection>
133
  create(SourceRange SelectionRange, const SelectedASTNode &ASTSelection);
134
135
private:
136
  CodeRangeASTSelection(SelectedASTNode::ReferenceType SelectedNode,
137
                        ArrayRef<SelectedASTNode::ReferenceType> Parents,
138
                        bool AreChildrenSelected)
139
      : SelectedNode(SelectedNode), Parents(Parents.begin(), Parents.end()),
140
57
        AreChildrenSelected(AreChildrenSelected) {}
141
142
  /// The reference to the selected node (or reference to the selected
143
  /// child nodes).
144
  SelectedASTNode::ReferenceType SelectedNode;
145
  /// The parent hierarchy (top to bottom) for the selected noe.
146
  llvm::SmallVector<SelectedASTNode::ReferenceType, 8> Parents;
147
  /// True only when the children of the selected node are actually selected.
148
  bool AreChildrenSelected;
149
};
150
151
} // end namespace tooling
152
} // end namespace clang
153
154
#endif // LLVM_CLANG_TOOLING_REFACTOR_AST_SELECTION_H