mirror of https://github.com/microsoft/clang.git
Eliminate BinaryTypeTraitExpr
There's nothing special about type traits accepting two arguments. This commit eliminates BinaryTypeTraitExpr and switches all related handling over to TypeTraitExpr. Also fixes a CodeGen failure with variadic type traits appearing in a non-constant expression. The BTT/TT prefix and evaluation code is retained as-is for now but will soon be further cleaned up. This is part of the ongoing work to unify type traits. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@197273 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
c614b2d1a9
commit
cbb29af710
|
@ -2168,76 +2168,6 @@ public:
|
||||||
friend class ASTStmtReader;
|
friend class ASTStmtReader;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// \brief Represents a GCC or MS binary type trait, as used in the
|
|
||||||
/// implementation of TR1/C++11 type trait templates.
|
|
||||||
///
|
|
||||||
/// Example:
|
|
||||||
/// \code
|
|
||||||
/// __is_base_of(Base, Derived) == true
|
|
||||||
/// \endcode
|
|
||||||
class BinaryTypeTraitExpr : public Expr {
|
|
||||||
/// \brief The trait. A BinaryTypeTrait enum in MSVC compatible unsigned.
|
|
||||||
unsigned BTT : 8;
|
|
||||||
|
|
||||||
/// The value of the type trait. Unspecified if dependent.
|
|
||||||
bool Value : 1;
|
|
||||||
|
|
||||||
/// \brief The location of the type trait keyword.
|
|
||||||
SourceLocation Loc;
|
|
||||||
|
|
||||||
/// \brief The location of the closing paren.
|
|
||||||
SourceLocation RParen;
|
|
||||||
|
|
||||||
/// \brief The lhs type being queried.
|
|
||||||
TypeSourceInfo *LhsType;
|
|
||||||
|
|
||||||
/// \brief The rhs type being queried.
|
|
||||||
TypeSourceInfo *RhsType;
|
|
||||||
|
|
||||||
public:
|
|
||||||
BinaryTypeTraitExpr(SourceLocation loc, BinaryTypeTrait btt,
|
|
||||||
TypeSourceInfo *lhsType, TypeSourceInfo *rhsType,
|
|
||||||
bool value, SourceLocation rparen, QualType ty)
|
|
||||||
: Expr(BinaryTypeTraitExprClass, ty, VK_RValue, OK_Ordinary, false,
|
|
||||||
lhsType->getType()->isDependentType() ||
|
|
||||||
rhsType->getType()->isDependentType(),
|
|
||||||
(lhsType->getType()->isInstantiationDependentType() ||
|
|
||||||
rhsType->getType()->isInstantiationDependentType()),
|
|
||||||
(lhsType->getType()->containsUnexpandedParameterPack() ||
|
|
||||||
rhsType->getType()->containsUnexpandedParameterPack())),
|
|
||||||
BTT(btt), Value(value), Loc(loc), RParen(rparen),
|
|
||||||
LhsType(lhsType), RhsType(rhsType) { }
|
|
||||||
|
|
||||||
|
|
||||||
explicit BinaryTypeTraitExpr(EmptyShell Empty)
|
|
||||||
: Expr(BinaryTypeTraitExprClass, Empty), BTT(0), Value(false),
|
|
||||||
LhsType(), RhsType() { }
|
|
||||||
|
|
||||||
SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
|
|
||||||
SourceLocation getLocEnd() const LLVM_READONLY { return RParen; }
|
|
||||||
|
|
||||||
BinaryTypeTrait getTrait() const {
|
|
||||||
return static_cast<BinaryTypeTrait>(BTT);
|
|
||||||
}
|
|
||||||
|
|
||||||
QualType getLhsType() const { return LhsType->getType(); }
|
|
||||||
QualType getRhsType() const { return RhsType->getType(); }
|
|
||||||
|
|
||||||
TypeSourceInfo *getLhsTypeSourceInfo() const { return LhsType; }
|
|
||||||
TypeSourceInfo *getRhsTypeSourceInfo() const { return RhsType; }
|
|
||||||
|
|
||||||
bool getValue() const { assert(!isTypeDependent()); return Value; }
|
|
||||||
|
|
||||||
static bool classof(const Stmt *T) {
|
|
||||||
return T->getStmtClass() == BinaryTypeTraitExprClass;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Iterators
|
|
||||||
child_range children() { return child_range(); }
|
|
||||||
|
|
||||||
friend class ASTStmtReader;
|
|
||||||
};
|
|
||||||
|
|
||||||
/// \brief A type trait used in the implementation of various C++11 and
|
/// \brief A type trait used in the implementation of various C++11 and
|
||||||
/// Library TR1 trait templates.
|
/// Library TR1 trait templates.
|
||||||
///
|
///
|
||||||
|
|
|
@ -2145,11 +2145,6 @@ DEF_TRAVERSE_STMT(UnaryTypeTraitExpr, {
|
||||||
TRY_TO(TraverseTypeLoc(S->getQueriedTypeSourceInfo()->getTypeLoc()));
|
TRY_TO(TraverseTypeLoc(S->getQueriedTypeSourceInfo()->getTypeLoc()));
|
||||||
})
|
})
|
||||||
|
|
||||||
DEF_TRAVERSE_STMT(BinaryTypeTraitExpr, {
|
|
||||||
TRY_TO(TraverseTypeLoc(S->getLhsTypeSourceInfo()->getTypeLoc()));
|
|
||||||
TRY_TO(TraverseTypeLoc(S->getRhsTypeSourceInfo()->getTypeLoc()));
|
|
||||||
})
|
|
||||||
|
|
||||||
DEF_TRAVERSE_STMT(TypeTraitExpr, {
|
DEF_TRAVERSE_STMT(TypeTraitExpr, {
|
||||||
for (unsigned I = 0, N = S->getNumArgs(); I != N; ++I)
|
for (unsigned I = 0, N = S->getNumArgs(); I != N; ++I)
|
||||||
TRY_TO(TraverseTypeLoc(S->getArg(I)->getTypeLoc()));
|
TRY_TO(TraverseTypeLoc(S->getArg(I)->getTypeLoc()));
|
||||||
|
|
|
@ -116,7 +116,6 @@ def CXXDeleteExpr : DStmt<Expr>;
|
||||||
def CXXPseudoDestructorExpr : DStmt<Expr>;
|
def CXXPseudoDestructorExpr : DStmt<Expr>;
|
||||||
def TypeTraitExpr : DStmt<Expr>;
|
def TypeTraitExpr : DStmt<Expr>;
|
||||||
def UnaryTypeTraitExpr : DStmt<Expr>;
|
def UnaryTypeTraitExpr : DStmt<Expr>;
|
||||||
def BinaryTypeTraitExpr : DStmt<Expr>;
|
|
||||||
def ArrayTypeTraitExpr : DStmt<Expr>;
|
def ArrayTypeTraitExpr : DStmt<Expr>;
|
||||||
def ExpressionTraitExpr : DStmt<Expr>;
|
def ExpressionTraitExpr : DStmt<Expr>;
|
||||||
def DependentScopeDeclRefExpr : DStmt<Expr>;
|
def DependentScopeDeclRefExpr : DStmt<Expr>;
|
||||||
|
|
|
@ -68,16 +68,6 @@ namespace clang {
|
||||||
UTT_IsVolatile
|
UTT_IsVolatile
|
||||||
};
|
};
|
||||||
|
|
||||||
/// \brief Names for the binary type traits.
|
|
||||||
enum BinaryTypeTrait {
|
|
||||||
BTT_IsBaseOf,
|
|
||||||
BTT_IsConvertible,
|
|
||||||
BTT_IsConvertibleTo,
|
|
||||||
BTT_IsSame,
|
|
||||||
BTT_TypeCompatible,
|
|
||||||
BTT_IsTriviallyAssignable
|
|
||||||
};
|
|
||||||
|
|
||||||
/// \brief Names for the array type traits.
|
/// \brief Names for the array type traits.
|
||||||
enum ArrayTypeTrait {
|
enum ArrayTypeTrait {
|
||||||
ATT_ArrayRank,
|
ATT_ArrayRank,
|
||||||
|
@ -93,6 +83,13 @@ namespace clang {
|
||||||
|
|
||||||
/// \brief Names for type traits that operate specifically on types.
|
/// \brief Names for type traits that operate specifically on types.
|
||||||
enum TypeTrait {
|
enum TypeTrait {
|
||||||
|
BTT_IsBaseOf,
|
||||||
|
BTT_IsConvertible,
|
||||||
|
BTT_IsConvertibleTo,
|
||||||
|
BTT_IsSame,
|
||||||
|
BTT_TypeCompatible,
|
||||||
|
BTT_IsTriviallyAssignable,
|
||||||
|
BTT_Last = BTT_IsTriviallyAssignable,
|
||||||
TT_IsTriviallyConstructible
|
TT_IsTriviallyConstructible
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -4218,23 +4218,9 @@ public:
|
||||||
TypeSourceInfo *T,
|
TypeSourceInfo *T,
|
||||||
SourceLocation RParen);
|
SourceLocation RParen);
|
||||||
|
|
||||||
/// ActOnBinaryTypeTrait - Parsed one of the bianry type trait support
|
|
||||||
/// pseudo-functions.
|
|
||||||
ExprResult ActOnBinaryTypeTrait(BinaryTypeTrait OTT,
|
|
||||||
SourceLocation KWLoc,
|
|
||||||
ParsedType LhsTy,
|
|
||||||
ParsedType RhsTy,
|
|
||||||
SourceLocation RParen);
|
|
||||||
|
|
||||||
ExprResult BuildBinaryTypeTrait(BinaryTypeTrait BTT,
|
|
||||||
SourceLocation KWLoc,
|
|
||||||
TypeSourceInfo *LhsT,
|
|
||||||
TypeSourceInfo *RhsT,
|
|
||||||
SourceLocation RParen);
|
|
||||||
|
|
||||||
/// \brief Parsed one of the type trait support pseudo-functions.
|
/// \brief Parsed one of the type trait support pseudo-functions.
|
||||||
ExprResult ActOnTypeTrait(TypeTrait Kind, SourceLocation KWLoc,
|
ExprResult ActOnTypeTrait(TypeTrait Kind, unsigned Arity,
|
||||||
ArrayRef<ParsedType> Args,
|
SourceLocation KWLoc, ArrayRef<ParsedType> Args,
|
||||||
SourceLocation RParenLoc);
|
SourceLocation RParenLoc);
|
||||||
ExprResult BuildTypeTrait(TypeTrait Kind, SourceLocation KWLoc,
|
ExprResult BuildTypeTrait(TypeTrait Kind, SourceLocation KWLoc,
|
||||||
ArrayRef<TypeSourceInfo *> Args,
|
ArrayRef<TypeSourceInfo *> Args,
|
||||||
|
|
|
@ -1308,7 +1308,6 @@ namespace clang {
|
||||||
|
|
||||||
EXPR_OPAQUE_VALUE, // OpaqueValueExpr
|
EXPR_OPAQUE_VALUE, // OpaqueValueExpr
|
||||||
EXPR_BINARY_CONDITIONAL_OPERATOR, // BinaryConditionalOperator
|
EXPR_BINARY_CONDITIONAL_OPERATOR, // BinaryConditionalOperator
|
||||||
EXPR_BINARY_TYPE_TRAIT, // BinaryTypeTraitExpr
|
|
||||||
EXPR_TYPE_TRAIT, // TypeTraitExpr
|
EXPR_TYPE_TRAIT, // TypeTraitExpr
|
||||||
EXPR_ARRAY_TYPE_TRAIT, // ArrayTypeTraitIntExpr
|
EXPR_ARRAY_TYPE_TRAIT, // ArrayTypeTraitIntExpr
|
||||||
|
|
||||||
|
|
|
@ -2799,7 +2799,6 @@ bool Expr::HasSideEffects(const ASTContext &Ctx) const {
|
||||||
case CXXScalarValueInitExprClass:
|
case CXXScalarValueInitExprClass:
|
||||||
case TypeTraitExprClass:
|
case TypeTraitExprClass:
|
||||||
case UnaryTypeTraitExprClass:
|
case UnaryTypeTraitExprClass:
|
||||||
case BinaryTypeTraitExprClass:
|
|
||||||
case ArrayTypeTraitExprClass:
|
case ArrayTypeTraitExprClass:
|
||||||
case ExpressionTraitExprClass:
|
case ExpressionTraitExprClass:
|
||||||
case CXXNoexceptExprClass:
|
case CXXNoexceptExprClass:
|
||||||
|
|
|
@ -166,7 +166,6 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) {
|
||||||
case Expr::CXXNoexceptExprClass:
|
case Expr::CXXNoexceptExprClass:
|
||||||
case Expr::CXXScalarValueInitExprClass:
|
case Expr::CXXScalarValueInitExprClass:
|
||||||
case Expr::UnaryTypeTraitExprClass:
|
case Expr::UnaryTypeTraitExprClass:
|
||||||
case Expr::BinaryTypeTraitExprClass:
|
|
||||||
case Expr::TypeTraitExprClass:
|
case Expr::TypeTraitExprClass:
|
||||||
case Expr::ArrayTypeTraitExprClass:
|
case Expr::ArrayTypeTraitExprClass:
|
||||||
case Expr::ExpressionTraitExprClass:
|
case Expr::ExpressionTraitExprClass:
|
||||||
|
|
|
@ -5731,10 +5731,6 @@ public:
|
||||||
return Success(E->getValue(), E);
|
return Success(E->getValue(), E);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VisitBinaryTypeTraitExpr(const BinaryTypeTraitExpr *E) {
|
|
||||||
return Success(E->getValue(), E);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool VisitTypeTraitExpr(const TypeTraitExpr *E) {
|
bool VisitTypeTraitExpr(const TypeTraitExpr *E) {
|
||||||
return Success(E->getValue(), E);
|
return Success(E->getValue(), E);
|
||||||
}
|
}
|
||||||
|
@ -8328,7 +8324,6 @@ static ICEDiag CheckICE(const Expr* E, const ASTContext &Ctx) {
|
||||||
case Expr::CXXBoolLiteralExprClass:
|
case Expr::CXXBoolLiteralExprClass:
|
||||||
case Expr::CXXScalarValueInitExprClass:
|
case Expr::CXXScalarValueInitExprClass:
|
||||||
case Expr::UnaryTypeTraitExprClass:
|
case Expr::UnaryTypeTraitExprClass:
|
||||||
case Expr::BinaryTypeTraitExprClass:
|
|
||||||
case Expr::TypeTraitExprClass:
|
case Expr::TypeTraitExprClass:
|
||||||
case Expr::ArrayTypeTraitExprClass:
|
case Expr::ArrayTypeTraitExprClass:
|
||||||
case Expr::ExpressionTraitExprClass:
|
case Expr::ExpressionTraitExprClass:
|
||||||
|
|
|
@ -2583,7 +2583,6 @@ recurse:
|
||||||
case Expr::ConvertVectorExprClass:
|
case Expr::ConvertVectorExprClass:
|
||||||
case Expr::StmtExprClass:
|
case Expr::StmtExprClass:
|
||||||
case Expr::UnaryTypeTraitExprClass:
|
case Expr::UnaryTypeTraitExprClass:
|
||||||
case Expr::BinaryTypeTraitExprClass:
|
|
||||||
case Expr::TypeTraitExprClass:
|
case Expr::TypeTraitExprClass:
|
||||||
case Expr::ArrayTypeTraitExprClass:
|
case Expr::ArrayTypeTraitExprClass:
|
||||||
case Expr::ExpressionTraitExprClass:
|
case Expr::ExpressionTraitExprClass:
|
||||||
|
|
|
@ -1691,17 +1691,11 @@ static const char *getTypeTraitName(UnaryTypeTrait UTT) {
|
||||||
llvm_unreachable("Type trait not covered by switch statement");
|
llvm_unreachable("Type trait not covered by switch statement");
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *getTypeTraitName(BinaryTypeTrait BTT) {
|
|
||||||
switch (BTT) {
|
|
||||||
#define TYPE_TRAIT_2(Spelling, Name, Key) \
|
|
||||||
case clang::BTT_##Name: return #Spelling;
|
|
||||||
#include "clang/Basic/TokenKinds.def"
|
|
||||||
}
|
|
||||||
llvm_unreachable("Binary type trait not covered by switch");
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char *getTypeTraitName(TypeTrait TT) {
|
static const char *getTypeTraitName(TypeTrait TT) {
|
||||||
switch (TT) {
|
switch (TT) {
|
||||||
|
#define TYPE_TRAIT_2(Spelling, Name, Key) \
|
||||||
|
case clang::BTT_##Name: return #Spelling;
|
||||||
|
#include "clang/Basic/TokenKinds.def"
|
||||||
#define TYPE_TRAIT_N(Spelling, Name, Key) \
|
#define TYPE_TRAIT_N(Spelling, Name, Key) \
|
||||||
case clang::TT_##Name: return #Spelling;
|
case clang::TT_##Name: return #Spelling;
|
||||||
#include "clang/Basic/TokenKinds.def"
|
#include "clang/Basic/TokenKinds.def"
|
||||||
|
@ -1731,14 +1725,6 @@ void StmtPrinter::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
|
||||||
OS << ')';
|
OS << ')';
|
||||||
}
|
}
|
||||||
|
|
||||||
void StmtPrinter::VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E) {
|
|
||||||
OS << getTypeTraitName(E->getTrait()) << '(';
|
|
||||||
E->getLhsType().print(OS, Policy);
|
|
||||||
OS << ',';
|
|
||||||
E->getRhsType().print(OS, Policy);
|
|
||||||
OS << ')';
|
|
||||||
}
|
|
||||||
|
|
||||||
void StmtPrinter::VisitTypeTraitExpr(TypeTraitExpr *E) {
|
void StmtPrinter::VisitTypeTraitExpr(TypeTraitExpr *E) {
|
||||||
OS << getTypeTraitName(E->getTrait()) << "(";
|
OS << getTypeTraitName(E->getTrait()) << "(";
|
||||||
for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
|
for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
|
||||||
|
|
|
@ -954,13 +954,6 @@ void StmtProfiler::VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *S) {
|
||||||
VisitType(S->getQueriedType());
|
VisitType(S->getQueriedType());
|
||||||
}
|
}
|
||||||
|
|
||||||
void StmtProfiler::VisitBinaryTypeTraitExpr(const BinaryTypeTraitExpr *S) {
|
|
||||||
VisitExpr(S);
|
|
||||||
ID.AddInteger(S->getTrait());
|
|
||||||
VisitType(S->getLhsType());
|
|
||||||
VisitType(S->getRhsType());
|
|
||||||
}
|
|
||||||
|
|
||||||
void StmtProfiler::VisitTypeTraitExpr(const TypeTraitExpr *S) {
|
void StmtProfiler::VisitTypeTraitExpr(const TypeTraitExpr *S) {
|
||||||
VisitExpr(S);
|
VisitExpr(S);
|
||||||
ID.AddInteger(S->getTrait());
|
ID.AddInteger(S->getTrait());
|
||||||
|
|
|
@ -371,7 +371,7 @@ public:
|
||||||
return Builder.getInt1(E->getValue());
|
return Builder.getInt1(E->getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
Value *VisitBinaryTypeTraitExpr(const BinaryTypeTraitExpr *E) {
|
Value *VisitTypeTraitExpr(const TypeTraitExpr *E) {
|
||||||
return llvm::ConstantInt::get(ConvertType(E->getType()), E->getValue());
|
return llvm::ConstantInt::get(ConvertType(E->getType()), E->getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2693,18 +2693,12 @@ static UnaryTypeTrait UnaryTypeTraitFromTokKind(tok::TokenKind kind) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static BinaryTypeTrait BinaryTypeTraitFromTokKind(tok::TokenKind kind) {
|
|
||||||
switch(kind) {
|
|
||||||
default: llvm_unreachable("Not a known binary type trait");
|
|
||||||
#define TYPE_TRAIT_2(Spelling, Name, Key) \
|
|
||||||
case tok::kw_ ## Spelling: return BTT_ ## Name;
|
|
||||||
#include "clang/Basic/TokenKinds.def"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static TypeTrait TypeTraitFromTokKind(tok::TokenKind kind) {
|
static TypeTrait TypeTraitFromTokKind(tok::TokenKind kind) {
|
||||||
switch (kind) {
|
switch (kind) {
|
||||||
default: llvm_unreachable("Not a known type trait");
|
default: llvm_unreachable("Not a known type trait");
|
||||||
|
#define TYPE_TRAIT_2(Spelling, Name, Key) \
|
||||||
|
case tok::kw_ ## Spelling: return BTT_ ## Name;
|
||||||
|
#include "clang/Basic/TokenKinds.def"
|
||||||
#define TYPE_TRAIT_N(Spelling, Name, Key) \
|
#define TYPE_TRAIT_N(Spelling, Name, Key) \
|
||||||
case tok::kw_ ## Spelling: return TT_ ## Name;
|
case tok::kw_ ## Spelling: return TT_ ## Name;
|
||||||
#include "clang/Basic/TokenKinds.def"
|
#include "clang/Basic/TokenKinds.def"
|
||||||
|
@ -2805,15 +2799,9 @@ ExprResult Parser::ParseTypeTrait() {
|
||||||
if (Arity == 1)
|
if (Arity == 1)
|
||||||
return Actions.ActOnUnaryTypeTrait(UnaryTypeTraitFromTokKind(Kind), Loc,
|
return Actions.ActOnUnaryTypeTrait(UnaryTypeTraitFromTokKind(Kind), Loc,
|
||||||
Args[0], EndLoc);
|
Args[0], EndLoc);
|
||||||
if (Arity == 2)
|
|
||||||
return Actions.ActOnBinaryTypeTrait(BinaryTypeTraitFromTokKind(Kind), Loc,
|
|
||||||
Args[0], Args[1], EndLoc);
|
|
||||||
if (!Arity)
|
|
||||||
return Actions.ActOnTypeTrait(TypeTraitFromTokKind(Kind), Loc, Args,
|
|
||||||
EndLoc);
|
|
||||||
|
|
||||||
llvm_unreachable("unhandled type trait rank");
|
return Actions.ActOnTypeTrait(TypeTraitFromTokKind(Kind), Arity, Loc, Args,
|
||||||
return ExprError();
|
EndLoc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ParseArrayTypeTrait - Parse the built-in array type-trait
|
/// ParseArrayTypeTrait - Parse the built-in array type-trait
|
||||||
|
|
|
@ -1063,7 +1063,6 @@ CanThrowResult Sema::canThrow(const Expr *E) {
|
||||||
case Expr::AddrLabelExprClass:
|
case Expr::AddrLabelExprClass:
|
||||||
case Expr::ArrayTypeTraitExprClass:
|
case Expr::ArrayTypeTraitExprClass:
|
||||||
case Expr::AtomicExprClass:
|
case Expr::AtomicExprClass:
|
||||||
case Expr::BinaryTypeTraitExprClass:
|
|
||||||
case Expr::TypeTraitExprClass:
|
case Expr::TypeTraitExprClass:
|
||||||
case Expr::CXXBoolLiteralExprClass:
|
case Expr::CXXBoolLiteralExprClass:
|
||||||
case Expr::CXXNoexceptExprClass:
|
case Expr::CXXNoexceptExprClass:
|
||||||
|
|
|
@ -3595,24 +3595,6 @@ ExprResult Sema::BuildUnaryTypeTrait(UnaryTypeTrait UTT,
|
||||||
RParen, Context.BoolTy));
|
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
|
/// \brief Determine whether T has a non-trivial Objective-C lifetime in
|
||||||
/// ARC mode.
|
/// ARC mode.
|
||||||
static bool hasNontrivialObjCLifetime(QualType T) {
|
static bool hasNontrivialObjCLifetime(QualType T) {
|
||||||
|
@ -3632,9 +3614,16 @@ static bool hasNontrivialObjCLifetime(QualType T) {
|
||||||
llvm_unreachable("Unknown ObjC lifetime qualifier");
|
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,
|
static bool evaluateTypeTrait(Sema &S, TypeTrait Kind, SourceLocation KWLoc,
|
||||||
ArrayRef<TypeSourceInfo *> Args,
|
ArrayRef<TypeSourceInfo *> Args,
|
||||||
SourceLocation RParenLoc) {
|
SourceLocation RParenLoc) {
|
||||||
|
if (Kind <= BTT_Last)
|
||||||
|
return EvaluateBinaryTypeTrait(S, Kind, Args[0]->getType(),
|
||||||
|
Args[1]->getType(), RParenLoc);
|
||||||
|
|
||||||
switch (Kind) {
|
switch (Kind) {
|
||||||
case clang::TT_IsTriviallyConstructible: {
|
case clang::TT_IsTriviallyConstructible: {
|
||||||
// C++11 [meta.unary.prop]:
|
// C++11 [meta.unary.prop]:
|
||||||
|
@ -3709,6 +3698,7 @@ static bool evaluateTypeTrait(Sema &S, TypeTrait Kind, SourceLocation KWLoc,
|
||||||
// calls.
|
// calls.
|
||||||
return !Result.get()->hasNonTrivialCall(S.Context);
|
return !Result.get()->hasNonTrivialCall(S.Context);
|
||||||
}
|
}
|
||||||
|
default: llvm_unreachable("not a TT");
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -3717,6 +3707,17 @@ static bool evaluateTypeTrait(Sema &S, TypeTrait Kind, SourceLocation KWLoc,
|
||||||
ExprResult Sema::BuildTypeTrait(TypeTrait Kind, SourceLocation KWLoc,
|
ExprResult Sema::BuildTypeTrait(TypeTrait Kind, SourceLocation KWLoc,
|
||||||
ArrayRef<TypeSourceInfo *> Args,
|
ArrayRef<TypeSourceInfo *> Args,
|
||||||
SourceLocation RParenLoc) {
|
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;
|
bool Dependent = false;
|
||||||
for (unsigned I = 0, N = Args.size(); I != N; ++I) {
|
for (unsigned I = 0, N = Args.size(); I != N; ++I) {
|
||||||
if (Args[I]->getType()->isDependentType()) {
|
if (Args[I]->getType()->isDependentType()) {
|
||||||
|
@ -3725,16 +3726,16 @@ ExprResult Sema::BuildTypeTrait(TypeTrait Kind, SourceLocation KWLoc,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Value = false;
|
bool Result = false;
|
||||||
if (!Dependent)
|
if (!Dependent)
|
||||||
Value = evaluateTypeTrait(*this, Kind, KWLoc, Args, RParenLoc);
|
Result = evaluateTypeTrait(*this, Kind, KWLoc, Args, RParenLoc);
|
||||||
|
|
||||||
return TypeTraitExpr::Create(Context, Context.BoolTy, KWLoc, Kind,
|
return TypeTraitExpr::Create(Context, ResultType, KWLoc, Kind, Args,
|
||||||
Args, RParenLoc, Value);
|
RParenLoc, Result);
|
||||||
}
|
}
|
||||||
|
|
||||||
ExprResult Sema::ActOnTypeTrait(TypeTrait Kind, SourceLocation KWLoc,
|
ExprResult Sema::ActOnTypeTrait(TypeTrait Kind, unsigned Arity,
|
||||||
ArrayRef<ParsedType> Args,
|
SourceLocation KWLoc, ArrayRef<ParsedType> Args,
|
||||||
SourceLocation RParenLoc) {
|
SourceLocation RParenLoc) {
|
||||||
SmallVector<TypeSourceInfo *, 4> ConvertedArgs;
|
SmallVector<TypeSourceInfo *, 4> ConvertedArgs;
|
||||||
ConvertedArgs.reserve(Args.size());
|
ConvertedArgs.reserve(Args.size());
|
||||||
|
@ -3751,9 +3752,8 @@ ExprResult Sema::ActOnTypeTrait(TypeTrait Kind, SourceLocation KWLoc,
|
||||||
return BuildTypeTrait(Kind, KWLoc, ConvertedArgs, RParenLoc);
|
return BuildTypeTrait(Kind, KWLoc, ConvertedArgs, RParenLoc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool EvaluateBinaryTypeTrait(Sema &Self, BinaryTypeTrait BTT,
|
static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT, QualType LhsT,
|
||||||
QualType LhsT, QualType RhsT,
|
QualType RhsT, SourceLocation KeyLoc) {
|
||||||
SourceLocation KeyLoc) {
|
|
||||||
assert(!LhsT->isDependentType() && !RhsT->isDependentType() &&
|
assert(!LhsT->isDependentType() && !RhsT->isDependentType() &&
|
||||||
"Cannot evaluate traits of dependent types");
|
"Cannot evaluate traits of dependent types");
|
||||||
|
|
||||||
|
@ -3910,38 +3910,11 @@ static bool EvaluateBinaryTypeTrait(Sema &Self, BinaryTypeTrait BTT,
|
||||||
|
|
||||||
return !Result.get()->hasNonTrivialCall(Self.Context);
|
return !Result.get()->hasNonTrivialCall(Self.Context);
|
||||||
}
|
}
|
||||||
|
default: llvm_unreachable("not a BTT");
|
||||||
}
|
}
|
||||||
llvm_unreachable("Unknown type trait or not implemented");
|
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,
|
ExprResult Sema::ActOnArrayTypeTrait(ArrayTypeTrait ATT,
|
||||||
SourceLocation KWLoc,
|
SourceLocation KWLoc,
|
||||||
ParsedType Ty,
|
ParsedType Ty,
|
||||||
|
|
|
@ -2146,18 +2146,6 @@ public:
|
||||||
return getSema().BuildUnaryTypeTrait(Trait, StartLoc, T, RParenLoc);
|
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 type trait expression.
|
/// \brief Build a new type trait expression.
|
||||||
///
|
///
|
||||||
/// By default, performs semantic analysis to build the new expression.
|
/// By default, performs semantic analysis to build the new expression.
|
||||||
|
@ -7893,27 +7881,6 @@ TreeTransform<Derived>::TransformUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
|
||||||
E->getLocEnd());
|
E->getLocEnd());
|
||||||
}
|
}
|
||||||
|
|
||||||
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>
|
template<typename Derived>
|
||||||
ExprResult
|
ExprResult
|
||||||
TreeTransform<Derived>::TransformTypeTraitExpr(TypeTraitExpr *E) {
|
TreeTransform<Derived>::TransformTypeTraitExpr(TypeTraitExpr *E) {
|
||||||
|
|
|
@ -1494,17 +1494,6 @@ void ASTStmtReader::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
|
||||||
E->QueriedType = GetTypeSourceInfo(Record, Idx);
|
E->QueriedType = GetTypeSourceInfo(Record, Idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ASTStmtReader::VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E) {
|
|
||||||
VisitExpr(E);
|
|
||||||
E->BTT = (BinaryTypeTrait)Record[Idx++];
|
|
||||||
E->Value = (bool)Record[Idx++];
|
|
||||||
SourceRange Range = ReadSourceRange(Record, Idx);
|
|
||||||
E->Loc = Range.getBegin();
|
|
||||||
E->RParen = Range.getEnd();
|
|
||||||
E->LhsType = GetTypeSourceInfo(Record, Idx);
|
|
||||||
E->RhsType = GetTypeSourceInfo(Record, Idx);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ASTStmtReader::VisitTypeTraitExpr(TypeTraitExpr *E) {
|
void ASTStmtReader::VisitTypeTraitExpr(TypeTraitExpr *E) {
|
||||||
VisitExpr(E);
|
VisitExpr(E);
|
||||||
E->TypeTraitExprBits.NumArgs = Record[Idx++];
|
E->TypeTraitExprBits.NumArgs = Record[Idx++];
|
||||||
|
@ -2398,10 +2387,6 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
|
||||||
S = new (Context) UnaryTypeTraitExpr(Empty);
|
S = new (Context) UnaryTypeTraitExpr(Empty);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EXPR_BINARY_TYPE_TRAIT:
|
|
||||||
S = new (Context) BinaryTypeTraitExpr(Empty);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EXPR_TYPE_TRAIT:
|
case EXPR_TYPE_TRAIT:
|
||||||
S = TypeTraitExpr::CreateDeserialized(Context,
|
S = TypeTraitExpr::CreateDeserialized(Context,
|
||||||
Record[ASTStmtReader::NumExprFields]);
|
Record[ASTStmtReader::NumExprFields]);
|
||||||
|
|
|
@ -776,7 +776,6 @@ static void AddStmtsExprs(llvm::BitstreamWriter &Stream,
|
||||||
RECORD(EXPR_CXX_UNARY_TYPE_TRAIT);
|
RECORD(EXPR_CXX_UNARY_TYPE_TRAIT);
|
||||||
RECORD(EXPR_CXX_NOEXCEPT);
|
RECORD(EXPR_CXX_NOEXCEPT);
|
||||||
RECORD(EXPR_OPAQUE_VALUE);
|
RECORD(EXPR_OPAQUE_VALUE);
|
||||||
RECORD(EXPR_BINARY_TYPE_TRAIT);
|
|
||||||
RECORD(EXPR_PACK_EXPANSION);
|
RECORD(EXPR_PACK_EXPANSION);
|
||||||
RECORD(EXPR_SIZEOF_PACK);
|
RECORD(EXPR_SIZEOF_PACK);
|
||||||
RECORD(EXPR_SUBST_NON_TYPE_TEMPLATE_PARM_PACK);
|
RECORD(EXPR_SUBST_NON_TYPE_TEMPLATE_PARM_PACK);
|
||||||
|
|
|
@ -1495,16 +1495,6 @@ void ASTStmtWriter::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
|
||||||
Code = serialization::EXPR_CXX_UNARY_TYPE_TRAIT;
|
Code = serialization::EXPR_CXX_UNARY_TYPE_TRAIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ASTStmtWriter::VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E) {
|
|
||||||
VisitExpr(E);
|
|
||||||
Record.push_back(E->getTrait());
|
|
||||||
Record.push_back(E->getValue());
|
|
||||||
Writer.AddSourceRange(E->getSourceRange(), Record);
|
|
||||||
Writer.AddTypeSourceInfo(E->getLhsTypeSourceInfo(), Record);
|
|
||||||
Writer.AddTypeSourceInfo(E->getRhsTypeSourceInfo(), Record);
|
|
||||||
Code = serialization::EXPR_BINARY_TYPE_TRAIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ASTStmtWriter::VisitTypeTraitExpr(TypeTraitExpr *E) {
|
void ASTStmtWriter::VisitTypeTraitExpr(TypeTraitExpr *E) {
|
||||||
VisitExpr(E);
|
VisitExpr(E);
|
||||||
Record.push_back(E->TypeTraitExprBits.NumArgs);
|
Record.push_back(E->TypeTraitExprBits.NumArgs);
|
||||||
|
|
|
@ -646,7 +646,6 @@ bool IdempotentOperationChecker::CanVary(const Expr *Ex,
|
||||||
case Stmt::OffsetOfExprClass:
|
case Stmt::OffsetOfExprClass:
|
||||||
case Stmt::CompoundLiteralExprClass:
|
case Stmt::CompoundLiteralExprClass:
|
||||||
case Stmt::AddrLabelExprClass:
|
case Stmt::AddrLabelExprClass:
|
||||||
case Stmt::BinaryTypeTraitExprClass:
|
|
||||||
case Stmt::GNUNullExprClass:
|
case Stmt::GNUNullExprClass:
|
||||||
case Stmt::InitListExprClass:
|
case Stmt::InitListExprClass:
|
||||||
case Stmt::DesignatedInitExprClass:
|
case Stmt::DesignatedInitExprClass:
|
||||||
|
|
|
@ -664,7 +664,6 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
|
||||||
case Stmt::CXXUnresolvedConstructExprClass:
|
case Stmt::CXXUnresolvedConstructExprClass:
|
||||||
case Stmt::DependentScopeDeclRefExprClass:
|
case Stmt::DependentScopeDeclRefExprClass:
|
||||||
case Stmt::UnaryTypeTraitExprClass:
|
case Stmt::UnaryTypeTraitExprClass:
|
||||||
case Stmt::BinaryTypeTraitExprClass:
|
|
||||||
case Stmt::TypeTraitExprClass:
|
case Stmt::TypeTraitExprClass:
|
||||||
case Stmt::ArrayTypeTraitExprClass:
|
case Stmt::ArrayTypeTraitExprClass:
|
||||||
case Stmt::ExpressionTraitExprClass:
|
case Stmt::ExpressionTraitExprClass:
|
||||||
|
|
|
@ -313,7 +313,7 @@ void test_unexpanded_exprs(Types ...values) {
|
||||||
// UnaryTypeTraitExpr
|
// UnaryTypeTraitExpr
|
||||||
__is_pod(Types); // expected-error{{expression contains unexpanded parameter pack 'Types'}}
|
__is_pod(Types); // expected-error{{expression contains unexpanded parameter pack 'Types'}}
|
||||||
|
|
||||||
// BinaryTypeTraitExpr
|
// Binary TypeTraitExpr
|
||||||
__is_base_of(Types, T); // expected-error{{expression contains unexpanded parameter pack 'Types'}}
|
__is_base_of(Types, T); // expected-error{{expression contains unexpanded parameter pack 'Types'}}
|
||||||
__is_base_of(T, Types); // expected-error{{expression contains unexpanded parameter pack 'Types'}}
|
__is_base_of(T, Types); // expected-error{{expression contains unexpanded parameter pack 'Types'}}
|
||||||
|
|
||||||
|
|
|
@ -2,3 +2,5 @@
|
||||||
// expected-no-diagnostics
|
// expected-no-diagnostics
|
||||||
|
|
||||||
bool a() { return __is_pod(int); }
|
bool a() { return __is_pod(int); }
|
||||||
|
|
||||||
|
bool b() { return __is_trivially_constructible(int, int, int); }
|
|
@ -1840,7 +1840,6 @@ public:
|
||||||
void VisitSwitchStmt(const SwitchStmt *S);
|
void VisitSwitchStmt(const SwitchStmt *S);
|
||||||
void VisitWhileStmt(const WhileStmt *W);
|
void VisitWhileStmt(const WhileStmt *W);
|
||||||
void VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E);
|
void VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E);
|
||||||
void VisitBinaryTypeTraitExpr(const BinaryTypeTraitExpr *E);
|
|
||||||
void VisitTypeTraitExpr(const TypeTraitExpr *E);
|
void VisitTypeTraitExpr(const TypeTraitExpr *E);
|
||||||
void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
|
void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
|
||||||
void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
|
void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
|
||||||
|
@ -2189,11 +2188,6 @@ void EnqueueVisitor::VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E) {
|
||||||
AddTypeLoc(E->getQueriedTypeSourceInfo());
|
AddTypeLoc(E->getQueriedTypeSourceInfo());
|
||||||
}
|
}
|
||||||
|
|
||||||
void EnqueueVisitor::VisitBinaryTypeTraitExpr(const BinaryTypeTraitExpr *E) {
|
|
||||||
AddTypeLoc(E->getRhsTypeSourceInfo());
|
|
||||||
AddTypeLoc(E->getLhsTypeSourceInfo());
|
|
||||||
}
|
|
||||||
|
|
||||||
void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
|
void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
|
||||||
for (unsigned I = E->getNumArgs(); I > 0; --I)
|
for (unsigned I = E->getNumArgs(); I > 0; --I)
|
||||||
AddTypeLoc(E->getArg(I-1));
|
AddTypeLoc(E->getArg(I-1));
|
||||||
|
|
|
@ -213,7 +213,6 @@ CXCursor cxcursor::MakeCXCursor(const Stmt *S, const Decl *Parent,
|
||||||
case Stmt::AsTypeExprClass:
|
case Stmt::AsTypeExprClass:
|
||||||
case Stmt::AtomicExprClass:
|
case Stmt::AtomicExprClass:
|
||||||
case Stmt::BinaryConditionalOperatorClass:
|
case Stmt::BinaryConditionalOperatorClass:
|
||||||
case Stmt::BinaryTypeTraitExprClass:
|
|
||||||
case Stmt::TypeTraitExprClass:
|
case Stmt::TypeTraitExprClass:
|
||||||
case Stmt::CXXBindTemporaryExprClass:
|
case Stmt::CXXBindTemporaryExprClass:
|
||||||
case Stmt::CXXDefaultArgExprClass:
|
case Stmt::CXXDefaultArgExprClass:
|
||||||
|
|
|
@ -2123,11 +2123,6 @@ DEF_TRAVERSE_STMT(UnaryTypeTraitExpr, {
|
||||||
TRY_TO(TraverseTypeLoc(S->getQueriedTypeSourceInfo()->getTypeLoc()));
|
TRY_TO(TraverseTypeLoc(S->getQueriedTypeSourceInfo()->getTypeLoc()));
|
||||||
})
|
})
|
||||||
|
|
||||||
DEF_TRAVERSE_STMT(BinaryTypeTraitExpr, {
|
|
||||||
TRY_TO(TraverseTypeLoc(S->getLhsTypeSourceInfo()->getTypeLoc()));
|
|
||||||
TRY_TO(TraverseTypeLoc(S->getRhsTypeSourceInfo()->getTypeLoc()));
|
|
||||||
})
|
|
||||||
|
|
||||||
DEF_TRAVERSE_STMT(TypeTraitExpr, {
|
DEF_TRAVERSE_STMT(TypeTraitExpr, {
|
||||||
for (unsigned I = 0, N = S->getNumArgs(); I != N; ++I)
|
for (unsigned I = 0, N = S->getNumArgs(); I != N; ++I)
|
||||||
TRY_TO(TraverseTypeLoc(S->getArg(I)->getTypeLoc()));
|
TRY_TO(TraverseTypeLoc(S->getArg(I)->getTypeLoc()));
|
||||||
|
|
Loading…
Reference in New Issue