[Builtins] Implement __builtin_is_constant_evaluated for use in C++2a

Summary:
This patch implements `__builtin_is_constant_evaluated` as specifier by [P0595R2](https://wg21.link/p0595r2). It is built on the back of Bill Wendling's work for `__builtin_constant_p()`.

More tests to come, but early feedback is appreciated.

I plan to implement warnings for common mis-usages like those belowe in a following patch:
```
void foo(int x) {
  if constexpr (std::is_constant_evaluated())) { // condition is always `true`. Should use plain `if` instead.
   foo_constexpr(x);
  } else {
    foo_runtime(x);
  }
}
```



Reviewers: rsmith, MaskRay, bruno, void

Reviewed By: rsmith

Subscribers: dexonsmith, zoecarver, fdeazeve, kristina, cfe-commits

Differential Revision: https://reviews.llvm.org/D55500

llvm-svn: 359067
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 168681b..0a8b60d 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -8279,6 +8279,9 @@
     return Success(false, E);
   }
 
+  case Builtin::BI__builtin_is_constant_evaluated:
+    return Success(Info.InConstantContext, E);
+
   case Builtin::BI__builtin_ctz:
   case Builtin::BI__builtin_ctzl:
   case Builtin::BI__builtin_ctzll:
@@ -11139,6 +11142,7 @@
   EvalInfo::EvaluationMode EM = EvalInfo::EM_ConstantExpression;
   EvalInfo Info(Ctx, Result, EM);
   Info.InConstantContext = true;
+
   if (!::Evaluate(Result.Val, Info, this))
     return false;
 
diff --git a/clang/lib/Basic/Builtins.cpp b/clang/lib/Basic/Builtins.cpp
index f04bc1f..cfc5927 100644
--- a/clang/lib/Basic/Builtins.cpp
+++ b/clang/lib/Basic/Builtins.cpp
@@ -75,9 +75,12 @@
   bool OclCUnsupported = !LangOpts.OpenCL &&
                          (BuiltinInfo.Langs & ALL_OCLC_LANGUAGES);
   bool OpenMPUnsupported = !LangOpts.OpenMP && BuiltinInfo.Langs == OMP_LANG;
+  bool CPlusPlusUnsupported =
+      !LangOpts.CPlusPlus && BuiltinInfo.Langs == CXX_LANG;
   return !BuiltinsUnsupported && !MathBuiltinsUnsupported && !OclCUnsupported &&
          !OclC1Unsupported && !OclC2Unsupported && !OpenMPUnsupported &&
-         !GnuModeUnsupported && !MSModeUnsupported && !ObjCUnsupported;
+         !GnuModeUnsupported && !MSModeUnsupported && !ObjCUnsupported &&
+         !CPlusPlusUnsupported;
 }
 
 /// initializeBuiltins - Mark the identifiers for all the builtins with their
diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp
index aea99dbb..a5c0224 100644
--- a/clang/lib/CodeGen/CGDecl.cpp
+++ b/clang/lib/CodeGen/CGDecl.cpp
@@ -1783,7 +1783,8 @@
   }
 
   llvm::Constant *constant = nullptr;
-  if (emission.IsConstantAggregate || D.isConstexpr()) {
+  if (emission.IsConstantAggregate || D.isConstexpr() ||
+      D.isUsableInConstantExpressions(getContext())) {
     assert(!capturedByInit && "constant init contains a capturing block?");
     constant = ConstantEmitter(*this).tryEmitAbstractForInitializer(D);
     if (constant && trivialAutoVarInit !=