r356964 - [MS] Add frontend support for __declspec(allocator)

Reid Kleckner via cfe-commits cfe-commits at lists.llvm.org
Mon Mar 25 16:20:18 PDT 2019


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);




More information about the cfe-commits mailing list