[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