aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema')
-rw-r--r--lib/Sema/SemaExprCXX.cpp71
-rw-r--r--lib/Sema/TreeTransform.h33
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