[cfe-commits] r43038 - in /cfe/trunk: AST/ASTContext.cpp AST/Expr.cpp AST/StmtDumper.cpp AST/StmtPrinter.cpp Parse/ParseObjc.cpp Sema/Sema.cpp Sema/Sema.h Sema/SemaExpr.cpp clang.xcodeproj/project.pbxproj include/clang/AST/ASTContext.h include/clang/AST/Expr.h include/clang/AST/StmtNodes.def include/clang/Basic/DiagnosticKinds.def include/clang/Parse/Action.h test/Sema/selector-1.m

Fariborz Jahanian fjahanian at apple.com
Tue Oct 16 13:40:24 PDT 2007


Author: fjahanian
Date: Tue Oct 16 15:40:23 2007
New Revision: 43038

URL: http://llvm.org/viewvc/llvm-project?rev=43038&view=rev
Log:
Patch to implement AST generation for objective-c's @selector expression.

Added:
    cfe/trunk/test/Sema/selector-1.m
Modified:
    cfe/trunk/AST/ASTContext.cpp
    cfe/trunk/AST/Expr.cpp
    cfe/trunk/AST/StmtDumper.cpp
    cfe/trunk/AST/StmtPrinter.cpp
    cfe/trunk/Parse/ParseObjc.cpp
    cfe/trunk/Sema/Sema.cpp
    cfe/trunk/Sema/Sema.h
    cfe/trunk/Sema/SemaExpr.cpp
    cfe/trunk/clang.xcodeproj/project.pbxproj
    cfe/trunk/include/clang/AST/ASTContext.h
    cfe/trunk/include/clang/AST/Expr.h
    cfe/trunk/include/clang/AST/StmtNodes.def
    cfe/trunk/include/clang/Basic/DiagnosticKinds.def
    cfe/trunk/include/clang/Parse/Action.h

Modified: cfe/trunk/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/AST/ASTContext.cpp?rev=43038&r1=43037&r2=43038&view=diff

==============================================================================
--- cfe/trunk/AST/ASTContext.cpp (original)
+++ cfe/trunk/AST/ASTContext.cpp Tue Oct 16 15:40:23 2007
@@ -856,6 +856,20 @@
   IdStructType = rec;
 }
 
+void ASTContext::setObjcSelType(TypedefDecl *TD)
+{
+  assert(ObjcSelType.isNull() && "'SEL' type already set!");
+    
+  ObjcSelType = getTypedefType(TD);
+
+  // typedef struct objc_selector *SEL;
+  const PointerType *ptr = TD->getUnderlyingType()->getAsPointerType();
+  assert(ptr && "'SEL' incorrectly typed");
+  const RecordType *rec = ptr->getPointeeType()->getAsStructureType();
+  assert(rec && "'SEL' incorrectly typed");
+  SelStructType = rec;
+}
+
 void ASTContext::setObjcConstantStringInterface(ObjcInterfaceDecl *Decl) {
   assert(ObjcConstantStringType.isNull() && 
          "'NSConstantString' type already set!");

Modified: cfe/trunk/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/AST/Expr.cpp?rev=43038&r1=43037&r2=43038&view=diff

==============================================================================
--- cfe/trunk/AST/Expr.cpp (original)
+++ cfe/trunk/AST/Expr.cpp Tue Oct 16 15:40:23 2007
@@ -1079,6 +1079,10 @@
 Stmt::child_iterator ObjCEncodeExpr::child_begin() { return NULL; }
 Stmt::child_iterator ObjCEncodeExpr::child_end() { return NULL; }
 
+// ObjCSelectorExpr
+Stmt::child_iterator ObjCSelectorExpr::child_begin() { return NULL; }
+Stmt::child_iterator ObjCSelectorExpr::child_end() { return NULL; }
+
 // ObjCMessageExpr
 Stmt::child_iterator ObjCMessageExpr::child_begin() {
   return reinterpret_cast<Stmt**>(&SubExprs[0]);

Modified: cfe/trunk/AST/StmtDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/AST/StmtDumper.cpp?rev=43038&r1=43037&r2=43038&view=diff

==============================================================================
--- cfe/trunk/AST/StmtDumper.cpp (original)
+++ cfe/trunk/AST/StmtDumper.cpp Tue Oct 16 15:40:23 2007
@@ -128,6 +128,7 @@
 
     // ObjC
     void VisitObjCEncodeExpr(ObjCEncodeExpr *Node);
+    void VisitObjCSelectorExpr(ObjCSelectorExpr *Node);
   };
 }
 
