[cfe-dev] [RFC] Preliminary patch to support MSVC __declspec(property)
endlessroad1991 at gmail.com
endlessroad1991 at gmail.com
Mon Dec 17 06:51:05 PST 2012
Here's a try to summarize implementation detail about __decpspec(property):
1. Add a MSPropertyDecl, because:
- Property can be private, as long as getter/setter is public. This is
different from regular members.
- Type of property can be imcomplete, like return type of a member
function. This is different from regular members.
- We can use it to store how many parameters should be used for
getter/setter
2. Add a MSPropertyRefExpr, like ObjCPropertyRefExpr. Preserve all
(index) parameters for getter/setter calls in ast. This is necessary
because (a.v)[1][2] and (a.v[1])[2] are both legal.
3. Lookup actual getter/setter, and generate CallExpr in PseudoObject
related routines.
And a complete test, covering all that I can think of now.
#include <iostream>
#include <vector>
class C
{
// property can be private, as long as getter/setter is public.
__declspec(property(get=GetA, put=SetA)) int A[123][321];
public:
// We choose getter/setter like regular overloaded functions.
int GetA() { std::cout << "Get 0\n"; return 0; }
int GetA(double i) { std::cout << "Get 1\n"; return 0; }
int GetA(int i) { std::cout << "Get 1i\n"; return 0; }
int GetA(double i, double j) { std::cout << "Get 2\n"; return 0; }
void SetA(int value) { std::cout << "Set 0\n"; }
void SetA(double i, double value) { std::cout << "Set 1\n"; }
void SetA(double i, double j, int value) { std::cout << "Set 2\n"; }
// Property type can be reference.
__declspec(property(get=GetA2, put=SetA2)) int& A2;
int& GetA2() { std::cout << "GetA2\n"; return ri; }
void SetA2(int& v) { std::cout << "SetA2\n"; ri = v; }
// "[]" can be filled with a integer number, which is legal, but useless.
// And "[]" that appear in typedef will also be treated as placeholder for
parameter.
typedef int int_arr[10][10];
__declspec(property(get=GetA3, put=SetA3)) int_arr A3;
int GetA3() { std::cout << "GetA3 0\n"; return 0; }
int GetA3(double i) { std::cout << "GetA3 1\n"; return 0; }
int GetA3(double i, double j) { std::cout << "GetA3 2\n"; return 0; } //
We can only leave this getter.
// If property type is pointer, only getter/setter with NO parameters will
be picked.
__declspec(property(get=GetA4, put=SetA4)) int ***A4;
int*** GetA4() { std::cout << "GetA4 0\n"; return ppp; }
int*** GetA4(int i) { std::cout << "GetA4 1\n"; return ppp; }
int*** GetA4(int i, int j) { std::cout << "GetA4 2\n"; return ppp; }
void SetA4(int ***v) { std::cout << "SetA4 0\n"; }
void SetA4(int i, int ***v) { std::cout << "SetA4 1\n"; }
void SetA4(int i, int j, int ***v) { std::cout << "SetA4 2\n"; }
// Even if property type can be subscripted, we cannot directly subsrcipt
it by appending "[]".
__declspec(property(get=GetA5)) std::vector<int> A5[];
std::vector<int> GetA5(int i) { std::cout << "GetA5 1\n"; return v; }
std::vector<int> GetA5(int i, int j) { std::cout << "GetA5 2\n"; return v;
}
std::vector<int> v;
int i;
int &ri;
int *p;
int **pp;
int ***ppp;
C(int &ri_): ri(ri_) { p = &i, pp = &p, ppp = &pp; }
};
int main()
{
int ri = 5445;
C c(ri);
int i = c.A; // Get 0
int j = c.A[1.0f]; // Get 1
int j2 = c.A[1]; // Get 1i
int k = c.A[1.0f][2.0f]; // Get 2
int k1 = (c.A)[1.0f][2.0f]; // Get 2
int k2 = (c.A[1.0f])[2.0f]; // Get 2
int& ir = c.A2; // GetA2
std::cout << ir << "\n"; // 5445
int ai = 4;
c.A2 = ai; // SetA2 // SetA2 must exist!
std::cout << c.A2 << "\n"; // GetA2 // 4
ai = 3;
std::cout << c.A2 << "\n"; // GetA2 // 4
int ii = c.A3; // GetA3 0
int jj = c.A3[1.0]; // GetA3 1
int kk = c.A3[1.0][2.0]; // GetA3 2
int ll = c.A3[1]; // GetA3 1
int ***a1 = c.A4; // GetA4 0
int **b1 = c.A4[0]; // GetA4 0
int *c1 = c.A4[0][0]; // GetA4 0
int d1 = c.A4[0][0][0]; // GetA4 0
// int d2 = c.A4[0][0][0][0]; // Doesn't compile
c.A4 = 0; // SetA4 0
c.A4[0] = c.pp; // GetA4 0
c.A4[0][0] = c.p; // GetA4 0
c.A4[0][0][0] = 0; // GetA4 0
std::vector<int> v = c.A5[0]; // GetA5 1
v = c.A5[0][0]; // GetA5 2
//int v2 = c.A5[0][0]; // Doesn't compile, "Cannot convert vector<int> to
int"
//int v3 = c.A5[0][0][0]; // Doesn't compile, "Cannot convert vector<int>
to int"
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20121217/3ab5f34c/attachment.html>
More information about the cfe-dev
mailing list