New declarations/defs for Objc2's foreach-statement. This is work in progress.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@45511 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/AST/Stmt.cpp b/AST/Stmt.cpp
index 0d1ec03..95d077c 100644
--- a/AST/Stmt.cpp
+++ b/AST/Stmt.cpp
@@ -183,6 +183,14 @@
Stmt::child_iterator ForStmt::child_begin() { return &SubExprs[0]; }
Stmt::child_iterator ForStmt::child_end() { return &SubExprs[0]+END_EXPR; }
+// ObjcForCollectionStmt
+Stmt::child_iterator ObjcForCollectionStmt::child_begin() {
+ return &SubExprs[0];
+}
+Stmt::child_iterator ObjcForCollectionStmt::child_end() {
+ return &SubExprs[0]+END_EXPR;
+}
+
// GotoStmt
Stmt::child_iterator GotoStmt::child_begin() { return child_iterator(); }
Stmt::child_iterator GotoStmt::child_end() { return child_iterator(); }
diff --git a/AST/StmtPrinter.cpp b/AST/StmtPrinter.cpp
index fc28d06..099dd28 100644
--- a/AST/StmtPrinter.cpp
+++ b/AST/StmtPrinter.cpp
@@ -296,6 +296,25 @@
}
}
+void StmtPrinter::VisitObjcForCollectionStmt(ObjcForCollectionStmt *Node) {
+ Indent() << "for (";
+ if (DeclStmt *DS = dyn_cast<DeclStmt>(Node->getElement()))
+ PrintRawDecl(DS->getDecl());
+ else
+ PrintExpr(cast<Expr>(Node->getElement()));
+ OS << " in ";
+ PrintExpr(Node->getCollection());
+ OS << ") ";
+
+ if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
+ PrintRawCompoundStmt(CS);
+ OS << "\n";
+ } else {
+ OS << "\n";
+ PrintStmt(Node->getBody());
+ }
+}
+
void StmtPrinter::VisitGotoStmt(GotoStmt *Node) {
Indent() << "goto " << Node->getLabel()->getName() << ";\n";
}
diff --git a/AST/StmtSerialization.cpp b/AST/StmtSerialization.cpp
index d6f9dca..53dabbd 100644
--- a/AST/StmtSerialization.cpp
+++ b/AST/StmtSerialization.cpp
@@ -94,6 +94,9 @@
case ForStmtClass:
return ForStmt::CreateImpl(D);
+
+ case ObjcForCollectionStmtClass:
+ return ObjcForCollectionStmt::CreateImpl(D);
case GotoStmtClass:
return GotoStmt::CreateImpl(D);
@@ -560,6 +563,21 @@
return new ForStmt(Init,Cond,Inc,Body,ForLoc);
}
+void ObjcForCollectionStmt::EmitImpl(Serializer& S) const {
+ S.Emit(ForCollectionLoc);
+ S.EmitOwnedPtr(getElement());
+ S.EmitOwnedPtr(getCollection());
+ S.EmitOwnedPtr(getBody());
+}
+
+ObjcForCollectionStmt* ObjcForCollectionStmt::CreateImpl(Deserializer& D) {
+ SourceLocation ForCollectionLoc = SourceLocation::ReadVal(D);
+ Stmt* Element = D.ReadOwnedPtr<Stmt>();
+ Expr* Collection = D.ReadOwnedPtr<Expr>();
+ Stmt* Body = D.ReadOwnedPtr<Stmt>();
+ return new ObjcForCollectionStmt(Element,Collection,Body,ForCollectionLoc);
+}
+
void GotoStmt::EmitImpl(Serializer& S) const {
S.Emit(GotoLoc);
S.Emit(LabelLoc);
diff --git a/Parse/ParseObjc.cpp b/Parse/ParseObjc.cpp
index 19bbfea..e661e87 100644
--- a/Parse/ParseObjc.cpp
+++ b/Parse/ParseObjc.cpp
@@ -491,6 +491,16 @@
return false;
}
+/// objc-for-collection-in: 'in'
+///
+bool Parser::isObjCForCollectionInKW() {
+ if (Tok.is(tok::identifier)) {
+ const IdentifierInfo *II = Tok.getIdentifierInfo();
+ return II == ObjCForCollectionInKW;
+ }
+ return false;
+}
+
/// ParseObjcTypeQualifierList - This routine parses the objective-c's type
/// qualifier list and builds their bitmask representation in the input
/// argument.
diff --git a/Parse/Parser.cpp b/Parse/Parser.cpp
index 04cfea6..4bcbfc7 100644
--- a/Parse/Parser.cpp
+++ b/Parse/Parser.cpp
@@ -254,6 +254,7 @@
ObjcPropertyAttrs[objc_copy] = &PP.getIdentifierTable().get("copy");
ObjcPropertyAttrs[objc_nonatomic] =
&PP.getIdentifierTable().get("nonatomic");
+ ObjCForCollectionInKW = &PP.getIdentifierTable().get("in");
}
}
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index 0eff0a7..58d61f6 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -573,6 +573,51 @@
static ForStmt* CreateImpl(llvm::Deserializer& D);
};
+/// ObjcForCollectionStmt - This represents Objective-c's collection statement;
+/// represented as 'for (element 'in' collection-expression)' stmt.
+///
+class ObjcForCollectionStmt : public Stmt {
+ enum { ELEM, COLLECTION, BODY, END_EXPR };
+ Stmt* SubExprs[END_EXPR]; // SubExprs[ELEM] is an expression or declstmt.
+ SourceLocation ForCollectionLoc;
+public:
+ ObjcForCollectionStmt(Stmt *Elem, Expr *Collect, Stmt *Body,
+ SourceLocation FCL)
+ : Stmt(ObjcForCollectionStmtClass) {
+ SubExprs[ELEM] = Elem;
+ SubExprs[COLLECTION] = reinterpret_cast<Stmt*>(Collect);
+ SubExprs[BODY] = Body;
+ ForCollectionLoc = FCL;
+ }
+
+ Stmt *getElement() { return SubExprs[ELEM]; }
+ Expr *getCollection() {
+ return reinterpret_cast<Expr*>(SubExprs[COLLECTION]);
+ }
+ Stmt *getBody() { return SubExprs[BODY]; }
+
+ const Stmt *getElement() const { return SubExprs[ELEM]; }
+ const Expr *getCollection() const {
+ return reinterpret_cast<Expr*>(SubExprs[COLLECTION]);
+ }
+ const Stmt *getBody() const { return SubExprs[BODY]; }
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(ForCollectionLoc, SubExprs[BODY]->getLocEnd());
+ }
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ObjcForCollectionStmtClass;
+ }
+ static bool classof(const ObjcForCollectionStmt *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+
+ virtual void EmitImpl(llvm::Serializer& S) const;
+ static ObjcForCollectionStmt* CreateImpl(llvm::Deserializer& D);
+};
+
/// GotoStmt - This represents a direct goto.
///
class GotoStmt : public Stmt {
diff --git a/include/clang/AST/StmtNodes.def b/include/clang/AST/StmtNodes.def
index 27a5d1e..387ff65 100644
--- a/include/clang/AST/StmtNodes.def
+++ b/include/clang/AST/StmtNodes.def
@@ -49,8 +49,10 @@
STMT(20, ObjcAtCatchStmt , Stmt)
STMT(21, ObjcAtFinallyStmt , Stmt)
STMT(22, ObjcAtThrowStmt , Stmt)
+// Obj-C2 statements
+STMT(23, ObjcForCollectionStmt, Stmt)
-LAST_STMT(22)
+LAST_STMT(23)
FIRST_EXPR(31)
// Expressions.
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h
index 20a836c..40531b6 100644
--- a/include/clang/Parse/Parser.h
+++ b/include/clang/Parse/Parser.h
@@ -292,6 +292,9 @@
};
IdentifierInfo *ObjcPropertyAttrs[objc_NumAttrs];
bool isObjCPropertyAttribute();
+
+ IdentifierInfo *ObjCForCollectionInKW;
+ bool isObjCForCollectionInKW();
TypeTy *ParseObjCTypeName(ObjcDeclSpec &DS);
void ParseObjCMethodRequirement();