Coverage Report

Created: 2023-11-11 10:31

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