[cfe-commits] r70163 - in /cfe/trunk: include/clang/AST/ExprObjC.h include/clang/Basic/IdentifierTable.h include/clang/Frontend/PCHBitCodes.h lib/Basic/IdentifierTable.cpp lib/Frontend/PCHReader.cpp lib/Frontend/PCHWriter.cpp utils/pch-test.pl

Douglas Gregor dgregor at apple.com
Sun Apr 26 15:20:50 PDT 2009


Author: dgregor
Date: Sun Apr 26 17:20:50 2009
New Revision: 70163

URL: http://llvm.org/viewvc/llvm-project?rev=70163&view=rev
Log:
Some fixes for PCH (de-)serialization of Objective-C AST nodes:
  - Deal with the Receiver/ClassInfo shared storage in ObjCMessageExpr
  - Implement PCH support for ImplicitParamDecl
  - Fix the handling of the body of an ObjCMethodDecl
  - Several cast -> cast_or_null fixes
  - Make Selector::getIdentifierInfoForSlot work for 1-argument, NULL
  selectors.
  - Make Selector::getAsString() work with NULL selectors.
  - Fix the names of VisitObjCAtCatchStmt and VisitObjCAtFinallyStmt
  in the PCH reader and writer; these were never getting called.

At this point, all of the pch-test tests pass for C and Objective-C.


Modified:
    cfe/trunk/include/clang/AST/ExprObjC.h
    cfe/trunk/include/clang/Basic/IdentifierTable.h
    cfe/trunk/include/clang/Frontend/PCHBitCodes.h
    cfe/trunk/lib/Basic/IdentifierTable.cpp
    cfe/trunk/lib/Frontend/PCHReader.cpp
    cfe/trunk/lib/Frontend/PCHWriter.cpp
    cfe/trunk/utils/pch-test.pl

Modified: cfe/trunk/include/clang/AST/ExprObjC.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExprObjC.h?rev=70163&r1=70162&r2=70163&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/ExprObjC.h (original)
+++ cfe/trunk/include/clang/AST/ExprObjC.h Sun Apr 26 17:20:50 2009
@@ -300,8 +300,8 @@
       return SourceRange(getBase()->getLocStart(), Loc);
     return SourceRange(ClassLoc, Loc);
   }
-  const Expr *getBase() const { return cast<Expr>(Base); }
-  Expr *getBase() { return cast<Expr>(Base); }
+  const Expr *getBase() const { return cast_or_null<Expr>(Base); }
+  Expr *getBase() { return cast_or_null<Expr>(Base); }
   void setBase(Expr *base) { Base = base; }
     
   SourceLocation getLocation() const { return Loc; }
@@ -375,7 +375,7 @@
                   Expr **ArgExprs, unsigned NumArgs);
                   
   explicit ObjCMessageExpr(EmptyShell Empty)
