Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

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

  1. //===--- SourceCode.h - Source code manipulation routines -------*- C++ -*-===//
  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. //  This file provides functions that simplify extraction of source code.
  10. //
  11. //===----------------------------------------------------------------------===//
  12.  
  13. #ifndef LLVM_CLANG_TOOLING_TRANSFORMER_SOURCECODE_H
  14. #define LLVM_CLANG_TOOLING_TRANSFORMER_SOURCECODE_H
  15.  
  16. #include "clang/AST/ASTContext.h"
  17. #include "clang/Basic/SourceLocation.h"
  18. #include "clang/Basic/TokenKinds.h"
  19. #include <optional>
  20.  
  21. namespace clang {
  22. namespace tooling {
  23.  
  24. /// Extends \p Range to include the token \p Terminator, if it immediately
  25. /// follows the end of the range. Otherwise, returns \p Range unchanged.
  26. CharSourceRange maybeExtendRange(CharSourceRange Range,
  27.                                  tok::TokenKind Terminator,
  28.                                  ASTContext &Context);
  29.  
  30. /// Returns the source range spanning the node, extended to include \p Next, if
  31. /// it immediately follows \p Node. Otherwise, returns the normal range of \p
  32. /// Node.  See comments on `getExtendedText()` for examples.
  33. template <typename T>
  34. CharSourceRange getExtendedRange(const T &Node, tok::TokenKind Next,
  35.                                  ASTContext &Context) {
  36.   return maybeExtendRange(CharSourceRange::getTokenRange(Node.getSourceRange()),
  37.                           Next, Context);
  38. }
  39.  
  40. /// Returns the logical source range of the node extended to include associated
  41. /// comments and whitespace before and after the node, and associated
  42. /// terminators. The returned range consists of file locations, if valid file
  43. /// locations can be found for the associated content; otherwise, an invalid
  44. /// range is returned.
  45. ///
  46. /// Note that parsing comments is disabled by default. In order to select a
  47. /// range containing associated comments, you may need to invoke the tool with
  48. /// `-fparse-all-comments`.
  49. CharSourceRange getAssociatedRange(const Decl &D, ASTContext &Context);
  50.  
  51. /// Returns the source-code text in the specified range.
  52. StringRef getText(CharSourceRange Range, const ASTContext &Context);
  53.  
  54. /// Returns the source-code text corresponding to \p Node.
  55. template <typename T>
  56. StringRef getText(const T &Node, const ASTContext &Context) {
  57.   return getText(CharSourceRange::getTokenRange(Node.getSourceRange()),
  58.                  Context);
  59. }
  60.  
  61. /// Returns the source text of the node, extended to include \p Next, if it
  62. /// immediately follows the node. Otherwise, returns the text of just \p Node.
  63. ///
  64. /// For example, given statements S1 and S2 below:
  65. /// \code
  66. ///   {
  67. ///     // S1:
  68. ///     if (!x) return foo();
  69. ///     // S2:
  70. ///     if (!x) { return 3; }
  71. ///   }
  72. /// \endcode
  73. /// then
  74. /// \code
  75. ///   getText(S1, Context) = "if (!x) return foo()"
  76. ///   getExtendedText(S1, tok::TokenKind::semi, Context)
  77. ///     = "if (!x) return foo();"
  78. ///   getExtendedText(*S1.getThen(), tok::TokenKind::semi, Context)
  79. ///     = "return foo();"
  80. ///   getExtendedText(*S2.getThen(), tok::TokenKind::semi, Context)
  81. ///     = getText(S2, Context) = "{ return 3; }"
  82. /// \endcode
  83. template <typename T>
  84. StringRef getExtendedText(const T &Node, tok::TokenKind Next,
  85.                           ASTContext &Context) {
  86.   return getText(getExtendedRange(Node, Next, Context), Context);
  87. }
  88.  
  89. /// Determines whether \p Range is one that can be edited by a rewrite;
  90. /// generally, one that starts and ends within a particular file.
  91. llvm::Error validateEditRange(const CharSourceRange &Range,
  92.                               const SourceManager &SM);
  93.  
  94. /// Attempts to resolve the given range to one that can be edited by a rewrite;
  95. /// generally, one that starts and ends within a particular file. If a value is
  96. /// returned, it satisfies \c validateEditRange.
  97. ///
  98. /// If \c IncludeMacroExpansion is true, a limited set of cases involving source
  99. /// locations in macro expansions is supported. For example, if we're looking to
  100. /// rewrite the int literal 3 to 6, and we have the following definition:
  101. ///    #define DO_NOTHING(x) x
  102. /// then
  103. ///    foo(DO_NOTHING(3))
  104. /// will be rewritten to
  105. ///    foo(6)
  106. std::optional<CharSourceRange>
  107. getFileRangeForEdit(const CharSourceRange &EditRange, const SourceManager &SM,
  108.                     const LangOptions &LangOpts,
  109.                     bool IncludeMacroExpansion = true);
  110. inline std::optional<CharSourceRange>
  111. getFileRangeForEdit(const CharSourceRange &EditRange, const ASTContext &Context,
  112.                     bool IncludeMacroExpansion = true) {
  113.   return getFileRangeForEdit(EditRange, Context.getSourceManager(),
  114.                              Context.getLangOpts(), IncludeMacroExpansion);
  115. }
  116.  
  117. /// Attempts to resolve the given range to one that starts and ends in a
  118. /// particular file.
  119. ///
  120. /// If \c IncludeMacroExpansion is true, a limited set of cases involving source
  121. /// locations in macro expansions is supported. For example, if we're looking to
  122. /// get the range of the int literal 3, and we have the following definition:
  123. ///    #define DO_NOTHING(x) x
  124. ///    foo(DO_NOTHING(3))
  125. /// the returned range will hold the source text `DO_NOTHING(3)`.
  126. std::optional<CharSourceRange> getFileRange(const CharSourceRange &EditRange,
  127.                                             const SourceManager &SM,
  128.                                             const LangOptions &LangOpts,
  129.                                             bool IncludeMacroExpansion);
  130. inline std::optional<CharSourceRange>
  131. getFileRange(const CharSourceRange &EditRange, const ASTContext &Context,
  132.              bool IncludeMacroExpansion) {
  133.   return getFileRange(EditRange, Context.getSourceManager(),
  134.                       Context.getLangOpts(), IncludeMacroExpansion);
  135. }
  136.  
  137. } // namespace tooling
  138. } // namespace clang
  139. #endif // LLVM_CLANG_TOOLING_TRANSFORMER_SOURCECODE_H
  140.