@@ -406,6 +407,19 @@
   DumpType(Node->getEncodedType());
 }
 
+void StmtDumper::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) {
+  DumpExpr(Node);
+  
+  fprintf(F, " ");
+  Selector &selector = Node->getSelector();
+  if (selector.isUnarySelector())
+    fprintf(F, "%s", selector.getIdentifierInfoForSlot(0)->getName());
+  else {
+    for (unsigned i = 0, e = Node->getNumArgs(); i != e; ++i)
+      fprintf(F, "%s:", selector.getIdentifierInfoForSlot(i)->getName());
+  }
+}
+
 //===----------------------------------------------------------------------===//
 // Stmt method implementations
 //===----------------------------------------------------------------------===//

Modified: cfe/trunk/AST/StmtPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/AST/StmtPrinter.cpp?rev=43038&r1=43037&r2=43038&view=diff

==============================================================================
--- cfe/trunk/AST/StmtPrinter.cpp (original)
+++ cfe/trunk/AST/StmtPrinter.cpp Tue Oct 16 15:40:23 2007
@@ -620,6 +620,18 @@
   OS << Node->getEncodedType().getAsString() << ")";
 }
 
+void StmtPrinter::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) {
+  OS << "@selector(";
+  Selector &selector = Node->getSelector();
+  if (selector.isUnarySelector())
+    OS << " " << selector.getIdentifierInfoForSlot(0)->getName();
+  else {
+    for (unsigned i = 0, e = Node->getNumArgs(); i != e; ++i)
+      OS << selector.getIdentifierInfoForSlot(i)->getName() << ":";
+  }
+  OS << ")";
+}
+
 void StmtPrinter::VisitObjCMessageExpr(ObjCMessageExpr *Mess) {
   OS << "[";
   Expr *receiver = Mess->getReceiver();

Modified: cfe/trunk/Parse/ParseObjc.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Parse/ParseObjc.cpp?rev=43038&r1=43037&r2=43038&view=diff

==============================================================================
--- cfe/trunk/Parse/ParseObjc.cpp (original)
+++ cfe/trunk/Parse/ParseObjc.cpp Tue Oct 16 15:40:23 2007
@@ -1318,6 +1318,7 @@
     return 0;
   }
   
+  llvm::SmallVector<IdentifierInfo *, 12> KeyIdents;
   SourceLocation LParenLoc = ConsumeParen();
   SourceLocation sLoc;
   IdentifierInfo *SelIdent = ParseObjCSelector(sLoc);
@@ -1326,6 +1327,9 @@
     Diag(Tok, diag::err_expected_ident); // missing selector name.
     return 0;
   }
+  if (!SelIdent)
+    SelIdent = &PP.getIdentifierTable().get("");
+  KeyIdents.push_back(SelIdent);
   if (Tok.isNot(tok::r_paren))
     while (1) {
       if (Tok.isNot(tok::colon)) {
@@ -1338,11 +1342,15 @@
       // Check for another keyword selector.
       SourceLocation Loc;
       SelIdent = ParseObjCSelector(Loc);
+      if (!SelIdent)
+        SelIdent = &PP.getIdentifierTable().get("");
+      KeyIdents.push_back(SelIdent);
       if (!SelIdent && Tok.isNot(tok::colon))
         break;
     }
   SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
-  
-  // FIXME 
-  return 0;
-}
\ No newline at end of file
+  Selector Sel = PP.getSelectorTable().getSelector(KeyIdents.size(),
+                                                   &KeyIdents[0]);
+  return Actions.ParseObjCSelectorExpression(Sel, SelectorLoc, LParenLoc, 
+                                             RParenLoc);
+ }
\ No newline at end of file

Modified: cfe/trunk/Sema/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/Sema.cpp?rev=43038&r1=43037&r2=43038&view=diff

==============================================================================
--- cfe/trunk/Sema/Sema.cpp (original)
+++ cfe/trunk/Sema/Sema.cpp Tue Oct 16 15:40:23 2007
@@ -45,6 +45,23 @@
   return Context.getObjcIdType();
 }
 
