[cfe-commits] r52676 - in /cfe/trunk: include/clang/AST/ExprObjC.h lib/AST/Expr.cpp lib/Sema/SemaExprObjC.cpp
Ted Kremenek
kremenek at apple.com
Tue Jun 24 08:50:53 PDT 2008
Author: kremenek
Date: Tue Jun 24 10:50:53 2008
New Revision: 52676
URL: http://llvm.org/viewvc/llvm-project?rev=52676&view=rev
Log:
ObjCMessageExpr objects that represent messages to class methods now can contain the ObjCInterfaceDecl* of the target class if it was available when the ObjCMessageExpr object was constructed. The original interfaces of the class has been preserved (requiring no functionality changes from clients), but now a "getClasSInfo" method returns both the ObjCInterfaceDecl* and IdentifierInfo* of the target class.
Modified:
cfe/trunk/include/clang/AST/ExprObjC.h
cfe/trunk/lib/AST/Expr.cpp
cfe/trunk/lib/Sema/SemaExprObjC.cpp
Modified: cfe/trunk/include/clang/AST/ExprObjC.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExprObjC.h?rev=52676&r1=52675&r2=52676&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ExprObjC.h (original)
+++ cfe/trunk/include/clang/AST/ExprObjC.h Tue Jun 24 10:50:53 2008
@@ -227,6 +227,9 @@
class ObjCMessageExpr : public Expr {
enum { RECEIVER=0, ARGS_START=1 };
+ // Bit-swizziling flags.
+ enum { IsInstMeth=0, IsClsMethDeclUnknown, IsClsMethDeclKnown, Flags=0x3 };
+
Stmt **SubExprs;
unsigned NumArgs;
@@ -249,12 +252,21 @@
MethodProto(NULL), LBracloc(LBrac), RBracloc(RBrac) {}
public:
- // constructor for class messages.
- // FIXME: clsName should be typed to ObjCInterfaceType
+ /// This constructor is used to represent class messages where the
+ /// ObjCInterfaceDecl* of the receiver is not known.
ObjCMessageExpr(IdentifierInfo *clsName, Selector selInfo,
QualType retType, ObjCMethodDecl *methDecl,
SourceLocation LBrac, SourceLocation RBrac,
Expr **ArgExprs, unsigned NumArgs);
+
+ /// This constructor is used to represent class messages where the
+ /// ObjCInterfaceDecl* of the receiver is known.
+ // FIXME: clsName should be typed to ObjCInterfaceType
+ ObjCMessageExpr(ObjCInterfaceDecl *cls, Selector selInfo,
+ QualType retType, ObjCMethodDecl *methDecl,
+ SourceLocation LBrac, SourceLocation RBrac,
+ Expr **ArgExprs, unsigned NumArgs);
+
// constructor for instance messages.
ObjCMessageExpr(Expr *receiver, Selector selInfo,
QualType retType, ObjCMethodDecl *methDecl,
@@ -270,7 +282,7 @@
/// class methods, use getClassName.
Expr *getReceiver() {
uintptr_t x = (uintptr_t) SubExprs[RECEIVER];
- return x & 0x1 ? NULL : (Expr*) x;
+ return (x & Flags) == IsInstMeth ? (Expr*) x : 0;
}
const Expr *getReceiver() const {
return const_cast<ObjCMessageExpr*>(this)->getReceiver();
@@ -280,16 +292,21 @@
const ObjCMethodDecl *getMethodDecl() const { return MethodProto; }
ObjCMethodDecl *getMethodDecl() { return MethodProto; }
+
+ typedef std::pair<ObjCInterfaceDecl*, IdentifierInfo*> ClassInfo;
+
+ /// getClassInfo - For class methods, this returns both the ObjCInterfaceDecl*
+ /// and IdentifierInfo* of the invoked class. Both can be NULL if this
+ /// is an instance message, and the ObjCInterfaceDecl* can be NULL if none
+ /// was available when this ObjCMessageExpr object was constructed.
+ ClassInfo getClassInfo() const;
/// getClassName - For class methods, this returns the invoked class,
/// and returns NULL otherwise. For instance methods, use getReceiver.
- IdentifierInfo *getClassName() {
- uintptr_t x = (uintptr_t) SubExprs[RECEIVER];
- return x & 0x1 ? (IdentifierInfo*) (x & ~0x1) : NULL;
- }
- const IdentifierInfo *getClassName() const {
- return const_cast<ObjCMessageExpr*>(this)->getClassName();
+ IdentifierInfo *getClassName() const {
+ return getClassInfo().second;
}
+
/// getNumArgs - Return the number of actual arguments to this call.
unsigned getNumArgs() const { return NumArgs; }
Modified: cfe/trunk/lib/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=52676&r1=52675&r2=52676&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Tue Jun 24 10:50:53 2008
@@ -1131,7 +1131,7 @@
MethodProto(mproto) {
NumArgs = nargs;
SubExprs = new Stmt*[NumArgs+1];
- SubExprs[RECEIVER] = (Expr*) ((uintptr_t) clsName | 0x1);
+ SubExprs[RECEIVER] = (Expr*) ((uintptr_t) clsName | IsClsMethDeclUnknown);
if (NumArgs) {
for (unsigned i = 0; i != NumArgs; ++i)
SubExprs[i+ARGS_START] = static_cast<Expr *>(ArgExprs[i]);
@@ -1140,6 +1140,40 @@
RBracloc = RBrac;
}
+// constructor for class messages.
+ObjCMessageExpr::ObjCMessageExpr(ObjCInterfaceDecl *cls, Selector selInfo,
+ QualType retType, ObjCMethodDecl *mproto,
+ SourceLocation LBrac, SourceLocation RBrac,
+ Expr **ArgExprs, unsigned nargs)
+: Expr(ObjCMessageExprClass, retType), SelName(selInfo),
+MethodProto(mproto) {
+ NumArgs = nargs;
+ SubExprs = new Stmt*[NumArgs+1];
+ SubExprs[RECEIVER] = (Expr*) ((uintptr_t) cls | IsClsMethDeclKnown);
+ if (NumArgs) {
+ for (unsigned i = 0; i != NumArgs; ++i)
+ SubExprs[i+ARGS_START] = static_cast<Expr *>(ArgExprs[i]);
+ }
+ LBracloc = LBrac;
+ RBracloc = RBrac;
+}
+
+ObjCMessageExpr::ClassInfo ObjCMessageExpr::getClassInfo() const {
+ uintptr_t x = (uintptr_t) SubExprs[RECEIVER];
+ switch (x & Flags) {
+ default:
+ assert(false && "Invalid ObjCMessageExpr.");
+ case IsInstMeth:
+ return ClassInfo(0, 0);
+ case IsClsMethDeclUnknown:
+ return ClassInfo(0, (IdentifierInfo*) (x & ~Flags));
+ case IsClsMethDeclKnown: {
+ ObjCInterfaceDecl* D = (ObjCInterfaceDecl*) (x & ~Flags);
+ return ClassInfo(D, D->getIdentifier());
+ }
+ }
+}
+
bool ChooseExpr::isConditionTrue(ASTContext &C) const {
llvm::APSInt CondVal(32);
bool IsConst = getCond()->isIntegerConstantExpr(CondVal, C);
Modified: cfe/trunk/lib/Sema/SemaExprObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprObjC.cpp?rev=52676&r1=52675&r2=52676&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprObjC.cpp Tue Jun 24 10:50:53 2008
@@ -202,8 +202,16 @@
return true;
}
}
- return new ObjCMessageExpr(receiverName, Sel, returnType, Method,
- lbrac, rbrac, ArgExprs, NumArgs);
+
+ // If we have the ObjCInterfaceDecl* for the class that is receiving
+ // the message, use that to construct the ObjCMessageExpr. Otherwise
+ // pass on the IdentifierInfo* for the class.
+ if (ClassDecl)
+ return new ObjCMessageExpr(ClassDecl, Sel, returnType, Method,
+ lbrac, rbrac, ArgExprs, NumArgs);
+ else
+ return new ObjCMessageExpr(receiverName, Sel, returnType, Method,
+ lbrac, rbrac, ArgExprs, NumArgs);
}
// ActOnInstanceMessage - used for both unary and keyword messages.
More information about the cfe-commits
mailing list