diff options
author | David Majnemer <david.majnemer@gmail.com> | 2015-05-18 00:05:25 +0000 |
---|---|---|
committer | David Majnemer <david.majnemer@gmail.com> | 2015-05-18 00:05:25 +0000 |
commit | ab4b4a1968b9276d353bb99cfd02e4fa10c7b742 (patch) | |
tree | a1c528214117becb574be2f935390d07d55b3164 /clang | |
parent | 5fb3a4277aaeeb83b3c501026c6b9cd09adaaac8 (diff) | |
download | bcm5719-llvm-ab4b4a1968b9276d353bb99cfd02e4fa10c7b742.tar.gz bcm5719-llvm-ab4b4a1968b9276d353bb99cfd02e4fa10c7b742.zip |
[MS ABI] Function encodings are always encoded in template arguments
llvm-svn: 237547
Diffstat (limited to 'clang')
-rw-r--r-- | clang/lib/AST/MicrosoftMangle.cpp | 23 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/mangle-ms.cpp | 6 |
2 files changed, 20 insertions, 9 deletions
diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp index b8327af6fa5..818ea30b328 100644 --- a/clang/lib/AST/MicrosoftMangle.cpp +++ b/clang/lib/AST/MicrosoftMangle.cpp @@ -250,7 +250,7 @@ public: void mangle(const NamedDecl *D, StringRef Prefix = "\01?"); void mangleName(const NamedDecl *ND); - void mangleFunctionEncoding(const FunctionDecl *FD); + void mangleFunctionEncoding(const FunctionDecl *FD, bool ShouldMangle); void mangleVariableEncoding(const VarDecl *VD); void mangleMemberDataPointer(const CXXRecordDecl *RD, const ValueDecl *VD); void mangleMemberFunctionPointer(const CXXRecordDecl *RD, @@ -383,7 +383,7 @@ void MicrosoftCXXNameMangler::mangle(const NamedDecl *D, StringRef Prefix) { Out << Prefix; mangleName(D); if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) - mangleFunctionEncoding(FD); + mangleFunctionEncoding(FD, Context.shouldMangleDeclName(FD)); else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) mangleVariableEncoding(VD); else { @@ -396,7 +396,8 @@ void MicrosoftCXXNameMangler::mangle(const NamedDecl *D, StringRef Prefix) { } } -void MicrosoftCXXNameMangler::mangleFunctionEncoding(const FunctionDecl *FD) { +void MicrosoftCXXNameMangler::mangleFunctionEncoding(const FunctionDecl *FD, + bool ShouldMangle) { // <type-encoding> ::= <function-class> <function-type> // Since MSVC operates on the type as written and not the canonical type, it @@ -411,13 +412,14 @@ void MicrosoftCXXNameMangler::mangleFunctionEncoding(const FunctionDecl *FD) { // extern "C" functions can hold entities that must be mangled. // As it stands, these functions still need to get expressed in the full // external name. They have their class and type omitted, replaced with '9'. - if (Context.shouldMangleDeclName(FD)) { + if (ShouldMangle) { // First, the function class. mangleFunctionClass(FD); mangleFunctionType(FT, FD); - } else + } else { Out << '9'; + } } void MicrosoftCXXNameMangler::mangleVariableEncoding(const VarDecl *VD) { @@ -556,7 +558,7 @@ MicrosoftCXXNameMangler::mangleMemberFunctionPointer(const CXXRecordDecl *RD, } } else { mangleName(MD); - mangleFunctionEncoding(MD); + mangleFunctionEncoding(MD, /*ShouldMangle=*/true); } } else { // Null single inheritance member functions are encoded as a simple nullptr. @@ -1171,10 +1173,13 @@ void MicrosoftCXXNameMangler::mangleTemplateArg(const TemplateDecl *TD, cast<ValueDecl>(ND)); } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) { const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD); - if (MD && MD->isInstance()) + if (MD && MD->isInstance()) { mangleMemberFunctionPointer(MD->getParent()->getMostRecentDecl(), MD); - else - mangle(FD, "$1?"); + } else { + Out << "$1?"; + mangleName(FD); + mangleFunctionEncoding(FD, /*ShouldMangle=*/true); + } } else { mangle(ND, TA.getParamTypeForDecl()->isReferenceType() ? "$E?" : "$1?"); } diff --git a/clang/test/CodeGenCXX/mangle-ms.cpp b/clang/test/CodeGenCXX/mangle-ms.cpp index 662278b3034..ed2172b7c4d 100644 --- a/clang/test/CodeGenCXX/mangle-ms.cpp +++ b/clang/test/CodeGenCXX/mangle-ms.cpp @@ -380,3 +380,9 @@ void TypedefNewDelete::operator delete[](void *) { } void __vectorcall vector_func() { } // CHECK-DAG: @"\01?vector_func@@YQXXZ" + +template <void (*)(void)> +void fn_tmpl() {} + +template void fn_tmpl<extern_c_func>(); +// CHECK-DAG: @"\01??$fn_tmpl@$1?extern_c_func@@YAXXZ@@YAXXZ" |