[cfe-commits] r107483 - in /cfe/trunk: include/clang/AST/DeclCXX.h lib/Frontend/PCHReaderDecl.cpp lib/Frontend/PCHWriterDecl.cpp

Argyrios Kyrtzidis akyrtzi at gmail.com
Fri Jul 2 08:58:43 PDT 2010


Author: akirtzidis
Date: Fri Jul  2 10:58:43 2010
New Revision: 107483

URL: http://llvm.org/viewvc/llvm-project?rev=107483&view=rev
Log:
Handle CXXConstructorDecl, CXXDestructorDecl, and CXXConversionDecl for PCH.

<vector> header can be used correctly through PCH now.

Modified:
    cfe/trunk/include/clang/AST/DeclCXX.h
    cfe/trunk/lib/Frontend/PCHReaderDecl.cpp
    cfe/trunk/lib/Frontend/PCHWriterDecl.cpp

Modified: cfe/trunk/include/clang/AST/DeclCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=107483&r1=107482&r2=107483&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclCXX.h (original)
+++ cfe/trunk/include/clang/AST/DeclCXX.h Fri Jul  2 10:58:43 2010
@@ -1455,6 +1455,9 @@
   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
   static bool classof(const CXXConstructorDecl *D) { return true; }
   static bool classofKind(Kind K) { return K == CXXConstructor; }
+  
+  friend class PCHDeclReader;
+  friend class PCHDeclWriter;
 };
 
 /// CXXDestructorDecl - Represents a C++ destructor within a
@@ -1518,6 +1521,9 @@
   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
   static bool classof(const CXXDestructorDecl *D) { return true; }
   static bool classofKind(Kind K) { return K == CXXDestructor; }
+  
+  friend class PCHDeclReader;
+  friend class PCHDeclWriter;
 };
 
 /// CXXConversionDecl - Represents a C++ conversion function within a
@@ -1572,6 +1578,9 @@
   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
   static bool classof(const CXXConversionDecl *D) { return true; }
   static bool classofKind(Kind K) { return K == CXXConversion; }
+  
+  friend class PCHDeclReader;
+  friend class PCHDeclWriter;
 };
 
 /// LinkageSpecDecl - This represents a linkage specification.  For example:

Modified: cfe/trunk/lib/Frontend/PCHReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHReaderDecl.cpp?rev=107483&r1=107482&r2=107483&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHReaderDecl.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHReaderDecl.cpp Fri Jul  2 10:58:43 2010
@@ -113,9 +113,14 @@
 void PCHDeclReader::Visit(Decl *D) {
   DeclVisitor<PCHDeclReader, void>::Visit(D);
 
-  // if we have a fully initialized TypeDecl, we can safely read its type now.
-  if (TypeDecl *TD = dyn_cast<TypeDecl>(D))
+  if (TypeDecl *TD = dyn_cast<TypeDecl>(D)) {
+    // if we have a fully initialized TypeDecl, we can safely read its type now.
     TD->setTypeForDecl(Reader.GetType(TypeIDForTypeDecl).getTypePtr());
+  } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+    // FunctionDecl's body was written last after all other Stmts/Exprs.
+    if (Record[Idx++])
+      FD->setLazyBody(Reader.getDeclsCursor().GetCurrentBitNo());
+  }
 }
 
 void PCHDeclReader::VisitDecl(Decl *D) {
@@ -272,8 +277,9 @@
   }
   }
 
-  if (Record[Idx++])
-    FD->setLazyBody(Reader.getDeclsCursor().GetCurrentBitNo());
+  // FunctionDecl's body is handled last at PCHReaderDecl::Visit,
+  // after everything else is read.
+
   FD->setPreviousDeclaration(
                    cast_or_null<FunctionDecl>(Reader.GetDecl(Record[Idx++])));
   FD->setStorageClass((FunctionDecl::StorageClass)Record[Idx++]);
