[cfe-commits] r41801 - in /cfe/trunk: AST/Decl.cpp Parse/ParseObjc.cpp Sema/Sema.h Sema/SemaDecl.cpp include/clang/AST/Decl.h include/clang/Parse/Action.h include/clang/Parse/Parser.h
Fariborz Jahanian
fjahanian at apple.com
Mon Sep 10 13:33:04 PDT 2007
Author: fjahanian
Date: Mon Sep 10 15:33:04 2007
New Revision: 41801
URL: http://llvm.org/viewvc/llvm-project?rev=41801&view=rev
Log:
Early patch to collect objective-c methods inserts them in
class object.
Modified:
cfe/trunk/AST/Decl.cpp
cfe/trunk/Parse/ParseObjc.cpp
cfe/trunk/Sema/Sema.h
cfe/trunk/Sema/SemaDecl.cpp
cfe/trunk/include/clang/AST/Decl.h
cfe/trunk/include/clang/Parse/Action.h
cfe/trunk/include/clang/Parse/Parser.h
Modified: cfe/trunk/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/AST/Decl.cpp?rev=41801&r1=41800&r2=41801&view=diff
==============================================================================
--- cfe/trunk/AST/Decl.cpp (original)
+++ cfe/trunk/AST/Decl.cpp Mon Sep 10 15:33:04 2007
@@ -163,3 +163,23 @@
}
return 0;
}
+
+/// addObjcMethods - Insert instance and methods declarations into
+/// ObjcInterfaceDecl's InsMethods and ClsMethods fields.
+///
+void ObjcInterfaceDecl::ObjcAddMethods(ObjcMethodDecl **insMethods,
+ unsigned numInsMembers,
+ ObjcMethodDecl **clsMethods,
+ unsigned numClsMembers) {
+ NumInsMethods = numInsMembers;
+ if (numInsMembers) {
+ InsMethods = new ObjcMethodDecl*[numInsMembers];
+ memcpy(InsMethods, insMethods, numInsMembers*sizeof(ObjcMethodDecl*));
+ }
+ NumClsMethods = numClsMembers;
+ if (numClsMembers) {
+ ClsMethods = new ObjcMethodDecl*[numClsMembers];
+ memcpy(ClsMethods, clsMethods, numClsMembers*sizeof(ObjcMethodDecl*));
+ }
+}
+
Modified: cfe/trunk/Parse/ParseObjc.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Parse/ParseObjc.cpp?rev=41801&r1=41800&r2=41801&view=diff
==============================================================================
--- cfe/trunk/Parse/ParseObjc.cpp (original)
+++ cfe/trunk/Parse/ParseObjc.cpp Mon Sep 10 15:33:04 2007
@@ -214,13 +214,14 @@
/// @optional
///
void Parser::ParseObjCInterfaceDeclList(DeclTy *interfaceDecl) {
+ llvm::SmallVector<DeclTy*, 32> allMethods;
while (1) {
if (Tok.getKind() == tok::at) {
SourceLocation AtLoc = ConsumeToken(); // the "@"
tok::ObjCKeywordKind ocKind = Tok.getObjCKeywordID();
if (ocKind == tok::objc_end) { // terminate list
- return;
+ break;
} else if (ocKind == tok::objc_required) { // protocols only
ConsumeToken();
continue;
@@ -236,7 +237,7 @@
}
}
if (Tok.getKind() == tok::minus || Tok.getKind() == tok::plus) {
- ParseObjCMethodPrototype(interfaceDecl);
+ allMethods.push_back(ParseObjCMethodPrototype(interfaceDecl));
// Consume the ';' here, since ParseObjCMethodPrototype() is re-used for
// method definitions.
ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "method proto");
@@ -245,13 +246,17 @@
if (Tok.getKind() == tok::semi)
ConsumeToken();
else if (Tok.getKind() == tok::eof)
- return;
+ break;
else {
// FIXME: as the name implies, this rule allows function definitions.
// We could pass a flag or check for functions during semantic analysis.
ParseDeclarationOrFunctionDefinition();
}
}
+
+ /// Insert collected methods declarations into the @interface object.
+ Actions.ObjcAddMethodsToClass(interfaceDecl, &allMethods[0], allMethods.size());
+ return;
}
/// Parse property attribute declarations.
@@ -364,15 +369,6 @@
SourceLocation methodLoc = ConsumeToken();
DeclTy *MDecl = ParseObjCMethodDecl(methodType, methodLoc);
-
- AttributeList *methodAttrs = 0;
- // If attributes exist after the method, parse them.
- if (getLang().ObjC2 && Tok.getKind() == tok::kw___attribute)
- methodAttrs = ParseAttributes();
-
- if (CDecl)
- Actions.ObjcAddMethod(CDecl, MDecl, methodAttrs);
-
// Since this rule is used for both method declarations and definitions,
// the caller is responsible for consuming the ';'.
return MDecl;
@@ -484,6 +480,7 @@
Parser::DeclTy *Parser::ParseObjCMethodDecl(tok::TokenKind mType, SourceLocation mLoc) {
TypeTy *ReturnType = 0;
+ AttributeList *methodAttrs = 0;
// Parse the return type.
if (Tok.getKind() == tok::l_paren)
@@ -491,42 +488,42 @@
IdentifierInfo *selIdent = ParseObjCSelector();
llvm::SmallVector<ObjcKeywordInfo, 12> KeyInfo;
- int KeySlot = 0;
if (Tok.getKind() == tok::colon) {
while (1) {
- KeyInfo[KeySlot].SelectorName = selIdent;
+ ObjcKeywordInfo KeyInfoDecl;
+ KeyInfoDecl.SelectorName = selIdent;
// Each iteration parses a single keyword argument.
if (Tok.getKind() != tok::colon) {
Diag(Tok, diag::err_expected_colon);
break;
}
- KeyInfo[KeySlot].ColonLoc = ConsumeToken(); // Eat the ':'.
+ KeyInfoDecl.ColonLoc = ConsumeToken(); // Eat the ':'.
if (Tok.getKind() == tok::l_paren) // Parse the argument type.
- KeyInfo[KeySlot].TypeInfo = ParseObjCTypeName();
+ KeyInfoDecl.TypeInfo = ParseObjCTypeName();
// If attributes exist before the argument name, parse them.
if (getLang().ObjC2 && Tok.getKind() == tok::kw___attribute)
- KeyInfo[KeySlot].AttrList = ParseAttributes();
+ KeyInfoDecl.AttrList = ParseAttributes();
if (Tok.getKind() != tok::identifier) {
Diag(Tok, diag::err_expected_ident); // missing argument name.
break;
}
- KeyInfo[KeySlot].ArgumentName = Tok.getIdentifierInfo();
+ KeyInfoDecl.ArgumentName = Tok.getIdentifierInfo();
ConsumeToken(); // Eat the identifier.
// Rather than call out to the actions, try packaging up the info
// locally, like we do for Declarator.
// FIXME: add Actions.BuildObjCKeyword()
+ KeyInfo.push_back(KeyInfoDecl);
selIdent = ParseObjCSelector();
if (!selIdent && Tok.getKind() != tok::colon)
break;
// We have a selector or a colon, continue parsing.
- KeySlot++;
}
// Parse the (optional) parameter list.
while (Tok.getKind() == tok::comma) {
@@ -543,12 +540,21 @@
ParseDeclarator(ParmDecl);
}
// FIXME: Add support for optional parmameter list...
+ // If attributes exist after the method, parse them.
+ if (getLang().ObjC2 && Tok.getKind() == tok::kw___attribute)
+ methodAttrs = ParseAttributes();
return Actions.ObjcBuildMethodDeclaration(mLoc, mType, ReturnType,
- &KeyInfo[0], KeyInfo.size());
+ &KeyInfo[0], KeyInfo.size(),
+ methodAttrs);
} else if (!selIdent) {
Diag(Tok, diag::err_expected_ident); // missing selector name.
}
- return Actions.ObjcBuildMethodDeclaration(mLoc, mType, ReturnType, selIdent);
+ // If attributes exist after the method, parse them.
+ if (getLang().ObjC2 && Tok.getKind() == tok::kw___attribute)
+ methodAttrs = ParseAttributes();
+
+ return Actions.ObjcBuildMethodDeclaration(mLoc, mType, ReturnType, selIdent,
+ methodAttrs);
}
/// objc-protocol-refs:
Modified: cfe/trunk/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/Sema.h?rev=41801&r1=41800&r2=41801&view=diff
==============================================================================
--- cfe/trunk/Sema/Sema.h (original)
+++ cfe/trunk/Sema/Sema.h Mon Sep 10 15:33:04 2007
@@ -156,6 +156,8 @@
Declarator &D, ExprTy *BitfieldWidth);
virtual void ParseRecordBody(SourceLocation RecLoc, DeclTy *TagDecl,
DeclTy **Fields, unsigned NumFields);
+ virtual void ObjcAddMethodsToClass(DeclTy *ClassDecl,
+ DeclTy **allMethods, unsigned allNum);
virtual DeclTy *ParseEnumConstant(Scope *S, DeclTy *EnumDecl,
DeclTy *LastEnumConstant,
SourceLocation IdLoc, IdentifierInfo *Id,
Modified: cfe/trunk/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaDecl.cpp?rev=41801&r1=41800&r2=41801&view=diff
==============================================================================
--- cfe/trunk/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/Sema/SemaDecl.cpp Mon Sep 10 15:33:04 2007
@@ -1140,6 +1140,30 @@
Record->defineBody(&RecFields[0], RecFields.size());
}
+void Sema::ObjcAddMethodsToClass(DeclTy *ClassDecl,
+ DeclTy **allMethods, unsigned allNum) {
+ // FIXME: Add method insertion code here.
+#if 0
+ ObjcInterfaceDecl *Interface = cast<ObjcInterfaceDecl>(
+ static_cast<Decl*>(ClassDecl));
+ llvm::SmallVector<ObjcMethodDecl*, 32> insMethods;
+ llvm::SmallVector<ObjcMethodDecl*, 16> clsMethods;
+
+ for (unsigned i = 0; i < allNum; i++ ) {
+ ObjcMethodDecl *Method =
+ cast_or_null<ObjcMethodDecl>(static_cast<Decl*>(allMethods[i]));
+ if (!Method) continue; // Already issued a diagnostic.
+ if (Method->isInstance())
+ insMethods.push_back(Method);
+ else
+ clsMethods.push_back(Method);
+ }
+ Interface->ObjcAddMethods(&insMethods[0], insMethods.size(),
+ &clsMethods[0], clsMethods.size());
+#endif
+ return;
+}
+
Sema::DeclTy *Sema::ParseEnumConstant(Scope *S, DeclTy *theEnumDecl,
DeclTy *lastEnumConst,
SourceLocation IdLoc, IdentifierInfo *Id,
Modified: cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=41801&r1=41800&r2=41801&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Mon Sep 10 15:33:04 2007
@@ -23,6 +23,8 @@
class Expr;
class Stmt;
class FunctionDecl;
+class ObjcMethodDecl;
+class AttributeList;
/// Decl - This represents one declaration (or definition), e.g. a variable,
@@ -34,7 +36,7 @@
// Concrete sub-classes of ValueDecl
Function, BlockVariable, FileVariable, ParmVariable, EnumConstant,
// Concrete sub-classes of TypeDecl
- Typedef, Struct, Union, Class, Enum, ObjcInterface, ObjcClass,
+ Typedef, Struct, Union, Class, Enum, ObjcInterface, ObjcClass, ObjcMethod,
// Concrete sub-class of Decl
Field
};
@@ -508,13 +510,25 @@
FieldDecl **Ivars; // Null if not defined.
int NumIvars; // -1 if not defined.
+ /// instance methods
+ ObjcMethodDecl **InsMethods; // Null if not defined
+ int NumInsMethods; // -1 if not defined
+
+ /// class methods
+ ObjcMethodDecl **ClsMethods; // Null if not defined
+ int NumClsMethods; // -1 if not defined
+
bool isForwardDecl; // declared with @class.
public:
ObjcInterfaceDecl(SourceLocation L, IdentifierInfo *Id, bool FD = false)
- : TypeDecl(ObjcInterface, L, Id, 0), Ivars(0), NumIvars(-1),
+ : TypeDecl(ObjcInterface, L, Id, 0), Ivars(0), NumIvars(-1),
+ InsMethods(0), NumInsMethods(-1), ClsMethods(0), NumClsMethods(-1),
isForwardDecl(FD) { }
void addInstanceVariable(FieldDecl ivar);
+
+ void ObjcAddMethods(ObjcMethodDecl **insMethods, unsigned numInsMembers,
+ ObjcMethodDecl **clsMethods, unsigned numClsMembers);
static bool classof(const Decl *D) {
return D->getKind() == ObjcInterface;
@@ -544,6 +558,43 @@
static bool classof(const ObjcClassDecl *D) { return true; }
};
-} // end namespace clang
+/// ObjcMethodDecl - An instance of this class is created to represent an instance
+/// or class method declaration.
+class ObjcMethodDecl : public ValueDecl {
+public:
+ ObjcMethodDecl(SourceLocation L, IdentifierInfo *Id, QualType T,
+ bool isInstance = true, Decl *PrevDecl = 0)
+ : ValueDecl(ObjcMethod, L, Id, T, PrevDecl), ParamInfo(0),
+ MethodAttrs(0), IsInstance(isInstance) {}
+
+ virtual ~ObjcMethodDecl();
+ unsigned getNumParams() const;
+ ParmVarDecl *getParamDecl(unsigned i) {
+ assert(i < getNumParams() && "Illegal param #");
+ return ParamInfo[i];
+ }
+ void setParams(ParmVarDecl **NewParamInfo, unsigned NumParams);
+
+ bool isInstance() const { return IsInstance; }
+ QualType getResultType() const { return getType(); }
+
+ void setMethodAttrs(AttributeList *attrs) {MethodAttrs = attrs;}
+ AttributeList *getMethodAttrs() const {return MethodAttrs;}
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Decl *D) { return D->getKind() == ObjcMethod; }
+ static bool classof(const ObjcMethodDecl *D) { return true; }
+private:
+ /// ParamInfo - new[]'d array of pointers to VarDecls for the formal
+ /// parameters of this Method. This is null if there are no formals.
+ ParmVarDecl **ParamInfo;
+
+ /// List of attributes for this method declaration.
+ AttributeList *MethodAttrs;
+
+ bool IsInstance : 1;
+};
+
+} // end namespace clang
#endif
Modified: cfe/trunk/include/clang/Parse/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=41801&r1=41800&r2=41801&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/trunk/include/clang/Parse/Action.h Mon Sep 10 15:33:04 2007
@@ -174,6 +174,9 @@
virtual void ParseRecordBody(SourceLocation RecLoc, DeclTy *TagDecl,
DeclTy **Fields, unsigned NumFields) {}
+ virtual void ObjcAddMethodsToClass(DeclTy *ClassDecl,
+ DeclTy **allMethods, unsigned allNum) {}
+
virtual DeclTy *ParseEnumConstant(Scope *S, DeclTy *EnumDecl,
DeclTy *LastEnumConstant,
SourceLocation IdLoc, IdentifierInfo *Id,
@@ -450,12 +453,13 @@
}
virtual DeclTy *ObjcBuildMethodDeclaration(
SourceLocation MethodLoc, tok::TokenKind MethodType, TypeTy *ReturnType,
- ObjcKeywordInfo *Keywords, unsigned NumKeywords) {
+ ObjcKeywordInfo *Keywords, unsigned NumKeywords,
+ AttributeList *AttrList) {
return 0;
}
virtual DeclTy *ObjcBuildMethodDeclaration(
SourceLocation MethodLoc, tok::TokenKind MethodType, TypeTy *ReturnType,
- IdentifierInfo *SelectorName) {
+ IdentifierInfo *SelectorName, AttributeList *AttrList) {
return 0;
}
virtual void ObjCStartCategoryInterface() { // FIXME
Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=41801&r1=41800&r2=41801&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Mon Sep 10 15:33:04 2007
@@ -288,7 +288,7 @@
TypeTy *ParseObjCTypeName();
void ParseObjCMethodRequirement();
- DeclTy *ParseObjCMethodPrototype(DeclTy *classOrCat);
+ DeclTy *ParseObjCMethodPrototype(DeclTy *classOrCat);
DeclTy *ParseObjCMethodDecl(tok::TokenKind mType, SourceLocation mLoc);
void ParseObjCPropertyAttribute(DeclTy *interfaceDecl);
void ParseObjCPropertyDecl(DeclTy *interfaceDecl);
More information about the cfe-commits
mailing list