clang 24.0.0git
ExprUtils.cpp
Go to the documentation of this file.
1//===--- ExprUtils.cpp - Shared expression emission queries ---------------===//
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
10#include "clang/AST/Attr.h"
11#include "clang/AST/ExprCXX.h"
12
13namespace clang::CodeGenUtils {
14
16 const VariableArrayType *VLA) {
17 QualType EltType;
18 do {
19 EltType = VLA->getElementType();
20 } while ((VLA = Ctx.getAsVariableArrayType(EltType)));
21 return EltType;
22}
23
24bool isBlockVarRef(const Expr *E) {
25 // Make sure we look through parens.
26 E = E->IgnoreParens();
27
28 // Check for a direct reference to a __block variable.
29 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
30 const VarDecl *Var = dyn_cast<VarDecl>(DRE->getDecl());
31 return (Var && Var->hasAttr<BlocksAttr>());
32 }
33
34 // More complicated stuff.
35
36 // Binary operators.
37 if (const BinaryOperator *Op = dyn_cast<BinaryOperator>(E)) {
38 // For an assignment or pointer-to-member operation, just care
39 // about the LHS.
40 if (Op->isAssignmentOp() || Op->isPtrMemOp())
41 return isBlockVarRef(Op->getLHS());
42
43 // For a comma, just care about the RHS.
44 if (Op->getOpcode() == BO_Comma)
45 return isBlockVarRef(Op->getRHS());
46
47 // FIXME: pointer arithmetic?
48 return false;
49
50 // Check both sides of a conditional operator.
51 } else if (const AbstractConditionalOperator *Op =
52 dyn_cast<AbstractConditionalOperator>(E)) {
53 return isBlockVarRef(Op->getTrueExpr()) ||
54 isBlockVarRef(Op->getFalseExpr());
55
56 // OVEs are required to support BinaryConditionalOperators.
57 } else if (const OpaqueValueExpr *Op = dyn_cast<OpaqueValueExpr>(E)) {
58 if (const Expr *Src = Op->getSourceExpr())
59 return isBlockVarRef(Src);
60
61 // Casts are necessary to get things like (*(int*)&var) = foo().
62 // We don't really care about the kind of cast here, except
63 // we don't want to look through l2r casts, because it's okay
64 // to get the *value* in a __block variable.
65 } else if (const CastExpr *Cast = dyn_cast<CastExpr>(E)) {
66 if (Cast->getCastKind() == CK_LValueToRValue)
67 return false;
68 return isBlockVarRef(Cast->getSubExpr());
69
70 // Handle unary operators. Again, just aggressively look through
71 // it, ignoring the operation.
72 } else if (const UnaryOperator *UOp = dyn_cast<UnaryOperator>(E)) {
73 return isBlockVarRef(UOp->getSubExpr());
74
75 // Look into the base of a field access.
76 } else if (const MemberExpr *Mem = dyn_cast<MemberExpr>(E)) {
77 return isBlockVarRef(Mem->getBase());
78
79 // Look into the base of a subscript.
80 } else if (const ArraySubscriptExpr *Sub = dyn_cast<ArraySubscriptExpr>(E)) {
81 return isBlockVarRef(Sub->getBase());
82 }
83
84 return false;
85}
86
88 const ASTContext &Ctx) {
89 // Anything that is an integer or floating point constant is fine.
90 return E->IgnoreParens()->isEvaluatable(Ctx);
91
92 // Even non-volatile automatic variables can't be evaluated unconditionally.
93 // Referencing a thread_local may cause non-trivial initialization work to
94 // occur. If we're inside a lambda and one of the variables is from the scope
95 // outside the lambda, that function may have returned already. Reading its
96 // locals is a bad idea. Also, these reads may introduce races there didn't
97 // exist in the source-level program.
98}
99
100bool isTrivialFiller(const Expr *E) {
101 if (!E)
102 return true;
103
105 return true;
106
107 if (const auto *ILE = dyn_cast<InitListExpr>(E)) {
108 if (ILE->getNumInits())
109 return false;
110 return isTrivialFiller(ILE->getArrayFiller());
111 }
112
113 if (const auto *Cons = dyn_cast_or_null<CXXConstructExpr>(E))
114 return Cons->getConstructor()->isDefaultConstructor() &&
115 Cons->getConstructor()->isTrivial();
116
117 // FIXME: Are there other cases where we can avoid emitting an initializer?
118 return false;
119}
120
122 for (const FunctionDecl *PD = FD; PD; PD = PD->getPreviousDecl())
123 if (!PD->isInlineBuiltinDeclaration())
124 return false;
125 return true;
126}
127
128} // namespace clang::CodeGenUtils
Defines the clang::Expr interface and subclasses for C++ expressions.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:239
const VariableArrayType * getAsVariableArrayType(QualType T) const
AbstractConditionalOperator - An abstract base class for ConditionalOperator and BinaryConditionalOpe...
Definition Expr.h:4397
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
Definition Expr.h:2765
QualType getElementType() const
Definition TypeBase.h:3825
A builtin binary operation expression such as "x + y" or "x <= y".
Definition Expr.h:4082
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
Definition Expr.h:3720
A reference to a declared variable, function, enum, etc.
Definition Expr.h:1290
bool hasAttr() const
Definition DeclBase.h:585
This represents one expression.
Definition Expr.h:113
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
Definition Expr.cpp:3119
bool isEvaluatable(const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects) const
isEvaluatable - Call EvaluateAsRValue to see if this expression can be constant folded without side-e...
Represents a function declaration or definition.
Definition Decl.h:2059
FunctionDecl * getPreviousDecl()
Return the previous declaration of this declaration or NULL if this is the first declaration.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
Definition Expr.h:3408
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
Definition Expr.h:1198
A (possibly-)qualified type.
Definition TypeBase.h:938
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Definition Expr.h:2288
Represents a variable declaration or definition.
Definition Decl.h:933
Represents a C array with a specified size that is not an integer-constant-expression.
Definition TypeBase.h:4057
QualType getFixedSizeElementType(const ASTContext &Ctx, const VariableArrayType *VLA)
Strip off the variably-modified array types wrapping VLA and return the first element type that has a...
Definition ExprUtils.cpp:15
bool isTrivialFiller(const Expr *E)
Check whether E is a trivial array filler, that is, one that is equivalent to zero-initialization.
bool isCheapEnoughToEvaluateUnconditionally(const Expr *E, const ASTContext &Ctx)
Check whether E is cheap enough and side-effect-free enough to evaluate unconditionally instead of co...
Definition ExprUtils.cpp:87
bool isBlockVarRef(const Expr *E)
Check whether the value of E is possibly a reference to or into a __block variable.
Definition ExprUtils.cpp:24
bool onlyHasInlineBuiltinDeclaration(const FunctionDecl *FD)
Detect the unusual situation where an inline version of a builtin is shadowed by a non-inline version...
bool isa(CodeGen::Address addr)
Definition Address.h:330