diff options
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 71 | ||||
-rw-r--r-- | lib/Sema/TreeTransform.h | 33 |
2 files changed, 104 insertions, 0 deletions
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 5b377cc778..7be1c3307a 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -2342,6 +2342,77 @@ ExprResult Sema::BuildUnaryTypeTrait(UnaryTypeTrait UTT, RParen, Context.BoolTy)); } +ExprResult Sema::ActOnBinaryTypeTrait(BinaryTypeTrait BTT, + SourceLocation KWLoc, + ParsedType LhsTy, + ParsedType RhsTy, + SourceLocation RParen) { + TypeSourceInfo *LhsTSInfo; + QualType LhsT = GetTypeFromParser(LhsTy, &LhsTSInfo); + if (!LhsTSInfo) + LhsTSInfo = Context.getTrivialTypeSourceInfo(LhsT); + + TypeSourceInfo *RhsTSInfo; + QualType RhsT = GetTypeFromParser(RhsTy, &RhsTSInfo); + if (!RhsTSInfo) + RhsTSInfo = Context.getTrivialTypeSourceInfo(RhsT); + + return BuildBinaryTypeTrait(BTT, KWLoc, LhsTSInfo, RhsTSInfo, RParen); +} + +static bool EvaluateBinaryTypeTrait(Sema &Self, BinaryTypeTrait BTT, + QualType LhsT, QualType RhsT, + SourceLocation KeyLoc) { + assert((!LhsT->isDependentType() || RhsT->isDependentType()) && + "Cannot evaluate traits for dependent types."); + + switch(BTT) { + case BTT_IsBaseOf: + // C++0x [meta.rel]p2 + // Base is a base class of Derived without regard to cv-qualifiers or + // Base and Derived are not unions and name the same class type without + // regard to cv-qualifiers. + if (Self.IsDerivedFrom(RhsT, LhsT) || + (!LhsT->isUnionType() && !RhsT->isUnionType() + && LhsT->getAsCXXRecordDecl() == RhsT->getAsCXXRecordDecl())) + return true; + + return false; + } + llvm_unreachable("Unknown type trait or not implemented"); +} + +ExprResult Sema::BuildBinaryTypeTrait(BinaryTypeTrait BTT, + SourceLocation KWLoc, + TypeSourceInfo *LhsTSInfo, + TypeSourceInfo *RhsTSInfo, + SourceLocation RParen) { + QualType LhsT = LhsTSInfo->getType(); + QualType RhsT = RhsTSInfo->getType(); + + if (BTT == BTT_IsBaseOf) { + // C++0x [meta.rel]p2 + // If Base and Derived are class types and are different types + // (ignoring possible cv-qualifiers) then Derived shall be a complete + // type. [] + CXXRecordDecl *LhsDecl = LhsT->getAsCXXRecordDecl(); + CXXRecordDecl *RhsDecl = RhsT->getAsCXXRecordDecl(); + if (!LhsT->isDependentType() && !RhsT->isDependentType() && + LhsDecl && RhsDecl && LhsT != RhsT && + RequireCompleteType(KWLoc, RhsT, + diag::err_incomplete_type_used_in_type_trait_expr)) + return ExprError(); + } + + bool Value = false; + if (!LhsT->isDependentType() && !RhsT->isDependentType()) + Value = EvaluateBinaryTypeTrait(*this, BTT, LhsT, RhsT, KWLoc); + + return Owned(new (Context) BinaryTypeTraitExpr(KWLoc, BTT, LhsTSInfo, + RhsTSInfo, Value, RParen, + Context.BoolTy)); +} + QualType Sema::CheckPointerToMemberOperands(Expr *&lex, Expr *&rex, ExprValueKind &VK, SourceLocation Loc, diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 8d3d4018ce..816a1701d8 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -1657,6 +1657,18 @@ public: return getSema().BuildUnaryTypeTrait(Trait, StartLoc, T, RParenLoc); } + /// \brief Build a new binary type trait expression. + /// + /// By default, performs semantic analysis to build the new expression. + /// Subclasses may override this routine to provide different behavior. + ExprResult RebuildBinaryTypeTrait(BinaryTypeTrait Trait, + SourceLocation StartLoc, + TypeSourceInfo *LhsT, + TypeSourceInfo *RhsT, + SourceLocation RParenLoc) { + return getSema().BuildBinaryTypeTrait(Trait, StartLoc, LhsT, RhsT, RParenLoc); + } + /// \brief Build a new (previously unresolved) declaration reference /// expression. /// @@ -5667,6 +5679,27 @@ TreeTransform<Derived>::TransformUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) { template<typename Derived> ExprResult +TreeTransform<Derived>::TransformBinaryTypeTraitExpr(BinaryTypeTraitExpr *E) { + TypeSourceInfo *LhsT = getDerived().TransformType(E->getLhsTypeSourceInfo()); + if (!LhsT) + return ExprError(); + + TypeSourceInfo *RhsT = getDerived().TransformType(E->getRhsTypeSourceInfo()); + if (!RhsT) + return ExprError(); + + if (!getDerived().AlwaysRebuild() && + LhsT == E->getLhsTypeSourceInfo() && RhsT == E->getRhsTypeSourceInfo()) + return SemaRef.Owned(E); + + return getDerived().RebuildBinaryTypeTrait(E->getTrait(), + E->getLocStart(), + LhsT, RhsT, + E->getLocEnd()); +} + +template<typename Derived> +ExprResult TreeTransform<Derived>::TransformDependentScopeDeclRefExpr( DependentScopeDeclRefExpr *E) { NestedNameSpecifier *NNS |