From: Reid Kleckner Date: Thu, 26 Jul 2018 23:18:44 +0000 (+0000) Subject: [MS] Add L__FUNCSIG__ for compatibility X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3eabc0d428ed870967574f5cca3771d2beb14777;p=clang [MS] Add L__FUNCSIG__ for compatibility Clang already has L__FUNCTION__ as a workaround for dealing with pre-processor code that expects to be able to do L##__FUNCTION__ in a macro. This patch implements the same logic for __FUNCSIG__. Fixes PR38295. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@338083 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index a4c4769c1a..ca5bd95160 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -1206,9 +1206,10 @@ public: enum IdentType { Func, Function, - LFunction, // Same as Function, but as wide string. + LFunction, // Same as Function, but as wide string. FuncDName, FuncSig, + LFuncSig, // Same as FuncSig, but as as wide string PrettyFunction, /// The same as PrettyFunction, except that the /// 'virtual' keyword is omitted for virtual member functions. diff --git a/include/clang/Basic/TokenKinds.def b/include/clang/Basic/TokenKinds.def index 7f363dbcc1..30cb022f1c 100644 --- a/include/clang/Basic/TokenKinds.def +++ b/include/clang/Basic/TokenKinds.def @@ -425,6 +425,7 @@ KEYWORD(typeof , KEYGNU) KEYWORD(__FUNCDNAME__ , KEYMS) KEYWORD(__FUNCSIG__ , KEYMS) KEYWORD(L__FUNCTION__ , KEYMS) +KEYWORD(L__FUNCSIG__ , KEYMS) TYPE_TRAIT_1(__is_interface_class, IsInterfaceClass, KEYMS) TYPE_TRAIT_1(__is_sealed, IsSealed, KEYMS) diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index 7e652b778b..193efa4e09 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -484,6 +484,8 @@ StringRef PredefinedExpr::getIdentTypeName(PredefinedExpr::IdentType IT) { return "__PRETTY_FUNCTION__"; case FuncSig: return "__FUNCSIG__"; + case LFuncSig: + return "L__FUNCSIG__"; case PrettyFunctionNoVirtual: break; } @@ -536,7 +538,8 @@ std::string PredefinedExpr::ComputeName(IdentType IT, const Decl *CurrentDecl) { return Out.str(); } if (const FunctionDecl *FD = dyn_cast(CurrentDecl)) { - if (IT != PrettyFunction && IT != PrettyFunctionNoVirtual && IT != FuncSig) + if (IT != PrettyFunction && IT != PrettyFunctionNoVirtual && + IT != FuncSig && IT != LFuncSig) return FD->getNameAsString(); SmallString<256> Name; @@ -561,7 +564,7 @@ std::string PredefinedExpr::ComputeName(IdentType IT, const Decl *CurrentDecl) { if (FD->hasWrittenPrototype()) FT = dyn_cast(AFT); - if (IT == FuncSig) { + if (IT == FuncSig || IT == LFuncSig) { switch (AFT->getCallConv()) { case CC_C: POut << "__cdecl "; break; case CC_X86StdCall: POut << "__stdcall "; break; @@ -586,7 +589,8 @@ std::string PredefinedExpr::ComputeName(IdentType IT, const Decl *CurrentDecl) { if (FT->isVariadic()) { if (FD->getNumParams()) POut << ", "; POut << "..."; - } else if ((IT == FuncSig || !Context.getLangOpts().CPlusPlus) && + } else if ((IT == FuncSig || IT == LFuncSig || + !Context.getLangOpts().CPlusPlus) && !Decl->getNumParams()) { POut << "void"; } diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp index 6904906403..4a0e1c5e34 100644 --- a/lib/Parse/ParseExpr.cpp +++ b/lib/Parse/ParseExpr.cpp @@ -617,6 +617,8 @@ class CastExpressionIdValidator : public CorrectionCandidateCallback { /// [GNU] '__FUNCTION__' /// [MS] '__FUNCDNAME__' /// [MS] 'L__FUNCTION__' +/// [MS] '__FUNCSIG__' +/// [MS] 'L__FUNCSIG__' /// [GNU] '__PRETTY_FUNCTION__' /// [GNU] '(' compound-statement ')' /// [GNU] '__builtin_va_arg' '(' assignment-expression ',' type-name ')' @@ -1061,6 +1063,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression, 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_L__FUNCSIG__: // primary-expression: L__FUNCSIG__ [MS] case tok::kw___PRETTY_FUNCTION__: // primary-expression: __P..Y_F..N__ [GNU] Res = Actions.ActOnPredefinedExpr(Tok.getLocation(), SavedKind); ConsumeToken(); diff --git a/lib/Parse/ParseTentative.cpp b/lib/Parse/ParseTentative.cpp index 79860545c2..0603d8e75e 100644 --- a/lib/Parse/ParseTentative.cpp +++ b/lib/Parse/ParseTentative.cpp @@ -1019,6 +1019,7 @@ Parser::isExpressionOrTypeSpecifierSimple(tok::TokenKind Kind) { case tok::kw___FUNCDNAME__: case tok::kw___FUNCSIG__: case tok::kw_L__FUNCTION__: + case tok::kw_L__FUNCSIG__: case tok::kw___PRETTY_FUNCTION__: case tok::kw___uuidof: #define TYPE_TRAIT(N,Spelling,K) \ diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index a72f6c3796..effaa888f0 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -3054,7 +3054,7 @@ ExprResult Sema::BuildPredefinedExpr(SourceLocation Loc, unsigned Length = Str.length(); llvm::APInt LengthI(32, Length + 1); - if (IT == PredefinedExpr::LFunction) { + if (IT == PredefinedExpr::LFunction || IT == PredefinedExpr::LFuncSig) { ResTy = Context.adjustStringLiteralBaseType(Context.WideCharTy.withConst()); SmallString<32> RawChars; @@ -3085,7 +3085,8 @@ ExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind) { 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_L__FUNCTION__: IT = PredefinedExpr::LFunction; break; // [MS] + case tok::kw_L__FUNCSIG__: IT = PredefinedExpr::LFuncSig; break; // [MS] case tok::kw___PRETTY_FUNCTION__: IT = PredefinedExpr::PrettyFunction; break; } diff --git a/test/Sema/ms_wide_predefined_expr.cpp b/test/Sema/ms_wide_predefined_expr.cpp index d56d1576cd..eb6efa5cdb 100644 --- a/test/Sema/ms_wide_predefined_expr.cpp +++ b/test/Sema/ms_wide_predefined_expr.cpp @@ -7,6 +7,8 @@ void abcdefghi12(void) { const wchar_t (*ss)[12] = &STR2WSTR(__FUNCTION__); static int arr[sizeof(STR2WSTR(__FUNCTION__))==12*sizeof(wchar_t) ? 1 : -1]; + const wchar_t (*ss2)[31] = &STR2WSTR(__FUNCSIG__); + static int arr2[sizeof(STR2WSTR(__FUNCSIG__))==31*sizeof(wchar_t) ? 1 : -1]; } namespace PR13206 {