[cfe-commits] r38929 - in /cfe/cfe/trunk: Parse/ParseStmt.cpp Parse/Parser.cpp include/clang/Basic/DiagnosticKinds.def include/clang/Parse/Parser.h
sabre at cs.uiuc.edu
sabre at cs.uiuc.edu
Wed Jul 11 09:25:53 PDT 2007
Author: sabre
Date: Wed Jul 11 11:25:52 2007
New Revision: 38929
URL: http://llvm.org/viewvc/llvm-project?rev=38929&view=rev
Log:
Implement asm statement parsing.
Modified:
cfe/cfe/trunk/Parse/ParseStmt.cpp
cfe/cfe/trunk/Parse/Parser.cpp
cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
cfe/cfe/trunk/include/clang/Parse/Parser.h
Modified: cfe/cfe/trunk/Parse/ParseStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Parse/ParseStmt.cpp?rev=38929&r1=38928&r2=38929&view=diff
==============================================================================
--- cfe/cfe/trunk/Parse/ParseStmt.cpp (original)
+++ cfe/cfe/trunk/Parse/ParseStmt.cpp Wed Jul 11 11:25:52 2007
@@ -37,7 +37,7 @@
/// [OBC] objc-throw-statement [TODO]
/// [OBC] objc-try-catch-statement [TODO]
/// [OBC] objc-synchronized-statement [TODO]
-/// [GNU] asm-statement [TODO]
+/// [GNU] asm-statement
/// [OMP] openmp-construct [TODO]
///
/// labeled-statement:
@@ -159,6 +159,11 @@
ParseReturnStatement();
SemiError = "return statement";
break;
+
+ case tok::kw_asm:
+ ParseAsmStatement();
+ SemiError = "asm statement";
+ break;
}
// If we reached this code, the statement must end in a semicolon.
@@ -543,3 +548,126 @@
SkipUntil(tok::semi, false, true);
}
}
+
+/// ParseAsmStatement - Parse a GNU extended asm statement.
+/// [GNU] asm-statement:
+/// 'asm' type-qualifier[opt] '(' asm-argument ')' ';'
+///
+/// [GNU] asm-argument:
+/// asm-string-literal
+/// asm-string-literal ':' asm-operands[opt]
+/// asm-string-literal ':' asm-operands[opt] ':' asm-operands[opt]
+/// asm-string-literal ':' asm-operands[opt] ':' asm-operands[opt]
+/// ':' asm-clobbers
+///
+/// [GNU] asm-clobbers:
+/// asm-string-literal
+/// asm-clobbers ',' asm-string-literal
+///
+void Parser::ParseAsmStatement() {
+ assert(Tok.getKind() == tok::kw_asm && "Not an asm stmt");
+ ConsumeToken();
+
+ DeclSpec DS;
+ SourceLocation Loc = Tok.getLocation();
+ ParseTypeQualifierListOpt(DS);
+
+ // GNU asms accept, but warn, about type-qualifiers other than volatile.
+ if (DS.TypeQualifiers & DeclSpec::TQ_const)
+ Diag(Loc, diag::w_asm_qualifier_ignored, "const");
+ if (DS.TypeQualifiers & DeclSpec::TQ_restrict)
+ Diag(Loc, diag::w_asm_qualifier_ignored, "restrict");
+
+ // Remember if this was a volatile asm.
+ bool isVolatile = DS.TypeQualifiers & DeclSpec::TQ_volatile;
+
+ if (Tok.getKind() != tok::l_paren) {
+ Diag(Tok, diag::err_expected_lparen_after, "asm");
+ SkipUntil(tok::r_paren);
+ return;
+ }
+ Loc = Tok.getLocation();
+ ConsumeParen();
+
+ ParseAsmStringLiteral();
+
+ // Parse Outputs, if present.
+ ParseAsmOperandsOpt();
+
+ // Parse Inputs, if present.
+ ParseAsmOperandsOpt();
+
+ // Parse the clobbers, if present.
+ if (Tok.getKind() == tok::colon) {
+ ConsumeToken();
+
+ if (Tok.getKind() == tok::string_literal) {
+ // Parse the asm-string list for clobbers.
+ while (1) {
+ ParseAsmStringLiteral();
+
+ if (Tok.getKind() != tok::comma) break;
+ ConsumeToken();
+ }
+ }
+ }
+
+ MatchRHSPunctuation(tok::r_paren, Loc);
+}
+
+/// ParseAsmOperands - Parse the asm-operands production as used by
+/// asm-statement. We also parse a leading ':' token. If the leading colon is
+/// not present, we do not parse anything.
+///
+/// [GNU] asm-operands:
+/// asm-operand
+/// asm-operands ',' asm-operand
+///
+/// [GNU] asm-operand:
+/// asm-string-literal '(' expression ')'
+/// '[' identifier ']' asm-string-literal '(' expression ')'
+///
+void Parser::ParseAsmOperandsOpt() {
+ // Only do anything if this operand is present.
+ if (Tok.getKind() != tok::colon) return;
+ ConsumeToken();
+
+ // 'asm-operands' isn't present?
+ if (Tok.getKind() != tok::string_literal && Tok.getKind() != tok::l_square)
+ return;
+
+ while (1) {
+ // Read the [id] if present.
+ if (Tok.getKind() == tok::l_square) {
+ SourceLocation Loc = Tok.getLocation();
+ ConsumeBracket();
+
+ if (Tok.getKind() != tok::identifier) {
+ Diag(Tok, diag::err_expected_ident);
+ SkipUntil(tok::r_paren);
+ return;
+ }
+ MatchRHSPunctuation(tok::r_square, Loc);
+ }
+
+ ParseAsmStringLiteral();
+
+ if (Tok.getKind() != tok::l_paren) {
+ Diag(Tok, diag::err_expected_lparen_after, "asm operand");
+ SkipUntil(tok::r_paren);
+ return;
+ }
+
+ // Read the parenthesized expression.
+ ParenParseOption ExprTy = SimpleExpr;
+ ExprResult Res = ParseParenExpression(ExprTy);
+ if (Res.isInvalid) {
+ SkipUntil(tok::r_paren);
+ return;
+ }
+
+ // Eat the comma and continue parsing if it exists.
+ if (Tok.getKind() != tok::comma) return;
+ ConsumeToken();
+ }
+}
Modified: cfe/cfe/trunk/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Parse/Parser.cpp?rev=38929&r1=38928&r2=38929&view=diff
==============================================================================
--- cfe/cfe/trunk/Parse/Parser.cpp (original)
+++ cfe/cfe/trunk/Parse/Parser.cpp Wed Jul 11 11:25:52 2007
@@ -376,12 +376,28 @@
ParseCompoundStatement();
}
+/// ParseAsmStringLiteral - This is just a normal string-literal, but is not
+/// allowed to be a wide string, and is not subject to character translation.
+///
+/// [GNU] asm-string-literal:
+/// string-literal
+///
+void Parser::ParseAsmStringLiteral() {
+ if (Tok.getKind() != tok::string_literal) {
+ Diag(Tok, diag::err_expected_string_literal);
+ return;
+ }
+
+ ExprResult Res = ParseStringLiteralExpression();
+ if (Res.isInvalid) return;
+
+ // TODO: Diagnose: wide string literal in 'asm'
+}
+
/// ParseSimpleAsm
///
/// [GNU] simple-asm-expr:
/// 'asm' '(' asm-string-literal ')'
-/// [GNU] asm-string-literal:
-/// string-literal
///
void Parser::ParseSimpleAsm() {
assert(Tok.getKind() == tok::kw_asm && "Not an asm!");
@@ -395,20 +411,7 @@
SourceLocation Loc = Tok.getLocation();
ConsumeParen();
- if (Tok.getKind() != tok::string_literal) {
- Diag(Tok, diag::err_expected_string_literal);
- SkipUntil(tok::r_paren);
- return;
- }
-
- ExprResult Res = ParseStringLiteralExpression();
- if (Res.isInvalid) {
- Diag(Tok, diag::err_expected_string_literal);
- SkipUntil(tok::r_paren);
- return;
- }
-
- // TODO: Diagnose: wide string literal in 'asm'
+ ParseAsmStringLiteral();
MatchRHSPunctuation(tok::r_paren, Loc);
}
Modified: cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=38929&r1=38928&r2=38929&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def Wed Jul 11 11:25:52 2007
@@ -238,6 +238,8 @@
"type defaults to 'int'")
DIAG(w_no_declarators, WARNING,
"declaration does not declare anything")
+DIAG(w_asm_qualifier_ignored, WARNING,
+ "ignored %s qualifier on asm")
DIAG(ext_empty_source_file, EXTENSION,
"ISO C forbids an empty source file")
@@ -330,6 +332,8 @@
"expected ':'")
DIAG(err_expected_string_literal, ERROR,
"expected string literal")
+DIAG(err_expected_asm_operand, ERROR,
+ "expected string literal or '[' for asm operand")
/// err_matching - this is used as a continuation of a previous error, e.g. to
/// specify the '(' when we expected a ')'. This should probably be some
Modified: cfe/cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Parse/Parser.h?rev=38929&r1=38928&r2=38929&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/cfe/trunk/include/clang/Parse/Parser.h Wed Jul 11 11:25:52 2007
@@ -205,6 +205,7 @@
void ParseDeclarationOrFunctionDefinition();
void ParseFunctionDefinition(Declarator &D);
void ParseSimpleAsm();
+ void ParseAsmStringLiteral();
//===--------------------------------------------------------------------===//
// C99 6.5: Expressions.
@@ -254,6 +255,8 @@
void ParseForStatement();
void ParseGotoStatement();
void ParseReturnStatement();
+ void ParseAsmStatement();
+ void ParseAsmOperandsOpt();
//===--------------------------------------------------------------------===//
// C99 6.7: Declarations.
More information about the cfe-commits
mailing list