summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2015-05-18 00:05:25 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2015-05-18 00:05:25 +0000
commitab4b4a1968b9276d353bb99cfd02e4fa10c7b742 (patch)
treea1c528214117becb574be2f935390d07d55b3164 /clang
parent5fb3a4277aaeeb83b3c501026c6b9cd09adaaac8 (diff)
downloadbcm5719-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.cpp23
-rw-r--r--clang/test/CodeGenCXX/mangle-ms.cpp6
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"
OpenPOWER on IntegriCloud