<commit_before>//===----------------------------------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// XFAIL: with_system_lib=x86_64-apple-darwin11

// <locale>

// class num_get<charT, InputIterator>

// iter_type get(iter_type in, iter_type end, ios_base&,
//               ios_base::iostate& err, double& v) const;

#include <locale>
#include <ios>
#include <cassert>
#include <streambuf>
#include <cmath>
#include "test_iterators.h"
#include "hexfloat.h"

typedef std::num_get<char, input_iterator<const char*> > F;

class my_facet
    : public F
{
public:
    explicit my_facet(std::size_t refs = 0)
        : F(refs) {}
};

class my_numpunct
    : public std::numpunct<char>
{
public:
    my_numpunct() : std::numpunct<char>() {}

protected:
    virtual char_type do_decimal_point() const {return ';';}
    virtual char_type do_thousands_sep() const {return '_';}
    virtual std::string do_grouping() const {return std::string("\1\2\3");}
};

int main()
{
    const my_facet f(1);
    std::ios ios(0);
    double v = -1;
    {
        const char str[] = "123";
        assert((ios.flags() & ios.basefield) == ios.dec);
        assert(ios.getloc().name() == "C");
        std::ios_base::iostate err = ios.goodbit;
        input_iterator<const char*> iter =
            f.get(input_iterator<const char*>(str),
                  input_iterator<const char*>(str+sizeof(str)),
                  ios, err, v);
        assert(iter.base() == str+sizeof(str)-1);
        assert(err == ios.goodbit);
        assert(v == 123);
    }
    {
        const char str[] = "-123";
        std::ios_base::iostate err = ios.goodbit;
        input_iterator<const char*> iter =
            f.get(input_iterator<const char*>(str),
                  input_iterator<const char*>(str+sizeof(str)),
                  ios, err, v);
        assert(iter.base() == str+sizeof(str)-1);
        assert(err == ios.goodbit);
        assert(v == -123);
    }
    {
        const char str[] = "123.5";
        std::ios_base::iostate err = ios.goodbit;
        input_iterator<const char*> iter =
            f.get(input_iterator<const char*>(str),
                  input_iterator<const char*>(str+sizeof(str)),
                  ios, err, v);
        assert(iter.base() == str+sizeof(str)-1);
        assert(err == ios.goodbit);
        assert(v == 123.5);
    }
    {
        const char str[] = "125e-1";
        hex(ios);
        std::ios_base::iostate err = ios.goodbit;
        input_iterator<const char*> iter =
            f.get(input_iterator<const char*>(str),
                  input_iterator<const char*>(str+sizeof(str)),
                  ios, err, v);
        assert(iter.base() == str+sizeof(str)-1);
        assert(err == ios.goodbit);
        assert(v == 125e-1);
    }
    {
        const char str[] = "0x125p-1";
        hex(ios);
        std::ios_base::iostate err = ios.goodbit;
        input_iterator<const char*> iter =
            f.get(input_iterator<const char*>(str),
                  input_iterator<const char*>(str+sizeof(str)),
                  ios, err, v);
        assert(iter.base() == str+sizeof(str)-1);
        assert(err == ios.goodbit);
        assert(v == hexfloat<double>(0x125, 0, -1));
    }
    {
        const char str[] = "inf";
        hex(ios);
        std::ios_base::iostate err = ios.goodbit;
        input_iterator<const char*> iter =
            f.get(input_iterator<const char*>(str),
                  input_iterator<const char*>(str+sizeof(str)),
                  ios, err, v);
        assert(iter.base() == str+sizeof(str)-1);
        assert(err == ios.goodbit);
        assert(v == INFINITY);
    }
    {
        const char str[] = "INF";
        hex(ios);
        std::ios_base::iostate err = ios.goodbit;
        input_iterator<const char*> iter =
            f.get(input_iterator<const char*>(str),
                  input_iterator<const char*>(str+sizeof(str)),
                  ios, err, v);
        assert(iter.base() == str+sizeof(str)-1);
        assert(err == ios.goodbit);
        assert(v == INFINITY);
    }
    {
        const char str[] = "-inf";
        hex(ios);
        std::ios_base::iostate err = ios.goodbit;
        input_iterator<const char*> iter =
            f.get(input_iterator<const char*>(str),
                  input_iterator<const char*>(str+sizeof(str)),
                  ios, err, v);
        assert(iter.base() == str+sizeof(str)-1);
        assert(err == ios.goodbit);
        assert(v == -INFINITY);
    }
    {
        const char str[] = "-INF";
        hex(ios);
        std::ios_base::iostate err = ios.goodbit;
        input_iterator<const char*> iter =
            f.get(input_iterator<const char*>(str),
                  input_iterator<const char*>(str+sizeof(str)),
                  ios, err, v);
        assert(iter.base() == str+sizeof(str)-1);
        assert(err == ios.goodbit);
        assert(v == -INFINITY);
    }
    {
        const char str[] = "nan";
        hex(ios);
        std::ios_base::iostate err = ios.goodbit;
        input_iterator<const char*> iter =
            f.get(input_iterator<const char*>(str),
                  input_iterator<const char*>(str+sizeof(str)),
                  ios, err, v);
        assert(iter.base() == str+sizeof(str)-1);
        assert(err == ios.goodbit);
        assert(std::isnan(v));
    }
    {
        const char str[] = "NAN";
        hex(ios);
        std::ios_base::iostate err = ios.goodbit;
        input_iterator<const char*> iter =
            f.get(input_iterator<const char*>(str),
                  input_iterator<const char*>(str+sizeof(str)),
                  ios, err, v);
        assert(iter.base() == str+sizeof(str)-1);
        assert(err == ios.goodbit);
        assert(std::isnan(v));
    }
    {
        v = -1;
        const char str[] = "123_456_78_9;125";
        std::ios_base::iostate err = ios.goodbit;
        input_iterator<const char*> iter =
            f.get(input_iterator<const char*>(str),
                  input_iterator<const char*>(str+sizeof(str)),
                  ios, err, v);
        assert(iter.base() == str+3);
        assert(err == ios.goodbit);
        assert(v == 123);
    }
    {
        v = -1;
        const char str[] = "2-";
        std::ios_base::iostate err = ios.goodbit;
        input_iterator<const char*> iter =
            f.get(input_iterator<const char*>(str),
                  input_iterator<const char*>(str+sizeof(str)),
                  ios, err, v);
        assert(iter.base() == str+1);
        assert(err == ios.goodbit);
        assert(v == 2);
    }
    ios.imbue(std::locale(std::locale(), new my_numpunct));
    {
        v = -1;
        const char str[] = "123_456_78_9;125";
        std::ios_base::iostate err = ios.goodbit;
        input_iterator<const char*> iter =
            f.get(input_iterator<const char*>(str),
                  input_iterator<const char*>(str+sizeof(str)),
                  ios, err, v);
        assert(iter.base() == str+sizeof(str)-1);
        assert(err == ios.goodbit);
        assert(v == 123456789.125);
    }
    {
        v = -1;
        const char str[] = "1_2_3_4_5_6_7_8_9_0_1_2_3_4_5_6_7_8_9_0_1_2_3_4_5_6_7_8_9_0_"
                           "1_2_3_4_5_6_7_8_9_0_1_2_3_4_5_6_7_8_9_0_1_2_3_4_5_6_7_8_9_0_"
                           "1_2_3_4_5_6_7_8_9_0_1_2_3_4_5_6_7_8_9_0_1_2_3_4_5_6_7_8_9_0_"
                           "1_2_3_4_5_6_7_8_9_0_1_2_3_4_5_6_7_8_9_0_1_2_3_4_5_6_7_8_9_0_"
                           "1_2_3_4_5_6_7_8_9_0_1_2_3_4_5_6_7_8_9_0_1_2_3_4_5_6_7_8_9_0_"
                           "1_2_3_4_5_6_7_8_9_0_1_2_3_4_5_6_7_8_9_0_1_2_3_4_5_6_7_8_9_0_"
                           "1_2_3_4_5_6_7_8_9_0_1_2_3_4_5_6_7_8_9_0_1_2_3_4_5_6_7_8_9_0_"
                           "1_2_3_4_5_6_7_8_9_0_1_2_3_4_5_6_7_8_9_0_1_2_3_4_5_6_7_8_9_0_"
                           "1_2_3_4_5_6_7_8_9_0_1_2_3_4_5_6_7_8_9_0_1_2_3_4_5_6_7_8_9_0_"
                           "1_2_3_4_5_6_7_8_9_0_1_2_3_4_5_6_7_8_9_0_1_2_3_4_5_6_7_8_9_0_"
                           "1_2_3_4_5_6_7_8_9_0_1_2_3_4_5_6_7_8_9_0_1_2_3_4_5_6_7_8_9_0_";
        std::ios_base::iostate err = ios.goodbit;
        input_iterator<const char*> iter =
            f.get(input_iterator<const char*>(str),
                  input_iterator<const char*>(str+sizeof(str)),
                  ios, err, v);
        assert(iter.base() == str+sizeof(str)-1);
        assert(err == ios.failbit);
    }
    {
        v = -1;
        const char str[] = "3;14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651e+10";
        std::ios_base::iostate err = ios.goodbit;
        input_iterator<const char*> iter =
            f.get(input_iterator<const char*>(str),
                  input_iterator<const char*>(str+sizeof(str)),
                  ios, err, v);
        assert(iter.base() == str+sizeof(str)-1);
        assert(err == ios.goodbit);
        assert(std::abs(v - 3.14159265358979e+10)/3.14159265358979e+10 < 1.e-8);
    }
}
<commit_msg>XFAIL this test when using the darwin12 system library. Reviewed by Howard<commit_after>//===----------------------------------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// XFAIL: with_system_lib=x86_64-apple-darwin11
// XFAIL: with_system_lib=x86_64-apple-darwin12

// <locale>

// class num_get<charT, InputIterator>

// iter_type get(iter_type in, iter_type end, ios_base&,
//               ios_base::iostate& err, double& v) const;

#include <locale>
#include <ios>
#include <cassert>
#include <streambuf>
#include <cmath>
#include "test_iterators.h"
#include "hexfloat.h"

typedef std::num_get<char, input_iterator<const char*> > F;

class my_facet
    : public F
{
public:
    explicit my_facet(std::size_t refs = 0)
        : F(refs) {}
};

class my_numpunct
    : public std::numpunct<char>
{
public:
    my_numpunct() : std::numpunct<char>() {}

protected:
    virtual char_type do_decimal_point() const {return ';';}
    virtual char_type do_thousands_sep() const {return '_';}
    virtual std::string do_grouping() const {return std::string("\1\2\3");}
};

int main()
{
    const my_facet f(1);
    std::ios ios(0);
    double v = -1;
    {
        const char str[] = "123";
        assert((ios.flags() & ios.basefield) == ios.dec);
        assert(ios.getloc().name() == "C");
        std::ios_base::iostate err = ios.goodbit;
        input_iterator<const char*> iter =
            f.get(input_iterator<const char*>(str),
                  input_iterator<const char*>(str+sizeof(str)),
                  ios, err, v);
        assert(iter.base() == str+sizeof(str)-1);
        assert(err == ios.goodbit);
        assert(v == 123);
    }
    {
        const char str[] = "-123";
        std::ios_base::iostate err = ios.goodbit;
        input_iterator<const char*> iter =
            f.get(input_iterator<const char*>(str),
                  input_iterator<const char*>(str+sizeof(str)),
                  ios, err, v);
        assert(iter.base() == str+sizeof(str)-1);
        assert(err == ios.goodbit);
        assert(v == -123);
    }
    {
        const char str[] = "123.5";
        std::ios_base::iostate err = ios.goodbit;
        input_iterator<const char*> iter =
            f.get(input_iterator<const char*>(str),
                  input_iterator<const char*>(str+sizeof(str)),
                  ios, err, v);
        assert(iter.base() == str+sizeof(str)-1);
        assert(err == ios.goodbit);
        assert(v == 123.5);
    }
    {
        const char str[] = "125e-1";
        hex(ios);
        std::ios_base::iostate err = ios.goodbit;
        input_iterator<const char*> iter =
            f.get(input_iterator<const char*>(str),
                  input_iterator<const char*>(str+sizeof(str)),
                  ios, err, v);
        assert(iter.base() == str+sizeof(str)-1);
        assert(err == ios.goodbit);
        assert(v == 125e-1);
    }
    {
        const char str[] = "0x125p-1";
        hex(ios);
        std::ios_base::iostate err = ios.goodbit;
        input_iterator<const char*> iter =
            f.get(input_iterator<const char*>(str),
                  input_iterator<const char*>(str+sizeof(str)),
                  ios, err, v);
        assert(iter.base() == str+sizeof(str)-1);
        assert(err == ios.goodbit);
        assert(v == hexfloat<double>(0x125, 0, -1));
    }
    {
        const char str[] = "inf";
        hex(ios);
        std::ios_base::iostate err = ios.goodbit;
        input_iterator<const char*> iter =
            f.get(input_iterator<const char*>(str),
                  input_iterator<const char*>(str+sizeof(str)),
                  ios, err, v);
        assert(iter.base() == str+sizeof(str)-1);
        assert(err == ios.goodbit);
        assert(v == INFINITY);
    }
    {
        const char str[] = "INF";
        hex(ios);
        std::ios_base::iostate err = ios.goodbit;
        input_iterator<const char*> iter =
            f.get(input_iterator<const char*>(str),
                  input_iterator<const char*>(str+sizeof(str)),
                  ios, err, v);
        assert(iter.base() == str+sizeof(str)-1);
        assert(err == ios.goodbit);
        assert(v == INFINITY);
    }
    {
        const char str[] = "-inf";
        hex(ios);
        std::ios_base::iostate err = ios.goodbit;
        input_iterator<const char*> iter =
            f.get(input_iterator<const char*>(str),
                  input_iterator<const char*>(str+sizeof(str)),
                  ios, err, v);
        assert(iter.base() == str+sizeof(str)-1);
        assert(err == ios.goodbit);
        assert(v == -INFINITY);
    }
    {
        const char str[] = "-INF";
        hex(ios);
        std::ios_base::iostate err = ios.goodbit;
        input_iterator<const char*> iter =
            f.get(input_iterator<const char*>(str),
                  input_iterator<const char*>(str+sizeof(str)),
                  ios, err, v);
        assert(iter.base() == str+sizeof(str)-1);
        assert(err == ios.goodbit);
        assert(v == -INFINITY);
    }
    {
        const char str[] = "nan";
        hex(ios);
        std::ios_base::iostate err = ios.goodbit;
        input_iterator<const char*> iter =
            f.get(input_iterator<const char*>(str),
                  input_iterator<const char*>(str+sizeof(str)),
                  ios, err, v);
        assert(iter.base() == str+sizeof(str)-1);
        assert(err == ios.goodbit);
        assert(std::isnan(v));
    }
    {
        const char str[] = "NAN";
        hex(ios);
        std::ios_base::iostate err = ios.goodbit;
        input_iterator<const char*> iter =
            f.get(input_iterator<const char*>(str),
                  input_iterator<const char*>(str+sizeof(str)),
                  ios, err, v);
        assert(iter.base() == str+sizeof(str)-1);
        assert(err == ios.goodbit);
        assert(std::isnan(v));
    }
    {
        v = -1;
        const char str[] = "123_456_78_9;125";
        std::ios_base::iostate err = ios.goodbit;
        input_iterator<const char*> iter =
            f.get(input_iterator<const char*>(str),
                  input_iterator<const char*>(str+sizeof(str)),
                  ios, err, v);
        assert(iter.base() == str+3);
        assert(err == ios.goodbit);
        assert(v == 123);
    }
    {
        v = -1;
        const char str[] = "2-";
        std::ios_base::iostate err = ios.goodbit;
        input_iterator<const char*> iter =
            f.get(input_iterator<const char*>(str),
                  input_iterator<const char*>(str+sizeof(str)),
                  ios, err, v);
        assert(iter.base() == str+1);
        assert(err == ios.goodbit);
        assert(v == 2);
    }
    ios.imbue(std::locale(std::locale(), new my_numpunct));
    {
        v = -1;
        const char str[] = "123_456_78_9;125";
        std::ios_base::iostate err = ios.goodbit;
        input_iterator<const char*> iter =
            f.get(input_iterator<const char*>(str),
                  input_iterator<const char*>(str+sizeof(str)),
                  ios, err, v);
        assert(iter.base() == str+sizeof(str)-1);
        assert(err == ios.goodbit);
        assert(v == 123456789.125);
    }
    {
        v = -1;
        const char str[] = "1_2_3_4_5_6_7_8_9_0_1_2_3_4_5_6_7_8_9_0_1_2_3_4_5_6_7_8_9_0_"
                           "1_2_3_4_5_6_7_8_9_0_1_2_3_4_5_6_7_8_9_0_1_2_3_4_5_6_7_8_9_0_"
                           "1_2_3_4_5_6_7_8_9_0_1_2_3_4_5_6_7_8_9_0_1_2_3_4_5_6_7_8_9_0_"
                           "1_2_3_4_5_6_7_8_9_0_1_2_3_4_5_6_7_8_9_0_1_2_3_4_5_6_7_8_9_0_"
                           "1_2_3_4_5_6_7_8_9_0_1_2_3_4_5_6_7_8_9_0_1_2_3_4_5_6_7_8_9_0_"
                           "1_2_3_4_5_6_7_8_9_0_1_2_3_4_5_6_7_8_9_0_1_2_3_4_5_6_7_8_9_0_"
                           "1_2_3_4_5_6_7_8_9_0_1_2_3_4_5_6_7_8_9_0_1_2_3_4_5_6_7_8_9_0_"
                           "1_2_3_4_5_6_7_8_9_0_1_2_3_4_5_6_7_8_9_0_1_2_3_4_5_6_7_8_9_0_"
                           "1_2_3_4_5_6_7_8_9_0_1_2_3_4_5_6_7_8_9_0_1_2_3_4_5_6_7_8_9_0_"
                           "1_2_3_4_5_6_7_8_9_0_1_2_3_4_5_6_7_8_9_0_1_2_3_4_5_6_7_8_9_0_"
                           "1_2_3_4_5_6_7_8_9_0_1_2_3_4_5_6_7_8_9_0_1_2_3_4_5_6_7_8_9_0_";
        std::ios_base::iostate err = ios.goodbit;
        input_iterator<const char*> iter =
            f.get(input_iterator<const char*>(str),
                  input_iterator<const char*>(str+sizeof(str)),
                  ios, err, v);
        assert(iter.base() == str+sizeof(str)-1);
        assert(err == ios.failbit);
    }
    {
        v = -1;
        const char str[] = "3;14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651e+10";
        std::ios_base::iostate err = ios.goodbit;
        input_iterator<const char*> iter =
            f.get(input_iterator<const char*>(str),
                  input_iterator<const char*>(str+sizeof(str)),
                  ios, err, v);
        assert(iter.base() == str+sizeof(str)-1);
        assert(err == ios.goodbit);
        assert(std::abs(v - 3.14159265358979e+10)/3.14159265358979e+10 < 1.e-8);
    }
}
<|endoftext|>


<commit_before>#ifndef UTILITY_HPP
# define UTILITY_HPP

#include <cstddef>

#include <type_traits>

namespace generic
{

template <::std::size_t...> struct indices { };

namespace detail
{

// indices
template<class A, class B> struct catenate_indices;

template <::std::size_t ...Is, ::std::size_t ...Js>
struct catenate_indices<indices<Is...>, indices<Js...> >
{
  using indices_type = indices<Is..., Js...>;
};

template <::std::size_t, ::std::size_t, typename = void> struct expand_indices;

template <::std::size_t A, ::std::size_t B>
struct expand_indices<A, B, typename ::std::enable_if::type>
{
  using indices_type = indices;
};

template <::std::size_t A, ::std::size_t B>
struct expand_indices<A, B, typename ::std::enable_if::type>
{
  static_assert(A  B");
  using indices_type = typename catenate_indices<
    typename expand_indices::indices_type,
    typename expand_indices<(A + B) / 2 + 1, B>::indices_type
  >::indices_type;
};

}

template <::std::size_t A>
struct make_indices : detail::expand_indices<0, A>::indices_type
{
};

template <::std::size_t A, ::std::size_t B>
struct make_indices_range : detail::expand_indices::indices_type
{
};

// sequences
template <::std::size_t I, typename A, typename ...B>
struct type_at : type_at
{
};

template <typename A, typename ...B>
struct type_at<0, A, B...>
{
  using type = A;
};

template <typename A, typename ...B>
struct front
{
  using type = A;
};

template <typename A, typename ...B>
struct back : back
{
};

template <typename A>
struct back
{
  using type = A;
};

template <bool B>
using bool_ = ::std::integral_constant<bool, B>;

template <class A, class ...B>
struct all_of : bool_<A::value && all_of::value> { };

template <class A>
struct all_of : bool_ { };

}

#endif // UTILITY_HPP
<commit_msg>some fixes<commit_after>#ifndef UTILITY_HPP
# define UTILITY_HPP

#include <cstddef>

#include <type_traits>

namespace generic
{

template <::std::size_t...> struct indices { };

namespace detail
{

// indices
template<class A, class B> struct catenate_indices;

template <::std::size_t ...Is, ::std::size_t ...Js>
struct catenate_indices<indices<Is...>, indices<Js...> >
{
  using indices_type = indices<Is..., Js...>;
};

template <::std::size_t, ::std::size_t, typename = void> struct expand_indices;

template <::std::size_t A, ::std::size_t B>
struct expand_indices<A, B, typename ::std::enable_if::type>
{
  using indices_type = indices;
};

template <::std::size_t A, ::std::size_t B>
struct expand_indices<A, B, typename ::std::enable_if::type>
{
  static_assert(A  B");
  using indices_type = typename catenate_indices<
    typename expand_indices::indices_type,
    typename expand_indices<(A + B) / 2 + 1, B>::indices_type
  >::indices_type;
};

}

template<typename T> constexpr inline T const& as_const(T& t) { return t; }

template <::std::size_t A>
struct make_indices : detail::expand_indices<0, A>::indices_type
{
};

template <::std::size_t A, ::std::size_t B>
struct make_indices_range : detail::expand_indices::indices_type
{
};

// sequences
template <::std::size_t I, typename A, typename ...B>
struct type_at : type_at
{
};

template <typename A, typename ...B>
struct type_at<0, A, B...>
{
  using type = A;
};

template <typename A, typename ...B>
struct front
{
  using type = A;
};

template <typename A, typename ...B>
struct back : back
{
};

template <typename A>
struct back
{
  using type = A;
};

template <bool B>
using bool_ = ::std::integral_constant<bool, B>;

template <class A, class ...B>
struct all_of : bool_<A::value && all_of::value> { };

template <class A>
struct all_of : bool_ { };

}

#endif // UTILITY_HPP
<|endoftext|>


<commit_before>/* Copyright 2018 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

#include "tensorflow/lite/micro/simple_memory_allocator.h"

#include <cstddef>
#include <cstdint>

#include "tensorflow/lite/core/api/error_reporter.h"
#include "tensorflow/lite/micro/memory_helpers.h"

namespace tflite {

SimpleMemoryAllocator::SimpleMemoryAllocator(ErrorReporter* error_reporter,
                                             uint8_t* buffer_head,
                                             uint8_t* buffer_tail)
    : error_reporter_(error_reporter),
      buffer_head_(buffer_head),
      buffer_tail_(buffer_tail),
      head_(buffer_head),
      tail_(buffer_tail) {}

SimpleMemoryAllocator::SimpleMemoryAllocator(ErrorReporter* error_reporter,
                                             uint8_t* buffer,
                                             size_t buffer_size)
    : SimpleMemoryAllocator(error_reporter, buffer, buffer + buffer_size) {}

/* static */
SimpleMemoryAllocator* SimpleMemoryAllocator::Create(
    ErrorReporter* error_reporter, uint8_t* buffer_head, size_t buffer_size) {
  SimpleMemoryAllocator tmp =
      SimpleMemoryAllocator(error_reporter, buffer_head, buffer_size);

  // Allocate enough bytes from the buffer to create a SimpleMemoryAllocator.
  // The new instance will use the current adjusted tail buffer from the tmp
  // allocator instance.
  uint8_t* allocator_buffer = tmp.AllocateFromTail(
      sizeof(SimpleMemoryAllocator), alignof(SimpleMemoryAllocator));
  return new (allocator_buffer)
      SimpleMemoryAllocator(error_reporter, tmp.head_, tmp.tail_);
}

SimpleMemoryAllocator::~SimpleMemoryAllocator() {}

uint8_t* SimpleMemoryAllocator::AllocateFromHead(size_t size,
                                                 size_t alignment) {
  uint8_t* const aligned_result = AlignPointerUp(head_, alignment);
  const size_t available_memory = tail_ - aligned_result;
  if (available_memory < size) {
    TF_LITE_REPORT_ERROR(
        error_reporter_,
        "Failed to allocate memory. Requested: %u, available %u, missing: %u",
        size, available_memory, size - available_memory);
    return nullptr;
  }
  head_ = aligned_result + size;
  return aligned_result;
}

uint8_t* SimpleMemoryAllocator::AllocateFromTail(size_t size,
                                                 size_t alignment) {
  uint8_t* const aligned_result = AlignPointerDown(tail_ - size, alignment);
  if (aligned_result < head_) {
    const size_t missing_memory = head_ - aligned_result;
    TF_LITE_REPORT_ERROR(
        error_reporter_,
        "Failed to allocate memory. Requested: %u, available %u, missing: %u",
        size, size - missing_memory, missing_memory);
    return nullptr;
  }
  tail_ = aligned_result;
  return aligned_result;
}

uint8_t* SimpleMemoryAllocator::GetHead() const { return head_; }

uint8_t* SimpleMemoryAllocator::GetTail() const { return tail_; }

size_t SimpleMemoryAllocator::GetHeadUsedBytes() const {
  return head_ - buffer_head_;
}

size_t SimpleMemoryAllocator::GetTailUsedBytes() const {
  return buffer_tail_ - tail_;
}

size_t SimpleMemoryAllocator::GetAvailableMemory() const {
  return tail_ - head_;
}

size_t SimpleMemoryAllocator::GetUsedBytes() const {
  return GetBufferSize() - GetAvailableMemory();
}

size_t SimpleMemoryAllocator::GetBufferSize() const {
  return buffer_tail_ - buffer_head_;
}

}  // namespace tflite
<commit_msg>TFLM: use default copy constructor instead of explicit constructor in simple_memory_allocator<commit_after>/* Copyright 2018 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

#include "tensorflow/lite/micro/simple_memory_allocator.h"

#include <cstddef>
#include <cstdint>

#include "tensorflow/lite/core/api/error_reporter.h"
#include "tensorflow/lite/micro/memory_helpers.h"

namespace tflite {

SimpleMemoryAllocator::SimpleMemoryAllocator(ErrorReporter* error_reporter,
                                             uint8_t* buffer_head,
                                             uint8_t* buffer_tail)
    : error_reporter_(error_reporter),
      buffer_head_(buffer_head),
      buffer_tail_(buffer_tail),
      head_(buffer_head),
      tail_(buffer_tail) {}

SimpleMemoryAllocator::SimpleMemoryAllocator(ErrorReporter* error_reporter,
                                             uint8_t* buffer,
                                             size_t buffer_size)
    : SimpleMemoryAllocator(error_reporter, buffer, buffer + buffer_size) {}

/* static */
SimpleMemoryAllocator* SimpleMemoryAllocator::Create(
    ErrorReporter* error_reporter, uint8_t* buffer_head, size_t buffer_size) {
  SimpleMemoryAllocator tmp =
      SimpleMemoryAllocator(error_reporter, buffer_head, buffer_size);

  // Allocate enough bytes from the buffer to create a SimpleMemoryAllocator.
  // The new instance will use the current adjusted tail buffer from the tmp
  // allocator instance.
  uint8_t* allocator_buffer = tmp.AllocateFromTail(
      sizeof(SimpleMemoryAllocator), alignof(SimpleMemoryAllocator));
  // Use the default copy constructor to populate internal states.
  return new (allocator_buffer) SimpleMemoryAllocator(tmp);
}

SimpleMemoryAllocator::~SimpleMemoryAllocator() {}

uint8_t* SimpleMemoryAllocator::AllocateFromHead(size_t size,
                                                 size_t alignment) {
  uint8_t* const aligned_result = AlignPointerUp(head_, alignment);
  const size_t available_memory = tail_ - aligned_result;
  if (available_memory < size) {
    TF_LITE_REPORT_ERROR(
        error_reporter_,
        "Failed to allocate memory. Requested: %u, available %u, missing: %u",
        size, available_memory, size - available_memory);
    return nullptr;
  }
  head_ = aligned_result + size;
  return aligned_result;
}

uint8_t* SimpleMemoryAllocator::AllocateFromTail(size_t size,
                                                 size_t alignment) {
  uint8_t* const aligned_result = AlignPointerDown(tail_ - size, alignment);
  if (aligned_result < head_) {
    const size_t missing_memory = head_ - aligned_result;
    TF_LITE_REPORT_ERROR(
        error_reporter_,
        "Failed to allocate memory. Requested: %u, available %u, missing: %u",
        size, size - missing_memory, missing_memory);
    return nullptr;
  }
  tail_ = aligned_result;
  return aligned_result;
}

uint8_t* SimpleMemoryAllocator::GetHead() const { return head_; }

uint8_t* SimpleMemoryAllocator::GetTail() const { return tail_; }

size_t SimpleMemoryAllocator::GetHeadUsedBytes() const {
  return head_ - buffer_head_;
}

size_t SimpleMemoryAllocator::GetTailUsedBytes() const {
  return buffer_tail_ - tail_;
}

size_t SimpleMemoryAllocator::GetAvailableMemory() const {
  return tail_ - head_;
}

size_t SimpleMemoryAllocator::GetUsedBytes() const {
  return GetBufferSize() - GetAvailableMemory();
}

size_t SimpleMemoryAllocator::GetBufferSize() const {
  return buffer_tail_ - buffer_head_;
}

}  // namespace tflite
<|endoftext|>


<commit_before>//===- IndexingContext.cpp - Indexing context data ------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "IndexingContext.h"
#include "clang/Index/IndexDataConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/DeclObjC.h"
#include "clang/Basic/SourceManager.h"

using namespace clang;
using namespace index;

bool IndexingContext::shouldIndexFunctionLocalSymbols() const {
  return IndexOpts.IndexFunctionLocals;
}

bool IndexingContext::handleDecl(const Decl *D,
                                 SymbolRoleSet Roles,
                                 ArrayRef<SymbolRelation> Relations) {
  return handleDeclOccurrence(D, D->getLocation(), /*IsRef=*/false,
                              cast<Decl>(D->getDeclContext()), Roles, Relations,
                              nullptr, nullptr, D->getDeclContext());
}

bool IndexingContext::handleDecl(const Decl *D, SourceLocation Loc,
                                 SymbolRoleSet Roles,
                                 ArrayRef<SymbolRelation> Relations,
                                 const DeclContext *DC) {
  if (!DC)
    DC = D->getDeclContext();
  return handleDeclOccurrence(D, Loc, /*IsRef=*/false, cast<Decl>(DC),
                              Roles, Relations,
                              nullptr, nullptr, DC);
}

bool IndexingContext::handleReference(const NamedDecl *D, SourceLocation Loc,
                                      const NamedDecl *Parent,
                                      const DeclContext *DC,
                                      SymbolRoleSet Roles,
                                      ArrayRef<SymbolRelation> Relations,
                                      const Expr *RefE,
                                      const Decl *RefD) {
  if (!shouldIndexFunctionLocalSymbols() && isFunctionLocalDecl(D))
    return true;

  if (isa<NonTypeTemplateParmDecl>(D) || isa<TemplateTypeParmDecl>(D))
    return true;

  return handleDeclOccurrence(D, Loc, /*IsRef=*/true, Parent, Roles, Relations,
                              RefE, RefD, DC);
}

bool IndexingContext::importedModule(const ImportDecl *ImportD) {
  SourceLocation Loc;
  auto IdLocs = ImportD->getIdentifierLocs();
  if (!IdLocs.empty())
    Loc = IdLocs.front();
  else
    Loc = ImportD->getLocation();
  SourceManager &SM = Ctx->getSourceManager();
  Loc = SM.getFileLoc(Loc);
  if (Loc.isInvalid())
    return true;

  FileID FID;
  unsigned Offset;
  std::tie(FID, Offset) = SM.getDecomposedLoc(Loc);
  if (FID.isInvalid())
    return true;

  bool Invalid = false;
  const SrcMgr::SLocEntry &SEntry = SM.getSLocEntry(FID, &Invalid);
  if (Invalid || !SEntry.isFile())
    return true;

  if (SEntry.getFile().getFileCharacteristic() != SrcMgr::C_User) {
    switch (IndexOpts.SystemSymbolFilter) {
    case IndexingOptions::SystemSymbolFilterKind::None:
    case IndexingOptions::SystemSymbolFilterKind::DeclarationsOnly:
      return true;
    case IndexingOptions::SystemSymbolFilterKind::All:
      break;
    }
  }

  SymbolRoleSet Roles = (unsigned)SymbolRole::Reference;
  if (ImportD->isImplicit())
    Roles |= (unsigned)SymbolRole::Implicit;

  return DataConsumer.handleModuleOccurence(ImportD, Roles, FID, Offset);
}

bool IndexingContext::isFunctionLocalDecl(const Decl *D) {
  assert(D);

  if (isa<TemplateTemplateParmDecl>(D))
    return true;

  if (isa<ObjCTypeParamDecl>(D))
    return true;

  if (!D->getParentFunctionOrMethod())
    return false;

  if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
    switch (ND->getFormalLinkage()) {
    case NoLinkage:
    case VisibleNoLinkage:
    case InternalLinkage:
      return true;
    case UniqueExternalLinkage:
      llvm_unreachable("Not a sema linkage");
    case ExternalLinkage:
      return false;
    }
  }

  return true;
}

bool IndexingContext::isTemplateImplicitInstantiation(const Decl *D) {
  TemplateSpecializationKind TKind = TSK_Undeclared;
  if (const ClassTemplateSpecializationDecl *
      SD = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
    TKind = SD->getSpecializationKind();
  }
  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
    TKind = FD->getTemplateSpecializationKind();
  }
  switch (TKind) {
    case TSK_Undeclared:
    case TSK_ExplicitSpecialization:
      return false;
    case TSK_ImplicitInstantiation:
    case TSK_ExplicitInstantiationDeclaration:
    case TSK_ExplicitInstantiationDefinition:
      return true;
  }
  llvm_unreachable("invalid TemplateSpecializationKind");
}

bool IndexingContext::shouldIgnoreIfImplicit(const Decl *D) {
  if (isa<ObjCInterfaceDecl>(D))
    return false;
  if (isa<ObjCCategoryDecl>(D))
    return false;
  if (isa<ObjCIvarDecl>(D))
    return false;
  if (isa<ObjCMethodDecl>(D))
    return false;
  if (isa<ImportDecl>(D))
    return false;
  return true;
}

static const Decl *adjustTemplateImplicitInstantiation(const Decl *D) {
  if (const ClassTemplateSpecializationDecl *
      SD = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
    return SD->getTemplateInstantiationPattern();
  }
  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
    return FD->getTemplateInstantiationPattern();
  }
  return nullptr;
}

static bool isDeclADefinition(const Decl *D, ASTContext &Ctx) {
  if (auto VD = dyn_cast<VarDecl>(D))
    return VD->isThisDeclarationADefinition(Ctx);

  if (auto FD = dyn_cast<FunctionDecl>(D))
    return FD->isThisDeclarationADefinition();

  if (auto TD = dyn_cast<TagDecl>(D))
    return TD->isThisDeclarationADefinition();

  if (auto MD = dyn_cast<ObjCMethodDecl>(D))
    return MD->isThisDeclarationADefinition();

  if (isa<TypedefNameDecl>(D) ||
      isa<EnumConstantDecl>(D) ||
      isa<FieldDecl>(D) ||
      isa<MSPropertyDecl>(D) ||
      isa<ObjCImplDecl>(D) ||
      isa<ObjCPropertyImplDecl>(D))
    return true;

  return false;
}

static const Decl *adjustParent(const Decl *Parent) {
  if (!Parent)
    return nullptr;
  for (;; Parent = cast<Decl>(Parent->getDeclContext())) {
    if (isa<TranslationUnitDecl>(Parent))
      return nullptr;
    if (isa<LinkageSpecDecl>(Parent) || isa<BlockDecl>(Parent))
      continue;
    if (auto NS = dyn_cast<NamespaceDecl>(Parent)) {
      if (NS->isAnonymousNamespace())
        continue;
    } else if (auto RD = dyn_cast<RecordDecl>(Parent)) {
      if (RD->isAnonymousStructOrUnion())
        continue;
    } else if (auto FD = dyn_cast<FieldDecl>(Parent)) {
      if (FD->getDeclName().isEmpty())
        continue;
    }
    return Parent;
  }
}

static const Decl *getCanonicalDecl(const Decl *D) {
  D = D->getCanonicalDecl();
  if (auto TD = dyn_cast<TemplateDecl>(D)) {
    D = TD->getTemplatedDecl();
    assert(D->isCanonicalDecl());
  }

  return D;
}

bool IndexingContext::handleDeclOccurrence(const Decl *D, SourceLocation Loc,
                                           bool IsRef, const Decl *Parent,
                                           SymbolRoleSet Roles,
                                           ArrayRef<SymbolRelation> Relations,
                                           const Expr *OrigE,
                                           const Decl *OrigD,
                                           const DeclContext *ContainerDC) {
  if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
    return true;
  if (!isa<NamedDecl>(D) ||
      (cast<NamedDecl>(D)->getDeclName().isEmpty() &&
       !isa<TagDecl>(D) && !isa<ObjCCategoryDecl>(D)))
    return true;

  SourceManager &SM = Ctx->getSourceManager();
  Loc = SM.getFileLoc(Loc);
  if (Loc.isInvalid())
    return true;

  FileID FID;
  unsigned Offset;
  std::tie(FID, Offset) = SM.getDecomposedLoc(Loc);
  if (FID.isInvalid())
    return true;

  bool Invalid = false;
  const SrcMgr::SLocEntry &SEntry = SM.getSLocEntry(FID, &Invalid);
  if (Invalid || !SEntry.isFile())
    return true;

  if (SEntry.getFile().getFileCharacteristic() != SrcMgr::C_User) {
    switch (IndexOpts.SystemSymbolFilter) {
    case IndexingOptions::SystemSymbolFilterKind::None:
      return true;
    case IndexingOptions::SystemSymbolFilterKind::DeclarationsOnly:
      if (IsRef)
        return true;
      break;
    case IndexingOptions::SystemSymbolFilterKind::All:
      break;
    }
  }

  if (isTemplateImplicitInstantiation(D)) {
    if (!IsRef)
      return true;
    D = adjustTemplateImplicitInstantiation(D);
    if (!D)
      return true;
    assert(!isTemplateImplicitInstantiation(D));
  }

  if (!OrigD)
    OrigD = D;

  if (IsRef)
    Roles |= (unsigned)SymbolRole::Reference;
  else if (isDeclADefinition(D, *Ctx))
    Roles |= (unsigned)SymbolRole::Definition;
  else
    Roles |= (unsigned)SymbolRole::Declaration;

  D = getCanonicalDecl(D);
  if (D->isImplicit() && !isa<ObjCMethodDecl>(D)) {
    // operator new declarations will link to the implicit one as canonical.
    return true;
  }
  Parent = adjustParent(Parent);
  if (Parent)
    Parent = getCanonicalDecl(Parent);
  assert(!Parent || !Parent->isImplicit() ||
         isa<FunctionDecl>(Parent) ||
         isa<ObjCInterfaceDecl>(Parent) || isa<ObjCMethodDecl>(Parent));

  SmallVector<SymbolRelation, 6> FinalRelations;
  FinalRelations.reserve(Relations.size()+1);

  auto addRelation = [&](SymbolRelation Rel) {
    auto It = std::find_if(FinalRelations.begin(), FinalRelations.end(),
                [&](SymbolRelation Elem)->bool {
                  return Elem.RelatedSymbol == Rel.RelatedSymbol;
                });
    if (It != FinalRelations.end()) {
      It->Roles |= Rel.Roles;
    } else {
      FinalRelations.push_back(Rel);
    }
    Roles |= Rel.Roles;
  };

  if (!IsRef && Parent && !cast<DeclContext>(Parent)->isFunctionOrMethod()) {
    addRelation(SymbolRelation{(unsigned)SymbolRole::RelationChildOf, Parent});
  }
  for (auto &Rel : Relations) {
    addRelation(SymbolRelation(Rel.Roles,
                               Rel.RelatedSymbol->getCanonicalDecl()));
  }

  IndexDataConsumer::ASTNodeInfo Node{ OrigE, OrigD, Parent, ContainerDC };
  return DataConsumer.handleDeclOccurence(D, Roles, FinalRelations, FID, Offset,
                                          Node);
}
<commit_msg>[index] Add a message for the assertion, NFC.<commit_after>//===- IndexingContext.cpp - Indexing context data ------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "IndexingContext.h"
#include "clang/Index/IndexDataConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/DeclObjC.h"
#include "clang/Basic/SourceManager.h"

using namespace clang;
using namespace index;

bool IndexingContext::shouldIndexFunctionLocalSymbols() const {
  return IndexOpts.IndexFunctionLocals;
}

bool IndexingContext::handleDecl(const Decl *D,
                                 SymbolRoleSet Roles,
                                 ArrayRef<SymbolRelation> Relations) {
  return handleDeclOccurrence(D, D->getLocation(), /*IsRef=*/false,
                              cast<Decl>(D->getDeclContext()), Roles, Relations,
                              nullptr, nullptr, D->getDeclContext());
}

bool IndexingContext::handleDecl(const Decl *D, SourceLocation Loc,
                                 SymbolRoleSet Roles,
                                 ArrayRef<SymbolRelation> Relations,
                                 const DeclContext *DC) {
  if (!DC)
    DC = D->getDeclContext();
  return handleDeclOccurrence(D, Loc, /*IsRef=*/false, cast<Decl>(DC),
                              Roles, Relations,
                              nullptr, nullptr, DC);
}

