Recognize the MS inheritance attributes and turn them into attributes

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
This commit is contained in:
John McCall 2012-05-22 21:28:12 +00:00
parent fa6cf4cc9a
commit 8d32c05ed4
10 changed files with 123 additions and 20 deletions

View 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"];
}

View 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|"

View 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)

View 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);

View 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);
}

View 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?

View 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:

View 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;

View 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)

View 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;
}