Recognize the MS inheritance attributes and turn them into attributes
authorJohn McCall <rjmccall@apple.com>
Tue, 22 May 2012 21:28:12 +0000 (21:28 +0000)
committerJohn McCall <rjmccall@apple.com>
Tue, 22 May 2012 21:28:12 +0000 (21:28 +0000)
on the RecordDecl.  Persist the MS portability type attributes and
ignore them in Sema rather than the parser.

Patch by João Matos!

llvm-svn: 157288

clang/include/clang/Basic/Attr.td
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/include/clang/Basic/TokenKinds.def
clang/include/clang/Parse/Parser.h
clang/lib/Parse/ParseDecl.cpp
clang/lib/Parse/ParseDeclCXX.cpp
clang/lib/Sema/SemaDeclAttr.cpp
clang/lib/Sema/SemaType.cpp
clang/test/Parser/MicrosoftExtensions.c
clang/test/Parser/MicrosoftExtensions.cpp

index f437011..72e0c69 100644 (file)
@@ -308,14 +308,6 @@ def Destructor : InheritableAttr {
   let Args = [IntArgument<"Priority">];
 }
 
-def DLLExport : InheritableAttr {
-  let Spellings = ["dllexport"];
-}
-
-def DLLImport : InheritableAttr {
-  let Spellings = ["dllimport"];
-}
-
 def ExtVectorType : Attr {
   let Spellings = ["ext_vector_type"];
   let Args = [ExprArgument<"NumElements">];
@@ -336,10 +328,6 @@ def Final : InheritableAttr {
   let SemaHandler = 0;
 }
 
-def MsStruct : InheritableAttr {
-  let Spellings = ["__ms_struct__"];
-}
-
 def Format : InheritableAttr {
   let Spellings = ["format"];
   let Args = [StringArgument<"Type">, IntArgument<"FormatIdx">,
@@ -816,3 +804,41 @@ def SharedLocksRequired : InheritableAttr {
   let LateParsed = 1;
   let TemplateDependent = 1;
 }
+
+// Microsoft-related attributes
+
+def MsStruct : InheritableAttr {
+  let Spellings = ["__ms_struct__"];
+}
+
+def DLLExport : InheritableAttr {
+  let Spellings = ["dllexport"];
+}
+
+def DLLImport : InheritableAttr {
+  let Spellings = ["dllimport"];
+}
+
+def Win64 : InheritableAttr {
+  let Spellings = ["__w64"];
+}
+
+def Ptr32 : InheritableAttr {
+  let Spellings = ["__ptr32"];
+}
+
+def Ptr64 : InheritableAttr {
+  let Spellings = ["__ptr64"];
+}
+
+def SingleInheritance : InheritableAttr {
+  let Spellings = ["__single_inheritance"];
+}
+
+def MultipleInheritance : InheritableAttr {
+  let Spellings = ["__multiple_inheritance"];
+}
+
+def VirtualInheritance : InheritableAttr {
+  let Spellings = ["__virtual_inheritance"];
+}
\ No newline at end of file
index d2292af..fba50ec 100644 (file)
@@ -1630,7 +1630,8 @@ def warn_attribute_wrong_decl_type : Warning<
   "variables and functions|functions and methods|parameters|"
   "functions, methods and blocks|functions, methods, and parameters|"
   "classes|variables|methods|variables, functions and labels|"
-  "fields and global variables|structs}1">;
+  "fields and global variables|structs|"
+  "variables, functions and tag types}1">;
 def err_attribute_wrong_decl_type : Error<
   "%0 attribute only applies to %select{functions|unions|"
   "variables and functions|functions and methods|parameters|"
index 9ea2c18..7c800df 100644 (file)
@@ -496,6 +496,9 @@ KEYWORD(__leave                       , KEYMS | KEYBORLAND)
 KEYWORD(__int64                       , KEYMS)
 KEYWORD(__if_exists                   , KEYMS)
 KEYWORD(__if_not_exists               , KEYMS)
+KEYWORD(__single_inheritance          , KEYMS)
+KEYWORD(__multiple_inheritance        , KEYMS)
+KEYWORD(__virtual_inheritance         , KEYMS)
 ALIAS("__int8"           , char       , KEYMS)
 ALIAS("__int16"          , short      , KEYMS)
 ALIAS("__int32"          , int        , KEYMS)
index 814b45a..f314376 100644 (file)
@@ -1859,6 +1859,7 @@ private:
                                 SourceLocation *endLoc = 0);
   void ParseMicrosoftDeclSpec(ParsedAttributes &attrs);
   void ParseMicrosoftTypeAttributes(ParsedAttributes &attrs);
+  void ParseMicrosoftInheritanceClassAttributes(ParsedAttributes &attrs);
   void ParseBorlandTypeAttributes(ParsedAttributes &attrs);
   void ParseOpenCLAttributes(ParsedAttributes &attrs);
   void ParseOpenCLQualifiers(DeclSpec &DS);
index c3ffd9e..ac63780 100644 (file)
@@ -343,10 +343,6 @@ void Parser::ParseMicrosoftTypeAttributes(ParsedAttributes &attrs) {
          Tok.is(tok::kw___unaligned)) {
     IdentifierInfo *AttrName = Tok.getIdentifierInfo();
     SourceLocation AttrNameLoc = ConsumeToken();
-    if (Tok.is(tok::kw___ptr64) || Tok.is(tok::kw___w64) ||
-        Tok.is(tok::kw___ptr32))
-      // FIXME: Support these properly!
-      continue;
     attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
                  SourceLocation(), 0, 0, true);
   }
index 0b5c396..c75e138 100644 (file)
@@ -900,6 +900,17 @@ Parser::TypeResult Parser::ParseBaseTypeSpecifier(SourceLocation &BaseLoc,
   return Actions.ActOnTypeName(getCurScope(), DeclaratorInfo);
 }
 
+void Parser::ParseMicrosoftInheritanceClassAttributes(ParsedAttributes &attrs) {
+  while (Tok.is(tok::kw___single_inheritance) ||
+         Tok.is(tok::kw___multiple_inheritance) ||
+         Tok.is(tok::kw___virtual_inheritance)) {
+    IdentifierInfo *AttrName = Tok.getIdentifierInfo();
+    SourceLocation AttrNameLoc = ConsumeToken();
+    attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
+                 SourceLocation(), 0, 0, false);
+  }
+}
+
 /// ParseClassSpecifier - Parse a C++ class-specifier [C++ class] or
 /// elaborated-type-specifier [C++ dcl.type.elab]; we can't tell which
 /// until we reach the start of a definition or see a token that
