Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  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.       : Node(Node), SelectionKind(SelectionKind) {}
  59.   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.   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.   size_t size() const {
  106.     if (!AreChildrenSelected)
  107.       return 1;
  108.     return SelectedNode.get().Children.size();
  109.   }
  110.  
  111.   const Stmt *operator[](size_t I) const {
  112.     if (!AreChildrenSelected) {
  113.       assert(I == 0 && "Invalid index");
  114.       return SelectedNode.get().Node.get<Stmt>();
  115.     }
  116.     return SelectedNode.get().Children[I].Node.get<Stmt>();
  117.   }
  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.       : SelectedNode(SelectedNode), Parents(Parents.begin(), Parents.end()),
  142.         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
  157.