diff --git a/clang/Driver/PrintParserCallbacks.cpp b/clang/Driver/PrintParserCallbacks.cpp index 126e8ed06ac9..aba91815b17c 100644 --- a/clang/Driver/PrintParserCallbacks.cpp +++ b/clang/Driver/PrintParserCallbacks.cpp @@ -365,22 +365,21 @@ namespace { llvm::cout << __FUNCTION__ << "\n"; return StmtEmpty(); } - virtual StmtResult ActOnAsmStmt(SourceLocation AsmLoc, - bool IsSimple, - bool IsVolatile, - unsigned NumOutputs, - unsigned NumInputs, - std::string *Names, - ExprTy **Constraints, - ExprTy **Exprs, - ExprTy *AsmString, - unsigned NumClobbers, - ExprTy **Clobbers, - SourceLocation RParenLoc) { + virtual OwningStmtResult ActOnAsmStmt(SourceLocation AsmLoc, + bool IsSimple, + bool IsVolatile, + unsigned NumOutputs, + unsigned NumInputs, + std::string *Names, + MultiExprArg Constraints, + MultiExprArg Exprs, + ExprArg AsmString, + MultiExprArg Clobbers, + SourceLocation RParenLoc) { llvm::cout << __FUNCTION__ << "\n"; - return 0; + return StmtEmpty(); } - + // Objective-c statements virtual StmtResult ActOnObjCAtCatchStmt(SourceLocation AtLoc, SourceLocation RParen, StmtTy *Parm, diff --git a/clang/include/clang/Parse/Action.h b/clang/include/clang/Parse/Action.h index f47021ac5fd3..311c381a928b 100644 --- a/clang/include/clang/Parse/Action.h +++ b/clang/include/clang/Parse/Action.h @@ -459,21 +459,20 @@ public: ExprArg RetValExp) { return StmtEmpty(); } - virtual StmtResult ActOnAsmStmt(SourceLocation AsmLoc, - bool IsSimple, - bool IsVolatile, - unsigned NumOutputs, - unsigned NumInputs, - std::string *Names, - ExprTy **Constraints, - ExprTy **Exprs, - ExprTy *AsmString, - unsigned NumClobbers, - ExprTy **Clobbers, - SourceLocation RParenLoc) { - return 0; + virtual OwningStmtResult ActOnAsmStmt(SourceLocation AsmLoc, + bool IsSimple, + bool IsVolatile, + unsigned NumOutputs, + unsigned NumInputs, + std::string *Names, + MultiExprArg Constraints, + MultiExprArg Exprs, + ExprArg AsmString, + MultiExprArg Clobbers, + SourceLocation RParenLoc) { + return StmtEmpty(); } - + // Objective-c statements virtual StmtResult ActOnObjCAtCatchStmt(SourceLocation AtLoc, SourceLocation RParen, StmtTy *Parm, diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp index 9ddd26a8b3ce..6ca577347ddd 100644 --- a/clang/lib/Parse/ParseStmt.cpp +++ b/clang/lib/Parse/ParseStmt.cpp @@ -1155,12 +1155,11 @@ Parser::OwningStmtResult Parser::ParseAsmStatement(bool &msAsm) { RParenLoc = MatchRHSPunctuation(tok::r_paren, Loc); } - return Owned(Actions.ActOnAsmStmt(AsmLoc, isSimple, isVolatile, - NumOutputs, NumInputs, - &Names[0], Constraints.take(), - Exprs.take(), AsmString.release(), - Clobbers.size(), Clobbers.take(), - RParenLoc)); + return Actions.ActOnAsmStmt(AsmLoc, isSimple, isVolatile, + NumOutputs, NumInputs, &Names[0], + move_convert(Constraints), move_convert(Exprs), + move_convert(AsmString), move_convert(Clobbers), + RParenLoc); } /// ParseAsmOperands - Parse the asm-operands production as used by diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 16c2f2f57efb..ef69ec24a791 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -901,18 +901,17 @@ public: OwningStmtResult ActOnBlockReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp); - virtual StmtResult ActOnAsmStmt(SourceLocation AsmLoc, - bool IsSimple, - bool IsVolatile, - unsigned NumOutputs, - unsigned NumInputs, - std::string *Names, - ExprTy **Constraints, - ExprTy **Exprs, - ExprTy *AsmString, - unsigned NumClobbers, - ExprTy **Clobbers, - SourceLocation RParenLoc); + virtual OwningStmtResult ActOnAsmStmt(SourceLocation AsmLoc, + bool IsSimple, + bool IsVolatile, + unsigned NumOutputs, + unsigned NumInputs, + std::string *Names, + MultiExprArg Constraints, + MultiExprArg Exprs, + ExprArg AsmString, + MultiExprArg Clobbers, + SourceLocation RParenLoc); virtual StmtResult ActOnObjCAtCatchStmt(SourceLocation AtLoc, SourceLocation RParen, StmtTy *Parm, diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index f143c5bfdccf..23f21c7a6a88 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -831,112 +831,108 @@ Sema::ActOnReturnStmt(SourceLocation ReturnLoc, ExprArg rex) { return Owned(new ReturnStmt(ReturnLoc, RetValExp)); } -Sema::StmtResult Sema::ActOnAsmStmt(SourceLocation AsmLoc, - bool IsSimple, - bool IsVolatile, - unsigned NumOutputs, - unsigned NumInputs, - std::string *Names, - ExprTy **constraints, - ExprTy **exprs, - ExprTy *asmString, - unsigned NumClobbers, - ExprTy **clobbers, - SourceLocation RParenLoc) { - StringLiteral **Constraints = reinterpret_cast(constraints); - Expr **Exprs = reinterpret_cast(exprs); - StringLiteral *AsmString = cast((Expr *)asmString); - StringLiteral **Clobbers = reinterpret_cast(clobbers); - +Sema::OwningStmtResult Sema::ActOnAsmStmt(SourceLocation AsmLoc, + bool IsSimple, + bool IsVolatile, + unsigned NumOutputs, + unsigned NumInputs, + std::string *Names, + MultiExprArg constraints, + MultiExprArg exprs, + ExprArg asmString, + MultiExprArg clobbers, + SourceLocation RParenLoc) { + unsigned NumClobbers = clobbers.size(); + StringLiteral **Constraints = + reinterpret_cast(constraints.get()); + Expr **Exprs = reinterpret_cast(exprs.get()); + StringLiteral *AsmString = cast((Expr *)asmString.get()); + StringLiteral **Clobbers = reinterpret_cast(clobbers.get()); + // The parser verifies that there is a string literal here. if (AsmString->isWide()) - // FIXME: We currently leak memory here. - return Diag(AsmString->getLocStart(), diag::err_asm_wide_character) - << AsmString->getSourceRange(); - - + return StmtError(Diag(AsmString->getLocStart(),diag::err_asm_wide_character) + << AsmString->getSourceRange()); + + for (unsigned i = 0; i != NumOutputs; i++) { StringLiteral *Literal = Constraints[i]; if (Literal->isWide()) - // FIXME: We currently leak memory here. - return Diag(Literal->getLocStart(), diag::err_asm_wide_character) - << Literal->getSourceRange(); - + return StmtError(Diag(Literal->getLocStart(),diag::err_asm_wide_character) + << Literal->getSourceRange()); + std::string OutputConstraint(Literal->getStrData(), Literal->getByteLength()); - + TargetInfo::ConstraintInfo info; if (!Context.Target.validateOutputConstraint(OutputConstraint.c_str(),info)) - // FIXME: We currently leak memory here. - return Diag(Literal->getLocStart(), - diag::err_asm_invalid_output_constraint) << OutputConstraint; - + return StmtError(Diag(Literal->getLocStart(), + diag::err_asm_invalid_output_constraint) << OutputConstraint); + // Check that the output exprs are valid lvalues. ParenExpr *OutputExpr = cast(Exprs[i]); Expr::isLvalueResult Result = OutputExpr->isLvalue(Context); if (Result != Expr::LV_Valid) { - // FIXME: We currently leak memory here. - return Diag(OutputExpr->getSubExpr()->getLocStart(), + return StmtError(Diag(OutputExpr->getSubExpr()->getLocStart(), diag::err_asm_invalid_lvalue_in_output) - << OutputExpr->getSubExpr()->getSourceRange(); + << OutputExpr->getSubExpr()->getSourceRange()); } } - + for (unsigned i = NumOutputs, e = NumOutputs + NumInputs; i != e; i++) { StringLiteral *Literal = Constraints[i]; if (Literal->isWide()) - // FIXME: We currently leak memory here. - return Diag(Literal->getLocStart(), diag::err_asm_wide_character) - << Literal->getSourceRange(); - - std::string InputConstraint(Literal->getStrData(), + return StmtError(Diag(Literal->getLocStart(),diag::err_asm_wide_character) + << Literal->getSourceRange()); + + std::string InputConstraint(Literal->getStrData(), Literal->getByteLength()); - + TargetInfo::ConstraintInfo info; if (!Context.Target.validateInputConstraint(InputConstraint.c_str(), &Names[0], &Names[0] + NumOutputs, info)) { - // FIXME: We currently leak memory here. - return Diag(Literal->getLocStart(), - diag::err_asm_invalid_input_constraint) << InputConstraint; + return StmtError(Diag(Literal->getLocStart(), + diag::err_asm_invalid_input_constraint) << InputConstraint); } - + // Check that the input exprs aren't of type void. ParenExpr *InputExpr = cast(Exprs[i]); if (InputExpr->getType()->isVoidType()) { - - // FIXME: We currently leak memory here. - return Diag(InputExpr->getSubExpr()->getLocStart(), + + return StmtError(Diag(InputExpr->getSubExpr()->getLocStart(), diag::err_asm_invalid_type_in_input) << InputExpr->getType() << InputConstraint - << InputExpr->getSubExpr()->getSourceRange(); + << InputExpr->getSubExpr()->getSourceRange()); } - + if (info & TargetInfo::CI_AllowsRegister) DefaultFunctionArrayConversion(Exprs[i]); } - + // Check that the clobbers are valid. for (unsigned i = 0; i != NumClobbers; i++) { StringLiteral *Literal = Clobbers[i]; if (Literal->isWide()) - // FIXME: We currently leak memory here. - return Diag(Literal->getLocStart(), diag::err_asm_wide_character) - << Literal->getSourceRange(); - - llvm::SmallString<16> Clobber(Literal->getStrData(), - Literal->getStrData() + + return StmtError(Diag(Literal->getLocStart(),diag::err_asm_wide_character) + << Literal->getSourceRange()); + + llvm::SmallString<16> Clobber(Literal->getStrData(), + Literal->getStrData() + Literal->getByteLength()); - + if (!Context.Target.isValidGCCRegisterName(Clobber.c_str())) - // FIXME: We currently leak memory here. - return Diag(Literal->getLocStart(), - diag::err_asm_unknown_register_name) << Clobber.c_str(); + return StmtError(Diag(Literal->getLocStart(), + diag::err_asm_unknown_register_name) << Clobber.c_str()); } - - return new AsmStmt(AsmLoc, IsSimple, IsVolatile, NumOutputs, NumInputs, - Names, Constraints, Exprs, AsmString, NumClobbers, - Clobbers, RParenLoc); + + constraints.release(); + exprs.release(); + asmString.release(); + clobbers.release(); + return Owned(new AsmStmt(AsmLoc, IsSimple, IsVolatile, NumOutputs, NumInputs, + Names, Constraints, Exprs, AsmString, NumClobbers, + Clobbers, RParenLoc)); } Action::StmtResult