@@ -710,23 +716,83 @@
 }
 
 void PCHDeclReader::VisitCXXMethodDecl(CXXMethodDecl *D) {
-  // assert(false && "cannot read CXXMethodDecl");
   VisitFunctionDecl(D);
 }
 
 void PCHDeclReader::VisitCXXConstructorDecl(CXXConstructorDecl *D) {
-  // assert(false && "cannot read CXXConstructorDecl");
   VisitCXXMethodDecl(D);
+  
+  D->IsExplicitSpecified = Record[Idx++];
+  D->ImplicitlyDefined = Record[Idx++];
+  
+  unsigned NumInitializers = Record[Idx++];
+  D->NumBaseOrMemberInitializers = NumInitializers;
+  if (NumInitializers) {
+    ASTContext &C = *Reader.getContext();
+
+    D->BaseOrMemberInitializers
+        = new (C) CXXBaseOrMemberInitializer*[NumInitializers];
+    for (unsigned i=0; i != NumInitializers; ++i) {
+      TypeSourceInfo *BaseClassInfo;
+      bool IsBaseVirtual;
+      FieldDecl *Member;
+  
+      bool IsBaseInitializer = Record[Idx++];
+      if (IsBaseInitializer) {
+        BaseClassInfo = Reader.GetTypeSourceInfo(Record, Idx);
+        IsBaseVirtual = Record[Idx++];
+      } else {
+        Member = cast<FieldDecl>(Reader.GetDecl(Record[Idx++]));
+      }
+      SourceLocation MemberLoc = Reader.ReadSourceLocation(Record, Idx);
+      Expr *Init = Reader.ReadExpr();
+      FieldDecl *AnonUnionMember
+          = cast_or_null<FieldDecl>(Reader.GetDecl(Record[Idx++]));
+      SourceLocation LParenLoc = Reader.ReadSourceLocation(Record, Idx);
+      SourceLocation RParenLoc = Reader.ReadSourceLocation(Record, Idx);
+      bool IsWritten = Record[Idx++];
+      unsigned SourceOrderOrNumArrayIndices;
+      llvm::SmallVector<VarDecl *, 8> Indices;
+      if (IsWritten) {
+        SourceOrderOrNumArrayIndices = Record[Idx++];
+      } else {
+        SourceOrderOrNumArrayIndices = Record[Idx++];
+        Indices.reserve(SourceOrderOrNumArrayIndices);
+        for (unsigned i=0; i != SourceOrderOrNumArrayIndices; ++i)
+          Indices.push_back(cast<VarDecl>(Reader.GetDecl(Record[Idx++])));
+      }
+      
+      CXXBaseOrMemberInitializer *BOMInit;
+      if (IsBaseInitializer) {
+        BOMInit = new (C) CXXBaseOrMemberInitializer(C, BaseClassInfo,
+                                                     IsBaseVirtual, LParenLoc,
+                                                     Init, RParenLoc);
+      } else if (IsWritten) {
+        BOMInit = new (C) CXXBaseOrMemberInitializer(C, Member, MemberLoc,
+                                                     LParenLoc, Init, RParenLoc);
+      } else {
+        BOMInit = CXXBaseOrMemberInitializer::Create(C, Member, MemberLoc,
+                                                     LParenLoc, Init, RParenLoc,
+                                                     Indices.data(),
+                                                     Indices.size());
+      }
+
+      BOMInit->setAnonUnionMember(AnonUnionMember);
+      D->BaseOrMemberInitializers[i] = BOMInit;
+    }
+  }
 }
 
 void PCHDeclReader::VisitCXXDestructorDecl(CXXDestructorDecl *D) {
-  // assert(false && "cannot read CXXDestructorDecl");
   VisitCXXMethodDecl(D);
+
+  D->ImplicitlyDefined = Record[Idx++];
+  D->OperatorDelete = cast_or_null<FunctionDecl>(Reader.GetDecl(Record[Idx++]));
 }
 
 void PCHDeclReader::VisitCXXConversionDecl(CXXConversionDecl *D) {
-  // assert(false && "cannot read CXXConversionDecl");
   VisitCXXMethodDecl(D);
+  D->IsExplicitSpecified = Record[Idx++];
 }
 
 void PCHDeclReader::VisitAccessSpecDecl(AccessSpecDecl *D) {

Modified: cfe/trunk/lib/Frontend/PCHWriterDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHWriterDecl.cpp?rev=107483&r1=107482&r2=107483&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHWriterDecl.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHWriterDecl.cpp Fri Jul  2 10:58:43 2010
@@ -40,6 +40,8 @@
                   PCHWriter::RecordData &Record)
       : Writer(Writer), Context(Context), Record(Record) {
     }
+    
+    void Visit(Decl *D);
 
     void VisitDecl(Decl *D);
     void VisitTranslationUnitDecl(TranslationUnitDecl *D);
