forked from OSchip/llvm-project
Capture a few implicit references to 'self'.
llvm-svn: 124786
This commit is contained in:
parent
f3a8860ee1
commit
5f2d556a92
|
@ -4269,6 +4269,8 @@ public:
|
|||
SourceLocation receiverNameLoc,
|
||||
SourceLocation propertyNameLoc);
|
||||
|
||||
ObjCMethodDecl *tryCaptureObjCSelf();
|
||||
|
||||
/// \brief Describes the kind of message expression indicated by a message
|
||||
/// send that starts with an identifier.
|
||||
enum ObjCMessageKind {
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "clang/Sema/SemaInternal.h"
|
||||
#include "clang/Sema/Lookup.h"
|
||||
#include "clang/Sema/Scope.h"
|
||||
#include "clang/Sema/ScopeInfo.h"
|
||||
#include "clang/Sema/Initialization.h"
|
||||
#include "clang/AST/ASTContext.h"
|
||||
#include "clang/AST/DeclObjC.h"
|
||||
|
@ -23,6 +24,7 @@
|
|||
#include "clang/Lex/Preprocessor.h"
|
||||
|
||||
using namespace clang;
|
||||
using namespace sema;
|
||||
|
||||
ExprResult Sema::ParseObjCStringLiteral(SourceLocation *AtLocs,
|
||||
Expr **strings,
|
||||
|
@ -195,6 +197,37 @@ ExprResult Sema::ParseObjCProtocolExpression(IdentifierInfo *ProtocolId,
|
|||
return new (Context) ObjCProtocolExpr(Ty, PDecl, AtLoc, RParenLoc);
|
||||
}
|
||||
|
||||
/// Try to capture an implicit reference to 'self'.
|
||||
ObjCMethodDecl *Sema::tryCaptureObjCSelf() {
|
||||
// Ignore block scopes: we can capture through them.
|
||||
DeclContext *DC = CurContext;
|
||||
while (true) {
|
||||
if (isa<BlockDecl>(DC)) DC = cast<BlockDecl>(DC)->getDeclContext();
|
||||
else if (isa<EnumDecl>(DC)) DC = cast<EnumDecl>(DC)->getDeclContext();
|
||||
else break;
|
||||
}
|
||||
|
||||
// If we're not in an ObjC method, error out. Note that, unlike the
|
||||
// C++ case, we don't require an instance method --- class methods
|
||||
// still have a 'self', and we really do still need to capture it!
|
||||
ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(DC);
|
||||
if (!method)
|
||||
return 0;
|
||||
|
||||
ImplicitParamDecl *self = method->getSelfDecl();
|
||||
assert(self && "capturing 'self' in non-definition?");
|
||||
|
||||
// Mark that we're closing on 'this' in all the block scopes, if applicable.
|
||||
for (unsigned idx = FunctionScopes.size() - 1;
|
||||
isa<BlockScopeInfo>(FunctionScopes[idx]);
|
||||
--idx)
|
||||
if (!cast<BlockScopeInfo>(FunctionScopes[idx])->Captures.insert(self))
|
||||
break;
|
||||
|
||||
return method;
|
||||
}
|
||||
|
||||
|
||||
bool Sema::CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs,
|
||||
Selector Sel, ObjCMethodDecl *Method,
|
||||
bool isClassMessage,
|
||||
|
@ -503,8 +536,8 @@ ActOnClassPropertyRefExpr(IdentifierInfo &receiverName,
|
|||
if (IFace == 0) {
|
||||
// If the "receiver" is 'super' in a method, handle it as an expression-like
|
||||
// property reference.
|
||||
if (ObjCMethodDecl *CurMethod = getCurMethodDecl())
|
||||
if (receiverNamePtr->isStr("super")) {
|
||||
if (receiverNamePtr->isStr("super")) {
|
||||
if (ObjCMethodDecl *CurMethod = tryCaptureObjCSelf()) {
|
||||
if (CurMethod->isInstanceMethod()) {
|
||||
QualType T =
|
||||
Context.getObjCInterfaceType(CurMethod->getClassInterface());
|
||||
|
@ -520,6 +553,7 @@ ActOnClassPropertyRefExpr(IdentifierInfo &receiverName,
|
|||
// superclass.
|
||||
IFace = CurMethod->getClassInterface()->getSuperClass();
|
||||
}
|
||||
}
|
||||
|
||||
if (IFace == 0) {
|
||||
Diag(receiverNameLoc, diag::err_expected_ident_or_lparen);
|
||||
|
@ -700,7 +734,7 @@ ExprResult Sema::ActOnSuperMessage(Scope *S,
|
|||
SourceLocation RBracLoc,
|
||||
MultiExprArg Args) {
|
||||
// Determine whether we are inside a method or not.
|
||||
ObjCMethodDecl *Method = getCurMethodDecl();
|
||||
ObjCMethodDecl *Method = tryCaptureObjCSelf();
|
||||
if (!Method) {
|
||||
Diag(SuperLoc, diag::err_invalid_receiver_to_message_super);
|
||||
return ExprError();
|
||||
|
|
Loading…
Reference in New Issue