mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-04-02 13:12:09 +00:00
Revert "[Temporary] Add an ExprWithCleanups for each C++ MaterializeTemporaryExpr."
This reverts r272296, since there are clang-tidy failures that appear to be caused by this change. llvm-svn: 272310
This commit is contained in:
parent
ee2ce4a50e
commit
17b3deeff3
@ -2877,8 +2877,7 @@ private:
|
|||||||
Stmt *SubExpr;
|
Stmt *SubExpr;
|
||||||
|
|
||||||
ExprWithCleanups(EmptyShell, unsigned NumObjects);
|
ExprWithCleanups(EmptyShell, unsigned NumObjects);
|
||||||
ExprWithCleanups(Expr *SubExpr, bool CleanupsHaveSideEffects,
|
ExprWithCleanups(Expr *SubExpr, ArrayRef<CleanupObject> Objects);
|
||||||
ArrayRef<CleanupObject> Objects);
|
|
||||||
|
|
||||||
friend TrailingObjects;
|
friend TrailingObjects;
|
||||||
friend class ASTStmtReader;
|
friend class ASTStmtReader;
|
||||||
@ -2888,7 +2887,6 @@ public:
|
|||||||
unsigned numObjects);
|
unsigned numObjects);
|
||||||
|
|
||||||
static ExprWithCleanups *Create(const ASTContext &C, Expr *subexpr,
|
static ExprWithCleanups *Create(const ASTContext &C, Expr *subexpr,
|
||||||
bool CleanupsHaveSideEffects,
|
|
||||||
ArrayRef<CleanupObject> objects);
|
ArrayRef<CleanupObject> objects);
|
||||||
|
|
||||||
ArrayRef<CleanupObject> getObjects() const {
|
ArrayRef<CleanupObject> getObjects() const {
|
||||||
@ -2905,9 +2903,6 @@ public:
|
|||||||
|
|
||||||
Expr *getSubExpr() { return cast<Expr>(SubExpr); }
|
Expr *getSubExpr() { return cast<Expr>(SubExpr); }
|
||||||
const Expr *getSubExpr() const { return cast<Expr>(SubExpr); }
|
const Expr *getSubExpr() const { return cast<Expr>(SubExpr); }
|
||||||
bool cleanupsHaveSideEffects() const {
|
|
||||||
return ExprWithCleanupsBits.CleanupsHaveSideEffects;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// As with any mutator of the AST, be very careful
|
/// As with any mutator of the AST, be very careful
|
||||||
/// when modifying an existing AST to preserve its invariants.
|
/// when modifying an existing AST to preserve its invariants.
|
||||||
|
@ -192,10 +192,7 @@ protected:
|
|||||||
|
|
||||||
unsigned : NumExprBits;
|
unsigned : NumExprBits;
|
||||||
|
|
||||||
// When false, it must not have side effects.
|
unsigned NumObjects : 32 - NumExprBits;
|
||||||
bool CleanupsHaveSideEffects : 1;
|
|
||||||
|
|
||||||
unsigned NumObjects : 32 - 1 - NumExprBits;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class PseudoObjectExprBitfields {
|
class PseudoObjectExprBitfields {
|
||||||
|
@ -1,47 +0,0 @@
|
|||||||
//===--- CleanupInfo.cpp - Cleanup Control in Sema ------------------------===//
|
|
||||||
//
|
|
||||||
// The LLVM Compiler Infrastructure
|
|
||||||
//
|
|
||||||
// This file is distributed under the University of Illinois Open Source
|
|
||||||
// License. See LICENSE.TXT for details.
|
|
||||||
//
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
//
|
|
||||||
// This file implements a set of operations on whether generating an
|
|
||||||
// ExprWithCleanups in a full expression.
|
|
||||||
//
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
|
|
||||||
#ifndef LLVM_CLANG_SEMA_CLEANUP_INFO_H
|
|
||||||
#define LLVM_CLANG_SEMA_CLEANUP_INFO_H
|
|
||||||
|
|
||||||
namespace clang {
|
|
||||||
|
|
||||||
class CleanupInfo {
|
|
||||||
bool ExprNeedsCleanups = false;
|
|
||||||
bool CleanupsHaveSideEffects = false;
|
|
||||||
|
|
||||||
public:
|
|
||||||
bool exprNeedsCleanups() const { return ExprNeedsCleanups; }
|
|
||||||
|
|
||||||
bool cleanupsHaveSideEffects() const { return CleanupsHaveSideEffects; }
|
|
||||||
|
|
||||||
void setExprNeedsCleanups(bool SideEffects) {
|
|
||||||
ExprNeedsCleanups = true;
|
|
||||||
CleanupsHaveSideEffects |= SideEffects;
|
|
||||||
}
|
|
||||||
|
|
||||||
void reset() {
|
|
||||||
ExprNeedsCleanups = false;
|
|
||||||
CleanupsHaveSideEffects = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mergeFrom(CleanupInfo Rhs) {
|
|
||||||
ExprNeedsCleanups |= Rhs.ExprNeedsCleanups;
|
|
||||||
CleanupsHaveSideEffects |= Rhs.CleanupsHaveSideEffects;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // end namespace clang
|
|
||||||
|
|
||||||
#endif
|
|
@ -19,7 +19,6 @@
|
|||||||
#include "clang/AST/Type.h"
|
#include "clang/AST/Type.h"
|
||||||
#include "clang/Basic/CapturedStmt.h"
|
#include "clang/Basic/CapturedStmt.h"
|
||||||
#include "clang/Basic/PartialDiagnostic.h"
|
#include "clang/Basic/PartialDiagnostic.h"
|
||||||
#include "clang/Sema/CleanupInfo.h"
|
|
||||||
#include "clang/Sema/Ownership.h"
|
#include "clang/Sema/Ownership.h"
|
||||||
#include "llvm/ADT/DenseMap.h"
|
#include "llvm/ADT/DenseMap.h"
|
||||||
#include "llvm/ADT/SmallSet.h"
|
#include "llvm/ADT/SmallSet.h"
|
||||||
@ -683,7 +682,7 @@ public:
|
|||||||
bool ExplicitParams;
|
bool ExplicitParams;
|
||||||
|
|
||||||
/// \brief Whether any of the capture expressions requires cleanups.
|
/// \brief Whether any of the capture expressions requires cleanups.
|
||||||
CleanupInfo Cleanup;
|
bool ExprNeedsCleanups;
|
||||||
|
|
||||||
/// \brief Whether the lambda contains an unexpanded parameter pack.
|
/// \brief Whether the lambda contains an unexpanded parameter pack.
|
||||||
bool ContainsUnexpandedParameterPack;
|
bool ContainsUnexpandedParameterPack;
|
||||||
@ -731,7 +730,7 @@ public:
|
|||||||
LambdaScopeInfo(DiagnosticsEngine &Diag)
|
LambdaScopeInfo(DiagnosticsEngine &Diag)
|
||||||
: CapturingScopeInfo(Diag, ImpCap_None), Lambda(nullptr),
|
: CapturingScopeInfo(Diag, ImpCap_None), Lambda(nullptr),
|
||||||
CallOperator(nullptr), NumExplicitCaptures(0), Mutable(false),
|
CallOperator(nullptr), NumExplicitCaptures(0), Mutable(false),
|
||||||
ExplicitParams(false), Cleanup{},
|
ExplicitParams(false), ExprNeedsCleanups(false),
|
||||||
ContainsUnexpandedParameterPack(false), AutoTemplateParameterDepth(0),
|
ContainsUnexpandedParameterPack(false), AutoTemplateParameterDepth(0),
|
||||||
GLTemplateParameterList(nullptr) {
|
GLTemplateParameterList(nullptr) {
|
||||||
Kind = SK_Lambda;
|
Kind = SK_Lambda;
|
||||||
|
@ -34,7 +34,6 @@
|
|||||||
#include "clang/Basic/TemplateKinds.h"
|
#include "clang/Basic/TemplateKinds.h"
|
||||||
#include "clang/Basic/TypeTraits.h"
|
#include "clang/Basic/TypeTraits.h"
|
||||||
#include "clang/Sema/AnalysisBasedWarnings.h"
|
#include "clang/Sema/AnalysisBasedWarnings.h"
|
||||||
#include "clang/Sema/CleanupInfo.h"
|
|
||||||
#include "clang/Sema/DeclSpec.h"
|
#include "clang/Sema/DeclSpec.h"
|
||||||
#include "clang/Sema/ExternalSemaSource.h"
|
#include "clang/Sema/ExternalSemaSource.h"
|
||||||
#include "clang/Sema/IdentifierResolver.h"
|
#include "clang/Sema/IdentifierResolver.h"
|
||||||
@ -441,8 +440,9 @@ public:
|
|||||||
/// if Sema is already doing so, which would cause infinite recursions.
|
/// if Sema is already doing so, which would cause infinite recursions.
|
||||||
bool IsBuildingRecoveryCallExpr;
|
bool IsBuildingRecoveryCallExpr;
|
||||||
|
|
||||||
/// Used to control the generation of ExprWithCleanups.
|
/// ExprNeedsCleanups - True if the current evaluation context
|
||||||
CleanupInfo Cleanup;
|
/// requires cleanups to be run at its conclusion.
|
||||||
|
bool ExprNeedsCleanups;
|
||||||
|
|
||||||
/// ExprCleanupObjects - This is the stack of objects requiring
|
/// ExprCleanupObjects - This is the stack of objects requiring
|
||||||
/// cleanup that are created by the current full expression. The
|
/// cleanup that are created by the current full expression. The
|
||||||
@ -830,7 +830,7 @@ public:
|
|||||||
ExpressionEvaluationContext Context;
|
ExpressionEvaluationContext Context;
|
||||||
|
|
||||||
/// \brief Whether the enclosing context needed a cleanup.
|
/// \brief Whether the enclosing context needed a cleanup.
|
||||||
CleanupInfo ParentCleanup;
|
bool ParentNeedsCleanups;
|
||||||
|
|
||||||
/// \brief Whether we are in a decltype expression.
|
/// \brief Whether we are in a decltype expression.
|
||||||
bool IsDecltype;
|
bool IsDecltype;
|
||||||
@ -871,10 +871,10 @@ public:
|
|||||||
|
|
||||||
ExpressionEvaluationContextRecord(ExpressionEvaluationContext Context,
|
ExpressionEvaluationContextRecord(ExpressionEvaluationContext Context,
|
||||||
unsigned NumCleanupObjects,
|
unsigned NumCleanupObjects,
|
||||||
CleanupInfo ParentCleanup,
|
bool ParentNeedsCleanups,
|
||||||
Decl *ManglingContextDecl,
|
Decl *ManglingContextDecl,
|
||||||
bool IsDecltype)
|
bool IsDecltype)
|
||||||
: Context(Context), ParentCleanup(ParentCleanup),
|
: Context(Context), ParentNeedsCleanups(ParentNeedsCleanups),
|
||||||
IsDecltype(IsDecltype), NumCleanupObjects(NumCleanupObjects),
|
IsDecltype(IsDecltype), NumCleanupObjects(NumCleanupObjects),
|
||||||
NumTypos(0),
|
NumTypos(0),
|
||||||
ManglingContextDecl(ManglingContextDecl), MangleNumbering() { }
|
ManglingContextDecl(ManglingContextDecl), MangleNumbering() { }
|
||||||
@ -4872,10 +4872,6 @@ public:
|
|||||||
Stmt *MaybeCreateStmtWithCleanups(Stmt *SubStmt);
|
Stmt *MaybeCreateStmtWithCleanups(Stmt *SubStmt);
|
||||||
ExprResult MaybeCreateExprWithCleanups(ExprResult SubExpr);
|
ExprResult MaybeCreateExprWithCleanups(ExprResult SubExpr);
|
||||||
|
|
||||||
MaterializeTemporaryExpr *
|
|
||||||
CreateMaterializeTemporaryExpr(QualType T, Expr *Temporary,
|
|
||||||
bool BoundToLvalueReference);
|
|
||||||
|
|
||||||
ExprResult ActOnFinishFullExpr(Expr *Expr) {
|
ExprResult ActOnFinishFullExpr(Expr *Expr) {
|
||||||
return ActOnFinishFullExpr(Expr, Expr ? Expr->getExprLoc()
|
return ActOnFinishFullExpr(Expr, Expr ? Expr->getExprLoc()
|
||||||
: SourceLocation());
|
: SourceLocation());
|
||||||
|
@ -2890,6 +2890,7 @@ bool Expr::HasSideEffects(const ASTContext &Ctx,
|
|||||||
case CXXThrowExprClass:
|
case CXXThrowExprClass:
|
||||||
case CXXNewExprClass:
|
case CXXNewExprClass:
|
||||||
case CXXDeleteExprClass:
|
case CXXDeleteExprClass:
|
||||||
|
case ExprWithCleanupsClass:
|
||||||
case CoawaitExprClass:
|
case CoawaitExprClass:
|
||||||
case CoyieldExprClass:
|
case CoyieldExprClass:
|
||||||
// These always have a side-effect.
|
// These always have a side-effect.
|
||||||
@ -2902,12 +2903,6 @@ bool Expr::HasSideEffects(const ASTContext &Ctx,
|
|||||||
return Finder.hasSideEffects();
|
return Finder.hasSideEffects();
|
||||||
}
|
}
|
||||||
|
|
||||||
case ExprWithCleanupsClass:
|
|
||||||
if (IncludePossibleEffects)
|
|
||||||
if (cast<ExprWithCleanups>(this)->cleanupsHaveSideEffects())
|
|
||||||
return true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ParenExprClass:
|
case ParenExprClass:
|
||||||
case ArraySubscriptExprClass:
|
case ArraySubscriptExprClass:
|
||||||
case OMPArraySectionExprClass:
|
case OMPArraySectionExprClass:
|
||||||
|
@ -1039,7 +1039,6 @@ bool LambdaExpr::isMutable() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ExprWithCleanups::ExprWithCleanups(Expr *subexpr,
|
ExprWithCleanups::ExprWithCleanups(Expr *subexpr,
|
||||||
bool CleanupsHaveSideEffects,
|
|
||||||
ArrayRef<CleanupObject> objects)
|
ArrayRef<CleanupObject> objects)
|
||||||
: Expr(ExprWithCleanupsClass, subexpr->getType(),
|
: Expr(ExprWithCleanupsClass, subexpr->getType(),
|
||||||
subexpr->getValueKind(), subexpr->getObjectKind(),
|
subexpr->getValueKind(), subexpr->getObjectKind(),
|
||||||
@ -1047,19 +1046,16 @@ ExprWithCleanups::ExprWithCleanups(Expr *subexpr,
|
|||||||
subexpr->isInstantiationDependent(),
|
subexpr->isInstantiationDependent(),
|
||||||
subexpr->containsUnexpandedParameterPack()),
|
subexpr->containsUnexpandedParameterPack()),
|
||||||
SubExpr(subexpr) {
|
SubExpr(subexpr) {
|
||||||
ExprWithCleanupsBits.CleanupsHaveSideEffects = CleanupsHaveSideEffects;
|
|
||||||
ExprWithCleanupsBits.NumObjects = objects.size();
|
ExprWithCleanupsBits.NumObjects = objects.size();
|
||||||
for (unsigned i = 0, e = objects.size(); i != e; ++i)
|
for (unsigned i = 0, e = objects.size(); i != e; ++i)
|
||||||
getTrailingObjects<CleanupObject>()[i] = objects[i];
|
getTrailingObjects<CleanupObject>()[i] = objects[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
ExprWithCleanups *ExprWithCleanups::Create(const ASTContext &C, Expr *subexpr,
|
ExprWithCleanups *ExprWithCleanups::Create(const ASTContext &C, Expr *subexpr,
|
||||||
bool CleanupsHaveSideEffects,
|
|
||||||
ArrayRef<CleanupObject> objects) {
|
ArrayRef<CleanupObject> objects) {
|
||||||
void *buffer = C.Allocate(totalSizeToAlloc<CleanupObject>(objects.size()),
|
void *buffer = C.Allocate(totalSizeToAlloc<CleanupObject>(objects.size()),
|
||||||
llvm::alignOf<ExprWithCleanups>());
|
llvm::alignOf<ExprWithCleanups>());
|
||||||
return new (buffer)
|
return new (buffer) ExprWithCleanups(subexpr, objects);
|
||||||
ExprWithCleanups(subexpr, CleanupsHaveSideEffects, objects);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ExprWithCleanups::ExprWithCleanups(EmptyShell empty, unsigned numObjects)
|
ExprWithCleanups::ExprWithCleanups(EmptyShell empty, unsigned numObjects)
|
||||||
|
@ -466,15 +466,9 @@ class ConsumedStmtVisitor : public ConstStmtVisitor<ConsumedStmtVisitor> {
|
|||||||
MapType PropagationMap;
|
MapType PropagationMap;
|
||||||
|
|
||||||
InfoEntry findInfo(const Expr *E) {
|
InfoEntry findInfo(const Expr *E) {
|
||||||
if (auto Cleanups = dyn_cast<ExprWithCleanups>(E))
|
|
||||||
if (!Cleanups->cleanupsHaveSideEffects())
|
|
||||||
E = Cleanups->getSubExpr();
|
|
||||||
return PropagationMap.find(E->IgnoreParens());
|
return PropagationMap.find(E->IgnoreParens());
|
||||||
}
|
}
|
||||||
ConstInfoEntry findInfo(const Expr *E) const {
|
ConstInfoEntry findInfo(const Expr *E) const {
|
||||||
if (auto Cleanups = dyn_cast<ExprWithCleanups>(E))
|
|
||||||
if (!Cleanups->cleanupsHaveSideEffects())
|
|
||||||
E = Cleanups->getSubExpr();
|
|
||||||
return PropagationMap.find(E->IgnoreParens());
|
return PropagationMap.find(E->IgnoreParens());
|
||||||
}
|
}
|
||||||
void insertInfo(const Expr *E, const PropagationInfo &PI) {
|
void insertInfo(const Expr *E, const PropagationInfo &PI) {
|
||||||
|
@ -764,12 +764,6 @@ public:
|
|||||||
return Visit(DIE->getExpr());
|
return Visit(DIE->getExpr());
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::Constant *VisitExprWithCleanups(ExprWithCleanups *E) {
|
|
||||||
if (!E->cleanupsHaveSideEffects())
|
|
||||||
return Visit(E->getSubExpr());
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
llvm::Constant *VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E) {
|
llvm::Constant *VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E) {
|
||||||
return Visit(E->GetTemporaryExpr());
|
return Visit(E->GetTemporaryExpr());
|
||||||
}
|
}
|
||||||
|
@ -88,7 +88,7 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
|
|||||||
ConstSegStack(nullptr), CodeSegStack(nullptr), CurInitSeg(nullptr),
|
ConstSegStack(nullptr), CodeSegStack(nullptr), CurInitSeg(nullptr),
|
||||||
VisContext(nullptr),
|
VisContext(nullptr),
|
||||||
IsBuildingRecoveryCallExpr(false),
|
IsBuildingRecoveryCallExpr(false),
|
||||||
Cleanup{}, LateTemplateParser(nullptr),
|
ExprNeedsCleanups(false), LateTemplateParser(nullptr),
|
||||||
LateTemplateParserCleanup(nullptr),
|
LateTemplateParserCleanup(nullptr),
|
||||||
OpaqueParser(nullptr), IdResolver(pp), StdInitializerList(nullptr),
|
OpaqueParser(nullptr), IdResolver(pp), StdInitializerList(nullptr),
|
||||||
CXXTypeInfoDecl(nullptr), MSVCGuidDecl(nullptr),
|
CXXTypeInfoDecl(nullptr), MSVCGuidDecl(nullptr),
|
||||||
@ -124,8 +124,7 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
|
|||||||
// Tell diagnostics how to render things from the AST library.
|
// Tell diagnostics how to render things from the AST library.
|
||||||
Diags.SetArgToStringFn(&FormatASTNodeDiagnosticArgument, &Context);
|
Diags.SetArgToStringFn(&FormatASTNodeDiagnosticArgument, &Context);
|
||||||
|
|
||||||
ExprEvalContexts.emplace_back(PotentiallyEvaluated, 0, CleanupInfo{}, nullptr,
|
ExprEvalContexts.emplace_back(PotentiallyEvaluated, 0, false, nullptr, false);
|
||||||
false);
|
|
||||||
|
|
||||||
FunctionScopes.push_back(new FunctionScopeInfo(Diags));
|
FunctionScopes.push_back(new FunctionScopeInfo(Diags));
|
||||||
|
|
||||||
|
@ -641,8 +641,8 @@ void CastOperation::CheckDynamicCast() {
|
|||||||
// If we're dynamic_casting from a prvalue to an rvalue reference, we need
|
// If we're dynamic_casting from a prvalue to an rvalue reference, we need
|
||||||
// to materialize the prvalue before we bind the reference to it.
|
// to materialize the prvalue before we bind the reference to it.
|
||||||
if (SrcExpr.get()->isRValue())
|
if (SrcExpr.get()->isRValue())
|
||||||
SrcExpr = Self.CreateMaterializeTemporaryExpr(
|
SrcExpr = new (Self.Context) MaterializeTemporaryExpr(
|
||||||
SrcType, SrcExpr.get(), /*IsLValueReference*/ false);
|
SrcType, SrcExpr.get(), /*IsLValueReference*/false);
|
||||||
SrcPointee = SrcType;
|
SrcPointee = SrcType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1649,8 +1649,8 @@ static TryCastResult TryConstCast(Sema &Self, ExprResult &SrcExpr,
|
|||||||
if (NeedToMaterializeTemporary)
|
if (NeedToMaterializeTemporary)
|
||||||
// This is a const_cast from a class prvalue to an rvalue reference type.
|
// This is a const_cast from a class prvalue to an rvalue reference type.
|
||||||
// Materialize a temporary to store the result of the conversion.
|
// Materialize a temporary to store the result of the conversion.
|
||||||
SrcExpr = Self.CreateMaterializeTemporaryExpr(SrcType, SrcExpr.get(),
|
SrcExpr = new (Self.Context) MaterializeTemporaryExpr(
|
||||||
/*IsLValueReference*/ false);
|
SrcType, SrcExpr.get(), /*IsLValueReference*/ false);
|
||||||
|
|
||||||
return TC_Success;
|
return TC_Success;
|
||||||
}
|
}
|
||||||
|
@ -244,7 +244,7 @@ ExprResult Sema::BuildCoawaitExpr(SourceLocation Loc, Expr *E) {
|
|||||||
// If the expression is a temporary, materialize it as an lvalue so that we
|
// If the expression is a temporary, materialize it as an lvalue so that we
|
||||||
// can use it multiple times.
|
// can use it multiple times.
|
||||||
if (E->getValueKind() == VK_RValue)
|
if (E->getValueKind() == VK_RValue)
|
||||||
E = CreateMaterializeTemporaryExpr(E->getType(), E, true);
|
E = new (Context) MaterializeTemporaryExpr(E->getType(), E, true);
|
||||||
|
|
||||||
// Build the await_ready, await_suspend, await_resume calls.
|
// Build the await_ready, await_suspend, await_resume calls.
|
||||||
ReadySuspendResumeResult RSS = buildCoawaitCalls(*this, Loc, E);
|
ReadySuspendResumeResult RSS = buildCoawaitCalls(*this, Loc, E);
|
||||||
@ -311,7 +311,7 @@ ExprResult Sema::BuildCoyieldExpr(SourceLocation Loc, Expr *E) {
|
|||||||
// If the expression is a temporary, materialize it as an lvalue so that we
|
// If the expression is a temporary, materialize it as an lvalue so that we
|
||||||
// can use it multiple times.
|
// can use it multiple times.
|
||||||
if (E->getValueKind() == VK_RValue)
|
if (E->getValueKind() == VK_RValue)
|
||||||
E = CreateMaterializeTemporaryExpr(E->getType(), E, true);
|
E = new (Context) MaterializeTemporaryExpr(E->getType(), E, true);
|
||||||
|
|
||||||
// Build the await_ready, await_suspend, await_resume calls.
|
// Build the await_ready, await_suspend, await_resume calls.
|
||||||
ReadySuspendResumeResult RSS = buildCoawaitCalls(*this, Loc, E);
|
ReadySuspendResumeResult RSS = buildCoawaitCalls(*this, Loc, E);
|
||||||
|
@ -11648,7 +11648,7 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
|
|||||||
assert(ExprCleanupObjects.size() ==
|
assert(ExprCleanupObjects.size() ==
|
||||||
ExprEvalContexts.back().NumCleanupObjects &&
|
ExprEvalContexts.back().NumCleanupObjects &&
|
||||||
"Leftover temporaries in function");
|
"Leftover temporaries in function");
|
||||||
assert(!Cleanup.exprNeedsCleanups() && "Unaccounted cleanups in function");
|
assert(!ExprNeedsCleanups && "Unaccounted cleanups in function");
|
||||||
assert(MaybeODRUseExprs.empty() &&
|
assert(MaybeODRUseExprs.empty() &&
|
||||||
"Leftover expressions for odr-use checking");
|
"Leftover expressions for odr-use checking");
|
||||||
}
|
}
|
||||||
|
@ -712,7 +712,7 @@ ExprResult Sema::DefaultLvalueConversion(Expr *E) {
|
|||||||
// balance that.
|
// balance that.
|
||||||
if (getLangOpts().ObjCAutoRefCount &&
|
if (getLangOpts().ObjCAutoRefCount &&
|
||||||
E->getType().getObjCLifetime() == Qualifiers::OCL_Weak)
|
E->getType().getObjCLifetime() == Qualifiers::OCL_Weak)
|
||||||
Cleanup.setExprNeedsCleanups(true);
|
ExprNeedsCleanups = true;
|
||||||
|
|
||||||
ExprResult Res = ImplicitCastExpr::Create(Context, T, CK_LValueToRValue, E,
|
ExprResult Res = ImplicitCastExpr::Create(Context, T, CK_LValueToRValue, E,
|
||||||
nullptr, VK_RValue);
|
nullptr, VK_RValue);
|
||||||
@ -4573,15 +4573,15 @@ ExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation CallLoc,
|
|||||||
// bound temporaries; see the comment in PR5810.
|
// bound temporaries; see the comment in PR5810.
|
||||||
// We don't need to do that with block decls, though, because
|
// We don't need to do that with block decls, though, because
|
||||||
// blocks in default argument expression can never capture anything.
|
// blocks in default argument expression can never capture anything.
|
||||||
if (auto Init = dyn_cast<ExprWithCleanups>(Param->getInit())) {
|
if (isa<ExprWithCleanups>(Param->getInit())) {
|
||||||
// Set the "needs cleanups" bit regardless of whether there are
|
// Set the "needs cleanups" bit regardless of whether there are
|
||||||
// any explicit objects.
|
// any explicit objects.
|
||||||
Cleanup.setExprNeedsCleanups(Init->cleanupsHaveSideEffects());
|
ExprNeedsCleanups = true;
|
||||||
|
|
||||||
// Append all the objects to the cleanup list. Right now, this
|
// Append all the objects to the cleanup list. Right now, this
|
||||||
// should always be a no-op, because blocks in default argument
|
// should always be a no-op, because blocks in default argument
|
||||||
// expressions should never be able to capture anything.
|
// expressions should never be able to capture anything.
|
||||||
assert(!Init->getNumObjects() &&
|
assert(!cast<ExprWithCleanups>(Param->getInit())->getNumObjects() &&
|
||||||
"default argument expression has capturing blocks?");
|
"default argument expression has capturing blocks?");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5596,7 +5596,7 @@ void Sema::maybeExtendBlockObject(ExprResult &E) {
|
|||||||
E = ImplicitCastExpr::Create(Context, E.get()->getType(),
|
E = ImplicitCastExpr::Create(Context, E.get()->getType(),
|
||||||
CK_ARCExtendBlockObject, E.get(),
|
CK_ARCExtendBlockObject, E.get(),
|
||||||
/*base path*/ nullptr, VK_RValue);
|
/*base path*/ nullptr, VK_RValue);
|
||||||
Cleanup.setExprNeedsCleanups(true);
|
ExprNeedsCleanups = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Prepare a conversion of the given expression to an ObjC object
|
/// Prepare a conversion of the given expression to an ObjC object
|
||||||
@ -10382,8 +10382,8 @@ QualType Sema::CheckAddressOfOperand(ExprResult &OrigOp, SourceLocation OpLoc) {
|
|||||||
if (sfinae)
|
if (sfinae)
|
||||||
return QualType();
|
return QualType();
|
||||||
// Materialize the temporary as an lvalue so that we can take its address.
|
// Materialize the temporary as an lvalue so that we can take its address.
|
||||||
OrigOp = op =
|
OrigOp = op = new (Context)
|
||||||
CreateMaterializeTemporaryExpr(op->getType(), OrigOp.get(), true);
|
MaterializeTemporaryExpr(op->getType(), OrigOp.get(), true);
|
||||||
} else if (isa<ObjCSelectorExpr>(op)) {
|
} else if (isa<ObjCSelectorExpr>(op)) {
|
||||||
return Context.getPointerType(op->getType());
|
return Context.getPointerType(op->getType());
|
||||||
} else if (lval == Expr::LV_MemberFunction) {
|
} else if (lval == Expr::LV_MemberFunction) {
|
||||||
@ -11596,8 +11596,7 @@ Sema::ActOnStmtExpr(SourceLocation LPLoc, Stmt *SubStmt,
|
|||||||
|
|
||||||
if (hasAnyUnrecoverableErrorsInThisFunction())
|
if (hasAnyUnrecoverableErrorsInThisFunction())
|
||||||
DiscardCleanupsInEvaluationContext();
|
DiscardCleanupsInEvaluationContext();
|
||||||
assert(!Cleanup.exprNeedsCleanups() &&
|
assert(!ExprNeedsCleanups && "cleanups within StmtExpr not correctly bound!");
|
||||||
"cleanups within StmtExpr not correctly bound!");
|
|
||||||
PopExpressionEvaluationContext();
|
PopExpressionEvaluationContext();
|
||||||
|
|
||||||
// FIXME: there are a variety of strange constraints to enforce here, for
|
// FIXME: there are a variety of strange constraints to enforce here, for
|
||||||
@ -12065,8 +12064,7 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc,
|
|||||||
// Leave the expression-evaluation context.
|
// Leave the expression-evaluation context.
|
||||||
if (hasAnyUnrecoverableErrorsInThisFunction())
|
if (hasAnyUnrecoverableErrorsInThisFunction())
|
||||||
DiscardCleanupsInEvaluationContext();
|
DiscardCleanupsInEvaluationContext();
|
||||||
assert(!Cleanup.exprNeedsCleanups() &&
|
assert(!ExprNeedsCleanups && "cleanups within block not correctly bound!");
|
||||||
"cleanups within block not correctly bound!");
|
|
||||||
PopExpressionEvaluationContext();
|
PopExpressionEvaluationContext();
|
||||||
|
|
||||||
BlockScopeInfo *BSI = cast<BlockScopeInfo>(FunctionScopes.back());
|
BlockScopeInfo *BSI = cast<BlockScopeInfo>(FunctionScopes.back());
|
||||||
@ -12157,7 +12155,7 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc,
|
|||||||
if (Result->getBlockDecl()->hasCaptures()) {
|
if (Result->getBlockDecl()->hasCaptures()) {
|
||||||
// First, this expression has a new cleanup object.
|
// First, this expression has a new cleanup object.
|
||||||
ExprCleanupObjects.push_back(Result->getBlockDecl());
|
ExprCleanupObjects.push_back(Result->getBlockDecl());
|
||||||
Cleanup.setExprNeedsCleanups(true);
|
ExprNeedsCleanups = true;
|
||||||
|
|
||||||
// It also gets a branch-protected scope if any of the captured
|
// It also gets a branch-protected scope if any of the captured
|
||||||
// variables needs destruction.
|
// variables needs destruction.
|
||||||
@ -12794,9 +12792,10 @@ void
|
|||||||
Sema::PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext,
|
Sema::PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext,
|
||||||
Decl *LambdaContextDecl,
|
Decl *LambdaContextDecl,
|
||||||
bool IsDecltype) {
|
bool IsDecltype) {
|
||||||
ExprEvalContexts.emplace_back(NewContext, ExprCleanupObjects.size(), Cleanup,
|
ExprEvalContexts.emplace_back(NewContext, ExprCleanupObjects.size(),
|
||||||
LambdaContextDecl, IsDecltype);
|
ExprNeedsCleanups, LambdaContextDecl,
|
||||||
Cleanup.reset();
|
IsDecltype);
|
||||||
|
ExprNeedsCleanups = false;
|
||||||
if (!MaybeODRUseExprs.empty())
|
if (!MaybeODRUseExprs.empty())
|
||||||
std::swap(MaybeODRUseExprs, ExprEvalContexts.back().SavedMaybeODRUseExprs);
|
std::swap(MaybeODRUseExprs, ExprEvalContexts.back().SavedMaybeODRUseExprs);
|
||||||
}
|
}
|
||||||
@ -12847,12 +12846,12 @@ void Sema::PopExpressionEvaluationContext() {
|
|||||||
if (Rec.isUnevaluated() || Rec.Context == ConstantEvaluated) {
|
if (Rec.isUnevaluated() || Rec.Context == ConstantEvaluated) {
|
||||||
ExprCleanupObjects.erase(ExprCleanupObjects.begin() + Rec.NumCleanupObjects,
|
ExprCleanupObjects.erase(ExprCleanupObjects.begin() + Rec.NumCleanupObjects,
|
||||||
ExprCleanupObjects.end());
|
ExprCleanupObjects.end());
|
||||||
Cleanup = Rec.ParentCleanup;
|
ExprNeedsCleanups = Rec.ParentNeedsCleanups;
|
||||||
CleanupVarDeclMarking();
|
CleanupVarDeclMarking();
|
||||||
std::swap(MaybeODRUseExprs, Rec.SavedMaybeODRUseExprs);
|
std::swap(MaybeODRUseExprs, Rec.SavedMaybeODRUseExprs);
|
||||||
// Otherwise, merge the contexts together.
|
// Otherwise, merge the contexts together.
|
||||||
} else {
|
} else {
|
||||||
Cleanup.mergeFrom(Rec.ParentCleanup);
|
ExprNeedsCleanups |= Rec.ParentNeedsCleanups;
|
||||||
MaybeODRUseExprs.insert(Rec.SavedMaybeODRUseExprs.begin(),
|
MaybeODRUseExprs.insert(Rec.SavedMaybeODRUseExprs.begin(),
|
||||||
Rec.SavedMaybeODRUseExprs.end());
|
Rec.SavedMaybeODRUseExprs.end());
|
||||||
}
|
}
|
||||||
@ -12871,7 +12870,7 @@ void Sema::DiscardCleanupsInEvaluationContext() {
|
|||||||
ExprCleanupObjects.erase(
|
ExprCleanupObjects.erase(
|
||||||
ExprCleanupObjects.begin() + ExprEvalContexts.back().NumCleanupObjects,
|
ExprCleanupObjects.begin() + ExprEvalContexts.back().NumCleanupObjects,
|
||||||
ExprCleanupObjects.end());
|
ExprCleanupObjects.end());
|
||||||
Cleanup.reset();
|
ExprNeedsCleanups = false;
|
||||||
MaybeODRUseExprs.clear();
|
MaybeODRUseExprs.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5551,7 +5551,7 @@ ExprResult Sema::MaybeBindToTemporary(Expr *E) {
|
|||||||
if (!ReturnsRetained && E->getType()->isObjCARCImplicitlyUnretainedType())
|
if (!ReturnsRetained && E->getType()->isObjCARCImplicitlyUnretainedType())
|
||||||
return E;
|
return E;
|
||||||
|
|
||||||
Cleanup.setExprNeedsCleanups(true);
|
ExprNeedsCleanups = true;
|
||||||
|
|
||||||
CastKind ck = (ReturnsRetained ? CK_ARCConsumeObject
|
CastKind ck = (ReturnsRetained ? CK_ARCConsumeObject
|
||||||
: CK_ARCReclaimReturnedObject);
|
: CK_ARCReclaimReturnedObject);
|
||||||
@ -5604,7 +5604,7 @@ ExprResult Sema::MaybeBindToTemporary(Expr *E) {
|
|||||||
return E;
|
return E;
|
||||||
|
|
||||||
// We need a cleanup, but we don't need to remember the temporary.
|
// We need a cleanup, but we don't need to remember the temporary.
|
||||||
Cleanup.setExprNeedsCleanups(true);
|
ExprNeedsCleanups = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
CXXTemporary *Temp = CXXTemporary::Create(Context, Destructor);
|
CXXTemporary *Temp = CXXTemporary::Create(Context, Destructor);
|
||||||
@ -5631,16 +5631,14 @@ Expr *Sema::MaybeCreateExprWithCleanups(Expr *SubExpr) {
|
|||||||
|
|
||||||
unsigned FirstCleanup = ExprEvalContexts.back().NumCleanupObjects;
|
unsigned FirstCleanup = ExprEvalContexts.back().NumCleanupObjects;
|
||||||
assert(ExprCleanupObjects.size() >= FirstCleanup);
|
assert(ExprCleanupObjects.size() >= FirstCleanup);
|
||||||
assert(Cleanup.exprNeedsCleanups() ||
|
assert(ExprNeedsCleanups || ExprCleanupObjects.size() == FirstCleanup);
|
||||||
ExprCleanupObjects.size() == FirstCleanup);
|
if (!ExprNeedsCleanups)
|
||||||
if (!Cleanup.exprNeedsCleanups())
|
|
||||||
return SubExpr;
|
return SubExpr;
|
||||||
|
|
||||||
auto Cleanups = llvm::makeArrayRef(ExprCleanupObjects.begin() + FirstCleanup,
|
auto Cleanups = llvm::makeArrayRef(ExprCleanupObjects.begin() + FirstCleanup,
|
||||||
ExprCleanupObjects.size() - FirstCleanup);
|
ExprCleanupObjects.size() - FirstCleanup);
|
||||||
|
|
||||||
auto *E = ExprWithCleanups::Create(
|
Expr *E = ExprWithCleanups::Create(Context, SubExpr, Cleanups);
|
||||||
Context, SubExpr, Cleanup.cleanupsHaveSideEffects(), Cleanups);
|
|
||||||
DiscardCleanupsInEvaluationContext();
|
DiscardCleanupsInEvaluationContext();
|
||||||
|
|
||||||
return E;
|
return E;
|
||||||
@ -5651,7 +5649,7 @@ Stmt *Sema::MaybeCreateStmtWithCleanups(Stmt *SubStmt) {
|
|||||||
|
|
||||||
CleanupVarDeclMarking();
|
CleanupVarDeclMarking();
|
||||||
|
|
||||||
if (!Cleanup.exprNeedsCleanups())
|
if (!ExprNeedsCleanups)
|
||||||
return SubStmt;
|
return SubStmt;
|
||||||
|
|
||||||
// FIXME: In order to attach the temporaries, wrap the statement into
|
// FIXME: In order to attach the temporaries, wrap the statement into
|
||||||
@ -5757,7 +5755,7 @@ ExprResult Sema::ActOnDecltypeExpression(Expr *E) {
|
|||||||
return ExprError();
|
return ExprError();
|
||||||
|
|
||||||
// We need a cleanup, but we don't need to remember the temporary.
|
// We need a cleanup, but we don't need to remember the temporary.
|
||||||
Cleanup.setExprNeedsCleanups(true);
|
ExprNeedsCleanups = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Possibly strip off the top CXXBindTemporaryExpr.
|
// Possibly strip off the top CXXBindTemporaryExpr.
|
||||||
|
@ -4067,7 +4067,7 @@ Sema::CheckObjCARCConversion(SourceRange castRange, QualType castType,
|
|||||||
castExpr = ImplicitCastExpr::Create(Context, castExpr->getType(),
|
castExpr = ImplicitCastExpr::Create(Context, castExpr->getType(),
|
||||||
CK_ARCConsumeObject, castExpr,
|
CK_ARCConsumeObject, castExpr,
|
||||||
nullptr, VK_RValue);
|
nullptr, VK_RValue);
|
||||||
Cleanup.setExprNeedsCleanups(true);
|
ExprNeedsCleanups = true;
|
||||||
return ACR_okay;
|
return ACR_okay;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4310,7 +4310,7 @@ ExprResult Sema::BuildObjCBridgedCast(SourceLocation LParenLoc,
|
|||||||
TSInfo, SubExpr);
|
TSInfo, SubExpr);
|
||||||
|
|
||||||
if (MustConsume) {
|
if (MustConsume) {
|
||||||
Cleanup.setExprNeedsCleanups(true);
|
ExprNeedsCleanups = true;
|
||||||
Result = ImplicitCastExpr::Create(Context, T, CK_ARCConsumeObject, Result,
|
Result = ImplicitCastExpr::Create(Context, T, CK_ARCConsumeObject, Result,
|
||||||
nullptr, VK_RValue);
|
nullptr, VK_RValue);
|
||||||
}
|
}
|
||||||
|
@ -4807,8 +4807,8 @@ static void checkIndirectCopyRestoreSource(Sema &S, Expr *src) {
|
|||||||
// If isWeakAccess to true, there will be an implicit
|
// If isWeakAccess to true, there will be an implicit
|
||||||
// load which requires a cleanup.
|
// load which requires a cleanup.
|
||||||
if (S.getLangOpts().ObjCAutoRefCount && isWeakAccess)
|
if (S.getLangOpts().ObjCAutoRefCount && isWeakAccess)
|
||||||
S.Cleanup.setExprNeedsCleanups(true);
|
S.ExprNeedsCleanups = true;
|
||||||
|
|
||||||
if (iik == IIK_okay) return;
|
if (iik == IIK_okay) return;
|
||||||
|
|
||||||
S.Diag(src->getExprLoc(), diag::err_arc_nonlocal_writeback)
|
S.Diag(src->getExprLoc(), diag::err_arc_nonlocal_writeback)
|
||||||
@ -6182,22 +6182,6 @@ static void CheckForNullPointerDereference(Sema &S, const Expr *E) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MaterializeTemporaryExpr *
|
|
||||||
Sema::CreateMaterializeTemporaryExpr(QualType T, Expr *Temporary,
|
|
||||||
bool BoundToLvalueReference) {
|
|
||||||
auto MTE = new (Context)
|
|
||||||
MaterializeTemporaryExpr(T, Temporary, BoundToLvalueReference);
|
|
||||||
|
|
||||||
// Order an ExprWithCleanups for lifetime marks.
|
|
||||||
//
|
|
||||||
// TODO: It'll be good to have a single place to check the access of the
|
|
||||||
// destructor and generate ExprWithCleanups for various uses. Currently these
|
|
||||||
// are done in both CreateMaterializeTemporaryExpr and MaybeBindToTemporary,
|
|
||||||
// but there may be a chance to merge them.
|
|
||||||
Cleanup.setExprNeedsCleanups(false);
|
|
||||||
return MTE;
|
|
||||||
}
|
|
||||||
|
|
||||||
ExprResult
|
ExprResult
|
||||||
InitializationSequence::Perform(Sema &S,
|
InitializationSequence::Perform(Sema &S,
|
||||||
const InitializedEntity &Entity,
|
const InitializedEntity &Entity,
|
||||||
@ -6462,7 +6446,7 @@ InitializationSequence::Perform(Sema &S,
|
|||||||
return ExprError();
|
return ExprError();
|
||||||
|
|
||||||
// Materialize the temporary into memory.
|
// Materialize the temporary into memory.
|
||||||
MaterializeTemporaryExpr *MTE = S.CreateMaterializeTemporaryExpr(
|
MaterializeTemporaryExpr *MTE = new (S.Context) MaterializeTemporaryExpr(
|
||||||
Entity.getType().getNonReferenceType(), CurInit.get(),
|
Entity.getType().getNonReferenceType(), CurInit.get(),
|
||||||
Entity.getType()->isLValueReferenceType());
|
Entity.getType()->isLValueReferenceType());
|
||||||
|
|
||||||
@ -6482,7 +6466,7 @@ InitializationSequence::Perform(Sema &S,
|
|||||||
MTE->getType()->isObjCLifetimeType()) ||
|
MTE->getType()->isObjCLifetimeType()) ||
|
||||||
(MTE->getStorageDuration() == SD_Automatic &&
|
(MTE->getStorageDuration() == SD_Automatic &&
|
||||||
MTE->getType().isDestructedType()))
|
MTE->getType().isDestructedType()))
|
||||||
S.Cleanup.setExprNeedsCleanups(true);
|
S.ExprNeedsCleanups = true;
|
||||||
|
|
||||||
CurInit = MTE;
|
CurInit = MTE;
|
||||||
break;
|
break;
|
||||||
@ -6874,9 +6858,9 @@ InitializationSequence::Perform(Sema &S,
|
|||||||
<< CurInit.get()->getSourceRange();
|
<< CurInit.get()->getSourceRange();
|
||||||
|
|
||||||
// Materialize the temporary into memory.
|
// Materialize the temporary into memory.
|
||||||
MaterializeTemporaryExpr *MTE = S.CreateMaterializeTemporaryExpr(
|
MaterializeTemporaryExpr *MTE = new (S.Context)
|
||||||
CurInit.get()->getType(), CurInit.get(),
|
MaterializeTemporaryExpr(CurInit.get()->getType(), CurInit.get(),
|
||||||
/*BoundToLvalueReference=*/false);
|
/*BoundToLvalueReference=*/false);
|
||||||
|
|
||||||
// Maybe lifetime-extend the array temporary's subobjects to match the
|
// Maybe lifetime-extend the array temporary's subobjects to match the
|
||||||
// entity's lifetime.
|
// entity's lifetime.
|
||||||
|
@ -1500,7 +1500,7 @@ ExprResult Sema::BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,
|
|||||||
SourceRange IntroducerRange;
|
SourceRange IntroducerRange;
|
||||||
bool ExplicitParams;
|
bool ExplicitParams;
|
||||||
bool ExplicitResultType;
|
bool ExplicitResultType;
|
||||||
CleanupInfo LambdaCleanup;
|
bool LambdaExprNeedsCleanups;
|
||||||
bool ContainsUnexpandedParameterPack;
|
bool ContainsUnexpandedParameterPack;
|
||||||
SmallVector<VarDecl *, 4> ArrayIndexVars;
|
SmallVector<VarDecl *, 4> ArrayIndexVars;
|
||||||
SmallVector<unsigned, 4> ArrayIndexStarts;
|
SmallVector<unsigned, 4> ArrayIndexStarts;
|
||||||
@ -1510,7 +1510,7 @@ ExprResult Sema::BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,
|
|||||||
IntroducerRange = LSI->IntroducerRange;
|
IntroducerRange = LSI->IntroducerRange;
|
||||||
ExplicitParams = LSI->ExplicitParams;
|
ExplicitParams = LSI->ExplicitParams;
|
||||||
ExplicitResultType = !LSI->HasImplicitReturnType;
|
ExplicitResultType = !LSI->HasImplicitReturnType;
|
||||||
LambdaCleanup = LSI->Cleanup;
|
LambdaExprNeedsCleanups = LSI->ExprNeedsCleanups;
|
||||||
ContainsUnexpandedParameterPack = LSI->ContainsUnexpandedParameterPack;
|
ContainsUnexpandedParameterPack = LSI->ContainsUnexpandedParameterPack;
|
||||||
|
|
||||||
CallOperator->setLexicalDeclContext(Class);
|
CallOperator->setLexicalDeclContext(Class);
|
||||||
@ -1591,8 +1591,9 @@ ExprResult Sema::BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,
|
|||||||
CheckCompletedCXXClass(Class);
|
CheckCompletedCXXClass(Class);
|
||||||
}
|
}
|
||||||
|
|
||||||
Cleanup.mergeFrom(LambdaCleanup);
|
if (LambdaExprNeedsCleanups)
|
||||||
|
ExprNeedsCleanups = true;
|
||||||
|
|
||||||
LambdaExpr *Lambda = LambdaExpr::Create(Context, Class, IntroducerRange,
|
LambdaExpr *Lambda = LambdaExpr::Create(Context, Class, IntroducerRange,
|
||||||
CaptureDefault, CaptureDefaultLoc,
|
CaptureDefault, CaptureDefaultLoc,
|
||||||
Captures,
|
Captures,
|
||||||
@ -1713,7 +1714,7 @@ ExprResult Sema::BuildBlockForLambdaConversion(SourceLocation CurrentLocation,
|
|||||||
// Create the block literal expression.
|
// Create the block literal expression.
|
||||||
Expr *BuildBlock = new (Context) BlockExpr(Block, Conv->getConversionType());
|
Expr *BuildBlock = new (Context) BlockExpr(Block, Conv->getConversionType());
|
||||||
ExprCleanupObjects.push_back(Block);
|
ExprCleanupObjects.push_back(Block);
|
||||||
Cleanup.setExprNeedsCleanups(true);
|
ExprNeedsCleanups = true;
|
||||||
|
|
||||||
return BuildBlock;
|
return BuildBlock;
|
||||||
}
|
}
|
||||||
|
@ -3801,10 +3801,6 @@ bool OpenMPIterationSpaceChecker::CheckInit(Stmt *S, bool EmitDiags) {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
|
|
||||||
if (!ExprTemp->cleanupsHaveSideEffects())
|
|
||||||
S = ExprTemp->getSubExpr();
|
|
||||||
|
|
||||||
InitSrcRange = S->getSourceRange();
|
InitSrcRange = S->getSourceRange();
|
||||||
if (Expr *E = dyn_cast<Expr>(S))
|
if (Expr *E = dyn_cast<Expr>(S))
|
||||||
S = E->IgnoreParens();
|
S = E->IgnoreParens();
|
||||||
@ -3992,10 +3988,6 @@ bool OpenMPIterationSpaceChecker::CheckInc(Expr *S) {
|
|||||||
SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl;
|
SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
|
|
||||||
if (!ExprTemp->cleanupsHaveSideEffects())
|
|
||||||
S = ExprTemp->getSubExpr();
|
|
||||||
|
|
||||||
IncrementSrcRange = S->getSourceRange();
|
IncrementSrcRange = S->getSourceRange();
|
||||||
S = S->IgnoreParens();
|
S = S->IgnoreParens();
|
||||||
if (auto UO = dyn_cast<UnaryOperator>(S)) {
|
if (auto UO = dyn_cast<UnaryOperator>(S)) {
|
||||||
|
@ -1518,10 +1518,6 @@ namespace {
|
|||||||
// variables Increment and DRE.
|
// variables Increment and DRE.
|
||||||
bool ProcessIterationStmt(Sema &S, Stmt* Statement, bool &Increment,
|
bool ProcessIterationStmt(Sema &S, Stmt* Statement, bool &Increment,
|
||||||
DeclRefExpr *&DRE) {
|
DeclRefExpr *&DRE) {
|
||||||
if (auto Cleanups = dyn_cast<ExprWithCleanups>(Statement))
|
|
||||||
if (!Cleanups->cleanupsHaveSideEffects())
|
|
||||||
Statement = Cleanups->getSubExpr();
|
|
||||||
|
|
||||||
if (UnaryOperator *UO = dyn_cast<UnaryOperator>(Statement)) {
|
if (UnaryOperator *UO = dyn_cast<UnaryOperator>(Statement)) {
|
||||||
switch (UO->getOpcode()) {
|
switch (UO->getOpcode()) {
|
||||||
default: return false;
|
default: return false;
|
||||||
@ -2476,10 +2472,6 @@ static void DiagnoseForRangeReferenceVariableCopies(Sema &SemaRef,
|
|||||||
|
|
||||||
QualType VariableType = VD->getType();
|
QualType VariableType = VD->getType();
|
||||||
|
|
||||||
if (auto Cleanups = dyn_cast<ExprWithCleanups>(InitExpr))
|
|
||||||
if (!Cleanups->cleanupsHaveSideEffects())
|
|
||||||
InitExpr = Cleanups->getSubExpr();
|
|
||||||
|
|
||||||
const MaterializeTemporaryExpr *MTE =
|
const MaterializeTemporaryExpr *MTE =
|
||||||
dyn_cast<MaterializeTemporaryExpr>(InitExpr);
|
dyn_cast<MaterializeTemporaryExpr>(InitExpr);
|
||||||
|
|
||||||
|
@ -1448,7 +1448,6 @@ void ASTStmtReader::VisitExprWithCleanups(ExprWithCleanups *E) {
|
|||||||
E->getTrailingObjects<BlockDecl *>()[i] =
|
E->getTrailingObjects<BlockDecl *>()[i] =
|
||||||
ReadDeclAs<BlockDecl>(Record, Idx);
|
ReadDeclAs<BlockDecl>(Record, Idx);
|
||||||
|
|
||||||
E->ExprWithCleanupsBits.CleanupsHaveSideEffects = Record[Idx++];
|
|
||||||
E->SubExpr = Reader.ReadSubExpr();
|
E->SubExpr = Reader.ReadSubExpr();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1430,8 +1430,7 @@ void ASTStmtWriter::VisitExprWithCleanups(ExprWithCleanups *E) {
|
|||||||
Record.push_back(E->getNumObjects());
|
Record.push_back(E->getNumObjects());
|
||||||
for (unsigned i = 0, e = E->getNumObjects(); i != e; ++i)
|
for (unsigned i = 0, e = E->getNumObjects(); i != e; ++i)
|
||||||
Record.AddDeclRef(E->getObject(i));
|
Record.AddDeclRef(E->getObject(i));
|
||||||
|
|
||||||
Record.push_back(E->cleanupsHaveSideEffects());
|
|
||||||
Record.AddStmt(E->getSubExpr());
|
Record.AddStmt(E->getSubExpr());
|
||||||
Code = serialization::EXPR_EXPR_WITH_CLEANUPS;
|
Code = serialization::EXPR_EXPR_WITH_CLEANUPS;
|
||||||
}
|
}
|
||||||
|
@ -999,8 +999,8 @@ TEST(ExprWithCleanups, MatchesExprWithCleanups) {
|
|||||||
EXPECT_TRUE(matches("struct Foo { ~Foo(); };"
|
EXPECT_TRUE(matches("struct Foo { ~Foo(); };"
|
||||||
"const Foo f = Foo();",
|
"const Foo f = Foo();",
|
||||||
varDecl(hasInitializer(exprWithCleanups()))));
|
varDecl(hasInitializer(exprWithCleanups()))));
|
||||||
EXPECT_FALSE(matches("struct Foo { }; Foo a;"
|
EXPECT_FALSE(matches("struct Foo { };"
|
||||||
"const Foo f = a;",
|
"const Foo f = Foo();",
|
||||||
varDecl(hasInitializer(exprWithCleanups()))));
|
varDecl(hasInitializer(exprWithCleanups()))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user