diff options
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r-- | clang/lib/Sema/SemaExprCXX.cpp | 39 | ||||
-rw-r--r-- | clang/lib/Sema/TreeTransform.h | 29 |
2 files changed, 68 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 27545d802e4..edfa4a532df 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -2739,6 +2739,45 @@ ExprResult Sema::BuildBinaryTypeTrait(BinaryTypeTrait BTT, 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/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index dc96e59420b..c642e642cc8 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -1915,6 +1915,17 @@ public: 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 @@ TreeTransform<Derived>::TransformBinaryTypeTraitExpr(BinaryTypeTraitExpr *E) { 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 |