[cfe-commits] Preliminary patch to support MSVC __declspec(property)
Aaron Ballman
aaron at aaronballman.com
Thu Jan 10 06:31:04 PST 2013
I was able to apply the patch to ToT cleanly, but it would not build
for me in MSVC 10. I would get the following error when expanding
StmtNodes.inc:
error C2664: '`anonymous-namespace'::is_good' : cannot convert
parameter 1 from '`anonymous-namespace'::bad' to
'`anonymous-namespace'::good'
C:\llvm\build\tools\clang\include\clang\AST\StmtNodes.inc 485
I think MSPropertyRefExpr doesn't implement some statement node
members as expected, but can't honestly say I've run across this
before.
A few more comments below (mostly nitpicky)...
~Aaron
> diff -ur /home/er91/Downloads/clang-3.2.src/include/clang/AST/Decl.h ./clang/include/clang/AST/Decl.h
> --- /home/er91/Downloads/clang-3.2.src/include/clang/AST/Decl.h 2012-11-10 03:03:35.000000000 +0800
> +++ ./clang/include/clang/AST/Decl.h 2013-01-03 17:51:48.632060006 +0800
> @@ -3053,6 +3053,29 @@
> static bool classof(const Decl *D) { return classofKind(D->getKind()); }
> static bool classofKind(Kind K) { return K == FileScopeAsm; }
> };
> +
> +class MSPropertyDecl : public DeclaratorDecl {
> + llvm::StringRef GetterName, SetterName;
> +
> +public:
> + MSPropertyDecl(DeclContext *DC, SourceLocation L,
> + DeclarationName N, QualType T, TypeSourceInfo *TInfo,
> + SourceLocation StartL, llvm::StringRef Getter,
> + llvm::StringRef Setter):
> + DeclaratorDecl(MSProperty, DC, L, N, T, TInfo, StartL), GetterName(Getter),
> + SetterName(Setter) {}
> +
> + static MSPropertyDecl *CreateDeserialized(ASTContext &C, unsigned ID);
> +
> + static bool classof(const Decl *D) { return D->getKind() == MSProperty; }
> +
> + bool hasGetter() { return !GetterName.empty(); }
> + llvm::StringRef getGetterName() { return GetterName; }
Both of these can be declared as const methods.
> + void setGetterName(llvm::StringRef getterName) { GetterName = getterName; }
> + bool hasSetter() { return !SetterName.empty(); }
This can be a const method as well.
> + void setSetterName(llvm::StringRef setterName) { SetterName = setterName; }
> + llvm::StringRef getSetterName() { return SetterName; }
Same here.
> +};
>
> /// BlockDecl - This represents a block literal declaration, which is like an
> /// unnamed FunctionDecl. For example:
> diff -ur /home/er91/Downloads/clang-3.2.src/include/clang/AST/ExprCXX.h ./clang/include/clang/AST/ExprCXX.h
> --- /home/er91/Downloads/clang-3.2.src/include/clang/AST/ExprCXX.h 2012-11-07 08:12:38.000000000 +0800
> +++ ./clang/include/clang/AST/ExprCXX.h 2013-01-03 17:51:48.880060010 +0800
> @@ -546,6 +546,50 @@
> }
> };
>
> +class MSPropertyRefExpr : public Expr {
> + Expr *BaseExpr;
> + MSPropertyDecl *Decl;
> + SourceLocation StartLoc, EndLoc, MemberLoc;
> + bool IsArrow;
> +
> +public:
> + MSPropertyRefExpr(Expr *baseExpr, MSPropertyDecl *decl, bool isArrow,
> + QualType ty, ExprValueKind VK, SourceLocation memberLoc,
> + SourceLocation startLoc, SourceLocation endLoc)
> + : Expr(MSPropertyRefExprClass, ty, VK, OK_Ordinary,
> + ty->isDependentType(), ty->isDependentType(),
> + ty->isInstantiationDependentType(),
> + ty->containsUnexpandedParameterPack()),
> + BaseExpr(baseExpr), Decl(decl),
> + MemberLoc(memberLoc), IsArrow(isArrow) {}
> +
> + MSPropertyRefExpr(EmptyShell Empty) : Expr(MSPropertyRefExprClass, Empty) {}
> +
> + SourceRange getSourceRange() const LLVM_READONLY {
> + return SourceRange(StartLoc, EndLoc);
> + }
> + void setSourceRange(SourceRange sr) {
> + StartLoc = sr.getBegin();
> + EndLoc = sr.getEnd();
> + }
> +
> + 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; }
> + void setBaseExpr(Expr *baseExpr) { BaseExpr = baseExpr; }
> + MSPropertyDecl* getMSPropertyDecl() const { return Decl; }
> + void setMSPropertyDecl(MSPropertyDecl *decl) { Decl = decl; }
> + bool isArrow() const { return IsArrow; }
> + void setArrow(bool isArrow) { IsArrow = isArrow; }
> + SourceLocation getMemberLoc() const { return MemberLoc; }
> + void setMemberLoc(SourceLocation memberLoc) { MemberLoc = memberLoc; }
> +};
> +
> /// CXXUuidofExpr - A microsoft C++ @c __uuidof expression, which gets
> /// the _GUID that corresponds to the supplied type or expression.
> ///
> diff -ur /home/er91/Downloads/clang-3.2.src/include/clang/AST/RecursiveASTVisitor.h ./clang/include/clang/AST/RecursiveASTVisitor.h
> --- /home/er91/Downloads/clang-3.2.src/include/clang/AST/RecursiveASTVisitor.h 2012-09-26 10:36:12.000000000 +0800
> +++ ./clang/include/clang/AST/RecursiveASTVisitor.h 2013-01-03 17:51:48.932060011 +0800
> @@ -1666,6 +1666,9 @@
> return true;
> }
>
> +DEF_TRAVERSE_DECL(MSPropertyDecl, {
> + TRY_TO(TraverseDeclaratorHelper(D));
> +})
> DEF_TRAVERSE_DECL(FieldDecl, {
> TRY_TO(TraverseDeclaratorHelper(D));
> if (D->isBitField())
> @@ -2053,6 +2056,8 @@
> TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc()));
> })
>
> +DEF_TRAVERSE_STMT(MSPropertyRefExpr, { })
> +
> 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 -ur /home/er91/Downloads/clang-3.2.src/include/clang/Basic/DeclNodes.td ./clang/include/clang/Basic/DeclNodes.td
> --- /home/er91/Downloads/clang-3.2.src/include/clang/Basic/DeclNodes.td 2012-01-02 05:23:57.000000000 +0800
> +++ ./clang/include/clang/Basic/DeclNodes.td 2013-01-03 17:51:49.276060017 +0800
> @@ -45,6 +45,7 @@
> def Var : DDecl<Declarator>;
> def ImplicitParam : DDecl<Var>;
> def ParmVar : DDecl<Var>;
> + def MSProperty : DDecl<Declarator>;
> def NonTypeTemplateParm : DDecl<Declarator>;
> def Template : DDecl<Named, 1>;
> def RedeclarableTemplate : DDecl<Template, 1>;
> diff -ur /home/er91/Downloads/clang-3.2.src/include/clang/Basic/DiagnosticParseKinds.td ./clang/include/clang/Basic/DiagnosticParseKinds.td
> --- /home/er91/Downloads/clang-3.2.src/include/clang/Basic/DiagnosticParseKinds.td 2012-11-05 13:32:00.000000000 +0800
> +++ ./clang/include/clang/Basic/DiagnosticParseKinds.td 2013-01-03 17:51:49.332060017 +0800
> @@ -514,6 +514,18 @@
> "__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_declspec_property_no_getter_or_putter : Error<
> + "no getter or putter in __declspec(property)">;
> +def err_expected_get_or_put : Error<
> + "expect 'get' or 'put' in __declspec(property)">;
> +def err_expected_equal : Error<
> + "expect '=' in __declspec(property)">;
> +def err_duplicate_accessor : Error<
> + "dupilcate accessor in __declspec(property)">;
> +def err_expected_identifier : Error<
> + "expected identifier in __declspec(property)">;
> +def err_expected_comma_or_right_paren : Error<
> + "expected ',' or ')' in __declspec(property)">;
>
> /// C++ Templates
> def err_expected_template : Error<"expected template">;
> diff -ur /home/er91/Downloads/clang-3.2.src/include/clang/Basic/DiagnosticSemaKinds.td ./clang/include/clang/Basic/DiagnosticSemaKinds.td
> --- /home/er91/Downloads/clang-3.2.src/include/clang/Basic/DiagnosticSemaKinds.td 2012-11-10 09:18:17.000000000 +0800
> +++ ./clang/include/clang/Basic/DiagnosticSemaKinds.td 2013-01-03 17:51:49.376060018 +0800
> @@ -1712,6 +1712,15 @@
> def warn_mismatched_section : Warning<
> "section does not match previous declaration">, InGroup<Section>;
>
> +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 -ur /home/er91/Downloads/clang-3.2.src/include/clang/Basic/StmtNodes.td ./clang/include/clang/Basic/StmtNodes.td
> --- /home/er91/Downloads/clang-3.2.src/include/clang/Basic/StmtNodes.td 2012-09-12 08:56:43.000000000 +0800
> +++ ./clang/include/clang/Basic/StmtNodes.td 2013-01-03 17:51:49.460060020 +0800
> @@ -163,6 +163,7 @@
> def OpaqueValueExpr : DStmt<Expr>;
>
> // Microsoft Extensions.
> +def MSPropertyRefExpr : DStmt<Expr>;
> def CXXUuidofExpr : DStmt<Expr>;
> def SEHTryStmt : Stmt;
> def SEHExceptStmt : Stmt;
> diff -ur /home/er91/Downloads/clang-3.2.src/include/clang/Sema/Sema.h ./clang/include/clang/Sema/Sema.h
> --- /home/er91/Downloads/clang-3.2.src/include/clang/Sema/Sema.h 2012-11-07 08:12:38.000000000 +0800
> +++ ./clang/include/clang/Sema/Sema.h 2013-01-03 17:51:49.960060028 +0800
> @@ -1492,6 +1492,12 @@
> 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 -ur /home/er91/Downloads/clang-3.2.src/include/clang/Sema/Template.h ./clang/include/clang/Sema/Template.h
> --- /home/er91/Downloads/clang-3.2.src/include/clang/Sema/Template.h 2012-09-18 12:52:05.000000000 +0800
> +++ ./clang/include/clang/Sema/Template.h 2013-01-03 17:51:49.972060029 +0800
> @@ -391,6 +391,7 @@
> 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 -ur /home/er91/Downloads/clang-3.2.src/include/clang/Serialization/ASTBitCodes.h ./clang/include/clang/Serialization/ASTBitCodes.h
> --- /home/er91/Downloads/clang-3.2.src/include/clang/Serialization/ASTBitCodes.h 2012-11-01 04:59:50.000000000 +0800
> +++ ./clang/include/clang/Serialization/ASTBitCodes.h 2013-01-03 17:51:49.988060029 +0800
> @@ -906,6 +906,8 @@
> DECL_OBJC_PROPERTY_IMPL,
> /// \brief A FieldDecl record.
> DECL_FIELD,
> + /// \brief A __delcpec(property) record.
> + DECL_MS_PROPERTY,
> /// \brief A VarDecl record.
> DECL_VAR,
> /// \brief An ImplicitParamDecl record.
> @@ -1251,6 +1253,7 @@
> 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 -ur /home/er91/Downloads/clang-3.2.src/lib/AST/DeclBase.cpp ./clang/lib/AST/DeclBase.cpp
> --- /home/er91/Downloads/clang-3.2.src/lib/AST/DeclBase.cpp 2012-09-11 05:20:09.000000000 +0800
> +++ ./clang/lib/AST/DeclBase.cpp 2013-01-03 17:51:51.812060059 +0800
> @@ -472,6 +472,7 @@
> case NonTypeTemplateParm:
> case ObjCMethod:
> case ObjCProperty:
> + case MSProperty:
> return IDNS_Ordinary;
> case Label:
> return IDNS_Label;
> diff -ur /home/er91/Downloads/clang-3.2.src/lib/AST/Decl.cpp ./clang/lib/AST/Decl.cpp
> --- /home/er91/Downloads/clang-3.2.src/lib/AST/Decl.cpp 2012-11-12 12:10:23.000000000 +0800
> +++ ./clang/lib/AST/Decl.cpp 2013-01-03 17:51:51.800060060 +0800
> @@ -994,7 +994,7 @@
> 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();
> @@ -2918,6 +2918,13 @@
> 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(),
> + llvm::StringRef(), llvm::StringRef());
> +}
> +
> EnumConstantDecl *EnumConstantDecl::Create(ASTContext &C, EnumDecl *CD,
> SourceLocation L,
> IdentifierInfo *Id, QualType T,
> diff -ur /home/er91/Downloads/clang-3.2.src/lib/AST/ExprClassification.cpp ./clang/lib/AST/ExprClassification.cpp
> --- /home/er91/Downloads/clang-3.2.src/lib/AST/ExprClassification.cpp 2012-09-12 08:56:43.000000000 +0800
> +++ ./clang/lib/AST/ExprClassification.cpp 2013-01-03 17:51:51.892060061 +0800
> @@ -135,6 +135,7 @@
> // FIXME: ObjC++0x might have different rules
> case Expr::ObjCIvarRefExprClass:
> case Expr::FunctionParmPackExprClass:
> + case Expr::MSPropertyRefExprClass:
> return Cl::CL_LValue;
>
> // C99 6.5.2.5p5 says that compound literals are lvalues.
> diff -ur /home/er91/Downloads/clang-3.2.src/lib/AST/ExprConstant.cpp ./clang/lib/AST/ExprConstant.cpp
> --- /home/er91/Downloads/clang-3.2.src/lib/AST/ExprConstant.cpp 2012-10-18 07:52:07.000000000 +0800
> +++ ./clang/lib/AST/ExprConstant.cpp 2013-01-03 17:51:51.916060061 +0800
> @@ -6448,6 +6448,7 @@
> case Expr::CXXDynamicCastExprClass:
> case Expr::CXXTypeidExprClass:
> case Expr::CXXUuidofExprClass:
> + case Expr::MSPropertyRefExprClass:
> case Expr::CXXNullPtrLiteralExprClass:
> case Expr::UserDefinedLiteralClass:
> case Expr::CXXThisExprClass:
> diff -ur /home/er91/Downloads/clang-3.2.src/lib/AST/Expr.cpp ./clang/lib/AST/Expr.cpp
> --- /home/er91/Downloads/clang-3.2.src/lib/AST/Expr.cpp 2012-11-09 02:41:43.000000000 +0800
> +++ ./clang/lib/AST/Expr.cpp 2013-01-03 17:51:51.888060061 +0800
> @@ -2764,6 +2764,7 @@
> return false;
>
> case CallExprClass:
> + case MSPropertyRefExprClass:
> case CompoundAssignOperatorClass:
> case VAArgExprClass:
> case AtomicExprClass:
> diff -ur /home/er91/Downloads/clang-3.2.src/lib/AST/ItaniumMangle.cpp ./clang/lib/AST/ItaniumMangle.cpp
> --- /home/er91/Downloads/clang-3.2.src/lib/AST/ItaniumMangle.cpp 2012-10-04 12:58:17.000000000 +0800
> +++ ./clang/lib/AST/ItaniumMangle.cpp 2013-01-03 17:51:51.960060062 +0800
> @@ -2367,6 +2367,7 @@
> case Expr::ImplicitValueInitExprClass:
> case Expr::ParenListExprClass:
> case Expr::LambdaExprClass:
> + case Expr::MSPropertyRefExprClass:
> llvm_unreachable("unexpected statement kind");
>
> // FIXME: invent manglings for all these.
> diff -ur /home/er91/Downloads/clang-3.2.src/lib/AST/StmtPrinter.cpp ./clang/lib/AST/StmtPrinter.cpp
> --- /home/er91/Downloads/clang-3.2.src/lib/AST/StmtPrinter.cpp 2012-10-24 04:26:57.000000000 +0800
> +++ ./clang/lib/AST/StmtPrinter.cpp 2013-01-03 18:48:29.756117478 +0800
> @@ -1224,6 +1224,15 @@
> OS << ")";
> }
>
> +void StmtPrinter::VisitMSPropertyRefExpr(MSPropertyRefExpr *Node) {
> + PrintExpr(Node->getBaseExpr());
> + if (Node->isArrow())
> + OS << "->";
> + else
> + OS << ".";
> + OS << Node->getMSPropertyDecl()->getName();
> +}
> +
> void StmtPrinter::VisitUserDefinedLiteral(UserDefinedLiteral *Node) {
> switch (Node->getLiteralOperatorKind()) {
> case UserDefinedLiteral::LOK_Raw:
> Only in ./clang/lib/AST: StmtPrinter.cpp~
> diff -ur /home/er91/Downloads/clang-3.2.src/lib/AST/StmtProfile.cpp ./clang/lib/AST/StmtProfile.cpp
> --- /home/er91/Downloads/clang-3.2.src/lib/AST/StmtProfile.cpp 2012-09-26 10:36:12.000000000 +0800
> +++ ./clang/lib/AST/StmtProfile.cpp 2013-01-03 17:51:52.072060064 +0800
> @@ -766,6 +766,11 @@
> VisitType(S->getTypeOperand());
> }
>
> +void StmtProfiler::VisitMSPropertyRefExpr(const MSPropertyRefExpr *S) {
> + VisitExpr(S);
> + VisitDecl(S->getMSPropertyDecl());
> +}
> +
> void StmtProfiler::VisitCXXThisExpr(const CXXThisExpr *S) {
> VisitExpr(S);
> ID.AddBoolean(S->isImplicit());
> diff -ur /home/er91/Downloads/clang-3.2.src/lib/CodeGen/CGDecl.cpp ./clang/lib/CodeGen/CGDecl.cpp
> --- /home/er91/Downloads/clang-3.2.src/lib/CodeGen/CGDecl.cpp 2012-11-02 06:30:59.000000000 +0800
> +++ ./clang/lib/CodeGen/CGDecl.cpp 2013-01-03 17:51:52.560060072 +0800
> @@ -45,6 +45,7 @@
> case Decl::CXXDestructor:
> case Decl::CXXConversion:
> case Decl::Field:
> + case Decl::MSProperty:
> case Decl::IndirectField:
> case Decl::ObjCIvar:
> case Decl::ObjCAtDefsField:
> diff -ur /home/er91/Downloads/clang-3.2.src/lib/Parse/ParseDecl.cpp ./clang/lib/Parse/ParseDecl.cpp
> --- /home/er91/Downloads/clang-3.2.src/lib/Parse/ParseDecl.cpp 2012-11-07 03:34:54.000000000 +0800
> +++ ./clang/lib/Parse/ParseDecl.cpp 2013-01-03 17:51:54.300060101 +0800
> @@ -363,17 +363,60 @@
> // The property declspec is more complex in that it can take one or two
> // assignment expressions as a parameter, but the lhs of the assignment
> // must be named get or put.
> - //
> - // For right now, we will just skip to the closing right paren of the
> - // property expression.
> - //
> - // FIXME: we should deal with __declspec(property) at some point because it
> - // is used in the platform SDK headers for the Parallel Patterns Library
> - // and ATL.
> BalancedDelimiterTracker T(*this, tok::l_paren);
> if (T.expectAndConsume(diag::err_expected_lparen_after,
> Ident->getNameStart(), tok::r_paren))
> return;
> + unsigned AccessorCount = 0;
> + llvm::StringRef PrevAccessorType;
> + IdentifierInfo *GetterName = 0, *SetterName = 0;
> + while (true) {
> + if (!Tok.is(tok::identifier) ||
> + ((Tok.getIdentifierInfo()->getName() != "get")
> + && (Tok.getIdentifierInfo()->getName() != "put"))) {
> + Diag(Tok.getLocation(), diag::err_expected_get_or_put);
> + break;
> + }
> + if (PrevAccessorType == Tok.getIdentifierInfo()->getName()) {
> + Diag(Tok.getLocation(), diag::err_duplicate_accessor);
> + break;
> + }
> + PrevAccessorType = Tok.getIdentifierInfo()->getName();
This may be nit picky, or contrary to someone else's recommendation,
but it strikes me as strange to make this a parser problem instead of
a semantics problem.
Also, this will fail when given input like:
__declspec( property( get=foo, put=bar, get=foobar ) )
> + ConsumeAnyToken();
> +
> + if (!Tok.is(tok::equal)) {
> + Diag(Tok.getLocation(), diag::err_expected_equal);
> + break;
> + }
> + ConsumeAnyToken();
> +
> + if (!Tok.is(tok::identifier)) {
> + Diag(Tok.getLocation(), diag::err_expected_identifier);
> + break;
> + }
> + if (PrevAccessorType == "get")
> + GetterName = Tok.getIdentifierInfo();
> + else
> + SetterName = Tok.getIdentifierInfo();
> + AccessorCount++;
> + ConsumeAnyToken();
> +
> + if (Tok.is(tok::comma)) {
> + ConsumeAnyToken();
> + continue;
> + } else if (Tok.is(tok::r_paren)) {
> + break;
> + } else {
> + Diag(Tok.getLocation(), diag::err_expected_comma_or_right_paren);
> + break;
> + }
> + }
> + if (AccessorCount == 0)
> + Diag(Loc, diag::err_ms_declspec_property_no_getter_or_putter);
> + else
> + // Use "scopeName" to store GetterName and "parmName" to store SetterName
> + Attrs.addNew(Ident, Loc, GetterName, Loc, SetterName, SourceLocation(),
> + 0, 0, AttributeList::AS_Declspec);
> T.skipToEnd();
> } else {
> // We don't recognize this as a valid declspec, but instead of creating the
> diff -ur /home/er91/Downloads/clang-3.2.src/lib/Sema/SemaDecl.cpp ./clang/lib/Sema/SemaDecl.cpp
> --- /home/er91/Downloads/clang-3.2.src/lib/Sema/SemaDecl.cpp 2012-11-10 07:03:14.000000000 +0800
> +++ ./clang/lib/Sema/SemaDecl.cpp 2013-01-03 19:13:44.808143078 +0800
> @@ -6512,6 +6512,13 @@
> /// initialization rather than copy initialization.
> void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init,
> bool DirectInit, bool TypeMayContainAuto) {
> + if (!Init->getType().isNull()
> + && (Init->getType()->getAsPlaceholderType() != NULL)) {
> + ExprResult result = CheckPlaceholderExpr(Init);
> + if (result.isInvalid()) return;
> + Init = result.take();
> + }
> +
> // If there is no declaration, there was an error parsing it. Just ignore
> // the initializer.
> if (RealDecl == 0 || RealDecl->isInvalidDecl())
> @@ -9542,6 +9549,98 @@
> return NewFD;
> }
>
> +/// HandleMSProperty - Analyze a __delcspec(property) field of a C++ class.
> +///
> +MSPropertyDecl *Sema::HandleMSProperty(Scope *S, RecordDecl *Record,
> + SourceLocation DeclStart,
> + Declarator &D, Expr *BitWidth,
> + InClassInitStyle InitStyle,
> + AccessSpecifier AS,
> + AttributeList *MSPropertyAttr) {
> + IdentifierInfo *II = D.getIdentifier();
> + SourceLocation Loc = DeclStart;
> + if (II) Loc = D.getIdentifierLoc();
> +
> + TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
> + QualType T = TInfo->getType();
> + if (getLangOpts().CPlusPlus) {
> + CheckExtraCXXDefaultArguments(D);
> +
> + if (DiagnoseUnexpandedParameterPack(D.getIdentifierLoc(), TInfo,
> + UPPC_DataMemberType)) {
> + D.setInvalidType();
> + T = Context.IntTy;
> + TInfo = Context.getTrivialTypeSourceInfo(T, Loc);
> + }
> + }
> +
> + DiagnoseFunctionSpecifiers(D);
> +
> + if (D.getDeclSpec().isThreadSpecified())
> + Diag(D.getDeclSpec().getThreadSpecLoc(), diag::err_invalid_thread);
> + if (D.getDeclSpec().isConstexprSpecified())
> + Diag(D.getDeclSpec().getConstexprSpecLoc(), diag::err_invalid_constexpr)
> + << 2;
> +
> + // Check to see if this name was declared as a member previously
> + NamedDecl *PrevDecl = 0;
> + LookupResult Previous(*this, II, Loc, LookupMemberName, ForRedeclaration);
> + LookupName(Previous, S);
> + switch (Previous.getResultKind()) {
> + case LookupResult::Found:
> + case LookupResult::FoundUnresolvedValue:
> + PrevDecl = Previous.getAsSingle<NamedDecl>();
> + break;
> +
> + case LookupResult::FoundOverloaded:
> + PrevDecl = Previous.getRepresentativeDecl();
> + break;
> +
> + case LookupResult::NotFound:
> + case LookupResult::NotFoundInCurrentInstantiation:
> + case LookupResult::Ambiguous:
> + break;
> + }
> + Previous.suppressDiagnostics();
> +
> + if (PrevDecl && PrevDecl->isTemplateParameter()) {
> + // Maybe we will complain about the shadowed template parameter.
> + DiagnoseTemplateParameterShadow(D.getIdentifierLoc(), PrevDecl);
> + // Just pretend that we didn't see the previous declaration.
> + PrevDecl = 0;
> + }
> +
> + if (PrevDecl && !isDeclInScope(PrevDecl, Record, S))
> + PrevDecl = 0;
> +
> + SourceLocation TSSL = D.getLocStart();
> + MSPropertyDecl *NewFD;
> + llvm::StringRef GetterName = MSPropertyAttr->getScopeName() ?
> + MSPropertyAttr->getScopeName()->getName() : StringRef();
> + llvm::StringRef SetterName = MSPropertyAttr->getParameterName() ?
> + MSPropertyAttr->getParameterName()->getName() : StringRef();
> + NewFD = new (Context) MSPropertyDecl(Record, Loc,
> + II, T, TInfo, TSSL,
> + GetterName, SetterName);
> + NewFD->setAccess(AS);
> +
> + if (NewFD->isInvalidDecl())
> + Record->setInvalidDecl();
> +
> + if (D.getDeclSpec().isModulePrivateSpecified())
> + NewFD->setModulePrivate();
> +
> + if (NewFD->isInvalidDecl() && PrevDecl) {
> + // Don't introduce NewFD into scope; there's already something
> + // with the same name in the same scope.
> + } else if (II) {
> + PushOnScopeChains(NewFD, S);
> + } else
> + Record->addDecl(NewFD);
> +
> + return NewFD;
> +}
> +
> /// \brief Build a new FieldDecl and check its well-formedness.
> ///
> /// This routine builds a new FieldDecl given the fields name, type,
> Only in ./clang/lib/Sema: SemaDecl.cpp~
> diff -ur /home/er91/Downloads/clang-3.2.src/lib/Sema/SemaDeclCXX.cpp ./clang/lib/Sema/SemaDeclCXX.cpp
> --- /home/er91/Downloads/clang-3.2.src/lib/Sema/SemaDeclCXX.cpp 2012-11-10 15:24:09.000000000 +0800
> +++ ./clang/lib/Sema/SemaDeclCXX.cpp 2013-01-03 18:53:55.888122989 +0800
> @@ -1551,6 +1551,13 @@
> return false;
> }
>
> +static AttributeList *getMSPropertyAttr(AttributeList *list) {
> + for (AttributeList* it = list; it != 0; it = it->getNext())
> + if (it->getName()->getName() == "property")
> + return it;
> + return 0;
> +}
> +
> /// ActOnCXXMemberDeclarator - This is invoked when a C++ class member
> /// declarator is parsed. 'AS' is the access specifier, 'BW' specifies the
> /// bitfield width if there is one, 'InitExpr' specifies the initializer if
> @@ -1707,8 +1714,15 @@
> SS.clear();
> }
>
> - Member = HandleField(S, cast<CXXRecordDecl>(CurContext), Loc, D, BitWidth,
> - InitStyle, AS);
> + AttributeList *MSPropertyAttr = getMSPropertyAttr(D.getDeclSpec().getAttributes().getList());
This line is > 80 characters
> + if (MSPropertyAttr) {
> + Member = HandleMSProperty(S, cast<CXXRecordDecl>(CurContext), Loc, D,
> + BitWidth, InitStyle, AS, MSPropertyAttr);
> + isInstField = false;
> + } else {
> + Member = HandleField(S, cast<CXXRecordDecl>(CurContext), Loc, D,
> + BitWidth, InitStyle, AS);
> + }
> assert(Member && "HandleField never returns null");
> } else {
> assert(InitStyle == ICIS_NoInit);
> Only in ./clang/lib/Sema: SemaDeclCXX.cpp~
> diff -ur /home/er91/Downloads/clang-3.2.src/lib/Sema/SemaExceptionSpec.cpp ./clang/lib/Sema/SemaExceptionSpec.cpp
> --- /home/er91/Downloads/clang-3.2.src/lib/Sema/SemaExceptionSpec.cpp 2012-10-20 16:26:51.000000000 +0800
> +++ ./clang/lib/Sema/SemaExceptionSpec.cpp 2013-01-03 17:51:54.872060111 +0800
> @@ -976,6 +976,9 @@
> return CT;
> return mergeCanThrow(CT, canSubExprsThrow(*this, E));
> }
> +
> + case Expr::MSPropertyRefExprClass:
> + return CT_Can;
>
> // ObjC message sends are like function calls, but never have exception
> // specs.
> diff -ur /home/er91/Downloads/clang-3.2.src/lib/Sema/SemaExpr.cpp ./clang/lib/Sema/SemaExpr.cpp
> --- /home/er91/Downloads/clang-3.2.src/lib/Sema/SemaExpr.cpp 2012-11-10 07:55:21.000000000 +0800
> +++ ./clang/lib/Sema/SemaExpr.cpp 2013-01-03 19:43:05.972172839 +0800
> @@ -2544,6 +2544,10 @@
> case Decl::CXXConstructor:
> valueKind = VK_RValue;
> break;
> +
> + case Decl::MSProperty:
> + valueKind = VK_LValue;
> + break;
> }
>
> return BuildDeclRefExpr(VD, type, valueKind, NameInfo, &SS);
> @@ -3309,6 +3313,11 @@
> RLoc));
> }
>
> + if (LHSExp->getType()->getAsPlaceholderType()) {
> + ExprResult result = CheckPlaceholderExpr(LHSExp);
> + if (result.isInvalid()) return ExprError();
> + LHSExp = result.take();
> + }
> if (getLangOpts().CPlusPlus &&
> (LHSExp->getType()->isRecordType() ||
> LHSExp->getType()->isEnumeralType() ||
> Only in ./clang/lib/Sema: SemaExpr.cpp~
> diff -ur /home/er91/Downloads/clang-3.2.src/lib/Sema/SemaExprCXX.cpp ./clang/lib/Sema/SemaExprCXX.cpp
> --- /home/er91/Downloads/clang-3.2.src/lib/Sema/SemaExprCXX.cpp 2012-11-07 08:12:38.000000000 +0800
> +++ ./clang/lib/Sema/SemaExprCXX.cpp 2013-01-03 19:14:28.520143817 +0800
> @@ -1192,6 +1192,11 @@
> }
> } SizeDiagnoser(ArraySize);
>
> + if (ArraySize->getType()->getAsPlaceholderType()) {
> + ExprResult result = CheckPlaceholderExpr(ArraySize);
> + if (result.isInvalid()) return ExprError();
> + ArraySize = result.take();
> + }
> ExprResult ConvertedSize
> = ConvertToIntegralOrEnumerationType(StartLoc, ArraySize, SizeDiagnoser,
> /*AllowScopedEnumerations*/ false);
> Only in ./clang/lib/Sema: SemaExprCXX.cpp~
> diff -ur /home/er91/Downloads/clang-3.2.src/lib/Sema/SemaExprMember.cpp ./clang/lib/Sema/SemaExprMember.cpp
> --- /home/er91/Downloads/clang-3.2.src/lib/Sema/SemaExprMember.cpp 2012-10-19 03:05:02.000000000 +0800
> +++ ./clang/lib/Sema/SemaExprMember.cpp 2013-01-03 17:51:55.016060113 +0800
> @@ -116,7 +116,8 @@
> NamedDecl *D = *I;
>
> if (D->isCXXInstanceMember()) {
> - if (dyn_cast<FieldDecl>(D) || dyn_cast<IndirectFieldDecl>(D))
> + if (dyn_cast<FieldDecl>(D) || dyn_cast<MSPropertyDecl>(D)
> + || dyn_cast<IndirectFieldDecl>(D))
> isField = true;
>
> CXXRecordDecl *R = cast<CXXRecordDecl>(D->getDeclContext());
> @@ -788,6 +789,17 @@
> return Owned(result);
> }
>
> +static ExprResult
> +BuildMSPropertyRefExpr(ASTContext &Context, Expr *BaseExpr, bool IsArrow,
> + SourceLocation StartLoc, SourceLocation EndLoc,
> + MSPropertyDecl *PD) {
> + return new (Context) MSPropertyRefExpr(BaseExpr, PD, IsArrow,
> + Context.PseudoObjectTy, VK_LValue,
> + StartLoc,
> + BaseExpr->getSourceRange().getBegin(),
> + EndLoc);
> +}
> +
> /// \brief Build a MemberExpr AST node.
> static MemberExpr *BuildMemberExpr(Sema &SemaRef,
> ASTContext &C, Expr *Base, bool isArrow,
> @@ -944,6 +956,11 @@
> if (FieldDecl *FD = dyn_cast<FieldDecl>(MemberDecl))
> return BuildFieldReferenceExpr(*this, BaseExpr, IsArrow,
> SS, FD, FoundDecl, MemberNameInfo);
> +
> + if (MSPropertyDecl *PD = dyn_cast<MSPropertyDecl>(MemberDecl))
> + return BuildMSPropertyRefExpr(Context, BaseExpr, IsArrow,
> + MemberNameInfo.getLocStart(),
> + MemberNameInfo.getLocEnd(), PD);
>
> if (IndirectFieldDecl *FD = dyn_cast<IndirectFieldDecl>(MemberDecl))
> // We may have found a field within an anonymous union or struct
> diff -ur /home/er91/Downloads/clang-3.2.src/lib/Sema/SemaPseudoObject.cpp ./clang/lib/Sema/SemaPseudoObject.cpp
> --- /home/er91/Downloads/clang-3.2.src/lib/Sema/SemaPseudoObject.cpp 2012-11-20 05:01:40.000000000 +0800
> +++ ./clang/lib/Sema/SemaPseudoObject.cpp 2013-01-03 18:43:44.072112650 +0800
> @@ -200,7 +200,7 @@
> /// Return true if assignments have a non-void result.
> bool CanCaptureValueOfType(QualType ty) {
> assert(!ty->isIncompleteType());
> - assert(!ty->isDependentType());
> + //assert(!ty->isDependentType());
Why is this commented out?
>
> if (const CXXRecordDecl *ClassDecl = ty->getAsCXXRecordDecl())
> return ClassDecl->isTriviallyCopyable();
> @@ -283,6 +283,18 @@
> ExprResult buildSet(Expr *op, SourceLocation, bool);
> };
>
> + class MSPropertyOpBuilder : public PseudoOpBuilder {
> + MSPropertyRefExpr *RefExpr;
> +
> + public:
> + MSPropertyOpBuilder(Sema &S, MSPropertyRefExpr *refExpr) :
> + PseudoOpBuilder(S, refExpr->getSourceRange().getBegin()),
> + RefExpr(refExpr) {}
> +
> + Expr *rebuildAndCaptureObject(Expr *);
> + ExprResult buildGet();
> + ExprResult buildSet(Expr *op, SourceLocation, bool);
> + };
> }
>
> /// Capture the given expression in an OpaqueValueExpr.
> @@ -1327,6 +1339,70 @@
> }
>
> //===----------------------------------------------------------------------===//
> +// MSVC __declspec(property) references
> +//===----------------------------------------------------------------------===//
> +
> +Expr* MSPropertyOpBuilder::rebuildAndCaptureObject(Expr *syntacticBase) {
> + return syntacticBase;
> +}
> +
> +ExprResult MSPropertyOpBuilder::buildGet() {
> + if (!RefExpr->getMSPropertyDecl()->hasGetter()) {
> + S.Diag(RefExpr->getMemberLoc(), diag::err_no_getter_for_property)
> + << RefExpr->getMSPropertyDecl()->getName();
> + return ExprError();
> + }
> +
> + UnqualifiedId GetterName;
> + IdentifierInfo *II = S.getPreprocessor().getIdentifierInfo(
> + RefExpr->getMSPropertyDecl()->getGetterName());
> + GetterName.setIdentifier(II, SourceLocation());
> + CXXScopeSpec SS;
> + ExprResult GetterExpr = S.ActOnMemberAccessExpr(
> + S.getCurScope(), RefExpr->getBaseExpr(), SourceLocation(),
> + RefExpr->isArrow() ? tok::arrow : tok::period, SS, SourceLocation(),
> + GetterName, 0, true);
> + if (GetterExpr.isInvalid()) {
> + S.Diag(RefExpr->getMemberLoc(), diag::error_cannot_find_suitable_getter)
> + << RefExpr->getMSPropertyDecl()->getName();
> + }
> +
> + MultiExprArg ArgExprs;
> + return S.ActOnCallExpr(S.getCurScope(), GetterExpr.take(),
> + RefExpr->getSourceRange().getBegin(), ArgExprs,
> + RefExpr->getSourceRange().getEnd());
> +}
> +
> +ExprResult MSPropertyOpBuilder::buildSet(Expr *op, SourceLocation sl,
> + bool captureSetValueAsResult) {
> + if (!RefExpr->getMSPropertyDecl()->hasSetter()) {
> + S.Diag(RefExpr->getMemberLoc(), diag::err_no_setter_for_property)
> + << RefExpr->getMSPropertyDecl()->getName();
> + return ExprError();
> + }
> +
> + UnqualifiedId SetterName;
> + IdentifierInfo *II = S.getPreprocessor().getIdentifierInfo(
> + RefExpr->getMSPropertyDecl()->getSetterName());
> + SetterName.setIdentifier(II, SourceLocation());
> + CXXScopeSpec SS;
> + ExprResult SetterExpr = S.ActOnMemberAccessExpr(
> + S.getCurScope(), RefExpr->getBaseExpr(), SourceLocation(),
> + RefExpr->isArrow() ? tok::arrow : tok::period, SS, SourceLocation(),
> + SetterName, 0, true);
> + if (SetterExpr.isInvalid()) {
> + S.Diag(RefExpr->getMemberLoc(), diag::error_cannot_find_suitable_setter)
> + << RefExpr->getMSPropertyDecl()->getName();
> + }
> +
> + SmallVector<Expr*, 1> ArgExprs;
> + ArgExprs.push_back(op);
> + return S.ActOnCallExpr(S.getCurScope(), SetterExpr.take(),
> + RefExpr->getSourceRange().getBegin(), ArgExprs,
> + op->getSourceRange().getEnd());
> +}
Source formatting concerns here as well with line length (check the
all of the new methods).
> +
> +//===----------------------------------------------------------------------===//
> // General Sema routines.
> //===----------------------------------------------------------------------===//
>
> @@ -1341,6 +1417,10 @@
> = dyn_cast<ObjCSubscriptRefExpr>(opaqueRef)) {
> ObjCSubscriptOpBuilder builder(*this, refExpr);
> return builder.buildRValueOperation(E);
> + } else if (MSPropertyRefExpr *refExpr
> + = dyn_cast<MSPropertyRefExpr>(opaqueRef)) {
> + MSPropertyOpBuilder builder(*this, refExpr);
> + return builder.buildRValueOperation(E);
> } else {
> llvm_unreachable("unknown pseudo-object kind!");
> }
> @@ -1363,6 +1443,10 @@
> } else if (isa<ObjCSubscriptRefExpr>(opaqueRef)) {
> Diag(opcLoc, diag::err_illegal_container_subscripting_op);
> return ExprError();
> + } else if (MSPropertyRefExpr *refExpr
> + = dyn_cast<MSPropertyRefExpr>(opaqueRef)) {
> + MSPropertyOpBuilder builder(*this, refExpr);
> + return builder.buildIncDecOperation(Sc, opcLoc, opcode, op);
> } else {
> llvm_unreachable("unknown pseudo-object kind!");
> }
> @@ -1392,6 +1476,10 @@
> = dyn_cast<ObjCSubscriptRefExpr>(opaqueRef)) {
> ObjCSubscriptOpBuilder builder(*this, refExpr);
> return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
> + } else if (MSPropertyRefExpr *refExpr
> + = dyn_cast<MSPropertyRefExpr>(opaqueRef)) {
> + MSPropertyOpBuilder builder(*this, refExpr);
> + return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
> } else {
> llvm_unreachable("unknown pseudo-object kind!");
> }
> @@ -1417,6 +1505,9 @@
> OpaqueValueExpr *keyOVE = cast<OpaqueValueExpr>(refExpr->getKeyExpr());
> return ObjCSubscriptRefRebuilder(S, baseOVE->getSourceExpr(),
> keyOVE->getSourceExpr()).rebuild(E);
> + } else if (MSPropertyRefExpr *refExpr
> + = dyn_cast<MSPropertyRefExpr>(opaqueRef)) {
> + return refExpr;
> } else {
> llvm_unreachable("unknown pseudo-object kind!");
> }
> Only in ./clang/lib/Sema: SemaPseudoObject.cpp~
> diff -ur /home/er91/Downloads/clang-3.2.src/lib/Sema/SemaTemplateInstantiateDecl.cpp ./clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
> --- /home/er91/Downloads/clang-3.2.src/lib/Sema/SemaTemplateInstantiateDecl.cpp 2012-10-23 08:32:41.000000000 +0800
> +++ ./clang/lib/Sema/SemaTemplateInstantiateDecl.cpp 2013-01-03 17:51:55.644060124 +0800
> @@ -479,6 +479,54 @@
> return Field;
> }
>
> +Decl *TemplateDeclInstantiator::VisitMSPropertyDecl(MSPropertyDecl *D) {
> + bool Invalid = false;
> + TypeSourceInfo *DI = D->getTypeSourceInfo();
> + if (DI->getType()->isInstantiationDependentType() ||
> + DI->getType()->isVariablyModifiedType()) {
> + DI = SemaRef.SubstType(DI, TemplateArgs,
> + D->getLocation(), D->getDeclName());
> + if (!DI) {
> + DI = D->getTypeSourceInfo();
> + Invalid = true;
> + } else if (DI->getType()->isFunctionType()) {
> + // C++ [temp.arg.type]p3:
> + // If a declaration acquires a function type through a type
> + // dependent on a template-parameter and this causes a
> + // declaration that does not use the syntactic form of a
> + // function declarator to have function type, the program is
> + // ill-formed.
> + SemaRef.Diag(D->getLocation(), diag::err_field_instantiates_to_function)
> + << DI->getType();
> + Invalid = true;
> + }
> + } else {
> + SemaRef.MarkDeclarationsReferencedInType(D->getLocation(), DI->getType());
> + }
> +
> + MSPropertyDecl *Property = new (SemaRef.Context)
> + MSPropertyDecl(Owner, D->getLocation(),
> + D->getDeclName(), D->getType(), DI,
> + D->getLocStart(),
> + D->getGetterName(), D->getSetterName());
> +
> + SemaRef.InstantiateAttrs(TemplateArgs, D, Property, LateAttrs, StartingScope);
> +
> + if (Invalid)
> + Property->setInvalidDecl();
> +
> + if (CXXRecordDecl *Parent= dyn_cast<CXXRecordDecl>(Property->getDeclContext())) {
Line length > 80.
> + if (Parent->isAnonymousStructOrUnion() &&
> + Parent->getRedeclContext()->isFunctionOrMethod())
> + SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Property);
> + }
> +
> + Property->setAccess(D->getAccess());
> + Owner->addDecl(Property);
> +
> + return Property;
> +}
> +
> Decl *TemplateDeclInstantiator::VisitIndirectFieldDecl(IndirectFieldDecl *D) {
> NamedDecl **NamedChain =
> new (SemaRef.Context)NamedDecl*[D->getChainingSize()];
> diff -ur /home/er91/Downloads/clang-3.2.src/lib/Sema/TreeTransform.h ./clang/lib/Sema/TreeTransform.h
> --- /home/er91/Downloads/clang-3.2.src/lib/Sema/TreeTransform.h 2012-11-29 07:44:46.000000000 +0800
> +++ ./clang/lib/Sema/TreeTransform.h 2013-01-03 17:51:55.712060126 +0800
> @@ -5945,6 +5945,20 @@
> NameInfo,
> SubStmt.get());
> }
> +
> +template<typename Derived>
> +ExprResult
> +TreeTransform<Derived>::TransformMSPropertyRefExpr(MSPropertyRefExpr *E) {
> + ExprResult Base = getDerived().TransformExpr(E->getBaseExpr());
> + if (Base.isInvalid())
> + return ExprError();
> + return new (SemaRef.getASTContext())
> + MSPropertyRefExpr(Base.get(), E->getMSPropertyDecl(), E->isArrow(),
> + SemaRef.getASTContext().PseudoObjectTy, VK_LValue,
> + E->getSourceRange().getBegin(),
> + E->getMemberLoc(),
> + E->getSourceRange().getEnd());
> +}
>
> template<typename Derived>
> StmtResult
> diff -ur /home/er91/Downloads/clang-3.2.src/lib/Serialization/ASTReaderDecl.cpp ./clang/lib/Serialization/ASTReaderDecl.cpp
> --- /home/er91/Downloads/clang-3.2.src/lib/Serialization/ASTReaderDecl.cpp 2012-11-06 08:35:02.000000000 +0800
> +++ ./clang/lib/Serialization/ASTReaderDecl.cpp 2013-01-03 17:51:55.768060126 +0800
> @@ -251,6 +251,7 @@
> void VisitCXXDestructorDecl(CXXDestructorDecl *D);
> void VisitCXXConversionDecl(CXXConversionDecl *D);
> void VisitFieldDecl(FieldDecl *FD);
> + void VisitMSPropertyDecl(MSPropertyDecl *FD);
> void VisitIndirectFieldDecl(IndirectFieldDecl *FD);
> void VisitVarDecl(VarDecl *VD);
> void VisitImplicitParamDecl(ImplicitParamDecl *PD);
> @@ -885,6 +886,12 @@
> }
> }
>
> +void ASTDeclReader::VisitMSPropertyDecl(MSPropertyDecl *PD) {
> + VisitDeclaratorDecl(PD);
> + PD->setGetterName(Reader.ReadString(Record, Idx));
> + PD->setSetterName(Reader.ReadString(Record, Idx));
> +}
> +
> void ASTDeclReader::VisitIndirectFieldDecl(IndirectFieldDecl *FD) {
> VisitValueDecl(FD);
>
> @@ -2101,6 +2108,9 @@
> case DECL_BLOCK:
> D = BlockDecl::CreateDeserialized(Context, ID);
> break;
> + case DECL_MS_PROPERTY:
> + D = MSPropertyDecl::CreateDeserialized(Context, ID);
> + break;
> case DECL_CXX_BASE_SPECIFIERS:
> Error("attempt to read a C++ base-specifier record as a declaration");
> return 0;
> diff -ur /home/er91/Downloads/clang-3.2.src/lib/Serialization/ASTReaderStmt.cpp ./clang/lib/Serialization/ASTReaderStmt.cpp
> --- /home/er91/Downloads/clang-3.2.src/lib/Serialization/ASTReaderStmt.cpp 2012-11-09 02:41:43.000000000 +0800
> +++ ./clang/lib/Serialization/ASTReaderStmt.cpp 2013-01-03 17:51:55.780060126 +0800
> @@ -1493,6 +1493,17 @@
> //===----------------------------------------------------------------------===//
> // Microsoft Expressions and Statements
> //===----------------------------------------------------------------------===//
> +void ASTStmtReader::VisitMSPropertyRefExpr(MSPropertyRefExpr *E) {
> + VisitExpr(E);
> + E->setArrow(Record[Idx++] != 0);
> + E->setBaseExpr(Reader.ReadSubExpr());
> + E->setMemberLoc(ReadSourceLocation(Record, Idx));
> + SourceLocation StartLoc = ReadSourceLocation(Record, Idx);
> + SourceLocation EndLoc = ReadSourceLocation(Record, Idx);
> + E->setSourceRange(SourceRange(StartLoc, EndLoc));
> + E->setMSPropertyDecl(ReadDeclAs<MSPropertyDecl>(Record, Idx));
> +}
> +
> void ASTStmtReader::VisitCXXUuidofExpr(CXXUuidofExpr *E) {
> VisitExpr(E);
> E->setSourceRange(ReadSourceRange(Record, Idx));
> @@ -2077,6 +2088,9 @@
> case EXPR_CXX_UUIDOF_EXPR:
> S = new (Context) CXXUuidofExpr(Empty, true);
> break;
> + case EXPR_CXX_PROPERTY_REF_EXPR:
> + S = new (Context) MSPropertyRefExpr(Empty);
> + break;
> case EXPR_CXX_UUIDOF_TYPE:
> S = new (Context) CXXUuidofExpr(Empty, false);
> break;
> diff -ur /home/er91/Downloads/clang-3.2.src/lib/Serialization/ASTWriterDecl.cpp ./clang/lib/Serialization/ASTWriterDecl.cpp
> --- /home/er91/Downloads/clang-3.2.src/lib/Serialization/ASTWriterDecl.cpp 2012-11-06 08:35:02.000000000 +0800
> +++ ./clang/lib/Serialization/ASTWriterDecl.cpp 2013-01-03 18:50:19.080119325 +0800
> @@ -81,6 +81,7 @@
> void VisitCXXDestructorDecl(CXXDestructorDecl *D);
> void VisitCXXConversionDecl(CXXConversionDecl *D);
> void VisitFieldDecl(FieldDecl *D);
> + void VisitMSPropertyDecl(MSPropertyDecl *D);
> void VisitIndirectFieldDecl(IndirectFieldDecl *D);
> void VisitVarDecl(VarDecl *D);
> void VisitImplicitParamDecl(ImplicitParamDecl *D);
> @@ -655,6 +656,14 @@
> Code = serialization::DECL_FIELD;
> }
>
> +void ASTDeclWriter::VisitMSPropertyDecl(MSPropertyDecl *D) {
> + VisitDeclaratorDecl(D);
> + Writer.AddString(D->getGetterName(), Record);
> + Writer.AddString(D->getSetterName(), Record);
> +
> + Code = serialization::DECL_MS_PROPERTY;
> +}
> +
> void ASTDeclWriter::VisitIndirectFieldDecl(IndirectFieldDecl *D) {
> VisitValueDecl(D);
> Record.push_back(D->getChainingSize());
> Only in ./clang/lib/Serialization: ASTWriterDecl.cpp~
> diff -ur /home/er91/Downloads/clang-3.2.src/lib/Serialization/ASTWriterStmt.cpp ./clang/lib/Serialization/ASTWriterStmt.cpp
> --- /home/er91/Downloads/clang-3.2.src/lib/Serialization/ASTWriterStmt.cpp 2012-11-09 02:41:43.000000000 +0800
> +++ ./clang/lib/Serialization/ASTWriterStmt.cpp 2013-01-03 17:51:55.812060127 +0800
> @@ -1531,6 +1531,17 @@
> //===----------------------------------------------------------------------===//
> // Microsoft Expressions and Statements.
> //===----------------------------------------------------------------------===//
> +void ASTStmtWriter::VisitMSPropertyRefExpr(MSPropertyRefExpr *E) {
> + VisitExpr(E);
> + Record.push_back(E->isArrow());
> + Writer.AddStmt(E->getBaseExpr());
> + Writer.AddSourceLocation(E->getMemberLoc(), Record);
> + Writer.AddSourceLocation(E->getSourceRange().getBegin(), Record);
> + Writer.AddSourceLocation(E->getSourceRange().getEnd(), Record);
> + Writer.AddDeclRef(E->getMSPropertyDecl(), Record);
> + Code = serialization::EXPR_CXX_PROPERTY_REF_EXPR;
> +}
> +
> void ASTStmtWriter::VisitCXXUuidofExpr(CXXUuidofExpr *E) {
> VisitExpr(E);
> Writer.AddSourceRange(E->getSourceRange(), Record);
> diff -ur /home/er91/Downloads/clang-3.2.src/lib/StaticAnalyzer/Core/ExprEngine.cpp ./clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
> --- /home/er91/Downloads/clang-3.2.src/lib/StaticAnalyzer/Core/ExprEngine.cpp 2012-11-03 10:54:20.000000000 +0800
> +++ ./clang/lib/StaticAnalyzer/Core/ExprEngine.cpp 2013-01-03 17:51:56.384060137 +0800
> @@ -530,6 +530,7 @@
> case Stmt::CXXTryStmtClass:
> case Stmt::CXXTypeidExprClass:
> case Stmt::CXXUuidofExprClass:
> + case Stmt::MSPropertyRefExprClass:
> case Stmt::CXXUnresolvedConstructExprClass:
> case Stmt::DependentScopeDeclRefExprClass:
> case Stmt::UnaryTypeTraitExprClass:
> diff -ur /home/er91/Downloads/clang-3.2.src/tools/libclang/IndexBody.cpp ./clang/tools/libclang/IndexBody.cpp
> --- /home/er91/Downloads/clang-3.2.src/tools/libclang/IndexBody.cpp 2012-09-11 06:58:04.000000000 +0800
> +++ ./clang/tools/libclang/IndexBody.cpp 2013-01-03 18:12:31.484081007 +0800
> @@ -89,6 +89,12 @@
> // be a message expr as part of PseudoObjectExpr.
> return true;
> }
> +
> + bool VisitMSPropertyRefExpr(MSPropertyRefExpr *E) {
> + IndexCtx.handleReference(E->getMSPropertyDecl(), E->getMemberLoc(), Parent,
> + ParentDC, E, CXIdxEntityRef_Direct);
> + return true;
> + }
>
> bool VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
> IndexCtx.handleReference(E->getProtocol(), E->getProtocolIdLoc(),
> Only in ./clang/tools/libclang: IndexBody.cpp~
> diff -ur /home/er91/Downloads/clang-3.2.src/tools/libclang/IndexDecl.cpp ./clang/tools/libclang/IndexDecl.cpp
> --- /home/er91/Downloads/clang-3.2.src/tools/libclang/IndexDecl.cpp 2012-10-11 00:42:25.000000000 +0800
> +++ ./clang/tools/libclang/IndexDecl.cpp 2013-01-03 18:05:23.792073780 +0800
> @@ -103,6 +103,11 @@
> IndexCtx.indexBody(D->getInClassInitializer(), D);
> return true;
> }
> +
> + bool VisitMSPropertyDecl(MSPropertyDecl *D) {
> + handleDeclarator(D);
> + return true;
> + }
>
> bool VisitEnumConstantDecl(EnumConstantDecl *D) {
> IndexCtx.handleEnumerator(D);
> Only in ./clang/tools/libclang: IndexDecl.cpp~
> diff -ur /home/er91/Downloads/clang-3.2.src/tools/libclang/IndexingContext.cpp ./clang/tools/libclang/IndexingContext.cpp
> --- /home/er91/Downloads/clang-3.2.src/tools/libclang/IndexingContext.cpp 2012-10-29 14:03:40.000000000 +0800
> +++ ./clang/tools/libclang/IndexingContext.cpp 2013-01-03 18:06:28.048074866 +0800
> @@ -382,6 +382,12 @@
> return handleDecl(D, D->getLocation(), getCursor(D), DInfo);
> }
>
> +bool IndexingContext::handleMSProperty(const MSPropertyDecl *D) {
> + DeclInfo DInfo(/*isRedeclaration=*/false, /*isDefinition=*/true,
> + /*isContainer=*/false);
> + return handleDecl(D, D->getLocation(), getCursor(D), DInfo);
> +}
> +
> bool IndexingContext::handleEnumerator(const EnumConstantDecl *D) {
> DeclInfo DInfo(/*isRedeclaration=*/false, /*isDefinition=*/true,
> /*isContainer=*/false);
> Only in ./clang/tools/libclang: IndexingContext.cpp~
> diff -ur /home/er91/Downloads/clang-3.2.src/tools/libclang/IndexingContext.h ./clang/tools/libclang/IndexingContext.h
> --- /home/er91/Downloads/clang-3.2.src/tools/libclang/IndexingContext.h 2012-10-29 14:02:59.000000000 +0800
> +++ ./clang/tools/libclang/IndexingContext.h 2013-01-03 18:07:12.468075617 +0800
> @@ -403,6 +403,8 @@
>
> bool handleField(const FieldDecl *D);
>
> + bool handleMSProperty(const MSPropertyDecl *D);
> +
> bool handleEnumerator(const EnumConstantDecl *D);
>
> bool handleTagDecl(const TagDecl *D);
> Only in ./clang/tools/libclang: IndexingContext.h~
> diff -ur /home/er91/Downloads/clang-3.2.src/tools/libclang/RecursiveASTVisitor.h ./clang/tools/libclang/RecursiveASTVisitor.h
> --- /home/er91/Downloads/clang-3.2.src/tools/libclang/RecursiveASTVisitor.h 2012-09-26 10:36:12.000000000 +0800
> +++ ./clang/tools/libclang/RecursiveASTVisitor.h 2013-01-03 18:13:42.716082211 +0800
> @@ -1603,6 +1603,10 @@
> TRY_TO(TraverseStmt(D->getInClassInitializer()));
> })
>
> +DEF_TRAVERSE_DECL(MSPropertyDecl, {
> + TRY_TO(TraverseDeclaratorHelper(D));
> + })
> +
> DEF_TRAVERSE_DECL(ObjCAtDefsFieldDecl, {
> TRY_TO(TraverseDeclaratorHelper(D));
> if (D->isBitField())
> @@ -2123,6 +2127,7 @@
> }
> })
>
> +DEF_TRAVERSE_STMT(MSPropertyRefExpr, {})
> DEF_TRAVERSE_STMT(SEHTryStmt, {})
> DEF_TRAVERSE_STMT(SEHExceptStmt, {})
> DEF_TRAVERSE_STMT(SEHFinallyStmt,{})
> Only in ./clang/tools/libclang: RecursiveASTVisitor.h~
>
Testcases? What you've attached is a reasonable start, but it's not
in the proper testcase format (see clang\tests for examples), nor does
it cover as many cases as I'd like to see.
That being said, I think you're getting pretty close!
Thanks!
~Aaron
More information about the cfe-commits
mailing list