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; 81 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:: 114 S_OwnerStack::CurNamespace() const 115 { 116 csv_assert( aStack_Namespaces.size() > 0 ); 117 return *aStack_Namespaces.top(); 118 } 119 120 inline ary::cpp::Class * 121 ContextForAry:: 122 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:: 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:: 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:: 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:: 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:: 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:: 182 S_OwnerStack::~S_OwnerStack() 183 { 184 } 185 186 inline void 187 ContextForAry:: 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:: 197 S_OwnerStack::OpenExternC() 198 { 199 ++nExternC; 200 // SetOwner_2None(); 201 } 202 203 inline void 204 ContextForAry:: 205 S_OwnerStack::SetCurProtection( ary::cpp::E_Protection i_eProtection ) 206 { 207 csv_assert( aStack_Classes.size() > 0 ); 208 aStack_Classes.top().second = i_eProtection; 209 } 210 211 inline ary::cpp::Enum * 212 ContextForAry:: 213 S_OwnerStack::CurEnum() const 214 { 215 return pCurEnum; 216 } 217 218 219 inline ary::cpp::InputContext::Owner & 220 ContextForAry:: 221 S_OwnerStack::CurOwner() const 222 { 223 csv_assert( pOwner_Cur != 0 ); 224 return *pOwner_Cur; 225 } 226 227 inline E_Protection 228 ContextForAry:: 229 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:: 238 S_OwnerStack::SetOwner_2None() 239 { 240 pOwner_Cur = 0; 241 } 242 243 void 244 ContextForAry:: 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:: 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:: 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:: 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:: 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