[cfe-commits] r46838 - in /cfe/trunk: Driver/clang.cpp Lex/Preprocessor.cpp Parse/ParseDecl.cpp Parse/ParseStmt.cpp Sema/SemaDecl.cpp include/clang/Basic/TokenKinds.def include/clang/Parse/Parser.h

Steve Naroff snaroff at apple.com
Wed Feb 6 19:50:06 PST 2008


Author: snaroff
Date: Wed Feb  6 21:50:06 2008
New Revision: 46838

URL: http://llvm.org/viewvc/llvm-project?rev=46838&view=rev
Log:

Implement -fms-extensions. This allows us to fuzzy parse non-standard MS constructs used in "windows.h".

Modified:
    cfe/trunk/Driver/clang.cpp
    cfe/trunk/Lex/Preprocessor.cpp
    cfe/trunk/Parse/ParseDecl.cpp
    cfe/trunk/Parse/ParseStmt.cpp
    cfe/trunk/Sema/SemaDecl.cpp
    cfe/trunk/include/clang/Basic/TokenKinds.def
    cfe/trunk/include/clang/Parse/Parser.h

Modified: cfe/trunk/Driver/clang.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/clang.cpp?rev=46838&r1=46837&r2=46838&view=diff

==============================================================================
--- cfe/trunk/Driver/clang.cpp (original)
+++ cfe/trunk/Driver/clang.cpp Wed Feb  6 21:50:06 2008
@@ -309,6 +309,11 @@
 PascalStrings("fpascal-strings",
               llvm::cl::desc("Recognize and construct Pascal-style "
                              "string literals"));
+                             
+static llvm::cl::opt<bool>
+MSExtensions("fms-extensions",
+             llvm::cl::desc("Accept some non-standard constructs used in "
+                            "Microsoft header files. "));
 
 static llvm::cl::opt<bool>
 WritableStrings("fwritable-strings",
@@ -376,6 +381,7 @@
   Options.Trigraphs = 1; // -trigraphs or -ansi
   Options.DollarIdents = 1;  // FIXME: Really a target property.
   Options.PascalStrings = PascalStrings;
+  Options.Microsoft = MSExtensions;
   Options.WritableStrings = WritableStrings;
   Options.LaxVectorConversions = LaxVectorConversions;
 }

Modified: cfe/trunk/Lex/Preprocessor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Lex/Preprocessor.cpp?rev=46838&r1=46837&r2=46838&view=diff

==============================================================================
--- cfe/trunk/Lex/Preprocessor.cpp (original)
+++ cfe/trunk/Lex/Preprocessor.cpp Wed Feb  6 21:50:06 2008
@@ -424,7 +424,13 @@
     DefineBuiltinMacro(Buf, "__cplusplus=1");
     DefineBuiltinMacro(Buf, "__private_extern__=extern");
   }
-  
+  if (PP.getLangOptions().Microsoft) {
+    DefineBuiltinMacro(Buf, "__stdcall=");
+    DefineBuiltinMacro(Buf, "__cdecl=");
+    DefineBuiltinMacro(Buf, "_cdecl=");
+    DefineBuiltinMacro(Buf, "__ptr64=");
+    DefineBuiltinMacro(Buf, "__forceinline=");
+  }
   // FIXME: Should emit a #line directive here.
 }
 

Modified: cfe/trunk/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Parse/ParseDecl.cpp?rev=46838&r1=46837&r2=46838&view=diff

==============================================================================
--- cfe/trunk/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/Parse/ParseDecl.cpp Wed Feb  6 21:50:06 2008
@@ -36,6 +36,48 @@
   return Actions.ActOnTypeName(CurScope, DeclaratorInfo).Val;
 }
 