+/// GetObjcSelType - See comments for Sema::GetObjcIdType above; replace "id"
+/// with "SEL".
+QualType Sema::GetObjcSelType(SourceLocation Loc) {
+  assert(TUScope && "GetObjcSelType(): Top-level scope is null");
+  if (Context.getObjcSelType().isNull()) {
+    IdentifierInfo *SelIdent = &Context.Idents.get("SEL");
+    ScopedDecl *SelDecl = LookupScopedDecl(SelIdent, Decl::IDNS_Ordinary, 
+                                          SourceLocation(), TUScope);
+    TypedefDecl *ObjcSelTypedef = dyn_cast_or_null<TypedefDecl>(SelDecl);
+    if (!ObjcSelTypedef) {
+      Diag(Loc, diag::err_missing_sel_definition);
+      return QualType();
+    }
+    Context.setObjcSelType(ObjcSelTypedef);
+  }
+  return Context.getObjcSelType();
+}
 
 Sema::Sema(Preprocessor &pp, ASTContext &ctxt, std::vector<Decl*> &prevInGroup)
   : PP(pp), Context(ctxt), CurFunctionDecl(0), LastInGroupList(prevInGroup) {

Modified: cfe/trunk/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/Sema.h?rev=43038&r1=43037&r2=43038&view=diff

==============================================================================
--- cfe/trunk/Sema/Sema.h (original)
+++ cfe/trunk/Sema/Sema.h Tue Oct 16 15:40:23 2007
@@ -277,6 +277,9 @@
   /// GetObjcIdType - Getter for the build-in "id" type.
   QualType GetObjcIdType(SourceLocation Loc = SourceLocation());
   
+  /// GetObjcSelType - Getter for the build-in "SEL" type.
+  QualType GetObjcSelType(SourceLocation Loc = SourceLocation());
+  
   /// AddInstanceMethodToGlobalPool - All instance methods in a translation
   /// unit are added to a global pool. This allows us to efficiently associate
   /// a selector with a method declaraation for purposes of typechecking
@@ -441,6 +444,12 @@
                                                TypeTy *Ty,
                                                SourceLocation RParenLoc);
   
+  // ParseObjCSelectorExpression - Build selector expression for @selector
+  virtual ExprResult ParseObjCSelectorExpression(Selector Sel,
+                                                 SourceLocation AtLoc,
+                                                 SourceLocation LParenLoc,
+                                                 SourceLocation RParenLoc);
+  
   // Objective-C declarations.
   virtual DeclTy *ActOnStartClassInterface(
 		    SourceLocation AtInterafceLoc,

Modified: cfe/trunk/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaExpr.cpp?rev=43038&r1=43037&r2=43038&view=diff

==============================================================================
--- cfe/trunk/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/Sema/SemaExpr.cpp Tue Oct 16 15:40:23 2007
@@ -1919,6 +1919,14 @@
   return new ObjCEncodeExpr(t, EncodedType, AtLoc, RParenLoc);
 }
 
+Sema::ExprResult Sema::ParseObjCSelectorExpression(Selector Sel,
+                                                   SourceLocation AtLoc,
+                                                   SourceLocation LParenLoc,
+                                                   SourceLocation RParenLoc) {
+  QualType t = GetObjcSelType(AtLoc);
+  return new ObjCSelectorExpr(t, Sel, AtLoc, RParenLoc);
+}
+
 // ActOnClassMessage - used for both unary and keyword messages.
 // ArgExprs is optional - if it is present, the number of expressions
 // is obtained from Sel.getNumArgs().

Modified: cfe/trunk/clang.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/clang.xcodeproj/project.pbxproj?rev=43038&r1=43037&r2=43038&view=diff

==============================================================================
--- cfe/trunk/clang.xcodeproj/project.pbxproj (original)
+++ cfe/trunk/clang.xcodeproj/project.pbxproj Tue Oct 16 15:40:23 2007
@@ -742,6 +742,7 @@
 		08FB7793FE84155DC02AAC07 /* Project object */ = {
 			isa = PBXProject;
 			buildConfigurationList = 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "clang" */;
+			compatibilityVersion = "Xcode 2.4";
 			hasScannedForEncodings = 1;
 			mainGroup = 08FB7794FE84155DC02AAC07 /* clang */;
 			projectDirPath = "";

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

==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Tue Oct 16 15:40:23 2007
@@ -50,6 +50,10 @@
   QualType ObjcIdType;
   const RecordType *IdStructType;
   
+  /// ObjcSelType - another psuedo built-in typedef type (set by Sema).
+  QualType ObjcSelType;
+  const RecordType *SelStructType;
+  
   QualType ObjcConstantStringType;
   RecordDecl *CFConstantStringTypeDecl;
 public:
@@ -162,12 +166,15 @@
   QualType getObjcConstantStringInterface() const { 
     return ObjcConstantStringType; 
   }
-  
+
   // This setter/getter repreents the ObjC 'id' type. It is setup lazily, by
   // Sema.
   void setObjcIdType(TypedefDecl *Decl);
   QualType getObjcIdType() const { return ObjcIdType; }
-
+  
+  void setObjcSelType(TypedefDecl *Decl);
+  QualType getObjcSelType() const { return ObjcSelType; }
+  
   void setBuiltinVaListType(QualType T);
   QualType getBuiltinVaListType() const { return BuiltinVaListType; }
     

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

==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Tue Oct 16 15:40:23 2007
@@ -1091,6 +1091,37 @@
   virtual child_iterator child_end();
 };
 
