summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/AST/Expr.h3
-rw-r--r--clang/include/clang/Basic/TokenKinds.def1
-rw-r--r--clang/lib/AST/Expr.cpp10
-rw-r--r--clang/lib/Parse/ParseExpr.cpp3
-rw-r--r--clang/lib/Parse/ParseTentative.cpp1
-rw-r--r--clang/lib/Sema/SemaExpr.cpp5
-rw-r--r--clang/test/Sema/ms_wide_predefined_expr.cpp2
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 {
OpenPOWER on IntegriCloud