andreybokhanko updated this revision to Diff 52662.
andreybokhanko added a comment.

Added Sema test, as per Aaron's and Reid's request.


http://reviews.llvm.org/D18596

Files:
  include/clang/AST/Type.h
  include/clang/Basic/Attr.td
  include/clang/Basic/AttrDocs.td
  lib/AST/MicrosoftMangle.cpp
  lib/AST/Type.cpp
  lib/AST/TypePrinter.cpp
  lib/Sema/SemaType.cpp
  test/CodeGenCXX/mangle-ms-cxx11.cpp
  test/SemaCXX/MicrosoftExtensions.cpp

Index: lib/AST/MicrosoftMangle.cpp
===================================================================
--- lib/AST/MicrosoftMangle.cpp
+++ lib/AST/MicrosoftMangle.cpp
@@ -1413,6 +1413,11 @@
 
   if (HasRestrict)
     Out << 'I';
+
+  if (!PointeeType.isNull())
+    if (auto AT = PointeeType->getAs<AttributedType>())
+      if (AT->getAttrKind() == AttributedType::attr_unaligned)
+        Out << 'F';
 }
 
 void MicrosoftCXXNameMangler::manglePointerCVQualifiers(Qualifiers Quals) {
Index: lib/AST/TypePrinter.cpp
===================================================================
--- lib/AST/TypePrinter.cpp
+++ lib/AST/TypePrinter.cpp
@@ -1156,6 +1156,7 @@
     case AttributedType::attr_ptr64: OS << " __ptr64"; break;
     case AttributedType::attr_sptr: OS << " __sptr"; break;
     case AttributedType::attr_uptr: OS << " __uptr"; break;
+    case AttributedType::attr_unaligned: OS << " __unaligned"; break;
     }
     spaceBeforePlaceHolder(OS);
   }
Index: lib/AST/Type.cpp
===================================================================
--- lib/AST/Type.cpp
+++ lib/AST/Type.cpp
@@ -3003,6 +3003,7 @@
   case AttributedType::attr_sptr:
   case AttributedType::attr_uptr:
   case AttributedType::attr_objc_kindof:
+  case AttributedType::attr_unaligned:
     return false;
   }
   llvm_unreachable("bad attributed type kind");
@@ -3015,6 +3016,7 @@
   case attr_ptr64:
   case attr_sptr:
   case attr_uptr:
+  case attr_unaligned:
     return true;
   }
   llvm_unreachable("invalid attr kind");
@@ -3039,6 +3041,7 @@
   case attr_nullable:
   case attr_null_unspecified:
   case attr_objc_kindof:
+  case attr_unaligned:
     return false;
 
   case attr_pcs:
Index: lib/Sema/SemaType.cpp
===================================================================
--- lib/Sema/SemaType.cpp
+++ lib/Sema/SemaType.cpp
@@ -120,7 +120,8 @@
     case AttributeList::AT_Ptr32: \
     case AttributeList::AT_Ptr64: \
     case AttributeList::AT_SPtr: \
-    case AttributeList::AT_UPtr
+    case AttributeList::AT_UPtr: \
+    case AttributeList::AT_Unaligned
 
 // Nullability qualifiers.
 #define NULLABILITY_TYPE_ATTRS_CASELIST         \
@@ -4538,6 +4539,8 @@
     return AttributeList::AT_TypeNullUnspecified;
   case AttributedType::attr_objc_kindof:
     return AttributeList::AT_ObjCKindOf;
+  case AttributedType::attr_unaligned:
+    return AttributeList::AT_Unaligned;
   }
   llvm_unreachable("unexpected attribute kind!");
 }
@@ -5548,7 +5551,7 @@
 
   // Pointer type qualifiers can only operate on pointer types, but not
   // pointer-to-member types.
