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" +} _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