@@ -985,6 +996,12 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
   while (Tok.is(tok::kw___declspec))
     ParseMicrosoftDeclSpec(attrs);
 
+  // Parse inheritance specifiers.
+  if (Tok.is(tok::kw___single_inheritance) ||
+      Tok.is(tok::kw___multiple_inheritance) ||
+      Tok.is(tok::kw___virtual_inheritance))
+      ParseMicrosoftInheritanceClassAttributes(attrs);
+
   // If C++0x attributes exist here, parse them.
   // FIXME: Are we consistent with the ordering of parsing of different
   // styles of attributes?
index 6d0e30c..ff25645 100644 (file)
@@ -3773,6 +3773,38 @@ static void handleUuidAttr(Sema &S, Decl *D, const AttributeList &Attr) {
     S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "uuid";
 }
 
+static void handleInheritanceAttr(Sema &S, Decl *D, const AttributeList &Attr) {
+  if (S.LangOpts.MicrosoftExt) {
+    AttributeList::Kind Kind = Attr.getKind();
+    if (Kind == AttributeList::AT_single_inheritance)
+      D->addAttr(
+          ::new (S.Context) SingleInheritanceAttr(Attr.getRange(), S.Context));
+    else if (Kind == AttributeList::AT_multiple_inheritance)
+      D->addAttr(
+          ::new (S.Context) MultipleInheritanceAttr(Attr.getRange(), S.Context));
+    else if (Kind == AttributeList::AT_virtual_inheritance)
+      D->addAttr(
+          ::new (S.Context) VirtualInheritanceAttr(Attr.getRange(), S.Context));
+  } else
+    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
+}
+
+static void handlePortabilityAttr(Sema &S, Decl *D, const AttributeList &Attr) {
+  if (S.LangOpts.MicrosoftExt) {
+    AttributeList::Kind Kind = Attr.getKind();
+    if (Kind == AttributeList::AT_ptr32)
+      D->addAttr(
+          ::new (S.Context) Ptr32Attr(Attr.getRange(), S.Context));
+    else if (Kind == AttributeList::AT_ptr64)
+      D->addAttr(
+          ::new (S.Context) Ptr64Attr(Attr.getRange(), S.Context));
+    else if (Kind == AttributeList::AT_w64)
+      D->addAttr(
+          ::new (S.Context) Win64Attr(Attr.getRange(), S.Context));
+  } else
+    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
+}
+
 //===----------------------------------------------------------------------===//
 // Top Level Sema Entry Points
 //===----------------------------------------------------------------------===//
