summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2007-09-12 18:23:47 +0000
committerFariborz Jahanian <fjahanian@apple.com>2007-09-12 18:23:47 +0000
commitcfb31fab5e33565c1455dd43c4fc642218edb68a (patch)
treed0cb975de5979c61e557f391d86cafaf715e88e0
parent7b412cb823f09378d45a0d0baf1127f4466c640c (diff)
downloadllvm-cfb31fab5e33565c1455dd43c4fc642218edb68a.tar.gz
Patch for building method declaration nodes. Also fixed a segfault in cocoa.m due
to use of @property. llvm-svn: 41880
-rw-r--r--clang/AST/Decl.cpp16
-rw-r--r--clang/Parse/ParseObjc.cpp2
-rw-r--r--clang/Sema/Sema.h7
-rw-r--r--clang/Sema/SemaDecl.cpp44
-rw-r--r--clang/include/clang/AST/Decl.h9
5 files changed, 71 insertions, 7 deletions
diff --git a/clang/AST/Decl.cpp b/clang/AST/Decl.cpp
index 0e6c218f2d5f..e84532923be6 100644
--- a/clang/AST/Decl.cpp
+++ b/clang/AST/Decl.cpp
@@ -164,6 +164,22 @@ FieldDecl* RecordDecl::getMember(IdentifierInfo *name) {
return 0;
}
+void ObjcMethodDecl::setMethodParams(ParmVarDecl **NewParamInfo,
+ unsigned NumParams) {
+ assert(ParamInfo == 0 && "Already has param info!");
+
+ // Zero params -> null pointer.
+ if (NumParams) {
+ ParamInfo = new ParmVarDecl*[NumParams];
+ memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams);
+ NumMethodParams = NumParams;
+ }
+}
+
+ObjcMethodDecl::~ObjcMethodDecl() {
+ delete[] ParamInfo;
+}
+
/// addObjcMethods - Insert instance and methods declarations into
/// ObjcInterfaceDecl's InsMethods and ClsMethods fields.
///
diff --git a/clang/Parse/ParseObjc.cpp b/clang/Parse/ParseObjc.cpp
index 803fe2f6707c..7ddcaabb04b4 100644
--- a/clang/Parse/ParseObjc.cpp
+++ b/clang/Parse/ParseObjc.cpp
@@ -229,7 +229,7 @@ void Parser::ParseObjCInterfaceDeclList(DeclTy *interfaceDecl) {
ConsumeToken();
continue;
} else if (ocKind == tok::objc_property) {
- ParseObjCPropertyDecl(0/*FIXME*/);
+ ParseObjCPropertyDecl(interfaceDecl);
continue;
} else {
Diag(Tok, diag::err_objc_illegal_interface_qual);
diff --git a/clang/Sema/Sema.h b/clang/Sema/Sema.h
index b6fe89a3fa19..7a3466f97d32 100644
--- a/clang/Sema/Sema.h
+++ b/clang/Sema/Sema.h
@@ -360,6 +360,13 @@ public:
virtual void ObjcAddMethodsToClass(DeclTy *ClassDecl,
DeclTy **allMethods, unsigned allNum);
+ virtual DeclTy *ObjcBuildMethodDeclaration(SourceLocation MethodLoc,
+ tok::TokenKind MethodType, TypeTy *ReturnType,
+ ObjcKeywordInfo *Keywords, unsigned NumKeywords,
+ AttributeList *AttrList);
+ virtual DeclTy *ObjcBuildMethodDeclaration(SourceLocation MethodLoc,
+ tok::TokenKind MethodType, TypeTy *ReturnType,
+ IdentifierInfo *SelectorName, AttributeList *AttrList);
virtual void ObjcAddInstanceVariable(DeclTy *ClassDec, DeclTy *Ivar,
tok::ObjCKeywordKind visibility);
diff --git a/clang/Sema/SemaDecl.cpp b/clang/Sema/SemaDecl.cpp
index 6bfae197e3c1..d367038cddfa 100644
--- a/clang/Sema/SemaDecl.cpp
+++ b/clang/Sema/SemaDecl.cpp
@@ -1197,8 +1197,10 @@ void Sema::ParseRecordBody(SourceLocation RecLoc, DeclTy *RecDecl,
void Sema::ObjcAddMethodsToClass(DeclTy *ClassDecl,
DeclTy **allMethods, unsigned allNum) {
- // FIXME: Add method insertion code here.
-#if 0
+ // FIXME: Fix this when we can handle methods declared in protocols.
+ // See Parser::ParseObjCAtProtocolDeclaration
+ if (!ClassDecl)
+ return;
ObjcInterfaceDecl *Interface = cast<ObjcInterfaceDecl>(
static_cast<Decl*>(ClassDecl));
llvm::SmallVector<ObjcMethodDecl*, 32> insMethods;
@@ -1215,10 +1217,46 @@ void Sema::ObjcAddMethodsToClass(DeclTy *ClassDecl,
}
Interface->ObjcAddMethods(&insMethods[0], insMethods.size(),
&clsMethods[0], clsMethods.size());
-#endif
return;
}
+Sema::DeclTy *Sema::ObjcBuildMethodDeclaration(SourceLocation MethodLoc,
+ tok::TokenKind MethodType, TypeTy *ReturnType,
+ ObjcKeywordInfo *Keywords, unsigned NumKeywords,
+ AttributeList *AttrList) {
+ assert(NumKeywords && "Selector must be specified");
+ // FIXME: SelectorName to be changed to comform to objc's abi for method names
+ IdentifierInfo *SelectorName = Keywords[0].SelectorName;
+ llvm::SmallVector<ParmVarDecl*, 16> Params;
+
+ for (unsigned i = 0; i < NumKeywords; i++) {
+ ObjcKeywordInfo *arg = &Keywords[i];
+ // FIXME: arg->AttrList must be stored too!
+ ParmVarDecl* Param = new ParmVarDecl(arg->ColonLoc, arg->ArgumentName,
+ QualType::getFromOpaquePtr(arg->TypeInfo),
+ VarDecl::None, 0);
+ // FIXME: 'InvalidType' does not get set by caller yet.
+ if (arg->InvalidType)
+ Param->setInvalidDecl();
+ Params.push_back(Param);
+ }
+ QualType resultDeclType = QualType::getFromOpaquePtr(ReturnType);
+ ObjcMethodDecl* ObjcMethod = new ObjcMethodDecl(MethodLoc,
+ SelectorName, resultDeclType,
+ 0, -1, AttrList, MethodType == tok::minus);
+ ObjcMethod->setMethodParams(&Params[0], NumKeywords);
+ return ObjcMethod;
+}
+
+Sema::DeclTy *Sema::ObjcBuildMethodDeclaration(SourceLocation MethodLoc,
+ tok::TokenKind MethodType, TypeTy *ReturnType,
+ IdentifierInfo *SelectorName, AttributeList *AttrList) {
+ // FIXME: SelectorName to be changed to comform to objc's abi for method names
+ QualType resultDeclType = QualType::getFromOpaquePtr(ReturnType);
+ return new ObjcMethodDecl(MethodLoc, SelectorName, resultDeclType, 0, -1,
+ AttrList, MethodType == tok::minus);
+}
+
Sema::DeclTy *Sema::ParseEnumConstant(Scope *S, DeclTy *theEnumDecl,
DeclTy *lastEnumConst,
SourceLocation IdLoc, IdentifierInfo *Id,
diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h
index d65ba6e4f458..aba9e17ded25 100644
--- a/clang/include/clang/AST/Decl.h
+++ b/clang/include/clang/AST/Decl.h
@@ -583,19 +583,21 @@ public:
class ObjcMethodDecl : public Decl {
public:
ObjcMethodDecl(SourceLocation L, IdentifierInfo *Id, QualType T,
+ ParmVarDecl **paramInfo = 0, int numParams=-1,
AttributeList *M = 0, bool isInstance = true,
Decl *PrevDecl = 0)
- : Decl(ObjcMethod, L, Id, PrevDecl), MethodDeclType(T), ParamInfo(0),
+ : Decl(ObjcMethod, L, Id, PrevDecl), MethodDeclType(T),
+ ParamInfo(paramInfo), NumMethodParams(numParams),
MethodAttrs(M), IsInstance(isInstance) {}
virtual ~ObjcMethodDecl();
QualType getMethodType() const { return MethodDeclType; }
- unsigned getNumMethodParams() const;
+ unsigned getNumMethodParams() const { return NumMethodParams; }
ParmVarDecl *getMethodParamDecl(unsigned i) {
assert(i < getNumMethodParams() && "Illegal param #");
return ParamInfo[i];
}
- void setParams(ParmVarDecl **NewParamInfo, unsigned NumParams);
+ void setMethodParams(ParmVarDecl **NewParamInfo, unsigned NumParams);
AttributeList *getMethodAttrs() const {return MethodAttrs;}
bool isInstance() const { return IsInstance; }
@@ -610,6 +612,7 @@ 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;
+ int NumMethodParams; // -1 if no parameters
/// List of attributes for this method declaration.
AttributeList *MethodAttrs;