aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/lib/AST/Expr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/clang/lib/AST/Expr.cpp')
-rw-r--r--contrib/llvm-project/clang/lib/AST/Expr.cpp1005
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));