cdavis5x updated this revision to Diff 57853.
cdavis5x marked an inline comment as done.
cdavis5x added a comment.

- Add Sema tests for the `ms_hook_prologue` attribute.
- Disallow `ms_hook_prologue` on architectures that Windows doesn't support.
- Disallow `ms_hook_prologue` with the `naked` and `always_inline` attributes.


http://reviews.llvm.org/D19909

Files:
  include/clang/Basic/Attr.td
  include/clang/Basic/AttrDocs.td
  lib/CodeGen/TargetInfo.cpp
  lib/Sema/SemaDeclAttr.cpp
  test/CodeGen/function-attributes.c
  test/Sema/attr-ms-hook-prologue.c

Index: test/Sema/attr-ms-hook-prologue.c
===================================================================
--- /dev/null
+++ test/Sema/attr-ms-hook-prologue.c
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -triple i386-pc-linux -fms-extensions -fsyntax-only -verify %s
+
+int __attribute__((ms_hook_prologue)) foo(int a, int b) {
+  return a+b;
+}
+
+// expected-note@+2{{conflicting attribute is here}}
+// expected-error@+1{{'naked' and 'ms_hook_prologue' attributes are not compatible}}
+__declspec(naked) int __attribute__((ms_hook_prologue)) bar(int a, int b) {
+}
+
+// expected-note@+2{{conflicting attribute is here}}
+// expected-error@+1{{'__forceinline' and 'ms_hook_prologue' attributes are not compatible}}
+__forceinline int __attribute__((ms_hook_prologue)) baz(int a, int b) {
+  return a-b;
+}
+
+// expected-warning@+1{{'ms_hook_prologue' attribute only applies to functions}}
+int x __attribute__((ms_hook_prologue));
+
+// expected-error@+1{{'ms_hook_prologue' attribute takes no arguments}}
+int f(int a, int b) __attribute__((ms_hook_prologue(2)));
Index: test/CodeGen/function-attributes.c
===================================================================
--- test/CodeGen/function-attributes.c
+++ test/CodeGen/function-attributes.c
@@ -108,11 +108,18 @@
   _setjmp(0);
 }
 
+// CHECK-LABEL: define void @f21
+// CHECK: [[HOTPATCH:#[0-9]+]]
+// CHECK: {
+void __attribute__((ms_hook_prologue)) f21(void) {
+}
+
 // CHECK: attributes [[NUW]] = { nounwind optsize{{.*}} }
 // CHECK: attributes [[AI]] = { alwaysinline nounwind optsize{{.*}} }
 // CHECK: attributes [[NUW_OS_RN]] = { nounwind optsize readnone{{.*}} }
 // CHECK: attributes [[ALIGN]] = { nounwind optsize alignstack=16{{.*}} }
 // CHECK: attributes [[RT]] = { nounwind optsize returns_twice{{.*}} }
+// CHECK: attributes [[HOTPATCH]] = { nounwind optsize{{.*}}"patchable-function"="ms-hotpatch"{{.*}} }
 // CHECK: attributes [[NR]] = { noreturn optsize }
 // CHECK: attributes [[NUW_RN]] = { nounwind optsize readnone }
 // CHECK: attributes [[RT_CALL]] = { optsize returns_twice }
Index: lib/Sema/SemaDeclAttr.cpp
===================================================================
--- lib/Sema/SemaDeclAttr.cpp
+++ lib/Sema/SemaDeclAttr.cpp
@@ -1663,15 +1663,6 @@
     D->addAttr(CA);
 }
 
