Index: lib/AST/Mangle.cpp =================================================================== --- lib/AST/Mangle.cpp +++ lib/AST/Mangle.cpp @@ -119,46 +119,37 @@ // over all other naming in the .o file. if (const AsmLabelAttr *ALA = D->getAttr()) { // If we have an asm name, then we use it as the mangling. - - // Adding the prefix can cause problems when one file has a "foo" and - // another has a "\01foo". That is known to happen on ELF with the - // 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. - StringRef UserLabelPrefix = - getASTContext().getTargetInfo().getUserLabelPrefix(); - if (!UserLabelPrefix.empty() && !ALA->getLabel().startswith("llvm.")) + if (!ALA->getLabel().startswith("llvm.")) Out << '\01'; // LLVM IR Marker for __asm("foo") Out << ALA->getLabel(); return; } + // ObjectiveC/C++ cannot support alternate calling conventions due to method + // dispatch. Honour the mangling irrespective of the annotations. + if (const ObjCMethodDecl *OMD = dyn_cast(D)) + return mangleObjCMethodName(OMD, Out); + const ASTContext &ASTContext = getASTContext(); CCMangling CC = getCallingConvMangling(ASTContext, D); bool MCXX = shouldMangleCXXName(D); const TargetInfo &TI = Context.getTargetInfo(); - if (CC == CCM_Other || (MCXX && TI.getCXXABI() == TargetCXXABI::Microsoft)) { - if (const ObjCMethodDecl *OMD = dyn_cast(D)) - mangleObjCMethodName(OMD, Out); - else - mangleCXXName(D, Out); - return; - } - Out << '\01'; + // shouldMangleCXXName lies sometimes for the MS-ABI, so check the CC mangling + // when targeting MS-ABI (it doesnt consider CC which take precedence over + // language). + if (MCXX || (CC == CM_Other && TI.getCXXABI() == TargetCXXABI::Microsoft)) + return mangleCXXName(D, Out); + if (CC == CCM_Std) - Out << '_'; + Out << "\01_"; else if (CC == CCM_Fast) - Out << '@'; + Out << "\01@"; + else if (C == CCM_Vector) + Out << '\01'; - if (!MCXX) - Out << D->getIdentifier()->getName(); - else if (const ObjCMethodDecl *OMD = dyn_cast(D)) - mangleObjCMethodName(OMD, Out); - else - mangleCXXName(D, Out); + Out << D->getIdentifier()->getName(); const FunctionDecl *FD = cast(D); const FunctionType *FT = FD->getType()->castAs(); @@ -197,7 +188,7 @@ if (discriminator == 0) Out << "_block_invoke"; else - Out << "_block_invoke_" << discriminator+1; + Out << "_block_invoke_" << discriminator + 1; } void MangleContext::mangleCtorBlock(const CXXConstructorDecl *CD, Index: test/CodeGen/asm-label.c =================================================================== --- test/CodeGen/asm-label.c +++ test/CodeGen/asm-label.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -triple=i686-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix=LINUX -// RUN: %clang_cc1 -triple=i686-apple-darwin9 -emit-llvm %s -o - | FileCheck %s --check-prefix=DARWIN +// RUN: %clang_cc1 -triple=i686-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -triple=i686-apple-darwin9 -emit-llvm %s -o - | FileCheck %s char *strerror(int) asm("alias"); int x __asm("foo"); @@ -10,13 +10,9 @@ return &y; } -// LINUX: @bar = internal global i32 0 -// LINUX: @foo = common global i32 0 -// LINUX: declare i8* @alias(i32) - -// DARWIN: @"\01bar" = internal global i32 0 -// DARWIN: @"\01foo" = common global i32 0 -// DARWIN: declare i8* @"\01alias"(i32) +// CHECK: @"\01bar" = internal global i32 0 +// CHECK: @"\01foo" = common global i32 0 +// CHECK: declare i8* @"\01alias"(i32) // PR7887 int pr7887_1 asm(""); Index: test/CodeGen/mangle.c =================================================================== --- test/CodeGen/mangle.c +++ test/CodeGen/mangle.c @@ -1,6 +1,7 @@ // RUN: %clang_cc1 -triple i386-pc-linux-gnu -emit-llvm -o - %s | FileCheck %s -// CHECK: @foo +// CHECK: @"\01foo" +// CHECK: @"\01foo7" // Make sure we mangle overloadable, even in C system headers. # 1 "somesystemheader.h" 1 3 4 @@ -9,7 +10,7 @@ // CHECK: @_Z2f0l void __attribute__((__overloadable__)) f0(long b) {} -// CHECK: @bar +// CHECK: @"\01bar" // These should get merged. void foo() __asm__("bar"); @@ -55,7 +56,7 @@ int func(void); extern int func (void) __asm__ ("FUNC"); -// CHECK: @FUNC +// CHECK: @"\01FUNC" int func(void) { return 42; } Index: test/CodeGen/pr9614.c =================================================================== --- test/CodeGen/pr9614.c +++ test/CodeGen/pr9614.c @@ -18,7 +18,7 @@ __builtin_prefetch(0, 0, 1); } -extern inline __attribute__((__always_inline__, __gnu_inline__)) void *memchr(void *__s, int __c, __SIZE_TYPE__ __n) { +extern inline __attribute__((__always_inline__, __gnu_inline__)) void *memchr(const void *__s, int __c, unsigned long __n) { return __builtin_memchr(__s, __c, __n); } @@ -33,13 +33,13 @@ // CHECK-LABEL: define void @f() // CHECK: call void @foo() // CHECK: call i32 @abs(i32 0) -// CHECK: call i8* @strrchr( +// CHECK: call i8* @"\01strrchr"( // CHECK: call void @llvm.prefetch( // CHECK: call i8* @memchr( // CHECK: ret void // CHECK: declare void @foo() // CHECK: declare i32 @abs(i32 -// CHECK: declare i8* @strrchr(i8*, i32) +// CHECK: declare i8* @"\01strrchr"(i8*, i32) // CHECK: declare i8* @memchr( // CHECK: declare void @llvm.prefetch( Index: test/CodeGen/redefine_extname.c =================================================================== --- test/CodeGen/redefine_extname.c +++ test/CodeGen/redefine_extname.c @@ -10,9 +10,9 @@ // __PRAGMA_REDEFINE_EXTNAME should be defined. This will fail if it isn't... int fish() { return fake() + __PRAGMA_REDEFINE_EXTNAME + name; } // Check that the call to fake() is emitted as a call to real() -// CHECK: call i32 @real() +// CHECK: call i32 @"\01real"() // Check that this also works with variables names -// CHECK: load i32, i32* @alias +// CHECK: load i32, i32* @"\01alias" // This is a case when redefenition is deferred *and* we have a local of the // same name. PR23923. Index: test/CodeGenCXX/redefine_extname.cpp =================================================================== --- test/CodeGenCXX/redefine_extname.cpp +++ test/CodeGenCXX/redefine_extname.cpp @@ -13,7 +13,7 @@ statvfs64(&st); // Check that even if there is a structure with redefined name before the // pragma, subsequent function name redefined properly. PR5172, Comment 11. -// CHECK: call i32 @statvfs(%struct.statvfs64* %st) +// CHECK: call i32 @"\01statvfs"(%struct.statvfs64* %st) } // This is a case when redefenition is deferred *and* we have a local of the @@ -25,7 +25,7 @@ } extern "C" { int foo() { return 1; } -// CHECK: define i32 @bar() +// CHECK: define i32 @"\01bar"() } // Check that #pragma redefine_extname applies to C code only, and shouldn't be Index: test/CodeGenObjCXX/mangling.mm =================================================================== --- /dev/null +++ test/CodeGenObjCXX/mangling.mm @@ -0,0 +1,88 @@ +// RUN: %clang_cc1 -triple i686-pc-linux -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK -check-prefix CHECK-IA +// RUN: %clang_cc1 -triple i386-darwin -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK -check-prefix CHECK-IA +// RUN: %clang_cc1 -triple i686-pc-windows-msvc -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK -check-prefix CHECK-MS + +extern "C" void extern_c_function(void) { } +// CHECK: @extern_c_function + +extern "C++" void extern_cpp_function(void) { } +// CHECK-IA: @_Z19extern_cpp_function +// CHECK-MS: @"\01?extern_cpp_function@@YAXXZ" + +void asm_label(void) __asm__("alternate_label"); +void asm_label(void) { } +// CHECK: @"\01alternate_label" + +extern "C++" void extern_cpp_asm_label(void) __asm__("_ZN3cppE"); +extern "C++" void extern_cpp_asm_label(void) { } +// CHECK: @"\01_ZN3cppE" + +#if !defined(_MSC_VER) +__attribute__ (( objc_root )) +@interface I ++ (void) class_method; +- (void) instance_method; ++ (void) class_stdcall_method __attribute__ (( stdcall )); +- (void) instance_stdcall_method __attribute__ (( stdcall )); ++ (void) class_fastcall_method __attribute__ (( fastcall )); +- (void) instance_fastcall_method __attribute__ (( fastcall )); +@end + +@implementation I ++ (void) class_method { } +- (void) instance_method { } ++ (void) class_stdcall_method __attribute__ (( stdcall )) { } +- (void) instance_stdcall_method __attribute__ (( stdcall )) { } ++ (void) class_fastcall_method __attribute__ (( fastcall )) { } +- (void) instance_fastcall_method __attribute__ (( fastcall )) { } +@end + +// CHECK-IA: @"\01+[I class_method]" +// CHECK-IA: @"\01-[I instance_method]" +// CHECK-IA: @"\01+[I class_stdcall_method]" +// CHECK-IA: @"\01-[I instance_stdcall_method]" +// CHECK-IA: @"\01+[I class_fastcall_method]" +// CHECK-IA: @"\01-[I instance_fastcall_method]" +#endif + +extern "C" void __attribute__ (( stdcall )) stdcall_c_function(void) { } +// CHECK-IA: @stdcall_c_function +// CHECK-MS: @"\01_stdcall_c_function@0" +extern "C++" void __attribute__ (( stdcall )) stdcall_cpp_function(void) { } +// CHECK-IA: @_Z20stdcall_cpp_functionv +// CHECK-MS: @"\01?stdcall_cpp_function@@YGXXZ" + +extern "C" void __attribute__ (( fastcall )) fastcall_c_function(void) { } +// CHECK-IA: @fastcall_c_function +// CHECK-MS: @"\01@fastcall_c_function@0" +extern "C++" void __attribute__ (( fastcall )) fastcall_cpp_function(void) { } +// CHECK-IA: @_Z21fastcall_cpp_functionv +// CHECK-MS: @"\01?fastcall_cpp_function@@YIXXZ" + +extern "C" void __attribute__ (( vectorcall )) vectorcall_c_function(void) { } +// CHECK-IA: @vectorcall_c_function +// CHECK-MS: @"\01vectorcall_c_function@@0" +extern "C++" void __attribute__ (( vectorcall )) vectorcall_cpp_function(void) { } +// CHECK-IA: @_Z23vectorcall_cpp_functionv +// CHECK-MS: @"\01?vectorcall_cpp_function@@YQXXZ" + +struct __attribute__ (( dllexport )) S { + void __attribute__ (( thiscall )) thiscall_method(void); + void __attribute__ (( stdcall )) stdcall_method(void); + void __attribute__ (( fastcall )) fastcall_method(void); + void __attribute__ (( vectorcall )) vectorcall_method(void); +}; + +void __attribute__ (( thiscall )) S::thiscall_method(void) { } +// CHECK-IA: @_ZN1S15thiscall_methodEv +// CHECK-MS: @"\01?thiscall_method@S@@QAEXXZ" +void __attribute__ (( stdcall )) S::stdcall_method(void) { } +// CHECK-IA: @_ZN1S14stdcall_methodEv +// CHECK-MS: @"\01?stdcall_method@S@@QAGXXZ" +void __attribute__ (( fastcall )) S::fastcall_method(void) { } +// CHECK-IA: @_ZN1S15fastcall_methodEv +// CHECK-MS: @"\01?fastcall_method@S@@QAIXXZ" +void __attribute__ (( vectorcall )) S::vectorcall_method(void) { } +// CHECK-IA: @_ZN1S17vectorcall_methodEv +// CHECK-MS: @"\01?fastcall_method@S@@QAQXXZ" +