ABataev updated this revision to Diff 37854.
ABataev added a comment.
Update after review
http://reviews.llvm.org/D13336
Files:
include/clang/AST/ASTContext.h
include/clang/AST/BuiltinTypes.def
include/clang/Serialization/ASTBitCodes.h
lib/AST/ASTContext.cpp
lib/AST/Type.cpp
lib/AST/TypeLoc.cpp
lib/Sema/SemaExpr.cpp
lib/Sema/SemaPseudoObject.cpp
lib/Serialization/ASTCommon.cpp
lib/Serialization/ASTReader.cpp
test/CodeGenCXX/ms-property.cpp
test/SemaCXX/ms-property-error.cpp
test/SemaCXX/ms-property.cpp
Index: lib/Serialization/ASTReader.cpp
===================================================================
--- lib/Serialization/ASTReader.cpp
+++ lib/Serialization/ASTReader.cpp
@@ -5955,6 +5955,10 @@
case PREDEF_TYPE_OMP_ARRAY_SECTION:
T = Context.OMPArraySectionTy;
break;
+
+ case PREDEF_TYPE_MS_PROPERTY_SUBSCRIPT:
+ T = Context.MSPropertySubscriptTy;
+ break;
}
assert(!T.isNull() && "Unknown predefined type");
Index: lib/Serialization/ASTCommon.cpp
===================================================================
--- lib/Serialization/ASTCommon.cpp
+++ lib/Serialization/ASTCommon.cpp
@@ -187,6 +187,9 @@
case BuiltinType::OMPArraySection:
ID = PREDEF_TYPE_OMP_ARRAY_SECTION;
break;
+ case BuiltinType::MSPropertySubscript:
+ ID = PREDEF_TYPE_MS_PROPERTY_SUBSCRIPT;
+ break;
}
return TypeIdx(ID);
Index: lib/AST/Type.cpp
===================================================================
--- lib/AST/Type.cpp
+++ lib/AST/Type.cpp
@@ -2597,6 +2597,8 @@
return "reserve_id_t";
case OMPArraySection:
return "<OpenMP array section type>";
+ case MSPropertySubscript:
+ return "<MS declspec property subscript type>";
}
llvm_unreachable("Invalid builtin type.");
@@ -3554,6 +3556,7 @@
case BuiltinType::BuiltinFn:
case BuiltinType::NullPtr:
case BuiltinType::OMPArraySection:
+ case BuiltinType::MSPropertySubscript:
return false;
}
Index: lib/AST/ASTContext.cpp
===================================================================
--- lib/AST/ASTContext.cpp
+++ lib/AST/ASTContext.cpp
@@ -1055,6 +1055,9 @@
if (LangOpts.OpenMP)
InitBuiltinType(OMPArraySectionTy, BuiltinType::OMPArraySection);
+ if(LangOpts.MSVCCompat)
+ InitBuiltinType(MSPropertySubscriptTy, BuiltinType::MSPropertySubscript);
+
// C99 6.2.5p11.
FloatComplexTy = getComplexType(FloatTy);
DoubleComplexTy = getComplexType(DoubleTy);
Index: lib/AST/TypeLoc.cpp
===================================================================
--- lib/AST/TypeLoc.cpp
+++ lib/AST/TypeLoc.cpp
@@ -353,6 +353,7 @@
case BuiltinType::OCLReserveID:
case BuiltinType::BuiltinFn:
case BuiltinType::OMPArraySection:
+ case BuiltinType::MSPropertySubscript:
return TST_unspecified;
}
Index: lib/Sema/SemaExpr.cpp
===================================================================
--- lib/Sema/SemaExpr.cpp
+++ lib/Sema/SemaExpr.cpp
@@ -3917,7 +3917,21 @@
// operand might be an overloadable type, in which case the overload
// resolution for the operator overload should get the first crack
// at the overload.
- if (base->getType()->isNonOverloadPlaceholderType()) {
+ // MSDN, property (C++)
+ // https://msdn.microsoft.com/en-us/library/yhfk0thd(v=vs.120).aspx
+ // This attribute can also be used in the declaration of an empty array in a
+ // class or structure definition. For example:
+ // __declspec(property(get=GetX, put=PutX)) int x[];
+ // The above statement indicates that x[] can be used with one or more array
+ // indices. In this case, i=p->x[a][b] will be turned into i=p->GetX(a, b),
+ // and p->x[a][b] = i will be turned into p->PutX(a, b, i);
+ auto *MSProp = dyn_cast<MSPropertyRefExpr>(base->IgnoreParens());
+ bool IsMSPropertySubscript =
+ (MSProp && MSProp->getPropertyDecl()->getType()->isArrayType()) ||
+ base->getType()->isSpecificPlaceholderType(
+ BuiltinType::MSPropertySubscript);
+ if (!IsMSPropertySubscript &&
+ base->getType()->isNonOverloadPlaceholderType()) {
ExprResult result = CheckPlaceholderExpr(base);
if (result.isInvalid()) return ExprError();
base = result.get();
@@ -4093,7 +4107,12 @@
Expr *RHSExp = Idx;
// Perform default conversions.
- if (!LHSExp->getType()->getAs<VectorType>()) {
+ auto *MSProp = dyn_cast<MSPropertyRefExpr>(LHSExp->IgnoreParens());
+ bool IsMSPropertySubscript =
+ (MSProp && MSProp->getPropertyDecl()->getType()->isArrayType()) ||
+ LHSExp->getType()->isSpecificPlaceholderType(
+ BuiltinType::MSPropertySubscript);
+ if (!LHSExp->getType()->getAs<VectorType>() && !IsMSPropertySubscript) {
ExprResult Result = DefaultFunctionArrayLvalueConversion(LHSExp);
if (Result.isInvalid())
return ExprError();
@@ -4118,6 +4137,10 @@
BaseExpr = LHSExp;
IndexExpr = RHSExp;
ResultType = Context.DependentTy;
+ } else if (IsMSPropertySubscript) {
+ BaseExpr = LHSExp;
+ IndexExpr = RHSExp;
+ ResultType = Context.MSPropertySubscriptTy;
} else if (const PointerType *PTy = LHSTy->getAs<PointerType>()) {
BaseExpr = LHSExp;
IndexExpr = RHSExp;
@@ -4707,6 +4730,7 @@
return false;
// Pseudo-objects should be converted as soon as possible.
+ case BuiltinType::MSPropertySubscript:
case BuiltinType::PseudoObject:
return true;
@@ -4849,7 +4873,8 @@
return new (Context)
CallExpr(Context, Fn, None, Context.VoidTy, VK_RValue, RParenLoc);
}
- if (Fn->getType() == Context.PseudoObjectTy) {
+ if (Fn->getType() == Context.PseudoObjectTy ||
+ Fn->getType() == Context.MSPropertySubscriptTy) {
ExprResult result = CheckPlaceholderExpr(Fn);
if (result.isInvalid()) return ExprError();
Fn = result.get();
@@ -9355,7 +9380,8 @@
/// CheckForModifiableLvalue - Verify that E is a modifiable lvalue. If not,
/// emit an error and return true. If so, return false.
static bool CheckForModifiableLvalue(Expr *E, SourceLocation Loc, Sema &S) {
- assert(!E->hasPlaceholderType(BuiltinType::PseudoObject));
+ assert(!E->hasPlaceholderType(BuiltinType::PseudoObject) &&
+ !E->hasPlaceholderType(BuiltinType::MSPropertySubscript));
SourceLocation OrigLoc = Loc;
Expr::isModifiableLvalueResult IsLV = E->isModifiableLvalue(S.Context,
&Loc);
@@ -9496,7 +9522,8 @@
QualType Sema::CheckAssignmentOperands(Expr *LHSExpr, ExprResult &RHS,
SourceLocation Loc,
QualType CompoundType) {
- assert(!LHSExpr->hasPlaceholderType(BuiltinType::PseudoObject));
+ assert(!LHSExpr->hasPlaceholderType(BuiltinType::PseudoObject) &&
+ !LHSExpr->hasPlaceholderType(BuiltinType::MSPropertySubscript));
// Verify that LHS is a modifiable lvalue, and emit error if not.
if (CheckForModifiableLvalue(LHSExpr, Loc, *this))
@@ -10678,7 +10705,8 @@
// Handle pseudo-objects in the LHS.
if (const BuiltinType *pty = LHSExpr->getType()->getAsPlaceholderType()) {
// Assignments with a pseudo-object l-value need special analysis.
- if (pty->getKind() == BuiltinType::PseudoObject &&
+ if ((pty->getKind() == BuiltinType::PseudoObject ||
+ pty->getKind() == BuiltinType::MSPropertySubscript) &&
BinaryOperator::isAssignmentOp(Opc))
return checkPseudoObjectAssignment(S, OpLoc, Opc, LHSExpr, RHSExpr);
@@ -10968,7 +10996,8 @@
// overloaded-operator check considers the right type.
if (const BuiltinType *pty = Input->getType()->getAsPlaceholderType()) {
// Increment and decrement of pseudo-object references.
- if (pty->getKind() == BuiltinType::PseudoObject &&
+ if ((pty->getKind() == BuiltinType::PseudoObject ||
+ pty->getKind() == BuiltinType::MSPropertySubscript) &&
UnaryOperator::isIncrementDecrementOp(Opc))
return checkPseudoObjectIncDec(S, OpLoc, Opc, Input);
@@ -14477,6 +14506,7 @@
return diagnoseUnknownAnyExpr(*this, E);
// Pseudo-objects.
+ case BuiltinType::MSPropertySubscript:
case BuiltinType::PseudoObject:
return checkPseudoObjectRValue(E);
Index: lib/Sema/SemaPseudoObject.cpp
===================================================================
--- lib/Sema/SemaPseudoObject.cpp
+++ lib/Sema/SemaPseudoObject.cpp
@@ -121,6 +121,15 @@
rebuiltExpr->isValueDependent());
}
+ if (e->getType()->isSpecificPlaceholderType(
+ BuiltinType::MSPropertySubscript)) {
+ auto *ASE = cast<ArraySubscriptExpr>(e);
+ return new (S.Context) ArraySubscriptExpr(
+ rebuild(ASE->getBase()), ASE->getIdx(), ASE->getType(),
+ ASE->getValueKind(), ASE->getObjectKind(), ASE->getRBracketLoc());
+ }
+
+
llvm_unreachable("bad expression to rebuild!");
}
};
@@ -329,11 +338,26 @@
class MSPropertyOpBuilder : public PseudoOpBuilder {
MSPropertyRefExpr *RefExpr;
OpaqueValueExpr *InstanceBase;
+ SmallVector<Expr *, 4> ArgExprs;
public:
MSPropertyOpBuilder(Sema &S, MSPropertyRefExpr *refExpr) :
PseudoOpBuilder(S, refExpr->getSourceRange().getBegin()),
RefExpr(refExpr), InstanceBase(nullptr) {}
+ MSPropertyOpBuilder(Sema &S, Expr *E)
+ : PseudoOpBuilder(S, E->getSourceRange().getBegin()),
+ InstanceBase(nullptr) {
+ assert(E->getType()->isSpecificPlaceholderType(
+ BuiltinType::MSPropertySubscript));
+ auto *Base = E->IgnoreParens();
+ while (Base->getType()->isSpecificPlaceholderType(
+ BuiltinType::MSPropertySubscript)) {
+ auto *ASE = cast<ArraySubscriptExpr>(Base);
+ ArgExprs.insert(ArgExprs.begin(), ASE->getIdx());
+ Base = ASE->getBase()->IgnoreParens();
+ }
+ RefExpr = cast<MSPropertyRefExpr>(Base);
+ }
Expr *rebuildAndCaptureObject(Expr *) override;
ExprResult buildGet() override;
@@ -1432,7 +1456,6 @@
return ExprError();
}
- MultiExprArg ArgExprs;
return S.ActOnCallExpr(S.getCurScope(), GetterExpr.get(),
RefExpr->getSourceRange().getBegin(), ArgExprs,
RefExpr->getSourceRange().getEnd());
@@ -1462,7 +1485,6 @@
return ExprError();
}
- SmallVector<Expr*, 1> ArgExprs;
ArgExprs.push_back(op);
return S.ActOnCallExpr(S.getCurScope(), SetterExpr.get(),
RefExpr->getSourceRange().getBegin(), ArgExprs,
@@ -1488,6 +1510,10 @@
= dyn_cast<MSPropertyRefExpr>(opaqueRef)) {
MSPropertyOpBuilder builder(*this, refExpr);
return builder.buildRValueOperation(E);
+ } else if (E->getType()->isSpecificPlaceholderType(
+ BuiltinType::MSPropertySubscript)) {
+ MSPropertyOpBuilder builder(*this, E);
+ return builder.buildRValueOperation(E);
} else {
llvm_unreachable("unknown pseudo-object kind!");
}
@@ -1514,6 +1540,10 @@
= dyn_cast<MSPropertyRefExpr>(opaqueRef)) {
MSPropertyOpBuilder builder(*this, refExpr);
return builder.buildIncDecOperation(Sc, opcLoc, opcode, op);
+ } else if (opaqueRef->getType()->isSpecificPlaceholderType(
+ BuiltinType::MSPropertySubscript)) {
+ MSPropertyOpBuilder builder(*this, opaqueRef);
+ return builder.buildIncDecOperation(Sc, opcLoc, opcode, op);
} else {
llvm_unreachable("unknown pseudo-object kind!");
}
@@ -1545,7 +1575,11 @@
return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
} else if (MSPropertyRefExpr *refExpr
= dyn_cast<MSPropertyRefExpr>(opaqueRef)) {
- MSPropertyOpBuilder builder(*this, refExpr);
+ MSPropertyOpBuilder builder(*this, refExpr);
+ return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
+ } else if (opaqueRef->getType()->isSpecificPlaceholderType(
+ BuiltinType::MSPropertySubscript)) {
+ MSPropertyOpBuilder builder(*this, opaqueRef);
return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
} else {
llvm_unreachable("unknown pseudo-object kind!");
@@ -1576,6 +1610,16 @@
= dyn_cast<MSPropertyRefExpr>(opaqueRef)) {
OpaqueValueExpr *baseOVE = cast<OpaqueValueExpr>(refExpr->getBaseExpr());
return MSPropertyRefRebuilder(S, baseOVE->getSourceExpr()).rebuild(E);
+ } else if (opaqueRef->getType()->isSpecificPlaceholderType(
+ BuiltinType::MSPropertySubscript)) {
+ while (opaqueRef->getType()->isSpecificPlaceholderType(
+ BuiltinType::MSPropertySubscript)) {
+ opaqueRef =
+ cast<ArraySubscriptExpr>(opaqueRef)->getBase()->IgnoreParens();
+ }
+ auto *BaseOVE = cast<OpaqueValueExpr>(
+ cast<MSPropertyRefExpr>(opaqueRef)->getBaseExpr());
+ return MSPropertyRefRebuilder(S, BaseOVE->getSourceExpr()).rebuild(E);
} else {
llvm_unreachable("unknown pseudo-object kind!");
}
@@ -1613,7 +1657,8 @@
bop->getObjectKind(),
bop->getOperatorLoc(), false);
} else {
- assert(syntax->hasPlaceholderType(BuiltinType::PseudoObject));
+ assert(syntax->hasPlaceholderType(BuiltinType::PseudoObject) ||
+ syntax->hasPlaceholderType(BuiltinType::MSPropertySubscript));
return stripOpaqueValuesFromPseudoObjectRef(*this, syntax);
}
}
Index: include/clang/Serialization/ASTBitCodes.h
===================================================================
--- include/clang/Serialization/ASTBitCodes.h
+++ include/clang/Serialization/ASTBitCodes.h
@@ -797,7 +797,10 @@
/// \brief OpenCL reserve_id type.
PREDEF_TYPE_RESERVE_ID_ID = 54,
/// \brief The placeholder type for OpenMP array section.
- PREDEF_TYPE_OMP_ARRAY_SECTION = 55
+ PREDEF_TYPE_OMP_ARRAY_SECTION = 55,
+ /// \brief The placeholder type for MS declspec property subscript pseudo
+ /// expression.
+ PREDEF_TYPE_MS_PROPERTY_SUBSCRIPT = 56,
};
/// \brief The number of predefined type IDs that are reserved for
Index: include/clang/AST/ASTContext.h
===================================================================
--- include/clang/AST/ASTContext.h
+++ include/clang/AST/ASTContext.h
@@ -851,6 +851,7 @@
CanQualType OCLSamplerTy, OCLEventTy, OCLClkEventTy;
CanQualType OCLQueueTy, OCLNDRangeTy, OCLReserveIDTy;
CanQualType OMPArraySectionTy;
+ CanQualType MSPropertySubscriptTy;
// Types for deductions in C++0x [stmt.ranged]'s desugaring. Built on demand.
mutable QualType AutoDeductTy; // Deduction against 'auto'.
Index: include/clang/AST/BuiltinTypes.def
===================================================================
--- include/clang/AST/BuiltinTypes.def
+++ include/clang/AST/BuiltinTypes.def
@@ -248,8 +248,11 @@
// A placeholder type for OpenMP array sections.
PLACEHOLDER_TYPE(OMPArraySection, OMPArraySectionTy)
+// A placeholder type for MS property subscript expression.
+PLACEHOLDER_TYPE(MSPropertySubscript, MSPropertySubscriptTy)
+
#ifdef LAST_BUILTIN_TYPE
-LAST_BUILTIN_TYPE(OMPArraySection)
+LAST_BUILTIN_TYPE(MSPropertySubscript)
#undef LAST_BUILTIN_TYPE
#endif
Index: test/SemaCXX/ms-property.cpp
===================================================================
--- test/SemaCXX/ms-property.cpp
+++ test/SemaCXX/ms-property.cpp
@@ -0,0 +1,58 @@
+// RUN: %clang_cc1 -ast-print -verify -triple=x86_64-pc-win32 -fms-compatibility %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple=x86_64-pc-win32 -fms-compatibility -emit-pch -o %t %s
+// RUN: %clang_cc1 -triple=x86_64-pc-win32 -fms-compatibility -include-pch %t -verify %s -ast-print -o - | FileCheck %s
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+class Test1 {
+private:
+ int x_;
+
+public:
+ Test1(int x) : x_(x) {}
+ __declspec(property(get = get_x)) int X;
+ int get_x() const { return x_; }
+ static Test1 *GetTest1() { return new Test1(10); }
+};
+
+class S {
+public:
+ __declspec(property(get=GetX,put=PutX)) int x[];
+ int GetX(int i, int j) { return i+j; }
+ void PutX(int i, int j, int k) { j = i = k; }
+};
+
+template <typename T>
+class St {
+public:
+ __declspec(property(get=GetX,put=PutX)) T x[];
+ T GetX(T i, T j) { return i+j; }
+ void PutX(T i, T j, T k) { j = i = k; }
+ ~St() { x[0][0] = x[1][1]; }
+};
+
+// CHECK: this->x[0][0] = this->x[1][1];
+// CHECK: this->x[0][0] = this->x[1][1];
+
+// CHECK-LABEL: main
+int main(int argc, char **argv) {
+ S *p1 = 0;
+ St<float> *p2 = 0;
+ // CHECK: St<int> a;
+ St<int> a;
+ // CHECK-NEXT: int j = (p1->x)[223][11];
+ int j = (p1->x)[223][11];
+ // CHECK-NEXT: (p1->x[23])[1] = j;
+ (p1->x[23])[1] = j;
+ // CHECK-NEXT: float j1 = (p2->x[223][11]);
+ float j1 = (p2->x[223][11]);
+ // CHECK-NEXT: ((p2->x)[23])[1] = j1;
+ ((p2->x)[23])[1] = j1;
+ // CHECK-NEXT: ++(((p2->x)[23])[1]);
+ ++(((p2->x)[23])[1]);
+ // CHECK-NEXT: return Test1::GetTest1()->X;
+ return Test1::GetTest1()->X;
+}
+#endif // HEADER
Index: test/SemaCXX/ms-property-error.cpp
===================================================================
--- test/SemaCXX/ms-property-error.cpp
+++ test/SemaCXX/ms-property-error.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -verify -fms-compatibility %s -fsyntax-only -o -
+
+class S {
+public:
+ __declspec(property(get=GetX,put=PutX)) int x[];
+ int GetX(int i, int j) { return i+j; } // expected-note {{'GetX' declared here}}
+ void PutX(int i, int j, int k) { j = i = k; } // expected-note {{'PutX' declared here}}
+};
+
+template <typename T>
+class St {
+public:
+ __declspec(property(get=GetX,put=PutX)) T x[];
+ T GetX(T i, T j) { return i+j; } // expected-note 3 {{'GetX' declared here}}
+ void PutX(T i, T j, T k) { j = i = k; } // expected-note 2 {{'PutX' declared here}}
+ ~St() {
+ x[1] = 0; // expected-error {{too few arguments to function call, expected 3, have 2}}
+ x[2][3] = 4;
+ ++x[2][3];
+ x[1][2] = x[3][4][5]; // expected-error {{too many arguments to function call, expected 2, have 3}}
+ }
+};
+
+// CHECK-LABEL: main
+int main(int argc, char **argv) {
+ S *p1 = 0;
+ St<float> *p2 = 0;
+ St<int> a; // expected-note {{in instantiation of member function 'St<int>::~St' requested here}}
+ int j = (p1->x)[223][11][2]; // expected-error {{too many arguments to function call, expected 2, have 3}}
+ (p1->x[23]) = argc; // expected-error {{too few arguments to function call, expected 3, have 2}}
+ float j1 = (p2->x); // expected-error {{too few arguments to function call, expected 2, have 0}}
+ ((p2->x)[23])[1][2] = *argv; // expected-error {{too many arguments to function call, expected 3, have 4}}
+ return ++(((p2->x)[23])); // expected-error {{too few arguments to function call, expected 2, have 1}}
+}
Index: test/CodeGenCXX/ms-property.cpp
===================================================================
--- test/CodeGenCXX/ms-property.cpp
+++ test/CodeGenCXX/ms-property.cpp
@@ -1,4 +1,10 @@
// RUN: %clang_cc1 -emit-llvm -triple=x86_64-pc-win32 -fms-compatibility %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple=x86_64-pc-win32 -fms-compatibility -emit-pch -o %t %s
+// RUN: %clang_cc1 -emit-llvm -triple=x86_64-pc-win32 -fms-compatibility -include-pch %t -verify %s -o - | FileCheck %s
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
class Test1 {
private:
@@ -11,9 +17,42 @@
static Test1 *GetTest1() { return new Test1(10); }
};
+class S {
+public:
+ __declspec(property(get=GetX,put=PutX)) int x[];
+ int GetX(int i, int j) { return i+j; }
+ void PutX(int i, int j, int k) { j = i = k; }
+};
+
+template <typename T>
+class St {
+public:
+ __declspec(property(get=GetX,put=PutX)) T x[];
+ T GetX(T i, T j) { return i+j; }
+ void PutX(T i, T j, T k) { j = i = k; }
+};
+
// CHECK-LABEL: main
int main(int argc, char **argv) {
+ S *p1 = 0;
+ St<float> *p2 = 0;
+ // CHECK: call i32 @"\01?GetX@S@@QEAAHHH@Z"(%class.S* %{{.+}}, i32 223, i32 11)
+ int j = p1->x[223][11];
+ // CHECK: [[J:%.+]] = load i32, i32* %
+ // CHECK-NEXT: call void @"\01?PutX@S@@QEAAXHHH@Z"(%class.S* %{{.+}}, i32 23, i32 1, i32 [[J]])
+ p1->x[23][1] = j;
+ // CHECK: call float @"\01?GetX@?$St@M@@QEAAMMM@Z"(%class.St* %{{.+}}, float 2.230000e+02, float 1.100000e+01)
+ float j1 = p2->x[223][11];
+ // CHECK: [[J1:%.+]] = load float, float* %
+ // CHECK-NEXT: call void @"\01?PutX@?$St@M@@QEAAXMMM@Z"(%class.St* %{{.+}}, float 2.300000e+01, float 1.000000e+00, float [[J1]])
+ p2->x[23][1] = j1;
+ // CHECK: [[GET:%.+]] = call float @"\01?GetX@?$St@M@@QEAAMMM@Z"(%class.St* %6, float 2.300000e+01, float 1.000000e+00)
+ // CHECK-NEXT: [[INC:%.+]] = fadd float [[GET]], 1.000000e+00
+ // CHECK-NEXT: call void @"\01?PutX@?$St@M@@QEAAXMMM@Z"(%class.St* %6, float 2.300000e+01, float 1.000000e+00, float [[INC]])
+ ++p2->x[23][1];
// CHECK: [[CALL:%.+]] = call %class.Test1* @"\01?GetTest1@Test1@@SAPEAV1@XZ"()
// CHECK-NEXT: call i32 @"\01?get_x@Test1@@QEBAHXZ"(%class.Test1* [[CALL]])
return Test1::GetTest1()->X;
}
+
+#endif //HEADER
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits