From: Chris Lattner Date: Wed, 22 Apr 2009 06:29:42 +0000 (+0000) Subject: add three new objc expression types. @selector doesn't work because we have no X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3a57a3765b6192a94ff4e5997ae0489a1471b308;p=clang add three new objc expression types. @selector doesn't work because we have no way to serialize selectors yet. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69780 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/ExprObjC.h b/include/clang/AST/ExprObjC.h index 2ac20a04de..118ef0225a 100644 --- a/include/clang/AST/ExprObjC.h +++ b/include/clang/AST/ExprObjC.h @@ -31,11 +31,15 @@ class ObjCStringLiteral : public Expr { public: ObjCStringLiteral(StringLiteral *SL, QualType T, SourceLocation L) : Expr(ObjCStringLiteralClass, T), String(SL), AtLoc(L) {} - - StringLiteral* getString() { return cast(String); } - const StringLiteral* getString() const { return cast(String); } + explicit ObjCStringLiteral(EmptyShell Empty) + : Expr(ObjCStringLiteralClass, Empty) {} + + StringLiteral *getString() { return cast(String); } + const StringLiteral *getString() const { return cast(String); } + void setString(StringLiteral *S) { String = S; } SourceLocation getAtLoc() const { return AtLoc; } + void setAtLoc(SourceLocation L) { AtLoc = L; } virtual SourceRange getSourceRange() const { return SourceRange(AtLoc, String->getLocEnd()); @@ -65,7 +69,6 @@ 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){} @@ -102,13 +105,17 @@ class ObjCSelectorExpr : public Expr { public: ObjCSelectorExpr(QualType T, Selector selInfo, SourceLocation at, SourceLocation rp) - : Expr(ObjCSelectorExprClass, T), SelName(selInfo), - AtLoc(at), RParenLoc(rp) {} - + : Expr(ObjCSelectorExprClass, T), SelName(selInfo), AtLoc(at), RParenLoc(rp){} + explicit ObjCSelectorExpr(EmptyShell Empty) + : Expr(ObjCSelectorExprClass, Empty) {} + Selector getSelector() const { return SelName; } + void setSelector(Selector S) { SelName = S; } SourceLocation getAtLoc() const { return AtLoc; } SourceLocation getRParenLoc() const { return RParenLoc; } + void setAtLoc(SourceLocation L) { AtLoc = L; } + void setRParenLoc(SourceLocation L) { RParenLoc = L; } virtual SourceRange getSourceRange() const { return SourceRange(AtLoc, RParenLoc); @@ -130,20 +137,28 @@ public: static ObjCSelectorExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C); }; -/// ObjCProtocolExpr used for protocol in Objective-C. +/// ObjCProtocolExpr used for protocol expression in Objective-C. This is used +/// as: @protocol(foo), as in: +/// obj conformsToProtocol:@protocol(foo)] +/// The return type is "Protocol*". class ObjCProtocolExpr : public Expr { ObjCProtocolDecl *Protocol; SourceLocation AtLoc, RParenLoc; public: ObjCProtocolExpr(QualType T, ObjCProtocolDecl *protocol, SourceLocation at, SourceLocation rp) - : Expr(ObjCProtocolExprClass, T), Protocol(protocol), - AtLoc(at), RParenLoc(rp) {} - + : Expr(ObjCProtocolExprClass, T), Protocol(protocol), + AtLoc(at), RParenLoc(rp) {} + explicit ObjCProtocolExpr(EmptyShell Empty) + : Expr(ObjCProtocolExprClass, Empty) {} + ObjCProtocolDecl *getProtocol() const { return Protocol; } + void setProtocol(ObjCProtocolDecl *P) { Protocol = P; } SourceLocation getAtLoc() const { return AtLoc; } SourceLocation getRParenLoc() const { return RParenLoc; } + void setAtLoc(SourceLocation L) { AtLoc = L; } + void setRParenLoc(SourceLocation L) { RParenLoc = L; } virtual SourceRange getSourceRange() const { return SourceRange(AtLoc, RParenLoc); diff --git a/include/clang/Frontend/PCHBitCodes.h b/include/clang/Frontend/PCHBitCodes.h index 490909056a..df3db3b70d 100644 --- a/include/clang/Frontend/PCHBitCodes.h +++ b/include/clang/Frontend/PCHBitCodes.h @@ -523,8 +523,15 @@ namespace clang { EXPR_BLOCK_DECL_REF, // Objective-C + + /// \brief A ObjCStringLiteral record. + EXPR_OBJC_STRING_LITERAL, /// \brief A ObjCEncodeExpr record. - EXPR_OBJC_ENCODE + EXPR_OBJC_ENCODE, + /// \brief A ObjCSelectorExpr record. + EXPR_OBJC_SELECTOR_EXPR, + /// \brief A ObjCProtocolExpr record. + EXPR_OBJC_PROTOCOL_EXPR }; diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp index e3413cbcd1..beb8ce8819 100644 --- a/lib/Frontend/PCHReader.cpp +++ b/lib/Frontend/PCHReader.cpp @@ -466,7 +466,10 @@ namespace { unsigned VisitShuffleVectorExpr(ShuffleVectorExpr *E); unsigned VisitBlockExpr(BlockExpr *E); unsigned VisitBlockDeclRefExpr(BlockDeclRefExpr *E); + unsigned VisitObjCStringLiteral(ObjCStringLiteral *E); unsigned VisitObjCEncodeExpr(ObjCEncodeExpr *E); + unsigned VisitObjCSelectorExpr(ObjCSelectorExpr *E); + unsigned VisitObjCProtocolExpr(ObjCProtocolExpr *E); }; } @@ -1016,6 +1019,16 @@ unsigned PCHStmtReader::VisitBlockDeclRefExpr(BlockDeclRefExpr *E) { return 0; } +//===----------------------------------------------------------------------===// +// Objective-C Expressions and Statements + +unsigned PCHStmtReader::VisitObjCStringLiteral(ObjCStringLiteral *E) { + VisitExpr(E); + E->setString(cast(StmtStack.back())); + E->setAtLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + return 1; +} + unsigned PCHStmtReader::VisitObjCEncodeExpr(ObjCEncodeExpr *E) { VisitExpr(E); E->setEncodedType(Reader.GetType(Record[Idx++])); @@ -1024,6 +1037,22 @@ unsigned PCHStmtReader::VisitObjCEncodeExpr(ObjCEncodeExpr *E) { return 0; } +unsigned PCHStmtReader::VisitObjCSelectorExpr(ObjCSelectorExpr *E) { + VisitExpr(E); + // FIXME: Selectors. + E->setAtLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + return 0; +} + +unsigned PCHStmtReader::VisitObjCProtocolExpr(ObjCProtocolExpr *E) { + VisitExpr(E); + E->setProtocol(cast(Reader.GetDecl(Record[Idx++]))); + E->setAtLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + return 0; +} + //===----------------------------------------------------------------------===// // PCH reader implementation @@ -2946,9 +2975,18 @@ Stmt *PCHReader::ReadStmt() { S = new (Context) BlockDeclRefExpr(Empty); break; + case pch::EXPR_OBJC_STRING_LITERAL: + S = new (Context) ObjCStringLiteral(Empty); + break; case pch::EXPR_OBJC_ENCODE: S = new (Context) ObjCEncodeExpr(Empty); break; + case pch::EXPR_OBJC_SELECTOR_EXPR: + S = new (Context) ObjCSelectorExpr(Empty); + break; + case pch::EXPR_OBJC_PROTOCOL_EXPR: + S = new (Context) ObjCProtocolExpr(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 a908a8bfee..0d7f58808a 100644 --- a/lib/Frontend/PCHWriter.cpp +++ b/lib/Frontend/PCHWriter.cpp @@ -658,9 +658,10 @@ namespace { void VisitBlockDeclRefExpr(BlockDeclRefExpr *E); // Objective-C + void VisitObjCStringLiteral(ObjCStringLiteral *E); void VisitObjCEncodeExpr(ObjCEncodeExpr *E); - - + void VisitObjCSelectorExpr(ObjCSelectorExpr *E); + void VisitObjCProtocolExpr(ObjCProtocolExpr *E); }; } @@ -1156,6 +1157,13 @@ void PCHStmtWriter::VisitBlockDeclRefExpr(BlockDeclRefExpr *E) { // Objective-C Expressions and Statements. //===----------------------------------------------------------------------===// +void PCHStmtWriter::VisitObjCStringLiteral(ObjCStringLiteral *E) { + VisitExpr(E); + Writer.WriteSubStmt(E->getString()); + Writer.AddSourceLocation(E->getAtLoc(), Record); + Code = pch::EXPR_OBJC_STRING_LITERAL; +} + void PCHStmtWriter::VisitObjCEncodeExpr(ObjCEncodeExpr *E) { VisitExpr(E); Writer.AddTypeRef(E->getEncodedType(), Record); @@ -1164,6 +1172,23 @@ void PCHStmtWriter::VisitObjCEncodeExpr(ObjCEncodeExpr *E) { Code = pch::EXPR_OBJC_ENCODE; } +void PCHStmtWriter::VisitObjCSelectorExpr(ObjCSelectorExpr *E) { + VisitExpr(E); + // FIXME! Write selectors. + //Writer.WriteSubStmt(E->getSelector()); + Writer.AddSourceLocation(E->getAtLoc(), Record); + Writer.AddSourceLocation(E->getRParenLoc(), Record); + Code = pch::EXPR_OBJC_SELECTOR_EXPR; +} + +void PCHStmtWriter::VisitObjCProtocolExpr(ObjCProtocolExpr *E) { + VisitExpr(E); + Writer.AddDeclRef(E->getProtocol(), Record); + Writer.AddSourceLocation(E->getAtLoc(), Record); + Writer.AddSourceLocation(E->getRParenLoc(), Record); + Code = pch::EXPR_OBJC_PROTOCOL_EXPR; +} + //===----------------------------------------------------------------------===// // PCHWriter Implementation diff --git a/test/PCH/objc_exprs.h b/test/PCH/objc_exprs.h index 136a34cb84..5c0c2aec79 100644 --- a/test/PCH/objc_exprs.h +++ b/test/PCH/objc_exprs.h @@ -1,5 +1,11 @@ -inline const char *foo() { - return @encode(int); -} +@protocol foo; +typedef typeof(@"foo" "bar") objc_string; + +typedef typeof(@encode(int)) objc_encode; + + +typedef typeof(@protocol(foo)) objc_protocol; + +//const char *X; diff --git a/test/PCH/objc_exprs.m b/test/PCH/objc_exprs.m index 7a373217b6..b11a7e5be1 100644 --- a/test/PCH/objc_exprs.m +++ b/test/PCH/objc_exprs.m @@ -5,3 +5,14 @@ // 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 + + +int *A1 = (objc_string)0; // expected-warning {{'struct objc_object *'}} + +char A2 = (objc_encode){}; // expected-error {{initializer element is not a compile-time constant}} \ + expected-warning {{char [2]}} + +int *A3 = (objc_protocol)0; // expected-warning {{aka 'Protocol *'}} + + +