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!

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@157288 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
John McCall 2012-05-22 21:28:12 +00:00
Родитель 6c20222da8
Коммит c052dbb2d8
10 изменённых файлов: 123 добавлений и 20 удалений

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

@ -317,3 +317,9 @@ namespace access_protected_PTM {
&A::f;
}
}
namespace Inheritance {
class __single_inheritance A;
class __multiple_inheritance B;
class __virtual_inheritance C;
}