summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST/Decl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/AST/Decl.cpp')
-rw-r--r--clang/lib/AST/Decl.cpp22
1 files changed, 21 insertions, 1 deletions
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 8b77e01f4e8..1b744c82a09 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -2245,12 +2245,16 @@ void VarDecl::setInit(Expr *I) {
Init = I;
}
-bool VarDecl::isUsableInConstantExpressions(ASTContext &C) const {
+bool VarDecl::mightBeUsableInConstantExpressions(ASTContext &C) const {
const LangOptions &Lang = C.getLangOpts();
if (!Lang.CPlusPlus)
return false;
+ // Function parameters are never usable in constant expressions.
+ if (isa<ParmVarDecl>(this))
+ return false;
+
// In C++11, any variable of reference type can be used in a constant
// expression if it is initialized by a constant expression.
if (Lang.CPlusPlus11 && getType()->isReferenceType())
@@ -2272,6 +2276,22 @@ bool VarDecl::isUsableInConstantExpressions(ASTContext &C) const {
return Lang.CPlusPlus11 && isConstexpr();
}
+bool VarDecl::isUsableInConstantExpressions(ASTContext &Context) const {
+ // C++2a [expr.const]p3:
+ // A variable is usable in constant expressions after its initializing
+ // declaration is encountered...
+ const VarDecl *DefVD = nullptr;
+ const Expr *Init = getAnyInitializer(DefVD);
+ if (!Init || Init->isValueDependent())
+ return false;
+ // ... if it is a constexpr variable, or it is of reference type or of
+ // const-qualified integral or enumeration type, ...
+ if (!DefVD->mightBeUsableInConstantExpressions(Context))
+ return false;
+ // ... and its initializer is a constant initializer.
+ return DefVD->checkInitIsICE();
+}
+
/// Convert the initializer for this declaration to the elaborated EvaluatedStmt
/// form, which contains extra information on the evaluated value of the
/// initializer.
OpenPOWER on IntegriCloud