For an Objective-C @synthesize statement, e.g.,

@synthesize foo = _foo;

keep track of the location of the ivar ("_foo"). Teach libclang to
visit the ivar as a member reference.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@119447 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Douglas Gregor 2010-11-17 01:03:52 +00:00
Родитель 1e7e877091
Коммит a4ffd85a66
9 изменённых файлов: 66 добавлений и 21 удалений

Просмотреть файл

@ -1455,6 +1455,15 @@ public:
};
private:
SourceLocation AtLoc; // location of @synthesize or @dynamic
/// \brief For @synthesize, the location of the ivar, if it was written in
/// the source code.
///
/// \code
/// @synthesize int a = b
/// \endcode
SourceLocation IvarLoc;
/// Property declaration being implemented
ObjCPropertyDecl *PropertyDecl;
@ -1471,9 +1480,10 @@ private:
ObjCPropertyImplDecl(DeclContext *DC, SourceLocation atLoc, SourceLocation L,
ObjCPropertyDecl *property,
Kind PK,
ObjCIvarDecl *ivarDecl)
ObjCIvarDecl *ivarDecl,
SourceLocation ivarLoc)
: Decl(ObjCPropertyImpl, DC, L), AtLoc(atLoc),
PropertyDecl(property), PropertyIvarDecl(ivarDecl),
IvarLoc(ivarLoc), PropertyDecl(property), PropertyIvarDecl(ivarDecl),
GetterCXXConstructor(0), SetterCXXAssignment(0) {
assert (PK == Dynamic || PropertyIvarDecl);
}
@ -1483,11 +1493,11 @@ public:
SourceLocation atLoc, SourceLocation L,
ObjCPropertyDecl *property,
Kind PK,
ObjCIvarDecl *ivarDecl);
ObjCIvarDecl *ivarDecl,
SourceLocation ivarLoc);
virtual SourceRange getSourceRange() const {
return SourceRange(AtLoc, getLocation());
}
virtual SourceRange getSourceRange() const;
SourceLocation getLocStart() const { return AtLoc; }
void setAtLoc(SourceLocation Loc) { AtLoc = Loc; }
@ -1503,7 +1513,13 @@ public:
ObjCIvarDecl *getPropertyIvarDecl() const {
return PropertyIvarDecl;
}
void setPropertyIvarDecl(ObjCIvarDecl *Ivar) { PropertyIvarDecl = Ivar; }
SourceLocation getPropertyIvarDeclLoc() const { return IvarLoc; }
void setPropertyIvarDecl(ObjCIvarDecl *Ivar,
SourceLocation IvarLoc) {
PropertyIvarDecl = Ivar;
this->IvarLoc = IvarLoc;
}
Expr *getGetterCXXConstructor() const {
return GetterCXXConstructor;
@ -1522,6 +1538,8 @@ public:
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ObjCPropertyImplDecl *D) { return true; }
static bool classofKind(Decl::Kind K) { return K == ObjCPropertyImpl; }
friend class ASTDeclReader;
};
} // end namespace clang

Просмотреть файл

@ -3781,7 +3781,8 @@ public:
SourceLocation PropertyLoc,
bool ImplKind,Decl *ClassImplDecl,
IdentifierInfo *PropertyId,
IdentifierInfo *PropertyIvar);
IdentifierInfo *PropertyIvar,
SourceLocation PropertyIvarLoc);
struct ObjCArgInfo {
IdentifierInfo *Name;

Просмотреть файл

@ -896,7 +896,6 @@ ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C, DeclContext *DC,
return new (C) ObjCPropertyDecl(DC, L, Id, AtLoc, T);
}
//===----------------------------------------------------------------------===//
// ObjCPropertyImplDecl
//===----------------------------------------------------------------------===//
@ -907,8 +906,16 @@ ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C,
SourceLocation L,
ObjCPropertyDecl *property,
Kind PK,
ObjCIvarDecl *ivar) {
return new (C) ObjCPropertyImplDecl(DC, atLoc, L, property, PK, ivar);
ObjCIvarDecl *ivar,
SourceLocation ivarLoc) {
return new (C) ObjCPropertyImplDecl(DC, atLoc, L, property, PK, ivar,
ivarLoc);
}
SourceRange ObjCPropertyImplDecl::getSourceRange() const {
SourceLocation EndLoc = getLocation();
if (IvarLoc.isValid())
EndLoc = IvarLoc;
return SourceRange(AtLoc, EndLoc);
}

Просмотреть файл

@ -1431,6 +1431,7 @@ Decl *Parser::ParseObjCPropertySynthesize(SourceLocation atLoc) {
IdentifierInfo *propertyIvar = 0;
IdentifierInfo *propertyId = Tok.getIdentifierInfo();
SourceLocation propertyLoc = ConsumeToken(); // consume property name
SourceLocation propertyIvarLoc;
if (Tok.is(tok::equal)) {
// property '=' ivar-name
ConsumeToken(); // consume '='
@ -1446,10 +1447,10 @@ Decl *Parser::ParseObjCPropertySynthesize(SourceLocation atLoc) {
break;
}
propertyIvar = Tok.getIdentifierInfo();
ConsumeToken(); // consume ivar-name
propertyIvarLoc = ConsumeToken(); // consume ivar-name
}
Actions.ActOnPropertyImplDecl(getCurScope(), atLoc, propertyLoc, true, ObjCImpDecl,
propertyId, propertyIvar);
propertyId, propertyIvar, propertyIvarLoc);
if (Tok.isNot(tok::comma))
break;
ConsumeToken(); // consume ','
@ -1489,7 +1490,7 @@ Decl *Parser::ParseObjCPropertyDynamic(SourceLocation atLoc) {
IdentifierInfo *propertyId = Tok.getIdentifierInfo();
SourceLocation propertyLoc = ConsumeToken(); // consume property name
Actions.ActOnPropertyImplDecl(getCurScope(), atLoc, propertyLoc, false, ObjCImpDecl,
propertyId, 0);
propertyId, 0, SourceLocation());
if (Tok.isNot(tok::comma))
break;