@@ -3889,7 +3921,6 @@ static void ProcessInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,
       handleInitPriorityAttr(S, D, Attr); break;
       
   case AttributeList::AT_packed:      handlePackedAttr      (S, D, Attr); break;
-  case AttributeList::AT_ms_struct:    handleMsStructAttr    (S, D, Attr); break;
   case AttributeList::AT_section:     handleSectionAttr     (S, D, Attr); break;
   case AttributeList::AT_unavailable:
     handleAttrWithMessage<UnavailableAttr>(S, D, Attr, "unavailable");
@@ -3949,9 +3980,24 @@ static void ProcessInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,
   case AttributeList::AT_opencl_kernel_function:
     handleOpenCLKernelAttr(S, D, Attr);
     break;
+
+  // Microsoft attributes:
+  case AttributeList::AT_ms_struct:
+    handleMsStructAttr(S, D, Attr);
+    break;
   case AttributeList::AT_uuid:
     handleUuidAttr(S, D, Attr);
     break;
+  case AttributeList::AT_single_inheritance:
+  case AttributeList::AT_multiple_inheritance:
+  case AttributeList::AT_virtual_inheritance:
+    handleInheritanceAttr(S, D, Attr);
+    break;
+  case AttributeList::AT_w64:
+  case AttributeList::AT_ptr32:
+  case AttributeList::AT_ptr64:
+    handlePortabilityAttr(S, D, Attr);
+    break;
 
   // Thread safety attributes:
   case AttributeList::AT_guarded_var:
index 13a72a5..f795660 100644 (file)
@@ -4028,6 +4028,13 @@ static void processTypeAttrs(TypeProcessingState &state, QualType &type,
       attr.setUsedAsTypeAttr();
       break;
 
+    case AttributeList::AT_w64:
+    case AttributeList::AT_ptr32:
+    case AttributeList::AT_ptr64:
+      // FIXME: don't ignore these
+      attr.setUsedAsTypeAttr();
+      break;
+
     case AttributeList::AT_ns_returns_retained:
       if (!state.getSema().getLangOpts().ObjCAutoRefCount)
        break;
index 6b00534..c20bdb6 100644 (file)
@@ -11,11 +11,11 @@ typedef __w64 unsigned long ULONG_PTR, *PULONG_PTR;
 
 void * __ptr64 PtrToPtr64(const void *p)
 {
-  return((void * __ptr64) (unsigned __int64) (ULONG_PTR)p ); // expected-warning {{unknown attribute '__ptr64' ignored}}
+  return((void * __ptr64) (unsigned __int64) (ULONG_PTR)p );
 }
 void * __ptr32 PtrToPtr32(const void *p)
 {
-  return((void * __ptr32) (unsigned __int32) (ULONG_PTR)p ); // expected-warning {{unknown attribute '__ptr32' ignored}}
+  return((void * __ptr32) (unsigned __int32) (ULONG_PTR)p );
 }
 
 void __forceinline InterlockedBitTestAndSet (long *Base, long Bit)
index 9404788..6219e29 100644 (file)
@@ -317,3 +317,9 @@ namespace access_protected_PTM {
     &A::f;
   }
 }
+
+namespace Inheritance {
+  class __single_inheritance A;
+  class __multiple_inheritance B;
+  class __virtual_inheritance C;
+}