// RUN: %clang_cc1 -triple i686-pc-linux-gnu -emit-pch %s -o %t_linux.ast
// RUN: c-index-test -test-print-mangle %t_linux.ast | FileCheck %s --check-prefix=ITANIUM
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-pch %s -o %t_macho.ast
+// RUN: c-index-test -test-print-mangle %t_macho.ast | FileCheck %s --check-prefix=MACHO
+
// RUN: %clang_cc1 -triple i686-pc-win32 -emit-pch %s -o %t_msft.ast
// RUN: c-index-test -test-print-mangle %t_msft.ast | FileCheck %s --check-prefix=MICROSOFT
int foo(int, int);
// ITANIUM: mangled=_Z3fooii
+// MACHO: mangled=__Z3fooii
// MICROSOFT: mangled=?foo@@YAHHH
int foo(float, int);
// ITANIUM: mangled=_Z3foofi
+// MACHO: mangled=__Z3foofi
// MICROSOFT: mangled=?foo@@YAHMH
struct S {
int x, y;
};
// ITANIUM: StructDecl{{.*}}mangled=]
+// MACHO: StructDecl{{.*}}mangled=]
// MICROSOFT: StructDecl{{.*}}mangled=]
int foo(S, S&);
-// ITANIUM: mangled=_Z3foo1SRS
+// ITANIUM: mangled=_Z3foo1SRS_
+// MACHO: mangled=__Z3foo1SRS_
// MICROSOFT: mangled=?foo@@YAHUS
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/DiagnosticCategories.h"
#include "clang/Basic/DiagnosticIDs.h"
+#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/Version.h"
#include "clang/Frontend/ASTUnit.h"
#include "clang/Frontend/CompilerInstance.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Config/llvm-config.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Mangler.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/CrashRecoveryContext.h"
#include "llvm/Support/Format.h"
if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
return cxstring::createEmpty();
- const Decl *D = getCursorDecl(C);
// Mangling only works for functions and variables.
+ const Decl *D = getCursorDecl(C);
if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
return cxstring::createEmpty();
+ // First apply frontend mangling.
const NamedDecl *ND = cast<NamedDecl>(D);
- std::unique_ptr<MangleContext> MC(ND->getASTContext().createMangleContext());
+ ASTContext &Ctx = ND->getASTContext();
+ std::unique_ptr<MangleContext> MC(Ctx.createMangleContext());
- std::string Buf;
- llvm::raw_string_ostream OS(Buf);
- MC->mangleName(ND, OS);
- OS.flush();
+ std::string FrontendBuf;
+ llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
+ MC->mangleName(ND, FrontendBufOS);
- // The Microsoft mangler may insert a special character in the beginning to
- // prevent further mangling. We can strip that for display purposes.
- if (Buf[0] == '\x01') {
- Buf.erase(0, 1);
- }
- return cxstring::createDup(Buf);
+ // Now apply backend mangling.
+ std::unique_ptr<llvm::DataLayout> DL(
+ new llvm::DataLayout(Ctx.getTargetInfo().getTargetDescription()));
+ llvm::Mangler BackendMangler(DL.get());
+
+ std::string FinalBuf;
+ llvm::raw_string_ostream FinalBufOS(FinalBuf);
+ BackendMangler.getNameWithPrefix(FinalBufOS,
+ llvm::Twine(FrontendBufOS.str()));
+
+ return cxstring::createDup(FinalBufOS.str());
}
CXString clang_getCursorDisplayName(CXCursor C) {