diff --git a/include/clang/AST/ExprObjC.h b/include/clang/AST/ExprObjC.h index 5775cab3ba..2ac20a04de 100644 --- a/include/clang/AST/ExprObjC.h +++ b/include/clang/AST/ExprObjC.h @@ -65,15 +65,23 @@ public: SourceLocation at, SourceLocation rp) : Expr(ObjCEncodeExprClass, T), EncType(ET), AtLoc(at), RParenLoc(rp) {} + /// \brief Build an empty block expression. + explicit ObjCEncodeExpr(EmptyShell Empty) : Expr(ObjCEncodeExprClass, Empty){} + + SourceLocation getAtLoc() const { return AtLoc; } + void setAtLoc(SourceLocation L) { AtLoc = L; } SourceLocation getRParenLoc() const { return RParenLoc; } + void setRParenLoc(SourceLocation L) { RParenLoc = L; } + + QualType getEncodedType() const { return EncType; } + void setEncodedType(QualType T) { EncType = T; } + virtual SourceRange getSourceRange() const { return SourceRange(AtLoc, RParenLoc); } - - QualType getEncodedType() const { return EncType; } - + static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCEncodeExprClass; } diff --git a/include/clang/Frontend/PCHBitCodes.h b/include/clang/Frontend/PCHBitCodes.h index d21e10cd69..490909056a 100644 --- a/include/clang/Frontend/PCHBitCodes.h +++ b/include/clang/Frontend/PCHBitCodes.h @@ -520,7 +520,12 @@ namespace clang { /// \brief BlockExpr EXPR_BLOCK, /// \brief A BlockDeclRef record. - EXPR_BLOCK_DECL_REF + EXPR_BLOCK_DECL_REF, + + // Objective-C + /// \brief A ObjCEncodeExpr record. + EXPR_OBJC_ENCODE + }; /// \brief The kinds of designators that can occur in a diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp index 7018b26c27..e3413cbcd1 100644 --- a/lib/Frontend/PCHReader.cpp +++ b/lib/Frontend/PCHReader.cpp @@ -225,7 +225,8 @@ void PCHDeclReader::VisitObjCContainerDecl(ObjCContainerDecl *CD) { void PCHDeclReader::VisitObjCInterfaceDecl(ObjCInterfaceDecl *ID) { VisitObjCContainerDecl(ID); ID->setTypeForDecl(Reader.GetType(Record[Idx++]).getTypePtr()); - ID->setSuperClass(cast(Reader.GetDecl(Record[Idx++]))); + ID->setSuperClass(cast_or_null + (Reader.GetDecl(Record[Idx++]))); unsigned NumIvars = Record[Idx++]; llvm::SmallVector IVars; IVars.reserve(NumIvars); @@ -237,6 +238,7 @@ void PCHDeclReader::VisitObjCInterfaceDecl(ObjCInterfaceDecl *ID) { ID->setImplicitInterfaceDecl(Record[Idx++]); ID->setClassLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); ID->setSuperClassLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + ID->setAtEndLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); // FIXME: add protocols, categories. } @@ -464,6 +466,7 @@ namespace { unsigned VisitShuffleVectorExpr(ShuffleVectorExpr *E); unsigned VisitBlockExpr(BlockExpr *E); unsigned VisitBlockDeclRefExpr(BlockDeclRefExpr *E); + unsigned VisitObjCEncodeExpr(ObjCEncodeExpr *E); }; } @@ -1013,6 +1016,15 @@ unsigned PCHStmtReader::VisitBlockDeclRefExpr(BlockDeclRefExpr *E) { return 0; } +unsigned PCHStmtReader::VisitObjCEncodeExpr(ObjCEncodeExpr *E) { + VisitExpr(E); + E->setEncodedType(Reader.GetType(Record[Idx++])); + E->setAtLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + return 0; +} + + //===----------------------------------------------------------------------===// // PCH reader implementation //===----------------------------------------------------------------------===// @@ -2040,9 +2052,9 @@ QualType PCHReader::ReadTypeRecord(uint64_t Offset) { return Context.getTypeDeclType(cast(GetDecl(Record[0]))); case pch::TYPE_OBJC_INTERFACE: - // FIXME: Deserialize ObjCInterfaceType - assert(false && "Cannot de-serialize ObjC interface types yet"); - return QualType(); + assert(Record.size() == 1 && "Incorrect encoding of objc interface type"); + return Context.getObjCInterfaceType( + cast(GetDecl(Record[0]))); case pch::TYPE_OBJC_QUALIFIED_INTERFACE: // FIXME: Deserialize ObjCQualifiedInterfaceType @@ -2933,6 +2945,10 @@ Stmt *PCHReader::ReadStmt() { case pch::EXPR_BLOCK_DECL_REF: S = new (Context) BlockDeclRefExpr(Empty); break; + + case pch::EXPR_OBJC_ENCODE: + S = new (Context) ObjCEncodeExpr(Empty); + break; } // We hit a STMT_STOP, so we're done with this expression. diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp index bdcd359314..a908a8bfee 100644 --- a/lib/Frontend/PCHWriter.cpp +++ b/lib/Frontend/PCHWriter.cpp @@ -656,6 +656,11 @@ namespace { void VisitShuffleVectorExpr(ShuffleVectorExpr *E); void VisitBlockExpr(BlockExpr *E); void VisitBlockDeclRefExpr(BlockDeclRefExpr *E); + + // Objective-C + void VisitObjCEncodeExpr(ObjCEncodeExpr *E); + + }; } @@ -1147,6 +1152,19 @@ void PCHStmtWriter::VisitBlockDeclRefExpr(BlockDeclRefExpr *E) { Code = pch::EXPR_BLOCK_DECL_REF; } +//===----------------------------------------------------------------------===// +// Objective-C Expressions and Statements. +//===----------------------------------------------------------------------===// + +void PCHStmtWriter::VisitObjCEncodeExpr(ObjCEncodeExpr *E) { + VisitExpr(E); + Writer.AddTypeRef(E->getEncodedType(), Record); + Writer.AddSourceLocation(E->getAtLoc(), Record); + Writer.AddSourceLocation(E->getRParenLoc(), Record); + Code = pch::EXPR_OBJC_ENCODE; +} + + //===----------------------------------------------------------------------===// // PCHWriter Implementation //===----------------------------------------------------------------------===// diff --git a/test/PCH/objc_exprs.h b/test/PCH/objc_exprs.h new file mode 100644 index 0000000000..136a34cb84 --- /dev/null +++ b/test/PCH/objc_exprs.h @@ -0,0 +1,5 @@ + +inline const char *foo() { + return @encode(int); +} + diff --git a/test/PCH/objc_exprs.m b/test/PCH/objc_exprs.m new file mode 100644 index 0000000000..7a373217b6 --- /dev/null +++ b/test/PCH/objc_exprs.m @@ -0,0 +1,7 @@ +// Test this without pch. +// RUN: clang-cc -fblocks -include %S/objc_exprs.h -fsyntax-only -verify %s && + +// Test with pch. +// RUN: clang-cc -x objective-c-header -emit-pch -fblocks -o %t %S/objc_exprs.h && +// RUN: clang-cc -fblocks -include-pch %t -fsyntax-only -verify %s +