r266976 - Correctly parse GCC-style asm line following MS-style asm line.
Denis Zobnin via cfe-commits
cfe-commits at lists.llvm.org
Thu Apr 21 03:59:19 PDT 2016
Author: dzobnin
Date: Thu Apr 21 05:59:18 2016
New Revision: 266976
URL: http://llvm.org/viewvc/llvm-project?rev=266976&view=rev
Log:
Correctly parse GCC-style asm line following MS-style asm line.
Quit parsing MS-style inline assembly if the following statement has GCC style.
Enables compilation of code like
void f() {
__asm mov ebx, ecx
__asm__("movl %ecx, %edx");
}
Differential Revision: http://reviews.llvm.org/D18652
Added:
cfe/trunk/test/CodeGen/inline-asm-mixed-style.c (with props)
Modified:
cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
cfe/trunk/include/clang/Parse/Parser.h
cfe/trunk/lib/Parse/ParseDecl.cpp
cfe/trunk/lib/Parse/ParseStmtAsm.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=266976&r1=266975&r2=266976&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td Thu Apr 21 05:59:18 2016
@@ -27,6 +27,8 @@ def err_msasm_unable_to_create_target :
"MS-style inline assembly is not available: %0">;
def err_gnu_inline_asm_disabled : Error<
"GNU-style inline assembly is disabled">;
+def err_asm_goto_not_supported_yet : Error<
+ "'asm goto' constructs are not supported yet">;
}
let CategoryName = "Parse Issue" in {
Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=266976&r1=266975&r2=266976&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Thu Apr 21 05:59:18 2016
@@ -1873,7 +1873,6 @@ private:
bool isDeclarationSpecifier(bool DisambiguatingWithExpression = false);
bool isTypeSpecifierQualifier();
- bool isTypeQualifier() const;
/// isKnownToBeTypeSpecifier - Return true if we know that the specified token
/// is definitely a type-specifier. Return false if it isn't part of a type
Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=266976&r1=266975&r2=266976&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Thu Apr 21 05:59:18 2016
@@ -4255,27 +4255,6 @@ void Parser::ParseEnumBody(SourceLocatio
}
}
-/// isTypeSpecifierQualifier - Return true if the current token could be the
-/// start of a type-qualifier-list.
-bool Parser::isTypeQualifier() const {
- switch (Tok.getKind()) {
- default: return false;
- // type-qualifier
- case tok::kw_const:
- case tok::kw_volatile:
- case tok::kw_restrict:
- case tok::kw___private:
- case tok::kw___local:
- case tok::kw___global:
- case tok::kw___constant:
- case tok::kw___generic:
- case tok::kw___read_only:
- case tok::kw___read_write:
- case tok::kw___write_only:
- return true;
- }
-}
-
/// isKnownToBeTypeSpecifier - Return true if we know that the specified token
/// is definitely a type-specifier. Return false if it isn't part of a type
/// specifier or if we're not sure.
Modified: cfe/trunk/lib/Parse/ParseStmtAsm.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseStmtAsm.cpp?rev=266976&r1=266975&r2=266976&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseStmtAsm.cpp (original)
+++ cfe/trunk/lib/Parse/ParseStmtAsm.cpp Thu Apr 21 05:59:18 2016
@@ -335,6 +335,33 @@ static bool buildMSAsmString(Preprocesso
return false;
}
+/// isTypeQualifier - Return true if the current token could be the
+/// start of a type-qualifier-list.
+static bool isTypeQualifier(const Token &Tok) {
+ switch (Tok.getKind()) {
+ default: return false;
+ // type-qualifier
+ case tok::kw_const:
+ case tok::kw_volatile:
+ case tok::kw_restrict:
+ case tok::kw___private:
+ case tok::kw___local:
+ case tok::kw___global:
+ case tok::kw___constant:
+ case tok::kw___generic:
+ case tok::kw___read_only:
+ case tok::kw___read_write:
+ case tok::kw___write_only:
+ return true;
+ }
+}
+
+// Determine if this is a GCC-style asm statement.
+static bool isGCCAsmStatement(const Token &TokAfterAsm) {
+ return TokAfterAsm.is(tok::l_paren) || TokAfterAsm.is(tok::kw_goto) ||
+ isTypeQualifier(TokAfterAsm);
+}
+
/// ParseMicrosoftAsmStatement. When -fms-extensions/-fasm-blocks is enabled,
/// this routine is called to collect the tokens for an MS asm statement.
///
@@ -415,11 +442,11 @@ StmtResult Parser::ParseMicrosoftAsmStat
if (ExpLoc.first != FID ||
SrcMgr.getLineNumber(ExpLoc.first, ExpLoc.second) != LineNo) {
// If this is a single-line __asm, we're done, except if the next
- // line begins with an __asm too, in which case we finish a comment
+ // line is MS-style asm too, in which case we finish a comment
// if needed and then keep processing the next line as a single
// line __asm.
bool isAsm = Tok.is(tok::kw_asm);
- if (SingleLineMode && !isAsm)
+ if (SingleLineMode && (!isAsm || isGCCAsmStatement(NextToken())))
break;
// We're no longer in a comment.
InAsmComment = false;
@@ -643,8 +670,7 @@ StmtResult Parser::ParseAsmStatement(boo
assert(Tok.is(tok::kw_asm) && "Not an asm stmt");
SourceLocation AsmLoc = ConsumeToken();
- if (getLangOpts().AsmBlocks && Tok.isNot(tok::l_paren) &&
- !isTypeQualifier()) {
+ if (getLangOpts().AsmBlocks && !isGCCAsmStatement(Tok)) {
msAsm = true;
return ParseMicrosoftAsmStatement(AsmLoc);
}
@@ -664,6 +690,14 @@ StmtResult Parser::ParseAsmStatement(boo
// Remember if this was a volatile asm.
bool isVolatile = DS.getTypeQualifiers() & DeclSpec::TQ_volatile;
+
+ // TODO: support "asm goto" constructs (PR#9295).
+ if (Tok.is(tok::kw_goto)) {
+ Diag(Tok, diag::err_asm_goto_not_supported_yet);
+ SkipUntil(tok::r_paren, StopAtSemi);
+ return StmtError();
+ }
+
if (Tok.isNot(tok::l_paren)) {
Diag(Tok, diag::err_expected_lparen_after) << "asm";
SkipUntil(tok::r_paren, StopAtSemi);
Added: cfe/trunk/test/CodeGen/inline-asm-mixed-style.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/inline-asm-mixed-style.c?rev=266976&view=auto
==============================================================================
--- cfe/trunk/test/CodeGen/inline-asm-mixed-style.c (added)
+++ cfe/trunk/test/CodeGen/inline-asm-mixed-style.c Thu Apr 21 05:59:18 2016
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown -fasm-blocks -fsyntax-only -verify %s -DCHECK_ASM_GOTO
+// RUN: %clang_cc1 -triple i386-unknown-unknown -fasm-blocks -O0 -emit-llvm -S %s -o - | FileCheck %s
+
+void f() {
+ __asm mov eax, ebx
+ __asm mov ebx, ecx
+ __asm__("movl %ecx, %edx");
+ // CHECK: movl %ebx, %eax
+ // CHECK: movl %ecx, %ebx
+ // CHECK: movl %ecx, %edx
+
+ __asm mov eax, ebx
+ __asm volatile ("movl %ecx, %edx");
+ // CHECK: movl %ebx, %eax
+ // CHECK: movl %ecx, %edx
+
+ __asm mov eax, ebx
+ __asm const ("movl %ecx, %edx"); // expected-warning {{ignored const qualifier on asm}}
+ // CHECK: movl %ebx, %eax
+ // CHECK: movl %ecx, %edx
+
+#ifdef CHECK_ASM_GOTO
+ __asm volatile goto ("movl %ecx, %edx"); // expected-error {{'asm goto' constructs are not supported yet}}
+
+ __asm mov eax, ebx
+ __asm goto ("movl %ecx, %edx"); // expected-error {{'asm goto' constructs are not supported yet}}
+#endif
+}
Propchange: cfe/trunk/test/CodeGen/inline-asm-mixed-style.c
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cfe/trunk/test/CodeGen/inline-asm-mixed-style.c
------------------------------------------------------------------------------
svn:keywords = Author Date Id Rev URL
Propchange: cfe/trunk/test/CodeGen/inline-asm-mixed-style.c
------------------------------------------------------------------------------
svn:mime-type = text/plain
More information about the cfe-commits
mailing list