[PATCH] Initial support for __sptr and __uptr

Richard Smith richard at metafoo.co.uk
Wed May 15 21:46:09 PDT 2013


+++ lib/Sema/SemaDeclAttr.cpp (working copy)
@@ -4225,7 +4225,7 @@
     QualType BufferTy = getFunctionOrMethodArgType(D, ArgumentIdx);
     if (!BufferTy->isPointerType()) {
       S.Diag(Attr.getLoc(), diag::err_attribute_pointers_only)
-        << AttrName;
+        << Attr.getName();

Did you mean to include this change?


+++ lib/Sema/SemaType.cpp (working copy)
@@ -110,6 +110,13 @@
     case AttributeList::AT_PnaclCall: \
     case AttributeList::AT_IntelOclBicc \

+// Microsoft-specific type qualifiers.
+#define MS_TYPE_ATTRS_CASELIST  \
+    case AttributeList::AT_Ptr32: \
+    case AttributeList::AT_Ptr64: \
+    case AttributeList::AT_SPtr: \
+    case AttributeList::AT_UPtr \
+

Please remove the trailing \ from the end of this macro (and the previous
existing one!)

+  // Pointer type qualifiers can only operate on pointer types, but not
+  // pointer-to-member types.
+  if (!Type->isPointerType() || Type->isMemberPointerType()) {

Member pointer types are not pointer types, so you can drop the || ... part
here.

Also, what if there is type sugar before the pointer type? For instance:

typedef int *T;
T __ptr32 __sptr P; // ok?

... or ...

int *(__ptr32 __sptr p); // ok?


+  // You cannot have both __sptr and __uptr on the same declaration, nor
can
+  // you duplicate the attributes.
+  const AttributedType *AT = dyn_cast<AttributedType>(Type);

What if there is another AttributedType in between? For instance:

  int * __sptr __ptr32 __sptr p; // presumably should be rejected,
presumably won't be

You could address both of these by looping over AttributedTypes until you
hit a PointerType, or by looking at the form of the pointer by inspecting
the TypeProcessingState.


Please add tests for these appearing at the start of the declaration, and
after the identifier.

On Wed, May 15, 2013 at 1:40 PM, Aaron Ballman <aaron at aaronballman.com>wrote:

> Here is an updated patch that is meant to handle the semantics up to
> (but not including) codegen, including test cases.
>
> ~Aaron
>
> On Tue, May 14, 2013 at 8:54 PM, Aaron Ballman <aaron at aaronballman.com>
> wrote:
> > On Tue, May 14, 2013 at 8:50 PM, Richard Smith <richard at metafoo.co.uk>
> wrote:
> >> On Tue, May 14, 2013 at 5:47 PM, Aaron Ballman <aaron at aaronballman.com>
> >> wrote:
> >>>
> >>> On Tue, May 14, 2013 at 8:42 PM, Richard Smith <richard at metafoo.co.uk>
> >>> wrote:
> >>> > On Tue, May 14, 2013 at 5:41 PM, Aaron Ballman <
> aaron at aaronballman.com>
> >>> > wrote:
> >>> >>
> >>> >> On Tue, May 14, 2013 at 8:34 PM, Richard Smith <
> richard at metafoo.co.uk>
> >>> >> wrote:
> >>> >> > On Tue, May 14, 2013 at 4:07 PM, Charles Davis <
> cdavis5x at gmail.com>
> >>> >> > wrote:
> >>> >> >>
> >>> >> >>
> >>> >> >> On May 14, 2013, at 4:26 PM, Aaron Ballman wrote:
> >>> >> >> >
> >>> >> >> >> Do __sptr and __uptr get different manglings?
> >>> >> >> >
> >>> >> >> > They do:
> >>> >> >> >
> >>> >> >> > void func( int * __ptr32 p ) {}
> >>> >> >> > void func2( int * __ptr64 p ) {}
> >>> >> >> >
> >>> >> >> > PUBLIC ?func@@YAXPAH at Z ; func
> >>> >> >> > PUBLIC ?func2@@YAXPEAH at Z ; func2
> >>> >> >> >
> >>> >> >> > Namely, the presence of E (rnk pointed this out previously).
> >>> >> >> He was asking about __sptr and __uptr :). They don't by the way:
> >>> >> >>
> >>> >> >> > cl /c test.cpp
> >>> >> >> [extraneous banner output omitted]
> >>> >> >> > dumpbin /symbols test.obj
> >>> >> >> [...]
> >>> >> >> 00F 00000010 SECT4  notype ()    External     | ?func@@YAXPAH at Z
> >>> >> >> (void
> >>> >> >> __cdecl func(int *))
> >>> >> >> 010 00000020 SECT4  notype ()    External     | ?func2@@YAXPAH at Z
> >>> >> >> (void
> >>> >> >> __cdecl func2(int *))
> >>> >> >
> >>> >> >
> >>> >> > Thanks. One more thing:
> >>> >> >
> >>> >> > template<typename T> void f(void **p, T *q) { *p = *q; }
> >>> >> >
> >>> >> > void *g(int *__ptr32 __sptr a) {
> >>> >> >   void *result;
> >>> >> >   f(&result, &a);
> >>> >> >   return result;
> >>> >> > }
> >>> >> > void *h(char *__ptr32 __uptr a) {
> >>> >> >   void *result;
> >>> >> >   f(&result, &a);
> >>> >> >   return result;
> >>> >> > }
> >>> >> >
> >>> >> > int main() {
> >>> >> >   printf("%p\n", g((int *__ptr32 __sptr)0xdeadbeef));
> >>> >> >   printf("%p\n", h((char *__ptr32 __uptr)0xdeadbeef));
> >>> >> > }
> >>> >> >
> >>> >> > Does one of these get sign-extended and the other one get
> >>> >> > zero-extended?
> >>> >>
> >>> >> The first is sign extended, and the second is zero extended in
> 64-bit.
> >>> >
> >>> >
> >>> > What happens if you change the two 'char's to 'int's?
> >>>
> >>> Both sign extend.  Is that due to the template instantiation?
> >>
> >>
> >> Yeah, both are instantiated with canonically-equivalent arguments. That
> is
> >> madness, and we shouldn't support it unless we have a strong
> compatibility
> >> argument to do so.
> >
> > I don't imagine that to be a problem.
> >
> >> Can we get away with rejecting __uptr and ignoring
> >> __sptr?
> >
> > In such an example, or on the whole?  I don't think we can do it on
> > the whole because the purpose for this feature is to aid with WOW64
> > development and interop, and __uptr is really the only one of interest
> > (__sptr is the default behavior for conversion).
> >
> > ~Aaron
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130515/20b09ff9/attachment.html>


More information about the cfe-commits mailing list