forked from OSchip/llvm-project
[-fms-extensions] Add support for __FUNCDNAME__
Summary: Similar to __FUNCTION__, MSVC exposes the name of the enclosing mangled function name via __FUNCDNAME__. This implementation is very naive and unoptimized, it is expected that __FUNCDNAME__ would be used rarely in practice. Reviewers: rnk, rsmith, thakis CC: cfe-commits, silvas Differential Revision: http://llvm-reviews.chandlerc.com/D2109 llvm-svn: 194181
This commit is contained in:
parent
695c3325af
commit
bed356a9ea
|
@ -1150,6 +1150,7 @@ public:
|
|||
Func,
|
||||
Function,
|
||||
LFunction, // Same as Function, but as wide string.
|
||||
FuncDName,
|
||||
PrettyFunction,
|
||||
/// PrettyFunctionNoVirtual - The same as PrettyFunction, except that the
|
||||
/// 'virtual' keyword is omitted for virtual member functions.
|
||||
|
|
|
@ -349,6 +349,7 @@ KEYWORD(__PRETTY_FUNCTION__ , KEYALL)
|
|||
KEYWORD(typeof , KEYGNU)
|
||||
|
||||
// MS Extensions
|
||||
KEYWORD(__FUNCDNAME__ , KEYMS)
|
||||
KEYWORD(L__FUNCTION__ , KEYMS)
|
||||
KEYWORD(__is_interface_class , KEYMS)
|
||||
KEYWORD(__is_sealed , KEYMS)
|
||||
|
|
|
@ -1661,6 +1661,7 @@ void ASTDumper::VisitPredefinedExpr(const PredefinedExpr *Node) {
|
|||
default: llvm_unreachable("unknown case");
|
||||
case PredefinedExpr::Func: OS << " __func__"; break;
|
||||
case PredefinedExpr::Function: OS << " __FUNCTION__"; break;
|
||||
case PredefinedExpr::FuncDName: OS << " __FUNCDNAME__"; break;
|
||||
case PredefinedExpr::LFunction: OS << " L__FUNCTION__"; break;
|
||||
case PredefinedExpr::PrettyFunction: OS << " __PRETTY_FUNCTION__";break;
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "clang/AST/EvaluatedExprVisitor.h"
|
||||
#include "clang/AST/Expr.h"
|
||||
#include "clang/AST/ExprCXX.h"
|
||||
#include "clang/AST/Mangle.h"
|
||||
#include "clang/AST/RecordLayout.h"
|
||||
#include "clang/AST/StmtVisitor.h"
|
||||
#include "clang/Basic/Builtins.h"
|
||||
|
@ -478,6 +479,30 @@ SourceLocation DeclRefExpr::getLocEnd() const {
|
|||
std::string PredefinedExpr::ComputeName(IdentType IT, const Decl *CurrentDecl) {
|
||||
ASTContext &Context = CurrentDecl->getASTContext();
|
||||
|
||||
if (IT == PredefinedExpr::FuncDName) {
|
||||
if (const NamedDecl *ND = dyn_cast<NamedDecl>(CurrentDecl)) {
|
||||
OwningPtr<MangleContext> MC;
|
||||
MC.reset(Context.createMangleContext());
|
||||
|
||||
if (MC->shouldMangleDeclName(ND)) {
|
||||
SmallString<256> Buffer;
|
||||
llvm::raw_svector_ostream Out(Buffer);
|
||||
if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(ND))
|
||||
MC->mangleCXXCtor(CD, Ctor_Base, Out);
|
||||
else if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(ND))
|
||||
MC->mangleCXXDtor(DD, Dtor_Base, Out);
|
||||
else
|
||||
MC->mangleName(ND, Out);
|
||||
|
||||
Out.flush();
|
||||
if (!Buffer.empty() && Buffer.front() == '\01')
|
||||
return Buffer.substr(1);
|
||||
return Buffer.str();
|
||||
} else
|
||||
return ND->getIdentifier()->getName();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CurrentDecl)) {
|
||||
if (IT != PrettyFunction && IT != PrettyFunctionNoVirtual)
|
||||
return FD->getNameAsString();
|
||||
|
|
|
@ -738,6 +738,9 @@ void StmtPrinter::VisitPredefinedExpr(PredefinedExpr *Node) {
|
|||
case PredefinedExpr::Function:
|
||||
OS << "__FUNCTION__";
|
||||
break;
|
||||
case PredefinedExpr::FuncDName:
|
||||
OS << "__FUNCDNAME__";
|
||||
break;
|
||||
case PredefinedExpr::LFunction:
|
||||
OS << "L__FUNCTION__";
|
||||
break;
|
||||
|
|
|
@ -1944,6 +1944,7 @@ LValue CodeGenFunction::EmitPredefinedLValue(const PredefinedExpr *E) {
|
|||
case PredefinedExpr::Func:
|
||||
case PredefinedExpr::Function:
|
||||
case PredefinedExpr::LFunction:
|
||||
case PredefinedExpr::FuncDName:
|
||||
case PredefinedExpr::PrettyFunction: {
|
||||
PredefinedExpr::IdentType IdentType = E->getIdentType();
|
||||
std::string GlobalVarName;
|
||||
|
@ -1956,6 +1957,9 @@ LValue CodeGenFunction::EmitPredefinedLValue(const PredefinedExpr *E) {
|
|||
case PredefinedExpr::Function:
|
||||
GlobalVarName = "__FUNCTION__.";
|
||||
break;
|
||||
case PredefinedExpr::FuncDName:
|
||||
GlobalVarName = "__FUNCDNAME__.";
|
||||
break;
|
||||
case PredefinedExpr::LFunction:
|
||||
GlobalVarName = "L__FUNCTION__.";
|
||||
break;
|
||||
|
|
|
@ -491,6 +491,8 @@ class CastExpressionIdValidator : public CorrectionCandidateCallback {
|
|||
/// [C11] generic-selection
|
||||
/// '__func__' [C99 6.4.2.2]
|
||||
/// [GNU] '__FUNCTION__'
|
||||
/// [MS] '__FUNCDNAME__'
|
||||
/// [MS] 'L__FUNCTION__'
|
||||
/// [GNU] '__PRETTY_FUNCTION__'
|
||||
/// [GNU] '(' compound-statement ')'
|
||||
/// [GNU] '__builtin_va_arg' '(' assignment-expression ',' type-name ')'
|
||||
|
@ -870,6 +872,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
|
|||
break;
|
||||
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_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);
|
||||
|
|
|
@ -940,6 +940,7 @@ Parser::isExpressionOrTypeSpecifierSimple(tok::TokenKind Kind) {
|
|||
case tok::kw___imag:
|
||||
case tok::kw___real:
|
||||
case tok::kw___FUNCTION__:
|
||||
case tok::kw___FUNCDNAME__:
|
||||
case tok::kw_L__FUNCTION__:
|
||||
case tok::kw___PRETTY_FUNCTION__:
|
||||
case tok::kw___has_nothrow_assign:
|
||||
|
|
|
@ -2855,6 +2855,7 @@ ExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind) {
|
|||
default: llvm_unreachable("Unknown simple primary expr!");
|
||||
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_L__FUNCTION__: IT = PredefinedExpr::LFunction; break;
|
||||
case tok::kw___PRETTY_FUNCTION__: IT = PredefinedExpr::PrettyFunction; break;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue