[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