@@ -112,6 +114,19 @@
   };
 }
 
+void PCHDeclWriter::Visit(Decl *D) {
+  DeclVisitor<PCHDeclWriter>::Visit(D);
+
+  // Handle FunctionDecl's body here and write it after all other Stmts/Exprs
+  // have been written. We want it last because we will not read it back when
+  // retrieving it from the PCH, we'll just lazily set the offset. 
+  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+    Record.push_back(FD->isThisDeclarationADefinition());
+    if (FD->isThisDeclarationADefinition())
+      Writer.AddStmt(FD->getBody());
+  }
+}
+
 void PCHDeclWriter::VisitDecl(Decl *D) {
   Writer.AddDeclRef(cast_or_null<Decl>(D->getDeclContext()), Record);
   Writer.AddDeclRef(cast_or_null<Decl>(D->getLexicalDeclContext()), Record);
@@ -255,11 +270,8 @@
   }
   }
 
-  // Make sure no Exprs are emitted after the body, because when reading the
-  // function, the body doesn't get read so the cursor doesn't advance. 
-  Record.push_back(D->isThisDeclarationADefinition());
-  if (D->isThisDeclarationADefinition())
-    Writer.AddStmt(D->getBody());
+  // FunctionDecl's body is handled last at PCHWriterDecl::Visit,
+  // after everything else is written.
 
   Writer.AddDeclRef(D->getPreviousDeclaration(), Record);
   Record.push_back(D->getStorageClass()); // FIXME: stable encoding
@@ -691,26 +703,57 @@
 }
 
 void PCHDeclWriter::VisitCXXMethodDecl(CXXMethodDecl *D) {
-  // assert(false && "cannot write CXXMethodDecl");
   VisitFunctionDecl(D);
   Code = pch::DECL_CXX_METHOD;
 }
 
 void PCHDeclWriter::VisitCXXConstructorDecl(CXXConstructorDecl *D) {
-  // assert(false && "cannot write CXXConstructorDecl");
   VisitCXXMethodDecl(D);
+
+  Record.push_back(D->IsExplicitSpecified);
+  Record.push_back(D->ImplicitlyDefined);
+  
+  Record.push_back(D->NumBaseOrMemberInitializers);
+  for (unsigned i=0; i != D->NumBaseOrMemberInitializers; ++i) {
+    CXXBaseOrMemberInitializer *Init = D->BaseOrMemberInitializers[i];
+
+    Record.push_back(Init->isBaseInitializer());
+    if (Init->isBaseInitializer()) {
+      Writer.AddTypeSourceInfo(Init->getBaseClassInfo(), Record);
+      Record.push_back(Init->isBaseVirtual());
+    } else {
+      Writer.AddDeclRef(Init->getMember(), Record);
+    }
+    Writer.AddSourceLocation(Init->getMemberLocation(), Record);
+    Writer.AddStmt(Init->getInit());
+    Writer.AddDeclRef(Init->getAnonUnionMember(), Record);
+    Writer.AddSourceLocation(Init->getLParenLoc(), Record);
+    Writer.AddSourceLocation(Init->getRParenLoc(), Record);
+    Record.push_back(Init->isWritten());
+    if (Init->isWritten()) {
+      Record.push_back(Init->getSourceOrder());
+    } else {
+      Record.push_back(Init->getNumArrayIndices());
+      for (unsigned i=0, e=Init->getNumArrayIndices(); i != e; ++i)
+        Writer.AddDeclRef(Init->getArrayIndex(i), Record);
+    }
+  }
+
   Code = pch::DECL_CXX_CONSTRUCTOR;
 }
 
 void PCHDeclWriter::VisitCXXDestructorDecl(CXXDestructorDecl *D) {
-  // assert(false && "cannot write CXXDestructorDecl");
   VisitCXXMethodDecl(D);
+
+  Record.push_back(D->ImplicitlyDefined);
+  Writer.AddDeclRef(D->OperatorDelete, Record);
+
   Code = pch::DECL_CXX_DESTRUCTOR;
 }
 
 void PCHDeclWriter::VisitCXXConversionDecl(CXXConversionDecl *D) {
-  // assert(false && "cannot write CXXConversionDecl");
   VisitCXXMethodDecl(D);
+  Record.push_back(D->IsExplicitSpecified);
   Code = pch::DECL_CXX_CONVERSION;
 }
 





More information about the cfe-commits mailing list