Index: clang/include/clang/AST/ExternalASTSource.h =================================================================== --- clang/include/clang/AST/ExternalASTSource.h +++ clang/include/clang/AST/ExternalASTSource.h @@ -104,6 +104,10 @@ /// The default implementation of this method is a no-op. virtual Decl *GetExternalDecl(uint32_t ID); + /// Allow use of a global prefix (as defined in DataLayout) in the mangle + /// for asm labels. Defaults to true. + virtual bool UseGlobalPrefixInAsmLabelMangle() { return true; } + /// Resolve a selector ID into a selector. /// /// This operation only needs to be implemented if the AST source Index: clang/lib/AST/Mangle.cpp =================================================================== --- clang/lib/AST/Mangle.cpp +++ clang/lib/AST/Mangle.cpp @@ -127,10 +127,13 @@ // tricks normally used for producing aliases (PR9177). Fortunately the // llvm mangler on ELF is a nop, so we can just avoid adding the \01 // marker. We also avoid adding the marker if this is an alias for an - // LLVM intrinsic. + // LLVM intrinsic, or if the external AST source which provided the decl + // opts out of this behavior. char GlobalPrefix = getASTContext().getTargetInfo().getDataLayout().getGlobalPrefix(); - if (GlobalPrefix && !ALA->getLabel().startswith("llvm.")) + ExternalASTSource *Source = getASTContext().getExternalSource(); + if (GlobalPrefix && !ALA->getLabel().startswith("llvm.") && + (!Source || Source->UseGlobalPrefixInAsmLabelMangle())) Out << '\01'; // LLVM IR Marker for __asm("foo") Out << ALA->getLabel(); Index: clang/test/Import/asm-label-mangle/Inputs/asm-label.cpp =================================================================== --- /dev/null +++ clang/test/Import/asm-label-mangle/Inputs/asm-label.cpp @@ -0,0 +1,4 @@ +struct S1 { + void func1() __asm("someotherfunc") { + } +}; Index: clang/test/Import/asm-label-mangle/test.cpp =================================================================== --- /dev/null +++ clang/test/Import/asm-label-mangle/test.cpp @@ -0,0 +1,9 @@ +// RUN: clang-import-test -dump-ir -import %S/Inputs/asm-label.cpp -expression %s | FileCheck %s + +// The asm label mangle should not include a mangle-suppression prefix. + +// CHECK: define void @someotherfunc + +void expr() { + S1().func1(); +} Index: clang/tools/clang-import-test/clang-import-test.cpp =================================================================== --- clang/tools/clang-import-test/clang-import-test.cpp +++ clang/tools/clang-import-test/clang-import-test.cpp @@ -231,6 +231,18 @@ namespace { +// A mock ExternalASTMerger, used for testing purposes. +class MockExternalASTMerger : public clang::ExternalASTMerger { +public: + MockExternalASTMerger(const ImporterTarget &Target, + llvm::ArrayRef Sources) + : clang::ExternalASTMerger(Target, Sources) {} + + // Disallow use of a global prefix in the mangle for asm labels. This is + // required by lldb. + bool UseGlobalPrefixInAsmLabelMangle() override { return false; } +}; + /// A container for a CompilerInstance (possibly with an ExternalASTMerger /// attached to its ASTContext). /// @@ -265,7 +277,7 @@ for (CIAndOrigins &Import : Imports) Sources.push_back({Import.getASTContext(), Import.getFileManager(), Import.getOriginMap()}); - auto ES = std::make_unique(Target, Sources); + auto ES = std::make_unique(Target, Sources); CI.getASTContext().setExternalSource(ES.release()); CI.getASTContext().getTranslationUnitDecl()->setHasExternalVisibleStorage(); } Index: lldb/include/lldb/Symbol/ClangExternalASTSourceCommon.h =================================================================== --- lldb/include/lldb/Symbol/ClangExternalASTSourceCommon.h +++ lldb/include/lldb/Symbol/ClangExternalASTSourceCommon.h @@ -132,6 +132,11 @@ static ClangExternalASTSourceCommon *Lookup(clang::ExternalASTSource *source); + // Request that no "hidden" prefix is added to the mangle for asm labels. + // LLDB synthesizes many decls as simple asm labels: these synthesized decls + // cannot have a mangle different than the one specified in the label name. + bool UseGlobalPrefixInAsmLabelMangle() override { return false; } + private: typedef llvm::DenseMap MetadataMap;