]> granicus.if.org Git - clang/commitdiff
[MS] Add L__FUNCSIG__ for compatibility
authorReid Kleckner <rnk@google.com>
Thu, 26 Jul 2018 23:18:44 +0000 (23:18 +0000)
committerReid Kleckner <rnk@google.com>
Thu, 26 Jul 2018 23:18:44 +0000 (23:18 +0000)
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

include/clang/AST/Expr.h
include/clang/Basic/TokenKinds.def
lib/AST/Expr.cpp
lib/Parse/ParseExpr.cpp
lib/Parse/ParseTentative.cpp
lib/Sema/SemaExpr.cpp
test/Sema/ms_wide_predefined_expr.cpp

index a4c4769c1a3bcf2705673f4f1f400f0bbbc173ca..ca5bd9516005bfca009ea9f7b1a2a93bb4b69ec5 100644 (file)
@@ -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.
index 7f363dbcc12c113866700d9e1c86e161b6e5d2c2..30cb022f1cba5398048ae5011f891552906643b0 100644 (file)
@@ -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)
 
index 7e652b778b80cf7878ce0d800cbfab2f68b82877..193efa4e097d9e309f622872cb4aeb6a97b16ad1 100644 (file)
@@ -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";
       }
index 6904906403d0d1c73478c8926212f29f8ecde195..4a0e1c5e34130daa6b6045830e7ff0cb94e299d5 100644 (file)
@@ -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();
index 79860545c294108932741e711610ca4f5070dd3b..0603d8e75eeac1444fdb282471622f9e536c733b 100644 (file)
@@ -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) \
index a72f6c3796d64fc9b8389e66c8fc13bd096e0c2e..effaa888f0e5db857cc104e2ca65751b498bcf6a 100644 (file)
@@ -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;
   }
 
index d56d1576cd0c76efc8419b64fb86570ecc43312c..eb6efa5cdbefc6ef2e0d77bb82797f1737374e54 100644 (file)
@@ -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 {