]> granicus.if.org Git - clang/commitdiff
pchify CXXTemporary, CXXBindTemporaryExpr, and
authorChris Lattner <sabre@nondot.org>
Mon, 10 May 2010 00:25:06 +0000 (00:25 +0000)
committerChris Lattner <sabre@nondot.org>
Mon, 10 May 2010 00:25:06 +0000 (00:25 +0000)
CXXExprWithTemporaries.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@103387 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/ExprCXX.h
include/clang/Frontend/PCHBitCodes.h
include/clang/Frontend/PCHReader.h
include/clang/Frontend/PCHWriter.h
lib/AST/ExprCXX.cpp
lib/Frontend/PCHReader.cpp
lib/Frontend/PCHReaderStmt.cpp
lib/Frontend/PCHWriter.cpp
lib/Frontend/PCHWriterStmt.cpp
test/PCH/cxx_exprs.h

index 1ae16c3eb876abeaf75cd9aa2a1675d0cd8a4efe..58603ebbfbdda13b05302eb055bf145f5f64fc8e 100644 (file)
@@ -580,11 +580,15 @@ protected:
   virtual void DoDestroy(ASTContext &C);
 
 public:
+  CXXBindTemporaryExpr(EmptyShell Empty)
+    : Expr(CXXBindTemporaryExprClass, Empty), Temp(0), SubExpr(0) {}
+  
   static CXXBindTemporaryExpr *Create(ASTContext &C, CXXTemporary *Temp,
                                       Expr* SubExpr);
 
   CXXTemporary *getTemporary() { return Temp; }
   const CXXTemporary *getTemporary() const { return Temp; }
+  void setTemporary(CXXTemporary *T) { Temp = T; }
 
   const Expr *getSubExpr() const { return cast<Expr>(SubExpr); }
   Expr *getSubExpr() { return cast<Expr>(SubExpr); }
@@ -611,8 +615,8 @@ public:
 /// const int &i = 10;
 ///
 /// a bind reference expression is inserted to indicate that 10 is bound to
-/// a reference. (Ans also that a temporary needs to be created to hold the
-/// value).
+/// a reference, and that a temporary needs to be created to hold the
+/// value.
 class CXXBindReferenceExpr : public Expr {
   // SubExpr - The expression being bound.
   Stmt *SubExpr;
@@ -1658,11 +1662,17 @@ protected:
   virtual void DoDestroy(ASTContext &C);
 
 public:
+  CXXExprWithTemporaries(EmptyShell Empty)
+    : Expr(CXXExprWithTemporariesClass, Empty),
+      SubExpr(0), Temps(0), NumTemps(0) {}
+                         
   static CXXExprWithTemporaries *Create(ASTContext &C, Expr *SubExpr,
                                         CXXTemporary **Temps, 
                                         unsigned NumTemps);
 
   unsigned getNumTemporaries() const { return NumTemps; }
+  void setNumTemporaries(unsigned N);
+    
   CXXTemporary *getTemporary(unsigned i) {
     assert(i < NumTemps && "Index out of range");
     return Temps[i];
@@ -1670,6 +1680,10 @@ public:
   const CXXTemporary *getTemporary(unsigned i) const {
     return const_cast<CXXExprWithTemporaries*>(this)->getTemporary(i);
   }
+  void setTemporary(unsigned i, CXXTemporary *T) {
+    assert(i < NumTemps && "Index out of range");
+    Temps[i] = T;
+  }
 
   Expr *getSubExpr() { return cast<Expr>(SubExpr); }
   const Expr *getSubExpr() const { return cast<Expr>(SubExpr); }
index c217a75a3b7b487e7cc38652a9a1275ef514b828..57823ff81003f5e00684a1b70abe5c56fb88dc68 100644 (file)
@@ -751,7 +751,10 @@ namespace clang {
       EXPR_CXX_TYPEID_TYPE,       // CXXTypeidExpr (of type).
       EXPR_CXX_THIS,              // CXXThisExpr
       EXPR_CXX_THROW,             // CXXThrowExpr
-      EXPR_CXX_DEFAULT_ARG        // CXXDefaultArgExpr
+      EXPR_CXX_DEFAULT_ARG,       // CXXDefaultArgExpr
+      EXPR_CXX_BIND_TEMPORARY,    // CXXBindTemporaryExpr
+      
+      EXPR_CXX_EXPR_WITH_TEMPORARIES // CXXExprWithTemporaries
     };
 
     /// \brief The kinds of designators that can occur in a
index cac3398b965c7f9d1531459423ae2bed48a9d929..e144738236ead40c053fd02e7e0ff88eaf6efdc3 100644 (file)
@@ -652,8 +652,8 @@ public:
   /// declarations with this name are visible from translation unit scope, their
   /// declarations will be deserialized and introduced into the declaration
   /// chain of the identifier.
-  virtual IdentifierInfoget(const char *NameStart, const char *NameEnd);
-  IdentifierInfoget(llvm::StringRef Name) {
+  virtual IdentifierInfo *get(const char *NameStart, const char *NameEnd);
+  IdentifierInfo *get(llvm::StringRef Name) {
     return get(Name.begin(), Name.end());
   }
 
@@ -724,6 +724,8 @@ public:
   // \brief Read a string
   std::string ReadString(const RecordData &Record, unsigned &Idx);
 
+  CXXTemporary *ReadCXXTemporary(const RecordData &Record, unsigned &Idx);
+      
   /// \brief Reads attributes from the current stream position.
   Attr *ReadAttributes();
 
index 24025c9feb42bcdce420004aa99bf6f582837c23..85f53b9e0302f685bb52d95dcf5ac3d74e04ab1e 100644 (file)
@@ -256,7 +256,7 @@ public:
 
   /// \brief Emit a source range.
   void AddSourceRange(SourceRange Range, RecordData &Record);
-
+  
   /// \brief Emit an integral value.
   void AddAPInt(const llvm::APInt &Value, RecordData &Record);
 
@@ -266,12 +266,15 @@ public:
   /// \brief Emit a floating-point value.
   void AddAPFloat(const llvm::APFloat &Value, RecordData &Record);
 
-  /// \brief Emit a reference to an identifier
+  /// \brief Emit a reference to an identifier.
   void AddIdentifierRef(const IdentifierInfo *II, RecordData &Record);
 
-  /// \brief Emit a Selector (which is a smart pointer reference)
-  void AddSelectorRef(const Selector, RecordData &Record);
+  /// \brief Emit a Selector (which is a smart pointer reference).
+  void AddSelectorRef(Selector, RecordData &Record);
 
+  /// \brief Emit a CXXTemporary.
+  void AddCXXTemporary(const CXXTemporary *Temp, RecordData &Record);
+  
   /// \brief Get the unique number used to refer to the given
   /// identifier.
   pch::IdentID getIdentifierRef(const IdentifierInfo *II);
index 2e03beb0f050aab4e19094c37c0b55915a9cb141..5eef5591d6d514c3cadff3c6ca781d62b174f73e 100644 (file)
@@ -520,16 +520,24 @@ void CXXConstructExpr::DoDestroy(ASTContext &C) {
 CXXExprWithTemporaries::CXXExprWithTemporaries(Expr *subexpr,
                                                CXXTemporary **temps,
                                                unsigned numtemps)
-: Expr(CXXExprWithTemporariesClass, subexpr->getType(),
+  : Expr(CXXExprWithTemporariesClass, subexpr->getType(),
        subexpr->isTypeDependent(), subexpr->isValueDependent()),
-  SubExpr(subexpr), Temps(0), NumTemps(numtemps) {
-  if (NumTemps > 0) {
-    Temps = new CXXTemporary*[NumTemps];
-    for (unsigned i = 0; i < NumTemps; ++i)
+    SubExpr(subexpr), Temps(0), NumTemps(0) {
+  if (NumTemps) {
+    setNumTemporaries(numtemps);
+    for (unsigned i = 0; i != numtemps; ++i)
       Temps[i] = temps[i];
   }
 }
 
+void CXXExprWithTemporaries::setNumTemporaries(unsigned N) {
+  assert(Temps == 0 && "Cannot resize with this");
+  // FIXME: This is a memory leak in disable free mode.
+  Temps = new CXXTemporary*[NumTemps];
+  NumTemps = N;
+}
+
+
 CXXExprWithTemporaries *CXXExprWithTemporaries::Create(ASTContext &C,
                                                        Expr *SubExpr,
                                                        CXXTemporary **Temps,
@@ -544,6 +552,7 @@ void CXXExprWithTemporaries::DoDestroy(ASTContext &C) {
 }
 
 CXXExprWithTemporaries::~CXXExprWithTemporaries() {
+  // FIXME: This is a memory leak in disable free mode.
   delete[] Temps;
 }
 
index 8bc3b18bab48af5390e35e95e497d7303902dfb0..6e4e28eed1bc6334fbd58fd7bcb3791630eb458e 100644 (file)
@@ -2974,6 +2974,12 @@ std::string PCHReader::ReadString(const RecordData &Record, unsigned &Idx) {
   return Result;
 }
 
+CXXTemporary *PCHReader::ReadCXXTemporary(const RecordData &Record,
+                                          unsigned &Idx) {
+  CXXDestructorDecl *Decl = cast<CXXDestructorDecl>(GetDecl(Record[Idx++]));
+  return CXXTemporary::Create(*Context, Decl);
+}
+
 DiagnosticBuilder PCHReader::Diag(unsigned DiagID) {
   return Diag(SourceLocation(), DiagID);
 }
index 3392c04d554fb9bdf73b1eebc50d6b8ff14104fd..fa3c681d9011a889c00bad6673e294ad6591dc3e 100644 (file)
@@ -130,6 +130,9 @@ namespace {
     unsigned VisitCXXThisExpr(CXXThisExpr *E);
     unsigned VisitCXXThrowExpr(CXXThrowExpr *E);
     unsigned VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E);
+    unsigned VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E);
+    
+    unsigned VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E);
   };
 }
 
@@ -1028,7 +1031,27 @@ unsigned PCHStmtReader::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
   bool HasStoredExpr = Record[Idx++];
   if (!HasStoredExpr) return 0;
   E->setExpr(cast<Expr>(StmtStack.back()));
-  return 1;  // Read it.
+  return 1;
+}
+
+unsigned PCHStmtReader::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
+  VisitExpr(E);
+  E->setTemporary(Reader.ReadCXXTemporary(Record, Idx));
+  E->setSubExpr(cast<Expr>(StmtStack.back()));
+  return 1;
+}
+
+
+unsigned PCHStmtReader::VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E) {
+  VisitExpr(E);
+  unsigned NumTemps = Record[Idx++];
+  if (NumTemps) {
+    E->setNumTemporaries(NumTemps);
+    for (unsigned i = 0; i != NumTemps; ++i)
+      E->setTemporary(i, Reader.ReadCXXTemporary(Record, Idx));
+  }
+  E->setSubExpr(cast<Expr>(StmtStack.back()));
+  return 1;
 }
 
 
@@ -1396,6 +1419,13 @@ Stmt *PCHReader::ReadStmt(llvm::BitstreamCursor &Cursor) {
     case pch::EXPR_CXX_DEFAULT_ARG:
       S = new (Context) CXXDefaultArgExpr(Empty);
       break;
+    case pch::EXPR_CXX_BIND_TEMPORARY:
+      S = new (Context) CXXBindTemporaryExpr(Empty);
+      break;
+        
+    case pch::EXPR_CXX_EXPR_WITH_TEMPORARIES:
+      S = new (Context) CXXExprWithTemporaries(Empty);
+      break;
     }
 
     // We hit a STMT_STOP, so we're done with this expression.
index 225772b30d3ddc3da637a983819d0d1f45499377..dc1fb23ac0ae3b6890f28967085c2f824d615533 100644 (file)
@@ -2241,6 +2241,10 @@ void PCHWriter::AddSelectorRef(const Selector SelRef, RecordData &Record) {
   Record.push_back(SID);
 }
 
+void PCHWriter::AddCXXTemporary(const CXXTemporary *Temp, RecordData &Record) {
+  AddDeclRef(Temp->getDestructor(), Record);
+}
+
 void PCHWriter::AddTemplateArgumentLoc(const TemplateArgumentLoc &Arg,
                                        RecordData &Record) {
   switch (Arg.getArgument().getKind()) {
index e64ebbe8a31e0ec351da187f9e54cc85c3683576..8c566d00fb7f5ef0caeb26ee96b42b664ef7e534 100644 (file)
@@ -126,6 +126,9 @@ namespace {
     void VisitCXXThisExpr(CXXThisExpr *E);
     void VisitCXXThrowExpr(CXXThrowExpr *E);
     void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E);
+    void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E);
+    
+    void VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E);
   };
 }
 
