[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