void ReflectionParser::buildGlobalFunctions(
    const Cursor &cursor, 
    Namespace &currentNamespace
)
{
    for (auto &child : cursor.GetChildren( ))
    {
        // skip static globals (hidden)
        if (child.GetStorageClass( ) == CX_SC_Static)
            continue;

        auto kind = child.GetKind( );

        // function declaration, which is global
        if (kind == CXCursor_FunctionDecl) 
        {
            auto function = std::make_shared<Function>( child, currentNamespace );

            TRY_ADD_LANGUAGE_TYPE( function, globalFunctions );
        }

        RECURSE_NAMESPACES( 
            kind, 
            child, 
            buildGlobalFunctions, 
            currentNamespace 
        );
    }
}
void ReflectionParser::buildClasses(
    const Cursor &cursor,
    Namespace &currentNamespace
)
{
    for (auto &child : cursor.GetChildren( ))
    {
        auto kind = child.GetKind( );

        // actual definition and a class or struct
        if (child.IsDefinition( ) && 
            (kind == CXCursor_ClassDecl || kind == CXCursor_StructDecl)
        )
        {
            auto klass = std::make_shared<Class>( child, currentNamespace );

            TRY_ADD_LANGUAGE_TYPE( klass, classes );
        }
        else if (kind == CXCursor_TypedefDecl)
        {
            auto displayName = child.GetDisplayName( );

            // external declaration; they're always compiled, but only registered
            if (boost::starts_with( displayName, kMetaExternalTypeDefName ))
            {
                m_externals.emplace_back(
                    std::make_shared<External>( child.GetTypedefType( ).GetDeclaration( ) )
                );
            }
        }
        
        RECURSE_NAMESPACES( kind, child, buildClasses, currentNamespace );
    }
}
void ReflectionParser::buildClasses(const Cursor &cursor, Namespace &currentNamespace)
{
  for (auto &child : cursor.GetChildren())
  {
    // skip classes from other files
    if (!IsInCurrentFile(child))
      continue;

    auto kind = child.GetKind();

    // actual definition and a class or struct
    if (child.IsDefinition() && (kind == CXCursor_ClassDecl || kind == CXCursor_StructDecl))
    {
      m_classes.emplace_back(new Class(child, currentNamespace));
    }

    RECURSE_NAMESPACES(kind, child, buildClasses, currentNamespace);
  }
}
void ReflectionParser::buildEnums(
    const Cursor &cursor, 
    Namespace &currentNamespace
)
{
    for (auto &child : cursor.GetChildren( ))
    {
        auto kind = child.GetKind( );

        // actual definition and an enum
        if (child.IsDefinition( ) && kind == CXCursor_EnumDecl)
        {
            // anonymous enum if the underlying type display name contains this
            if (child.GetType( ).GetDisplayName( ).find( "anonymous enum at" ) 
                != std::string::npos)
            {
                // anonymous enums are just loaded as 
                // globals with each of their values
                for (auto &enumChild : child.GetChildren( ))
                {
                    if (enumChild.GetKind( ) == CXCursor_EnumConstantDecl)
                    {
                        auto global = std::make_shared<Global>( enumChild, currentNamespace, nullptr );

                        TRY_ADD_LANGUAGE_TYPE( global, globals );
                    }
                }
            }
            else
            {
                auto enewm = std::make_shared<Enum>( child, currentNamespace );

                TRY_ADD_LANGUAGE_TYPE( enewm, enums );
            }
        }

        RECURSE_NAMESPACES( kind, child, buildEnums, currentNamespace );
    }
}