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 21namespace clang { 22namespace 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. 28const 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. 33bool 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. 39inline 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. 45bool 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. 54bool 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. 62std::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. 67std::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. 72std::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`. 83std::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`. 93std::optional<std::string> buildArrow(const Expr &E, const ASTContext &Context); 94 95/// Specifies how to classify pointer-like types -- like values or like pointers 96/// -- with regard to generating member-access syntax. 97enum class PLTClass : bool { 98 Value, 99 Pointer, 100}; 101 102/// Adds an appropriate access operator (`.`, `->` or nothing, in the case of 103/// implicit `this`) to the end of the given expression. Adds parentheses when 104/// needed by the syntax and simplifies when possible. If `PLTypeClass` is 105/// `Pointer`, for known pointer-like types (see `isKnownPointerLikeType`), 106/// treats `operator->` and `operator*` like the built-in `->` and `*` 107/// operators. 108/// 109/// `x` becomes `x->` or `x.`, depending on `E`'s type 110/// `a+b` becomes `(a+b)->` or `(a+b).`, depending on `E`'s type 111/// `&a` becomes `a.` 112/// `*a` becomes `a->` 113std::optional<std::string> 114buildAccess(const Expr &E, ASTContext &Context, 115 PLTClass Classification = PLTClass::Pointer); 116/// @} 117 118} // namespace tooling 119} // namespace clang 120#endif // LLVM_CLANG_TOOLING_TRANSFORMER_SOURCECODEBUILDERS_H 121