SourceCodeBuilders.h 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===--- SourceCodeBuilders.h - Source-code building facilities -*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. ///
  14. /// \file
  15. /// This file collects facilities for generating source code strings.
  16. ///
  17. //===----------------------------------------------------------------------===//
  18. #ifndef LLVM_CLANG_TOOLING_TRANSFORMER_SOURCECODEBUILDERS_H
  19. #define LLVM_CLANG_TOOLING_TRANSFORMER_SOURCECODEBUILDERS_H
  20. #include "clang/AST/ASTContext.h"
  21. #include "clang/AST/Expr.h"
  22. #include <string>
  23. namespace clang {
  24. namespace tooling {
  25. /// \name Code analysis utilities.
  26. /// @{
  27. /// Ignores implicit object-construction expressions in addition to the normal
  28. /// implicit expressions that are ignored.
  29. const Expr *reallyIgnoreImplicit(const Expr &E);
  30. /// Determines whether printing this expression in *any* expression requires
  31. /// parentheses to preserve its meaning. This analyses is necessarily
  32. /// conservative because it lacks information about the target context.
  33. bool mayEverNeedParens(const Expr &E);
  34. /// Determines whether printing this expression to the left of a dot or arrow
  35. /// operator requires a parentheses to preserve its meaning. Given that
  36. /// dot/arrow are (effectively) the highest precedence, this is equivalent to
  37. /// asking whether it ever needs parens.
  38. inline bool needParensBeforeDotOrArrow(const Expr &E) {
  39. return mayEverNeedParens(E);
  40. }
  41. /// Determines whether printing this expression to the right of a unary operator
  42. /// requires a parentheses to preserve its meaning.
  43. bool needParensAfterUnaryOperator(const Expr &E);
  44. // Recognizes known types (and sugared versions thereof) that overload the `*`
  45. // and `->` operator. Below is the list of currently included types, but it is
  46. // subject to change:
  47. //
  48. // * std::unique_ptr, std::shared_ptr, std::weak_ptr,
  49. // * std::optional, absl::optional, llvm::Optional,
  50. // * absl::StatusOr, llvm::Expected.
  51. bool isKnownPointerLikeType(QualType Ty, ASTContext &Context);
  52. /// @}
  53. /// \name Basic code-string generation utilities.
  54. /// @{
  55. /// Builds source for an expression, adding parens if needed for unambiguous
  56. /// parsing.
  57. std::optional<std::string> buildParens(const Expr &E,
  58. const ASTContext &Context);
  59. /// Builds idiomatic source for the dereferencing of `E`: prefix with `*` but
  60. /// simplify when it already begins with `&`. \returns empty string on failure.
  61. std::optional<std::string> buildDereference(const Expr &E,
  62. const ASTContext &Context);
  63. /// Builds idiomatic source for taking the address of `E`: prefix with `&` but
  64. /// simplify when it already begins with `*`. \returns empty string on failure.
  65. std::optional<std::string> buildAddressOf(const Expr &E,
  66. const ASTContext &Context);
  67. /// Adds a dot to the end of the given expression, but adds parentheses when
  68. /// needed by the syntax, and simplifies to `->` when possible, e.g.:
  69. ///
  70. /// `x` becomes `x.`
  71. /// `*a` becomes `a->`
  72. /// `a+b` becomes `(a+b).`
  73. ///
  74. /// DEPRECATED. Use `buildAccess`.
  75. std::optional<std::string> buildDot(const Expr &E, const ASTContext &Context);
  76. /// Adds an arrow to the end of the given expression, but adds parentheses
  77. /// when needed by the syntax, and simplifies to `.` when possible, e.g.:
  78. ///
  79. /// `x` becomes `x->`
  80. /// `&a` becomes `a.`
  81. /// `a+b` becomes `(a+b)->`
  82. ///
  83. /// DEPRECATED. Use `buildAccess`.
  84. std::optional<std::string> buildArrow(const Expr &E, const ASTContext &Context);
  85. /// Specifies how to classify pointer-like types -- like values or like pointers
  86. /// -- with regard to generating member-access syntax.
  87. enum class PLTClass : bool {
  88. Value,
  89. Pointer,
  90. };
  91. /// Adds an appropriate access operator (`.`, `->` or nothing, in the case of
  92. /// implicit `this`) to the end of the given expression. Adds parentheses when
  93. /// needed by the syntax and simplifies when possible. If `PLTypeClass` is
  94. /// `Pointer`, for known pointer-like types (see `isKnownPointerLikeType`),
  95. /// treats `operator->` and `operator*` like the built-in `->` and `*`
  96. /// operators.
  97. ///
  98. /// `x` becomes `x->` or `x.`, depending on `E`'s type
  99. /// `a+b` becomes `(a+b)->` or `(a+b).`, depending on `E`'s type
  100. /// `&a` becomes `a.`
  101. /// `*a` becomes `a->`
  102. std::optional<std::string>
  103. buildAccess(const Expr &E, ASTContext &Context,
  104. PLTClass Classification = PLTClass::Pointer);
  105. /// @}
  106. } // namespace tooling
  107. } // namespace clang
  108. #endif // LLVM_CLANG_TOOLING_TRANSFORMER_SOURCECODEBUILDERS_H
  109. #ifdef __GNUC__
  110. #pragma GCC diagnostic pop
  111. #endif