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