bool IndexingContext::handleReference(const NamedDecl *D, SourceLocation Loc,
                                      const NamedDecl *Parent,
                                      const DeclContext *DC,
                                      SymbolRoleSet Roles,
                                      ArrayRef<SymbolRelation> Relations,
                                      const Expr *RefE,
                                      const Decl *RefD) {
  if (!shouldIndexFunctionLocalSymbols() && isFunctionLocalDecl(D))
    return true;

  if (isa<NonTypeTemplateParmDecl>(D) || isa<TemplateTypeParmDecl>(D))
    return true;

  return handleDeclOccurrence(D, Loc, /*IsRef=*/true, Parent, Roles, Relations,
                              RefE, RefD, DC);
}

bool IndexingContext::importedModule(const ImportDecl *ImportD) {
  SourceLocation Loc;
  auto IdLocs = ImportD->getIdentifierLocs();
  if (!IdLocs.empty())
    Loc = IdLocs.front();
  else
    Loc = ImportD->getLocation();
  SourceManager &SM = Ctx->getSourceManager();
  Loc = SM.getFileLoc(Loc);
  if (Loc.isInvalid())
    return true;

  FileID FID;
  unsigned Offset;
  std::tie(FID, Offset) = SM.getDecomposedLoc(Loc);
  if (FID.isInvalid())
    return true;

  bool Invalid = false;
  const SrcMgr::SLocEntry &SEntry = SM.getSLocEntry(FID, &Invalid);
  if (Invalid || !SEntry.isFile())
    return true;

  if (SEntry.getFile().getFileCharacteristic() != SrcMgr::C_User) {
    switch (IndexOpts.SystemSymbolFilter) {
    case IndexingOptions::SystemSymbolFilterKind::None:
    case IndexingOptions::SystemSymbolFilterKind::DeclarationsOnly:
      return true;
    case IndexingOptions::SystemSymbolFilterKind::All:
      break;
    }
  }

  SymbolRoleSet Roles = (unsigned)SymbolRole::Reference;
  if (ImportD->isImplicit())
    Roles |= (unsigned)SymbolRole::Implicit;

  return DataConsumer.handleModuleOccurence(ImportD, Roles, FID, Offset);
}

bool IndexingContext::isFunctionLocalDecl(const Decl *D) {
  assert(D);

  if (isa<TemplateTemplateParmDecl>(D))
    return true;

  if (isa<ObjCTypeParamDecl>(D))
    return true;

  if (!D->getParentFunctionOrMethod())
    return false;

  if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
    switch (ND->getFormalLinkage()) {
    case NoLinkage:
    case VisibleNoLinkage:
    case InternalLinkage:
      return true;
    case UniqueExternalLinkage:
      llvm_unreachable("Not a sema linkage");
    case ExternalLinkage:
      return false;
    }
  }

  return true;
}

bool IndexingContext::isTemplateImplicitInstantiation(const Decl *D) {
  TemplateSpecializationKind TKind = TSK_Undeclared;
  if (const ClassTemplateSpecializationDecl *
      SD = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
    TKind = SD->getSpecializationKind();
  }
  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
    TKind = FD->getTemplateSpecializationKind();
  }
  switch (TKind) {
    case TSK_Undeclared:
    case TSK_ExplicitSpecialization:
      return false;
    case TSK_ImplicitInstantiation:
    case TSK_ExplicitInstantiationDeclaration:
    case TSK_ExplicitInstantiationDefinition:
      return true;
  }
  llvm_unreachable("invalid TemplateSpecializationKind");
}

bool IndexingContext::shouldIgnoreIfImplicit(const Decl *D) {
  if (isa<ObjCInterfaceDecl>(D))
    return false;
  if (isa<ObjCCategoryDecl>(D))
    return false;
  if (isa<ObjCIvarDecl>(D))
    return false;
  if (isa<ObjCMethodDecl>(D))
    return false;
  if (isa<ImportDecl>(D))
    return false;
  return true;
}

static const Decl *adjustTemplateImplicitInstantiation(const Decl *D) {
  if (const ClassTemplateSpecializationDecl *
      SD = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
    return SD->getTemplateInstantiationPattern();
  }
  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
    return FD->getTemplateInstantiationPattern();
  }
  return nullptr;
}

static bool isDeclADefinition(const Decl *D, ASTContext &Ctx) {
  if (auto VD = dyn_cast<VarDecl>(D))
    return VD->isThisDeclarationADefinition(Ctx);

  if (auto FD = dyn_cast<FunctionDecl>(D))
    return FD->isThisDeclarationADefinition();

  if (auto TD = dyn_cast<TagDecl>(D))
    return TD->isThisDeclarationADefinition();

  if (auto MD = dyn_cast<ObjCMethodDecl>(D))
    return MD->isThisDeclarationADefinition();

  if (isa<TypedefNameDecl>(D) ||
      isa<EnumConstantDecl>(D) ||
      isa<FieldDecl>(D) ||
      isa<MSPropertyDecl>(D) ||
      isa<ObjCImplDecl>(D) ||
      isa<ObjCPropertyImplDecl>(D))
    return true;

  return false;
}

static const Decl *adjustParent(const Decl *Parent) {
  if (!Parent)
    return nullptr;
  for (;; Parent = cast<Decl>(Parent->getDeclContext())) {
    if (isa<TranslationUnitDecl>(Parent))
      return nullptr;
    if (isa<LinkageSpecDecl>(Parent) || isa<BlockDecl>(Parent))
      continue;
    if (auto NS = dyn_cast<NamespaceDecl>(Parent)) {
      if (NS->isAnonymousNamespace())
        continue;
    } else if (auto RD = dyn_cast<RecordDecl>(Parent)) {
      if (RD->isAnonymousStructOrUnion())
        continue;
    } else if (auto FD = dyn_cast<FieldDecl>(Parent)) {
      if (FD->getDeclName().isEmpty())
        continue;
    }
    return Parent;
  }
}

static const Decl *getCanonicalDecl(const Decl *D) {
  D = D->getCanonicalDecl();
  if (auto TD = dyn_cast<TemplateDecl>(D)) {
    D = TD->getTemplatedDecl();
    assert(D->isCanonicalDecl());
  }

  return D;
}

bool IndexingContext::handleDeclOccurrence(const Decl *D, SourceLocation Loc,
                                           bool IsRef, const Decl *Parent,
                                           SymbolRoleSet Roles,
                                           ArrayRef<SymbolRelation> Relations,
                                           const Expr *OrigE,
                                           const Decl *OrigD,
                                           const DeclContext *ContainerDC) {
  if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
    return true;
  if (!isa<NamedDecl>(D) ||
      (cast<NamedDecl>(D)->getDeclName().isEmpty() &&
       !isa<TagDecl>(D) && !isa<ObjCCategoryDecl>(D)))
    return true;

  SourceManager &SM = Ctx->getSourceManager();
  Loc = SM.getFileLoc(Loc);
  if (Loc.isInvalid())
    return true;

  FileID FID;
  unsigned Offset;
  std::tie(FID, Offset) = SM.getDecomposedLoc(Loc);
  if (FID.isInvalid())
    return true;

  bool Invalid = false;
  const SrcMgr::SLocEntry &SEntry = SM.getSLocEntry(FID, &Invalid);
  if (Invalid || !SEntry.isFile())
    return true;

  if (SEntry.getFile().getFileCharacteristic() != SrcMgr::C_User) {
    switch (IndexOpts.SystemSymbolFilter) {
    case IndexingOptions::SystemSymbolFilterKind::None:
      return true;
    case IndexingOptions::SystemSymbolFilterKind::DeclarationsOnly:
      if (IsRef)
        return true;
      break;
    case IndexingOptions::SystemSymbolFilterKind::All:
      break;
    }
  }

  if (isTemplateImplicitInstantiation(D)) {
    if (!IsRef)
      return true;
    D = adjustTemplateImplicitInstantiation(D);
    if (!D)
      return true;
    assert(!isTemplateImplicitInstantiation(D));
  }

  if (!OrigD)
    OrigD = D;

  if (IsRef)
    Roles |= (unsigned)SymbolRole::Reference;
  else if (isDeclADefinition(D, *Ctx))
    Roles |= (unsigned)SymbolRole::Definition;
  else
    Roles |= (unsigned)SymbolRole::Declaration;

  D = getCanonicalDecl(D);
  if (D->isImplicit() && !isa<ObjCMethodDecl>(D)) {
    // operator new declarations will link to the implicit one as canonical.
    return true;
  }
  Parent = adjustParent(Parent);
  if (Parent)
    Parent = getCanonicalDecl(Parent);
  assert(!Parent || !Parent->isImplicit() ||
         isa<FunctionDecl>(Parent) ||
         isa<ObjCInterfaceDecl>(Parent) || isa<ObjCMethodDecl>(Parent) &&
         "unexpected implicit parent!");

  SmallVector<SymbolRelation, 6> FinalRelations;
  FinalRelations.reserve(Relations.size()+1);

  auto addRelation = [&](SymbolRelation Rel) {
    auto It = std::find_if(FinalRelations.begin(), FinalRelations.end(),
                [&](SymbolRelation Elem)->bool {
                  return Elem.RelatedSymbol == Rel.RelatedSymbol;
                });
    if (It != FinalRelations.end()) {
      It->Roles |= Rel.Roles;
    } else {
      FinalRelations.push_back(Rel);
    }
    Roles |= Rel.Roles;
  };

  if (!IsRef && Parent && !cast<DeclContext>(Parent)->isFunctionOrMethod()) {
    addRelation(SymbolRelation{(unsigned)SymbolRole::RelationChildOf, Parent});
  }
  for (auto &Rel : Relations) {
    addRelation(SymbolRelation(Rel.Roles,
                               Rel.RelatedSymbol->getCanonicalDecl()));
  }

  IndexDataConsumer::ASTNodeInfo Node{ OrigE, OrigD, Parent, ContainerDC };
  return DataConsumer.handleDeclOccurence(D, Roles, FinalRelations, FID, Offset,
                                          Node);
}
<|endoftext|>


<commit_before>///////////////////////////////////////////////////////////////////////
// File:        fontinfo.cpp
// Description: Font information classes abstracted from intproto.h/cpp.
// Author:      rays@google.com (Ray Smith)
// Created:     Wed May 18 10:39:01 PDT 2011
//
// (C) Copyright 2011, Google Inc.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
///////////////////////////////////////////////////////////////////////

#include "fontinfo.h"
#include "bitvector.h"
#include "unicity_table.h"