-    : Expr(ObjCMessageExprClass, Empty) {}
+    : Expr(ObjCMessageExprClass, Empty), SubExprs(0), NumArgs(0) {}
   
   ~ObjCMessageExpr() {
     delete [] SubExprs;
@@ -418,7 +418,13 @@
   
   /// getNumArgs - Return the number of actual arguments to this call.
   unsigned getNumArgs() const { return NumArgs; }
-  void setNumArgs(unsigned nArgs) { NumArgs = nArgs; }
+  void setNumArgs(unsigned nArgs) { 
+    NumArgs = nArgs; 
+    // FIXME: should always allocate SubExprs via the ASTContext's
+    // allocator.
+    if (!SubExprs)
+      SubExprs = new Stmt* [NumArgs + 1];
+  }
   
   /// getArg - Return the specified argument.
   Expr *getArg(unsigned Arg) {

Modified: cfe/trunk/include/clang/Basic/IdentifierTable.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/IdentifierTable.h?rev=70163&r1=70162&r2=70163&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/IdentifierTable.h (original)
+++ cfe/trunk/include/clang/Basic/IdentifierTable.h Sun Apr 26 17:20:50 2009
@@ -412,6 +412,10 @@
   void *getAsOpaquePtr() const {
     return reinterpret_cast<void*>(InfoPtr);
   }
+
+  /// \brief Determine whether this is the empty selector.
+  bool isNull() const { return InfoPtr == 0; }
+
   // Predicates to identify the selector type.
   bool isKeywordSelector() const { 
     return getIdentifierInfoFlag() != ZeroArg; 

Modified: cfe/trunk/include/clang/Frontend/PCHBitCodes.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/PCHBitCodes.h?rev=70163&r1=70162&r2=70163&view=diff

==============================================================================
--- cfe/trunk/include/clang/Frontend/PCHBitCodes.h (original)
+++ cfe/trunk/include/clang/Frontend/PCHBitCodes.h Sun Apr 26 17:20:50 2009
@@ -412,6 +412,8 @@
       DECL_FIELD,
       /// \brief A VarDecl record.
       DECL_VAR,
+      /// \brief An ImplicitParamDecl record.
+      DECL_IMPLICIT_PARAM,
       /// \brief A ParmVarDecl record.
       DECL_PARM_VAR,
       /// \brief An OriginalParmVarDecl record.

Modified: cfe/trunk/lib/Basic/IdentifierTable.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/IdentifierTable.cpp?rev=70163&r1=70162&r2=70163&view=diff

==============================================================================
--- cfe/trunk/lib/Basic/IdentifierTable.cpp (original)
+++ cfe/trunk/lib/Basic/IdentifierTable.cpp Sun Apr 26 17:20:50 2009
@@ -315,9 +315,9 @@
 }
 
 IdentifierInfo *Selector::getIdentifierInfoForSlot(unsigned argIndex) const {
-  if (IdentifierInfo *II = getAsIdentifierInfo()) {
+  if (getIdentifierInfoFlag()) {
     assert(argIndex == 0 && "illegal keyword index");
-    return II;
+    return getAsIdentifierInfo();
   }
   // We point to a MultiKeywordSelector (pointer doesn't contain any flags).
   MultiKeywordSelector *SI = reinterpret_cast<MultiKeywordSelector *>(InfoPtr);
@@ -346,6 +346,9 @@
 }
 
 std::string Selector::getAsString() const {
+  if (InfoPtr == 0)
+    return "<null selector>";
+
   if (InfoPtr & ArgFlags) {
     IdentifierInfo *II = getAsIdentifierInfo();
     

Modified: cfe/trunk/lib/Frontend/PCHReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHReader.cpp?rev=70163&r1=70162&r2=70163&view=diff

==============================================================================
--- cfe/trunk/lib/Frontend/PCHReader.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHReader.cpp Sun Apr 26 17:20:50 2009
@@ -82,6 +82,7 @@
     void VisitFunctionDecl(FunctionDecl *FD);
     void VisitFieldDecl(FieldDecl *FD);
     void VisitVarDecl(VarDecl *VD);
+    void VisitImplicitParamDecl(ImplicitParamDecl *PD);
     void VisitParmVarDecl(ParmVarDecl *PD);
     void VisitOriginalParmVarDecl(OriginalParmVarDecl *PD);
     void VisitFileScopeAsmDecl(FileScopeAsmDecl *AD);
@@ -200,7 +201,7 @@
   if (Record[Idx++]) {
     // In practice, this won't be executed (since method definitions
     // don't occur in header files).
-    MD->setBody(cast<CompoundStmt>(Reader.GetStmt(Record[Idx++])));
+    MD->setBody(cast<CompoundStmt>(Reader.ReadStmt()));
     MD->setSelfDecl(cast<ImplicitParamDecl>(Reader.GetDecl(Record[Idx++])));
     MD->setCmdDecl(cast<ImplicitParamDecl>(Reader.GetDecl(Record[Idx++])));
   }
@@ -376,6 +377,10 @@
     VD->setInit(Reader.ReadExpr());
 }
 
+void PCHDeclReader::VisitImplicitParamDecl(ImplicitParamDecl *PD) {
+  VisitVarDecl(PD);
+}
+
 void PCHDeclReader::VisitParmVarDecl(ParmVarDecl *PD) {
   VisitVarDecl(PD);
   PD->setObjCDeclQualifier((Decl::ObjCDeclQualifier)Record[Idx++]);
@@ -504,8 +509,8 @@
     unsigned VisitObjCSuperExpr(ObjCSuperExpr *E);
     
     unsigned VisitObjCForCollectionStmt(ObjCForCollectionStmt *);
-    unsigned VisitObjCCatchStmt(ObjCAtCatchStmt *);
-    unsigned VisitObjCFinallyStmt(ObjCAtFinallyStmt *);
+    unsigned VisitObjCAtCatchStmt(ObjCAtCatchStmt *);
+    unsigned VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *);
     unsigned VisitObjCAtTryStmt(ObjCAtTryStmt *);
     unsigned VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *);
     unsigned VisitObjCAtThrowStmt(ObjCAtThrowStmt *);
@@ -1112,10 +1117,13 @@
 
 unsigned PCHStmtReader::VisitObjCKVCRefExpr(ObjCKVCRefExpr *E) {
   VisitExpr(E);
-  E->setGetterMethod(cast<ObjCMethodDecl>(Reader.GetDecl(Record[Idx++])));
-  E->setSetterMethod(cast<ObjCMethodDecl>(Reader.GetDecl(Record[Idx++])));
-  E->setClassProp(cast<ObjCInterfaceDecl>(Reader.GetDecl(Record[Idx++])));
-  E->setBase(cast<Expr>(StmtStack.back()));
+  E->setGetterMethod(
+                 cast_or_null<ObjCMethodDecl>(Reader.GetDecl(Record[Idx++])));
+  E->setSetterMethod(
+                 cast_or_null<ObjCMethodDecl>(Reader.GetDecl(Record[Idx++])));
+  E->setClassProp(
+              cast_or_null<ObjCInterfaceDecl>(Reader.GetDecl(Record[Idx++])));
+  E->setBase(cast_or_null<Expr>(StmtStack.back()));
   E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++]));
   E->setClassLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
   return 1;
@@ -1129,13 +1137,15 @@
   E->setSelector(Reader.GetSelector(Record, Idx));
   E->setMethodDecl(cast_or_null<ObjCMethodDecl>(Reader.GetDecl(Record[Idx++])));
   
-  ObjCMessageExpr::ClassInfo CI;
-  CI.first = cast_or_null<ObjCInterfaceDecl>(Reader.GetDecl(Record[Idx++]));
-  CI.second = Reader.GetIdentifierInfo(Record, Idx);
-  if (E->getMethodDecl() == 0)
+  E->setReceiver(
+         cast_or_null<Expr>(StmtStack[StmtStack.size() - E->getNumArgs() - 1]));
+  if (!E->getReceiver()) {
+    ObjCMessageExpr::ClassInfo CI;
+    CI.first = cast_or_null<ObjCInterfaceDecl>(Reader.GetDecl(Record[Idx++]));
+    CI.second = Reader.GetIdentifierInfo(Record, Idx);
     E->setClassInfo(CI);
-  
-  E->setReceiver(cast<Expr>(StmtStack[StmtStack.size() - E->getNumArgs() - 1]));
+  }
+
   for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
     E->setArg(I, cast<Expr>(StmtStack[StmtStack.size() - N + I]));
   return E->getNumArgs() + 1;
@@ -1157,7 +1167,7 @@
   return 3;
 }
 