+/// FuzzyParseMicrosoftDeclspec. The following construct is Microsoft's
+/// equivalent of GCC's __attribute__. The grammar below is taken from 
+/// Microsoft's website. Unfortunately, it is incomplete. FIXME: If/when we 
+/// parse this for real, we will need to get a real/current grammar.
+///
+///  decl-specifier:
+///    '__declspec' '(' extended-decl-modifier-seq ')'
+///  
+///  extended-decl-modifier-seq:
+///    extended-decl-modifier opt
+///    extended-decl-modifier extended-decl-modifier-seq
+///
+///  extended-decl-modifier:
+///    align( # )
+///    allocate(" segname ")
+///    appdomain
+///    deprecated
+///    dllimport
+///    dllexport
+///    jitintrinsic
+///    naked
+///    noalias
+///    noinline
+///    noreturn
+///    nothrow
+///    novtable
+///    process
+///    property({get=get_func_name|,put=put_func_name})
+///    restrict
+///    selectany
+///    thread
+///    uuid(" ComObjectGUID ")
+///
+void Parser::FuzzyParseMicrosoftDeclspec() {
+  assert(Tok.is(tok::kw___declspec) && "Not an declspec!");
+  ConsumeToken();
+  do {
+    ConsumeAnyToken();
+  } while (ParenCount > 0 && Tok.isNot(tok::eof));
+  return;
+}
+
 /// ParseAttributes - Parse a non-empty attributes list.
 ///
 /// [GNU] attributes:
@@ -441,6 +483,15 @@
     case tok::kw_typedef:
       isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_typedef, Loc, PrevSpec);
       break;
+    case tok::kw___w64: // ignore Microsoft specifier
+      break;
+    case tok::kw___declspec:
+      FuzzyParseMicrosoftDeclspec();
+      // Don't consume the next token, __declspec's can appear one after
+      // another. For example:
+      //   __declspec(deprecated("comment1")) 
+      //   __declspec(deprecated("comment2")) extern unsigned int _winmajor;
+      continue;
     case tok::kw_extern:
       if (DS.isThreadSpecified())
         Diag(Tok, diag::ext_thread_before, "extern");
@@ -465,9 +516,11 @@
       break;
       
     // type-specifiers
+    case tok::kw___int16:
     case tok::kw_short:
       isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec);
       break;
+    case tok::kw___int64:
     case tok::kw_long:
       if (DS.getTypeSpecWidth() != DeclSpec::TSW_long)
         isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec);
@@ -489,9 +542,11 @@
     case tok::kw_void:
       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec);
       break;
+    case tok::kw___int8:
     case tok::kw_char:
       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec);
       break;
+    case tok::kw___int32:
     case tok::kw_int:
       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec);
       break;
@@ -625,6 +680,9 @@
     Tok.is(tok::kw_union) ? DeclSpec::TST_union : DeclSpec::TST_struct;
   SourceLocation StartLoc = ConsumeToken();
 
+  if (getLang().Microsoft && Tok.is(tok::kw___declspec))
+    FuzzyParseMicrosoftDeclspec();
+  
   // Parse the tag portion of this.
   DeclTy *TagDecl;
   if (ParseTag(TagDecl, TagType, StartLoc))
@@ -671,7 +729,8 @@
   
   // If there are no declarators, issue a warning.
   if (Tok.is(tok::semi)) {
-    Diag(SpecQualLoc, diag::w_no_declarators);
+    if (!getLang().Microsoft) // MS allows unnamed struct/union fields.
+      Diag(SpecQualLoc, diag::w_no_declarators);
     return;
   }
 

Modified: cfe/trunk/Parse/ParseStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Parse/ParseStmt.cpp?rev=46838&r1=46837&r2=46838&view=diff

==============================================================================
--- cfe/trunk/Parse/ParseStmt.cpp (original)
+++ cfe/trunk/Parse/ParseStmt.cpp Wed Feb  6 21:50:06 2008
@@ -153,7 +153,9 @@
     break;
     
   case tok::kw_asm:
-    Res = ParseAsmStatement();
+    bool msAsm = false;
+    Res = ParseAsmStatement(msAsm);
+    if (msAsm) return Res;
     SemiError = "asm statement";
     break;
   }
@@ -908,6 +910,14 @@
   return Actions.ActOnReturnStmt(ReturnLoc, R.Val);
 }
 
+Parser::StmtResult Parser::FuzzyParseMicrosoftAsmStatement() {
+  unsigned short savedBraceCount = BraceCount;
+  do {
+    ConsumeAnyToken();
+  } while (BraceCount > savedBraceCount && Tok.isNot(tok::eof));
+  return false;
+}
+
 /// ParseAsmStatement - Parse a GNU extended asm statement.
 /// [GNU] asm-statement:
 ///         'asm' type-qualifier[opt] '(' asm-argument ')' ';'
@@ -923,10 +933,14 @@
 ///         asm-string-literal
 ///         asm-clobbers ',' asm-string-literal
 ///
-Parser::StmtResult Parser::ParseAsmStatement() {
+Parser::StmtResult Parser::ParseAsmStatement(bool &msAsm) {
   assert(Tok.is(tok::kw_asm) && "Not an asm stmt");
   SourceLocation AsmLoc = ConsumeToken();
   
+  if (Tok.is(tok::l_brace)) {
+    msAsm = true;
+    return FuzzyParseMicrosoftAsmStatement();
+  }
   DeclSpec DS;
   SourceLocation Loc = Tok.getLocation();
   ParseTypeQualifierListOpt(DS);

Modified: cfe/trunk/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaDecl.cpp?rev=46838&r1=46837&r2=46838&view=diff

==============================================================================
--- cfe/trunk/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/Sema/SemaDecl.cpp Wed Feb  6 21:50:06 2008
@@ -228,8 +228,9 @@
   DirectoryLookup::DirType OldDirType = HdrInfo.getFileDirFlavor(OldDeclFile);
   DirectoryLookup::DirType NewDirType = HdrInfo.getFileDirFlavor(NewDeclFile);
   
-  if (OldDirType == DirectoryLookup::ExternCSystemHeaderDir || 
-      NewDirType == DirectoryLookup::ExternCSystemHeaderDir)
+  if ((OldDirType == DirectoryLookup::ExternCSystemHeaderDir || 
+       NewDirType == DirectoryLookup::ExternCSystemHeaderDir) ||
+      getLangOptions().Microsoft)
     return New;
     
   // TODO: CHECK FOR CONFLICTS, multiple decls with same name in one scope.

Modified: cfe/trunk/include/clang/Basic/TokenKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/TokenKinds.def?rev=46838&r1=46837&r2=46838&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/TokenKinds.def (original)
+++ cfe/trunk/include/clang/Basic/TokenKinds.def Wed Feb  6 21:50:06 2008
@@ -302,6 +302,14 @@
 // Apple Extension.
 KEYWORD(__private_extern__          , EXTC90|EXTC99|NOTCPP)
 
+// Microsoft Extensions.
+KEYWORD(__w64          , EXTC90|EXTC99|NOTCPP)
+KEYWORD(__declspec     , EXTC90|EXTC99|NOTCPP)
+KEYWORD(__int8         , EXTC90|EXTC99|NOTCPP)
+KEYWORD(__int16        , EXTC90|EXTC99|NOTCPP)
+KEYWORD(__int32        , EXTC90|EXTC99|NOTCPP)
+KEYWORD(__int64        , EXTC90|EXTC99|NOTCPP)
+
 // Alternate spelling for various tokens.  There are GCC extensions in all
 // languages, but should not be disabled in strict conformance mode.
 ALIAS("__attribute__", __attribute)

Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=46838&r1=46837&r2=46838&view=diff

==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Wed Feb  6 21:50:06 2008
@@ -130,6 +130,8 @@
       return ConsumeBracket();
     else if (isTokenBrace())
       return ConsumeBrace();
+    else if (isTokenStringLiteral())
+      return ConsumeStringToken();
     else
       return ConsumeToken();
   }
@@ -402,7 +404,8 @@
   StmtResult ParseContinueStatement();
   StmtResult ParseBreakStatement();
   StmtResult ParseReturnStatement();
-  StmtResult ParseAsmStatement();
+  StmtResult ParseAsmStatement(bool &msAsm);
+  StmtResult FuzzyParseMicrosoftAsmStatement();
   StmtResult ParseObjCAtStatement(SourceLocation atLoc);
   StmtResult ParseObjCTryStmt(SourceLocation atLoc, bool &processAtKeyword);
   StmtResult ParseObjCThrowStmt(SourceLocation atLoc);
@@ -438,6 +441,7 @@
   bool isTypeSpecifierQualifier() const;
 
   TypeTy *ParseTypeName();
+  void FuzzyParseMicrosoftDeclspec();
   AttributeList *ParseAttributes();
   void ParseTypeofSpecifier(DeclSpec &DS);
   





More information about the cfe-commits mailing list