summaryrefslogtreecommitdiff
path: root/tests/cpp-compiler/c-compile-shared-library-link-error.c.expected
diff options
context:
space:
mode:
Diffstat (limited to 'tests/cpp-compiler/c-compile-shared-library-link-error.c.expected')
0 files changed, 0 insertions, 0 deletions
67'>67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405
#ifndef SLANG_CORE_RTTI_INFO_H
#define SLANG_CORE_RTTI_INFO_H

#include "slang-basic.h"
#include "slang-memory-arena.h"

#include "slang-list.h"
#include "slang-dictionary.h"

namespace Slang {

struct RttiInfo;
struct RttiTypeFuncsMap;

struct RttiTypeFuncs
{
    typedef void (*CtorArray)(RttiTypeFuncsMap* typeMap, const RttiInfo* rttiInfo, void* dst, Index count);
    typedef void (*DtorArray)(RttiTypeFuncsMap* typeMap, const RttiInfo* rttiInfo, void* dst, Index count);
    typedef void (*CopyArray)(RttiTypeFuncsMap* typeMap, const RttiInfo* rttiInfo, void* dst, const void* src, Index count);

    bool isValid() const { return ctorArray && dtorArray && copyArray;  }

    static RttiTypeFuncs makeEmpty() { return RttiTypeFuncs{ nullptr, nullptr, nullptr }; }

    CtorArray ctorArray;
    DtorArray dtorArray;
    CopyArray copyArray;
};

/* Provides a mechanism to map a type to it's RttiFuncs */
struct RttiTypeFuncsMap
{
        /// For a given type returns the funcs.
        /// If not found returns funcs that return 'isValid' as false. 
    RttiTypeFuncs getFuncsForType(const RttiInfo* rttiInfo);

        /// Add funcs for a type
    void add(const RttiInfo* rttiInfo, const RttiTypeFuncs& funcs);

protected:
    Dictionary<const RttiInfo*, RttiTypeFuncs> m_map;
};

/* Template to get funcs for any arbitrary type */
template <typename T>
struct GetRttiTypeFuncs
{
    static void ctorArray(RttiTypeFuncsMap* typeMap, const RttiInfo* rttiInfo, void* in, Index count)
    {
        SLANG_UNUSED(typeMap);
        SLANG_UNUSED(rttiInfo);
        T* dst = (T*)in;
        for (Index i = 0; i < count; ++i)
        {
            new (dst + i) T;
        }
    }
    static void dtorArray(RttiTypeFuncsMap* typeMap, const RttiInfo* rttiInfo, void* in, Index count)
    {
        SLANG_UNUSED(typeMap);
        SLANG_UNUSED(rttiInfo);
        T* dst = (T*)in;
        for (Index i = 0; i < count; ++i)
        {
            (dst + i)->~T();
        }
    }
    static void copyArray(RttiTypeFuncsMap* typeMap, const RttiInfo* rttiInfo, void* inDst, const void* inSrc, Index count)
    {
        SLANG_UNUSED(rttiInfo);
        SLANG_UNUSED(typeMap);

        T* dst = (T*)inDst;
        const T* src = (T*)inSrc;
        for (Index i = 0; i < count; ++i)
        {
            dst[i] = src[i];
        }
    }
    static RttiTypeFuncs getFuncs()
    {
        RttiTypeFuncs funcs;
        funcs.copyArray = &copyArray;
        funcs.dtorArray = &dtorArray;
        funcs.ctorArray = &ctorArray;
        return funcs;
    }
};

/* An implementation of funcs, for a type that is POD *and* can be zero initialized.
Built in types generally fall into this catagory, but so do raw pointers and other types,
such as structs that only contain "ZeroPod" types */
template <typename T>
struct GetRttiTypeFuncsForZeroPod
{
    static void ctorArray(RttiTypeFuncsMap* typeMap, const RttiInfo* rttiInfo, void* dst, Index count)
    {
        SLANG_UNUSED(typeMap);
        SLANG_UNUSED(rttiInfo);
        ::memset(dst, 0, sizeof(T) * count);
    }
    static void dtorArray(RttiTypeFuncsMap* typeMap, const RttiInfo* rttiInfo, void* dst, Index count)
    {
        SLANG_UNUSED(typeMap);
        SLANG_UNUSED(rttiInfo);
        SLANG_UNUSED(dst);
        SLANG_UNUSED(count);
    }
    static void copyArray(RttiTypeFuncsMap* typeMap, const RttiInfo* rttiInfo, void* dst, const void* src, Index count)
    {
        SLANG_UNUSED(typeMap);
        SLANG_UNUSED(rttiInfo);
        ::memcpy(dst, src, sizeof(T) * count);
    }

    static RttiTypeFuncs getFuncs()
    {
        RttiTypeFuncs funcs;
        funcs.copyArray = &copyArray;
        funcs.dtorArray = &dtorArray;
        funcs.ctorArray = &ctorArray;
        return funcs;
    }
};

struct RttiInfo
{
    typedef uint8_t AlignmentType;
    typedef uint16_t SizeType;

    enum class Kind : uint8_t
    {
        Invalid,
        I32,
        U32,
        I64,
        U64,
        F32,
        F64,
        Bool,
        String,
        UnownedStringSlice,
        Ptr,
        RefPtr,
        FixedArray,
        Struct,
        Other,
        Enum,
        List,
        Dictionary,
     
        CountOf,
    };

    Kind m_kind;
    AlignmentType m_alignment;
    SizeType m_size;

    void init(Kind kind, size_t alignment, size_t size) { m_kind = kind; m_alignment = AlignmentType(alignment); m_size = SizeType(size); }

    template <typename T>
    void init(Kind kind) { init(kind, SLANG_ALIGN_OF(T), sizeof(T)); }
    
        /// Allocate memory for RttiInfo types.
        /// Is thread safe, and doesn't require the memory to be freed explicitly
        /// Will be freed at shutdown (via global dtor)
    static void* allocate(size_t size);
        /// Will free up any allocations. Can only be called at shutdown, and there are guarenteed no uses of
        /// RttiInfo - otherwise contents may be undefined.
        /// NOTE! Memory *will* be freed with final dtors, but if memory check functions are used they can report
        /// this memory.
    static void deallocateAll();

    static bool isIntegral(RttiInfo::Kind kind) { return Index(kind) >= Index(RttiInfo::Kind::I32) && Index(kind) <= Index(RttiInfo::Kind::U64); }
    static bool isFloat(RttiInfo::Kind kind) { return kind == RttiInfo::Kind::F32 || kind == RttiInfo::Kind::F64; }
    static bool isBuiltIn(RttiInfo::Kind kind) { return Index(kind) >= Index(RttiInfo::Kind::I32) && Index(kind) <= Index(RttiInfo::Kind::Bool); }
    static bool isNamed(RttiInfo::Kind kind) { return Index(kind) >= Index(RttiInfo::Kind::Struct) && Index(kind) <= Index(RttiInfo::Kind::Enum); }

    bool isIntegral() const { return isIntegral(m_kind); }
    bool isFloat() const { return isFloat(m_kind); }
    bool isBuiltIn() const { return isBuiltIn(m_kind); }
    bool isNamed() const { return isNamed(m_kind); }

    static void append(const RttiInfo* info, StringBuilder& out);

    static const RttiInfo g_basicTypes[Index(Kind::CountOf)];
};

// Can combine into flags on a field. Could store default value with a field,
// but this works fine for most purposes
enum class RttiDefaultValue : uint8_t
{
    Normal,             ///< Zero for integral/float types/false for bool
    One,
    MinusOne,

    Mask = 0x7,
};

struct NamedRttiInfo : public RttiInfo
{
    const char* m_name;                 ///< Name
};

struct StructRttiInfo : public NamedRttiInfo
{
    typedef uint8_t Flags;
    struct Flag
    {
        enum Enum : Flags
        {
            // We use low bits for 'RttiDefaultValue' value
            Optional = 0x8,
        };
    };

    struct Field
    {
        const char* m_name;             ///< Name of this field
        const RttiInfo* m_type;         ///< The type of this field
        uint32_t m_offset;              ///< Offset from object type in bytes
        Flags m_flags;                  ///< Field flags
    };

    const StructRttiInfo* m_super;      ///< Super class or nullptr if not defined