namespace tesseract {

// Writes to the given file. Returns false in case of error.
bool FontInfo::Serialize(FILE* fp) const {
  if (!write_info(fp, *this)) return false;
  if (!write_spacing_info(fp, *this)) return false;
  return true;
}
// Reads from the given file. Returns false in case of error.
// If swap is true, assumes a big/little-endian swap is needed.
bool FontInfo::DeSerialize(TFile* fp) {
  if (!read_info(fp, this)) return false;
  if (!read_spacing_info(fp, this)) return false;
  return true;
}

FontInfoTable::FontInfoTable() {
  set_compare_callback(NewPermanentTessCallback(CompareFontInfo));
  set_clear_callback(NewPermanentTessCallback(FontInfoDeleteCallback));
}

FontInfoTable::~FontInfoTable() {
}

// Writes to the given file. Returns false in case of error.
bool FontInfoTable::Serialize(FILE* fp) const {
  return this->SerializeClasses(fp);
}
// Reads from the given file. Returns false in case of error.
// If swap is true, assumes a big/little-endian swap is needed.
bool FontInfoTable::DeSerialize(TFile* fp) {
  truncate(0);
  return this->DeSerializeClasses(fp);
}

// Returns true if the given set of fonts includes one with the same
// properties as font_id.
bool FontInfoTable::SetContainsFontProperties(
    int font_id, const GenericVector<ScoredFont>& font_set) const {
  uint32_t properties = get(font_id).properties;
  for (int f = 0; f < font_set.size(); ++f) {
    if (get(font_set[f].fontinfo_id).properties == properties)
      return true;
  }
  return false;
}

// Returns true if the given set of fonts includes multiple properties.
bool FontInfoTable::SetContainsMultipleFontProperties(
    const GenericVector<ScoredFont>& font_set) const {
  if (font_set.empty()) return false;
  int first_font = font_set[0].fontinfo_id;
  uint32_t properties = get(first_font).properties;
  for (int f = 1; f < font_set.size(); ++f) {
    if (get(font_set[f].fontinfo_id).properties != properties)
      return true;
  }
  return false;
}

// Moves any non-empty FontSpacingInfo entries from other to this.
void FontInfoTable::MoveSpacingInfoFrom(FontInfoTable* other) {
  set_compare_callback(NewPermanentTessCallback(CompareFontInfo));
  set_clear_callback(NewPermanentTessCallback(FontInfoDeleteCallback));
  for (int i = 0; i < other->size(); ++i) {
    GenericVector<FontSpacingInfo*>* spacing_vec = other->get(i).spacing_vec;
    if (spacing_vec != nullptr) {
      int target_index = get_index(other->get(i));
      if (target_index < 0) {
        // Bit copy the FontInfo and steal all the pointers.
        push_back(other->get(i));
        other->get(i).name = nullptr;
      } else {
        delete [] get(target_index).spacing_vec;
        get(target_index).spacing_vec = other->get(i).spacing_vec;
      }
      other->get(i).spacing_vec = nullptr;
    }
  }
}

// Moves this to the target unicity table.
void FontInfoTable::MoveTo(UnicityTable<FontInfo>* target) {
  target->clear();
  target->set_compare_callback(NewPermanentTessCallback(CompareFontInfo));
  target->set_clear_callback(NewPermanentTessCallback(FontInfoDeleteCallback));
  for (int i = 0; i < size(); ++i) {
    // Bit copy the FontInfo and steal all the pointers.
    target->push_back(get(i));
    get(i).name = nullptr;
    get(i).spacing_vec = nullptr;
  }
}

// Compare FontInfo structures.
bool CompareFontInfo(const FontInfo& fi1, const FontInfo& fi2) {
  // The font properties are required to be the same for two font with the same
  // name, so there is no need to test them.
  // Consequently, querying the table with only its font name as information is
  // enough to retrieve its properties.
  return strcmp(fi1.name, fi2.name) == 0;
}
// Compare FontSet structures.
bool CompareFontSet(const FontSet& fs1, const FontSet& fs2) {
  if (fs1.size != fs2.size)
    return false;
  for (int i = 0; i < fs1.size; ++i) {
    if (fs1.configs[i] != fs2.configs[i])
      return false;
  }
  return true;
}

// Callbacks for GenericVector.
void FontInfoDeleteCallback(FontInfo f) {
  if (f.spacing_vec != nullptr) {
    f.spacing_vec->delete_data_pointers();
    delete f.spacing_vec;
  }
  delete[] f.name;
}
void FontSetDeleteCallback(FontSet fs) {
  delete[] fs.configs;
}

/*---------------------------------------------------------------------------*/
// Callbacks used by UnicityTable to read/write FontInfo/FontSet structures.
bool read_info(TFile* f, FontInfo* fi) {
  uint32_t size;
  if (!f->DeSerialize(&size)) return false;
  char* font_name = new char[size + 1];
  fi->name = font_name;
  if (!f->DeSerialize(font_name, size)) return false;
  font_name[size] = '\0';
  return f->DeSerialize(&fi->properties);
}

bool write_info(FILE* f, const FontInfo& fi) {
  int32_t size = strlen(fi.name);
  return tesseract::Serialize(f, &size) &&
         tesseract::Serialize(f, &fi.name[0], size) &&
         tesseract::Serialize(f, &fi.properties);
}

bool read_spacing_info(TFile* f, FontInfo* fi) {
  int32_t vec_size, kern_size;
  if (!f->DeSerialize(&vec_size)) return false;
  ASSERT_HOST(vec_size >= 0);
  if (vec_size == 0) return true;
  fi->init_spacing(vec_size);
  for (int i = 0; i < vec_size; ++i) {
    FontSpacingInfo *fs = new FontSpacingInfo();
    if (!f->DeSerialize(&fs->x_gap_before) ||
        !f->DeSerialize(&fs->x_gap_after) ||
        !f->DeSerialize(&kern_size)) {
      delete fs;
      return false;
    }
    if (kern_size < 0) {  // indication of a nullptr entry in fi->spacing_vec
      delete fs;
      continue;
    }
    if (kern_size > 0 && (!fs->kerned_unichar_ids.DeSerialize(f) ||
                          !fs->kerned_x_gaps.DeSerialize(f))) {
      delete fs;
      return false;
    }
    fi->add_spacing(i, fs);
  }
  return true;
}

bool write_spacing_info(FILE* f, const FontInfo& fi) {
  int32_t vec_size = (fi.spacing_vec == nullptr) ? 0 : fi.spacing_vec->size();
  if (!tesseract::Serialize(f, &vec_size)) return false;
  int16_t x_gap_invalid = -1;
  for (int i = 0; i < vec_size; ++i) {
    FontSpacingInfo *fs = fi.spacing_vec->get(i);
    int32_t kern_size = (fs == nullptr) ? -1 : fs->kerned_x_gaps.size();
    if (fs == nullptr) {
      // Writing two invalid x-gaps.
      if (!tesseract::Serialize(f, &x_gap_invalid, 2) ||
          !tesseract::Serialize(f, &kern_size)) {
        return false;
      }
    } else {
      if (!tesseract::Serialize(f, &fs->x_gap_before) ||
          !tesseract::Serialize(f, &fs->x_gap_after) ||
          !tesseract::Serialize(f, &kern_size)) {
        return false;
      }
    }
    if (kern_size > 0 && (!fs->kerned_unichar_ids.Serialize(f) ||
                          !fs->kerned_x_gaps.Serialize(f))) {
      return false;
    }
  }
  return true;
}

bool read_set(TFile* f, FontSet* fs) {
  if (!f->DeSerialize(&fs->size)) return false;
  fs->configs = new int[fs->size];
  return f->DeSerialize(&fs->configs[0], fs->size);
}

bool write_set(FILE* f, const FontSet& fs) {
  return tesseract::Serialize(f, &fs.size) &&
         tesseract::Serialize(f, &fs.configs[0], fs.size);
}

}  // namespace tesseract.
<commit_msg>FontInfo: Make sure that deleted member variables can no longer be used<commit_after>///////////////////////////////////////////////////////////////////////
// File:        fontinfo.cpp
// Description: Font information classes abstracted from intproto.h/cpp.
// Author:      rays@google.com (Ray Smith)
//
// (C) Copyright 2011, Google Inc.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
///////////////////////////////////////////////////////////////////////

#include "fontinfo.h"
#include "bitvector.h"
#include "unicity_table.h"

