PCH support for ShuffleVectorExpr and BlockDeclRefExpr
authorDouglas Gregor <dgregor@apple.com>
Thu, 16 Apr 2009 00:01:45 +0000 (00:01 +0000)
committerDouglas Gregor <dgregor@apple.com>
Thu, 16 Apr 2009 00:01:45 +0000 (00:01 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69244 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/Expr.h
include/clang/Frontend/PCHBitCodes.h
lib/AST/Expr.cpp
lib/Frontend/PCHReader.cpp
lib/Frontend/PCHWriter.cpp
test/PCH/exprs.c
test/PCH/exprs.h

index 27b76e3db73f84af309fa791a24da297ce72bf73..a0a1689d1880aec8c9830637f8151d2f25d3ff29 100644 (file)
@@ -1718,7 +1718,17 @@ public:
     for (unsigned i = 0; i < nexpr; i++)
       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();
@@ -2452,13 +2464,24 @@ class BlockDeclRefExpr : public Expr {
 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; 
   }
index 700d990721b9eb1172f9e1d557c180455a19f555..568bda0b98289e6ccb761e485c031fe27a649b4a 100644 (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
     };
     /// @}
   }
index 91b6dc9d4c55c9bf396d8dfe298deafa186e7be1..e1603c90e15c0aa41bf40c327565d7064d44be28 100644 (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
index 67c7dc73371de716b9e38eb792654b5560e7c2cd..b829075913ff3f0a37d875d4b6550aa5833df525 100644 (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.
index dc5aabdd5ba7bc8b8ac5cd3c5ed2a24a0fb0446b..4201a69f73d0b3c638c227714aba33790a1a6048 100644 (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
 //===----------------------------------------------------------------------===//
index 5396c0421678f261b76ed4730a24593f8a1174ad..d3d4b37a889d99ec84f2c548703eb0239c586d3d 100644 (file)
@@ -72,3 +72,6 @@ choose_expr *int_ptr8 = &integer;
 
 // GNUNullExpr FIXME: needs C++
 //null_type null = __null;
+
+// ShuffleVectorExpr
+shuffle_expr *vec_ptr = &vec2;
index f02a24902fb84affa0f3a601244f760d66458bb1..a928b9b2e8f4ef014724e128a464ae6fd784e8d7 100644 (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;