From: Anders Carlsson Date: Tue, 5 Feb 2008 23:03:50 +0000 (+0000) Subject: Handle simple asm statements correctly. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=dfab34a696d1dba8622248c31aaf605906cb6109;p=clang Handle simple asm statements correctly. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@46777 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/AST/Stmt.cpp b/AST/Stmt.cpp index 249794db59..572280bc05 100644 --- a/AST/Stmt.cpp +++ b/AST/Stmt.cpp @@ -115,13 +115,14 @@ bool Stmt::hasImplicitControlFlow() const { // Constructors //===----------------------------------------------------------------------===// -AsmStmt::AsmStmt(SourceLocation asmloc, bool isvolatile, +AsmStmt::AsmStmt(SourceLocation asmloc, bool issimple, bool isvolatile, unsigned numoutputs, unsigned numinputs, std::string *names, StringLiteral **constraints, Expr **exprs, StringLiteral *asmstr, unsigned numclobbers, StringLiteral **clobbers, SourceLocation rparenloc) : Stmt(AsmStmtClass), AsmLoc(asmloc), RParenLoc(rparenloc), AsmStr(asmstr) - , IsVolatile(isvolatile), NumOutputs(numoutputs), NumInputs(numinputs) { + , IsSimple(issimple), IsVolatile(isvolatile) + , NumOutputs(numoutputs), NumInputs(numinputs) { for (unsigned i = 0, e = numinputs + numoutputs; i != e; i++) { Names.push_back(names[i]); Exprs.push_back(exprs[i]); diff --git a/AST/StmtSerialization.cpp b/AST/StmtSerialization.cpp index 9a03a5320f..f075e1c12d 100644 --- a/AST/StmtSerialization.cpp +++ b/AST/StmtSerialization.cpp @@ -229,6 +229,7 @@ void AsmStmt::EmitImpl(Serializer& S) const { S.Emit(RParenLoc); S.EmitBool(IsVolatile); + S.EmitBool(IsSimple); S.EmitInt(NumOutputs); S.EmitInt(NumInputs); @@ -254,7 +255,8 @@ AsmStmt* AsmStmt::CreateImpl(Deserializer& D) { SourceLocation PLoc = SourceLocation::ReadVal(D); bool IsVolatile = D.ReadBool(); - AsmStmt *Stmt = new AsmStmt(ALoc, IsVolatile, 0, 0, 0, 0, 0, + bool IsSimple = D.ReadBool(); + AsmStmt *Stmt = new AsmStmt(ALoc, IsSimple, IsVolatile, 0, 0, 0, 0, 0, AsmStr, 0, 0, PLoc); diff --git a/Parse/ParseStmt.cpp b/Parse/ParseStmt.cpp index b6cd558b04..a074463f3c 100644 --- a/Parse/ParseStmt.cpp +++ b/Parse/ParseStmt.cpp @@ -939,7 +939,7 @@ Parser::StmtResult Parser::ParseAsmStatement() { // Remember if this was a volatile asm. bool isVolatile = DS.getTypeQualifiers() & DeclSpec::TQ_volatile; - + bool isSimple = false; if (Tok.isNot(tok::l_paren)) { Diag(Tok, diag::err_expected_lparen_after, "asm"); SkipUntil(tok::r_paren); @@ -954,43 +954,53 @@ Parser::StmtResult Parser::ParseAsmStatement() { llvm::SmallVector Names; llvm::SmallVector Constraints; llvm::SmallVector Exprs; + llvm::SmallVector Clobbers; + + unsigned NumInputs = 0, NumOutputs = 0; - // Parse Outputs, if present. - ParseAsmOperandsOpt(Names, Constraints, Exprs); + SourceLocation RParenLoc; + if (Tok.is(tok::r_paren)) { + // We have a simple asm expression + isSimple = true; + + RParenLoc = ConsumeParen(); + } else { + // Parse Outputs, if present. + ParseAsmOperandsOpt(Names, Constraints, Exprs); - unsigned NumOutputs = Names.size(); + NumOutputs = Names.size(); - // Parse Inputs, if present. - ParseAsmOperandsOpt(Names, Constraints, Exprs); - assert(Names.size() == Constraints.size() && - Constraints.size() == Exprs.size() - && "Input operand size mismatch!"); + // Parse Inputs, if present. + ParseAsmOperandsOpt(Names, Constraints, Exprs); + assert(Names.size() == Constraints.size() && + Constraints.size() == Exprs.size() + && "Input operand size mismatch!"); - unsigned NumInputs = Names.size() - NumOutputs; - - llvm::SmallVector Clobbers; + NumInputs = Names.size() - NumOutputs; - // Parse the clobbers, if present. - if (Tok.is(tok::colon)) { - ConsumeToken(); + // Parse the clobbers, if present. + if (Tok.is(tok::colon)) { + ConsumeToken(); - // Parse the asm-string list for clobbers. - while (1) { - ExprResult Clobber = ParseAsmStringLiteral(); + // Parse the asm-string list for clobbers. + while (1) { + ExprResult Clobber = ParseAsmStringLiteral(); - if (Clobber.isInvalid) - break; + if (Clobber.isInvalid) + break; - Clobbers.push_back(Clobber.Val); + Clobbers.push_back(Clobber.Val); - if (Tok.isNot(tok::comma)) break; - ConsumeToken(); + if (Tok.isNot(tok::comma)) break; + ConsumeToken(); + } } - } - SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, Loc); + RParenLoc = MatchRHSPunctuation(tok::r_paren, Loc); + } - return Actions.ActOnAsmStmt(AsmLoc, isVolatile, NumOutputs, NumInputs, + return Actions.ActOnAsmStmt(AsmLoc, isSimple, isVolatile, + NumOutputs, NumInputs, &Names[0], &Constraints[0], &Exprs[0], AsmString.Val, Clobbers.size(), &Clobbers[0], diff --git a/Sema/Sema.h b/Sema/Sema.h index ecd5ffd2c9..3b463eb407 100644 --- a/Sema/Sema.h +++ b/Sema/Sema.h @@ -361,6 +361,7 @@ public: ExprTy *RetValExp); virtual StmtResult ActOnAsmStmt(SourceLocation AsmLoc, + bool IsSimple, bool IsVolatile, unsigned NumOutputs, unsigned NumInputs, diff --git a/Sema/SemaStmt.cpp b/Sema/SemaStmt.cpp index c84b3f344f..1c84771762 100644 --- a/Sema/SemaStmt.cpp +++ b/Sema/SemaStmt.cpp @@ -668,6 +668,7 @@ Sema::ActOnReturnStmt(SourceLocation ReturnLoc, ExprTy *rex) { } Sema::StmtResult Sema::ActOnAsmStmt(SourceLocation AsmLoc, + bool IsSimple, bool IsVolatile, unsigned NumOutputs, unsigned NumInputs, @@ -765,6 +766,7 @@ Sema::StmtResult Sema::ActOnAsmStmt(SourceLocation AsmLoc, } return new AsmStmt(AsmLoc, + IsSimple, IsVolatile, NumOutputs, NumInputs, diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h index 8ea6f1edbf..dae7fbf49b 100644 --- a/include/clang/AST/Stmt.h +++ b/include/clang/AST/Stmt.h @@ -755,6 +755,7 @@ class AsmStmt : public Stmt { SourceLocation AsmLoc, RParenLoc; StringLiteral *AsmStr; + bool IsSimple; bool IsVolatile; unsigned NumOutputs; @@ -766,13 +767,15 @@ class AsmStmt : public Stmt { llvm::SmallVector Clobbers; public: - AsmStmt(SourceLocation asmloc, bool isvolatile, unsigned numoutputs, - unsigned numinputs, std::string *names, StringLiteral **constraints, + AsmStmt(SourceLocation asmloc, bool issimple, bool isvolatile, + unsigned numoutputs, unsigned numinputs, + std::string *names, StringLiteral **constraints, Expr **exprs, StringLiteral *asmstr, unsigned numclobbers, StringLiteral **clobbers, SourceLocation rparenloc); bool isVolatile() const { return IsVolatile; } - + bool isSimple() const { return IsSimple; } + unsigned getNumOutputs() const { return NumOutputs; } const std::string &getOutputName(unsigned i) const { return Names[i]; } diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h index ce4781b91a..7a2081978d 100644 --- a/include/clang/Parse/Action.h +++ b/include/clang/Parse/Action.h @@ -299,6 +299,7 @@ public: return 0; } virtual StmtResult ActOnAsmStmt(SourceLocation AsmLoc, + bool IsSimple, bool IsVolatile, unsigned NumOutputs, unsigned NumInputs,