r205780 - Add support for MSVC's __FUNCSIG__
Reid Kleckner
reid at kleckner.net
Tue Apr 8 11:13:25 PDT 2014
Author: rnk
Date: Tue Apr 8 13:13:24 2014
New Revision: 205780
URL: http://llvm.org/viewvc/llvm-project?rev=205780&view=rev
Log:
Add support for MSVC's __FUNCSIG__
It is very similar to GCC's __PRETTY_FUNCTION__, except it prints the
calling convention.
Reviewers: majnemer
Differential Revision: http://reviews.llvm.org/D3311
Added:
cfe/trunk/test/CodeGenCXX/funcsig.cpp
Modified:
cfe/trunk/include/clang/AST/Expr.h
cfe/trunk/include/clang/Basic/TokenKinds.def
cfe/trunk/lib/AST/ASTDumper.cpp
cfe/trunk/lib/AST/Expr.cpp
cfe/trunk/lib/AST/StmtPrinter.cpp
cfe/trunk/lib/CodeGen/CGExpr.cpp
cfe/trunk/lib/Parse/ParseExpr.cpp
cfe/trunk/lib/Parse/ParseTentative.cpp
cfe/trunk/lib/Sema/SemaExpr.cpp
Modified: cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=205780&r1=205779&r2=205780&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Tue Apr 8 13:13:24 2014
@@ -1164,6 +1164,7 @@ public:
Function,
LFunction, // Same as Function, but as wide string.
FuncDName,
+ FuncSig,
PrettyFunction,
/// PrettyFunctionNoVirtual - The same as PrettyFunction, except that the
/// 'virtual' keyword is omitted for virtual member functions.
Modified: cfe/trunk/include/clang/Basic/TokenKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/TokenKinds.def?rev=205780&r1=205779&r2=205780&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/TokenKinds.def (original)
+++ cfe/trunk/include/clang/Basic/TokenKinds.def Tue Apr 8 13:13:24 2014
@@ -365,6 +365,7 @@ KEYWORD(typeof , KE
// MS Extensions
KEYWORD(__FUNCDNAME__ , KEYMS)
+KEYWORD(__FUNCSIG__ , KEYMS)
KEYWORD(L__FUNCTION__ , KEYMS)
TYPE_TRAIT_1(__is_interface_class, IsInterfaceClass, KEYMS)
TYPE_TRAIT_1(__is_sealed, IsSealed, KEYMS)
Modified: cfe/trunk/lib/AST/ASTDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTDumper.cpp?rev=205780&r1=205779&r2=205780&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTDumper.cpp (original)
+++ cfe/trunk/lib/AST/ASTDumper.cpp Tue Apr 8 13:13:24 2014
@@ -1684,6 +1684,7 @@ void ASTDumper::VisitPredefinedExpr(cons
case PredefinedExpr::FuncDName: OS << " __FUNCDNAME__"; break;
case PredefinedExpr::LFunction: OS << " L__FUNCTION__"; break;
case PredefinedExpr::PrettyFunction: OS << " __PRETTY_FUNCTION__";break;
+ case PredefinedExpr::FuncSig: OS << " __FUNCSIG__"; break;
}
}
Modified: cfe/trunk/lib/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=205780&r1=205779&r2=205780&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Tue Apr 8 13:13:24 2014
@@ -478,7 +478,7 @@ std::string PredefinedExpr::ComputeName(
return "";
}
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CurrentDecl)) {
- if (IT != PrettyFunction && IT != PrettyFunctionNoVirtual)
+ if (IT != PrettyFunction && IT != PrettyFunctionNoVirtual && IT != FuncSig)
return FD->getNameAsString();
SmallString<256> Name;
@@ -494,7 +494,6 @@ std::string PredefinedExpr::ComputeName(
PrintingPolicy Policy(Context.getLangOpts());
std::string Proto;
llvm::raw_string_ostream POut(Proto);
- FD->printQualifiedName(POut, Policy);
const FunctionDecl *Decl = FD;
if (const FunctionDecl* Pattern = FD->getTemplateInstantiationPattern())
@@ -504,6 +503,19 @@ std::string PredefinedExpr::ComputeName(
if (FD->hasWrittenPrototype())
FT = dyn_cast<FunctionProtoType>(AFT);
+ if (IT == FuncSig) {
+ switch (FT->getCallConv()) {
+ case CC_C: POut << "__cdecl "; break;
+ case CC_X86StdCall: POut << "__stdcall "; break;
+ case CC_X86FastCall: POut << "__fastcall "; break;
+ case CC_X86ThisCall: POut << "__thiscall "; break;
+ // Only bother printing the conventions that MSVC knows about.
+ default: break;
+ }
+ }
+
+ FD->printQualifiedName(POut, Policy);
+
POut << "(";
if (FT) {
for (unsigned i = 0, e = Decl->getNumParams(); i != e; ++i) {
Modified: cfe/trunk/lib/AST/StmtPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtPrinter.cpp?rev=205780&r1=205779&r2=205780&view=diff
==============================================================================
--- cfe/trunk/lib/AST/StmtPrinter.cpp (original)
+++ cfe/trunk/lib/AST/StmtPrinter.cpp Tue Apr 8 13:13:24 2014
@@ -789,6 +789,9 @@ void StmtPrinter::VisitPredefinedExpr(Pr
case PredefinedExpr::FuncDName:
OS << "__FUNCDNAME__";
break;
+ case PredefinedExpr::FuncSig:
+ OS << "__FUNCSIG__";
+ break;
case PredefinedExpr::LFunction:
OS << "L__FUNCTION__";
break;
Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=205780&r1=205779&r2=205780&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Tue Apr 8 13:13:24 2014
@@ -1953,33 +1953,27 @@ LValue CodeGenFunction::EmitPredefinedLV
case PredefinedExpr::Function:
case PredefinedExpr::LFunction:
case PredefinedExpr::FuncDName:
+ case PredefinedExpr::FuncSig:
case PredefinedExpr::PrettyFunction: {
PredefinedExpr::IdentType IdentType = E->getIdentType();
- std::string GlobalVarName;
+ std::string GVName;
+ // FIXME: We should use the string literal mangling for the Microsoft C++
+ // ABI so that strings get merged.
switch (IdentType) {
default: llvm_unreachable("Invalid type");
- case PredefinedExpr::Func:
- GlobalVarName = "__func__.";
- break;
- case PredefinedExpr::Function:
- GlobalVarName = "__FUNCTION__.";
- break;
- case PredefinedExpr::FuncDName:
- GlobalVarName = "__FUNCDNAME__.";
- break;
- case PredefinedExpr::LFunction:
- GlobalVarName = "L__FUNCTION__.";
- break;
- case PredefinedExpr::PrettyFunction:
- GlobalVarName = "__PRETTY_FUNCTION__.";
- break;
+ case PredefinedExpr::Func: GVName = "__func__."; break;
+ case PredefinedExpr::Function: GVName = "__FUNCTION__."; break;
+ case PredefinedExpr::FuncDName: GVName = "__FUNCDNAME__."; break;
+ case PredefinedExpr::FuncSig: GVName = "__FUNCSIG__."; break;
+ case PredefinedExpr::LFunction: GVName = "L__FUNCTION__."; break;
+ case PredefinedExpr::PrettyFunction: GVName = "__PRETTY_FUNCTION__."; break;
}
StringRef FnName = CurFn->getName();
if (FnName.startswith("\01"))
FnName = FnName.substr(1);
- GlobalVarName += FnName;
+ GVName += FnName;
// If this is outside of a function use the top level decl.
const Decl *CurDecl = CurCodeDecl;
@@ -2010,15 +2004,13 @@ LValue CodeGenFunction::EmitPredefinedLV
getContext().getTypeSizeInChars(ElemType).getQuantity(),
FunctionName, RawChars);
C = GetAddrOfConstantWideString(RawChars,
- GlobalVarName.c_str(),
+ GVName.c_str(),
getContext(),
E->getType(),
E->getLocation(),
CGM);
} else {
- C = CGM.GetAddrOfConstantCString(FunctionName,
- GlobalVarName.c_str(),
- 1);
+ C = CGM.GetAddrOfConstantCString(FunctionName, GVName.c_str(), 1);
}
return MakeAddrLValue(C, E->getType());
}
Modified: cfe/trunk/lib/Parse/ParseExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExpr.cpp?rev=205780&r1=205779&r2=205780&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExpr.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExpr.cpp Tue Apr 8 13:13:24 2014
@@ -835,6 +835,7 @@ ExprResult Parser::ParseCastExpression(b
case tok::kw___func__: // primary-expression: __func__ [C99 6.4.2.2]
case tok::kw___FUNCTION__: // primary-expression: __FUNCTION__ [GNU]
case tok::kw___FUNCDNAME__: // primary-expression: __FUNCDNAME__ [MS]
+ case tok::kw___FUNCSIG__: // primary-expression: __FUNCSIG__ [MS]
case tok::kw_L__FUNCTION__: // primary-expression: L__FUNCTION__ [MS]
case tok::kw___PRETTY_FUNCTION__: // primary-expression: __P..Y_F..N__ [GNU]
Res = Actions.ActOnPredefinedExpr(Tok.getLocation(), SavedKind);
Modified: cfe/trunk/lib/Parse/ParseTentative.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseTentative.cpp?rev=205780&r1=205779&r2=205780&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseTentative.cpp (original)
+++ cfe/trunk/lib/Parse/ParseTentative.cpp Tue Apr 8 13:13:24 2014
@@ -936,6 +936,7 @@ Parser::isExpressionOrTypeSpecifierSimpl
case tok::kw___real:
case tok::kw___FUNCTION__:
case tok::kw___FUNCDNAME__:
+ case tok::kw___FUNCSIG__:
case tok::kw_L__FUNCTION__:
case tok::kw___PRETTY_FUNCTION__:
case tok::kw___uuidof:
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=205780&r1=205779&r2=205780&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Apr 8 13:13:24 2014
@@ -2872,6 +2872,7 @@ ExprResult Sema::ActOnPredefinedExpr(Sou
case tok::kw___func__: IT = PredefinedExpr::Func; break; // [C99 6.4.2.2]
case tok::kw___FUNCTION__: IT = PredefinedExpr::Function; break;
case tok::kw___FUNCDNAME__: IT = PredefinedExpr::FuncDName; break; // [MS]
+ case tok::kw___FUNCSIG__: IT = PredefinedExpr::FuncSig; break; // [MS]
case tok::kw_L__FUNCTION__: IT = PredefinedExpr::LFunction; break;
case tok::kw___PRETTY_FUNCTION__: IT = PredefinedExpr::PrettyFunction; break;
}
Added: cfe/trunk/test/CodeGenCXX/funcsig.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/funcsig.cpp?rev=205780&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenCXX/funcsig.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/funcsig.cpp Tue Apr 8 13:13:24 2014
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -std=c++11 %s -fms-extensions -fno-rtti -emit-llvm -o - | FileCheck %s
+
+// Similar to predefined-expr.cpp, but not as exhaustive, since it's basically
+// equivalent to __PRETTY_FUNCTION__.
+
+extern "C" int printf(const char *, ...);
+
+void freeFunc(int *, char) {
+ printf("__FUNCSIG__ %s\n\n", __FUNCSIG__);
+}
+// CHECK: private unnamed_addr constant [{{.*}} x i8] c"void __cdecl freeFunc(int *, char)\00"
+
+struct TopLevelClass {
+ void topLevelMethod(int *, char);
+};
+void TopLevelClass::topLevelMethod(int *, char) {
+ printf("__FUNCSIG__ %s\n\n", __FUNCSIG__);
+}
+// CHECK: private unnamed_addr constant [{{.*}} x i8] c"void __thiscall TopLevelClass::topLevelMethod(int *, char)\00"
+
+namespace NS {
+struct NamespacedClass {
+ void namespacedMethod(int *, char);
+};
+void NamespacedClass::namespacedMethod(int *, char) {
+ printf("__FUNCSIG__ %s\n\n", __FUNCSIG__);
+}
+// CHECK: private unnamed_addr constant [{{.*}} x i8] c"void __thiscall NS::NamespacedClass::namespacedMethod(int *, char)\00"
+}
More information about the cfe-commits
mailing list