[Review, -cxx-abi microsoft] Implement proper handling of virtual destructors (single-inheritance case)
Charles Davis
cdavis5x at gmail.com
Tue Jan 29 10:06:23 PST 2013
On Jan 29, 2013, at 9:58 AM, Timur Iskhodzhanov wrote:
> 2013/1/28 Timur Iskhodzhanov <timurrrr at google.com>:
>> Two problems:
>> 1) I was optimistically running only the new tests and didn't notice
>> I've broken one of my own earlier tests in the Clang sources. I'll fix
>> that soon
>>
>> 2) CGM code has changed over the weekend, I'll have to rebase.
>>
>> I'll ping this thread with a new patch when I resolve these.
> Here it is attached.
> Sorry for the delay, the Windows build was broken a few times in the
> interim and also my VS checkout was borked for some reason.
>
> Please note that I had to change the test/CodeGenCXX/arm.cpp test
> because I believe it is wrong :)
> See the other e-mail thread for the details.
> diff --git lib/AST/MicrosoftMangle.cpp lib/AST/MicrosoftMangle.cpp
> index 0b77ac8..5a68704 100644
> --- lib/AST/MicrosoftMangle.cpp
> +++ lib/AST/MicrosoftMangle.cpp
> @@ -47,10 +47,11 @@ class MicrosoftCXXNameMangler {
>
> public:
> MicrosoftCXXNameMangler(MangleContext &C, raw_ostream &Out_)
> - : Context(C), Out(Out_), UseNameBackReferences(true) { }
> + : Context(C), Out(Out_), UseNameBackReferences(true), DtorType(Dtor_Complete) { }
>
> raw_ostream &getStream() const { return Out; }
>
> + CXXDtorType DtorType; // FIXME: pass as arg?
Yes, it should be an argument. It seems like a simple enough change.
> void mangle(const NamedDecl *D, StringRef Prefix = "\01?");
> void mangleName(const NamedDecl *ND);
> void mangleFunctionEncoding(const FunctionDecl *FD);
> @@ -483,11 +484,25 @@ MicrosoftCXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,
> case DeclarationName::CXXConstructorName:
> Out << "?0";
> break;
> -
> +
> case DeclarationName::CXXDestructorName:
> - Out << "?1";
> + switch (DtorType) {
> + case Dtor_Deleting:
> + Out << "?_G";
> + break;
> + case Dtor_Base:
> + // FIXME: base dtors are not supported yet. Even though the current
> + // codegen won't emit base dtors, we may still need to mangle a base
> + // dtor for a base class destruction in case of inheritance.
> + // For now, just mangle a base dtor the same way as a complete dtor.
IIRC the only real difference between a "base" and "complete" destructor in the MS ABI is a boolean flag that gets passed indicating if it's a base or a complete call (cf. 'for base' TODOs in MicrosoftCXXABI.cpp). They really are one and the same otherwise.
> @@ -1109,9 +1124,17 @@ void MicrosoftCXXNameMangler::mangleType(const FunctionType *T,
>
> // <return-type> ::= <type>
> // ::= @ # structors (they have no declared return type)
> - if (IsStructor)
> + if (IsStructor) {
> + if (DtorType == Dtor_Deleting) {
> + // The scalar deleting destructor takes an extra int argument.
> + // However, the FunctionType generated has 0 arguments.
> + // FIXME: This is a temporary hack.
> + // Maybe should fix the FunctionType creation instead?
"Maybe"? ;) Seriously, this is a gross hack. I'd prefer to avoid it, but I guess it's OK (with me anyway) for now if you don't want to fix it yet.
> + Out << "PAXI at Z";
Are you sure that's right? That would seem to imply that the return type is void *--which it appears to be in fact, based on the code we're generating, but my impression was that VS mangled all 'structors' return types as "@" because they have no declared return type. The deleting destructors might be different, though. In any case, do VS-generated destructors get mangled this way?
> @@ -1711,6 +1734,7 @@ void MicrosoftMangleContext::mangleCXXDtor(const CXXDestructorDecl *D,
> CXXDtorType Type,
> raw_ostream & Out) {
> MicrosoftCXXNameMangler mangler(*this, Out);
> + mangler.DtorType = Type;
Yeah, it should definitely be an argument.
> diff --git lib/CodeGen/CGCXX.cpp lib/CodeGen/CGCXX.cpp
> index 43813fe..bcd3f2c 100644
> --- lib/CodeGen/CGCXX.cpp
> +++ lib/CodeGen/CGCXX.cpp
> @@ -240,7 +240,10 @@ void CodeGenModule::EmitCXXDestructors(const CXXDestructorDecl *D) {
>
> // The destructor used for destructing this as a base class; ignores
> // virtual bases.
> - EmitGlobal(GlobalDecl(D, Dtor_Base));
> + if (!IsMicrosoftABI) {
> + // FIXME: base dtors are not supported in Microsoft ABI yet, skip for now.
> + EmitGlobal(GlobalDecl(D, Dtor_Base));
> + }
Like I said earlier, there's no real distinction in the MS ABI.
> diff --git lib/CodeGen/CGVTables.cpp lib/CodeGen/CGVTables.cpp
> index 6d40219..d28a4e2 100644
> --- lib/CodeGen/CGVTables.cpp
> +++ lib/CodeGen/CGVTables.cpp
> @@ -736,7 +736,10 @@ CodeGenModule::getVTableLinkage(const CXXRecordDecl *RD) {
> return !Context.getLangOpts().AppleKext ?
> llvm::GlobalVariable::LinkOnceODRLinkage :
> llvm::Function::InternalLinkage;
> -
> +
> + if (IsMicrosoftABI) {
> + return llvm::GlobalVariable::WeakODRLinkage;
> + }
Style nit: we prefer no braces if there's only a single statement.
> diff --git lib/CodeGen/CodeGenModule.cpp lib/CodeGen/CodeGenModule.cpp
> index da419dd..5b3dfd7 100644
> --- lib/CodeGen/CodeGenModule.cpp
> +++ lib/CodeGen/CodeGenModule.cpp
> @@ -83,7 +83,8 @@ CodeGenModule::CodeGenModule(ASTContext &C, const CodeGenOptions &CGO,
> BlockDescriptorType(0), GenericBlockLiteralType(0),
> SanitizerBlacklist(CGO.SanitizerBlacklistFile),
> SanOpts(SanitizerBlacklist.isIn(M) ?
> - SanitizerOptions::Disabled : LangOpts.Sanitize) {
> + SanitizerOptions::Disabled : LangOpts.Sanitize),
> + IsMicrosoftABI(C.getTargetInfo().getCXXABI().isMicrosoft()) {
>
> // Initialize the type cache.
> llvm::LLVMContext &LLVMContext = M.getContext();
> diff --git lib/CodeGen/CodeGenModule.h lib/CodeGen/CodeGenModule.h
> index 75c5e93..a511640 100644
> --- lib/CodeGen/CodeGenModule.h
> +++ lib/CodeGen/CodeGenModule.h
> @@ -375,6 +375,8 @@ class CodeGenModule : public CodeGenTypeCache {
>
> const SanitizerOptions &SanOpts;
>
> + bool IsMicrosoftABI;
> +
> /// @}
> public:
> CodeGenModule(ASTContext &C, const CodeGenOptions &CodeGenOpts,
I thought I added the CGCXXABI class to avoid special cases like this. :) Don't get me wrong; for a quick'n'dirty first pass, I guess it's OK (pending John's approval), but I'd really like to see this gone later.
Other than these minor points, LGTM overall.
Chip
>
>> 2013/1/25 Timur Iskhodzhanov <timurrrr at google.com>:
>>> Hi John,
>>>
>>> Attached is a patch that allows me to pass all the single-inheritance
>>> vdtor tests I've extracted while building and running Chromium.
>>>
>>> It includes changing the deleting destructor to take an implicit bool
>>> parameter when compiling in the Microsoft ABI.
>>> Can you please take a look?
>>> See also http://llvm.org/bugs/show_bug.cgi?id=15058 for the details.
>>>
>>> The patch contains a couple of FIXMEs, I'd like to defer them for
>>> later analysis if possible.
>>>
>>> Note that I had to adjust the EmitCXXMemberCall interface slightly; I
>>> think generalizing "VTT" to "implicit parameter in general" should be
>>> OK.
>>>
>>> Please tell me if I need to change anything.
>>>
>>> --
>>> Timur Iskhodzhanov,
>>> Google Russia
>>
>>
>>
>> --
>> Timur Iskhodzhanov,
>> Google Russia
> <bug_15058_2.patch>_______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
More information about the cfe-commits
mailing list