-static void handleNakedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
-  if (checkAttrMutualExclusion<DisableTailCallsAttr>(S, D, Attr.getRange(),
-                                                     Attr.getName()))
-    return;
-
-  D->addAttr(::new (S.Context) NakedAttr(Attr.getRange(), S.Context,
-                                         Attr.getAttributeSpellingListIndex()));
-}
-
 static void handleNoReturnAttr(Sema &S, Decl *D, const AttributeList &attr) {
   if (hasDeclarator(D)) return;
 
@@ -3672,7 +3663,9 @@
 static void handleAlwaysInlineAttr(Sema &S, Decl *D,
                                    const AttributeList &Attr) {
   if (checkAttrMutualExclusion<NotTailCalledAttr>(S, D, Attr.getRange(),
-                                                  Attr.getName()))
+                                                  Attr.getName()) ||
+      checkAttrMutualExclusion<MSHookPrologueAttr>(S, D, Attr.getRange(),
+                                                   Attr.getName()))
     return;
 
   if (AlwaysInlineAttr *Inline = S.mergeAlwaysInlineAttr(
@@ -5525,7 +5518,8 @@
     handleHotAttr(S, D, Attr);
     break;
   case AttributeList::AT_Naked:
-    handleNakedAttr(S, D, Attr);
+    handleSimpleAttributeWithExclusions<NakedAttr, DisableTailCallsAttr,
+                                        MSHookPrologueAttr>(S, D, Attr);
     break;
   case AttributeList::AT_NoReturn:
     handleNoReturnAttr(S, D, Attr);
@@ -5748,6 +5742,10 @@
     break;
 
   // Microsoft attributes:
+  case AttributeList::AT_MSHookPrologue:
+    handleSimpleAttributeWithExclusions<MSHookPrologueAttr, NakedAttr,
+      AlwaysInlineAttr>(S, D, Attr);
+    break;
   case AttributeList::AT_MSNoVTable:
     handleSimpleAttribute<MSNoVTableAttr>(S, D, Attr);
     break;
Index: lib/CodeGen/TargetInfo.cpp
===================================================================
--- lib/CodeGen/TargetInfo.cpp
+++ lib/CodeGen/TargetInfo.cpp
@@ -1749,6 +1749,10 @@
       llvm::Function *Fn = cast<llvm::Function>(GV);
       Fn->setCallingConv(llvm::CallingConv::X86_INTR);
     }
+    if (FD->hasAttr<MSHookPrologueAttr>()) {
+      llvm::Function *Fn = cast<llvm::Function>(GV);
+      Fn->addFnAttr("patchable-function", "ms-hotpatch");
+    }
   }
 }
 
@@ -2079,6 +2083,10 @@
         llvm::Function *Fn = cast<llvm::Function>(GV);
         Fn->setCallingConv(llvm::CallingConv::X86_INTR);
       }
+      if (FD->hasAttr<MSHookPrologueAttr>()) {
+        llvm::Function *Fn = cast<llvm::Function>(GV);
+        Fn->addFnAttr("patchable-function", "ms-hotpatch");
+      }
     }
   }
 };
Index: include/clang/Basic/AttrDocs.td
===================================================================
--- include/clang/Basic/AttrDocs.td
+++ include/clang/Basic/AttrDocs.td
@@ -494,6 +494,19 @@
   }];
 }
 
+def MSHookPrologueDocs : Documentation {
+  let Category = DocCatFunction;
+  let Content = [{
+The ``ms_hook_prologue`` attribute marks a function as "hotpatchable" according
+to conventions used on Windows. Specifically, enough space will be ensured
+in the prologue for a short jump, and an architecturally dependently sized
+patch space will be reserved prior to the entry point. See the documentation
+for the `/HOTPATCH`_ switch on MSDN.
+
+.. _`/HOTPATCH`: https://msdn.microsoft.com/en-us/library/ms173507.aspx
+  }];
+}
+
 def NoDebugDocs : Documentation {
   let Category = DocCatVariable;
   let Content = [{
Index: include/clang/Basic/Attr.td
===================================================================
--- include/clang/Basic/Attr.td
+++ include/clang/Basic/Attr.td
@@ -254,6 +254,7 @@
 def TargetMSP430 : TargetArch<["msp430"]>;
 def TargetX86 : TargetArch<["x86"]>;
 def TargetAnyX86 : TargetArch<["x86", "x86_64"]>;
+def TargetWindowsArches : TargetArch<["x86", "x86_64", "arm", "thumb"]>;
 def TargetWindows : TargetArch<["x86", "x86_64", "arm", "thumb"]> {
   let OSes = ["Win32"];
 }
@@ -2029,6 +2030,12 @@
 
 // Microsoft-related attributes
 
+def MSHookPrologue : InheritableAttr, TargetSpecificAttr<TargetWindowsArches> {
+  let Spellings = [GCC<"ms_hook_prologue">];
+  let Subjects = SubjectList<[Function]>;
+  let Documentation = [MSHookPrologueDocs];
+}
+
 def MSNoVTable : InheritableAttr, TargetSpecificAttr<TargetMicrosoftCXXABI> {
   let Spellings = [Declspec<"novtable">];
   let Subjects = SubjectList<[CXXRecord]>;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to