annotate gcc/d/dmd/access.c @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
145
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1 /* Compiler implementation of the D programming language
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2 * Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3 * written by Walter Bright
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
4 * http://www.digitalmars.com
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
5 * Distributed under the Boost Software License, Version 1.0.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
6 * http://www.boost.org/LICENSE_1_0.txt
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
7 * https://github.com/D-Programming-Language/dmd/blob/master/src/access.c
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
8 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
9
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
10 #include "root/dsystem.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
11 #include "root/root.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
12 #include "root/rmem.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
13
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
14 #include "errors.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
15 #include "enum.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
16 #include "aggregate.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
17 #include "init.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
18 #include "attrib.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
19 #include "scope.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
20 #include "id.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
21 #include "mtype.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
22 #include "declaration.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
23 #include "aggregate.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
24 #include "expression.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
25 #include "module.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
26 #include "template.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
27
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
28 /* Code to do access checks
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
29 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
30
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
31 bool hasPackageAccess(Scope *sc, Dsymbol *s);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
32 bool hasPackageAccess(Module *mod, Dsymbol *s);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
33 bool hasPrivateAccess(AggregateDeclaration *ad, Dsymbol *smember);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
34 bool isFriendOf(AggregateDeclaration *ad, AggregateDeclaration *cd);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
35 static Dsymbol *mostVisibleOverload(Dsymbol *s);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
36
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
37 /****************************************
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
38 * Return Prot access for Dsymbol smember in this declaration.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
39 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
40 Prot getAccess(AggregateDeclaration *ad, Dsymbol *smember)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
41 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
42 Prot access_ret = Prot(PROTnone);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
43
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
44 assert(ad->isStructDeclaration() || ad->isClassDeclaration());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
45 if (smember->toParent() == ad)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
46 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
47 access_ret = smember->prot();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
48 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
49 else if (smember->isDeclaration()->isStatic())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
50 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
51 access_ret = smember->prot();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
52 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
53 if (ClassDeclaration *cd = ad->isClassDeclaration())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
54 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
55 for (size_t i = 0; i < cd->baseclasses->dim; i++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
56 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
57 BaseClass *b = (*cd->baseclasses)[i];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
58
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
59 Prot access = getAccess(b->sym, smember);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
60 switch (access.kind)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
61 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
62 case PROTnone:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
63 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
64
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
65 case PROTprivate:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
66 access_ret = Prot(PROTnone); // private members of base class not accessible
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
67 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
68
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
69 case PROTpackage:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
70 case PROTprotected:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
71 case PROTpublic:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
72 case PROTexport:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
73 // If access is to be tightened
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
74 if (PROTpublic < access.kind)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
75 access = Prot(PROTpublic);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
76
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
77 // Pick path with loosest access
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
78 if (access_ret.isMoreRestrictiveThan(access))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
79 access_ret = access;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
80 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
81
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
82 default:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
83 assert(0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
84 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
85 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
86 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
87
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
88 return access_ret;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
89 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
90
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
91 /********************************************************
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
92 * Helper function for checkAccess()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
93 * Returns:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
94 * false is not accessible
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
95 * true is accessible
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
96 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
97 static bool isAccessible(
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
98 Dsymbol *smember,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
99 Dsymbol *sfunc,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
100 AggregateDeclaration *dthis,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
101 AggregateDeclaration *cdscope)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
102 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
103 assert(dthis);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
104
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
105 if (hasPrivateAccess(dthis, sfunc) ||
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
106 isFriendOf(dthis, cdscope))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
107 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
108 if (smember->toParent() == dthis)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
109 return true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
110
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
111 if (ClassDeclaration *cdthis = dthis->isClassDeclaration())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
112 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
113 for (size_t i = 0; i < cdthis->baseclasses->dim; i++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
114 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
115 BaseClass *b = (*cdthis->baseclasses)[i];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
116 Prot access = getAccess(b->sym, smember);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
117 if (access.kind >= PROTprotected ||
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
118 isAccessible(smember, sfunc, b->sym, cdscope))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
119 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
120 return true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
121 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
122 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
123 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
124 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
125 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
126 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
127 if (smember->toParent() != dthis)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
128 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
129 if (ClassDeclaration *cdthis = dthis->isClassDeclaration())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
130 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
131 for (size_t i = 0; i < cdthis->baseclasses->dim; i++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
132 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
133 BaseClass *b = (*cdthis->baseclasses)[i];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
134 if (isAccessible(smember, sfunc, b->sym, cdscope))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
135 return true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
136 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
137 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
138 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
139 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
140 return false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
141 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
142
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
143 /*******************************
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
144 * Do access check for member of this class, this class being the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
145 * type of the 'this' pointer used to access smember.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
146 * Returns true if the member is not accessible.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
147 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
148 bool checkAccess(AggregateDeclaration *ad, Loc loc, Scope *sc, Dsymbol *smember)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
149 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
150 FuncDeclaration *f = sc->func;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
151 AggregateDeclaration *cdscope = sc->getStructClassScope();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
152
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
153 Dsymbol *smemberparent = smember->toParent();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
154 if (!smemberparent || !smemberparent->isAggregateDeclaration())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
155 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
156 return false; // then it is accessible
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
157 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
158
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
159 // BUG: should enable this check
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
160 //assert(smember->parent->isBaseOf(this, NULL));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
161
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
162 bool result;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
163 Prot access;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
164 if (smemberparent == ad)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
165 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
166 access = smember->prot();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
167 result = access.kind >= PROTpublic ||
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
168 hasPrivateAccess(ad, f) ||
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
169 isFriendOf(ad, cdscope) ||
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
170 (access.kind == PROTpackage && hasPackageAccess(sc, smember)) ||
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
171 ad->getAccessModule() == sc->_module;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
172 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
173 else if ((access = getAccess(ad, smember)).kind >= PROTpublic)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
174 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
175 result = true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
176 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
177 else if (access.kind == PROTpackage && hasPackageAccess(sc, ad))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
178 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
179 result = true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
180 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
181 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
182 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
183 result = isAccessible(smember, f, ad, cdscope);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
184 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
185 if (!result)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
186 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
187 ad->error(loc, "member %s is not accessible", smember->toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
188 //printf("smember = %s %s, prot = %d, semanticRun = %d\n",
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
189 // smember->kind(), smember->toPrettyChars(), smember->prot(), smember->semanticRun);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
190 return true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
191 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
192 return false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
193 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
194
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
195 /****************************************
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
196 * Determine if this is the same or friend of cd.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
197 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
198 bool isFriendOf(AggregateDeclaration *ad, AggregateDeclaration *cd)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
199 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
200 if (ad == cd)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
201 return true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
202
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
203 // Friends if both are in the same module
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
204 //if (toParent() == cd->toParent())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
205 if (cd && ad->getAccessModule() == cd->getAccessModule())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
206 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
207 return true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
208 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
209
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
210 return false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
211 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
212
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
213 /****************************************
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
214 * Determine if scope sc has package level access to s.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
215 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
216 bool hasPackageAccess(Scope *sc, Dsymbol *s)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
217 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
218 return hasPackageAccess(sc->_module, s);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
219 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
220
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
221 bool hasPackageAccess(Module *mod, Dsymbol *s)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
222 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
223 Package *pkg = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
224
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
225 if (s->prot().pkg)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
226 pkg = s->prot().pkg;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
227 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
228 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
229 // no explicit package for protection, inferring most qualified one
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
230 for (; s; s = s->parent)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
231 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
232 if (Module *m = s->isModule())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
233 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
234 DsymbolTable *dst = Package::resolve(m->md ? m->md->packages : NULL, NULL, NULL);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
235 assert(dst);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
236 Dsymbol *s2 = dst->lookup(m->ident);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
237 assert(s2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
238 Package *p = s2->isPackage();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
239 if (p && p->isPackageMod())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
240 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
241 pkg = p;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
242 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
243 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
244 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
245 else if ((pkg = s->isPackage()) != NULL)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
246 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
247 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
248 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
249
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
250 if (pkg)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
251 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
252 if (pkg == mod->parent)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
253 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
254 return true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
255 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
256 if (pkg->isPackageMod() == mod)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
257 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
258 return true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
259 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
260 Dsymbol* ancestor = mod->parent;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
261 for (; ancestor; ancestor = ancestor->parent)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
262 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
263 if (ancestor == pkg)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
264 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
265 return true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
266 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
267 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
268 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
269
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
270 return false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
271 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
272
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
273 /****************************************
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
274 * Determine if scope sc has protected level access to cd.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
275 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
276 bool hasProtectedAccess(Scope *sc, Dsymbol *s)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
277 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
278 if (ClassDeclaration *cd = s->isClassMember()) // also includes interfaces
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
279 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
280 for (Scope *scx = sc; scx; scx = scx->enclosing)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
281 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
282 if (!scx->scopesym)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
283 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
284 ClassDeclaration *cd2 = scx->scopesym->isClassDeclaration();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
285 if (cd2 && cd->isBaseOf(cd2, NULL))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
286 return true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
287 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
288 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
289 return sc->_module == s->getAccessModule();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
290 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
291
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
292 /**********************************
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
293 * Determine if smember has access to private members of this declaration.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
294 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
295 bool hasPrivateAccess(AggregateDeclaration *ad, Dsymbol *smember)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
296 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
297 if (smember)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
298 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
299 AggregateDeclaration *cd = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
300 Dsymbol *smemberparent = smember->toParent();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
301 if (smemberparent)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
302 cd = smemberparent->isAggregateDeclaration();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
303
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
304 if (ad == cd) // smember is a member of this class
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
305 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
306 return true; // so we get private access
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
307 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
308
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
309 // If both are members of the same module, grant access
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
310 while (1)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
311 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
312 Dsymbol *sp = smember->toParent();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
313 if (sp->isFuncDeclaration() && smember->isFuncDeclaration())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
314 smember = sp;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
315 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
316 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
317 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
318 if (!cd && ad->toParent() == smember->toParent())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
319 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
320 return true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
321 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
322 if (!cd && ad->getAccessModule() == smember->getAccessModule())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
323 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
324 return true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
325 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
326 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
327 return false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
328 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
329
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
330 /****************************************
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
331 * Check access to d for expression e.d
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
332 * Returns true if the declaration is not accessible.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
333 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
334 bool checkAccess(Loc loc, Scope *sc, Expression *e, Declaration *d)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
335 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
336 if (sc->flags & SCOPEnoaccesscheck)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
337 return false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
338
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
339 if (d->isUnitTestDeclaration())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
340 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
341 // Unittests are always accessible.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
342 return false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
343 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
344 if (!e)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
345 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
346 if ((d->prot().kind == PROTprivate && d->getAccessModule() != sc->_module) ||
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
347 (d->prot().kind == PROTpackage && !hasPackageAccess(sc, d)))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
348 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
349 error(loc, "%s %s is not accessible from module %s",
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
350 d->kind(), d->toPrettyChars(), sc->_module->toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
351 return true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
352 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
353 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
354 else if (e->type->ty == Tclass)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
355 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
356 // Do access check
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
357 ClassDeclaration *cd = (ClassDeclaration *)(((TypeClass *)e->type)->sym);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
358 if (e->op == TOKsuper)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
359 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
360 ClassDeclaration *cd2 = sc->func->toParent()->isClassDeclaration();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
361 if (cd2)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
362 cd = cd2;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
363 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
364 return checkAccess(cd, loc, sc, d);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
365 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
366 else if (e->type->ty == Tstruct)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
367 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
368 // Do access check
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
369 StructDeclaration *cd = (StructDeclaration *)(((TypeStruct *)e->type)->sym);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
370 return checkAccess(cd, loc, sc, d);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
371 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
372 return false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
373 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
374
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
375 /****************************************
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
376 * Check access to package/module `p` from scope `sc`.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
377 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
378 * Params:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
379 * loc = source location for issued error message
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
380 * sc = scope from which to access to a fully qualified package name
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
381 * p = the package/module to check access for
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
382 * Returns: true if the package is not accessible.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
383 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
384 * Because a global symbol table tree is used for imported packages/modules,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
385 * access to them needs to be checked based on the imports in the scope chain
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
386 * (see Bugzilla 313).
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
387 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
388 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
389 bool checkAccess(Loc loc, Scope *sc, Package *p)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
390 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
391 if (sc->_module == p)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
392 return false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
393 for (; sc; sc = sc->enclosing)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
394 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
395 if (sc->scopesym && sc->scopesym->isPackageAccessible(p, Prot(PROTprivate)))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
396 return false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
397 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
398 const char *name = p->toPrettyChars();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
399 if (p->isPkgMod == PKGmodule || p->isModule())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
400 deprecation(loc, "%s %s is not accessible here, perhaps add 'static import %s;'", p->kind(), name, name);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
401 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
402 deprecation(loc, "%s %s is not accessible here", p->kind(), name);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
403 return true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
404 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
405
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
406 /**
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
407 * Check whether symbols `s` is visible in `mod`.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
408 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
409 * Params:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
410 * mod = lookup origin
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
411 * s = symbol to check for visibility
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
412 * Returns: true if s is visible in mod
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
413 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
414 bool symbolIsVisible(Module *mod, Dsymbol *s)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
415 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
416 // should sort overloads by ascending protection instead of iterating here
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
417 s = mostVisibleOverload(s);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
418
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
419 switch (s->prot().kind)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
420 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
421 case PROTundefined:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
422 return true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
423 case PROTnone:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
424 return false; // no access
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
425 case PROTprivate:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
426 return s->getAccessModule() == mod;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
427 case PROTpackage:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
428 return s->getAccessModule() == mod || hasPackageAccess(mod, s);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
429 case PROTprotected:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
430 return s->getAccessModule() == mod;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
431 case PROTpublic:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
432 case PROTexport:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
433 return true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
434 default:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
435 assert(0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
436 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
437 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
438
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
439 /**
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
440 * Same as above, but determines the lookup module from symbols `origin`.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
441 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
442 bool symbolIsVisible(Dsymbol *origin, Dsymbol *s)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
443 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
444 return symbolIsVisible(origin->getAccessModule(), s);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
445 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
446
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
447 /**
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
448 * Same as above but also checks for protected symbols visible from scope `sc`.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
449 * Used for qualified name lookup.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
450 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
451 * Params:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
452 * sc = lookup scope
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
453 * s = symbol to check for visibility
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
454 * Returns: true if s is visible by origin
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
455 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
456 bool symbolIsVisible(Scope *sc, Dsymbol *s)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
457 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
458 s = mostVisibleOverload(s);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
459
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
460 switch (s->prot().kind)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
461 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
462 case PROTundefined:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
463 return true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
464 case PROTnone:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
465 return false; // no access
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
466 case PROTprivate:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
467 return sc->_module == s->getAccessModule();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
468 case PROTpackage:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
469 return sc->_module == s->getAccessModule() || hasPackageAccess(sc->_module, s);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
470 case PROTprotected:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
471 return hasProtectedAccess(sc, s);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
472 case PROTpublic:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
473 case PROTexport:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
474 return true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
475 default:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
476 assert(0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
477 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
478 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
479
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
480 /**
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
481 * Use the most visible overload to check visibility. Later perform an access
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
482 * check on the resolved overload. This function is similar to overloadApply,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
483 * but doesn't recurse nor resolve aliases because protection/visibility is an
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
484 * attribute of the alias not the aliasee.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
485 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
486 static Dsymbol *mostVisibleOverload(Dsymbol *s)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
487 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
488 if (!s->isOverloadable())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
489 return s;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
490
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
491 Dsymbol *next = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
492 Dsymbol *fstart = s;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
493 Dsymbol *mostVisible = s;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
494 for (; s; s = next)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
495 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
496 // void func() {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
497 // private void func(int) {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
498 if (FuncDeclaration *fd = s->isFuncDeclaration())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
499 next = fd->overnext;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
500 // template temp(T) {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
501 // private template temp(T:int) {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
502 else if (TemplateDeclaration *td = s->isTemplateDeclaration())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
503 next = td->overnext;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
504 // alias common = mod1.func1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
505 // alias common = mod2.func2;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
506 else if (FuncAliasDeclaration *fa = s->isFuncAliasDeclaration())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
507 next = fa->overnext;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
508 // alias common = mod1.templ1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
509 // alias common = mod2.templ2;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
510 else if (OverDeclaration *od = s->isOverDeclaration())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
511 next = od->overnext;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
512 // alias name = sym;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
513 // private void name(int) {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
514 else if (AliasDeclaration *ad = s->isAliasDeclaration())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
515 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
516 if (!ad->isOverloadable())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
517 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
518 //printf("Non overloadable Aliasee in overload list\n");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
519 assert(0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
520 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
521 // Yet unresolved aliases store overloads in overnext.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
522 if (ad->semanticRun < PASSsemanticdone)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
523 next = ad->overnext;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
524 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
525 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
526 /* This is a bit messy due to the complicated implementation of
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
527 * alias. Aliases aren't overloadable themselves, but if their
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
528 * Aliasee is overloadable they can be converted to an overloadable
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
529 * alias.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
530 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
531 * This is done by replacing the Aliasee w/ FuncAliasDeclaration
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
532 * (for functions) or OverDeclaration (for templates) which are
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
533 * simply overloadable aliases w/ weird names.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
534 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
535 * Usually aliases should not be resolved for visibility checking
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
536 * b/c public aliases to private symbols are public. But for the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
537 * overloadable alias situation, the Alias (_ad_) has been moved
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
538 * into it's own Aliasee, leaving a shell that we peel away here.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
539 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
540 Dsymbol *aliasee = ad->toAlias();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
541 if (aliasee->isFuncAliasDeclaration() || aliasee->isOverDeclaration())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
542 next = aliasee;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
543 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
544 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
545 /* A simple alias can be at the end of a function or template overload chain.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
546 * It can't have further overloads b/c it would have been
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
547 * converted to an overloadable alias.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
548 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
549 if (ad->overnext)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
550 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
551 //printf("Unresolved overload of alias\n");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
552 assert(0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
553 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
554 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
555 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
556 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
557
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
558 // handled by overloadApply for unknown reason
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
559 assert(next != ad); // should not alias itself
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
560 assert(next != fstart); // should not alias the overload list itself
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
561 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
562 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
563 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
564
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
565 if (next && mostVisible->prot().isMoreRestrictiveThan(next->prot()))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
566 mostVisible = next;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
567 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
568 return mostVisible;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
569 }