[cfe-commits] [PATCH] Constructor and Destructor mangling, along with improved Calling Convention handling for Windows.

Ricky Taylor rickytaylor26 at gmail.com
Fri Jan 21 07:06:04 PST 2011


Not sure how, but that last message had an old version of the patch.
I've attached the correct version to this message.

-- Ricky Taylor

On Fri, Jan 21, 2011 at 11:16 AM, Ricky Taylor <rickytaylor26 at gmail.com> wrote:
> On Fri, Jan 21, 2011 at 6:05 AM, Charles Davis <cdavis at mymail.mines.edu> wrote:
>>
>> On 1/20/11 10:12 PM, Ricky Taylor wrote:
>> > Hello,
>> >
>> > I've created a patch for clang, that addresses some issues with the
>> > Microsoft ABI:
>> >
>> > - Constructors and Destructors are now mangled correctly
>> > - 'Repeated Namespaces' are mangled correctly
>> > - The correct default calling convention is used for class/struct methods
>> > - __declspec syntax is now used, (and presumably the GCC equivalent).
>> > - Attributes are passed down the chain correctly, (they were not being
>> > copied into the Declarator).
>> >
>> > The patch is attached below,
>> Hi,
>>
>> I wrote the Microsoft C++ Mangler initially. Comments below:
>>
>> Index: include/clang/Sema/DeclSpec.h
>> ===================================================================
>> --- include/clang/Sema/DeclSpec.h       (revision 123612)
>> +++ include/clang/Sema/DeclSpec.h       (working copy)
>> @@ -1206,7 +1206,7 @@
>>   Declarator(const DeclSpec &ds, TheContext C)
>>     : DS(ds), Range(ds.getSourceRange()), Context(C),
>>       InvalidType(DS.getTypeSpecType() == DeclSpec::TST_error),
>> -      GroupingParens(false), AttrList(0), AsmLabel(0),
>> +         GroupingParens(false), AttrList(ds.getAttributes().getList()),
>> AsmLabel(0),
>>       InlineParamsUsed(false), Extension(false) {
>>   }
>>
>> I think there's a reason they weren't being passed down. I'm not sure
>> about Microsoft attributes, but IIRC GNU attributes on the decl-spec
>> belong to the type, not the declarator. Maybe we should pass down only
>> Microsoft (i.e. __declspec) attributes.
>>
>> Also, you used tab characters instead of spaces. Please don't do that.
>> Lots of people use a tab width of 8, so the indentation looks off.
>>
>> Index: lib/AST/ASTContext.cpp
>> ===================================================================
>> --- lib/AST/ASTContext.cpp      (revision 123612)
>> +++ lib/AST/ASTContext.cpp      (working copy)
>> @@ -885,6 +885,14 @@
>>   return toCharUnitsFromBits(getTypeAlign(T));
>>  }
>>
>> +/// getDefaultCallingConvForDeclarator - Determines the default calling
>> convention
>> +/// for a Declarator before attributes are applied.
>> +CallingConv ASTContext::getDefaultCallingConvForDeclarator(Declarator
>> &D, Scope *S) const
>> +{
>> +       // Pass through to ABI.
>> +       return ABI->getDefaultCallingConvForDeclarator(D, S);
>> +}
>> +
>>
>> You could avoid having to add another method to the C++ ABI object by
>> calling the getDefaultMethodCallingConv() method on the ABI object. Then
>> this becomes:
>>
>>  CallingConv getDefaultCallingConvForDeclarator(Declarator &D, Scope
>> *S) const {
>>          if(<the declarator refers to an instance method>)
>>                  return ABI->getDefaultMethodCallingConv();
>>
>>          return CC_C;
>>  }
>>
>>
>> Index: lib/AST/CXXABI.h
>> ===================================================================
>> --- lib/AST/CXXABI.h    (revision 123612)
>> +++ lib/AST/CXXABI.h    (working copy)
>> @@ -21,6 +21,8 @@
>>
>>  class ASTContext;
>>  class MemberPointerType;
>> +class Declarator;
>> +class Scope;
>>
>>  /// Implements C++ ABI-specific semantic analysis functions.
>>  class CXXABI {
>> @@ -30,10 +32,13 @@
>>   /// Returns the size of a member pointer in multiples of the target
>>   /// pointer size.
>>   virtual unsigned getMemberPointerSize(const MemberPointerType *MPT)
>> const = 0;
>> -
>> +
>>   /// Returns the default calling convention for C++ methods.
>>   virtual CallingConv getDefaultMethodCallConv() const = 0;
>>
>> +  /// Returns the default calling convention for a particular Declarator.
>> +  virtual CallingConv getDefaultCallingConvForDeclarator(Declarator &D,
>> Scope *S) const = 0;
>> +
>>
>> You shouldn't have to do this (see above).
>>
>> Index: lib/AST/MicrosoftCXXABI.cpp
>> ===================================================================
>> --- lib/AST/MicrosoftCXXABI.cpp (revision 123612)
>> +++ lib/AST/MicrosoftCXXABI.cpp (working copy)
>> @@ -17,6 +17,8 @@
>>  #include "clang/AST/DeclCXX.h"
>>  #include "clang/AST/RecordLayout.h"
>>  #include "clang/AST/Type.h"
>> +#include "clang/Sema/DeclSpec.h"
>> +#include "clang/Sema/Scope.h"
>>  #include "clang/Basic/TargetInfo.h"
>>
>>  using namespace clang;
>> @@ -36,6 +38,13 @@
>>       return CC_C;
>>   }
>>
>> +  CallingConv getDefaultCallingConvForDeclarator(Declarator &D, Scope
>> *S) const {
>> +         if(S && (S->getFlags() & Scope::ClassScope))
>> +                 return CC_X86ThisCall;
>> +
>> +         return CC_C;
>> +  }
>> +
>>
>> You should probably make sure that the declarator doesn't have the
>> static storage class. For static methods, the default calling convention
>> is still __cdecl. (Of course, this is after moving the implementation
>> over to ASTContext.)
>>
>> Index: lib/AST/MicrosoftMangle.cpp
>> ===================================================================
>> --- lib/AST/MicrosoftMangle.cpp (revision 123612)
>> +++ lib/AST/MicrosoftMangle.cpp (working copy)
>> @@ -30,6 +30,7 @@
>>  class MicrosoftCXXNameMangler {
>>   MangleContext &Context;
>>   llvm::raw_svector_ostream Out;
>> +  std::vector<llvm::StringRef> Shortcuts;
>>
>> You might consider using a SmallVector here (there can only be 10
>> replacements anyway).
>>
>>   ASTContext &getASTContext() const { return Context.getASTContext(); }
>>
>> @@ -336,11 +337,13 @@
>>       break;
>>
>>     case DeclarationName::CXXConstructorName:
>> -      assert(false && "Can't mangle constructors yet!");
>> +         // <constructor> ::= ?0 class-name
>> +         Out << "?0";
>>       break;
>>
>> Tabs.
>>
>>     case DeclarationName::CXXDestructorName:
>> -      assert(false && "Can't mangle destructors yet!");
>> +         // <destructor> ::= ?1
>> +      Out << "?1";
>>       break;
>>
>> Tabs again. (The second line is okay, though.)
>>
>>     case DeclarationName::CXXConversionFunctionName:
>> @@ -382,7 +385,8 @@
>>   if (const BlockDecl *BD = dyn_cast<BlockDecl>(DC)) {
>>     llvm::SmallString<64> Name;
>>     Context.mangleBlock(BD, Name);
>> -    Out << Name << '@';
>> +
>> +       Out << Name << '@';
>>     return manglePostfix(DC->getParent(), NoFunction);
>>   }
>>
>> Please avoid gratuitous whitespace changes.
>>
>> @@ -525,8 +529,34 @@
>>  }
>>
>>  void MicrosoftCXXNameMangler::mangleSourceName(const IdentifierInfo *II) {
>> -  // <source name> ::= <identifier> @
>> -  Out << II->getName() << '@';
>> +       // <source name> ::= <identifier> @
>> +
>> +       llvm::StringRef Name = II->getName();
>> +
>> +       // Microsoft assign the first 10 names to ascii shortcuts
>> +       // '0'-'9'. They are then used instead of the name@ syntax.
>> +       bool newName = true;
>> +       for(size_t i = 0; i < Shortcuts.size(); i++)
>> +       {
>> +               if(Shortcuts[i].compare(Name) == 0)
>> +               {
>> +                       Out << std::string(1, '0' + i);
>> +                       newName = false;
>> +                       break;
>> +               }
>> +       }
>> +
>> +       // If we weren't in the shortcut list, then we will have to
>> +       // write the whole name out.
>> +       if(newName)
>> +       {
>> +               Out << Name << '@';
>> +
>> +               if(Shortcuts.size() < 10)
>> +               {
>> +                       Shortcuts.push_back(Name);
>> +               }
>> +       }
>>  }
>>
>> You should probably add a test for this to
>> <clang>/test/CodeGenCXX/mangle-ms.cpp.
>>
>> Oh, and tabs again.
>>
>> The whole patch file had mixed line endings (CR-LF and LF). Try to avoid
>> that.
>>
>> Did you make sure to run Clang's tests with your patch, in case you
>> introduced a regression?
>>
>> Other than those, LGTM! Doug, John, your thoughts?
>>
>> Chip
>> _______________________________________________
>> cfe-commits mailing list
>> cfe-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
> Hello again,
>
> Thanks for your help. I had totally mistaken how the AttributeLists
> were handled, and have corrected that.
>
> I've checked this new patch against clang's tests, and there appear to
> be no regressions.
>
> One thing to note is that I've added a bit definition to ExtInfo, this
> is so that the compiler doesn't print the calling convention of every
> function, only ones you've explicitly declared in your code. This
> could be changed, but it would require that a few of the tests are
> re-written too. (As they depend on the 'plain' function signature
> being printed out.)
>
> I've also gone through and sorted out all the white-space, sorry about that.
>
> Please find attached the improved patch.
>
> -- Ricky Taylor
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: MSVCCallingConvCTorsDTors2.patch
Type: application/octet-stream
Size: 7716 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20110121/7d1f79b7/attachment.obj>


More information about the cfe-commits mailing list