+/// ObjCSelectorExpr used for @selector in Objective-C.
+class ObjCSelectorExpr : public Expr {
+
+  Selector SelName;
+  
+  SourceLocation SelLoc, RParenLoc;
+public:
+  ObjCSelectorExpr(QualType T, Selector selInfo,
+                   SourceLocation selLoc, SourceLocation rp)
+  : Expr(ObjCSelectorExprClass, T), SelName(selInfo), 
+  SelLoc(selLoc), RParenLoc(rp) {}
+  
+  const Selector &getSelector() const { return SelName; }
+  Selector &getSelector() { return SelName; }
+  
+  /// getNumArgs - Return the number of actual arguments to this call.
+  unsigned getNumArgs() const { return SelName.getNumArgs(); }
+  
+  SourceRange getSourceRange() const { return SourceRange(SelLoc, RParenLoc); }
+  
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ObjCSelectorExprClass;
+  }
+  static bool classof(const ObjCEncodeExpr *) { return true; }
+  
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+  
+};
+  
 class ObjCMessageExpr : public Expr {
   enum { RECEIVER=0, ARGS_START=1 };
 

Modified: cfe/trunk/include/clang/AST/StmtNodes.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/StmtNodes.def?rev=43038&r1=43037&r2=43038&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/StmtNodes.def (original)
+++ cfe/trunk/include/clang/AST/StmtNodes.def Tue Oct 16 15:40:23 2007
@@ -82,8 +82,9 @@
 STMT(70, ObjCStringLiteral    , Expr)
 STMT(71, ObjCEncodeExpr       , Expr)
 STMT(72, ObjCMessageExpr      , Expr)
+STMT(73, ObjCSelectorExpr     , Expr)
 
-LAST_EXPR(72)
+LAST_EXPR(73)
 
 #undef STMT
 #undef FIRST_STMT

Modified: cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=43038&r1=43037&r2=43038&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticKinds.def Tue Oct 16 15:40:23 2007
@@ -444,6 +444,8 @@
      "previous declaration is here")
 DIAG(err_undeclared_protocol, ERROR,
      "cannot find protocol declaration for '%0'")
+DIAG(err_missing_sel_definition, ERROR,
+     "cannot find definition of 'SEL'")
 DIAG(err_missing_id_definition, ERROR,
      "cannot find definition of 'id'")
 DIAG(warn_previous_alias_decl, WARNING,

Modified: cfe/trunk/include/clang/Parse/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=43038&r1=43037&r2=43038&view=diff

==============================================================================
--- cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/trunk/include/clang/Parse/Action.h Tue Oct 16 15:40:23 2007
@@ -594,10 +594,10 @@
     return 0;
   }
   
-  virtual ExprResult ParseObjCSelectorExpression(SourceLocation EncLoc,
-                                               SourceLocation LParenLoc,
-                                               TypeTy *Ty,
-                                               SourceLocation RParenLoc) {
+  virtual ExprResult ParseObjCSelectorExpression(Selector Sel,
+                                                 SourceLocation SelLoc,
+                                                 SourceLocation LParenLoc,
+                                                 SourceLocation RParenLoc) {
     return 0;
   }
   

Added: cfe/trunk/test/Sema/selector-1.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/selector-1.m?rev=43038&view=auto

==============================================================================
--- cfe/trunk/test/Sema/selector-1.m (added)
+++ cfe/trunk/test/Sema/selector-1.m Tue Oct 16 15:40:23 2007
@@ -0,0 +1,16 @@
+// RUN: clang -verify %s 
+
+typedef struct objc_selector *SEL;
+
+int main() {
+ SEL s = @selector(retain);
+ SEL s1 = @selector(meth1:);
+ SEL s2 = @selector(retainArgument::);
+ SEL s3 = @selector(retainArgument:::::);
+ SEL s4 = @selector(retainArgument:with:);
+ SEL s5 = @selector(meth1:with:with:);
+ SEL s6 = @selector(getEnum:enum:bool:);
+ SEL s7 = @selector(char:float:double:unsigned:short:long:);
+
+ SEL s9 = @selector(:enum:bool:);
+}





More information about the cfe-commits mailing list