diff options
| -rw-r--r-- | clang/include/clang/AST/Expr.h | 3 | ||||
| -rw-r--r-- | clang/include/clang/Basic/TokenKinds.def | 1 | ||||
| -rw-r--r-- | clang/lib/AST/Expr.cpp | 10 | ||||
| -rw-r--r-- | clang/lib/Parse/ParseExpr.cpp | 3 | ||||
| -rw-r--r-- | clang/lib/Parse/ParseTentative.cpp | 1 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 5 | ||||
| -rw-r--r-- | clang/test/Sema/ms_wide_predefined_expr.cpp | 2 |
7 files changed, 19 insertions, 6 deletions
diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index a4c4769c1a3..ca5bd951600 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/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/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def index 7f363dbcc12..30cb022f1cb 100644 --- a/clang/include/clang/Basic/TokenKinds.def +++ b/clang/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/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 7e652b778b8..193efa4e097 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/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<FunctionDecl>(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<FunctionProtoType>(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/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index 6904906403d..4a0e1c5e341 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/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/clang/lib/Parse/ParseTentative.cpp b/clang/lib/Parse/ParseTentative.cpp index 79860545c29..0603d8e75ee 100644 --- a/clang/lib/Parse/ParseTentative.cpp +++ b/clang/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/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index a72f6c3796d..effaa888f0e 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/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/clang/test/Sema/ms_wide_predefined_expr.cpp b/clang/test/Sema/ms_wide_predefined_expr.cpp index d56d1576cd0..eb6efa5cdbe 100644 --- a/clang/test/Sema/ms_wide_predefined_expr.cpp +++ b/clang/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 { |

