зеркало из https://github.com/microsoft/clang-1.git
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:
Родитель
1e7e877091
Коммит
a4ffd85a66
|
@ -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);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче