[libclang/AST] Index references of protocols in "@protocol(...)" syntax.

To do that, keep track of the location of the protocol id in the ObjCProtocolExpr
AST node.

rdar://11190837

llvm-svn: 156890
This commit is contained in:
Argyrios Kyrtzidis 2012-05-16 00:50:02 +00:00
parent 3bcf4b5cc7
commit b7e4367fef
7 changed files with 21 additions and 6 deletions

View File

@ -421,19 +421,20 @@ public:
/// The return type is "Protocol*". /// The return type is "Protocol*".
class ObjCProtocolExpr : public Expr { class ObjCProtocolExpr : public Expr {
ObjCProtocolDecl *TheProtocol; ObjCProtocolDecl *TheProtocol;
SourceLocation AtLoc, RParenLoc; SourceLocation AtLoc, ProtoLoc, RParenLoc;
public: public:
ObjCProtocolExpr(QualType T, ObjCProtocolDecl *protocol, ObjCProtocolExpr(QualType T, ObjCProtocolDecl *protocol,
SourceLocation at, SourceLocation rp) SourceLocation at, SourceLocation protoLoc, SourceLocation rp)
: Expr(ObjCProtocolExprClass, T, VK_RValue, OK_Ordinary, false, false, : Expr(ObjCProtocolExprClass, T, VK_RValue, OK_Ordinary, false, false,
false, false), false, false),
TheProtocol(protocol), AtLoc(at), RParenLoc(rp) {} TheProtocol(protocol), AtLoc(at), ProtoLoc(protoLoc), RParenLoc(rp) {}
explicit ObjCProtocolExpr(EmptyShell Empty) explicit ObjCProtocolExpr(EmptyShell Empty)
: Expr(ObjCProtocolExprClass, Empty) {} : Expr(ObjCProtocolExprClass, Empty) {}
ObjCProtocolDecl *getProtocol() const { return TheProtocol; } ObjCProtocolDecl *getProtocol() const { return TheProtocol; }
void setProtocol(ObjCProtocolDecl *P) { TheProtocol = P; } void setProtocol(ObjCProtocolDecl *P) { TheProtocol = P; }
SourceLocation getProtocolIdLoc() const { return ProtoLoc; }
SourceLocation getAtLoc() const { return AtLoc; } SourceLocation getAtLoc() const { return AtLoc; }
SourceLocation getRParenLoc() const { return RParenLoc; } SourceLocation getRParenLoc() const { return RParenLoc; }
void setAtLoc(SourceLocation L) { AtLoc = L; } void setAtLoc(SourceLocation L) { AtLoc = L; }
@ -450,6 +451,9 @@ public:
// Iterators // Iterators
child_range children() { return child_range(); } child_range children() { return child_range(); }
friend class ASTStmtReader;
friend class ASTStmtWriter;
}; };
/// ObjCIvarRefExpr - A reference to an ObjC instance variable. /// ObjCIvarRefExpr - A reference to an ObjC instance variable.

View File

@ -4096,6 +4096,7 @@ public:
SourceLocation AtLoc, SourceLocation AtLoc,
SourceLocation ProtoLoc, SourceLocation ProtoLoc,
SourceLocation LParenLoc, SourceLocation LParenLoc,
SourceLocation ProtoIdLoc,
SourceLocation RParenLoc); SourceLocation RParenLoc);
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//

View File

@ -2743,12 +2743,13 @@ Parser::ParseObjCProtocolExpression(SourceLocation AtLoc) {
return ExprError(Diag(Tok, diag::err_expected_ident)); return ExprError(Diag(Tok, diag::err_expected_ident));
IdentifierInfo *protocolId = Tok.getIdentifierInfo(); IdentifierInfo *protocolId = Tok.getIdentifierInfo();
ConsumeToken(); SourceLocation ProtoIdLoc = ConsumeToken();
T.consumeClose(); T.consumeClose();
return Owned(Actions.ParseObjCProtocolExpression(protocolId, AtLoc, ProtoLoc, return Owned(Actions.ParseObjCProtocolExpression(protocolId, AtLoc, ProtoLoc,
T.getOpenLocation(), T.getOpenLocation(),
ProtoIdLoc,
T.getCloseLocation())); T.getCloseLocation()));
} }

