forked from OSchip/llvm-project
Template instantiation for IndirectGotoStmt. Now my life is complete.
llvm-svn: 71917
This commit is contained in:
parent
2a2d00f041
commit
30776d419f
|
@ -840,10 +840,13 @@ public:
|
|||
///
|
||||
class IndirectGotoStmt : public Stmt {
|
||||
SourceLocation GotoLoc;
|
||||
SourceLocation StarLoc;
|
||||
Stmt *Target;
|
||||
public:
|
||||
IndirectGotoStmt(SourceLocation gotoLoc, Expr *target)
|
||||
: Stmt(IndirectGotoStmtClass), GotoLoc(gotoLoc), Target((Stmt*)target) {}
|
||||
IndirectGotoStmt(SourceLocation gotoLoc, SourceLocation starLoc,
|
||||
Expr *target)
|
||||
: Stmt(IndirectGotoStmtClass), GotoLoc(gotoLoc), StarLoc(starLoc),
|
||||
Target((Stmt*)target) {}
|
||||
|
||||
/// \brief Build an empty indirect goto statement.
|
||||
explicit IndirectGotoStmt(EmptyShell Empty)
|
||||
|
@ -851,6 +854,8 @@ public:
|
|||
|
||||
void setGotoLoc(SourceLocation L) { GotoLoc = L; }
|
||||
SourceLocation getGotoLoc() const { return GotoLoc; }
|
||||
void setStarLoc(SourceLocation L) { StarLoc = L; }
|
||||
SourceLocation getStarLoc() const { return StarLoc; }
|
||||
|
||||
Expr *getTarget();
|
||||
const Expr *getTarget() const;
|
||||
|
|
|
@ -236,6 +236,7 @@ unsigned PCHStmtReader::VisitGotoStmt(GotoStmt *S) {
|
|||
unsigned PCHStmtReader::VisitIndirectGotoStmt(IndirectGotoStmt *S) {
|
||||
VisitStmt(S);
|
||||
S->setGotoLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
|
||||
S->setStarLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
|
||||
S->setTarget(cast_or_null<Expr>(StmtStack.back()));
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -223,6 +223,7 @@ void PCHStmtWriter::VisitGotoStmt(GotoStmt *S) {
|
|||
void PCHStmtWriter::VisitIndirectGotoStmt(IndirectGotoStmt *S) {
|
||||
VisitStmt(S);
|
||||
Writer.AddSourceLocation(S->getGotoLoc(), Record);
|
||||
Writer.AddSourceLocation(S->getStarLoc(), Record);
|
||||
Writer.WriteSubStmt(S->getTarget());
|
||||
Code = pch::STMT_INDIRECT_GOTO;
|
||||
}
|
||||
|
|
|
@ -706,13 +706,15 @@ Sema::ActOnIndirectGotoStmt(SourceLocation GotoLoc, SourceLocation StarLoc,
|
|||
ExprArg DestExp) {
|
||||
// Convert operand to void*
|
||||
Expr* E = DestExp.takeAs<Expr>();
|
||||
QualType ETy = E->getType();
|
||||
AssignConvertType ConvTy =
|
||||
CheckSingleAssignmentConstraints(Context.VoidPtrTy, E);
|
||||
if (DiagnoseAssignmentResult(ConvTy, StarLoc, Context.VoidPtrTy, ETy,
|
||||
E, "passing"))
|
||||
return StmtError();
|
||||
return Owned(new (Context) IndirectGotoStmt(GotoLoc, E));
|
||||
if (!E->isTypeDependent()) {
|
||||
QualType ETy = E->getType();
|
||||
AssignConvertType ConvTy =
|
||||
CheckSingleAssignmentConstraints(Context.VoidPtrTy, E);
|
||||
if (DiagnoseAssignmentResult(ConvTy, StarLoc, Context.VoidPtrTy, ETy,
|
||||
E, "passing"))
|
||||
return StmtError();
|
||||
}
|
||||
return Owned(new (Context) IndirectGotoStmt(GotoLoc, StarLoc, E));
|
||||
}
|
||||
|
||||
Action::OwningStmtResult
|
||||
|
|
|
@ -49,6 +49,7 @@ namespace {
|
|||
OwningStmtResult VisitExpr(Expr *E);
|
||||
OwningStmtResult VisitLabelStmt(LabelStmt *S);
|
||||
OwningStmtResult VisitGotoStmt(GotoStmt *S);
|
||||
OwningStmtResult VisitIndirectGotoStmt(IndirectGotoStmt *S);
|
||||
OwningStmtResult VisitBreakStmt(BreakStmt *S);
|
||||
OwningStmtResult VisitContinueStmt(ContinueStmt *S);
|
||||
OwningStmtResult VisitReturnStmt(ReturnStmt *S);
|
||||
|
@ -104,6 +105,17 @@ Sema::OwningStmtResult TemplateStmtInstantiator::VisitGotoStmt(GotoStmt *S) {
|
|||
S->getLabel()->getID());
|
||||
}
|
||||
|
||||
Sema::OwningStmtResult
|
||||
TemplateStmtInstantiator::VisitIndirectGotoStmt(IndirectGotoStmt *S) {
|
||||
OwningExprResult Target = SemaRef.InstantiateExpr(S->getTarget(),
|
||||
TemplateArgs);
|
||||
if (Target.isInvalid())
|
||||
return SemaRef.StmtError();
|
||||
|
||||
return SemaRef.ActOnIndirectGotoStmt(S->getGotoLoc(), S->getStarLoc(),
|
||||
move(Target));
|
||||
}
|
||||
|
||||
Sema::OwningStmtResult TemplateStmtInstantiator::VisitBreakStmt(BreakStmt *S) {
|
||||
return SemaRef.Owned(S->Clone(SemaRef.Context));
|
||||
}
|
||||
|
|
|
@ -170,3 +170,13 @@ template<typename T, int I1, int I2> struct Switch1 {
|
|||
|
||||
template struct Switch1<int, 1, 2>;
|
||||
template struct Switch1<int, 2, 2>; // expected-note{{instantiation}}
|
||||
|
||||
template<typename T> struct IndirectGoto0 {
|
||||
void f(T x) {
|
||||
// FIXME: crummy error message below
|
||||
goto *x; // expected-error{{incompatible}}
|
||||
}
|
||||
};
|
||||
|
||||
template struct IndirectGoto0<void*>;
|
||||
template struct IndirectGoto0<int>; // expected-note{{instantiation}}
|
||||
|
|
Loading…
Reference in New Issue