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"?
|
// FIXME: Recover from "NSObject foo" by inserting the * in "NSObject *foo"?
|
||||||
if (Invalid) {
|
if (Invalid) {
|
||||||
// Don't do any further checking.
|
// 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()) {
|
} else if (!T->isObjCObjectPointerType()) {
|
||||||
Invalid = true;
|
Invalid = true;
|
||||||
Diag(NameLoc ,diag::err_catch_param_not_objc_type);
|
Diag(NameLoc ,diag::err_catch_param_not_objc_type);
|
||||||
|
|
|
@ -589,6 +589,11 @@ namespace {
|
||||||
IdentifierInfo *Name,
|
IdentifierInfo *Name,
|
||||||
SourceLocation Loc, SourceRange TypeRange);
|
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
|
/// \brief Check for tag mismatches when instantiating an
|
||||||
/// elaborated type.
|
/// elaborated type.
|
||||||
QualType RebuildElaboratedType(QualType T, ElaboratedType::TagKind Tag);
|
QualType RebuildElaboratedType(QualType T, ElaboratedType::TagKind Tag);
|
||||||
|
@ -687,7 +692,16 @@ TemplateInstantiator::RebuildExceptionDecl(VarDecl *ExceptionDecl,
|
||||||
SourceRange TypeRange) {
|
SourceRange TypeRange) {
|
||||||
VarDecl *Var = inherited::RebuildExceptionDecl(ExceptionDecl, T, Declarator,
|
VarDecl *Var = inherited::RebuildExceptionDecl(ExceptionDecl, T, Declarator,
|
||||||
Name, Loc, TypeRange);
|
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);
|
getSema().CurrentInstantiationScope->InstantiatedLocal(ExceptionDecl, Var);
|
||||||
return Var;
|
return Var;
|
||||||
}
|
}
|
||||||
|
|
|
@ -901,6 +901,30 @@ public:
|
||||||
move(Finally));
|
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.
|
/// \brief Build a new Objective-C @finally statement.
|
||||||
///
|
///
|
||||||
/// By default, performs semantic analysis to build the new statement.
|
/// By default, performs semantic analysis to build the new statement.
|
||||||
|
@ -3722,9 +3746,37 @@ TreeTransform<Derived>::TransformObjCAtTryStmt(ObjCAtTryStmt *S) {
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
Sema::OwningStmtResult
|
Sema::OwningStmtResult
|
||||||
TreeTransform<Derived>::TransformObjCAtCatchStmt(ObjCAtCatchStmt *S) {
|
TreeTransform<Derived>::TransformObjCAtCatchStmt(ObjCAtCatchStmt *S) {
|
||||||
// FIXME: Implement this
|
// Transform the @catch parameter, if there is one.
|
||||||
assert(false && "Cannot transform an Objective-C @catch statement");
|
VarDecl *Var = 0;
|
||||||
return SemaRef.Owned(S->Retain());
|
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>
|
template<typename Derived>
|
||||||
|
|
|
@ -65,11 +65,13 @@ void try_catch_finally_test(U value) {
|
||||||
@try {
|
@try {
|
||||||
value = 1; // expected-error{{assigning to 'int *' from incompatible type 'int'}}
|
value = 1; // expected-error{{assigning to 'int *' from incompatible type 'int'}}
|
||||||
}
|
}
|
||||||
// FIXME: Add @catch
|
@catch (T obj) { // expected-error{{@catch parameter is not a pointer to an interface type}}
|
||||||
@finally {
|
id x = obj;
|
||||||
|
} @finally {
|
||||||
value = 0;
|
value = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template void try_catch_finally_test<NSString *>(int);
|
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}}
|
||||||
|
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