diff options
author | John McCall <rjmccall@apple.com> | 2012-05-22 21:28:12 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2012-05-22 21:28:12 +0000 |
commit | c052dbb2d8fe0e23e90d81236aab0f864f712b45 (patch) | |
tree | 5a99a2c13dbe2d2cabdd32b64b20b595d0c260d9 /lib | |
parent | 6c20222da814df4cb1ef97681f0e1e8cb5a01b40 (diff) |
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
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Parse/ParseDecl.cpp | 4 | ||||
-rw-r--r-- | lib/Parse/ParseDeclCXX.cpp | 17 | ||||
-rw-r--r-- | lib/Sema/SemaDeclAttr.cpp | 48 | ||||
-rw-r--r-- | lib/Sema/SemaType.cpp | 7 |
4 files changed, 71 insertions, 5 deletions
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index c3ffd9e135..ac6378035c 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -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); } diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp index 0b5c39680d..c75e138f61 100644 --- a/lib/Parse/ParseDeclCXX.cpp +++ b/lib/Parse/ParseDeclCXX.cpp @@ -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? diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index 6d0e30c77c..ff25645707 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -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: diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index 13a72a5338..f795660d08 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -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; |