aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2012-05-22 21:28:12 +0000
committerJohn McCall <rjmccall@apple.com>2012-05-22 21:28:12 +0000
commitc052dbb2d8fe0e23e90d81236aab0f864f712b45 (patch)
tree5a99a2c13dbe2d2cabdd32b64b20b595d0c260d9 /lib
parent6c20222da814df4cb1ef97681f0e1e8cb5a01b40 (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.cpp4
-rw-r--r--lib/Parse/ParseDeclCXX.cpp17
-rw-r--r--lib/Sema/SemaDeclAttr.cpp48
-rw-r--r--lib/Sema/SemaType.cpp7
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;