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 430b57cec5SDimitry 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 680b57cec5SDimitry 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 820b57cec5SDimitry 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 136480093f4SDimitry 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 206bdd1243dSDimitry 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 * 2260eae32dcSDimitry 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> 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> 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 266*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 2770b57cec5SDimitry 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 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 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 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 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 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 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 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 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 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 4010b57cec5SDimitry 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 4130b57cec5SDimitry 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 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 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 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 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 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 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 5510b57cec5SDimitry Andric SourceLocation DeclRefExpr::getBeginLoc() const { 5520b57cec5SDimitry Andric if (hasQualifier()) 5530b57cec5SDimitry Andric return getQualifierLoc().getBeginLoc(); 5540b57cec5SDimitry Andric return getNameInfo().getBeginLoc(); 5550b57cec5SDimitry Andric } 5560b57cec5SDimitry Andric SourceLocation DeclRefExpr::getEndLoc() const { 5570b57cec5SDimitry Andric if (hasExplicitTemplateArgs()) 5580b57cec5SDimitry Andric return getRAngleLoc(); 5590b57cec5SDimitry Andric return getNameInfo().getEndLoc(); 5600b57cec5SDimitry Andric } 5610b57cec5SDimitry Andric 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 573fe6060f1SDimitry Andric SYCLUniqueStableNameExpr::SYCLUniqueStableNameExpr(EmptyShell Empty, 574fe6060f1SDimitry Andric QualType ResultTy) 575fe6060f1SDimitry Andric : Expr(SYCLUniqueStableNameExprClass, ResultTy, VK_PRValue, OK_Ordinary) {} 576fe6060f1SDimitry Andric 577fe6060f1SDimitry Andric SYCLUniqueStableNameExpr * 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 * 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 592fe6060f1SDimitry Andric std::string SYCLUniqueStableNameExpr::ComputeName(ASTContext &Context) const { 593fe6060f1SDimitry Andric return SYCLUniqueStableNameExpr::ComputeName(Context, 594fe6060f1SDimitry Andric getTypeSourceInfo()->getType()); 595fe6060f1SDimitry Andric } 596fe6060f1SDimitry Andric 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 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 6330b57cec5SDimitry Andric PredefinedExpr::PredefinedExpr(EmptyShell Empty, bool HasFunctionName) 6340b57cec5SDimitry Andric : Expr(PredefinedExprClass, Empty) { 6350b57cec5SDimitry Andric PredefinedExprBits.HasFunctionName = HasFunctionName; 6360b57cec5SDimitry Andric } 6370b57cec5SDimitry Andric 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 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 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. 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 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 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 * 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 * 9830b57cec5SDimitry Andric IntegerLiteral::Create(const ASTContext &C, EmptyShell Empty) { 9840b57cec5SDimitry Andric return new (C) IntegerLiteral(Empty); 9850b57cec5SDimitry Andric } 9860b57cec5SDimitry Andric 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 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 10075ffd83dbSDimitry Andric FixedPointLiteral *FixedPointLiteral::Create(const ASTContext &C, 10085ffd83dbSDimitry Andric EmptyShell Empty) { 10095ffd83dbSDimitry Andric return new (C) FixedPointLiteral(Empty); 10105ffd83dbSDimitry Andric } 10115ffd83dbSDimitry Andric 10120b57cec5SDimitry 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 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 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 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 * 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 * 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. 10910b57cec5SDimitry 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 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 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 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 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 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 12130b57cec5SDimitry 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 13290b57cec5SDimitry 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]++". 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 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 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 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 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 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 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 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 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 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. 15790b57cec5SDimitry Andric unsigned CallExpr::getBuiltinCallee() const { 158006c3fb27SDimitry Andric const auto *FDecl = getDirectCallee(); 15815ffd83dbSDimitry Andric return FDecl ? FDecl->getBuiltinID() : 0; 15820b57cec5SDimitry Andric } 15830b57cec5SDimitry Andric 15840b57cec5SDimitry 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 15900b57cec5SDimitry 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 16200b57cec5SDimitry 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 16380b57cec5SDimitry 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 } 16470b57cec5SDimitry 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 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 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 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 16920b57cec5SDimitry 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 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 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 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 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 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 17980b57cec5SDimitry 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 } 18120b57cec5SDimitry 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 18210b57cec5SDimitry 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 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. 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 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 20030b57cec5SDimitry 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 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 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 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 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 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 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 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 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. "<<=". 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 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 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 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 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 22530b57cec5SDimitry 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 22730b57cec5SDimitry 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 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 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 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 24030b57cec5SDimitry Andric void InitListExpr::resizeInits(const ASTContext &C, unsigned NumInits) { 24040b57cec5SDimitry Andric InitExprs.resize(C, NumInits, nullptr); 24050b57cec5SDimitry Andric } 24060b57cec5SDimitry Andric 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 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 24290b57cec5SDimitry 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 24430b57cec5SDimitry 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 24660b57cec5SDimitry 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 24770b57cec5SDimitry 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 24950b57cec5SDimitry 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 /// 25130b57cec5SDimitry 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 25190b57cec5SDimitry Andric SourceLocation BlockExpr::getCaretLocation() const { 25200b57cec5SDimitry Andric return TheBlock->getCaretLocation(); 25210b57cec5SDimitry Andric } 25220b57cec5SDimitry Andric const Stmt *BlockExpr::getBody() const { 25230b57cec5SDimitry Andric return TheBlock->getBody(); 25240b57cec5SDimitry Andric } 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 25345ffd83dbSDimitry 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. 26000b57cec5SDimitry 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. 29810b57cec5SDimitry 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 30200b57cec5SDimitry 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 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 30500b57cec5SDimitry Andric Expr *Expr::IgnoreImpCasts() { 3051e8d8bef9SDimitry Andric return IgnoreExprNodes(this, IgnoreImplicitCastsSingleStep); 30520b57cec5SDimitry Andric } 30530b57cec5SDimitry Andric 30540b57cec5SDimitry Andric Expr *Expr::IgnoreCasts() { 30550b57cec5SDimitry Andric return IgnoreExprNodes(this, IgnoreCastsSingleStep); 30560b57cec5SDimitry Andric } 30570b57cec5SDimitry Andric 30580b57cec5SDimitry Andric Expr *Expr::IgnoreImplicit() { 30590b57cec5SDimitry Andric return IgnoreExprNodes(this, IgnoreImplicitSingleStep); 30600b57cec5SDimitry Andric } 30610b57cec5SDimitry Andric 3062480093f4SDimitry Andric Expr *Expr::IgnoreImplicitAsWritten() { 3063480093f4SDimitry Andric return IgnoreExprNodes(this, IgnoreImplicitAsWrittenSingleStep); 3064480093f4SDimitry Andric } 3065480093f4SDimitry Andric 30660b57cec5SDimitry Andric Expr *Expr::IgnoreParens() { 30670b57cec5SDimitry Andric return IgnoreExprNodes(this, IgnoreParensSingleStep); 30680b57cec5SDimitry Andric } 30690b57cec5SDimitry Andric 30700b57cec5SDimitry Andric Expr *Expr::IgnoreParenImpCasts() { 30710b57cec5SDimitry Andric return IgnoreExprNodes(this, IgnoreParensSingleStep, 3072e8d8bef9SDimitry Andric IgnoreImplicitCastsExtraSingleStep); 30730b57cec5SDimitry Andric } 30740b57cec5SDimitry Andric 30750b57cec5SDimitry Andric Expr *Expr::IgnoreParenCasts() { 30760b57cec5SDimitry Andric return IgnoreExprNodes(this, IgnoreParensSingleStep, IgnoreCastsSingleStep); 30770b57cec5SDimitry Andric } 30780b57cec5SDimitry Andric 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 30870b57cec5SDimitry Andric Expr *Expr::IgnoreParenLValueCasts() { 30880b57cec5SDimitry Andric return IgnoreExprNodes(this, IgnoreParensSingleStep, 30890b57cec5SDimitry Andric IgnoreLValueCastsSingleStep); 30900b57cec5SDimitry Andric } 30910b57cec5SDimitry Andric 3092e8d8bef9SDimitry Andric Expr *Expr::IgnoreParenBaseCasts() { 30930b57cec5SDimitry Andric return IgnoreExprNodes(this, IgnoreParensSingleStep, 30940b57cec5SDimitry Andric IgnoreBaseCastsSingleStep); 30950b57cec5SDimitry Andric } 30960b57cec5SDimitry Andric 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 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 31650b57cec5SDimitry 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. 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. 32040b57cec5SDimitry 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 32460b57cec5SDimitry 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. 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 32980b57cec5SDimitry 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 35090b57cec5SDimitry 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 352181ad6265SDimitry 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: 35330b57cec5SDimitry Andric explicit SideEffectFinder(const ASTContext &Context, bool IncludePossible) 35340b57cec5SDimitry Andric : Inherited(Context), 35350b57cec5SDimitry Andric IncludePossibleEffects(IncludePossible), HasSideEffects(false) { } 35360b57cec5SDimitry Andric 35370b57cec5SDimitry Andric bool hasSideEffects() const { return HasSideEffects; } 35380b57cec5SDimitry Andric 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 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 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 35670b57cec5SDimitry 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 3864e8d8bef9SDimitry 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: 38850b57cec5SDimitry Andric explicit NonTrivialCallFinder(const ASTContext &Context) 38860b57cec5SDimitry Andric : Inherited(Context), NonTrivial(false) { } 38870b57cec5SDimitry Andric 38880b57cec5SDimitry Andric bool hasNonTrivialCall() const { return NonTrivial; } 38890b57cec5SDimitry Andric 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 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 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 39290b57cec5SDimitry 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 39410b57cec5SDimitry 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. 40650b57cec5SDimitry 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 40840b57cec5SDimitry 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 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 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 41560b57cec5SDimitry 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 41810b57cec5SDimitry 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 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. 43010b57cec5SDimitry Andric bool ExtVectorElementExpr::isArrow() const { 43020b57cec5SDimitry Andric return getBase()->getType()->isPointerType(); 43030b57cec5SDimitry Andric } 43040b57cec5SDimitry Andric 43050b57cec5SDimitry 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. 43120b57cec5SDimitry 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. 43330b57cec5SDimitry 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 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 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 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 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 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 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 44900b57cec5SDimitry Andric GenericSelectionExpr::GenericSelectionExpr(EmptyShell Empty, unsigned NumAssocs) 44910b57cec5SDimitry Andric : Expr(GenericSelectionExprClass, Empty), NumAssocs(NumAssocs) {} 44920b57cec5SDimitry Andric 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 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 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 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 * 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 456306c3fb27SDimitry 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 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 * 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 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 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 46330b57cec5SDimitry 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 46410b57cec5SDimitry 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 46580b57cec5SDimitry Andric SourceLocation DesignatedInitExpr::getEndLoc() const { 46590b57cec5SDimitry Andric return getInit()->getEndLoc(); 46600b57cec5SDimitry Andric } 46610b57cec5SDimitry Andric 46620b57cec5SDimitry 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 46670b57cec5SDimitry 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 46720b57cec5SDimitry 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). 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 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 47220b57cec5SDimitry Andric SourceLocation DesignatedInitUpdateExpr::getBeginLoc() const { 47230b57cec5SDimitry Andric return getBase()->getBeginLoc(); 47240b57cec5SDimitry Andric } 47250b57cec5SDimitry Andric 47260b57cec5SDimitry Andric SourceLocation DesignatedInitUpdateExpr::getEndLoc() const { 47270b57cec5SDimitry Andric return getBase()->getEndLoc(); 47280b57cec5SDimitry Andric } 47290b57cec5SDimitry Andric 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 47410b57cec5SDimitry Andric ParenListExpr::ParenListExpr(EmptyShell Empty, unsigned NumExprs) 47420b57cec5SDimitry Andric : Expr(ParenListExprClass, Empty) { 47430b57cec5SDimitry Andric ParenListExprBits.NumExprs = NumExprs; 47440b57cec5SDimitry Andric } 47450b57cec5SDimitry Andric 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 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 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 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 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 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 * 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 * 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 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 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 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 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 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 48930b57cec5SDimitry Andric PseudoObjectExpr::PseudoObjectExpr(EmptyShell shell, unsigned numSemanticExprs) 48940b57cec5SDimitry Andric : Expr(PseudoObjectExprClass, shell) { 48950b57cec5SDimitry Andric PseudoObjectExprBits.NumSubExprs = numSemanticExprs + 1; 48960b57cec5SDimitry Andric } 48970b57cec5SDimitry Andric 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 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 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 49530b57cec5SDimitry 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 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 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 50790b57cec5SDimitry 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 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 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 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 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 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 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 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 * 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 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 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 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 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 52265ffd83dbSDimitry Andric Decl *OMPIteratorExpr::getIteratorDecl(unsigned I) { 52275ffd83dbSDimitry Andric return getTrailingObjects<Decl *>()[I]; 52285ffd83dbSDimitry Andric } 52295ffd83dbSDimitry Andric 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 52475ffd83dbSDimitry 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 52535ffd83dbSDimitry 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 52595ffd83dbSDimitry 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 52655ffd83dbSDimitry Andric void OMPIteratorExpr::setHelper(unsigned I, const OMPIteratorHelperData &D) { 52665ffd83dbSDimitry Andric getTrailingObjects<OMPIteratorHelperData>()[I] = D; 52675ffd83dbSDimitry Andric } 52685ffd83dbSDimitry Andric 52695ffd83dbSDimitry Andric OMPIteratorHelperData &OMPIteratorExpr::getHelper(unsigned I) { 52705ffd83dbSDimitry Andric return getTrailingObjects<OMPIteratorHelperData>()[I]; 52715ffd83dbSDimitry Andric } 52725ffd83dbSDimitry Andric 52735ffd83dbSDimitry Andric const OMPIteratorHelperData &OMPIteratorExpr::getHelper(unsigned I) const { 52745ffd83dbSDimitry Andric return getTrailingObjects<OMPIteratorHelperData>()[I]; 52755ffd83dbSDimitry Andric } 52765ffd83dbSDimitry Andric 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 * 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 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