Author: rnk Date: Mon Mar 25 16:20:18 2019 New Revision: 356964 URL: http://llvm.org/viewvc/llvm-project?rev=356964&view=rev Log: [MS] Add frontend support for __declspec(allocator)
The intention is to add metadata to direct call sites of functions marked with __declspec(allocator), which will ultimately result in some S_HEAPALLOCSITE debug info records when emitting codeview. This is a piece of PR38491 Added: cfe/trunk/test/SemaCXX/declspec-allocator.cpp Modified: cfe/trunk/include/clang/Basic/Attr.td cfe/trunk/include/clang/Basic/AttrDocs.td cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td cfe/trunk/lib/Sema/SemaDeclAttr.cpp Modified: cfe/trunk/include/clang/Basic/Attr.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=356964&r1=356963&r2=356964&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/Attr.td (original) +++ cfe/trunk/include/clang/Basic/Attr.td Mon Mar 25 16:20:18 2019 @@ -2757,6 +2757,12 @@ def : IgnoredAttr { let Spellings = [Declspec<"property">]; } +def MSAllocator : InheritableAttr { + let Spellings = [Declspec<"allocator">]; + let Subjects = SubjectList<[Function]>; + let Documentation = [MSAllocatorDocs]; +} + def MSStruct : InheritableAttr { let Spellings = [GCC<"ms_struct">]; let Subjects = SubjectList<[Record]>; Modified: cfe/trunk/include/clang/Basic/AttrDocs.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/AttrDocs.td?rev=356964&r1=356963&r2=356964&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/AttrDocs.td (original) +++ cfe/trunk/include/clang/Basic/AttrDocs.td Mon Mar 25 16:20:18 2019 @@ -4089,3 +4089,20 @@ it will be automatically applied to over attribute can also be written using C++11 syntax: ``[[mig::server_routine]]``. }]; } + +def MSAllocatorDocs : Documentation { + let Category = DocCatType; + let Content = [{ +The ``__declspec(allocator)`` attribute is applied to functions that allocate +memory, such as operator new in C++. When CodeView debug information is emitted +(enabled by ``clang -gcodeview`` or ``clang-cl /Z7``), Clang will attempt to +record the code offset of heap allocation call sites in the debug info. It will +also record the type being allocated using some local heuristics. The Visual +Studio debugger uses this information to `profile memory usage`_. + +.. _profile memory usage: https://docs.microsoft.com/en-us/visualstudio/profiling/memory-usage + +This attribute does not affect optimizations in any way, unlike GCC's +``__attribute__((malloc))``. +}]; +} Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=356964&r1=356963&r2=356964&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Mar 25 16:20:18 2019 @@ -2956,6 +2956,9 @@ def err_base_specifier_attribute : Error "%0 attribute cannot be applied to a base specifier">; def err_invalid_attribute_on_virtual_function : Error< "%0 attribute cannot be applied to virtual functions">; +def warn_declspec_allocator_nonpointer : Warning< + "ignoring __declspec(allocator) because the function return type %0 is not " + "a pointer or reference type">, InGroup<IgnoredAttributes>; def ext_cannot_use_trivial_abi : ExtWarn< "'trivial_abi' cannot be applied to %0">, InGroup<IgnoredAttributes>; Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=356964&r1=356963&r2=356964&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original) +++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Mon Mar 25 16:20:18 2019 @@ -6548,6 +6548,20 @@ static void handleMIGServerRoutineAttr(S handleSimpleAttribute<MIGServerRoutineAttr>(S, D, AL); } +static void handleMSAllocatorAttr(Sema &S, Decl *D, const ParsedAttr &AL) { + // Warn if the return type is not a pointer or reference type. + if (auto *FD = dyn_cast<FunctionDecl>(D)) { + QualType RetTy = FD->getReturnType(); + if (!RetTy->isPointerType() && !RetTy->isReferenceType()) { + S.Diag(AL.getLoc(), diag::warn_declspec_allocator_nonpointer) + << AL.getRange() << RetTy; + return; + } + } + + handleSimpleAttribute<MSAllocatorAttr>(S, D, AL); +} + //===----------------------------------------------------------------------===// // Top Level Sema Entry Points //===----------------------------------------------------------------------===// @@ -7281,6 +7295,10 @@ static void ProcessDeclAttribute(Sema &S case ParsedAttr::AT_MIGServerRoutine: handleMIGServerRoutineAttr(S, D, AL); break; + + case ParsedAttr::AT_MSAllocator: + handleMSAllocatorAttr(S, D, AL); + break; } } Added: cfe/trunk/test/SemaCXX/declspec-allocator.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/declspec-allocator.cpp?rev=356964&view=auto ============================================================================== --- cfe/trunk/test/SemaCXX/declspec-allocator.cpp (added) +++ cfe/trunk/test/SemaCXX/declspec-allocator.cpp Mon Mar 25 16:20:18 2019 @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -fms-compatibility -triple x86_64-windows-msvc -std=c++14 -fms-extensions -fms-compatibility-version=19.00 -verify %s + +__declspec(allocator) int err_on_data; // expected-warning {{'allocator' attribute only applies to functions}} +__declspec(allocator) struct ErrOnStruct1; // expected-warning {{place it after "struct" to apply attribute}} +struct __declspec(allocator) ErrOnStruct2 {}; // expected-warning {{'allocator' attribute only applies to functions}} +__declspec(allocator) void err_on_ret_void(); // expected-warning {{not a pointer or reference type}} +__declspec(allocator) int err_on_ret_int(); // expected-warning {{not a pointer or reference type}} +__declspec(allocator) void *accept_on_ptr1(); +__declspec(allocator) void *accept_on_ptr2(size_t); +void * __declspec(allocator) accept_on_ptr3(size_t); // expected-error {{expected unqualified-id}} + +struct Foo { int x; }; +__declspec(allocator) Foo *accept_nonvoid_ptr(size_t); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits