vsk created this revision.
vsk added reviewers: teemperor, jasonmolenda, rjmccall.

LLDB may synthesize decls using asm labels. These decls cannot have a
mangle different than the one specified in the label name. I.e., the
mangle-suppression prefix should not be added.

Fixes an expression evaluation failure in lldb's TestVirtual.py on iOS.

rdar://45827323


https://reviews.llvm.org/D67774

Files:
  clang/include/clang/AST/ExternalASTSource.h
  clang/lib/AST/Mangle.cpp
  clang/test/Import/asm-label-mangle/Inputs/asm-label.cpp
  clang/test/Import/asm-label-mangle/test.cpp
  clang/tools/clang-import-test/clang-import-test.cpp
  lldb/include/lldb/Symbol/ClangExternalASTSourceCommon.h

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<const void *, ClangASTMetadata> MetadataMap;
 
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<ImporterSource> 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<ExternalASTMerger>(Target, Sources);
+  auto ES = std::make_unique<MockExternalASTMerger>(Target, Sources);
   CI.getASTContext().setExternalSource(ES.release());
   CI.getASTContext().getTranslationUnitDecl()->setHasExternalVisibleStorage();
 }
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/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/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/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
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to