|
@@ -3595,24 +3595,6 @@ 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);
|
|
|
-}
|
|
|
-
|
|
|
/// \brief Determine whether T has a non-trivial Objective-C lifetime in
|
|
|
/// ARC mode.
|
|
|
static bool hasNontrivialObjCLifetime(QualType T) {
|
|
@@ -3632,9 +3614,16 @@ static bool hasNontrivialObjCLifetime(QualType T) {
|
|
|
llvm_unreachable("Unknown ObjC lifetime qualifier");
|
|
|
}
|
|
|
|
|
|
+static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT, QualType LhsT,
|
|
|
+ QualType RhsT, SourceLocation KeyLoc);
|
|
|
+
|
|
|
static bool evaluateTypeTrait(Sema &S, TypeTrait Kind, SourceLocation KWLoc,
|
|
|
ArrayRef<TypeSourceInfo *> Args,
|
|
|
SourceLocation RParenLoc) {
|
|
|
+ if (Kind <= BTT_Last)
|
|
|
+ return EvaluateBinaryTypeTrait(S, Kind, Args[0]->getType(),
|
|
|
+ Args[1]->getType(), RParenLoc);
|
|
|
+
|
|
|
switch (Kind) {
|
|
|
case clang::TT_IsTriviallyConstructible: {
|
|
|
// C++11 [meta.unary.prop]:
|
|
@@ -3709,6 +3698,7 @@ static bool evaluateTypeTrait(Sema &S, TypeTrait Kind, SourceLocation KWLoc,
|
|
|
// calls.
|
|
|
return !Result.get()->hasNonTrivialCall(S.Context);
|
|
|
}
|
|
|
+ default: llvm_unreachable("not a TT");
|
|
|
}
|
|
|
|
|
|
return false;
|
|
@@ -3717,6 +3707,17 @@ static bool evaluateTypeTrait(Sema &S, TypeTrait Kind, SourceLocation KWLoc,
|
|
|
ExprResult Sema::BuildTypeTrait(TypeTrait Kind, SourceLocation KWLoc,
|
|
|
ArrayRef<TypeSourceInfo *> Args,
|
|
|
SourceLocation RParenLoc) {
|
|
|
+ QualType ResultType = Context.BoolTy;
|
|
|
+ // __builtin_types_compatible_p is a GNU C extension, not a C++ type trait.
|
|
|
+ if (Kind == BTT_TypeCompatible) {
|
|
|
+ ResultType = Context.IntTy;
|
|
|
+ if (getLangOpts().CPlusPlus) {
|
|
|
+ Diag(KWLoc, diag::err_types_compatible_p_in_cplusplus)
|
|
|
+ << SourceRange(KWLoc, RParenLoc);
|
|
|
+ return ExprError();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
bool Dependent = false;
|
|
|
for (unsigned I = 0, N = Args.size(); I != N; ++I) {
|
|
|
if (Args[I]->getType()->isDependentType()) {
|
|
@@ -3724,17 +3725,17 @@ ExprResult Sema::BuildTypeTrait(TypeTrait Kind, SourceLocation KWLoc,
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- bool Value = false;
|
|
|
+
|
|
|
+ bool Result = false;
|
|
|
if (!Dependent)
|
|
|
- Value = evaluateTypeTrait(*this, Kind, KWLoc, Args, RParenLoc);
|
|
|
-
|
|
|
- return TypeTraitExpr::Create(Context, Context.BoolTy, KWLoc, Kind,
|
|
|
- Args, RParenLoc, Value);
|
|
|
+ Result = evaluateTypeTrait(*this, Kind, KWLoc, Args, RParenLoc);
|
|
|
+
|
|
|
+ return TypeTraitExpr::Create(Context, ResultType, KWLoc, Kind, Args,
|
|
|
+ RParenLoc, Result);
|
|
|
}
|
|
|
|
|
|
-ExprResult Sema::ActOnTypeTrait(TypeTrait Kind, SourceLocation KWLoc,
|
|
|
- ArrayRef<ParsedType> Args,
|
|
|
+ExprResult Sema::ActOnTypeTrait(TypeTrait Kind, unsigned Arity,
|
|
|
+ SourceLocation KWLoc, ArrayRef<ParsedType> Args,
|
|
|
SourceLocation RParenLoc) {
|
|
|
SmallVector<TypeSourceInfo *, 4> ConvertedArgs;
|
|
|
ConvertedArgs.reserve(Args.size());
|
|
@@ -3747,13 +3748,12 @@ ExprResult Sema::ActOnTypeTrait(TypeTrait Kind, SourceLocation KWLoc,
|
|
|
|
|
|
ConvertedArgs.push_back(TInfo);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
return BuildTypeTrait(Kind, KWLoc, ConvertedArgs, RParenLoc);
|
|
|
}
|
|
|
|
|
|
-static bool EvaluateBinaryTypeTrait(Sema &Self, BinaryTypeTrait BTT,
|
|
|
- QualType LhsT, QualType RhsT,
|
|
|
- SourceLocation KeyLoc) {
|
|
|
+static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT, QualType LhsT,
|
|
|
+ QualType RhsT, SourceLocation KeyLoc) {
|
|
|
assert(!LhsT->isDependentType() && !RhsT->isDependentType() &&
|
|
|
"Cannot evaluate traits of dependent types");
|
|
|
|
|
@@ -3910,38 +3910,11 @@ static bool EvaluateBinaryTypeTrait(Sema &Self, BinaryTypeTrait BTT,
|
|
|
|
|
|
return !Result.get()->hasNonTrivialCall(Self.Context);
|
|
|
}
|
|
|
+ default: llvm_unreachable("not a BTT");
|
|
|
}
|
|
|
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();
|
|
|
- QualType ResultType = Context.BoolTy;
|
|
|
-
|
|
|
- // __builtin_types_compatible_p is a GNU C extension, not a C++ type trait.
|
|
|
- if (BTT == BTT_TypeCompatible) {
|
|
|
- ResultType = Context.IntTy;
|
|
|
- if (getLangOpts().CPlusPlus) {
|
|
|
- Diag(KWLoc, diag::err_types_compatible_p_in_cplusplus)
|
|
|
- << SourceRange(KWLoc, RParen);
|
|
|
- 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,
|
|
|
- ResultType));
|
|
|
-}
|
|
|
-
|
|
|
ExprResult Sema::ActOnArrayTypeTrait(ArrayTypeTrait ATT,
|
|
|
SourceLocation KWLoc,
|
|
|
ParsedType Ty,
|