aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/AST/Expr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/AST/Expr.cpp')
-rw-r--r--clang/lib/AST/Expr.cpp1164
1 files changed, 709 insertions, 455 deletions
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index 73ddbc62482d..399e7e13c445 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -14,9 +14,11 @@
#include "clang/AST/APValue.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Attr.h"
+#include "clang/AST/ComputeDependence.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/DependenceFlags.h"
#include "clang/AST/EvaluatedExprVisitor.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/Mangle.h"
@@ -242,6 +244,7 @@ static void AssertResultStorageKind(ConstantExpr::ResultStorageKind Kind) {
assert((Kind == ConstantExpr::RSK_APValue ||
Kind == ConstantExpr::RSK_Int64 || Kind == ConstantExpr::RSK_None) &&
"Invalid StorageKind Value");
+ (void)Kind;
}
ConstantExpr::ResultStorageKind
@@ -266,29 +269,31 @@ ConstantExpr::getStorageKind(const Type *T, const ASTContext &Context) {
return ConstantExpr::RSK_APValue;
}
-void ConstantExpr::DefaultInit(ResultStorageKind StorageKind) {
+ConstantExpr::ConstantExpr(Expr *SubExpr, ResultStorageKind StorageKind,
+ bool IsImmediateInvocation)
+ : FullExpr(ConstantExprClass, SubExpr) {
ConstantExprBits.ResultKind = StorageKind;
ConstantExprBits.APValueKind = APValue::None;
+ ConstantExprBits.IsUnsigned = false;
+ ConstantExprBits.BitWidth = 0;
ConstantExprBits.HasCleanup = false;
+ ConstantExprBits.IsImmediateInvocation = IsImmediateInvocation;
+
if (StorageKind == ConstantExpr::RSK_APValue)
::new (getTrailingObjects<APValue>()) APValue();
}
-ConstantExpr::ConstantExpr(Expr *subexpr, ResultStorageKind StorageKind)
- : FullExpr(ConstantExprClass, subexpr) {
- DefaultInit(StorageKind);
-}
-
ConstantExpr *ConstantExpr::Create(const ASTContext &Context, Expr *E,
- ResultStorageKind StorageKind) {
+ ResultStorageKind StorageKind,
+ bool IsImmediateInvocation) {
assert(!isa<ConstantExpr>(E));
AssertResultStorageKind(StorageKind);
+
unsigned Size = totalSizeToAlloc<APValue, uint64_t>(
StorageKind == ConstantExpr::RSK_APValue,
StorageKind == ConstantExpr::RSK_Int64);
void *Mem = Context.Allocate(Size, alignof(ConstantExpr));
- ConstantExpr *Self = new (Mem) ConstantExpr(E, StorageKind);
- return Self;
+ return new (Mem) ConstantExpr(E, StorageKind, IsImmediateInvocation);
}
ConstantExpr *ConstantExpr::Create(const ASTContext &Context, Expr *E,
@@ -299,25 +304,27 @@ ConstantExpr *ConstantExpr::Create(const ASTContext &Context, Expr *E,
return Self;
}
-ConstantExpr::ConstantExpr(ResultStorageKind StorageKind, EmptyShell Empty)
+ConstantExpr::ConstantExpr(EmptyShell Empty, ResultStorageKind StorageKind)
: FullExpr(ConstantExprClass, Empty) {
- DefaultInit(StorageKind);
+ ConstantExprBits.ResultKind = StorageKind;
+
+ if (StorageKind == ConstantExpr::RSK_APValue)
+ ::new (getTrailingObjects<APValue>()) APValue();
}
ConstantExpr *ConstantExpr::CreateEmpty(const ASTContext &Context,
- ResultStorageKind StorageKind,
- EmptyShell Empty) {
+ ResultStorageKind StorageKind) {
AssertResultStorageKind(StorageKind);
+
unsigned Size = totalSizeToAlloc<APValue, uint64_t>(
StorageKind == ConstantExpr::RSK_APValue,
StorageKind == ConstantExpr::RSK_Int64);
void *Mem = Context.Allocate(Size, alignof(ConstantExpr));
- ConstantExpr *Self = new (Mem) ConstantExpr(StorageKind, Empty);
- return Self;
+ return new (Mem) ConstantExpr(EmptyShell(), StorageKind);
}
void ConstantExpr::MoveIntoResult(APValue &Value, const ASTContext &Context) {
- assert(getStorageKind(Value) == ConstantExprBits.ResultKind &&
+ assert((unsigned)getStorageKind(Value) <= ConstantExprBits.ResultKind &&
"Invalid storage for this value kind");
ConstantExprBits.APValueKind = Value.getKind();
switch (ConstantExprBits.ResultKind) {
@@ -352,6 +359,8 @@ llvm::APSInt ConstantExpr::getResultAsAPSInt() const {
}
APValue ConstantExpr::getAPValueResult() const {
+ assert(hasAPValueResult());
+
switch (ConstantExprBits.ResultKind) {
case ConstantExpr::RSK_APValue:
return APValueResult();
@@ -365,125 +374,12 @@ APValue ConstantExpr::getAPValueResult() const {
llvm_unreachable("invalid ResultKind");
}
-/// Compute the type-, value-, and instantiation-dependence of a
-/// declaration reference
-/// based on the declaration being referenced.
-static void computeDeclRefDependence(const ASTContext &Ctx, NamedDecl *D,
- QualType T, bool &TypeDependent,
- bool &ValueDependent,
- bool &InstantiationDependent) {
- TypeDependent = false;
- ValueDependent = false;
- InstantiationDependent = false;
-
- // (TD) C++ [temp.dep.expr]p3:
- // An id-expression is type-dependent if it contains:
- //
- // and
- //
- // (VD) C++ [temp.dep.constexpr]p2:
- // An identifier is value-dependent if it is:
-
- // (TD) - an identifier that was declared with dependent type
- // (VD) - a name declared with a dependent type,
- if (T->isDependentType()) {
- TypeDependent = true;
- ValueDependent = true;
- InstantiationDependent = true;
- return;
- } else if (T->isInstantiationDependentType()) {
- InstantiationDependent = true;
- }
-
- // (TD) - a conversion-function-id that specifies a dependent type
- if (D->getDeclName().getNameKind()
- == DeclarationName::CXXConversionFunctionName) {
- QualType T = D->getDeclName().getCXXNameType();
- if (T->isDependentType()) {
- TypeDependent = true;
- ValueDependent = true;
- InstantiationDependent = true;
- return;
- }
-
- if (T->isInstantiationDependentType())
- InstantiationDependent = true;
- }
-
- // (VD) - the name of a non-type template parameter,
- if (isa<NonTypeTemplateParmDecl>(D)) {
- ValueDependent = true;
- InstantiationDependent = true;
- return;
- }
-
- // (VD) - a constant with integral or enumeration type and is
- // initialized with an expression that is value-dependent.
- // (VD) - a constant with literal type and is initialized with an
- // expression that is value-dependent [C++11].
- // (VD) - FIXME: Missing from the standard:
- // - an entity with reference type and is initialized with an
- // expression that is value-dependent [C++11]
- if (VarDecl *Var = dyn_cast<VarDecl>(D)) {
- if ((Ctx.getLangOpts().CPlusPlus11 ?
- Var->getType()->isLiteralType(Ctx) :
- Var->getType()->isIntegralOrEnumerationType()) &&
- (Var->getType().isConstQualified() ||
- Var->getType()->isReferenceType())) {
- if (const Expr *Init = Var->getAnyInitializer())
- if (Init->isValueDependent()) {
- ValueDependent = true;
- InstantiationDependent = true;
- }
- }
-
- // (VD) - FIXME: Missing from the standard:
- // - a member function or a static data member of the current
- // instantiation
- if (Var->isStaticDataMember() &&
- Var->getDeclContext()->isDependentContext()) {
- ValueDependent = true;
- InstantiationDependent = true;
- TypeSourceInfo *TInfo = Var->getFirstDecl()->getTypeSourceInfo();
- if (TInfo->getType()->isIncompleteArrayType())
- TypeDependent = true;
- }
-
- return;
- }
-
- // (VD) - FIXME: Missing from the standard:
- // - a member function or a static data member of the current
- // instantiation
- if (isa<CXXMethodDecl>(D) && D->getDeclContext()->isDependentContext()) {
- ValueDependent = true;
- InstantiationDependent = true;
- }
-}
-
-void DeclRefExpr::computeDependence(const ASTContext &Ctx) {
- bool TypeDependent = false;
- bool ValueDependent = false;
- bool InstantiationDependent = false;
- computeDeclRefDependence(Ctx, getDecl(), getType(), TypeDependent,
- ValueDependent, InstantiationDependent);
-
- ExprBits.TypeDependent |= TypeDependent;
- ExprBits.ValueDependent |= ValueDependent;
- ExprBits.InstantiationDependent |= InstantiationDependent;
-
- // Is the declaration a parameter pack?
- if (getDecl()->isParameterPack())
- ExprBits.ContainsUnexpandedParameterPack = true;
-}
-
DeclRefExpr::DeclRefExpr(const ASTContext &Ctx, ValueDecl *D,
bool RefersToEnclosingVariableOrCapture, QualType T,
ExprValueKind VK, SourceLocation L,
const DeclarationNameLoc &LocInfo,
NonOdrUseReason NOUR)
- : Expr(DeclRefExprClass, T, VK, OK_Ordinary, false, false, false, false),
- D(D), DNLoc(LocInfo) {
+ : Expr(DeclRefExprClass, T, VK, OK_Ordinary), D(D), DNLoc(LocInfo) {
DeclRefExprBits.HasQualifier = false;
DeclRefExprBits.HasTemplateKWAndArgsInfo = false;
DeclRefExprBits.HasFoundDecl = false;
@@ -492,7 +388,7 @@ DeclRefExpr::DeclRefExpr(const ASTContext &Ctx, ValueDecl *D,
RefersToEnclosingVariableOrCapture;
DeclRefExprBits.NonOdrUseReason = NOUR;
DeclRefExprBits.Loc = L;
- computeDependence(Ctx);
+ setDependence(computeDependence(this, Ctx));
}
DeclRefExpr::DeclRefExpr(const ASTContext &Ctx,
@@ -502,19 +398,13 @@ DeclRefExpr::DeclRefExpr(const ASTContext &Ctx,
const DeclarationNameInfo &NameInfo, NamedDecl *FoundD,
const TemplateArgumentListInfo *TemplateArgs,
QualType T, ExprValueKind VK, NonOdrUseReason NOUR)
- : Expr(DeclRefExprClass, T, VK, OK_Ordinary, false, false, false, false),
- D(D), DNLoc(NameInfo.getInfo()) {
+ : Expr(DeclRefExprClass, T, VK, OK_Ordinary), D(D),
+ DNLoc(NameInfo.getInfo()) {
DeclRefExprBits.Loc = NameInfo.getLoc();
DeclRefExprBits.HasQualifier = QualifierLoc ? 1 : 0;
- if (QualifierLoc) {
+ if (QualifierLoc)
new (getTrailingObjects<NestedNameSpecifierLoc>())
NestedNameSpecifierLoc(QualifierLoc);
- auto *NNS = QualifierLoc.getNestedNameSpecifier();
- if (NNS->isInstantiationDependent())
- ExprBits.InstantiationDependent = true;
- if (NNS->containsUnexpandedParameterPack())
- ExprBits.ContainsUnexpandedParameterPack = true;
- }
DeclRefExprBits.HasFoundDecl = FoundD ? 1 : 0;
if (FoundD)
*getTrailingObjects<NamedDecl *>() = FoundD;
@@ -524,22 +414,18 @@ DeclRefExpr::DeclRefExpr(const ASTContext &Ctx,
RefersToEnclosingVariableOrCapture;
DeclRefExprBits.NonOdrUseReason = NOUR;
if (TemplateArgs) {
- bool Dependent = false;
- bool InstantiationDependent = false;
- bool ContainsUnexpandedParameterPack = false;
+ auto Deps = TemplateArgumentDependence::None;
getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom(
TemplateKWLoc, *TemplateArgs, getTrailingObjects<TemplateArgumentLoc>(),
- Dependent, InstantiationDependent, ContainsUnexpandedParameterPack);
- assert(!Dependent && "built a DeclRefExpr with dependent template args");
- ExprBits.InstantiationDependent |= InstantiationDependent;
- ExprBits.ContainsUnexpandedParameterPack |= ContainsUnexpandedParameterPack;
+ Deps);
+ assert(!(Deps & TemplateArgumentDependence::Dependent) &&
+ "built a DeclRefExpr with dependent template args");
} else if (TemplateKWLoc.isValid()) {
getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom(
TemplateKWLoc);
}
DeclRefExprBits.HadMultipleCandidates = 0;
-
- computeDependence(Ctx);
+ setDependence(computeDependence(this, Ctx));
}
DeclRefExpr *DeclRefExpr::Create(const ASTContext &Context,
@@ -611,10 +497,7 @@ SourceLocation DeclRefExpr::getEndLoc() const {
PredefinedExpr::PredefinedExpr(SourceLocation L, QualType FNTy, IdentKind IK,
StringLiteral *SL)
- : Expr(PredefinedExprClass, FNTy, VK_LValue, OK_Ordinary,
- FNTy->isDependentType(), FNTy->isDependentType(),
- FNTy->isInstantiationDependentType(),
- /*ContainsUnexpandedParameterPack=*/false) {
+ : Expr(PredefinedExprClass, FNTy, VK_LValue, OK_Ordinary) {
PredefinedExprBits.Kind = IK;
assert((getIdentKind() == IK) &&
"IdentKind do not fit in PredefinedExprBitfields!");
@@ -623,6 +506,35 @@ PredefinedExpr::PredefinedExpr(SourceLocation L, QualType FNTy, IdentKind IK,
PredefinedExprBits.Loc = L;
if (HasFunctionName)
setFunctionName(SL);
+ setDependence(computeDependence(this));
+}
+
+PredefinedExpr::PredefinedExpr(SourceLocation L, QualType FnTy, IdentKind IK,
+ TypeSourceInfo *Info)
+ : Expr(PredefinedExprClass, FnTy, VK_LValue, OK_Ordinary) {
+ PredefinedExprBits.Kind = IK;
+ assert((getIdentKind() == IK) &&
+ "IdentKind do not fit in PredefinedExprBitFields!");
+ assert(IK == UniqueStableNameType &&
+ "Constructor only valid with UniqueStableNameType");
+ PredefinedExprBits.HasFunctionName = false;
+ PredefinedExprBits.Loc = L;
+ setTypeSourceInfo(Info);
+ setDependence(computeDependence(this));
+}
+
+PredefinedExpr::PredefinedExpr(SourceLocation L, QualType FnTy, IdentKind IK,
+ Expr *E)
+ : Expr(PredefinedExprClass, FnTy, VK_LValue, OK_Ordinary) {
+ PredefinedExprBits.Kind = IK;
+ assert((getIdentKind() == IK) &&
+ "IdentKind do not fit in PredefinedExprBitFields!");
+ assert(IK == UniqueStableNameExpr &&
+ "Constructor only valid with UniqueStableNameExpr");
+ PredefinedExprBits.HasFunctionName = false;
+ PredefinedExprBits.Loc = L;
+ setExpr(E);
+ setDependence(computeDependence(this));
}
PredefinedExpr::PredefinedExpr(EmptyShell Empty, bool HasFunctionName)
@@ -634,15 +546,44 @@ PredefinedExpr *PredefinedExpr::Create(const ASTContext &Ctx, SourceLocation L,
QualType FNTy, IdentKind IK,
StringLiteral *SL) {
bool HasFunctionName = SL != nullptr;
- void *Mem = Ctx.Allocate(totalSizeToAlloc<Stmt *>(HasFunctionName),
- alignof(PredefinedExpr));
+ void *Mem = Ctx.Allocate(
+ totalSizeToAlloc<Stmt *, Expr *, TypeSourceInfo *>(HasFunctionName, 0, 0),
+ alignof(PredefinedExpr));
return new (Mem) PredefinedExpr(L, FNTy, IK, SL);
}
+PredefinedExpr *PredefinedExpr::Create(const ASTContext &Ctx, SourceLocation L,
+ QualType FNTy, IdentKind IK,
+ StringLiteral *SL,
+ TypeSourceInfo *Info) {
+ assert(IK == UniqueStableNameType && "Only valid with UniqueStableNameType");
+ bool HasFunctionName = SL != nullptr;
+ void *Mem = Ctx.Allocate(totalSizeToAlloc<Stmt *, Expr *, TypeSourceInfo *>(
+ HasFunctionName, 0, !HasFunctionName),
+ alignof(PredefinedExpr));
+ if (HasFunctionName)
+ return new (Mem) PredefinedExpr(L, FNTy, IK, SL);
+ return new (Mem) PredefinedExpr(L, FNTy, IK, Info);
+}
+
+PredefinedExpr *PredefinedExpr::Create(const ASTContext &Ctx, SourceLocation L,
+ QualType FNTy, IdentKind IK,
+ StringLiteral *SL, Expr *E) {
+ assert(IK == UniqueStableNameExpr && "Only valid with UniqueStableNameExpr");
+ bool HasFunctionName = SL != nullptr;
+ void *Mem = Ctx.Allocate(totalSizeToAlloc<Stmt *, Expr *, TypeSourceInfo *>(
+ HasFunctionName, !HasFunctionName, 0),
+ alignof(PredefinedExpr));
+ if (HasFunctionName)
+ return new (Mem) PredefinedExpr(L, FNTy, IK, SL);
+ return new (Mem) PredefinedExpr(L, FNTy, IK, E);
+}
+
PredefinedExpr *PredefinedExpr::CreateEmpty(const ASTContext &Ctx,
bool HasFunctionName) {
- void *Mem = Ctx.Allocate(totalSizeToAlloc<Stmt *>(HasFunctionName),
- alignof(PredefinedExpr));
+ void *Mem = Ctx.Allocate(
+ totalSizeToAlloc<Stmt *, Expr *, TypeSourceInfo *>(HasFunctionName, 0, 0),
+ alignof(PredefinedExpr));
return new (Mem) PredefinedExpr(EmptyShell(), HasFunctionName);
}
@@ -662,12 +603,28 @@ StringRef PredefinedExpr::getIdentKindName(PredefinedExpr::IdentKind IK) {
return "__FUNCSIG__";
case LFuncSig:
return "L__FUNCSIG__";
+ case UniqueStableNameType:
+ case UniqueStableNameExpr:
+ return "__builtin_unique_stable_name";
case PrettyFunctionNoVirtual:
break;
}
llvm_unreachable("Unknown ident kind for PredefinedExpr");
}
+std::string PredefinedExpr::ComputeName(ASTContext &Context, IdentKind IK,
+ QualType Ty) {
+ std::unique_ptr<MangleContext> Ctx{ItaniumMangleContext::create(
+ Context, Context.getDiagnostics(), /*IsUniqueNameMangler*/ true)};
+
+ Ty = Ty.getCanonicalType();
+
+ SmallString<256> Buffer;
+ llvm::raw_svector_ostream Out(Buffer);
+ Ctx->mangleTypeName(Ty, Out);
+ return std::string(Buffer.str());
+}
+
// FIXME: Maybe this should use DeclPrinter with a special "print predefined
// expr" policy instead.
std::string PredefinedExpr::ComputeName(IdentKind IK, const Decl *CurrentDecl) {
@@ -681,18 +638,22 @@ std::string PredefinedExpr::ComputeName(IdentKind IK, const Decl *CurrentDecl) {
if (MC->shouldMangleDeclName(ND)) {
SmallString<256> Buffer;
llvm::raw_svector_ostream Out(Buffer);
+ GlobalDecl GD;
if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(ND))
- MC->mangleCXXCtor(CD, Ctor_Base, Out);
+ GD = GlobalDecl(CD, Ctor_Base);
else if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(ND))
- MC->mangleCXXDtor(DD, Dtor_Base, Out);
+ GD = GlobalDecl(DD, Dtor_Base);
+ else if (ND->hasAttr<CUDAGlobalAttr>())
+ GD = GlobalDecl(cast<FunctionDecl>(ND));
else
- MC->mangleName(ND, Out);
+ GD = GlobalDecl(ND);
+ MC->mangleName(GD, Out);
if (!Buffer.empty() && Buffer.front() == '\01')
- return Buffer.substr(1);
- return Buffer.str();
+ return std::string(Buffer.substr(1));
+ return std::string(Buffer.str());
} else
- return ND->getIdentifier()->getName();
+ return std::string(ND->getIdentifier()->getName());
}
return "";
}
@@ -711,7 +672,7 @@ std::string PredefinedExpr::ComputeName(IdentKind IK, const Decl *CurrentDecl) {
Out << ComputeName(IK, DCBlock);
else if (auto *DCDecl = dyn_cast<Decl>(DC))
Out << ComputeName(IK, DCDecl) << "_block_invoke";
- return Out.str();
+ return std::string(Out.str());
}
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CurrentDecl)) {
if (IK != PrettyFunction && IK != PrettyFunctionNoVirtual &&
@@ -856,7 +817,7 @@ std::string PredefinedExpr::ComputeName(IdentKind IK, const Decl *CurrentDecl) {
Out << Proto;
- return Name.str().str();
+ return std::string(Name);
}
if (const CapturedDecl *CD = dyn_cast<CapturedDecl>(CurrentDecl)) {
for (const DeclContext *DC = CD->getParent(); DC; DC = DC->getParent())
@@ -887,7 +848,7 @@ std::string PredefinedExpr::ComputeName(IdentKind IK, const Decl *CurrentDecl) {
MD->getSelector().print(Out);
Out << ']';
- return Name.str().str();
+ return std::string(Name);
}
if (isa<TranslationUnitDecl>(CurrentDecl) && IK == PrettyFunction) {
// __PRETTY_FUNCTION__ -> "top level", the others produce an empty string.
@@ -915,13 +876,12 @@ 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, false, false,
- false, false),
- Loc(l) {
+ : Expr(IntegerLiteralClass, type, VK_RValue, 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.");
setValue(C, V);
+ setDependence(ExprDependence::None);
}
IntegerLiteral *
@@ -938,13 +898,13 @@ 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, false, false,
- false, false),
- Loc(l), Scale(Scale) {
+ : Expr(FixedPointLiteralClass, type, VK_RValue, OK_Ordinary), Loc(l),
+ Scale(Scale) {
assert(type->isFixedPointType() && "Illegal type in FixedPointLiteral");
assert(V.getBitWidth() == C.getTypeInfo(type).Width &&
"Fixed point type is not the correct size for constant.");
setValue(C, V);
+ setDependence(ExprDependence::None);
}
FixedPointLiteral *FixedPointLiteral::CreateFromRawInt(const ASTContext &C,
@@ -955,6 +915,11 @@ FixedPointLiteral *FixedPointLiteral::CreateFromRawInt(const ASTContext &C,
return new (C) FixedPointLiteral(C, V, type, l, Scale);
}
+FixedPointLiteral *FixedPointLiteral::Create(const ASTContext &C,
+ EmptyShell Empty) {
+ return new (C) FixedPointLiteral(Empty);
+}
+
std::string FixedPointLiteral::getValueAsString(unsigned Radix) const {
// Currently the longest decimal number that can be printed is the max for an
// unsigned long _Accum: 4294967295.99999999976716935634613037109375
@@ -962,16 +927,16 @@ std::string FixedPointLiteral::getValueAsString(unsigned Radix) const {
SmallString<64> S;
FixedPointValueToString(
S, llvm::APSInt::getUnsigned(getValue().getZExtValue()), Scale);
- return S.str();
+ return std::string(S.str());
}
FloatingLiteral::FloatingLiteral(const ASTContext &C, const llvm::APFloat &V,
bool isexact, QualType Type, SourceLocation L)
- : Expr(FloatingLiteralClass, Type, VK_RValue, OK_Ordinary, false, false,
- false, false), Loc(L) {
+ : Expr(FloatingLiteralClass, Type, VK_RValue, OK_Ordinary), Loc(L) {
setSemantics(V.getSemantics());
FloatingLiteralBits.IsExact = isexact;
setValue(C, V);
+ setDependence(ExprDependence::None);
}
FloatingLiteral::FloatingLiteral(const ASTContext &C, EmptyShell Empty)
@@ -1031,8 +996,7 @@ StringLiteral::StringLiteral(const ASTContext &Ctx, StringRef Str,
StringKind Kind, bool Pascal, QualType Ty,
const SourceLocation *Loc,
unsigned NumConcatenated)
- : Expr(StringLiteralClass, Ty, VK_LValue, OK_Ordinary, false, false, false,
- false) {
+ : Expr(StringLiteralClass, Ty, VK_LValue, OK_Ordinary) {
assert(Ctx.getAsConstantArrayType(Ty) &&
"StringLiteral must be of constant array type!");
unsigned CharByteWidth = mapCharByteWidth(Ctx.getTargetInfo(), Kind);
@@ -1071,6 +1035,8 @@ StringLiteral::StringLiteral(const ASTContext &Ctx, StringRef Str,
// Initialize the trailing array of char holding the string data.
std::memcpy(getTrailingObjects<char>(), Str.data(), ByteLength);
+
+ setDependence(ExprDependence::None);
}
StringLiteral::StringLiteral(EmptyShell Empty, unsigned NumConcatenated,
@@ -1339,10 +1305,7 @@ CallExpr::CallExpr(StmtClass SC, Expr *Fn, ArrayRef<Expr *> PreArgs,
ArrayRef<Expr *> Args, QualType Ty, ExprValueKind VK,
SourceLocation RParenLoc, unsigned MinNumArgs,
ADLCallKind UsesADL)
- : Expr(SC, Ty, VK, OK_Ordinary, Fn->isTypeDependent(),
- Fn->isValueDependent(), Fn->isInstantiationDependent(),
- Fn->containsUnexpandedParameterPack()),
- RParenLoc(RParenLoc) {
+ : Expr(SC, Ty, VK, OK_Ordinary), RParenLoc(RParenLoc) {
NumArgs = std::max<unsigned>(Args.size(), MinNumArgs);
unsigned NumPreArgs = PreArgs.size();
CallExprBits.NumPreArgs = NumPreArgs;
@@ -1356,17 +1319,14 @@ CallExpr::CallExpr(StmtClass SC, Expr *Fn, ArrayRef<Expr *> PreArgs,
CallExprBits.UsesADL = static_cast<bool>(UsesADL);
setCallee(Fn);
- for (unsigned I = 0; I != NumPreArgs; ++I) {
- updateDependenciesFromArg(PreArgs[I]);
+ for (unsigned I = 0; I != NumPreArgs; ++I)
setPreArg(I, PreArgs[I]);
- }
- for (unsigned I = 0; I != Args.size(); ++I) {
- updateDependenciesFromArg(Args[I]);
+ for (unsigned I = 0; I != Args.size(); ++I)
setArg(I, Args[I]);
- }
- for (unsigned I = Args.size(); I != NumArgs; ++I) {
+ for (unsigned I = Args.size(); I != NumArgs; ++I)
setArg(I, nullptr);
- }
+
+ setDependence(computeDependence(this, PreArgs));
}
CallExpr::CallExpr(StmtClass SC, unsigned NumPreArgs, unsigned NumArgs,
@@ -1400,7 +1360,8 @@ CallExpr *CallExpr::CreateTemporary(void *Mem, Expr *Fn, QualType Ty,
assert(!(reinterpret_cast<uintptr_t>(Mem) % alignof(CallExpr)) &&
"Misaligned memory in CallExpr::CreateTemporary!");
return new (Mem) CallExpr(CallExprClass, Fn, /*PreArgs=*/{}, /*Args=*/{}, Ty,
- VK, RParenLoc, /*MinNumArgs=*/0, UsesADL);
+ VK, RParenLoc,
+ /*MinNumArgs=*/0, UsesADL);
}
CallExpr *CallExpr::CreateEmpty(const ASTContext &Ctx, unsigned NumArgs,
@@ -1429,33 +1390,31 @@ unsigned CallExpr::offsetToTrailingObjects(StmtClass SC) {
}
}
-void CallExpr::updateDependenciesFromArg(Expr *Arg) {
- if (Arg->isTypeDependent())
- ExprBits.TypeDependent = true;
- if (Arg->isValueDependent())
- ExprBits.ValueDependent = true;
- if (Arg->isInstantiationDependent())
- ExprBits.InstantiationDependent = true;
- if (Arg->containsUnexpandedParameterPack())
- ExprBits.ContainsUnexpandedParameterPack = true;
-}
-
Decl *Expr::getReferencedDeclOfCallee() {
Expr *CEE = IgnoreParenImpCasts();
- while (SubstNonTypeTemplateParmExpr *NTTP
- = dyn_cast<SubstNonTypeTemplateParmExpr>(CEE)) {
- CEE = NTTP->getReplacement()->IgnoreParenCasts();
+ while (SubstNonTypeTemplateParmExpr *NTTP =
+ dyn_cast<SubstNonTypeTemplateParmExpr>(CEE)) {
+ CEE = NTTP->getReplacement()->IgnoreParenImpCasts();
}
// If we're calling a dereference, look at the pointer instead.
- if (BinaryOperator *BO = dyn_cast<BinaryOperator>(CEE)) {
- if (BO->isPtrMemOp())
- CEE = BO->getRHS()->IgnoreParenCasts();
- } else if (UnaryOperator *UO = dyn_cast<UnaryOperator>(CEE)) {
- if (UO->getOpcode() == UO_Deref)
- CEE = UO->getSubExpr()->IgnoreParenCasts();
+ while (true) {
+ if (BinaryOperator *BO = dyn_cast<BinaryOperator>(CEE)) {
+ if (BO->isPtrMemOp()) {
+ CEE = BO->getRHS()->IgnoreParenImpCasts();
+ continue;
+ }
+ } else if (UnaryOperator *UO = dyn_cast<UnaryOperator>(CEE)) {
+ if (UO->getOpcode() == UO_Deref || UO->getOpcode() == UO_AddrOf ||
+ UO->getOpcode() == UO_Plus) {
+ CEE = UO->getSubExpr()->IgnoreParenImpCasts();
+ continue;
+ }
+ }
+ break;
}
+
if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CEE))
return DRE->getDecl();
if (MemberExpr *ME = dyn_cast<MemberExpr>(CEE))
@@ -1466,28 +1425,11 @@ Decl *Expr::getReferencedDeclOfCallee() {
return nullptr;
}
-/// getBuiltinCallee - If this is a call to a builtin, return the builtin ID. If
-/// not, return 0.
+/// If this is a call to a builtin, return the builtin ID. If not, return 0.
unsigned CallExpr::getBuiltinCallee() const {
- // All simple function calls (e.g. func()) are implicitly cast to pointer to
- // function. As a result, we try and obtain the DeclRefExpr from the
- // ImplicitCastExpr.
- const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(getCallee());
- if (!ICE) // FIXME: deal with more complex calls (e.g. (func)(), (*func)()).
- return 0;
-
- const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(ICE->getSubExpr());
- if (!DRE)
- return 0;
-
- const FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl());
- if (!FDecl)
- return 0;
-
- if (!FDecl->getIdentifier())
- return 0;
-
- return FDecl->getBuiltinID();
+ auto *FDecl =
+ dyn_cast_or_null<FunctionDecl>(getCallee()->getReferencedDeclOfCallee());
+ return FDecl ? FDecl->getBuiltinID() : 0;
}
bool CallExpr::isUnevaluatedBuiltinCall(const ASTContext &Ctx) const {
@@ -1569,28 +1511,17 @@ OffsetOfExpr *OffsetOfExpr::CreateEmpty(const ASTContext &C,
OffsetOfExpr::OffsetOfExpr(const ASTContext &C, QualType type,
SourceLocation OperatorLoc, TypeSourceInfo *tsi,
- ArrayRef<OffsetOfNode> comps, ArrayRef<Expr*> exprs,
+ ArrayRef<OffsetOfNode> comps, ArrayRef<Expr *> exprs,
SourceLocation RParenLoc)
- : Expr(OffsetOfExprClass, type, VK_RValue, OK_Ordinary,
- /*TypeDependent=*/false,
- /*ValueDependent=*/tsi->getType()->isDependentType(),
- tsi->getType()->isInstantiationDependentType(),
- tsi->getType()->containsUnexpandedParameterPack()),
- OperatorLoc(OperatorLoc), RParenLoc(RParenLoc), TSInfo(tsi),
- NumComps(comps.size()), NumExprs(exprs.size())
-{
- for (unsigned i = 0; i != comps.size(); ++i) {
+ : Expr(OffsetOfExprClass, type, VK_RValue, OK_Ordinary),
+ OperatorLoc(OperatorLoc), RParenLoc(RParenLoc), TSInfo(tsi),
+ NumComps(comps.size()), NumExprs(exprs.size()) {
+ for (unsigned i = 0; i != comps.size(); ++i)
setComponent(i, comps[i]);
- }
-
- for (unsigned i = 0; i != exprs.size(); ++i) {
- if (exprs[i]->isTypeDependent() || exprs[i]->isValueDependent())
- ExprBits.ValueDependent = true;
- if (exprs[i]->containsUnexpandedParameterPack())
- ExprBits.ContainsUnexpandedParameterPack = true;
-
+ for (unsigned i = 0; i != exprs.size(); ++i)
setIndexExpr(i, exprs[i]);
- }
+
+ setDependence(computeDependence(this));
}
IdentifierInfo *OffsetOfNode::getFieldName() const {
@@ -1604,39 +1535,15 @@ IdentifierInfo *OffsetOfNode::getFieldName() const {
UnaryExprOrTypeTraitExpr::UnaryExprOrTypeTraitExpr(
UnaryExprOrTypeTrait ExprKind, Expr *E, QualType resultType,
SourceLocation op, SourceLocation rp)
- : Expr(UnaryExprOrTypeTraitExprClass, resultType, VK_RValue, OK_Ordinary,
- false, // Never type-dependent (C++ [temp.dep.expr]p3).
- // Value-dependent if the argument is type-dependent.
- E->isTypeDependent(), E->isInstantiationDependent(),
- E->containsUnexpandedParameterPack()),
+ : Expr(UnaryExprOrTypeTraitExprClass, resultType, VK_RValue, OK_Ordinary),
OpLoc(op), RParenLoc(rp) {
+ assert(ExprKind <= UETT_Last && "invalid enum value!");
UnaryExprOrTypeTraitExprBits.Kind = ExprKind;
+ assert(static_cast<unsigned>(ExprKind) == UnaryExprOrTypeTraitExprBits.Kind &&
+ "UnaryExprOrTypeTraitExprBits.Kind overflow!");
UnaryExprOrTypeTraitExprBits.IsType = false;
Argument.Ex = E;
-
- // Check to see if we are in the situation where alignof(decl) should be
- // dependent because decl's alignment is dependent.
- if (ExprKind == UETT_AlignOf || ExprKind == UETT_PreferredAlignOf) {
- if (!isValueDependent() || !isInstantiationDependent()) {
- E = E->IgnoreParens();
-
- const ValueDecl *D = nullptr;
- if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
- D = DRE->getDecl();
- else if (const auto *ME = dyn_cast<MemberExpr>(E))
- D = ME->getMemberDecl();
-
- if (D) {
- for (const auto *I : D->specific_attrs<AlignedAttr>()) {
- if (I->isAlignmentDependent()) {
- setValueDependent(true);
- setInstantiationDependent(true);
- break;
- }
- }
- }
- }
- }
+ setDependence(computeDependence(this));
}
MemberExpr::MemberExpr(Expr *Base, bool IsArrow, SourceLocation OperatorLoc,
@@ -1644,11 +1551,8 @@ MemberExpr::MemberExpr(Expr *Base, bool IsArrow, SourceLocation OperatorLoc,
const DeclarationNameInfo &NameInfo, QualType T,
ExprValueKind VK, ExprObjectKind OK,
NonOdrUseReason NOUR)
- : Expr(MemberExprClass, T, VK, OK, Base->isTypeDependent(),
- Base->isValueDependent(), Base->isInstantiationDependent(),
- Base->containsUnexpandedParameterPack()),
- Base(Base), MemberDecl(MemberDecl), MemberDNLoc(NameInfo.getInfo()),
- MemberLoc(NameInfo.getLoc()) {
+ : Expr(MemberExprClass, T, VK, OK), Base(Base), MemberDecl(MemberDecl),
+ MemberDNLoc(NameInfo.getInfo()), MemberLoc(NameInfo.getLoc()) {
assert(!NameInfo.getName() ||
MemberDecl->getDeclName() == NameInfo.getName());
MemberExprBits.IsArrow = IsArrow;
@@ -1657,6 +1561,7 @@ MemberExpr::MemberExpr(Expr *Base, bool IsArrow, SourceLocation OperatorLoc,
MemberExprBits.HadMultipleCandidates = false;
MemberExprBits.NonOdrUseReason = NOUR;
MemberExprBits.OperatorLoc = OperatorLoc;
+ setDependence(computeDependence(this));
}
MemberExpr *MemberExpr::Create(
@@ -1678,25 +1583,15 @@ MemberExpr *MemberExpr::Create(
MemberExpr *E = new (Mem) MemberExpr(Base, IsArrow, OperatorLoc, MemberDecl,
NameInfo, T, VK, OK, NOUR);
- if (isa<FieldDecl>(MemberDecl)) {
- DeclContext *DC = MemberDecl->getDeclContext();
- // dyn_cast_or_null is used to handle objC variables which do not
- // have a declaration context.
- CXXRecordDecl *RD = dyn_cast_or_null<CXXRecordDecl>(DC);
- if (RD && RD->isDependentContext() && RD->isCurrentInstantiation(DC))
- E->setTypeDependent(T->isDependentType());
- }
-
+ // 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()) {
- E->setValueDependent(true);
- E->setTypeDependent(true);
- E->setInstantiationDependent(true);
- }
+ if (QualifierLoc && QualifierLoc.getNestedNameSpecifier()->isDependent())
+ Deps |= ExprDependence::TypeValueInstantiation;
else if (QualifierLoc &&
QualifierLoc.getNestedNameSpecifier()->isInstantiationDependent())
- E->setInstantiationDependent(true);
+ Deps |= ExprDependence::Instantiation;
E->MemberExprBits.HasQualifierOrFoundDecl = true;
@@ -1710,19 +1605,17 @@ MemberExpr *MemberExpr::Create(
TemplateArgs || TemplateKWLoc.isValid();
if (TemplateArgs) {
- bool Dependent = false;
- bool InstantiationDependent = false;
- bool ContainsUnexpandedParameterPack = false;
+ auto TemplateArgDeps = TemplateArgumentDependence::None;
E->getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom(
TemplateKWLoc, *TemplateArgs,
- E->getTrailingObjects<TemplateArgumentLoc>(), Dependent,
- InstantiationDependent, ContainsUnexpandedParameterPack);
- if (InstantiationDependent)
- E->setInstantiationDependent(true);
+ E->getTrailingObjects<TemplateArgumentLoc>(), TemplateArgDeps);
+ if (TemplateArgDeps & TemplateArgumentDependence::Instantiation)
+ Deps |= ExprDependence::Instantiation;
} else if (TemplateKWLoc.isValid()) {
E->getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom(
TemplateKWLoc);
}
+ E->setDependence(Deps);
return E;
}
@@ -1823,12 +1716,13 @@ bool CastExpr::CastConsistency() const {
auto Ty = getType();
auto SETy = getSubExpr()->getType();
assert(getValueKindForType(Ty) == Expr::getValueKindForType(SETy));
- if (isRValue()) {
+ if (isRValue() && !Ty->isDependentType() && !SETy->isDependentType()) {
Ty = Ty->getPointeeType();
SETy = SETy->getPointeeType();
}
- assert(!Ty.isNull() && !SETy.isNull() &&
- Ty.getAddressSpace() != SETy.getAddressSpace());
+ assert((Ty->isDependentType() || SETy->isDependentType()) ||
+ (!Ty.isNull() && !SETy.isNull() &&
+ Ty.getAddressSpace() != SETy.getAddressSpace()));
goto CheckNoBasePath;
}
// These should not have an inheritance path.
@@ -2163,9 +2057,10 @@ SourceLocExpr::SourceLocExpr(const ASTContext &Ctx, IdentKind Kind,
SourceLocation BLoc, SourceLocation RParenLoc,
DeclContext *ParentContext)
: Expr(SourceLocExprClass, getDecayedSourceLocExprType(Ctx, Kind),
- VK_RValue, OK_Ordinary, false, false, false, false),
+ VK_RValue, OK_Ordinary),
BuiltinLoc(BLoc), RParenLoc(RParenLoc), ParentContext(ParentContext) {
SourceLocExprBits.Kind = Kind;
+ setDependence(ExprDependence::None);
}
StringRef SourceLocExpr::getBuiltinStr() const {
@@ -2229,25 +2124,14 @@ 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, false, false,
- false, false),
- InitExprs(C, initExprs.size()),
- LBraceLoc(lbraceloc), RBraceLoc(rbraceloc), AltForm(nullptr, true)
-{
+ ArrayRef<Expr *> initExprs, SourceLocation rbraceloc)
+ : Expr(InitListExprClass, QualType(), VK_RValue, OK_Ordinary),
+ InitExprs(C, initExprs.size()), LBraceLoc(lbraceloc),
+ RBraceLoc(rbraceloc), AltForm(nullptr, true) {
sawArrayRangeDesignator(false);
- for (unsigned I = 0; I != initExprs.size(); ++I) {
- if (initExprs[I]->isTypeDependent())
- ExprBits.TypeDependent = true;
- if (initExprs[I]->isValueDependent())
- ExprBits.ValueDependent = true;
- if (initExprs[I]->isInstantiationDependent())
- ExprBits.InstantiationDependent = true;
- if (initExprs[I]->containsUnexpandedParameterPack())
- ExprBits.ContainsUnexpandedParameterPack = true;
- }
-
InitExprs.insert(C, InitExprs.end(), initExprs.begin(), initExprs.end());
+
+ setDependence(computeDependence(this));
}
void InitListExpr::reserveInits(const ASTContext &C, unsigned NumInits) {
@@ -2388,6 +2272,64 @@ Stmt *BlockExpr::getBody() {
// Generic Expression Routines
//===----------------------------------------------------------------------===//
+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
+ // one of the following forms:
+ if (!isGLValue() || !getType().isVolatileQualified())
+ return false;
+
+ const Expr *E = IgnoreParens();
+
+ // - id-expression (5.1.1),
+ if (isa<DeclRefExpr>(E))
+ return true;
+
+ // - subscripting (5.2.1),
+ if (isa<ArraySubscriptExpr>(E))
+ return true;
+
+ // - class member access (5.2.5),
+ if (isa<MemberExpr>(E))
+ return true;
+
+ // - indirection (5.3.1),
+ if (auto *UO = dyn_cast<UnaryOperator>(E))
+ if (UO->getOpcode() == UO_Deref)
+ return true;
+
+ if (auto *BO = dyn_cast<BinaryOperator>(E)) {
+ // - pointer-to-member operation (5.5),
+ if (BO->isPtrMemOp())
+ return true;
+
+ // - comma expression (5.18) where the right operand is one of the above.
+ if (BO->getOpcode() == BO_Comma)
+ return BO->getRHS()->isReadIfDiscardedInCPlusPlus11();
+ }
+
+ // - conditional expression (5.16) where both the second and the third
+ // operands are one of the above, or
+ if (auto *CO = dyn_cast<ConditionalOperator>(E))
+ return CO->getTrueExpr()->isReadIfDiscardedInCPlusPlus11() &&
+ CO->getFalseExpr()->isReadIfDiscardedInCPlusPlus11();
+ // The related edge case of "*x ?: *x".
+ if (auto *BCO =
+ dyn_cast<BinaryConditionalOperator>(E)) {
+ if (auto *OVE = dyn_cast<OpaqueValueExpr>(BCO->getTrueExpr()))
+ return OVE->getSourceExpr()->isReadIfDiscardedInCPlusPlus11() &&
+ BCO->getFalseExpr()->isReadIfDiscardedInCPlusPlus11();
+ }
+
+ // Objective-C++ extensions to the rule.
+ if (isa<PseudoObjectExpr>(E) || isa<ObjCIvarRefExpr>(E))
+ return true;
+
+ return false;
+}
+
/// isUnusedResultAWarning - Return true if this immediate expression should
/// be warned about if the result is unused. If so, fill in Loc and Ranges
/// with location to warn on and the source range[s] to report with the
@@ -2576,6 +2518,7 @@ bool Expr::isUnusedResultAWarning(const Expr *&WarnE, SourceLocation &Loc,
// If we don't know precisely what we're looking at, let's not warn.
case UnresolvedLookupExprClass:
case CXXUnresolvedConstructExprClass:
+ case RecoveryExprClass:
return false;
case CXXTemporaryObjectExprClass:
@@ -2675,20 +2618,31 @@ bool Expr::isUnusedResultAWarning(const Expr *&WarnE, SourceLocation &Loc,
}
case CXXFunctionalCastExprClass:
case CStyleCastExprClass: {
- // Ignore an explicit cast to void unless the operand is a non-trivial
- // volatile lvalue.
+ // Ignore an explicit cast to void, except in C++98 if the operand is a
+ // volatile glvalue for which we would trigger an implicit read in any
+ // other language mode. (Such an implicit read always happens as part of
+ // the lvalue conversion in C, and happens in C++ for expressions of all
+ // forms where it seems likely the user intended to trigger a volatile
+ // load.)
const CastExpr *CE = cast<CastExpr>(this);
+ const Expr *SubE = CE->getSubExpr()->IgnoreParens();
if (CE->getCastKind() == CK_ToVoid) {
- if (CE->getSubExpr()->isGLValue() &&
- CE->getSubExpr()->getType().isVolatileQualified()) {
- const DeclRefExpr *DRE =
- dyn_cast<DeclRefExpr>(CE->getSubExpr()->IgnoreParens());
- if (!(DRE && isa<VarDecl>(DRE->getDecl()) &&
- cast<VarDecl>(DRE->getDecl())->hasLocalStorage()) &&
- !isa<CallExpr>(CE->getSubExpr()->IgnoreParens())) {
- return CE->getSubExpr()->isUnusedResultAWarning(WarnE, Loc,
- R1, R2, Ctx);
- }
+ if (Ctx.getLangOpts().CPlusPlus && !Ctx.getLangOpts().CPlusPlus11 &&
+ SubE->isReadIfDiscardedInCPlusPlus11()) {
+ // Suppress the "unused value" warning for idiomatic usage of
+ // '(void)var;' used to suppress "unused variable" warnings.
+ if (auto *DRE = dyn_cast<DeclRefExpr>(SubE))
+ if (auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
+ if (!VD->isExternallyVisible())
+ return false;
+
+ // The lvalue-to-rvalue conversion would have no effect for an array.
+ // It's implausible that the programmer expected this to result in a
+ // volatile array load, so don't warn.
+ if (SubE->getType()->isArrayType())
+ return false;
+
+ return SubE->isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx);
}
return false;
}
@@ -2900,6 +2854,12 @@ static Expr *IgnoreImplicitAsWrittenSingleStep(Expr *E) {
return IgnoreImplicitSingleStep(E);
}
+static Expr *IgnoreParensOnlySingleStep(Expr *E) {
+ if (auto *PE = dyn_cast<ParenExpr>(E))
+ return PE->getSubExpr();
+ return E;
+}
+
static Expr *IgnoreParensSingleStep(Expr *E) {
if (auto *PE = dyn_cast<ParenExpr>(E))
return PE->getSubExpr();
@@ -2919,9 +2879,6 @@ static Expr *IgnoreParensSingleStep(Expr *E) {
return CE->getChosenSubExpr();
}
- else if (auto *CE = dyn_cast<ConstantExpr>(E))
- return CE->getSubExpr();
-
return E;
}
@@ -3026,12 +2983,16 @@ Expr *Expr::IgnoreUnlessSpelledInSource() {
Expr *LastE = nullptr;
while (E != LastE) {
LastE = E;
- E = E->IgnoreParenImpCasts();
+ E = IgnoreExprNodes(E, IgnoreImplicitSingleStep,
+ IgnoreImpCastsExtraSingleStep,
+ IgnoreParensOnlySingleStep);
auto SR = E->getSourceRange();
if (auto *C = dyn_cast<CXXConstructExpr>(E)) {
- if (C->getNumArgs() == 1) {
+ auto NumArgs = C->getNumArgs();
+ if (NumArgs == 1 ||
+ (NumArgs > 1 && isa<CXXDefaultArgExpr>(C->getArg(1)))) {
Expr *A = C->getArg(0);
if (A->getSourceRange() == SR || !isa<CXXTemporaryObjectExpr>(C))
E = A;
@@ -3039,7 +3000,18 @@ Expr *Expr::IgnoreUnlessSpelledInSource() {
}
if (auto *C = dyn_cast<CXXMemberCallExpr>(E)) {
- Expr *ExprNode = C->getImplicitObjectArgument()->IgnoreParenImpCasts();
+ Expr *ExprNode = C->getImplicitObjectArgument();
+ if (ExprNode->getSourceRange() == SR) {
+ E = ExprNode;
+ continue;
+ }
+ if (auto *PE = dyn_cast<ParenExpr>(ExprNode)) {
+ if (PE->getSourceRange() == C->getSourceRange()) {
+ E = PE;
+ continue;
+ }
+ }
+ ExprNode = ExprNode->IgnoreParenImpCasts();
if (ExprNode->getSourceRange() == SR)
E = ExprNode;
}
@@ -3206,6 +3178,9 @@ bool Expr::isConstantInitializer(ASTContext &Ctx, bool IsForRef,
switch (getStmtClass()) {
default: break;
+ case Stmt::ExprWithCleanupsClass:
+ return cast<ExprWithCleanups>(this)->getSubExpr()->isConstantInitializer(
+ Ctx, IsForRef, Culprit);
case StringLiteralClass:
case ObjCEncodeExprClass:
return true;
@@ -3319,6 +3294,7 @@ bool Expr::isConstantInitializer(ASTContext &Ctx, bool IsForRef,
case ObjCBridgedCastExprClass:
case CXXDynamicCastExprClass:
case CXXReinterpretCastExprClass:
+ case CXXAddrspaceCastExprClass:
case CXXConstCastExprClass: {
const CastExpr *CE = cast<CastExpr>(this);
@@ -3385,6 +3361,26 @@ namespace {
bool hasSideEffects() const { return HasSideEffects; }
+ void VisitDecl(const Decl *D) {
+ if (!D)
+ return;
+
+ // We assume the caller checks subexpressions (eg, the initializer, VLA
+ // bounds) for side-effects on our behalf.
+ if (auto *VD = dyn_cast<VarDecl>(D)) {
+ // Registering a destructor is a side-effect.
+ if (IncludePossibleEffects && VD->isThisDeclarationADefinition() &&
+ VD->needsDestruction(Context))
+ HasSideEffects = true;
+ }
+ }
+
+ void VisitDeclStmt(const DeclStmt *DS) {
+ for (auto *D : DS->decls())
+ VisitDecl(D);
+ Inherited::VisitDeclStmt(DS);
+ }
+
void VisitExpr(const Expr *E) {
if (!HasSideEffects &&
E->HasSideEffects(Context, IncludePossibleEffects))
@@ -3421,6 +3417,7 @@ bool Expr::HasSideEffects(const ASTContext &Ctx,
case SubstNonTypeTemplateParmPackExprClass:
case FunctionParmPackExprClass:
case TypoExprClass:
+ case RecoveryExprClass:
case CXXFoldExprClass:
llvm_unreachable("shouldn't see dependent / unresolved nodes here");
@@ -3457,6 +3454,7 @@ bool Expr::HasSideEffects(const ASTContext &Ctx,
case OpaqueValueExprClass:
case SourceLocExprClass:
case ConceptSpecializationExprClass:
+ case RequiresExprClass:
// These never have a side-effect.
return false;
@@ -3515,7 +3513,10 @@ bool Expr::HasSideEffects(const ASTContext &Ctx,
case ParenExprClass:
case ArraySubscriptExprClass:
+ case MatrixSubscriptExprClass:
case OMPArraySectionExprClass:
+ case OMPArrayShapingExprClass:
+ case OMPIteratorExprClass:
case MemberExprClass:
case ConditionalOperatorClass:
case BinaryConditionalOperatorClass:
@@ -3586,6 +3587,7 @@ bool Expr::HasSideEffects(const ASTContext &Ctx,
case CXXStaticCastExprClass:
case CXXReinterpretCastExprClass:
case CXXConstCastExprClass:
+ case CXXAddrspaceCastExprClass:
case CXXFunctionalCastExprClass:
case BuiltinBitCastExprClass: {
// While volatile reads are side-effecting in both C and C++, we treat them
@@ -3627,7 +3629,7 @@ bool Expr::HasSideEffects(const ASTContext &Ctx,
case LambdaExprClass: {
const LambdaExpr *LE = cast<LambdaExpr>(this);
for (Expr *E : LE->capture_inits())
- if (E->HasSideEffects(Ctx, IncludePossibleEffects))
+ if (E && E->HasSideEffects(Ctx, IncludePossibleEffects))
return true;
return false;
}
@@ -3810,6 +3812,11 @@ Expr::isNullPointerConstant(ASTContext &Ctx,
return Source->isNullPointerConstant(Ctx, NPC);
}
+ // If the expression has no type information, it cannot be a null pointer
+ // constant.
+ if (getType().isNull())
+ return NPCK_NotNull;
+
// C++11 nullptr_t is always a null pointer constant.
if (getType()->isNullPtrType())
return NPCK_CXX11_nullptr;
@@ -4148,28 +4155,16 @@ void ExtVectorElementExpr::getEncodedElementAccess(
}
}
-ShuffleVectorExpr::ShuffleVectorExpr(const ASTContext &C, ArrayRef<Expr*> args,
+ShuffleVectorExpr::ShuffleVectorExpr(const ASTContext &C, ArrayRef<Expr *> args,
QualType Type, SourceLocation BLoc,
SourceLocation RP)
- : Expr(ShuffleVectorExprClass, Type, VK_RValue, OK_Ordinary,
- Type->isDependentType(), Type->isDependentType(),
- Type->isInstantiationDependentType(),
- Type->containsUnexpandedParameterPack()),
- BuiltinLoc(BLoc), RParenLoc(RP), NumExprs(args.size())
-{
+ : Expr(ShuffleVectorExprClass, Type, VK_RValue, OK_Ordinary),
+ BuiltinLoc(BLoc), RParenLoc(RP), NumExprs(args.size()) {
SubExprs = new (C) Stmt*[args.size()];
- for (unsigned i = 0; i != args.size(); i++) {
- if (args[i]->isTypeDependent())
- ExprBits.TypeDependent = true;
- if (args[i]->isValueDependent())
- ExprBits.ValueDependent = true;
- if (args[i]->isInstantiationDependent())
- ExprBits.InstantiationDependent = true;
- if (args[i]->containsUnexpandedParameterPack())
- ExprBits.ContainsUnexpandedParameterPack = true;
-
+ for (unsigned i = 0; i != args.size(); i++)
SubExprs[i] = args[i];
- }
+
+ setDependence(computeDependence(this));
}
void ShuffleVectorExpr::setExprs(const ASTContext &C, ArrayRef<Expr *> Exprs) {
@@ -4187,11 +4182,7 @@ GenericSelectionExpr::GenericSelectionExpr(
bool ContainsUnexpandedParameterPack, unsigned ResultIndex)
: Expr(GenericSelectionExprClass, AssocExprs[ResultIndex]->getType(),
AssocExprs[ResultIndex]->getValueKind(),
- AssocExprs[ResultIndex]->getObjectKind(),
- AssocExprs[ResultIndex]->isTypeDependent(),
- AssocExprs[ResultIndex]->isValueDependent(),
- AssocExprs[ResultIndex]->isInstantiationDependent(),
- ContainsUnexpandedParameterPack),
+ AssocExprs[ResultIndex]->getObjectKind()),
NumAssocs(AssocExprs.size()), ResultIndex(ResultIndex),
DefaultLoc(DefaultLoc), RParenLoc(RParenLoc) {
assert(AssocTypes.size() == AssocExprs.size() &&
@@ -4205,6 +4196,8 @@ GenericSelectionExpr::GenericSelectionExpr(
getTrailingObjects<Stmt *>() + AssocExprStartIndex);
std::copy(AssocTypes.begin(), AssocTypes.end(),
getTrailingObjects<TypeSourceInfo *>());
+
+ setDependence(computeDependence(this, ContainsUnexpandedParameterPack));
}
GenericSelectionExpr::GenericSelectionExpr(
@@ -4213,10 +4206,7 @@ GenericSelectionExpr::GenericSelectionExpr(
SourceLocation DefaultLoc, SourceLocation RParenLoc,
bool ContainsUnexpandedParameterPack)
: Expr(GenericSelectionExprClass, Context.DependentTy, VK_RValue,
- OK_Ordinary,
- /*isTypeDependent=*/true,
- /*isValueDependent=*/true,
- /*isInstantiationDependent=*/true, ContainsUnexpandedParameterPack),
+ OK_Ordinary),
NumAssocs(AssocExprs.size()), ResultIndex(ResultDependentIndex),
DefaultLoc(DefaultLoc), RParenLoc(RParenLoc) {
assert(AssocTypes.size() == AssocExprs.size() &&
@@ -4229,6 +4219,8 @@ GenericSelectionExpr::GenericSelectionExpr(
getTrailingObjects<Stmt *>() + AssocExprStartIndex);
std::copy(AssocTypes.begin(), AssocTypes.end(),
getTrailingObjects<TypeSourceInfo *>());
+
+ setDependence(computeDependence(this, ContainsUnexpandedParameterPack));
}
GenericSelectionExpr::GenericSelectionExpr(EmptyShell Empty, unsigned NumAssocs)
@@ -4287,15 +4279,11 @@ DesignatedInitExpr::DesignatedInitExpr(const ASTContext &C, QualType Ty,
llvm::ArrayRef<Designator> Designators,
SourceLocation EqualOrColonLoc,
bool GNUSyntax,
- ArrayRef<Expr*> IndexExprs,
- Expr *Init)
- : Expr(DesignatedInitExprClass, Ty,
- Init->getValueKind(), Init->getObjectKind(),
- Init->isTypeDependent(), Init->isValueDependent(),
- Init->isInstantiationDependent(),
- Init->containsUnexpandedParameterPack()),
- EqualOrColonLoc(EqualOrColonLoc), GNUSyntax(GNUSyntax),
- NumDesignators(Designators.size()), NumSubExprs(IndexExprs.size() + 1) {
+ ArrayRef<Expr *> IndexExprs, Expr *Init)
+ : Expr(DesignatedInitExprClass, Ty, Init->getValueKind(),
+ Init->getObjectKind()),
+ EqualOrColonLoc(EqualOrColonLoc), GNUSyntax(GNUSyntax),
+ NumDesignators(Designators.size()), NumSubExprs(IndexExprs.size() + 1) {
this->Designators = new (C) Designator[NumDesignators];
// Record the initializer itself.
@@ -4307,38 +4295,10 @@ DesignatedInitExpr::DesignatedInitExpr(const ASTContext &C, QualType Ty,
unsigned IndexIdx = 0;
for (unsigned I = 0; I != NumDesignators; ++I) {
this->Designators[I] = Designators[I];
-
if (this->Designators[I].isArrayDesignator()) {
- // Compute type- and value-dependence.
- Expr *Index = IndexExprs[IndexIdx];
- if (Index->isTypeDependent() || Index->isValueDependent())
- ExprBits.TypeDependent = ExprBits.ValueDependent = true;
- if (Index->isInstantiationDependent())
- ExprBits.InstantiationDependent = true;
- // Propagate unexpanded parameter packs.
- if (Index->containsUnexpandedParameterPack())
- ExprBits.ContainsUnexpandedParameterPack = true;
-
// Copy the index expressions into permanent storage.
*Child++ = IndexExprs[IndexIdx++];
} else if (this->Designators[I].isArrayRangeDesignator()) {
- // Compute type- and value-dependence.
- Expr *Start = IndexExprs[IndexIdx];
- Expr *End = IndexExprs[IndexIdx + 1];
- if (Start->isTypeDependent() || Start->isValueDependent() ||
- End->isTypeDependent() || End->isValueDependent()) {
- ExprBits.TypeDependent = ExprBits.ValueDependent = true;
- ExprBits.InstantiationDependent = true;
- } else if (Start->isInstantiationDependent() ||
- End->isInstantiationDependent()) {
- ExprBits.InstantiationDependent = true;
- }
-
- // Propagate unexpanded parameter packs.
- if (Start->containsUnexpandedParameterPack() ||
- End->containsUnexpandedParameterPack())
- ExprBits.ContainsUnexpandedParameterPack = true;
-
// Copy the start/end expressions into permanent storage.
*Child++ = IndexExprs[IndexIdx++];
*Child++ = IndexExprs[IndexIdx++];
@@ -4346,6 +4306,7 @@ DesignatedInitExpr::DesignatedInitExpr(const ASTContext &C, QualType Ty,
}
assert(IndexIdx == IndexExprs.size() && "Wrong number of index expressions");
+ setDependence(computeDependence(this));
}
DesignatedInitExpr *
@@ -4449,14 +4410,19 @@ void DesignatedInitExpr::ExpandDesignator(const ASTContext &C, unsigned Idx,
}
DesignatedInitUpdateExpr::DesignatedInitUpdateExpr(const ASTContext &C,
- SourceLocation lBraceLoc, Expr *baseExpr, SourceLocation rBraceLoc)
- : Expr(DesignatedInitUpdateExprClass, baseExpr->getType(), VK_RValue,
- OK_Ordinary, false, false, false, false) {
+ SourceLocation lBraceLoc,
+ Expr *baseExpr,
+ SourceLocation rBraceLoc)
+ : Expr(DesignatedInitUpdateExprClass, baseExpr->getType(), VK_RValue,
+ OK_Ordinary) {
BaseAndUpdaterExprs[0] = baseExpr;
InitListExpr *ILE = new (C) InitListExpr(C, lBraceLoc, None, rBraceLoc);
ILE->setType(baseExpr->getType());
BaseAndUpdaterExprs[1] = ILE;
+
+ // FIXME: this is wrong, set it correctly.
+ setDependence(ExprDependence::None);
}
SourceLocation DesignatedInitUpdateExpr::getBeginLoc() const {
@@ -4469,23 +4435,13 @@ SourceLocation DesignatedInitUpdateExpr::getEndLoc() const {
ParenListExpr::ParenListExpr(SourceLocation LParenLoc, ArrayRef<Expr *> Exprs,
SourceLocation RParenLoc)
- : Expr(ParenListExprClass, QualType(), VK_RValue, OK_Ordinary, false, false,
- false, false),
+ : Expr(ParenListExprClass, QualType(), VK_RValue, OK_Ordinary),
LParenLoc(LParenLoc), RParenLoc(RParenLoc) {
ParenListExprBits.NumExprs = Exprs.size();
- for (unsigned I = 0, N = Exprs.size(); I != N; ++I) {
- if (Exprs[I]->isTypeDependent())
- ExprBits.TypeDependent = true;
- if (Exprs[I]->isValueDependent())
- ExprBits.ValueDependent = true;
- if (Exprs[I]->isInstantiationDependent())
- ExprBits.InstantiationDependent = true;
- if (Exprs[I]->containsUnexpandedParameterPack())
- ExprBits.ContainsUnexpandedParameterPack = true;
-
+ for (unsigned I = 0, N = Exprs.size(); I != N; ++I)
getTrailingObjects<Stmt *>()[I] = Exprs[I];
- }
+ setDependence(computeDependence(this));
}
ParenListExpr::ParenListExpr(EmptyShell Empty, unsigned NumExprs)
@@ -4509,6 +4465,115 @@ ParenListExpr *ParenListExpr::CreateEmpty(const ASTContext &Ctx,
return new (Mem) ParenListExpr(EmptyShell(), NumExprs);
}
+BinaryOperator::BinaryOperator(const ASTContext &Ctx, Expr *lhs, Expr *rhs,
+ Opcode opc, QualType ResTy, ExprValueKind VK,
+ ExprObjectKind OK, SourceLocation opLoc,
+ FPOptionsOverride FPFeatures)
+ : Expr(BinaryOperatorClass, ResTy, VK, OK) {
+ BinaryOperatorBits.Opc = opc;
+ assert(!isCompoundAssignmentOp() &&
+ "Use CompoundAssignOperator for compound assignments");
+ BinaryOperatorBits.OpLoc = opLoc;
+ SubExprs[LHS] = lhs;
+ SubExprs[RHS] = rhs;
+ BinaryOperatorBits.HasFPFeatures = FPFeatures.requiresTrailingStorage();
+ if (BinaryOperatorBits.HasFPFeatures)
+ *getTrailingFPFeatures() = FPFeatures;
+ setDependence(computeDependence(this));
+}
+
+BinaryOperator::BinaryOperator(const ASTContext &Ctx, Expr *lhs, Expr *rhs,
+ Opcode opc, QualType ResTy, ExprValueKind VK,
+ ExprObjectKind OK, SourceLocation opLoc,
+ FPOptionsOverride FPFeatures, bool dead2)
+ : Expr(CompoundAssignOperatorClass, ResTy, VK, OK) {
+ BinaryOperatorBits.Opc = opc;
+ assert(isCompoundAssignmentOp() &&
+ "Use CompoundAssignOperator for compound assignments");
+ BinaryOperatorBits.OpLoc = opLoc;
+ SubExprs[LHS] = lhs;
+ SubExprs[RHS] = rhs;
+ BinaryOperatorBits.HasFPFeatures = FPFeatures.requiresTrailingStorage();
+ if (BinaryOperatorBits.HasFPFeatures)
+ *getTrailingFPFeatures() = FPFeatures;
+ setDependence(computeDependence(this));
+}
+
+BinaryOperator *BinaryOperator::CreateEmpty(const ASTContext &C,
+ bool HasFPFeatures) {
+ unsigned Extra = sizeOfTrailingObjects(HasFPFeatures);
+ void *Mem =
+ C.Allocate(sizeof(BinaryOperator) + Extra, alignof(BinaryOperator));
+ return new (Mem) BinaryOperator(EmptyShell());
+}
+
+BinaryOperator *BinaryOperator::Create(const ASTContext &C, Expr *lhs,
+ Expr *rhs, Opcode opc, QualType ResTy,
+ ExprValueKind VK, ExprObjectKind OK,
+ SourceLocation opLoc,
+ FPOptionsOverride FPFeatures) {
+ bool HasFPFeatures = FPFeatures.requiresTrailingStorage();
+ unsigned Extra = sizeOfTrailingObjects(HasFPFeatures);
+ void *Mem =
+ C.Allocate(sizeof(BinaryOperator) + Extra, alignof(BinaryOperator));
+ return new (Mem)
+ BinaryOperator(C, lhs, rhs, opc, ResTy, VK, OK, opLoc, FPFeatures);
+}
+
+CompoundAssignOperator *
+CompoundAssignOperator::CreateEmpty(const ASTContext &C, bool HasFPFeatures) {
+ unsigned Extra = sizeOfTrailingObjects(HasFPFeatures);
+ void *Mem = C.Allocate(sizeof(CompoundAssignOperator) + Extra,
+ alignof(CompoundAssignOperator));
+ return new (Mem) CompoundAssignOperator(C, EmptyShell(), HasFPFeatures);
+}
+
+CompoundAssignOperator *
+CompoundAssignOperator::Create(const ASTContext &C, Expr *lhs, Expr *rhs,
+ Opcode opc, QualType ResTy, ExprValueKind VK,
+ ExprObjectKind OK, SourceLocation opLoc,
+ FPOptionsOverride FPFeatures,
+ QualType CompLHSType, QualType CompResultType) {
+ bool HasFPFeatures = FPFeatures.requiresTrailingStorage();
+ unsigned Extra = sizeOfTrailingObjects(HasFPFeatures);
+ void *Mem = C.Allocate(sizeof(CompoundAssignOperator) + Extra,
+ alignof(CompoundAssignOperator));
+ return new (Mem)
+ CompoundAssignOperator(C, lhs, rhs, opc, ResTy, VK, OK, opLoc, FPFeatures,
+ CompLHSType, CompResultType);
+}
+
+UnaryOperator *UnaryOperator::CreateEmpty(const ASTContext &C,
+ bool hasFPFeatures) {
+ void *Mem = C.Allocate(totalSizeToAlloc<FPOptionsOverride>(hasFPFeatures),
+ alignof(UnaryOperator));
+ return new (Mem) UnaryOperator(hasFPFeatures, EmptyShell());
+}
+
+UnaryOperator::UnaryOperator(const ASTContext &Ctx, Expr *input, Opcode opc,
+ QualType type, ExprValueKind VK, ExprObjectKind OK,
+ SourceLocation l, bool CanOverflow,
+ FPOptionsOverride FPFeatures)
+ : Expr(UnaryOperatorClass, type, VK, OK), Val(input) {
+ UnaryOperatorBits.Opc = opc;
+ UnaryOperatorBits.CanOverflow = CanOverflow;
+ UnaryOperatorBits.Loc = l;
+ UnaryOperatorBits.HasFPFeatures = FPFeatures.requiresTrailingStorage();
+ setDependence(computeDependence(this));
+}
+
+UnaryOperator *UnaryOperator::Create(const ASTContext &C, Expr *input,
+ Opcode opc, QualType type,
+ ExprValueKind VK, ExprObjectKind OK,
+ SourceLocation l, bool CanOverflow,
+ FPOptionsOverride FPFeatures) {
+ bool HasFPFeatures = FPFeatures.requiresTrailingStorage();
+ unsigned Size = totalSizeToAlloc<FPOptionsOverride>(HasFPFeatures);
+ void *Mem = C.Allocate(Size, alignof(UnaryOperator));
+ return new (Mem)
+ UnaryOperator(C, input, opc, type, VK, OK, l, CanOverflow, FPFeatures);
+}
+
const OpaqueValueExpr *OpaqueValueExpr::findInCopyConstruct(const Expr *e) {
if (const ExprWithCleanups *ewc = dyn_cast<ExprWithCleanups>(e))
e = ewc->getSubExpr();
@@ -4559,10 +4624,9 @@ PseudoObjectExpr *PseudoObjectExpr::Create(const ASTContext &C, Expr *syntax,
}
PseudoObjectExpr::PseudoObjectExpr(QualType type, ExprValueKind VK,
- Expr *syntax, ArrayRef<Expr*> semantics,
+ Expr *syntax, ArrayRef<Expr *> semantics,
unsigned resultIndex)
- : Expr(PseudoObjectExprClass, type, VK, OK_Ordinary,
- /*filled in at end of ctor*/ false, false, false, false) {
+ : Expr(PseudoObjectExprClass, type, VK, OK_Ordinary) {
PseudoObjectExprBits.NumSubExprs = semantics.size() + 1;
PseudoObjectExprBits.ResultIndex = resultIndex + 1;
@@ -4570,20 +4634,13 @@ PseudoObjectExpr::PseudoObjectExpr(QualType type, ExprValueKind VK,
Expr *E = (i == 0 ? syntax : semantics[i-1]);
getSubExprsBuffer()[i] = E;
- if (E->isTypeDependent())
- ExprBits.TypeDependent = true;
- if (E->isValueDependent())
- ExprBits.ValueDependent = true;
- if (E->isInstantiationDependent())
- ExprBits.InstantiationDependent = true;
- if (E->containsUnexpandedParameterPack())
- ExprBits.ContainsUnexpandedParameterPack = true;
-
if (isa<OpaqueValueExpr>(E))
assert(cast<OpaqueValueExpr>(E)->getSourceExpr() != nullptr &&
"opaque-value semantic expressions for pseudo-object "
"operations must have sources");
}
+
+ setDependence(computeDependence(this));
}
//===----------------------------------------------------------------------===//
@@ -4610,25 +4667,14 @@ Stmt::const_child_range UnaryExprOrTypeTraitExpr::children() const {
return const_child_range(&Argument.Ex, &Argument.Ex + 1);
}
-AtomicExpr::AtomicExpr(SourceLocation BLoc, ArrayRef<Expr*> args,
- QualType t, AtomicOp op, SourceLocation RP)
- : Expr(AtomicExprClass, t, VK_RValue, OK_Ordinary,
- false, false, false, false),
- NumSubExprs(args.size()), BuiltinLoc(BLoc), RParenLoc(RP), Op(op)
-{
+AtomicExpr::AtomicExpr(SourceLocation BLoc, ArrayRef<Expr *> args, QualType t,
+ AtomicOp op, SourceLocation RP)
+ : Expr(AtomicExprClass, t, VK_RValue, 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++) {
- if (args[i]->isTypeDependent())
- ExprBits.TypeDependent = true;
- if (args[i]->isValueDependent())
- ExprBits.ValueDependent = true;
- if (args[i]->isInstantiationDependent())
- ExprBits.InstantiationDependent = true;
- if (args[i]->containsUnexpandedParameterPack())
- ExprBits.ContainsUnexpandedParameterPack = true;
-
+ for (unsigned i = 0; i != args.size(); i++)
SubExprs[i] = args[i];
- }
+ setDependence(computeDependence(this));
}
unsigned AtomicExpr::getNumSubExprs(AtomicOp Op) {
@@ -4730,3 +4776,211 @@ QualType OMPArraySectionExpr::getBaseOriginalType(const Expr *Base) {
}
return OriginalTy;
}
+
+RecoveryExpr::RecoveryExpr(ASTContext &Ctx, QualType T, SourceLocation BeginLoc,
+ SourceLocation EndLoc, ArrayRef<Expr *> SubExprs)
+ : Expr(RecoveryExprClass, T.getNonReferenceType(),
+ T->isDependentType() ? VK_LValue : getValueKindForType(T),
+ OK_Ordinary),
+ BeginLoc(BeginLoc), EndLoc(EndLoc), NumExprs(SubExprs.size()) {
+ assert(!T.isNull());
+ assert(llvm::all_of(SubExprs, [](Expr* E) { return E != nullptr; }));
+
+ llvm::copy(SubExprs, getTrailingObjects<Expr *>());
+ setDependence(computeDependence(this));
+}
+
+RecoveryExpr *RecoveryExpr::Create(ASTContext &Ctx, QualType T,
+ SourceLocation BeginLoc,
+ SourceLocation EndLoc,
+ ArrayRef<Expr *> SubExprs) {
+ void *Mem = Ctx.Allocate(totalSizeToAlloc<Expr *>(SubExprs.size()),
+ alignof(RecoveryExpr));
+ return new (Mem) RecoveryExpr(Ctx, T, BeginLoc, EndLoc, SubExprs);
+}
+
+RecoveryExpr *RecoveryExpr::CreateEmpty(ASTContext &Ctx, unsigned NumSubExprs) {
+ void *Mem = Ctx.Allocate(totalSizeToAlloc<Expr *>(NumSubExprs),
+ alignof(RecoveryExpr));
+ return new (Mem) RecoveryExpr(EmptyShell(), NumSubExprs);
+}
+
+void OMPArrayShapingExpr::setDimensions(ArrayRef<Expr *> Dims) {
+ assert(
+ NumDims == Dims.size() &&
+ "Preallocated number of dimensions is different from the provided one.");
+ llvm::copy(Dims, getTrailingObjects<Expr *>());
+}
+
+void OMPArrayShapingExpr::setBracketsRanges(ArrayRef<SourceRange> BR) {
+ assert(
+ NumDims == BR.size() &&
+ "Preallocated number of dimensions is different from the provided one.");
+ llvm::copy(BR, getTrailingObjects<SourceRange>());
+}
+
+OMPArrayShapingExpr::OMPArrayShapingExpr(QualType ExprTy, Expr *Op,
+ SourceLocation L, SourceLocation R,
+ ArrayRef<Expr *> Dims)
+ : Expr(OMPArrayShapingExprClass, ExprTy, VK_LValue, OK_Ordinary), LPLoc(L),
+ RPLoc(R), NumDims(Dims.size()) {
+ setBase(Op);
+ setDimensions(Dims);
+ setDependence(computeDependence(this));
+}
+
+OMPArrayShapingExpr *
+OMPArrayShapingExpr::Create(const ASTContext &Context, QualType T, Expr *Op,
+ SourceLocation L, SourceLocation R,
+ ArrayRef<Expr *> Dims,
+ ArrayRef<SourceRange> BracketRanges) {
+ assert(Dims.size() == BracketRanges.size() &&
+ "Different number of dimensions and brackets ranges.");
+ void *Mem = Context.Allocate(
+ totalSizeToAlloc<Expr *, SourceRange>(Dims.size() + 1, Dims.size()),
+ alignof(OMPArrayShapingExpr));
+ auto *E = new (Mem) OMPArrayShapingExpr(T, Op, L, R, Dims);
+ E->setBracketsRanges(BracketRanges);
+ return E;
+}
+
+OMPArrayShapingExpr *OMPArrayShapingExpr::CreateEmpty(const ASTContext &Context,
+ unsigned NumDims) {
+ void *Mem = Context.Allocate(
+ totalSizeToAlloc<Expr *, SourceRange>(NumDims + 1, NumDims),
+ alignof(OMPArrayShapingExpr));
+ return new (Mem) OMPArrayShapingExpr(EmptyShell(), NumDims);
+}
+
+void OMPIteratorExpr::setIteratorDeclaration(unsigned I, Decl *D) {
+ assert(I < NumIterators &&
+ "Idx is greater or equal the number of iterators definitions.");
+ getTrailingObjects<Decl *>()[I] = D;
+}
+
+void OMPIteratorExpr::setAssignmentLoc(unsigned I, SourceLocation Loc) {
+ assert(I < NumIterators &&
+ "Idx is greater or equal the number of iterators definitions.");
+ getTrailingObjects<
+ SourceLocation>()[I * static_cast<int>(RangeLocOffset::Total) +
+ static_cast<int>(RangeLocOffset::AssignLoc)] = Loc;
+}
+
+void OMPIteratorExpr::setIteratorRange(unsigned I, Expr *Begin,
+ SourceLocation ColonLoc, Expr *End,
+ SourceLocation SecondColonLoc,
+ Expr *Step) {
+ assert(I < NumIterators &&
+ "Idx is greater or equal the number of iterators definitions.");
+ getTrailingObjects<Expr *>()[I * static_cast<int>(RangeExprOffset::Total) +
+ static_cast<int>(RangeExprOffset::Begin)] =
+ Begin;
+ getTrailingObjects<Expr *>()[I * static_cast<int>(RangeExprOffset::Total) +
+ static_cast<int>(RangeExprOffset::End)] = End;
+ getTrailingObjects<Expr *>()[I * static_cast<int>(RangeExprOffset::Total) +
+ static_cast<int>(RangeExprOffset::Step)] = Step;
+ getTrailingObjects<
+ SourceLocation>()[I * static_cast<int>(RangeLocOffset::Total) +
+ static_cast<int>(RangeLocOffset::FirstColonLoc)] =
+ ColonLoc;
+ getTrailingObjects<
+ SourceLocation>()[I * static_cast<int>(RangeLocOffset::Total) +
+ static_cast<int>(RangeLocOffset::SecondColonLoc)] =
+ SecondColonLoc;
+}
+
+Decl *OMPIteratorExpr::getIteratorDecl(unsigned I) {
+ return getTrailingObjects<Decl *>()[I];
+}
+
+OMPIteratorExpr::IteratorRange OMPIteratorExpr::getIteratorRange(unsigned I) {
+ IteratorRange Res;
+ Res.Begin =
+ getTrailingObjects<Expr *>()[I * static_cast<int>(
+ RangeExprOffset::Total) +
+ static_cast<int>(RangeExprOffset::Begin)];
+ Res.End =
+ getTrailingObjects<Expr *>()[I * static_cast<int>(
+ RangeExprOffset::Total) +
+ static_cast<int>(RangeExprOffset::End)];
+ Res.Step =
+ getTrailingObjects<Expr *>()[I * static_cast<int>(
+ RangeExprOffset::Total) +
+ static_cast<int>(RangeExprOffset::Step)];
+ return Res;
+}
+
+SourceLocation OMPIteratorExpr::getAssignLoc(unsigned I) const {
+ return getTrailingObjects<
+ SourceLocation>()[I * static_cast<int>(RangeLocOffset::Total) +
+ static_cast<int>(RangeLocOffset::AssignLoc)];
+}
+
+SourceLocation OMPIteratorExpr::getColonLoc(unsigned I) const {
+ return getTrailingObjects<
+ SourceLocation>()[I * static_cast<int>(RangeLocOffset::Total) +
+ static_cast<int>(RangeLocOffset::FirstColonLoc)];
+}
+
+SourceLocation OMPIteratorExpr::getSecondColonLoc(unsigned I) const {
+ return getTrailingObjects<
+ SourceLocation>()[I * static_cast<int>(RangeLocOffset::Total) +
+ static_cast<int>(RangeLocOffset::SecondColonLoc)];
+}
+
+void OMPIteratorExpr::setHelper(unsigned I, const OMPIteratorHelperData &D) {
+ getTrailingObjects<OMPIteratorHelperData>()[I] = D;
+}
+
+OMPIteratorHelperData &OMPIteratorExpr::getHelper(unsigned I) {
+ return getTrailingObjects<OMPIteratorHelperData>()[I];
+}
+
+const OMPIteratorHelperData &OMPIteratorExpr::getHelper(unsigned I) const {
+ return getTrailingObjects<OMPIteratorHelperData>()[I];
+}
+
+OMPIteratorExpr::OMPIteratorExpr(
+ QualType ExprTy, SourceLocation IteratorKwLoc, SourceLocation L,
+ SourceLocation R, ArrayRef<OMPIteratorExpr::IteratorDefinition> Data,
+ ArrayRef<OMPIteratorHelperData> Helpers)
+ : Expr(OMPIteratorExprClass, ExprTy, VK_LValue, OK_Ordinary),
+ IteratorKwLoc(IteratorKwLoc), LPLoc(L), RPLoc(R),
+ NumIterators(Data.size()) {
+ for (unsigned I = 0, E = Data.size(); I < E; ++I) {
+ const IteratorDefinition &D = Data[I];
+ setIteratorDeclaration(I, D.IteratorDecl);
+ setAssignmentLoc(I, D.AssignmentLoc);
+ setIteratorRange(I, D.Range.Begin, D.ColonLoc, D.Range.End,
+ D.SecondColonLoc, D.Range.Step);
+ setHelper(I, Helpers[I]);
+ }
+ setDependence(computeDependence(this));
+}
+
+OMPIteratorExpr *
+OMPIteratorExpr::Create(const ASTContext &Context, QualType T,
+ SourceLocation IteratorKwLoc, SourceLocation L,
+ SourceLocation R,
+ ArrayRef<OMPIteratorExpr::IteratorDefinition> Data,
+ ArrayRef<OMPIteratorHelperData> Helpers) {
+ assert(Data.size() == Helpers.size() &&
+ "Data and helpers must have the same size.");
+ void *Mem = Context.Allocate(
+ totalSizeToAlloc<Decl *, Expr *, SourceLocation, OMPIteratorHelperData>(
+ Data.size(), Data.size() * static_cast<int>(RangeExprOffset::Total),
+ Data.size() * static_cast<int>(RangeLocOffset::Total),
+ Helpers.size()),
+ alignof(OMPIteratorExpr));
+ return new (Mem) OMPIteratorExpr(T, IteratorKwLoc, L, R, Data, Helpers);
+}
+
+OMPIteratorExpr *OMPIteratorExpr::CreateEmpty(const ASTContext &Context,
+ unsigned NumIterators) {
+ void *Mem = Context.Allocate(
+ totalSizeToAlloc<Decl *, Expr *, SourceLocation, OMPIteratorHelperData>(
+ NumIterators, NumIterators * static_cast<int>(RangeExprOffset::Total),
+ NumIterators * static_cast<int>(RangeLocOffset::Total), NumIterators),
+ alignof(OMPIteratorExpr));
+ return new (Mem) OMPIteratorExpr(EmptyShell(), NumIterators);
+}