forked from OSchip/llvm-project
Implement template instantiation for Objective-C @catch
statements. This is the last of the Objective-C statements. llvm-svn: 102356
This commit is contained in:
parent
5de7f6e02b
commit
f4e837f66c
|
@ -1726,6 +1726,8 @@ VarDecl *Sema::BuildObjCExceptionDecl(TypeSourceInfo *TInfo,
|
|||
// FIXME: Recover from "NSObject foo" by inserting the * in "NSObject *foo"?
|
||||
if (Invalid) {
|
||||
// Don't do any further checking.
|
||||
} else if (T->isDependentType()) {
|
||||
// Okay: we don't know what this type will instantiate to.
|
||||
} else if (!T->isObjCObjectPointerType()) {
|
||||
Invalid = true;
|
||||
Diag(NameLoc ,diag::err_catch_param_not_objc_type);
|
||||
|
|
|
@ -589,6 +589,11 @@ namespace {
|
|||
IdentifierInfo *Name,
|
||||
SourceLocation Loc, SourceRange TypeRange);
|
||||
|
||||
/// \brief Rebuild the Objective-C exception declaration and register the
|
||||
/// declaration as an instantiated local.
|
||||
VarDecl *RebuildObjCExceptionDecl(VarDecl *ExceptionDecl,
|
||||
TypeSourceInfo *TSInfo, QualType T);
|
||||
|
||||
/// \brief Check for tag mismatches when instantiating an
|
||||
/// elaborated type.
|
||||
QualType RebuildElaboratedType(QualType T, ElaboratedType::TagKind Tag);
|
||||
|
@ -687,7 +692,16 @@ TemplateInstantiator::RebuildExceptionDecl(VarDecl *ExceptionDecl,
|
|||
SourceRange TypeRange) {
|
||||
VarDecl *Var = inherited::RebuildExceptionDecl(ExceptionDecl, T, Declarator,
|
||||
Name, Loc, TypeRange);
|
||||
if (Var && !Var->isInvalidDecl())
|
||||
if (Var)
|
||||
getSema().CurrentInstantiationScope->InstantiatedLocal(ExceptionDecl, Var);
|
||||
return Var;
|
||||
}
|
||||
|
||||
VarDecl *TemplateInstantiator::RebuildObjCExceptionDecl(VarDecl *ExceptionDecl,
|
||||
TypeSourceInfo *TSInfo,
|
||||
QualType T) {
|
||||
VarDecl *Var = inherited::RebuildObjCExceptionDecl(ExceptionDecl, TSInfo, T);
|
||||
if (Var)
|
||||
getSema().CurrentInstantiationScope->InstantiatedLocal(ExceptionDecl, Var);
|
||||
return Var;
|
||||
}
|
||||
|
|
|
@ -901,6 +901,30 @@ public:
|
|||
move(Finally));
|
||||
}
|
||||
|
||||
/// \brief Rebuild an Objective-C exception declaration.
|
||||
///
|
||||
/// By default, performs semantic analysis to build the new declaration.
|
||||
/// Subclasses may override this routine to provide different behavior.
|
||||
VarDecl *RebuildObjCExceptionDecl(VarDecl *ExceptionDecl,
|
||||
TypeSourceInfo *TInfo, QualType T) {
|
||||
return getSema().BuildObjCExceptionDecl(TInfo, T,
|
||||
ExceptionDecl->getIdentifier(),
|
||||
ExceptionDecl->getLocation());
|
||||
}
|
||||
|
||||
/// \brief Build a new Objective-C @catch statement.
|
||||
///
|
||||
/// By default, performs semantic analysis to build the new statement.
|
||||
/// Subclasses may override this routine to provide different behavior.
|
||||
OwningStmtResult RebuildObjCAtCatchStmt(SourceLocation AtLoc,
|
||||
SourceLocation RParenLoc,
|
||||
VarDecl *Var,
|
||||
StmtArg Body) {
|
||||
return getSema().ActOnObjCAtCatchStmt(AtLoc, RParenLoc,
|
||||
Sema::DeclPtrTy::make(Var),
|
||||
move(Body));
|
||||
}
|
||||
|
||||
/// \brief Build a new Objective-C @finally statement.
|
||||
///
|
||||
/// By default, performs semantic analysis to build the new statement.
|
||||
|
@ -3722,9 +3746,37 @@ TreeTransform<Derived>::TransformObjCAtTryStmt(ObjCAtTryStmt *S) {
|
|||
template<typename Derived>
|
||||
Sema::OwningStmtResult
|
||||
TreeTransform<Derived>::TransformObjCAtCatchStmt(ObjCAtCatchStmt *S) {
|
||||
// FIXME: Implement this
|
||||
assert(false && "Cannot transform an Objective-C @catch statement");
|
||||
return SemaRef.Owned(S->Retain());
|
||||
// Transform the @catch parameter, if there is one.
|
||||
VarDecl *Var = 0;
|
||||
if (VarDecl *FromVar = S->getCatchParamDecl()) {
|
||||
TypeSourceInfo *TSInfo = 0;
|
||||
if (FromVar->getTypeSourceInfo()) {
|
||||
TSInfo = getDerived().TransformType(FromVar->getTypeSourceInfo());
|
||||
if (!TSInfo)
|
||||
return SemaRef.StmtError();
|
||||
}
|
||||
|
||||
QualType T;
|
||||
if (TSInfo)
|
||||
T = TSInfo->getType();
|
||||
else {
|
||||
T = getDerived().TransformType(FromVar->getType());
|
||||
if (T.isNull())
|
||||
return SemaRef.StmtError();
|
||||
}
|
||||
|
||||
Var = getDerived().RebuildObjCExceptionDecl(FromVar, TSInfo, T);
|
||||
if (!Var)
|
||||
return SemaRef.StmtError();
|
||||
}
|
||||
|
||||
OwningStmtResult Body = getDerived().TransformStmt(S->getCatchBody());
|
||||
if (Body.isInvalid())
|
||||
return SemaRef.StmtError();
|
||||
|
||||
return getDerived().RebuildObjCAtCatchStmt(S->getAtCatchLoc(),
|
||||
S->getRParenLoc(),
|
||||
Var, move(Body));
|
||||
}
|
||||
|
||||
template<typename Derived>
|
||||
|
|
|
@ -65,11 +65,13 @@ void try_catch_finally_test(U value) {
|
|||
@try {
|
||||
value = 1; // expected-error{{assigning to 'int *' from incompatible type 'int'}}
|
||||
}
|
||||
// FIXME: Add @catch
|
||||
@finally {
|
||||
@catch (T obj) { // expected-error{{@catch parameter is not a pointer to an interface type}}
|
||||
id x = obj;
|
||||
} @finally {
|
||||
value = 0;
|
||||
}
|
||||
}
|
||||
|
||||
template void try_catch_finally_test<NSString *>(int);
|
||||
template void try_catch_finally_test<NSString *>(int*); // expected-note{{in instantiation of}}
|
||||
template void try_catch_finally_test<NSString>(int); // expected-note{{in instantiation of function template specialization 'try_catch_finally_test<NSString, int>' requested here}}
|
||||
|
|
Loading…
Reference in New Issue