aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/AST/DeclCXX.h50
-rw-r--r--include/clang/AST/ExprCXX.h59
-rw-r--r--include/clang/AST/RecursiveASTVisitor.h8
-rw-r--r--include/clang/Basic/Attr.td4
-rw-r--r--include/clang/Basic/DeclNodes.td7
-rw-r--r--include/clang/Basic/DiagnosticParseKinds.td16
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td13
-rw-r--r--include/clang/Basic/StmtNodes.td1
-rw-r--r--include/clang/Sema/AttributeList.h89
-rw-r--r--include/clang/Sema/Sema.h6
-rw-r--r--include/clang/Sema/Template.h1
-rw-r--r--include/clang/Serialization/ASTBitCodes.h3
-rw-r--r--lib/AST/Decl.cpp10
-rw-r--r--lib/AST/DeclBase.cpp1
-rw-r--r--lib/AST/Expr.cpp1
-rw-r--r--lib/AST/ExprClassification.cpp1
-rw-r--r--lib/AST/ExprConstant.cpp1
-rw-r--r--lib/AST/ItaniumMangle.cpp1
-rw-r--r--lib/AST/StmtPrinter.cpp12
-rw-r--r--lib/AST/StmtProfile.cpp5
-rw-r--r--lib/CodeGen/CGDecl.cpp1
-rw-r--r--lib/Parse/ParseDecl.cpp122
-rw-r--r--lib/Sema/AttributeList.cpp2
-rw-r--r--lib/Sema/SemaDeclAttr.cpp1
-rw-r--r--lib/Sema/SemaDeclCXX.cpp110
-rw-r--r--lib/Sema/SemaExceptionSpec.cpp3
-rw-r--r--lib/Sema/SemaExpr.cpp69
-rw-r--r--lib/Sema/SemaExprCXX.cpp5
-rw-r--r--lib/Sema/SemaExprMember.cpp20
-rw-r--r--lib/Sema/SemaInit.cpp27
-rw-r--r--lib/Sema/SemaPseudoObject.cpp116
-rw-r--r--lib/Sema/SemaTemplateInstantiateDecl.cpp47
-rw-r--r--lib/Sema/TreeTransform.h26
-rw-r--r--lib/Serialization/ASTCommon.cpp1
-rw-r--r--lib/Serialization/ASTReaderDecl.cpp10
-rw-r--r--lib/Serialization/ASTReaderStmt.cpp12
-rw-r--r--lib/Serialization/ASTWriter.cpp1
-rw-r--r--lib/Serialization/ASTWriterDecl.cpp8
-rw-r--r--lib/Serialization/ASTWriterStmt.cpp10
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngine.cpp1
-rw-r--r--test/Parser/MicrosoftExtensions.cpp29
-rw-r--r--test/SemaCXX/MicrosoftExtensions.cpp124
-rw-r--r--test/SemaObjC/property-user-setter.m2
-rw-r--r--tools/libclang/CIndex.cpp1
-rw-r--r--tools/libclang/CXCursor.cpp1
-rw-r--r--tools/libclang/IndexBody.cpp6
-rw-r--r--tools/libclang/IndexDecl.cpp5
-rw-r--r--tools/libclang/IndexingContext.cpp6
-rw-r--r--tools/libclang/IndexingContext.h3
-rw-r--r--tools/libclang/RecursiveASTVisitor.h5
50 files changed, 1029 insertions, 34 deletions
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index 7afb45c23a..5506d211cc 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -2984,6 +2984,56 @@ public:
friend class ASTDeclReader;
};
+/// An instance of this class represents the declaration of a property
+/// member. This is a Microsoft extension to C++, first introduced in
+/// Visual Studio .NET 2003 as a parallel to similar features in C#
+/// and Managed C++.
+///
+/// A property must always be a non-static class member.
+///
+/// A property member superficially resembles a non-static data
+/// member, except preceded by a property attribute:
+/// __declspec(property(get=GetX, put=PutX)) int x;
+/// Either (but not both) of the 'get' and 'put' names may be omitted.
+///
+/// A reference to a property is always an lvalue. If the lvalue
+/// undergoes lvalue-to-rvalue conversion, then a getter name is
+/// required, and that member is called with no arguments.
+/// If the lvalue is assigned into, then a setter name is required,
+/// and that member is called with one argument, the value assigned.
+/// Both operations are potentially overloaded. Compound assignments
+/// are permitted, as are the increment and decrement operators.
+///
+/// The getter and putter methods are permitted to be overloaded,
+/// although their return and parameter types are subject to certain
+/// restrictions according to the type of the property.
+///
+/// A property declared using an incomplete array type may
+/// additionally be subscripted, adding extra parameters to the getter
+/// and putter methods.
+class MSPropertyDecl : public DeclaratorDecl {
+ IdentifierInfo *GetterId, *SetterId;
+
+public:
+ MSPropertyDecl(DeclContext *DC, SourceLocation L,
+ DeclarationName N, QualType T, TypeSourceInfo *TInfo,
+ SourceLocation StartL, IdentifierInfo *Getter,
+ IdentifierInfo *Setter):
+ DeclaratorDecl(MSProperty, DC, L, N, T, TInfo, StartL), GetterId(Getter),
+ SetterId(Setter) {}
+
+ static MSPropertyDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+
+ static bool classof(const Decl *D) { return D->getKind() == MSProperty; }
+
+ bool hasGetter() const { return GetterId != NULL; }
+ IdentifierInfo* getGetterId() const { return GetterId; }
+ bool hasSetter() const { return SetterId != NULL; }
+ IdentifierInfo* getSetterId() const { return SetterId; }
+
+ friend class ASTDeclReader;
+};
+
/// Insertion operator for diagnostics. This allows sending an AccessSpecifier
/// into a diagnostic with <<.
const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index 04f6fb64cf..3189426f9d 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -29,6 +29,7 @@ class CXXConstructorDecl;
class CXXDestructorDecl;
class CXXMethodDecl;
class CXXTemporary;
+class MSPropertyDecl;
class TemplateArgumentListInfo;
class UuidAttr;
@@ -560,6 +561,64 @@ public:
}
};
+/// A member reference to an MSPropertyDecl. This expression always
+/// has pseudo-object type, and therefore it is typically not
+/// encountered in a fully-typechecked expression except within the
+/// syntactic form of a PseudoObjectExpr.
+class MSPropertyRefExpr : public Expr {
+ Expr *BaseExpr;
+ MSPropertyDecl *TheDecl;
+ SourceLocation MemberLoc;
+ bool IsArrow;
+ NestedNameSpecifierLoc QualifierLoc;
+
+public:
+ MSPropertyRefExpr(Expr *baseExpr, MSPropertyDecl *decl, bool isArrow,
+ QualType ty, ExprValueKind VK,
+ NestedNameSpecifierLoc qualifierLoc,
+ SourceLocation nameLoc)
+ : Expr(MSPropertyRefExprClass, ty, VK, OK_Ordinary,
+ /*type-dependent*/ false, baseExpr->isValueDependent(),
+ baseExpr->isInstantiationDependent(),
+ baseExpr->containsUnexpandedParameterPack()),
+ BaseExpr(baseExpr), TheDecl(decl),
+ MemberLoc(nameLoc), IsArrow(isArrow),
+ QualifierLoc(qualifierLoc) {}
+
+ MSPropertyRefExpr(EmptyShell Empty) : Expr(MSPropertyRefExprClass, Empty) {}
+
+ SourceRange getSourceRange() const LLVM_READONLY {
+ return SourceRange(getLocStart(), getLocEnd());
+ }
+ bool isImplicitAccess() const {
+ return getBaseExpr() && getBaseExpr()->isImplicitCXXThis();
+ }
+ SourceLocation getLocStart() const {
+ if (!isImplicitAccess())
+ return BaseExpr->getLocStart();
+ else if (QualifierLoc)
+ return QualifierLoc.getBeginLoc();
+ else
+ return MemberLoc;
+ }
+ SourceLocation getLocEnd() const { return getMemberLoc(); }
+
+ child_range children() {
+ return child_range((Stmt**)&BaseExpr, (Stmt**)&BaseExpr + 1);
+ }
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == MSPropertyRefExprClass;
+ }
+
+ Expr *getBaseExpr() const { return BaseExpr; }
+ MSPropertyDecl *getPropertyDecl() const { return TheDecl; }
+ bool isArrow() const { return IsArrow; }
+ SourceLocation getMemberLoc() const { return MemberLoc; }
+ NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
+
+ friend class ASTStmtReader;
+};
+
/// CXXUuidofExpr - A microsoft C++ @c __uuidof expression, which gets
/// the _GUID that corresponds to the supplied type or expression.
///
diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h
index 0191964bbf..33534ecc7c 100644
--- a/include/clang/AST/RecursiveASTVisitor.h
+++ b/include/clang/AST/RecursiveASTVisitor.h
@@ -1671,6 +1671,10 @@ bool RecursiveASTVisitor<Derived>::TraverseDeclaratorHelper(DeclaratorDecl *D) {
return true;
}
+DEF_TRAVERSE_DECL(MSPropertyDecl, {
+ TRY_TO(TraverseDeclaratorHelper(D));
+ })
+
DEF_TRAVERSE_DECL(FieldDecl, {
TRY_TO(TraverseDeclaratorHelper(D));
if (D->isBitField())
@@ -2058,6 +2062,10 @@ DEF_TRAVERSE_STMT(CXXTypeidExpr, {
TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc()));
})
+DEF_TRAVERSE_STMT(MSPropertyRefExpr, {
+ TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
+})
+
DEF_TRAVERSE_STMT(CXXUuidofExpr, {
// The child-iterator will pick up the arg if it's an expression,
// but not if it's a type.
diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td
index 37aa332b81..441a79a23b 100644
--- a/include/clang/Basic/Attr.td
+++ b/include/clang/Basic/Attr.td
@@ -928,6 +928,10 @@ def TypeTagForDatatype : InheritableAttr {
// Microsoft-related attributes
+def MsProperty : Attr {
+ let Spellings = [Declspec<"property">];
+}
+
def MsStruct : InheritableAttr {
let Spellings = [Declspec<"ms_struct">];
}
diff --git a/include/clang/Basic/DeclNodes.td b/include/clang/Basic/DeclNodes.td
index 45742bc665..ebcd81252f 100644
--- a/include/clang/Basic/DeclNodes.td
+++ b/include/clang/Basic/DeclNodes.td
@@ -34,14 +34,15 @@ def Named : Decl<1>;
def UnresolvedUsingValue : DDecl<Value>;
def IndirectField : DDecl<Value>;
def Declarator : DDecl<Value, 1>;
+ def Field : DDecl<Declarator>;
+ def ObjCIvar : DDecl<Field>;
+ def ObjCAtDefsField : DDecl<Field>;
+ def MSProperty : DDecl<Declarator>;
def Function : DDecl<Declarator>, DeclContext;
def CXXMethod : DDecl<Function>;
def CXXConstructor : DDecl<CXXMethod>;
def CXXDestructor : DDecl<CXXMethod>;
def CXXConversion : DDecl<CXXMethod>;
- def Field : DDecl<Declarator>;
- def ObjCIvar : DDecl<Field>;
- def ObjCAtDefsField : DDecl<Field>;
def Var : DDecl<Declarator>;
def ImplicitParam : DDecl<Var>;
def ParmVar : DDecl<Var>;
diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td
index 04a433c0a6..788b1cf317 100644
--- a/include/clang/Basic/DiagnosticParseKinds.td
+++ b/include/clang/Basic/DiagnosticParseKinds.td
@@ -527,6 +527,22 @@ def err_ms_declspec_type : Error<
"__declspec attributes must be an identifier or string literal">;
def warn_ms_declspec_unknown : Warning<
"unknown __declspec attribute %0 ignored">, InGroup<UnknownAttributes>;
+def err_ms_property_no_getter_or_putter : Error<
+ "property does not specify a getter or a putter">;
+def err_ms_property_unknown_accessor : Error<
+ "expected 'get' or 'put' in property declaration">;
+def err_ms_property_has_set_accessor : Error<
+ "putter for property must be specified as 'put', not 'set'">;
+def err_ms_property_missing_accessor_kind : Error<
+ "missing 'get=' or 'put='">;
+def err_ms_property_expected_equal : Error<
+ "expected '=' after '%0'">;
+def err_ms_property_duplicate_accessor : Error<
+ "property declaration specifies '%0' accessor twice">;
+def err_ms_property_expected_accessor_name : Error<
+ "expected name of accessor method">;
+def err_ms_property_expected_comma_or_rparen : Error<
+ "expected ',' or ')' at end of property accessor list">;
/// C++ Templates
def err_expected_template : Error<"expected template">;
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 17a7f00b63..cfb1798def 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1810,6 +1810,19 @@ def err_attribute_section_local_variable : Error<
def warn_mismatched_section : Warning<
"section does not match previous declaration">, InGroup<Section>;
+def err_anonymous_property: Error<
+ "anonymous property is not supported">;
+def err_property_is_variably_modified: Error<
+ "property '%0' has a variably modified type">;
+def err_no_getter_for_property : Error<
+ "no getter defined for property '%0'">;
+def err_no_setter_for_property : Error<
+ "no setter defined for property '%0'">;
+def error_cannot_find_suitable_getter : Error<
+ "cannot find suitable getter for property '%0'">;
+def error_cannot_find_suitable_setter : Error<
+ "cannot find suitable setter for property '%0'">;
+
def err_attribute_aligned_not_power_of_two : Error<
"requested alignment is not a power of 2">;
def err_attribute_aligned_greater_than_8192 : Error<
diff --git a/include/clang/Basic/StmtNodes.td b/include/clang/Basic/StmtNodes.td
index 8f6a1c9f98..979555e1a6 100644
--- a/include/clang/Basic/StmtNodes.td
+++ b/include/clang/Basic/StmtNodes.td
@@ -163,6 +163,7 @@ def BlockExpr : DStmt<Expr>;
def OpaqueValueExpr : DStmt<Expr>;
// Microsoft Extensions.
+def MSPropertyRefExpr : DStmt<Expr>;
def CXXUuidofExpr : DStmt<Expr>;
def SEHTryStmt : Stmt;
def SEHExceptStmt : Stmt;
diff --git a/include/clang/Sema/AttributeList.h b/include/clang/Sema/AttributeList.h
index 0f0d2185b0..d5f31779a6 100644
--- a/include/clang/Sema/AttributeList.h
+++ b/include/clang/Sema/AttributeList.h
@@ -96,6 +96,10 @@ private:
/// type_tag_for_datatype attribute.
unsigned IsTypeTagForDatatype : 1;
+ /// True if this has extra information associated with a
+ /// Microsoft __delcspec(property) attribute.
+ unsigned IsProperty : 1;
+
unsigned AttrKind : 8;
/// \brief The location of the 'unavailable' keyword in an
@@ -134,6 +138,11 @@ public:
unsigned LayoutCompatible : 1;
unsigned MustBeNull : 1;
};
+ struct PropertyData {
+ IdentifierInfo *GetterId, *SetterId;
+ PropertyData(IdentifierInfo *getterId, IdentifierInfo *setterId)
+ : GetterId(getterId), SetterId(setterId) {}
+ };
private:
TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() {
@@ -152,6 +161,16 @@ private:
return *reinterpret_cast<const ParsedType *>(this + 1);
}
+ PropertyData &getPropertyDataBuffer() {
+ assert(IsProperty);
+ return *reinterpret_cast<PropertyData*>(this + 1);
+ }
+
+ const PropertyData &getPropertyDataBuffer() const {
+ assert(IsProperty);
+ return *reinterpret_cast<const PropertyData*>(this + 1);
+ }
+
AttributeList(const AttributeList &) LLVM_DELETED_FUNCTION;
void operator=(const AttributeList &) LLVM_DELETED_FUNCTION;
void operator delete(void *) LLVM_DELETED_FUNCTION;
@@ -169,7 +188,8 @@ private:
AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(parmLoc),
EllipsisLoc(ellipsisLoc), NumArgs(numArgs), SyntaxUsed(syntaxUsed),
Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
- IsTypeTagForDatatype(false), NextInPosition(0), NextInPool(0) {
+ IsTypeTagForDatatype(false), IsProperty(false), NextInPosition(0),
+ NextInPool(0) {
if (numArgs) memcpy(getArgsBuffer(), args, numArgs * sizeof(Expr*));
AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
}
@@ -188,7 +208,7 @@ private:
AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(parmLoc), EllipsisLoc(),
NumArgs(0), SyntaxUsed(syntaxUsed),
Invalid(false), UsedAsTypeAttr(false), IsAvailability(true),
- IsTypeTagForDatatype(false),
+ IsTypeTagForDatatype(false), IsProperty(false),
UnavailableLoc(unavailable), MessageExpr(messageExpr),
NextInPosition(0), NextInPool(0) {
new (&getAvailabilitySlot(IntroducedSlot)) AvailabilityChange(introduced);
@@ -208,7 +228,8 @@ private:
AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(argumentKindLoc),
EllipsisLoc(), NumArgs(0), SyntaxUsed(syntaxUsed),
Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
- IsTypeTagForDatatype(true), NextInPosition(NULL), NextInPool(NULL) {
+ IsTypeTagForDatatype(true), IsProperty(false), NextInPosition(NULL),
+ NextInPool(NULL) {
TypeTagForDatatypeData &ExtraData = getTypeTagForDatatypeDataSlot();
new (&ExtraData.MatchingCType) ParsedType(matchingCType);
ExtraData.LayoutCompatible = layoutCompatible;
@@ -225,11 +246,28 @@ private:
AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(parmLoc),
EllipsisLoc(), NumArgs(1), SyntaxUsed(syntaxUsed), Invalid(false),
UsedAsTypeAttr(false), IsAvailability(false),
- IsTypeTagForDatatype(false), NextInPosition(0), NextInPool(0) {
+ IsTypeTagForDatatype(false), IsProperty(false), NextInPosition(0),
+ NextInPool(0) {
new (&getTypeBuffer()) ParsedType(typeArg);
AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
}
+ /// Constructor for microsoft __declspec(property) attribute.
+ AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
+ IdentifierInfo *scopeName, SourceLocation scopeLoc,
+ IdentifierInfo *parmName, SourceLocation parmLoc,
+ IdentifierInfo *getterId, IdentifierInfo *setterId,
+ Syntax syntaxUsed)
+ : AttrName(attrName), ScopeName(scopeName), ParmName(parmName),
+ AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(parmLoc),
+ SyntaxUsed(syntaxUsed),
+ Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
+ IsTypeTagForDatatype(false), IsProperty(true), NextInPosition(0),
+ NextInPool(0) {
+ new (&getPropertyDataBuffer()) PropertyData(getterId, setterId);
+ AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
+ }
+
friend class AttributePool;
friend class AttributeFactory;
@@ -253,6 +291,11 @@ public:
IdentifierInfo *getParameterName() const { return ParmName; }
SourceLocation getParameterLoc() const { return ParmLoc; }
+ /// Is this the Microsoft __declspec(property) attribute?
+ bool isDeclspecPropertyAttribute() const {
+ return IsProperty;
+ }
+
bool isAlignasAttribute() const {
// FIXME: Use a better mechanism to determine this.
return getKind() == AT_Aligned && SyntaxUsed == AS_Keyword;
@@ -379,6 +422,11 @@ public:
return getTypeBuffer();
}
+ const PropertyData &getPropertyData() const {
+ assert(isDeclspecPropertyAttribute() && "Not a __delcspec(property) attribute");
+ return getPropertyDataBuffer();
+ }
+
/// \brief Get an index into the attribute spelling list
/// defined in Attr.td. This index is used by an attribute
/// to pretty print itself.
@@ -402,6 +450,10 @@ public:
TypeTagForDatatypeAllocSize =
sizeof(AttributeList)
+ (sizeof(AttributeList::TypeTagForDatatypeData) + sizeof(void *) - 1)
+ / sizeof(void*) * sizeof(void*),
+ PropertyAllocSize =
+ sizeof(AttributeList)
+ + (sizeof(AttributeList::PropertyData) + sizeof(void *) - 1)
/ sizeof(void*) * sizeof(void*)
};
@@ -548,6 +600,20 @@ public:
parmName, parmLoc,
typeArg, syntaxUsed));
}
+
+ AttributeList *createPropertyAttribute(
+ IdentifierInfo *attrName, SourceRange attrRange,
+ IdentifierInfo *scopeName, SourceLocation scopeLoc,
+ IdentifierInfo *parmName, SourceLocation parmLoc,
+ IdentifierInfo *getterId, IdentifierInfo *setterId,
+ AttributeList::Syntax syntaxUsed) {
+ void *memory = allocate(AttributeFactory::PropertyAllocSize);
+ return add(new (memory) AttributeList(attrName, attrRange,
+ scopeName, scopeLoc,
+ parmName, parmLoc,
+ getterId, setterId,
+ syntaxUsed));
+ }
};
/// addAttributeLists - Add two AttributeLists together
@@ -703,6 +769,21 @@ public:
return attr;
}
+ /// Add microsoft __delspec(property) attribute.
+ AttributeList *
+ addNewPropertyAttr(IdentifierInfo *attrName, SourceRange attrRange,
+ IdentifierInfo *scopeName, SourceLocation scopeLoc,
+ IdentifierInfo *parmName, SourceLocation parmLoc,
+ IdentifierInfo *getterId, IdentifierInfo *setterId,
+ AttributeList::Syntax syntaxUsed) {
+ AttributeList *attr =
+ pool.createPropertyAttribute(attrName, attrRange, scopeName, scopeLoc,
+ parmName, parmLoc, getterId, setterId,
+ syntaxUsed);
+ add(attr);
+ return attr;
+ }
+
AttributeList *addNewInteger(ASTContext &C, IdentifierInfo *name,
SourceLocation loc, int arg) {
AttributeList *attr =
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index 67dacfc8c7..01e646ef4d 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -1586,6 +1586,12 @@ public:
Declarator &D, Expr *BitfieldWidth,
InClassInitStyle InitStyle,
AccessSpecifier AS);
+ MSPropertyDecl *HandleMSProperty(Scope *S, RecordDecl *TagD,
+ SourceLocation DeclStart,
+ Declarator &D, Expr *BitfieldWidth,
+ InClassInitStyle InitStyle,
+ AccessSpecifier AS,
+ AttributeList *MSPropertyAttr);
FieldDecl *CheckFieldDecl(DeclarationName Name, QualType T,
TypeSourceInfo *TInfo,
diff --git a/include/clang/Sema/Template.h b/include/clang/Sema/Template.h
index 8ee8f35ccb..4edfa0a45d 100644
--- a/include/clang/Sema/Template.h
+++ b/include/clang/Sema/Template.h
@@ -401,6 +401,7 @@ namespace clang {
Decl *VisitVarDecl(VarDecl *D);
Decl *VisitAccessSpecDecl(AccessSpecDecl *D);
Decl *VisitFieldDecl(FieldDecl *D);
+ Decl *VisitMSPropertyDecl(MSPropertyDecl *D);
Decl *VisitIndirectFieldDecl(IndirectFieldDecl *D);
Decl *VisitStaticAssertDecl(StaticAssertDecl *D);
Decl *VisitEnumDecl(EnumDecl *D);
diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h
index 9b685ba118..e3f9e0643a 100644
--- a/include/clang/Serialization/ASTBitCodes.h
+++ b/include/clang/Serialization/ASTBitCodes.h
@@ -951,6 +951,8 @@ namespace clang {
DECL_OBJC_PROPERTY_IMPL,
/// \brief A FieldDecl record.
DECL_FIELD,
+ /// \brief A MSPropertyDecl record.
+ DECL_MS_PROPERTY,
/// \brief A VarDecl record.
DECL_VAR,
/// \brief An ImplicitParamDecl record.
@@ -1300,6 +1302,7 @@ namespace clang {
EXPR_ASTYPE, // AsTypeExpr
// Microsoft
+ EXPR_CXX_PROPERTY_REF_EXPR, // MSPropertyRefExpr
EXPR_CXX_UUIDOF_EXPR, // CXXUuidofExpr (of expr).
EXPR_CXX_UUIDOF_TYPE, // CXXUuidofExpr (of type).
STMT_SEH_EXCEPT, // SEHExceptStmt
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 9505d299ab..36044826e8 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -1293,7 +1293,7 @@ bool NamedDecl::isCXXInstanceMember() const {
if (isa<UsingShadowDecl>(D))
D = cast<UsingShadowDecl>(D)->getTargetDecl();
- if (isa<FieldDecl>(D) || isa<IndirectFieldDecl>(D))
+ if (isa<FieldDecl>(D) || isa<IndirectFieldDecl>(D) || isa<MSPropertyDecl>(D))
return true;
if (isa<CXXMethodDecl>(D))
return cast<CXXMethodDecl>(D)->isInstance();
@@ -3226,6 +3226,14 @@ BlockDecl *BlockDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
return new (Mem) BlockDecl(0, SourceLocation());
}
+MSPropertyDecl *MSPropertyDecl::CreateDeserialized(ASTContext &C,
+ unsigned ID) {
+ void *Mem = AllocateDeserializedDecl(C, ID, sizeof(MSPropertyDecl));
+ return new (Mem) MSPropertyDecl(0, SourceLocation(), DeclarationName(),
+ QualType(), 0, SourceLocation(),
+ 0, 0);
+}
+
EnumConstantDecl *EnumConstantDecl::Create(ASTContext &C, EnumDecl *CD,
SourceLocation L,
IdentifierInfo *Id, QualType T,
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp
index bd6d99cd59..3f23f3d855 100644
--- a/lib/AST/DeclBase.cpp
+++ b/lib/AST/DeclBase.cpp
@@ -493,6 +493,7 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) {
case NonTypeTemplateParm:
case ObjCMethod:
case ObjCProperty:
+ case MSProperty:
return IDNS_Ordinary;
case Label:
return IDNS_Label;
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index b97f4d1d3a..748d3084fe 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -2789,6 +2789,7 @@ bool Expr::HasSideEffects(const ASTContext &Ctx) const {
return false;
case CallExprClass:
+ case MSPropertyRefExprClass:
case CompoundAssignOperatorClass:
case VAArgExprClass:
case AtomicExprClass:
diff --git a/lib/AST/ExprClassification.cpp b/lib/AST/ExprClassification.cpp
index 61bc3e2de5..c2a35f42c1 100644
--- a/lib/AST/ExprClassificatio