forked from OSchip/llvm-project
Implementation of Embarcadero array type traits
Patch authored by John Wiegley. These are array type traits used for parsing code that employs certain features of the Embarcadero C++ compiler: __array_rank(T) and __array_extent(T, Dim). llvm-svn: 130351
This commit is contained in:
parent
1e34241abd
commit
6242b6a688
|
@ -1594,6 +1594,68 @@ public:
|
|||
friend class ASTStmtReader;
|
||||
};
|
||||
|
||||
/// ArrayTypeTraitExpr - An Embarcadero array type trait, as used in the
|
||||
/// implementation of __array_rank and __array_extent.
|
||||
/// Example:
|
||||
/// __array_rank(int[10][20]) == 2
|
||||
/// __array_extent(int, 1) == 20
|
||||
class ArrayTypeTraitExpr : public Expr {
|
||||
/// ATT - The trait. An ArrayTypeTrait enum in MSVC compat unsigned.
|
||||
unsigned ATT : 2;
|
||||
|
||||
/// The value of the type trait. Unspecified if dependent.
|
||||
uint64_t Value;
|
||||
|
||||
/// The array dimension being queried, or -1 if not used
|
||||
Expr *Dimension;
|
||||
|
||||
/// Loc - The location of the type trait keyword.
|
||||
SourceLocation Loc;
|
||||
|
||||
/// RParen - The location of the closing paren.
|
||||
SourceLocation RParen;
|
||||
|
||||
/// The type being queried.
|
||||
TypeSourceInfo *QueriedType;
|
||||
|
||||
public:
|
||||
ArrayTypeTraitExpr(SourceLocation loc, ArrayTypeTrait att,
|
||||
TypeSourceInfo *queried, uint64_t value,
|
||||
Expr *dimension, SourceLocation rparen, QualType ty)
|
||||
: Expr(ArrayTypeTraitExprClass, ty, VK_RValue, OK_Ordinary,
|
||||
false, queried->getType()->isDependentType(),
|
||||
queried->getType()->containsUnexpandedParameterPack()),
|
||||
ATT(att), Value(value), Dimension(dimension),
|
||||
Loc(loc), RParen(rparen), QueriedType(queried) { }
|
||||
|
||||
|
||||
explicit ArrayTypeTraitExpr(EmptyShell Empty)
|
||||
: Expr(ArrayTypeTraitExprClass, Empty), ATT(0), Value(false),
|
||||
QueriedType() { }
|
||||
|
||||
virtual SourceRange getSourceRange() const { return SourceRange(Loc, RParen); }
|
||||
|
||||
ArrayTypeTrait getTrait() const { return static_cast<ArrayTypeTrait>(ATT); }
|
||||
|
||||
QualType getQueriedType() const { return QueriedType->getType(); }
|
||||
|
||||
TypeSourceInfo *getQueriedTypeSourceInfo() const { return QueriedType; }
|
||||
|
||||
uint64_t getValue() const { assert(!isTypeDependent()); return Value; }
|
||||
|
||||
Expr *getDimensionExpression() const { return Dimension; }
|
||||
|
||||
static bool classof(const Stmt *T) {
|
||||
return T->getStmtClass() == ArrayTypeTraitExprClass;
|
||||
}
|
||||
static bool classof(const ArrayTypeTraitExpr *) { return true; }
|
||||
|
||||
// Iterators
|
||||
child_range children() { return child_range(); }
|
||||
|
||||
friend class ASTStmtReader;
|
||||
};
|
||||
|
||||
/// ExpressionTraitExpr - An expression trait intrinsic
|
||||
/// Example:
|
||||
/// __is_lvalue_expr(std::cout) == true
|
||||
|
|
|
@ -1849,6 +1849,10 @@ DEF_TRAVERSE_STMT(BinaryTypeTraitExpr, {
|
|||
TRY_TO(TraverseTypeLoc(S->getRhsTypeSourceInfo()->getTypeLoc()));
|
||||
})
|
||||
|
||||
DEF_TRAVERSE_STMT(ArrayTypeTraitExpr, {
|
||||
TRY_TO(TraverseTypeLoc(S->getQueriedTypeSourceInfo()->getTypeLoc()));
|
||||
})
|
||||
|
||||
DEF_TRAVERSE_STMT(ExpressionTraitExpr, {
|
||||
TRY_TO(TraverseStmt(S->getQueriedExpression()));
|
||||
})
|
||||
|
|
|
@ -104,6 +104,7 @@ def CXXDeleteExpr : DStmt<Expr>;
|
|||
def CXXPseudoDestructorExpr : DStmt<Expr>;
|
||||
def UnaryTypeTraitExpr : DStmt<Expr>;
|
||||
def BinaryTypeTraitExpr : DStmt<Expr>;
|
||||
def ArrayTypeTraitExpr : DStmt<Expr>;
|
||||
def ExpressionTraitExpr : DStmt<Expr>;
|
||||
def DependentScopeDeclRefExpr : DStmt<Expr>;
|
||||
def CXXConstructExpr : DStmt<Expr>;
|
||||
|
|
|
@ -378,6 +378,8 @@ KEYWORD(__is_unsigned , KEYCXX)
|
|||
// Embarcadero Binary Type Traits
|
||||
KEYWORD(__is_same , KEYCXX)
|
||||
KEYWORD(__is_convertible , KEYCXX)
|
||||
KEYWORD(__array_rank , KEYCXX)
|
||||
KEYWORD(__array_extent , KEYCXX)
|
||||
|
||||
// Apple Extension.
|
||||
KEYWORD(__private_extern__ , KEYALL)
|
||||
|
|
|
@ -71,6 +71,12 @@ namespace clang {
|
|||
BTT_TypeCompatible
|
||||
};
|
||||
|
||||
/// ArrayTypeTrait - Names for the array type traits.
|
||||
enum ArrayTypeTrait {
|
||||
ATT_ArrayRank,
|
||||
ATT_ArrayExtent
|
||||
};
|
||||
|
||||
/// UnaryExprOrTypeTrait - Names for the "expression or type" traits.
|
||||
enum UnaryExprOrTypeTrait {
|
||||
UETT_SizeOf,
|
||||
|
|
|
@ -1816,7 +1816,8 @@ private:
|
|||
ExprResult ParseBinaryTypeTrait();
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Embarcadero: Expression Traits
|
||||
// Embarcadero: Arary and Expression Traits
|
||||
ExprResult ParseArrayTypeTrait();
|
||||
ExprResult ParseExpressionTrait();
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
|
|
@ -2736,6 +2736,20 @@ public:
|
|||
TypeSourceInfo *RhsT,
|
||||
SourceLocation RParen);
|
||||
|
||||
/// ActOnArrayTypeTrait - Parsed one of the bianry type trait support
|
||||
/// pseudo-functions.
|
||||
ExprResult ActOnArrayTypeTrait(ArrayTypeTrait ATT,
|
||||
SourceLocation KWLoc,
|
||||
ParsedType LhsTy,
|
||||
Expr *DimExpr,
|
||||
SourceLocation RParen);
|
||||
|
||||
ExprResult BuildArrayTypeTrait(ArrayTypeTrait ATT,
|
||||
SourceLocation KWLoc,
|
||||
TypeSourceInfo *TSInfo,
|
||||
Expr *DimExpr,
|
||||
SourceLocation RParen);
|
||||
|
||||
/// ActOnExpressionTrait - Parsed one of the unary type trait support
|
||||
/// pseudo-functions.
|
||||
ExprResult ActOnExpressionTrait(ExpressionTrait OET,
|
||||
|
|
|
@ -978,6 +978,7 @@ namespace clang {
|
|||
EXPR_OPAQUE_VALUE, // OpaqueValueExpr
|
||||
EXPR_BINARY_CONDITIONAL_OPERATOR, // BinaryConditionalOperator
|
||||
EXPR_BINARY_TYPE_TRAIT, // BinaryTypeTraitExpr
|
||||
EXPR_ARRAY_TYPE_TRAIT, // ArrayTypeTraitIntExpr
|
||||
|
||||
EXPR_PACK_EXPANSION, // PackExpansionExpr
|
||||
EXPR_SIZEOF_PACK, // SizeOfPackExpr
|
||||
|
|
|
@ -152,6 +152,7 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) {
|
|||
case Expr::CXXScalarValueInitExprClass:
|
||||
case Expr::UnaryTypeTraitExprClass:
|
||||
case Expr::BinaryTypeTraitExprClass:
|
||||
case Expr::ArrayTypeTraitExprClass:
|
||||
case Expr::ExpressionTraitExprClass:
|
||||
case Expr::ObjCSelectorExprClass:
|
||||
case Expr::ObjCProtocolExprClass:
|
||||
|
|
|
@ -1061,6 +1061,10 @@ public:
|
|||
return Success(E->getValue(), E);
|
||||
}
|
||||
|
||||
bool VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
|
||||
return Success(E->getValue(), E);
|
||||
}
|
||||
|
||||
bool VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
|
||||
return Success(E->getValue(), E);
|
||||
}
|
||||
|
@ -2879,6 +2883,7 @@ static ICEDiag CheckICE(const Expr* E, ASTContext &Ctx) {
|
|||
case Expr::CXXScalarValueInitExprClass:
|
||||
case Expr::UnaryTypeTraitExprClass:
|
||||
case Expr::BinaryTypeTraitExprClass:
|
||||
case Expr::ArrayTypeTraitExprClass:
|
||||
case Expr::ExpressionTraitExprClass:
|
||||
case Expr::CXXNoexceptExprClass:
|
||||
return NoDiag();
|
||||
|
|
|
@ -1911,6 +1911,7 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity) {
|
|||
case Expr::StmtExprClass:
|
||||
case Expr::UnaryTypeTraitExprClass:
|
||||
case Expr::BinaryTypeTraitExprClass:
|
||||
case Expr::ArrayTypeTraitExprClass:
|
||||
case Expr::ExpressionTraitExprClass:
|
||||
case Expr::VAArgExprClass:
|
||||
case Expr::CXXUuidofExprClass:
|
||||
|
|
|
@ -1308,6 +1308,14 @@ static const char *getTypeTraitName(BinaryTypeTrait BTT) {
|
|||
return "";
|
||||
}
|
||||
|
||||
static const char *getTypeTraitName(ArrayTypeTrait ATT) {
|
||||
switch (ATT) {
|
||||
case ATT_ArrayRank: return "__array_rank";
|
||||
case ATT_ArrayExtent: return "__array_extent";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
static const char *getExpressionTraitName(ExpressionTrait ET) {
|
||||
switch (ET) {
|
||||
default: llvm_unreachable("Unknown expression trait");
|
||||
|
@ -1328,6 +1336,11 @@ void StmtPrinter::VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E) {
|
|||
<< E->getRhsType().getAsString(Policy) << ")";
|
||||
}
|
||||
|
||||
void StmtPrinter::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
|
||||
OS << getTypeTraitName(E->getTrait()) << "("
|
||||
<< E->getQueriedType().getAsString(Policy) << ")";
|
||||
}
|
||||
|
||||
void StmtPrinter::VisitExpressionTraitExpr(ExpressionTraitExpr *E) {
|
||||
OS << getExpressionTraitName(E->getTrait()) << "(";
|
||||
PrintExpr(E->getQueriedExpression());
|
||||
|
|
|
@ -802,6 +802,12 @@ void StmtProfiler::VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *S) {
|
|||
VisitType(S->getRhsType());
|
||||
}
|
||||
|
||||
void StmtProfiler::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *S) {
|
||||
VisitExpr(S);
|
||||
ID.AddInteger(S->getTrait());
|
||||
VisitType(S->getQueriedType());
|
||||
}
|
||||
|
||||
void StmtProfiler::VisitExpressionTraitExpr(ExpressionTraitExpr *S) {
|
||||
VisitExpr(S);
|
||||
ID.AddInteger(S->getTrait());
|
||||
|
|
|
@ -367,6 +367,10 @@ public:
|
|||
return llvm::ConstantInt::get(ConvertType(E->getType()), E->getValue());
|
||||
}
|
||||
|
||||
Value *VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
|
||||
return llvm::ConstantInt::get(Builder.getInt32Ty(), E->getValue());
|
||||
}
|
||||
|
||||
Value *VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
|
||||
return llvm::ConstantInt::get(Builder.getInt1Ty(), E->getValue());
|
||||
}
|
||||
|
|
|
@ -490,6 +490,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
|
|||
/// [C++] 'this' [C++ 9.3.2]
|
||||
/// [G++] unary-type-trait '(' type-id ')'
|
||||
/// [G++] binary-type-trait '(' type-id ',' type-id ')' [TODO]
|
||||
/// [EMBT] array-type-trait '(' type-id ',' integer ')'
|
||||
/// [clang] '^' block-literal
|
||||
///
|
||||
/// constant: [C99 6.4.4]
|
||||
|
@ -571,6 +572,10 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
|
|||
/// '__is_convertible'
|
||||
/// '__is_same'
|
||||
///
|
||||
/// [Embarcadero] array-type-trait:
|
||||
/// '__array_rank'
|
||||
/// '__array_extent'
|
||||
///
|
||||
/// [Embarcadero] expression-trait:
|
||||
/// '__is_lvalue_expr'
|
||||
/// '__is_rvalue_expr'
|
||||
|
@ -1072,6 +1077,10 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
|
|||
case tok::kw___is_convertible_to:
|
||||
return ParseBinaryTypeTrait();
|
||||
|
||||
case tok::kw___array_rank:
|
||||
case tok::kw___array_extent:
|
||||
return ParseArrayTypeTrait();
|
||||
|
||||
case tok::kw___is_lvalue_expr:
|
||||
case tok::kw___is_rvalue_expr:
|
||||
return ParseExpressionTrait();
|
||||
|
|
|
@ -1970,6 +1970,14 @@ static BinaryTypeTrait BinaryTypeTraitFromTokKind(tok::TokenKind kind) {
|
|||
}
|
||||
}
|
||||
|
||||
static ArrayTypeTrait ArrayTypeTraitFromTokKind(tok::TokenKind kind) {
|
||||
switch(kind) {
|
||||
default: llvm_unreachable("Not a known binary type trait");
|
||||
case tok::kw___array_rank: return ATT_ArrayRank;
|
||||
case tok::kw___array_extent: return ATT_ArrayExtent;
|
||||
}
|
||||
}
|
||||
|
||||
static ExpressionTrait ExpressionTraitFromTokKind(tok::TokenKind kind) {
|
||||
switch(kind) {
|
||||
default: assert(false && "Not a known unary expression trait.");
|
||||
|
@ -2043,6 +2051,50 @@ ExprResult Parser::ParseBinaryTypeTrait() {
|
|||
return Actions.ActOnBinaryTypeTrait(BTT, Loc, LhsTy.get(), RhsTy.get(), RParen);
|
||||
}
|
||||
|
||||
/// ParseArrayTypeTrait - Parse the built-in array type-trait
|
||||
/// pseudo-functions.
|
||||
///
|
||||
/// primary-expression:
|
||||
/// [Embarcadero] '__array_rank' '(' type-id ')'
|
||||
/// [Embarcadero] '__array_extent' '(' type-id ',' expression ')'
|
||||
///
|
||||
ExprResult Parser::ParseArrayTypeTrait() {
|
||||
ArrayTypeTrait ATT = ArrayTypeTraitFromTokKind(Tok.getKind());
|
||||
SourceLocation Loc = ConsumeToken();
|
||||
|
||||
SourceLocation LParen = Tok.getLocation();
|
||||
if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen))
|
||||
return ExprError();
|
||||
|
||||
TypeResult Ty = ParseTypeName();
|
||||
if (Ty.isInvalid()) {
|
||||
SkipUntil(tok::comma);
|
||||
SkipUntil(tok::r_paren);
|
||||
return ExprError();
|
||||
}
|
||||
|
||||
switch (ATT) {
|
||||
case ATT_ArrayRank: {
|
||||
SourceLocation RParen = MatchRHSPunctuation(tok::r_paren, LParen);
|
||||
return Actions.ActOnArrayTypeTrait(ATT, Loc, Ty.get(), NULL, RParen);
|
||||
}
|
||||
case ATT_ArrayExtent: {
|
||||
if (ExpectAndConsume(tok::comma, diag::err_expected_comma)) {
|
||||
SkipUntil(tok::r_paren);
|
||||
return ExprError();
|
||||
}
|
||||
|
||||
ExprResult DimExpr = ParseExpression();
|
||||
SourceLocation RParen = MatchRHSPunctuation(tok::r_paren, LParen);
|
||||
|
||||
return Actions.ActOnArrayTypeTrait(ATT, Loc, Ty.get(), DimExpr.get(), RParen);
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ExprError();
|
||||
}
|
||||
|
||||
/// ParseExpressionTrait - Parse built-in expression-trait
|
||||
/// pseudo-functions like __is_lvalue_expr( xxx ).
|
||||
///
|
||||
|
|
|
@ -2812,6 +2812,94 @@ ExprResult Sema::BuildBinaryTypeTrait(BinaryTypeTrait BTT,
|
|||
ResultType));
|
||||
}
|
||||
|
||||
ExprResult Sema::ActOnArrayTypeTrait(ArrayTypeTrait ATT,
|
||||
SourceLocation KWLoc,
|
||||
ParsedType Ty,
|
||||
Expr* DimExpr,
|
||||
SourceLocation RParen) {
|
||||
TypeSourceInfo *TSInfo;
|
||||
QualType T = GetTypeFromParser(Ty, &TSInfo);
|
||||
if (!TSInfo)
|
||||
TSInfo = Context.getTrivialTypeSourceInfo(T);
|
||||
|
||||
return BuildArrayTypeTrait(ATT, KWLoc, TSInfo, DimExpr, RParen);
|
||||
}
|
||||
|
||||
static uint64_t EvaluateArrayTypeTrait(Sema &Self, ArrayTypeTrait ATT,
|
||||
QualType T, Expr *DimExpr,
|
||||
SourceLocation KeyLoc) {
|
||||
assert((!T->isDependentType()) &&
|
||||
"Cannot evaluate traits for dependent types.");
|
||||
|
||||
switch(ATT) {
|
||||
case ATT_ArrayRank:
|
||||
if (T->isArrayType()) {
|
||||
unsigned Dim = 0;
|
||||
while (const ArrayType *AT = Self.Context.getAsArrayType(T)) {
|
||||
++Dim;
|
||||
T = AT->getElementType();
|
||||
}
|
||||
return Dim;
|
||||
} else {
|
||||
assert(! "Array type trait applied to non-array type");
|
||||
}
|
||||
case ATT_ArrayExtent: {
|
||||
llvm::APSInt Value;
|
||||
uint64_t Dim;
|
||||
if (DimExpr->isIntegerConstantExpr(Value, Self.Context, 0, false))
|
||||
Dim = Value.getLimitedValue();
|
||||
else
|
||||
assert(! "Dimension expression did not evaluate to a constant integer");
|
||||
|
||||
if (T->isArrayType()) {
|
||||
unsigned D = 0;
|
||||
bool Matched = false;
|
||||
while (const ArrayType *AT = Self.Context.getAsArrayType(T)) {
|
||||
if (Dim == D) {
|
||||
Matched = true;
|
||||
break;
|
||||
}
|
||||
++D;
|
||||
T = AT->getElementType();
|
||||
}
|
||||
|
||||
assert(Matched && T->isArrayType() &&
|
||||
"__array_extent does not refer to an array dimension");
|
||||
|
||||
llvm::APInt size = Self.Context.getAsConstantArrayType(T)->getSize();
|
||||
return size.getLimitedValue();
|
||||
} else {
|
||||
assert(! "Array type trait applied to non-array type");
|
||||
}
|
||||
}
|
||||
}
|
||||
llvm_unreachable("Unknown type trait or not implemented");
|
||||
}
|
||||
|
||||
ExprResult Sema::BuildArrayTypeTrait(ArrayTypeTrait ATT,
|
||||
SourceLocation KWLoc,
|
||||
TypeSourceInfo *TSInfo,
|
||||
Expr* DimExpr,
|
||||
SourceLocation RParen) {
|
||||
QualType T = TSInfo->getType();
|
||||
|
||||
uint64_t Value;
|
||||
if (!T->isDependentType())
|
||||
Value = EvaluateArrayTypeTrait(*this, ATT, T, DimExpr, KWLoc);
|
||||
else
|
||||
return ExprError();
|
||||
|
||||
// Select trait result type.
|
||||
QualType ResultType;
|
||||
switch (ATT) {
|
||||
case ATT_ArrayRank: ResultType = Context.IntTy; break;
|
||||
case ATT_ArrayExtent: ResultType = Context.IntTy; break;
|
||||
}
|
||||
|
||||
return Owned(new (Context) ArrayTypeTraitExpr(KWLoc, ATT, TSInfo, Value,
|
||||
DimExpr, RParen, ResultType));
|
||||
}
|
||||
|
||||
ExprResult Sema::ActOnExpressionTrait(ExpressionTrait ET,
|
||||
SourceLocation KWLoc,
|
||||
Expr* Queried,
|
||||
|
|
|
@ -1915,6 +1915,18 @@ public:
|
|||
return getSema().BuildBinaryTypeTrait(Trait, StartLoc, LhsT, RhsT, RParenLoc);
|
||||
}
|
||||
|
||||
/// \brief Build a new array type trait expression.
|
||||
///
|
||||
/// By default, performs semantic analysis to build the new expression.
|
||||
/// Subclasses may override this routine to provide different behavior.
|
||||
ExprResult RebuildArrayTypeTrait(ArrayTypeTrait Trait,
|
||||
SourceLocation StartLoc,
|
||||
TypeSourceInfo *TSInfo,
|
||||
Expr *DimExpr,
|
||||
SourceLocation RParenLoc) {
|
||||
return getSema().BuildArrayTypeTrait(Trait, StartLoc, TSInfo, DimExpr, RParenLoc);
|
||||
}
|
||||
|
||||
/// \brief Build a new expression trait expression.
|
||||
///
|
||||
/// By default, performs semantic analysis to build the new expression.
|
||||
|
@ -6919,6 +6931,35 @@ TreeTransform<Derived>::TransformBinaryTypeTraitExpr(BinaryTypeTraitExpr *E) {
|
|||
E->getLocEnd());
|
||||
}
|
||||
|
||||
template<typename Derived>
|
||||
ExprResult
|
||||
TreeTransform<Derived>::TransformArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
|
||||
TypeSourceInfo *T = getDerived().TransformType(E->getQueriedTypeSourceInfo());
|
||||
if (!T)
|
||||
return ExprError();
|
||||
|
||||
if (!getDerived().AlwaysRebuild() &&
|
||||
T == E->getQueriedTypeSourceInfo())
|
||||
return SemaRef.Owned(E);
|
||||
|
||||
ExprResult SubExpr;
|
||||
{
|
||||
EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated);
|
||||
SubExpr = getDerived().TransformExpr(E->getDimensionExpression());
|
||||
if (SubExpr.isInvalid())
|
||||
return ExprError();
|
||||
|
||||
if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getDimensionExpression())
|
||||
return SemaRef.Owned(E);
|
||||
}
|
||||
|
||||
return getDerived().RebuildArrayTypeTrait(E->getTrait(),
|
||||
E->getLocStart(),
|
||||
T,
|
||||
SubExpr.get(),
|
||||
E->getLocEnd());
|
||||
}
|
||||
|
||||
template<typename Derived>
|
||||
ExprResult
|
||||
TreeTransform<Derived>::TransformExpressionTraitExpr(ExpressionTraitExpr *E) {
|
||||
|
|
|
@ -179,6 +179,7 @@ namespace clang {
|
|||
|
||||
void VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E);
|
||||
void VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E);
|
||||
void VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E);
|
||||
void VisitExpressionTraitExpr(ExpressionTraitExpr *E);
|
||||
void VisitCXXNoexceptExpr(CXXNoexceptExpr *E);
|
||||
void VisitPackExpansionExpr(PackExpansionExpr *E);
|
||||
|
@ -1344,6 +1345,16 @@ void ASTStmtReader::VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E) {
|
|||
E->RhsType = GetTypeSourceInfo(Record, Idx);
|
||||
}
|
||||
|
||||
void ASTStmtReader::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
|
||||
VisitExpr(E);
|
||||
E->ATT = (ArrayTypeTrait)Record[Idx++];
|
||||
E->Value = (unsigned int)Record[Idx++];
|
||||
SourceRange Range = ReadSourceRange(Record, Idx);
|
||||
E->Loc = Range.getBegin();
|
||||
E->RParen = Range.getEnd();
|
||||
E->QueriedType = GetTypeSourceInfo(Record, Idx);
|
||||
}
|
||||
|
||||
void ASTStmtReader::VisitExpressionTraitExpr(ExpressionTraitExpr *E) {
|
||||
VisitExpr(E);
|
||||
E->ET = (ExpressionTrait)Record[Idx++];
|
||||
|
@ -1946,6 +1957,10 @@ Stmt *ASTReader::ReadStmtFromStream(PerFileData &F) {
|
|||
S = new (Context) BinaryTypeTraitExpr(Empty);
|
||||
break;
|
||||
|
||||
case EXPR_ARRAY_TYPE_TRAIT:
|
||||
S = new (Context) ArrayTypeTraitExpr(Empty);
|
||||
break;
|
||||
|
||||
case EXPR_CXX_EXPRESSION_TRAIT:
|
||||
S = new (Context) ExpressionTraitExpr(Empty);
|
||||
break;
|
||||
|
|
|
@ -153,6 +153,7 @@ namespace clang {
|
|||
|
||||
void VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E);
|
||||
void VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E);
|
||||
void VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E);
|
||||
void VisitExpressionTraitExpr(ExpressionTraitExpr *E);
|
||||
void VisitCXXNoexceptExpr(CXXNoexceptExpr *E);
|
||||
void VisitPackExpansionExpr(PackExpansionExpr *E);
|
||||
|
@ -1340,6 +1341,15 @@ void ASTStmtWriter::VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E) {
|
|||
Code = serialization::EXPR_BINARY_TYPE_TRAIT;
|
||||
}
|
||||
|
||||
void ASTStmtWriter::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
|
||||
VisitExpr(E);
|
||||
Record.push_back(E->getTrait());
|
||||
Record.push_back(E->getValue());
|
||||
Writer.AddSourceRange(E->getSourceRange(), Record);
|
||||
Writer.AddTypeSourceInfo(E->getQueriedTypeSourceInfo(), Record);
|
||||
Code = serialization::EXPR_ARRAY_TYPE_TRAIT;
|
||||
}
|
||||
|
||||
void ASTStmtWriter::VisitExpressionTraitExpr(ExpressionTraitExpr *E) {
|
||||
VisitExpr(E);
|
||||
Record.push_back(E->getTrait());
|
||||
|
|
|
@ -435,6 +435,7 @@ void ExprEngine::Visit(const Stmt* S, ExplodedNode* Pred,
|
|||
case Stmt::DependentScopeDeclRefExprClass:
|
||||
case Stmt::UnaryTypeTraitExprClass:
|
||||
case Stmt::BinaryTypeTraitExprClass:
|
||||
case Stmt::ArrayTypeTraitExprClass:
|
||||
case Stmt::ExpressionTraitExprClass:
|
||||
case Stmt::UnresolvedLookupExprClass:
|
||||
case Stmt::UnresolvedMemberExprClass:
|
||||
|
|
|
@ -1464,3 +1464,14 @@ void is_trivial()
|
|||
{ int arr[F(__is_trivial(void))]; }
|
||||
{ int arr[F(__is_trivial(cvoid))]; }
|
||||
}
|
||||
|
||||
void array_rank() {
|
||||
int t01[T(__array_rank(IntAr) == 1)];
|
||||
int t02[T(__array_rank(ConstIntArAr) == 2)];
|
||||
}
|
||||
|
||||
void array_extent() {
|
||||
int t01[T(__array_extent(IntAr, 0) == 10)];
|
||||
int t02[T(__array_extent(ConstIntArAr, 0) == 4)];
|
||||
int t03[T(__array_extent(ConstIntArAr, 1) == 10)];
|
||||
}
|
||||
|
|
|
@ -1790,6 +1790,7 @@ public:
|
|||
void VisitWhileStmt(WhileStmt *W);
|
||||
void VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E);
|
||||
void VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E);
|
||||
void VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E);
|
||||
void VisitExpressionTraitExpr(ExpressionTraitExpr *E);
|
||||
void VisitUnresolvedMemberExpr(UnresolvedMemberExpr *U);
|
||||
void VisitVAArgExpr(VAArgExpr *E);
|
||||
|
@ -2070,6 +2071,7 @@ void EnqueueVisitor::VisitWhileStmt(WhileStmt *W) {
|
|||
AddStmt(W->getCond());
|
||||
AddDecl(W->getConditionVariable());
|
||||
}
|
||||
|
||||
void EnqueueVisitor::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
|
||||
AddTypeLoc(E->getQueriedTypeSourceInfo());
|
||||
}
|
||||
|
@ -2079,6 +2081,10 @@ void EnqueueVisitor::VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E) {
|
|||
AddTypeLoc(E->getLhsTypeSourceInfo());
|
||||
}
|
||||
|
||||
void EnqueueVisitor::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
|
||||
AddTypeLoc(E->getQueriedTypeSourceInfo());
|
||||
}
|
||||
|
||||
void EnqueueVisitor::VisitExpressionTraitExpr(ExpressionTraitExpr *E) {
|
||||
EnqueueChildren(E);
|
||||
}
|
||||
|
|
|
@ -151,6 +151,7 @@ CXCursor cxcursor::MakeCXCursor(Stmt *S, Decl *Parent,
|
|||
case Stmt::UnresolvedLookupExprClass:
|
||||
case Stmt::UnaryTypeTraitExprClass:
|
||||
case Stmt::BinaryTypeTraitExprClass:
|
||||
case Stmt::ArrayTypeTraitExprClass:
|
||||
case Stmt::ExpressionTraitExprClass:
|
||||
case Stmt::DependentScopeDeclRefExprClass:
|
||||
case Stmt::CXXBindTemporaryExprClass:
|
||||
|
|
Loading…
Reference in New Issue