namespace tesseract {

// Writes to the given file. Returns false in case of error.
bool FontInfo::Serialize(FILE* fp) const {
  if (!write_info(fp, *this)) return false;
  if (!write_spacing_info(fp, *this)) return false;
  return true;
}
// Reads from the given file. Returns false in case of error.
// If swap is true, assumes a big/little-endian swap is needed.
bool FontInfo::DeSerialize(TFile* fp) {
  if (!read_info(fp, this)) return false;
  if (!read_spacing_info(fp, this)) return false;
  return true;
}

FontInfoTable::FontInfoTable() {
  set_compare_callback(NewPermanentTessCallback(CompareFontInfo));
  set_clear_callback(NewPermanentTessCallback(FontInfoDeleteCallback));
}

FontInfoTable::~FontInfoTable() {
}

// Writes to the given file. Returns false in case of error.
bool FontInfoTable::Serialize(FILE* fp) const {
  return this->SerializeClasses(fp);
}
// Reads from the given file. Returns false in case of error.
// If swap is true, assumes a big/little-endian swap is needed.
bool FontInfoTable::DeSerialize(TFile* fp) {
  truncate(0);
  return this->DeSerializeClasses(fp);
}

// Returns true if the given set of fonts includes one with the same
// properties as font_id.
bool FontInfoTable::SetContainsFontProperties(
    int font_id, const GenericVector<ScoredFont>& font_set) const {
  uint32_t properties = get(font_id).properties;
  for (int f = 0; f < font_set.size(); ++f) {
    if (get(font_set[f].fontinfo_id).properties == properties)
      return true;
  }
  return false;
}

// Returns true if the given set of fonts includes multiple properties.
bool FontInfoTable::SetContainsMultipleFontProperties(
    const GenericVector<ScoredFont>& font_set) const {
  if (font_set.empty()) return false;
  int first_font = font_set[0].fontinfo_id;
  uint32_t properties = get(first_font).properties;
  for (int f = 1; f < font_set.size(); ++f) {
    if (get(font_set[f].fontinfo_id).properties != properties)
      return true;
  }
  return false;
}

// Moves any non-empty FontSpacingInfo entries from other to this.
void FontInfoTable::MoveSpacingInfoFrom(FontInfoTable* other) {
  set_compare_callback(NewPermanentTessCallback(CompareFontInfo));
  set_clear_callback(NewPermanentTessCallback(FontInfoDeleteCallback));
  for (int i = 0; i < other->size(); ++i) {
    GenericVector<FontSpacingInfo*>* spacing_vec = other->get(i).spacing_vec;
    if (spacing_vec != nullptr) {
      int target_index = get_index(other->get(i));
      if (target_index < 0) {
        // Bit copy the FontInfo and steal all the pointers.
        push_back(other->get(i));
        other->get(i).name = nullptr;
      } else {
        delete [] get(target_index).spacing_vec;
        get(target_index).spacing_vec = other->get(i).spacing_vec;
      }
      other->get(i).spacing_vec = nullptr;
    }
  }
}

// Moves this to the target unicity table.
void FontInfoTable::MoveTo(UnicityTable<FontInfo>* target) {
  target->clear();
  target->set_compare_callback(NewPermanentTessCallback(CompareFontInfo));
  target->set_clear_callback(NewPermanentTessCallback(FontInfoDeleteCallback));
  for (int i = 0; i < size(); ++i) {
    // Bit copy the FontInfo and steal all the pointers.
    target->push_back(get(i));
    get(i).name = nullptr;
    get(i).spacing_vec = nullptr;
  }
}

// Compare FontInfo structures.
bool CompareFontInfo(const FontInfo& fi1, const FontInfo& fi2) {
  // The font properties are required to be the same for two font with the same
  // name, so there is no need to test them.
  // Consequently, querying the table with only its font name as information is
  // enough to retrieve its properties.
  return strcmp(fi1.name, fi2.name) == 0;
}
// Compare FontSet structures.
bool CompareFontSet(const FontSet& fs1, const FontSet& fs2) {
  if (fs1.size != fs2.size)
    return false;
  for (int i = 0; i < fs1.size; ++i) {
    if (fs1.configs[i] != fs2.configs[i])
      return false;
  }
  return true;
}

// Callbacks for GenericVector.
void FontInfoDeleteCallback(FontInfo f) {
  if (f.spacing_vec != nullptr) {
    f.spacing_vec->delete_data_pointers();
    delete f.spacing_vec;
    f.spacing_vec = nullptr;
  }
  delete[] f.name;
  f.name = nullptr;
}
void FontSetDeleteCallback(FontSet fs) {
  delete[] fs.configs;
}

/*---------------------------------------------------------------------------*/
// Callbacks used by UnicityTable to read/write FontInfo/FontSet structures.
bool read_info(TFile* f, FontInfo* fi) {
  uint32_t size;
  if (!f->DeSerialize(&size)) return false;
  char* font_name = new char[size + 1];
  fi->name = font_name;
  if (!f->DeSerialize(font_name, size)) return false;
  font_name[size] = '\0';
  return f->DeSerialize(&fi->properties);
}

bool write_info(FILE* f, const FontInfo& fi) {
  int32_t size = strlen(fi.name);
  return tesseract::Serialize(f, &size) &&
         tesseract::Serialize(f, &fi.name[0], size) &&
         tesseract::Serialize(f, &fi.properties);
}

bool read_spacing_info(TFile* f, FontInfo* fi) {
  int32_t vec_size, kern_size;
  if (!f->DeSerialize(&vec_size)) return false;
  ASSERT_HOST(vec_size >= 0);
  if (vec_size == 0) return true;
  fi->init_spacing(vec_size);
  for (int i = 0; i < vec_size; ++i) {
    FontSpacingInfo *fs = new FontSpacingInfo();
    if (!f->DeSerialize(&fs->x_gap_before) ||
        !f->DeSerialize(&fs->x_gap_after) ||
        !f->DeSerialize(&kern_size)) {
      delete fs;
      return false;
    }
    if (kern_size < 0) {  // indication of a nullptr entry in fi->spacing_vec
      delete fs;
      continue;
    }
    if (kern_size > 0 && (!fs->kerned_unichar_ids.DeSerialize(f) ||
                          !fs->kerned_x_gaps.DeSerialize(f))) {
      delete fs;
      return false;
    }
    fi->add_spacing(i, fs);
  }
  return true;
}

bool write_spacing_info(FILE* f, const FontInfo& fi) {
  int32_t vec_size = (fi.spacing_vec == nullptr) ? 0 : fi.spacing_vec->size();
  if (!tesseract::Serialize(f, &vec_size)) return false;
  int16_t x_gap_invalid = -1;
  for (int i = 0; i < vec_size; ++i) {
    FontSpacingInfo *fs = fi.spacing_vec->get(i);
    int32_t kern_size = (fs == nullptr) ? -1 : fs->kerned_x_gaps.size();
    if (fs == nullptr) {
      // Writing two invalid x-gaps.
      if (!tesseract::Serialize(f, &x_gap_invalid, 2) ||
          !tesseract::Serialize(f, &kern_size)) {
        return false;
      }
    } else {
      if (!tesseract::Serialize(f, &fs->x_gap_before) ||
          !tesseract::Serialize(f, &fs->x_gap_after) ||
          !tesseract::Serialize(f, &kern_size)) {
        return false;
      }
    }
    if (kern_size > 0 && (!fs->kerned_unichar_ids.Serialize(f) ||
                          !fs->kerned_x_gaps.Serialize(f))) {
      return false;
    }
  }
  return true;
}

bool read_set(TFile* f, FontSet* fs) {
  if (!f->DeSerialize(&fs->size)) return false;
  fs->configs = new int[fs->size];
  return f->DeSerialize(&fs->configs[0], fs->size);
}

bool write_set(FILE* f, const FontSet& fs) {
  return tesseract::Serialize(f, &fs.size) &&
         tesseract::Serialize(f, &fs.configs[0], fs.size);
}

}  // namespace tesseract.
<|endoftext|>


<commit_before>/*
* Copyright 2018 NXP.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* Neither the name of the NXP Semiconductor nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/

#include <iostream>
#include <stdio.h>
#include <thread>
#include <atomic>
#include <iomanip>

#include "../libuuu/libuuu.h"

using namespace std;
void print_help()
{
	printf("uuu u-boot.imx\\flash.bin\n");
	printf("\tDownload u-boot.imx\\flash.bin to board by usb\n");
}
void print_version()
{
	printf("uuu (universal update utitle) for nxp imx chips -- %s\n\n", get_version_string());
}

int polling_usb(std::atomic<int>& bexit);

class ShowNotify
{
public:
	string m_cmd;
	string m_dev;
	int	m_trans_size;
	int m_trans_pos;

	ShowNotify()
	{
		m_trans_size = m_trans_pos = 0;
	}

	void print(notify nt)
	{
		if (nt.type == notify::NOFITY_DEV_ATTACH)
		{
			m_dev = nt.str;
		}
		if (nt.type == notify::NOTIFY_CMD_START)
		{
			m_cmd = nt.str;
		}
		if (nt.type == notify::NOTIFY_TRANS_SIZE)
		{
			m_trans_size = nt.total;
		}
		if (nt.type == notify::NOTIFY_TRANS_POS)
		{
			if (m_trans_size == 0)
				return;

			if ((nt.index - m_trans_pos) < (m_trans_size / 100))
				return;

			m_trans_pos = nt.index;
		}

		cout << m_dev.c_str() << std::setw(8) << "[";
		int width=40;
		int s = 0;
		for (int i = 1; i <= width; i++)
		{
			if (m_trans_size == 0)
			{
				cout << " ";
				continue;
			}

			if (m_trans_pos*width / (m_trans_size*i))
			{
				cout << "=";
				s = 1;
			}
			else
			{
				if (s)
				{
					s = 0;
					cout << ">";
				}
				else
				{
					cout << " ";
				}
			}
		}

		cout << "] " << m_cmd.c_str() <<"\r";
	}
};

int progress(notify nt, void *p)
{
	ShowNotify *np = (ShowNotify*)p;
	np->print(nt);
	return 0;
}

int main(int argc, char **argv)
{
	print_version();

	if (argc == 1)
		print_help();

	ShowNotify sn;
	register_notify_callback(progress, &sn);

	if (run_cmd("SDPS: boot flash_mfg.bin"))
		printf("Error: %s\n", get_last_err_string());
	return 0;
}

<commit_msg>Test SPDS command<commit_after>/*
* Copyright 2018 NXP.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* Neither the name of the NXP Semiconductor nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/

#include <iostream>
#include <stdio.h>
#include <thread>
#include <atomic>
#include <iomanip>

#include "../libuuu/libuuu.h"

using namespace std;
void print_help()
{
	printf("uuu u-boot.imx\\flash.bin\n");
	printf("\tDownload u-boot.imx\\flash.bin to board by usb\n");
}
void print_version()
{
	printf("uuu (universal update utitle) for nxp imx chips -- %s\n\n", get_version_string());
}

int polling_usb(std::atomic<int>& bexit);

class ShowNotify
{
public:
	string m_cmd;
	string m_dev;
	int	m_trans_size;
	int m_trans_pos;

	ShowNotify()
	{
		m_trans_size = m_trans_pos = 0;
	}

	void print(notify nt)
	{
		if (nt.type == notify::NOFITY_DEV_ATTACH)
		{
			m_dev = nt.str;
		}
		if (nt.type == notify::NOTIFY_CMD_START)
		{
			m_cmd = nt.str;
		}
		if (nt.type == notify::NOTIFY_TRANS_SIZE)
		{
			m_trans_size = nt.total;
		}
		if (nt.type == notify::NOTIFY_TRANS_POS)
		{
			if (m_trans_size == 0)
				return;

			if ((nt.index - m_trans_pos) < (m_trans_size / 100))
				return;

			m_trans_pos = nt.index;
		}

		cout << m_dev.c_str() << std::setw(8) << "[";
		int width=40;
		int s = 0;
		for (int i = 1; i <= width; i++)
		{
			if (m_trans_size == 0)
			{
				cout << " ";
				continue;
			}

			if (m_trans_pos*width / (m_trans_size*i))
			{
				cout << "=";
				s = 1;
			}
			else
			{
				if (s)
				{
					s = 0;
					cout << ">";
				}
				else
				{
					cout << " ";
				}
			}
		}

		cout << "] " << m_cmd.c_str() <<"\r";
	}
};

int progress(notify nt, void *p)
{
	ShowNotify *np = (ShowNotify*)p;
	np->print(nt);
	return 0;
}

int main(int argc, char **argv)
{
	print_version();

	if (argc == 1)
		print_help();

	ShowNotify sn;
	register_notify_callback(progress, &sn);

	string cmd = "SDPS: boot ";
	cmd += argv[1];

	if (run_cmd(cmd.c_str()))
		printf("Error: %s\n", get_last_err_string());
	return 0;
}

<|endoftext|>


<commit_before>//===-- StringTableBuilder.cpp - String table building utility ------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "llvm/MC/StringTableBuilder.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/COFF.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/raw_ostream.h"

#include <vector>

using namespace llvm;

namespace llvm {
template <> struct DenseMapInfo<CachedHashString> {
  static CachedHashString getEmptyKey() {
    StringRef S = DenseMapInfo<StringRef>::getEmptyKey();
    return {S, 0};
  }
  static CachedHashString getTombstoneKey() {
    StringRef S = DenseMapInfo<StringRef>::getTombstoneKey();
    return {S, 0};
  }
  static unsigned getHashValue(CachedHashString Val) {
    assert(!isEqual(Val, getEmptyKey()) && "Cannot hash the empty key!");
    assert(!isEqual(Val, getTombstoneKey()) &&
           "Cannot hash the tombstone key!");
    return Val.hash();
  }
  static bool isEqual(CachedHashString A, CachedHashString B) {
    return DenseMapInfo<StringRef>::isEqual(A.val(), B.val());
  }
};
}

StringTableBuilder::~StringTableBuilder() {}

void StringTableBuilder::initSize() {
  // Account for leading bytes in table so that offsets returned from add are
  // correct.
  switch (K) {
  case RAW:
    Size = 0;
    break;
  case MachO:
  case ELF:
    // Start the table with a NUL byte.
    Size = 1;
    break;
  case WinCOFF:
    // Make room to write the table size later.
    Size = 4;
    break;
  }
}

StringTableBuilder::StringTableBuilder(Kind K, unsigned Alignment)
    : K(K), Alignment(Alignment) {
  initSize();
}

void StringTableBuilder::write(raw_ostream &OS) const {
  assert(isFinalized());
  SmallString<0> Data;
  Data.resize(getSize());
  write((uint8_t *)&Data[0]);
  OS << Data;
}

typedef std::pair<CachedHashString, size_t> StringPair;

void StringTableBuilder::write(uint8_t *Buf) const {
  assert(isFinalized());
  for (const StringPair &P : StringIndexMap) {
    StringRef Data = P.first.val();
    memcpy(Buf + P.second, Data.data(), Data.size());
  }
  if (K != WinCOFF)
    return;
  support::endian::write32le(Buf, Size);
}

// Returns the character at Pos from end of a string.
static int charTailAt(StringPair *P, size_t Pos) {
  StringRef S = P->first.val();
  if (Pos >= S.size())
    return -1;
  return (unsigned char)S[S.size() - Pos - 1];
}

// Three-way radix quicksort. This is much faster than std::sort with strcmp
// because it does not compare characters that we already know the same.
static void multikey_qsort(StringPair **Begin, StringPair **End, int Pos) {
tailcall:
  if (End - Begin <= 1)
    return;

  // Partition items. Items in [Begin, P) are greater than the pivot,
  // [P, Q) are the same as the pivot, and [Q, End) are less than the pivot.
  int Pivot = charTailAt(*Begin, Pos);
  StringPair **P = Begin;
  StringPair **Q = End;
  for (StringPair **R = Begin + 1; R < Q;) {
    int C = charTailAt(*R, Pos);
    if (C > Pivot)
      std::swap(*P++, *R++);
    else if (C < Pivot)
      std::swap(*--Q, *R);
    else
      R++;
  }

  multikey_qsort(Begin, P, Pos);
  multikey_qsort(Q, End, Pos);
  if (Pivot != -1) {
    // qsort(P, Q, Pos + 1), but with tail call optimization.
    Begin = P;
    End = Q;
    ++Pos;
    goto tailcall;
  }
}

void StringTableBuilder::finalize() {
  finalizeStringTable(/*Optimize=*/true);
}

