PCH support for ShuffleVectorExpr and BlockDeclRefExpr

llvm-svn: 69244
This commit is contained in:
Douglas Gregor 2009-04-16 00:01:45 +00:00
parent 8693ec4e58
commit a3c5590ec2
7 changed files with 94 additions and 4 deletions

View File

@ -1719,6 +1719,16 @@ public:
SubExprs[i] = args[i];
}
/// \brief Build an empty vector-shuffle expression.
explicit ShuffleVectorExpr(EmptyShell Empty)
: Expr(ShuffleVectorExprClass, Empty), SubExprs(0) { }
SourceLocation getBuiltinLoc() const { return BuiltinLoc; }
void setBuiltinLoc(SourceLocation L) { BuiltinLoc = L; }
SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation L) { RParenLoc = L; }
virtual SourceRange getSourceRange() const {
return SourceRange(BuiltinLoc, RParenLoc);
}
@ -1746,6 +1756,8 @@ public:
return cast<Expr>(SubExprs[Index]);
}
void setExprs(Expr ** Exprs, unsigned NumExprs);
unsigned getShuffleMaskIdx(ASTContext &Ctx, unsigned N) {
assert((N < NumExprs - 2) && "Shuffle idx out of range!");
return getExpr(N+2)->getIntegerConstantExprValue(Ctx).getZExtValue();
@ -2453,11 +2465,22 @@ public:
BlockDeclRefExpr(ValueDecl *d, QualType t, SourceLocation l, bool ByRef) :
Expr(BlockDeclRefExprClass, t), D(d), Loc(l), IsByRef(ByRef) {}
// \brief Build an empty reference to a declared variable in a
// block.
explicit BlockDeclRefExpr(EmptyShell Empty)
: Expr(BlockDeclRefExprClass, Empty) { }
ValueDecl *getDecl() { return D; }
const ValueDecl *getDecl() const { return D; }
void setDecl(ValueDecl *VD) { D = VD; }
SourceLocation getLocation() const { return Loc; }
void setLocation(SourceLocation L) { Loc = L; }
virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
bool isByRef() const { return IsByRef; }
void setByRef(bool BR) { IsByRef = BR; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == BlockDeclRefExprClass;

View File

@ -434,7 +434,11 @@ namespace clang {
/// \brief A ChooseExpr record.
EXPR_CHOOSE,
/// \brief A GNUNullExpr record.
EXPR_GNU_NULL
EXPR_GNU_NULL,
/// \brief A ShuffleVectorExpr record.
EXPR_SHUFFLE_VECTOR,
/// FIXME: BlockExpr
EXPR_BLOCK_DECL_REF
};
/// @}
}

View File

@ -1500,6 +1500,15 @@ bool ChooseExpr::isConditionTrue(ASTContext &C) const {
return getCond()->getIntegerConstantExprValue(C) != 0;
}
void ShuffleVectorExpr::setExprs(Expr ** Exprs, unsigned NumExprs) {
if (NumExprs)
delete [] SubExprs;
SubExprs = new Stmt* [NumExprs];
this->NumExprs = NumExprs;
memcpy(SubExprs, Exprs, sizeof(Expr *) * NumExprs);
}
void SizeOfAlignOfExpr::Destroy(ASTContext& C) {
// Override default behavior of traversing children. If this has a type
// operand and the type is a variable-length array, the child iteration

View File

@ -262,6 +262,8 @@ namespace {
unsigned VisitTypesCompatibleExpr(TypesCompatibleExpr *E);
unsigned VisitChooseExpr(ChooseExpr *E);
unsigned VisitGNUNullExpr(GNUNullExpr *E);
unsigned VisitShuffleVectorExpr(ShuffleVectorExpr *E);
unsigned VisitBlockDeclRefExpr(BlockDeclRefExpr *E);
};
}
@ -483,6 +485,23 @@ unsigned PCHStmtReader::VisitGNUNullExpr(GNUNullExpr *E) {
return 0;
}
unsigned PCHStmtReader::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
VisitExpr(E);
unsigned NumExprs = Record[Idx++];
E->setExprs(&ExprStack[ExprStack.size() - NumExprs], NumExprs);
E->setBuiltinLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
return NumExprs;
}
unsigned PCHStmtReader::VisitBlockDeclRefExpr(BlockDeclRefExpr *E) {
VisitExpr(E);
E->setDecl(cast<ValueDecl>(Reader.GetDecl(Record[Idx++])));
E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++]));
E->setByRef(Record[Idx++]);
return 0;
}
// FIXME: use the diagnostics machinery
static bool Error(const char *Str) {
std::fprintf(stderr, "%s\n", Str);
@ -2016,6 +2035,15 @@ Expr *PCHReader::ReadExpr() {
case pch::EXPR_GNU_NULL:
E = new (Context) GNUNullExpr(Empty);
break;
case pch::EXPR_SHUFFLE_VECTOR:
E = new (Context) ShuffleVectorExpr(Empty);
break;
case pch::EXPR_BLOCK_DECL_REF:
// FIXME: untested until we have statement and block support
E = new (Context) BlockDeclRefExpr(Empty);
break;
}
// We hit an EXPR_STOP, so we're done with this expression.

View File

@ -469,6 +469,8 @@ namespace {
void VisitTypesCompatibleExpr(TypesCompatibleExpr *E);
void VisitChooseExpr(ChooseExpr *E);
void VisitGNUNullExpr(GNUNullExpr *E);
void VisitShuffleVectorExpr(ShuffleVectorExpr *E);
void VisitBlockDeclRefExpr(BlockDeclRefExpr *E);
};
}
@ -683,6 +685,24 @@ void PCHStmtWriter::VisitGNUNullExpr(GNUNullExpr *E) {
Code = pch::EXPR_GNU_NULL;
}
void PCHStmtWriter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
VisitExpr(E);
Record.push_back(E->getNumSubExprs());
for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I)
Writer.WriteSubExpr(E->getExpr(I));
Writer.AddSourceLocation(E->getBuiltinLoc(), Record);
Writer.AddSourceLocation(E->getRParenLoc(), Record);
Code = pch::EXPR_SHUFFLE_VECTOR;
}
void PCHStmtWriter::VisitBlockDeclRefExpr(BlockDeclRefExpr *E) {
VisitExpr(E);
Writer.AddDeclRef(E->getDecl(), Record);
Writer.AddSourceLocation(E->getLocation(), Record);
Record.push_back(E->isByRef());
Code = pch::EXPR_BLOCK_DECL_REF;
}
//===----------------------------------------------------------------------===//
// PCHWriter Implementation
//===----------------------------------------------------------------------===//

View File

@ -72,3 +72,6 @@ choose_expr *int_ptr8 = &integer;
// GNUNullExpr FIXME: needs C++
//null_type null = __null;
// ShuffleVectorExpr
shuffle_expr *vec_ptr = &vec2;

View File

@ -58,7 +58,7 @@ typedef typeof((void *)0) void_ptr;
// ExtVectorElementExpr
typedef __attribute__(( ext_vector_type(2) )) double double2;
double2 vec2;
extern double2 vec2, vec2b;
typedef typeof(vec2.x) ext_vector_element;
// TypesCompatibleExpr
@ -69,3 +69,6 @@ typedef typeof(__builtin_choose_expr(17 > 19, d0, 1)) choose_expr;
// GNUNullExpr FIXME: needs C++
// typedef typeof(__null) null_type;
// ShuffleVectorExpr
typedef typeof(__builtin_shufflevector(vec2, vec2b, 2, 1)) shuffle_expr;