From b245a33e6f562377946dc9cb5694a2d3cb8a98a3 Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Tue, 13 Nov 2007 01:10:08 +0000 Subject: [PATCH] Patch to set context (interface, category, etc.) in which method is declared. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@44038 91177308-0d34-0410-b5e6-96231b3b80d8 --- Sema/SemaDecl.cpp | 22 ++-- include/clang/AST/DeclObjC.h | 225 +++++++++++++++++++---------------- 2 files changed, 127 insertions(+), 120 deletions(-) diff --git a/Sema/SemaDecl.cpp b/Sema/SemaDecl.cpp index 65488cafa7..7f059b4554 100644 --- a/Sema/SemaDecl.cpp +++ b/Sema/SemaDecl.cpp @@ -2140,21 +2140,9 @@ Sema::DeclTy *Sema::ActOnMethodDeclaration( resultDeclType = Context.getObjcIdType(); Decl *CDecl = static_cast(ClassDecl); - ObjcInterfaceDecl *IDecl = 0; - ObjcImplementationDecl *ImpDecl = 0; - ObjcCategoryImplDecl *CatImpDecl = 0; - if (isa(CDecl)) - IDecl = cast(CDecl); - else if (isa(CDecl)) - IDecl = cast(CDecl)->getClassInterface(); // FIXME: what is this? (talk to fariborz) - else if ((ImpDecl = dyn_cast(CDecl))) - IDecl = ImpDecl->getClassInterface(); // FIXME: what is this? (talk to fariborz) - else if ((CatImpDecl = dyn_cast(CDecl))) - IDecl = cast(CDecl)->getClassInterface(); // FIXME: what is this? (talk to fariborz) - ObjcMethodDecl* ObjcMethod = new ObjcMethodDecl(MethodLoc, EndLoc, Sel, resultDeclType, - IDecl, + CDecl, 0, -1, AttrList, MethodType == tok::minus, MethodDeclKind == tok::objc_optional ? @@ -2164,11 +2152,13 @@ Sema::DeclTy *Sema::ActOnMethodDeclaration( ObjcMethod->setObjcDeclQualifier( CvtQTToAstBitMask(ReturnQT.getObjcDeclQualifier())); const ObjcMethodDecl *PrevMethod = 0; + // For implementations (which can be very "coarse grain"), we add the // method now. This allows the AST to implement lookup methods that work // incrementally (without waiting until we parse the @end). It also allows // us to flag multiple declaration errors as they occur. - if (ImpDecl) { + if (ObjcImplementationDecl *ImpDecl = + dyn_cast(CDecl)) { if (MethodType == tok::minus) { PrevMethod = ImpDecl->lookupInstanceMethod(Sel); ImpDecl->addInstanceMethod(ObjcMethod); @@ -2176,7 +2166,9 @@ Sema::DeclTy *Sema::ActOnMethodDeclaration( PrevMethod = ImpDecl->lookupClassMethod(Sel); ImpDecl->addClassMethod(ObjcMethod); } - } else if (CatImpDecl) { + } + else if (ObjcCategoryImplDecl *CatImpDecl = + dyn_cast(CDecl)) { if (MethodType == tok::minus) { PrevMethod = CatImpDecl->lookupInstanceMethod(Sel); CatImpDecl->addInstanceMethod(ObjcMethod); diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h index 9320c60d25..548d4c5390 100644 --- a/include/clang/AST/DeclObjC.h +++ b/include/clang/AST/DeclObjC.h @@ -27,7 +27,7 @@ class ObjcMethodDecl; class ObjcProtocolDecl; class ObjcCategoryDecl; class ObjcPropertyDecl; - + /// ObjcInterfaceDecl - Represents an ObjC class declaration. For example: /// /// // MostPrimitive declares no super class (not particularly useful). @@ -207,110 +207,6 @@ private: AccessControl DeclAccess : 3; }; -/// ObjcMethodDecl - Represents an instance or class method declaration. -/// ObjC methods can be declared within 4 contexts: class interfaces, -/// categories, protocols, and class implementations. While C++ member -/// functions leverage C syntax, Objective-C method syntax is modeled after -/// Smalltalk (using colons to specify argument types/expressions). -/// Here are some brief examples: -/// -/// Setter/getter instance methods: -/// - (void)setMenu:(NSMenu *)menu; -/// - (NSMenu *)menu; -/// -/// Instance method that takes 2 NSView arguments: -/// - (void)replaceSubview:(NSView *)oldView with:(NSView *)newView; -/// -/// Getter class method: -/// + (NSMenu *)defaultMenu; -/// -/// A selector represents a unique name for a method. The selector names for -/// the above methods are setMenu:, menu, replaceSubview:with:, and defaultMenu. -/// -class ObjcMethodDecl : public Decl { -public: - enum ImplementationControl { None, Required, Optional }; -private: - /// Bitfields must be first fields in this class so they pack with those - /// declared in class Decl. - /// instance (true) or class (false) method. - bool IsInstance : 1; - /// @required/@optional - ImplementationControl DeclImplementation : 2; - - /// in, inout, etc. - ObjcDeclQualifier objcDeclQualifier : 6; - - // @interface decl this Method belongs to. - ObjcInterfaceDecl *ClassInterface; - - // A unigue name for this method. - Selector SelName; - - // Type of this method. - QualType MethodDeclType; - /// 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; - - Stmt *Body; // Null if a prototype. - - SourceLocation EndLoc; // the location of the ';' or '{'. -public: - ObjcMethodDecl(SourceLocation beginLoc, SourceLocation endLoc, - Selector SelInfo, QualType T, - ObjcInterfaceDecl *interfaceDecl, - ParmVarDecl **paramInfo = 0, int numParams=-1, - AttributeList *M = 0, bool isInstance = true, - ImplementationControl impControl = None, - Decl *PrevDecl = 0) - : Decl(ObjcMethod, beginLoc), - IsInstance(isInstance), DeclImplementation(impControl), - objcDeclQualifier(OBJC_TQ_None), - ClassInterface(interfaceDecl), - SelName(SelInfo), MethodDeclType(T), - ParamInfo(paramInfo), NumMethodParams(numParams), - MethodAttrs(M), EndLoc(endLoc) {} - virtual ~ObjcMethodDecl(); - - ObjcDeclQualifier getObjcDeclQualifier() const { return objcDeclQualifier; } - void setObjcDeclQualifier(ObjcDeclQualifier QV) { objcDeclQualifier = QV; } - - // Location information, modeled after the Stmt API. - SourceLocation getLocStart() const { return getLocation(); } - SourceLocation getLocEnd() const { return EndLoc; } - - ObjcInterfaceDecl *const getClassInterface() const { return ClassInterface; } - - Selector getSelector() const { return SelName; } - QualType getResultType() const { return MethodDeclType; } - - int getNumParams() const { return NumMethodParams; } - ParmVarDecl *getParamDecl(int i) const { - assert(i < getNumParams() && "Illegal param #"); - return ParamInfo[i]; - } - void setMethodParams(ParmVarDecl **NewParamInfo, unsigned NumParams); - - AttributeList *getMethodAttrs() const {return MethodAttrs;} - bool isInstance() const { return IsInstance; } - // Related to protocols declared in @protocol - void setDeclImplementation(ImplementationControl ic) - { DeclImplementation = ic; } - ImplementationControl getImplementationControl() const - { return DeclImplementation; } - - Stmt *const getBody() const { return Body; } - void setBody(Stmt *B) { Body = B; } - - // Implement isa/cast/dyncast/etc. - static bool classof(const Decl *D) { return D->getKind() == ObjcMethod; } - static bool classof(const ObjcMethodDecl *D) { return true; } -}; /// ObjcProtocolDecl - Represents a protocol declaration. ObjC protocols /// declare a pure abstract type (i.e no instance variables are permitted). @@ -702,6 +598,125 @@ public: static bool classof(const ObjcImplementationDecl *D) { return true; } }; +/// ObjcMethodDecl - Represents an instance or class method declaration. +/// ObjC methods can be declared within 4 contexts: class interfaces, +/// categories, protocols, and class implementations. While C++ member +/// functions leverage C syntax, Objective-C method syntax is modeled after +/// Smalltalk (using colons to specify argument types/expressions). +/// Here are some brief examples: +/// +/// Setter/getter instance methods: +/// - (void)setMenu:(NSMenu *)menu; +/// - (NSMenu *)menu; +/// +/// Instance method that takes 2 NSView arguments: +/// - (void)replaceSubview:(NSView *)oldView with:(NSView *)newView; +/// +/// Getter class method: +/// + (NSMenu *)defaultMenu; +/// +/// A selector represents a unique name for a method. The selector names for +/// the above methods are setMenu:, menu, replaceSubview:with:, and defaultMenu. +/// +class ObjcMethodDecl : public Decl { + public: + enum ImplementationControl { None, Required, Optional }; + private: + /// Bitfields must be first fields in this class so they pack with those + /// declared in class Decl. + /// instance (true) or class (false) method. + bool IsInstance : 1; + /// @required/@optional + ImplementationControl DeclImplementation : 2; + + /// in, inout, etc. + ObjcDeclQualifier objcDeclQualifier : 6; + + // Context this method is declared in. + NamedDecl *MethodContext; + + // A unigue name for this method. + Selector SelName; + + // Type of this method. + QualType MethodDeclType; + /// 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; + + Stmt *Body; // Null if a prototype. + + SourceLocation EndLoc; // the location of the ';' or '{'. + public: + ObjcMethodDecl(SourceLocation beginLoc, SourceLocation endLoc, + Selector SelInfo, QualType T, + Decl *contextDecl, + ParmVarDecl **paramInfo = 0, int numParams=-1, + AttributeList *M = 0, bool isInstance = true, + ImplementationControl impControl = None, + Decl *PrevDecl = 0) + : Decl(ObjcMethod, beginLoc), + IsInstance(isInstance), DeclImplementation(impControl), + objcDeclQualifier(OBJC_TQ_None), + MethodContext(static_cast(contextDecl)), + SelName(SelInfo), MethodDeclType(T), + ParamInfo(paramInfo), NumMethodParams(numParams), + MethodAttrs(M), EndLoc(endLoc) {} + virtual ~ObjcMethodDecl(); + + ObjcDeclQualifier getObjcDeclQualifier() const { return objcDeclQualifier; } + void setObjcDeclQualifier(ObjcDeclQualifier QV) { objcDeclQualifier = QV; } + + // Location information, modeled after the Stmt API. + SourceLocation getLocStart() const { return getLocation(); } + SourceLocation getLocEnd() const { return EndLoc; } + + NamedDecl *getMethodContext() const { return MethodContext; } + + ObjcInterfaceDecl *const getClassInterface() const { + if (isa(MethodContext)) + return dyn_cast(MethodContext); + else if (isa(MethodContext)) + return dyn_cast(MethodContext)->getClassInterface(); + else if (isa(MethodContext)) + return dyn_cast(MethodContext) + ->getClassInterface(); + else if (isa(MethodContext)) + return dyn_cast(MethodContext)->getClassInterface(); + assert(false && "unknown method context"); + return 0; + } + + Selector getSelector() const { return SelName; } + QualType getResultType() const { return MethodDeclType; } + + int getNumParams() const { return NumMethodParams; } + ParmVarDecl *getParamDecl(int i) const { + assert(i < getNumParams() && "Illegal param #"); + return ParamInfo[i]; + } + void setMethodParams(ParmVarDecl **NewParamInfo, unsigned NumParams); + + AttributeList *getMethodAttrs() const {return MethodAttrs;} + bool isInstance() const { return IsInstance; } + // Related to protocols declared in @protocol + void setDeclImplementation(ImplementationControl ic) + { DeclImplementation = ic; } + ImplementationControl getImplementationControl() const + { return DeclImplementation; } + + Stmt *const getBody() const { return Body; } + void setBody(Stmt *B) { Body = B; } + + // Implement isa/cast/dyncast/etc. + static bool classof(const Decl *D) { return D->getKind() == ObjcMethod; } + static bool classof(const ObjcMethodDecl *D) { return true; } +}; + /// ObjcCompatibleAliasDecl - Represents alias of a class. This alias is /// declared as @compatibility_alias alias class. class ObjcCompatibleAliasDecl : public ScopedDecl { -- 2.40.0