]> granicus.if.org Git - clang/commitdiff
Add parser support for __cdecl, __stdcall, and __fastcall.
authorSteve Naroff <snaroff@apple.com>
Thu, 25 Dec 2008 14:16:32 +0000 (14:16 +0000)
committerSteve Naroff <snaroff@apple.com>
Thu, 25 Dec 2008 14:16:32 +0000 (14:16 +0000)
Change preprocessor implementation of _cdecl to reference __cdecl.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@61430 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/TokenKinds.def
lib/Lex/Preprocessor.cpp
lib/Parse/ParseDecl.cpp
test/Parser/MicrosoftExtensions.c [new file with mode: 0644]

index c0a448dfa771194e20443d596bfce297188e048c..686c1b5b2a007d6495fde7f9f2162072b4ac9ebb 100644 (file)
@@ -309,6 +309,9 @@ KEYWORD(__private_extern__          , EXTC90|EXTC99|NOTCPP)
 
 // Microsoft Extension.
 KEYWORD(__declspec                  , EXTC90|EXTC99|EXTCPP|EXTCPP0x)
+KEYWORD(__cdecl                     , EXTC90|EXTC99|EXTCPP|EXTCPP0x)
+KEYWORD(__stdcall                   , EXTC90|EXTC99|EXTCPP|EXTCPP0x)
+KEYWORD(__fastcall                  , EXTC90|EXTC99|EXTCPP|EXTCPP0x)
 
 // Alternate spelling for various tokens.  There are GCC extensions in all
 // languages, but should not be disabled in strict conformance mode.
index 97ff07049f97b474583c44bef340b98980e19f9d..e68a44c188b2cfa1b8f853eb8b59c8a15f2f6fd7 100644 (file)
@@ -483,9 +483,7 @@ static void InitializePredefinedMacros(Preprocessor &PP,
   // Filter out some microsoft extensions when trying to parse in ms-compat
   // mode. 
   if (PP.getLangOptions().Microsoft) {
-    DefineBuiltinMacro(Buf, "__stdcall=");
-    DefineBuiltinMacro(Buf, "__cdecl=");
-    DefineBuiltinMacro(Buf, "_cdecl=");
+    DefineBuiltinMacro(Buf, "_cdecl=__cdecl");
     DefineBuiltinMacro(Buf, "__ptr64=");
     DefineBuiltinMacro(Buf, "__w64=");
     DefineBuiltinMacro(Buf, "__forceinline=");
index a8052dc2904292573d1626f70976d4cdfcae065e..bf75ab0e93e2a6563e6aab6a2525ff3da0484631 100644 (file)
@@ -560,6 +560,15 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
       FuzzyParseMicrosoftDeclSpec();
       continue;
       
+    // Microsoft single token adornments.
+    case tok::kw___cdecl:
+    case tok::kw___stdcall:
+    case tok::kw___fastcall:
+      if (!PP.getLangOptions().Microsoft)
+        goto DoneWithDeclSpec;
+      // Just ignore it.
+      break;
+      
     // storage-class-specifier
     case tok::kw_typedef:
       isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_typedef, Loc, PrevSpec);
@@ -798,6 +807,11 @@ bool Parser::MaybeParseTypeSpecifier(DeclSpec &DS, int& isInvalid,
     ParseTypeofSpecifier(DS);
     return true;
 
+  case tok::kw___cdecl:
+  case tok::kw___stdcall:
+  case tok::kw___fastcall:
+    return PP.getLangOptions().Microsoft;
+
   default:
     // Not a type-specifier; do nothing.
     return false;
@@ -1199,6 +1213,11 @@ bool Parser::isTypeSpecifierQualifier() {
     // GNU ObjC bizarre protocol extension: <proto1,proto2> with implicit 'id'.
   case tok::less:
     return getLang().ObjC1;
+  
+  case tok::kw___cdecl:
+  case tok::kw___stdcall:
+  case tok::kw___fastcall:
+    return PP.getLangOptions().Microsoft;
   }
 }
 
@@ -1268,6 +1287,11 @@ bool Parser::isDeclarationSpecifier() {
     // GNU ObjC bizarre protocol extension: <proto1,proto2> with implicit 'id'.
   case tok::less:
     return getLang().ObjC1;
+    
+  case tok::kw___cdecl:
+  case tok::kw___stdcall:
+  case tok::kw___fastcall:
+    return PP.getLangOptions().Microsoft;
   }
 }
 
@@ -1298,6 +1322,13 @@ void Parser::ParseTypeQualifierListOpt(DeclSpec &DS, bool AttributesAllowed) {
       isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec,
                                  getLang())*2;
       break;
+    case tok::kw___cdecl:
+    case tok::kw___stdcall:
+    case tok::kw___fastcall:
+      if (!PP.getLangOptions().Microsoft)
+        goto DoneWithTypeQuals;
+      // Just ignore it.
+      break;
     case tok::kw___attribute:
       if (AttributesAllowed) {
         DS.AddAttributes(ParseAttributes());
@@ -1305,6 +1336,7 @@ void Parser::ParseTypeQualifierListOpt(DeclSpec &DS, bool AttributesAllowed) {
       }
       // otherwise, FALL THROUGH!
     default:
+      DoneWithTypeQuals:
       // If this is not a type-qualifier token, we're done reading type
       // qualifiers.  First verify that DeclSpec's are consistent.
       DS.Finish(Diags, PP.getSourceManager(), getLang());
@@ -1632,6 +1664,10 @@ void Parser::ParseParenDeclarator(Declarator &D) {
     // present even if the attribute list was empty.
     RequiresArg = true;
   }
+  // Eat any Microsoft extensions.
+  if ((Tok.is(tok::kw___cdecl) || Tok.is(tok::kw___stdcall) ||
+      (Tok.is(tok::kw___fastcall))) && PP.getLangOptions().Microsoft)
+    ConsumeToken();
   
   // If we haven't past the identifier yet (or where the identifier would be
   // stored, if this is an abstract declarator), then this is probably just
diff --git a/test/Parser/MicrosoftExtensions.c b/test/Parser/MicrosoftExtensions.c
new file mode 100644 (file)
index 0000000..dc26c57
--- /dev/null
@@ -0,0 +1,8 @@
+// RUN: clang -fsyntax-only -verify -fms-extensions %s
+__stdcall int func0();
+int __stdcall func();
+typedef int (__cdecl *tptr)();
+void (*__fastcall fastpfunc)();
+extern __declspec(dllimport) void __stdcall VarR4FromDec();
+__declspec(deprecated) __declspec(deprecated) char * __cdecl ltoa( long _Val, char * _DstBuf, int _Radix);
+__declspec(noalias) __declspec(restrict) void * __cdecl xxx( void * _Memory );