diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2016-03-30 06:27:31 +0000 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2016-03-30 06:27:31 +0000 |
commit | 17d7d145717cc9eedee5f9650f5188a0bf32a65f (patch) | |
tree | 86dbd32ddec472b67e9c6dc95c820643482a9ef5 /clang/lib/CodeGen/ModuleBuilder.cpp | |
parent | e9ff01b2a701713a82d09efab7649c11d0b4d1e6 (diff) | |
download | bcm5719-llvm-17d7d145717cc9eedee5f9650f5188a0bf32a65f.tar.gz bcm5719-llvm-17d7d145717cc9eedee5f9650f5188a0bf32a65f.zip |
For MS ABI, emit dllexport friend functions defined inline in class
...as that is apparently what MSVC does. This is an updated version of r263738,
which had to be reverted in r263740 due to test failures. The original version
had erroneously emitted functions that are defined in class templates, too (see
the updated "Handle friend functions" code in EmitDeferredDecls,
lib/CodeGen/ModuleBuilder.cpp). (The updated tests needed to be split out into
their own dllexport-ms-friend.cpp because of the CHECK-NOTs which would have
interfered with subsequent CHECK-DAGs in dllexport.cpp.)
Differential Revision: http://reviews.llvm.org/D18430
llvm-svn: 264841
Diffstat (limited to 'clang/lib/CodeGen/ModuleBuilder.cpp')
-rw-r--r-- | clang/lib/CodeGen/ModuleBuilder.cpp | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/clang/lib/CodeGen/ModuleBuilder.cpp b/clang/lib/CodeGen/ModuleBuilder.cpp index bd59332a274..5b7201e12d1 100644 --- a/clang/lib/CodeGen/ModuleBuilder.cpp +++ b/clang/lib/CodeGen/ModuleBuilder.cpp @@ -143,12 +143,23 @@ namespace { DeferredInlineMethodDefinitions.clear(); } - void HandleInlineMethodDefinition(CXXMethodDecl *D) override { + void HandleInlineFunctionDefinition(FunctionDecl *D) override { if (Diags.hasErrorOccurred()) return; assert(D->doesThisDeclarationHaveABody()); + // Handle friend functions. + if (D->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend)) { + if (Ctx->getTargetInfo().getCXXABI().isMicrosoft() + && !D->getLexicalDeclContext()->isDependentContext()) + Builder->EmitTopLevelDecl(D); + return; + } + + // Otherwise, must be a method. + auto MD = cast<CXXMethodDecl>(D); + // We may want to emit this definition. However, that decision might be // based on computing the linkage, and we have to defer that in case we // are inside of something that will change the method's final linkage, @@ -157,13 +168,13 @@ namespace { // void bar(); // void foo() { bar(); } // } A; - DeferredInlineMethodDefinitions.push_back(D); + DeferredInlineMethodDefinitions.push_back(MD); // Provide some coverage mapping even for methods that aren't emitted. // Don't do this for templated classes though, as they may not be // instantiable. - if (!D->getParent()->getDescribedClassTemplate()) - Builder->AddDeferredUnusedCoverageMapping(D); + if (!MD->getParent()->getDescribedClassTemplate()) + Builder->AddDeferredUnusedCoverageMapping(MD); } /// HandleTagDeclDefinition - This callback is invoked each time a TagDecl |