[Patch] Mangle C __stdcall and __fastcall in clang

Reid Kleckner rnk at google.com
Tue Oct 15 10:46:16 PDT 2013


diff --git a/include/clang/AST/Mangle.h b/include/clang/AST/Mangle.h
index 76d099f..d3a49f1 100644
--- a/include/clang/AST/Mangle.h
+++ b/include/clang/AST/Mangle.h
@@ -108,10 +108,12 @@ public:
   /// @name Mangler Entry Points
   /// @{

-  virtual bool shouldMangleDeclName(const NamedDecl *D) = 0;
+  bool shouldMangleDeclName(const NamedDecl *D);
+  virtual bool shouldMangleDeclNameImpl(const NamedDecl *D) = 0;

shouldMangleDeclNameImpl can be shouldMangleCXXName, following the same
logic as mangleName.

   // FIXME: consider replacing raw_ostream & with something like
SmallString &.
-  virtual void mangleName(const NamedDecl *D, raw_ostream &) = 0;
+  void mangleName(const NamedDecl *D, raw_ostream &);
+  virtual void mangleCXXName(const NamedDecl *D, raw_ostream &) = 0;

+enum StdOrFastCC {
+  SOF_OTHER,
+  SOF_FAST,
+  SOF_STD
+};
+
+static StdOrFastCC isStdOrFastCallFunc(const ASTContext &Context,
+                                       const NamedDecl *ND) {
+  llvm::Triple Triple = Context.getTargetInfo().getTriple();
+  if (!Triple.isOSWindows() || Triple.getArch() != llvm::Triple::x86 ||
+      Context.getLangOpts().CPlusPlus)
+    return SOF_OTHER;
+
+  const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND);
+  if (!FD)
+    return SOF_OTHER;
+  QualType T = FD->getType();
+
+  if (const AttributedType *AT = dyn_cast<AttributedType>(T)) {
+    AttributedType::Kind Kind = AT->getAttrKind();
+    switch (Kind) {
+    default:
+      return SOF_OTHER;
+    case AttributedType::attr_stdcall:
+      return SOF_STD;
+    case AttributedType::attr_fastcall:
+      return SOF_FAST;
+    }
+  }

This AttributedType handling isn't necessary, use T->castAs<FunctionType>()
instead of cast<>() to look through the type sugar.

+  const FunctionType *FT = cast<FunctionType>(T);
+  CallingConv CC = FT->getCallConv();
+  switch (CC) {
+  default:
+    return SOF_OTHER;
+  case CC_X86FastCall:
+    return SOF_FAST;
+  case CC_X86StdCall:
+    return SOF_STD;
+  }
+}
...
+  const ASTContext &ASTContext = getASTContext();
+  StdOrFastCC CC = isStdOrFastCallFunc(ASTContext, D);
+  if (CC != SOF_OTHER) {
+ ...
+  }
+
+  return mangleCXXName(D, Out);

We shouldn't apply the stdcall or fastcall manglings to C++ symbols.  You
should check if we should mangle this as a C++ name first, and after that
see if we need to apply C manglings.



On Tue, Oct 15, 2013 at 7:42 AM, Rafael EspĂ­ndola <
rafael.espindola at gmail.com> wrote:

> A new patch is attached. I think I implemented all of Reid's suggestions.
>
> On 9 October 2013 16:01, Reid Kleckner <rnk at google.com> wrote:
> > This sounds like the right direction to me, if Anton's OK with removing
> the
> > mangling from LLVM.
> >
> > -  virtual bool shouldMangleDeclName(const NamedDecl *D) = 0;
> > +  bool shouldMangleDeclName(const NamedDecl *D);
> > +  virtual bool shouldMangleDeclNameImpl(const NamedDecl *D) = 0;
> >
> >    // FIXME: consider replacing raw_ostream & with something like
> > SmallString &.
> > -  virtual void mangleName(const NamedDecl *D, raw_ostream &) = 0;
> > +  void mangleName(const NamedDecl *D, raw_ostream &);
> > +  virtual void mangleNameImpl(const NamedDecl *D, raw_ostream &) = 0;
> >
> > Rather than mangleNameImpl, how about mangleCXXName?  Basically, the
> shared
> > code is C / asm mangling only, and the ABI-specific code is all C++.
> >
> > ....
> >
> > +static bool isStdOrFastCallFunc(const ASTContext &Context,
> > +                                const NamedDecl *ND) {
> > +  llvm::Triple Triple = Context.getTargetInfo().getTriple();
> > +  if (!Triple.isOSWindows() || Triple.getArch() != llvm::Triple::x86 ||
> > +      Context.getLangOpts().CPlusPlus)
> > +    return false;
> > +
> > +  const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND);
> > +  if (!FD)
> > +    return false;
> > +  QualType T = FD->getType();
> > +  const AttributedType *AT = dyn_cast<AttributedType>(T);
> > +  if (!AT)
> > +    return false;
> > +  AttributedType::Kind Kind = AT->getAttrKind();
> > +  return Kind == AttributedType::attr_stdcall ||
> > +         Kind == AttributedType::attr_fastcall;
> > +}
> >
> > Don't look for the attributed type, it won't be there with -mrtd, for
> > example.  That'd be a good test, btw.  You can pull the true CC directly
> > from FunctionType::getCallConv().
> >
> > ...
> >
> > +    unsigned ArgWords = 0;
> > +    for (FunctionProtoType::arg_type_iterator Arg =
> > Proto->arg_type_begin(),
> > +                                              ArgEnd =
> > Proto->arg_type_end();
> > +         Arg != ArgEnd; ++Arg) {
> > +      QualType AT = *Arg;
> > +      // Size should be aligned to DWORD boundary
> > +      ArgWords += (ASTContext.getTypeSize(AT) + 31) / 32;
> >
> > Grumble grumble RoundUpToAlignment().
> >
> > +    }
> > +    Out << 4 * ArgWords;
> >
> > ...
> >
> > diff --git a/test/CodeGen/mangle-ms.c b/test/CodeGen/mangle-ms.c
> > new file mode 100644
> > index 0000000..6706492
> > --- /dev/null
> > +++ b/test/CodeGen/mangle-ms.c
> >
> > mangle-windows.c seems more accurate.
> >
> >
> >
> > On Wed, Oct 9, 2013 at 12:45 PM, Rafael EspĂ­ndola
> > <rafael.espindola at gmail.com> wrote:
> >>
> >> On 9 October 2013 14:48, Anton Korobeynikov <anton at korobeynikov.info>
> >> wrote:
> >> >> Doesn't mingw need these manglings to match the Windows C ABI?
> >> > Correct, it does need it.
> >>
> >> Good catch. The attached patch handles mingw too.
> >>
> >> > Another problem, which is much more severe, is that moving mangling in
> >> > clang will force non-clang users to handle the mangling by themselves.
> >>
> >> Judging from
> >> http://lists.cs.uiuc.edu/pipermail/llvmdev/2013-February/059626.html
> >>
> >> that would be an welcome change. The mangling consists of adding how
> >> many bytes are used for arguments. If a frontend can produce a call at
> >> all it has that information.
> >>
> >> In any case. This patch changes only clang. Even if we decide to not
> >> change llvm, I think this patch is an improvement as it makes it
> >> possible for us to test that clang produces the desired name for C
> >> code (as we do for C++ already).
> >>
> >> > Also, keep in mind, that gcc on linux does support stdcall / fastcall
> >> > calling conventions, but does not mangle the stuff.
> >>
> >> That is also handled correctly.
> >>
> >> Cheers,
> >> Rafael
> >
> >
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20131015/4a1b2e53/attachment.html>


More information about the cfe-commits mailing list