nickdesaulniers updated this revision to Diff 248020.
nickdesaulniers added a comment.
- seems `arc diff` wiped out my previous changes...
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D75563/new/
https://reviews.llvm.org/D75563
Files:
clang/docs/ReleaseNotes.rst
clang/include/clang/Basic/DiagnosticParseKinds.td
clang/include/clang/Parse/Parser.h
clang/include/clang/Sema/DeclSpec.h
clang/lib/Parse/ParseStmtAsm.cpp
clang/lib/Sema/DeclSpec.cpp
clang/test/Parser/asm-qualifiers.c
Index: clang/test/Parser/asm-qualifiers.c
===================================================================
--- /dev/null
+++ clang/test/Parser/asm-qualifiers.c
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -fsyntax-only -verify %s
+
+void qualifiers(void) {
+ asm("");
+ asm volatile("");
+ asm inline("");
+ asm goto("" ::::foo);
+foo:;
+}
+
+void underscores(void) {
+ __asm__("");
+ __asm__ __volatile__("");
+ __asm__ __inline__("");
+ // Note: goto is not supported with underscore prefix+suffix.
+ __asm__ goto("" ::::foo);
+foo:;
+}
+
+void combinations(void) {
+ asm volatile inline("");
+ asm volatile goto("" ::::foo);
+ asm inline goto("" ::::foo);
+ asm volatile inline goto("" ::::foo);
+foo:;
+}
+
+void permutations(void) {
+ asm inline volatile("");
+ asm goto volatile("");
+ asm goto inline("");
+ asm inline goto volatile("" ::::foo);
+ asm inline volatile goto("" ::::foo);
+ asm goto inline volatile("" ::::foo);
+ asm goto volatile inline("" ::::foo);
+foo:;
+}
+
+void duplicates(void) {
+ asm volatile volatile(""); // expected-error {{duplicate asm qualifier volatile}}
+ __asm__ __volatile__ __volatile__(""); // expected-error {{duplicate asm qualifier volatile}}
+ asm inline inline(""); // expected-error {{duplicate asm qualifier inline}}
+ __asm__ __inline__ __inline__(""); // expected-error {{duplicate asm qualifier inline}}
+ asm goto goto("" ::::foo); // expected-error {{duplicate asm qualifier goto}}
+ __asm__ goto goto("" ::::foo); // expected-error {{duplicate asm qualifier goto}}
+foo:;
+}
Index: clang/lib/Sema/DeclSpec.cpp
===================================================================
--- clang/lib/Sema/DeclSpec.cpp
+++ clang/lib/Sema/DeclSpec.cpp
@@ -589,6 +589,16 @@
llvm_unreachable("Unknown typespec!");
}
+const char *DeclSpec::getSpecifierName(AQ A) {
+ switch (A) {
+ case DeclSpec::AQ_unspecified: return "unspecified";
+ case DeclSpec::AQ_volatile: return "volatile";
+ case DeclSpec::AQ_inline: return "inline";
+ case DeclSpec::AQ_goto: return "goto";
+ }
+ llvm_unreachable("Unknown GNUAsmQualifier!");
+}
+
bool DeclSpec::SetStorageClassSpec(Sema &S, SCS SC, SourceLocation Loc,
const char *&PrevSpec,
unsigned &DiagID,
@@ -938,6 +948,12 @@
llvm_unreachable("Unknown type qualifier!");
}
+bool DeclSpec::SetGNUAsmQual(AQ A, SourceLocation Loc) {
+ bool IsInvalid = GNUAsmQualifiers & A;
+ GNUAsmQualifiers |= A;
+ return IsInvalid;
+}
+
bool DeclSpec::setFunctionSpecInline(SourceLocation Loc, const char *&PrevSpec,
unsigned &DiagID) {
// 'inline inline' is ok. However, since this is likely not what the user
Index: clang/lib/Parse/ParseStmtAsm.cpp
===================================================================
--- clang/lib/Parse/ParseStmtAsm.cpp
+++ clang/lib/Parse/ParseStmtAsm.cpp
@@ -684,13 +684,42 @@
ClobberRefs, Exprs, EndLoc);
}
+/// ParseGNUAsmQualifierListOpt - Parse a GNU extended asm qualifier list.
+/// asm-qualifiers:
+/// volatile
+/// inline
+/// goto
+void Parser::ParseGNUAsmQualifierListOpt(DeclSpec &DS) {
+ SourceLocation EndLoc;
+ while (1) {
+ SourceLocation Loc = Tok.getLocation();
+ DeclSpec::AQ AQ = DeclSpec::AQ_unspecified;
+
+ if (Tok.getKind() == tok::kw_volatile)
+ AQ = DeclSpec::AQ_volatile;
+ else if (Tok.getKind() == tok::kw_inline)
+ AQ = DeclSpec::AQ_inline;
+ else if (Tok.getKind() == tok::kw_goto)
+ AQ = DeclSpec::AQ_goto;
+ else {
+ if (EndLoc.isValid())
+ DS.SetRangeEnd(EndLoc);
+ return;
+ }
+ if (DS.SetGNUAsmQual(AQ, Loc))
+ Diag(Loc, diag::err_asm_duplicate_qual)
+ << DeclSpec::getSpecifierName(AQ);
+ EndLoc = ConsumeToken();
+ }
+}
+
/// ParseAsmStatement - Parse a GNU extended asm statement.
/// asm-statement:
/// gnu-asm-statement
/// ms-asm-statement
///
/// [GNU] gnu-asm-statement:
-/// 'asm' type-qualifier[opt] '(' asm-argument ')' ';'
+/// 'asm' asm-qualifier[opt] '(' asm-argument ')' ';'
///
/// [GNU] asm-argument:
/// asm-string-literal
@@ -713,6 +742,7 @@
}
DeclSpec DS(AttrFactory);
+ ParseGNUAsmQualifierListOpt(DS);
SourceLocation Loc = Tok.getLocation();
ParseTypeQualifierListOpt(DS, AR_VendorAttributesParsed);
@@ -726,14 +756,9 @@
Diag(Loc, diag::warn_asm_qualifier_ignored) << "_Atomic";
// Remember if this was a volatile asm.
- bool isVolatile = DS.getTypeQualifiers() & DeclSpec::TQ_volatile;
+ bool isVolatile = DS.GetGNUAsmQual() & DeclSpec::AQ_volatile;
// Remember if this was a goto asm.
- bool isGotoAsm = false;
-
- if (Tok.is(tok::kw_goto)) {
- isGotoAsm = true;
- ConsumeToken();
- }
+ bool isGotoAsm = DS.GetGNUAsmQual() & DeclSpec::AQ_goto;
if (Tok.isNot(tok::l_paren)) {
Diag(Tok, diag::err_expected_lparen_after) << "asm";
Index: clang/include/clang/Sema/DeclSpec.h
===================================================================
--- clang/include/clang/Sema/DeclSpec.h
+++ clang/include/clang/Sema/DeclSpec.h
@@ -321,6 +321,14 @@
TQ_atomic = 16
};
+ // GNU Asm Qualifiers
+ enum AQ {
+ AQ_unspecified = 0,
+ AQ_volatile = 1,
+ AQ_inline = 2,
+ AQ_goto = 4,
+ };
+
/// ParsedSpecifiers - Flags to query which specifiers were applied. This is
/// returned by getParsedSpecifiers.
enum ParsedSpecifiers {
@@ -366,6 +374,9 @@
// constexpr-specifier
unsigned ConstexprSpecifier : 2;
+ // GNU asm specifier
+ unsigned GNUAsmQualifiers : 4;
+
union {
UnionParsedType TypeRep;
Decl *DeclRep;
@@ -543,6 +554,7 @@
static const char *getSpecifierName(DeclSpec::SCS S);
static const char *getSpecifierName(DeclSpec::TSCS S);
static const char *getSpecifierName(ConstexprSpecKind C);
+ static const char *getSpecifierName(DeclSpec::AQ A);
// type-qualifiers
@@ -566,6 +578,9 @@
TQ_pipeLoc = SourceLocation();
}
+ /// getGNUAsmQualifiers - Return a set of AQs.
+ unsigned GetGNUAsmQual() const { return GNUAsmQualifiers; }
+
// function-specifier
bool isInlineSpecified() const {
return FS_inline_specified | FS_forceinline_specified;
@@ -718,6 +733,8 @@
bool SetTypeQual(TQ T, SourceLocation Loc, const char *&PrevSpec,
unsigned &DiagID, const LangOptions &Lang);
+ bool SetGNUAsmQual(AQ A, SourceLocation Loc);
+
bool setFunctionSpecInline(SourceLocation Loc, const char *&PrevSpec,
unsigned &DiagID);
bool setFunctionSpecForceInline(SourceLocation Loc, const char *&PrevSpec,
Index: clang/include/clang/Parse/Parser.h
===================================================================
--- clang/include/clang/Parse/Parser.h
+++ clang/include/clang/Parse/Parser.h
@@ -2762,6 +2762,7 @@
DeclSpec &DS, unsigned AttrReqs = AR_AllAttributesParsed,
bool AtomicAllowed = true, bool IdentifierRequired = false,
Optional<llvm::function_ref<void()>> CodeCompletionHandler = None);
+ void ParseGNUAsmQualifierListOpt(DeclSpec &DS);
void ParseDirectDeclarator(Declarator &D);
void ParseDecompositionDeclarator(Declarator &D);
void ParseParenDeclarator(Declarator &D);
Index: clang/include/clang/Basic/DiagnosticParseKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticParseKinds.td
+++ clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -29,6 +29,7 @@
"GNU-style inline assembly is disabled">;
def err_asm_goto_cannot_have_output : Error<
"'asm goto' cannot have output constraints">;
+def err_asm_duplicate_qual : Error<"duplicate asm qualifier %0">;
}
let CategoryName = "Parse Issue" in {
Index: clang/docs/ReleaseNotes.rst
===================================================================
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -104,6 +104,9 @@
- The default C language standard used when `-std=` is not specified has been
upgraded from gnu11 to gnu17.
+- Clang now supports the GNU C extension `asm inline`; it won't do anything
+ *yet*, but it will be parsed.
+
- ...
C++ Language Changes in Clang
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits