diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2009-06-05 18:16:35 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2009-06-05 18:16:35 +0000 |
commit | 496b5a894c5ec5425de53909f5aac3fb4771a2ec (patch) | |
tree | 72853dce38a871d04763325c89e8a6acd3dcb879 | |
parent | f5dba388e7d4a725b7ac9a7000bfdf0c2da9a36a (diff) |
Use of DeclContext for objc's ivars. No functionality
change. More to follow.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@72951 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/AST/DeclObjC.h | 1 | ||||
-rw-r--r-- | include/clang/Parse/Action.h | 1 | ||||
-rw-r--r-- | lib/AST/DeclObjC.cpp | 22 | ||||
-rw-r--r-- | lib/Frontend/PrintParserCallbacks.cpp | 1 | ||||
-rw-r--r-- | lib/Parse/ParseObjc.cpp | 1 | ||||
-rw-r--r-- | lib/Sema/Sema.h | 1 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 35 |
7 files changed, 47 insertions, 15 deletions
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h index 6e89a7ae7b..3943ddc196 100644 --- a/include/clang/AST/DeclObjC.h +++ b/include/clang/AST/DeclObjC.h @@ -330,6 +330,7 @@ public: // Get the local instance/class method declared in this interface. ObjCMethodDecl *getInstanceMethod(ASTContext &Context, Selector Sel) const; ObjCMethodDecl *getClassMethod(ASTContext &Context, Selector Sel) const; + ObjCIvarDecl *getIvarDecl(ASTContext &Context, IdentifierInfo *Id) const; ObjCMethodDecl * getMethod(ASTContext &Context, Selector Sel, bool isInstance) const { diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h index 588e659176..579fe6cb03 100644 --- a/include/clang/Parse/Action.h +++ b/include/clang/Parse/Action.h @@ -417,6 +417,7 @@ public: } virtual DeclPtrTy ActOnIvar(Scope *S, SourceLocation DeclStart, + DeclPtrTy IntfDecl, Declarator &D, ExprTy *BitfieldWidth, tok::ObjCKeywordKind visibility) { return DeclPtrTy(); diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp index f4bb895730..21aefdd567 100644 --- a/lib/AST/DeclObjC.cpp +++ b/lib/AST/DeclObjC.cpp @@ -42,6 +42,19 @@ void ObjCListBase::set(void *const* InList, unsigned Elts, ASTContext &Ctx) { // ObjCInterfaceDecl //===----------------------------------------------------------------------===// +/// getIvarDecl - This method looks up an ivar in this ContextDecl. +/// +ObjCIvarDecl * +ObjCContainerDecl::getIvarDecl(ASTContext &Context, IdentifierInfo *Id) const { + lookup_const_iterator Ivar, IvarEnd; + for (llvm::tie(Ivar, IvarEnd) = lookup(Context, Id); + Ivar != IvarEnd; ++Ivar) { + if (ObjCIvarDecl *ivar = dyn_cast<ObjCIvarDecl>(*Ivar)) + return ivar; + } + return 0; +} + // Get the local instance method declared in this interface. ObjCMethodDecl * ObjCContainerDecl::getInstanceMethod(ASTContext &Context, Selector Sel) const { @@ -139,12 +152,9 @@ ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable( ASTContext &Context, IdentifierInfo *ID, ObjCInterfaceDecl *&clsDeclared) { ObjCInterfaceDecl* ClassDecl = this; while (ClassDecl != NULL) { - for (ivar_iterator I = ClassDecl->ivar_begin(), E = ClassDecl->ivar_end(); - I != E; ++I) { - if ((*I)->getIdentifier() == ID) { - clsDeclared = ClassDecl; - return *I; - } + if (ObjCIvarDecl *I = ClassDecl->getIvarDecl(Context, ID)) { + clsDeclared = ClassDecl; + return I; } // look into properties. for (ObjCInterfaceDecl::prop_iterator I = ClassDecl->prop_begin(Context), diff --git a/lib/Frontend/PrintParserCallbacks.cpp b/lib/Frontend/PrintParserCallbacks.cpp index f02d5d469c..b9fe0680af 100644 --- a/lib/Frontend/PrintParserCallbacks.cpp +++ b/lib/Frontend/PrintParserCallbacks.cpp @@ -220,6 +220,7 @@ namespace { } virtual DeclPtrTy ActOnIvar(Scope *S, SourceLocation DeclStart, + DeclPtrTy IntfDecl, Declarator &D, ExprTy *BitfieldWidth, tok::ObjCKeywordKind visibility) { Out << __FUNCTION__ << "\n"; diff --git a/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp index 3014f95a84..cb7fe58807 100644 --- a/lib/Parse/ParseObjc.cpp +++ b/lib/Parse/ParseObjc.cpp @@ -891,6 +891,7 @@ void Parser::ParseObjCClassInstanceVariables(DeclPtrTy interfaceDecl, // Install the declarator into interfaceDecl. DeclPtrTy Field = Actions.ActOnIvar(CurScope, DS.getSourceRange().getBegin(), + interfaceDecl, FD.D, FD.BitfieldSize, visibility); AllIvarDecls.push_back(Field); } diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index faf25710a4..ecf08ad7fe 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -472,6 +472,7 @@ public: Declarator *D = 0); virtual DeclPtrTy ActOnIvar(Scope *S, SourceLocation DeclStart, + DeclPtrTy IntfDecl, Declarator &D, ExprTy *BitfieldWidth, tok::ObjCKeywordKind visibility); diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 51b5449d9f..c67af295c1 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -3914,6 +3914,7 @@ TranslateIvarVisibility(tok::ObjCKeywordKind ivarVisibility) { /// in order to create an IvarDecl object for it. Sema::DeclPtrTy Sema::ActOnIvar(Scope *S, SourceLocation DeclStart, + DeclPtrTy IntfDecl, Declarator &D, ExprTy *BitfieldWidth, tok::ObjCKeywordKind Visibility) { @@ -3952,14 +3953,28 @@ Sema::DeclPtrTy Sema::ActOnIvar(Scope *S, ObjCIvarDecl::AccessControl ac = Visibility != tok::objc_not_keyword ? TranslateIvarVisibility(Visibility) : ObjCIvarDecl::None; - + // Must set ivar's DeclContext to its enclosing interface. + Decl *EnclosingDecl = IntfDecl.getAs<Decl>(); + DeclContext *EnclosingContext; + if (ObjCImplementationDecl *IMPDecl = + dyn_cast<ObjCImplementationDecl>(EnclosingDecl)) { + // Case of ivar declared in an implementation. Context is that of its class. + ObjCInterfaceDecl* IDecl = IMPDecl->getClassInterface(); + assert(IDecl && "No class- ActOnIvar"); + EnclosingContext = cast_or_null<DeclContext>(IDecl); + } + else + EnclosingContext = dyn_cast<DeclContext>(EnclosingDecl); + assert(EnclosingContext && "null DeclContext for ivar - ActOnIvar"); + // Construct the decl. - ObjCIvarDecl *NewID = ObjCIvarDecl::Create(Context, CurContext, Loc, II, T,ac, + ObjCIvarDecl *NewID = ObjCIvarDecl::Create(Context, + EnclosingContext, Loc, II, T,ac, (Expr *)BitfieldWidth); if (II) { NamedDecl *PrevDecl = LookupName(S, II, LookupMemberName, true); - if (PrevDecl && isDeclInScope(PrevDecl, CurContext, S) + if (PrevDecl && isDeclInScope(PrevDecl, EnclosingContext, S) && !isa<TagDecl>(PrevDecl)) { Diag(Loc, diag::err_duplicate_member) << II; Diag(PrevDecl->getLocation(), diag::note_previous_declaration); @@ -4100,7 +4115,11 @@ void Sema::ActOnFields(Scope* S, if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(EnclosingDecl)) { ID->setIVarList(ClsFields, RecFields.size(), Context); ID->setLocEnd(RBrac); - + // Add ivar's to class's DeclContext. + for (unsigned i = 0, e = RecFields.size(); i != e; ++i) { + ClsFields[i]->setLexicalDeclContext(ID); + ID->addDecl(Context, ClsFields[i]); + } // Must enforce the rule that ivars in the base classes may not be // duplicates. if (ID->getSuperClass()) { @@ -4121,12 +4140,10 @@ void Sema::ActOnFields(Scope* S, } else if (ObjCImplementationDecl *IMPDecl = dyn_cast<ObjCImplementationDecl>(EnclosingDecl)) { assert(IMPDecl && "ActOnFields - missing ObjCImplementationDecl"); - for (unsigned I = 0, N = RecFields.size(); I != N; ++I) { - // FIXME: Set the DeclContext correctly when we build the - // declarations. + for (unsigned I = 0, N = RecFields.size(); I != N; ++I) + // Ivar declared in @implementation never belongs to the implementation. + // Only it is in implementation's lexical context. ClsFields[I]->setLexicalDeclContext(IMPDecl); - IMPDecl->addDecl(Context, ClsFields[I]); - } CheckImplementationIvars(IMPDecl, ClsFields, RecFields.size(), RBrac); } } |