diff --git a/clang/AST/StmtPrinter.cpp b/clang/AST/StmtPrinter.cpp index fa3eb84b5297..306bfcb18e64 100644 --- a/clang/AST/StmtPrinter.cpp +++ b/clang/AST/StmtPrinter.cpp @@ -326,7 +326,9 @@ void StmtPrinter::VisitReturnStmt(ReturnStmt *Node) { void StmtPrinter::VisitAsmStmt(AsmStmt *Node) { - Indent() << "asm (/*todo*/);\n"; + Indent() << "asm ("; + VisitStringLiteral(Node->getAsmString()); + OS << ");\n"; } void StmtPrinter::VisitObjcAtTryStmt(ObjcAtTryStmt *Node) { diff --git a/clang/AST/StmtSerialization.cpp b/clang/AST/StmtSerialization.cpp index 24733eb7ac41..f2c7834e729b 100644 --- a/clang/AST/StmtSerialization.cpp +++ b/clang/AST/StmtSerialization.cpp @@ -197,14 +197,16 @@ ArraySubscriptExpr* ArraySubscriptExpr::CreateImpl(Deserializer& D) { void AsmStmt::EmitImpl(Serializer& S) const { S.Emit(AsmLoc); + getAsmString()->EmitImpl(S); S.Emit(RParenLoc); } AsmStmt* AsmStmt::CreateImpl(Deserializer& D) { SourceLocation ALoc = SourceLocation::ReadVal(D); + StringLiteral *AsmStr = StringLiteral::CreateImpl(D); SourceLocation PLoc = SourceLocation::ReadVal(D); - return new AsmStmt(ALoc,PLoc); + return new AsmStmt(ALoc, AsmStr, PLoc); } void BinaryOperator::EmitImpl(Serializer& S) const { diff --git a/clang/Parse/ParseStmt.cpp b/clang/Parse/ParseStmt.cpp index cb2a69171905..8d5be6868cf0 100644 --- a/clang/Parse/ParseStmt.cpp +++ b/clang/Parse/ParseStmt.cpp @@ -943,8 +943,10 @@ Parser::StmtResult Parser::ParseAsmStatement() { } Loc = ConsumeParen(); - ParseAsmStringLiteral(); - + ExprResult AsmString = ParseAsmStringLiteral(); + if (AsmString.isInvalid) + return true; + // Parse Outputs, if present. ParseAsmOperandsOpt(); @@ -969,7 +971,7 @@ Parser::StmtResult Parser::ParseAsmStatement() { SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, Loc); // FIXME: Pass all the details down to the action. - return Actions.ActOnAsmStmt(AsmLoc, RParenLoc); + return Actions.ActOnAsmStmt(AsmLoc, AsmString.Val, RParenLoc); } /// ParseAsmOperands - Parse the asm-operands production as used by diff --git a/clang/Parse/Parser.cpp b/clang/Parse/Parser.cpp index b571703a3a5c..8a0d8c7ecd01 100644 --- a/clang/Parse/Parser.cpp +++ b/clang/Parse/Parser.cpp @@ -575,16 +575,18 @@ void Parser::ParseKNRParamDeclarations(Declarator &D) { /// [GNU] asm-string-literal: /// string-literal /// -void Parser::ParseAsmStringLiteral() { +Parser::ExprResult Parser::ParseAsmStringLiteral() { if (!isTokenStringLiteral()) { Diag(Tok, diag::err_expected_string_literal); - return; + return true; } ExprResult Res = ParseStringLiteralExpression(); - if (Res.isInvalid) return; + if (Res.isInvalid) return true; // TODO: Diagnose: wide string literal in 'asm' + + return Res; } /// ParseSimpleAsm diff --git a/clang/Sema/Sema.h b/clang/Sema/Sema.h index 4ed71f7388d1..78cc888f3412 100644 --- a/clang/Sema/Sema.h +++ b/clang/Sema/Sema.h @@ -346,7 +346,8 @@ public: virtual StmtResult ActOnReturnStmt(SourceLocation ReturnLoc, ExprTy *RetValExp); - virtual StmtResult ActOnAsmStmt(SourceLocation AsmLoc, + virtual StmtResult ActOnAsmStmt(SourceLocation AsmLoc, + ExprTy *AsmString, SourceLocation RParenLoc); virtual StmtResult ActOnObjcAtCatchStmt(SourceLocation AtLoc, diff --git a/clang/Sema/SemaStmt.cpp b/clang/Sema/SemaStmt.cpp index 65acf0bb14d1..ad3d2e4ee660 100644 --- a/clang/Sema/SemaStmt.cpp +++ b/clang/Sema/SemaStmt.cpp @@ -644,9 +644,12 @@ Sema::ActOnReturnStmt(SourceLocation ReturnLoc, ExprTy *rex) { return new ReturnStmt(ReturnLoc, (Expr*)RetValExp); } -Sema::StmtResult Sema::ActOnAsmStmt(SourceLocation AsmLoc, +Sema::StmtResult Sema::ActOnAsmStmt(SourceLocation AsmLoc, + ExprTy *AsmString, SourceLocation RParenLoc) { - return new AsmStmt(AsmLoc, RParenLoc); + Expr *E = (Expr *)AsmString; + + return new AsmStmt(AsmLoc, cast(E), RParenLoc); } Action::StmtResult diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h index 20344829d0ea..802c025cdbeb 100644 --- a/clang/include/clang/AST/Stmt.h +++ b/clang/include/clang/AST/Stmt.h @@ -30,6 +30,7 @@ namespace clang { class ScopedDecl; class IdentifierInfo; class SourceManager; + class StringLiteral; class SwitchStmt; class PrinterHelper; @@ -704,11 +705,17 @@ public: /// class AsmStmt : public Stmt { SourceLocation AsmLoc, RParenLoc; + StringLiteral *AsmStr; // FIXME: This doesn't capture most of the interesting pieces. public: - AsmStmt(SourceLocation asmloc, SourceLocation rparenloc) - : Stmt(AsmStmtClass), AsmLoc(asmloc), RParenLoc(rparenloc) {} + AsmStmt(SourceLocation asmloc, StringLiteral *asmstr, + SourceLocation rparenloc) + : Stmt(AsmStmtClass), AsmLoc(asmloc), RParenLoc(rparenloc), + AsmStr(asmstr) {} + const StringLiteral *getAsmString() const { return AsmStr; } + StringLiteral *getAsmString() { return AsmStr; } + virtual SourceRange getSourceRange() const { return SourceRange(AsmLoc, RParenLoc); } diff --git a/clang/include/clang/Parse/Action.h b/clang/include/clang/Parse/Action.h index 2e8b4de927b0..2da8e01149eb 100644 --- a/clang/include/clang/Parse/Action.h +++ b/clang/include/clang/Parse/Action.h @@ -286,7 +286,8 @@ public: ExprTy *RetValExp) { return 0; } - virtual StmtResult ActOnAsmStmt(SourceLocation AsmLoc, + virtual StmtResult ActOnAsmStmt(SourceLocation AsmLoc, + ExprTy *AsmString, SourceLocation RParenLoc) { return 0; } diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index 57fd4e1e790f..9d7f27e1844d 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -244,7 +244,10 @@ private: } bool SkipUntil(const tok::TokenKind *Toks, unsigned NumToks, bool StopAtSemi = true, bool DontConsume = false); - + + typedef Action::ExprResult ExprResult; + typedef Action::StmtResult StmtResult; + //===--------------------------------------------------------------------===// // C99 6.9: External Definitions. DeclTy *ParseExternalDeclaration(); @@ -252,7 +255,7 @@ private: DeclTy *ParseFunctionDefinition(Declarator &D); void ParseKNRParamDeclarations(Declarator &D); void ParseSimpleAsm(); - void ParseAsmStringLiteral(); + ExprResult ParseAsmStringLiteral(); // Objective-C External Declarations DeclTy *ParseObjCAtDirectives(); @@ -305,9 +308,6 @@ private: //===--------------------------------------------------------------------===// // C99 6.5: Expressions. - typedef Action::ExprResult ExprResult; - typedef Action::StmtResult StmtResult; - ExprResult ParseExpression(); ExprResult ParseConstantExpression(); ExprResult ParseAssignmentExpression(); // Expr that doesn't include commas.