Просмотреть файл

@ -318,7 +318,8 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S,
bool Synthesize,
Decl *ClassCatImpDecl,
IdentifierInfo *PropertyId,
IdentifierInfo *PropertyIvar) {
IdentifierInfo *PropertyIvar,
SourceLocation PropertyIvarLoc) {
ObjCContainerDecl *ClassImpDecl =
cast_or_null<ObjCContainerDecl>(ClassCatImpDecl);
// Make sure we have a context for the property implementation declaration.
@ -474,7 +475,7 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S,
(Synthesize ?
ObjCPropertyImplDecl::Synthesize
: ObjCPropertyImplDecl::Dynamic),
Ivar);
Ivar, PropertyIvarLoc);
if (ObjCMethodDecl *getterMethod = property->getGetterMethodDecl()) {
getterMethod->createImplicitParams(Context, IDecl);
if (getLangOptions().CPlusPlus && Synthesize &&
@ -997,7 +998,8 @@ void Sema::DefaultSynthesizeProperties (Scope *S, ObjCImplDecl* IMPDecl,
// to help users.
ActOnPropertyImplDecl(S, SourceLocation(), SourceLocation(),
true,IMPDecl,
Prop->getIdentifier(), Prop->getIdentifier());
Prop->getIdentifier(), Prop->getIdentifier(),
SourceLocation());
}
}

Просмотреть файл

@ -616,8 +616,9 @@ void ASTDeclReader::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
D->setAtLoc(ReadSourceLocation(Record, Idx));
D->setPropertyDecl(
cast_or_null<ObjCPropertyDecl>(Reader.GetDecl(Record[Idx++])));
D->setPropertyIvarDecl(
cast_or_null<ObjCIvarDecl>(Reader.GetDecl(Record[Idx++])));
D->PropertyIvarDecl =
cast_or_null<ObjCIvarDecl>(Reader.GetDecl(Record[Idx++]));
D->IvarLoc = ReadSourceLocation(Record, Idx);
D->setGetterCXXConstructor(Reader.ReadExpr(F));
D->setSetterCXXAssignment(Reader.ReadExpr(F));
}
@ -1467,7 +1468,8 @@ Decl *ASTReader::ReadDeclRecord(unsigned Index, DeclID ID) {
case DECL_OBJC_PROPERTY_IMPL:
D = ObjCPropertyImplDecl::Create(*Context, 0, SourceLocation(),
SourceLocation(), 0,
ObjCPropertyImplDecl::Dynamic, 0);
ObjCPropertyImplDecl::Dynamic, 0,
SourceLocation());
break;
case DECL_FIELD:
D = FieldDecl::Create(*Context, 0, SourceLocation(), 0, QualType(), 0, 0,

Просмотреть файл

@ -511,6 +511,7 @@ void ASTDeclWriter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
Writer.AddSourceLocation(D->getLocStart(), Record);
Writer.AddDeclRef(D->getPropertyDecl(), Record);
Writer.AddDeclRef(D->getPropertyIvarDecl(), Record);
Writer.AddSourceLocation(D->getPropertyIvarDeclLoc(), Record);
Writer.AddStmt(D->getGetterCXXConstructor());
Writer.AddStmt(D->getSetterCXXAssignment());
Code = serialization::DECL_OBJC_PROPERTY_IMPL;

Просмотреть файл

@ -479,4 +479,9 @@ static Rdar8595462_A * Rdar8595462_staticVar;
// CHECK: Punctuation: "*" [111:26 - 111:27] ObjCPropertyDecl=foo2:111:27
// CHECK: Identifier: "foo2" [111:27 - 111:31] ObjCPropertyDecl=foo2:111:27
// FIXME: Very poor handling of @synthesized
// CHECK: Punctuation: "@" [115:1 - 115:2] UnexposedDecl=foo:110:33 (Definition)
// CHECK: Keyword: "synthesize" [115:2 - 115:12] UnexposedDecl=foo:110:33 (Definition)
// CHECK: Identifier: "foo" [115:13 - 115:16] UnexposedDecl=foo:110:33 (Definition)
// CHECK: Punctuation: "=" [115:17 - 115:18] UnexposedDecl=foo:110:33 (Definition)
// CHECK: Identifier: "_foo" [115:19 - 115:23] MemberRef=_foo:107:8
// CHECK: Punctuation: ";" [115:23 - 115:24] ObjCImplementationDecl=Rdar8595386:114:1 (Definition)

Просмотреть файл

@ -293,6 +293,7 @@ public:
// FIXME: ObjCCompatibleAliasDecl requires aliased-class locations.
bool VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D);
bool VisitObjCClassDecl(ObjCClassDecl *D);
bool VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD);
bool VisitLinkageSpecDecl(LinkageSpecDecl *D);
bool VisitNamespaceDecl(NamespaceDecl *D);
bool VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
@ -1044,6 +1045,13 @@ bool CursorVisitor::VisitObjCClassDecl(ObjCClassDecl *D) {
return false;
}
bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
return false;
}
bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
return VisitDeclContext(D);
}