Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:37:11

0001 //===--- ASTSelection.h - Clang refactoring library -----------------------===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef LLVM_CLANG_TOOLING_REFACTORING_ASTSELECTION_H
0010 #define LLVM_CLANG_TOOLING_REFACTORING_ASTSELECTION_H
0011 
0012 #include "clang/AST/ASTTypeTraits.h"
0013 #include "clang/AST/Stmt.h"
0014 #include "clang/Basic/LLVM.h"
0015 #include "clang/Basic/SourceLocation.h"
0016 #include "llvm/Support/raw_ostream.h"
0017 #include <optional>
0018 #include <vector>
0019 
0020 namespace clang {
0021 
0022 class ASTContext;
0023 
0024 namespace tooling {
0025 
0026 enum class SourceSelectionKind {
0027   /// A node that's not selected.
0028   None,
0029 
0030   /// A node that's considered to be selected because the whole selection range
0031   /// is inside of its source range.
0032   ContainsSelection,
0033   /// A node that's considered to be selected because the start of the selection
0034   /// range is inside its source range.
0035   ContainsSelectionStart,
0036   /// A node that's considered to be selected because the end of the selection
0037   /// range is inside its source range.
0038   ContainsSelectionEnd,
0039 
0040   /// A node that's considered to be selected because the node is entirely in
0041   /// the selection range.
0042   InsideSelection,
0043 };
0044 
0045 /// Represents a selected AST node.
0046 ///
0047 /// AST selection is represented using a tree of \c SelectedASTNode. The tree
0048 /// follows the top-down shape of the actual AST. Each selected node has
0049 /// a selection kind. The kind might be none as the node itself might not
0050 /// actually be selected, e.g. a statement in macro whose child is in a macro
0051 /// argument.
0052 struct SelectedASTNode {
0053   DynTypedNode Node;
0054   SourceSelectionKind SelectionKind;
0055   std::vector<SelectedASTNode> Children;
0056 
0057   SelectedASTNode(const DynTypedNode &Node, SourceSelectionKind SelectionKind)
0058       : Node(Node), SelectionKind(SelectionKind) {}
0059   SelectedASTNode(SelectedASTNode &&) = default;
0060   SelectedASTNode &operator=(SelectedASTNode &&) = default;
0061 
0062   void dump(llvm::raw_ostream &OS = llvm::errs()) const;
0063 
0064   using ReferenceType = std::reference_wrapper<const SelectedASTNode>;
0065 };
0066 
0067 /// Traverses the given ASTContext and creates a tree of selected AST nodes.
0068 ///
0069 /// \returns std::nullopt if no nodes are selected in the AST, or a selected AST
0070 /// node that corresponds to the TranslationUnitDecl otherwise.
0071 std::optional<SelectedASTNode> findSelectedASTNodes(const ASTContext &Context,
0072                                                     SourceRange SelectionRange);
0073 
0074 /// An AST selection value that corresponds to a selection of a set of
0075 /// statements that belong to one body of code (like one function).
0076 ///
0077 /// For example, the following selection in the source.
0078 ///
0079 /// \code
0080 /// void function() {
0081 ///  // selection begin:
0082 ///  int x = 0;
0083 ///  {
0084 ///     // selection end
0085 ///     x = 1;
0086 ///  }
0087 ///  x = 2;
0088 /// }
0089 /// \endcode
0090 ///
0091 /// Would correspond to a code range selection of statements "int x = 0"
0092 /// and the entire compound statement that follows it.
0093 ///
0094 /// A \c CodeRangeASTSelection value stores references to the full
0095 /// \c SelectedASTNode tree and should not outlive it.
0096 class CodeRangeASTSelection {
0097 public:
0098   CodeRangeASTSelection(CodeRangeASTSelection &&) = default;
0099   CodeRangeASTSelection &operator=(CodeRangeASTSelection &&) = default;
0100 
0101   /// Returns the parent hierarchy (top to bottom) for the selected nodes.
0102   ArrayRef<SelectedASTNode::ReferenceType> getParents() { return Parents; }
0103 
0104   /// Returns the number of selected statements.
0105   size_t size() const {
0106     if (!AreChildrenSelected)
0107       return 1;
0108     return SelectedNode.get().Children.size();
0109   }
0110 
0111   const Stmt *operator[](size_t I) const {
0112     if (!AreChildrenSelected) {
0113       assert(I == 0 && "Invalid index");
0114       return SelectedNode.get().Node.get<Stmt>();
0115     }
0116     return SelectedNode.get().Children[I].Node.get<Stmt>();
0117   }
0118 
0119   /// Returns true when a selected code range is in a function-like body
0120   /// of code, like a function, method or a block.
0121   ///
0122   /// This function can be used to test against selected expressions that are
0123   /// located outside of a function, e.g. global variable initializers, default
0124   /// argument values, or even template arguments.
0125   ///
0126   /// Use the \c getFunctionLikeNearestParent to get the function-like parent
0127   /// declaration.
0128   bool isInFunctionLikeBodyOfCode() const;
0129 
0130   /// Returns the nearest function-like parent declaration or null if such
0131   /// declaration doesn't exist.
0132   const Decl *getFunctionLikeNearestParent() const;
0133 
0134   static std::optional<CodeRangeASTSelection>
0135   create(SourceRange SelectionRange, const SelectedASTNode &ASTSelection);
0136 
0137 private:
0138   CodeRangeASTSelection(SelectedASTNode::ReferenceType SelectedNode,
0139                         ArrayRef<SelectedASTNode::ReferenceType> Parents,
0140                         bool AreChildrenSelected)
0141       : SelectedNode(SelectedNode), Parents(Parents),
0142         AreChildrenSelected(AreChildrenSelected) {}
0143 
0144   /// The reference to the selected node (or reference to the selected
0145   /// child nodes).
0146   SelectedASTNode::ReferenceType SelectedNode;
0147   /// The parent hierarchy (top to bottom) for the selected noe.
0148   llvm::SmallVector<SelectedASTNode::ReferenceType, 8> Parents;
0149   /// True only when the children of the selected node are actually selected.
0150   bool AreChildrenSelected;
0151 };
0152 
0153 } // end namespace tooling
0154 } // end namespace clang
0155 
0156 #endif // LLVM_CLANG_TOOLING_REFACTORING_ASTSELECTION_H