@@ -954,6 +957,23 @@ void PCHStmtWriter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
   Code = pch::EXPR_CXX_DEFAULT_ARG;
 }
 
+void PCHStmtWriter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
+  VisitExpr(E);
+  Writer.AddCXXTemporary(E->getTemporary(), Record);
+  Writer.WriteSubStmt(E->getSubExpr());
+  Code = pch::EXPR_CXX_BIND_TEMPORARY;
+}
+
+void PCHStmtWriter::VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E) {
+  VisitExpr(E);
+  Record.push_back(E->getNumTemporaries());
+  for (unsigned i = 0, e = E->getNumTemporaries(); i != e; ++i)
+    Writer.AddCXXTemporary(E->getTemporary(i), Record);
+  
+  Writer.WriteSubStmt(E->getSubExpr());
+  Code = pch::EXPR_CXX_EXPR_WITH_TEMPORARIES;
+}
+
 
 //===----------------------------------------------------------------------===//
 // PCHWriter Implementation
@@ -1021,8 +1041,12 @@ void PCHWriter::FlushStmts() {
 
     Writer.Code = pch::STMT_NULL_PTR;
     Writer.Visit(S);
-    assert(Writer.Code != pch::STMT_NULL_PTR &&
-           "Unhandled expression writing PCH file");
+#ifndef NDEBUG
+    if (Writer.Code == pch::STMT_NULL_PTR) {
+      S->dump();
+      assert(0 && "Unhandled expression writing PCH file");
+    }
+#endif
     Stream.EmitRecord(Writer.Code, Record);
 
     assert(N == StmtsToEmit.size() &&
index 60ac2637151e5cb9d942a8740dcfdd25c05aaf8f..6cc83f458512d5d26da4b90c8383da2783250c84 100644 (file)
@@ -5,7 +5,7 @@
 typedef __typeof__(static_cast<void *>(0)) static_cast_result;
 
 // CXXDynamicCastExpr
-struct Base { virtual void f(int x = 492); };
+struct Base { virtual void f(int x = 492); ~Base(); };
 struct Derived : Base { void g(); };
 Base *base_ptr;
 typedef __typeof__(dynamic_cast<Derived *>(base_ptr)) dynamic_cast_result;
@@ -44,6 +44,8 @@ namespace std {
 typedef __typeof__(typeid(int))* typeid_result1;
 typedef __typeof__(typeid(2))*   typeid_result2;
 
+Derived foo();
+
 void Derived::g() {
   // CXXThisExpr
   f(2);        // Implicit
@@ -55,4 +57,9 @@ void Derived::g() {
   
   // CXXDefaultArgExpr
   f();
+  
+  const Derived &X = foo();
+  
+  
+  // FIXME: CXXBindReferenceExpr ?
 }
\ No newline at end of file