Tyker updated this revision to Diff 204916.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D63376/new/
https://reviews.llvm.org/D63376
Files:
clang/include/clang/AST/ASTContext.h
clang/include/clang/AST/Expr.h
clang/include/clang/AST/Stmt.h
clang/include/clang/Sema/Sema.h
clang/lib/AST/ASTContext.cpp
clang/lib/AST/Expr.cpp
clang/lib/AST/ExprConstant.cpp
clang/lib/Sema/SemaDeclCXX.cpp
clang/lib/Sema/SemaExpr.cpp
clang/lib/Sema/SemaOverload.cpp
Index: clang/lib/Sema/SemaOverload.cpp
===================================================================
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -5514,7 +5514,12 @@
if (Notes.empty()) {
// It's a constant expression.
- return ConstantExpr::Create(S.Context, Result.get(), Value);
+
+ // ExplicitBool wouldn't use the value stored in ConstantExpr.
+ if (CCE != Sema::CCEK_ExplicitBool)
+ return ConstantExpr::Create(S.Context, Result.get(), Value);
+ else
+ return ConstantExpr::Create(S.Context, Result.get());
}
}
Index: clang/lib/Sema/SemaExpr.cpp
===================================================================
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -14467,10 +14467,10 @@
S.Diag(Loc, diag::ext_expr_not_ice) << SR << S.LangOpts.CPlusPlus;
}
-ExprResult
-Sema::VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result,
- VerifyICEDiagnoser &Diagnoser,
- bool AllowFold) {
+ExprResult Sema::VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result,
+ VerifyICEDiagnoser &Diagnoser,
+ bool AllowFold,
+ bool StoreResult) {
SourceLocation DiagLoc = E->getBeginLoc();
if (getLangOpts().CPlusPlus11) {
@@ -14538,14 +14538,13 @@
return ExprError();
}
- if (!isa<ConstantExpr>(E))
- E = ConstantExpr::Create(Context, E);
-
// Circumvent ICE checking in C++11 to avoid evaluating the expression twice
// in the non-ICE case.
if (!getLangOpts().CPlusPlus11 && E->isIntegerConstantExpr(Context)) {
if (Result)
*Result = E->EvaluateKnownConstIntCheckOverflow(Context);
+ if (!isa<ConstantExpr>(E))
+ E = ConstantExpr::Create(Context, E);
return E;
}
@@ -14555,8 +14554,13 @@
// Try to evaluate the expression, and produce diagnostics explaining why it's
// not a constant expression as a side-effect.
- bool Folded = E->EvaluateAsRValue(EvalResult, Context) &&
- EvalResult.Val.isInt() && !EvalResult.HasSideEffects;
+ bool Folded =
+ E->EvaluateAsRValue(EvalResult, Context, /*isConstantContext*/ true) &&
+ EvalResult.Val.isInt() && !EvalResult.HasSideEffects;
+
+ if (!isa<ConstantExpr>(E))
+ if (StoreResult)
+ E = ConstantExpr::Create(Context, E, EvalResult.Val);
// In C++11, we can rely on diagnostics being produced for any expression
// which is not a constant expression. If no diagnostics were produced, then
Index: clang/lib/Sema/SemaDeclCXX.cpp
===================================================================
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -14006,8 +14006,6 @@
ExprResult Converted = PerformContextuallyConvertToBool(AssertExpr);
if (Converted.isInvalid())
Failed = true;
- else
- Converted = ConstantExpr::Create(Context, Converted.get());
llvm::APSInt Cond;
if (!Failed && VerifyIntegerConstantExpression(Converted.get(), &Cond,
Index: clang/lib/AST/ExprConstant.cpp
===================================================================
--- clang/lib/AST/ExprConstant.cpp
+++ clang/lib/AST/ExprConstant.cpp
@@ -8963,6 +8963,8 @@
bool IntExprEvaluator::VisitConstantExpr(const ConstantExpr *E) {
llvm::SaveAndRestore<bool> InConstantContext(Info.InConstantContext, true);
+ if (E->getResultStorageKind() != ConstantExpr::RSK_None)
+ return Success(E->getAPValueResult(), E);
return ExprEvaluatorBaseTy::VisitConstantExpr(E);
}
Index: clang/lib/AST/Expr.cpp
===================================================================
--- clang/lib/AST/Expr.cpp
+++ clang/lib/AST/Expr.cpp
@@ -239,6 +239,7 @@
ConstantExpr::getStorageKind(const APValue &Value) {
switch (Value.getKind()) {
case APValue::None:
+ case APValue::Indeterminate:
return ConstantExpr::RSK_None;
case APValue::Int:
if (!Value.getInt().needsCleanup())
@@ -249,9 +250,18 @@
}
}
+ConstantExpr::ResultStorageKind
+ConstantExpr::getStorageKind(const Type *T, const ASTContext &Context) {
+ if (T->isIntegralOrEnumerationType() && Context.getTypeInfo(T).Width <= 64)
+ return ConstantExpr::RSK_Int64;
+ return ConstantExpr::RSK_APValue;
+}
+
void ConstantExpr::DefaultInit(ResultStorageKind StorageKind) {
ConstantExprBits.ResultKind = StorageKind;
- if (StorageKind == RSK_APValue)
+ ConstantExprBits.APValueKind = APValue::None;
+ ConstantExprBits.HasCleanup = false;
+ if (StorageKind == ConstantExpr::RSK_APValue)
::new (getTrailingObjects<APValue>()) APValue();
}
@@ -269,8 +279,6 @@
StorageKind == ConstantExpr::RSK_Int64);
void *Mem = Context.Allocate(Size, alignof(ConstantExpr));
ConstantExpr *Self = new (Mem) ConstantExpr(E, StorageKind);
- if (StorageKind == ConstantExpr::RSK_APValue)
- Context.AddAPValueCleanup(&Self->APValueResult());
return Self;
}
@@ -278,7 +286,7 @@
const APValue &Result) {
ResultStorageKind StorageKind = getStorageKind(Result);
ConstantExpr *Self = Create(Context, E, StorageKind);
- Self->SetResult(Result);
+ Self->SetResult(Result, Context);
return Self;
}
@@ -296,14 +304,13 @@
StorageKind == ConstantExpr::RSK_Int64);
void *Mem = Context.Allocate(Size, alignof(ConstantExpr));
ConstantExpr *Self = new (Mem) ConstantExpr(StorageKind, Empty);
- if (StorageKind == ConstantExpr::RSK_APValue)
- Context.AddAPValueCleanup(&Self->APValueResult());
return Self;
}
-void ConstantExpr::MoveIntoResult(APValue &Value) {
+void ConstantExpr::MoveIntoResult(APValue &Value, const ASTContext &Context) {
assert(getStorageKind(Value) == ConstantExprBits.ResultKind &&
"Invalid storage for this value kind");
+ ConstantExprBits.APValueKind = Value.getKind();
switch (ConstantExprBits.ResultKind) {
case RSK_None:
return;
@@ -313,12 +320,28 @@
ConstantExprBits.IsUnsigned = Value.getInt().isUnsigned();
return;
case RSK_APValue:
+ if (!ConstantExprBits.HasCleanup && Value.needsCleanup()) {
+ ConstantExprBits.HasCleanup = true;
+ Context.addDestruction(&APValueResult());
+ }
APValueResult() = std::move(Value);
return;
}
llvm_unreachable("Invalid ResultKind Bits");
}
+llvm::APSInt ConstantExpr::getResultAsAPSInt() const {
+ switch (ConstantExprBits.ResultKind) {
+ case ConstantExpr::RSK_APValue:
+ return APValueResult().getInt();
+ case ConstantExpr::RSK_Int64:
+ return llvm::APSInt(llvm::APInt(ConstantExprBits.BitWidth, Int64Result()),
+ ConstantExprBits.IsUnsigned);
+ default:
+ llvm_unreachable("invalid Accessor");
+ }
+}
+
APValue ConstantExpr::getAPValueResult() const {
switch (ConstantExprBits.ResultKind) {
case ConstantExpr::RSK_APValue:
Index: clang/lib/AST/ASTContext.cpp
===================================================================
--- clang/lib/AST/ASTContext.cpp
+++ clang/lib/AST/ASTContext.cpp
@@ -908,7 +908,7 @@
Parents.reset();
}
-void ASTContext::AddDeallocation(void (*Callback)(void*), void *Data) {
+void ASTContext::AddDeallocation(void (*Callback)(void *), void *Data) const {
Deallocations.push_back({Callback, Data});
}
Index: clang/include/clang/Sema/Sema.h
===================================================================
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -10294,7 +10294,8 @@
/// Can optionally return the value of the expression.
ExprResult VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result,
VerifyICEDiagnoser &Diagnoser,
- bool AllowFold = true);
+ bool AllowFold = true,
+ bool StoreResult = true);
ExprResult VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result,
unsigned DiagID,
bool AllowFold = true);
Index: clang/include/clang/AST/Stmt.h
===================================================================
--- clang/include/clang/AST/Stmt.h
+++ clang/include/clang/AST/Stmt.h
@@ -332,6 +332,9 @@
/// The kind of result that is trail-allocated.
unsigned ResultKind : 2;
+ /// Kind of Result as defined by APValue::Kind
+ unsigned APValueKind : 4;
+
/// When ResultKind == RSK_Int64. whether the trail-allocated integer is
/// signed.
unsigned IsUnsigned : 1;
@@ -340,6 +343,10 @@
/// integer. 7 bits because it is the minimal number of bit to represent a
/// value from 0 to 64 (the size of the trail-allocated number).
unsigned BitWidth : 7;
+
+ /// When ResultKind == RSK_APValue. Wether the ASTContext will cleanup the
+ /// destructor on the trail-allocated APValue.
+ unsigned HasCleanup : 1;
};
class PredefinedExprBitfields {
Index: clang/include/clang/AST/Expr.h
===================================================================
--- clang/include/clang/AST/Expr.h
+++ clang/include/clang/AST/Expr.h
@@ -998,6 +998,9 @@
EmptyShell Empty);
static ResultStorageKind getStorageKind(const APValue &Value);
+ static ResultStorageKind getStorageKind(const Type *T,
+ const ASTContext &Context);
+
SourceLocation getBeginLoc() const LLVM_READONLY {
return SubExpr->getBeginLoc();
}
@@ -1009,24 +1012,20 @@
return T->getStmtClass() == ConstantExprClass;
}
- void SetResult(APValue Value) { MoveIntoResult(Value); }
- void MoveIntoResult(APValue &Value);
+ void SetResult(APValue Value, const ASTContext &Context) {
+ MoveIntoResult(Value, Context);
+ }
+ void MoveIntoResult(APValue &Value, const ASTContext &Context);
APValue::ValueKind getResultAPValueKind() const {
- switch (ConstantExprBits.ResultKind) {
- case ConstantExpr::RSK_APValue:
- return APValueResult().getKind();
- case ConstantExpr::RSK_Int64:
- return APValue::Int;
- case ConstantExpr::RSK_None:
- return APValue::None;
- }
- llvm_unreachable("invalid ResultKind");
+ return static_cast<APValue::ValueKind>(ConstantExprBits.APValueKind);
}
ResultStorageKind getResultStorageKind() const {
return static_cast<const ResultStorageKind>(ConstantExprBits.ResultKind);
}
APValue getAPValueResult() const;
+ const APValue &getResultAsAPValue() const { return APValueResult(); }
+ llvm::APSInt getResultAsAPSInt() const;
// Iterators
child_range children() { return child_range(&SubExpr, &SubExpr+1); }
Index: clang/include/clang/AST/ASTContext.h
===================================================================
--- clang/include/clang/AST/ASTContext.h
+++ clang/include/clang/AST/ASTContext.h
@@ -2751,12 +2751,11 @@
///
/// \param Data Pointer data that will be provided to the callback function
/// when it is called.
- void AddDeallocation(void (*Callback)(void*), void *Data);
+ void AddDeallocation(void (*Callback)(void *), void *Data) const;
/// If T isn't trivially destructible, calls AddDeallocation to register it
/// for destruction.
- template <typename T>
- void addDestruction(T *Ptr) {
+ template <typename T> void addDestruction(T *Ptr) const {
if (!std::is_trivially_destructible<T>::value) {
auto DestroyPtr = [](void *V) { static_cast<T *>(V)->~T(); };
AddDeallocation(DestroyPtr, Ptr);
@@ -2819,10 +2818,6 @@
APValue *getMaterializedTemporaryValue(const MaterializeTemporaryExpr *E,
bool MayCreate);
- /// Adds an APValue that will be destructed during the destruction of the
- /// ASTContext.
- void AddAPValueCleanup(APValue *Ptr) const { APValueCleanups.push_back(Ptr); }
-
/// Return a string representing the human readable name for the specified
/// function declaration or file name. Used by SourceLocExpr and
/// PredefinedExpr to cache evaluated results.
@@ -2989,7 +2984,7 @@
// in order to track and run destructors while we're tearing things down.
using DeallocationFunctionsAndArguments =
llvm::SmallVector<std::pair<void (*)(void *), void *>, 16>;
- DeallocationFunctionsAndArguments Deallocations;
+ mutable DeallocationFunctionsAndArguments Deallocations;
// FIXME: This currently contains the set of StoredDeclMaps used
// by DeclContext objects. This probably should not be in ASTContext,
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits