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