-unsigned PCHStmtReader::VisitObjCCatchStmt(ObjCAtCatchStmt *S) {
+unsigned PCHStmtReader::VisitObjCAtCatchStmt(ObjCAtCatchStmt *S) {
   VisitStmt(S);
   S->setCatchBody(cast_or_null<Stmt>(StmtStack[StmtStack.size() - 2]));
   S->setNextCatchStmt(cast_or_null<Stmt>(StmtStack[StmtStack.size() - 1]));
@@ -1167,7 +1177,7 @@
   return 2;
 }
 
-unsigned PCHStmtReader::VisitObjCFinallyStmt(ObjCAtFinallyStmt *S) {
+unsigned PCHStmtReader::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
   VisitStmt(S);
   S->setFinallyBody(StmtStack.back());
   S->setAtFinallyLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
@@ -2519,11 +2529,14 @@
     break;
   }
 
-  case pch::DECL_VAR: {
+  case pch::DECL_VAR:
     D = VarDecl::Create(Context, 0, SourceLocation(), 0, QualType(),
                         VarDecl::None, SourceLocation());
     break;
-  }
+
+  case pch::DECL_IMPLICIT_PARAM:
+    D = ImplicitParamDecl::Create(Context, 0, SourceLocation(), 0, QualType());
+    break;
 
   case pch::DECL_PARM_VAR: {
     D = ParmVarDecl::Create(Context, 0, SourceLocation(), 0, QualType(), 

Modified: cfe/trunk/lib/Frontend/PCHWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHWriter.cpp?rev=70163&r1=70162&r2=70163&view=diff

==============================================================================
--- cfe/trunk/lib/Frontend/PCHWriter.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHWriter.cpp Sun Apr 26 17:20:50 2009
@@ -260,6 +260,7 @@
     void VisitFunctionDecl(FunctionDecl *D);
     void VisitFieldDecl(FieldDecl *D);
     void VisitVarDecl(VarDecl *D);
+    void VisitImplicitParamDecl(ImplicitParamDecl *D);
     void VisitParmVarDecl(ParmVarDecl *D);
     void VisitOriginalParmVarDecl(OriginalParmVarDecl *D);
     void VisitFileScopeAsmDecl(FileScopeAsmDecl *D);
@@ -548,6 +549,11 @@
   Code = pch::DECL_VAR;
 }
 
+void PCHDeclWriter::VisitImplicitParamDecl(ImplicitParamDecl *D) {
+  VisitVarDecl(D);
+  Code = pch::DECL_IMPLICIT_PARAM;
+}
+
 void PCHDeclWriter::VisitParmVarDecl(ParmVarDecl *D) {
   VisitVarDecl(D);
   Record.push_back(D->getObjCDeclQualifier()); // FIXME: stable encoding
@@ -680,8 +686,8 @@
     
     // Objective-C Statements    
     void VisitObjCForCollectionStmt(ObjCForCollectionStmt *);
-    void VisitObjCCatchStmt(ObjCAtCatchStmt *);
-    void VisitObjCFinallyStmt(ObjCAtFinallyStmt *);
+    void VisitObjCAtCatchStmt(ObjCAtCatchStmt *);
+    void VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *);
     void VisitObjCAtTryStmt(ObjCAtTryStmt *);
     void VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *);
     void VisitObjCAtThrowStmt(ObjCAtThrowStmt *);
@@ -1249,12 +1255,14 @@
   Writer.AddSourceLocation(E->getRightLoc(), Record);
   Writer.AddSelectorRef(E->getSelector(), Record);
   Writer.AddDeclRef(E->getMethodDecl(), Record); // optional
-
-  ObjCMessageExpr::ClassInfo CI = E->getClassInfo();
   Writer.WriteSubStmt(E->getReceiver());
-  Writer.AddDeclRef(CI.first, Record);
-  Writer.AddIdentifierRef(CI.second, Record);
-  
+
+  if (!E->getReceiver()) {
+    ObjCMessageExpr::ClassInfo CI = E->getClassInfo();
+    Writer.AddDeclRef(CI.first, Record);
+    Writer.AddIdentifierRef(CI.second, Record);
+  }
+
   for (CallExpr::arg_iterator Arg = E->arg_begin(), ArgEnd = E->arg_end();
        Arg != ArgEnd; ++Arg)
     Writer.WriteSubStmt(*Arg);
@@ -1277,7 +1285,7 @@
   Code = pch::STMT_OBJC_FOR_COLLECTION;
 }
 
-void PCHStmtWriter::VisitObjCCatchStmt(ObjCAtCatchStmt *S) {
+void PCHStmtWriter::VisitObjCAtCatchStmt(ObjCAtCatchStmt *S) {
   Writer.WriteSubStmt(S->getCatchBody());
   Writer.WriteSubStmt(S->getNextCatchStmt());
   Writer.AddDeclRef(S->getCatchParamDecl(), Record);
@@ -1286,7 +1294,7 @@
   Code = pch::STMT_OBJC_CATCH;
 }
 
-void PCHStmtWriter::VisitObjCFinallyStmt(ObjCAtFinallyStmt *S) {
+void PCHStmtWriter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
   Writer.WriteSubStmt(S->getFinallyBody());
   Writer.AddSourceLocation(S->getAtFinallyLoc(), Record);
   Code = pch::STMT_OBJC_FINALLY;

Modified: cfe/trunk/utils/pch-test.pl
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/pch-test.pl?rev=70163&r1=70162&r2=70163&view=diff

==============================================================================
--- cfe/trunk/utils/pch-test.pl (original)
+++ cfe/trunk/utils/pch-test.pl Sun Apr 26 17:20:50 2009
@@ -7,26 +7,30 @@
 use POSIX;
 
 $exitcode = 0;
-
 sub testfiles($$) {
   my $suffix = shift;
   my $language = shift;
+  my $passed = 0;
+  my $failed = 0;
+  my $skipped = 0;
 
   @files = `ls test/*/*.$suffix`;
   foreach $file (@files) {
     chomp($file);
-    print(".");
     my $code = system("clang-cc -fsyntax-only -x $language $file > /dev/null 2>&1");
     if ($code == 0) {
+      print(".");
       $code = system("clang-cc -emit-pch -x $language -o $file.pch $file > /dev/null 2>&1");
       if ($code == 0) {
         $code = system("clang-cc -include-pch $file.pch -x $language -ast-dump-full /dev/null > /dev/null 2>&1");
         if ($code == 0) {
+          $passed++;
         } elsif (($code & 0xFF) == SIGINT) {
           exit($exitcode);
         } else {
           print("\n---Failed to dump AST file for \"$file\"---\n");
           $exitcode = 1;
+          $failed++;
         }
         unlink "$file.pch";
       } elsif (($code & 0xFF) == SIGINT) {
@@ -34,11 +38,19 @@
       } else {
         print("\n---Failed to build PCH file for \"$file\"---\n");
         $exitcode = 1;
+          $failed++;
       }
     } elsif (($code & 0xFF) == SIGINT) {
       exit($exitcode);
+    } else {
+      print("x");
+      $skipped++;
     }
   }
+
+  print("\n\n$passed tests passed\n");
+  print("$failed tests failed\n");
+  print("$skipped tests skipped ('x')\n")
 }
 
 printf("-----Testing precompiled headers for C-----\n");





More information about the cfe-commits mailing list