1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 #ifndef ADC_CPP_SOWNSTCK_HXX
25 #define ADC_CPP_SOWNSTCK_HXX
26
27
28
29 // USED SERVICES
30 // BASE CLASSES
31 #include "cxt2ary.hxx"
32 // COMPONENTS
33 #include <ary/cpp/c_types4cpp.hxx>
34 #include <estack.hxx>
35 // PARAMETERS
36 #include <ary/cpp/c_namesp.hxx>
37 #include <x_parse.hxx>
38
39
40 namespace cpp
41 {
42
43 using ary::cpp::E_Protection;
44
45
46 /** Implementation struct for cpp::ContextForAry.
47 */
48 struct ContextForAry::S_OwnerStack
49 {
50 public:
51 S_OwnerStack();
52 void SetGlobalNamespace(
53 ary::cpp::Namespace &
54 io_rGlobalNamespace );
55 ~S_OwnerStack();
56
57 void Reset();
58
59 void OpenNamespace(
60 ary::cpp::Namespace &
61 io_rOpenedNamespace );
62 void OpenExternC();
63 void OpenClass(
64 ary::cpp::Class & io_rOpenedClass );
65 void OpenEnum(
66 ary::cpp::Enum & io_rOpenedEnum );
67 void CloseBlock();
68 void CloseClass();
69 void CloseEnum();
70 void SetCurProtection(
71 ary::cpp::E_Protection
72 i_eProtection );
73 ary::cpp::Namespace &
74 CurNamespace() const;
75 ary::cpp::Class * CurClass() const;
76 ary::cpp::Enum * CurEnum() const;
77
78 Owner & CurOwner() const;
79 ary::cpp::E_Protection
80 CurProtection() const;
IsExternCcpp::ContextForAry::S_OwnerStack81 bool IsExternC() const { return nExternC > 0; }
82
83 private:
84 typedef std::pair< ary::cpp::Class*, E_Protection > ClassEnv;
85 typedef EStack< ary::cpp::Namespace* > Stack_Namespaces;
86 typedef EStack< ClassEnv > Stack_Classes;
87 typedef ary::cpp::InputContext::Owner Ifc_Owner;
88
89 void SetOwner_2CurNamespace();
90 void SetOwner_2CurClass();
91 void SetOwner_2None();
92
93 // DATA
94 Stack_Namespaces aStack_Namespaces;
95 Stack_Classes aStack_Classes;
96 ary::cpp::Enum * pCurEnum;
97 uintt nExternC; /// This is a number, for the case that extern "C" blocks are nested.
98
99 Dyn<Owner_Namespace>
100 pOwner_Namespace;
101 Dyn<Owner_Class> pOwner_Class;
102 Ifc_Owner * pOwner_Cur;
103 };
104
105
106 // IMPLEMENTATION
107
108 /* The implementation is in header, though not inline, because this file is included
109 in cxt2ary.cxx only!
110 */
111
112 inline ary::cpp::Namespace &
113 ContextForAry::
CurNamespace() const114 S_OwnerStack::CurNamespace() const
115 {
116 csv_assert( ! aStack_Namespaces.empty() );
117 return *aStack_Namespaces.top();
118 }
119
120 inline ary::cpp::Class *
121 ContextForAry::
CurClass() const122 S_OwnerStack::CurClass() const
123 {
124 return !aStack_Classes.empty()
125 ? aStack_Classes.top().first
126 : (ary::cpp::Class *) 0;
127 }
128
129 inline void
130 ContextForAry::
SetOwner_2CurNamespace()131 S_OwnerStack::SetOwner_2CurNamespace()
132 {
133 csv_assert( !aStack_Namespaces.empty() );
134 pOwner_Cur = pOwner_Namespace.MutablePtr();
135 pOwner_Namespace->SetAnotherNamespace( CurNamespace() );
136 }
137
138 inline void
139 ContextForAry::
SetOwner_2CurClass()140 S_OwnerStack::SetOwner_2CurClass()
141 {
142 csv_assert( !aStack_Classes.empty() );
143 pOwner_Cur = pOwner_Class.MutablePtr();
144 pOwner_Class->SetAnotherClass( *CurClass() );
145 }
146
147 ContextForAry::
S_OwnerStack()148 S_OwnerStack::S_OwnerStack()
149 : // aStack_Namespaces,
150 // aStack_Classes,
151 pCurEnum(0),
152 nExternC(0),
153 pOwner_Namespace(new Owner_Namespace),
154 pOwner_Class(new Owner_Class),
155 pOwner_Cur(0)
156 {
157 }
158
159 void
160 ContextForAry::
Reset()161 S_OwnerStack::Reset()
162 {
163 while ( aStack_Namespaces.top()->Owner().IsValid() )
164 aStack_Namespaces.pop();
165 while ( NOT aStack_Classes.empty() )
166 aStack_Classes.pop();
167 pCurEnum = 0;
168 nExternC = 0;
169 SetOwner_2CurNamespace();
170 }
171
172 inline void
173 ContextForAry::
SetGlobalNamespace(ary::cpp::Namespace & io_rGlobalNamespace)174 S_OwnerStack::SetGlobalNamespace( ary::cpp::Namespace & io_rGlobalNamespace )
175 {
176 csv_assert( aStack_Namespaces.empty() );
177 aStack_Namespaces.push(&io_rGlobalNamespace);
178 SetOwner_2CurNamespace();
179 }
180
181 ContextForAry::
~S_OwnerStack()182 S_OwnerStack::~S_OwnerStack()
183 {
184 }
185
186 inline void
187 ContextForAry::
OpenNamespace(ary::cpp::Namespace & io_rOpenedNamespace)188 S_OwnerStack::OpenNamespace( ary::cpp::Namespace & io_rOpenedNamespace )
189 {
190 csv_assert( !aStack_Namespaces.empty() OR io_rOpenedNamespace.Parent() == 0 );
191 aStack_Namespaces.push(&io_rOpenedNamespace);
192 SetOwner_2CurNamespace();
193 }
194
195 inline void
196 ContextForAry::
OpenExternC()197 S_OwnerStack::OpenExternC()
198 {
199 ++nExternC;
200 // SetOwner_2None();
201 }
202
203 inline void
204 ContextForAry::
SetCurProtection(ary::cpp::E_Protection i_eProtection)205 S_OwnerStack::SetCurProtection( ary::cpp::E_Protection i_eProtection )
206 {
207 csv_assert( ! aStack_Classes.empty() );
208 aStack_Classes.top().second = i_eProtection;
209 }
210
211 inline ary::cpp::Enum *
212 ContextForAry::
CurEnum() const213 S_OwnerStack::CurEnum() const
214 {
215 return pCurEnum;
216 }
217
218
219 inline ary::cpp::InputContext::Owner &
220 ContextForAry::
CurOwner() const221 S_OwnerStack::CurOwner() const
222 {
223 csv_assert( pOwner_Cur != 0 );
224 return *pOwner_Cur;
225 }
226
227 inline E_Protection
228 ContextForAry::
CurProtection() const229 S_OwnerStack::CurProtection() const
230 {
231 return !aStack_Classes.empty()
232 ? aStack_Classes.top().second
233 : ary::cpp::PROTECT_global;
234 }
235
236 inline void
237 ContextForAry::
SetOwner_2None()238 S_OwnerStack::SetOwner_2None()
239 {
240 pOwner_Cur = 0;
241 }
242
243 void
244 ContextForAry::
OpenClass(ary::cpp::Class & io_rOpenedClass)245 S_OwnerStack::OpenClass( ary::cpp::Class & io_rOpenedClass )
246 {
247 E_Protection eDefaultProtection
248 = io_rOpenedClass.ClassKey() == ary::cpp::CK_class
249 ? ary::cpp::PROTECT_private
250 : ary::cpp::PROTECT_public;
251 aStack_Classes.push( ClassEnv(&io_rOpenedClass, eDefaultProtection) );
252 SetOwner_2CurClass();
253 }
254
255 inline void
256 ContextForAry::
OpenEnum(ary::cpp::Enum & io_rOpenedEnum)257 S_OwnerStack::OpenEnum( ary::cpp::Enum & io_rOpenedEnum )
258 {
259 csv_assert( pCurEnum == 0 );
260 pCurEnum = &io_rOpenedEnum;
261 SetOwner_2None();
262 }
263
264 void
265 ContextForAry::
CloseBlock()266 S_OwnerStack::CloseBlock()
267 {
268 if (nExternC > 0)
269 {
270 --nExternC;
271 }
272 else
273 {
274 // csv_assert( aStack_Classes.empty() );
275 if ( !aStack_Classes.empty() )
276 throw X_Parser(X_Parser::x_UnspecifiedSyntaxError, "", String::Null_(), 0);
277
278 csv_assert( pCurEnum == 0 );
279 aStack_Namespaces.pop();
280
281 // csv_assert( !aStack_Namespaces.empty() );
282 if( aStack_Namespaces.empty() )
283 throw X_Parser(X_Parser::x_UnspecifiedSyntaxError, "", String::Null_(), 0);
284
285 }
286 SetOwner_2CurNamespace();
287 }
288
289 void
290 ContextForAry::
CloseClass()291 S_OwnerStack::CloseClass()
292 {
293 // csv_assert( !aStack_Classes.empty() );
294 if ( aStack_Classes.empty() )
295 throw X_Parser(X_Parser::x_UnspecifiedSyntaxError, "", String::Null_(), 0);
296
297 aStack_Classes.pop();
298 if ( !aStack_Classes.empty() )
299 SetOwner_2CurClass();
300 else
301 SetOwner_2CurNamespace();
302 }
303
304 void
305 ContextForAry::
CloseEnum()306 S_OwnerStack::CloseEnum()
307 {
308 csv_assert( pCurEnum != 0 );
309 pCurEnum = 0;
310 if ( !aStack_Classes.empty() )
311 SetOwner_2CurClass();
312 else
313 SetOwner_2CurNamespace();
314 }
315
316
317 } // namespace cpp
318
319
320 #endif
321
322