[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