[cfe-dev] [RFC] Preliminary patch to support MSVC __declspec(property)
endlessroad1991 at gmail.com
endlessroad1991 at gmail.com
Mon Dec 17 07:07:22 PST 2012
Or, we can only implement a WELL-DEFINED subset of property: no [] support.
- I looked at ATL headers, those properties are all defined without [].
- My work is financially supported by GEMS8(http://wwwm.gems8.com), which
only use property without [].
- Any property usage involving [] seems totally "undefined". I guess there
are only god-know-what rules defined by VC developers, and they'are not
intended for real-world use.
Is this suggestion ok?
On Mon, Dec 17, 2012 at 10:51 PM, endlessroad1991 at gmail.com <
endlessroad1991 at gmail.com> wrote:
> 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"
> }
>
--
Best Regards, Tong Shen (沈彤)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20121217/325eed4c/attachment.html>
More information about the cfe-dev
mailing list