Coverage Report

Created: 2020-02-25 14:32

/Users/buildslave/jenkins/workspace/coverage/llvm-project/libcxx/src/include/refstring.h
Line
Count
Source (jump to first uncovered line)
1
//===------------------------ __refstring ---------------------------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#ifndef _LIBCPP_REFSTRING_H
10
#define _LIBCPP_REFSTRING_H
11
12
#include <__config>
13
#include <stdexcept>
14
#include <cstddef>
15
#include <cstring>
16
#ifdef __APPLE__
17
#include <dlfcn.h>
18
#include <mach-o/dyld.h>
19
#endif
20
#include "atomic_support.h"
21
22
_LIBCPP_BEGIN_NAMESPACE_STD
23
24
namespace __refstring_imp { namespace {
25
typedef int count_t;
26
27
struct _Rep_base {
28
    std::size_t len;
29
    std::size_t cap;
30
    count_t     count;
31
};
32
33
0
inline _Rep_base* rep_from_data(const char *data_) noexcept {
34
0
    char *data = const_cast<char *>(data_);
35
0
    return reinterpret_cast<_Rep_base *>(data - sizeof(_Rep_base));
36
0
}
37
38
0
inline char * data_from_rep(_Rep_base *rep) noexcept {
39
0
    char *data = reinterpret_cast<char *>(rep);
40
0
    return data + sizeof(*rep);
41
0
}
42
43
#if defined(__APPLE__)
44
inline
45
const char* compute_gcc_empty_string_storage() _NOEXCEPT
46
0
{
47
0
    void* handle = dlopen("/usr/lib/libstdc++.6.dylib", RTLD_NOLOAD);
48
0
    if (handle == nullptr)
49
0
        return nullptr;
50
0
    void* sym = dlsym(handle, "_ZNSs4_Rep20_S_empty_rep_storageE");
51
0
    if (sym == nullptr)
52
0
        return nullptr;
53
0
    return data_from_rep(reinterpret_cast<_Rep_base *>(sym));
54
0
}
55
56
inline
57
const char*
58
get_gcc_empty_string_storage() _NOEXCEPT
59
0
{
60
0
    static const char* p = compute_gcc_empty_string_storage();
61
0
    return p;
62
0
}
63
#endif
64
65
}} // namespace __refstring_imp
66
67
using namespace __refstring_imp;
68
69
inline
70
0
__libcpp_refstring::__libcpp_refstring(const char* msg) {
71
0
    std::size_t len = strlen(msg);
72
0
    _Rep_base* rep = static_cast<_Rep_base *>(::operator new(sizeof(*rep) + len + 1));
73
0
    rep->len = len;
74
0
    rep->cap = len;
75
0
    rep->count = 0;
76
0
    char *data = data_from_rep(rep);
77
0
    std::memcpy(data, msg, len + 1);
78
0
    __imp_ = data;
79
0
}
80
81
inline
82
__libcpp_refstring::__libcpp_refstring(const __libcpp_refstring &s) _NOEXCEPT
83
    : __imp_(s.__imp_)
84
0
{
85
0
    if (__uses_refcount())
86
0
        __libcpp_atomic_add(&rep_from_data(__imp_)->count, 1);
87
0
}
88
89
inline
90
0
__libcpp_refstring& __libcpp_refstring::operator=(__libcpp_refstring const& s) _NOEXCEPT {
91
0
    bool adjust_old_count = __uses_refcount();
92
0
    struct _Rep_base *old_rep = rep_from_data(__imp_);
93
0
    __imp_ = s.__imp_;
94
0
    if (__uses_refcount())
95
0
        __libcpp_atomic_add(&rep_from_data(__imp_)->count, 1);
96
0
    if (adjust_old_count)
97
0
    {
98
0
        if (__libcpp_atomic_add(&old_rep->count, count_t(-1)) < 0)
99
0
        {
100
0
            ::operator delete(old_rep);
101
0
        }
102
0
    }
103
0
    return *this;
104
0
}
105
106
inline
107
__libcpp_refstring::~__libcpp_refstring() {
108
    if (__uses_refcount()) {
109
        _Rep_base* rep = rep_from_data(__imp_);
110
        if (__libcpp_atomic_add(&rep->count, count_t(-1)) < 0) {
111
            ::operator delete(rep);
112
        }
113
    }
114
}
115
116
inline
117
0
bool __libcpp_refstring::__uses_refcount() const {
118
0
#ifdef __APPLE__
119
0
    return __imp_ != get_gcc_empty_string_storage();
120
#else
121
    return true;
122
#endif
123
}
124
125
_LIBCPP_END_NAMESPACE_STD
126
127
#endif //_LIBCPP_REFSTRING_H