2 +----------------------------------------------------------------------+
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 #include "hphp/runtime/base/array/array_util.h"
18 #include "hphp/runtime/base/class_info.h"
19 #include "hphp/runtime/base/complex_types.h"
20 #include "hphp/runtime/base/externals.h"
21 #include "hphp/runtime/base/hphp_system.h"
22 #include "hphp/runtime/base/variable_serializer.h"
23 #include "hphp/runtime/base/variable_unserializer.h"
24 #include "hphp/util/util.h"
25 #include "hphp/util/lock.h"
26 #include "hphp/util/logger.h"
29 ///////////////////////////////////////////////////////////////////////////////
32 bool ClassInfo::s_loaded
= false;
33 ClassInfo
*ClassInfo::s_systemFuncs
= nullptr;
34 ClassInfo::ClassMap
ClassInfo::s_class_like
;
35 ClassInfoHook
*ClassInfo::s_hook
= nullptr;
37 Array
ClassInfo::GetSystemFunctions() {
40 Array ret
= Array::Create();
42 const MethodVec
&methods
= s_systemFuncs
->getMethodsVec();
43 for (unsigned i
= 0; i
< methods
.size(); i
++) {
44 ret
.append(methods
[i
]->name
);
50 Array
ClassInfo::GetUserFunctions() {
53 Array ret
= Array::Create();
55 Array dyn
= s_hook
->getUserFunctions();
58 // De-dup values, then renumber (for aesthetics).
59 ret
= ArrayUtil::StringUnique(ret
).toArrRef();
66 const ClassInfo::MethodInfo
*ClassInfo::FindSystemFunction(CStrRef name
) {
67 assert(!name
.isNull());
70 return s_systemFuncs
->getMethodInfo(name
);
73 const ClassInfo::MethodInfo
*ClassInfo::FindFunction(CStrRef name
) {
74 assert(!name
.isNull());
77 const MethodInfo
*ret
= s_systemFuncs
->getMethodInfo(name
);
78 if (ret
== nullptr && s_hook
) {
79 ret
= s_hook
->findFunction(name
);
84 const ClassInfo
*ClassInfo::FindClassInterfaceOrTrait(CStrRef name
) {
85 assert(!name
.isNull());
89 const ClassInfo
*r
= s_hook
->findClassLike(name
);
93 ClassMap::const_iterator iter
= s_class_like
.find(name
);
94 if (iter
!= s_class_like
.end()) {
95 return iter
->second
->getDeclared();
101 const ClassInfo
*ClassInfo::FindClass(CStrRef name
) {
102 if (const ClassInfo
*r
= FindClassInterfaceOrTrait(name
)) {
103 return r
->getAttribute() & (IsTrait
|IsInterface
) ? 0 : r
;
108 const ClassInfo
*ClassInfo::FindInterface(CStrRef name
) {
109 if (const ClassInfo
*r
= FindClassInterfaceOrTrait(name
)) {
110 return r
->getAttribute() & IsInterface
? r
: 0;
115 const ClassInfo
*ClassInfo::FindTrait(CStrRef name
) {
116 if (const ClassInfo
*r
= FindClassInterfaceOrTrait(name
)) {
117 return r
->getAttribute() & IsTrait
? r
: 0;
122 const ClassInfo
*ClassInfo::FindSystemClassInterfaceOrTrait(CStrRef name
) {
123 assert(!name
.isNull());
126 ClassMap::const_iterator iter
= s_class_like
.find(name
);
127 if (iter
!= s_class_like
.end()) {
128 const ClassInfo
*ci
= iter
->second
;
129 if (ci
->m_attribute
& IsSystem
) return ci
;
135 const ClassInfo
*ClassInfo::FindSystemClass(CStrRef name
) {
136 if (const ClassInfo
*r
= FindSystemClassInterfaceOrTrait(name
)) {
137 return r
->getAttribute() & (IsTrait
|IsInterface
) ? 0 : r
;
142 const ClassInfo
*ClassInfo::FindSystemInterface(CStrRef name
) {
143 if (const ClassInfo
*r
= FindSystemClassInterfaceOrTrait(name
)) {
144 return r
->getAttribute() & IsInterface
? r
: 0;
149 const ClassInfo
*ClassInfo::FindSystemTrait(CStrRef name
) {
150 if (const ClassInfo
*r
= FindSystemClassInterfaceOrTrait(name
)) {
151 return r
->getAttribute() & IsTrait
? r
: 0;
156 Array
ClassInfo::GetClassLike(unsigned mask
, unsigned value
) {
159 Array ret
= Array::Create();
160 for (ClassMap::const_iterator iter
= s_class_like
.begin();
161 iter
!= s_class_like
.end(); ++iter
) {
162 const ClassInfo
*info
= iter
->second
->getDeclared();
163 if (!info
|| (info
->m_attribute
& mask
) != value
) continue;
164 ret
.append(info
->m_name
);
167 if (value
& IsInterface
) {
168 Array dyn
= s_hook
->getInterfaces();
171 // De-dup values, then renumber (for aesthetics).
172 ret
= ArrayUtil::StringUnique(ret
).toArrRef();
175 } else if (value
& IsTrait
) {
176 Array dyn
= s_hook
->getTraits();
179 // De-dup values, then renumber (for aesthetics).
180 ret
= ArrayUtil::StringUnique(ret
).toArrRef();
184 Array dyn
= s_hook
->getClasses();
187 // De-dup values, then renumber (for aesthetics).
188 ret
= ArrayUtil::StringUnique(ret
).toArrRef();
196 ClassInfo::ConstantInfo::ConstantInfo() :
197 valueLen(0), callback(nullptr), deferred(true) {
200 CVarRef
ClassInfo::ConstantInfo::getDeferredValue() const {
203 CVarRef (*f
)()=(CVarRef(*)())callback
;
206 SystemGlobals
* g
= get_global_variables();
207 return g
->stgv_Variant
[valueLen
];
210 Variant
ClassInfo::ConstantInfo::getValue() const {
212 return getDeferredValue();
214 if (!svalue
.empty()) {
216 VariableUnserializer
vu(svalue
.data(), svalue
.size(),
217 VariableUnserializer::Serialize
);
218 return vu
.unserialize();
219 } catch (Exception
&e
) {
226 void ClassInfo::ConstantInfo::setValue(CVarRef value
) {
227 VariableSerializer
vs(VariableSerializer::Serialize
);
228 String s
= vs
.serialize(value
, true);
229 svalue
= string(s
.data(), s
.size());
233 void ClassInfo::ConstantInfo::setStaticValue(CVarRef v
) {
235 value
.setEvalScalar();
239 void ClassInfo::InitializeSystemConstants() {
241 const ConstantMap
&scm
= s_systemFuncs
->getConstants();
242 for (ConstantMap::const_iterator it
= scm
.begin(); it
!= scm
.end(); ++it
) {
243 ConstantInfo
* ci
= it
->second
;
244 if (ci
->isDynamic()) {
245 Unit::defDynamicSystemConstant(ci
->name
.get(), ci
);
247 Variant v
= ci
->getValue();
248 bool DEBUG_ONLY res
= Unit::defCns(ci
->name
.get(),
249 v
.asTypedValue(), true);
255 Array
ClassInfo::GetSystemConstants() {
258 const ConstantMap
&scm
= s_systemFuncs
->getConstants();
259 for (ConstantMap::const_iterator it
= scm
.begin(); it
!= scm
.end(); ++it
) {
260 if (!it
->second
->isDynamic()) {
261 res
.set(it
->second
->name
, it
->second
->getValue());
267 Array
ClassInfo::GetConstants() {
272 const ConstantMap
&scm
= s_systemFuncs
->getConstants();
273 for (ConstantMap::const_iterator it
= scm
.begin(); it
!= scm
.end(); ++it
) {
274 res
.set(it
->second
->name
, it
->second
->getValue());
278 dyn
= s_hook
->getConstants();
286 ClassInfo::UserAttributeInfo::UserAttributeInfo() {
289 Variant
ClassInfo::UserAttributeInfo::getValue() const {
293 void ClassInfo::UserAttributeInfo::setStaticValue(CVarRef v
) {
295 value
.setEvalScalar();
298 bool ClassInfo::GetClassMethods(MethodVec
&ret
, CStrRef classname
,
299 int type
/* = 0 */) {
300 if (classname
.empty()) return false;
302 const ClassInfo
*classInfo
= nullptr;
305 classInfo
= FindClassInterfaceOrTrait(classname
);
308 classInfo
= FindClass(classname
);
311 classInfo
= FindInterface(classname
);
314 classInfo
= FindTrait(classname
);
320 if (!classInfo
) return false;
321 return GetClassMethods(ret
, classInfo
);
324 bool ClassInfo::GetClassMethods(MethodVec
&ret
, const ClassInfo
*classInfo
) {
325 const ClassInfo::MethodVec
&methods
= classInfo
->getMethodsVec();
326 ret
.insert(ret
.end(), methods
.begin(), methods
.end());
328 if (!(classInfo
->getAttribute() & (IsInterface
|IsTrait
))) {
329 CStrRef parentClass
= classInfo
->getParentClass();
330 if (!parentClass
.empty()) {
331 if (!GetClassMethods(ret
, parentClass
, 1)) return false;
335 const ClassInfo::InterfaceVec
&interfaces
=
336 classInfo
->getInterfacesVec();
337 for (unsigned int i
= 0; i
< interfaces
.size(); i
++) {
338 if (!GetClassMethods(ret
, interfaces
[i
], 2)) return false;
344 void ClassInfo::GetClassSymbolNames(CArrRef names
, bool interface
, bool trait
,
345 std::vector
<String
> &classes
,
346 std::vector
<String
> *clsMethods
,
347 std::vector
<String
> *clsProperties
,
348 std::vector
<String
> *clsConstants
) {
349 if (clsMethods
|| clsProperties
|| clsConstants
) {
350 for (ArrayIter
iter(names
); iter
; ++iter
) {
351 String clsname
= iter
.second().toString();
352 classes
.push_back(clsname
);
354 const ClassInfo
*cls
;
356 cls
= FindInterface(clsname
.data());
358 cls
= FindTrait(clsname
.data());
361 cls
= FindClass(clsname
.data());
362 } catch (Exception
&e
) {
363 Logger::Error("Caught exception %s", e
.getMessage().c_str());
366 Logger::Error("Caught unknown exception");
372 const ClassInfo::MethodVec
&methods
= cls
->getMethodsVec();
373 for (unsigned int i
= 0; i
< methods
.size(); i
++) {
374 clsMethods
->push_back(clsname
+ "::" + methods
[i
]->name
);
378 const ClassInfo::PropertyVec
&properties
= cls
->getPropertiesVec();
379 for (ClassInfo::PropertyVec::const_iterator iter
= properties
.begin();
380 iter
!= properties
.end(); ++iter
) {
381 clsProperties
->push_back(clsname
+ "::$" + (*iter
)->name
);
385 const ClassInfo::ConstantVec
&constants
= cls
->getConstantsVec();
386 for (ClassInfo::ConstantVec::const_iterator iter
= constants
.begin();
387 iter
!= constants
.end(); ++iter
) {
388 clsConstants
->push_back(clsname
+ "::" + (*iter
)->name
);
393 for (ArrayIter
iter(names
); iter
; ++iter
) {
394 classes
.push_back(iter
.second().toString());
399 void ClassInfo::GetSymbolNames(std::vector
<String
> &classes
,
400 std::vector
<String
> &functions
,
401 std::vector
<String
> &constants
,
402 std::vector
<String
> *clsMethods
,
403 std::vector
<String
> *clsProperties
,
404 std::vector
<String
> *clsConstants
) {
405 static unsigned int methodSize
= 128;
406 static unsigned int propSize
= 128;
407 static unsigned int constSize
= 128;
410 clsMethods
->reserve(methodSize
);
413 clsProperties
->reserve(propSize
);
416 clsConstants
->reserve(constSize
);
419 GetClassSymbolNames(GetClasses(), false, false, classes
,
420 clsMethods
, clsProperties
, clsConstants
);
421 GetClassSymbolNames(GetInterfaces(), true, false, classes
,
422 clsMethods
, clsProperties
, clsConstants
);
424 if (clsMethods
&& methodSize
< clsMethods
->size()) {
425 methodSize
= clsMethods
->size();
427 if (clsProperties
&& propSize
< clsProperties
->size()) {
428 propSize
= clsProperties
->size();
430 if (constSize
&& constSize
< clsConstants
->size()) {
431 constSize
= clsConstants
->size();
434 Array funcs1
= ClassInfo::GetSystemFunctions();
435 Array funcs2
= ClassInfo::GetUserFunctions();
436 functions
.reserve(funcs1
.size() + funcs2
.size());
437 for (ArrayIter
iter(funcs1
); iter
; ++iter
) {
438 functions
.push_back(iter
.second().toString());
440 for (ArrayIter
iter(funcs2
); iter
; ++iter
) {
441 functions
.push_back(iter
.second().toString());
443 Array consts
= GetConstants();
444 constants
.reserve(consts
.size());
445 for (ArrayIter
iter(consts
); iter
; ++iter
) {
446 constants
.push_back(iter
.first().toString());
450 ///////////////////////////////////////////////////////////////////////////////
453 const ClassInfo
*ClassInfo::getDeclared() const {
454 if (m_attribute
& IsRedeclared
) {
455 return getCurrentOrNull();
456 } else if (m_attribute
& IsVolatile
) {
457 return *(bool*)((char*)get_global_variables() + m_cdec_offset
) ? this : 0;
463 const ClassInfo
*ClassInfo::getParentClassInfo() const {
464 CStrRef parentName
= getParentClass();
465 if (parentName
.empty()) return nullptr;
466 return FindClass(parentName
);
469 ClassInfo::MethodInfo
*ClassInfo::getMethodInfo(CStrRef name
) const {
470 assert(!name
.isNull());
472 const MethodMap
&methods
= getMethods();
473 MethodMap::const_iterator iter
= methods
.find(name
);
474 if (iter
!= methods
.end()) {
475 ClassInfo::MethodInfo
*m
= iter
->second
;
476 if (m
->attribute
& (IsVolatile
|IsRedeclared
)) {
477 return m
->getDeclared();
484 ClassInfo::MethodInfo
*ClassInfo::hasMethod(CStrRef name
,
485 ClassInfo
* &classInfo
,
486 bool interfaces
/* = false */)
488 assert(!name
.isNull());
489 classInfo
= (ClassInfo
*)this;
490 const MethodMap
&methods
= getMethods();
491 MethodMap::const_iterator it
= methods
.find(name
);
492 if (it
!= methods
.end()) {
493 assert(!(it
->second
->attribute
& (IsVolatile
|IsRedeclared
)));
496 ClassInfo::MethodInfo
*result
= nullptr;
497 const ClassInfo
*parent
= getParentClassInfo();
498 if (parent
) result
= parent
->hasMethod(name
, classInfo
);
499 if (result
|| !interfaces
|| !(m_attribute
& IsAbstract
)) return result
;
500 // TODO: consider caching the iface lookups
501 const InterfaceVec
&ifaces
= getInterfacesVec();
502 for (InterfaceVec::const_iterator it
= ifaces
.begin();
503 it
!= ifaces
.end(); ++it
) {
504 const ClassInfo
*iface
= FindInterface(*it
);
505 if (iface
) result
= iface
->hasMethod(name
, classInfo
, true);
506 if (result
) return result
;
511 ///////////////////////////////////////////////////////////////////////////////
514 static String
makeStaticString(const char *s
) {
518 return StringData::GetStaticString(s
);
521 void ClassInfo::ReadUserAttributes(const char **&p
,
522 std::vector
<const UserAttributeInfo
*> &userAttrVec
) {
524 UserAttributeInfo
*userAttr
= new UserAttributeInfo();
525 userAttr
->name
= makeStaticString(*p
++);
527 const char *len
= *p
++;
528 const char *valueText
= *p
++;
529 int64_t valueLen
= (int64_t)len
;
530 VariableUnserializer
vu(valueText
,
532 VariableUnserializer::Serialize
);
533 userAttr
->setStaticValue(vu
.unserialize());
535 userAttrVec
.push_back(userAttr
);
539 ClassInfo::MethodInfo
*ClassInfo::MethodInfo::getDeclared() {
540 assert(!(attribute
& ClassInfo::IsRedeclared
));
541 assert(!(attribute
& ClassInfo::IsVolatile
));
545 ClassInfo::MethodInfo::MethodInfo(const char **&p
) {
546 attribute
= (Attribute
)(int64_t)(*p
++);
547 name
= makeStaticString(*p
++);
549 if (attribute
& ClassInfo::IsRedeclared
) {
550 volatile_redec_offset
= (int)(int64_t)(*p
++);
552 MethodInfo
*m
= new MethodInfo(p
);
553 parameters
.push_back((ParameterInfo
*)(void*)m
);
557 line1
= (int)(int64_t)(*p
++);
558 line2
= (int)(int64_t)(*p
++);
559 if (attribute
& IsVolatile
) {
560 volatile_redec_offset
= (int)(int64_t)(*p
++);
563 if (attribute
& HasDocComment
) {
567 if (attribute
& IsSystem
) {
568 returnType
= (DataType
)(int64_t)(*p
++);
571 ParameterInfo
*parameter
= new ParameterInfo();
572 parameter
->attribute
= (Attribute
)(int64_t)(*p
++);
573 parameter
->name
= *p
++;
574 parameter
->type
= *p
++;
575 if (attribute
& IsSystem
) {
576 parameter
->argType
= (DataType
)(int64_t)(*p
++);
578 parameter
->value
= *p
++;
579 parameter
->valueLen
= (int64_t)*p
++;
580 parameter
->valueText
= *p
++;
581 parameter
->valueTextLen
= (int64_t)*p
++;
583 ClassInfo::ReadUserAttributes(p
, parameter
->userAttrs
);
586 parameters
.push_back(parameter
);
591 ConstantInfo
*staticVariable
= new ConstantInfo();
592 staticVariable
->name
= makeStaticString(*p
++);
593 staticVariable
->valueLen
= (int64_t)(*p
++);
594 staticVariable
->valueText
= *p
++;
595 VariableUnserializer
vu(staticVariable
->valueText
,
596 staticVariable
->valueLen
,
597 VariableUnserializer::Serialize
);
599 staticVariable
->setStaticValue(vu
.unserialize());
600 } catch (Exception
&e
) {
603 staticVariables
.push_back(staticVariable
);
607 ClassInfo::ReadUserAttributes(p
, userAttrs
);
613 ClassInfoUnique::ClassInfoUnique(const char **&p
) {
614 m_attribute
= (Attribute
)(int64_t)(*p
++);
615 assert(!(m_attribute
& IsRedeclared
));
617 // ClassInfoUnique is only created by ClassInfo::Load(), which is called
618 // from hphp_process_init() in the thread-neutral initialization phase.
619 // It is OK to create StaticStrings here, and throw the smart ptrs away,
620 // because the underlying static StringData will not be released.
621 m_name
= makeStaticString(*p
++);
622 m_parent
= makeStaticString(*p
++);
626 m_line1
= (int)(int64_t)(*p
++);
627 m_line2
= (int)(int64_t)(*p
++);
629 if (m_attribute
& IsVolatile
) {
630 m_cdec_offset
= (int)(int64_t)(*p
++);
633 if (m_attribute
& HasDocComment
) {
638 String iface_name
= makeStaticString(*p
++);
639 assert(m_interfaces
.find(iface_name
) == m_interfaces
.end());
640 m_interfaces
.insert(iface_name
);
641 m_interfacesVec
.push_back(iface_name
);
645 if (m_attribute
& ClassInfo::UsesTraits
) {
647 String trait_name
= makeStaticString(*p
++);
648 assert(m_traits
.find(trait_name
) == m_traits
.end());
649 m_traits
.insert(trait_name
);
650 m_traitsVec
.push_back(trait_name
);
655 if (m_attribute
& ClassInfo::HasAliasedMethods
) {
657 String new_name
= makeStaticString(*p
++);
658 String old_name
= makeStaticString(*p
++);
659 m_traitAliasesVec
.push_back(std::pair
<String
, String
>(
660 new_name
, old_name
));
666 MethodInfo
*method
= new MethodInfo(p
);
668 assert(m_methods
.find(method
->name
) == m_methods
.end());
669 m_methods
[method
->name
] = method
;
670 m_methodsVec
.push_back(method
);
675 PropertyInfo
*property
= new PropertyInfo();
676 property
->attribute
= (Attribute
)(int64_t)(*p
++);
677 property
->name
= makeStaticString(*p
++);
678 property
->type
= DataType((int)uintptr_t(*p
++));
679 property
->owner
= this;
680 assert(m_properties
.find(property
->name
) == m_properties
.end());
681 m_properties
[property
->name
] = property
;
682 m_propertiesVec
.push_back(property
);
687 ConstantInfo
*constant
= new ConstantInfo();
688 constant
->name
= makeStaticString(*p
++);
689 const char *len_or_cw
= *p
++;
690 constant
->valueText
= *p
++;
692 if (uintptr_t(constant
->valueText
) > 0x100) {
693 constant
->valueLen
= (int64_t)len_or_cw
;
694 VariableUnserializer
vu(constant
->valueText
,
696 VariableUnserializer::Serialize
);
698 constant
->setStaticValue(vu
.unserialize());
699 } catch (Exception
&e
) {
702 } else if (constant
->valueText
) {
703 DataType dt
= DataType((int)uintptr_t(constant
->valueText
) - 2);
704 constant
->valueLen
= 0;
705 constant
->valueText
= nullptr;
707 if (dt
== KindOfUnknown
) {
708 constant
->valueLen
= intptr_t(len_or_cw
);
710 v
= ClassInfo::GetVariant(dt
, len_or_cw
);
711 constant
->setStaticValue(v
);
714 constant
->callback
= (void*)len_or_cw
;
717 assert(m_constants
.find(constant
->name
) == m_constants
.end());
718 m_constants
[constant
->name
] = constant
;
719 m_constantsVec
.push_back(constant
);
724 UserAttributeInfo
*userAttr
= new UserAttributeInfo();
725 userAttr
->name
= makeStaticString(*p
++);
727 const char *len
= *p
++;
728 const char *valueText
= *p
++;
729 int64_t valueLen
= (int64_t)len
;
730 VariableUnserializer
vu(valueText
,
732 VariableUnserializer::Serialize
);
733 userAttr
->setStaticValue(vu
.unserialize());
735 m_userAttrVec
.push_back(userAttr
);
740 ClassInfoUnique::~ClassInfoUnique() {
741 for (auto it
= m_userAttrVec
.begin(); it
!= m_userAttrVec
.end(); ++it
) {
746 const ClassInfo
*ClassInfoUnique::getParentClassInfo() const {
747 if (m_parentInfo
) return m_parentInfo
;
748 if (m_parent
.empty()) return nullptr;
749 return FindClass(m_parent
);
752 void ClassInfoUnique::postInit() {
753 if (m_parent
.empty()) return;
754 const ClassInfo
*ci
= FindClassInterfaceOrTrait(m_parent
);
756 if ((m_attribute
& IsInterface
) !=
757 (ci
->getAttribute() & (IsInterface
|IsTrait
|IsRedeclared
))) {
763 void ClassInfo::Load() {
764 if (s_loaded
) return;
765 const char **p
= g_class_map
;
767 Attribute attribute
= (Attribute
)(int64_t)*p
;
768 always_assert(!(attribute
& IsRedeclared
));
769 ClassInfo
*info
= new ClassInfoUnique(p
);
771 if (info
->m_name
.empty()) {
772 if (attribute
& IsSystem
) {
773 assert(s_systemFuncs
== nullptr);
774 s_systemFuncs
= info
;
776 always_assert(false);
779 ClassInfo
*&i
= s_class_like
[info
->m_name
];
785 assert(s_systemFuncs
);
788 for (ClassMap::iterator it
= s_class_like
.begin(), end
= s_class_like
.end();
790 it
->second
->postInit();
794 void ClassInfo::postInit() {}
796 ClassInfo::ParameterInfo::~ParameterInfo() {
797 for (auto it
= userAttrs
.begin(); it
!= userAttrs
.end(); ++it
) {
802 ClassInfo::MethodInfo::~MethodInfo() {
803 if (attribute
& ClassInfo::IsRedeclared
) {
804 for (vector
<const ParameterInfo
*>::iterator it
= parameters
.begin();
805 it
!= parameters
.end(); ++it
) {
806 delete (MethodInfo
*)(void*)*it
;
809 for (vector
<const ParameterInfo
*>::iterator it
= parameters
.begin();
810 it
!= parameters
.end(); ++it
) {
813 for (vector
<const ConstantInfo
*>::iterator it
= staticVariables
.begin();
814 it
!= staticVariables
.end(); ++it
) {
818 for (auto it
= userAttrs
.begin(); it
!= userAttrs
.end(); ++it
) {
823 ///////////////////////////////////////////////////////////////////////////////