aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2009-06-05 18:16:35 +0000
committerFariborz Jahanian <fjahanian@apple.com>2009-06-05 18:16:35 +0000
commit496b5a894c5ec5425de53909f5aac3fb4771a2ec (patch)
tree72853dce38a871d04763325c89e8a6acd3dcb879
parentf5dba388e7d4a725b7ac9a7000bfdf0c2da9a36a (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.h1
-rw-r--r--include/clang/Parse/Action.h1
-rw-r--r--lib/AST/DeclObjC.cpp22
-rw-r--r--lib/Frontend/PrintParserCallbacks.cpp1
-rw-r--r--lib/Parse/ParseObjc.cpp1
-rw-r--r--lib/Sema/Sema.h1
-rw-r--r--lib/Sema/SemaDecl.cpp35
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);
}
}