    Index m_fieldCount;                 ///< Amount of fields
    const Field* m_fields;              ///< Fields
    bool m_ignoreUnknownFieldsInJson = false;
};

struct EnumRttiInfo : public NamedRttiInfo
{
    // TODO(JS):
};

SLANG_FORCE_INLINE StructRttiInfo::Flags combine(StructRttiInfo::Flags flags, RttiDefaultValue defaultValue)
{
    return StructRttiInfo::Flags(defaultValue) | flags;
}

struct ListRttiInfo : public RttiInfo
{
    const RttiInfo* m_elementType;
};

struct DictionaryRttiInfo : public RttiInfo
{
    const RttiInfo* m_keyType;
    const RttiInfo* m_valueType;
};

struct PtrRttiInfo : public RttiInfo
{
    const RttiInfo* m_targetType;
};

struct RefPtrRttiInfo : public RttiInfo
{
    const RttiInfo* m_targetType;
};

struct FixedArrayRttiInfo : public RttiInfo
{
    const RttiInfo* m_elementType;
    size_t m_elementCount;
};

struct OtherRttiInfo : public NamedRttiInfo
{
    typedef bool (*IsDefaultFunc)(const RttiInfo* rttiInfo, const void* in);
    IsDefaultFunc m_isDefaultFunc;
    RttiTypeFuncs m_typeFuncs;
};

// The default is to just get the info from a global held inside the type.
template <typename T>
struct GetRttiInfo
{
    SLANG_FORCE_INLINE static const RttiInfo* get() { return &T::g_rttiInfo; }
};

template <> struct GetRttiInfo<bool> { static const RttiInfo* get() { return &RttiInfo::g_basicTypes[Index(RttiInfo::Kind::Bool)];} };
template <> struct GetRttiInfo<int32_t> { static const RttiInfo* get() { return &RttiInfo::g_basicTypes[Index(RttiInfo::Kind::I32)]; } };
template <> struct GetRttiInfo<int64_t> { static const RttiInfo* get() { return &RttiInfo::g_basicTypes[Index(RttiInfo::Kind::I64)]; } };
template <> struct GetRttiInfo<uint32_t> { static const RttiInfo* get() { return &RttiInfo::g_basicTypes[Index(RttiInfo::Kind::U32)]; } };
template <> struct GetRttiInfo<uint64_t> { static const RttiInfo* get() { return &RttiInfo::g_basicTypes[Index(RttiInfo::Kind::U64)]; } };
template <> struct GetRttiInfo<float> { static const RttiInfo* get() { return &RttiInfo::g_basicTypes[Index(RttiInfo::Kind::F32)]; } };
template <> struct GetRttiInfo<double> { static const RttiInfo* get() { return &RttiInfo::g_basicTypes[Index(RttiInfo::Kind::F64)]; } };
template <> struct GetRttiInfo<String> { static const RttiInfo* get() { return &RttiInfo::g_basicTypes[Index(RttiInfo::Kind::String)]; } };
template <> struct GetRttiInfo<UnownedStringSlice> { static const RttiInfo* get() { return &RttiInfo::g_basicTypes[Index(RttiInfo::Kind::UnownedStringSlice)]; } };

template <typename T>
struct GetRttiInfo<List<T>>
{
    static const ListRttiInfo _make()
    {
        ListRttiInfo info;
        info.init<List<Byte>>(RttiInfo::Kind::List);
        info.m_elementType = GetRttiInfo<T>::get();
        return info;
    }
    static const RttiInfo* get() { static const ListRttiInfo g_info = _make(); return &g_info; }
};

// Strip const
template <typename T>
struct GetRttiInfo<const T>
{
    static const RttiInfo* get() { return GetRttiInfo<T>::get(); }
};

template <typename K, typename V>
struct GetRttiInfo<Dictionary<K, V>>
{
    static const DictionaryRttiInfo _make()
    {
        DictionaryRttiInfo info;
        info.init<Dictionary<Byte, Byte>>(RttiInfo::Kind::Dictionary);
        info.m_keyType = GetRttiInfo<K>::get();
        info.m_valueType = GetRttiInfo<V>::get();
        return info;
    }
    static const RttiInfo* get() { static const DictionaryRttiInfo g_info = _make(); return &g_info; }
};

template <typename TARGET>
struct GetRttiInfo<TARGET*>
{
    static const PtrRttiInfo _make()
    {
        PtrRttiInfo info;
        info.init<void*>(RttiInfo::Kind::Ptr);
        info.m_targetType = GetRttiInfo<TARGET>::get();
        return info;
    }
    static const RttiInfo* get() { static const PtrRttiInfo g_info = _make(); return &g_info; }
};

template <typename TARGET>
struct GetRttiInfo<RefPtr<TARGET>>
{
    static const RefPtrRttiInfo _make()
    {
        RefPtrRttiInfo info;
        info.init<RefPtr<StringRepresentation>>(RttiInfo::Kind::RefPtr);
        info.m_targetType = GetRttiInfo<TARGET>::get();
        return info;
    }
    static const RttiInfo* get() { static const RefPtrRttiInfo g_info = _make(); return &g_info; }
};

template <typename T, size_t COUNT>
struct GetRttiInfo<T[COUNT]>
{
    static const FixedArrayRttiInfo _make()
    {
        FixedArrayRttiInfo info;
        info.m_kind = RttiInfo::Kind::FixedArray;
        info.m_alignment = RttiInfo::AlignmentType(SLANG_ALIGN_OF(T));
        info.m_size = RttiInfo::SizeType(sizeof(T) * COUNT);
        info.m_elementType = GetRttiInfo<T>::get();
        info.m_elementCount = COUNT;
        return info;
    }
    static const RttiInfo* get() { static const FixedArrayRttiInfo g_info = _make(); return &g_info; }
};

struct StructRttiBuilder
{
    template <typename T>
    StructRttiBuilder(T* obj, const char* name, const StructRttiInfo* super) 
    {
        m_rttiInfo.init<T>(RttiInfo::Kind::Struct);
        _init(name, super, (const Byte*)obj);
    }

    template <typename T>
    void addField(const char* name, const T* fieldPtr, StructRttiInfo::Flags flags = 0)
    {
        StructRttiInfo::Field field;

        field.m_name = name;
        field.m_type = GetRttiInfo<T>::get();
        field.m_offset = uint32_t(ptrdiff_t((const Byte*)fieldPtr - m_base));
        field.m_flags = flags;
        m_fields.add(field);
    }

    void ignoreUnknownFields() { m_rttiInfo.m_ignoreUnknownFieldsInJson = true; }

    StructRttiInfo make();

    void _init(const char* name, const StructRttiInfo* super, const Byte* base);

    StructRttiInfo m_rttiInfo;

    List<StructRttiInfo::Field> m_fields;
    const Byte* m_base;
};


} // namespace Slang

#endif // SLANG_CORE_RTTI_INFO_H