10b57cec5SDimitry Andric //===--- Expr.cpp - Expression AST Node Implementation --------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file implements the Expr class and subclasses.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric
130b57cec5SDimitry Andric #include "clang/AST/Expr.h"
140b57cec5SDimitry Andric #include "clang/AST/APValue.h"
150b57cec5SDimitry Andric #include "clang/AST/ASTContext.h"
160b57cec5SDimitry Andric #include "clang/AST/Attr.h"
175ffd83dbSDimitry Andric #include "clang/AST/ComputeDependence.h"
180b57cec5SDimitry Andric #include "clang/AST/DeclCXX.h"
190b57cec5SDimitry Andric #include "clang/AST/DeclObjC.h"
200b57cec5SDimitry Andric #include "clang/AST/DeclTemplate.h"
215ffd83dbSDimitry Andric #include "clang/AST/DependenceFlags.h"
220b57cec5SDimitry Andric #include "clang/AST/EvaluatedExprVisitor.h"
230b57cec5SDimitry Andric #include "clang/AST/ExprCXX.h"
24e8d8bef9SDimitry Andric #include "clang/AST/IgnoreExpr.h"
250b57cec5SDimitry Andric #include "clang/AST/Mangle.h"
260b57cec5SDimitry Andric #include "clang/AST/RecordLayout.h"
270b57cec5SDimitry Andric #include "clang/AST/StmtVisitor.h"
280b57cec5SDimitry Andric #include "clang/Basic/Builtins.h"
290b57cec5SDimitry Andric #include "clang/Basic/CharInfo.h"
300b57cec5SDimitry Andric #include "clang/Basic/SourceManager.h"
310b57cec5SDimitry Andric #include "clang/Basic/TargetInfo.h"
320b57cec5SDimitry Andric #include "clang/Lex/Lexer.h"
330b57cec5SDimitry Andric #include "clang/Lex/LiteralSupport.h"
3481ad6265SDimitry Andric #include "clang/Lex/Preprocessor.h"
350b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
36fe6060f1SDimitry Andric #include "llvm/Support/Format.h"
370b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
380b57cec5SDimitry Andric #include <algorithm>
390b57cec5SDimitry Andric #include <cstring>
40bdd1243dSDimitry Andric #include <optional>
410b57cec5SDimitry Andric using namespace clang;
420b57cec5SDimitry Andric
getBestDynamicClassTypeExpr() const430b57cec5SDimitry Andric const Expr *Expr::getBestDynamicClassTypeExpr() const {
440b57cec5SDimitry Andric const Expr *E = this;
450b57cec5SDimitry Andric while (true) {
46e8d8bef9SDimitry Andric E = E->IgnoreParenBaseCasts();
470b57cec5SDimitry Andric
480b57cec5SDimitry Andric // Follow the RHS of a comma operator.
490b57cec5SDimitry Andric if (auto *BO = dyn_cast<BinaryOperator>(E)) {
500b57cec5SDimitry Andric if (BO->getOpcode() == BO_Comma) {
510b57cec5SDimitry Andric E = BO->getRHS();
520b57cec5SDimitry Andric continue;
530b57cec5SDimitry Andric }
540b57cec5SDimitry Andric }
550b57cec5SDimitry Andric
560b57cec5SDimitry Andric // Step into initializer for materialized temporaries.
570b57cec5SDimitry Andric if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) {
58480093f4SDimitry Andric E = MTE->getSubExpr();
590b57cec5SDimitry Andric continue;
600b57cec5SDimitry Andric }
610b57cec5SDimitry Andric
620b57cec5SDimitry Andric break;
630b57cec5SDimitry Andric }
640b57cec5SDimitry Andric
650b57cec5SDimitry Andric return E;
660b57cec5SDimitry Andric }
670b57cec5SDimitry Andric
getBestDynamicClassType() const680b57cec5SDimitry Andric const CXXRecordDecl *Expr::getBestDynamicClassType() const {
690b57cec5SDimitry Andric const Expr *E = getBestDynamicClassTypeExpr();
700b57cec5SDimitry Andric QualType DerivedType = E->getType();
710b57cec5SDimitry Andric if (const PointerType *PTy = DerivedType->getAs<PointerType>())
720b57cec5SDimitry Andric DerivedType = PTy->getPointeeType();
730b57cec5SDimitry Andric
740b57cec5SDimitry Andric if (DerivedType->isDependentType())
750b57cec5SDimitry Andric return nullptr;
760b57cec5SDimitry Andric
770b57cec5SDimitry Andric const RecordType *Ty = DerivedType->castAs<RecordType>();
780b57cec5SDimitry Andric Decl *D = Ty->getDecl();
790b57cec5SDimitry Andric return cast<CXXRecordDecl>(D);
800b57cec5SDimitry Andric }
810b57cec5SDimitry Andric
skipRValueSubobjectAdjustments(SmallVectorImpl<const Expr * > & CommaLHSs,SmallVectorImpl<SubobjectAdjustment> & Adjustments) const820b57cec5SDimitry Andric const Expr *Expr::skipRValueSubobjectAdjustments(
830b57cec5SDimitry Andric SmallVectorImpl<const Expr *> &CommaLHSs,
840b57cec5SDimitry Andric SmallVectorImpl<SubobjectAdjustment> &Adjustments) const {
850b57cec5SDimitry Andric const Expr *E = this;
860b57cec5SDimitry Andric while (true) {
870b57cec5SDimitry Andric E = E->IgnoreParens();
880b57cec5SDimitry Andric
89*0fca6ea1SDimitry Andric if (const auto *CE = dyn_cast<CastExpr>(E)) {
900b57cec5SDimitry Andric if ((CE->getCastKind() == CK_DerivedToBase ||
910b57cec5SDimitry Andric CE->getCastKind() == CK_UncheckedDerivedToBase) &&
920b57cec5SDimitry Andric E->getType()->isRecordType()) {
930b57cec5SDimitry Andric E = CE->getSubExpr();
94*0fca6ea1SDimitry Andric const auto *Derived =
95a7dea167SDimitry Andric cast<CXXRecordDecl>(E->getType()->castAs<RecordType>()->getDecl());
960b57cec5SDimitry Andric Adjustments.push_back(SubobjectAdjustment(CE, Derived));
970b57cec5SDimitry Andric continue;
980b57cec5SDimitry Andric }
990b57cec5SDimitry Andric
1000b57cec5SDimitry Andric if (CE->getCastKind() == CK_NoOp) {
1010b57cec5SDimitry Andric E = CE->getSubExpr();
1020b57cec5SDimitry Andric continue;
1030b57cec5SDimitry Andric }
104*0fca6ea1SDimitry Andric } else if (const auto *ME = dyn_cast<MemberExpr>(E)) {
1050b57cec5SDimitry Andric if (!ME->isArrow()) {
106*0fca6ea1SDimitry Andric assert(ME->getBase()->getType()->getAsRecordDecl());
107*0fca6ea1SDimitry Andric if (const auto *Field = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
1080b57cec5SDimitry Andric if (!Field->isBitField() && !Field->getType()->isReferenceType()) {
1090b57cec5SDimitry Andric E = ME->getBase();
1100b57cec5SDimitry Andric Adjustments.push_back(SubobjectAdjustment(Field));
1110b57cec5SDimitry Andric continue;
1120b57cec5SDimitry Andric }
1130b57cec5SDimitry Andric }
1140b57cec5SDimitry Andric }
115*0fca6ea1SDimitry Andric } else if (const auto *BO = dyn_cast<BinaryOperator>(E)) {
1160b57cec5SDimitry Andric if (BO->getOpcode() == BO_PtrMemD) {
117fe6060f1SDimitry Andric assert(BO->getRHS()->isPRValue());
1180b57cec5SDimitry Andric E = BO->getLHS();
119*0fca6ea1SDimitry Andric const auto *MPT = BO->getRHS()->getType()->getAs<MemberPointerType>();
1200b57cec5SDimitry Andric Adjustments.push_back(SubobjectAdjustment(MPT, BO->getRHS()));
1210b57cec5SDimitry Andric continue;
122e8d8bef9SDimitry Andric }
123e8d8bef9SDimitry Andric if (BO->getOpcode() == BO_Comma) {
1240b57cec5SDimitry Andric CommaLHSs.push_back(BO->getLHS());
1250b57cec5SDimitry Andric E = BO->getRHS();
1260b57cec5SDimitry Andric continue;
1270b57cec5SDimitry Andric }
1280b57cec5SDimitry Andric }
1290b57cec5SDimitry Andric
1300b57cec5SDimitry Andric // Nothing changed.
1310b57cec5SDimitry Andric break;
1320b57cec5SDimitry Andric }
1330b57cec5SDimitry Andric return E;
1340b57cec5SDimitry Andric }
1350b57cec5SDimitry Andric
isKnownToHaveBooleanValue(bool Semantic) const136480093f4SDimitry Andric bool Expr::isKnownToHaveBooleanValue(bool Semantic) const {
1370b57cec5SDimitry Andric const Expr *E = IgnoreParens();
1380b57cec5SDimitry Andric
1390b57cec5SDimitry Andric // If this value has _Bool type, it is obvious 0/1.
1400b57cec5SDimitry Andric if (E->getType()->isBooleanType()) return true;
1410b57cec5SDimitry Andric // If this is a non-scalar-integer type, we don't care enough to try.
1420b57cec5SDimitry Andric if (!E->getType()->isIntegralOrEnumerationType()) return false;
1430b57cec5SDimitry Andric
1440b57cec5SDimitry Andric if (const UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) {
1450b57cec5SDimitry Andric switch (UO->getOpcode()) {
1460b57cec5SDimitry Andric case UO_Plus:
147480093f4SDimitry Andric return UO->getSubExpr()->isKnownToHaveBooleanValue(Semantic);
1480b57cec5SDimitry Andric case UO_LNot:
1490b57cec5SDimitry Andric return true;
1500b57cec5SDimitry Andric default:
1510b57cec5SDimitry Andric return false;
1520b57cec5SDimitry Andric }
1530b57cec5SDimitry Andric }
1540b57cec5SDimitry Andric
1550b57cec5SDimitry Andric // Only look through implicit casts. If the user writes
1560b57cec5SDimitry Andric // '(int) (a && b)' treat it as an arbitrary int.
157480093f4SDimitry Andric // FIXME: Should we look through any cast expression in !Semantic mode?
1580b57cec5SDimitry Andric if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
159480093f4SDimitry Andric return CE->getSubExpr()->isKnownToHaveBooleanValue(Semantic);
1600b57cec5SDimitry Andric
1610b57cec5SDimitry Andric if (const BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) {
1620b57cec5SDimitry Andric switch (BO->getOpcode()) {
1630b57cec5SDimitry Andric default: return false;
1640b57cec5SDimitry Andric case BO_LT: // Relational operators.
1650b57cec5SDimitry Andric case BO_GT:
1660b57cec5SDimitry Andric case BO_LE:
1670b57cec5SDimitry Andric case BO_GE:
1680b57cec5SDimitry Andric case BO_EQ: // Equality operators.
1690b57cec5SDimitry Andric case BO_NE:
1700b57cec5SDimitry Andric case BO_LAnd: // AND operator.
1710b57cec5SDimitry Andric case BO_LOr: // Logical OR operator.
1720b57cec5SDimitry Andric return true;
1730b57cec5SDimitry Andric
1740b57cec5SDimitry Andric case BO_And: // Bitwise AND operator.
1750b57cec5SDimitry Andric case BO_Xor: // Bitwise XOR operator.
1760b57cec5SDimitry Andric case BO_Or: // Bitwise OR operator.
1770b57cec5SDimitry Andric // Handle things like (x==2)|(y==12).
178480093f4SDimitry Andric return BO->getLHS()->isKnownToHaveBooleanValue(Semantic) &&
179480093f4SDimitry Andric BO->getRHS()->isKnownToHaveBooleanValue(Semantic);
1800b57cec5SDimitry Andric
1810b57cec5SDimitry Andric case BO_Comma:
1820b57cec5SDimitry Andric case BO_Assign:
183480093f4SDimitry Andric return BO->getRHS()->isKnownToHaveBooleanValue(Semantic);
1840b57cec5SDimitry Andric }
1850b57cec5SDimitry Andric }
1860b57cec5SDimitry Andric
1870b57cec5SDimitry Andric if (const ConditionalOperator *CO = dyn_cast<ConditionalOperator>(E))
188480093f4SDimitry Andric return CO->getTrueExpr()->isKnownToHaveBooleanValue(Semantic) &&
189480093f4SDimitry Andric CO->getFalseExpr()->isKnownToHaveBooleanValue(Semantic);
1900b57cec5SDimitry Andric
191a7dea167SDimitry Andric if (isa<ObjCBoolLiteralExpr>(E))
192a7dea167SDimitry Andric return true;
193a7dea167SDimitry Andric
194a7dea167SDimitry Andric if (const auto *OVE = dyn_cast<OpaqueValueExpr>(E))
195480093f4SDimitry Andric return OVE->getSourceExpr()->isKnownToHaveBooleanValue(Semantic);
196480093f4SDimitry Andric
197480093f4SDimitry Andric if (const FieldDecl *FD = E->getSourceBitField())
198480093f4SDimitry Andric if (!Semantic && FD->getType()->isUnsignedIntegerType() &&
199480093f4SDimitry Andric !FD->getBitWidth()->isValueDependent() &&
200480093f4SDimitry Andric FD->getBitWidthValue(FD->getASTContext()) == 1)
201480093f4SDimitry Andric return true;
202a7dea167SDimitry Andric
2030b57cec5SDimitry Andric return false;
2040b57cec5SDimitry Andric }
2050b57cec5SDimitry Andric
isFlexibleArrayMemberLike(ASTContext & Ctx,LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel,bool IgnoreTemplateOrMacroSubstitution) const206bdd1243dSDimitry Andric bool Expr::isFlexibleArrayMemberLike(
207297eecfbSDimitry Andric ASTContext &Ctx,
208bdd1243dSDimitry Andric LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel,
209bdd1243dSDimitry Andric bool IgnoreTemplateOrMacroSubstitution) const {
210bdd1243dSDimitry Andric const Expr *E = IgnoreParens();
211297eecfbSDimitry Andric const Decl *D = nullptr;
212bdd1243dSDimitry Andric
213297eecfbSDimitry Andric if (const auto *ME = dyn_cast<MemberExpr>(E))
214297eecfbSDimitry Andric D = ME->getMemberDecl();
215297eecfbSDimitry Andric else if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
216297eecfbSDimitry Andric D = DRE->getDecl();
217bdd1243dSDimitry Andric else if (const auto *IRE = dyn_cast<ObjCIvarRefExpr>(E))
218297eecfbSDimitry Andric D = IRE->getDecl();
219bdd1243dSDimitry Andric
220297eecfbSDimitry Andric return Decl::isFlexibleArrayMemberLike(Ctx, D, E->getType(),
221297eecfbSDimitry Andric StrictFlexArraysLevel,
222297eecfbSDimitry Andric IgnoreTemplateOrMacroSubstitution);
223bdd1243dSDimitry Andric }
224bdd1243dSDimitry Andric
2250eae32dcSDimitry Andric const ValueDecl *
getAsBuiltinConstantDeclRef(const ASTContext & Context) const2260eae32dcSDimitry Andric Expr::getAsBuiltinConstantDeclRef(const ASTContext &Context) const {
2270eae32dcSDimitry Andric Expr::EvalResult Eval;
2280eae32dcSDimitry Andric
2290eae32dcSDimitry Andric if (EvaluateAsConstantExpr(Eval, Context)) {
2300eae32dcSDimitry Andric APValue &Value = Eval.Val;
2310eae32dcSDimitry Andric
2320eae32dcSDimitry Andric if (Value.isMemberPointer())
2330eae32dcSDimitry Andric return Value.getMemberPointerDecl();
2340eae32dcSDimitry Andric
2350eae32dcSDimitry Andric if (Value.isLValue() && Value.getLValueOffset().isZero())
2360eae32dcSDimitry Andric return Value.getLValueBase().dyn_cast<const ValueDecl *>();
2370eae32dcSDimitry Andric }
2380eae32dcSDimitry Andric
2390eae32dcSDimitry Andric return nullptr;
2400eae32dcSDimitry Andric }
2410eae32dcSDimitry Andric
2420b57cec5SDimitry Andric // Amusing macro metaprogramming hack: check whether a class provides
2430b57cec5SDimitry Andric // a more specific implementation of getExprLoc().
2440b57cec5SDimitry Andric //
2450b57cec5SDimitry Andric // See also Stmt.cpp:{getBeginLoc(),getEndLoc()}.
2460b57cec5SDimitry Andric namespace {
2470b57cec5SDimitry Andric /// This implementation is used when a class provides a custom
2480b57cec5SDimitry Andric /// implementation of getExprLoc.
2490b57cec5SDimitry Andric template <class E, class T>
getExprLocImpl(const Expr * expr,SourceLocation (T::* v)()const)2500b57cec5SDimitry Andric SourceLocation getExprLocImpl(const Expr *expr,
2510b57cec5SDimitry Andric SourceLocation (T::*v)() const) {
2520b57cec5SDimitry Andric return static_cast<const E*>(expr)->getExprLoc();
2530b57cec5SDimitry Andric }
2540b57cec5SDimitry Andric
2550b57cec5SDimitry Andric /// This implementation is used when a class doesn't provide
2560b57cec5SDimitry Andric /// a custom implementation of getExprLoc. Overload resolution
2570b57cec5SDimitry Andric /// should pick it over the implementation above because it's
2580b57cec5SDimitry Andric /// more specialized according to function template partial ordering.
2590b57cec5SDimitry Andric template <class E>
getExprLocImpl(const Expr * expr,SourceLocation (Expr::* v)()const)2600b57cec5SDimitry Andric SourceLocation getExprLocImpl(const Expr *expr,
2610b57cec5SDimitry Andric SourceLocation (Expr::*v)() const) {
2620b57cec5SDimitry Andric return static_cast<const E *>(expr)->getBeginLoc();
2630b57cec5SDimitry Andric }
2640b57cec5SDimitry Andric }
2650b57cec5SDimitry Andric
getEnumCoercedType(const ASTContext & Ctx) const266*0fca6ea1SDimitry Andric QualType Expr::getEnumCoercedType(const ASTContext &Ctx) const {
267*0fca6ea1SDimitry Andric if (isa<EnumType>(getType()))
268*0fca6ea1SDimitry Andric return getType();
269*0fca6ea1SDimitry Andric if (const auto *ECD = getEnumConstantDecl()) {
270*0fca6ea1SDimitry Andric const auto *ED = cast<EnumDecl>(ECD->getDeclContext());
271*0fca6ea1SDimitry Andric if (ED->isCompleteDefinition())
272*0fca6ea1SDimitry Andric return Ctx.getTypeDeclType(ED);
273*0fca6ea1SDimitry Andric }
274*0fca6ea1SDimitry Andric return getType();
275*0fca6ea1SDimitry Andric }
276*0fca6ea1SDimitry Andric
getExprLoc() const2770b57cec5SDimitry Andric SourceLocation Expr::getExprLoc() const {
2780b57cec5SDimitry Andric switch (getStmtClass()) {
2790b57cec5SDimitry Andric case Stmt::NoStmtClass: llvm_unreachable("statement without class");
2800b57cec5SDimitry Andric #define ABSTRACT_STMT(type)
2810b57cec5SDimitry Andric #define STMT(type, base) \
2820b57cec5SDimitry Andric case Stmt::type##Class: break;
2830b57cec5SDimitry Andric #define EXPR(type, base) \
2840b57cec5SDimitry Andric case Stmt::type##Class: return getExprLocImpl<type>(this, &type::getExprLoc);
2850b57cec5SDimitry Andric #include "clang/AST/StmtNodes.inc"
2860b57cec5SDimitry Andric }
2870b57cec5SDimitry Andric llvm_unreachable("unknown expression kind");
2880b57cec5SDimitry Andric }
2890b57cec5SDimitry Andric
2900b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
2910b57cec5SDimitry Andric // Primary Expressions.
2920b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
2930b57cec5SDimitry Andric
AssertResultStorageKind(ConstantResultStorageKind Kind)2945f757f3fSDimitry Andric static void AssertResultStorageKind(ConstantResultStorageKind Kind) {
2955f757f3fSDimitry Andric assert((Kind == ConstantResultStorageKind::APValue ||
2965f757f3fSDimitry Andric Kind == ConstantResultStorageKind::Int64 ||
2975f757f3fSDimitry Andric Kind == ConstantResultStorageKind::None) &&
2980b57cec5SDimitry Andric "Invalid StorageKind Value");
2995ffd83dbSDimitry Andric (void)Kind;
3000b57cec5SDimitry Andric }
3010b57cec5SDimitry Andric
getStorageKind(const APValue & Value)3025f757f3fSDimitry Andric ConstantResultStorageKind ConstantExpr::getStorageKind(const APValue &Value) {
3030b57cec5SDimitry Andric switch (Value.getKind()) {
3040b57cec5SDimitry Andric case APValue::None:
3050b57cec5SDimitry Andric case APValue::Indeterminate:
3065f757f3fSDimitry Andric return ConstantResultStorageKind::None;
3070b57cec5SDimitry Andric case APValue::Int:
3080b57cec5SDimitry Andric if (!Value.getInt().needsCleanup())
3095f757f3fSDimitry Andric return ConstantResultStorageKind::Int64;
310bdd1243dSDimitry Andric [[fallthrough]];
3110b57cec5SDimitry Andric default:
3125f757f3fSDimitry Andric return ConstantResultStorageKind::APValue;
3130b57cec5SDimitry Andric }
3140b57cec5SDimitry Andric }
3150b57cec5SDimitry Andric
3165f757f3fSDimitry Andric ConstantResultStorageKind
getStorageKind(const Type * T,const ASTContext & Context)3170b57cec5SDimitry Andric ConstantExpr::getStorageKind(const Type *T, const ASTContext &Context) {
3180b57cec5SDimitry Andric if (T->isIntegralOrEnumerationType() && Context.getTypeInfo(T).Width <= 64)
3195f757f3fSDimitry Andric return ConstantResultStorageKind::Int64;
3205f757f3fSDimitry Andric return ConstantResultStorageKind::APValue;
3210b57cec5SDimitry Andric }
3220b57cec5SDimitry Andric
ConstantExpr(Expr * SubExpr,ConstantResultStorageKind StorageKind,bool IsImmediateInvocation)3235f757f3fSDimitry Andric ConstantExpr::ConstantExpr(Expr *SubExpr, ConstantResultStorageKind StorageKind,
3245ffd83dbSDimitry Andric bool IsImmediateInvocation)
3255ffd83dbSDimitry Andric : FullExpr(ConstantExprClass, SubExpr) {
3265f757f3fSDimitry Andric ConstantExprBits.ResultKind = llvm::to_underlying(StorageKind);
3270b57cec5SDimitry Andric ConstantExprBits.APValueKind = APValue::None;
3285ffd83dbSDimitry Andric ConstantExprBits.IsUnsigned = false;
3295ffd83dbSDimitry Andric ConstantExprBits.BitWidth = 0;
3300b57cec5SDimitry Andric ConstantExprBits.HasCleanup = false;
3315ffd83dbSDimitry Andric ConstantExprBits.IsImmediateInvocation = IsImmediateInvocation;
3325ffd83dbSDimitry Andric
3335f757f3fSDimitry Andric if (StorageKind == ConstantResultStorageKind::APValue)
3340b57cec5SDimitry Andric ::new (getTrailingObjects<APValue>()) APValue();
3350b57cec5SDimitry Andric }
3360b57cec5SDimitry Andric
Create(const ASTContext & Context,Expr * E,ConstantResultStorageKind StorageKind,bool IsImmediateInvocation)3370b57cec5SDimitry Andric ConstantExpr *ConstantExpr::Create(const ASTContext &Context, Expr *E,
3385f757f3fSDimitry Andric ConstantResultStorageKind StorageKind,
3395ffd83dbSDimitry Andric bool IsImmediateInvocation) {
3400b57cec5SDimitry Andric assert(!isa<ConstantExpr>(E));
3410b57cec5SDimitry Andric AssertResultStorageKind(StorageKind);
3425ffd83dbSDimitry Andric
3430b57cec5SDimitry Andric unsigned Size = totalSizeToAlloc<APValue, uint64_t>(
3445f757f3fSDimitry Andric StorageKind == ConstantResultStorageKind::APValue,
3455f757f3fSDimitry Andric StorageKind == ConstantResultStorageKind::Int64);
3460b57cec5SDimitry Andric void *Mem = Context.Allocate(Size, alignof(ConstantExpr));
3475ffd83dbSDimitry Andric return new (Mem) ConstantExpr(E, StorageKind, IsImmediateInvocation);
3480b57cec5SDimitry Andric }
3490b57cec5SDimitry Andric
Create(const ASTContext & Context,Expr * E,const APValue & Result)3500b57cec5SDimitry Andric ConstantExpr *ConstantExpr::Create(const ASTContext &Context, Expr *E,
3510b57cec5SDimitry Andric const APValue &Result) {
3525f757f3fSDimitry Andric ConstantResultStorageKind StorageKind = getStorageKind(Result);
3530b57cec5SDimitry Andric ConstantExpr *Self = Create(Context, E, StorageKind);
3540b57cec5SDimitry Andric Self->SetResult(Result, Context);
3550b57cec5SDimitry Andric return Self;
3560b57cec5SDimitry Andric }
3570b57cec5SDimitry Andric
ConstantExpr(EmptyShell Empty,ConstantResultStorageKind StorageKind)3585f757f3fSDimitry Andric ConstantExpr::ConstantExpr(EmptyShell Empty,
3595f757f3fSDimitry Andric ConstantResultStorageKind StorageKind)
3600b57cec5SDimitry Andric : FullExpr(ConstantExprClass, Empty) {
3615f757f3fSDimitry Andric ConstantExprBits.ResultKind = llvm::to_underlying(StorageKind);
3625ffd83dbSDimitry Andric
3635f757f3fSDimitry Andric if (StorageKind == ConstantResultStorageKind::APValue)
3645ffd83dbSDimitry Andric ::new (getTrailingObjects<APValue>()) APValue();
3650b57cec5SDimitry Andric }
3660b57cec5SDimitry Andric
CreateEmpty(const ASTContext & Context,ConstantResultStorageKind StorageKind)3670b57cec5SDimitry Andric ConstantExpr *ConstantExpr::CreateEmpty(const ASTContext &Context,
3685f757f3fSDimitry Andric ConstantResultStorageKind StorageKind) {
3690b57cec5SDimitry Andric AssertResultStorageKind(StorageKind);
3705ffd83dbSDimitry Andric
3710b57cec5SDimitry Andric unsigned Size = totalSizeToAlloc<APValue, uint64_t>(
3725f757f3fSDimitry Andric StorageKind == ConstantResultStorageKind::APValue,
3735f757f3fSDimitry Andric StorageKind == ConstantResultStorageKind::Int64);
3740b57cec5SDimitry Andric void *Mem = Context.Allocate(Size, alignof(ConstantExpr));
3755ffd83dbSDimitry Andric return new (Mem) ConstantExpr(EmptyShell(), StorageKind);
3760b57cec5SDimitry Andric }
3770b57cec5SDimitry Andric
MoveIntoResult(APValue & Value,const ASTContext & Context)3780b57cec5SDimitry Andric void ConstantExpr::MoveIntoResult(APValue &Value, const ASTContext &Context) {
3795ffd83dbSDimitry Andric assert((unsigned)getStorageKind(Value) <= ConstantExprBits.ResultKind &&
3800b57cec5SDimitry Andric "Invalid storage for this value kind");
3810b57cec5SDimitry Andric ConstantExprBits.APValueKind = Value.getKind();
3825f757f3fSDimitry Andric switch (getResultStorageKind()) {
3835f757f3fSDimitry Andric case ConstantResultStorageKind::None:
3840b57cec5SDimitry Andric return;
3855f757f3fSDimitry Andric case ConstantResultStorageKind::Int64:
3860b57cec5SDimitry Andric Int64Result() = *Value.getInt().getRawData();
3870b57cec5SDimitry Andric ConstantExprBits.BitWidth = Value.getInt().getBitWidth();
3880b57cec5SDimitry Andric ConstantExprBits.IsUnsigned = Value.getInt().isUnsigned();
3890b57cec5SDimitry Andric return;
3905f757f3fSDimitry Andric case ConstantResultStorageKind::APValue:
3910b57cec5SDimitry Andric if (!ConstantExprBits.HasCleanup && Value.needsCleanup()) {
3920b57cec5SDimitry Andric ConstantExprBits.HasCleanup = true;
3930b57cec5SDimitry Andric Context.addDestruction(&APValueResult());
3940b57cec5SDimitry Andric }
3950b57cec5SDimitry Andric APValueResult() = std::move(Value);
3960b57cec5SDimitry Andric return;
3970b57cec5SDimitry Andric }
3980b57cec5SDimitry Andric llvm_unreachable("Invalid ResultKind Bits");
3990b57cec5SDimitry Andric }
4000b57cec5SDimitry Andric
getResultAsAPSInt() const4010b57cec5SDimitry Andric llvm::APSInt ConstantExpr::getResultAsAPSInt() const {
4025f757f3fSDimitry Andric switch (getResultStorageKind()) {
4035f757f3fSDimitry Andric case ConstantResultStorageKind::APValue:
4040b57cec5SDimitry Andric return APValueResult().getInt();
4055f757f3fSDimitry Andric case ConstantResultStorageKind::Int64:
4060b57cec5SDimitry Andric return llvm::APSInt(llvm::APInt(ConstantExprBits.BitWidth, Int64Result()),
4070b57cec5SDimitry Andric ConstantExprBits.IsUnsigned);
4080b57cec5SDimitry Andric default:
4090b57cec5SDimitry Andric llvm_unreachable("invalid Accessor");
4100b57cec5SDimitry Andric }
4110b57cec5SDimitry Andric }
4120b57cec5SDimitry Andric
getAPValueResult() const4130b57cec5SDimitry Andric APValue ConstantExpr::getAPValueResult() const {
4145ffd83dbSDimitry Andric
4155f757f3fSDimitry Andric switch (getResultStorageKind()) {
4165f757f3fSDimitry Andric case ConstantResultStorageKind::APValue:
4170b57cec5SDimitry Andric return APValueResult();
4185f757f3fSDimitry Andric case ConstantResultStorageKind::Int64:
4190b57cec5SDimitry Andric return APValue(
4200b57cec5SDimitry Andric llvm::APSInt(llvm::APInt(ConstantExprBits.BitWidth, Int64Result()),
4210b57cec5SDimitry Andric ConstantExprBits.IsUnsigned));
4225f757f3fSDimitry Andric case ConstantResultStorageKind::None:
423e8d8bef9SDimitry Andric if (ConstantExprBits.APValueKind == APValue::Indeterminate)
424e8d8bef9SDimitry Andric return APValue::IndeterminateValue();
4250b57cec5SDimitry Andric return APValue();
4260b57cec5SDimitry Andric }
4270b57cec5SDimitry Andric llvm_unreachable("invalid ResultKind");
4280b57cec5SDimitry Andric }
4290b57cec5SDimitry Andric
DeclRefExpr(const ASTContext & Ctx,ValueDecl * D,bool RefersToEnclosingVariableOrCapture,QualType T,ExprValueKind VK,SourceLocation L,const DeclarationNameLoc & LocInfo,NonOdrUseReason NOUR)4300b57cec5SDimitry Andric DeclRefExpr::DeclRefExpr(const ASTContext &Ctx, ValueDecl *D,
4310b57cec5SDimitry Andric bool RefersToEnclosingVariableOrCapture, QualType T,
4320b57cec5SDimitry Andric ExprValueKind VK, SourceLocation L,
4330b57cec5SDimitry Andric const DeclarationNameLoc &LocInfo,
4340b57cec5SDimitry Andric NonOdrUseReason NOUR)
4355ffd83dbSDimitry Andric : Expr(DeclRefExprClass, T, VK, OK_Ordinary), D(D), DNLoc(LocInfo) {
4360b57cec5SDimitry Andric DeclRefExprBits.HasQualifier = false;
4370b57cec5SDimitry Andric DeclRefExprBits.HasTemplateKWAndArgsInfo = false;
4380b57cec5SDimitry Andric DeclRefExprBits.HasFoundDecl = false;
4390b57cec5SDimitry Andric DeclRefExprBits.HadMultipleCandidates = false;
4400b57cec5SDimitry Andric DeclRefExprBits.RefersToEnclosingVariableOrCapture =
4410b57cec5SDimitry Andric RefersToEnclosingVariableOrCapture;
4425f757f3fSDimitry Andric DeclRefExprBits.CapturedByCopyInLambdaWithExplicitObjectParameter = false;
4430b57cec5SDimitry Andric DeclRefExprBits.NonOdrUseReason = NOUR;
44406c3fb27SDimitry Andric DeclRefExprBits.IsImmediateEscalating = false;
4450b57cec5SDimitry Andric DeclRefExprBits.Loc = L;
4465ffd83dbSDimitry Andric setDependence(computeDependence(this, Ctx));
4470b57cec5SDimitry Andric }
4480b57cec5SDimitry Andric
DeclRefExpr(const ASTContext & Ctx,NestedNameSpecifierLoc QualifierLoc,SourceLocation TemplateKWLoc,ValueDecl * D,bool RefersToEnclosingVariableOrCapture,const DeclarationNameInfo & NameInfo,NamedDecl * FoundD,const TemplateArgumentListInfo * TemplateArgs,QualType T,ExprValueKind VK,NonOdrUseReason NOUR)4490b57cec5SDimitry Andric DeclRefExpr::DeclRefExpr(const ASTContext &Ctx,
4500b57cec5SDimitry Andric NestedNameSpecifierLoc QualifierLoc,
4510b57cec5SDimitry Andric SourceLocation TemplateKWLoc, ValueDecl *D,
4520b57cec5SDimitry Andric bool RefersToEnclosingVariableOrCapture,
4530b57cec5SDimitry Andric const DeclarationNameInfo &NameInfo, NamedDecl *FoundD,
4540b57cec5SDimitry Andric const TemplateArgumentListInfo *TemplateArgs,
4550b57cec5SDimitry Andric QualType T, ExprValueKind VK, NonOdrUseReason NOUR)
4565ffd83dbSDimitry Andric : Expr(DeclRefExprClass, T, VK, OK_Ordinary), D(D),
4575ffd83dbSDimitry Andric DNLoc(NameInfo.getInfo()) {
4580b57cec5SDimitry Andric DeclRefExprBits.Loc = NameInfo.getLoc();
4590b57cec5SDimitry Andric DeclRefExprBits.HasQualifier = QualifierLoc ? 1 : 0;
4605ffd83dbSDimitry Andric if (QualifierLoc)
4610b57cec5SDimitry Andric new (getTrailingObjects<NestedNameSpecifierLoc>())
4620b57cec5SDimitry Andric NestedNameSpecifierLoc(QualifierLoc);
4630b57cec5SDimitry Andric DeclRefExprBits.HasFoundDecl = FoundD ? 1 : 0;
4640b57cec5SDimitry Andric if (FoundD)
4650b57cec5SDimitry Andric *getTrailingObjects<NamedDecl *>() = FoundD;
4660b57cec5SDimitry Andric DeclRefExprBits.HasTemplateKWAndArgsInfo
4670b57cec5SDimitry Andric = (TemplateArgs || TemplateKWLoc.isValid()) ? 1 : 0;
4680b57cec5SDimitry Andric DeclRefExprBits.RefersToEnclosingVariableOrCapture =
4690b57cec5SDimitry Andric RefersToEnclosingVariableOrCapture;
4705f757f3fSDimitry Andric DeclRefExprBits.CapturedByCopyInLambdaWithExplicitObjectParameter = false;
4710b57cec5SDimitry Andric DeclRefExprBits.NonOdrUseReason = NOUR;
4720b57cec5SDimitry Andric if (TemplateArgs) {
4735ffd83dbSDimitry Andric auto Deps = TemplateArgumentDependence::None;
4740b57cec5SDimitry Andric getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom(
4750b57cec5SDimitry Andric TemplateKWLoc, *TemplateArgs, getTrailingObjects<TemplateArgumentLoc>(),
4765ffd83dbSDimitry Andric Deps);
4775ffd83dbSDimitry Andric assert(!(Deps & TemplateArgumentDependence::Dependent) &&
4785ffd83dbSDimitry Andric "built a DeclRefExpr with dependent template args");
4790b57cec5SDimitry Andric } else if (TemplateKWLoc.isValid()) {
4800b57cec5SDimitry Andric getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom(
4810b57cec5SDimitry Andric TemplateKWLoc);
4820b57cec5SDimitry Andric }
48306c3fb27SDimitry Andric DeclRefExprBits.IsImmediateEscalating = false;
4840b57cec5SDimitry Andric DeclRefExprBits.HadMultipleCandidates = 0;
4855ffd83dbSDimitry Andric setDependence(computeDependence(this, Ctx));
4860b57cec5SDimitry Andric }
4870b57cec5SDimitry Andric
Create(const ASTContext & Context,NestedNameSpecifierLoc QualifierLoc,SourceLocation TemplateKWLoc,ValueDecl * D,bool RefersToEnclosingVariableOrCapture,SourceLocation NameLoc,QualType T,ExprValueKind VK,NamedDecl * FoundD,const TemplateArgumentListInfo * TemplateArgs,NonOdrUseReason NOUR)4880b57cec5SDimitry Andric DeclRefExpr *DeclRefExpr::Create(const ASTContext &Context,
4890b57cec5SDimitry Andric NestedNameSpecifierLoc QualifierLoc,
4900b57cec5SDimitry Andric SourceLocation TemplateKWLoc, ValueDecl *D,
4910b57cec5SDimitry Andric bool RefersToEnclosingVariableOrCapture,
4920b57cec5SDimitry Andric SourceLocation NameLoc, QualType T,
4930b57cec5SDimitry Andric ExprValueKind VK, NamedDecl *FoundD,
4940b57cec5SDimitry Andric const TemplateArgumentListInfo *TemplateArgs,
4950b57cec5SDimitry Andric NonOdrUseReason NOUR) {
4960b57cec5SDimitry Andric return Create(Context, QualifierLoc, TemplateKWLoc, D,
4970b57cec5SDimitry Andric RefersToEnclosingVariableOrCapture,
4980b57cec5SDimitry Andric DeclarationNameInfo(D->getDeclName(), NameLoc),
4990b57cec5SDimitry Andric T, VK, FoundD, TemplateArgs, NOUR);
5000b57cec5SDimitry Andric }
5010b57cec5SDimitry Andric
Create(const ASTContext & Context,NestedNameSpecifierLoc QualifierLoc,SourceLocation TemplateKWLoc,ValueDecl * D,bool RefersToEnclosingVariableOrCapture,const DeclarationNameInfo & NameInfo,QualType T,ExprValueKind VK,NamedDecl * FoundD,const TemplateArgumentListInfo * TemplateArgs,NonOdrUseReason NOUR)5020b57cec5SDimitry Andric DeclRefExpr *DeclRefExpr::Create(const ASTContext &Context,
5030b57cec5SDimitry Andric NestedNameSpecifierLoc QualifierLoc,
5040b57cec5SDimitry Andric SourceLocation TemplateKWLoc, ValueDecl *D,
5050b57cec5SDimitry Andric bool RefersToEnclosingVariableOrCapture,
5060b57cec5SDimitry Andric const DeclarationNameInfo &NameInfo,
5070b57cec5SDimitry Andric QualType T, ExprValueKind VK,
5080b57cec5SDimitry Andric NamedDecl *FoundD,
5090b57cec5SDimitry Andric const TemplateArgumentListInfo *TemplateArgs,
5100b57cec5SDimitry Andric NonOdrUseReason NOUR) {
5110b57cec5SDimitry Andric // Filter out cases where the found Decl is the same as the value refenenced.
5120b57cec5SDimitry Andric if (D == FoundD)
5130b57cec5SDimitry Andric FoundD = nullptr;
5140b57cec5SDimitry Andric
5150b57cec5SDimitry Andric bool HasTemplateKWAndArgsInfo = TemplateArgs || TemplateKWLoc.isValid();
5160b57cec5SDimitry Andric std::size_t Size =
5170b57cec5SDimitry Andric totalSizeToAlloc<NestedNameSpecifierLoc, NamedDecl *,
5180b57cec5SDimitry Andric ASTTemplateKWAndArgsInfo, TemplateArgumentLoc>(
5190b57cec5SDimitry Andric QualifierLoc ? 1 : 0, FoundD ? 1 : 0,
5200b57cec5SDimitry Andric HasTemplateKWAndArgsInfo ? 1 : 0,
5210b57cec5SDimitry Andric TemplateArgs ? TemplateArgs->size() : 0);
5220b57cec5SDimitry Andric
5230b57cec5SDimitry Andric void *Mem = Context.Allocate(Size, alignof(DeclRefExpr));
5240b57cec5SDimitry Andric return new (Mem) DeclRefExpr(Context, QualifierLoc, TemplateKWLoc, D,
5250b57cec5SDimitry Andric RefersToEnclosingVariableOrCapture, NameInfo,
5260b57cec5SDimitry Andric FoundD, TemplateArgs, T, VK, NOUR);
5270b57cec5SDimitry Andric }
5280b57cec5SDimitry Andric
CreateEmpty(const ASTContext & Context,bool HasQualifier,bool HasFoundDecl,bool HasTemplateKWAndArgsInfo,unsigned NumTemplateArgs)5290b57cec5SDimitry Andric DeclRefExpr *DeclRefExpr::CreateEmpty(const ASTContext &Context,
5300b57cec5SDimitry Andric bool HasQualifier,
5310b57cec5SDimitry Andric bool HasFoundDecl,
5320b57cec5SDimitry Andric bool HasTemplateKWAndArgsInfo,
5330b57cec5SDimitry Andric unsigned NumTemplateArgs) {
5340b57cec5SDimitry Andric assert(NumTemplateArgs == 0 || HasTemplateKWAndArgsInfo);
5350b57cec5SDimitry Andric std::size_t Size =
5360b57cec5SDimitry Andric totalSizeToAlloc<NestedNameSpecifierLoc, NamedDecl *,
5370b57cec5SDimitry Andric ASTTemplateKWAndArgsInfo, TemplateArgumentLoc>(
5380b57cec5SDimitry Andric HasQualifier ? 1 : 0, HasFoundDecl ? 1 : 0, HasTemplateKWAndArgsInfo,
5390b57cec5SDimitry Andric NumTemplateArgs);
5400b57cec5SDimitry Andric void *Mem = Context.Allocate(Size, alignof(DeclRefExpr));
5410b57cec5SDimitry Andric return new (Mem) DeclRefExpr(EmptyShell());
5420b57cec5SDimitry Andric }
5430b57cec5SDimitry Andric
setDecl(ValueDecl * NewD)544e8d8bef9SDimitry Andric void DeclRefExpr::setDecl(ValueDecl *NewD) {
545e8d8bef9SDimitry Andric D = NewD;
546fe6060f1SDimitry Andric if (getType()->isUndeducedType())
547fe6060f1SDimitry Andric setType(NewD->getType());
548e8d8bef9SDimitry Andric setDependence(computeDependence(this, NewD->getASTContext()));
549e8d8bef9SDimitry Andric }
550e8d8bef9SDimitry Andric
getBeginLoc() const5510b57cec5SDimitry Andric SourceLocation DeclRefExpr::getBeginLoc() const {
5520b57cec5SDimitry Andric if (hasQualifier())
5530b57cec5SDimitry Andric return getQualifierLoc().getBeginLoc();
5540b57cec5SDimitry Andric return getNameInfo().getBeginLoc();
5550b57cec5SDimitry Andric }
getEndLoc() const5560b57cec5SDimitry Andric SourceLocation DeclRefExpr::getEndLoc() const {
5570b57cec5SDimitry Andric if (hasExplicitTemplateArgs())
5580b57cec5SDimitry Andric return getRAngleLoc();
5590b57cec5SDimitry Andric return getNameInfo().getEndLoc();
5600b57cec5SDimitry Andric }
5610b57cec5SDimitry Andric
SYCLUniqueStableNameExpr(SourceLocation OpLoc,SourceLocation LParen,SourceLocation RParen,QualType ResultTy,TypeSourceInfo * TSI)562fe6060f1SDimitry Andric SYCLUniqueStableNameExpr::SYCLUniqueStableNameExpr(SourceLocation OpLoc,
563fe6060f1SDimitry Andric SourceLocation LParen,
564fe6060f1SDimitry Andric SourceLocation RParen,
565fe6060f1SDimitry Andric QualType ResultTy,
566fe6060f1SDimitry Andric TypeSourceInfo *TSI)
567fe6060f1SDimitry Andric : Expr(SYCLUniqueStableNameExprClass, ResultTy, VK_PRValue, OK_Ordinary),
568fe6060f1SDimitry Andric OpLoc(OpLoc), LParen(LParen), RParen(RParen) {
569fe6060f1SDimitry Andric setTypeSourceInfo(TSI);
570fe6060f1SDimitry Andric setDependence(computeDependence(this));
571fe6060f1SDimitry Andric }
572fe6060f1SDimitry Andric
SYCLUniqueStableNameExpr(EmptyShell Empty,QualType ResultTy)573fe6060f1SDimitry Andric SYCLUniqueStableNameExpr::SYCLUniqueStableNameExpr(EmptyShell Empty,
574fe6060f1SDimitry Andric QualType ResultTy)
575fe6060f1SDimitry Andric : Expr(SYCLUniqueStableNameExprClass, ResultTy, VK_PRValue, OK_Ordinary) {}
576fe6060f1SDimitry Andric
577fe6060f1SDimitry Andric SYCLUniqueStableNameExpr *
Create(const ASTContext & Ctx,SourceLocation OpLoc,SourceLocation LParen,SourceLocation RParen,TypeSourceInfo * TSI)578fe6060f1SDimitry Andric SYCLUniqueStableNameExpr::Create(const ASTContext &Ctx, SourceLocation OpLoc,
579fe6060f1SDimitry Andric SourceLocation LParen, SourceLocation RParen,
580fe6060f1SDimitry Andric TypeSourceInfo *TSI) {
581fe6060f1SDimitry Andric QualType ResultTy = Ctx.getPointerType(Ctx.CharTy.withConst());
582fe6060f1SDimitry Andric return new (Ctx)
583fe6060f1SDimitry Andric SYCLUniqueStableNameExpr(OpLoc, LParen, RParen, ResultTy, TSI);
584fe6060f1SDimitry Andric }
585fe6060f1SDimitry Andric
586fe6060f1SDimitry Andric SYCLUniqueStableNameExpr *
CreateEmpty(const ASTContext & Ctx)587fe6060f1SDimitry Andric SYCLUniqueStableNameExpr::CreateEmpty(const ASTContext &Ctx) {
588fe6060f1SDimitry Andric QualType ResultTy = Ctx.getPointerType(Ctx.CharTy.withConst());
589fe6060f1SDimitry Andric return new (Ctx) SYCLUniqueStableNameExpr(EmptyShell(), ResultTy);
590fe6060f1SDimitry Andric }
591fe6060f1SDimitry Andric
ComputeName(ASTContext & Context) const592fe6060f1SDimitry Andric std::string SYCLUniqueStableNameExpr::ComputeName(ASTContext &Context) const {
593fe6060f1SDimitry Andric return SYCLUniqueStableNameExpr::ComputeName(Context,
594fe6060f1SDimitry Andric getTypeSourceInfo()->getType());
595fe6060f1SDimitry Andric }
596fe6060f1SDimitry Andric
ComputeName(ASTContext & Context,QualType Ty)597fe6060f1SDimitry Andric std::string SYCLUniqueStableNameExpr::ComputeName(ASTContext &Context,
598fe6060f1SDimitry Andric QualType Ty) {
599fe6060f1SDimitry Andric auto MangleCallback = [](ASTContext &Ctx,
600bdd1243dSDimitry Andric const NamedDecl *ND) -> std::optional<unsigned> {
601349cc55cSDimitry Andric if (const auto *RD = dyn_cast<CXXRecordDecl>(ND))
602349cc55cSDimitry Andric return RD->getDeviceLambdaManglingNumber();
603bdd1243dSDimitry Andric return std::nullopt;
604fe6060f1SDimitry Andric };
605349cc55cSDimitry Andric
606fe6060f1SDimitry Andric std::unique_ptr<MangleContext> Ctx{ItaniumMangleContext::create(
607fe6060f1SDimitry Andric Context, Context.getDiagnostics(), MangleCallback)};
608fe6060f1SDimitry Andric
609fe6060f1SDimitry Andric std::string Buffer;
610fe6060f1SDimitry Andric Buffer.reserve(128);
611fe6060f1SDimitry Andric llvm::raw_string_ostream Out(Buffer);
6125f757f3fSDimitry Andric Ctx->mangleCanonicalTypeName(Ty, Out);
613fe6060f1SDimitry Andric
614fe6060f1SDimitry Andric return Out.str();
615fe6060f1SDimitry Andric }
616fe6060f1SDimitry Andric
PredefinedExpr(SourceLocation L,QualType FNTy,PredefinedIdentKind IK,bool IsTransparent,StringLiteral * SL)6175f757f3fSDimitry Andric PredefinedExpr::PredefinedExpr(SourceLocation L, QualType FNTy,
6185f757f3fSDimitry Andric PredefinedIdentKind IK, bool IsTransparent,
6195f757f3fSDimitry Andric StringLiteral *SL)
6205ffd83dbSDimitry Andric : Expr(PredefinedExprClass, FNTy, VK_LValue, OK_Ordinary) {
6215f757f3fSDimitry Andric PredefinedExprBits.Kind = llvm::to_underlying(IK);
6220b57cec5SDimitry Andric assert((getIdentKind() == IK) &&
6230b57cec5SDimitry Andric "IdentKind do not fit in PredefinedExprBitfields!");
6240b57cec5SDimitry Andric bool HasFunctionName = SL != nullptr;
6250b57cec5SDimitry Andric PredefinedExprBits.HasFunctionName = HasFunctionName;
62606c3fb27SDimitry Andric PredefinedExprBits.IsTransparent = IsTransparent;
6270b57cec5SDimitry Andric PredefinedExprBits.Loc = L;
6280b57cec5SDimitry Andric if (HasFunctionName)
6290b57cec5SDimitry Andric setFunctionName(SL);
6305ffd83dbSDimitry Andric setDependence(computeDependence(this));
6315ffd83dbSDimitry Andric }
6325ffd83dbSDimitry Andric
PredefinedExpr(EmptyShell Empty,bool HasFunctionName)6330b57cec5SDimitry Andric PredefinedExpr::PredefinedExpr(EmptyShell Empty, bool HasFunctionName)
6340b57cec5SDimitry Andric : Expr(PredefinedExprClass, Empty) {
6350b57cec5SDimitry Andric PredefinedExprBits.HasFunctionName = HasFunctionName;
6360b57cec5SDimitry Andric }
6370b57cec5SDimitry Andric
Create(const ASTContext & Ctx,SourceLocation L,QualType FNTy,PredefinedIdentKind IK,bool IsTransparent,StringLiteral * SL)6380b57cec5SDimitry Andric PredefinedExpr *PredefinedExpr::Create(const ASTContext &Ctx, SourceLocation L,
6395f757f3fSDimitry Andric QualType FNTy, PredefinedIdentKind IK,
64006c3fb27SDimitry Andric bool IsTransparent, StringLiteral *SL) {
6410b57cec5SDimitry Andric bool HasFunctionName = SL != nullptr;
642e8d8bef9SDimitry Andric void *Mem = Ctx.Allocate(totalSizeToAlloc<Stmt *>(HasFunctionName),
6430b57cec5SDimitry Andric alignof(PredefinedExpr));
64406c3fb27SDimitry Andric return new (Mem) PredefinedExpr(L, FNTy, IK, IsTransparent, SL);
6450b57cec5SDimitry Andric }
6460b57cec5SDimitry Andric
CreateEmpty(const ASTContext & Ctx,bool HasFunctionName)6470b57cec5SDimitry Andric PredefinedExpr *PredefinedExpr::CreateEmpty(const ASTContext &Ctx,
6480b57cec5SDimitry Andric bool HasFunctionName) {
649e8d8bef9SDimitry Andric void *Mem = Ctx.Allocate(totalSizeToAlloc<Stmt *>(HasFunctionName),
6500b57cec5SDimitry Andric alignof(PredefinedExpr));
6510b57cec5SDimitry Andric return new (Mem) PredefinedExpr(EmptyShell(), HasFunctionName);
6520b57cec5SDimitry Andric }
6530b57cec5SDimitry Andric
getIdentKindName(PredefinedIdentKind IK)6545f757f3fSDimitry Andric StringRef PredefinedExpr::getIdentKindName(PredefinedIdentKind IK) {
6550b57cec5SDimitry Andric switch (IK) {
6565f757f3fSDimitry Andric case PredefinedIdentKind::Func:
6570b57cec5SDimitry Andric return "__func__";
6585f757f3fSDimitry Andric case PredefinedIdentKind::Function:
6590b57cec5SDimitry Andric return "__FUNCTION__";
6605f757f3fSDimitry Andric case PredefinedIdentKind::FuncDName:
6610b57cec5SDimitry Andric return "__FUNCDNAME__";
6625f757f3fSDimitry Andric case PredefinedIdentKind::LFunction:
6630b57cec5SDimitry Andric return "L__FUNCTION__";
6645f757f3fSDimitry Andric case PredefinedIdentKind::PrettyFunction:
6650b57cec5SDimitry Andric return "__PRETTY_FUNCTION__";
6665f757f3fSDimitry Andric case PredefinedIdentKind::FuncSig:
6670b57cec5SDimitry Andric return "__FUNCSIG__";
6685f757f3fSDimitry Andric case PredefinedIdentKind::LFuncSig:
6690b57cec5SDimitry Andric return "L__FUNCSIG__";
6705f757f3fSDimitry Andric case PredefinedIdentKind::PrettyFunctionNoVirtual:
6710b57cec5SDimitry Andric break;
6720b57cec5SDimitry Andric }
6730b57cec5SDimitry Andric llvm_unreachable("Unknown ident kind for PredefinedExpr");
6740b57cec5SDimitry Andric }
6750b57cec5SDimitry Andric
6760b57cec5SDimitry Andric // FIXME: Maybe this should use DeclPrinter with a special "print predefined
6770b57cec5SDimitry Andric // expr" policy instead.
ComputeName(PredefinedIdentKind IK,const Decl * CurrentDecl,bool ForceElaboratedPrinting)6785f757f3fSDimitry Andric std::string PredefinedExpr::ComputeName(PredefinedIdentKind IK,
679*0fca6ea1SDimitry Andric const Decl *CurrentDecl,
680*0fca6ea1SDimitry Andric bool ForceElaboratedPrinting) {
6810b57cec5SDimitry Andric ASTContext &Context = CurrentDecl->getASTContext();
6820b57cec5SDimitry Andric
6835f757f3fSDimitry Andric if (IK == PredefinedIdentKind::FuncDName) {
6840b57cec5SDimitry Andric if (const NamedDecl *ND = dyn_cast<NamedDecl>(CurrentDecl)) {
6850b57cec5SDimitry Andric std::unique_ptr<MangleContext> MC;
6860b57cec5SDimitry Andric MC.reset(Context.createMangleContext());
6870b57cec5SDimitry Andric
6880b57cec5SDimitry Andric if (MC->shouldMangleDeclName(ND)) {
6890b57cec5SDimitry Andric SmallString<256> Buffer;
6900b57cec5SDimitry Andric llvm::raw_svector_ostream Out(Buffer);
6915ffd83dbSDimitry Andric GlobalDecl GD;
6920b57cec5SDimitry Andric if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(ND))
6935ffd83dbSDimitry Andric GD = GlobalDecl(CD, Ctor_Base);
6940b57cec5SDimitry Andric else if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(ND))
6955ffd83dbSDimitry Andric GD = GlobalDecl(DD, Dtor_Base);
6965ffd83dbSDimitry Andric else if (ND->hasAttr<CUDAGlobalAttr>())
6975ffd83dbSDimitry Andric GD = GlobalDecl(cast<FunctionDecl>(ND));
6980b57cec5SDimitry Andric else
6995ffd83dbSDimitry Andric GD = GlobalDecl(ND);
7005ffd83dbSDimitry Andric MC->mangleName(GD, Out);
7010b57cec5SDimitry Andric
7020b57cec5SDimitry Andric if (!Buffer.empty() && Buffer.front() == '\01')
7035ffd83dbSDimitry Andric return std::string(Buffer.substr(1));
7047a6dacacSDimitry Andric return std::string(Buffer);
705e8d8bef9SDimitry Andric }
7065ffd83dbSDimitry Andric return std::string(ND->getIdentifier()->getName());
7070b57cec5SDimitry Andric }
7080b57cec5SDimitry Andric return "";
7090b57cec5SDimitry Andric }
7100b57cec5SDimitry Andric if (isa<BlockDecl>(CurrentDecl)) {
7110b57cec5SDimitry Andric // For blocks we only emit something if it is enclosed in a function
7120b57cec5SDimitry Andric // For top-level block we'd like to include the name of variable, but we
7130b57cec5SDimitry Andric // don't have it at this point.
7140b57cec5SDimitry Andric auto DC = CurrentDecl->getDeclContext();
7150b57cec5SDimitry Andric if (DC->isFileContext())
7160b57cec5SDimitry Andric return "";
7170b57cec5SDimitry Andric
7180b57cec5SDimitry Andric SmallString<256> Buffer;
7190b57cec5SDimitry Andric llvm::raw_svector_ostream Out(Buffer);
7200b57cec5SDimitry Andric if (auto *DCBlock = dyn_cast<BlockDecl>(DC))
7210b57cec5SDimitry Andric // For nested blocks, propagate up to the parent.
7220b57cec5SDimitry Andric Out << ComputeName(IK, DCBlock);
7230b57cec5SDimitry Andric else if (auto *DCDecl = dyn_cast<Decl>(DC))
7240b57cec5SDimitry Andric Out << ComputeName(IK, DCDecl) << "_block_invoke";
7255ffd83dbSDimitry Andric return std::string(Out.str());
7260b57cec5SDimitry Andric }
7270b57cec5SDimitry Andric if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CurrentDecl)) {
728*0fca6ea1SDimitry Andric const auto &LO = Context.getLangOpts();
729*0fca6ea1SDimitry Andric bool IsFuncOrFunctionInNonMSVCCompatEnv =
730*0fca6ea1SDimitry Andric ((IK == PredefinedIdentKind::Func ||
731*0fca6ea1SDimitry Andric IK == PredefinedIdentKind ::Function) &&
732*0fca6ea1SDimitry Andric !LO.MSVCCompat);
733*0fca6ea1SDimitry Andric bool IsLFunctionInMSVCCommpatEnv =
734*0fca6ea1SDimitry Andric IK == PredefinedIdentKind::LFunction && LO.MSVCCompat;
735*0fca6ea1SDimitry Andric bool IsFuncOrFunctionOrLFunctionOrFuncDName =
736*0fca6ea1SDimitry Andric IK != PredefinedIdentKind::PrettyFunction &&
7375f757f3fSDimitry Andric IK != PredefinedIdentKind::PrettyFunctionNoVirtual &&
7385f757f3fSDimitry Andric IK != PredefinedIdentKind::FuncSig &&
739*0fca6ea1SDimitry Andric IK != PredefinedIdentKind::LFuncSig;
740*0fca6ea1SDimitry Andric if ((ForceElaboratedPrinting &&
741*0fca6ea1SDimitry Andric (IsFuncOrFunctionInNonMSVCCompatEnv || IsLFunctionInMSVCCommpatEnv)) ||
742*0fca6ea1SDimitry Andric (!ForceElaboratedPrinting && IsFuncOrFunctionOrLFunctionOrFuncDName))
7430b57cec5SDimitry Andric return FD->getNameAsString();
7440b57cec5SDimitry Andric
7450b57cec5SDimitry Andric SmallString<256> Name;
7460b57cec5SDimitry Andric llvm::raw_svector_ostream Out(Name);
7470b57cec5SDimitry Andric
7480b57cec5SDimitry Andric if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
7495f757f3fSDimitry Andric if (MD->isVirtual() && IK != PredefinedIdentKind::PrettyFunctionNoVirtual)
7500b57cec5SDimitry Andric Out << "virtual ";
7510b57cec5SDimitry Andric if (MD->isStatic())
7520b57cec5SDimitry Andric Out << "static ";
7530b57cec5SDimitry Andric }
7540b57cec5SDimitry Andric
75506c3fb27SDimitry Andric class PrettyCallbacks final : public PrintingCallbacks {
75606c3fb27SDimitry Andric public:
75706c3fb27SDimitry Andric PrettyCallbacks(const LangOptions &LO) : LO(LO) {}
75806c3fb27SDimitry Andric std::string remapPath(StringRef Path) const override {
75906c3fb27SDimitry Andric SmallString<128> p(Path);
76006c3fb27SDimitry Andric LO.remapPathPrefix(p);
76106c3fb27SDimitry Andric return std::string(p);
76206c3fb27SDimitry Andric }
76306c3fb27SDimitry Andric
76406c3fb27SDimitry Andric private:
76506c3fb27SDimitry Andric const LangOptions &LO;
76606c3fb27SDimitry Andric };
7670b57cec5SDimitry Andric PrintingPolicy Policy(Context.getLangOpts());
76806c3fb27SDimitry Andric PrettyCallbacks PrettyCB(Context.getLangOpts());
76906c3fb27SDimitry Andric Policy.Callbacks = &PrettyCB;
770*0fca6ea1SDimitry Andric if (IK == PredefinedIdentKind::Function && ForceElaboratedPrinting)
771*0fca6ea1SDimitry Andric Policy.SuppressTagKeyword = !LO.MSVCCompat;
7720b57cec5SDimitry Andric std::string Proto;
7730b57cec5SDimitry Andric llvm::raw_string_ostream POut(Proto);
7740b57cec5SDimitry Andric
7750b57cec5SDimitry Andric const FunctionDecl *Decl = FD;
7760b57cec5SDimitry Andric if (const FunctionDecl* Pattern = FD->getTemplateInstantiationPattern())
7770b57cec5SDimitry Andric Decl = Pattern;
7780b57cec5SDimitry Andric const FunctionType *AFT = Decl->getType()->getAs<FunctionType>();
7790b57cec5SDimitry Andric const FunctionProtoType *FT = nullptr;
7800b57cec5SDimitry Andric if (FD->hasWrittenPrototype())
7810b57cec5SDimitry Andric FT = dyn_cast<FunctionProtoType>(AFT);
7820b57cec5SDimitry Andric
7835f757f3fSDimitry Andric if (IK == PredefinedIdentKind::FuncSig ||
7845f757f3fSDimitry Andric IK == PredefinedIdentKind::LFuncSig) {
7850b57cec5SDimitry Andric switch (AFT->getCallConv()) {
7860b57cec5SDimitry Andric case CC_C: POut << "__cdecl "; break;
7870b57cec5SDimitry Andric case CC_X86StdCall: POut << "__stdcall "; break;
7880b57cec5SDimitry Andric case CC_X86FastCall: POut << "__fastcall "; break;
7890b57cec5SDimitry Andric case CC_X86ThisCall: POut << "__thiscall "; break;
7900b57cec5SDimitry Andric case CC_X86VectorCall: POut << "__vectorcall "; break;
7910b57cec5SDimitry Andric case CC_X86RegCall: POut << "__regcall "; break;
7920b57cec5SDimitry Andric // Only bother printing the conventions that MSVC knows about.
7930b57cec5SDimitry Andric default: break;
7940b57cec5SDimitry Andric }
7950b57cec5SDimitry Andric }
7960b57cec5SDimitry Andric
7970b57cec5SDimitry Andric FD->printQualifiedName(POut, Policy);
7980b57cec5SDimitry Andric
799*0fca6ea1SDimitry Andric if (IK == PredefinedIdentKind::Function) {
800*0fca6ea1SDimitry Andric POut.flush();
801*0fca6ea1SDimitry Andric Out << Proto;
802*0fca6ea1SDimitry Andric return std::string(Name);
803*0fca6ea1SDimitry Andric }
804*0fca6ea1SDimitry Andric
8050b57cec5SDimitry Andric POut << "(";
8060b57cec5SDimitry Andric if (FT) {
8070b57cec5SDimitry Andric for (unsigned i = 0, e = Decl->getNumParams(); i != e; ++i) {
8080b57cec5SDimitry Andric if (i) POut << ", ";
8090b57cec5SDimitry Andric POut << Decl->getParamDecl(i)->getType().stream(Policy);
8100b57cec5SDimitry Andric }
8110b57cec5SDimitry Andric
8120b57cec5SDimitry Andric if (FT->isVariadic()) {
8130b57cec5SDimitry Andric if (FD->getNumParams()) POut << ", ";
8140b57cec5SDimitry Andric POut << "...";
8155f757f3fSDimitry Andric } else if ((IK == PredefinedIdentKind::FuncSig ||
8165f757f3fSDimitry Andric IK == PredefinedIdentKind::LFuncSig ||
8170b57cec5SDimitry Andric !Context.getLangOpts().CPlusPlus) &&
8180b57cec5SDimitry Andric !Decl->getNumParams()) {
8190b57cec5SDimitry Andric POut << "void";
8200b57cec5SDimitry Andric }
8210b57cec5SDimitry Andric }
8220b57cec5SDimitry Andric POut << ")";
8230b57cec5SDimitry Andric
8240b57cec5SDimitry Andric if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
8250b57cec5SDimitry Andric assert(FT && "We must have a written prototype in this case.");
8260b57cec5SDimitry Andric if (FT->isConst())
8270b57cec5SDimitry Andric POut << " const";
8280b57cec5SDimitry Andric if (FT->isVolatile())
8290b57cec5SDimitry Andric POut << " volatile";
8300b57cec5SDimitry Andric RefQualifierKind Ref = MD->getRefQualifier();
8310b57cec5SDimitry Andric if (Ref == RQ_LValue)
8320b57cec5SDimitry Andric POut << " &";
8330b57cec5SDimitry Andric else if (Ref == RQ_RValue)
8340b57cec5SDimitry Andric POut << " &&";
8350b57cec5SDimitry Andric }
8360b57cec5SDimitry Andric
8370b57cec5SDimitry Andric typedef SmallVector<const ClassTemplateSpecializationDecl *, 8> SpecsTy;
8380b57cec5SDimitry Andric SpecsTy Specs;
8390b57cec5SDimitry Andric const DeclContext *Ctx = FD->getDeclContext();
840*0fca6ea1SDimitry Andric while (isa_and_nonnull<NamedDecl>(Ctx)) {
8410b57cec5SDimitry Andric const ClassTemplateSpecializationDecl *Spec
8420b57cec5SDimitry Andric = dyn_cast<ClassTemplateSpecializationDecl>(Ctx);
8430b57cec5SDimitry Andric if (Spec && !Spec->isExplicitSpecialization())
8440b57cec5SDimitry Andric Specs.push_back(Spec);
8450b57cec5SDimitry Andric Ctx = Ctx->getParent();
8460b57cec5SDimitry Andric }
8470b57cec5SDimitry Andric
8480b57cec5SDimitry Andric std::string TemplateParams;
8490b57cec5SDimitry Andric llvm::raw_string_ostream TOut(TemplateParams);
850349cc55cSDimitry Andric for (const ClassTemplateSpecializationDecl *D : llvm::reverse(Specs)) {
851349cc55cSDimitry Andric const TemplateParameterList *Params =
852349cc55cSDimitry Andric D->getSpecializedTemplate()->getTemplateParameters();
853349cc55cSDimitry Andric const TemplateArgumentList &Args = D->getTemplateArgs();
8540b57cec5SDimitry Andric assert(Params->size() == Args.size());
8550b57cec5SDimitry Andric for (unsigned i = 0, numParams = Params->size(); i != numParams; ++i) {
8560b57cec5SDimitry Andric StringRef Param = Params->getParam(i)->getName();
8570b57cec5SDimitry Andric if (Param.empty()) continue;
8580b57cec5SDimitry Andric TOut << Param << " = ";
859349cc55cSDimitry Andric Args.get(i).print(Policy, TOut,
860349cc55cSDimitry Andric TemplateParameterList::shouldIncludeTypeForArgument(
861349cc55cSDimitry Andric Policy, Params, i));
8620b57cec5SDimitry Andric TOut << ", ";
8630b57cec5SDimitry Andric }
8640b57cec5SDimitry Andric }
8650b57cec5SDimitry Andric
8660b57cec5SDimitry Andric FunctionTemplateSpecializationInfo *FSI
8670b57cec5SDimitry Andric = FD->getTemplateSpecializationInfo();
8680b57cec5SDimitry Andric if (FSI && !FSI->isExplicitSpecialization()) {
8690b57cec5SDimitry Andric const TemplateParameterList* Params
8700b57cec5SDimitry Andric = FSI->getTemplate()->getTemplateParameters();
8710b57cec5SDimitry Andric const TemplateArgumentList* Args = FSI->TemplateArguments;
8720b57cec5SDimitry Andric assert(Params->size() == Args->size());
8730b57cec5SDimitry Andric for (unsigned i = 0, e = Params->size(); i != e; ++i) {
8740b57cec5SDimitry Andric StringRef Param = Params->getParam(i)->getName();
8750b57cec5SDimitry Andric if (Param.empty()) continue;
8760b57cec5SDimitry Andric TOut << Param << " = ";
877fe6060f1SDimitry Andric Args->get(i).print(Policy, TOut, /*IncludeType*/ true);
8780b57cec5SDimitry Andric TOut << ", ";
8790b57cec5SDimitry Andric }
8800b57cec5SDimitry Andric }
8810b57cec5SDimitry Andric
8820b57cec5SDimitry Andric TOut.flush();
8830b57cec5SDimitry Andric if (!TemplateParams.empty()) {
8840b57cec5SDimitry Andric // remove the trailing comma and space
8850b57cec5SDimitry Andric TemplateParams.resize(TemplateParams.size() - 2);
8860b57cec5SDimitry Andric POut << " [" << TemplateParams << "]";
8870b57cec5SDimitry Andric }
8880b57cec5SDimitry Andric
8890b57cec5SDimitry Andric POut.flush();
8900b57cec5SDimitry Andric
8910b57cec5SDimitry Andric // Print "auto" for all deduced return types. This includes C++1y return
8920b57cec5SDimitry Andric // type deduction and lambdas. For trailing return types resolve the
8930b57cec5SDimitry Andric // decltype expression. Otherwise print the real type when this is
8940b57cec5SDimitry Andric // not a constructor or destructor.
8950b57cec5SDimitry Andric if (isa<CXXMethodDecl>(FD) &&
8960b57cec5SDimitry Andric cast<CXXMethodDecl>(FD)->getParent()->isLambda())
8970b57cec5SDimitry Andric Proto = "auto " + Proto;
8980b57cec5SDimitry Andric else if (FT && FT->getReturnType()->getAs<DecltypeType>())
8990b57cec5SDimitry Andric FT->getReturnType()
9000b57cec5SDimitry Andric ->getAs<DecltypeType>()
9010b57cec5SDimitry Andric ->getUnderlyingType()
9020b57cec5SDimitry Andric .getAsStringInternal(Proto, Policy);
9030b57cec5SDimitry Andric else if (!isa<CXXConstructorDecl>(FD) && !isa<CXXDestructorDecl>(FD))
9040b57cec5SDimitry Andric AFT->getReturnType().getAsStringInternal(Proto, Policy);
9050b57cec5SDimitry Andric
9060b57cec5SDimitry Andric Out << Proto;
9070b57cec5SDimitry Andric
9085ffd83dbSDimitry Andric return std::string(Name);
9090b57cec5SDimitry Andric }
9100b57cec5SDimitry Andric if (const CapturedDecl *CD = dyn_cast<CapturedDecl>(CurrentDecl)) {
9110b57cec5SDimitry Andric for (const DeclContext *DC = CD->getParent(); DC; DC = DC->getParent())
9120b57cec5SDimitry Andric // Skip to its enclosing function or method, but not its enclosing
9130b57cec5SDimitry Andric // CapturedDecl.
9140b57cec5SDimitry Andric if (DC->isFunctionOrMethod() && (DC->getDeclKind() != Decl::Captured)) {
9150b57cec5SDimitry Andric const Decl *D = Decl::castFromDeclContext(DC);
9160b57cec5SDimitry Andric return ComputeName(IK, D);
9170b57cec5SDimitry Andric }
9180b57cec5SDimitry Andric llvm_unreachable("CapturedDecl not inside a function or method");
9190b57cec5SDimitry Andric }
9200b57cec5SDimitry Andric if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(CurrentDecl)) {
9210b57cec5SDimitry Andric SmallString<256> Name;
9220b57cec5SDimitry Andric llvm::raw_svector_ostream Out(Name);
9230b57cec5SDimitry Andric Out << (MD->isInstanceMethod() ? '-' : '+');
9240b57cec5SDimitry Andric Out << '[';
9250b57cec5SDimitry Andric
9260b57cec5SDimitry Andric // For incorrect code, there might not be an ObjCInterfaceDecl. Do
9270b57cec5SDimitry Andric // a null check to avoid a crash.
9280b57cec5SDimitry Andric if (const ObjCInterfaceDecl *ID = MD->getClassInterface())
9290b57cec5SDimitry Andric Out << *ID;
9300b57cec5SDimitry Andric
9310b57cec5SDimitry Andric if (const ObjCCategoryImplDecl *CID =
9320b57cec5SDimitry Andric dyn_cast<ObjCCategoryImplDecl>(MD->getDeclContext()))
9330b57cec5SDimitry Andric Out << '(' << *CID << ')';
9340b57cec5SDimitry Andric
9350b57cec5SDimitry Andric Out << ' ';
9360b57cec5SDimitry Andric MD->getSelector().print(Out);
9370b57cec5SDimitry Andric Out << ']';
9380b57cec5SDimitry Andric
9395ffd83dbSDimitry Andric return std::string(Name);
9400b57cec5SDimitry Andric }
9415f757f3fSDimitry Andric if (isa<TranslationUnitDecl>(CurrentDecl) &&
9425f757f3fSDimitry Andric IK == PredefinedIdentKind::PrettyFunction) {
9430b57cec5SDimitry Andric // __PRETTY_FUNCTION__ -> "top level", the others produce an empty string.
9440b57cec5SDimitry Andric return "top level";
9450b57cec5SDimitry Andric }
9460b57cec5SDimitry Andric return "";
9470b57cec5SDimitry Andric }
9480b57cec5SDimitry Andric
setIntValue(const ASTContext & C,const llvm::APInt & Val)9490b57cec5SDimitry Andric void APNumericStorage::setIntValue(const ASTContext &C,
9500b57cec5SDimitry Andric const llvm::APInt &Val) {
9510b57cec5SDimitry Andric if (hasAllocation())
9520b57cec5SDimitry Andric C.Deallocate(pVal);
9530b57cec5SDimitry Andric
9540b57cec5SDimitry Andric BitWidth = Val.getBitWidth();
9550b57cec5SDimitry Andric unsigned NumWords = Val.getNumWords();
9560b57cec5SDimitry Andric const uint64_t* Words = Val.getRawData();
9570b57cec5SDimitry Andric if (NumWords > 1) {
9580b57cec5SDimitry Andric pVal = new (C) uint64_t[NumWords];
9590b57cec5SDimitry Andric std::copy(Words, Words + NumWords, pVal);
9600b57cec5SDimitry Andric } else if (NumWords == 1)
9610b57cec5SDimitry Andric VAL = Words[0];
9620b57cec5SDimitry Andric else
9630b57cec5SDimitry Andric VAL = 0;
9640b57cec5SDimitry Andric }
9650b57cec5SDimitry Andric
IntegerLiteral(const ASTContext & C,const llvm::APInt & V,QualType type,SourceLocation l)9660b57cec5SDimitry Andric IntegerLiteral::IntegerLiteral(const ASTContext &C, const llvm::APInt &V,
9670b57cec5SDimitry Andric QualType type, SourceLocation l)
968fe6060f1SDimitry Andric : Expr(IntegerLiteralClass, type, VK_PRValue, OK_Ordinary), Loc(l) {
9690b57cec5SDimitry Andric assert(type->isIntegerType() && "Illegal type in IntegerLiteral");
9700b57cec5SDimitry Andric assert(V.getBitWidth() == C.getIntWidth(type) &&
9710b57cec5SDimitry Andric "Integer type is not the correct size for constant.");
9720b57cec5SDimitry Andric setValue(C, V);
9735ffd83dbSDimitry Andric setDependence(ExprDependence::None);
9740b57cec5SDimitry Andric }
9750b57cec5SDimitry Andric
9760b57cec5SDimitry Andric IntegerLiteral *
Create(const ASTContext & C,const llvm::APInt & V,QualType type,SourceLocation l)9770b57cec5SDimitry Andric IntegerLiteral::Create(const ASTContext &C, const llvm::APInt &V,
9780b57cec5SDimitry Andric QualType type, SourceLocation l) {
9790b57cec5SDimitry Andric return new (C) IntegerLiteral(C, V, type, l);
9800b57cec5SDimitry Andric }
9810b57cec5SDimitry Andric
9820b57cec5SDimitry Andric IntegerLiteral *
Create(const ASTContext & C,EmptyShell Empty)9830b57cec5SDimitry Andric IntegerLiteral::Create(const ASTContext &C, EmptyShell Empty) {
9840b57cec5SDimitry Andric return new (C) IntegerLiteral(Empty);
9850b57cec5SDimitry Andric }
9860b57cec5SDimitry Andric
FixedPointLiteral(const ASTContext & C,const llvm::APInt & V,QualType type,SourceLocation l,unsigned Scale)9870b57cec5SDimitry Andric FixedPointLiteral::FixedPointLiteral(const ASTContext &C, const llvm::APInt &V,
9880b57cec5SDimitry Andric QualType type, SourceLocation l,
9890b57cec5SDimitry Andric unsigned Scale)
990fe6060f1SDimitry Andric : Expr(FixedPointLiteralClass, type, VK_PRValue, OK_Ordinary), Loc(l),
9915ffd83dbSDimitry Andric Scale(Scale) {
9920b57cec5SDimitry Andric assert(type->isFixedPointType() && "Illegal type in FixedPointLiteral");
9930b57cec5SDimitry Andric assert(V.getBitWidth() == C.getTypeInfo(type).Width &&
9940b57cec5SDimitry Andric "Fixed point type is not the correct size for constant.");
9950b57cec5SDimitry Andric setValue(C, V);
9965ffd83dbSDimitry Andric setDependence(ExprDependence::None);
9970b57cec5SDimitry Andric }
9980b57cec5SDimitry Andric
CreateFromRawInt(const ASTContext & C,const llvm::APInt & V,QualType type,SourceLocation l,unsigned Scale)9990b57cec5SDimitry Andric FixedPointLiteral *FixedPointLiteral::CreateFromRawInt(const ASTContext &C,
10000b57cec5SDimitry Andric const llvm::APInt &V,
10010b57cec5SDimitry Andric QualType type,
10020b57cec5SDimitry Andric SourceLocation l,
10030b57cec5SDimitry Andric unsigned Scale) {
10040b57cec5SDimitry Andric return new (C) FixedPointLiteral(C, V, type, l, Scale);
10050b57cec5SDimitry Andric }
10060b57cec5SDimitry Andric
Create(const ASTContext & C,EmptyShell Empty)10075ffd83dbSDimitry Andric FixedPointLiteral *FixedPointLiteral::Create(const ASTContext &C,
10085ffd83dbSDimitry Andric EmptyShell Empty) {
10095ffd83dbSDimitry Andric return new (C) FixedPointLiteral(Empty);
10105ffd83dbSDimitry Andric }
10115ffd83dbSDimitry Andric
getValueAsString(unsigned Radix) const10120b57cec5SDimitry Andric std::string FixedPointLiteral::getValueAsString(unsigned Radix) const {
10130b57cec5SDimitry Andric // Currently the longest decimal number that can be printed is the max for an
10140b57cec5SDimitry Andric // unsigned long _Accum: 4294967295.99999999976716935634613037109375
10150b57cec5SDimitry Andric // which is 43 characters.
10160b57cec5SDimitry Andric SmallString<64> S;
10170b57cec5SDimitry Andric FixedPointValueToString(
10180b57cec5SDimitry Andric S, llvm::APSInt::getUnsigned(getValue().getZExtValue()), Scale);
10197a6dacacSDimitry Andric return std::string(S);
10200b57cec5SDimitry Andric }
10210b57cec5SDimitry Andric
print(unsigned Val,CharacterLiteralKind Kind,raw_ostream & OS)10225f757f3fSDimitry Andric void CharacterLiteral::print(unsigned Val, CharacterLiteralKind Kind,
1023fe6060f1SDimitry Andric raw_ostream &OS) {
1024fe6060f1SDimitry Andric switch (Kind) {
10255f757f3fSDimitry Andric case CharacterLiteralKind::Ascii:
1026fe6060f1SDimitry Andric break; // no prefix.
10275f757f3fSDimitry Andric case CharacterLiteralKind::Wide:
1028fe6060f1SDimitry Andric OS << 'L';
1029fe6060f1SDimitry Andric break;
10305f757f3fSDimitry Andric case CharacterLiteralKind::UTF8:
1031fe6060f1SDimitry Andric OS << "u8";
1032fe6060f1SDimitry Andric break;
10335f757f3fSDimitry Andric case CharacterLiteralKind::UTF16:
1034fe6060f1SDimitry Andric OS << 'u';
1035fe6060f1SDimitry Andric break;
10365f757f3fSDimitry Andric case CharacterLiteralKind::UTF32:
1037fe6060f1SDimitry Andric OS << 'U';
1038fe6060f1SDimitry Andric break;
1039fe6060f1SDimitry Andric }
1040fe6060f1SDimitry Andric
104181ad6265SDimitry Andric StringRef Escaped = escapeCStyle<EscapeChar::Single>(Val);
104281ad6265SDimitry Andric if (!Escaped.empty()) {
104381ad6265SDimitry Andric OS << "'" << Escaped << "'";
104481ad6265SDimitry Andric } else {
1045fe6060f1SDimitry Andric // A character literal might be sign-extended, which
1046fe6060f1SDimitry Andric // would result in an invalid \U escape sequence.
1047fe6060f1SDimitry Andric // FIXME: multicharacter literals such as '\xFF\xFF\xFF\xFF'
1048fe6060f1SDimitry Andric // are not correctly handled.
10495f757f3fSDimitry Andric if ((Val & ~0xFFu) == ~0xFFu && Kind == CharacterLiteralKind::Ascii)
1050fe6060f1SDimitry Andric Val &= 0xFFu;
1051fe6060f1SDimitry Andric if (Val < 256 && isPrintable((unsigned char)Val))
1052fe6060f1SDimitry Andric OS << "'" << (char)Val << "'";
1053fe6060f1SDimitry Andric else if (Val < 256)
1054fe6060f1SDimitry Andric OS << "'\\x" << llvm::format("%02x", Val) << "'";
1055fe6060f1SDimitry Andric else if (Val <= 0xFFFF)
1056fe6060f1SDimitry Andric OS << "'\\u" << llvm::format("%04x", Val) << "'";
1057fe6060f1SDimitry Andric else
1058fe6060f1SDimitry Andric OS << "'\\U" << llvm::format("%08x", Val) << "'";
1059fe6060f1SDimitry Andric }
1060fe6060f1SDimitry Andric }
1061fe6060f1SDimitry Andric
FloatingLiteral(const ASTContext & C,const llvm::APFloat & V,bool isexact,QualType Type,SourceLocation L)10620b57cec5SDimitry Andric FloatingLiteral::FloatingLiteral(const ASTContext &C, const llvm::APFloat &V,
10630b57cec5SDimitry Andric bool isexact, QualType Type, SourceLocation L)
1064fe6060f1SDimitry Andric : Expr(FloatingLiteralClass, Type, VK_PRValue, OK_Ordinary), Loc(L) {
10650b57cec5SDimitry Andric setSemantics(V.getSemantics());
10660b57cec5SDimitry Andric FloatingLiteralBits.IsExact = isexact;
10670b57cec5SDimitry Andric setValue(C, V);
10685ffd83dbSDimitry Andric setDependence(ExprDependence::None);
10690b57cec5SDimitry Andric }
10700b57cec5SDimitry Andric
FloatingLiteral(const ASTContext & C,EmptyShell Empty)10710b57cec5SDimitry Andric FloatingLiteral::FloatingLiteral(const ASTContext &C, EmptyShell Empty)
10720b57cec5SDimitry Andric : Expr(FloatingLiteralClass, Empty) {
10730b57cec5SDimitry Andric setRawSemantics(llvm::APFloatBase::S_IEEEhalf);
10740b57cec5SDimitry Andric FloatingLiteralBits.IsExact = false;
10750b57cec5SDimitry Andric }
10760b57cec5SDimitry Andric
10770b57cec5SDimitry Andric FloatingLiteral *
Create(const ASTContext & C,const llvm::APFloat & V,bool isexact,QualType Type,SourceLocation L)10780b57cec5SDimitry Andric FloatingLiteral::Create(const ASTContext &C, const llvm::APFloat &V,
10790b57cec5SDimitry Andric bool isexact, QualType Type, SourceLocation L) {
10800b57cec5SDimitry Andric return new (C) FloatingLiteral(C, V, isexact, Type, L);
10810b57cec5SDimitry Andric }
10820b57cec5SDimitry Andric
10830b57cec5SDimitry Andric FloatingLiteral *
Create(const ASTContext & C,EmptyShell Empty)10840b57cec5SDimitry Andric FloatingLiteral::Create(const ASTContext &C, EmptyShell Empty) {
10850b57cec5SDimitry Andric return new (C) FloatingLiteral(C, Empty);
10860b57cec5SDimitry Andric }
10870b57cec5SDimitry Andric
10880b57cec5SDimitry Andric /// getValueAsApproximateDouble - This returns the value as an inaccurate
10890b57cec5SDimitry Andric /// double. Note that this may cause loss of precision, but is useful for
10900b57cec5SDimitry Andric /// debugging dumps, etc.
getValueAsApproximateDouble() const10910b57cec5SDimitry Andric double FloatingLiteral::getValueAsApproximateDouble() const {
10920b57cec5SDimitry Andric llvm::APFloat V = getValue();
10930b57cec5SDimitry Andric bool ignored;
10940b57cec5SDimitry Andric V.convert(llvm::APFloat::IEEEdouble(), llvm::APFloat::rmNearestTiesToEven,
10950b57cec5SDimitry Andric &ignored);
10960b57cec5SDimitry Andric return V.convertToDouble();
10970b57cec5SDimitry Andric }
10980b57cec5SDimitry Andric
mapCharByteWidth(TargetInfo const & Target,StringLiteralKind SK)10990b57cec5SDimitry Andric unsigned StringLiteral::mapCharByteWidth(TargetInfo const &Target,
11005f757f3fSDimitry Andric StringLiteralKind SK) {
11010b57cec5SDimitry Andric unsigned CharByteWidth = 0;
11020b57cec5SDimitry Andric switch (SK) {
11035f757f3fSDimitry Andric case StringLiteralKind::Ordinary:
11045f757f3fSDimitry Andric case StringLiteralKind::UTF8:
11050b57cec5SDimitry Andric CharByteWidth = Target.getCharWidth();
11060b57cec5SDimitry Andric break;
11075f757f3fSDimitry Andric case StringLiteralKind::Wide:
11080b57cec5SDimitry Andric CharByteWidth = Target.getWCharWidth();
11090b57cec5SDimitry Andric break;
11105f757f3fSDimitry Andric case StringLiteralKind::UTF16:
11110b57cec5SDimitry Andric CharByteWidth = Target.getChar16Width();
11120b57cec5SDimitry Andric break;
11135f757f3fSDimitry Andric case StringLiteralKind::UTF32:
11140b57cec5SDimitry Andric CharByteWidth = Target.getChar32Width();
11150b57cec5SDimitry Andric break;
11165f757f3fSDimitry Andric case StringLiteralKind::Unevaluated:
111706c3fb27SDimitry Andric return sizeof(char); // Host;
11180b57cec5SDimitry Andric }
11190b57cec5SDimitry Andric assert((CharByteWidth & 7) == 0 && "Assumes character size is byte multiple");
11200b57cec5SDimitry Andric CharByteWidth /= 8;
11210b57cec5SDimitry Andric assert((CharByteWidth == 1 || CharByteWidth == 2 || CharByteWidth == 4) &&
11220b57cec5SDimitry Andric "The only supported character byte widths are 1,2 and 4!");
11230b57cec5SDimitry Andric return CharByteWidth;
11240b57cec5SDimitry Andric }
11250b57cec5SDimitry Andric
StringLiteral(const ASTContext & Ctx,StringRef Str,StringLiteralKind Kind,bool Pascal,QualType Ty,const SourceLocation * Loc,unsigned NumConcatenated)11260b57cec5SDimitry Andric StringLiteral::StringLiteral(const ASTContext &Ctx, StringRef Str,
11275f757f3fSDimitry Andric StringLiteralKind Kind, bool Pascal, QualType Ty,
11280b57cec5SDimitry Andric const SourceLocation *Loc,
11290b57cec5SDimitry Andric unsigned NumConcatenated)
11305ffd83dbSDimitry Andric : Expr(StringLiteralClass, Ty, VK_LValue, OK_Ordinary) {
113106c3fb27SDimitry Andric
113206c3fb27SDimitry Andric unsigned Length = Str.size();
113306c3fb27SDimitry Andric
11345f757f3fSDimitry Andric StringLiteralBits.Kind = llvm::to_underlying(Kind);
113506c3fb27SDimitry Andric StringLiteralBits.NumConcatenated = NumConcatenated;
113606c3fb27SDimitry Andric
11375f757f3fSDimitry Andric if (Kind != StringLiteralKind::Unevaluated) {
11380b57cec5SDimitry Andric assert(Ctx.getAsConstantArrayType(Ty) &&
11390b57cec5SDimitry Andric "StringLiteral must be of constant array type!");
11400b57cec5SDimitry Andric unsigned CharByteWidth = mapCharByteWidth(Ctx.getTargetInfo(), Kind);
11410b57cec5SDimitry Andric unsigned ByteLength = Str.size();
11420b57cec5SDimitry Andric assert((ByteLength % CharByteWidth == 0) &&
11430b57cec5SDimitry Andric "The size of the data must be a multiple of CharByteWidth!");
11440b57cec5SDimitry Andric
11450b57cec5SDimitry Andric // Avoid the expensive division. The compiler should be able to figure it
11460b57cec5SDimitry Andric // out by itself. However as of clang 7, even with the appropriate
11470b57cec5SDimitry Andric // llvm_unreachable added just here, it is not able to do so.
11480b57cec5SDimitry Andric switch (CharByteWidth) {
11490b57cec5SDimitry Andric case 1:
11500b57cec5SDimitry Andric Length = ByteLength;
11510b57cec5SDimitry Andric break;
11520b57cec5SDimitry Andric case 2:
11530b57cec5SDimitry Andric Length = ByteLength / 2;
11540b57cec5SDimitry Andric break;
11550b57cec5SDimitry Andric case 4:
11560b57cec5SDimitry Andric Length = ByteLength / 4;
11570b57cec5SDimitry Andric break;
11580b57cec5SDimitry Andric default:
11590b57cec5SDimitry Andric llvm_unreachable("Unsupported character width!");
11600b57cec5SDimitry Andric }
11610b57cec5SDimitry Andric
11620b57cec5SDimitry Andric StringLiteralBits.CharByteWidth = CharByteWidth;
11630b57cec5SDimitry Andric StringLiteralBits.IsPascal = Pascal;
116406c3fb27SDimitry Andric } else {
116506c3fb27SDimitry Andric assert(!Pascal && "Can't make an unevaluated Pascal string");
116606c3fb27SDimitry Andric StringLiteralBits.CharByteWidth = 1;
116706c3fb27SDimitry Andric StringLiteralBits.IsPascal = false;
116806c3fb27SDimitry Andric }
116906c3fb27SDimitry Andric
11700b57cec5SDimitry Andric *getTrailingObjects<unsigned>() = Length;
11710b57cec5SDimitry Andric
11720b57cec5SDimitry Andric // Initialize the trailing array of SourceLocation.
11730b57cec5SDimitry Andric // This is safe since SourceLocation is POD-like.
11740b57cec5SDimitry Andric std::memcpy(getTrailingObjects<SourceLocation>(), Loc,
11750b57cec5SDimitry Andric NumConcatenated * sizeof(SourceLocation));
11760b57cec5SDimitry Andric
11770b57cec5SDimitry Andric // Initialize the trailing array of char holding the string data.
117806c3fb27SDimitry Andric std::memcpy(getTrailingObjects<char>(), Str.data(), Str.size());
11795ffd83dbSDimitry Andric
11805ffd83dbSDimitry Andric setDependence(ExprDependence::None);
11810b57cec5SDimitry Andric }
11820b57cec5SDimitry Andric
StringLiteral(EmptyShell Empty,unsigned NumConcatenated,unsigned Length,unsigned CharByteWidth)11830b57cec5SDimitry Andric StringLiteral::StringLiteral(EmptyShell Empty, unsigned NumConcatenated,
11840b57cec5SDimitry Andric unsigned Length, unsigned CharByteWidth)
11850b57cec5SDimitry Andric : Expr(StringLiteralClass, Empty) {
11860b57cec5SDimitry Andric StringLiteralBits.CharByteWidth = CharByteWidth;
11870b57cec5SDimitry Andric StringLiteralBits.NumConcatenated = NumConcatenated;
11880b57cec5SDimitry Andric *getTrailingObjects<unsigned>() = Length;
11890b57cec5SDimitry Andric }
11900b57cec5SDimitry Andric
Create(const ASTContext & Ctx,StringRef Str,StringLiteralKind Kind,bool Pascal,QualType Ty,const SourceLocation * Loc,unsigned NumConcatenated)11910b57cec5SDimitry Andric StringLiteral *StringLiteral::Create(const ASTContext &Ctx, StringRef Str,
11925f757f3fSDimitry Andric StringLiteralKind Kind, bool Pascal,
11935f757f3fSDimitry Andric QualType Ty, const SourceLocation *Loc,
11940b57cec5SDimitry Andric unsigned NumConcatenated) {
11950b57cec5SDimitry Andric void *Mem = Ctx.Allocate(totalSizeToAlloc<unsigned, SourceLocation, char>(
11960b57cec5SDimitry Andric 1, NumConcatenated, Str.size()),
11970b57cec5SDimitry Andric alignof(StringLiteral));
11980b57cec5SDimitry Andric return new (Mem)
11990b57cec5SDimitry Andric StringLiteral(Ctx, Str, Kind, Pascal, Ty, Loc, NumConcatenated);
12000b57cec5SDimitry Andric }
12010b57cec5SDimitry Andric
CreateEmpty(const ASTContext & Ctx,unsigned NumConcatenated,unsigned Length,unsigned CharByteWidth)12020b57cec5SDimitry Andric StringLiteral *StringLiteral::CreateEmpty(const ASTContext &Ctx,
12030b57cec5SDimitry Andric unsigned NumConcatenated,
12040b57cec5SDimitry Andric unsigned Length,
12050b57cec5SDimitry Andric unsigned CharByteWidth) {
12060b57cec5SDimitry Andric void *Mem = Ctx.Allocate(totalSizeToAlloc<unsigned, SourceLocation, char>(
12070b57cec5SDimitry Andric 1, NumConcatenated, Length * CharByteWidth),
12080b57cec5SDimitry Andric alignof(StringLiteral));
12090b57cec5SDimitry Andric return new (Mem)
12100b57cec5SDimitry Andric StringLiteral(EmptyShell(), NumConcatenated, Length, CharByteWidth);
12110b57cec5SDimitry Andric }
12120b57cec5SDimitry Andric
outputString(raw_ostream & OS) const12130b57cec5SDimitry Andric void StringLiteral::outputString(raw_ostream &OS) const {
12140b57cec5SDimitry Andric switch (getKind()) {
12155f757f3fSDimitry Andric case StringLiteralKind::Unevaluated:
12165f757f3fSDimitry Andric case StringLiteralKind::Ordinary:
121781ad6265SDimitry Andric break; // no prefix.
12185f757f3fSDimitry Andric case StringLiteralKind::Wide:
12195f757f3fSDimitry Andric OS << 'L';
12205f757f3fSDimitry Andric break;
12215f757f3fSDimitry Andric case StringLiteralKind::UTF8:
12225f757f3fSDimitry Andric OS << "u8";
12235f757f3fSDimitry Andric break;
12245f757f3fSDimitry Andric case StringLiteralKind::UTF16:
12255f757f3fSDimitry Andric OS << 'u';
12265f757f3fSDimitry Andric break;
12275f757f3fSDimitry Andric case StringLiteralKind::UTF32:
12285f757f3fSDimitry Andric OS << 'U';
12295f757f3fSDimitry Andric break;
12300b57cec5SDimitry Andric }
12310b57cec5SDimitry Andric OS << '"';
12320b57cec5SDimitry Andric static const char Hex[] = "0123456789ABCDEF";
12330b57cec5SDimitry Andric
12340b57cec5SDimitry Andric unsigned LastSlashX = getLength();
12350b57cec5SDimitry Andric for (unsigned I = 0, N = getLength(); I != N; ++I) {
123681ad6265SDimitry Andric uint32_t Char = getCodeUnit(I);
123781ad6265SDimitry Andric StringRef Escaped = escapeCStyle<EscapeChar::Double>(Char);
123881ad6265SDimitry Andric if (Escaped.empty()) {
12390b57cec5SDimitry Andric // FIXME: Convert UTF-8 back to codepoints before rendering.
12400b57cec5SDimitry Andric
12410b57cec5SDimitry Andric // Convert UTF-16 surrogate pairs back to codepoints before rendering.
12420b57cec5SDimitry Andric // Leave invalid surrogates alone; we'll use \x for those.
12435f757f3fSDimitry Andric if (getKind() == StringLiteralKind::UTF16 && I != N - 1 &&
12445f757f3fSDimitry Andric Char >= 0xd800 && Char <= 0xdbff) {
12450b57cec5SDimitry Andric uint32_t Trail = getCodeUnit(I + 1);
12460b57cec5SDimitry Andric if (Trail >= 0xdc00 && Trail <= 0xdfff) {
12470b57cec5SDimitry Andric Char = 0x10000 + ((Char - 0xd800) << 10) + (Trail - 0xdc00);
12480b57cec5SDimitry Andric ++I;
12490b57cec5SDimitry Andric }
12500b57cec5SDimitry Andric }
12510b57cec5SDimitry Andric
12520b57cec5SDimitry Andric if (Char > 0xff) {
12530b57cec5SDimitry Andric // If this is a wide string, output characters over 0xff using \x
12540b57cec5SDimitry Andric // escapes. Otherwise, this is a UTF-16 or UTF-32 string, and Char is a
12550b57cec5SDimitry Andric // codepoint: use \x escapes for invalid codepoints.
12565f757f3fSDimitry Andric if (getKind() == StringLiteralKind::Wide ||
12570b57cec5SDimitry Andric (Char >= 0xd800 && Char <= 0xdfff) || Char >= 0x110000) {
12580b57cec5SDimitry Andric // FIXME: Is this the best way to print wchar_t?
12590b57cec5SDimitry Andric OS << "\\x";
12600b57cec5SDimitry Andric int Shift = 28;
12610b57cec5SDimitry Andric while ((Char >> Shift) == 0)
12620b57cec5SDimitry Andric Shift -= 4;
12630b57cec5SDimitry Andric for (/**/; Shift >= 0; Shift -= 4)
12640b57cec5SDimitry Andric OS << Hex[(Char >> Shift) & 15];
12650b57cec5SDimitry Andric LastSlashX = I;
126681ad6265SDimitry Andric continue;
12670b57cec5SDimitry Andric }
12680b57cec5SDimitry Andric
12690b57cec5SDimitry Andric if (Char > 0xffff)
12700b57cec5SDimitry Andric OS << "\\U00"
12710b57cec5SDimitry Andric << Hex[(Char >> 20) & 15]
12720b57cec5SDimitry Andric << Hex[(Char >> 16) & 15];
12730b57cec5SDimitry Andric else
12740b57cec5SDimitry Andric OS << "\\u";
12750b57cec5SDimitry Andric OS << Hex[(Char >> 12) & 15]
12760b57cec5SDimitry Andric << Hex[(Char >> 8) & 15]
12770b57cec5SDimitry Andric << Hex[(Char >> 4) & 15]
12780b57cec5SDimitry Andric << Hex[(Char >> 0) & 15];
127981ad6265SDimitry Andric continue;
12800b57cec5SDimitry Andric }
12810b57cec5SDimitry Andric
12820b57cec5SDimitry Andric // If we used \x... for the previous character, and this character is a
12830b57cec5SDimitry Andric // hexadecimal digit, prevent it being slurped as part of the \x.
12840b57cec5SDimitry Andric if (LastSlashX + 1 == I) {
12850b57cec5SDimitry Andric switch (Char) {
12860b57cec5SDimitry Andric case '0': case '1': case '2': case '3': case '4':
12870b57cec5SDimitry Andric case '5': case '6': case '7': case '8': case '9':
12880b57cec5SDimitry Andric case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
12890b57cec5SDimitry Andric case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
12900b57cec5SDimitry Andric OS << "\"\"";
12910b57cec5SDimitry Andric }
12920b57cec5SDimitry Andric }
12930b57cec5SDimitry Andric
12940b57cec5SDimitry Andric assert(Char <= 0xff &&
12950b57cec5SDimitry Andric "Characters above 0xff should already have been handled.");
12960b57cec5SDimitry Andric
12970b57cec5SDimitry Andric if (isPrintable(Char))
12980b57cec5SDimitry Andric OS << (char)Char;
12990b57cec5SDimitry Andric else // Output anything hard as an octal escape.
13000b57cec5SDimitry Andric OS << '\\'
13010b57cec5SDimitry Andric << (char)('0' + ((Char >> 6) & 7))
13020b57cec5SDimitry Andric << (char)('0' + ((Char >> 3) & 7))
13030b57cec5SDimitry Andric << (char)('0' + ((Char >> 0) & 7));
130481ad6265SDimitry Andric } else {
13050b57cec5SDimitry Andric // Handle some common non-printable cases to make dumps prettier.
130681ad6265SDimitry Andric OS << Escaped;
13070b57cec5SDimitry Andric }
13080b57cec5SDimitry Andric }
13090b57cec5SDimitry Andric OS << '"';
13100b57cec5SDimitry Andric }
13110b57cec5SDimitry Andric
13120b57cec5SDimitry Andric /// getLocationOfByte - Return a source location that points to the specified
13130b57cec5SDimitry Andric /// byte of this string literal.
13140b57cec5SDimitry Andric ///
13150b57cec5SDimitry Andric /// Strings are amazingly complex. They can be formed from multiple tokens and
13160b57cec5SDimitry Andric /// can have escape sequences in them in addition to the usual trigraph and
13170b57cec5SDimitry Andric /// escaped newline business. This routine handles this complexity.
13180b57cec5SDimitry Andric ///
13190b57cec5SDimitry Andric /// The *StartToken sets the first token to be searched in this function and
13200b57cec5SDimitry Andric /// the *StartTokenByteOffset is the byte offset of the first token. Before
13210b57cec5SDimitry Andric /// returning, it updates the *StartToken to the TokNo of the token being found
13220b57cec5SDimitry Andric /// and sets *StartTokenByteOffset to the byte offset of the token in the
13230b57cec5SDimitry Andric /// string.
13240b57cec5SDimitry Andric /// Using these two parameters can reduce the time complexity from O(n^2) to
13250b57cec5SDimitry Andric /// O(n) if one wants to get the location of byte for all the tokens in a
13260b57cec5SDimitry Andric /// string.
13270b57cec5SDimitry Andric ///
13280b57cec5SDimitry Andric SourceLocation
getLocationOfByte(unsigned ByteNo,const SourceManager & SM,const LangOptions & Features,const TargetInfo & Target,unsigned * StartToken,unsigned * StartTokenByteOffset) const13290b57cec5SDimitry Andric StringLiteral::getLocationOfByte(unsigned ByteNo, const SourceManager &SM,
13300b57cec5SDimitry Andric const LangOptions &Features,
13310b57cec5SDimitry Andric const TargetInfo &Target, unsigned *StartToken,
13320b57cec5SDimitry Andric unsigned *StartTokenByteOffset) const {
13335f757f3fSDimitry Andric assert((getKind() == StringLiteralKind::Ordinary ||
13345f757f3fSDimitry Andric getKind() == StringLiteralKind::UTF8 ||
13355f757f3fSDimitry Andric getKind() == StringLiteralKind::Unevaluated) &&
13360b57cec5SDimitry Andric "Only narrow string literals are currently supported");
13370b57cec5SDimitry Andric
13380b57cec5SDimitry Andric // Loop over all of the tokens in this string until we find the one that
13390b57cec5SDimitry Andric // contains the byte we're looking for.
13400b57cec5SDimitry Andric unsigned TokNo = 0;
13410b57cec5SDimitry Andric unsigned StringOffset = 0;
13420b57cec5SDimitry Andric if (StartToken)
13430b57cec5SDimitry Andric TokNo = *StartToken;
13440b57cec5SDimitry Andric if (StartTokenByteOffset) {
13450b57cec5SDimitry Andric StringOffset = *StartTokenByteOffset;
13460b57cec5SDimitry Andric ByteNo -= StringOffset;
13470b57cec5SDimitry Andric }
134804eeddc0SDimitry Andric while (true) {
13490b57cec5SDimitry Andric assert(TokNo < getNumConcatenated() && "Invalid byte number!");
13500b57cec5SDimitry Andric SourceLocation StrTokLoc = getStrTokenLoc(TokNo);
13510b57cec5SDimitry Andric
13520b57cec5SDimitry Andric // Get the spelling of the string so that we can get the data that makes up
13530b57cec5SDimitry Andric // the string literal, not the identifier for the macro it is potentially
13540b57cec5SDimitry Andric // expanded through.
13550b57cec5SDimitry Andric SourceLocation StrTokSpellingLoc = SM.getSpellingLoc(StrTokLoc);
13560b57cec5SDimitry Andric
13570b57cec5SDimitry Andric // Re-lex the token to get its length and original spelling.
13580b57cec5SDimitry Andric std::pair<FileID, unsigned> LocInfo =
13590b57cec5SDimitry Andric SM.getDecomposedLoc(StrTokSpellingLoc);
13600b57cec5SDimitry Andric bool Invalid = false;
13610b57cec5SDimitry Andric StringRef Buffer = SM.getBufferData(LocInfo.first, &Invalid);
13620b57cec5SDimitry Andric if (Invalid) {
13630b57cec5SDimitry Andric if (StartTokenByteOffset != nullptr)
13640b57cec5SDimitry Andric *StartTokenByteOffset = StringOffset;
13650b57cec5SDimitry Andric if (StartToken != nullptr)
13660b57cec5SDimitry Andric *StartToken = TokNo;
13670b57cec5SDimitry Andric return StrTokSpellingLoc;
13680b57cec5SDimitry Andric }
13690b57cec5SDimitry Andric
13700b57cec5SDimitry Andric const char *StrData = Buffer.data()+LocInfo.second;
13710b57cec5SDimitry Andric
13720b57cec5SDimitry Andric // Create a lexer starting at the beginning of this token.
13730b57cec5SDimitry Andric Lexer TheLexer(SM.getLocForStartOfFile(LocInfo.first), Features,
13740b57cec5SDimitry Andric Buffer.begin(), StrData, Buffer.end());
13750b57cec5SDimitry Andric Token TheTok;
13760b57cec5SDimitry Andric TheLexer.LexFromRawLexer(TheTok);
13770b57cec5SDimitry Andric
13780b57cec5SDimitry Andric // Use the StringLiteralParser to compute the length of the string in bytes.
13790b57cec5SDimitry Andric StringLiteralParser SLP(TheTok, SM, Features, Target);
13800b57cec5SDimitry Andric unsigned TokNumBytes = SLP.GetStringLength();
13810b57cec5SDimitry Andric
13820b57cec5SDimitry Andric // If the byte is in this token, return the location of the byte.
13830b57cec5SDimitry Andric if (ByteNo < TokNumBytes ||
13840b57cec5SDimitry Andric (ByteNo == TokNumBytes && TokNo == getNumConcatenated() - 1)) {
13850b57cec5SDimitry Andric unsigned Offset = SLP.getOffsetOfStringByte(TheTok, ByteNo);
13860b57cec5SDimitry Andric
13870b57cec5SDimitry Andric // Now that we know the offset of the token in the spelling, use the
13880b57cec5SDimitry Andric // preprocessor to get the offset in the original source.
13890b57cec5SDimitry Andric if (StartTokenByteOffset != nullptr)
13900b57cec5SDimitry Andric *StartTokenByteOffset = StringOffset;
13910b57cec5SDimitry Andric if (StartToken != nullptr)
13920b57cec5SDimitry Andric *StartToken = TokNo;
13930b57cec5SDimitry Andric return Lexer::AdvanceToTokenCharacter(StrTokLoc, Offset, SM, Features);
13940b57cec5SDimitry Andric }
13950b57cec5SDimitry Andric
13960b57cec5SDimitry Andric // Move to the next string token.
13970b57cec5SDimitry Andric StringOffset += TokNumBytes;
13980b57cec5SDimitry Andric ++TokNo;
13990b57cec5SDimitry Andric ByteNo -= TokNumBytes;
14000b57cec5SDimitry Andric }
14010b57cec5SDimitry Andric }
14020b57cec5SDimitry Andric
14030b57cec5SDimitry Andric /// getOpcodeStr - Turn an Opcode enum value into the punctuation char it
14040b57cec5SDimitry Andric /// corresponds to, e.g. "sizeof" or "[pre]++".
getOpcodeStr(Opcode Op)14050b57cec5SDimitry Andric StringRef UnaryOperator::getOpcodeStr(Opcode Op) {
14060b57cec5SDimitry Andric switch (Op) {
14070b57cec5SDimitry Andric #define UNARY_OPERATION(Name, Spelling) case UO_##Name: return Spelling;
14080b57cec5SDimitry Andric #include "clang/AST/OperationKinds.def"
14090b57cec5SDimitry Andric }
14100b57cec5SDimitry Andric llvm_unreachable("Unknown unary operator");
14110b57cec5SDimitry Andric }
14120b57cec5SDimitry Andric
14130b57cec5SDimitry Andric UnaryOperatorKind
getOverloadedOpcode(OverloadedOperatorKind OO,bool Postfix)14140b57cec5SDimitry Andric UnaryOperator::getOverloadedOpcode(OverloadedOperatorKind OO, bool Postfix) {
14150b57cec5SDimitry Andric switch (OO) {
14160b57cec5SDimitry Andric default: llvm_unreachable("No unary operator for overloaded function");
14170b57cec5SDimitry Andric case OO_PlusPlus: return Postfix ? UO_PostInc : UO_PreInc;
14180b57cec5SDimitry Andric case OO_MinusMinus: return Postfix ? UO_PostDec : UO_PreDec;
14190b57cec5SDimitry Andric case OO_Amp: return UO_AddrOf;
14200b57cec5SDimitry Andric case OO_Star: return UO_Deref;
14210b57cec5SDimitry Andric case OO_Plus: return UO_Plus;
14220b57cec5SDimitry Andric case OO_Minus: return UO_Minus;
14230b57cec5SDimitry Andric case OO_Tilde: return UO_Not;
14240b57cec5SDimitry Andric case OO_Exclaim: return UO_LNot;
14250b57cec5SDimitry Andric case OO_Coawait: return UO_Coawait;
14260b57cec5SDimitry Andric }
14270b57cec5SDimitry Andric }
14280b57cec5SDimitry Andric
getOverloadedOperator(Opcode Opc)14290b57cec5SDimitry Andric OverloadedOperatorKind UnaryOperator::getOverloadedOperator(Opcode Opc) {
14300b57cec5SDimitry Andric switch (Opc) {
14310b57cec5SDimitry Andric case UO_PostInc: case UO_PreInc: return OO_PlusPlus;
14320b57cec5SDimitry Andric case UO_PostDec: case UO_PreDec: return OO_MinusMinus;
14330b57cec5SDimitry Andric case UO_AddrOf: return OO_Amp;
14340b57cec5SDimitry Andric case UO_Deref: return OO_Star;
14350b57cec5SDimitry Andric case UO_Plus: return OO_Plus;
14360b57cec5SDimitry Andric case UO_Minus: return OO_Minus;
14370b57cec5SDimitry Andric case UO_Not: return OO_Tilde;
14380b57cec5SDimitry Andric case UO_LNot: return OO_Exclaim;
14390b57cec5SDimitry Andric case UO_Coawait: return OO_Coawait;
14400b57cec5SDimitry Andric default: return OO_None;
14410b57cec5SDimitry Andric }
14420b57cec5SDimitry Andric }
14430b57cec5SDimitry Andric
14440b57cec5SDimitry Andric
14450b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
14460b57cec5SDimitry Andric // Postfix Operators.
14470b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
14480b57cec5SDimitry Andric
CallExpr(StmtClass SC,Expr * Fn,ArrayRef<Expr * > PreArgs,ArrayRef<Expr * > Args,QualType Ty,ExprValueKind VK,SourceLocation RParenLoc,FPOptionsOverride FPFeatures,unsigned MinNumArgs,ADLCallKind UsesADL)14490b57cec5SDimitry Andric CallExpr::CallExpr(StmtClass SC, Expr *Fn, ArrayRef<Expr *> PreArgs,
14500b57cec5SDimitry Andric ArrayRef<Expr *> Args, QualType Ty, ExprValueKind VK,
1451e8d8bef9SDimitry Andric SourceLocation RParenLoc, FPOptionsOverride FPFeatures,
1452e8d8bef9SDimitry Andric unsigned MinNumArgs, ADLCallKind UsesADL)
14535ffd83dbSDimitry Andric : Expr(SC, Ty, VK, OK_Ordinary), RParenLoc(RParenLoc) {
14540b57cec5SDimitry Andric NumArgs = std::max<unsigned>(Args.size(), MinNumArgs);
14550b57cec5SDimitry Andric unsigned NumPreArgs = PreArgs.size();
14560b57cec5SDimitry Andric CallExprBits.NumPreArgs = NumPreArgs;
14570b57cec5SDimitry Andric assert((NumPreArgs == getNumPreArgs()) && "NumPreArgs overflow!");
14580b57cec5SDimitry Andric
14590b57cec5SDimitry Andric unsigned OffsetToTrailingObjects = offsetToTrailingObjects(SC);
14600b57cec5SDimitry Andric CallExprBits.OffsetToTrailingObjects = OffsetToTrailingObjects;
14610b57cec5SDimitry Andric assert((CallExprBits.OffsetToTrailingObjects == OffsetToTrailingObjects) &&
14620b57cec5SDimitry Andric "OffsetToTrailingObjects overflow!");
14630b57cec5SDimitry Andric
14640b57cec5SDimitry Andric CallExprBits.UsesADL = static_cast<bool>(UsesADL);
14650b57cec5SDimitry Andric
14660b57cec5SDimitry Andric setCallee(Fn);
14675ffd83dbSDimitry Andric for (unsigned I = 0; I != NumPreArgs; ++I)
14680b57cec5SDimitry Andric setPreArg(I, PreArgs[I]);
14695ffd83dbSDimitry Andric for (unsigned I = 0; I != Args.size(); ++I)
14700b57cec5SDimitry Andric setArg(I, Args[I]);
14715ffd83dbSDimitry Andric for (unsigned I = Args.size(); I != NumArgs; ++I)
14720b57cec5SDimitry Andric setArg(I, nullptr);
14735ffd83dbSDimitry Andric
1474fe6060f1SDimitry Andric this->computeDependence();
1475e8d8bef9SDimitry Andric
1476e8d8bef9SDimitry Andric CallExprBits.HasFPFeatures = FPFeatures.requiresTrailingStorage();
1477e8d8bef9SDimitry Andric if (hasStoredFPFeatures())
1478e8d8bef9SDimitry Andric setStoredFPFeatures(FPFeatures);
14790b57cec5SDimitry Andric }
14800b57cec5SDimitry Andric
CallExpr(StmtClass SC,unsigned NumPreArgs,unsigned NumArgs,bool HasFPFeatures,EmptyShell Empty)14810b57cec5SDimitry Andric CallExpr::CallExpr(StmtClass SC, unsigned NumPreArgs, unsigned NumArgs,
1482e8d8bef9SDimitry Andric bool HasFPFeatures, EmptyShell Empty)
14830b57cec5SDimitry Andric : Expr(SC, Empty), NumArgs(NumArgs) {
14840b57cec5SDimitry Andric CallExprBits.NumPreArgs = NumPreArgs;
14850b57cec5SDimitry Andric assert((NumPreArgs == getNumPreArgs()) && "NumPreArgs overflow!");
14860b57cec5SDimitry Andric
14870b57cec5SDimitry Andric unsigned OffsetToTrailingObjects = offsetToTrailingObjects(SC);
14880b57cec5SDimitry Andric CallExprBits.OffsetToTrailingObjects = OffsetToTrailingObjects;
14890b57cec5SDimitry Andric assert((CallExprBits.OffsetToTrailingObjects == OffsetToTrailingObjects) &&
14900b57cec5SDimitry Andric "OffsetToTrailingObjects overflow!");
1491e8d8bef9SDimitry Andric CallExprBits.HasFPFeatures = HasFPFeatures;
14920b57cec5SDimitry Andric }
14930b57cec5SDimitry Andric
Create(const ASTContext & Ctx,Expr * Fn,ArrayRef<Expr * > Args,QualType Ty,ExprValueKind VK,SourceLocation RParenLoc,FPOptionsOverride FPFeatures,unsigned MinNumArgs,ADLCallKind UsesADL)14940b57cec5SDimitry Andric CallExpr *CallExpr::Create(const ASTContext &Ctx, Expr *Fn,
14950b57cec5SDimitry Andric ArrayRef<Expr *> Args, QualType Ty, ExprValueKind VK,
1496e8d8bef9SDimitry Andric SourceLocation RParenLoc,
1497e8d8bef9SDimitry Andric FPOptionsOverride FPFeatures, unsigned MinNumArgs,
14980b57cec5SDimitry Andric ADLCallKind UsesADL) {
14990b57cec5SDimitry Andric unsigned NumArgs = std::max<unsigned>(Args.size(), MinNumArgs);
1500e8d8bef9SDimitry Andric unsigned SizeOfTrailingObjects = CallExpr::sizeOfTrailingObjects(
1501e8d8bef9SDimitry Andric /*NumPreArgs=*/0, NumArgs, FPFeatures.requiresTrailingStorage());
15020b57cec5SDimitry Andric void *Mem =
15030b57cec5SDimitry Andric Ctx.Allocate(sizeof(CallExpr) + SizeOfTrailingObjects, alignof(CallExpr));
15040b57cec5SDimitry Andric return new (Mem) CallExpr(CallExprClass, Fn, /*PreArgs=*/{}, Args, Ty, VK,
1505e8d8bef9SDimitry Andric RParenLoc, FPFeatures, MinNumArgs, UsesADL);
15060b57cec5SDimitry Andric }
15070b57cec5SDimitry Andric
CreateTemporary(void * Mem,Expr * Fn,QualType Ty,ExprValueKind VK,SourceLocation RParenLoc,ADLCallKind UsesADL)15080b57cec5SDimitry Andric CallExpr *CallExpr::CreateTemporary(void *Mem, Expr *Fn, QualType Ty,
15090b57cec5SDimitry Andric ExprValueKind VK, SourceLocation RParenLoc,
15100b57cec5SDimitry Andric ADLCallKind UsesADL) {
15110b57cec5SDimitry Andric assert(!(reinterpret_cast<uintptr_t>(Mem) % alignof(CallExpr)) &&
15120b57cec5SDimitry Andric "Misaligned memory in CallExpr::CreateTemporary!");
15130b57cec5SDimitry Andric return new (Mem) CallExpr(CallExprClass, Fn, /*PreArgs=*/{}, /*Args=*/{}, Ty,
1514e8d8bef9SDimitry Andric VK, RParenLoc, FPOptionsOverride(),
15155ffd83dbSDimitry Andric /*MinNumArgs=*/0, UsesADL);
15160b57cec5SDimitry Andric }
15170b57cec5SDimitry Andric
CreateEmpty(const ASTContext & Ctx,unsigned NumArgs,bool HasFPFeatures,EmptyShell Empty)15180b57cec5SDimitry Andric CallExpr *CallExpr::CreateEmpty(const ASTContext &Ctx, unsigned NumArgs,
1519e8d8bef9SDimitry Andric bool HasFPFeatures, EmptyShell Empty) {
15200b57cec5SDimitry Andric unsigned SizeOfTrailingObjects =
1521e8d8bef9SDimitry Andric CallExpr::sizeOfTrailingObjects(/*NumPreArgs=*/0, NumArgs, HasFPFeatures);
15220b57cec5SDimitry Andric void *Mem =
15230b57cec5SDimitry Andric Ctx.Allocate(sizeof(CallExpr) + SizeOfTrailingObjects, alignof(CallExpr));
1524e8d8bef9SDimitry Andric return new (Mem)
1525e8d8bef9SDimitry Andric CallExpr(CallExprClass, /*NumPreArgs=*/0, NumArgs, HasFPFeatures, Empty);
15260b57cec5SDimitry Andric }
15270b57cec5SDimitry Andric
offsetToTrailingObjects(StmtClass SC)15280b57cec5SDimitry Andric unsigned CallExpr::offsetToTrailingObjects(StmtClass SC) {
15290b57cec5SDimitry Andric switch (SC) {
15300b57cec5SDimitry Andric case CallExprClass:
15310b57cec5SDimitry Andric return sizeof(CallExpr);
15320b57cec5SDimitry Andric case CXXOperatorCallExprClass:
15330b57cec5SDimitry Andric return sizeof(CXXOperatorCallExpr);
15340b57cec5SDimitry Andric case CXXMemberCallExprClass:
15350b57cec5SDimitry Andric return sizeof(CXXMemberCallExpr);
15360b57cec5SDimitry Andric case UserDefinedLiteralClass:
15370b57cec5SDimitry Andric return sizeof(UserDefinedLiteral);
15380b57cec5SDimitry Andric case CUDAKernelCallExprClass:
15390b57cec5SDimitry Andric return sizeof(CUDAKernelCallExpr);
15400b57cec5SDimitry Andric default:
15410b57cec5SDimitry Andric llvm_unreachable("unexpected class deriving from CallExpr!");
15420b57cec5SDimitry Andric }
15430b57cec5SDimitry Andric }
15440b57cec5SDimitry Andric
getReferencedDeclOfCallee()15450b57cec5SDimitry Andric Decl *Expr::getReferencedDeclOfCallee() {
15460b57cec5SDimitry Andric Expr *CEE = IgnoreParenImpCasts();
15470b57cec5SDimitry Andric
154806c3fb27SDimitry Andric while (auto *NTTP = dyn_cast<SubstNonTypeTemplateParmExpr>(CEE))
15495ffd83dbSDimitry Andric CEE = NTTP->getReplacement()->IgnoreParenImpCasts();
15500b57cec5SDimitry Andric
15510b57cec5SDimitry Andric // If we're calling a dereference, look at the pointer instead.
15525ffd83dbSDimitry Andric while (true) {
155306c3fb27SDimitry Andric if (auto *BO = dyn_cast<BinaryOperator>(CEE)) {
15545ffd83dbSDimitry Andric if (BO->isPtrMemOp()) {
15555ffd83dbSDimitry Andric CEE = BO->getRHS()->IgnoreParenImpCasts();
15565ffd83dbSDimitry Andric continue;
15570b57cec5SDimitry Andric }
155806c3fb27SDimitry Andric } else if (auto *UO = dyn_cast<UnaryOperator>(CEE)) {
15595ffd83dbSDimitry Andric if (UO->getOpcode() == UO_Deref || UO->getOpcode() == UO_AddrOf ||
15605ffd83dbSDimitry Andric UO->getOpcode() == UO_Plus) {
15615ffd83dbSDimitry Andric CEE = UO->getSubExpr()->IgnoreParenImpCasts();
15625ffd83dbSDimitry Andric continue;
15635ffd83dbSDimitry Andric }
15645ffd83dbSDimitry Andric }
15655ffd83dbSDimitry Andric break;
15665ffd83dbSDimitry Andric }
15675ffd83dbSDimitry Andric
156806c3fb27SDimitry Andric if (auto *DRE = dyn_cast<DeclRefExpr>(CEE))
15690b57cec5SDimitry Andric return DRE->getDecl();
157006c3fb27SDimitry Andric if (auto *ME = dyn_cast<MemberExpr>(CEE))
15710b57cec5SDimitry Andric return ME->getMemberDecl();
15720b57cec5SDimitry Andric if (auto *BE = dyn_cast<BlockExpr>(CEE))
15730b57cec5SDimitry Andric return BE->getBlockDecl();
15740b57cec5SDimitry Andric
15750b57cec5SDimitry Andric return nullptr;
15760b57cec5SDimitry Andric }
15770b57cec5SDimitry Andric
15785ffd83dbSDimitry Andric /// If this is a call to a builtin, return the builtin ID. If not, return 0.
getBuiltinCallee() const15790b57cec5SDimitry Andric unsigned CallExpr::getBuiltinCallee() const {
158006c3fb27SDimitry Andric const auto *FDecl = getDirectCallee();
15815ffd83dbSDimitry Andric return FDecl ? FDecl->getBuiltinID() : 0;
15820b57cec5SDimitry Andric }
15830b57cec5SDimitry Andric
isUnevaluatedBuiltinCall(const ASTContext & Ctx) const15840b57cec5SDimitry Andric bool CallExpr::isUnevaluatedBuiltinCall(const ASTContext &Ctx) const {
15850b57cec5SDimitry Andric if (unsigned BI = getBuiltinCallee())
15860b57cec5SDimitry Andric return Ctx.BuiltinInfo.isUnevaluated(BI);
15870b57cec5SDimitry Andric return false;
15880b57cec5SDimitry Andric }
15890b57cec5SDimitry Andric
getCallReturnType(const ASTContext & Ctx) const15900b57cec5SDimitry Andric QualType CallExpr::getCallReturnType(const ASTContext &Ctx) const {
15910b57cec5SDimitry Andric const Expr *Callee = getCallee();
15920b57cec5SDimitry Andric QualType CalleeType = Callee->getType();
15930b57cec5SDimitry Andric if (const auto *FnTypePtr = CalleeType->getAs<PointerType>()) {
15940b57cec5SDimitry Andric CalleeType = FnTypePtr->getPointeeType();
15950b57cec5SDimitry Andric } else if (const auto *BPT = CalleeType->getAs<BlockPointerType>()) {
15960b57cec5SDimitry Andric CalleeType = BPT->getPointeeType();
15970b57cec5SDimitry Andric } else if (CalleeType->isSpecificPlaceholderType(BuiltinType::BoundMember)) {
15980b57cec5SDimitry Andric if (isa<CXXPseudoDestructorExpr>(Callee->IgnoreParens()))
15990b57cec5SDimitry Andric return Ctx.VoidTy;
16000b57cec5SDimitry Andric
1601fe6060f1SDimitry Andric if (isa<UnresolvedMemberExpr>(Callee->IgnoreParens()))
1602fe6060f1SDimitry Andric return Ctx.DependentTy;
1603fe6060f1SDimitry Andric
16040b57cec5SDimitry Andric // This should never be overloaded and so should never return null.
16050b57cec5SDimitry Andric CalleeType = Expr::findBoundMemberType(Callee);
1606fe6060f1SDimitry Andric assert(!CalleeType.isNull());
16075f757f3fSDimitry Andric } else if (CalleeType->isRecordType()) {
16085f757f3fSDimitry Andric // If the Callee is a record type, then it is a not-yet-resolved
16095f757f3fSDimitry Andric // dependent call to the call operator of that type.
16105f757f3fSDimitry Andric return Ctx.DependentTy;
1611fe6060f1SDimitry Andric } else if (CalleeType->isDependentType() ||
1612fe6060f1SDimitry Andric CalleeType->isSpecificPlaceholderType(BuiltinType::Overload)) {
1613fe6060f1SDimitry Andric return Ctx.DependentTy;
16140b57cec5SDimitry Andric }
16150b57cec5SDimitry Andric
16160b57cec5SDimitry Andric const FunctionType *FnType = CalleeType->castAs<FunctionType>();
16170b57cec5SDimitry Andric return FnType->getReturnType();
16180b57cec5SDimitry Andric }
16190b57cec5SDimitry Andric
getUnusedResultAttr(const ASTContext & Ctx) const16200b57cec5SDimitry Andric const Attr *CallExpr::getUnusedResultAttr(const ASTContext &Ctx) const {
16210b57cec5SDimitry Andric // If the return type is a struct, union, or enum that is marked nodiscard,
16220b57cec5SDimitry Andric // then return the return type attribute.
16230b57cec5SDimitry Andric if (const TagDecl *TD = getCallReturnType(Ctx)->getAsTagDecl())
16240b57cec5SDimitry Andric if (const auto *A = TD->getAttr<WarnUnusedResultAttr>())
16250b57cec5SDimitry Andric return A;
16260b57cec5SDimitry Andric
162781ad6265SDimitry Andric for (const auto *TD = getCallReturnType(Ctx)->getAs<TypedefType>(); TD;
162881ad6265SDimitry Andric TD = TD->desugar()->getAs<TypedefType>())
162981ad6265SDimitry Andric if (const auto *A = TD->getDecl()->getAttr<WarnUnusedResultAttr>())
163081ad6265SDimitry Andric return A;
163181ad6265SDimitry Andric
16320b57cec5SDimitry Andric // Otherwise, see if the callee is marked nodiscard and return that attribute
16330b57cec5SDimitry Andric // instead.
16340b57cec5SDimitry Andric const Decl *D = getCalleeDecl();
16350b57cec5SDimitry Andric return D ? D->getAttr<WarnUnusedResultAttr>() : nullptr;
16360b57cec5SDimitry Andric }
16370b57cec5SDimitry Andric
getBeginLoc() const16380b57cec5SDimitry Andric SourceLocation CallExpr::getBeginLoc() const {
163906c3fb27SDimitry Andric if (const auto *OCE = dyn_cast<CXXOperatorCallExpr>(this))
164006c3fb27SDimitry Andric return OCE->getBeginLoc();
16410b57cec5SDimitry Andric
16420b57cec5SDimitry Andric SourceLocation begin = getCallee()->getBeginLoc();
16430b57cec5SDimitry Andric if (begin.isInvalid() && getNumArgs() > 0 && getArg(0))
16440b57cec5SDimitry Andric begin = getArg(0)->getBeginLoc();
16450b57cec5SDimitry Andric return begin;
16460b57cec5SDimitry Andric }
getEndLoc() const16470b57cec5SDimitry Andric SourceLocation CallExpr::getEndLoc() const {
164806c3fb27SDimitry Andric if (const auto *OCE = dyn_cast<CXXOperatorCallExpr>(this))
164906c3fb27SDimitry Andric return OCE->getEndLoc();
16500b57cec5SDimitry Andric
16510b57cec5SDimitry Andric SourceLocation end = getRParenLoc();
16520b57cec5SDimitry Andric if (end.isInvalid() && getNumArgs() > 0 && getArg(getNumArgs() - 1))
16530b57cec5SDimitry Andric end = getArg(getNumArgs() - 1)->getEndLoc();
16540b57cec5SDimitry Andric return end;
16550b57cec5SDimitry Andric }
16560b57cec5SDimitry Andric
Create(const ASTContext & C,QualType type,SourceLocation OperatorLoc,TypeSourceInfo * tsi,ArrayRef<OffsetOfNode> comps,ArrayRef<Expr * > exprs,SourceLocation RParenLoc)16570b57cec5SDimitry Andric OffsetOfExpr *OffsetOfExpr::Create(const ASTContext &C, QualType type,
16580b57cec5SDimitry Andric SourceLocation OperatorLoc,
16590b57cec5SDimitry Andric TypeSourceInfo *tsi,
16600b57cec5SDimitry Andric ArrayRef<OffsetOfNode> comps,
16610b57cec5SDimitry Andric ArrayRef<Expr*> exprs,
16620b57cec5SDimitry Andric SourceLocation RParenLoc) {
16630b57cec5SDimitry Andric void *Mem = C.Allocate(
16640b57cec5SDimitry Andric totalSizeToAlloc<OffsetOfNode, Expr *>(comps.size(), exprs.size()));
16650b57cec5SDimitry Andric
16660b57cec5SDimitry Andric return new (Mem) OffsetOfExpr(C, type, OperatorLoc, tsi, comps, exprs,
16670b57cec5SDimitry Andric RParenLoc);
16680b57cec5SDimitry Andric }
16690b57cec5SDimitry Andric
CreateEmpty(const ASTContext & C,unsigned numComps,unsigned numExprs)16700b57cec5SDimitry Andric OffsetOfExpr *OffsetOfExpr::CreateEmpty(const ASTContext &C,
16710b57cec5SDimitry Andric unsigned numComps, unsigned numExprs) {
16720b57cec5SDimitry Andric void *Mem =
16730b57cec5SDimitry Andric C.Allocate(totalSizeToAlloc<OffsetOfNode, Expr *>(numComps, numExprs));
16740b57cec5SDimitry Andric return new (Mem) OffsetOfExpr(numComps, numExprs);
16750b57cec5SDimitry Andric }
16760b57cec5SDimitry Andric
OffsetOfExpr(const ASTContext & C,QualType type,SourceLocation OperatorLoc,TypeSourceInfo * tsi,ArrayRef<OffsetOfNode> comps,ArrayRef<Expr * > exprs,SourceLocation RParenLoc)16770b57cec5SDimitry Andric OffsetOfExpr::OffsetOfExpr(const ASTContext &C, QualType type,
16780b57cec5SDimitry Andric SourceLocation OperatorLoc, TypeSourceInfo *tsi,
16790b57cec5SDimitry Andric ArrayRef<OffsetOfNode> comps, ArrayRef<Expr *> exprs,
16800b57cec5SDimitry Andric SourceLocation RParenLoc)
1681fe6060f1SDimitry Andric : Expr(OffsetOfExprClass, type, VK_PRValue, OK_Ordinary),
16820b57cec5SDimitry Andric OperatorLoc(OperatorLoc), RParenLoc(RParenLoc), TSInfo(tsi),
16835ffd83dbSDimitry Andric NumComps(comps.size()), NumExprs(exprs.size()) {
16845ffd83dbSDimitry Andric for (unsigned i = 0; i != comps.size(); ++i)
16850b57cec5SDimitry Andric setComponent(i, comps[i]);
16865ffd83dbSDimitry Andric for (unsigned i = 0; i != exprs.size(); ++i)
16870b57cec5SDimitry Andric setIndexExpr(i, exprs[i]);
16885ffd83dbSDimitry Andric
16895ffd83dbSDimitry Andric setDependence(computeDependence(this));
16900b57cec5SDimitry Andric }
16910b57cec5SDimitry Andric
getFieldName() const16920b57cec5SDimitry Andric IdentifierInfo *OffsetOfNode::getFieldName() const {
16930b57cec5SDimitry Andric assert(getKind() == Field || getKind() == Identifier);
16940b57cec5SDimitry Andric if (getKind() == Field)
16950b57cec5SDimitry Andric return getField()->getIdentifier();
16960b57cec5SDimitry Andric
16970b57cec5SDimitry Andric return reinterpret_cast<IdentifierInfo *> (Data & ~(uintptr_t)Mask);
16980b57cec5SDimitry Andric }
16990b57cec5SDimitry Andric
UnaryExprOrTypeTraitExpr(UnaryExprOrTypeTrait ExprKind,Expr * E,QualType resultType,SourceLocation op,SourceLocation rp)17000b57cec5SDimitry Andric UnaryExprOrTypeTraitExpr::UnaryExprOrTypeTraitExpr(
17010b57cec5SDimitry Andric UnaryExprOrTypeTrait ExprKind, Expr *E, QualType resultType,
17020b57cec5SDimitry Andric SourceLocation op, SourceLocation rp)
1703fe6060f1SDimitry Andric : Expr(UnaryExprOrTypeTraitExprClass, resultType, VK_PRValue, OK_Ordinary),
17040b57cec5SDimitry Andric OpLoc(op), RParenLoc(rp) {
17055ffd83dbSDimitry Andric assert(ExprKind <= UETT_Last && "invalid enum value!");
17060b57cec5SDimitry Andric UnaryExprOrTypeTraitExprBits.Kind = ExprKind;
17075ffd83dbSDimitry Andric assert(static_cast<unsigned>(ExprKind) == UnaryExprOrTypeTraitExprBits.Kind &&
17085ffd83dbSDimitry Andric "UnaryExprOrTypeTraitExprBits.Kind overflow!");
17090b57cec5SDimitry Andric UnaryExprOrTypeTraitExprBits.IsType = false;
17100b57cec5SDimitry Andric Argument.Ex = E;
17115ffd83dbSDimitry Andric setDependence(computeDependence(this));
17120b57cec5SDimitry Andric }
17130b57cec5SDimitry Andric
MemberExpr(Expr * Base,bool IsArrow,SourceLocation OperatorLoc,NestedNameSpecifierLoc QualifierLoc,SourceLocation TemplateKWLoc,ValueDecl * MemberDecl,DeclAccessPair FoundDecl,const DeclarationNameInfo & NameInfo,const TemplateArgumentListInfo * TemplateArgs,QualType T,ExprValueKind VK,ExprObjectKind OK,NonOdrUseReason NOUR)17140b57cec5SDimitry Andric MemberExpr::MemberExpr(Expr *Base, bool IsArrow, SourceLocation OperatorLoc,
1715*0fca6ea1SDimitry Andric NestedNameSpecifierLoc QualifierLoc,
1716*0fca6ea1SDimitry Andric SourceLocation TemplateKWLoc, ValueDecl *MemberDecl,
1717*0fca6ea1SDimitry Andric DeclAccessPair FoundDecl,
1718*0fca6ea1SDimitry Andric const DeclarationNameInfo &NameInfo,
1719*0fca6ea1SDimitry Andric const TemplateArgumentListInfo *TemplateArgs, QualType T,
17200b57cec5SDimitry Andric ExprValueKind VK, ExprObjectKind OK,
17210b57cec5SDimitry Andric NonOdrUseReason NOUR)
17225ffd83dbSDimitry Andric : Expr(MemberExprClass, T, VK, OK), Base(Base), MemberDecl(MemberDecl),
17235ffd83dbSDimitry Andric MemberDNLoc(NameInfo.getInfo()), MemberLoc(NameInfo.getLoc()) {
17240b57cec5SDimitry Andric assert(!NameInfo.getName() ||
17250b57cec5SDimitry Andric MemberDecl->getDeclName() == NameInfo.getName());
17260b57cec5SDimitry Andric MemberExprBits.IsArrow = IsArrow;
1727*0fca6ea1SDimitry Andric MemberExprBits.HasQualifier = QualifierLoc.hasQualifier();
1728*0fca6ea1SDimitry Andric MemberExprBits.HasFoundDecl =
1729*0fca6ea1SDimitry Andric FoundDecl.getDecl() != MemberDecl ||
1730*0fca6ea1SDimitry Andric FoundDecl.getAccess() != MemberDecl->getAccess();
1731*0fca6ea1SDimitry Andric MemberExprBits.HasTemplateKWAndArgsInfo =
1732*0fca6ea1SDimitry Andric TemplateArgs || TemplateKWLoc.isValid();
17330b57cec5SDimitry Andric MemberExprBits.HadMultipleCandidates = false;
17340b57cec5SDimitry Andric MemberExprBits.NonOdrUseReason = NOUR;
17350b57cec5SDimitry Andric MemberExprBits.OperatorLoc = OperatorLoc;
1736*0fca6ea1SDimitry Andric
1737*0fca6ea1SDimitry Andric if (hasQualifier())
1738*0fca6ea1SDimitry Andric new (getTrailingObjects<NestedNameSpecifierLoc>())
1739*0fca6ea1SDimitry Andric NestedNameSpecifierLoc(QualifierLoc);
1740*0fca6ea1SDimitry Andric if (hasFoundDecl())
1741*0fca6ea1SDimitry Andric *getTrailingObjects<DeclAccessPair>() = FoundDecl;
1742*0fca6ea1SDimitry Andric if (TemplateArgs) {
1743*0fca6ea1SDimitry Andric auto Deps = TemplateArgumentDependence::None;
1744*0fca6ea1SDimitry Andric getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom(
1745*0fca6ea1SDimitry Andric TemplateKWLoc, *TemplateArgs, getTrailingObjects<TemplateArgumentLoc>(),
1746*0fca6ea1SDimitry Andric Deps);
1747*0fca6ea1SDimitry Andric } else if (TemplateKWLoc.isValid()) {
1748*0fca6ea1SDimitry Andric getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom(
1749*0fca6ea1SDimitry Andric TemplateKWLoc);
1750*0fca6ea1SDimitry Andric }
17515ffd83dbSDimitry Andric setDependence(computeDependence(this));
17520b57cec5SDimitry Andric }
17530b57cec5SDimitry Andric
Create(const ASTContext & C,Expr * Base,bool IsArrow,SourceLocation OperatorLoc,NestedNameSpecifierLoc QualifierLoc,SourceLocation TemplateKWLoc,ValueDecl * MemberDecl,DeclAccessPair FoundDecl,DeclarationNameInfo NameInfo,const TemplateArgumentListInfo * TemplateArgs,QualType T,ExprValueKind VK,ExprObjectKind OK,NonOdrUseReason NOUR)17540b57cec5SDimitry Andric MemberExpr *MemberExpr::Create(
17550b57cec5SDimitry Andric const ASTContext &C, Expr *Base, bool IsArrow, SourceLocation OperatorLoc,
17560b57cec5SDimitry Andric NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc,
17570b57cec5SDimitry Andric ValueDecl *MemberDecl, DeclAccessPair FoundDecl,
17580b57cec5SDimitry Andric DeclarationNameInfo NameInfo, const TemplateArgumentListInfo *TemplateArgs,
17590b57cec5SDimitry Andric QualType T, ExprValueKind VK, ExprObjectKind OK, NonOdrUseReason NOUR) {
1760*0fca6ea1SDimitry Andric bool HasQualifier = QualifierLoc.hasQualifier();
1761*0fca6ea1SDimitry Andric bool HasFoundDecl = FoundDecl.getDecl() != MemberDecl ||
17620b57cec5SDimitry Andric FoundDecl.getAccess() != MemberDecl->getAccess();
17630b57cec5SDimitry Andric bool HasTemplateKWAndArgsInfo = TemplateArgs || TemplateKWLoc.isValid();
17640b57cec5SDimitry Andric std::size_t Size =
1765*0fca6ea1SDimitry Andric totalSizeToAlloc<NestedNameSpecifierLoc, DeclAccessPair,
1766*0fca6ea1SDimitry Andric ASTTemplateKWAndArgsInfo, TemplateArgumentLoc>(
1767*0fca6ea1SDimitry Andric HasQualifier, HasFoundDecl, HasTemplateKWAndArgsInfo,
17680b57cec5SDimitry Andric TemplateArgs ? TemplateArgs->size() : 0);
17690b57cec5SDimitry Andric
17700b57cec5SDimitry Andric void *Mem = C.Allocate(Size, alignof(MemberExpr));
1771*0fca6ea1SDimitry Andric return new (Mem) MemberExpr(Base, IsArrow, OperatorLoc, QualifierLoc,
1772*0fca6ea1SDimitry Andric TemplateKWLoc, MemberDecl, FoundDecl, NameInfo,
1773*0fca6ea1SDimitry Andric TemplateArgs, T, VK, OK, NOUR);
17740b57cec5SDimitry Andric }
17750b57cec5SDimitry Andric
CreateEmpty(const ASTContext & Context,bool HasQualifier,bool HasFoundDecl,bool HasTemplateKWAndArgsInfo,unsigned NumTemplateArgs)17760b57cec5SDimitry Andric MemberExpr *MemberExpr::CreateEmpty(const ASTContext &Context,
17770b57cec5SDimitry Andric bool HasQualifier, bool HasFoundDecl,
17780b57cec5SDimitry Andric bool HasTemplateKWAndArgsInfo,
17790b57cec5SDimitry Andric unsigned NumTemplateArgs) {
17800b57cec5SDimitry Andric assert((!NumTemplateArgs || HasTemplateKWAndArgsInfo) &&
17810b57cec5SDimitry Andric "template args but no template arg info?");
17820b57cec5SDimitry Andric std::size_t Size =
1783*0fca6ea1SDimitry Andric totalSizeToAlloc<NestedNameSpecifierLoc, DeclAccessPair,
1784*0fca6ea1SDimitry Andric ASTTemplateKWAndArgsInfo, TemplateArgumentLoc>(
1785*0fca6ea1SDimitry Andric HasQualifier, HasFoundDecl, HasTemplateKWAndArgsInfo,
17860b57cec5SDimitry Andric NumTemplateArgs);
17870b57cec5SDimitry Andric void *Mem = Context.Allocate(Size, alignof(MemberExpr));
17880b57cec5SDimitry Andric return new (Mem) MemberExpr(EmptyShell());
17890b57cec5SDimitry Andric }
17900b57cec5SDimitry Andric
setMemberDecl(ValueDecl * NewD)1791fe6060f1SDimitry Andric void MemberExpr::setMemberDecl(ValueDecl *NewD) {
1792fe6060f1SDimitry Andric MemberDecl = NewD;
1793fe6060f1SDimitry Andric if (getType()->isUndeducedType())
1794fe6060f1SDimitry Andric setType(NewD->getType());
1795e8d8bef9SDimitry Andric setDependence(computeDependence(this));
1796e8d8bef9SDimitry Andric }
1797e8d8bef9SDimitry Andric
getBeginLoc() const17980b57cec5SDimitry Andric SourceLocation MemberExpr::getBeginLoc() const {
17990b57cec5SDimitry Andric if (isImplicitAccess()) {
18000b57cec5SDimitry Andric if (hasQualifier())
18010b57cec5SDimitry Andric return getQualifierLoc().getBeginLoc();
18020b57cec5SDimitry Andric return MemberLoc;
18030b57cec5SDimitry Andric }
18040b57cec5SDimitry Andric
18050b57cec5SDimitry Andric // FIXME: We don't want this to happen. Rather, we should be able to
18060b57cec5SDimitry Andric // detect all kinds of implicit accesses more cleanly.
18070b57cec5SDimitry Andric SourceLocation BaseStartLoc = getBase()->getBeginLoc();
18080b57cec5SDimitry Andric if (BaseStartLoc.isValid())
18090b57cec5SDimitry Andric return BaseStartLoc;
18100b57cec5SDimitry Andric return MemberLoc;
18110b57cec5SDimitry Andric }
getEndLoc() const18120b57cec5SDimitry Andric SourceLocation MemberExpr::getEndLoc() const {
18130b57cec5SDimitry Andric SourceLocation EndLoc = getMemberNameInfo().getEndLoc();
18140b57cec5SDimitry Andric if (hasExplicitTemplateArgs())
18150b57cec5SDimitry Andric EndLoc = getRAngleLoc();
18160b57cec5SDimitry Andric else if (EndLoc.isInvalid())
18170b57cec5SDimitry Andric EndLoc = getBase()->getEndLoc();
18180b57cec5SDimitry Andric return EndLoc;
18190b57cec5SDimitry Andric }
18200b57cec5SDimitry Andric
CastConsistency() const18210b57cec5SDimitry Andric bool CastExpr::CastConsistency() const {
18220b57cec5SDimitry Andric switch (getCastKind()) {
18230b57cec5SDimitry Andric case CK_DerivedToBase:
18240b57cec5SDimitry Andric case CK_UncheckedDerivedToBase:
18250b57cec5SDimitry Andric case CK_DerivedToBaseMemberPointer:
18260b57cec5SDimitry Andric case CK_BaseToDerived:
18270b57cec5SDimitry Andric case CK_BaseToDerivedMemberPointer:
18280b57cec5SDimitry Andric assert(!path_empty() && "Cast kind should have a base path!");
18290b57cec5SDimitry Andric break;
18300b57cec5SDimitry Andric
18310b57cec5SDimitry Andric case CK_CPointerToObjCPointerCast:
18320b57cec5SDimitry Andric assert(getType()->isObjCObjectPointerType());
18330b57cec5SDimitry Andric assert(getSubExpr()->getType()->isPointerType());
18340b57cec5SDimitry Andric goto CheckNoBasePath;
18350b57cec5SDimitry Andric
18360b57cec5SDimitry Andric case CK_BlockPointerToObjCPointerCast:
18370b57cec5SDimitry Andric assert(getType()->isObjCObjectPointerType());
18380b57cec5SDimitry Andric assert(getSubExpr()->getType()->isBlockPointerType());
18390b57cec5SDimitry Andric goto CheckNoBasePath;
18400b57cec5SDimitry Andric
18410b57cec5SDimitry Andric case CK_ReinterpretMemberPointer:
18420b57cec5SDimitry Andric assert(getType()->isMemberPointerType());
18430b57cec5SDimitry Andric assert(getSubExpr()->getType()->isMemberPointerType());
18440b57cec5SDimitry Andric goto CheckNoBasePath;
18450b57cec5SDimitry Andric
18460b57cec5SDimitry Andric case CK_BitCast:
18470b57cec5SDimitry Andric // Arbitrary casts to C pointer types count as bitcasts.
18480b57cec5SDimitry Andric // Otherwise, we should only have block and ObjC pointer casts
18490b57cec5SDimitry Andric // here if they stay within the type kind.
18500b57cec5SDimitry Andric if (!getType()->isPointerType()) {
18510b57cec5SDimitry Andric assert(getType()->isObjCObjectPointerType() ==
18520b57cec5SDimitry Andric getSubExpr()->getType()->isObjCObjectPointerType());
18530b57cec5SDimitry Andric assert(getType()->isBlockPointerType() ==
18540b57cec5SDimitry Andric getSubExpr()->getType()->isBlockPointerType());
18550b57cec5SDimitry Andric }
18560b57cec5SDimitry Andric goto CheckNoBasePath;
18570b57cec5SDimitry Andric
18580b57cec5SDimitry Andric case CK_AnyPointerToBlockPointerCast:
18590b57cec5SDimitry Andric assert(getType()->isBlockPointerType());
18600b57cec5SDimitry Andric assert(getSubExpr()->getType()->isAnyPointerType() &&
18610b57cec5SDimitry Andric !getSubExpr()->getType()->isBlockPointerType());
18620b57cec5SDimitry Andric goto CheckNoBasePath;
18630b57cec5SDimitry Andric
18640b57cec5SDimitry Andric case CK_CopyAndAutoreleaseBlockObject:
18650b57cec5SDimitry Andric assert(getType()->isBlockPointerType());
18660b57cec5SDimitry Andric assert(getSubExpr()->getType()->isBlockPointerType());
18670b57cec5SDimitry Andric goto CheckNoBasePath;
18680b57cec5SDimitry Andric
18690b57cec5SDimitry Andric case CK_FunctionToPointerDecay:
18700b57cec5SDimitry Andric assert(getType()->isPointerType());
18710b57cec5SDimitry Andric assert(getSubExpr()->getType()->isFunctionType());
18720b57cec5SDimitry Andric goto CheckNoBasePath;
18730b57cec5SDimitry Andric
18740b57cec5SDimitry Andric case CK_AddressSpaceConversion: {
18750b57cec5SDimitry Andric auto Ty = getType();
18760b57cec5SDimitry Andric auto SETy = getSubExpr()->getType();
18770b57cec5SDimitry Andric assert(getValueKindForType(Ty) == Expr::getValueKindForType(SETy));
1878fe6060f1SDimitry Andric if (isPRValue() && !Ty->isDependentType() && !SETy->isDependentType()) {
18790b57cec5SDimitry Andric Ty = Ty->getPointeeType();
18800b57cec5SDimitry Andric SETy = SETy->getPointeeType();
18810b57cec5SDimitry Andric }
18825ffd83dbSDimitry Andric assert((Ty->isDependentType() || SETy->isDependentType()) ||
18835ffd83dbSDimitry Andric (!Ty.isNull() && !SETy.isNull() &&
18845ffd83dbSDimitry Andric Ty.getAddressSpace() != SETy.getAddressSpace()));
18850b57cec5SDimitry Andric goto CheckNoBasePath;
18860b57cec5SDimitry Andric }
18870b57cec5SDimitry Andric // These should not have an inheritance path.
18880b57cec5SDimitry Andric case CK_Dynamic:
18890b57cec5SDimitry Andric case CK_ToUnion:
18900b57cec5SDimitry Andric case CK_ArrayToPointerDecay:
18910b57cec5SDimitry Andric case CK_NullToMemberPointer:
18920b57cec5SDimitry Andric case CK_NullToPointer:
18930b57cec5SDimitry Andric case CK_ConstructorConversion:
18940b57cec5SDimitry Andric case CK_IntegralToPointer:
18950b57cec5SDimitry Andric case CK_PointerToIntegral:
18960b57cec5SDimitry Andric case CK_ToVoid:
18970b57cec5SDimitry Andric case CK_VectorSplat:
18980b57cec5SDimitry Andric case CK_IntegralCast:
18990b57cec5SDimitry Andric case CK_BooleanToSignedIntegral:
19000b57cec5SDimitry Andric case CK_IntegralToFloating:
19010b57cec5SDimitry Andric case CK_FloatingToIntegral:
19020b57cec5SDimitry Andric case CK_FloatingCast:
19030b57cec5SDimitry Andric case CK_ObjCObjectLValueCast:
19040b57cec5SDimitry Andric case CK_FloatingRealToComplex:
19050b57cec5SDimitry Andric case CK_FloatingComplexToReal:
19060b57cec5SDimitry Andric case CK_FloatingComplexCast:
19070b57cec5SDimitry Andric case CK_FloatingComplexToIntegralComplex:
19080b57cec5SDimitry Andric case CK_IntegralRealToComplex:
19090b57cec5SDimitry Andric case CK_IntegralComplexToReal:
19100b57cec5SDimitry Andric case CK_IntegralComplexCast:
19110b57cec5SDimitry Andric case CK_IntegralComplexToFloatingComplex:
19120b57cec5SDimitry Andric case CK_ARCProduceObject:
19130b57cec5SDimitry Andric case CK_ARCConsumeObject:
19140b57cec5SDimitry Andric case CK_ARCReclaimReturnedObject:
19150b57cec5SDimitry Andric case CK_ARCExtendBlockObject:
19160b57cec5SDimitry Andric case CK_ZeroToOCLOpaqueType:
19170b57cec5SDimitry Andric case CK_IntToOCLSampler:
1918e8d8bef9SDimitry Andric case CK_FloatingToFixedPoint:
1919e8d8bef9SDimitry Andric case CK_FixedPointToFloating:
19200b57cec5SDimitry Andric case CK_FixedPointCast:
19210b57cec5SDimitry Andric case CK_FixedPointToIntegral:
19220b57cec5SDimitry Andric case CK_IntegralToFixedPoint:
1923fe6060f1SDimitry Andric case CK_MatrixCast:
1924*0fca6ea1SDimitry Andric case CK_HLSLVectorTruncation:
19250b57cec5SDimitry Andric assert(!getType()->isBooleanType() && "unheralded conversion to bool");
19260b57cec5SDimitry Andric goto CheckNoBasePath;
19270b57cec5SDimitry Andric
19280b57cec5SDimitry Andric case CK_Dependent:
19290b57cec5SDimitry Andric case CK_LValueToRValue:
19300b57cec5SDimitry Andric case CK_NoOp:
19310b57cec5SDimitry Andric case CK_AtomicToNonAtomic:
19320b57cec5SDimitry Andric case CK_NonAtomicToAtomic:
19330b57cec5SDimitry Andric case CK_PointerToBoolean:
19340b57cec5SDimitry Andric case CK_IntegralToBoolean:
19350b57cec5SDimitry Andric case CK_FloatingToBoolean:
19360b57cec5SDimitry Andric case CK_MemberPointerToBoolean:
19370b57cec5SDimitry Andric case CK_FloatingComplexToBoolean:
19380b57cec5SDimitry Andric case CK_IntegralComplexToBoolean:
19390b57cec5SDimitry Andric case CK_LValueBitCast: // -> bool&
19400b57cec5SDimitry Andric case CK_LValueToRValueBitCast:
19410b57cec5SDimitry Andric case CK_UserDefinedConversion: // operator bool()
19420b57cec5SDimitry Andric case CK_BuiltinFnToFnPtr:
19430b57cec5SDimitry Andric case CK_FixedPointToBoolean:
1944*0fca6ea1SDimitry Andric case CK_HLSLArrayRValue:
19450b57cec5SDimitry Andric CheckNoBasePath:
19460b57cec5SDimitry Andric assert(path_empty() && "Cast kind should not have a base path!");
19470b57cec5SDimitry Andric break;
19480b57cec5SDimitry Andric }
19490b57cec5SDimitry Andric return true;
19500b57cec5SDimitry Andric }
19510b57cec5SDimitry Andric
getCastKindName(CastKind CK)19520b57cec5SDimitry Andric const char *CastExpr::getCastKindName(CastKind CK) {
19530b57cec5SDimitry Andric switch (CK) {
19540b57cec5SDimitry Andric #define CAST_OPERATION(Name) case CK_##Name: return #Name;
19550b57cec5SDimitry Andric #include "clang/AST/OperationKinds.def"
19560b57cec5SDimitry Andric }
19570b57cec5SDimitry Andric llvm_unreachable("Unhandled cast kind!");
19580b57cec5SDimitry Andric }
19590b57cec5SDimitry Andric
19600b57cec5SDimitry Andric namespace {
196181ad6265SDimitry Andric // Skip over implicit nodes produced as part of semantic analysis.
196281ad6265SDimitry Andric // Designed for use with IgnoreExprNodes.
ignoreImplicitSemaNodes(Expr * E)196306c3fb27SDimitry Andric static Expr *ignoreImplicitSemaNodes(Expr *E) {
19640b57cec5SDimitry Andric if (auto *Materialize = dyn_cast<MaterializeTemporaryExpr>(E))
196581ad6265SDimitry Andric return Materialize->getSubExpr();
19660b57cec5SDimitry Andric
19670b57cec5SDimitry Andric if (auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E))
196881ad6265SDimitry Andric return Binder->getSubExpr();
196981ad6265SDimitry Andric
197081ad6265SDimitry Andric if (auto *Full = dyn_cast<FullExpr>(E))
197181ad6265SDimitry Andric return Full->getSubExpr();
19720b57cec5SDimitry Andric
1973cbe9438cSDimitry Andric if (auto *CPLIE = dyn_cast<CXXParenListInitExpr>(E);
1974cbe9438cSDimitry Andric CPLIE && CPLIE->getInitExprs().size() == 1)
1975cbe9438cSDimitry Andric return CPLIE->getInitExprs()[0];
1976cbe9438cSDimitry Andric
19770b57cec5SDimitry Andric return E;
19780b57cec5SDimitry Andric }
197981ad6265SDimitry Andric } // namespace
19800b57cec5SDimitry Andric
getSubExprAsWritten()19810b57cec5SDimitry Andric Expr *CastExpr::getSubExprAsWritten() {
19820b57cec5SDimitry Andric const Expr *SubExpr = nullptr;
198381ad6265SDimitry Andric
198481ad6265SDimitry Andric for (const CastExpr *E = this; E; E = dyn_cast<ImplicitCastExpr>(SubExpr)) {
198581ad6265SDimitry Andric SubExpr = IgnoreExprNodes(E->getSubExpr(), ignoreImplicitSemaNodes);
19860b57cec5SDimitry Andric
19870b57cec5SDimitry Andric // Conversions by constructor and conversion functions have a
19880b57cec5SDimitry Andric // subexpression describing the call; strip it off.
198981ad6265SDimitry Andric if (E->getCastKind() == CK_ConstructorConversion) {
199081ad6265SDimitry Andric SubExpr = IgnoreExprNodes(cast<CXXConstructExpr>(SubExpr)->getArg(0),
199181ad6265SDimitry Andric ignoreImplicitSemaNodes);
199281ad6265SDimitry Andric } else if (E->getCastKind() == CK_UserDefinedConversion) {
199381ad6265SDimitry Andric assert((isa<CXXMemberCallExpr>(SubExpr) || isa<BlockExpr>(SubExpr)) &&
19940b57cec5SDimitry Andric "Unexpected SubExpr for CK_UserDefinedConversion.");
19950b57cec5SDimitry Andric if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SubExpr))
19960b57cec5SDimitry Andric SubExpr = MCE->getImplicitObjectArgument();
19970b57cec5SDimitry Andric }
199881ad6265SDimitry Andric }
19990b57cec5SDimitry Andric
20000b57cec5SDimitry Andric return const_cast<Expr *>(SubExpr);
20010b57cec5SDimitry Andric }
20020b57cec5SDimitry Andric
getConversionFunction() const20030b57cec5SDimitry Andric NamedDecl *CastExpr::getConversionFunction() const {
20040b57cec5SDimitry Andric const Expr *SubExpr = nullptr;
20050b57cec5SDimitry Andric
20060b57cec5SDimitry Andric for (const CastExpr *E = this; E; E = dyn_cast<ImplicitCastExpr>(SubExpr)) {
200781ad6265SDimitry Andric SubExpr = IgnoreExprNodes(E->getSubExpr(), ignoreImplicitSemaNodes);
20080b57cec5SDimitry Andric
20090b57cec5SDimitry Andric if (E->getCastKind() == CK_ConstructorConversion)
20100b57cec5SDimitry Andric return cast<CXXConstructExpr>(SubExpr)->getConstructor();
20110b57cec5SDimitry Andric
20120b57cec5SDimitry Andric if (E->getCastKind() == CK_UserDefinedConversion) {
20130b57cec5SDimitry Andric if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SubExpr))
20140b57cec5SDimitry Andric return MCE->getMethodDecl();
20150b57cec5SDimitry Andric }
20160b57cec5SDimitry Andric }
20170b57cec5SDimitry Andric
20180b57cec5SDimitry Andric return nullptr;
20190b57cec5SDimitry Andric }
20200b57cec5SDimitry Andric
path_buffer()20210b57cec5SDimitry Andric CXXBaseSpecifier **CastExpr::path_buffer() {
20220b57cec5SDimitry Andric switch (getStmtClass()) {
20230b57cec5SDimitry Andric #define ABSTRACT_STMT(x)
20240b57cec5SDimitry Andric #define CASTEXPR(Type, Base) \
20250b57cec5SDimitry Andric case Stmt::Type##Class: \
20260b57cec5SDimitry Andric return static_cast<Type *>(this)->getTrailingObjects<CXXBaseSpecifier *>();
20270b57cec5SDimitry Andric #define STMT(Type, Base)
20280b57cec5SDimitry Andric #include "clang/AST/StmtNodes.inc"
20290b57cec5SDimitry Andric default:
20300b57cec5SDimitry Andric llvm_unreachable("non-cast expressions not possible here");
20310b57cec5SDimitry Andric }
20320b57cec5SDimitry Andric }
20330b57cec5SDimitry Andric
getTargetFieldForToUnionCast(QualType unionType,QualType opType)20340b57cec5SDimitry Andric const FieldDecl *CastExpr::getTargetFieldForToUnionCast(QualType unionType,
20350b57cec5SDimitry Andric QualType opType) {
20360b57cec5SDimitry Andric auto RD = unionType->castAs<RecordType>()->getDecl();
20370b57cec5SDimitry Andric return getTargetFieldForToUnionCast(RD, opType);
20380b57cec5SDimitry Andric }
20390b57cec5SDimitry Andric
getTargetFieldForToUnionCast(const RecordDecl * RD,QualType OpType)20400b57cec5SDimitry Andric const FieldDecl *CastExpr::getTargetFieldForToUnionCast(const RecordDecl *RD,
20410b57cec5SDimitry Andric QualType OpType) {
20420b57cec5SDimitry Andric auto &Ctx = RD->getASTContext();
20430b57cec5SDimitry Andric RecordDecl::field_iterator Field, FieldEnd;
20440b57cec5SDimitry Andric for (Field = RD->field_begin(), FieldEnd = RD->field_end();
20450b57cec5SDimitry Andric Field != FieldEnd; ++Field) {
20460b57cec5SDimitry Andric if (Ctx.hasSameUnqualifiedType(Field->getType(), OpType) &&
2047*0fca6ea1SDimitry Andric !Field->isUnnamedBitField()) {
20480b57cec5SDimitry Andric return *Field;
20490b57cec5SDimitry Andric }
20500b57cec5SDimitry Andric }
20510b57cec5SDimitry Andric return nullptr;
20520b57cec5SDimitry Andric }
20530b57cec5SDimitry Andric
getTrailingFPFeatures()2054e8d8bef9SDimitry Andric FPOptionsOverride *CastExpr::getTrailingFPFeatures() {
2055e8d8bef9SDimitry Andric assert(hasStoredFPFeatures());
2056e8d8bef9SDimitry Andric switch (getStmtClass()) {
2057e8d8bef9SDimitry Andric case ImplicitCastExprClass:
2058e8d8bef9SDimitry Andric return static_cast<ImplicitCastExpr *>(this)
2059e8d8bef9SDimitry Andric ->getTrailingObjects<FPOptionsOverride>();
2060e8d8bef9SDimitry Andric case CStyleCastExprClass:
2061e8d8bef9SDimitry Andric return static_cast<CStyleCastExpr *>(this)
2062e8d8bef9SDimitry Andric ->getTrailingObjects<FPOptionsOverride>();
2063e8d8bef9SDimitry Andric case CXXFunctionalCastExprClass:
2064e8d8bef9SDimitry Andric return static_cast<CXXFunctionalCastExpr *>(this)
2065e8d8bef9SDimitry Andric ->getTrailingObjects<FPOptionsOverride>();
2066e8d8bef9SDimitry Andric case CXXStaticCastExprClass:
2067e8d8bef9SDimitry Andric return static_cast<CXXStaticCastExpr *>(this)
2068e8d8bef9SDimitry Andric ->getTrailingObjects<FPOptionsOverride>();
2069e8d8bef9SDimitry Andric default:
2070e8d8bef9SDimitry Andric llvm_unreachable("Cast does not have FPFeatures");
2071e8d8bef9SDimitry Andric }
2072e8d8bef9SDimitry Andric }
2073e8d8bef9SDimitry Andric
Create(const ASTContext & C,QualType T,CastKind Kind,Expr * Operand,const CXXCastPath * BasePath,ExprValueKind VK,FPOptionsOverride FPO)20740b57cec5SDimitry Andric ImplicitCastExpr *ImplicitCastExpr::Create(const ASTContext &C, QualType T,
20750b57cec5SDimitry Andric CastKind Kind, Expr *Operand,
20760b57cec5SDimitry Andric const CXXCastPath *BasePath,
2077e8d8bef9SDimitry Andric ExprValueKind VK,
2078e8d8bef9SDimitry Andric FPOptionsOverride FPO) {
20790b57cec5SDimitry Andric unsigned PathSize = (BasePath ? BasePath->size() : 0);
2080e8d8bef9SDimitry Andric void *Buffer =
2081e8d8bef9SDimitry Andric C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *, FPOptionsOverride>(
2082e8d8bef9SDimitry Andric PathSize, FPO.requiresTrailingStorage()));
20830b57cec5SDimitry Andric // Per C++ [conv.lval]p3, lvalue-to-rvalue conversions on class and
20840b57cec5SDimitry Andric // std::nullptr_t have special semantics not captured by CK_LValueToRValue.
20850b57cec5SDimitry Andric assert((Kind != CK_LValueToRValue ||
20860b57cec5SDimitry Andric !(T->isNullPtrType() || T->getAsCXXRecordDecl())) &&
20870b57cec5SDimitry Andric "invalid type for lvalue-to-rvalue conversion");
20880b57cec5SDimitry Andric ImplicitCastExpr *E =
2089e8d8bef9SDimitry Andric new (Buffer) ImplicitCastExpr(T, Kind, Operand, PathSize, FPO, VK);
20900b57cec5SDimitry Andric if (PathSize)
20910b57cec5SDimitry Andric std::uninitialized_copy_n(BasePath->data(), BasePath->size(),
20920b57cec5SDimitry Andric E->getTrailingObjects<CXXBaseSpecifier *>());
20930b57cec5SDimitry Andric return E;
20940b57cec5SDimitry Andric }
20950b57cec5SDimitry Andric
CreateEmpty(const ASTContext & C,unsigned PathSize,bool HasFPFeatures)20960b57cec5SDimitry Andric ImplicitCastExpr *ImplicitCastExpr::CreateEmpty(const ASTContext &C,
2097e8d8bef9SDimitry Andric unsigned PathSize,
2098e8d8bef9SDimitry Andric bool HasFPFeatures) {
2099e8d8bef9SDimitry Andric void *Buffer =
2100e8d8bef9SDimitry Andric C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *, FPOptionsOverride>(
2101e8d8bef9SDimitry Andric PathSize, HasFPFeatures));
2102e8d8bef9SDimitry Andric return new (Buffer) ImplicitCastExpr(EmptyShell(), PathSize, HasFPFeatures);
21030b57cec5SDimitry Andric }
21040b57cec5SDimitry Andric
Create(const ASTContext & C,QualType T,ExprValueKind VK,CastKind K,Expr * Op,const CXXCastPath * BasePath,FPOptionsOverride FPO,TypeSourceInfo * WrittenTy,SourceLocation L,SourceLocation R)21050b57cec5SDimitry Andric CStyleCastExpr *CStyleCastExpr::Create(const ASTContext &C, QualType T,
21060b57cec5SDimitry Andric ExprValueKind VK, CastKind K, Expr *Op,
21070b57cec5SDimitry Andric const CXXCastPath *BasePath,
2108e8d8bef9SDimitry Andric FPOptionsOverride FPO,
21090b57cec5SDimitry Andric TypeSourceInfo *WrittenTy,
21100b57cec5SDimitry Andric SourceLocation L, SourceLocation R) {
21110b57cec5SDimitry Andric unsigned PathSize = (BasePath ? BasePath->size() : 0);
2112e8d8bef9SDimitry Andric void *Buffer =
2113e8d8bef9SDimitry Andric C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *, FPOptionsOverride>(
2114e8d8bef9SDimitry Andric PathSize, FPO.requiresTrailingStorage()));
21150b57cec5SDimitry Andric CStyleCastExpr *E =
2116e8d8bef9SDimitry Andric new (Buffer) CStyleCastExpr(T, VK, K, Op, PathSize, FPO, WrittenTy, L, R);
21170b57cec5SDimitry Andric if (PathSize)
21180b57cec5SDimitry Andric std::uninitialized_copy_n(BasePath->data(), BasePath->size(),
21190b57cec5SDimitry Andric E->getTrailingObjects<CXXBaseSpecifier *>());
21200b57cec5SDimitry Andric return E;
21210b57cec5SDimitry Andric }
21220b57cec5SDimitry Andric
CreateEmpty(const ASTContext & C,unsigned PathSize,bool HasFPFeatures)21230b57cec5SDimitry Andric CStyleCastExpr *CStyleCastExpr::CreateEmpty(const ASTContext &C,
2124e8d8bef9SDimitry Andric unsigned PathSize,
2125e8d8bef9SDimitry Andric bool HasFPFeatures) {
2126e8d8bef9SDimitry Andric void *Buffer =
2127e8d8bef9SDimitry Andric C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *, FPOptionsOverride>(
2128e8d8bef9SDimitry Andric PathSize, HasFPFeatures));
2129e8d8bef9SDimitry Andric return new (Buffer) CStyleCastExpr(EmptyShell(), PathSize, HasFPFeatures);
21300b57cec5SDimitry Andric }
21310b57cec5SDimitry Andric
21320b57cec5SDimitry Andric /// getOpcodeStr - Turn an Opcode enum value into the punctuation char it
21330b57cec5SDimitry Andric /// corresponds to, e.g. "<<=".
getOpcodeStr(Opcode Op)21340b57cec5SDimitry Andric StringRef BinaryOperator::getOpcodeStr(Opcode Op) {
21350b57cec5SDimitry Andric switch (Op) {
21360b57cec5SDimitry Andric #define BINARY_OPERATION(Name, Spelling) case BO_##Name: return Spelling;
21370b57cec5SDimitry Andric #include "clang/AST/OperationKinds.def"
21380b57cec5SDimitry Andric }
21390b57cec5SDimitry Andric llvm_unreachable("Invalid OpCode!");
21400b57cec5SDimitry Andric }
21410b57cec5SDimitry Andric
21420b57cec5SDimitry Andric BinaryOperatorKind
getOverloadedOpcode(OverloadedOperatorKind OO)21430b57cec5SDimitry Andric BinaryOperator::getOverloadedOpcode(OverloadedOperatorKind OO) {
21440b57cec5SDimitry Andric switch (OO) {
21450b57cec5SDimitry Andric default: llvm_unreachable("Not an overloadable binary operator");
21460b57cec5SDimitry Andric case OO_Plus: return BO_Add;
21470b57cec5SDimitry Andric case OO_Minus: return BO_Sub;
21480b57cec5SDimitry Andric case OO_Star: return BO_Mul;
21490b57cec5SDimitry Andric case OO_Slash: return BO_Div;
21500b57cec5SDimitry Andric case OO_Percent: return BO_Rem;
21510b57cec5SDimitry Andric case OO_Caret: return BO_Xor;
21520b57cec5SDimitry Andric case OO_Amp: return BO_And;
21530b57cec5SDimitry Andric case OO_Pipe: return BO_Or;
21540b57cec5SDimitry Andric case OO_Equal: return BO_Assign;
21550b57cec5SDimitry Andric case OO_Spaceship: return BO_Cmp;
21560b57cec5SDimitry Andric case OO_Less: return BO_LT;
21570b57cec5SDimitry Andric case OO_Greater: return BO_GT;
21580b57cec5SDimitry Andric case OO_PlusEqual: return BO_AddAssign;
21590b57cec5SDimitry Andric case OO_MinusEqual: return BO_SubAssign;
21600b57cec5SDimitry Andric case OO_StarEqual: return BO_MulAssign;
21610b57cec5SDimitry Andric case OO_SlashEqual: return BO_DivAssign;
21620b57cec5SDimitry Andric case OO_PercentEqual: return BO_RemAssign;
21630b57cec5SDimitry Andric case OO_CaretEqual: return BO_XorAssign;
21640b57cec5SDimitry Andric case OO_AmpEqual: return BO_AndAssign;
21650b57cec5SDimitry Andric case OO_PipeEqual: return BO_OrAssign;
21660b57cec5SDimitry Andric case OO_LessLess: return BO_Shl;
21670b57cec5SDimitry Andric case OO_GreaterGreater: return BO_Shr;
21680b57cec5SDimitry Andric case OO_LessLessEqual: return BO_ShlAssign;
21690b57cec5SDimitry Andric case OO_GreaterGreaterEqual: return BO_ShrAssign;
21700b57cec5SDimitry Andric case OO_EqualEqual: return BO_EQ;
21710b57cec5SDimitry Andric case OO_ExclaimEqual: return BO_NE;
21720b57cec5SDimitry Andric case OO_LessEqual: return BO_LE;
21730b57cec5SDimitry Andric case OO_GreaterEqual: return BO_GE;
21740b57cec5SDimitry Andric case OO_AmpAmp: return BO_LAnd;
21750b57cec5SDimitry Andric case OO_PipePipe: return BO_LOr;
21760b57cec5SDimitry Andric case OO_Comma: return BO_Comma;
21770b57cec5SDimitry Andric case OO_ArrowStar: return BO_PtrMemI;
21780b57cec5SDimitry Andric }
21790b57cec5SDimitry Andric }
21800b57cec5SDimitry Andric
getOverloadedOperator(Opcode Opc)21810b57cec5SDimitry Andric OverloadedOperatorKind BinaryOperator::getOverloadedOperator(Opcode Opc) {
21820b57cec5SDimitry Andric static const OverloadedOperatorKind OverOps[] = {
21830b57cec5SDimitry Andric /* .* Cannot be overloaded */OO_None, OO_ArrowStar,
21840b57cec5SDimitry Andric OO_Star, OO_Slash, OO_Percent,
21850b57cec5SDimitry Andric OO_Plus, OO_Minus,
21860b57cec5SDimitry Andric OO_LessLess, OO_GreaterGreater,
21870b57cec5SDimitry Andric OO_Spaceship,
21880b57cec5SDimitry Andric OO_Less, OO_Greater, OO_LessEqual, OO_GreaterEqual,
21890b57cec5SDimitry Andric OO_EqualEqual, OO_ExclaimEqual,
21900b57cec5SDimitry Andric OO_Amp,
21910b57cec5SDimitry Andric OO_Caret,
21920b57cec5SDimitry Andric OO_Pipe,
21930b57cec5SDimitry Andric OO_AmpAmp,
21940b57cec5SDimitry Andric OO_PipePipe,
21950b57cec5SDimitry Andric OO_Equal, OO_StarEqual,
21960b57cec5SDimitry Andric OO_SlashEqual, OO_PercentEqual,
21970b57cec5SDimitry Andric OO_PlusEqual, OO_MinusEqual,
21980b57cec5SDimitry Andric OO_LessLessEqual, OO_GreaterGreaterEqual,
21990b57cec5SDimitry Andric OO_AmpEqual, OO_CaretEqual,
22000b57cec5SDimitry Andric OO_PipeEqual,
22010b57cec5SDimitry Andric OO_Comma
22020b57cec5SDimitry Andric };
22030b57cec5SDimitry Andric return OverOps[Opc];
22040b57cec5SDimitry Andric }
22050b57cec5SDimitry Andric
isNullPointerArithmeticExtension(ASTContext & Ctx,Opcode Opc,const Expr * LHS,const Expr * RHS)22060b57cec5SDimitry Andric bool BinaryOperator::isNullPointerArithmeticExtension(ASTContext &Ctx,
22070b57cec5SDimitry Andric Opcode Opc,
220806c3fb27SDimitry Andric const Expr *LHS,
220906c3fb27SDimitry Andric const Expr *RHS) {
22100b57cec5SDimitry Andric if (Opc != BO_Add)
22110b57cec5SDimitry Andric return false;
22120b57cec5SDimitry Andric
22130b57cec5SDimitry Andric // Check that we have one pointer and one integer operand.
221406c3fb27SDimitry Andric const Expr *PExp;
22150b57cec5SDimitry Andric if (LHS->getType()->isPointerType()) {
22160b57cec5SDimitry Andric if (!RHS->getType()->isIntegerType())
22170b57cec5SDimitry Andric return false;
22180b57cec5SDimitry Andric PExp = LHS;
22190b57cec5SDimitry Andric } else if (RHS->getType()->isPointerType()) {
22200b57cec5SDimitry Andric if (!LHS->getType()->isIntegerType())
22210b57cec5SDimitry Andric return false;
22220b57cec5SDimitry Andric PExp = RHS;
22230b57cec5SDimitry Andric } else {
22240b57cec5SDimitry Andric return false;
22250b57cec5SDimitry Andric }
22260b57cec5SDimitry Andric
22270b57cec5SDimitry Andric // Check that the pointer is a nullptr.
22280b57cec5SDimitry Andric if (!PExp->IgnoreParenCasts()
22290b57cec5SDimitry Andric ->isNullPointerConstant(Ctx, Expr::NPC_ValueDependentIsNotNull))
22300b57cec5SDimitry Andric return false;
22310b57cec5SDimitry Andric
22320b57cec5SDimitry Andric // Check that the pointee type is char-sized.
22330b57cec5SDimitry Andric const PointerType *PTy = PExp->getType()->getAs<PointerType>();
22340b57cec5SDimitry Andric if (!PTy || !PTy->getPointeeType()->isCharType())
22350b57cec5SDimitry Andric return false;
22360b57cec5SDimitry Andric
22370b57cec5SDimitry Andric return true;
22380b57cec5SDimitry Andric }
22390b57cec5SDimitry Andric
SourceLocExpr(const ASTContext & Ctx,SourceLocIdentKind Kind,QualType ResultTy,SourceLocation BLoc,SourceLocation RParenLoc,DeclContext * ParentContext)22405f757f3fSDimitry Andric SourceLocExpr::SourceLocExpr(const ASTContext &Ctx, SourceLocIdentKind Kind,
224181ad6265SDimitry Andric QualType ResultTy, SourceLocation BLoc,
224281ad6265SDimitry Andric SourceLocation RParenLoc,
22430b57cec5SDimitry Andric DeclContext *ParentContext)
224481ad6265SDimitry Andric : Expr(SourceLocExprClass, ResultTy, VK_PRValue, OK_Ordinary),
22450b57cec5SDimitry Andric BuiltinLoc(BLoc), RParenLoc(RParenLoc), ParentContext(ParentContext) {
22465f757f3fSDimitry Andric SourceLocExprBits.Kind = llvm::to_underlying(Kind);
22477a6dacacSDimitry Andric // In dependent contexts, function names may change.
22487a6dacacSDimitry Andric setDependence(MayBeDependent(Kind) && ParentContext->isDependentContext()
22497a6dacacSDimitry Andric ? ExprDependence::Value
22507a6dacacSDimitry Andric : ExprDependence::None);
22510b57cec5SDimitry Andric }
22520b57cec5SDimitry Andric
getBuiltinStr() const22530b57cec5SDimitry Andric StringRef SourceLocExpr::getBuiltinStr() const {
22540b57cec5SDimitry Andric switch (getIdentKind()) {
22555f757f3fSDimitry Andric case SourceLocIdentKind::File:
22560b57cec5SDimitry Andric return "__builtin_FILE";
22575f757f3fSDimitry Andric case SourceLocIdentKind::FileName:
225806c3fb27SDimitry Andric return "__builtin_FILE_NAME";
22595f757f3fSDimitry Andric case SourceLocIdentKind::Function:
22600b57cec5SDimitry Andric return "__builtin_FUNCTION";
22615f757f3fSDimitry Andric case SourceLocIdentKind::FuncSig:
226206c3fb27SDimitry Andric return "__builtin_FUNCSIG";
22635f757f3fSDimitry Andric case SourceLocIdentKind::Line:
22640b57cec5SDimitry Andric return "__builtin_LINE";
22655f757f3fSDimitry Andric case SourceLocIdentKind::Column:
22660b57cec5SDimitry Andric return "__builtin_COLUMN";
22675f757f3fSDimitry Andric case SourceLocIdentKind::SourceLocStruct:
226881ad6265SDimitry Andric return "__builtin_source_location";
22690b57cec5SDimitry Andric }
22700b57cec5SDimitry Andric llvm_unreachable("unexpected IdentKind!");
22710b57cec5SDimitry Andric }
22720b57cec5SDimitry Andric
EvaluateInContext(const ASTContext & Ctx,const Expr * DefaultExpr) const22730b57cec5SDimitry Andric APValue SourceLocExpr::EvaluateInContext(const ASTContext &Ctx,
22740b57cec5SDimitry Andric const Expr *DefaultExpr) const {
22750b57cec5SDimitry Andric SourceLocation Loc;
22760b57cec5SDimitry Andric const DeclContext *Context;
22770b57cec5SDimitry Andric
227806c3fb27SDimitry Andric if (const auto *DIE = dyn_cast_if_present<CXXDefaultInitExpr>(DefaultExpr)) {
227906c3fb27SDimitry Andric Loc = DIE->getUsedLocation();
228006c3fb27SDimitry Andric Context = DIE->getUsedContext();
228106c3fb27SDimitry Andric } else if (const auto *DAE =
228206c3fb27SDimitry Andric dyn_cast_if_present<CXXDefaultArgExpr>(DefaultExpr)) {
228306c3fb27SDimitry Andric Loc = DAE->getUsedLocation();
228406c3fb27SDimitry Andric Context = DAE->getUsedContext();
228506c3fb27SDimitry Andric } else {
228606c3fb27SDimitry Andric Loc = getLocation();
228706c3fb27SDimitry Andric Context = getParentContext();
228806c3fb27SDimitry Andric }
22890b57cec5SDimitry Andric
22900b57cec5SDimitry Andric PresumedLoc PLoc = Ctx.getSourceManager().getPresumedLoc(
22910b57cec5SDimitry Andric Ctx.getSourceManager().getExpansionRange(Loc).getEnd());
22920b57cec5SDimitry Andric
22930b57cec5SDimitry Andric auto MakeStringLiteral = [&](StringRef Tmp) {
22940b57cec5SDimitry Andric using LValuePathEntry = APValue::LValuePathEntry;
22950b57cec5SDimitry Andric StringLiteral *Res = Ctx.getPredefinedStringLiteralFromCache(Tmp);
22960b57cec5SDimitry Andric // Decay the string to a pointer to the first character.
22970b57cec5SDimitry Andric LValuePathEntry Path[1] = {LValuePathEntry::ArrayIndex(0)};
22980b57cec5SDimitry Andric return APValue(Res, CharUnits::Zero(), Path, /*OnePastTheEnd=*/false);
22990b57cec5SDimitry Andric };
23000b57cec5SDimitry Andric
23010b57cec5SDimitry Andric switch (getIdentKind()) {
23025f757f3fSDimitry Andric case SourceLocIdentKind::FileName: {
230306c3fb27SDimitry Andric // __builtin_FILE_NAME() is a Clang-specific extension that expands to the
230406c3fb27SDimitry Andric // the last part of __builtin_FILE().
230506c3fb27SDimitry Andric SmallString<256> FileName;
230606c3fb27SDimitry Andric clang::Preprocessor::processPathToFileName(
230706c3fb27SDimitry Andric FileName, PLoc, Ctx.getLangOpts(), Ctx.getTargetInfo());
230806c3fb27SDimitry Andric return MakeStringLiteral(FileName);
230906c3fb27SDimitry Andric }
23105f757f3fSDimitry Andric case SourceLocIdentKind::File: {
23116e75b2fbSDimitry Andric SmallString<256> Path(PLoc.getFilename());
231281ad6265SDimitry Andric clang::Preprocessor::processPathForFileMacro(Path, Ctx.getLangOpts(),
231381ad6265SDimitry Andric Ctx.getTargetInfo());
23146e75b2fbSDimitry Andric return MakeStringLiteral(Path);
23156e75b2fbSDimitry Andric }
23165f757f3fSDimitry Andric case SourceLocIdentKind::Function:
23175f757f3fSDimitry Andric case SourceLocIdentKind::FuncSig: {
231881ad6265SDimitry Andric const auto *CurDecl = dyn_cast<Decl>(Context);
23195f757f3fSDimitry Andric const auto Kind = getIdentKind() == SourceLocIdentKind::Function
23205f757f3fSDimitry Andric ? PredefinedIdentKind::Function
23215f757f3fSDimitry Andric : PredefinedIdentKind::FuncSig;
23220b57cec5SDimitry Andric return MakeStringLiteral(
232306c3fb27SDimitry Andric CurDecl ? PredefinedExpr::ComputeName(Kind, CurDecl) : std::string(""));
23240b57cec5SDimitry Andric }
23255f757f3fSDimitry Andric case SourceLocIdentKind::Line:
232606c3fb27SDimitry Andric return APValue(Ctx.MakeIntValue(PLoc.getLine(), Ctx.UnsignedIntTy));
23275f757f3fSDimitry Andric case SourceLocIdentKind::Column:
232806c3fb27SDimitry Andric return APValue(Ctx.MakeIntValue(PLoc.getColumn(), Ctx.UnsignedIntTy));
23295f757f3fSDimitry Andric case SourceLocIdentKind::SourceLocStruct: {
233081ad6265SDimitry Andric // Fill in a std::source_location::__impl structure, by creating an
233181ad6265SDimitry Andric // artificial file-scoped CompoundLiteralExpr, and returning a pointer to
233281ad6265SDimitry Andric // that.
233381ad6265SDimitry Andric const CXXRecordDecl *ImplDecl = getType()->getPointeeCXXRecordDecl();
233481ad6265SDimitry Andric assert(ImplDecl);
233581ad6265SDimitry Andric
233681ad6265SDimitry Andric // Construct an APValue for the __impl struct, and get or create a Decl
233781ad6265SDimitry Andric // corresponding to that. Note that we've already verified that the shape of
233881ad6265SDimitry Andric // the ImplDecl type is as expected.
233981ad6265SDimitry Andric
234081ad6265SDimitry Andric APValue Value(APValue::UninitStruct(), 0, 4);
234106c3fb27SDimitry Andric for (const FieldDecl *F : ImplDecl->fields()) {
234281ad6265SDimitry Andric StringRef Name = F->getName();
234381ad6265SDimitry Andric if (Name == "_M_file_name") {
234481ad6265SDimitry Andric SmallString<256> Path(PLoc.getFilename());
234581ad6265SDimitry Andric clang::Preprocessor::processPathForFileMacro(Path, Ctx.getLangOpts(),
234681ad6265SDimitry Andric Ctx.getTargetInfo());
234781ad6265SDimitry Andric Value.getStructField(F->getFieldIndex()) = MakeStringLiteral(Path);
234881ad6265SDimitry Andric } else if (Name == "_M_function_name") {
234981ad6265SDimitry Andric // Note: this emits the PrettyFunction name -- different than what
235081ad6265SDimitry Andric // __builtin_FUNCTION() above returns!
235181ad6265SDimitry Andric const auto *CurDecl = dyn_cast<Decl>(Context);
235281ad6265SDimitry Andric Value.getStructField(F->getFieldIndex()) = MakeStringLiteral(
235381ad6265SDimitry Andric CurDecl && !isa<TranslationUnitDecl>(CurDecl)
235481ad6265SDimitry Andric ? StringRef(PredefinedExpr::ComputeName(
23555f757f3fSDimitry Andric PredefinedIdentKind::PrettyFunction, CurDecl))
235681ad6265SDimitry Andric : "");
235781ad6265SDimitry Andric } else if (Name == "_M_line") {
235806c3fb27SDimitry Andric llvm::APSInt IntVal = Ctx.MakeIntValue(PLoc.getLine(), F->getType());
235981ad6265SDimitry Andric Value.getStructField(F->getFieldIndex()) = APValue(IntVal);
236081ad6265SDimitry Andric } else if (Name == "_M_column") {
236106c3fb27SDimitry Andric llvm::APSInt IntVal = Ctx.MakeIntValue(PLoc.getColumn(), F->getType());
236281ad6265SDimitry Andric Value.getStructField(F->getFieldIndex()) = APValue(IntVal);
236381ad6265SDimitry Andric }
236481ad6265SDimitry Andric }
236581ad6265SDimitry Andric
236681ad6265SDimitry Andric UnnamedGlobalConstantDecl *GV =
236781ad6265SDimitry Andric Ctx.getUnnamedGlobalConstantDecl(getType()->getPointeeType(), Value);
236881ad6265SDimitry Andric
236981ad6265SDimitry Andric return APValue(GV, CharUnits::Zero(), ArrayRef<APValue::LValuePathEntry>{},
237081ad6265SDimitry Andric false);
237181ad6265SDimitry Andric }
23720b57cec5SDimitry Andric }
23730b57cec5SDimitry Andric llvm_unreachable("unhandled case");
23740b57cec5SDimitry Andric }
23750b57cec5SDimitry Andric
EmbedExpr(const ASTContext & Ctx,SourceLocation Loc,EmbedDataStorage * Data,unsigned Begin,unsigned NumOfElements)2376*0fca6ea1SDimitry Andric EmbedExpr::EmbedExpr(const ASTContext &Ctx, SourceLocation Loc,
2377*0fca6ea1SDimitry Andric EmbedDataStorage *Data, unsigned Begin,
2378*0fca6ea1SDimitry Andric unsigned NumOfElements)
2379*0fca6ea1SDimitry Andric : Expr(EmbedExprClass, Ctx.IntTy, VK_PRValue, OK_Ordinary),
2380*0fca6ea1SDimitry Andric EmbedKeywordLoc(Loc), Ctx(&Ctx), Data(Data), Begin(Begin),
2381*0fca6ea1SDimitry Andric NumOfElements(NumOfElements) {
2382*0fca6ea1SDimitry Andric setDependence(ExprDependence::None);
2383*0fca6ea1SDimitry Andric FakeChildNode = IntegerLiteral::Create(
2384*0fca6ea1SDimitry Andric Ctx, llvm::APInt::getZero(Ctx.getTypeSize(getType())), getType(), Loc);
2385*0fca6ea1SDimitry Andric }
2386*0fca6ea1SDimitry Andric
InitListExpr(const ASTContext & C,SourceLocation lbraceloc,ArrayRef<Expr * > initExprs,SourceLocation rbraceloc)23870b57cec5SDimitry Andric InitListExpr::InitListExpr(const ASTContext &C, SourceLocation lbraceloc,
23880b57cec5SDimitry Andric ArrayRef<Expr *> initExprs, SourceLocation rbraceloc)
2389fe6060f1SDimitry Andric : Expr(InitListExprClass, QualType(), VK_PRValue, OK_Ordinary),
23905ffd83dbSDimitry Andric InitExprs(C, initExprs.size()), LBraceLoc(lbraceloc),
23915ffd83dbSDimitry Andric RBraceLoc(rbraceloc), AltForm(nullptr, true) {
23920b57cec5SDimitry Andric sawArrayRangeDesignator(false);
23930b57cec5SDimitry Andric InitExprs.insert(C, InitExprs.end(), initExprs.begin(), initExprs.end());
23945ffd83dbSDimitry Andric
23955ffd83dbSDimitry Andric setDependence(computeDependence(this));
23960b57cec5SDimitry Andric }
23970b57cec5SDimitry Andric
reserveInits(const ASTContext & C,unsigned NumInits)23980b57cec5SDimitry Andric void InitListExpr::reserveInits(const ASTContext &C, unsigned NumInits) {
23990b57cec5SDimitry Andric if (NumInits > InitExprs.size())
24000b57cec5SDimitry Andric InitExprs.reserve(C, NumInits);
24010b57cec5SDimitry Andric }
24020b57cec5SDimitry Andric
resizeInits(const ASTContext & C,unsigned NumInits)24030b57cec5SDimitry Andric void InitListExpr::resizeInits(const ASTContext &C, unsigned NumInits) {
24040b57cec5SDimitry Andric InitExprs.resize(C, NumInits, nullptr);
24050b57cec5SDimitry Andric }
24060b57cec5SDimitry Andric
updateInit(const ASTContext & C,unsigned Init,Expr * expr)24070b57cec5SDimitry Andric Expr *InitListExpr::updateInit(const ASTContext &C, unsigned Init, Expr *expr) {
24080b57cec5SDimitry Andric if (Init >= InitExprs.size()) {
24090b57cec5SDimitry Andric InitExprs.insert(C, InitExprs.end(), Init - InitExprs.size() + 1, nullptr);
24100b57cec5SDimitry Andric setInit(Init, expr);
24110b57cec5SDimitry Andric return nullptr;
24120b57cec5SDimitry Andric }
24130b57cec5SDimitry Andric
24140b57cec5SDimitry Andric Expr *Result = cast_or_null<Expr>(InitExprs[Init]);
24150b57cec5SDimitry Andric setInit(Init, expr);
24160b57cec5SDimitry Andric return Result;
24170b57cec5SDimitry Andric }
24180b57cec5SDimitry Andric
setArrayFiller(Expr * filler)24190b57cec5SDimitry Andric void InitListExpr::setArrayFiller(Expr *filler) {
24200b57cec5SDimitry Andric assert(!hasArrayFiller() && "Filler already set!");
24210b57cec5SDimitry Andric ArrayFillerOrUnionFieldInit = filler;
24220b57cec5SDimitry Andric // Fill out any "holes" in the array due to designated initializers.
24230b57cec5SDimitry Andric Expr **inits = getInits();
24240b57cec5SDimitry Andric for (unsigned i = 0, e = getNumInits(); i != e; ++i)
24250b57cec5SDimitry Andric if (inits[i] == nullptr)
24260b57cec5SDimitry Andric inits[i] = filler;
24270b57cec5SDimitry Andric }
24280b57cec5SDimitry Andric
isStringLiteralInit() const24290b57cec5SDimitry Andric bool InitListExpr::isStringLiteralInit() const {
24300b57cec5SDimitry Andric if (getNumInits() != 1)
24310b57cec5SDimitry Andric return false;
24320b57cec5SDimitry Andric const ArrayType *AT = getType()->getAsArrayTypeUnsafe();
24330b57cec5SDimitry Andric if (!AT || !AT->getElementType()->isIntegerType())
24340b57cec5SDimitry Andric return false;
24350b57cec5SDimitry Andric // It is possible for getInit() to return null.
24360b57cec5SDimitry Andric const Expr *Init = getInit(0);
24370b57cec5SDimitry Andric if (!Init)
24380b57cec5SDimitry Andric return false;
2439349cc55cSDimitry Andric Init = Init->IgnoreParenImpCasts();
24400b57cec5SDimitry Andric return isa<StringLiteral>(Init) || isa<ObjCEncodeExpr>(Init);
24410b57cec5SDimitry Andric }
24420b57cec5SDimitry Andric
isTransparent() const24430b57cec5SDimitry Andric bool InitListExpr::isTransparent() const {
24440b57cec5SDimitry Andric assert(isSemanticForm() && "syntactic form never semantically transparent");
24450b57cec5SDimitry Andric
24460b57cec5SDimitry Andric // A glvalue InitListExpr is always just sugar.
24470b57cec5SDimitry Andric if (isGLValue()) {
24480b57cec5SDimitry Andric assert(getNumInits() == 1 && "multiple inits in glvalue init list");
24490b57cec5SDimitry Andric return true;
24500b57cec5SDimitry Andric }
24510b57cec5SDimitry Andric
24520b57cec5SDimitry Andric // Otherwise, we're sugar if and only if we have exactly one initializer that
24530b57cec5SDimitry Andric // is of the same type.
24540b57cec5SDimitry Andric if (getNumInits() != 1 || !getInit(0))
24550b57cec5SDimitry Andric return false;
24560b57cec5SDimitry Andric
24570b57cec5SDimitry Andric // Don't confuse aggregate initialization of a struct X { X &x; }; with a
24580b57cec5SDimitry Andric // transparent struct copy.
2459fe6060f1SDimitry Andric if (!getInit(0)->isPRValue() && getType()->isRecordType())
24600b57cec5SDimitry Andric return false;
24610b57cec5SDimitry Andric
24620b57cec5SDimitry Andric return getType().getCanonicalType() ==
24630b57cec5SDimitry Andric getInit(0)->getType().getCanonicalType();
24640b57cec5SDimitry Andric }
24650b57cec5SDimitry Andric
isIdiomaticZeroInitializer(const LangOptions & LangOpts) const24660b57cec5SDimitry Andric bool InitListExpr::isIdiomaticZeroInitializer(const LangOptions &LangOpts) const {
24670b57cec5SDimitry Andric assert(isSyntacticForm() && "only test syntactic form as zero initializer");
24680b57cec5SDimitry Andric
24690b57cec5SDimitry Andric if (LangOpts.CPlusPlus || getNumInits() != 1 || !getInit(0)) {
24700b57cec5SDimitry Andric return false;
24710b57cec5SDimitry Andric }
24720b57cec5SDimitry Andric
24730b57cec5SDimitry Andric const IntegerLiteral *Lit = dyn_cast<IntegerLiteral>(getInit(0)->IgnoreImplicit());
24740b57cec5SDimitry Andric return Lit && Lit->getValue() == 0;
24750b57cec5SDimitry Andric }
24760b57cec5SDimitry Andric
getBeginLoc() const24770b57cec5SDimitry Andric SourceLocation InitListExpr::getBeginLoc() const {
24780b57cec5SDimitry Andric if (InitListExpr *SyntacticForm = getSyntacticForm())
24790b57cec5SDimitry Andric return SyntacticForm->getBeginLoc();
24800b57cec5SDimitry Andric SourceLocation Beg = LBraceLoc;
24810b57cec5SDimitry Andric if (Beg.isInvalid()) {
24820b57cec5SDimitry Andric // Find the first non-null initializer.
24830b57cec5SDimitry Andric for (InitExprsTy::const_iterator I = InitExprs.begin(),
24840b57cec5SDimitry Andric E = InitExprs.end();
24850b57cec5SDimitry Andric I != E; ++I) {
24860b57cec5SDimitry Andric if (Stmt *S = *I) {
24870b57cec5SDimitry Andric Beg = S->getBeginLoc();
24880b57cec5SDimitry Andric break;
24890b57cec5SDimitry Andric }
24900b57cec5SDimitry Andric }
24910b57cec5SDimitry Andric }
24920b57cec5SDimitry Andric return Beg;
24930b57cec5SDimitry Andric }
24940b57cec5SDimitry Andric
getEndLoc() const24950b57cec5SDimitry Andric SourceLocation InitListExpr::getEndLoc() const {
24960b57cec5SDimitry Andric if (InitListExpr *SyntacticForm = getSyntacticForm())
24970b57cec5SDimitry Andric return SyntacticForm->getEndLoc();
24980b57cec5SDimitry Andric SourceLocation End = RBraceLoc;
24990b57cec5SDimitry Andric if (End.isInvalid()) {
25000b57cec5SDimitry Andric // Find the first non-null initializer from the end.
2501349cc55cSDimitry Andric for (Stmt *S : llvm::reverse(InitExprs)) {
2502349cc55cSDimitry Andric if (S) {
25030b57cec5SDimitry Andric End = S->getEndLoc();
25040b57cec5SDimitry Andric break;
25050b57cec5SDimitry Andric }
25060b57cec5SDimitry Andric }
25070b57cec5SDimitry Andric }
25080b57cec5SDimitry Andric return End;
25090b57cec5SDimitry Andric }
25100b57cec5SDimitry Andric
25110b57cec5SDimitry Andric /// getFunctionType - Return the underlying function type for this block.
25120b57cec5SDimitry Andric ///
getFunctionType() const25130b57cec5SDimitry Andric const FunctionProtoType *BlockExpr::getFunctionType() const {
25140b57cec5SDimitry Andric // The block pointer is never sugared, but the function type might be.
25150b57cec5SDimitry Andric return cast<BlockPointerType>(getType())
25160b57cec5SDimitry Andric ->getPointeeType()->castAs<FunctionProtoType>();
25170b57cec5SDimitry Andric }
25180b57cec5SDimitry Andric
getCaretLocation() const25190b57cec5SDimitry Andric SourceLocation BlockExpr::getCaretLocation() const {
25200b57cec5SDimitry Andric return TheBlock->getCaretLocation();
25210b57cec5SDimitry Andric }
getBody() const25220b57cec5SDimitry Andric const Stmt *BlockExpr::getBody() const {
25230b57cec5SDimitry Andric return TheBlock->getBody();
25240b57cec5SDimitry Andric }
getBody()25250b57cec5SDimitry Andric Stmt *BlockExpr::getBody() {
25260b57cec5SDimitry Andric return TheBlock->getBody();
25270b57cec5SDimitry Andric }
25280b57cec5SDimitry Andric
25290b57cec5SDimitry Andric
25300b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
25310b57cec5SDimitry Andric // Generic Expression Routines
25320b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
25330b57cec5SDimitry Andric
isReadIfDiscardedInCPlusPlus11() const25345ffd83dbSDimitry Andric bool Expr::isReadIfDiscardedInCPlusPlus11() const {
25355ffd83dbSDimitry Andric // In C++11, discarded-value expressions of a certain form are special,
25365ffd83dbSDimitry Andric // according to [expr]p10:
25375ffd83dbSDimitry Andric // The lvalue-to-rvalue conversion (4.1) is applied only if the
2538fe6060f1SDimitry Andric // expression is a glvalue of volatile-qualified type and it has
25395ffd83dbSDimitry Andric // one of the following forms:
25405ffd83dbSDimitry Andric if (!isGLValue() || !getType().isVolatileQualified())
25415ffd83dbSDimitry Andric return false;
25425ffd83dbSDimitry Andric
25435ffd83dbSDimitry Andric const Expr *E = IgnoreParens();
25445ffd83dbSDimitry Andric
25455ffd83dbSDimitry Andric // - id-expression (5.1.1),
25465ffd83dbSDimitry Andric if (isa<DeclRefExpr>(E))
25475ffd83dbSDimitry Andric return true;
25485ffd83dbSDimitry Andric
25495ffd83dbSDimitry Andric // - subscripting (5.2.1),
25505ffd83dbSDimitry Andric if (isa<ArraySubscriptExpr>(E))
25515ffd83dbSDimitry Andric return true;
25525ffd83dbSDimitry Andric
25535ffd83dbSDimitry Andric // - class member access (5.2.5),
25545ffd83dbSDimitry Andric if (isa<MemberExpr>(E))
25555ffd83dbSDimitry Andric return true;
25565ffd83dbSDimitry Andric
25575ffd83dbSDimitry Andric // - indirection (5.3.1),
25585ffd83dbSDimitry Andric if (auto *UO = dyn_cast<UnaryOperator>(E))
25595ffd83dbSDimitry Andric if (UO->getOpcode() == UO_Deref)
25605ffd83dbSDimitry Andric return true;
25615ffd83dbSDimitry Andric
25625ffd83dbSDimitry Andric if (auto *BO = dyn_cast<BinaryOperator>(E)) {
25635ffd83dbSDimitry Andric // - pointer-to-member operation (5.5),
25645ffd83dbSDimitry Andric if (BO->isPtrMemOp())
25655ffd83dbSDimitry Andric return true;
25665ffd83dbSDimitry Andric
25675ffd83dbSDimitry Andric // - comma expression (5.18) where the right operand is one of the above.
25685ffd83dbSDimitry Andric if (BO->getOpcode() == BO_Comma)
25695ffd83dbSDimitry Andric return BO->getRHS()->isReadIfDiscardedInCPlusPlus11();
25705ffd83dbSDimitry Andric }
25715ffd83dbSDimitry Andric
25725ffd83dbSDimitry Andric // - conditional expression (5.16) where both the second and the third
25735ffd83dbSDimitry Andric // operands are one of the above, or
25745ffd83dbSDimitry Andric if (auto *CO = dyn_cast<ConditionalOperator>(E))
25755ffd83dbSDimitry Andric return CO->getTrueExpr()->isReadIfDiscardedInCPlusPlus11() &&
25765ffd83dbSDimitry Andric CO->getFalseExpr()->isReadIfDiscardedInCPlusPlus11();
25775ffd83dbSDimitry Andric // The related edge case of "*x ?: *x".
25785ffd83dbSDimitry Andric if (auto *BCO =
25795ffd83dbSDimitry Andric dyn_cast<BinaryConditionalOperator>(E)) {
25805ffd83dbSDimitry Andric if (auto *OVE = dyn_cast<OpaqueValueExpr>(BCO->getTrueExpr()))
25815ffd83dbSDimitry Andric return OVE->getSourceExpr()->isReadIfDiscardedInCPlusPlus11() &&
25825ffd83dbSDimitry Andric BCO->getFalseExpr()->isReadIfDiscardedInCPlusPlus11();
25835ffd83dbSDimitry Andric }
25845ffd83dbSDimitry Andric
25855ffd83dbSDimitry Andric // Objective-C++ extensions to the rule.
258681ad6265SDimitry Andric if (isa<ObjCIvarRefExpr>(E))
25875ffd83dbSDimitry Andric return true;
258881ad6265SDimitry Andric if (const auto *POE = dyn_cast<PseudoObjectExpr>(E)) {
258981ad6265SDimitry Andric if (isa<ObjCPropertyRefExpr, ObjCSubscriptRefExpr>(POE->getSyntacticForm()))
259081ad6265SDimitry Andric return true;
259181ad6265SDimitry Andric }
25925ffd83dbSDimitry Andric
25935ffd83dbSDimitry Andric return false;
25945ffd83dbSDimitry Andric }
25955ffd83dbSDimitry Andric
25960b57cec5SDimitry Andric /// isUnusedResultAWarning - Return true if this immediate expression should
25970b57cec5SDimitry Andric /// be warned about if the result is unused. If so, fill in Loc and Ranges
25980b57cec5SDimitry Andric /// with location to warn on and the source range[s] to report with the
25990b57cec5SDimitry Andric /// warning.
isUnusedResultAWarning(const Expr * & WarnE,SourceLocation & Loc,SourceRange & R1,SourceRange & R2,ASTContext & Ctx) const26000b57cec5SDimitry Andric bool Expr::isUnusedResultAWarning(const Expr *&WarnE, SourceLocation &Loc,
26010b57cec5SDimitry Andric SourceRange &R1, SourceRange &R2,
26020b57cec5SDimitry Andric ASTContext &Ctx) const {
26030b57cec5SDimitry Andric // Don't warn if the expr is type dependent. The type could end up
26040b57cec5SDimitry Andric // instantiating to void.
26050b57cec5SDimitry Andric if (isTypeDependent())
26060b57cec5SDimitry Andric return false;
26070b57cec5SDimitry Andric
26080b57cec5SDimitry Andric switch (getStmtClass()) {
26090b57cec5SDimitry Andric default:
26100b57cec5SDimitry Andric if (getType()->isVoidType())
26110b57cec5SDimitry Andric return false;
26120b57cec5SDimitry Andric WarnE = this;
26130b57cec5SDimitry Andric Loc = getExprLoc();
26140b57cec5SDimitry Andric R1 = getSourceRange();
26150b57cec5SDimitry Andric return true;
26160b57cec5SDimitry Andric case ParenExprClass:
26170b57cec5SDimitry Andric return cast<ParenExpr>(this)->getSubExpr()->
26180b57cec5SDimitry Andric isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx);
26190b57cec5SDimitry Andric case GenericSelectionExprClass:
26200b57cec5SDimitry Andric return cast<GenericSelectionExpr>(this)->getResultExpr()->
26210b57cec5SDimitry Andric isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx);
26220b57cec5SDimitry Andric case CoawaitExprClass:
26230b57cec5SDimitry Andric case CoyieldExprClass:
26240b57cec5SDimitry Andric return cast<CoroutineSuspendExpr>(this)->getResumeExpr()->
26250b57cec5SDimitry Andric isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx);
26260b57cec5SDimitry Andric case ChooseExprClass:
26270b57cec5SDimitry Andric return cast<ChooseExpr>(this)->getChosenSubExpr()->
26280b57cec5SDimitry Andric isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx);
26290b57cec5SDimitry Andric case UnaryOperatorClass: {
26300b57cec5SDimitry Andric const UnaryOperator *UO = cast<UnaryOperator>(this);
26310b57cec5SDimitry Andric
26320b57cec5SDimitry Andric switch (UO->getOpcode()) {
26330b57cec5SDimitry Andric case UO_Plus:
26340b57cec5SDimitry Andric case UO_Minus:
26350b57cec5SDimitry Andric case UO_AddrOf:
26360b57cec5SDimitry Andric case UO_Not:
26370b57cec5SDimitry Andric case UO_LNot:
26380b57cec5SDimitry Andric case UO_Deref:
26390b57cec5SDimitry Andric break;
26400b57cec5SDimitry Andric case UO_Coawait:
26410b57cec5SDimitry Andric // This is just the 'operator co_await' call inside the guts of a
26420b57cec5SDimitry Andric // dependent co_await call.
26430b57cec5SDimitry Andric case UO_PostInc:
26440b57cec5SDimitry Andric case UO_PostDec:
26450b57cec5SDimitry Andric case UO_PreInc:
26460b57cec5SDimitry Andric case UO_PreDec: // ++/--
26470b57cec5SDimitry Andric return false; // Not a warning.
26480b57cec5SDimitry Andric case UO_Real:
26490b57cec5SDimitry Andric case UO_Imag:
26500b57cec5SDimitry Andric // accessing a piece of a volatile complex is a side-effect.
26510b57cec5SDimitry Andric if (Ctx.getCanonicalType(UO->getSubExpr()->getType())
26520b57cec5SDimitry Andric .isVolatileQualified())
26530b57cec5SDimitry Andric return false;
26540b57cec5SDimitry Andric break;
26550b57cec5SDimitry Andric case UO_Extension:
26560b57cec5SDimitry Andric return UO->getSubExpr()->isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx);
26570b57cec5SDimitry Andric }
26580b57cec5SDimitry Andric WarnE = this;
26590b57cec5SDimitry Andric Loc = UO->getOperatorLoc();
26600b57cec5SDimitry Andric R1 = UO->getSubExpr()->getSourceRange();
26610b57cec5SDimitry Andric return true;
26620b57cec5SDimitry Andric }
26630b57cec5SDimitry Andric case BinaryOperatorClass: {
26640b57cec5SDimitry Andric const BinaryOperator *BO = cast<BinaryOperator>(this);
26650b57cec5SDimitry Andric switch (BO->getOpcode()) {
26660b57cec5SDimitry Andric default:
26670b57cec5SDimitry Andric break;
26680b57cec5SDimitry Andric // Consider the RHS of comma for side effects. LHS was checked by
26690b57cec5SDimitry Andric // Sema::CheckCommaOperands.
26700b57cec5SDimitry Andric case BO_Comma:
26710b57cec5SDimitry Andric // ((foo = <blah>), 0) is an idiom for hiding the result (and
26720b57cec5SDimitry Andric // lvalue-ness) of an assignment written in a macro.
26730b57cec5SDimitry Andric if (IntegerLiteral *IE =
26740b57cec5SDimitry Andric dyn_cast<IntegerLiteral>(BO->getRHS()->IgnoreParens()))
26750b57cec5SDimitry Andric if (IE->getValue() == 0)
26760b57cec5SDimitry Andric return false;
26770b57cec5SDimitry Andric return BO->getRHS()->isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx);
26780b57cec5SDimitry Andric // Consider '||', '&&' to have side effects if the LHS or RHS does.
26790b57cec5SDimitry Andric case BO_LAnd:
26800b57cec5SDimitry Andric case BO_LOr:
26810b57cec5SDimitry Andric if (!BO->getLHS()->isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx) ||
26820b57cec5SDimitry Andric !BO->getRHS()->isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx))
26830b57cec5SDimitry Andric return false;
26840b57cec5SDimitry Andric break;
26850b57cec5SDimitry Andric }
26860b57cec5SDimitry Andric if (BO->isAssignmentOp())
26870b57cec5SDimitry Andric return false;
26880b57cec5SDimitry Andric WarnE = this;
26890b57cec5SDimitry Andric Loc = BO->getOperatorLoc();
26900b57cec5SDimitry Andric R1 = BO->getLHS()->getSourceRange();
26910b57cec5SDimitry Andric R2 = BO->getRHS()->getSourceRange();
26920b57cec5SDimitry Andric return true;
26930b57cec5SDimitry Andric }
26940b57cec5SDimitry Andric case CompoundAssignOperatorClass:
26950b57cec5SDimitry Andric case VAArgExprClass:
26960b57cec5SDimitry Andric case AtomicExprClass:
26970b57cec5SDimitry Andric return false;
26980b57cec5SDimitry Andric
26990b57cec5SDimitry Andric case ConditionalOperatorClass: {
27000b57cec5SDimitry Andric // If only one of the LHS or RHS is a warning, the operator might
27010b57cec5SDimitry Andric // be being used for control flow. Only warn if both the LHS and
27020b57cec5SDimitry Andric // RHS are warnings.
27030b57cec5SDimitry Andric const auto *Exp = cast<ConditionalOperator>(this);
27040b57cec5SDimitry Andric return Exp->getLHS()->isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx) &&
27050b57cec5SDimitry Andric Exp->getRHS()->isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx);
27060b57cec5SDimitry Andric }
27070b57cec5SDimitry Andric case BinaryConditionalOperatorClass: {
27080b57cec5SDimitry Andric const auto *Exp = cast<BinaryConditionalOperator>(this);
27090b57cec5SDimitry Andric return Exp->getFalseExpr()->isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx);
27100b57cec5SDimitry Andric }
27110b57cec5SDimitry Andric
27120b57cec5SDimitry Andric case MemberExprClass:
27130b57cec5SDimitry Andric WarnE = this;
27140b57cec5SDimitry Andric Loc = cast<MemberExpr>(this)->getMemberLoc();
27150b57cec5SDimitry Andric R1 = SourceRange(Loc, Loc);
27160b57cec5SDimitry Andric R2 = cast<MemberExpr>(this)->getBase()->getSourceRange();
27170b57cec5SDimitry Andric return true;
27180b57cec5SDimitry Andric
27190b57cec5SDimitry Andric case ArraySubscriptExprClass:
27200b57cec5SDimitry Andric WarnE = this;
27210b57cec5SDimitry Andric Loc = cast<ArraySubscriptExpr>(this)->getRBracketLoc();
27220b57cec5SDimitry Andric R1 = cast<ArraySubscriptExpr>(this)->getLHS()->getSourceRange();
27230b57cec5SDimitry Andric R2 = cast<ArraySubscriptExpr>(this)->getRHS()->getSourceRange();
27240b57cec5SDimitry Andric return true;
27250b57cec5SDimitry Andric
27260b57cec5SDimitry Andric case CXXOperatorCallExprClass: {
27270b57cec5SDimitry Andric // Warn about operator ==,!=,<,>,<=, and >= even when user-defined operator
27280b57cec5SDimitry Andric // overloads as there is no reasonable way to define these such that they
27290b57cec5SDimitry Andric // have non-trivial, desirable side-effects. See the -Wunused-comparison
27300b57cec5SDimitry Andric // warning: operators == and != are commonly typo'ed, and so warning on them
27310b57cec5SDimitry Andric // provides additional value as well. If this list is updated,
27320b57cec5SDimitry Andric // DiagnoseUnusedComparison should be as well.
27330b57cec5SDimitry Andric const CXXOperatorCallExpr *Op = cast<CXXOperatorCallExpr>(this);
27340b57cec5SDimitry Andric switch (Op->getOperator()) {
27350b57cec5SDimitry Andric default:
27360b57cec5SDimitry Andric break;
27370b57cec5SDimitry Andric case OO_EqualEqual:
27380b57cec5SDimitry Andric case OO_ExclaimEqual:
27390b57cec5SDimitry Andric case OO_Less:
27400b57cec5SDimitry Andric case OO_Greater:
27410b57cec5SDimitry Andric case OO_GreaterEqual:
27420b57cec5SDimitry Andric case OO_LessEqual:
27430b57cec5SDimitry Andric if (Op->getCallReturnType(Ctx)->isReferenceType() ||
27440b57cec5SDimitry Andric Op->getCallReturnType(Ctx)->isVoidType())
27450b57cec5SDimitry Andric break;
27460b57cec5SDimitry Andric WarnE = this;
27470b57cec5SDimitry Andric Loc = Op->getOperatorLoc();
27480b57cec5SDimitry Andric R1 = Op->getSourceRange();
27490b57cec5SDimitry Andric return true;
27500b57cec5SDimitry Andric }
27510b57cec5SDimitry Andric
27520b57cec5SDimitry Andric // Fallthrough for generic call handling.
2753bdd1243dSDimitry Andric [[fallthrough]];
27540b57cec5SDimitry Andric }
27550b57cec5SDimitry Andric case CallExprClass:
27560b57cec5SDimitry Andric case CXXMemberCallExprClass:
27570b57cec5SDimitry Andric case UserDefinedLiteralClass: {
27580b57cec5SDimitry Andric // If this is a direct call, get the callee.
27590b57cec5SDimitry Andric const CallExpr *CE = cast<CallExpr>(this);
27600b57cec5SDimitry Andric if (const Decl *FD = CE->getCalleeDecl()) {
27610b57cec5SDimitry Andric // If the callee has attribute pure, const, or warn_unused_result, warn
27620b57cec5SDimitry Andric // about it. void foo() { strlen("bar"); } should warn.
27630b57cec5SDimitry Andric //
27640b57cec5SDimitry Andric // Note: If new cases are added here, DiagnoseUnusedExprResult should be
27650b57cec5SDimitry Andric // updated to match for QoI.
27660b57cec5SDimitry Andric if (CE->hasUnusedResultAttr(Ctx) ||
27670b57cec5SDimitry Andric FD->hasAttr<PureAttr>() || FD->hasAttr<ConstAttr>()) {
27680b57cec5SDimitry Andric WarnE = this;
27690b57cec5SDimitry Andric Loc = CE->getCallee()->getBeginLoc();
27700b57cec5SDimitry Andric R1 = CE->getCallee()->getSourceRange();
27710b57cec5SDimitry Andric
27720b57cec5SDimitry Andric if (unsigned NumArgs = CE->getNumArgs())
27730b57cec5SDimitry Andric R2 = SourceRange(CE->getArg(0)->getBeginLoc(),
27740b57cec5SDimitry Andric CE->getArg(NumArgs - 1)->getEndLoc());
27750b57cec5SDimitry Andric return true;
27760b57cec5SDimitry Andric }
27770b57cec5SDimitry Andric }
27780b57cec5SDimitry Andric return false;
27790b57cec5SDimitry Andric }
27800b57cec5SDimitry Andric
27810b57cec5SDimitry Andric // If we don't know precisely what we're looking at, let's not warn.
27820b57cec5SDimitry Andric case UnresolvedLookupExprClass:
27830b57cec5SDimitry Andric case CXXUnresolvedConstructExprClass:
27845ffd83dbSDimitry Andric case RecoveryExprClass:
27850b57cec5SDimitry Andric return false;
27860b57cec5SDimitry Andric
27870b57cec5SDimitry Andric case CXXTemporaryObjectExprClass:
27880b57cec5SDimitry Andric case CXXConstructExprClass: {
27890b57cec5SDimitry Andric if (const CXXRecordDecl *Type = getType()->getAsCXXRecordDecl()) {
2790a7dea167SDimitry Andric const auto *WarnURAttr = Type->getAttr<WarnUnusedResultAttr>();
2791a7dea167SDimitry Andric if (Type->hasAttr<WarnUnusedAttr>() ||
2792a7dea167SDimitry Andric (WarnURAttr && WarnURAttr->IsCXX11NoDiscard())) {
27930b57cec5SDimitry Andric WarnE = this;
27940b57cec5SDimitry Andric Loc = getBeginLoc();
27950b57cec5SDimitry Andric R1 = getSourceRange();
27960b57cec5SDimitry Andric return true;
27970b57cec5SDimitry Andric }
27980b57cec5SDimitry Andric }
2799a7dea167SDimitry Andric
2800a7dea167SDimitry Andric const auto *CE = cast<CXXConstructExpr>(this);
2801a7dea167SDimitry Andric if (const CXXConstructorDecl *Ctor = CE->getConstructor()) {
2802a7dea167SDimitry Andric const auto *WarnURAttr = Ctor->getAttr<WarnUnusedResultAttr>();
2803a7dea167SDimitry Andric if (WarnURAttr && WarnURAttr->IsCXX11NoDiscard()) {
2804a7dea167SDimitry Andric WarnE = this;
2805a7dea167SDimitry Andric Loc = getBeginLoc();
2806a7dea167SDimitry Andric R1 = getSourceRange();
2807a7dea167SDimitry Andric
2808a7dea167SDimitry Andric if (unsigned NumArgs = CE->getNumArgs())
2809a7dea167SDimitry Andric R2 = SourceRange(CE->getArg(0)->getBeginLoc(),
2810a7dea167SDimitry Andric CE->getArg(NumArgs - 1)->getEndLoc());
2811a7dea167SDimitry Andric return true;
2812a7dea167SDimitry Andric }
2813a7dea167SDimitry Andric }
2814a7dea167SDimitry Andric
28150b57cec5SDimitry Andric return false;
28160b57cec5SDimitry Andric }
28170b57cec5SDimitry Andric
28180b57cec5SDimitry Andric case ObjCMessageExprClass: {
28190b57cec5SDimitry Andric const ObjCMessageExpr *ME = cast<ObjCMessageExpr>(this);
28200b57cec5SDimitry Andric if (Ctx.getLangOpts().ObjCAutoRefCount &&
28210b57cec5SDimitry Andric ME->isInstanceMessage() &&
28220b57cec5SDimitry Andric !ME->getType()->isVoidType() &&
28230b57cec5SDimitry Andric ME->getMethodFamily() == OMF_init) {
28240b57cec5SDimitry Andric WarnE = this;
28250b57cec5SDimitry Andric Loc = getExprLoc();
28260b57cec5SDimitry Andric R1 = ME->getSourceRange();
28270b57cec5SDimitry Andric return true;
28280b57cec5SDimitry Andric }
28290b57cec5SDimitry Andric
28300b57cec5SDimitry Andric if (const ObjCMethodDecl *MD = ME->getMethodDecl())
28310b57cec5SDimitry Andric if (MD->hasAttr<WarnUnusedResultAttr>()) {
28320b57cec5SDimitry Andric WarnE = this;
28330b57cec5SDimitry Andric Loc = getExprLoc();
28340b57cec5SDimitry Andric return true;
28350b57cec5SDimitry Andric }
28360b57cec5SDimitry Andric
28370b57cec5SDimitry Andric return false;
28380b57cec5SDimitry Andric }
28390b57cec5SDimitry Andric
28400b57cec5SDimitry Andric case ObjCPropertyRefExprClass:
284181ad6265SDimitry Andric case ObjCSubscriptRefExprClass:
28420b57cec5SDimitry Andric WarnE = this;
28430b57cec5SDimitry Andric Loc = getExprLoc();
28440b57cec5SDimitry Andric R1 = getSourceRange();
28450b57cec5SDimitry Andric return true;
28460b57cec5SDimitry Andric
28470b57cec5SDimitry Andric case PseudoObjectExprClass: {
284881ad6265SDimitry Andric const auto *POE = cast<PseudoObjectExpr>(this);
28490b57cec5SDimitry Andric
285081ad6265SDimitry Andric // For some syntactic forms, we should always warn.
285181ad6265SDimitry Andric if (isa<ObjCPropertyRefExpr, ObjCSubscriptRefExpr>(
285281ad6265SDimitry Andric POE->getSyntacticForm())) {
28530b57cec5SDimitry Andric WarnE = this;
28540b57cec5SDimitry Andric Loc = getExprLoc();
28550b57cec5SDimitry Andric R1 = getSourceRange();
28560b57cec5SDimitry Andric return true;
28570b57cec5SDimitry Andric }
28580b57cec5SDimitry Andric
285981ad6265SDimitry Andric // For others, we should never warn.
286081ad6265SDimitry Andric if (auto *BO = dyn_cast<BinaryOperator>(POE->getSyntacticForm()))
286181ad6265SDimitry Andric if (BO->isAssignmentOp())
286281ad6265SDimitry Andric return false;
286381ad6265SDimitry Andric if (auto *UO = dyn_cast<UnaryOperator>(POE->getSyntacticForm()))
286481ad6265SDimitry Andric if (UO->isIncrementDecrementOp())
286581ad6265SDimitry Andric return false;
286681ad6265SDimitry Andric
286781ad6265SDimitry Andric // Otherwise, warn if the result expression would warn.
286881ad6265SDimitry Andric const Expr *Result = POE->getResultExpr();
286981ad6265SDimitry Andric return Result && Result->isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx);
287081ad6265SDimitry Andric }
287181ad6265SDimitry Andric
28720b57cec5SDimitry Andric case StmtExprClass: {
28730b57cec5SDimitry Andric // Statement exprs don't logically have side effects themselves, but are
28740b57cec5SDimitry Andric // sometimes used in macros in ways that give them a type that is unused.
28750b57cec5SDimitry Andric // For example ({ blah; foo(); }) will end up with a type if foo has a type.
28760b57cec5SDimitry Andric // however, if the result of the stmt expr is dead, we don't want to emit a
28770b57cec5SDimitry Andric // warning.
28780b57cec5SDimitry Andric const CompoundStmt *CS = cast<StmtExpr>(this)->getSubStmt();
28790b57cec5SDimitry Andric if (!CS->body_empty()) {
28800b57cec5SDimitry Andric if (const Expr *E = dyn_cast<Expr>(CS->body_back()))
28810b57cec5SDimitry Andric return E->isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx);
28820b57cec5SDimitry Andric if (const LabelStmt *Label = dyn_cast<LabelStmt>(CS->body_back()))
28830b57cec5SDimitry Andric if (const Expr *E = dyn_cast<Expr>(Label->getSubStmt()))
28840b57cec5SDimitry Andric return E->isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx);
28850b57cec5SDimitry Andric }
28860b57cec5SDimitry Andric
28870b57cec5SDimitry Andric if (getType()->isVoidType())
28880b57cec5SDimitry Andric return false;
28890b57cec5SDimitry Andric WarnE = this;
28900b57cec5SDimitry Andric Loc = cast<StmtExpr>(this)->getLParenLoc();
28910b57cec5SDimitry Andric R1 = getSourceRange();
28920b57cec5SDimitry Andric return true;
28930b57cec5SDimitry Andric }
28940b57cec5SDimitry Andric case CXXFunctionalCastExprClass:
28950b57cec5SDimitry Andric case CStyleCastExprClass: {
28965ffd83dbSDimitry Andric // Ignore an explicit cast to void, except in C++98 if the operand is a
28975ffd83dbSDimitry Andric // volatile glvalue for which we would trigger an implicit read in any
28985ffd83dbSDimitry Andric // other language mode. (Such an implicit read always happens as part of
28995ffd83dbSDimitry Andric // the lvalue conversion in C, and happens in C++ for expressions of all
29005ffd83dbSDimitry Andric // forms where it seems likely the user intended to trigger a volatile
29015ffd83dbSDimitry Andric // load.)
29020b57cec5SDimitry Andric const CastExpr *CE = cast<CastExpr>(this);
29035ffd83dbSDimitry Andric const Expr *SubE = CE->getSubExpr()->IgnoreParens();
29040b57cec5SDimitry Andric if (CE->getCastKind() == CK_ToVoid) {
29055ffd83dbSDimitry Andric if (Ctx.getLangOpts().CPlusPlus && !Ctx.getLangOpts().CPlusPlus11 &&
29065ffd83dbSDimitry Andric SubE->isReadIfDiscardedInCPlusPlus11()) {
29075ffd83dbSDimitry Andric // Suppress the "unused value" warning for idiomatic usage of
29085ffd83dbSDimitry Andric // '(void)var;' used to suppress "unused variable" warnings.
29095ffd83dbSDimitry Andric if (auto *DRE = dyn_cast<DeclRefExpr>(SubE))
29105ffd83dbSDimitry Andric if (auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
29115ffd83dbSDimitry Andric if (!VD->isExternallyVisible())
29125ffd83dbSDimitry Andric return false;
29135ffd83dbSDimitry Andric
29145ffd83dbSDimitry Andric // The lvalue-to-rvalue conversion would have no effect for an array.
29155ffd83dbSDimitry Andric // It's implausible that the programmer expected this to result in a
29165ffd83dbSDimitry Andric // volatile array load, so don't warn.
29175ffd83dbSDimitry Andric if (SubE->getType()->isArrayType())
29185ffd83dbSDimitry Andric return false;
29195ffd83dbSDimitry Andric
29205ffd83dbSDimitry Andric return SubE->isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx);
29210b57cec5SDimitry Andric }
29220b57cec5SDimitry Andric return false;
29230b57cec5SDimitry Andric }
29240b57cec5SDimitry Andric
29250b57cec5SDimitry Andric // If this is a cast to a constructor conversion, check the operand.
29260b57cec5SDimitry Andric // Otherwise, the result of the cast is unused.
29270b57cec5SDimitry Andric if (CE->getCastKind() == CK_ConstructorConversion)
29280b57cec5SDimitry Andric return CE->getSubExpr()->isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx);
2929e8d8bef9SDimitry Andric if (CE->getCastKind() == CK_Dependent)
2930e8d8bef9SDimitry Andric return false;
29310b57cec5SDimitry Andric
29320b57cec5SDimitry Andric WarnE = this;
29330b57cec5SDimitry Andric if (const CXXFunctionalCastExpr *CXXCE =
29340b57cec5SDimitry Andric dyn_cast<CXXFunctionalCastExpr>(this)) {
29350b57cec5SDimitry Andric Loc = CXXCE->getBeginLoc();
29360b57cec5SDimitry Andric R1 = CXXCE->getSubExpr()->getSourceRange();
29370b57cec5SDimitry Andric } else {
29380b57cec5SDimitry Andric const CStyleCastExpr *CStyleCE = cast<CStyleCastExpr>(this);
29390b57cec5SDimitry Andric Loc = CStyleCE->getLParenLoc();
29400b57cec5SDimitry Andric R1 = CStyleCE->getSubExpr()->getSourceRange();
29410b57cec5SDimitry Andric }
29420b57cec5SDimitry Andric return true;
29430b57cec5SDimitry Andric }
29440b57cec5SDimitry Andric case ImplicitCastExprClass: {
29450b57cec5SDimitry Andric const CastExpr *ICE = cast<ImplicitCastExpr>(this);
29460b57cec5SDimitry Andric
29470b57cec5SDimitry Andric // lvalue-to-rvalue conversion on a volatile lvalue is a side-effect.
29480b57cec5SDimitry Andric if (ICE->getCastKind() == CK_LValueToRValue &&
29490b57cec5SDimitry Andric ICE->getSubExpr()->getType().isVolatileQualified())
29500b57cec5SDimitry Andric return false;
29510b57cec5SDimitry Andric
29520b57cec5SDimitry Andric return ICE->getSubExpr()->isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx);
29530b57cec5SDimitry Andric }
29540b57cec5SDimitry Andric case CXXDefaultArgExprClass:
29550b57cec5SDimitry Andric return (cast<CXXDefaultArgExpr>(this)
29560b57cec5SDimitry Andric ->getExpr()->isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx));
29570b57cec5SDimitry Andric case CXXDefaultInitExprClass:
29580b57cec5SDimitry Andric return (cast<CXXDefaultInitExpr>(this)
29590b57cec5SDimitry Andric ->getExpr()->isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx));
29600b57cec5SDimitry Andric
29610b57cec5SDimitry Andric case CXXNewExprClass:
29620b57cec5SDimitry Andric // FIXME: In theory, there might be new expressions that don't have side
29630b57cec5SDimitry Andric // effects (e.g. a placement new with an uninitialized POD).
29640b57cec5SDimitry Andric case CXXDeleteExprClass:
29650b57cec5SDimitry Andric return false;
29660b57cec5SDimitry Andric case MaterializeTemporaryExprClass:
2967480093f4SDimitry Andric return cast<MaterializeTemporaryExpr>(this)
2968480093f4SDimitry Andric ->getSubExpr()
29690b57cec5SDimitry Andric ->isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx);
29700b57cec5SDimitry Andric case CXXBindTemporaryExprClass:
29710b57cec5SDimitry Andric return cast<CXXBindTemporaryExpr>(this)->getSubExpr()
29720b57cec5SDimitry Andric ->isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx);
29730b57cec5SDimitry Andric case ExprWithCleanupsClass:
29740b57cec5SDimitry Andric return cast<ExprWithCleanups>(this)->getSubExpr()
29750b57cec5SDimitry Andric ->isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx);
29760b57cec5SDimitry Andric }
29770b57cec5SDimitry Andric }
29780b57cec5SDimitry Andric
29790b57cec5SDimitry Andric /// isOBJCGCCandidate - Check if an expression is objc gc'able.
29800b57cec5SDimitry Andric /// returns true, if it is; false otherwise.
isOBJCGCCandidate(ASTContext & Ctx) const29810b57cec5SDimitry Andric bool Expr::isOBJCGCCandidate(ASTContext &Ctx) const {
29820b57cec5SDimitry Andric const Expr *E = IgnoreParens();
29830b57cec5SDimitry Andric switch (E->getStmtClass()) {
29840b57cec5SDimitry Andric default:
29850b57cec5SDimitry Andric return false;
29860b57cec5SDimitry Andric case ObjCIvarRefExprClass:
29870b57cec5SDimitry Andric return true;
29880b57cec5SDimitry Andric case Expr::UnaryOperatorClass:
29890b57cec5SDimitry Andric return cast<UnaryOperator>(E)->getSubExpr()->isOBJCGCCandidate(Ctx);
29900b57cec5SDimitry Andric case ImplicitCastExprClass:
29910b57cec5SDimitry Andric return cast<ImplicitCastExpr>(E)->getSubExpr()->isOBJCGCCandidate(Ctx);
29920b57cec5SDimitry Andric case MaterializeTemporaryExprClass:
2993480093f4SDimitry Andric return cast<MaterializeTemporaryExpr>(E)->getSubExpr()->isOBJCGCCandidate(
2994480093f4SDimitry Andric Ctx);
29950b57cec5SDimitry Andric case CStyleCastExprClass:
29960b57cec5SDimitry Andric return cast<CStyleCastExpr>(E)->getSubExpr()->isOBJCGCCandidate(Ctx);
29970b57cec5SDimitry Andric case DeclRefExprClass: {
29980b57cec5SDimitry Andric const Decl *D = cast<DeclRefExpr>(E)->getDecl();
29990b57cec5SDimitry Andric
30000b57cec5SDimitry Andric if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
30010b57cec5SDimitry Andric if (VD->hasGlobalStorage())
30020b57cec5SDimitry Andric return true;
30030b57cec5SDimitry Andric QualType T = VD->getType();
30040b57cec5SDimitry Andric // dereferencing to a pointer is always a gc'able candidate,
30050b57cec5SDimitry Andric // unless it is __weak.
30060b57cec5SDimitry Andric return T->isPointerType() &&
30070b57cec5SDimitry Andric (Ctx.getObjCGCAttrKind(T) != Qualifiers::Weak);
30080b57cec5SDimitry Andric }
30090b57cec5SDimitry Andric return false;
30100b57cec5SDimitry Andric }
30110b57cec5SDimitry Andric case MemberExprClass: {
30120b57cec5SDimitry Andric const MemberExpr *M = cast<MemberExpr>(E);
30130b57cec5SDimitry Andric return M->getBase()->isOBJCGCCandidate(Ctx);
30140b57cec5SDimitry Andric }
30150b57cec5SDimitry Andric case ArraySubscriptExprClass:
30160b57cec5SDimitry Andric return cast<ArraySubscriptExpr>(E)->getBase()->isOBJCGCCandidate(Ctx);
30170b57cec5SDimitry Andric }
30180b57cec5SDimitry Andric }
30190b57cec5SDimitry Andric
isBoundMemberFunction(ASTContext & Ctx) const30200b57cec5SDimitry Andric bool Expr::isBoundMemberFunction(ASTContext &Ctx) const {
30210b57cec5SDimitry Andric if (isTypeDependent())
30220b57cec5SDimitry Andric return false;
30230b57cec5SDimitry Andric return ClassifyLValue(Ctx) == Expr::LV_MemberFunction;
30240b57cec5SDimitry Andric }
30250b57cec5SDimitry Andric
findBoundMemberType(const Expr * expr)30260b57cec5SDimitry Andric QualType Expr::findBoundMemberType(const Expr *expr) {
30270b57cec5SDimitry Andric assert(expr->hasPlaceholderType(BuiltinType::BoundMember));
30280b57cec5SDimitry Andric
30290b57cec5SDimitry Andric // Bound member expressions are always one of these possibilities:
30300b57cec5SDimitry Andric // x->m x.m x->*y x.*y
30310b57cec5SDimitry Andric // (possibly parenthesized)
30320b57cec5SDimitry Andric
30330b57cec5SDimitry Andric expr = expr->IgnoreParens();
30340b57cec5SDimitry Andric if (const MemberExpr *mem = dyn_cast<MemberExpr>(expr)) {
30350b57cec5SDimitry Andric assert(isa<CXXMethodDecl>(mem->getMemberDecl()));
30360b57cec5SDimitry Andric return mem->getMemberDecl()->getType();
30370b57cec5SDimitry Andric }
30380b57cec5SDimitry Andric
30390b57cec5SDimitry Andric if (const BinaryOperator *op = dyn_cast<BinaryOperator>(expr)) {
30400b57cec5SDimitry Andric QualType type = op->getRHS()->getType()->castAs<MemberPointerType>()
30410b57cec5SDimitry Andric ->getPointeeType();
30420b57cec5SDimitry Andric assert(type->isFunctionType());
30430b57cec5SDimitry Andric return type;
30440b57cec5SDimitry Andric }
30450b57cec5SDimitry Andric
30460b57cec5SDimitry Andric assert(isa<UnresolvedMemberExpr>(expr) || isa<CXXPseudoDestructorExpr>(expr));
30470b57cec5SDimitry Andric return QualType();
30480b57cec5SDimitry Andric }
30490b57cec5SDimitry Andric
IgnoreImpCasts()30500b57cec5SDimitry Andric Expr *Expr::IgnoreImpCasts() {
3051e8d8bef9SDimitry Andric return IgnoreExprNodes(this, IgnoreImplicitCastsSingleStep);
30520b57cec5SDimitry Andric }
30530b57cec5SDimitry Andric
IgnoreCasts()30540b57cec5SDimitry Andric Expr *Expr::IgnoreCasts() {
30550b57cec5SDimitry Andric return IgnoreExprNodes(this, IgnoreCastsSingleStep);
30560b57cec5SDimitry Andric }
30570b57cec5SDimitry Andric
IgnoreImplicit()30580b57cec5SDimitry Andric Expr *Expr::IgnoreImplicit() {
30590b57cec5SDimitry Andric return IgnoreExprNodes(this, IgnoreImplicitSingleStep);
30600b57cec5SDimitry Andric }
30610b57cec5SDimitry Andric
IgnoreImplicitAsWritten()3062480093f4SDimitry Andric Expr *Expr::IgnoreImplicitAsWritten() {
3063480093f4SDimitry Andric return IgnoreExprNodes(this, IgnoreImplicitAsWrittenSingleStep);
3064480093f4SDimitry Andric }
3065480093f4SDimitry Andric
IgnoreParens()30660b57cec5SDimitry Andric Expr *Expr::IgnoreParens() {
30670b57cec5SDimitry Andric return IgnoreExprNodes(this, IgnoreParensSingleStep);
30680b57cec5SDimitry Andric }
30690b57cec5SDimitry Andric
IgnoreParenImpCasts()30700b57cec5SDimitry Andric Expr *Expr::IgnoreParenImpCasts() {
30710b57cec5SDimitry Andric return IgnoreExprNodes(this, IgnoreParensSingleStep,
3072e8d8bef9SDimitry Andric IgnoreImplicitCastsExtraSingleStep);
30730b57cec5SDimitry Andric }
30740b57cec5SDimitry Andric
IgnoreParenCasts()30750b57cec5SDimitry Andric Expr *Expr::IgnoreParenCasts() {
30760b57cec5SDimitry Andric return IgnoreExprNodes(this, IgnoreParensSingleStep, IgnoreCastsSingleStep);
30770b57cec5SDimitry Andric }
30780b57cec5SDimitry Andric
IgnoreConversionOperatorSingleStep()3079e8d8bef9SDimitry Andric Expr *Expr::IgnoreConversionOperatorSingleStep() {
30800b57cec5SDimitry Andric if (auto *MCE = dyn_cast<CXXMemberCallExpr>(this)) {
3081*0fca6ea1SDimitry Andric if (isa_and_nonnull<CXXConversionDecl>(MCE->getMethodDecl()))
30820b57cec5SDimitry Andric return MCE->getImplicitObjectArgument();
30830b57cec5SDimitry Andric }
30840b57cec5SDimitry Andric return this;
30850b57cec5SDimitry Andric }
30860b57cec5SDimitry Andric
IgnoreParenLValueCasts()30870b57cec5SDimitry Andric Expr *Expr::IgnoreParenLValueCasts() {
30880b57cec5SDimitry Andric return IgnoreExprNodes(this, IgnoreParensSingleStep,
30890b57cec5SDimitry Andric IgnoreLValueCastsSingleStep);
30900b57cec5SDimitry Andric }
30910b57cec5SDimitry Andric
IgnoreParenBaseCasts()3092e8d8bef9SDimitry Andric Expr *Expr::IgnoreParenBaseCasts() {
30930b57cec5SDimitry Andric return IgnoreExprNodes(this, IgnoreParensSingleStep,
30940b57cec5SDimitry Andric IgnoreBaseCastsSingleStep);
30950b57cec5SDimitry Andric }
30960b57cec5SDimitry Andric
IgnoreParenNoopCasts(const ASTContext & Ctx)30970b57cec5SDimitry Andric Expr *Expr::IgnoreParenNoopCasts(const ASTContext &Ctx) {
3098e8d8bef9SDimitry Andric auto IgnoreNoopCastsSingleStep = [&Ctx](Expr *E) {
3099e8d8bef9SDimitry Andric if (auto *CE = dyn_cast<CastExpr>(E)) {
3100e8d8bef9SDimitry Andric // We ignore integer <-> casts that are of the same width, ptr<->ptr and
3101e8d8bef9SDimitry Andric // ptr<->int casts of the same width. We also ignore all identity casts.
3102e8d8bef9SDimitry Andric Expr *SubExpr = CE->getSubExpr();
3103e8d8bef9SDimitry Andric bool IsIdentityCast =
3104e8d8bef9SDimitry Andric Ctx.hasSameUnqualifiedType(E->getType(), SubExpr->getType());
3105e8d8bef9SDimitry Andric bool IsSameWidthCast = (E->getType()->isPointerType() ||
3106e8d8bef9SDimitry Andric E->getType()->isIntegralType(Ctx)) &&
3107e8d8bef9SDimitry Andric (SubExpr->getType()->isPointerType() ||
3108e8d8bef9SDimitry Andric SubExpr->getType()->isIntegralType(Ctx)) &&
3109e8d8bef9SDimitry Andric (Ctx.getTypeSize(E->getType()) ==
3110e8d8bef9SDimitry Andric Ctx.getTypeSize(SubExpr->getType()));
3111e8d8bef9SDimitry Andric
3112e8d8bef9SDimitry Andric if (IsIdentityCast || IsSameWidthCast)
3113e8d8bef9SDimitry Andric return SubExpr;
3114e8d8bef9SDimitry Andric } else if (auto *NTTP = dyn_cast<SubstNonTypeTemplateParmExpr>(E))
3115e8d8bef9SDimitry Andric return NTTP->getReplacement();
3116e8d8bef9SDimitry Andric
3117e8d8bef9SDimitry Andric return E;
3118e8d8bef9SDimitry Andric };
3119e8d8bef9SDimitry Andric return IgnoreExprNodes(this, IgnoreParensSingleStep,
3120e8d8bef9SDimitry Andric IgnoreNoopCastsSingleStep);
31210b57cec5SDimitry Andric }
31220b57cec5SDimitry Andric
IgnoreUnlessSpelledInSource()3123480093f4SDimitry Andric Expr *Expr::IgnoreUnlessSpelledInSource() {
3124e8d8bef9SDimitry Andric auto IgnoreImplicitConstructorSingleStep = [](Expr *E) {
3125e8d8bef9SDimitry Andric if (auto *Cast = dyn_cast<CXXFunctionalCastExpr>(E)) {
3126e8d8bef9SDimitry Andric auto *SE = Cast->getSubExpr();
3127e8d8bef9SDimitry Andric if (SE->getSourceRange() == E->getSourceRange())
3128e8d8bef9SDimitry Andric return SE;
3129e8d8bef9SDimitry Andric }
3130480093f4SDimitry Andric
3131480093f4SDimitry Andric if (auto *C = dyn_cast<CXXConstructExpr>(E)) {
31325ffd83dbSDimitry Andric auto NumArgs = C->getNumArgs();
31335ffd83dbSDimitry Andric if (NumArgs == 1 ||
31345ffd83dbSDimitry Andric (NumArgs > 1 && isa<CXXDefaultArgExpr>(C->getArg(1)))) {
3135480093f4SDimitry Andric Expr *A = C->getArg(0);
3136e8d8bef9SDimitry Andric if (A->getSourceRange() == E->getSourceRange() || C->isElidable())
3137e8d8bef9SDimitry Andric return A;
3138480093f4SDimitry Andric }
3139480093f4SDimitry Andric }
3140e8d8bef9SDimitry Andric return E;
3141e8d8bef9SDimitry Andric };
3142e8d8bef9SDimitry Andric auto IgnoreImplicitMemberCallSingleStep = [](Expr *E) {
3143480093f4SDimitry Andric if (auto *C = dyn_cast<CXXMemberCallExpr>(E)) {
31445ffd83dbSDimitry Andric Expr *ExprNode = C->getImplicitObjectArgument();
3145e8d8bef9SDimitry Andric if (ExprNode->getSourceRange() == E->getSourceRange()) {
3146e8d8bef9SDimitry Andric return ExprNode;
31475ffd83dbSDimitry Andric }
31485ffd83dbSDimitry Andric if (auto *PE = dyn_cast<ParenExpr>(ExprNode)) {
31495ffd83dbSDimitry Andric if (PE->getSourceRange() == C->getSourceRange()) {
3150e8d8bef9SDimitry Andric return cast<Expr>(PE);
31515ffd83dbSDimitry Andric }
31525ffd83dbSDimitry Andric }
31535ffd83dbSDimitry Andric ExprNode = ExprNode->IgnoreParenImpCasts();
3154e8d8bef9SDimitry Andric if (ExprNode->getSourceRange() == E->getSourceRange())
3155e8d8bef9SDimitry Andric return ExprNode;
3156480093f4SDimitry Andric }
3157480093f4SDimitry Andric return E;
3158e8d8bef9SDimitry Andric };
3159e8d8bef9SDimitry Andric return IgnoreExprNodes(
3160e8d8bef9SDimitry Andric this, IgnoreImplicitSingleStep, IgnoreImplicitCastsExtraSingleStep,
3161e8d8bef9SDimitry Andric IgnoreParensOnlySingleStep, IgnoreImplicitConstructorSingleStep,
3162e8d8bef9SDimitry Andric IgnoreImplicitMemberCallSingleStep);
3163480093f4SDimitry Andric }
3164480093f4SDimitry Andric
isDefaultArgument() const31650b57cec5SDimitry Andric bool Expr::isDefaultArgument() const {
31660b57cec5SDimitry Andric const Expr *E = this;
31670b57cec5SDimitry Andric if (const MaterializeTemporaryExpr *M = dyn_cast<MaterializeTemporaryExpr>(E))
3168480093f4SDimitry Andric E = M->getSubExpr();
31690b57cec5SDimitry Andric
31700b57cec5SDimitry Andric while (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E))
31710b57cec5SDimitry Andric E = ICE->getSubExprAsWritten();
31720b57cec5SDimitry Andric
31730b57cec5SDimitry Andric return isa<CXXDefaultArgExpr>(E);
31740b57cec5SDimitry Andric }
31750b57cec5SDimitry Andric
31760b57cec5SDimitry Andric /// Skip over any no-op casts and any temporary-binding
31770b57cec5SDimitry Andric /// expressions.
skipTemporaryBindingsNoOpCastsAndParens(const Expr * E)31780b57cec5SDimitry Andric static const Expr *skipTemporaryBindingsNoOpCastsAndParens(const Expr *E) {
31790b57cec5SDimitry Andric if (const MaterializeTemporaryExpr *M = dyn_cast<MaterializeTemporaryExpr>(E))
3180480093f4SDimitry Andric E = M->getSubExpr();
31810b57cec5SDimitry Andric
31820b57cec5SDimitry Andric while (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) {
31830b57cec5SDimitry Andric if (ICE->getCastKind() == CK_NoOp)
31840b57cec5SDimitry Andric E = ICE->getSubExpr();
31850b57cec5SDimitry Andric else
31860b57cec5SDimitry Andric break;
31870b57cec5SDimitry Andric }
31880b57cec5SDimitry Andric
31890b57cec5SDimitry Andric while (const CXXBindTemporaryExpr *BE = dyn_cast<CXXBindTemporaryExpr>(E))
31900b57cec5SDimitry Andric E = BE->getSubExpr();
31910b57cec5SDimitry Andric
31920b57cec5SDimitry Andric while (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) {
31930b57cec5SDimitry Andric if (ICE->getCastKind() == CK_NoOp)
31940b57cec5SDimitry Andric E = ICE->getSubExpr();
31950b57cec5SDimitry Andric else
31960b57cec5SDimitry Andric break;
31970b57cec5SDimitry Andric }
31980b57cec5SDimitry Andric
31990b57cec5SDimitry Andric return E->IgnoreParens();
32000b57cec5SDimitry Andric }
32010b57cec5SDimitry Andric
32020b57cec5SDimitry Andric /// isTemporaryObject - Determines if this expression produces a
32030b57cec5SDimitry Andric /// temporary of the given class type.
isTemporaryObject(ASTContext & C,const CXXRecordDecl * TempTy) const32040b57cec5SDimitry Andric bool Expr::isTemporaryObject(ASTContext &C, const CXXRecordDecl *TempTy) const {
32050b57cec5SDimitry Andric if (!C.hasSameUnqualifiedType(getType(), C.getTypeDeclType(TempTy)))
32060b57cec5SDimitry Andric return false;
32070b57cec5SDimitry Andric
32080b57cec5SDimitry Andric const Expr *E = skipTemporaryBindingsNoOpCastsAndParens(this);
32090b57cec5SDimitry Andric
32100b57cec5SDimitry Andric // Temporaries are by definition pr-values of class type.
32110b57cec5SDimitry Andric if (!E->Classify(C).isPRValue()) {
32120b57cec5SDimitry Andric // In this context, property reference is a message call and is pr-value.
32130b57cec5SDimitry Andric if (!isa<ObjCPropertyRefExpr>(E))
32140b57cec5SDimitry Andric return false;
32150b57cec5SDimitry Andric }
32160b57cec5SDimitry Andric
32170b57cec5SDimitry Andric // Black-list a few cases which yield pr-values of class type that don't
32180b57cec5SDimitry Andric // refer to temporaries of that type:
32190b57cec5SDimitry Andric
32200b57cec5SDimitry Andric // - implicit derived-to-base conversions
32210b57cec5SDimitry Andric if (isa<ImplicitCastExpr>(E)) {
32220b57cec5SDimitry Andric switch (cast<ImplicitCastExpr>(E)->getCastKind()) {
32230b57cec5SDimitry Andric case CK_DerivedToBase:
32240b57cec5SDimitry Andric case CK_UncheckedDerivedToBase:
32250b57cec5SDimitry Andric return false;
32260b57cec5SDimitry Andric default:
32270b57cec5SDimitry Andric break;
32280b57cec5SDimitry Andric }
32290b57cec5SDimitry Andric }
32300b57cec5SDimitry Andric
32310b57cec5SDimitry Andric // - member expressions (all)
32320b57cec5SDimitry Andric if (isa<MemberExpr>(E))
32330b57cec5SDimitry Andric return false;
32340b57cec5SDimitry Andric
32350b57cec5SDimitry Andric if (const BinaryOperator *BO = dyn_cast<BinaryOperator>(E))
32360b57cec5SDimitry Andric if (BO->isPtrMemOp())
32370b57cec5SDimitry Andric return false;
32380b57cec5SDimitry Andric
32390b57cec5SDimitry Andric // - opaque values (all)
32400b57cec5SDimitry Andric if (isa<OpaqueValueExpr>(E))
32410b57cec5SDimitry Andric return false;
32420b57cec5SDimitry Andric
32430b57cec5SDimitry Andric return true;
32440b57cec5SDimitry Andric }
32450b57cec5SDimitry Andric
isImplicitCXXThis() const32460b57cec5SDimitry Andric bool Expr::isImplicitCXXThis() const {
32470b57cec5SDimitry Andric const Expr *E = this;
32480b57cec5SDimitry Andric
32490b57cec5SDimitry Andric // Strip away parentheses and casts we don't care about.
32500b57cec5SDimitry Andric while (true) {
32510b57cec5SDimitry Andric if (const ParenExpr *Paren = dyn_cast<ParenExpr>(E)) {
32520b57cec5SDimitry Andric E = Paren->getSubExpr();
32530b57cec5SDimitry Andric continue;
32540b57cec5SDimitry Andric }
32550b57cec5SDimitry Andric
32560b57cec5SDimitry Andric if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) {
32570b57cec5SDimitry Andric if (ICE->getCastKind() == CK_NoOp ||
32580b57cec5SDimitry Andric ICE->getCastKind() == CK_LValueToRValue ||
32590b57cec5SDimitry Andric ICE->getCastKind() == CK_DerivedToBase ||
32600b57cec5SDimitry Andric ICE->getCastKind() == CK_UncheckedDerivedToBase) {
32610b57cec5SDimitry Andric E = ICE->getSubExpr();
32620b57cec5SDimitry Andric continue;
32630b57cec5SDimitry Andric }
32640b57cec5SDimitry Andric }
32650b57cec5SDimitry Andric
32660b57cec5SDimitry Andric if (const UnaryOperator* UnOp = dyn_cast<UnaryOperator>(E)) {
32670b57cec5SDimitry Andric if (UnOp->getOpcode() == UO_Extension) {
32680b57cec5SDimitry Andric E = UnOp->getSubExpr();
32690b57cec5SDimitry Andric continue;
32700b57cec5SDimitry Andric }
32710b57cec5SDimitry Andric }
32720b57cec5SDimitry Andric
32730b57cec5SDimitry Andric if (const MaterializeTemporaryExpr *M
32740b57cec5SDimitry Andric = dyn_cast<MaterializeTemporaryExpr>(E)) {
3275480093f4SDimitry Andric E = M->getSubExpr();
32760b57cec5SDimitry Andric continue;
32770b57cec5SDimitry Andric }
32780b57cec5SDimitry Andric
32790b57cec5SDimitry Andric break;
32800b57cec5SDimitry Andric }
32810b57cec5SDimitry Andric
32820b57cec5SDimitry Andric if (const CXXThisExpr *This = dyn_cast<CXXThisExpr>(E))
32830b57cec5SDimitry Andric return This->isImplicit();
32840b57cec5SDimitry Andric
32850b57cec5SDimitry Andric return false;
32860b57cec5SDimitry Andric }
32870b57cec5SDimitry Andric
32880b57cec5SDimitry Andric /// hasAnyTypeDependentArguments - Determines if any of the expressions
32890b57cec5SDimitry Andric /// in Exprs is type-dependent.
hasAnyTypeDependentArguments(ArrayRef<Expr * > Exprs)32900b57cec5SDimitry Andric bool Expr::hasAnyTypeDependentArguments(ArrayRef<Expr *> Exprs) {
32910b57cec5SDimitry Andric for (unsigned I = 0; I < Exprs.size(); ++I)
32920b57cec5SDimitry Andric if (Exprs[I]->isTypeDependent())
32930b57cec5SDimitry Andric return true;
32940b57cec5SDimitry Andric
32950b57cec5SDimitry Andric return false;
32960b57cec5SDimitry Andric }
32970b57cec5SDimitry Andric
isConstantInitializer(ASTContext & Ctx,bool IsForRef,const Expr ** Culprit) const32980b57cec5SDimitry Andric bool Expr::isConstantInitializer(ASTContext &Ctx, bool IsForRef,
32990b57cec5SDimitry Andric const Expr **Culprit) const {
33000b57cec5SDimitry Andric assert(!isValueDependent() &&
33010b57cec5SDimitry Andric "Expression evaluator can't be called on a dependent expression.");
33020b57cec5SDimitry Andric
33030b57cec5SDimitry Andric // This function is attempting whether an expression is an initializer
33040b57cec5SDimitry Andric // which can be evaluated at compile-time. It very closely parallels
33050b57cec5SDimitry Andric // ConstExprEmitter in CGExprConstant.cpp; if they don't match, it
33060b57cec5SDimitry Andric // will lead to unexpected results. Like ConstExprEmitter, it falls back
33070b57cec5SDimitry Andric // to isEvaluatable most of the time.
33080b57cec5SDimitry Andric //
33090b57cec5SDimitry Andric // If we ever capture reference-binding directly in the AST, we can
33100b57cec5SDimitry Andric // kill the second parameter.
33110b57cec5SDimitry Andric
33120b57cec5SDimitry Andric if (IsForRef) {
331306c3fb27SDimitry Andric if (auto *EWC = dyn_cast<ExprWithCleanups>(this))
331406c3fb27SDimitry Andric return EWC->getSubExpr()->isConstantInitializer(Ctx, true, Culprit);
331506c3fb27SDimitry Andric if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(this))
331606c3fb27SDimitry Andric return MTE->getSubExpr()->isConstantInitializer(Ctx, false, Culprit);
33170b57cec5SDimitry Andric EvalResult Result;
33180b57cec5SDimitry Andric if (EvaluateAsLValue(Result, Ctx) && !Result.HasSideEffects)
33190b57cec5SDimitry Andric return true;
33200b57cec5SDimitry Andric if (Culprit)
33210b57cec5SDimitry Andric *Culprit = this;
33220b57cec5SDimitry Andric return false;
33230b57cec5SDimitry Andric }
33240b57cec5SDimitry Andric
33250b57cec5SDimitry Andric switch (getStmtClass()) {
33260b57cec5SDimitry Andric default: break;
33275ffd83dbSDimitry Andric case Stmt::ExprWithCleanupsClass:
33285ffd83dbSDimitry Andric return cast<ExprWithCleanups>(this)->getSubExpr()->isConstantInitializer(
33295ffd83dbSDimitry Andric Ctx, IsForRef, Culprit);
33300b57cec5SDimitry Andric case StringLiteralClass:
33310b57cec5SDimitry Andric case ObjCEncodeExprClass:
33320b57cec5SDimitry Andric return true;
33330b57cec5SDimitry Andric case CXXTemporaryObjectExprClass:
33340b57cec5SDimitry Andric case CXXConstructExprClass: {
33350b57cec5SDimitry Andric const CXXConstructExpr *CE = cast<CXXConstructExpr>(this);
33360b57cec5SDimitry Andric
33370b57cec5SDimitry Andric if (CE->getConstructor()->isTrivial() &&
33380b57cec5SDimitry Andric CE->getConstructor()->getParent()->hasTrivialDestructor()) {
33390b57cec5SDimitry Andric // Trivial default constructor
33400b57cec5SDimitry Andric if (!CE->getNumArgs()) return true;
33410b57cec5SDimitry Andric
33420b57cec5SDimitry Andric // Trivial copy constructor
33430b57cec5SDimitry Andric assert(CE->getNumArgs() == 1 && "trivial ctor with > 1 argument");
33440b57cec5SDimitry Andric return CE->getArg(0)->isConstantInitializer(Ctx, false, Culprit);
33450b57cec5SDimitry Andric }
33460b57cec5SDimitry Andric
33470b57cec5SDimitry Andric break;
33480b57cec5SDimitry Andric }
33490b57cec5SDimitry Andric case ConstantExprClass: {
33500b57cec5SDimitry Andric // FIXME: We should be able to return "true" here, but it can lead to extra
33510b57cec5SDimitry Andric // error messages. E.g. in Sema/array-init.c.
33520b57cec5SDimitry Andric const Expr *Exp = cast<ConstantExpr>(this)->getSubExpr();
33530b57cec5SDimitry Andric return Exp->isConstantInitializer(Ctx, false, Culprit);
33540b57cec5SDimitry Andric }
33550b57cec5SDimitry Andric case CompoundLiteralExprClass: {
33560b57cec5SDimitry Andric // This handles gcc's extension that allows global initializers like
33570b57cec5SDimitry Andric // "struct x {int x;} x = (struct x) {};".
33580b57cec5SDimitry Andric // FIXME: This accepts other cases it shouldn't!
33590b57cec5SDimitry Andric const Expr *Exp = cast<CompoundLiteralExpr>(this)->getInitializer();
33600b57cec5SDimitry Andric return Exp->isConstantInitializer(Ctx, false, Culprit);
33610b57cec5SDimitry Andric }
33620b57cec5SDimitry Andric case DesignatedInitUpdateExprClass: {
33630b57cec5SDimitry Andric const DesignatedInitUpdateExpr *DIUE = cast<DesignatedInitUpdateExpr>(this);
33640b57cec5SDimitry Andric return DIUE->getBase()->isConstantInitializer(Ctx, false, Culprit) &&
33650b57cec5SDimitry Andric DIUE->getUpdater()->isConstantInitializer(Ctx, false, Culprit);
33660b57cec5SDimitry Andric }
33670b57cec5SDimitry Andric case InitListExprClass: {
3368*0fca6ea1SDimitry Andric // C++ [dcl.init.aggr]p2:
3369*0fca6ea1SDimitry Andric // The elements of an aggregate are:
3370*0fca6ea1SDimitry Andric // - for an array, the array elements in increasing subscript order, or
3371*0fca6ea1SDimitry Andric // - for a class, the direct base classes in declaration order, followed
3372*0fca6ea1SDimitry Andric // by the direct non-static data members (11.4) that are not members of
3373*0fca6ea1SDimitry Andric // an anonymous union, in declaration order.
33740b57cec5SDimitry Andric const InitListExpr *ILE = cast<InitListExpr>(this);
33750b57cec5SDimitry Andric assert(ILE->isSemanticForm() && "InitListExpr must be in semantic form");
33760b57cec5SDimitry Andric if (ILE->getType()->isArrayType()) {
33770b57cec5SDimitry Andric unsigned numInits = ILE->getNumInits();
33780b57cec5SDimitry Andric for (unsigned i = 0; i < numInits; i++) {
33790b57cec5SDimitry Andric if (!ILE->getInit(i)->isConstantInitializer(Ctx, false, Culprit))
33800b57cec5SDimitry Andric return false;
33810b57cec5SDimitry Andric }
33820b57cec5SDimitry Andric return true;
33830b57cec5SDimitry Andric }
33840b57cec5SDimitry Andric
33850b57cec5SDimitry Andric if (ILE->getType()->isRecordType()) {
33860b57cec5SDimitry Andric unsigned ElementNo = 0;
3387a7dea167SDimitry Andric RecordDecl *RD = ILE->getType()->castAs<RecordType>()->getDecl();
3388*0fca6ea1SDimitry Andric
3389*0fca6ea1SDimitry Andric // In C++17, bases were added to the list of members used by aggregate
3390*0fca6ea1SDimitry Andric // initialization.
3391*0fca6ea1SDimitry Andric if (const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
3392*0fca6ea1SDimitry Andric for (unsigned i = 0, e = CXXRD->getNumBases(); i < e; i++) {
3393*0fca6ea1SDimitry Andric if (ElementNo < ILE->getNumInits()) {
3394*0fca6ea1SDimitry Andric const Expr *Elt = ILE->getInit(ElementNo++);
3395*0fca6ea1SDimitry Andric if (!Elt->isConstantInitializer(Ctx, false, Culprit))
3396*0fca6ea1SDimitry Andric return false;
3397*0fca6ea1SDimitry Andric }
3398*0fca6ea1SDimitry Andric }
3399*0fca6ea1SDimitry Andric }
3400*0fca6ea1SDimitry Andric
34010b57cec5SDimitry Andric for (const auto *Field : RD->fields()) {
34020b57cec5SDimitry Andric // If this is a union, skip all the fields that aren't being initialized.
34030b57cec5SDimitry Andric if (RD->isUnion() && ILE->getInitializedFieldInUnion() != Field)
34040b57cec5SDimitry Andric continue;
34050b57cec5SDimitry Andric
34060b57cec5SDimitry Andric // Don't emit anonymous bitfields, they just affect layout.
3407*0fca6ea1SDimitry Andric if (Field->isUnnamedBitField())
34080b57cec5SDimitry Andric continue;
34090b57cec5SDimitry Andric
34100b57cec5SDimitry Andric if (ElementNo < ILE->getNumInits()) {
34110b57cec5SDimitry Andric const Expr *Elt = ILE->getInit(ElementNo++);
34120b57cec5SDimitry Andric if (Field->isBitField()) {
34130b57cec5SDimitry Andric // Bitfields have to evaluate to an integer.
34140b57cec5SDimitry Andric EvalResult Result;
34150b57cec5SDimitry Andric if (!Elt->EvaluateAsInt(Result, Ctx)) {
34160b57cec5SDimitry Andric if (Culprit)
34170b57cec5SDimitry Andric *Culprit = Elt;
34180b57cec5SDimitry Andric return false;
34190b57cec5SDimitry Andric }
34200b57cec5SDimitry Andric } else {
34210b57cec5SDimitry Andric bool RefType = Field->getType()->isReferenceType();
34220b57cec5SDimitry Andric if (!Elt->isConstantInitializer(Ctx, RefType, Culprit))
34230b57cec5SDimitry Andric return false;
34240b57cec5SDimitry Andric }
34250b57cec5SDimitry Andric }
34260b57cec5SDimitry Andric }
34270b57cec5SDimitry Andric return true;
34280b57cec5SDimitry Andric }
34290b57cec5SDimitry Andric
34300b57cec5SDimitry Andric break;
34310b57cec5SDimitry Andric }
34320b57cec5SDimitry Andric case ImplicitValueInitExprClass:
34330b57cec5SDimitry Andric case NoInitExprClass:
34340b57cec5SDimitry Andric return true;
34350b57cec5SDimitry Andric case ParenExprClass:
34360b57cec5SDimitry Andric return cast<ParenExpr>(this)->getSubExpr()
34370b57cec5SDimitry Andric ->isConstantInitializer(Ctx, IsForRef, Culprit);
34380b57cec5SDimitry Andric case GenericSelectionExprClass:
34390b57cec5SDimitry Andric return cast<GenericSelectionExpr>(this)->getResultExpr()
34400b57cec5SDimitry Andric ->isConstantInitializer(Ctx, IsForRef, Culprit);
34410b57cec5SDimitry Andric case ChooseExprClass:
34420b57cec5SDimitry Andric if (cast<ChooseExpr>(this)->isConditionDependent()) {
34430b57cec5SDimitry Andric if (Culprit)
34440b57cec5SDimitry Andric *Culprit = this;
34450b57cec5SDimitry Andric return false;
34460b57cec5SDimitry Andric }
34470b57cec5SDimitry Andric return cast<ChooseExpr>(this)->getChosenSubExpr()
34480b57cec5SDimitry Andric ->isConstantInitializer(Ctx, IsForRef, Culprit);
34490b57cec5SDimitry Andric case UnaryOperatorClass: {
34500b57cec5SDimitry Andric const UnaryOperator* Exp = cast<UnaryOperator>(this);
34510b57cec5SDimitry Andric if (Exp->getOpcode() == UO_Extension)
34520b57cec5SDimitry Andric return Exp->getSubExpr()->isConstantInitializer(Ctx, false, Culprit);
34530b57cec5SDimitry Andric break;
34540b57cec5SDimitry Andric }
3455*0fca6ea1SDimitry Andric case PackIndexingExprClass: {
3456*0fca6ea1SDimitry Andric return cast<PackIndexingExpr>(this)
3457*0fca6ea1SDimitry Andric ->getSelectedExpr()
3458*0fca6ea1SDimitry Andric ->isConstantInitializer(Ctx, false, Culprit);
3459*0fca6ea1SDimitry Andric }
34600b57cec5SDimitry Andric case CXXFunctionalCastExprClass:
34610b57cec5SDimitry Andric case CXXStaticCastExprClass:
34620b57cec5SDimitry Andric case ImplicitCastExprClass:
34630b57cec5SDimitry Andric case CStyleCastExprClass:
34640b57cec5SDimitry Andric case ObjCBridgedCastExprClass:
34650b57cec5SDimitry Andric case CXXDynamicCastExprClass:
34660b57cec5SDimitry Andric case CXXReinterpretCastExprClass:
34675ffd83dbSDimitry Andric case CXXAddrspaceCastExprClass:
34680b57cec5SDimitry Andric case CXXConstCastExprClass: {
34690b57cec5SDimitry Andric const CastExpr *CE = cast<CastExpr>(this);
34700b57cec5SDimitry Andric
34710b57cec5SDimitry Andric // Handle misc casts we want to ignore.
34720b57cec5SDimitry Andric if (CE->getCastKind() == CK_NoOp ||
34730b57cec5SDimitry Andric CE->getCastKind() == CK_LValueToRValue ||
34740b57cec5SDimitry Andric CE->getCastKind() == CK_ToUnion ||
34750b57cec5SDimitry Andric CE->getCastKind() == CK_ConstructorConversion ||
34760b57cec5SDimitry Andric CE->getCastKind() == CK_NonAtomicToAtomic ||
34770b57cec5SDimitry Andric CE->getCastKind() == CK_AtomicToNonAtomic ||
347806c3fb27SDimitry Andric CE->getCastKind() == CK_NullToPointer ||
34790b57cec5SDimitry Andric CE->getCastKind() == CK_IntToOCLSampler)
34800b57cec5SDimitry Andric return CE->getSubExpr()->isConstantInitializer(Ctx, false, Culprit);
34810b57cec5SDimitry Andric
34820b57cec5SDimitry Andric break;
34830b57cec5SDimitry Andric }
34840b57cec5SDimitry Andric case MaterializeTemporaryExprClass:
3485480093f4SDimitry Andric return cast<MaterializeTemporaryExpr>(this)
3486480093f4SDimitry Andric ->getSubExpr()
34870b57cec5SDimitry Andric ->isConstantInitializer(Ctx, false, Culprit);
34880b57cec5SDimitry Andric
34890b57cec5SDimitry Andric case SubstNonTypeTemplateParmExprClass:
34900b57cec5SDimitry Andric return cast<SubstNonTypeTemplateParmExpr>(this)->getReplacement()
34910b57cec5SDimitry Andric ->isConstantInitializer(Ctx, false, Culprit);
34920b57cec5SDimitry Andric case CXXDefaultArgExprClass:
34930b57cec5SDimitry Andric return cast<CXXDefaultArgExpr>(this)->getExpr()
34940b57cec5SDimitry Andric ->isConstantInitializer(Ctx, false, Culprit);
34950b57cec5SDimitry Andric case CXXDefaultInitExprClass:
34960b57cec5SDimitry Andric return cast<CXXDefaultInitExpr>(this)->getExpr()
34970b57cec5SDimitry Andric ->isConstantInitializer(Ctx, false, Culprit);
34980b57cec5SDimitry Andric }
34990b57cec5SDimitry Andric // Allow certain forms of UB in constant initializers: signed integer
35000b57cec5SDimitry Andric // overflow and floating-point division by zero. We'll give a warning on
35010b57cec5SDimitry Andric // these, but they're common enough that we have to accept them.
35020b57cec5SDimitry Andric if (isEvaluatable(Ctx, SE_AllowUndefinedBehavior))
35030b57cec5SDimitry Andric return true;
35040b57cec5SDimitry Andric if (Culprit)
35050b57cec5SDimitry Andric *Culprit = this;
35060b57cec5SDimitry Andric return false;
35070b57cec5SDimitry Andric }
35080b57cec5SDimitry Andric
isBuiltinAssumeFalse(const ASTContext & Ctx) const35090b57cec5SDimitry Andric bool CallExpr::isBuiltinAssumeFalse(const ASTContext &Ctx) const {
351081ad6265SDimitry Andric unsigned BuiltinID = getBuiltinCallee();
351181ad6265SDimitry Andric if (BuiltinID != Builtin::BI__assume &&
351281ad6265SDimitry Andric BuiltinID != Builtin::BI__builtin_assume)
35130b57cec5SDimitry Andric return false;
35140b57cec5SDimitry Andric
35150b57cec5SDimitry Andric const Expr* Arg = getArg(0);
35160b57cec5SDimitry Andric bool ArgVal;
35170b57cec5SDimitry Andric return !Arg->isValueDependent() &&
35180b57cec5SDimitry Andric Arg->EvaluateAsBooleanCondition(ArgVal, Ctx) && !ArgVal;
35190b57cec5SDimitry Andric }
35200b57cec5SDimitry Andric
isCallToStdMove() const352181ad6265SDimitry Andric bool CallExpr::isCallToStdMove() const {
352281ad6265SDimitry Andric return getBuiltinCallee() == Builtin::BImove;
352381ad6265SDimitry Andric }
352481ad6265SDimitry Andric
35250b57cec5SDimitry Andric namespace {
35260b57cec5SDimitry Andric /// Look for any side effects within a Stmt.
35270b57cec5SDimitry Andric class SideEffectFinder : public ConstEvaluatedExprVisitor<SideEffectFinder> {
35280b57cec5SDimitry Andric typedef ConstEvaluatedExprVisitor<SideEffectFinder> Inherited;
35290b57cec5SDimitry Andric const bool IncludePossibleEffects;
35300b57cec5SDimitry Andric bool HasSideEffects;
35310b57cec5SDimitry Andric
35320b57cec5SDimitry Andric public:
SideEffectFinder(const ASTContext & Context,bool IncludePossible)35330b57cec5SDimitry Andric explicit SideEffectFinder(const ASTContext &Context, bool IncludePossible)
35340b57cec5SDimitry Andric : Inherited(Context),
35350b57cec5SDimitry Andric IncludePossibleEffects(IncludePossible), HasSideEffects(false) { }
35360b57cec5SDimitry Andric
hasSideEffects() const35370b57cec5SDimitry Andric bool hasSideEffects() const { return HasSideEffects; }
35380b57cec5SDimitry Andric
VisitDecl(const Decl * D)35395ffd83dbSDimitry Andric void VisitDecl(const Decl *D) {
35405ffd83dbSDimitry Andric if (!D)
35415ffd83dbSDimitry Andric return;
35425ffd83dbSDimitry Andric
35435ffd83dbSDimitry Andric // We assume the caller checks subexpressions (eg, the initializer, VLA
35445ffd83dbSDimitry Andric // bounds) for side-effects on our behalf.
35455ffd83dbSDimitry Andric if (auto *VD = dyn_cast<VarDecl>(D)) {
35465ffd83dbSDimitry Andric // Registering a destructor is a side-effect.
35475ffd83dbSDimitry Andric if (IncludePossibleEffects && VD->isThisDeclarationADefinition() &&
35485ffd83dbSDimitry Andric VD->needsDestruction(Context))
35495ffd83dbSDimitry Andric HasSideEffects = true;
35505ffd83dbSDimitry Andric }
35515ffd83dbSDimitry Andric }
35525ffd83dbSDimitry Andric
VisitDeclStmt(const DeclStmt * DS)35535ffd83dbSDimitry Andric void VisitDeclStmt(const DeclStmt *DS) {
35545ffd83dbSDimitry Andric for (auto *D : DS->decls())
35555ffd83dbSDimitry Andric VisitDecl(D);
35565ffd83dbSDimitry Andric Inherited::VisitDeclStmt(DS);
35575ffd83dbSDimitry Andric }
35585ffd83dbSDimitry Andric
VisitExpr(const Expr * E)35590b57cec5SDimitry Andric void VisitExpr(const Expr *E) {
35600b57cec5SDimitry Andric if (!HasSideEffects &&
35610b57cec5SDimitry Andric E->HasSideEffects(Context, IncludePossibleEffects))
35620b57cec5SDimitry Andric HasSideEffects = true;
35630b57cec5SDimitry Andric }
35640b57cec5SDimitry Andric };
35650b57cec5SDimitry Andric }
35660b57cec5SDimitry Andric
HasSideEffects(const ASTContext & Ctx,bool IncludePossibleEffects) const35670b57cec5SDimitry Andric bool Expr::HasSideEffects(const ASTContext &Ctx,
35680b57cec5SDimitry Andric bool IncludePossibleEffects) const {
35690b57cec5SDimitry Andric // In circumstances where we care about definite side effects instead of
35700b57cec5SDimitry Andric // potential side effects, we want to ignore expressions that are part of a
35710b57cec5SDimitry Andric // macro expansion as a potential side effect.
35720b57cec5SDimitry Andric if (!IncludePossibleEffects && getExprLoc().isMacroID())
35730b57cec5SDimitry Andric return false;
35740b57cec5SDimitry Andric
35750b57cec5SDimitry Andric switch (getStmtClass()) {
35760b57cec5SDimitry Andric case NoStmtClass:
35770b57cec5SDimitry Andric #define ABSTRACT_STMT(Type)
35780b57cec5SDimitry Andric #define STMT(Type, Base) case Type##Class:
35790b57cec5SDimitry Andric #define EXPR(Type, Base)
35800b57cec5SDimitry Andric #include "clang/AST/StmtNodes.inc"
35810b57cec5SDimitry Andric llvm_unreachable("unexpected Expr kind");
35820b57cec5SDimitry Andric
35830b57cec5SDimitry Andric case DependentScopeDeclRefExprClass:
35840b57cec5SDimitry Andric case CXXUnresolvedConstructExprClass:
35850b57cec5SDimitry Andric case CXXDependentScopeMemberExprClass:
35860b57cec5SDimitry Andric case UnresolvedLookupExprClass:
35870b57cec5SDimitry Andric case UnresolvedMemberExprClass:
35880b57cec5SDimitry Andric case PackExpansionExprClass:
35890b57cec5SDimitry Andric case SubstNonTypeTemplateParmPackExprClass:
35900b57cec5SDimitry Andric case FunctionParmPackExprClass:
35910b57cec5SDimitry Andric case TypoExprClass:
35925ffd83dbSDimitry Andric case RecoveryExprClass:
35930b57cec5SDimitry Andric case CXXFoldExprClass:
3594e8d8bef9SDimitry Andric // Make a conservative assumption for dependent nodes.
3595e8d8bef9SDimitry Andric return IncludePossibleEffects;
35960b57cec5SDimitry Andric
35970b57cec5SDimitry Andric case DeclRefExprClass:
35980b57cec5SDimitry Andric case ObjCIvarRefExprClass:
35990b57cec5SDimitry Andric case PredefinedExprClass:
36000b57cec5SDimitry Andric case IntegerLiteralClass:
36010b57cec5SDimitry Andric case FixedPointLiteralClass:
36020b57cec5SDimitry Andric case FloatingLiteralClass:
36030b57cec5SDimitry Andric case ImaginaryLiteralClass:
36040b57cec5SDimitry Andric case StringLiteralClass:
36050b57cec5SDimitry Andric case CharacterLiteralClass:
36060b57cec5SDimitry Andric case OffsetOfExprClass:
36070b57cec5SDimitry Andric case ImplicitValueInitExprClass:
36080b57cec5SDimitry Andric case UnaryExprOrTypeTraitExprClass:
36090b57cec5SDimitry Andric case AddrLabelExprClass:
36100b57cec5SDimitry Andric case GNUNullExprClass:
36110b57cec5SDimitry Andric case ArrayInitIndexExprClass:
36120b57cec5SDimitry Andric case NoInitExprClass:
36130b57cec5SDimitry Andric case CXXBoolLiteralExprClass:
36140b57cec5SDimitry Andric case CXXNullPtrLiteralExprClass:
36150b57cec5SDimitry Andric case CXXThisExprClass:
36160b57cec5SDimitry Andric case CXXScalarValueInitExprClass:
36170b57cec5SDimitry Andric case TypeTraitExprClass:
36180b57cec5SDimitry Andric case ArrayTypeTraitExprClass:
36190b57cec5SDimitry Andric case ExpressionTraitExprClass:
36200b57cec5SDimitry Andric case CXXNoexceptExprClass:
36210b57cec5SDimitry Andric case SizeOfPackExprClass:
36220b57cec5SDimitry Andric case ObjCStringLiteralClass:
36230b57cec5SDimitry Andric case ObjCEncodeExprClass:
36240b57cec5SDimitry Andric case ObjCBoolLiteralExprClass:
36250b57cec5SDimitry Andric case ObjCAvailabilityCheckExprClass:
36260b57cec5SDimitry Andric case CXXUuidofExprClass:
36270b57cec5SDimitry Andric case OpaqueValueExprClass:
36280b57cec5SDimitry Andric case SourceLocExprClass:
3629*0fca6ea1SDimitry Andric case EmbedExprClass:
3630a7dea167SDimitry Andric case ConceptSpecializationExprClass:
363155e4f9d5SDimitry Andric case RequiresExprClass:
3632fe6060f1SDimitry Andric case SYCLUniqueStableNameExprClass:
3633*0fca6ea1SDimitry Andric case PackIndexingExprClass:
36340b57cec5SDimitry Andric // These never have a side-effect.
36350b57cec5SDimitry Andric return false;
36360b57cec5SDimitry Andric
36370b57cec5SDimitry Andric case ConstantExprClass:
36380b57cec5SDimitry Andric // FIXME: Move this into the "return false;" block above.
36390b57cec5SDimitry Andric return cast<ConstantExpr>(this)->getSubExpr()->HasSideEffects(
36400b57cec5SDimitry Andric Ctx, IncludePossibleEffects);
36410b57cec5SDimitry Andric
36420b57cec5SDimitry Andric case CallExprClass:
36430b57cec5SDimitry Andric case CXXOperatorCallExprClass:
36440b57cec5SDimitry Andric case CXXMemberCallExprClass:
36450b57cec5SDimitry Andric case CUDAKernelCallExprClass:
36460b57cec5SDimitry Andric case UserDefinedLiteralClass: {
36470b57cec5SDimitry Andric // We don't know a call definitely has side effects, except for calls
36480b57cec5SDimitry Andric // to pure/const functions that definitely don't.
36490b57cec5SDimitry Andric // If the call itself is considered side-effect free, check the operands.
36500b57cec5SDimitry Andric const Decl *FD = cast<CallExpr>(this)->getCalleeDecl();
36510b57cec5SDimitry Andric bool IsPure = FD && (FD->hasAttr<ConstAttr>() || FD->hasAttr<PureAttr>());
36520b57cec5SDimitry Andric if (IsPure || !IncludePossibleEffects)
36530b57cec5SDimitry Andric break;
36540b57cec5SDimitry Andric return true;
36550b57cec5SDimitry Andric }
36560b57cec5SDimitry Andric
36570b57cec5SDimitry Andric case BlockExprClass:
36580b57cec5SDimitry Andric case CXXBindTemporaryExprClass:
36590b57cec5SDimitry Andric if (!IncludePossibleEffects)
36600b57cec5SDimitry Andric break;
36610b57cec5SDimitry Andric return true;
36620b57cec5SDimitry Andric
36630b57cec5SDimitry Andric case MSPropertyRefExprClass:
36640b57cec5SDimitry Andric case MSPropertySubscriptExprClass:
36650b57cec5SDimitry Andric case CompoundAssignOperatorClass:
36660b57cec5SDimitry Andric case VAArgExprClass:
36670b57cec5SDimitry Andric case AtomicExprClass:
36680b57cec5SDimitry Andric case CXXThrowExprClass:
36690b57cec5SDimitry Andric case CXXNewExprClass:
36700b57cec5SDimitry Andric case CXXDeleteExprClass:
36710b57cec5SDimitry Andric case CoawaitExprClass:
36720b57cec5SDimitry Andric case DependentCoawaitExprClass:
36730b57cec5SDimitry Andric case CoyieldExprClass:
36740b57cec5SDimitry Andric // These always have a side-effect.
36750b57cec5SDimitry Andric return true;
36760b57cec5SDimitry Andric
36770b57cec5SDimitry Andric case StmtExprClass: {
36780b57cec5SDimitry Andric // StmtExprs have a side-effect if any substatement does.
36790b57cec5SDimitry Andric SideEffectFinder Finder(Ctx, IncludePossibleEffects);
36800b57cec5SDimitry Andric Finder.Visit(cast<StmtExpr>(this)->getSubStmt());
36810b57cec5SDimitry Andric return Finder.hasSideEffects();
36820b57cec5SDimitry Andric }
36830b57cec5SDimitry Andric
36840b57cec5SDimitry Andric case ExprWithCleanupsClass:
36850b57cec5SDimitry Andric if (IncludePossibleEffects)
36860b57cec5SDimitry Andric if (cast<ExprWithCleanups>(this)->cleanupsHaveSideEffects())
36870b57cec5SDimitry Andric return true;
36880b57cec5SDimitry Andric break;
36890b57cec5SDimitry Andric
36900b57cec5SDimitry Andric case ParenExprClass:
36910b57cec5SDimitry Andric case ArraySubscriptExprClass:
36925ffd83dbSDimitry Andric case MatrixSubscriptExprClass:
3693*0fca6ea1SDimitry Andric case ArraySectionExprClass:
36945ffd83dbSDimitry Andric case OMPArrayShapingExprClass:
36955ffd83dbSDimitry Andric case OMPIteratorExprClass:
36960b57cec5SDimitry Andric case MemberExprClass:
36970b57cec5SDimitry Andric case ConditionalOperatorClass:
36980b57cec5SDimitry Andric case BinaryConditionalOperatorClass:
36990b57cec5SDimitry Andric case CompoundLiteralExprClass:
37000b57cec5SDimitry Andric case ExtVectorElementExprClass:
37010b57cec5SDimitry Andric case DesignatedInitExprClass:
37020b57cec5SDimitry Andric case DesignatedInitUpdateExprClass:
37030b57cec5SDimitry Andric case ArrayInitLoopExprClass:
37040b57cec5SDimitry Andric case ParenListExprClass:
37050b57cec5SDimitry Andric case CXXPseudoDestructorExprClass:
3706a7dea167SDimitry Andric case CXXRewrittenBinaryOperatorClass:
37070b57cec5SDimitry Andric case CXXStdInitializerListExprClass:
37080b57cec5SDimitry Andric case SubstNonTypeTemplateParmExprClass:
37090b57cec5SDimitry Andric case MaterializeTemporaryExprClass:
37100b57cec5SDimitry Andric case ShuffleVectorExprClass:
37110b57cec5SDimitry Andric case ConvertVectorExprClass:
37120b57cec5SDimitry Andric case AsTypeExprClass:
3713bdd1243dSDimitry Andric case CXXParenListInitExprClass:
37140b57cec5SDimitry Andric // These have a side-effect if any subexpression does.
37150b57cec5SDimitry Andric break;
37160b57cec5SDimitry Andric
37170b57cec5SDimitry Andric case UnaryOperatorClass:
37180b57cec5SDimitry Andric if (cast<UnaryOperator>(this)->isIncrementDecrementOp())
37190b57cec5SDimitry Andric return true;
37200b57cec5SDimitry Andric break;
37210b57cec5SDimitry Andric
37220b57cec5SDimitry Andric case BinaryOperatorClass:
37230b57cec5SDimitry Andric if (cast<BinaryOperator>(this)->isAssignmentOp())
37240b57cec5SDimitry Andric return true;
37250b57cec5SDimitry Andric break;
37260b57cec5SDimitry Andric
37270b57cec5SDimitry Andric case InitListExprClass:
37280b57cec5SDimitry Andric // FIXME: The children for an InitListExpr doesn't include the array filler.
37290b57cec5SDimitry Andric if (const Expr *E = cast<InitListExpr>(this)->getArrayFiller())
37300b57cec5SDimitry Andric if (E->HasSideEffects(Ctx, IncludePossibleEffects))
37310b57cec5SDimitry Andric return true;
37320b57cec5SDimitry Andric break;
37330b57cec5SDimitry Andric
37340b57cec5SDimitry Andric case GenericSelectionExprClass:
37350b57cec5SDimitry Andric return cast<GenericSelectionExpr>(this)->getResultExpr()->
37360b57cec5SDimitry Andric HasSideEffects(Ctx, IncludePossibleEffects);
37370b57cec5SDimitry Andric
37380b57cec5SDimitry Andric case ChooseExprClass:
37390b57cec5SDimitry Andric return cast<ChooseExpr>(this)->getChosenSubExpr()->HasSideEffects(
37400b57cec5SDimitry Andric Ctx, IncludePossibleEffects);
37410b57cec5SDimitry Andric
37420b57cec5SDimitry Andric case CXXDefaultArgExprClass:
37430b57cec5SDimitry Andric return cast<CXXDefaultArgExpr>(this)->getExpr()->HasSideEffects(
37440b57cec5SDimitry Andric Ctx, IncludePossibleEffects);
37450b57cec5SDimitry Andric
37460b57cec5SDimitry Andric case CXXDefaultInitExprClass: {
37470b57cec5SDimitry Andric const FieldDecl *FD = cast<CXXDefaultInitExpr>(this)->getField();
37480b57cec5SDimitry Andric if (const Expr *E = FD->getInClassInitializer())
37490b57cec5SDimitry Andric return E->HasSideEffects(Ctx, IncludePossibleEffects);
37500b57cec5SDimitry Andric // If we've not yet parsed the initializer, assume it has side-effects.
37510b57cec5SDimitry Andric return true;
37520b57cec5SDimitry Andric }
37530b57cec5SDimitry Andric
37540b57cec5SDimitry Andric case CXXDynamicCastExprClass: {
37550b57cec5SDimitry Andric // A dynamic_cast expression has side-effects if it can throw.
37560b57cec5SDimitry Andric const CXXDynamicCastExpr *DCE = cast<CXXDynamicCastExpr>(this);
37570b57cec5SDimitry Andric if (DCE->getTypeAsWritten()->isReferenceType() &&
37580b57cec5SDimitry Andric DCE->getCastKind() == CK_Dynamic)
37590b57cec5SDimitry Andric return true;
37600b57cec5SDimitry Andric }
3761bdd1243dSDimitry Andric [[fallthrough]];
37620b57cec5SDimitry Andric case ImplicitCastExprClass:
37630b57cec5SDimitry Andric case CStyleCastExprClass:
37640b57cec5SDimitry Andric case CXXStaticCastExprClass:
37650b57cec5SDimitry Andric case CXXReinterpretCastExprClass:
37660b57cec5SDimitry Andric case CXXConstCastExprClass:
37675ffd83dbSDimitry Andric case CXXAddrspaceCastExprClass:
37680b57cec5SDimitry Andric case CXXFunctionalCastExprClass:
37690b57cec5SDimitry Andric case BuiltinBitCastExprClass: {
37700b57cec5SDimitry Andric // While volatile reads are side-effecting in both C and C++, we treat them
37710b57cec5SDimitry Andric // as having possible (not definite) side-effects. This allows idiomatic
37720b57cec5SDimitry Andric // code to behave without warning, such as sizeof(*v) for a volatile-
37730b57cec5SDimitry Andric // qualified pointer.
37740b57cec5SDimitry Andric if (!IncludePossibleEffects)
37750b57cec5SDimitry Andric break;
37760b57cec5SDimitry Andric
37770b57cec5SDimitry Andric const CastExpr *CE = cast<CastExpr>(this);
37780b57cec5SDimitry Andric if (CE->getCastKind() == CK_LValueToRValue &&
37790b57cec5SDimitry Andric CE->getSubExpr()->getType().isVolatileQualified())
37800b57cec5SDimitry Andric return true;
37810b57cec5SDimitry Andric break;
37820b57cec5SDimitry Andric }
37830b57cec5SDimitry Andric
3784*0fca6ea1SDimitry Andric case CXXTypeidExprClass: {
3785*0fca6ea1SDimitry Andric const auto *TE = cast<CXXTypeidExpr>(this);
3786*0fca6ea1SDimitry Andric if (!TE->isPotentiallyEvaluated())
3787*0fca6ea1SDimitry Andric return false;
3788*0fca6ea1SDimitry Andric
3789*0fca6ea1SDimitry Andric // If this type id expression can throw because of a null pointer, that is a
3790*0fca6ea1SDimitry Andric // side-effect independent of if the operand has a side-effect
3791*0fca6ea1SDimitry Andric if (IncludePossibleEffects && TE->hasNullCheck())
3792*0fca6ea1SDimitry Andric return true;
3793*0fca6ea1SDimitry Andric
3794*0fca6ea1SDimitry Andric break;
3795*0fca6ea1SDimitry Andric }
37960b57cec5SDimitry Andric
37970b57cec5SDimitry Andric case CXXConstructExprClass:
37980b57cec5SDimitry Andric case CXXTemporaryObjectExprClass: {
37990b57cec5SDimitry Andric const CXXConstructExpr *CE = cast<CXXConstructExpr>(this);
38000b57cec5SDimitry Andric if (!CE->getConstructor()->isTrivial() && IncludePossibleEffects)
38010b57cec5SDimitry Andric return true;
38020b57cec5SDimitry Andric // A trivial constructor does not add any side-effects of its own. Just look
38030b57cec5SDimitry Andric // at its arguments.
38040b57cec5SDimitry Andric break;
38050b57cec5SDimitry Andric }
38060b57cec5SDimitry Andric
38070b57cec5SDimitry Andric case CXXInheritedCtorInitExprClass: {
38080b57cec5SDimitry Andric const auto *ICIE = cast<CXXInheritedCtorInitExpr>(this);
38090b57cec5SDimitry Andric if (!ICIE->getConstructor()->isTrivial() && IncludePossibleEffects)
38100b57cec5SDimitry Andric return true;
38110b57cec5SDimitry Andric break;
38120b57cec5SDimitry Andric }
38130b57cec5SDimitry Andric
38140b57cec5SDimitry Andric case LambdaExprClass: {
38150b57cec5SDimitry Andric const LambdaExpr *LE = cast<LambdaExpr>(this);
38160b57cec5SDimitry Andric for (Expr *E : LE->capture_inits())
38175ffd83dbSDimitry Andric if (E && E->HasSideEffects(Ctx, IncludePossibleEffects))
38180b57cec5SDimitry Andric return true;
38190b57cec5SDimitry Andric return false;
38200b57cec5SDimitry Andric }
38210b57cec5SDimitry Andric
38220b57cec5SDimitry Andric case PseudoObjectExprClass: {
38230b57cec5SDimitry Andric // Only look for side-effects in the semantic form, and look past
38240b57cec5SDimitry Andric // OpaqueValueExpr bindings in that form.
38250b57cec5SDimitry Andric const PseudoObjectExpr *PO = cast<PseudoObjectExpr>(this);
38260b57cec5SDimitry Andric for (PseudoObjectExpr::const_semantics_iterator I = PO->semantics_begin(),
38270b57cec5SDimitry Andric E = PO->semantics_end();
38280b57cec5SDimitry Andric I != E; ++I) {
38290b57cec5SDimitry Andric const Expr *Subexpr = *I;
38300b57cec5SDimitry Andric if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(Subexpr))
38310b57cec5SDimitry Andric Subexpr = OVE->getSourceExpr();
38320b57cec5SDimitry Andric if (Subexpr->HasSideEffects(Ctx, IncludePossibleEffects))
38330b57cec5SDimitry Andric return true;
38340b57cec5SDimitry Andric }
38350b57cec5SDimitry Andric return false;
38360b57cec5SDimitry Andric }
38370b57cec5SDimitry Andric
38380b57cec5SDimitry Andric case ObjCBoxedExprClass:
38390b57cec5SDimitry Andric case ObjCArrayLiteralClass:
38400b57cec5SDimitry Andric case ObjCDictionaryLiteralClass:
38410b57cec5SDimitry Andric case ObjCSelectorExprClass:
38420b57cec5SDimitry Andric case ObjCProtocolExprClass:
38430b57cec5SDimitry Andric case ObjCIsaExprClass:
38440b57cec5SDimitry Andric case ObjCIndirectCopyRestoreExprClass:
38450b57cec5SDimitry Andric case ObjCSubscriptRefExprClass:
38460b57cec5SDimitry Andric case ObjCBridgedCastExprClass:
38470b57cec5SDimitry Andric case ObjCMessageExprClass:
38480b57cec5SDimitry Andric case ObjCPropertyRefExprClass:
38490b57cec5SDimitry Andric // FIXME: Classify these cases better.
38500b57cec5SDimitry Andric if (IncludePossibleEffects)
38510b57cec5SDimitry Andric return true;
38520b57cec5SDimitry Andric break;
38530b57cec5SDimitry Andric }
38540b57cec5SDimitry Andric
38550b57cec5SDimitry Andric // Recurse to children.
38560b57cec5SDimitry Andric for (const Stmt *SubStmt : children())
38570b57cec5SDimitry Andric if (SubStmt &&
38580b57cec5SDimitry Andric cast<Expr>(SubStmt)->HasSideEffects(Ctx, IncludePossibleEffects))
38590b57cec5SDimitry Andric return true;
38600b57cec5SDimitry Andric
38610b57cec5SDimitry Andric return false;
38620b57cec5SDimitry Andric }
38630b57cec5SDimitry Andric
getFPFeaturesInEffect(const LangOptions & LO) const3864e8d8bef9SDimitry Andric FPOptions Expr::getFPFeaturesInEffect(const LangOptions &LO) const {
3865e8d8bef9SDimitry Andric if (auto Call = dyn_cast<CallExpr>(this))
3866e8d8bef9SDimitry Andric return Call->getFPFeaturesInEffect(LO);
3867e8d8bef9SDimitry Andric if (auto UO = dyn_cast<UnaryOperator>(this))
3868e8d8bef9SDimitry Andric return UO->getFPFeaturesInEffect(LO);
3869e8d8bef9SDimitry Andric if (auto BO = dyn_cast<BinaryOperator>(this))
3870e8d8bef9SDimitry Andric return BO->getFPFeaturesInEffect(LO);
3871e8d8bef9SDimitry Andric if (auto Cast = dyn_cast<CastExpr>(this))
3872e8d8bef9SDimitry Andric return Cast->getFPFeaturesInEffect(LO);
3873e8d8bef9SDimitry Andric return FPOptions::defaultWithoutTrailingStorage(LO);
3874e8d8bef9SDimitry Andric }
3875e8d8bef9SDimitry Andric
38760b57cec5SDimitry Andric namespace {
38770b57cec5SDimitry Andric /// Look for a call to a non-trivial function within an expression.
38780b57cec5SDimitry Andric class NonTrivialCallFinder : public ConstEvaluatedExprVisitor<NonTrivialCallFinder>
38790b57cec5SDimitry Andric {
38800b57cec5SDimitry Andric typedef ConstEvaluatedExprVisitor<NonTrivialCallFinder> Inherited;
38810b57cec5SDimitry Andric
38820b57cec5SDimitry Andric bool NonTrivial;
38830b57cec5SDimitry Andric
38840b57cec5SDimitry Andric public:
NonTrivialCallFinder(const ASTContext & Context)38850b57cec5SDimitry Andric explicit NonTrivialCallFinder(const ASTContext &Context)
38860b57cec5SDimitry Andric : Inherited(Context), NonTrivial(false) { }
38870b57cec5SDimitry Andric
hasNonTrivialCall() const38880b57cec5SDimitry Andric bool hasNonTrivialCall() const { return NonTrivial; }
38890b57cec5SDimitry Andric
VisitCallExpr(const CallExpr * E)38900b57cec5SDimitry Andric void VisitCallExpr(const CallExpr *E) {
38910b57cec5SDimitry Andric if (const CXXMethodDecl *Method
38920b57cec5SDimitry Andric = dyn_cast_or_null<const CXXMethodDecl>(E->getCalleeDecl())) {
38930b57cec5SDimitry Andric if (Method->isTrivial()) {
38940b57cec5SDimitry Andric // Recurse to children of the call.
38950b57cec5SDimitry Andric Inherited::VisitStmt(E);
38960b57cec5SDimitry Andric return;
38970b57cec5SDimitry Andric }
38980b57cec5SDimitry Andric }
38990b57cec5SDimitry Andric
39000b57cec5SDimitry Andric NonTrivial = true;
39010b57cec5SDimitry Andric }
39020b57cec5SDimitry Andric
VisitCXXConstructExpr(const CXXConstructExpr * E)39030b57cec5SDimitry Andric void VisitCXXConstructExpr(const CXXConstructExpr *E) {
39040b57cec5SDimitry Andric if (E->getConstructor()->isTrivial()) {
39050b57cec5SDimitry Andric // Recurse to children of the call.
39060b57cec5SDimitry Andric Inherited::VisitStmt(E);
39070b57cec5SDimitry Andric return;
39080b57cec5SDimitry Andric }
39090b57cec5SDimitry Andric
39100b57cec5SDimitry Andric NonTrivial = true;
39110b57cec5SDimitry Andric }
39120b57cec5SDimitry Andric
VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr * E)39130b57cec5SDimitry Andric void VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *E) {
3914*0fca6ea1SDimitry Andric // Destructor of the temporary might be null if destructor declaration
3915*0fca6ea1SDimitry Andric // is not valid.
3916*0fca6ea1SDimitry Andric if (const CXXDestructorDecl *DtorDecl =
3917*0fca6ea1SDimitry Andric E->getTemporary()->getDestructor()) {
3918*0fca6ea1SDimitry Andric if (DtorDecl->isTrivial()) {
39190b57cec5SDimitry Andric Inherited::VisitStmt(E);
39200b57cec5SDimitry Andric return;
39210b57cec5SDimitry Andric }
3922*0fca6ea1SDimitry Andric }
39230b57cec5SDimitry Andric
39240b57cec5SDimitry Andric NonTrivial = true;
39250b57cec5SDimitry Andric }
39260b57cec5SDimitry Andric };
39270b57cec5SDimitry Andric }
39280b57cec5SDimitry Andric
hasNonTrivialCall(const ASTContext & Ctx) const39290b57cec5SDimitry Andric bool Expr::hasNonTrivialCall(const ASTContext &Ctx) const {
39300b57cec5SDimitry Andric NonTrivialCallFinder Finder(Ctx);
39310b57cec5SDimitry Andric Finder.Visit(this);
39320b57cec5SDimitry Andric return Finder.hasNonTrivialCall();
39330b57cec5SDimitry Andric }
39340b57cec5SDimitry Andric
39350b57cec5SDimitry Andric /// isNullPointerConstant - C99 6.3.2.3p3 - Return whether this is a null
39360b57cec5SDimitry Andric /// pointer constant or not, as well as the specific kind of constant detected.
39370b57cec5SDimitry Andric /// Null pointer constants can be integer constant expressions with the
39380b57cec5SDimitry Andric /// value zero, casts of zero to void*, nullptr (C++0X), or __null
39390b57cec5SDimitry Andric /// (a GNU extension).
39400b57cec5SDimitry Andric Expr::NullPointerConstantKind
isNullPointerConstant(ASTContext & Ctx,NullPointerConstantValueDependence NPC) const39410b57cec5SDimitry Andric Expr::isNullPointerConstant(ASTContext &Ctx,
39420b57cec5SDimitry Andric NullPointerConstantValueDependence NPC) const {
39430b57cec5SDimitry Andric if (isValueDependent() &&
39440b57cec5SDimitry Andric (!Ctx.getLangOpts().CPlusPlus11 || Ctx.getLangOpts().MSVCCompat)) {
3945e8d8bef9SDimitry Andric // Error-dependent expr should never be a null pointer.
3946e8d8bef9SDimitry Andric if (containsErrors())
3947e8d8bef9SDimitry Andric return NPCK_NotNull;
39480b57cec5SDimitry Andric switch (NPC) {
39490b57cec5SDimitry Andric case NPC_NeverValueDependent:
39500b57cec5SDimitry Andric llvm_unreachable("Unexpected value dependent expression!");
39510b57cec5SDimitry Andric case NPC_ValueDependentIsNull:
39520b57cec5SDimitry Andric if (isTypeDependent() || getType()->isIntegralType(Ctx))
39530b57cec5SDimitry Andric return NPCK_ZeroExpression;
39540b57cec5SDimitry Andric else
39550b57cec5SDimitry Andric return NPCK_NotNull;
39560b57cec5SDimitry Andric
39570b57cec5SDimitry Andric case NPC_ValueDependentIsNotNull:
39580b57cec5SDimitry Andric return NPCK_NotNull;
39590b57cec5SDimitry Andric }
39600b57cec5SDimitry Andric }
39610b57cec5SDimitry Andric
39620b57cec5SDimitry Andric // Strip off a cast to void*, if it exists. Except in C++.
39630b57cec5SDimitry Andric if (const ExplicitCastExpr *CE = dyn_cast<ExplicitCastExpr>(this)) {
39640b57cec5SDimitry Andric if (!Ctx.getLangOpts().CPlusPlus) {
39650b57cec5SDimitry Andric // Check that it is a cast to void*.
39660b57cec5SDimitry Andric if (const PointerType *PT = CE->getType()->getAs<PointerType>()) {
39670b57cec5SDimitry Andric QualType Pointee = PT->getPointeeType();
39680b57cec5SDimitry Andric Qualifiers Qs = Pointee.getQualifiers();
39690b57cec5SDimitry Andric // Only (void*)0 or equivalent are treated as nullptr. If pointee type
39700b57cec5SDimitry Andric // has non-default address space it is not treated as nullptr.
39710b57cec5SDimitry Andric // (__generic void*)0 in OpenCL 2.0 should not be treated as nullptr
39720b57cec5SDimitry Andric // since it cannot be assigned to a pointer to constant address space.
3973349cc55cSDimitry Andric if (Ctx.getLangOpts().OpenCL &&
3974349cc55cSDimitry Andric Pointee.getAddressSpace() == Ctx.getDefaultOpenCLPointeeAddrSpace())
39750b57cec5SDimitry Andric Qs.removeAddressSpace();
39760b57cec5SDimitry Andric
39770b57cec5SDimitry Andric if (Pointee->isVoidType() && Qs.empty() && // to void*
39780b57cec5SDimitry Andric CE->getSubExpr()->getType()->isIntegerType()) // from int
39790b57cec5SDimitry Andric return CE->getSubExpr()->isNullPointerConstant(Ctx, NPC);
39800b57cec5SDimitry Andric }
39810b57cec5SDimitry Andric }
39820b57cec5SDimitry Andric } else if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(this)) {
39830b57cec5SDimitry Andric // Ignore the ImplicitCastExpr type entirely.
39840b57cec5SDimitry Andric return ICE->getSubExpr()->isNullPointerConstant(Ctx, NPC);
39850b57cec5SDimitry Andric } else if (const ParenExpr *PE = dyn_cast<ParenExpr>(this)) {
39860b57cec5SDimitry Andric // Accept ((void*)0) as a null pointer constant, as many other
39870b57cec5SDimitry Andric // implementations do.
39880b57cec5SDimitry Andric return PE->getSubExpr()->isNullPointerConstant(Ctx, NPC);
39890b57cec5SDimitry Andric } else if (const GenericSelectionExpr *GE =
39900b57cec5SDimitry Andric dyn_cast<GenericSelectionExpr>(this)) {
39910b57cec5SDimitry Andric if (GE->isResultDependent())
39920b57cec5SDimitry Andric return NPCK_NotNull;
39930b57cec5SDimitry Andric return GE->getResultExpr()->isNullPointerConstant(Ctx, NPC);
39940b57cec5SDimitry Andric } else if (const ChooseExpr *CE = dyn_cast<ChooseExpr>(this)) {
39950b57cec5SDimitry Andric if (CE->isConditionDependent())
39960b57cec5SDimitry Andric return NPCK_NotNull;
39970b57cec5SDimitry Andric return CE->getChosenSubExpr()->isNullPointerConstant(Ctx, NPC);
39980b57cec5SDimitry Andric } else if (const CXXDefaultArgExpr *DefaultArg
39990b57cec5SDimitry Andric = dyn_cast<CXXDefaultArgExpr>(this)) {
40000b57cec5SDimitry Andric // See through default argument expressions.
40010b57cec5SDimitry Andric return DefaultArg->getExpr()->isNullPointerConstant(Ctx, NPC);
40020b57cec5SDimitry Andric } else if (const CXXDefaultInitExpr *DefaultInit
40030b57cec5SDimitry Andric = dyn_cast<CXXDefaultInitExpr>(this)) {
40040b57cec5SDimitry Andric // See through default initializer expressions.
40050b57cec5SDimitry Andric return DefaultInit->getExpr()->isNullPointerConstant(Ctx, NPC);
40060b57cec5SDimitry Andric } else if (isa<GNUNullExpr>(this)) {
40070b57cec5SDimitry Andric // The GNU __null extension is always a null pointer constant.
40080b57cec5SDimitry Andric return NPCK_GNUNull;
40090b57cec5SDimitry Andric } else if (const MaterializeTemporaryExpr *M
40100b57cec5SDimitry Andric = dyn_cast<MaterializeTemporaryExpr>(this)) {
4011480093f4SDimitry Andric return M->getSubExpr()->isNullPointerConstant(Ctx, NPC);
40120b57cec5SDimitry Andric } else if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(this)) {
40130b57cec5SDimitry Andric if (const Expr *Source = OVE->getSourceExpr())
40140b57cec5SDimitry Andric return Source->isNullPointerConstant(Ctx, NPC);
40150b57cec5SDimitry Andric }
40160b57cec5SDimitry Andric
40175ffd83dbSDimitry Andric // If the expression has no type information, it cannot be a null pointer
40185ffd83dbSDimitry Andric // constant.
40195ffd83dbSDimitry Andric if (getType().isNull())
40205ffd83dbSDimitry Andric return NPCK_NotNull;
40215ffd83dbSDimitry Andric
40225f757f3fSDimitry Andric // C++11/C23 nullptr_t is always a null pointer constant.
40230b57cec5SDimitry Andric if (getType()->isNullPtrType())
40240b57cec5SDimitry Andric return NPCK_CXX11_nullptr;
40250b57cec5SDimitry Andric
40260b57cec5SDimitry Andric if (const RecordType *UT = getType()->getAsUnionType())
40270b57cec5SDimitry Andric if (!Ctx.getLangOpts().CPlusPlus11 &&
40280b57cec5SDimitry Andric UT && UT->getDecl()->hasAttr<TransparentUnionAttr>())
40290b57cec5SDimitry Andric if (const CompoundLiteralExpr *CLE = dyn_cast<CompoundLiteralExpr>(this)){
40300b57cec5SDimitry Andric const Expr *InitExpr = CLE->getInitializer();
40310b57cec5SDimitry Andric if (const InitListExpr *ILE = dyn_cast<InitListExpr>(InitExpr))
40320b57cec5SDimitry Andric return ILE->getInit(0)->isNullPointerConstant(Ctx, NPC);
40330b57cec5SDimitry Andric }
40340b57cec5SDimitry Andric // This expression must be an integer type.
40350b57cec5SDimitry Andric if (!getType()->isIntegerType() ||
40360b57cec5SDimitry Andric (Ctx.getLangOpts().CPlusPlus && getType()->isEnumeralType()))
40370b57cec5SDimitry Andric return NPCK_NotNull;
40380b57cec5SDimitry Andric
40390b57cec5SDimitry Andric if (Ctx.getLangOpts().CPlusPlus11) {
40400b57cec5SDimitry Andric // C++11 [conv.ptr]p1: A null pointer constant is an integer literal with
40410b57cec5SDimitry Andric // value zero or a prvalue of type std::nullptr_t.
40420b57cec5SDimitry Andric // Microsoft mode permits C++98 rules reflecting MSVC behavior.
40430b57cec5SDimitry Andric const IntegerLiteral *Lit = dyn_cast<IntegerLiteral>(this);
40440b57cec5SDimitry Andric if (Lit && !Lit->getValue())
40450b57cec5SDimitry Andric return NPCK_ZeroLiteral;
4046e8d8bef9SDimitry Andric if (!Ctx.getLangOpts().MSVCCompat || !isCXX98IntegralConstantExpr(Ctx))
40470b57cec5SDimitry Andric return NPCK_NotNull;
40480b57cec5SDimitry Andric } else {
40490b57cec5SDimitry Andric // If we have an integer constant expression, we need to *evaluate* it and
40500b57cec5SDimitry Andric // test for the value 0.
40510b57cec5SDimitry Andric if (!isIntegerConstantExpr(Ctx))
40520b57cec5SDimitry Andric return NPCK_NotNull;
40530b57cec5SDimitry Andric }
40540b57cec5SDimitry Andric
40550b57cec5SDimitry Andric if (EvaluateKnownConstInt(Ctx) != 0)
40560b57cec5SDimitry Andric return NPCK_NotNull;
40570b57cec5SDimitry Andric
40580b57cec5SDimitry Andric if (isa<IntegerLiteral>(this))
40590b57cec5SDimitry Andric return NPCK_ZeroLiteral;
40600b57cec5SDimitry Andric return NPCK_ZeroExpression;
40610b57cec5SDimitry Andric }
40620b57cec5SDimitry Andric
40630b57cec5SDimitry Andric /// If this expression is an l-value for an Objective C
40640b57cec5SDimitry Andric /// property, find the underlying property reference expression.
getObjCProperty() const40650b57cec5SDimitry Andric const ObjCPropertyRefExpr *Expr::getObjCProperty() const {
40660b57cec5SDimitry Andric const Expr *E = this;
40670b57cec5SDimitry Andric while (true) {
4068fe6060f1SDimitry Andric assert((E->isLValue() && E->getObjectKind() == OK_ObjCProperty) &&
40690b57cec5SDimitry Andric "expression is not a property reference");
40700b57cec5SDimitry Andric E = E->IgnoreParenCasts();
40710b57cec5SDimitry Andric if (const BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) {
40720b57cec5SDimitry Andric if (BO->getOpcode() == BO_Comma) {
40730b57cec5SDimitry Andric E = BO->getRHS();
40740b57cec5SDimitry Andric continue;
40750b57cec5SDimitry Andric }
40760b57cec5SDimitry Andric }
40770b57cec5SDimitry Andric
40780b57cec5SDimitry Andric break;
40790b57cec5SDimitry Andric }
40800b57cec5SDimitry Andric
40810b57cec5SDimitry Andric return cast<ObjCPropertyRefExpr>(E);
40820b57cec5SDimitry Andric }
40830b57cec5SDimitry Andric
isObjCSelfExpr() const40840b57cec5SDimitry Andric bool Expr::isObjCSelfExpr() const {
40850b57cec5SDimitry Andric const Expr *E = IgnoreParenImpCasts();
40860b57cec5SDimitry Andric
40870b57cec5SDimitry Andric const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E);
40880b57cec5SDimitry Andric if (!DRE)
40890b57cec5SDimitry Andric return false;
40900b57cec5SDimitry Andric
40910b57cec5SDimitry Andric const ImplicitParamDecl *Param = dyn_cast<ImplicitParamDecl>(DRE->getDecl());
40920b57cec5SDimitry Andric if (!Param)
40930b57cec5SDimitry Andric return false;
40940b57cec5SDimitry Andric
40950b57cec5SDimitry Andric const ObjCMethodDecl *M = dyn_cast<ObjCMethodDecl>(Param->getDeclContext());
40960b57cec5SDimitry Andric if (!M)
40970b57cec5SDimitry Andric return false;
40980b57cec5SDimitry Andric
40990b57cec5SDimitry Andric return M->getSelfDecl() == Param;
41000b57cec5SDimitry Andric }
41010b57cec5SDimitry Andric
getSourceBitField()41020b57cec5SDimitry Andric FieldDecl *Expr::getSourceBitField() {
41030b57cec5SDimitry Andric Expr *E = this->IgnoreParens();
41040b57cec5SDimitry Andric
41050b57cec5SDimitry Andric while (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) {
41060b57cec5SDimitry Andric if (ICE->getCastKind() == CK_LValueToRValue ||
4107fe6060f1SDimitry Andric (ICE->isGLValue() && ICE->getCastKind() == CK_NoOp))
41080b57cec5SDimitry Andric E = ICE->getSubExpr()->IgnoreParens();
41090b57cec5SDimitry Andric else
41100b57cec5SDimitry Andric break;
41110b57cec5SDimitry Andric }
41120b57cec5SDimitry Andric
41130b57cec5SDimitry Andric if (MemberExpr *MemRef = dyn_cast<MemberExpr>(E))
41140b57cec5SDimitry Andric if (FieldDecl *Field = dyn_cast<FieldDecl>(MemRef->getMemberDecl()))
41150b57cec5SDimitry Andric if (Field->isBitField())
41160b57cec5SDimitry Andric return Field;
41170b57cec5SDimitry Andric
41180b57cec5SDimitry Andric if (ObjCIvarRefExpr *IvarRef = dyn_cast<ObjCIvarRefExpr>(E)) {
41190b57cec5SDimitry Andric FieldDecl *Ivar = IvarRef->getDecl();
41200b57cec5SDimitry Andric if (Ivar->isBitField())
41210b57cec5SDimitry Andric return Ivar;
41220b57cec5SDimitry Andric }
41230b57cec5SDimitry Andric
41240b57cec5SDimitry Andric if (DeclRefExpr *DeclRef = dyn_cast<DeclRefExpr>(E)) {
41250b57cec5SDimitry Andric if (FieldDecl *Field = dyn_cast<FieldDecl>(DeclRef->getDecl()))
41260b57cec5SDimitry Andric if (Field->isBitField())
41270b57cec5SDimitry Andric return Field;
41280b57cec5SDimitry Andric
41290b57cec5SDimitry Andric if (BindingDecl *BD = dyn_cast<BindingDecl>(DeclRef->getDecl()))
41300b57cec5SDimitry Andric if (Expr *E = BD->getBinding())
41310b57cec5SDimitry Andric return E->getSourceBitField();
41320b57cec5SDimitry Andric }
41330b57cec5SDimitry Andric
41340b57cec5SDimitry Andric if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(E)) {
41350b57cec5SDimitry Andric if (BinOp->isAssignmentOp() && BinOp->getLHS())
41360b57cec5SDimitry Andric return BinOp->getLHS()->getSourceBitField();
41370b57cec5SDimitry Andric
41380b57cec5SDimitry Andric if (BinOp->getOpcode() == BO_Comma && BinOp->getRHS())
41390b57cec5SDimitry Andric return BinOp->getRHS()->getSourceBitField();
41400b57cec5SDimitry Andric }
41410b57cec5SDimitry Andric
41420b57cec5SDimitry Andric if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(E))
41430b57cec5SDimitry Andric if (UnOp->isPrefix() && UnOp->isIncrementDecrementOp())
41440b57cec5SDimitry Andric return UnOp->getSubExpr()->getSourceBitField();
41450b57cec5SDimitry Andric
41460b57cec5SDimitry Andric return nullptr;
41470b57cec5SDimitry Andric }
41480b57cec5SDimitry Andric
getEnumConstantDecl()4149*0fca6ea1SDimitry Andric EnumConstantDecl *Expr::getEnumConstantDecl() {
4150*0fca6ea1SDimitry Andric Expr *E = this->IgnoreParenImpCasts();
4151*0fca6ea1SDimitry Andric if (auto *DRE = dyn_cast<DeclRefExpr>(E))
4152*0fca6ea1SDimitry Andric return dyn_cast<EnumConstantDecl>(DRE->getDecl());
4153*0fca6ea1SDimitry Andric return nullptr;
4154*0fca6ea1SDimitry Andric }
4155*0fca6ea1SDimitry Andric
refersToVectorElement() const41560b57cec5SDimitry Andric bool Expr::refersToVectorElement() const {
41570b57cec5SDimitry Andric // FIXME: Why do we not just look at the ObjectKind here?
41580b57cec5SDimitry Andric const Expr *E = this->IgnoreParens();
41590b57cec5SDimitry Andric
41600b57cec5SDimitry Andric while (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) {
4161fe6060f1SDimitry Andric if (ICE->isGLValue() && ICE->getCastKind() == CK_NoOp)
41620b57cec5SDimitry Andric E = ICE->getSubExpr()->IgnoreParens();
41630b57cec5SDimitry Andric else
41640b57cec5SDimitry Andric break;
41650b57cec5SDimitry Andric }
41660b57cec5SDimitry Andric
41670b57cec5SDimitry Andric if (const ArraySubscriptExpr *ASE = dyn_cast<ArraySubscriptExpr>(E))
41680b57cec5SDimitry Andric return ASE->getBase()->getType()->isVectorType();
41690b57cec5SDimitry Andric
41700b57cec5SDimitry Andric if (isa<ExtVectorElementExpr>(E))
41710b57cec5SDimitry Andric return true;
41720b57cec5SDimitry Andric
41730b57cec5SDimitry Andric if (auto *DRE = dyn_cast<DeclRefExpr>(E))
41740b57cec5SDimitry Andric if (auto *BD = dyn_cast<BindingDecl>(DRE->getDecl()))
41750b57cec5SDimitry Andric if (auto *E = BD->getBinding())
41760b57cec5SDimitry Andric return E->refersToVectorElement();
41770b57cec5SDimitry Andric
41780b57cec5SDimitry Andric return false;
41790b57cec5SDimitry Andric }
41800b57cec5SDimitry Andric
refersToGlobalRegisterVar() const41810b57cec5SDimitry Andric bool Expr::refersToGlobalRegisterVar() const {
41820b57cec5SDimitry Andric const Expr *E = this->IgnoreParenImpCasts();
41830b57cec5SDimitry Andric
41840b57cec5SDimitry Andric if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
41850b57cec5SDimitry Andric if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
41860b57cec5SDimitry Andric if (VD->getStorageClass() == SC_Register &&
41870b57cec5SDimitry Andric VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())
41880b57cec5SDimitry Andric return true;
41890b57cec5SDimitry Andric
41900b57cec5SDimitry Andric return false;
41910b57cec5SDimitry Andric }
41920b57cec5SDimitry Andric
isSameComparisonOperand(const Expr * E1,const Expr * E2)4193a7dea167SDimitry Andric bool Expr::isSameComparisonOperand(const Expr* E1, const Expr* E2) {
4194a7dea167SDimitry Andric E1 = E1->IgnoreParens();
4195a7dea167SDimitry Andric E2 = E2->IgnoreParens();
4196a7dea167SDimitry Andric
4197a7dea167SDimitry Andric if (E1->getStmtClass() != E2->getStmtClass())
4198a7dea167SDimitry Andric return false;
4199a7dea167SDimitry Andric
4200a7dea167SDimitry Andric switch (E1->getStmtClass()) {
4201a7dea167SDimitry Andric default:
4202a7dea167SDimitry Andric return false;
4203a7dea167SDimitry Andric case CXXThisExprClass:
4204a7dea167SDimitry Andric return true;
4205a7dea167SDimitry Andric case DeclRefExprClass: {
4206a7dea167SDimitry Andric // DeclRefExpr without an ImplicitCastExpr can happen for integral
4207a7dea167SDimitry Andric // template parameters.
4208a7dea167SDimitry Andric const auto *DRE1 = cast<DeclRefExpr>(E1);
4209a7dea167SDimitry Andric const auto *DRE2 = cast<DeclRefExpr>(E2);
4210fe6060f1SDimitry Andric return DRE1->isPRValue() && DRE2->isPRValue() &&
4211a7dea167SDimitry Andric DRE1->getDecl() == DRE2->getDecl();
4212a7dea167SDimitry Andric }
4213a7dea167SDimitry Andric case ImplicitCastExprClass: {
4214a7dea167SDimitry Andric // Peel off implicit casts.
4215a7dea167SDimitry Andric while (true) {
4216a7dea167SDimitry Andric const auto *ICE1 = dyn_cast<ImplicitCastExpr>(E1);
4217a7dea167SDimitry Andric const auto *ICE2 = dyn_cast<ImplicitCastExpr>(E2);
4218a7dea167SDimitry Andric if (!ICE1 || !ICE2)
4219a7dea167SDimitry Andric return false;
4220a7dea167SDimitry Andric if (ICE1->getCastKind() != ICE2->getCastKind())
4221a7dea167SDimitry Andric return false;
4222a7dea167SDimitry Andric E1 = ICE1->getSubExpr()->IgnoreParens();
4223a7dea167SDimitry Andric E2 = ICE2->getSubExpr()->IgnoreParens();
4224a7dea167SDimitry Andric // The final cast must be one of these types.
4225a7dea167SDimitry Andric if (ICE1->getCastKind() == CK_LValueToRValue ||
4226a7dea167SDimitry Andric ICE1->getCastKind() == CK_ArrayToPointerDecay ||
4227a7dea167SDimitry Andric ICE1->getCastKind() == CK_FunctionToPointerDecay) {
4228a7dea167SDimitry Andric break;
4229a7dea167SDimitry Andric }
4230a7dea167SDimitry Andric }
4231a7dea167SDimitry Andric
4232a7dea167SDimitry Andric const auto *DRE1 = dyn_cast<DeclRefExpr>(E1);
4233a7dea167SDimitry Andric const auto *DRE2 = dyn_cast<DeclRefExpr>(E2);
4234a7dea167SDimitry Andric if (DRE1 && DRE2)
4235a7dea167SDimitry Andric return declaresSameEntity(DRE1->getDecl(), DRE2->getDecl());
4236a7dea167SDimitry Andric
4237a7dea167SDimitry Andric const auto *Ivar1 = dyn_cast<ObjCIvarRefExpr>(E1);
4238a7dea167SDimitry Andric const auto *Ivar2 = dyn_cast<ObjCIvarRefExpr>(E2);
4239a7dea167SDimitry Andric if (Ivar1 && Ivar2) {
4240a7dea167SDimitry Andric return Ivar1->isFreeIvar() && Ivar2->isFreeIvar() &&
4241a7dea167SDimitry Andric declaresSameEntity(Ivar1->getDecl(), Ivar2->getDecl());
4242a7dea167SDimitry Andric }
4243a7dea167SDimitry Andric
4244a7dea167SDimitry Andric const auto *Array1 = dyn_cast<ArraySubscriptExpr>(E1);
4245a7dea167SDimitry Andric const auto *Array2 = dyn_cast<ArraySubscriptExpr>(E2);
4246a7dea167SDimitry Andric if (Array1 && Array2) {
4247a7dea167SDimitry Andric if (!isSameComparisonOperand(Array1->getBase(), Array2->getBase()))
4248a7dea167SDimitry Andric return false;
4249a7dea167SDimitry Andric
4250a7dea167SDimitry Andric auto Idx1 = Array1->getIdx();
4251a7dea167SDimitry Andric auto Idx2 = Array2->getIdx();
4252a7dea167SDimitry Andric const auto Integer1 = dyn_cast<IntegerLiteral>(Idx1);
4253a7dea167SDimitry Andric const auto Integer2 = dyn_cast<IntegerLiteral>(Idx2);
4254a7dea167SDimitry Andric if (Integer1 && Integer2) {
4255a7dea167SDimitry Andric if (!llvm::APInt::isSameValue(Integer1->getValue(),
4256a7dea167SDimitry Andric Integer2->getValue()))
4257a7dea167SDimitry Andric return false;
4258a7dea167SDimitry Andric } else {
4259a7dea167SDimitry Andric if (!isSameComparisonOperand(Idx1, Idx2))
4260a7dea167SDimitry Andric return false;
4261a7dea167SDimitry Andric }
4262a7dea167SDimitry Andric
4263a7dea167SDimitry Andric return true;
4264a7dea167SDimitry Andric }
4265a7dea167SDimitry Andric
4266a7dea167SDimitry Andric // Walk the MemberExpr chain.
4267a7dea167SDimitry Andric while (isa<MemberExpr>(E1) && isa<MemberExpr>(E2)) {
4268a7dea167SDimitry Andric const auto *ME1 = cast<MemberExpr>(E1);
4269a7dea167SDimitry Andric const auto *ME2 = cast<MemberExpr>(E2);
4270a7dea167SDimitry Andric if (!declaresSameEntity(ME1->getMemberDecl(), ME2->getMemberDecl()))
4271a7dea167SDimitry Andric return false;
4272a7dea167SDimitry Andric if (const auto *D = dyn_cast<VarDecl>(ME1->getMemberDecl()))
4273a7dea167SDimitry Andric if (D->isStaticDataMember())
4274a7dea167SDimitry Andric return true;
4275a7dea167SDimitry Andric E1 = ME1->getBase()->IgnoreParenImpCasts();
4276a7dea167SDimitry Andric E2 = ME2->getBase()->IgnoreParenImpCasts();
4277a7dea167SDimitry Andric }
4278a7dea167SDimitry Andric
4279a7dea167SDimitry Andric if (isa<CXXThisExpr>(E1) && isa<CXXThisExpr>(E2))
4280a7dea167SDimitry Andric return true;
4281a7dea167SDimitry Andric
4282a7dea167SDimitry Andric // A static member variable can end the MemberExpr chain with either
4283a7dea167SDimitry Andric // a MemberExpr or a DeclRefExpr.
4284a7dea167SDimitry Andric auto getAnyDecl = [](const Expr *E) -> const ValueDecl * {
4285a7dea167SDimitry Andric if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
4286a7dea167SDimitry Andric return DRE->getDecl();
4287a7dea167SDimitry Andric if (const auto *ME = dyn_cast<MemberExpr>(E))
4288a7dea167SDimitry Andric return ME->getMemberDecl();
4289a7dea167SDimitry Andric return nullptr;
4290a7dea167SDimitry Andric };
4291a7dea167SDimitry Andric
4292a7dea167SDimitry Andric const ValueDecl *VD1 = getAnyDecl(E1);
4293a7dea167SDimitry Andric const ValueDecl *VD2 = getAnyDecl(E2);
4294a7dea167SDimitry Andric return declaresSameEntity(VD1, VD2);
4295a7dea167SDimitry Andric }
4296a7dea167SDimitry Andric }
4297a7dea167SDimitry Andric }
4298a7dea167SDimitry Andric
42990b57cec5SDimitry Andric /// isArrow - Return true if the base expression is a pointer to vector,
43000b57cec5SDimitry Andric /// return false if the base expression is a vector.
isArrow() const43010b57cec5SDimitry Andric bool ExtVectorElementExpr::isArrow() const {
43020b57cec5SDimitry Andric return getBase()->getType()->isPointerType();
43030b57cec5SDimitry Andric }
43040b57cec5SDimitry Andric
getNumElements() const43050b57cec5SDimitry Andric unsigned ExtVectorElementExpr::getNumElements() const {
43060b57cec5SDimitry Andric if (const VectorType *VT = getType()->getAs<VectorType>())
43070b57cec5SDimitry Andric return VT->getNumElements();
43080b57cec5SDimitry Andric return 1;
43090b57cec5SDimitry Andric }
43100b57cec5SDimitry Andric
43110b57cec5SDimitry Andric /// containsDuplicateElements - Return true if any element access is repeated.
containsDuplicateElements() const43120b57cec5SDimitry Andric bool ExtVectorElementExpr::containsDuplicateElements() const {
43130b57cec5SDimitry Andric // FIXME: Refactor this code to an accessor on the AST node which returns the
43140b57cec5SDimitry Andric // "type" of component access, and share with code below and in Sema.
43150b57cec5SDimitry Andric StringRef Comp = Accessor->getName();
43160b57cec5SDimitry Andric
43170b57cec5SDimitry Andric // Halving swizzles do not contain duplicate elements.
43180b57cec5SDimitry Andric if (Comp == "hi" || Comp == "lo" || Comp == "even" || Comp == "odd")
43190b57cec5SDimitry Andric return false;
43200b57cec5SDimitry Andric
43210b57cec5SDimitry Andric // Advance past s-char prefix on hex swizzles.
43220b57cec5SDimitry Andric if (Comp[0] == 's' || Comp[0] == 'S')
43230b57cec5SDimitry Andric Comp = Comp.substr(1);
43240b57cec5SDimitry Andric
43250b57cec5SDimitry Andric for (unsigned i = 0, e = Comp.size(); i != e; ++i)
4326349cc55cSDimitry Andric if (Comp.substr(i + 1).contains(Comp[i]))
43270b57cec5SDimitry Andric return true;
43280b57cec5SDimitry Andric
43290b57cec5SDimitry Andric return false;
43300b57cec5SDimitry Andric }
43310b57cec5SDimitry Andric
43320b57cec5SDimitry Andric /// getEncodedElementAccess - We encode the fields as a llvm ConstantArray.
getEncodedElementAccess(SmallVectorImpl<uint32_t> & Elts) const43330b57cec5SDimitry Andric void ExtVectorElementExpr::getEncodedElementAccess(
43340b57cec5SDimitry Andric SmallVectorImpl<uint32_t> &Elts) const {
43350b57cec5SDimitry Andric StringRef Comp = Accessor->getName();
43360b57cec5SDimitry Andric bool isNumericAccessor = false;
43370b57cec5SDimitry Andric if (Comp[0] == 's' || Comp[0] == 'S') {
43380b57cec5SDimitry Andric Comp = Comp.substr(1);
43390b57cec5SDimitry Andric isNumericAccessor = true;
43400b57cec5SDimitry Andric }
43410b57cec5SDimitry Andric
43420b57cec5SDimitry Andric bool isHi = Comp == "hi";
43430b57cec5SDimitry Andric bool isLo = Comp == "lo";
43440b57cec5SDimitry Andric bool isEven = Comp == "even";
43450b57cec5SDimitry Andric bool isOdd = Comp == "odd";
43460b57cec5SDimitry Andric
43470b57cec5SDimitry Andric for (unsigned i = 0, e = getNumElements(); i != e; ++i) {
43480b57cec5SDimitry Andric uint64_t Index;
43490b57cec5SDimitry Andric
43500b57cec5SDimitry Andric if (isHi)
43510b57cec5SDimitry Andric Index = e + i;
43520b57cec5SDimitry Andric else if (isLo)
43530b57cec5SDimitry Andric Index = i;
43540b57cec5SDimitry Andric else if (isEven)
43550b57cec5SDimitry Andric Index = 2 * i;
43560b57cec5SDimitry Andric else if (isOdd)
43570b57cec5SDimitry Andric Index = 2 * i + 1;
43580b57cec5SDimitry Andric else
43590b57cec5SDimitry Andric Index = ExtVectorType::getAccessorIdx(Comp[i], isNumericAccessor);
43600b57cec5SDimitry Andric
43610b57cec5SDimitry Andric Elts.push_back(Index);
43620b57cec5SDimitry Andric }
43630b57cec5SDimitry Andric }
43640b57cec5SDimitry Andric
ShuffleVectorExpr(const ASTContext & C,ArrayRef<Expr * > args,QualType Type,SourceLocation BLoc,SourceLocation RP)43650b57cec5SDimitry Andric ShuffleVectorExpr::ShuffleVectorExpr(const ASTContext &C, ArrayRef<Expr *> args,
43660b57cec5SDimitry Andric QualType Type, SourceLocation BLoc,
43670b57cec5SDimitry Andric SourceLocation RP)
4368fe6060f1SDimitry Andric : Expr(ShuffleVectorExprClass, Type, VK_PRValue, OK_Ordinary),
43695ffd83dbSDimitry Andric BuiltinLoc(BLoc), RParenLoc(RP), NumExprs(args.size()) {
43700b57cec5SDimitry Andric SubExprs = new (C) Stmt*[args.size()];
43715ffd83dbSDimitry Andric for (unsigned i = 0; i != args.size(); i++)
43720b57cec5SDimitry Andric SubExprs[i] = args[i];
43735ffd83dbSDimitry Andric
43745ffd83dbSDimitry Andric setDependence(computeDependence(this));
43750b57cec5SDimitry Andric }
43760b57cec5SDimitry Andric
setExprs(const ASTContext & C,ArrayRef<Expr * > Exprs)43770b57cec5SDimitry Andric void ShuffleVectorExpr::setExprs(const ASTContext &C, ArrayRef<Expr *> Exprs) {
43780b57cec5SDimitry Andric if (SubExprs) C.Deallocate(SubExprs);
43790b57cec5SDimitry Andric
43800b57cec5SDimitry Andric this->NumExprs = Exprs.size();
43810b57cec5SDimitry Andric SubExprs = new (C) Stmt*[NumExprs];
43820b57cec5SDimitry Andric memcpy(SubExprs, Exprs.data(), sizeof(Expr *) * Exprs.size());
43830b57cec5SDimitry Andric }
43840b57cec5SDimitry Andric
GenericSelectionExpr(const ASTContext &,SourceLocation GenericLoc,Expr * ControllingExpr,ArrayRef<TypeSourceInfo * > AssocTypes,ArrayRef<Expr * > AssocExprs,SourceLocation DefaultLoc,SourceLocation RParenLoc,bool ContainsUnexpandedParameterPack,unsigned ResultIndex)43850b57cec5SDimitry Andric GenericSelectionExpr::GenericSelectionExpr(
43860b57cec5SDimitry Andric const ASTContext &, SourceLocation GenericLoc, Expr *ControllingExpr,
43870b57cec5SDimitry Andric ArrayRef<TypeSourceInfo *> AssocTypes, ArrayRef<Expr *> AssocExprs,
43880b57cec5SDimitry Andric SourceLocation DefaultLoc, SourceLocation RParenLoc,
43890b57cec5SDimitry Andric bool ContainsUnexpandedParameterPack, unsigned ResultIndex)
43900b57cec5SDimitry Andric : Expr(GenericSelectionExprClass, AssocExprs[ResultIndex]->getType(),
43910b57cec5SDimitry Andric AssocExprs[ResultIndex]->getValueKind(),
43925ffd83dbSDimitry Andric AssocExprs[ResultIndex]->getObjectKind()),
43930b57cec5SDimitry Andric NumAssocs(AssocExprs.size()), ResultIndex(ResultIndex),
439406c3fb27SDimitry Andric IsExprPredicate(true), DefaultLoc(DefaultLoc), RParenLoc(RParenLoc) {
43950b57cec5SDimitry Andric assert(AssocTypes.size() == AssocExprs.size() &&
43960b57cec5SDimitry Andric "Must have the same number of association expressions"
43970b57cec5SDimitry Andric " and TypeSourceInfo!");
43980b57cec5SDimitry Andric assert(ResultIndex < NumAssocs && "ResultIndex is out-of-bounds!");
43990b57cec5SDimitry Andric
44000b57cec5SDimitry Andric GenericSelectionExprBits.GenericLoc = GenericLoc;
440106c3fb27SDimitry Andric getTrailingObjects<Stmt *>()[getIndexOfControllingExpression()] =
440206c3fb27SDimitry Andric ControllingExpr;
44030b57cec5SDimitry Andric std::copy(AssocExprs.begin(), AssocExprs.end(),
440406c3fb27SDimitry Andric getTrailingObjects<Stmt *>() + getIndexOfStartOfAssociatedExprs());
44050b57cec5SDimitry Andric std::copy(AssocTypes.begin(), AssocTypes.end(),
440606c3fb27SDimitry Andric getTrailingObjects<TypeSourceInfo *>() +
440706c3fb27SDimitry Andric getIndexOfStartOfAssociatedTypes());
440806c3fb27SDimitry Andric
440906c3fb27SDimitry Andric setDependence(computeDependence(this, ContainsUnexpandedParameterPack));
441006c3fb27SDimitry Andric }
441106c3fb27SDimitry Andric
GenericSelectionExpr(const ASTContext &,SourceLocation GenericLoc,TypeSourceInfo * ControllingType,ArrayRef<TypeSourceInfo * > AssocTypes,ArrayRef<Expr * > AssocExprs,SourceLocation DefaultLoc,SourceLocation RParenLoc,bool ContainsUnexpandedParameterPack,unsigned ResultIndex)441206c3fb27SDimitry Andric GenericSelectionExpr::GenericSelectionExpr(
441306c3fb27SDimitry Andric const ASTContext &, SourceLocation GenericLoc,
441406c3fb27SDimitry Andric TypeSourceInfo *ControllingType, ArrayRef<TypeSourceInfo *> AssocTypes,
441506c3fb27SDimitry Andric ArrayRef<Expr *> AssocExprs, SourceLocation DefaultLoc,
441606c3fb27SDimitry Andric SourceLocation RParenLoc, bool ContainsUnexpandedParameterPack,
441706c3fb27SDimitry Andric unsigned ResultIndex)
441806c3fb27SDimitry Andric : Expr(GenericSelectionExprClass, AssocExprs[ResultIndex]->getType(),
441906c3fb27SDimitry Andric AssocExprs[ResultIndex]->getValueKind(),
442006c3fb27SDimitry Andric AssocExprs[ResultIndex]->getObjectKind()),
442106c3fb27SDimitry Andric NumAssocs(AssocExprs.size()), ResultIndex(ResultIndex),
442206c3fb27SDimitry Andric IsExprPredicate(false), DefaultLoc(DefaultLoc), RParenLoc(RParenLoc) {
442306c3fb27SDimitry Andric assert(AssocTypes.size() == AssocExprs.size() &&
442406c3fb27SDimitry Andric "Must have the same number of association expressions"
442506c3fb27SDimitry Andric " and TypeSourceInfo!");
442606c3fb27SDimitry Andric assert(ResultIndex < NumAssocs && "ResultIndex is out-of-bounds!");
442706c3fb27SDimitry Andric
442806c3fb27SDimitry Andric GenericSelectionExprBits.GenericLoc = GenericLoc;
442906c3fb27SDimitry Andric getTrailingObjects<TypeSourceInfo *>()[getIndexOfControllingType()] =
443006c3fb27SDimitry Andric ControllingType;
443106c3fb27SDimitry Andric std::copy(AssocExprs.begin(), AssocExprs.end(),
443206c3fb27SDimitry Andric getTrailingObjects<Stmt *>() + getIndexOfStartOfAssociatedExprs());
443306c3fb27SDimitry Andric std::copy(AssocTypes.begin(), AssocTypes.end(),
443406c3fb27SDimitry Andric getTrailingObjects<TypeSourceInfo *>() +
443506c3fb27SDimitry Andric getIndexOfStartOfAssociatedTypes());
44365ffd83dbSDimitry Andric
44375ffd83dbSDimitry Andric setDependence(computeDependence(this, ContainsUnexpandedParameterPack));
44380b57cec5SDimitry Andric }
44390b57cec5SDimitry Andric
GenericSelectionExpr(const ASTContext & Context,SourceLocation GenericLoc,Expr * ControllingExpr,ArrayRef<TypeSourceInfo * > AssocTypes,ArrayRef<Expr * > AssocExprs,SourceLocation DefaultLoc,SourceLocation RParenLoc,bool ContainsUnexpandedParameterPack)44400b57cec5SDimitry Andric GenericSelectionExpr::GenericSelectionExpr(
44410b57cec5SDimitry Andric const ASTContext &Context, SourceLocation GenericLoc, Expr *ControllingExpr,
44420b57cec5SDimitry Andric ArrayRef<TypeSourceInfo *> AssocTypes, ArrayRef<Expr *> AssocExprs,
44430b57cec5SDimitry Andric SourceLocation DefaultLoc, SourceLocation RParenLoc,
44440b57cec5SDimitry Andric bool ContainsUnexpandedParameterPack)
4445fe6060f1SDimitry Andric : Expr(GenericSelectionExprClass, Context.DependentTy, VK_PRValue,
44465ffd83dbSDimitry Andric OK_Ordinary),
44470b57cec5SDimitry Andric NumAssocs(AssocExprs.size()), ResultIndex(ResultDependentIndex),
444806c3fb27SDimitry Andric IsExprPredicate(true), DefaultLoc(DefaultLoc), RParenLoc(RParenLoc) {
44490b57cec5SDimitry Andric assert(AssocTypes.size() == AssocExprs.size() &&
44500b57cec5SDimitry Andric "Must have the same number of association expressions"
44510b57cec5SDimitry Andric " and TypeSourceInfo!");
44520b57cec5SDimitry Andric
44530b57cec5SDimitry Andric GenericSelectionExprBits.GenericLoc = GenericLoc;
445406c3fb27SDimitry Andric getTrailingObjects<Stmt *>()[getIndexOfControllingExpression()] =
445506c3fb27SDimitry Andric ControllingExpr;
44560b57cec5SDimitry Andric std::copy(AssocExprs.begin(), AssocExprs.end(),
445706c3fb27SDimitry Andric getTrailingObjects<Stmt *>() + getIndexOfStartOfAssociatedExprs());
44580b57cec5SDimitry Andric std::copy(AssocTypes.begin(), AssocTypes.end(),
445906c3fb27SDimitry Andric getTrailingObjects<TypeSourceInfo *>() +
446006c3fb27SDimitry Andric getIndexOfStartOfAssociatedTypes());
446106c3fb27SDimitry Andric
446206c3fb27SDimitry Andric setDependence(computeDependence(this, ContainsUnexpandedParameterPack));
446306c3fb27SDimitry Andric }
446406c3fb27SDimitry Andric
GenericSelectionExpr(const ASTContext & Context,SourceLocation GenericLoc,TypeSourceInfo * ControllingType,ArrayRef<TypeSourceInfo * > AssocTypes,ArrayRef<Expr * > AssocExprs,SourceLocation DefaultLoc,SourceLocation RParenLoc,bool ContainsUnexpandedParameterPack)446506c3fb27SDimitry Andric GenericSelectionExpr::GenericSelectionExpr(
446606c3fb27SDimitry Andric const ASTContext &Context, SourceLocation GenericLoc,
446706c3fb27SDimitry Andric TypeSourceInfo *ControllingType, ArrayRef<TypeSourceInfo *> AssocTypes,
446806c3fb27SDimitry Andric ArrayRef<Expr *> AssocExprs, SourceLocation DefaultLoc,
446906c3fb27SDimitry Andric SourceLocation RParenLoc, bool ContainsUnexpandedParameterPack)
447006c3fb27SDimitry Andric : Expr(GenericSelectionExprClass, Context.DependentTy, VK_PRValue,
447106c3fb27SDimitry Andric OK_Ordinary),
447206c3fb27SDimitry Andric NumAssocs(AssocExprs.size()), ResultIndex(ResultDependentIndex),
447306c3fb27SDimitry Andric IsExprPredicate(false), DefaultLoc(DefaultLoc), RParenLoc(RParenLoc) {
447406c3fb27SDimitry Andric assert(AssocTypes.size() == AssocExprs.size() &&
447506c3fb27SDimitry Andric "Must have the same number of association expressions"
447606c3fb27SDimitry Andric " and TypeSourceInfo!");
447706c3fb27SDimitry Andric
447806c3fb27SDimitry Andric GenericSelectionExprBits.GenericLoc = GenericLoc;
447906c3fb27SDimitry Andric getTrailingObjects<TypeSourceInfo *>()[getIndexOfControllingType()] =
448006c3fb27SDimitry Andric ControllingType;
448106c3fb27SDimitry Andric std::copy(AssocExprs.begin(), AssocExprs.end(),
448206c3fb27SDimitry Andric getTrailingObjects<Stmt *>() + getIndexOfStartOfAssociatedExprs());
448306c3fb27SDimitry Andric std::copy(AssocTypes.begin(), AssocTypes.end(),
448406c3fb27SDimitry Andric getTrailingObjects<TypeSourceInfo *>() +
448506c3fb27SDimitry Andric getIndexOfStartOfAssociatedTypes());
44865ffd83dbSDimitry Andric
44875ffd83dbSDimitry Andric setDependence(computeDependence(this, ContainsUnexpandedParameterPack));
44880b57cec5SDimitry Andric }
44890b57cec5SDimitry Andric
GenericSelectionExpr(EmptyShell Empty,unsigned NumAssocs)44900b57cec5SDimitry Andric GenericSelectionExpr::GenericSelectionExpr(EmptyShell Empty, unsigned NumAssocs)
44910b57cec5SDimitry Andric : Expr(GenericSelectionExprClass, Empty), NumAssocs(NumAssocs) {}
44920b57cec5SDimitry Andric
Create(const ASTContext & Context,SourceLocation GenericLoc,Expr * ControllingExpr,ArrayRef<TypeSourceInfo * > AssocTypes,ArrayRef<Expr * > AssocExprs,SourceLocation DefaultLoc,SourceLocation RParenLoc,bool ContainsUnexpandedParameterPack,unsigned ResultIndex)44930b57cec5SDimitry Andric GenericSelectionExpr *GenericSelectionExpr::Create(
44940b57cec5SDimitry Andric const ASTContext &Context, SourceLocation GenericLoc, Expr *ControllingExpr,
44950b57cec5SDimitry Andric ArrayRef<TypeSourceInfo *> AssocTypes, ArrayRef<Expr *> AssocExprs,
44960b57cec5SDimitry Andric SourceLocation DefaultLoc, SourceLocation RParenLoc,
44970b57cec5SDimitry Andric bool ContainsUnexpandedParameterPack, unsigned ResultIndex) {
44980b57cec5SDimitry Andric unsigned NumAssocs = AssocExprs.size();
44990b57cec5SDimitry Andric void *Mem = Context.Allocate(
45000b57cec5SDimitry Andric totalSizeToAlloc<Stmt *, TypeSourceInfo *>(1 + NumAssocs, NumAssocs),
45010b57cec5SDimitry Andric alignof(GenericSelectionExpr));
45020b57cec5SDimitry Andric return new (Mem) GenericSelectionExpr(
45030b57cec5SDimitry Andric Context, GenericLoc, ControllingExpr, AssocTypes, AssocExprs, DefaultLoc,
45040b57cec5SDimitry Andric RParenLoc, ContainsUnexpandedParameterPack, ResultIndex);
45050b57cec5SDimitry Andric }
45060b57cec5SDimitry Andric
Create(const ASTContext & Context,SourceLocation GenericLoc,Expr * ControllingExpr,ArrayRef<TypeSourceInfo * > AssocTypes,ArrayRef<Expr * > AssocExprs,SourceLocation DefaultLoc,SourceLocation RParenLoc,bool ContainsUnexpandedParameterPack)45070b57cec5SDimitry Andric GenericSelectionExpr *GenericSelectionExpr::Create(
45080b57cec5SDimitry Andric const ASTContext &Context, SourceLocation GenericLoc, Expr *ControllingExpr,
45090b57cec5SDimitry Andric ArrayRef<TypeSourceInfo *> AssocTypes, ArrayRef<Expr *> AssocExprs,
45100b57cec5SDimitry Andric SourceLocation DefaultLoc, SourceLocation RParenLoc,
45110b57cec5SDimitry Andric bool ContainsUnexpandedParameterPack) {
45120b57cec5SDimitry Andric unsigned NumAssocs = AssocExprs.size();
45130b57cec5SDimitry Andric void *Mem = Context.Allocate(
45140b57cec5SDimitry Andric totalSizeToAlloc<Stmt *, TypeSourceInfo *>(1 + NumAssocs, NumAssocs),
45150b57cec5SDimitry Andric alignof(GenericSelectionExpr));
45160b57cec5SDimitry Andric return new (Mem) GenericSelectionExpr(
45170b57cec5SDimitry Andric Context, GenericLoc, ControllingExpr, AssocTypes, AssocExprs, DefaultLoc,
45180b57cec5SDimitry Andric RParenLoc, ContainsUnexpandedParameterPack);
45190b57cec5SDimitry Andric }
45200b57cec5SDimitry Andric
Create(const ASTContext & Context,SourceLocation GenericLoc,TypeSourceInfo * ControllingType,ArrayRef<TypeSourceInfo * > AssocTypes,ArrayRef<Expr * > AssocExprs,SourceLocation DefaultLoc,SourceLocation RParenLoc,bool ContainsUnexpandedParameterPack,unsigned ResultIndex)452106c3fb27SDimitry Andric GenericSelectionExpr *GenericSelectionExpr::Create(
452206c3fb27SDimitry Andric const ASTContext &Context, SourceLocation GenericLoc,
452306c3fb27SDimitry Andric TypeSourceInfo *ControllingType, ArrayRef<TypeSourceInfo *> AssocTypes,
452406c3fb27SDimitry Andric ArrayRef<Expr *> AssocExprs, SourceLocation DefaultLoc,
452506c3fb27SDimitry Andric SourceLocation RParenLoc, bool ContainsUnexpandedParameterPack,
452606c3fb27SDimitry Andric unsigned ResultIndex) {
452706c3fb27SDimitry Andric unsigned NumAssocs = AssocExprs.size();
452806c3fb27SDimitry Andric void *Mem = Context.Allocate(
452906c3fb27SDimitry Andric totalSizeToAlloc<Stmt *, TypeSourceInfo *>(1 + NumAssocs, NumAssocs),
453006c3fb27SDimitry Andric alignof(GenericSelectionExpr));
453106c3fb27SDimitry Andric return new (Mem) GenericSelectionExpr(
453206c3fb27SDimitry Andric Context, GenericLoc, ControllingType, AssocTypes, AssocExprs, DefaultLoc,
453306c3fb27SDimitry Andric RParenLoc, ContainsUnexpandedParameterPack, ResultIndex);
453406c3fb27SDimitry Andric }
453506c3fb27SDimitry Andric
Create(const ASTContext & Context,SourceLocation GenericLoc,TypeSourceInfo * ControllingType,ArrayRef<TypeSourceInfo * > AssocTypes,ArrayRef<Expr * > AssocExprs,SourceLocation DefaultLoc,SourceLocation RParenLoc,bool ContainsUnexpandedParameterPack)453606c3fb27SDimitry Andric GenericSelectionExpr *GenericSelectionExpr::Create(
453706c3fb27SDimitry Andric const ASTContext &Context, SourceLocation GenericLoc,
453806c3fb27SDimitry Andric TypeSourceInfo *ControllingType, ArrayRef<TypeSourceInfo *> AssocTypes,
453906c3fb27SDimitry Andric ArrayRef<Expr *> AssocExprs, SourceLocation DefaultLoc,
454006c3fb27SDimitry Andric SourceLocation RParenLoc, bool ContainsUnexpandedParameterPack) {
454106c3fb27SDimitry Andric unsigned NumAssocs = AssocExprs.size();
454206c3fb27SDimitry Andric void *Mem = Context.Allocate(
454306c3fb27SDimitry Andric totalSizeToAlloc<Stmt *, TypeSourceInfo *>(1 + NumAssocs, NumAssocs),
454406c3fb27SDimitry Andric alignof(GenericSelectionExpr));
454506c3fb27SDimitry Andric return new (Mem) GenericSelectionExpr(
454606c3fb27SDimitry Andric Context, GenericLoc, ControllingType, AssocTypes, AssocExprs, DefaultLoc,
454706c3fb27SDimitry Andric RParenLoc, ContainsUnexpandedParameterPack);
454806c3fb27SDimitry Andric }
454906c3fb27SDimitry Andric
45500b57cec5SDimitry Andric GenericSelectionExpr *
CreateEmpty(const ASTContext & Context,unsigned NumAssocs)45510b57cec5SDimitry Andric GenericSelectionExpr::CreateEmpty(const ASTContext &Context,
45520b57cec5SDimitry Andric unsigned NumAssocs) {
45530b57cec5SDimitry Andric void *Mem = Context.Allocate(
45540b57cec5SDimitry Andric totalSizeToAlloc<Stmt *, TypeSourceInfo *>(1 + NumAssocs, NumAssocs),
45550b57cec5SDimitry Andric alignof(GenericSelectionExpr));
45560b57cec5SDimitry Andric return new (Mem) GenericSelectionExpr(EmptyShell(), NumAssocs);
45570b57cec5SDimitry Andric }
45580b57cec5SDimitry Andric
45590b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
45600b57cec5SDimitry Andric // DesignatedInitExpr
45610b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
45620b57cec5SDimitry Andric
getFieldName() const456306c3fb27SDimitry Andric const IdentifierInfo *DesignatedInitExpr::Designator::getFieldName() const {
456406c3fb27SDimitry Andric assert(isFieldDesignator() && "Only valid on a field designator");
456506c3fb27SDimitry Andric if (FieldInfo.NameOrField & 0x01)
456606c3fb27SDimitry Andric return reinterpret_cast<IdentifierInfo *>(FieldInfo.NameOrField & ~0x01);
456706c3fb27SDimitry Andric return getFieldDecl()->getIdentifier();
45680b57cec5SDimitry Andric }
45690b57cec5SDimitry Andric
DesignatedInitExpr(const ASTContext & C,QualType Ty,llvm::ArrayRef<Designator> Designators,SourceLocation EqualOrColonLoc,bool GNUSyntax,ArrayRef<Expr * > IndexExprs,Expr * Init)45700b57cec5SDimitry Andric DesignatedInitExpr::DesignatedInitExpr(const ASTContext &C, QualType Ty,
45710b57cec5SDimitry Andric llvm::ArrayRef<Designator> Designators,
45720b57cec5SDimitry Andric SourceLocation EqualOrColonLoc,
45730b57cec5SDimitry Andric bool GNUSyntax,
45745ffd83dbSDimitry Andric ArrayRef<Expr *> IndexExprs, Expr *Init)
45755ffd83dbSDimitry Andric : Expr(DesignatedInitExprClass, Ty, Init->getValueKind(),
45765ffd83dbSDimitry Andric Init->getObjectKind()),
45770b57cec5SDimitry Andric EqualOrColonLoc(EqualOrColonLoc), GNUSyntax(GNUSyntax),
45780b57cec5SDimitry Andric NumDesignators(Designators.size()), NumSubExprs(IndexExprs.size() + 1) {
45790b57cec5SDimitry Andric this->Designators = new (C) Designator[NumDesignators];
45800b57cec5SDimitry Andric
45810b57cec5SDimitry Andric // Record the initializer itself.
45820b57cec5SDimitry Andric child_iterator Child = child_begin();
45830b57cec5SDimitry Andric *Child++ = Init;
45840b57cec5SDimitry Andric
45850b57cec5SDimitry Andric // Copy the designators and their subexpressions, computing
45860b57cec5SDimitry Andric // value-dependence along the way.
45870b57cec5SDimitry Andric unsigned IndexIdx = 0;
45880b57cec5SDimitry Andric for (unsigned I = 0; I != NumDesignators; ++I) {
45890b57cec5SDimitry Andric this->Designators[I] = Designators[I];
45900b57cec5SDimitry Andric if (this->Designators[I].isArrayDesignator()) {
45910b57cec5SDimitry Andric // Copy the index expressions into permanent storage.
45920b57cec5SDimitry Andric *Child++ = IndexExprs[IndexIdx++];
45930b57cec5SDimitry Andric } else if (this->Designators[I].isArrayRangeDesignator()) {
45940b57cec5SDimitry Andric // Copy the start/end expressions into permanent storage.
45950b57cec5SDimitry Andric *Child++ = IndexExprs[IndexIdx++];
45960b57cec5SDimitry Andric *Child++ = IndexExprs[IndexIdx++];
45970b57cec5SDimitry Andric }
45980b57cec5SDimitry Andric }
45990b57cec5SDimitry Andric
46000b57cec5SDimitry Andric assert(IndexIdx == IndexExprs.size() && "Wrong number of index expressions");
46015ffd83dbSDimitry Andric setDependence(computeDependence(this));
46020b57cec5SDimitry Andric }
46030b57cec5SDimitry Andric
46040b57cec5SDimitry Andric DesignatedInitExpr *
Create(const ASTContext & C,llvm::ArrayRef<Designator> Designators,ArrayRef<Expr * > IndexExprs,SourceLocation ColonOrEqualLoc,bool UsesColonSyntax,Expr * Init)46050b57cec5SDimitry Andric DesignatedInitExpr::Create(const ASTContext &C,
46060b57cec5SDimitry Andric llvm::ArrayRef<Designator> Designators,
46070b57cec5SDimitry Andric ArrayRef<Expr*> IndexExprs,
46080b57cec5SDimitry Andric SourceLocation ColonOrEqualLoc,
46090b57cec5SDimitry Andric bool UsesColonSyntax, Expr *Init) {
46100b57cec5SDimitry Andric void *Mem = C.Allocate(totalSizeToAlloc<Stmt *>(IndexExprs.size() + 1),
46110b57cec5SDimitry Andric alignof(DesignatedInitExpr));
46120b57cec5SDimitry Andric return new (Mem) DesignatedInitExpr(C, C.VoidTy, Designators,
46130b57cec5SDimitry Andric ColonOrEqualLoc, UsesColonSyntax,
46140b57cec5SDimitry Andric IndexExprs, Init);
46150b57cec5SDimitry Andric }
46160b57cec5SDimitry Andric
CreateEmpty(const ASTContext & C,unsigned NumIndexExprs)46170b57cec5SDimitry Andric DesignatedInitExpr *DesignatedInitExpr::CreateEmpty(const ASTContext &C,
46180b57cec5SDimitry Andric unsigned NumIndexExprs) {
46190b57cec5SDimitry Andric void *Mem = C.Allocate(totalSizeToAlloc<Stmt *>(NumIndexExprs + 1),
46200b57cec5SDimitry Andric alignof(DesignatedInitExpr));
46210b57cec5SDimitry Andric return new (Mem) DesignatedInitExpr(NumIndexExprs + 1);
46220b57cec5SDimitry Andric }
46230b57cec5SDimitry Andric
setDesignators(const ASTContext & C,const Designator * Desigs,unsigned NumDesigs)46240b57cec5SDimitry Andric void DesignatedInitExpr::setDesignators(const ASTContext &C,
46250b57cec5SDimitry Andric const Designator *Desigs,
46260b57cec5SDimitry Andric unsigned NumDesigs) {
46270b57cec5SDimitry Andric Designators = new (C) Designator[NumDesigs];
46280b57cec5SDimitry Andric NumDesignators = NumDesigs;
46290b57cec5SDimitry Andric for (unsigned I = 0; I != NumDesigs; ++I)
46300b57cec5SDimitry Andric Designators[I] = Desigs[I];
46310b57cec5SDimitry Andric }
46320b57cec5SDimitry Andric
getDesignatorsSourceRange() const46330b57cec5SDimitry Andric SourceRange DesignatedInitExpr::getDesignatorsSourceRange() const {
46340b57cec5SDimitry Andric DesignatedInitExpr *DIE = const_cast<DesignatedInitExpr*>(this);
46350b57cec5SDimitry Andric if (size() == 1)
46360b57cec5SDimitry Andric return DIE->getDesignator(0)->getSourceRange();
46370b57cec5SDimitry Andric return SourceRange(DIE->getDesignator(0)->getBeginLoc(),
46380b57cec5SDimitry Andric DIE->getDesignator(size() - 1)->getEndLoc());
46390b57cec5SDimitry Andric }
46400b57cec5SDimitry Andric
getBeginLoc() const46410b57cec5SDimitry Andric SourceLocation DesignatedInitExpr::getBeginLoc() const {
46420b57cec5SDimitry Andric auto *DIE = const_cast<DesignatedInitExpr *>(this);
46430b57cec5SDimitry Andric Designator &First = *DIE->getDesignator(0);
4644*0fca6ea1SDimitry Andric if (First.isFieldDesignator()) {
4645*0fca6ea1SDimitry Andric // Skip past implicit designators for anonymous structs/unions, since
4646*0fca6ea1SDimitry Andric // these do not have valid source locations.
4647*0fca6ea1SDimitry Andric for (unsigned int i = 0; i < DIE->size(); i++) {
4648*0fca6ea1SDimitry Andric Designator &Des = *DIE->getDesignator(i);
4649*0fca6ea1SDimitry Andric SourceLocation retval = GNUSyntax ? Des.getFieldLoc() : Des.getDotLoc();
4650*0fca6ea1SDimitry Andric if (!retval.isValid())
4651*0fca6ea1SDimitry Andric continue;
4652*0fca6ea1SDimitry Andric return retval;
4653*0fca6ea1SDimitry Andric }
4654*0fca6ea1SDimitry Andric }
465506c3fb27SDimitry Andric return First.getLBracketLoc();
46560b57cec5SDimitry Andric }
46570b57cec5SDimitry Andric
getEndLoc() const46580b57cec5SDimitry Andric SourceLocation DesignatedInitExpr::getEndLoc() const {
46590b57cec5SDimitry Andric return getInit()->getEndLoc();
46600b57cec5SDimitry Andric }
46610b57cec5SDimitry Andric
getArrayIndex(const Designator & D) const46620b57cec5SDimitry Andric Expr *DesignatedInitExpr::getArrayIndex(const Designator& D) const {
466306c3fb27SDimitry Andric assert(D.isArrayDesignator() && "Requires array designator");
466406c3fb27SDimitry Andric return getSubExpr(D.getArrayIndex() + 1);
46650b57cec5SDimitry Andric }
46660b57cec5SDimitry Andric
getArrayRangeStart(const Designator & D) const46670b57cec5SDimitry Andric Expr *DesignatedInitExpr::getArrayRangeStart(const Designator &D) const {
466806c3fb27SDimitry Andric assert(D.isArrayRangeDesignator() && "Requires array range designator");
466906c3fb27SDimitry Andric return getSubExpr(D.getArrayIndex() + 1);
46700b57cec5SDimitry Andric }
46710b57cec5SDimitry Andric
getArrayRangeEnd(const Designator & D) const46720b57cec5SDimitry Andric Expr *DesignatedInitExpr::getArrayRangeEnd(const Designator &D) const {
467306c3fb27SDimitry Andric assert(D.isArrayRangeDesignator() && "Requires array range designator");
467406c3fb27SDimitry Andric return getSubExpr(D.getArrayIndex() + 2);
46750b57cec5SDimitry Andric }
46760b57cec5SDimitry Andric
46770b57cec5SDimitry Andric /// Replaces the designator at index @p Idx with the series
46780b57cec5SDimitry Andric /// of designators in [First, Last).
ExpandDesignator(const ASTContext & C,unsigned Idx,const Designator * First,const Designator * Last)46790b57cec5SDimitry Andric void DesignatedInitExpr::ExpandDesignator(const ASTContext &C, unsigned Idx,
46800b57cec5SDimitry Andric const Designator *First,
46810b57cec5SDimitry Andric const Designator *Last) {
46820b57cec5SDimitry Andric unsigned NumNewDesignators = Last - First;
46830b57cec5SDimitry Andric if (NumNewDesignators == 0) {
46840b57cec5SDimitry Andric std::copy_backward(Designators + Idx + 1,
46850b57cec5SDimitry Andric Designators + NumDesignators,
46860b57cec5SDimitry Andric Designators + Idx);
46870b57cec5SDimitry Andric --NumNewDesignators;
46880b57cec5SDimitry Andric return;
4689e8d8bef9SDimitry Andric }
4690e8d8bef9SDimitry Andric if (NumNewDesignators == 1) {
46910b57cec5SDimitry Andric Designators[Idx] = *First;
46920b57cec5SDimitry Andric return;
46930b57cec5SDimitry Andric }
46940b57cec5SDimitry Andric
46950b57cec5SDimitry Andric Designator *NewDesignators
46960b57cec5SDimitry Andric = new (C) Designator[NumDesignators - 1 + NumNewDesignators];
46970b57cec5SDimitry Andric std::copy(Designators, Designators + Idx, NewDesignators);
46980b57cec5SDimitry Andric std::copy(First, Last, NewDesignators + Idx);
46990b57cec5SDimitry Andric std::copy(Designators + Idx + 1, Designators + NumDesignators,
47000b57cec5SDimitry Andric NewDesignators + Idx + NumNewDesignators);
47010b57cec5SDimitry Andric Designators = NewDesignators;
47020b57cec5SDimitry Andric NumDesignators = NumDesignators - 1 + NumNewDesignators;
47030b57cec5SDimitry Andric }
47040b57cec5SDimitry Andric
DesignatedInitUpdateExpr(const ASTContext & C,SourceLocation lBraceLoc,Expr * baseExpr,SourceLocation rBraceLoc)47050b57cec5SDimitry Andric DesignatedInitUpdateExpr::DesignatedInitUpdateExpr(const ASTContext &C,
47065ffd83dbSDimitry Andric SourceLocation lBraceLoc,
47075ffd83dbSDimitry Andric Expr *baseExpr,
47085ffd83dbSDimitry Andric SourceLocation rBraceLoc)
4709fe6060f1SDimitry Andric : Expr(DesignatedInitUpdateExprClass, baseExpr->getType(), VK_PRValue,
47105ffd83dbSDimitry Andric OK_Ordinary) {
47110b57cec5SDimitry Andric BaseAndUpdaterExprs[0] = baseExpr;
47120b57cec5SDimitry Andric
4713bdd1243dSDimitry Andric InitListExpr *ILE =
4714bdd1243dSDimitry Andric new (C) InitListExpr(C, lBraceLoc, std::nullopt, rBraceLoc);
47150b57cec5SDimitry Andric ILE->setType(baseExpr->getType());
47160b57cec5SDimitry Andric BaseAndUpdaterExprs[1] = ILE;
47175ffd83dbSDimitry Andric
47185ffd83dbSDimitry Andric // FIXME: this is wrong, set it correctly.
47195ffd83dbSDimitry Andric setDependence(ExprDependence::None);
47200b57cec5SDimitry Andric }
47210b57cec5SDimitry Andric
getBeginLoc() const47220b57cec5SDimitry Andric SourceLocation DesignatedInitUpdateExpr::getBeginLoc() const {
47230b57cec5SDimitry Andric return getBase()->getBeginLoc();
47240b57cec5SDimitry Andric }
47250b57cec5SDimitry Andric
getEndLoc() const47260b57cec5SDimitry Andric SourceLocation DesignatedInitUpdateExpr::getEndLoc() const {
47270b57cec5SDimitry Andric return getBase()->getEndLoc();
47280b57cec5SDimitry Andric }
47290b57cec5SDimitry Andric
ParenListExpr(SourceLocation LParenLoc,ArrayRef<Expr * > Exprs,SourceLocation RParenLoc)47300b57cec5SDimitry Andric ParenListExpr::ParenListExpr(SourceLocation LParenLoc, ArrayRef<Expr *> Exprs,
47310b57cec5SDimitry Andric SourceLocation RParenLoc)
4732fe6060f1SDimitry Andric : Expr(ParenListExprClass, QualType(), VK_PRValue, OK_Ordinary),
47330b57cec5SDimitry Andric LParenLoc(LParenLoc), RParenLoc(RParenLoc) {
47340b57cec5SDimitry Andric ParenListExprBits.NumExprs = Exprs.size();
47350b57cec5SDimitry Andric
47365ffd83dbSDimitry Andric for (unsigned I = 0, N = Exprs.size(); I != N; ++I)
47370b57cec5SDimitry Andric getTrailingObjects<Stmt *>()[I] = Exprs[I];
47385ffd83dbSDimitry Andric setDependence(computeDependence(this));
47390b57cec5SDimitry Andric }
47400b57cec5SDimitry Andric
ParenListExpr(EmptyShell Empty,unsigned NumExprs)47410b57cec5SDimitry Andric ParenListExpr::ParenListExpr(EmptyShell Empty, unsigned NumExprs)
47420b57cec5SDimitry Andric : Expr(ParenListExprClass, Empty) {
47430b57cec5SDimitry Andric ParenListExprBits.NumExprs = NumExprs;
47440b57cec5SDimitry Andric }
47450b57cec5SDimitry Andric
Create(const ASTContext & Ctx,SourceLocation LParenLoc,ArrayRef<Expr * > Exprs,SourceLocation RParenLoc)47460b57cec5SDimitry Andric ParenListExpr *ParenListExpr::Create(const ASTContext &Ctx,
47470b57cec5SDimitry Andric SourceLocation LParenLoc,
47480b57cec5SDimitry Andric ArrayRef<Expr *> Exprs,
47490b57cec5SDimitry Andric SourceLocation RParenLoc) {
47500b57cec5SDimitry Andric void *Mem = Ctx.Allocate(totalSizeToAlloc<Stmt *>(Exprs.size()),
47510b57cec5SDimitry Andric alignof(ParenListExpr));
47520b57cec5SDimitry Andric return new (Mem) ParenListExpr(LParenLoc, Exprs, RParenLoc);
47530b57cec5SDimitry Andric }
47540b57cec5SDimitry Andric
CreateEmpty(const ASTContext & Ctx,unsigned NumExprs)47550b57cec5SDimitry Andric ParenListExpr *ParenListExpr::CreateEmpty(const ASTContext &Ctx,
47560b57cec5SDimitry Andric unsigned NumExprs) {
47570b57cec5SDimitry Andric void *Mem =
47580b57cec5SDimitry Andric Ctx.Allocate(totalSizeToAlloc<Stmt *>(NumExprs), alignof(ParenListExpr));
47590b57cec5SDimitry Andric return new (Mem) ParenListExpr(EmptyShell(), NumExprs);
47600b57cec5SDimitry Andric }
47610b57cec5SDimitry Andric
BinaryOperator(const ASTContext & Ctx,Expr * lhs,Expr * rhs,Opcode opc,QualType ResTy,ExprValueKind VK,ExprObjectKind OK,SourceLocation opLoc,FPOptionsOverride FPFeatures)47625ffd83dbSDimitry Andric BinaryOperator::BinaryOperator(const ASTContext &Ctx, Expr *lhs, Expr *rhs,
47635ffd83dbSDimitry Andric Opcode opc, QualType ResTy, ExprValueKind VK,
47645ffd83dbSDimitry Andric ExprObjectKind OK, SourceLocation opLoc,
47655ffd83dbSDimitry Andric FPOptionsOverride FPFeatures)
47665ffd83dbSDimitry Andric : Expr(BinaryOperatorClass, ResTy, VK, OK) {
47675ffd83dbSDimitry Andric BinaryOperatorBits.Opc = opc;
47685ffd83dbSDimitry Andric assert(!isCompoundAssignmentOp() &&
47695ffd83dbSDimitry Andric "Use CompoundAssignOperator for compound assignments");
47705ffd83dbSDimitry Andric BinaryOperatorBits.OpLoc = opLoc;
47715ffd83dbSDimitry Andric SubExprs[LHS] = lhs;
47725ffd83dbSDimitry Andric SubExprs[RHS] = rhs;
47735ffd83dbSDimitry Andric BinaryOperatorBits.HasFPFeatures = FPFeatures.requiresTrailingStorage();
4774e8d8bef9SDimitry Andric if (hasStoredFPFeatures())
4775e8d8bef9SDimitry Andric setStoredFPFeatures(FPFeatures);
47765ffd83dbSDimitry Andric setDependence(computeDependence(this));
47775ffd83dbSDimitry Andric }
47785ffd83dbSDimitry Andric
BinaryOperator(const ASTContext & Ctx,Expr * lhs,Expr * rhs,Opcode opc,QualType ResTy,ExprValueKind VK,ExprObjectKind OK,SourceLocation opLoc,FPOptionsOverride FPFeatures,bool dead2)47795ffd83dbSDimitry Andric BinaryOperator::BinaryOperator(const ASTContext &Ctx, Expr *lhs, Expr *rhs,
47805ffd83dbSDimitry Andric Opcode opc, QualType ResTy, ExprValueKind VK,
47815ffd83dbSDimitry Andric ExprObjectKind OK, SourceLocation opLoc,
47825ffd83dbSDimitry Andric FPOptionsOverride FPFeatures, bool dead2)
47835ffd83dbSDimitry Andric : Expr(CompoundAssignOperatorClass, ResTy, VK, OK) {
47845ffd83dbSDimitry Andric BinaryOperatorBits.Opc = opc;
47855ffd83dbSDimitry Andric assert(isCompoundAssignmentOp() &&
47865ffd83dbSDimitry Andric "Use CompoundAssignOperator for compound assignments");
47875ffd83dbSDimitry Andric BinaryOperatorBits.OpLoc = opLoc;
47885ffd83dbSDimitry Andric SubExprs[LHS] = lhs;
47895ffd83dbSDimitry Andric SubExprs[RHS] = rhs;
47905ffd83dbSDimitry Andric BinaryOperatorBits.HasFPFeatures = FPFeatures.requiresTrailingStorage();
4791e8d8bef9SDimitry Andric if (hasStoredFPFeatures())
4792e8d8bef9SDimitry Andric setStoredFPFeatures(FPFeatures);
47935ffd83dbSDimitry Andric setDependence(computeDependence(this));
47945ffd83dbSDimitry Andric }
47955ffd83dbSDimitry Andric
CreateEmpty(const ASTContext & C,bool HasFPFeatures)47965ffd83dbSDimitry Andric BinaryOperator *BinaryOperator::CreateEmpty(const ASTContext &C,
47975ffd83dbSDimitry Andric bool HasFPFeatures) {
47985ffd83dbSDimitry Andric unsigned Extra = sizeOfTrailingObjects(HasFPFeatures);
47995ffd83dbSDimitry Andric void *Mem =
48005ffd83dbSDimitry Andric C.Allocate(sizeof(BinaryOperator) + Extra, alignof(BinaryOperator));
48015ffd83dbSDimitry Andric return new (Mem) BinaryOperator(EmptyShell());
48025ffd83dbSDimitry Andric }
48035ffd83dbSDimitry Andric
Create(const ASTContext & C,Expr * lhs,Expr * rhs,Opcode opc,QualType ResTy,ExprValueKind VK,ExprObjectKind OK,SourceLocation opLoc,FPOptionsOverride FPFeatures)48045ffd83dbSDimitry Andric BinaryOperator *BinaryOperator::Create(const ASTContext &C, Expr *lhs,
48055ffd83dbSDimitry Andric Expr *rhs, Opcode opc, QualType ResTy,
48065ffd83dbSDimitry Andric ExprValueKind VK, ExprObjectKind OK,
48075ffd83dbSDimitry Andric SourceLocation opLoc,
48085ffd83dbSDimitry Andric FPOptionsOverride FPFeatures) {
48095ffd83dbSDimitry Andric bool HasFPFeatures = FPFeatures.requiresTrailingStorage();
48105ffd83dbSDimitry Andric unsigned Extra = sizeOfTrailingObjects(HasFPFeatures);
48115ffd83dbSDimitry Andric void *Mem =
48125ffd83dbSDimitry Andric C.Allocate(sizeof(BinaryOperator) + Extra, alignof(BinaryOperator));
48135ffd83dbSDimitry Andric return new (Mem)
48145ffd83dbSDimitry Andric BinaryOperator(C, lhs, rhs, opc, ResTy, VK, OK, opLoc, FPFeatures);
48155ffd83dbSDimitry Andric }
48165ffd83dbSDimitry Andric
48175ffd83dbSDimitry Andric CompoundAssignOperator *
CreateEmpty(const ASTContext & C,bool HasFPFeatures)48185ffd83dbSDimitry Andric CompoundAssignOperator::CreateEmpty(const ASTContext &C, bool HasFPFeatures) {
48195ffd83dbSDimitry Andric unsigned Extra = sizeOfTrailingObjects(HasFPFeatures);
48205ffd83dbSDimitry Andric void *Mem = C.Allocate(sizeof(CompoundAssignOperator) + Extra,
48215ffd83dbSDimitry Andric alignof(CompoundAssignOperator));
48225ffd83dbSDimitry Andric return new (Mem) CompoundAssignOperator(C, EmptyShell(), HasFPFeatures);
48235ffd83dbSDimitry Andric }
48245ffd83dbSDimitry Andric
48255ffd83dbSDimitry Andric CompoundAssignOperator *
Create(const ASTContext & C,Expr * lhs,Expr * rhs,Opcode opc,QualType ResTy,ExprValueKind VK,ExprObjectKind OK,SourceLocation opLoc,FPOptionsOverride FPFeatures,QualType CompLHSType,QualType CompResultType)48265ffd83dbSDimitry Andric CompoundAssignOperator::Create(const ASTContext &C, Expr *lhs, Expr *rhs,
48275ffd83dbSDimitry Andric Opcode opc, QualType ResTy, ExprValueKind VK,
48285ffd83dbSDimitry Andric ExprObjectKind OK, SourceLocation opLoc,
48295ffd83dbSDimitry Andric FPOptionsOverride FPFeatures,
48305ffd83dbSDimitry Andric QualType CompLHSType, QualType CompResultType) {
48315ffd83dbSDimitry Andric bool HasFPFeatures = FPFeatures.requiresTrailingStorage();
48325ffd83dbSDimitry Andric unsigned Extra = sizeOfTrailingObjects(HasFPFeatures);
48335ffd83dbSDimitry Andric void *Mem = C.Allocate(sizeof(CompoundAssignOperator) + Extra,
48345ffd83dbSDimitry Andric alignof(CompoundAssignOperator));
48355ffd83dbSDimitry Andric return new (Mem)
48365ffd83dbSDimitry Andric CompoundAssignOperator(C, lhs, rhs, opc, ResTy, VK, OK, opLoc, FPFeatures,
48375ffd83dbSDimitry Andric CompLHSType, CompResultType);
48385ffd83dbSDimitry Andric }
48395ffd83dbSDimitry Andric
CreateEmpty(const ASTContext & C,bool hasFPFeatures)48405ffd83dbSDimitry Andric UnaryOperator *UnaryOperator::CreateEmpty(const ASTContext &C,
48415ffd83dbSDimitry Andric bool hasFPFeatures) {
48425ffd83dbSDimitry Andric void *Mem = C.Allocate(totalSizeToAlloc<FPOptionsOverride>(hasFPFeatures),
48435ffd83dbSDimitry Andric alignof(UnaryOperator));
48445ffd83dbSDimitry Andric return new (Mem) UnaryOperator(hasFPFeatures, EmptyShell());
48455ffd83dbSDimitry Andric }
48465ffd83dbSDimitry Andric
UnaryOperator(const ASTContext & Ctx,Expr * input,Opcode opc,QualType type,ExprValueKind VK,ExprObjectKind OK,SourceLocation l,bool CanOverflow,FPOptionsOverride FPFeatures)48475ffd83dbSDimitry Andric UnaryOperator::UnaryOperator(const ASTContext &Ctx, Expr *input, Opcode opc,
48485ffd83dbSDimitry Andric QualType type, ExprValueKind VK, ExprObjectKind OK,
48495ffd83dbSDimitry Andric SourceLocation l, bool CanOverflow,
48505ffd83dbSDimitry Andric FPOptionsOverride FPFeatures)
48515ffd83dbSDimitry Andric : Expr(UnaryOperatorClass, type, VK, OK), Val(input) {
48525ffd83dbSDimitry Andric UnaryOperatorBits.Opc = opc;
48535ffd83dbSDimitry Andric UnaryOperatorBits.CanOverflow = CanOverflow;
48545ffd83dbSDimitry Andric UnaryOperatorBits.Loc = l;
48555ffd83dbSDimitry Andric UnaryOperatorBits.HasFPFeatures = FPFeatures.requiresTrailingStorage();
4856e8d8bef9SDimitry Andric if (hasStoredFPFeatures())
4857e8d8bef9SDimitry Andric setStoredFPFeatures(FPFeatures);
4858e8d8bef9SDimitry Andric setDependence(computeDependence(this, Ctx));
48595ffd83dbSDimitry Andric }
48605ffd83dbSDimitry Andric
Create(const ASTContext & C,Expr * input,Opcode opc,QualType type,ExprValueKind VK,ExprObjectKind OK,SourceLocation l,bool CanOverflow,FPOptionsOverride FPFeatures)48615ffd83dbSDimitry Andric UnaryOperator *UnaryOperator::Create(const ASTContext &C, Expr *input,
48625ffd83dbSDimitry Andric Opcode opc, QualType type,
48635ffd83dbSDimitry Andric ExprValueKind VK, ExprObjectKind OK,
48645ffd83dbSDimitry Andric SourceLocation l, bool CanOverflow,
48655ffd83dbSDimitry Andric FPOptionsOverride FPFeatures) {
48665ffd83dbSDimitry Andric bool HasFPFeatures = FPFeatures.requiresTrailingStorage();
48675ffd83dbSDimitry Andric unsigned Size = totalSizeToAlloc<FPOptionsOverride>(HasFPFeatures);
48685ffd83dbSDimitry Andric void *Mem = C.Allocate(Size, alignof(UnaryOperator));
48695ffd83dbSDimitry Andric return new (Mem)
48705ffd83dbSDimitry Andric UnaryOperator(C, input, opc, type, VK, OK, l, CanOverflow, FPFeatures);
48715ffd83dbSDimitry Andric }
48725ffd83dbSDimitry Andric
findInCopyConstruct(const Expr * e)48730b57cec5SDimitry Andric const OpaqueValueExpr *OpaqueValueExpr::findInCopyConstruct(const Expr *e) {
48740b57cec5SDimitry Andric if (const ExprWithCleanups *ewc = dyn_cast<ExprWithCleanups>(e))
48750b57cec5SDimitry Andric e = ewc->getSubExpr();
48760b57cec5SDimitry Andric if (const MaterializeTemporaryExpr *m = dyn_cast<MaterializeTemporaryExpr>(e))
4877480093f4SDimitry Andric e = m->getSubExpr();
48780b57cec5SDimitry Andric e = cast<CXXConstructExpr>(e)->getArg(0);
48790b57cec5SDimitry Andric while (const ImplicitCastExpr *ice = dyn_cast<ImplicitCastExpr>(e))
48800b57cec5SDimitry Andric e = ice->getSubExpr();
48810b57cec5SDimitry Andric return cast<OpaqueValueExpr>(e);
48820b57cec5SDimitry Andric }
48830b57cec5SDimitry Andric
Create(const ASTContext & Context,EmptyShell sh,unsigned numSemanticExprs)48840b57cec5SDimitry Andric PseudoObjectExpr *PseudoObjectExpr::Create(const ASTContext &Context,
48850b57cec5SDimitry Andric EmptyShell sh,
48860b57cec5SDimitry Andric unsigned numSemanticExprs) {
48870b57cec5SDimitry Andric void *buffer =
48880b57cec5SDimitry Andric Context.Allocate(totalSizeToAlloc<Expr *>(1 + numSemanticExprs),
48890b57cec5SDimitry Andric alignof(PseudoObjectExpr));
48900b57cec5SDimitry Andric return new(buffer) PseudoObjectExpr(sh, numSemanticExprs);
48910b57cec5SDimitry Andric }
48920b57cec5SDimitry Andric
PseudoObjectExpr(EmptyShell shell,unsigned numSemanticExprs)48930b57cec5SDimitry Andric PseudoObjectExpr::PseudoObjectExpr(EmptyShell shell, unsigned numSemanticExprs)
48940b57cec5SDimitry Andric : Expr(PseudoObjectExprClass, shell) {
48950b57cec5SDimitry Andric PseudoObjectExprBits.NumSubExprs = numSemanticExprs + 1;
48960b57cec5SDimitry Andric }
48970b57cec5SDimitry Andric
Create(const ASTContext & C,Expr * syntax,ArrayRef<Expr * > semantics,unsigned resultIndex)48980b57cec5SDimitry Andric PseudoObjectExpr *PseudoObjectExpr::Create(const ASTContext &C, Expr *syntax,
48990b57cec5SDimitry Andric ArrayRef<Expr*> semantics,
49000b57cec5SDimitry Andric unsigned resultIndex) {
49010b57cec5SDimitry Andric assert(syntax && "no syntactic expression!");
49020b57cec5SDimitry Andric assert(semantics.size() && "no semantic expressions!");
49030b57cec5SDimitry Andric
49040b57cec5SDimitry Andric QualType type;
49050b57cec5SDimitry Andric ExprValueKind VK;
49060b57cec5SDimitry Andric if (resultIndex == NoResult) {
49070b57cec5SDimitry Andric type = C.VoidTy;
4908fe6060f1SDimitry Andric VK = VK_PRValue;
49090b57cec5SDimitry Andric } else {
49100b57cec5SDimitry Andric assert(resultIndex < semantics.size());
49110b57cec5SDimitry Andric type = semantics[resultIndex]->getType();
49120b57cec5SDimitry Andric VK = semantics[resultIndex]->getValueKind();
49130b57cec5SDimitry Andric assert(semantics[resultIndex]->getObjectKind() == OK_Ordinary);
49140b57cec5SDimitry Andric }
49150b57cec5SDimitry Andric
49160b57cec5SDimitry Andric void *buffer = C.Allocate(totalSizeToAlloc<Expr *>(semantics.size() + 1),
49170b57cec5SDimitry Andric alignof(PseudoObjectExpr));
49180b57cec5SDimitry Andric return new(buffer) PseudoObjectExpr(type, VK, syntax, semantics,
49190b57cec5SDimitry Andric resultIndex);
49200b57cec5SDimitry Andric }
49210b57cec5SDimitry Andric
PseudoObjectExpr(QualType type,ExprValueKind VK,Expr * syntax,ArrayRef<Expr * > semantics,unsigned resultIndex)49220b57cec5SDimitry Andric PseudoObjectExpr::PseudoObjectExpr(QualType type, ExprValueKind VK,
49230b57cec5SDimitry Andric Expr *syntax, ArrayRef<Expr *> semantics,
49240b57cec5SDimitry Andric unsigned resultIndex)
49255ffd83dbSDimitry Andric : Expr(PseudoObjectExprClass, type, VK, OK_Ordinary) {
49260b57cec5SDimitry Andric PseudoObjectExprBits.NumSubExprs = semantics.size() + 1;
49270b57cec5SDimitry Andric PseudoObjectExprBits.ResultIndex = resultIndex + 1;
49280b57cec5SDimitry Andric
49290b57cec5SDimitry Andric for (unsigned i = 0, e = semantics.size() + 1; i != e; ++i) {
49300b57cec5SDimitry Andric Expr *E = (i == 0 ? syntax : semantics[i-1]);
49310b57cec5SDimitry Andric getSubExprsBuffer()[i] = E;
49320b57cec5SDimitry Andric
49330b57cec5SDimitry Andric if (isa<OpaqueValueExpr>(E))
49340b57cec5SDimitry Andric assert(cast<OpaqueValueExpr>(E)->getSourceExpr() != nullptr &&
49350b57cec5SDimitry Andric "opaque-value semantic expressions for pseudo-object "
49360b57cec5SDimitry Andric "operations must have sources");
49370b57cec5SDimitry Andric }
49385ffd83dbSDimitry Andric
49395ffd83dbSDimitry Andric setDependence(computeDependence(this));
49400b57cec5SDimitry Andric }
49410b57cec5SDimitry Andric
49420b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
49430b57cec5SDimitry Andric // Child Iterators for iterating over subexpressions/substatements
49440b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
49450b57cec5SDimitry Andric
49460b57cec5SDimitry Andric // UnaryExprOrTypeTraitExpr
children()49470b57cec5SDimitry Andric Stmt::child_range UnaryExprOrTypeTraitExpr::children() {
49480b57cec5SDimitry Andric const_child_range CCR =
49490b57cec5SDimitry Andric const_cast<const UnaryExprOrTypeTraitExpr *>(this)->children();
49500b57cec5SDimitry Andric return child_range(cast_away_const(CCR.begin()), cast_away_const(CCR.end()));
49510b57cec5SDimitry Andric }
49520b57cec5SDimitry Andric
children() const49530b57cec5SDimitry Andric Stmt::const_child_range UnaryExprOrTypeTraitExpr::children() const {
49540b57cec5SDimitry Andric // If this is of a type and the type is a VLA type (and not a typedef), the
49550b57cec5SDimitry Andric // size expression of the VLA needs to be treated as an executable expression.
49560b57cec5SDimitry Andric // Why isn't this weirdness documented better in StmtIterator?
49570b57cec5SDimitry Andric if (isArgumentType()) {
49580b57cec5SDimitry Andric if (const VariableArrayType *T =
49590b57cec5SDimitry Andric dyn_cast<VariableArrayType>(getArgumentType().getTypePtr()))
49600b57cec5SDimitry Andric return const_child_range(const_child_iterator(T), const_child_iterator());
49610b57cec5SDimitry Andric return const_child_range(const_child_iterator(), const_child_iterator());
49620b57cec5SDimitry Andric }
49630b57cec5SDimitry Andric return const_child_range(&Argument.Ex, &Argument.Ex + 1);
49640b57cec5SDimitry Andric }
49650b57cec5SDimitry Andric
AtomicExpr(SourceLocation BLoc,ArrayRef<Expr * > args,QualType t,AtomicOp op,SourceLocation RP)49665ffd83dbSDimitry Andric AtomicExpr::AtomicExpr(SourceLocation BLoc, ArrayRef<Expr *> args, QualType t,
49675ffd83dbSDimitry Andric AtomicOp op, SourceLocation RP)
4968fe6060f1SDimitry Andric : Expr(AtomicExprClass, t, VK_PRValue, OK_Ordinary),
49695ffd83dbSDimitry Andric NumSubExprs(args.size()), BuiltinLoc(BLoc), RParenLoc(RP), Op(op) {
49700b57cec5SDimitry Andric assert(args.size() == getNumSubExprs(op) && "wrong number of subexpressions");
49715ffd83dbSDimitry Andric for (unsigned i = 0; i != args.size(); i++)
49720b57cec5SDimitry Andric SubExprs[i] = args[i];
49735ffd83dbSDimitry Andric setDependence(computeDependence(this));
49740b57cec5SDimitry Andric }
49750b57cec5SDimitry Andric
getNumSubExprs(AtomicOp Op)49760b57cec5SDimitry Andric unsigned AtomicExpr::getNumSubExprs(AtomicOp Op) {
49770b57cec5SDimitry Andric switch (Op) {
49780b57cec5SDimitry Andric case AO__c11_atomic_init:
49790b57cec5SDimitry Andric case AO__opencl_atomic_init:
49800b57cec5SDimitry Andric case AO__c11_atomic_load:
49810b57cec5SDimitry Andric case AO__atomic_load_n:
49820b57cec5SDimitry Andric return 2;
49830b57cec5SDimitry Andric
49845f757f3fSDimitry Andric case AO__scoped_atomic_load_n:
49850b57cec5SDimitry Andric case AO__opencl_atomic_load:
49864824e7fdSDimitry Andric case AO__hip_atomic_load:
49870b57cec5SDimitry Andric case AO__c11_atomic_store:
49880b57cec5SDimitry Andric case AO__c11_atomic_exchange:
49890b57cec5SDimitry Andric case AO__atomic_load:
49900b57cec5SDimitry Andric case AO__atomic_store:
49910b57cec5SDimitry Andric case AO__atomic_store_n:
49920b57cec5SDimitry Andric case AO__atomic_exchange_n:
49930b57cec5SDimitry Andric case AO__c11_atomic_fetch_add:
49940b57cec5SDimitry Andric case AO__c11_atomic_fetch_sub:
49950b57cec5SDimitry Andric case AO__c11_atomic_fetch_and:
49960b57cec5SDimitry Andric case AO__c11_atomic_fetch_or:
49970b57cec5SDimitry Andric case AO__c11_atomic_fetch_xor:
4998349cc55cSDimitry Andric case AO__c11_atomic_fetch_nand:
4999480093f4SDimitry Andric case AO__c11_atomic_fetch_max:
5000480093f4SDimitry Andric case AO__c11_atomic_fetch_min:
50010b57cec5SDimitry Andric case AO__atomic_fetch_add:
50020b57cec5SDimitry Andric case AO__atomic_fetch_sub:
50030b57cec5SDimitry Andric case AO__atomic_fetch_and:
50040b57cec5SDimitry Andric case AO__atomic_fetch_or:
50050b57cec5SDimitry Andric case AO__atomic_fetch_xor:
50060b57cec5SDimitry Andric case AO__atomic_fetch_nand:
50070b57cec5SDimitry Andric case AO__atomic_add_fetch:
50080b57cec5SDimitry Andric case AO__atomic_sub_fetch:
50090b57cec5SDimitry Andric case AO__atomic_and_fetch:
50100b57cec5SDimitry Andric case AO__atomic_or_fetch:
50110b57cec5SDimitry Andric case AO__atomic_xor_fetch:
50120b57cec5SDimitry Andric case AO__atomic_nand_fetch:
5013480093f4SDimitry Andric case AO__atomic_min_fetch:
5014480093f4SDimitry Andric case AO__atomic_max_fetch:
50150b57cec5SDimitry Andric case AO__atomic_fetch_min:
50160b57cec5SDimitry Andric case AO__atomic_fetch_max:
50170b57cec5SDimitry Andric return 3;
50180b57cec5SDimitry Andric
50195f757f3fSDimitry Andric case AO__scoped_atomic_load:
50205f757f3fSDimitry Andric case AO__scoped_atomic_store:
50215f757f3fSDimitry Andric case AO__scoped_atomic_store_n:
50225f757f3fSDimitry Andric case AO__scoped_atomic_fetch_add:
50235f757f3fSDimitry Andric case AO__scoped_atomic_fetch_sub:
50245f757f3fSDimitry Andric case AO__scoped_atomic_fetch_and:
50255f757f3fSDimitry Andric case AO__scoped_atomic_fetch_or:
50265f757f3fSDimitry Andric case AO__scoped_atomic_fetch_xor:
50275f757f3fSDimitry Andric case AO__scoped_atomic_fetch_nand:
50285f757f3fSDimitry Andric case AO__scoped_atomic_add_fetch:
50295f757f3fSDimitry Andric case AO__scoped_atomic_sub_fetch:
50305f757f3fSDimitry Andric case AO__scoped_atomic_and_fetch:
50315f757f3fSDimitry Andric case AO__scoped_atomic_or_fetch:
50325f757f3fSDimitry Andric case AO__scoped_atomic_xor_fetch:
50335f757f3fSDimitry Andric case AO__scoped_atomic_nand_fetch:
50345f757f3fSDimitry Andric case AO__scoped_atomic_min_fetch:
50355f757f3fSDimitry Andric case AO__scoped_atomic_max_fetch:
50365f757f3fSDimitry Andric case AO__scoped_atomic_fetch_min:
50375f757f3fSDimitry Andric case AO__scoped_atomic_fetch_max:
50385f757f3fSDimitry Andric case AO__scoped_atomic_exchange_n:
50394824e7fdSDimitry Andric case AO__hip_atomic_exchange:
50404824e7fdSDimitry Andric case AO__hip_atomic_fetch_add:
504106c3fb27SDimitry Andric case AO__hip_atomic_fetch_sub:
50424824e7fdSDimitry Andric case AO__hip_atomic_fetch_and:
50434824e7fdSDimitry Andric case AO__hip_atomic_fetch_or:
50444824e7fdSDimitry Andric case AO__hip_atomic_fetch_xor:
50454824e7fdSDimitry Andric case AO__hip_atomic_fetch_min:
50464824e7fdSDimitry Andric case AO__hip_atomic_fetch_max:
50470b57cec5SDimitry Andric case AO__opencl_atomic_store:
50484824e7fdSDimitry Andric case AO__hip_atomic_store:
50490b57cec5SDimitry Andric case AO__opencl_atomic_exchange:
50500b57cec5SDimitry Andric case AO__opencl_atomic_fetch_add:
50510b57cec5SDimitry Andric case AO__opencl_atomic_fetch_sub:
50520b57cec5SDimitry Andric case AO__opencl_atomic_fetch_and:
50530b57cec5SDimitry Andric case AO__opencl_atomic_fetch_or:
50540b57cec5SDimitry Andric case AO__opencl_atomic_fetch_xor:
50550b57cec5SDimitry Andric case AO__opencl_atomic_fetch_min:
50560b57cec5SDimitry Andric case AO__opencl_atomic_fetch_max:
50570b57cec5SDimitry Andric case AO__atomic_exchange:
50580b57cec5SDimitry Andric return 4;
50590b57cec5SDimitry Andric
50605f757f3fSDimitry Andric case AO__scoped_atomic_exchange:
50610b57cec5SDimitry Andric case AO__c11_atomic_compare_exchange_strong:
50620b57cec5SDimitry Andric case AO__c11_atomic_compare_exchange_weak:
50630b57cec5SDimitry Andric return 5;
50644824e7fdSDimitry Andric case AO__hip_atomic_compare_exchange_strong:
50650b57cec5SDimitry Andric case AO__opencl_atomic_compare_exchange_strong:
50660b57cec5SDimitry Andric case AO__opencl_atomic_compare_exchange_weak:
50674824e7fdSDimitry Andric case AO__hip_atomic_compare_exchange_weak:
50680b57cec5SDimitry Andric case AO__atomic_compare_exchange:
50690b57cec5SDimitry Andric case AO__atomic_compare_exchange_n:
50700b57cec5SDimitry Andric return 6;
50715f757f3fSDimitry Andric
50725f757f3fSDimitry Andric case AO__scoped_atomic_compare_exchange:
50735f757f3fSDimitry Andric case AO__scoped_atomic_compare_exchange_n:
50745f757f3fSDimitry Andric return 7;
50750b57cec5SDimitry Andric }
50760b57cec5SDimitry Andric llvm_unreachable("unknown atomic op");
50770b57cec5SDimitry Andric }
50780b57cec5SDimitry Andric
getValueType() const50790b57cec5SDimitry Andric QualType AtomicExpr::getValueType() const {
50800b57cec5SDimitry Andric auto T = getPtr()->getType()->castAs<PointerType>()->getPointeeType();
50810b57cec5SDimitry Andric if (auto AT = T->getAs<AtomicType>())
50820b57cec5SDimitry Andric return AT->getValueType();
50830b57cec5SDimitry Andric return T;
50840b57cec5SDimitry Andric }
50850b57cec5SDimitry Andric
getBaseOriginalType(const Expr * Base)5086*0fca6ea1SDimitry Andric QualType ArraySectionExpr::getBaseOriginalType(const Expr *Base) {
50870b57cec5SDimitry Andric unsigned ArraySectionCount = 0;
5088*0fca6ea1SDimitry Andric while (auto *OASE = dyn_cast<ArraySectionExpr>(Base->IgnoreParens())) {
50890b57cec5SDimitry Andric Base = OASE->getBase();
50900b57cec5SDimitry Andric ++ArraySectionCount;
50910b57cec5SDimitry Andric }
50920b57cec5SDimitry Andric while (auto *ASE =
50930b57cec5SDimitry Andric dyn_cast<ArraySubscriptExpr>(Base->IgnoreParenImpCasts())) {
50940b57cec5SDimitry Andric Base = ASE->getBase();
50950b57cec5SDimitry Andric ++ArraySectionCount;
50960b57cec5SDimitry Andric }
50970b57cec5SDimitry Andric Base = Base->IgnoreParenImpCasts();
50980b57cec5SDimitry Andric auto OriginalTy = Base->getType();
50990b57cec5SDimitry Andric if (auto *DRE = dyn_cast<DeclRefExpr>(Base))
51000b57cec5SDimitry Andric if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
51010b57cec5SDimitry Andric OriginalTy = PVD->getOriginalType().getNonReferenceType();
51020b57cec5SDimitry Andric
51030b57cec5SDimitry Andric for (unsigned Cnt = 0; Cnt < ArraySectionCount; ++Cnt) {
51040b57cec5SDimitry Andric if (OriginalTy->isAnyPointerType())
51050b57cec5SDimitry Andric OriginalTy = OriginalTy->getPointeeType();
51065f757f3fSDimitry Andric else if (OriginalTy->isArrayType())
51070b57cec5SDimitry Andric OriginalTy = OriginalTy->castAsArrayTypeUnsafe()->getElementType();
51085f757f3fSDimitry Andric else
51095f757f3fSDimitry Andric return {};
51100b57cec5SDimitry Andric }
51110b57cec5SDimitry Andric return OriginalTy;
51120b57cec5SDimitry Andric }
51135ffd83dbSDimitry Andric
RecoveryExpr(ASTContext & Ctx,QualType T,SourceLocation BeginLoc,SourceLocation EndLoc,ArrayRef<Expr * > SubExprs)51145ffd83dbSDimitry Andric RecoveryExpr::RecoveryExpr(ASTContext &Ctx, QualType T, SourceLocation BeginLoc,
51155ffd83dbSDimitry Andric SourceLocation EndLoc, ArrayRef<Expr *> SubExprs)
51165ffd83dbSDimitry Andric : Expr(RecoveryExprClass, T.getNonReferenceType(),
51175ffd83dbSDimitry Andric T->isDependentType() ? VK_LValue : getValueKindForType(T),
51185ffd83dbSDimitry Andric OK_Ordinary),
51195ffd83dbSDimitry Andric BeginLoc(BeginLoc), EndLoc(EndLoc), NumExprs(SubExprs.size()) {
51205ffd83dbSDimitry Andric assert(!T.isNull());
5121bdd1243dSDimitry Andric assert(!llvm::is_contained(SubExprs, nullptr));
51225ffd83dbSDimitry Andric
51235ffd83dbSDimitry Andric llvm::copy(SubExprs, getTrailingObjects<Expr *>());
51245ffd83dbSDimitry Andric setDependence(computeDependence(this));
51255ffd83dbSDimitry Andric }
51265ffd83dbSDimitry Andric
Create(ASTContext & Ctx,QualType T,SourceLocation BeginLoc,SourceLocation EndLoc,ArrayRef<Expr * > SubExprs)51275ffd83dbSDimitry Andric RecoveryExpr *RecoveryExpr::Create(ASTContext &Ctx, QualType T,
51285ffd83dbSDimitry Andric SourceLocation BeginLoc,
51295ffd83dbSDimitry Andric SourceLocation EndLoc,
51305ffd83dbSDimitry Andric ArrayRef<Expr *> SubExprs) {
51315ffd83dbSDimitry Andric void *Mem = Ctx.Allocate(totalSizeToAlloc<Expr *>(SubExprs.size()),
51325ffd83dbSDimitry Andric alignof(RecoveryExpr));
51335ffd83dbSDimitry Andric return new (Mem) RecoveryExpr(Ctx, T, BeginLoc, EndLoc, SubExprs);
51345ffd83dbSDimitry Andric }
51355ffd83dbSDimitry Andric
CreateEmpty(ASTContext & Ctx,unsigned NumSubExprs)51365ffd83dbSDimitry Andric RecoveryExpr *RecoveryExpr::CreateEmpty(ASTContext &Ctx, unsigned NumSubExprs) {
51375ffd83dbSDimitry Andric void *Mem = Ctx.Allocate(totalSizeToAlloc<Expr *>(NumSubExprs),
51385ffd83dbSDimitry Andric alignof(RecoveryExpr));
51395ffd83dbSDimitry Andric return new (Mem) RecoveryExpr(EmptyShell(), NumSubExprs);
51405ffd83dbSDimitry Andric }
51415ffd83dbSDimitry Andric
setDimensions(ArrayRef<Expr * > Dims)51425ffd83dbSDimitry Andric void OMPArrayShapingExpr::setDimensions(ArrayRef<Expr *> Dims) {
51435ffd83dbSDimitry Andric assert(
51445ffd83dbSDimitry Andric NumDims == Dims.size() &&
51455ffd83dbSDimitry Andric "Preallocated number of dimensions is different from the provided one.");
51465ffd83dbSDimitry Andric llvm::copy(Dims, getTrailingObjects<Expr *>());
51475ffd83dbSDimitry Andric }
51485ffd83dbSDimitry Andric
setBracketsRanges(ArrayRef<SourceRange> BR)51495ffd83dbSDimitry Andric void OMPArrayShapingExpr::setBracketsRanges(ArrayRef<SourceRange> BR) {
51505ffd83dbSDimitry Andric assert(
51515ffd83dbSDimitry Andric NumDims == BR.size() &&
51525ffd83dbSDimitry Andric "Preallocated number of dimensions is different from the provided one.");
51535ffd83dbSDimitry Andric llvm::copy(BR, getTrailingObjects<SourceRange>());
51545ffd83dbSDimitry Andric }
51555ffd83dbSDimitry Andric
OMPArrayShapingExpr(QualType ExprTy,Expr * Op,SourceLocation L,SourceLocation R,ArrayRef<Expr * > Dims)51565ffd83dbSDimitry Andric OMPArrayShapingExpr::OMPArrayShapingExpr(QualType ExprTy, Expr *Op,
51575ffd83dbSDimitry Andric SourceLocation L, SourceLocation R,
51585ffd83dbSDimitry Andric ArrayRef<Expr *> Dims)
51595ffd83dbSDimitry Andric : Expr(OMPArrayShapingExprClass, ExprTy, VK_LValue, OK_Ordinary), LPLoc(L),
51605ffd83dbSDimitry Andric RPLoc(R), NumDims(Dims.size()) {
51615ffd83dbSDimitry Andric setBase(Op);
51625ffd83dbSDimitry Andric setDimensions(Dims);
51635ffd83dbSDimitry Andric setDependence(computeDependence(this));
51645ffd83dbSDimitry Andric }
51655ffd83dbSDimitry Andric
51665ffd83dbSDimitry Andric OMPArrayShapingExpr *
Create(const ASTContext & Context,QualType T,Expr * Op,SourceLocation L,SourceLocation R,ArrayRef<Expr * > Dims,ArrayRef<SourceRange> BracketRanges)51675ffd83dbSDimitry Andric OMPArrayShapingExpr::Create(const ASTContext &Context, QualType T, Expr *Op,
51685ffd83dbSDimitry Andric SourceLocation L, SourceLocation R,
51695ffd83dbSDimitry Andric ArrayRef<Expr *> Dims,
51705ffd83dbSDimitry Andric ArrayRef<SourceRange> BracketRanges) {
51715ffd83dbSDimitry Andric assert(Dims.size() == BracketRanges.size() &&
51725ffd83dbSDimitry Andric "Different number of dimensions and brackets ranges.");
51735ffd83dbSDimitry Andric void *Mem = Context.Allocate(
51745ffd83dbSDimitry Andric totalSizeToAlloc<Expr *, SourceRange>(Dims.size() + 1, Dims.size()),
51755ffd83dbSDimitry Andric alignof(OMPArrayShapingExpr));
51765ffd83dbSDimitry Andric auto *E = new (Mem) OMPArrayShapingExpr(T, Op, L, R, Dims);
51775ffd83dbSDimitry Andric E->setBracketsRanges(BracketRanges);
51785ffd83dbSDimitry Andric return E;
51795ffd83dbSDimitry Andric }
51805ffd83dbSDimitry Andric
CreateEmpty(const ASTContext & Context,unsigned NumDims)51815ffd83dbSDimitry Andric OMPArrayShapingExpr *OMPArrayShapingExpr::CreateEmpty(const ASTContext &Context,
51825ffd83dbSDimitry Andric unsigned NumDims) {
51835ffd83dbSDimitry Andric void *Mem = Context.Allocate(
51845ffd83dbSDimitry Andric totalSizeToAlloc<Expr *, SourceRange>(NumDims + 1, NumDims),
51855ffd83dbSDimitry Andric alignof(OMPArrayShapingExpr));
51865ffd83dbSDimitry Andric return new (Mem) OMPArrayShapingExpr(EmptyShell(), NumDims);
51875ffd83dbSDimitry Andric }
51885ffd83dbSDimitry Andric
setIteratorDeclaration(unsigned I,Decl * D)51895ffd83dbSDimitry Andric void OMPIteratorExpr::setIteratorDeclaration(unsigned I, Decl *D) {
51905ffd83dbSDimitry Andric assert(I < NumIterators &&
51915ffd83dbSDimitry Andric "Idx is greater or equal the number of iterators definitions.");
51925ffd83dbSDimitry Andric getTrailingObjects<Decl *>()[I] = D;
51935ffd83dbSDimitry Andric }
51945ffd83dbSDimitry Andric
setAssignmentLoc(unsigned I,SourceLocation Loc)51955ffd83dbSDimitry Andric void OMPIteratorExpr::setAssignmentLoc(unsigned I, SourceLocation Loc) {
51965ffd83dbSDimitry Andric assert(I < NumIterators &&
51975ffd83dbSDimitry Andric "Idx is greater or equal the number of iterators definitions.");
51985ffd83dbSDimitry Andric getTrailingObjects<
51995ffd83dbSDimitry Andric SourceLocation>()[I * static_cast<int>(RangeLocOffset::Total) +
52005ffd83dbSDimitry Andric static_cast<int>(RangeLocOffset::AssignLoc)] = Loc;
52015ffd83dbSDimitry Andric }
52025ffd83dbSDimitry Andric
setIteratorRange(unsigned I,Expr * Begin,SourceLocation ColonLoc,Expr * End,SourceLocation SecondColonLoc,Expr * Step)52035ffd83dbSDimitry Andric void OMPIteratorExpr::setIteratorRange(unsigned I, Expr *Begin,
52045ffd83dbSDimitry Andric SourceLocation ColonLoc, Expr *End,
52055ffd83dbSDimitry Andric SourceLocation SecondColonLoc,
52065ffd83dbSDimitry Andric Expr *Step) {
52075ffd83dbSDimitry Andric assert(I < NumIterators &&
52085ffd83dbSDimitry Andric "Idx is greater or equal the number of iterators definitions.");
52095ffd83dbSDimitry Andric getTrailingObjects<Expr *>()[I * static_cast<int>(RangeExprOffset::Total) +
52105ffd83dbSDimitry Andric static_cast<int>(RangeExprOffset::Begin)] =
52115ffd83dbSDimitry Andric Begin;
52125ffd83dbSDimitry Andric getTrailingObjects<Expr *>()[I * static_cast<int>(RangeExprOffset::Total) +
52135ffd83dbSDimitry Andric static_cast<int>(RangeExprOffset::End)] = End;
52145ffd83dbSDimitry Andric getTrailingObjects<Expr *>()[I * static_cast<int>(RangeExprOffset::Total) +
52155ffd83dbSDimitry Andric static_cast<int>(RangeExprOffset::Step)] = Step;
52165ffd83dbSDimitry Andric getTrailingObjects<
52175ffd83dbSDimitry Andric SourceLocation>()[I * static_cast<int>(RangeLocOffset::Total) +
52185ffd83dbSDimitry Andric static_cast<int>(RangeLocOffset::FirstColonLoc)] =
52195ffd83dbSDimitry Andric ColonLoc;
52205ffd83dbSDimitry Andric getTrailingObjects<
52215ffd83dbSDimitry Andric SourceLocation>()[I * static_cast<int>(RangeLocOffset::Total) +
52225ffd83dbSDimitry Andric static_cast<int>(RangeLocOffset::SecondColonLoc)] =
52235ffd83dbSDimitry Andric SecondColonLoc;
52245ffd83dbSDimitry Andric }
52255ffd83dbSDimitry Andric
getIteratorDecl(unsigned I)52265ffd83dbSDimitry Andric Decl *OMPIteratorExpr::getIteratorDecl(unsigned I) {
52275ffd83dbSDimitry Andric return getTrailingObjects<Decl *>()[I];
52285ffd83dbSDimitry Andric }
52295ffd83dbSDimitry Andric
getIteratorRange(unsigned I)52305ffd83dbSDimitry Andric OMPIteratorExpr::IteratorRange OMPIteratorExpr::getIteratorRange(unsigned I) {
52315ffd83dbSDimitry Andric IteratorRange Res;
52325ffd83dbSDimitry Andric Res.Begin =
52335ffd83dbSDimitry Andric getTrailingObjects<Expr *>()[I * static_cast<int>(
52345ffd83dbSDimitry Andric RangeExprOffset::Total) +
52355ffd83dbSDimitry Andric static_cast<int>(RangeExprOffset::Begin)];
52365ffd83dbSDimitry Andric Res.End =
52375ffd83dbSDimitry Andric getTrailingObjects<Expr *>()[I * static_cast<int>(
52385ffd83dbSDimitry Andric RangeExprOffset::Total) +
52395ffd83dbSDimitry Andric static_cast<int>(RangeExprOffset::End)];
52405ffd83dbSDimitry Andric Res.Step =
52415ffd83dbSDimitry Andric getTrailingObjects<Expr *>()[I * static_cast<int>(
52425ffd83dbSDimitry Andric RangeExprOffset::Total) +
52435ffd83dbSDimitry Andric static_cast<int>(RangeExprOffset::Step)];
52445ffd83dbSDimitry Andric return Res;
52455ffd83dbSDimitry Andric }
52465ffd83dbSDimitry Andric
getAssignLoc(unsigned I) const52475ffd83dbSDimitry Andric SourceLocation OMPIteratorExpr::getAssignLoc(unsigned I) const {
52485ffd83dbSDimitry Andric return getTrailingObjects<
52495ffd83dbSDimitry Andric SourceLocation>()[I * static_cast<int>(RangeLocOffset::Total) +
52505ffd83dbSDimitry Andric static_cast<int>(RangeLocOffset::AssignLoc)];
52515ffd83dbSDimitry Andric }
52525ffd83dbSDimitry Andric
getColonLoc(unsigned I) const52535ffd83dbSDimitry Andric SourceLocation OMPIteratorExpr::getColonLoc(unsigned I) const {
52545ffd83dbSDimitry Andric return getTrailingObjects<
52555ffd83dbSDimitry Andric SourceLocation>()[I * static_cast<int>(RangeLocOffset::Total) +
52565ffd83dbSDimitry Andric static_cast<int>(RangeLocOffset::FirstColonLoc)];
52575ffd83dbSDimitry Andric }
52585ffd83dbSDimitry Andric
getSecondColonLoc(unsigned I) const52595ffd83dbSDimitry Andric SourceLocation OMPIteratorExpr::getSecondColonLoc(unsigned I) const {
52605ffd83dbSDimitry Andric return getTrailingObjects<
52615ffd83dbSDimitry Andric SourceLocation>()[I * static_cast<int>(RangeLocOffset::Total) +
52625ffd83dbSDimitry Andric static_cast<int>(RangeLocOffset::SecondColonLoc)];
52635ffd83dbSDimitry Andric }
52645ffd83dbSDimitry Andric
setHelper(unsigned I,const OMPIteratorHelperData & D)52655ffd83dbSDimitry Andric void OMPIteratorExpr::setHelper(unsigned I, const OMPIteratorHelperData &D) {
52665ffd83dbSDimitry Andric getTrailingObjects<OMPIteratorHelperData>()[I] = D;
52675ffd83dbSDimitry Andric }
52685ffd83dbSDimitry Andric
getHelper(unsigned I)52695ffd83dbSDimitry Andric OMPIteratorHelperData &OMPIteratorExpr::getHelper(unsigned I) {
52705ffd83dbSDimitry Andric return getTrailingObjects<OMPIteratorHelperData>()[I];
52715ffd83dbSDimitry Andric }
52725ffd83dbSDimitry Andric
getHelper(unsigned I) const52735ffd83dbSDimitry Andric const OMPIteratorHelperData &OMPIteratorExpr::getHelper(unsigned I) const {
52745ffd83dbSDimitry Andric return getTrailingObjects<OMPIteratorHelperData>()[I];
52755ffd83dbSDimitry Andric }
52765ffd83dbSDimitry Andric
OMPIteratorExpr(QualType ExprTy,SourceLocation IteratorKwLoc,SourceLocation L,SourceLocation R,ArrayRef<OMPIteratorExpr::IteratorDefinition> Data,ArrayRef<OMPIteratorHelperData> Helpers)52775ffd83dbSDimitry Andric OMPIteratorExpr::OMPIteratorExpr(
52785ffd83dbSDimitry Andric QualType ExprTy, SourceLocation IteratorKwLoc, SourceLocation L,
52795ffd83dbSDimitry Andric SourceLocation R, ArrayRef<OMPIteratorExpr::IteratorDefinition> Data,
52805ffd83dbSDimitry Andric ArrayRef<OMPIteratorHelperData> Helpers)
52815ffd83dbSDimitry Andric : Expr(OMPIteratorExprClass, ExprTy, VK_LValue, OK_Ordinary),
52825ffd83dbSDimitry Andric IteratorKwLoc(IteratorKwLoc), LPLoc(L), RPLoc(R),
52835ffd83dbSDimitry Andric NumIterators(Data.size()) {
52845ffd83dbSDimitry Andric for (unsigned I = 0, E = Data.size(); I < E; ++I) {
52855ffd83dbSDimitry Andric const IteratorDefinition &D = Data[I];
52865ffd83dbSDimitry Andric setIteratorDeclaration(I, D.IteratorDecl);
52875ffd83dbSDimitry Andric setAssignmentLoc(I, D.AssignmentLoc);
52885ffd83dbSDimitry Andric setIteratorRange(I, D.Range.Begin, D.ColonLoc, D.Range.End,
52895ffd83dbSDimitry Andric D.SecondColonLoc, D.Range.Step);
52905ffd83dbSDimitry Andric setHelper(I, Helpers[I]);
52915ffd83dbSDimitry Andric }
52925ffd83dbSDimitry Andric setDependence(computeDependence(this));
52935ffd83dbSDimitry Andric }
52945ffd83dbSDimitry Andric
52955ffd83dbSDimitry Andric OMPIteratorExpr *
Create(const ASTContext & Context,QualType T,SourceLocation IteratorKwLoc,SourceLocation L,SourceLocation R,ArrayRef<OMPIteratorExpr::IteratorDefinition> Data,ArrayRef<OMPIteratorHelperData> Helpers)52965ffd83dbSDimitry Andric OMPIteratorExpr::Create(const ASTContext &Context, QualType T,
52975ffd83dbSDimitry Andric SourceLocation IteratorKwLoc, SourceLocation L,
52985ffd83dbSDimitry Andric SourceLocation R,
52995ffd83dbSDimitry Andric ArrayRef<OMPIteratorExpr::IteratorDefinition> Data,
53005ffd83dbSDimitry Andric ArrayRef<OMPIteratorHelperData> Helpers) {
53015ffd83dbSDimitry Andric assert(Data.size() == Helpers.size() &&
53025ffd83dbSDimitry Andric "Data and helpers must have the same size.");
53035ffd83dbSDimitry Andric void *Mem = Context.Allocate(
53045ffd83dbSDimitry Andric totalSizeToAlloc<Decl *, Expr *, SourceLocation, OMPIteratorHelperData>(
53055ffd83dbSDimitry Andric Data.size(), Data.size() * static_cast<int>(RangeExprOffset::Total),
53065ffd83dbSDimitry Andric Data.size() * static_cast<int>(RangeLocOffset::Total),
53075ffd83dbSDimitry Andric Helpers.size()),
53085ffd83dbSDimitry Andric alignof(OMPIteratorExpr));
53095ffd83dbSDimitry Andric return new (Mem) OMPIteratorExpr(T, IteratorKwLoc, L, R, Data, Helpers);
53105ffd83dbSDimitry Andric }
53115ffd83dbSDimitry Andric
CreateEmpty(const ASTContext & Context,unsigned NumIterators)53125ffd83dbSDimitry Andric OMPIteratorExpr *OMPIteratorExpr::CreateEmpty(const ASTContext &Context,
53135ffd83dbSDimitry Andric unsigned NumIterators) {
53145ffd83dbSDimitry Andric void *Mem = Context.Allocate(
53155ffd83dbSDimitry Andric totalSizeToAlloc<Decl *, Expr *, SourceLocation, OMPIteratorHelperData>(
53165ffd83dbSDimitry Andric NumIterators, NumIterators * static_cast<int>(RangeExprOffset::Total),
53175ffd83dbSDimitry Andric NumIterators * static_cast<int>(RangeLocOffset::Total), NumIterators),
53185ffd83dbSDimitry Andric alignof(OMPIteratorExpr));
53195ffd83dbSDimitry Andric return new (Mem) OMPIteratorExpr(EmptyShell(), NumIterators);
53205ffd83dbSDimitry Andric }
5321