[cfe-commits] r97943 - in /cfe/trunk: include/clang/AST/ExprObjC.h lib/AST/Expr.cpp lib/Checker/CFRefCount.cpp lib/CodeGen/CGObjC.cpp lib/Frontend/PCHReaderStmt.cpp lib/Frontend/PCHWriterStmt.cpp lib/Index/Analyzer.cpp lib/Sema/SemaExprObjC.cpp test/Index/c-index-getCursor-test.m tools/CIndex/CIndex.cpp
Douglas Gregor
dgregor at apple.com
Mon Mar 8 08:40:19 PST 2010
Author: dgregor
Date: Mon Mar 8 10:40:19 2010
New Revision: 97943
URL: http://llvm.org/viewvc/llvm-project?rev=97943&view=rev
Log:
Extend ObjCMessageExpr for class method sends with the source location
of the class name.
Modified:
cfe/trunk/include/clang/AST/ExprObjC.h
cfe/trunk/lib/AST/Expr.cpp
cfe/trunk/lib/Checker/CFRefCount.cpp
cfe/trunk/lib/CodeGen/CGObjC.cpp
cfe/trunk/lib/Frontend/PCHReaderStmt.cpp
cfe/trunk/lib/Frontend/PCHWriterStmt.cpp
cfe/trunk/lib/Index/Analyzer.cpp
cfe/trunk/lib/Sema/SemaExprObjC.cpp
cfe/trunk/test/Index/c-index-getCursor-test.m
cfe/trunk/tools/CIndex/CIndex.cpp
Modified: cfe/trunk/include/clang/AST/ExprObjC.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExprObjC.h?rev=97943&r1=97942&r2=97943&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ExprObjC.h (original)
+++ cfe/trunk/include/clang/AST/ExprObjC.h Mon Mar 8 10:40:19 2010
@@ -347,6 +347,9 @@
// message expression.
unsigned NumArgs;
+ /// \brief The location of the class name in a class message.
+ SourceLocation ClassNameLoc;
+
// A unigue name for this message.
Selector SelName;
@@ -367,7 +370,8 @@
public:
/// This constructor is used to represent class messages where the
/// ObjCInterfaceDecl* of the receiver is not known.
- ObjCMessageExpr(ASTContext &C, IdentifierInfo *clsName, Selector selInfo,
+ ObjCMessageExpr(ASTContext &C, IdentifierInfo *clsName,
+ SourceLocation clsNameLoc, Selector selInfo,
QualType retType, ObjCMethodDecl *methDecl,
SourceLocation LBrac, SourceLocation RBrac,
Expr **ArgExprs, unsigned NumArgs);
@@ -375,7 +379,8 @@
/// This constructor is used to represent class messages where the
/// ObjCInterfaceDecl* of the receiver is known.
// FIXME: clsName should be typed to ObjCInterfaceType
- ObjCMessageExpr(ASTContext &C, ObjCInterfaceDecl *cls, Selector selInfo,
+ ObjCMessageExpr(ASTContext &C, ObjCInterfaceDecl *cls,
+ SourceLocation clsNameLoc, Selector selInfo,
QualType retType, ObjCMethodDecl *methDecl,
SourceLocation LBrac, SourceLocation RBrac,
Expr **ArgExprs, unsigned NumArgs);
@@ -411,7 +416,24 @@
ObjCMethodDecl *getMethodDecl() { return MethodProto; }
void setMethodDecl(ObjCMethodDecl *MD) { MethodProto = MD; }
- typedef std::pair<ObjCInterfaceDecl*, IdentifierInfo*> ClassInfo;
+ /// \brief Describes the class receiver of a message send.
+ struct ClassInfo {
+ /// \brief The interface declaration for the class that is
+ /// receiving the message. May be NULL.
+ ObjCInterfaceDecl *Decl;
+
+ /// \brief The name of the class that is receiving the
+ /// message. This will never be NULL.
+ IdentifierInfo *Name;
+
+ /// \brief The source location of the class name.
+ SourceLocation Loc;
+
+ ClassInfo() : Decl(0), Name(0), Loc() { }
+
+ ClassInfo(ObjCInterfaceDecl *Decl, IdentifierInfo *Name, SourceLocation Loc)
+ : Decl(Decl), Name(Name), Loc(Loc) { }
+ };
/// getClassInfo - For class methods, this returns both the ObjCInterfaceDecl*
/// and IdentifierInfo* of the invoked class. Both can be NULL if this
@@ -423,7 +445,7 @@
/// getClassName - For class methods, this returns the invoked class,
/// and returns NULL otherwise. For instance methods, use getReceiver.
IdentifierInfo *getClassName() const {
- return getClassInfo().second;
+ return getClassInfo().Name;
}
/// getNumArgs - Return the number of actual arguments to this call.
Modified: cfe/trunk/lib/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=97943&r1=97942&r2=97943&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Mon Mar 8 10:40:19 2010
@@ -2115,12 +2115,12 @@
// constructor for class messages.
// FIXME: clsName should be typed to ObjCInterfaceType
ObjCMessageExpr::ObjCMessageExpr(ASTContext &C, IdentifierInfo *clsName,
- Selector selInfo, QualType retType,
- ObjCMethodDecl *mproto,
+ SourceLocation clsNameLoc, Selector selInfo,
+ QualType retType, ObjCMethodDecl *mproto,
SourceLocation LBrac, SourceLocation RBrac,
Expr **ArgExprs, unsigned nargs)
- : Expr(ObjCMessageExprClass, retType, false, false), SelName(selInfo),
- MethodProto(mproto) {
+ : Expr(ObjCMessageExprClass, retType, false, false), ClassNameLoc(clsNameLoc),
+ SelName(selInfo), MethodProto(mproto) {
NumArgs = nargs;
SubExprs = new (C) Stmt*[NumArgs+1];
SubExprs[RECEIVER] = (Expr*) ((uintptr_t) clsName | IsClsMethDeclUnknown);
@@ -2134,12 +2134,14 @@
// constructor for class messages.
ObjCMessageExpr::ObjCMessageExpr(ASTContext &C, ObjCInterfaceDecl *cls,
- Selector selInfo, QualType retType,
+ SourceLocation clsNameLoc, Selector selInfo,
+ QualType retType,
ObjCMethodDecl *mproto, SourceLocation LBrac,
SourceLocation RBrac, Expr **ArgExprs,
unsigned nargs)
-: Expr(ObjCMessageExprClass, retType, false, false), SelName(selInfo),
-MethodProto(mproto) {
+ : Expr(ObjCMessageExprClass, retType, false, false), ClassNameLoc(clsNameLoc),
+ SelName(selInfo), MethodProto(mproto)
+{
NumArgs = nargs;
SubExprs = new (C) Stmt*[NumArgs+1];
SubExprs[RECEIVER] = (Expr*) ((uintptr_t) cls | IsClsMethDeclKnown);
@@ -2157,23 +2159,27 @@
default:
assert(false && "Invalid ObjCMessageExpr.");
case IsInstMeth:
- return ClassInfo(0, 0);
+ return ClassInfo(0, 0, SourceLocation());
case IsClsMethDeclUnknown:
- return ClassInfo(0, (IdentifierInfo*) (x & ~Flags));
+ return ClassInfo(0, (IdentifierInfo*) (x & ~Flags), ClassNameLoc);
case IsClsMethDeclKnown: {
ObjCInterfaceDecl* D = (ObjCInterfaceDecl*) (x & ~Flags);
- return ClassInfo(D, D->getIdentifier());
+ return ClassInfo(D, D->getIdentifier(), ClassNameLoc);
}
}
}
void ObjCMessageExpr::setClassInfo(const ObjCMessageExpr::ClassInfo &CI) {
- if (CI.first == 0 && CI.second == 0)
+ if (CI.Decl == 0 && CI.Name == 0) {
SubExprs[RECEIVER] = (Expr*)((uintptr_t)0 | IsInstMeth);
- else if (CI.first == 0)
- SubExprs[RECEIVER] = (Expr*)((uintptr_t)CI.second | IsClsMethDeclUnknown);
+ return;
+ }
+
+ if (CI.Decl == 0)
+ SubExprs[RECEIVER] = (Expr*)((uintptr_t)CI.Name | IsClsMethDeclUnknown);
else
- SubExprs[RECEIVER] = (Expr*)((uintptr_t)CI.first | IsClsMethDeclKnown);
+ SubExprs[RECEIVER] = (Expr*)((uintptr_t)CI.Decl | IsClsMethDeclKnown);
+ ClassNameLoc = CI.Loc;
}
void ObjCMessageExpr::DoDestroy(ASTContext &C) {
Modified: cfe/trunk/lib/Checker/CFRefCount.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Checker/CFRefCount.cpp?rev=97943&r1=97942&r2=97943&view=diff
==============================================================================
--- cfe/trunk/lib/Checker/CFRefCount.cpp (original)
+++ cfe/trunk/lib/Checker/CFRefCount.cpp Mon Mar 8 10:40:19 2010
@@ -853,7 +853,7 @@
RetainSummary *getClassMethodSummary(const ObjCMessageExpr *ME) {
return getClassMethodSummary(ME->getSelector(), ME->getClassName(),
- ME->getClassInfo().first,
+ ME->getClassInfo().Decl,
ME->getMethodDecl(), ME->getType());
}
@@ -2511,7 +2511,7 @@
// id, id<...>, or Class. If we have an ObjCInterfaceDecl, we know this
// is a call to a class method whose type we can resolve. In such
// cases, promote the return type to XXX* (where XXX is the class).
- const ObjCInterfaceDecl *D = ME->getClassInfo().first;
+ const ObjCInterfaceDecl *D = ME->getClassInfo().Decl;
return !D ? RetTy : Ctx.getPointerType(Ctx.getObjCInterfaceType(D));
}
Modified: cfe/trunk/lib/CodeGen/CGObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjC.cpp?rev=97943&r1=97942&r2=97943&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjC.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjC.cpp Mon Mar 8 10:40:19 2010
@@ -59,7 +59,7 @@
// Find the receiver
llvm::Value *Receiver;
if (!ReceiverExpr) {
- const ObjCInterfaceDecl *OID = E->getClassInfo().first;
+ const ObjCInterfaceDecl *OID = E->getClassInfo().Decl;
// Very special case, super send in class method. The receiver is
// self (the class object) and the send uses super semantics.
Modified: cfe/trunk/lib/Frontend/PCHReaderStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHReaderStmt.cpp?rev=97943&r1=97942&r2=97943&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHReaderStmt.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHReaderStmt.cpp Mon Mar 8 10:40:19 2010
@@ -792,8 +792,9 @@
cast_or_null<Expr>(StmtStack[StmtStack.size() - E->getNumArgs() - 1]));
if (!E->getReceiver()) {
ObjCMessageExpr::ClassInfo CI;
- CI.first = cast_or_null<ObjCInterfaceDecl>(Reader.GetDecl(Record[Idx++]));
- CI.second = Reader.GetIdentifierInfo(Record, Idx);
+ CI.Decl = cast_or_null<ObjCInterfaceDecl>(Reader.GetDecl(Record[Idx++]));
+ CI.Name = Reader.GetIdentifierInfo(Record, Idx);
+ CI.Loc = SourceLocation::getFromRawEncoding(Record[Idx++]);
E->setClassInfo(CI);
}
Modified: cfe/trunk/lib/Frontend/PCHWriterStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHWriterStmt.cpp?rev=97943&r1=97942&r2=97943&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHWriterStmt.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHWriterStmt.cpp Mon Mar 8 10:40:19 2010
@@ -720,8 +720,9 @@
if (!E->getReceiver()) {
ObjCMessageExpr::ClassInfo CI = E->getClassInfo();
- Writer.AddDeclRef(CI.first, Record);
- Writer.AddIdentifierRef(CI.second, Record);
+ Writer.AddDeclRef(CI.Decl, Record);
+ Writer.AddIdentifierRef(CI.Name, Record);
+ Writer.AddSourceLocation(CI.Loc, Record);
}
for (CallExpr::arg_iterator Arg = E->arg_begin(), ArgEnd = E->arg_end();
Modified: cfe/trunk/lib/Index/Analyzer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Index/Analyzer.cpp?rev=97943&r1=97942&r2=97943&view=diff
==============================================================================
--- cfe/trunk/lib/Index/Analyzer.cpp (original)
+++ cfe/trunk/lib/Index/Analyzer.cpp Mon Mar 8 10:40:19 2010
@@ -177,7 +177,7 @@
if (IsInstanceMethod)
return false;
- MsgD = Msg->getClassInfo().first;
+ MsgD = Msg->getClassInfo().Decl;
// FIXME: Case when we only have an identifier.
assert(MsgD && "Identifier only");
}
@@ -250,7 +250,7 @@
while (true) {
if (Msg->getReceiver() == 0) {
CanBeClassMethod = true;
- MsgD = Msg->getClassInfo().first;
+ MsgD = Msg->getClassInfo().Decl;
// FIXME: Case when we only have an identifier.
assert(MsgD && "Identifier only");
break;
Modified: cfe/trunk/lib/Sema/SemaExprObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprObjC.cpp?rev=97943&r1=97942&r2=97943&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprObjC.cpp Mon Mar 8 10:40:19 2010
@@ -470,13 +470,13 @@
// now, we simply pass the "super" identifier through (which isn't consistent
// with instance methods.
if (isSuper)
- return new (Context) ObjCMessageExpr(Context, receiverName, Sel, returnType,
- Method, lbrac, rbrac, ArgExprs,
- NumArgs);
+ return new (Context) ObjCMessageExpr(Context, receiverName, receiverLoc,
+ Sel, returnType, Method, lbrac, rbrac,
+ ArgExprs, NumArgs);
else
- return new (Context) ObjCMessageExpr(Context, ClassDecl, Sel, returnType,
- Method, lbrac, rbrac, ArgExprs,
- NumArgs);
+ return new (Context) ObjCMessageExpr(Context, ClassDecl, receiverLoc,
+ Sel, returnType, Method, lbrac, rbrac,
+ ArgExprs, NumArgs);
}
// ActOnInstanceMessage - used for both unary and keyword messages.
Modified: cfe/trunk/test/Index/c-index-getCursor-test.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/c-index-getCursor-test.m?rev=97943&r1=97942&r2=97943&view=diff
==============================================================================
--- cfe/trunk/test/Index/c-index-getCursor-test.m (original)
+++ cfe/trunk/test/Index/c-index-getCursor-test.m Mon Mar 8 10:40:19 2010
@@ -120,7 +120,9 @@
// CHECK: [47:4 - 47:6] VarDecl=c:47:12 (Definition)
// CHECK: [47:6 - 47:10] ObjCProtocolRef=SubP:27:1
// CHECK: [47:10 - 47:16] VarDecl=c:47:12 (Definition)
-// CHECK: [47:16 - 47:26] ObjCMessageExpr=fooC:8:1
+// CHECK: [47:16 - 47:17] ObjCMessageExpr=fooC:8:1
+// CHECK: [47:17 - 47:20] ObjCClassRef=Foo:3:12
+// CHECK: [47:20 - 47:26] ObjCMessageExpr=fooC:8:1
// CHECK: [47:26 - 47:27] UnexposedStmt=
// CHECK: [47:27 - 48:2] UnexposedStmt=
// CHECK: [48:2 - 48:4] TypeRef=id:0:0
Modified: cfe/trunk/tools/CIndex/CIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/CIndex/CIndex.cpp?rev=97943&r1=97942&r2=97943&view=diff
==============================================================================
--- cfe/trunk/tools/CIndex/CIndex.cpp (original)
+++ cfe/trunk/tools/CIndex/CIndex.cpp Mon Mar 8 10:40:19 2010
@@ -315,6 +315,7 @@
bool VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E);
bool VisitExplicitCastExpr(ExplicitCastExpr *E);
bool VisitCompoundLiteralExpr(CompoundLiteralExpr *E);
+ bool VisitObjCMessageExpr(ObjCMessageExpr *E);
};
} // end anonymous namespace
@@ -901,6 +902,14 @@
return VisitExpr(E);
}
+bool CursorVisitor::VisitObjCMessageExpr(ObjCMessageExpr *E) {
+ ObjCMessageExpr::ClassInfo CI = E->getClassInfo();
+ if (CI.Decl && Visit(MakeCursorObjCClassRef(CI.Decl, CI.Loc, TU)))
+ return true;
+
+ return VisitExpr(E);
+}
+
bool CursorVisitor::VisitAttributes(Decl *D) {
for (const Attr *A = D->getAttrs(); A; A = A->getNext())
if (Visit(MakeCXCursor(A, D, TU)))
More information about the cfe-commits
mailing list