Relationship between ObjCPropertyRefExpr and ObjCIvarDecl

I’m experimenting with clang to do some analyzes and inspections on
Objective-C-code, or, to be more precise, iPhone-Code.
Currently, I’m trying to ‘guess’ the inner-types of enumeratable types, especially for

NSArrays. For this, I set up a RecursiveASTVisitor and collect all of the variables
that I am interested in (ObjCIVar, VarDecl, ParmVarDecl). Also, I’m looking into
statements and declarations where those variables get used. I already got it to
guess some inner-types by inspecting ObjCForCollection-statments, which is
fine.
Now, I’m doing some specializations for NSMutableArray inside my visitor to get
some hints from statements like
[ addObject:]
so i can build a relationship between the type of variable X and the inner-type of
the array. This already works for local declared arrays, but not for ObjCIvars.
For the moment, I’m stuck with an expression that looks like
[self.items addObject:item]
where items is declared as

@interface Foo : NSObject {
@private
NSMutableArray *items;
}
@property(retain) NSMutableArray *items;
@end

@implementation Foo
@synthesize items;
@end

So, I’m diving into the ObjCMessageExpression and try to get the ObjCIvarDecl.
For this, I’m catching the instance-receiver, which is a ImplicitCastExpr, get it’s
subExpr and cast it to the ObjCPropertyRefExpr that it is. On this, I’m calling
getExplicitProperty() and receiving the ObjCPropertyDecl.

And here’s the point that confuses me: when I try to get the ObjCIvarDecl by
calling getPropertyIvarDecl on the ObjCPropertyDecl, I’m receiving a nullpointer.

The header of Foo is included and also my compilerinstance reports no errors,
so i think the configuration of the project itself should be correct. Am I
misunderstanding the concept/functionality of the methods I’m using - or is it
maybe a bug inside clang, that it doesn’t set the ObjCIvarDecl properly for
every ObjCProperetyDecl?
svn log says that I am using r127573.

Thanks,
Hendrik

It only sets it for synthesized ivars. Look at Sema::ActOnPropertyImplDecl for details. You can follow
the same logic for looking up the ivar; starting at if (Synthesize) {...}

- Fariborz

The items-property gets synthesized within the implementation. But i just realized

that i missed two details within my example, those are

  1. Foo implements a protocol with a method, call it bar
  2. the access to the items happen inside the implementation of bar
    Is it possible that clang doesn’t resolve the ObjCIvar as it isn’t a method that got
    declared within the interface or something like that?

I’ll take a look into Sema::ActOnPropertyImplDecl - thank you so far.

2011/3/16 Fariborz Jahanian <fjahanian@apple.com>

I haven’t had a very deep look into the Sema-code, as my knowledge of the internals
of clang at this level isn’t that good that i could benefit from it.
Instead, i tried to get the ObjCIvarDecl with the methods I know and I’m used too - and
finally i got it.
I get to the ObjCInterfaceDecl through the ValueDecl that lies in the deeps of the base of
the ObjCPropertyRefExpr. Through this, I can get to the ObjCImplementationDecl, to
the ObjCPropertyImplDecl and to the ObjCIvarDecl. By comparing the getter-name within
the ObjCPropertyRefExpr, i finally can find the right ObjCPropertyImplDecl and the
ObjCIvarDecl. The method itseld can be found at
http://pastebin.com/VEVACTvP

I still have no clue if clang misses something in Sema to set the ObjCIvar-reference on
the ObjCPropertyDecl, or if I’m misinterpreting some methods or maybe if it is totally
wrong what I’m doing - but for now, it seems to work and I’m going to grant now my
braincells some cooldown :wink:

2011/3/16 Hendrik vP <variadic.template@googlemail.com>