diff options
Diffstat (limited to 'contrib/llvm-project/clang/lib/AST/Expr.cpp')
-rw-r--r-- | contrib/llvm-project/clang/lib/AST/Expr.cpp | 1005 |
1 files changed, 695 insertions, 310 deletions
diff --git a/contrib/llvm-project/clang/lib/AST/Expr.cpp b/contrib/llvm-project/clang/lib/AST/Expr.cpp index adb33036a168..f1efa98e175e 100644 --- a/contrib/llvm-project/clang/lib/AST/Expr.cpp +++ b/contrib/llvm-project/clang/lib/AST/Expr.cpp @@ -31,10 +31,13 @@ #include "clang/Basic/TargetInfo.h" #include "clang/Lex/Lexer.h" #include "clang/Lex/LiteralSupport.h" +#include "clang/Lex/Preprocessor.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/Format.h" #include "llvm/Support/raw_ostream.h" #include <algorithm> #include <cstring> +#include <optional> using namespace clang; const Expr *Expr::getBestDynamicClassTypeExpr() const { @@ -111,7 +114,7 @@ const Expr *Expr::skipRValueSubobjectAdjustments( } } else if (const BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) { if (BO->getOpcode() == BO_PtrMemD) { - assert(BO->getRHS()->isRValue()); + assert(BO->getRHS()->isPRValue()); E = BO->getLHS(); const MemberPointerType *MPT = BO->getRHS()->getType()->getAs<MemberPointerType>(); @@ -201,6 +204,42 @@ bool Expr::isKnownToHaveBooleanValue(bool Semantic) const { return false; } +bool Expr::isFlexibleArrayMemberLike( + ASTContext &Ctx, + LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel, + bool IgnoreTemplateOrMacroSubstitution) const { + const Expr *E = IgnoreParens(); + const Decl *D = nullptr; + + if (const auto *ME = dyn_cast<MemberExpr>(E)) + D = ME->getMemberDecl(); + else if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) + D = DRE->getDecl(); + else if (const auto *IRE = dyn_cast<ObjCIvarRefExpr>(E)) + D = IRE->getDecl(); + + return Decl::isFlexibleArrayMemberLike(Ctx, D, E->getType(), + StrictFlexArraysLevel, + IgnoreTemplateOrMacroSubstitution); +} + +const ValueDecl * +Expr::getAsBuiltinConstantDeclRef(const ASTContext &Context) const { + Expr::EvalResult Eval; + + if (EvaluateAsConstantExpr(Eval, Context)) { + APValue &Value = Eval.Val; + + if (Value.isMemberPointer()) + return Value.getMemberPointerDecl(); + + if (Value.isLValue() && Value.getLValueOffset().isZero()) + return Value.getLValueBase().dyn_cast<const ValueDecl *>(); + } + + return nullptr; +} + // Amusing macro metaprogramming hack: check whether a class provides // a more specific implementation of getExprLoc(). // @@ -242,85 +281,86 @@ SourceLocation Expr::getExprLoc() const { // Primary Expressions. //===----------------------------------------------------------------------===// -static void AssertResultStorageKind(ConstantExpr::ResultStorageKind Kind) { - assert((Kind == ConstantExpr::RSK_APValue || - Kind == ConstantExpr::RSK_Int64 || Kind == ConstantExpr::RSK_None) && +static void AssertResultStorageKind(ConstantResultStorageKind Kind) { + assert((Kind == ConstantResultStorageKind::APValue || + Kind == ConstantResultStorageKind::Int64 || + Kind == ConstantResultStorageKind::None) && "Invalid StorageKind Value"); (void)Kind; } -ConstantExpr::ResultStorageKind -ConstantExpr::getStorageKind(const APValue &Value) { +ConstantResultStorageKind ConstantExpr::getStorageKind(const APValue &Value) { switch (Value.getKind()) { case APValue::None: case APValue::Indeterminate: - return ConstantExpr::RSK_None; + return ConstantResultStorageKind::None; case APValue::Int: if (!Value.getInt().needsCleanup()) - return ConstantExpr::RSK_Int64; - LLVM_FALLTHROUGH; + return ConstantResultStorageKind::Int64; + [[fallthrough]]; default: - return ConstantExpr::RSK_APValue; + return ConstantResultStorageKind::APValue; } } -ConstantExpr::ResultStorageKind +ConstantResultStorageKind ConstantExpr::getStorageKind(const Type *T, const ASTContext &Context) { if (T->isIntegralOrEnumerationType() && Context.getTypeInfo(T).Width <= 64) - return ConstantExpr::RSK_Int64; - return ConstantExpr::RSK_APValue; + return ConstantResultStorageKind::Int64; + return ConstantResultStorageKind::APValue; } -ConstantExpr::ConstantExpr(Expr *SubExpr, ResultStorageKind StorageKind, +ConstantExpr::ConstantExpr(Expr *SubExpr, ConstantResultStorageKind StorageKind, bool IsImmediateInvocation) : FullExpr(ConstantExprClass, SubExpr) { - ConstantExprBits.ResultKind = StorageKind; + ConstantExprBits.ResultKind = llvm::to_underlying(StorageKind); ConstantExprBits.APValueKind = APValue::None; ConstantExprBits.IsUnsigned = false; ConstantExprBits.BitWidth = 0; ConstantExprBits.HasCleanup = false; ConstantExprBits.IsImmediateInvocation = IsImmediateInvocation; - if (StorageKind == ConstantExpr::RSK_APValue) + if (StorageKind == ConstantResultStorageKind::APValue) ::new (getTrailingObjects<APValue>()) APValue(); } ConstantExpr *ConstantExpr::Create(const ASTContext &Context, Expr *E, - ResultStorageKind StorageKind, + ConstantResultStorageKind StorageKind, bool IsImmediateInvocation) { assert(!isa<ConstantExpr>(E)); AssertResultStorageKind(StorageKind); unsigned Size = totalSizeToAlloc<APValue, uint64_t>( - StorageKind == ConstantExpr::RSK_APValue, - StorageKind == ConstantExpr::RSK_Int64); + StorageKind == ConstantResultStorageKind::APValue, + StorageKind == ConstantResultStorageKind::Int64); void *Mem = Context.Allocate(Size, alignof(ConstantExpr)); return new (Mem) ConstantExpr(E, StorageKind, IsImmediateInvocation); } ConstantExpr *ConstantExpr::Create(const ASTContext &Context, Expr *E, const APValue &Result) { - ResultStorageKind StorageKind = getStorageKind(Result); + ConstantResultStorageKind StorageKind = getStorageKind(Result); ConstantExpr *Self = Create(Context, E, StorageKind); Self->SetResult(Result, Context); return Self; } -ConstantExpr::ConstantExpr(EmptyShell Empty, ResultStorageKind StorageKind) +ConstantExpr::ConstantExpr(EmptyShell Empty, + ConstantResultStorageKind StorageKind) : FullExpr(ConstantExprClass, Empty) { - ConstantExprBits.ResultKind = StorageKind; + ConstantExprBits.ResultKind = llvm::to_underlying(StorageKind); - if (StorageKind == ConstantExpr::RSK_APValue) + if (StorageKind == ConstantResultStorageKind::APValue) ::new (getTrailingObjects<APValue>()) APValue(); } ConstantExpr *ConstantExpr::CreateEmpty(const ASTContext &Context, - ResultStorageKind StorageKind) { + ConstantResultStorageKind StorageKind) { AssertResultStorageKind(StorageKind); unsigned Size = totalSizeToAlloc<APValue, uint64_t>( - StorageKind == ConstantExpr::RSK_APValue, - StorageKind == ConstantExpr::RSK_Int64); + StorageKind == ConstantResultStorageKind::APValue, + StorageKind == ConstantResultStorageKind::Int64); void *Mem = Context.Allocate(Size, alignof(ConstantExpr)); return new (Mem) ConstantExpr(EmptyShell(), StorageKind); } @@ -329,15 +369,15 @@ void ConstantExpr::MoveIntoResult(APValue &Value, const ASTContext &Context) { assert((unsigned)getStorageKind(Value) <= ConstantExprBits.ResultKind && "Invalid storage for this value kind"); ConstantExprBits.APValueKind = Value.getKind(); - switch (ConstantExprBits.ResultKind) { - case RSK_None: + switch (getResultStorageKind()) { + case ConstantResultStorageKind::None: return; - case RSK_Int64: + case ConstantResultStorageKind::Int64: Int64Result() = *Value.getInt().getRawData(); ConstantExprBits.BitWidth = Value.getInt().getBitWidth(); ConstantExprBits.IsUnsigned = Value.getInt().isUnsigned(); return; - case RSK_APValue: + case ConstantResultStorageKind::APValue: if (!ConstantExprBits.HasCleanup && Value.needsCleanup()) { ConstantExprBits.HasCleanup = true; Context.addDestruction(&APValueResult()); @@ -349,10 +389,10 @@ void ConstantExpr::MoveIntoResult(APValue &Value, const ASTContext &Context) { } llvm::APSInt ConstantExpr::getResultAsAPSInt() const { - switch (ConstantExprBits.ResultKind) { - case ConstantExpr::RSK_APValue: + switch (getResultStorageKind()) { + case ConstantResultStorageKind::APValue: return APValueResult().getInt(); - case ConstantExpr::RSK_Int64: + case ConstantResultStorageKind::Int64: return llvm::APSInt(llvm::APInt(ConstantExprBits.BitWidth, Int64Result()), ConstantExprBits.IsUnsigned); default: @@ -362,14 +402,14 @@ llvm::APSInt ConstantExpr::getResultAsAPSInt() const { APValue ConstantExpr::getAPValueResult() const { - switch (ConstantExprBits.ResultKind) { - case ConstantExpr::RSK_APValue: + switch (getResultStorageKind()) { + case ConstantResultStorageKind::APValue: return APValueResult(); - case ConstantExpr::RSK_Int64: + case ConstantResultStorageKind::Int64: return APValue( llvm::APSInt(llvm::APInt(ConstantExprBits.BitWidth, Int64Result()), ConstantExprBits.IsUnsigned)); - case ConstantExpr::RSK_None: + case ConstantResultStorageKind::None: if (ConstantExprBits.APValueKind == APValue::Indeterminate) return APValue::IndeterminateValue(); return APValue(); @@ -389,7 +429,9 @@ DeclRefExpr::DeclRefExpr(const ASTContext &Ctx, ValueDecl *D, DeclRefExprBits.HadMultipleCandidates = false; DeclRefExprBits.RefersToEnclosingVariableOrCapture = RefersToEnclosingVariableOrCapture; + DeclRefExprBits.CapturedByCopyInLambdaWithExplicitObjectParameter = false; DeclRefExprBits.NonOdrUseReason = NOUR; + DeclRefExprBits.IsImmediateEscalating = false; DeclRefExprBits.Loc = L; setDependence(computeDependence(this, Ctx)); } @@ -415,6 +457,7 @@ DeclRefExpr::DeclRefExpr(const ASTContext &Ctx, = (TemplateArgs || TemplateKWLoc.isValid()) ? 1 : 0; DeclRefExprBits.RefersToEnclosingVariableOrCapture = RefersToEnclosingVariableOrCapture; + DeclRefExprBits.CapturedByCopyInLambdaWithExplicitObjectParameter = false; DeclRefExprBits.NonOdrUseReason = NOUR; if (TemplateArgs) { auto Deps = TemplateArgumentDependence::None; @@ -427,6 +470,7 @@ DeclRefExpr::DeclRefExpr(const ASTContext &Ctx, getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom( TemplateKWLoc); } + DeclRefExprBits.IsImmediateEscalating = false; DeclRefExprBits.HadMultipleCandidates = 0; setDependence(computeDependence(this, Ctx)); } @@ -489,6 +533,8 @@ DeclRefExpr *DeclRefExpr::CreateEmpty(const ASTContext &Context, void DeclRefExpr::setDecl(ValueDecl *NewD) { D = NewD; + if (getType()->isUndeducedType()) + setType(NewD->getType()); setDependence(computeDependence(this, NewD->getASTContext())); } @@ -503,14 +549,71 @@ SourceLocation DeclRefExpr::getEndLoc() const { return getNameInfo().getEndLoc(); } -PredefinedExpr::PredefinedExpr(SourceLocation L, QualType FNTy, IdentKind IK, +SYCLUniqueStableNameExpr::SYCLUniqueStableNameExpr(SourceLocation OpLoc, + SourceLocation LParen, + SourceLocation RParen, + QualType ResultTy, + TypeSourceInfo *TSI) + : Expr(SYCLUniqueStableNameExprClass, ResultTy, VK_PRValue, OK_Ordinary), + OpLoc(OpLoc), LParen(LParen), RParen(RParen) { + setTypeSourceInfo(TSI); + setDependence(computeDependence(this)); +} + +SYCLUniqueStableNameExpr::SYCLUniqueStableNameExpr(EmptyShell Empty, + QualType ResultTy) + : Expr(SYCLUniqueStableNameExprClass, ResultTy, VK_PRValue, OK_Ordinary) {} + +SYCLUniqueStableNameExpr * +SYCLUniqueStableNameExpr::Create(const ASTContext &Ctx, SourceLocation OpLoc, + SourceLocation LParen, SourceLocation RParen, + TypeSourceInfo *TSI) { + QualType ResultTy = Ctx.getPointerType(Ctx.CharTy.withConst()); + return new (Ctx) + SYCLUniqueStableNameExpr(OpLoc, LParen, RParen, ResultTy, TSI); +} + +SYCLUniqueStableNameExpr * +SYCLUniqueStableNameExpr::CreateEmpty(const ASTContext &Ctx) { + QualType ResultTy = Ctx.getPointerType(Ctx.CharTy.withConst()); + return new (Ctx) SYCLUniqueStableNameExpr(EmptyShell(), ResultTy); +} + +std::string SYCLUniqueStableNameExpr::ComputeName(ASTContext &Context) const { + return SYCLUniqueStableNameExpr::ComputeName(Context, + getTypeSourceInfo()->getType()); +} + +std::string SYCLUniqueStableNameExpr::ComputeName(ASTContext &Context, + QualType Ty) { + auto MangleCallback = [](ASTContext &Ctx, + const NamedDecl *ND) -> std::optional<unsigned> { + if (const auto *RD = dyn_cast<CXXRecordDecl>(ND)) + return RD->getDeviceLambdaManglingNumber(); + return std::nullopt; + }; + + std::unique_ptr<MangleContext> Ctx{ItaniumMangleContext::create( + Context, Context.getDiagnostics(), MangleCallback)}; + + std::string Buffer; + Buffer.reserve(128); + llvm::raw_string_ostream Out(Buffer); + Ctx->mangleCanonicalTypeName(Ty, Out); + + return Out.str(); +} + +PredefinedExpr::PredefinedExpr(SourceLocation L, QualType FNTy, + PredefinedIdentKind IK, bool IsTransparent, StringLiteral *SL) : Expr(PredefinedExprClass, FNTy, VK_LValue, OK_Ordinary) { - PredefinedExprBits.Kind = IK; + PredefinedExprBits.Kind = llvm::to_underlying(IK); assert((getIdentKind() == IK) && "IdentKind do not fit in PredefinedExprBitfields!"); bool HasFunctionName = SL != nullptr; PredefinedExprBits.HasFunctionName = HasFunctionName; + PredefinedExprBits.IsTransparent = IsTransparent; PredefinedExprBits.Loc = L; if (HasFunctionName) setFunctionName(SL); @@ -523,12 +626,12 @@ PredefinedExpr::PredefinedExpr(EmptyShell Empty, bool HasFunctionName) } PredefinedExpr *PredefinedExpr::Create(const ASTContext &Ctx, SourceLocation L, - QualType FNTy, IdentKind IK, - StringLiteral *SL) { + QualType FNTy, PredefinedIdentKind IK, + bool IsTransparent, StringLiteral *SL) { bool HasFunctionName = SL != nullptr; void *Mem = Ctx.Allocate(totalSizeToAlloc<Stmt *>(HasFunctionName), alignof(PredefinedExpr)); - return new (Mem) PredefinedExpr(L, FNTy, IK, SL); + return new (Mem) PredefinedExpr(L, FNTy, IK, IsTransparent, SL); } PredefinedExpr *PredefinedExpr::CreateEmpty(const ASTContext &Ctx, @@ -538,23 +641,23 @@ PredefinedExpr *PredefinedExpr::CreateEmpty(const ASTContext &Ctx, return new (Mem) PredefinedExpr(EmptyShell(), HasFunctionName); } -StringRef PredefinedExpr::getIdentKindName(PredefinedExpr::IdentKind IK) { +StringRef PredefinedExpr::getIdentKindName(PredefinedIdentKind IK) { switch (IK) { - case Func: + case PredefinedIdentKind::Func: return "__func__"; - case Function: + case PredefinedIdentKind::Function: return "__FUNCTION__"; - case FuncDName: + case PredefinedIdentKind::FuncDName: return "__FUNCDNAME__"; - case LFunction: + case PredefinedIdentKind::LFunction: return "L__FUNCTION__"; - case PrettyFunction: + case PredefinedIdentKind::PrettyFunction: return "__PRETTY_FUNCTION__"; - case FuncSig: + case PredefinedIdentKind::FuncSig: return "__FUNCSIG__"; - case LFuncSig: + case PredefinedIdentKind::LFuncSig: return "L__FUNCSIG__"; - case PrettyFunctionNoVirtual: + case PredefinedIdentKind::PrettyFunctionNoVirtual: break; } llvm_unreachable("Unknown ident kind for PredefinedExpr"); @@ -562,10 +665,11 @@ StringRef PredefinedExpr::getIdentKindName(PredefinedExpr::IdentKind IK) { // FIXME: Maybe this should use DeclPrinter with a special "print predefined // expr" policy instead. -std::string PredefinedExpr::ComputeName(IdentKind IK, const Decl *CurrentDecl) { +std::string PredefinedExpr::ComputeName(PredefinedIdentKind IK, + const Decl *CurrentDecl) { ASTContext &Context = CurrentDecl->getASTContext(); - if (IK == PredefinedExpr::FuncDName) { + if (IK == PredefinedIdentKind::FuncDName) { if (const NamedDecl *ND = dyn_cast<NamedDecl>(CurrentDecl)) { std::unique_ptr<MangleContext> MC; MC.reset(Context.createMangleContext()); @@ -586,7 +690,7 @@ std::string PredefinedExpr::ComputeName(IdentKind IK, const Decl *CurrentDecl) { if (!Buffer.empty() && Buffer.front() == '\01') return std::string(Buffer.substr(1)); - return std::string(Buffer.str()); + return std::string(Buffer); } return std::string(ND->getIdentifier()->getName()); } @@ -610,21 +714,37 @@ std::string PredefinedExpr::ComputeName(IdentKind IK, const Decl *CurrentDecl) { return std::string(Out.str()); } if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CurrentDecl)) { - if (IK != PrettyFunction && IK != PrettyFunctionNoVirtual && - IK != FuncSig && IK != LFuncSig) + if (IK != PredefinedIdentKind::PrettyFunction && + IK != PredefinedIdentKind::PrettyFunctionNoVirtual && + IK != PredefinedIdentKind::FuncSig && + IK != PredefinedIdentKind::LFuncSig) return FD->getNameAsString(); SmallString<256> Name; llvm::raw_svector_ostream Out(Name); if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) { - if (MD->isVirtual() && IK != PrettyFunctionNoVirtual) + if (MD->isVirtual() && IK != PredefinedIdentKind::PrettyFunctionNoVirtual) Out << "virtual "; if (MD->isStatic()) Out << "static "; } + class PrettyCallbacks final : public PrintingCallbacks { + public: + PrettyCallbacks(const LangOptions &LO) : LO(LO) {} + std::string remapPath(StringRef Path) const override { + SmallString<128> p(Path); + LO.remapPathPrefix(p); + return std::string(p); + } + + private: + const LangOptions &LO; + }; PrintingPolicy Policy(Context.getLangOpts()); + PrettyCallbacks PrettyCB(Context.getLangOpts()); + Policy.Callbacks = &PrettyCB; std::string Proto; llvm::raw_string_ostream POut(Proto); @@ -636,7 +756,8 @@ std::string PredefinedExpr::ComputeName(IdentKind IK, const Decl *CurrentDecl) { if (FD->hasWrittenPrototype()) FT = dyn_cast<FunctionProtoType>(AFT); - if (IK == FuncSig || IK == LFuncSig) { + if (IK == PredefinedIdentKind::FuncSig || + IK == PredefinedIdentKind::LFuncSig) { switch (AFT->getCallConv()) { case CC_C: POut << "__cdecl "; break; case CC_X86StdCall: POut << "__stdcall "; break; @@ -661,7 +782,8 @@ std::string PredefinedExpr::ComputeName(IdentKind IK, const Decl *CurrentDecl) { if (FT->isVariadic()) { if (FD->getNumParams()) POut << ", "; POut << "..."; - } else if ((IK == FuncSig || IK == LFuncSig || + } else if ((IK == PredefinedIdentKind::FuncSig || + IK == PredefinedIdentKind::LFuncSig || !Context.getLangOpts().CPlusPlus) && !Decl->getNumParams()) { POut << "void"; @@ -695,17 +817,18 @@ std::string PredefinedExpr::ComputeName(IdentKind IK, const Decl *CurrentDecl) { std::string TemplateParams; llvm::raw_string_ostream TOut(TemplateParams); - for (SpecsTy::reverse_iterator I = Specs.rbegin(), E = Specs.rend(); - I != E; ++I) { - const TemplateParameterList *Params - = (*I)->getSpecializedTemplate()->getTemplateParameters(); - const TemplateArgumentList &Args = (*I)->getTemplateArgs(); + for (const ClassTemplateSpecializationDecl *D : llvm::reverse(Specs)) { + const TemplateParameterList *Params = + D->getSpecializedTemplate()->getTemplateParameters(); + const TemplateArgumentList &Args = D->getTemplateArgs(); assert(Params->size() == Args.size()); for (unsigned i = 0, numParams = Params->size(); i != numParams; ++i) { StringRef Param = Params->getParam(i)->getName(); if (Param.empty()) continue; TOut << Param << " = "; - Args.get(i).print(Policy, TOut); + Args.get(i).print(Policy, TOut, + TemplateParameterList::shouldIncludeTypeForArgument( + Policy, Params, i)); TOut << ", "; } } @@ -721,7 +844,7 @@ std::string PredefinedExpr::ComputeName(IdentKind IK, const Decl *CurrentDecl) { StringRef Param = Params->getParam(i)->getName(); if (Param.empty()) continue; TOut << Param << " = "; - Args->get(i).print(Policy, TOut); + Args->get(i).print(Policy, TOut, /*IncludeType*/ true); TOut << ", "; } } @@ -785,7 +908,8 @@ std::string PredefinedExpr::ComputeName(IdentKind IK, const Decl *CurrentDecl) { return std::string(Name); } - if (isa<TranslationUnitDecl>(CurrentDecl) && IK == PrettyFunction) { + if (isa<TranslationUnitDecl>(CurrentDecl) && + IK == PredefinedIdentKind::PrettyFunction) { // __PRETTY_FUNCTION__ -> "top level", the others produce an empty string. return "top level"; } @@ -811,7 +935,7 @@ void APNumericStorage::setIntValue(const ASTContext &C, IntegerLiteral::IntegerLiteral(const ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l) - : Expr(IntegerLiteralClass, type, VK_RValue, OK_Ordinary), Loc(l) { + : Expr(IntegerLiteralClass, type, VK_PRValue, OK_Ordinary), Loc(l) { assert(type->isIntegerType() && "Illegal type in IntegerLiteral"); assert(V.getBitWidth() == C.getIntWidth(type) && "Integer type is not the correct size for constant."); @@ -833,7 +957,7 @@ IntegerLiteral::Create(const ASTContext &C, EmptyShell Empty) { FixedPointLiteral::FixedPointLiteral(const ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l, unsigned Scale) - : Expr(FixedPointLiteralClass, type, VK_RValue, OK_Ordinary), Loc(l), + : Expr(FixedPointLiteralClass, type, VK_PRValue, OK_Ordinary), Loc(l), Scale(Scale) { assert(type->isFixedPointType() && "Illegal type in FixedPointLiteral"); assert(V.getBitWidth() == C.getTypeInfo(type).Width && @@ -862,12 +986,52 @@ std::string FixedPointLiteral::getValueAsString(unsigned Radix) const { SmallString<64> S; FixedPointValueToString( S, llvm::APSInt::getUnsigned(getValue().getZExtValue()), Scale); - return std::string(S.str()); + return std::string(S); +} + +void CharacterLiteral::print(unsigned Val, CharacterLiteralKind Kind, + raw_ostream &OS) { + switch (Kind) { + case CharacterLiteralKind::Ascii: + break; // no prefix. + case CharacterLiteralKind::Wide: + OS << 'L'; + break; + case CharacterLiteralKind::UTF8: + OS << "u8"; + break; + case CharacterLiteralKind::UTF16: + OS << 'u'; + break; + case CharacterLiteralKind::UTF32: + OS << 'U'; + break; + } + + StringRef Escaped = escapeCStyle<EscapeChar::Single>(Val); + if (!Escaped.empty()) { + OS << "'" << Escaped << "'"; + } else { + // A character literal might be sign-extended, which + // would result in an invalid \U escape sequence. + // FIXME: multicharacter literals such as '\xFF\xFF\xFF\xFF' + // are not correctly handled. + if ((Val & ~0xFFu) == ~0xFFu && Kind == CharacterLiteralKind::Ascii) + Val &= 0xFFu; + if (Val < 256 && isPrintable((unsigned char)Val)) + OS << "'" << (char)Val << "'"; + else if (Val < 256) + OS << "'\\x" << llvm::format("%02x", Val) << "'"; + else if (Val <= 0xFFFF) + OS << "'\\u" << llvm::format("%04x", Val) << "'"; + else + OS << "'\\U" << llvm::format("%08x", Val) << "'"; + } } FloatingLiteral::FloatingLiteral(const ASTContext &C, const llvm::APFloat &V, bool isexact, QualType Type, SourceLocation L) - : Expr(FloatingLiteralClass, Type, VK_RValue, OK_Ordinary), Loc(L) { + : Expr(FloatingLiteralClass, Type, VK_PRValue, OK_Ordinary), Loc(L) { setSemantics(V.getSemantics()); FloatingLiteralBits.IsExact = isexact; setValue(C, V); @@ -903,22 +1067,24 @@ double FloatingLiteral::getValueAsApproximateDouble() const { } unsigned StringLiteral::mapCharByteWidth(TargetInfo const &Target, - StringKind SK) { + StringLiteralKind SK) { unsigned CharByteWidth = 0; switch (SK) { - case Ascii: - case UTF8: + case StringLiteralKind::Ordinary: + case StringLiteralKind::UTF8: CharByteWidth = Target.getCharWidth(); break; - case Wide: + case StringLiteralKind::Wide: CharByteWidth = Target.getWCharWidth(); break; - case UTF16: + case StringLiteralKind::UTF16: CharByteWidth = Target.getChar16Width(); break; - case UTF32: + case StringLiteralKind::UTF32: CharByteWidth = Target.getChar32Width(); break; + case StringLiteralKind::Unevaluated: + return sizeof(char); // Host; } assert((CharByteWidth & 7) == 0 && "Assumes character size is byte multiple"); CharByteWidth /= 8; @@ -928,39 +1094,49 @@ unsigned StringLiteral::mapCharByteWidth(TargetInfo const &Target, } StringLiteral::StringLiteral(const ASTContext &Ctx, StringRef Str, - StringKind Kind, bool Pascal, QualType Ty, + StringLiteralKind Kind, bool Pascal, QualType Ty, const SourceLocation *Loc, unsigned NumConcatenated) : Expr(StringLiteralClass, Ty, VK_LValue, OK_Ordinary) { - assert(Ctx.getAsConstantArrayType(Ty) && - "StringLiteral must be of constant array type!"); - unsigned CharByteWidth = mapCharByteWidth(Ctx.getTargetInfo(), Kind); - unsigned ByteLength = Str.size(); - assert((ByteLength % CharByteWidth == 0) && - "The size of the data must be a multiple of CharByteWidth!"); - - // Avoid the expensive division. The compiler should be able to figure it - // out by itself. However as of clang 7, even with the appropriate - // llvm_unreachable added just here, it is not able to do so. - unsigned Length; - switch (CharByteWidth) { - case 1: - Length = ByteLength; - break; - case 2: - Length = ByteLength / 2; - break; - case 4: - Length = ByteLength / 4; - break; - default: - llvm_unreachable("Unsupported character width!"); - } - StringLiteralBits.Kind = Kind; - StringLiteralBits.CharByteWidth = CharByteWidth; - StringLiteralBits.IsPascal = Pascal; + unsigned Length = Str.size(); + + StringLiteralBits.Kind = llvm::to_underlying(Kind); StringLiteralBits.NumConcatenated = NumConcatenated; + + if (Kind != StringLiteralKind::Unevaluated) { + assert(Ctx.getAsConstantArrayType(Ty) && + "StringLiteral must be of constant array type!"); + unsigned CharByteWidth = mapCharByteWidth(Ctx.getTargetInfo(), Kind); + unsigned ByteLength = Str.size(); + assert((ByteLength % CharByteWidth == 0) && + "The size of the data must be a multiple of CharByteWidth!"); + + // Avoid the expensive division. The compiler should be able to figure it + // out by itself. However as of clang 7, even with the appropriate + // llvm_unreachable added just here, it is not able to do so. + switch (CharByteWidth) { + case 1: + Length = ByteLength; + break; + case 2: + Length = ByteLength / 2; + break; + case 4: + Length = ByteLength / 4; + break; + default: + llvm_unreachable("Unsupported character width!"); + } + + StringLiteralBits.CharByteWidth = CharByteWidth; + StringLiteralBits.IsPascal = Pascal; + } else { + assert(!Pascal && "Can't make an unevaluated Pascal string"); + StringLiteralBits.CharByteWidth = 1; + StringLiteralBits.IsPascal = false; + } + *getTrailingObjects<unsigned>() = Length; // Initialize the trailing array of SourceLocation. @@ -969,7 +1145,7 @@ StringLiteral::StringLiteral(const ASTContext &Ctx, StringRef Str, NumConcatenated * sizeof(SourceLocation)); // Initialize the trailing array of char holding the string data. - std::memcpy(getTrailingObjects<char>(), Str.data(), ByteLength); + std::memcpy(getTrailingObjects<char>(), Str.data(), Str.size()); setDependence(ExprDependence::None); } @@ -983,8 +1159,8 @@ StringLiteral::StringLiteral(EmptyShell Empty, unsigned NumConcatenated, } StringLiteral *StringLiteral::Create(const ASTContext &Ctx, StringRef Str, - StringKind Kind, bool Pascal, QualType Ty, - const SourceLocation *Loc, + StringLiteralKind Kind, bool Pascal, + QualType Ty, const SourceLocation *Loc, unsigned NumConcatenated) { void *Mem = Ctx.Allocate(totalSizeToAlloc<unsigned, SourceLocation, char>( 1, NumConcatenated, Str.size()), @@ -1006,25 +1182,36 @@ StringLiteral *StringLiteral::CreateEmpty(const ASTContext &Ctx, void StringLiteral::outputString(raw_ostream &OS) const { switch (getKind()) { - case Ascii: break; // no prefix. - case Wide: OS << 'L'; break; - case UTF8: OS << "u8"; break; - case UTF16: OS << 'u'; break; - case UTF32: OS << 'U'; break; + case StringLiteralKind::Unevaluated: + case StringLiteralKind::Ordinary: + break; // no prefix. + case StringLiteralKind::Wide: + OS << 'L'; + break; + case StringLiteralKind::UTF8: + OS << "u8"; + break; + case StringLiteralKind::UTF16: + OS << 'u'; + break; + case StringLiteralKind::UTF32: + OS << 'U'; + break; } OS << '"'; static const char Hex[] = "0123456789ABCDEF"; unsigned LastSlashX = getLength(); for (unsigned I = 0, N = getLength(); I != N; ++I) { - switch (uint32_t Char = getCodeUnit(I)) { - default: + uint32_t Char = getCodeUnit(I); + StringRef Escaped = escapeCStyle<EscapeChar::Double>(Char); + if (Escaped.empty()) { // FIXME: Convert UTF-8 back to codepoints before rendering. // Convert UTF-16 surrogate pairs back to codepoints before rendering. // Leave invalid surrogates alone; we'll use \x for those. - if (getKind() == UTF16 && I != N - 1 && Char >= 0xd800 && - Char <= 0xdbff) { + if (getKind() == StringLiteralKind::UTF16 && I != N - 1 && + Char >= 0xd800 && Char <= 0xdbff) { uint32_t Trail = getCodeUnit(I + 1); if (Trail >= 0xdc00 && Trail <= 0xdfff) { Char = 0x10000 + ((Char - 0xd800) << 10) + (Trail - 0xdc00); @@ -1036,7 +1223,7 @@ void StringLiteral::outputString(raw_ostream &OS) const { // If this is a wide string, output characters over 0xff using \x // escapes. Otherwise, this is a UTF-16 or UTF-32 string, and Char is a // codepoint: use \x escapes for invalid codepoints. - if (getKind() == Wide || + if (getKind() == StringLiteralKind::Wide || (Char >= 0xd800 && Char <= 0xdfff) || Char >= 0x110000) { // FIXME: Is this the best way to print wchar_t? OS << "\\x"; @@ -1046,7 +1233,7 @@ void StringLiteral::outputString(raw_ostream &OS) const { for (/**/; Shift >= 0; Shift -= 4) OS << Hex[(Char >> Shift) & 15]; LastSlashX = I; - break; + continue; } if (Char > 0xffff) @@ -1059,7 +1246,7 @@ void StringLiteral::outputString(raw_ostream &OS) const { << Hex[(Char >> 8) & 15] << Hex[(Char >> 4) & 15] << Hex[(Char >> 0) & 15]; - break; + continue; } // If we used \x... for the previous character, and this character is a @@ -1084,17 +1271,9 @@ void StringLiteral::outputString(raw_ostream &OS) const { << (char)('0' + ((Char >> 6) & 7)) << (char)('0' + ((Char >> 3) & 7)) << (char)('0' + ((Char >> 0) & 7)); - break; - // Handle some common non-printable cases to make dumps prettier. - case '\\': OS << "\\\\"; break; - case '"': OS << "\\\""; break; - case '\a': OS << "\\a"; break; - case '\b': OS << "\\b"; break; - case '\f': OS << "\\f"; break; - case '\n': OS << "\\n"; break; - case '\r': OS << "\\r"; break; - case '\t': OS << "\\t"; break; - case '\v': OS << "\\v"; break; + } else { + // Handle some common non-printable cases to make dumps prettier. + OS << Escaped; } } OS << '"'; @@ -1121,8 +1300,9 @@ StringLiteral::getLocationOfByte(unsigned ByteNo, const SourceManager &SM, const LangOptions &Features, const TargetInfo &Target, unsigned *StartToken, unsigned *StartTokenByteOffset) const { - assert((getKind() == StringLiteral::Ascii || - getKind() == StringLiteral::UTF8) && + assert((getKind() == StringLiteralKind::Ordinary || + getKind() == StringLiteralKind::UTF8 || + getKind() == StringLiteralKind::Unevaluated) && "Only narrow string literals are currently supported"); // Loop over all of the tokens in this string until we find the one that @@ -1135,7 +1315,7 @@ StringLiteral::getLocationOfByte(unsigned ByteNo, const SourceManager &SM, StringOffset = *StartTokenByteOffset; ByteNo -= StringOffset; } - while (1) { + while (true) { assert(TokNo < getNumConcatenated() && "Invalid byte number!"); SourceLocation StrTokLoc = getStrTokenLoc(TokNo); @@ -1261,7 +1441,7 @@ CallExpr::CallExpr(StmtClass SC, Expr *Fn, ArrayRef<Expr *> PreArgs, for (unsigned I = Args.size(); I != NumArgs; ++I) setArg(I, nullptr); - setDependence(computeDependence(this, PreArgs)); + this->computeDependence(); CallExprBits.HasFPFeatures = FPFeatures.requiresTrailingStorage(); if (hasStoredFPFeatures()) @@ -1335,19 +1515,17 @@ unsigned CallExpr::offsetToTrailingObjects(StmtClass SC) { Decl *Expr::getReferencedDeclOfCallee() { Expr *CEE = IgnoreParenImpCasts(); - while (SubstNonTypeTemplateParmExpr *NTTP = - dyn_cast<SubstNonTypeTemplateParmExpr>(CEE)) { + while (auto *NTTP = dyn_cast<SubstNonTypeTemplateParmExpr>(CEE)) CEE = NTTP->getReplacement()->IgnoreParenImpCasts(); - } // If we're calling a dereference, look at the pointer instead. while (true) { - if (BinaryOperator *BO = dyn_cast<BinaryOperator>(CEE)) { + if (auto *BO = dyn_cast<BinaryOperator>(CEE)) { if (BO->isPtrMemOp()) { CEE = BO->getRHS()->IgnoreParenImpCasts(); continue; } - } else if (UnaryOperator *UO = dyn_cast<UnaryOperator>(CEE)) { + } else if (auto *UO = dyn_cast<UnaryOperator>(CEE)) { if (UO->getOpcode() == UO_Deref || UO->getOpcode() == UO_AddrOf || UO->getOpcode() == UO_Plus) { CEE = UO->getSubExpr()->IgnoreParenImpCasts(); @@ -1357,9 +1535,9 @@ Decl *Expr::getReferencedDeclOfCallee() { break; } - if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CEE)) + if (auto *DRE = dyn_cast<DeclRefExpr>(CEE)) return DRE->getDecl(); - if (MemberExpr *ME = dyn_cast<MemberExpr>(CEE)) + if (auto *ME = dyn_cast<MemberExpr>(CEE)) return ME->getMemberDecl(); if (auto *BE = dyn_cast<BlockExpr>(CEE)) return BE->getBlockDecl(); @@ -1369,8 +1547,7 @@ Decl *Expr::getReferencedDeclOfCallee() { /// If this is a call to a builtin, return the builtin ID. If not, return 0. unsigned CallExpr::getBuiltinCallee() const { - auto *FDecl = - dyn_cast_or_null<FunctionDecl>(getCallee()->getReferencedDeclOfCallee()); + const auto *FDecl = getDirectCallee(); return FDecl ? FDecl->getBuiltinID() : 0; } @@ -1391,8 +1568,19 @@ QualType CallExpr::getCallReturnType(const ASTContext &Ctx) const { if (isa<CXXPseudoDestructorExpr>(Callee->IgnoreParens())) return Ctx.VoidTy; + if (isa<UnresolvedMemberExpr>(Callee->IgnoreParens())) + return Ctx.DependentTy; + // This should never be overloaded and so should never return null. CalleeType = Expr::findBoundMemberType(Callee); + assert(!CalleeType.isNull()); + } else if (CalleeType->isRecordType()) { + // If the Callee is a record type, then it is a not-yet-resolved + // dependent call to the call operator of that type. + return Ctx.DependentTy; + } else if (CalleeType->isDependentType() || + CalleeType->isSpecificPlaceholderType(BuiltinType::Overload)) { + return Ctx.DependentTy; } const FunctionType *FnType = CalleeType->castAs<FunctionType>(); @@ -1406,6 +1594,11 @@ const Attr *CallExpr::getUnusedResultAttr(const ASTContext &Ctx) const { if (const auto *A = TD->getAttr<WarnUnusedResultAttr>()) return A; + for (const auto *TD = getCallReturnType(Ctx)->getAs<TypedefType>(); TD; + TD = TD->desugar()->getAs<TypedefType>()) + if (const auto *A = TD->getDecl()->getAttr<WarnUnusedResultAttr>()) + return A; + // Otherwise, see if the callee is marked nodiscard and return that attribute // instead. const Decl *D = getCalleeDecl(); @@ -1413,8 +1606,8 @@ const Attr *CallExpr::getUnusedResultAttr(const ASTContext &Ctx) const { } SourceLocation CallExpr::getBeginLoc() const { - if (isa<CXXOperatorCallExpr>(this)) - return cast<CXXOperatorCallExpr>(this)->getBeginLoc(); + if (const auto *OCE = dyn_cast<CXXOperatorCallExpr>(this)) + return OCE->getBeginLoc(); SourceLocation begin = getCallee()->getBeginLoc(); if (begin.isInvalid() && getNumArgs() > 0 && getArg(0)) @@ -1422,8 +1615,8 @@ SourceLocation CallExpr::getBeginLoc() const { return begin; } SourceLocation CallExpr::getEndLoc() const { - if (isa<CXXOperatorCallExpr>(this)) - return cast<CXXOperatorCallExpr>(this)->getEndLoc(); + if (const auto *OCE = dyn_cast<CXXOperatorCallExpr>(this)) + return OCE->getEndLoc(); SourceLocation end = getRParenLoc(); if (end.isInvalid() && getNumArgs() > 0 && getArg(getNumArgs() - 1)) @@ -1455,7 +1648,7 @@ OffsetOfExpr::OffsetOfExpr(const ASTContext &C, QualType type, SourceLocation OperatorLoc, TypeSourceInfo *tsi, ArrayRef<OffsetOfNode> comps, ArrayRef<Expr *> exprs, SourceLocation RParenLoc) - : Expr(OffsetOfExprClass, type, VK_RValue, OK_Ordinary), + : Expr(OffsetOfExprClass, type, VK_PRValue, OK_Ordinary), OperatorLoc(OperatorLoc), RParenLoc(RParenLoc), TSInfo(tsi), NumComps(comps.size()), NumExprs(exprs.size()) { for (unsigned i = 0; i != comps.size(); ++i) @@ -1477,7 +1670,7 @@ IdentifierInfo *OffsetOfNode::getFieldName() const { UnaryExprOrTypeTraitExpr::UnaryExprOrTypeTraitExpr( UnaryExprOrTypeTrait ExprKind, Expr *E, QualType resultType, SourceLocation op, SourceLocation rp) - : Expr(UnaryExprOrTypeTraitExprClass, resultType, VK_RValue, OK_Ordinary), + : Expr(UnaryExprOrTypeTraitExprClass, resultType, VK_PRValue, OK_Ordinary), OpLoc(op), RParenLoc(rp) { assert(ExprKind <= UETT_Last && "invalid enum value!"); UnaryExprOrTypeTraitExprBits.Kind = ExprKind; @@ -1525,16 +1718,7 @@ MemberExpr *MemberExpr::Create( MemberExpr *E = new (Mem) MemberExpr(Base, IsArrow, OperatorLoc, MemberDecl, NameInfo, T, VK, OK, NOUR); - // FIXME: remove remaining dependence computation to computeDependence(). - auto Deps = E->getDependence(); if (HasQualOrFound) { - // FIXME: Wrong. We should be looking at the member declaration we found. - if (QualifierLoc && QualifierLoc.getNestedNameSpecifier()->isDependent()) - Deps |= ExprDependence::TypeValueInstantiation; - else if (QualifierLoc && - QualifierLoc.getNestedNameSpecifier()->isInstantiationDependent()) - Deps |= ExprDependence::Instantiation; - E->MemberExprBits.HasQualifierOrFoundDecl = true; MemberExprNameQualifier *NQ = @@ -1546,13 +1730,16 @@ MemberExpr *MemberExpr::Create( E->MemberExprBits.HasTemplateKWAndArgsInfo = TemplateArgs || TemplateKWLoc.isValid(); + // FIXME: remove remaining dependence computation to computeDependence(). + auto Deps = E->getDependence(); if (TemplateArgs) { auto TemplateArgDeps = TemplateArgumentDependence::None; E->getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom( TemplateKWLoc, *TemplateArgs, E->getTrailingObjects<TemplateArgumentLoc>(), TemplateArgDeps); - if (TemplateArgDeps & TemplateArgumentDependence::Instantiation) - Deps |= ExprDependence::Instantiation; + for (const TemplateArgumentLoc &ArgLoc : TemplateArgs->arguments()) { + Deps |= toExprDependence(ArgLoc.getArgument().getDependence()); + } } else if (TemplateKWLoc.isValid()) { E->getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom( TemplateKWLoc); @@ -1578,8 +1765,10 @@ MemberExpr *MemberExpr::CreateEmpty(const ASTContext &Context, return new (Mem) MemberExpr(EmptyShell()); } -void MemberExpr::setMemberDecl(ValueDecl *D) { - MemberDecl = D; +void MemberExpr::setMemberDecl(ValueDecl *NewD) { + MemberDecl = NewD; + if (getType()->isUndeducedType()) + setType(NewD->getType()); setDependence(computeDependence(this)); } @@ -1663,7 +1852,7 @@ bool CastExpr::CastConsistency() const { auto Ty = getType(); auto SETy = getSubExpr()->getType(); assert(getValueKindForType(Ty) == Expr::getValueKindForType(SETy)); - if (isRValue() && !Ty->isDependentType() && !SETy->isDependentType()) { + if (isPRValue() && !Ty->isDependentType() && !SETy->isDependentType()) { Ty = Ty->getPointeeType(); SETy = SETy->getPointeeType(); } @@ -1708,6 +1897,7 @@ bool CastExpr::CastConsistency() const { case CK_FixedPointCast: case CK_FixedPointToIntegral: case CK_IntegralToFixedPoint: + case CK_MatrixCast: assert(!getType()->isBooleanType() && "unheralded conversion to bool"); goto CheckNoBasePath; @@ -1743,50 +1933,53 @@ const char *CastExpr::getCastKindName(CastKind CK) { } namespace { - const Expr *skipImplicitTemporary(const Expr *E) { - // Skip through reference binding to temporary. - if (auto *Materialize = dyn_cast<MaterializeTemporaryExpr>(E)) - E = Materialize->getSubExpr(); +// Skip over implicit nodes produced as part of semantic analysis. +// Designed for use with IgnoreExprNodes. +static Expr *ignoreImplicitSemaNodes(Expr *E) { + if (auto *Materialize = dyn_cast<MaterializeTemporaryExpr>(E)) + return Materialize->getSubExpr(); - // Skip any temporary bindings; they're implicit. - if (auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) - E = Binder->getSubExpr(); + if (auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) + return Binder->getSubExpr(); - return E; - } + if (auto *Full = dyn_cast<FullExpr>(E)) + return Full->getSubExpr(); + + if (auto *CPLIE = dyn_cast<CXXParenListInitExpr>(E); + CPLIE && CPLIE->getInitExprs().size() == 1) + return CPLIE->getInitExprs()[0]; + + return E; } +} // namespace Expr *CastExpr::getSubExprAsWritten() { const Expr *SubExpr = nullptr; - const CastExpr *E = this; - do { - SubExpr = skipImplicitTemporary(E->getSubExpr()); + + for (const CastExpr *E = this; E; E = dyn_cast<ImplicitCastExpr>(SubExpr)) { + SubExpr = IgnoreExprNodes(E->getSubExpr(), ignoreImplicitSemaNodes); // Conversions by constructor and conversion functions have a // subexpression describing the call; strip it off. - if (E->getCastKind() == CK_ConstructorConversion) - SubExpr = - skipImplicitTemporary(cast<CXXConstructExpr>(SubExpr->IgnoreImplicit())->getArg(0)); - else if (E->getCastKind() == CK_UserDefinedConversion) { - assert((isa<CXXMemberCallExpr>(SubExpr) || - isa<BlockExpr>(SubExpr)) && + if (E->getCastKind() == CK_ConstructorConversion) { + SubExpr = IgnoreExprNodes(cast<CXXConstructExpr>(SubExpr)->getArg(0), + ignoreImplicitSemaNodes); + } else if (E->getCastKind() == CK_UserDefinedConversion) { + assert((isa<CXXMemberCallExpr>(SubExpr) || isa<BlockExpr>(SubExpr)) && "Unexpected SubExpr for CK_UserDefinedConversion."); if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SubExpr)) SubExpr = MCE->getImplicitObjectArgument(); } + } - // If the subexpression we're left with is an implicit cast, look - // through that, too. - } while ((E = dyn_cast<ImplicitCastExpr>(SubExpr))); - - return const_cast<Expr*>(SubExpr); + return const_cast<Expr *>(SubExpr); } NamedDecl *CastExpr::getConversionFunction() const { const Expr *SubExpr = nullptr; for (const CastExpr *E = this; E; E = dyn_cast<ImplicitCastExpr>(SubExpr)) { - SubExpr = skipImplicitTemporary(E->getSubExpr()); + SubExpr = IgnoreExprNodes(E->getSubExpr(), ignoreImplicitSemaNodes); if (E->getCastKind() == CK_ConstructorConversion) return cast<CXXConstructExpr>(SubExpr)->getConstructor(); @@ -1987,12 +2180,13 @@ OverloadedOperatorKind BinaryOperator::getOverloadedOperator(Opcode Opc) { bool BinaryOperator::isNullPointerArithmeticExtension(ASTContext &Ctx, Opcode Opc, - Expr *LHS, Expr *RHS) { + const Expr *LHS, + const Expr *RHS) { if (Opc != BO_Add) return false; // Check that we have one pointer and one integer operand. - Expr *PExp; + const Expr *PExp; if (LHS->getType()->isPointerType()) { if (!RHS->getType()->isIntegerType()) return false; @@ -2018,41 +2212,35 @@ bool BinaryOperator::isNullPointerArithmeticExtension(ASTContext &Ctx, return true; } -static QualType getDecayedSourceLocExprType(const ASTContext &Ctx, - SourceLocExpr::IdentKind Kind) { - switch (Kind) { - case SourceLocExpr::File: - case SourceLocExpr::Function: { - QualType ArrTy = Ctx.getStringLiteralArrayType(Ctx.CharTy, 0); - return Ctx.getPointerType(ArrTy->getAsArrayTypeUnsafe()->getElementType()); - } - case SourceLocExpr::Line: - case SourceLocExpr::Column: - return Ctx.UnsignedIntTy; - } - llvm_unreachable("unhandled case"); -} - -SourceLocExpr::SourceLocExpr(const ASTContext &Ctx, IdentKind Kind, - SourceLocation BLoc, SourceLocation RParenLoc, +SourceLocExpr::SourceLocExpr(const ASTContext &Ctx, SourceLocIdentKind Kind, + QualType ResultTy, SourceLocation BLoc, + SourceLocation RParenLoc, DeclContext *ParentContext) - : Expr(SourceLocExprClass, getDecayedSourceLocExprType(Ctx, Kind), - VK_RValue, OK_Ordinary), + : Expr(SourceLocExprClass, ResultTy, VK_PRValue, OK_Ordinary), BuiltinLoc(BLoc), RParenLoc(RParenLoc), ParentContext(ParentContext) { - SourceLocExprBits.Kind = Kind; - setDependence(ExprDependence::None); + SourceLocExprBits.Kind = llvm::to_underlying(Kind); + // In dependent contexts, function names may change. + setDependence(MayBeDependent(Kind) && ParentContext->isDependentContext() + ? ExprDependence::Value + : ExprDependence::None); } StringRef SourceLocExpr::getBuiltinStr() const { switch (getIdentKind()) { - case File: + case SourceLocIdentKind::File: return "__builtin_FILE"; - case Function: + case SourceLocIdentKind::FileName: + return "__builtin_FILE_NAME"; + case SourceLocIdentKind::Function: return "__builtin_FUNCTION"; - case Line: + case SourceLocIdentKind::FuncSig: + return "__builtin_FUNCSIG"; + case SourceLocIdentKind::Line: return "__builtin_LINE"; - case Column: + case SourceLocIdentKind::Column: return "__builtin_COLUMN"; + case SourceLocIdentKind::SourceLocStruct: + return "__builtin_source_location"; } llvm_unreachable("unexpected IdentKind!"); } @@ -2062,14 +2250,17 @@ APValue SourceLocExpr::EvaluateInContext(const ASTContext &Ctx, SourceLocation Loc; const DeclContext *Context; - std::tie(Loc, - Context) = [&]() -> std::pair<SourceLocation, const DeclContext *> { - if (auto *DIE = dyn_cast_or_null<CXXDefaultInitExpr>(DefaultExpr)) - return {DIE->getUsedLocation(), DIE->getUsedContext()}; - if (auto *DAE = dyn_cast_or_null<CXXDefaultArgExpr>(DefaultExpr)) - return {DAE->getUsedLocation(), DAE->getUsedContext()}; - return {this->getLocation(), this->getParentContext()}; - }(); + if (const auto *DIE = dyn_cast_if_present<CXXDefaultInitExpr>(DefaultExpr)) { + Loc = DIE->getUsedLocation(); + Context = DIE->getUsedContext(); + } else if (const auto *DAE = + dyn_cast_if_present<CXXDefaultArgExpr>(DefaultExpr)) { + Loc = DAE->getUsedLocation(); + Context = DAE->getUsedContext(); + } else { + Loc = getLocation(); + Context = getParentContext(); + } PresumedLoc PLoc = Ctx.getSourceManager().getPresumedLoc( Ctx.getSourceManager().getExpansionRange(Loc).getEnd()); @@ -2083,21 +2274,75 @@ APValue SourceLocExpr::EvaluateInContext(const ASTContext &Ctx, }; switch (getIdentKind()) { - case SourceLocExpr::File: - return MakeStringLiteral(PLoc.getFilename()); - case SourceLocExpr::Function: { - const Decl *CurDecl = dyn_cast_or_null<Decl>(Context); + case SourceLocIdentKind::FileName: { + // __builtin_FILE_NAME() is a Clang-specific extension that expands to the + // the last part of __builtin_FILE(). + SmallString<256> FileName; + clang::Preprocessor::processPathToFileName( + FileName, PLoc, Ctx.getLangOpts(), Ctx.getTargetInfo()); + return MakeStringLiteral(FileName); + } + case SourceLocIdentKind::File: { + SmallString<256> Path(PLoc.getFilename()); + clang::Preprocessor::processPathForFileMacro(Path, Ctx.getLangOpts(), + Ctx.getTargetInfo()); + return MakeStringLiteral(Path); + } + case SourceLocIdentKind::Function: + case SourceLocIdentKind::FuncSig: { + const auto *CurDecl = dyn_cast<Decl>(Context); + const auto Kind = getIdentKind() == SourceLocIdentKind::Function + ? PredefinedIdentKind::Function + : PredefinedIdentKind::FuncSig; return MakeStringLiteral( - CurDecl ? PredefinedExpr::ComputeName(PredefinedExpr::Function, CurDecl) - : std::string("")); + CurDecl ? PredefinedExpr::ComputeName(Kind, CurDecl) : std::string("")); } - case SourceLocExpr::Line: - case SourceLocExpr::Column: { - llvm::APSInt IntVal(Ctx.getIntWidth(Ctx.UnsignedIntTy), - /*isUnsigned=*/true); - IntVal = getIdentKind() == SourceLocExpr::Line ? PLoc.getLine() - : PLoc.getColumn(); - return APValue(IntVal); + case SourceLocIdentKind::Line: + return APValue(Ctx.MakeIntValue(PLoc.getLine(), Ctx.UnsignedIntTy)); + case SourceLocIdentKind::Column: + return APValue(Ctx.MakeIntValue(PLoc.getColumn(), Ctx.UnsignedIntTy)); + case SourceLocIdentKind::SourceLocStruct: { + // Fill in a std::source_location::__impl structure, by creating an + // artificial file-scoped CompoundLiteralExpr, and returning a pointer to + // that. + const CXXRecordDecl *ImplDecl = getType()->getPointeeCXXRecordDecl(); + assert(ImplDecl); + + // Construct an APValue for the __impl struct, and get or create a Decl + // corresponding to that. Note that we've already verified that the shape of + // the ImplDecl type is as expected. + + APValue Value(APValue::UninitStruct(), 0, 4); + for (const FieldDecl *F : ImplDecl->fields()) { + StringRef Name = F->getName(); + if (Name == "_M_file_name") { + SmallString<256> Path(PLoc.getFilename()); + clang::Preprocessor::processPathForFileMacro(Path, Ctx.getLangOpts(), + Ctx.getTargetInfo()); + Value.getStructField(F->getFieldIndex()) = MakeStringLiteral(Path); + } else if (Name == "_M_function_name") { + // Note: this emits the PrettyFunction name -- different than what + // __builtin_FUNCTION() above returns! + const auto *CurDecl = dyn_cast<Decl>(Context); + Value.getStructField(F->getFieldIndex()) = MakeStringLiteral( + CurDecl && !isa<TranslationUnitDecl>(CurDecl) + ? StringRef(PredefinedExpr::ComputeName( + PredefinedIdentKind::PrettyFunction, CurDecl)) + : ""); + } else if (Name == "_M_line") { + llvm::APSInt IntVal = Ctx.MakeIntValue(PLoc.getLine(), F->getType()); + Value.getStructField(F->getFieldIndex()) = APValue(IntVal); + } else if (Name == "_M_column") { + llvm::APSInt IntVal = Ctx.MakeIntValue(PLoc.getColumn(), F->getType()); + Value.getStructField(F->getFieldIndex()) = APValue(IntVal); + } + } + + UnnamedGlobalConstantDecl *GV = + Ctx.getUnnamedGlobalConstantDecl(getType()->getPointeeType(), Value); + + return APValue(GV, CharUnits::Zero(), ArrayRef<APValue::LValuePathEntry>{}, + false); } } llvm_unreachable("unhandled case"); @@ -2105,7 +2350,7 @@ APValue SourceLocExpr::EvaluateInContext(const ASTContext &Ctx, InitListExpr::InitListExpr(const ASTContext &C, SourceLocation lbraceloc, ArrayRef<Expr *> initExprs, SourceLocation rbraceloc) - : Expr(InitListExprClass, QualType(), VK_RValue, OK_Ordinary), + : Expr(InitListExprClass, QualType(), VK_PRValue, OK_Ordinary), InitExprs(C, initExprs.size()), LBraceLoc(lbraceloc), RBraceLoc(rbraceloc), AltForm(nullptr, true) { sawArrayRangeDesignator(false); @@ -2155,7 +2400,7 @@ bool InitListExpr::isStringLiteralInit() const { const Expr *Init = getInit(0); if (!Init) return false; - Init = Init->IgnoreParens(); + Init = Init->IgnoreParenImpCasts(); return isa<StringLiteral>(Init) || isa<ObjCEncodeExpr>(Init); } @@ -2175,7 +2420,7 @@ bool InitListExpr::isTransparent() const { // Don't confuse aggregate initialization of a struct X { X &x; }; with a // transparent struct copy. - if (!getInit(0)->isRValue() && getType()->isRecordType()) + if (!getInit(0)->isPRValue() && getType()->isRecordType()) return false; return getType().getCanonicalType() == @@ -2217,10 +2462,8 @@ SourceLocation InitListExpr::getEndLoc() const { SourceLocation End = RBraceLoc; if (End.isInvalid()) { // Find the first non-null initializer from the end. - for (InitExprsTy::const_reverse_iterator I = InitExprs.rbegin(), - E = InitExprs.rend(); - I != E; ++I) { - if (Stmt *S = *I) { + for (Stmt *S : llvm::reverse(InitExprs)) { + if (S) { End = S->getEndLoc(); break; } @@ -2256,7 +2499,7 @@ bool Expr::isReadIfDiscardedInCPlusPlus11() const { // In C++11, discarded-value expressions of a certain form are special, // according to [expr]p10: // The lvalue-to-rvalue conversion (4.1) is applied only if the - // expression is an lvalue of volatile-qualified type and it has + // expression is a glvalue of volatile-qualified type and it has // one of the following forms: if (!isGLValue() || !getType().isVolatileQualified()) return false; @@ -2304,8 +2547,12 @@ bool Expr::isReadIfDiscardedInCPlusPlus11() const { } // Objective-C++ extensions to the rule. - if (isa<PseudoObjectExpr>(E) || isa<ObjCIvarRefExpr>(E)) + if (isa<ObjCIvarRefExpr>(E)) return true; + if (const auto *POE = dyn_cast<PseudoObjectExpr>(E)) { + if (isa<ObjCPropertyRefExpr, ObjCSubscriptRefExpr>(POE->getSyntacticForm())) + return true; + } return false; } @@ -2467,7 +2714,7 @@ bool Expr::isUnusedResultAWarning(const Expr *&WarnE, SourceLocation &Loc, } // Fallthrough for generic call handling. - LLVM_FALLTHROUGH; + [[fallthrough]]; } case CallExprClass: case CXXMemberCallExprClass: @@ -2555,23 +2802,35 @@ bool Expr::isUnusedResultAWarning(const Expr *&WarnE, SourceLocation &Loc, } case ObjCPropertyRefExprClass: + case ObjCSubscriptRefExprClass: WarnE = this; Loc = getExprLoc(); R1 = getSourceRange(); return true; case PseudoObjectExprClass: { - const PseudoObjectExpr *PO = cast<PseudoObjectExpr>(this); + const auto *POE = cast<PseudoObjectExpr>(this); - // Only complain about things that have the form of a getter. - if (isa<UnaryOperator>(PO->getSyntacticForm()) || - isa<BinaryOperator>(PO->getSyntacticForm())) - return false; + // For some syntactic forms, we should always warn. + if (isa<ObjCPropertyRefExpr, ObjCSubscriptRefExpr>( + POE->getSyntacticForm())) { + WarnE = this; + Loc = getExprLoc(); + R1 = getSourceRange(); + return true; + } - WarnE = this; - Loc = getExprLoc(); - R1 = getSourceRange(); - return true; + // For others, we should never warn. + if (auto *BO = dyn_cast<BinaryOperator>(POE->getSyntacticForm())) + if (BO->isAssignmentOp()) + return false; + if (auto *UO = dyn_cast<UnaryOperator>(POE->getSyntacticForm())) + if (UO->isIncrementDecrementOp()) + return false; + + // Otherwise, warn if the result expression would warn. + const Expr *Result = POE->getResultExpr(); + return Result && Result->isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx); } case StmtExprClass: { @@ -3015,6 +3274,10 @@ bool Expr::isConstantInitializer(ASTContext &Ctx, bool IsForRef, // kill the second parameter. if (IsForRef) { + if (auto *EWC = dyn_cast<ExprWithCleanups>(this)) + return EWC->getSubExpr()->isConstantInitializer(Ctx, true, Culprit); + if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(this)) + return MTE->getSubExpr()->isConstantInitializer(Ctx, false, Culprit); EvalResult Result; if (EvaluateAsLValue(Result, Ctx) && !Result.HasSideEffects) return true; @@ -3152,6 +3415,7 @@ bool Expr::isConstantInitializer(ASTContext &Ctx, bool IsForRef, CE->getCastKind() == CK_ConstructorConversion || CE->getCastKind() == CK_NonAtomicToAtomic || CE->getCastKind() == CK_AtomicToNonAtomic || + CE->getCastKind() == CK_NullToPointer || CE->getCastKind() == CK_IntToOCLSampler) return CE->getSubExpr()->isConstantInitializer(Ctx, false, Culprit); @@ -3183,9 +3447,9 @@ bool Expr::isConstantInitializer(ASTContext &Ctx, bool IsForRef, } bool CallExpr::isBuiltinAssumeFalse(const ASTContext &Ctx) const { - const FunctionDecl* FD = getDirectCallee(); - if (!FD || (FD->getBuiltinID() != Builtin::BI__assume && - FD->getBuiltinID() != Builtin::BI__builtin_assume)) + unsigned BuiltinID = getBuiltinCallee(); + if (BuiltinID != Builtin::BI__assume && + BuiltinID != Builtin::BI__builtin_assume) return false; const Expr* Arg = getArg(0); @@ -3194,6 +3458,10 @@ bool CallExpr::isBuiltinAssumeFalse(const ASTContext &Ctx) const { Arg->EvaluateAsBooleanCondition(ArgVal, Ctx) && !ArgVal; } +bool CallExpr::isCallToStdMove() const { + return getBuiltinCallee() == Builtin::BImove; +} + namespace { /// Look for any side effects within a Stmt. class SideEffectFinder : public ConstEvaluatedExprVisitor<SideEffectFinder> { @@ -3300,6 +3568,7 @@ bool Expr::HasSideEffects(const ASTContext &Ctx, case SourceLocExprClass: case ConceptSpecializationExprClass: case RequiresExprClass: + case SYCLUniqueStableNameExprClass: // These never have a side-effect. return false; @@ -3379,6 +3648,7 @@ bool Expr::HasSideEffects(const ASTContext &Ctx, case ShuffleVectorExprClass: case ConvertVectorExprClass: case AsTypeExprClass: + case CXXParenListInitExprClass: // These have a side-effect if any subexpression does. break; @@ -3426,7 +3696,7 @@ bool Expr::HasSideEffects(const ASTContext &Ctx, DCE->getCastKind() == CK_Dynamic) return true; } - LLVM_FALLTHROUGH; + [[fallthrough]]; case ImplicitCastExprClass: case CStyleCastExprClass: case CXXStaticCastExprClass: @@ -3625,11 +3895,8 @@ Expr::isNullPointerConstant(ASTContext &Ctx, // has non-default address space it is not treated as nullptr. // (__generic void*)0 in OpenCL 2.0 should not be treated as nullptr // since it cannot be assigned to a pointer to constant address space. - if ((Ctx.getLangOpts().OpenCLVersion >= 200 && - Pointee.getAddressSpace() == LangAS::opencl_generic) || - (Ctx.getLangOpts().OpenCL && - Ctx.getLangOpts().OpenCLVersion < 200 && - Pointee.getAddressSpace() == LangAS::opencl_private)) + if (Ctx.getLangOpts().OpenCL && + Pointee.getAddressSpace() == Ctx.getDefaultOpenCLPointeeAddrSpace()) Qs.removeAddressSpace(); if (Pointee->isVoidType() && Qs.empty() && // to void* @@ -3677,7 +3944,7 @@ Expr::isNullPointerConstant(ASTContext &Ctx, if (getType().isNull()) return NPCK_NotNull; - // C++11 nullptr_t is always a null pointer constant. + // C++11/C23 nullptr_t is always a null pointer constant. if (getType()->isNullPtrType()) return NPCK_CXX11_nullptr; @@ -3723,8 +3990,7 @@ Expr::isNullPointerConstant(ASTContext &Ctx, const ObjCPropertyRefExpr *Expr::getObjCProperty() const { const Expr *E = this; while (true) { - assert((E->getValueKind() == VK_LValue && - E->getObjectKind() == OK_ObjCProperty) && + assert((E->isLValue() && E->getObjectKind() == OK_ObjCProperty) && "expression is not a property reference"); E = E->IgnoreParenCasts(); if (const BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) { @@ -3763,7 +4029,7 @@ FieldDecl *Expr::getSourceBitField() { while (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) { if (ICE->getCastKind() == CK_LValueToRValue || - (ICE->getValueKind() != VK_RValue && ICE->getCastKind() == CK_NoOp)) + (ICE->isGLValue() && ICE->getCastKind() == CK_NoOp)) E = ICE->getSubExpr()->IgnoreParens(); else break; @@ -3810,8 +4076,7 @@ bool Expr::refersToVectorElement() const { const Expr *E = this->IgnoreParens(); while (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) { - if (ICE->getValueKind() != VK_RValue && - ICE->getCastKind() == CK_NoOp) + if (ICE->isGLValue() && ICE->getCastKind() == CK_NoOp) E = ICE->getSubExpr()->IgnoreParens(); else break; @@ -3860,7 +4125,7 @@ bool Expr::isSameComparisonOperand(const Expr* E1, const Expr* E2) { // template parameters. const auto *DRE1 = cast<DeclRefExpr>(E1); const auto *DRE2 = cast<DeclRefExpr>(E2); - return DRE1->isRValue() && DRE2->isRValue() && + return DRE1->isPRValue() && DRE2->isPRValue() && DRE1->getDecl() == DRE2->getDecl(); } case ImplicitCastExprClass: { @@ -3976,7 +4241,7 @@ bool ExtVectorElementExpr::containsDuplicateElements() const { Comp = Comp.substr(1); for (unsigned i = 0, e = Comp.size(); i != e; ++i) - if (Comp.substr(i + 1).find(Comp[i]) != StringRef::npos) + if (Comp.substr(i + 1).contains(Comp[i])) return true; return false; @@ -4018,7 +4283,7 @@ void ExtVectorElementExpr::getEncodedElementAccess( ShuffleVectorExpr::ShuffleVectorExpr(const ASTContext &C, ArrayRef<Expr *> args, QualType Type, SourceLocation BLoc, SourceLocation RP) - : Expr(ShuffleVectorExprClass, Type, VK_RValue, OK_Ordinary), + : Expr(ShuffleVectorExprClass, Type, VK_PRValue, OK_Ordinary), BuiltinLoc(BLoc), RParenLoc(RP), NumExprs(args.size()) { SubExprs = new (C) Stmt*[args.size()]; for (unsigned i = 0; i != args.size(); i++) @@ -4044,18 +4309,48 @@ GenericSelectionExpr::GenericSelectionExpr( AssocExprs[ResultIndex]->getValueKind(), AssocExprs[ResultIndex]->getObjectKind()), NumAssocs(AssocExprs.size()), ResultIndex(ResultIndex), - DefaultLoc(DefaultLoc), RParenLoc(RParenLoc) { + IsExprPredicate(true), DefaultLoc(DefaultLoc), RParenLoc(RParenLoc) { assert(AssocTypes.size() == AssocExprs.size() && "Must have the same number of association expressions" " and TypeSourceInfo!"); assert(ResultIndex < NumAssocs && "ResultIndex is out-of-bounds!"); GenericSelectionExprBits.GenericLoc = GenericLoc; - getTrailingObjects<Stmt *>()[ControllingIndex] = ControllingExpr; + getTrailingObjects<Stmt *>()[getIndexOfControllingExpression()] = + ControllingExpr; std::copy(AssocExprs.begin(), AssocExprs.end(), - getTrailingObjects<Stmt *>() + AssocExprStartIndex); + getTrailingObjects<Stmt *>() + getIndexOfStartOfAssociatedExprs()); std::copy(AssocTypes.begin(), AssocTypes.end(), - getTrailingObjects<TypeSourceInfo *>()); + getTrailingObjects<TypeSourceInfo *>() + + getIndexOfStartOfAssociatedTypes()); + + setDependence(computeDependence(this, ContainsUnexpandedParameterPack)); +} + +GenericSelectionExpr::GenericSelectionExpr( + const ASTContext &, SourceLocation GenericLoc, + TypeSourceInfo *ControllingType, ArrayRef<TypeSourceInfo *> AssocTypes, + ArrayRef<Expr *> AssocExprs, SourceLocation DefaultLoc, + SourceLocation RParenLoc, bool ContainsUnexpandedParameterPack, + unsigned ResultIndex) + : Expr(GenericSelectionExprClass, AssocExprs[ResultIndex]->getType(), + AssocExprs[ResultIndex]->getValueKind(), + AssocExprs[ResultIndex]->getObjectKind()), + NumAssocs(AssocExprs.size()), ResultIndex(ResultIndex), + IsExprPredicate(false), DefaultLoc(DefaultLoc), RParenLoc(RParenLoc) { + assert(AssocTypes.size() == AssocExprs.size() && + "Must have the same number of association expressions" + " and TypeSourceInfo!"); + assert(ResultIndex < NumAssocs && "ResultIndex is out-of-bounds!"); + + GenericSelectionExprBits.GenericLoc = GenericLoc; + getTrailingObjects<TypeSourceInfo *>()[getIndexOfControllingType()] = + ControllingType; + std::copy(AssocExprs.begin(), AssocExprs.end(), + getTrailingObjects<Stmt *>() + getIndexOfStartOfAssociatedExprs()); + std::copy(AssocTypes.begin(), AssocTypes.end(), + getTrailingObjects<TypeSourceInfo *>() + + getIndexOfStartOfAssociatedTypes()); setDependence(computeDependence(this, ContainsUnexpandedParameterPack)); } @@ -4065,20 +4360,47 @@ GenericSelectionExpr::GenericSelectionExpr( ArrayRef<TypeSourceInfo *> AssocTypes, ArrayRef<Expr *> AssocExprs, SourceLocation DefaultLoc, SourceLocation RParenLoc, bool ContainsUnexpandedParameterPack) - : Expr(GenericSelectionExprClass, Context.DependentTy, VK_RValue, + : Expr(GenericSelectionExprClass, Context.DependentTy, VK_PRValue, OK_Ordinary), NumAssocs(AssocExprs.size()), ResultIndex(ResultDependentIndex), - DefaultLoc(DefaultLoc), RParenLoc(RParenLoc) { + IsExprPredicate(true), DefaultLoc(DefaultLoc), RParenLoc(RParenLoc) { assert(AssocTypes.size() == AssocExprs.size() && "Must have the same number of association expressions" " and TypeSourceInfo!"); GenericSelectionExprBits.GenericLoc = GenericLoc; - getTrailingObjects<Stmt *>()[ControllingIndex] = ControllingExpr; + getTrailingObjects<Stmt *>()[getIndexOfControllingExpression()] = + ControllingExpr; std::copy(AssocExprs.begin(), AssocExprs.end(), - getTrailingObjects<Stmt *>() + AssocExprStartIndex); + getTrailingObjects<Stmt *>() + getIndexOfStartOfAssociatedExprs()); std::copy(AssocTypes.begin(), AssocTypes.end(), - getTrailingObjects<TypeSourceInfo *>()); + getTrailingObjects<TypeSourceInfo *>() + + getIndexOfStartOfAssociatedTypes()); + + setDependence(computeDependence(this, ContainsUnexpandedParameterPack)); +} + +GenericSelectionExpr::GenericSelectionExpr( + const ASTContext &Context, SourceLocation GenericLoc, + TypeSourceInfo *ControllingType, ArrayRef<TypeSourceInfo *> AssocTypes, + ArrayRef<Expr *> AssocExprs, SourceLocation DefaultLoc, + SourceLocation RParenLoc, bool ContainsUnexpandedParameterPack) + : Expr(GenericSelectionExprClass, Context.DependentTy, VK_PRValue, + OK_Ordinary), + NumAssocs(AssocExprs.size()), ResultIndex(ResultDependentIndex), + IsExprPredicate(false), DefaultLoc(DefaultLoc), RParenLoc(RParenLoc) { + assert(AssocTypes.size() == AssocExprs.size() && + "Must have the same number of association expressions" + " and TypeSourceInfo!"); + + GenericSelectionExprBits.GenericLoc = GenericLoc; + getTrailingObjects<TypeSourceInfo *>()[getIndexOfControllingType()] = + ControllingType; + std::copy(AssocExprs.begin(), AssocExprs.end(), + getTrailingObjects<Stmt *>() + getIndexOfStartOfAssociatedExprs()); + std::copy(AssocTypes.begin(), AssocTypes.end(), + getTrailingObjects<TypeSourceInfo *>() + + getIndexOfStartOfAssociatedTypes()); setDependence(computeDependence(this, ContainsUnexpandedParameterPack)); } @@ -4114,6 +4436,35 @@ GenericSelectionExpr *GenericSelectionExpr::Create( RParenLoc, ContainsUnexpandedParameterPack); } +GenericSelectionExpr *GenericSelectionExpr::Create( + const ASTContext &Context, SourceLocation GenericLoc, + TypeSourceInfo *ControllingType, ArrayRef<TypeSourceInfo *> AssocTypes, + ArrayRef<Expr *> AssocExprs, SourceLocation DefaultLoc, + SourceLocation RParenLoc, bool ContainsUnexpandedParameterPack, + unsigned ResultIndex) { + unsigned NumAssocs = AssocExprs.size(); + void *Mem = Context.Allocate( + totalSizeToAlloc<Stmt *, TypeSourceInfo *>(1 + NumAssocs, NumAssocs), + alignof(GenericSelectionExpr)); + return new (Mem) GenericSelectionExpr( + Context, GenericLoc, ControllingType, AssocTypes, AssocExprs, DefaultLoc, + RParenLoc, ContainsUnexpandedParameterPack, ResultIndex); +} + +GenericSelectionExpr *GenericSelectionExpr::Create( + const ASTContext &Context, SourceLocation GenericLoc, + TypeSourceInfo *ControllingType, ArrayRef<TypeSourceInfo *> AssocTypes, + ArrayRef<Expr *> AssocExprs, SourceLocation DefaultLoc, + SourceLocation RParenLoc, bool ContainsUnexpandedParameterPack) { + unsigned NumAssocs = AssocExprs.size(); + void *Mem = Context.Allocate( + totalSizeToAlloc<Stmt *, TypeSourceInfo *>(1 + NumAssocs, NumAssocs), + alignof(GenericSelectionExpr)); + return new (Mem) GenericSelectionExpr( + Context, GenericLoc, ControllingType, AssocTypes, AssocExprs, DefaultLoc, + RParenLoc, ContainsUnexpandedParameterPack); +} + GenericSelectionExpr * GenericSelectionExpr::CreateEmpty(const ASTContext &Context, unsigned NumAssocs) { @@ -4127,11 +4478,11 @@ GenericSelectionExpr::CreateEmpty(const ASTContext &Context, // DesignatedInitExpr //===----------------------------------------------------------------------===// -IdentifierInfo *DesignatedInitExpr::Designator::getFieldName() const { - assert(Kind == FieldDesignator && "Only valid on a field designator"); - if (Field.NameOrField & 0x01) - return reinterpret_cast<IdentifierInfo *>(Field.NameOrField & ~0x01); - return getField()->getIdentifier(); +const IdentifierInfo *DesignatedInitExpr::Designator::getFieldName() const { + assert(isFieldDesignator() && "Only valid on a field designator"); + if (FieldInfo.NameOrField & 0x01) + return reinterpret_cast<IdentifierInfo *>(FieldInfo.NameOrField & ~0x01); + return getFieldDecl()->getIdentifier(); } DesignatedInitExpr::DesignatedInitExpr(const ASTContext &C, QualType Ty, @@ -4206,14 +4557,11 @@ SourceRange DesignatedInitExpr::getDesignatorsSourceRange() const { } SourceLocation DesignatedInitExpr::getBeginLoc() const { - SourceLocation StartLoc; auto *DIE = const_cast<DesignatedInitExpr *>(this); Designator &First = *DIE->getDesignator(0); if (First.isFieldDesignator()) - StartLoc = GNUSyntax ? First.Field.FieldLoc : First.Field.DotLoc; - else - StartLoc = First.ArrayOrRange.LBracketLoc; - return StartLoc; + return GNUSyntax ? First.getFieldLoc() : First.getDotLoc(); + return First.getLBracketLoc(); } SourceLocation DesignatedInitExpr::getEndLoc() const { @@ -4221,20 +4569,18 @@ SourceLocation DesignatedInitExpr::getEndLoc() const { } Expr *DesignatedInitExpr::getArrayIndex(const Designator& D) const { - assert(D.Kind == Designator::ArrayDesignator && "Requires array designator"); - return getSubExpr(D.ArrayOrRange.Index + 1); + assert(D.isArrayDesignator() && "Requires array designator"); + return getSubExpr(D.getArrayIndex() + 1); } Expr *DesignatedInitExpr::getArrayRangeStart(const Designator &D) const { - assert(D.Kind == Designator::ArrayRangeDesignator && - "Requires array range designator"); - return getSubExpr(D.ArrayOrRange.Index + 1); + assert(D.isArrayRangeDesignator() && "Requires array range designator"); + return getSubExpr(D.getArrayIndex() + 1); } Expr *DesignatedInitExpr::getArrayRangeEnd(const Designator &D) const { - assert(D.Kind == Designator::ArrayRangeDesignator && - "Requires array range designator"); - return getSubExpr(D.ArrayOrRange.Index + 2); + assert(D.isArrayRangeDesignator() && "Requires array range designator"); + return getSubExpr(D.getArrayIndex() + 2); } /// Replaces the designator at index @p Idx with the series @@ -4269,11 +4615,12 @@ DesignatedInitUpdateExpr::DesignatedInitUpdateExpr(const ASTContext &C, SourceLocation lBraceLoc, Expr *baseExpr, SourceLocation rBraceLoc) - : Expr(DesignatedInitUpdateExprClass, baseExpr->getType(), VK_RValue, + : Expr(DesignatedInitUpdateExprClass, baseExpr->getType(), VK_PRValue, OK_Ordinary) { BaseAndUpdaterExprs[0] = baseExpr; - InitListExpr *ILE = new (C) InitListExpr(C, lBraceLoc, None, rBraceLoc); + InitListExpr *ILE = + new (C) InitListExpr(C, lBraceLoc, std::nullopt, rBraceLoc); ILE->setType(baseExpr->getType()); BaseAndUpdaterExprs[1] = ILE; @@ -4291,7 +4638,7 @@ SourceLocation DesignatedInitUpdateExpr::getEndLoc() const { ParenListExpr::ParenListExpr(SourceLocation LParenLoc, ArrayRef<Expr *> Exprs, SourceLocation RParenLoc) - : Expr(ParenListExprClass, QualType(), VK_RValue, OK_Ordinary), + : Expr(ParenListExprClass, QualType(), VK_PRValue, OK_Ordinary), LParenLoc(LParenLoc), RParenLoc(RParenLoc) { ParenListExprBits.NumExprs = Exprs.size(); @@ -4467,7 +4814,7 @@ PseudoObjectExpr *PseudoObjectExpr::Create(const ASTContext &C, Expr *syntax, ExprValueKind VK; if (resultIndex == NoResult) { type = C.VoidTy; - VK = VK_RValue; + VK = VK_PRValue; } else { assert(resultIndex < semantics.size()); type = semantics[resultIndex]->getType(); @@ -4527,7 +4874,7 @@ Stmt::const_child_range UnaryExprOrTypeTraitExpr::children() const { AtomicExpr::AtomicExpr(SourceLocation BLoc, ArrayRef<Expr *> args, QualType t, AtomicOp op, SourceLocation RP) - : Expr(AtomicExprClass, t, VK_RValue, OK_Ordinary), + : Expr(AtomicExprClass, t, VK_PRValue, OK_Ordinary), NumSubExprs(args.size()), BuiltinLoc(BLoc), RParenLoc(RP), Op(op) { assert(args.size() == getNumSubExprs(op) && "wrong number of subexpressions"); for (unsigned i = 0; i != args.size(); i++) @@ -4543,7 +4890,9 @@ unsigned AtomicExpr::getNumSubExprs(AtomicOp Op) { case AO__atomic_load_n: return 2; + case AO__scoped_atomic_load_n: case AO__opencl_atomic_load: + case AO__hip_atomic_load: case AO__c11_atomic_store: case AO__c11_atomic_exchange: case AO__atomic_load: @@ -4555,6 +4904,7 @@ unsigned AtomicExpr::getNumSubExprs(AtomicOp Op) { case AO__c11_atomic_fetch_and: case AO__c11_atomic_fetch_or: case AO__c11_atomic_fetch_xor: + case AO__c11_atomic_fetch_nand: case AO__c11_atomic_fetch_max: case AO__c11_atomic_fetch_min: case AO__atomic_fetch_add: @@ -4575,7 +4925,36 @@ unsigned AtomicExpr::getNumSubExprs(AtomicOp Op) { case AO__atomic_fetch_max: return 3; + case AO__scoped_atomic_load: + case AO__scoped_atomic_store: + case AO__scoped_atomic_store_n: + case AO__scoped_atomic_fetch_add: + case AO__scoped_atomic_fetch_sub: + case AO__scoped_atomic_fetch_and: + case AO__scoped_atomic_fetch_or: + case AO__scoped_atomic_fetch_xor: + case AO__scoped_atomic_fetch_nand: + case AO__scoped_atomic_add_fetch: + case AO__scoped_atomic_sub_fetch: + case AO__scoped_atomic_and_fetch: + case AO__scoped_atomic_or_fetch: + case AO__scoped_atomic_xor_fetch: + case AO__scoped_atomic_nand_fetch: + case AO__scoped_atomic_min_fetch: + case AO__scoped_atomic_max_fetch: + case AO__scoped_atomic_fetch_min: + case AO__scoped_atomic_fetch_max: + case AO__scoped_atomic_exchange_n: + case AO__hip_atomic_exchange: + case AO__hip_atomic_fetch_add: + case AO__hip_atomic_fetch_sub: + case AO__hip_atomic_fetch_and: + case AO__hip_atomic_fetch_or: + case AO__hip_atomic_fetch_xor: + case AO__hip_atomic_fetch_min: + case AO__hip_atomic_fetch_max: case AO__opencl_atomic_store: + case AO__hip_atomic_store: case AO__opencl_atomic_exchange: case AO__opencl_atomic_fetch_add: case AO__opencl_atomic_fetch_sub: @@ -4587,15 +4966,21 @@ unsigned AtomicExpr::getNumSubExprs(AtomicOp Op) { case AO__atomic_exchange: return 4; + case AO__scoped_atomic_exchange: case AO__c11_atomic_compare_exchange_strong: case AO__c11_atomic_compare_exchange_weak: return 5; - + case AO__hip_atomic_compare_exchange_strong: case AO__opencl_atomic_compare_exchange_strong: case AO__opencl_atomic_compare_exchange_weak: + case AO__hip_atomic_compare_exchange_weak: case AO__atomic_compare_exchange: case AO__atomic_compare_exchange_n: return 6; + + case AO__scoped_atomic_compare_exchange: + case AO__scoped_atomic_compare_exchange_n: + return 7; } llvm_unreachable("unknown atomic op"); } @@ -4627,10 +5012,10 @@ QualType OMPArraySectionExpr::getBaseOriginalType(const Expr *Base) { for (unsigned Cnt = 0; Cnt < ArraySectionCount; ++Cnt) { if (OriginalTy->isAnyPointerType()) OriginalTy = OriginalTy->getPointeeType(); - else { - assert (OriginalTy->isArrayType()); + else if (OriginalTy->isArrayType()) OriginalTy = OriginalTy->castAsArrayTypeUnsafe()->getElementType(); - } + else + return {}; } return OriginalTy; } @@ -4642,7 +5027,7 @@ RecoveryExpr::RecoveryExpr(ASTContext &Ctx, QualType T, SourceLocation BeginLoc, OK_Ordinary), BeginLoc(BeginLoc), EndLoc(EndLoc), NumExprs(SubExprs.size()) { assert(!T.isNull()); - assert(llvm::all_of(SubExprs, [](Expr* E) { return E != nullptr; })); + assert(!llvm::is_contained(SubExprs, nullptr)); llvm::copy(SubExprs, getTrailingObjects<Expr *>()); setDependence(computeDependence(this)); |