t/clang/expr-traits

Patch authored by David Abrahams.

These two expression traits (__is_lvalue_expr, __is_rvalue_expr) are used for
parsing code that employs certain features of the Embarcadero C++ compiler.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@130122 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index 27545d8..edfa4a5 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -2739,6 +2739,45 @@
                                                  ResultType));
 }
 
+ExprResult Sema::ActOnExpressionTrait(ExpressionTrait ET,
+                                     SourceLocation KWLoc,
+                                     Expr* Queried,
+                                     SourceLocation RParen) {
+  // If error parsing the expression, ignore.
+  if (!Queried)
+      return ExprError();
+
+  ExprResult Result
+    = BuildExpressionTrait(ET, KWLoc, Queried, RParen);
+
+  return move(Result);
+}
+
+ExprResult Sema::BuildExpressionTrait(ExpressionTrait ET,
+                                     SourceLocation KWLoc,
+                                     Expr* Queried,
+                                     SourceLocation RParen) {
+  if (Queried->isTypeDependent()) {
+    // Delay type-checking for type-dependent expressions.
+  } else if (Queried->getType()->isPlaceholderType()) {
+    ExprResult PE = CheckPlaceholderExpr(Queried);
+    if (PE.isInvalid()) return ExprError();
+    return BuildExpressionTrait(ET, KWLoc, PE.take(), RParen);
+  }
+
+  bool Value = false;
+  switch (ET) {
+  default: llvm_unreachable("Unknown or unimplemented expression trait");
+  case ET_IsLValueExpr:       Value = Queried->isLValue(); break;
+  case ET_IsRValueExpr:       Value = Queried->isRValue(); break;
+  }
+  
+  // C99 6.5.3.4p4: the type (an unsigned integer type) is size_t.
+  return Owned(
+      new (Context) ExpressionTraitExpr(
+          KWLoc, ET, Queried, Value, RParen, Context.BoolTy));
+}
+
 QualType Sema::CheckPointerToMemberOperands(ExprResult &lex, ExprResult &rex,
                                             ExprValueKind &VK,
                                             SourceLocation Loc,
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index dc96e59..c642e64 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -1915,6 +1915,17 @@
     return getSema().BuildBinaryTypeTrait(Trait, StartLoc, LhsT, RhsT, RParenLoc);
   }
 
+  /// \brief Build a new expression trait expression.
+  ///
+  /// By default, performs semantic analysis to build the new expression.
+  /// Subclasses may override this routine to provide different behavior.
+  ExprResult RebuildExpressionTrait(ExpressionTrait Trait,
+                                   SourceLocation StartLoc,
+                                   Expr *Queried,
+                                   SourceLocation RParenLoc) {
+    return getSema().BuildExpressionTrait(Trait, StartLoc, Queried, RParenLoc);
+  }
+
   /// \brief Build a new (previously unresolved) declaration reference
   /// expression.
   ///
@@ -6911,6 +6922,24 @@
 
 template<typename Derived>
 ExprResult
+TreeTransform<Derived>::TransformExpressionTraitExpr(ExpressionTraitExpr *E) {
+  ExprResult SubExpr;
+  {
+    EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated);
+    SubExpr = getDerived().TransformExpr(E->getQueriedExpression());
+    if (SubExpr.isInvalid())
+      return ExprError();
+
+    if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getQueriedExpression())
+      return SemaRef.Owned(E);
+  }
+
+  return getDerived().RebuildExpressionTrait(
+      E->getTrait(), E->getLocStart(), SubExpr.get(), E->getLocEnd());
+}
+
+template<typename Derived>
+ExprResult
 TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
                                                DependentScopeDeclRefExpr *E) {
   NestedNameSpecifierLoc QualifierLoc