[PATCH] Recognize __unaligned in more cases
Nico Rieck
nico.rieck at gmail.com
Mon Nov 24 09:43:14 PST 2014
The __unaligned keyword is currently only parsed in simple typedefs
like:
typedef int __unaligned* foo;
But it can also appear after a struct definition:
struct foo {...} __unaligned *x;
and after the comma in declarator lists:
typedef int foo, __unaligned *bar;
Both cases appear in current Windows SDK headers.
Note: Specifying type qualifiers after the comma, as in the latter case,
is a Microsoft extension. This patch only recognizes __unaligned.
--Nico
-------------- next part --------------
From d2f935b82a96d31a113124f2fa9feccda38d981e Mon Sep 17 00:00:00 2001
From: Nico Rieck <nico.rieck at gmail.com>
Date: Sun, 23 Nov 2014 18:32:40 +0100
Subject: [PATCH] Recognize __unaligned in more cases
The __unaligned keyword can appear after a struct definition:
struct foo {...} __unaligned *x;
and after the comma in declarator lists:
typedef int foo, __unaligned *bar;
Note: Specifying type qualifiers after the comma is a Microsoft extension.
---
lib/Parse/ParseDecl.cpp | 12 ++++++++++++
lib/Parse/ParseDeclCXX.cpp | 1 +
test/SemaCXX/MicrosoftExtensions.cpp | 2 ++
3 files changed, 15 insertions(+)
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index fbf3337..bb07bd5 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -1732,6 +1732,18 @@ Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS,
// short x, __attribute__((common)) var; -> declarator
MaybeParseGNUAttributes(D);
+ // [MS] Type qualifiers after the comma is a Microsoft extensions. Currently
+ // only __unaligned is parsed to support:
+ // typedef struct { ... } X, __unaligned *PX;
+ if (Tok.is(tok::kw___unaligned)) {
+ IdentifierInfo *AttrName = Tok.getIdentifierInfo();
+ SourceLocation AttrNameLoc = ConsumeToken();
+ ParsedAttributes attrs(AttrFactory);
+ attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0,
+ AttributeList::AS_Keyword);
+ D.takeAttributes(attrs, AttrNameLoc);
+ }
+
ParseDeclarator(D);
if (!D.isInvalidType()) {
Decl *ThisDecl = ParseDeclarationAfterDeclarator(D);
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp
index 79ae878..85f6303 100644
--- a/lib/Parse/ParseDeclCXX.cpp
+++ b/lib/Parse/ParseDeclCXX.cpp
@@ -1095,6 +1095,7 @@ bool Parser::isValidAfterTypeSpecifier(bool CouldBeBitfield) {
case tok::kw_volatile: // struct foo {...} volatile x;
case tok::kw_restrict: // struct foo {...} restrict x;
case tok::kw__Atomic: // struct foo {...} _Atomic x;
+ case tok::kw___unaligned: // struct foo {...} __unaligned *x;
// Function specifiers
// Note, no 'explicit'. An explicit function must be either a conversion
// operator or a constructor. Either way, it can't have a return type.
diff --git a/test/SemaCXX/MicrosoftExtensions.cpp b/test/SemaCXX/MicrosoftExtensions.cpp
index ec3dfce..ab03434 100644
--- a/test/SemaCXX/MicrosoftExtensions.cpp
+++ b/test/SemaCXX/MicrosoftExtensions.cpp
@@ -79,6 +79,8 @@ struct M {
// __unaligned handling
typedef char __unaligned *aligned_type;
+typedef struct UnalignedTag { int f; } __unaligned *aligned_type2;
+typedef char aligned_dummy, __unaligned *aligned_type3;
template<typename T> void h1(T (__stdcall M::* const )()) { }
--
1.9.4.msysgit.2
More information about the cfe-commits
mailing list