aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Basic/Attr.td50
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td3
-rw-r--r--include/clang/Basic/TokenKinds.def3
-rw-r--r--include/clang/Parse/Parser.h1
-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
-rw-r--r--test/Parser/MicrosoftExtensions.c4
-rw-r--r--test/Parser/MicrosoftExtensions.cpp6
10 files changed, 123 insertions, 20 deletions
diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td
index f4370113fd..72e0c69bf3 100644
--- a/include/clang/Basic/Attr.td
+++ b/include/clang/Basic/Attr.td
@@ -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
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index d2292af468..fba50ece83 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -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|"
diff --git a/include/clang/Basic/TokenKinds.def b/include/clang/Basic/TokenKinds.def
index 9ea2c18693..7c800df7fb 100644
--- a/include/clang/Basic/TokenKinds.def
+++ b/include/clang/Basic/TokenKinds.def
@@ -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)
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h
index 814b45afc7..f3143766cb 100644
--- a/include/clang/Parse/Parser.h
+++ b/include/clang/Parse/Parser.h
@@ -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);
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;
diff --git a/test/Parser/MicrosoftExtensions.c b/test/Parser/MicrosoftExtensions.c
index 6b00534d1d..c20bdb6b14 100644
--- a/test/Parser/MicrosoftExtensions.c
+++ b/test/Parser/MicrosoftExtensions.c
@@ -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)
diff --git a/test/Parser/MicrosoftExtensions.cpp b/test/Parser/MicrosoftExtensions.cpp
index 94047884d6..6219e29f59 100644
--- a/test/Parser/MicrosoftExtensions.cpp
+++ b/test/Parser/MicrosoftExtensions.cpp
@@ -317,3 +317,9 @@ namespace access_protected_PTM {
&A::f;
}
}
+
+namespace Inheritance {
+ class __single_inheritance A;
+ class __multiple_inheritance B;
+ class __virtual_inheritance C;
+}