Coverage Report

Created: 2020-09-22 08:39

/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 "llvm/Support/raw_ostream.h"
17
#include <vector>
18
19
namespace clang {
20
21
class ASTContext;
22
23
namespace tooling {
24
25
enum class SourceSelectionKind {
26
  /// A node that's not selected.
27
  None,
28
29
  /// A node that's considered to be selected because the whole selection range
30
  /// is inside of its source range.
31
  ContainsSelection,
32
  /// A node that's considered to be selected because the start of the selection
33
  /// range is inside its source range.
34
  ContainsSelectionStart,
35
  /// A node that's considered to be selected because the end of the selection
36
  /// range is inside its source range.
37
  ContainsSelectionEnd,
38
39
  /// A node that's considered to be selected because the node is entirely in
40
  /// the selection range.
41
  InsideSelection,
42
};
43
44
/// Represents a selected AST node.
45
///
46
/// AST selection is represented using a tree of \c SelectedASTNode. The tree
47
/// follows the top-down shape of the actual AST. Each selected node has
48
/// a selection kind. The kind might be none as the node itself might not
49
/// actually be selected, e.g. a statement in macro whose child is in a macro
50
/// argument.
51
struct SelectedASTNode {
52
  DynTypedNode Node;
53
  SourceSelectionKind SelectionKind;
54
  std::vector<SelectedASTNode> Children;
55
56
  SelectedASTNode(const DynTypedNode &Node, SourceSelectionKind SelectionKind)
57
3.29k
      : Node(Node), SelectionKind(SelectionKind) {}
58
8.46k
  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
258
  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
127
  size_t size() const {
105
127
    if (!AreChildrenSelected)
106
113
      return 1;
107
14
    return SelectedNode.get().Children.size();
108
14
  }
109
110
192
  const Stmt *operator[](size_t I) const {
111
192
    if (!AreChildrenSelected) {
112
170
      assert(I == 0 && "Invalid index");
113
170
      return SelectedNode.get().Node.get<Stmt>();
114
170
    }
115
22
    return SelectedNode.get().Children[I].Node.get<Stmt>();
116
22
  }
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
57
        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