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"];
}
// 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]>;
}];
}
-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.
-
-This attribute cannot be used in conjunction with the ``naked``,
-``always_inline``, or ``__forceinline`` attributes.
-
-.. _`/HOTPATCH`: https://msdn.microsoft.com/en-us/library/ms173507.aspx
- }];
-}
-
def NoDebugDocs : Documentation {
let Category = DocCatVariable;
let Content = [{
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");
- }
}
}
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");
- }
}
}
};
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;
static void handleAlwaysInlineAttr(Sema &S, Decl *D,
const AttributeList &Attr) {
if (checkAttrMutualExclusion<NotTailCalledAttr>(S, D, Attr.getRange(),
- Attr.getName()) ||
- checkAttrMutualExclusion<MSHookPrologueAttr>(S, D, Attr.getRange(),
- Attr.getName()))
+ Attr.getName()))
return;
if (AlwaysInlineAttr *Inline = S.mergeAlwaysInlineAttr(
handleHotAttr(S, D, Attr);
break;
case AttributeList::AT_Naked:
- handleSimpleAttributeWithExclusions<NakedAttr, DisableTailCallsAttr,
- MSHookPrologueAttr>(S, D, Attr);
+ handleNakedAttr(S, D, Attr);
break;
case AttributeList::AT_NoReturn:
handleNoReturnAttr(S, D, Attr);
break;
case AttributeList::AT_LayoutVersion:
handleLayoutVersion(S, D, Attr);
- case AttributeList::AT_MSHookPrologue:
- handleSimpleAttributeWithExclusions<MSHookPrologueAttr, NakedAttr,
- AlwaysInlineAttr>(S, D, Attr);
break;
case AttributeList::AT_MSNoVTable:
handleSimpleAttribute<MSNoVTableAttr>(S, D, Attr);
_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 }
+++ /dev/null
-// RUN: %clang_cc1 -triple s390x-unknown-linux -fms-extensions -fsyntax-only -verify %s
-
-// expected-warning@+1{{unknown attribute 'ms_hook_prologue' ignored}}
-int __attribute__((ms_hook_prologue)) foo(int a, int b) {
- return a+b;
-}
+++ /dev/null
-// 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)));