void StringTableBuilder::finalizeInOrder() {
  finalizeStringTable(/*Optimize=*/false);
}

void StringTableBuilder::finalizeStringTable(bool Optimize) {
  Finalized = true;

  if (Optimize) {
    std::vector<StringPair *> Strings;
    Strings.reserve(StringIndexMap.size());
    for (StringPair &P : StringIndexMap)
      Strings.push_back(&P);

    if (!Strings.empty()) {
      // If we're optimizing, sort by name. If not, sort by previously assigned
      // offset.
      multikey_qsort(&Strings[0], &Strings[0] + Strings.size(), 0);
    }

    initSize();

    StringRef Previous;
    for (StringPair *P : Strings) {
      StringRef S = P->first.val();
      if (Previous.endswith(S)) {
        size_t Pos = Size - S.size() - (K != RAW);
        if (!(Pos & (Alignment - 1))) {
          P->second = Pos;
          continue;
        }
      }

      Size = alignTo(Size, Alignment);
      P->second = Size;

      Size += S.size();
      if (K != RAW)
        ++Size;
      Previous = S;
    }
  }

  if (K == MachO)
    Size = alignTo(Size, 4); // Pad to multiple of 4.
}

void StringTableBuilder::clear() {
  Finalized = false;
  StringIndexMap.clear();
}

size_t StringTableBuilder::getOffset(StringRef S) const {
  assert(isFinalized());
  auto I = StringIndexMap.find(S);
  assert(I != StringIndexMap.end() && "String is not in table!");
  return I->second;
}

size_t StringTableBuilder::add(StringRef S) {
  if (K == WinCOFF)
    assert(S.size() > COFF::NameSize && "Short string in COFF string table!");

  assert(!isFinalized());
  size_t Start = alignTo(Size, Alignment);
  auto P = StringIndexMap.insert(std::make_pair(S, Start));
  if (P.second)
    Size = Start + S.size() + (K != RAW);
  return P.first->second;
}
<commit_msg>Don't pass null to memcpy. Should fix the asan bots.<commit_after>//===-- StringTableBuilder.cpp - String table building utility ------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "llvm/MC/StringTableBuilder.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/COFF.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/raw_ostream.h"

#include <vector>

using namespace llvm;

namespace llvm {
template <> struct DenseMapInfo<CachedHashString> {
  static CachedHashString getEmptyKey() {
    StringRef S = DenseMapInfo<StringRef>::getEmptyKey();
    return {S, 0};
  }
  static CachedHashString getTombstoneKey() {
    StringRef S = DenseMapInfo<StringRef>::getTombstoneKey();
    return {S, 0};
  }
  static unsigned getHashValue(CachedHashString Val) {
    assert(!isEqual(Val, getEmptyKey()) && "Cannot hash the empty key!");
    assert(!isEqual(Val, getTombstoneKey()) &&
           "Cannot hash the tombstone key!");
    return Val.hash();
  }
  static bool isEqual(CachedHashString A, CachedHashString B) {
    return DenseMapInfo<StringRef>::isEqual(A.val(), B.val());
  }
};
}

StringTableBuilder::~StringTableBuilder() {}

void StringTableBuilder::initSize() {
  // Account for leading bytes in table so that offsets returned from add are
  // correct.
  switch (K) {
  case RAW:
    Size = 0;
    break;
  case MachO:
  case ELF:
    // Start the table with a NUL byte.
    Size = 1;
    break;
  case WinCOFF:
    // Make room to write the table size later.
    Size = 4;
    break;
  }
}

StringTableBuilder::StringTableBuilder(Kind K, unsigned Alignment)
    : K(K), Alignment(Alignment) {
  initSize();
}

void StringTableBuilder::write(raw_ostream &OS) const {
  assert(isFinalized());
  SmallString<0> Data;
  Data.resize(getSize());
  write((uint8_t *)&Data[0]);
  OS << Data;
}

typedef std::pair<CachedHashString, size_t> StringPair;

void StringTableBuilder::write(uint8_t *Buf) const {
  assert(isFinalized());
  for (const StringPair &P : StringIndexMap) {
    StringRef Data = P.first.val();
    if (!Data.empty())
      memcpy(Buf + P.second, Data.data(), Data.size());
  }
  if (K != WinCOFF)
    return;
  support::endian::write32le(Buf, Size);
}

// Returns the character at Pos from end of a string.
static int charTailAt(StringPair *P, size_t Pos) {
  StringRef S = P->first.val();
  if (Pos >= S.size())
    return -1;
  return (unsigned char)S[S.size() - Pos - 1];
}

// Three-way radix quicksort. This is much faster than std::sort with strcmp
// because it does not compare characters that we already know the same.
static void multikey_qsort(StringPair **Begin, StringPair **End, int Pos) {
tailcall:
  if (End - Begin <= 1)
    return;

  // Partition items. Items in [Begin, P) are greater than the pivot,
  // [P, Q) are the same as the pivot, and [Q, End) are less than the pivot.
  int Pivot = charTailAt(*Begin, Pos);
  StringPair **P = Begin;
  StringPair **Q = End;
  for (StringPair **R = Begin + 1; R < Q;) {
    int C = charTailAt(*R, Pos);
    if (C > Pivot)
      std::swap(*P++, *R++);
    else if (C < Pivot)
      std::swap(*--Q, *R);
    else
      R++;
  }

  multikey_qsort(Begin, P, Pos);
  multikey_qsort(Q, End, Pos);
  if (Pivot != -1) {
    // qsort(P, Q, Pos + 1), but with tail call optimization.
    Begin = P;
    End = Q;
    ++Pos;
    goto tailcall;
  }
}

void StringTableBuilder::finalize() {
  finalizeStringTable(/*Optimize=*/true);
}

void StringTableBuilder::finalizeInOrder() {
  finalizeStringTable(/*Optimize=*/false);
}

void StringTableBuilder::finalizeStringTable(bool Optimize) {
  Finalized = true;

  if (Optimize) {
    std::vector<StringPair *> Strings;
    Strings.reserve(StringIndexMap.size());
    for (StringPair &P : StringIndexMap)
      Strings.push_back(&P);

    if (!Strings.empty()) {
      // If we're optimizing, sort by name. If not, sort by previously assigned
      // offset.
      multikey_qsort(&Strings[0], &Strings[0] + Strings.size(), 0);
    }

    initSize();

    StringRef Previous;
    for (StringPair *P : Strings) {
      StringRef S = P->first.val();
      if (Previous.endswith(S)) {
        size_t Pos = Size - S.size() - (K != RAW);
        if (!(Pos & (Alignment - 1))) {
          P->second = Pos;
          continue;
        }
      }

      Size = alignTo(Size, Alignment);
      P->second = Size;

      Size += S.size();
      if (K != RAW)
        ++Size;
      Previous = S;
    }
  }

  if (K == MachO)
    Size = alignTo(Size, 4); // Pad to multiple of 4.
}

void StringTableBuilder::clear() {
  Finalized = false;
  StringIndexMap.clear();
}

size_t StringTableBuilder::getOffset(StringRef S) const {
  assert(isFinalized());
  auto I = StringIndexMap.find(S);
  assert(I != StringIndexMap.end() && "String is not in table!");
  return I->second;
}

size_t StringTableBuilder::add(StringRef S) {
  if (K == WinCOFF)
    assert(S.size() > COFF::NameSize && "Short string in COFF string table!");

  assert(!isFinalized());
  size_t Start = alignTo(Size, Alignment);
  auto P = StringIndexMap.insert(std::make_pair(S, Start));
  if (P.second)
    Size = Start + S.size() + (K != RAW);
  return P.first->second;
}
<|endoftext|>