View File

@ -1012,8 +1012,9 @@ ExprResult Sema::ParseObjCProtocolExpression(IdentifierInfo *ProtocolId,
SourceLocation AtLoc, SourceLocation AtLoc,
SourceLocation ProtoLoc, SourceLocation ProtoLoc,
SourceLocation LParenLoc, SourceLocation LParenLoc,
SourceLocation ProtoIdLoc,
SourceLocation RParenLoc) { SourceLocation RParenLoc) {
ObjCProtocolDecl* PDecl = LookupProtocol(ProtocolId, ProtoLoc); ObjCProtocolDecl* PDecl = LookupProtocol(ProtocolId, ProtoIdLoc);
if (!PDecl) { if (!PDecl) {
Diag(ProtoLoc, diag::err_undeclared_protocol) << ProtocolId; Diag(ProtoLoc, diag::err_undeclared_protocol) << ProtocolId;
return true; return true;
@ -1023,7 +1024,7 @@ ExprResult Sema::ParseObjCProtocolExpression(IdentifierInfo *ProtocolId,
if (Ty.isNull()) if (Ty.isNull())
return true; return true;
Ty = Context.getObjCObjectPointerType(Ty); Ty = Context.getObjCObjectPointerType(Ty);
return new (Context) ObjCProtocolExpr(Ty, PDecl, AtLoc, RParenLoc); return new (Context) ObjCProtocolExpr(Ty, PDecl, AtLoc, ProtoIdLoc, RParenLoc);
} }
/// Try to capture an implicit reference to 'self'. /// Try to capture an implicit reference to 'self'.

View File

@ -873,6 +873,7 @@ void ASTStmtReader::VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
VisitExpr(E); VisitExpr(E);
E->setProtocol(ReadDeclAs<ObjCProtocolDecl>(Record, Idx)); E->setProtocol(ReadDeclAs<ObjCProtocolDecl>(Record, Idx));
E->setAtLoc(ReadSourceLocation(Record, Idx)); E->setAtLoc(ReadSourceLocation(Record, Idx));
E->ProtoLoc = ReadSourceLocation(Record, Idx);
E->setRParenLoc(ReadSourceLocation(Record, Idx)); E->setRParenLoc(ReadSourceLocation(Record, Idx));
} }

View File

@ -837,6 +837,7 @@ void ASTStmtWriter::VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
VisitExpr(E); VisitExpr(E);
Writer.AddDeclRef(E->getProtocol(), Record); Writer.AddDeclRef(E->getProtocol(), Record);
Writer.AddSourceLocation(E->getAtLoc(), Record); Writer.AddSourceLocation(E->getAtLoc(), Record);
Writer.AddSourceLocation(E->ProtoLoc, Record);
Writer.AddSourceLocation(E->getRParenLoc(), Record); Writer.AddSourceLocation(E->getRParenLoc(), Record);
Code = serialization::EXPR_OBJC_PROTOCOL_EXPR; Code = serialization::EXPR_OBJC_PROTOCOL_EXPR;
} }

View File

@ -90,6 +90,12 @@ public:
return true; return true;
} }
bool VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
IndexCtx.handleReference(E->getProtocol(), E->getProtocolIdLoc(),
Parent, ParentDC, E, CXIdxEntityRef_Direct);
return true;
}
bool VisitObjCBoxedExpr(ObjCBoxedExpr *E) { bool VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
if (ObjCMethodDecl *MD = E->getBoxingMethod()) if (ObjCMethodDecl *MD = E->getBoxingMethod())
IndexCtx.handleReference(MD, E->getLocStart(), IndexCtx.handleReference(MD, E->getLocStart(),