-  if (!isa<PointerType>(Desugared)) {
+  if (!isa<PointerType>(Desugared) && (Kind != AttributeList::AT_Unaligned)) {
     if (Type->isMemberPointerType())
       S.Diag(Attr.getLoc(), diag::err_attribute_no_member_pointers)
           << Attr.getName();
@@ -5565,6 +5568,7 @@
   case AttributeList::AT_Ptr64: TAK = AttributedType::attr_ptr64; break;
   case AttributeList::AT_SPtr: TAK = AttributedType::attr_sptr; break;
   case AttributeList::AT_UPtr: TAK = AttributedType::attr_uptr; break;
+  case AttributeList::AT_Unaligned: TAK = AttributedType::attr_unaligned; break;
   }
 
   Type = S.Context.getAttributedType(TAK, Type, Type);
Index: include/clang/AST/Type.h
===================================================================
--- include/clang/AST/Type.h
+++ include/clang/AST/Type.h
@@ -3639,6 +3639,7 @@
     attr_null_unspecified,
     attr_objc_kindof,
     attr_objc_inert_unsafe_unretained,
+    attr_unaligned,
   };
 
 private:
Index: include/clang/Basic/AttrDocs.td
===================================================================
--- include/clang/Basic/AttrDocs.td
+++ include/clang/Basic/AttrDocs.td
@@ -1957,3 +1957,18 @@
   The system will crash if the wrong handler is used.
   }];
 }
+
+def UnalignedDocs : Documentation {
+  let Category = DocCatVariable;
+  let Content = [{
+The ``__unaligned`` modifier declares a pointer with an unaligned address.
+It is available under the ``-fms-extensions`` flag for MSVC compatibility.
+See the documentation for `__unaligned`_ on MSDN.
+
+.. _`__unaligned`: https://msdn.microsoft.com/en-us/library/ms177389.aspx 
+
+Clang supports proper mangling of the variables with ``unaligned`` modifier,
+but it doesn't affect generated code in any other way.
+  }];
+}
+
Index: include/clang/Basic/Attr.td
===================================================================
--- include/clang/Basic/Attr.td
+++ include/clang/Basic/Attr.td
@@ -2075,8 +2075,10 @@
   }];
 }
 
-def Unaligned : IgnoredAttr {
+def Unaligned : TypeAttr {
   let Spellings = [Keyword<"__unaligned">];
+  let LangOpts = [MicrosoftExt];
+  let Documentation = [UnalignedDocs];
 }
 
 def LoopHint : Attr {
Index: test/SemaCXX/MicrosoftExtensions.cpp
===================================================================
--- test/SemaCXX/MicrosoftExtensions.cpp
+++ test/SemaCXX/MicrosoftExtensions.cpp
@@ -80,6 +80,7 @@
 // __unaligned handling
 typedef char __unaligned *aligned_type;
 typedef struct UnalignedTag { int f; } __unaligned *aligned_type2;
+typedef __unaligned char *aligned_type3;
 
 
 template<typename T> void h1(T (__stdcall M::* const )()) { }
Index: test/CodeGenCXX/mangle-ms-cxx11.cpp
===================================================================
--- test/CodeGenCXX/mangle-ms-cxx11.cpp
+++ test/CodeGenCXX/mangle-ms-cxx11.cpp
@@ -293,3 +293,13 @@
 }
 // CHECK-DAG: @"\01??R<lambda_0>@?0??PR26105@@YAHXZ@QBE@H@Z"
 // CHECK-DAG: @"\01??R<lambda_1>@?0???R<lambda_0>@?0??PR26105@@YAHXZ@QBE@H@Z@QBE@H@Z"
+
+int __unaligned * unaligned_foo1() { return 0; }
+int __unaligned * __unaligned * unaligned_foo2() { return 0; }
+__unaligned int unaligned_foo3() { return 0; }
+void unaligned_foo4(int __unaligned *p1) {}
+
+// CHECK-DAG: @"\01?unaligned_foo1@@YAPFAHXZ"
+// CHECK-DAG: @"\01?unaligned_foo2@@YAPFAPFAHXZ"
+// CHECK-DAG: @"\01?unaligned_foo3@@YAHXZ"
+// CHECK-DAG: @"\01?unaligned_foo4@@YAXPFAH@Z"
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to