1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-26 04:32:44 +01:00
Commit Graph

188 Commits

Author SHA1 Message Date
Benjamin Kramer
ce7baceeed Add missing includes. make_unique proliferated everywhere.
llvm-svn: 230909
2015-03-01 21:28:53 +00:00
Aaron Ballman
7bf5e9ba92 MSVC 2013 does not ICE on this code in the same fashion that MSVC 2012 did; NFC.
llvm-svn: 229422
2015-02-16 19:33:36 +00:00
Zachary Turner
76143c865c Use ADDITIONAL_HEADER_DIRS in all LLVM CMake projects.
This allows IDEs to recognize the entire set of header files for
each of the core LLVM projects.

Differential Revision: http://reviews.llvm.org/D7526
Reviewed By: Chris Bieneman

llvm-svn: 228798
2015-02-11 03:28:02 +00:00
Alexander Kornienko
66580103e2 Replace size method call of containers to empty method where appropriate
This patch was generated by a clang tidy checker that is being open sourced.
The documentation of that checker is the following:

/// The emptiness of a container should be checked using the empty method
/// instead of the size method. It is not guaranteed that size is a
/// constant-time function, and it is generally more efficient and also shows
/// clearer intent to use empty. Furthermore some containers may implement the
/// empty method but not implement the size method. Using empty whenever
/// possible makes it easier to switch to another container in the future.

Patch by Gábor Horváth!

llvm-svn: 226161
2015-01-15 11:41:30 +00:00
Michael Ilseman
6d636ee500 Clean up static analyzer warnings.
Clang's static analyzer found several potential cases of undefined
behavior, use of un-initialized values, and potentially null pointer
dereferences in tablegen, Support, MC, and ADT. This cleans them up
with specific assertions on the assumptions of the code.

llvm-svn: 224154
2014-12-12 21:48:03 +00:00
Craig Topper
9a511af4f9 Use range-based for loops. NFC
llvm-svn: 224005
2014-12-11 07:04:54 +00:00
Craig Topper
09f2fc9487 Make MultiClass::DefPrototypes own their Records to fix memory leaks.
llvm-svn: 223998
2014-12-11 05:25:33 +00:00
Craig Topper
4e19eb8884 Replace std::map<K, V*> with std::map<K, std::unique_ptr<V>> to handle ownership and deletion of the values.
Ideally we would store the MultiClasses by value directly in the maps, but I had some trouble with that before and this at least fixes the leak.

llvm-svn: 223997
2014-12-11 05:25:30 +00:00
Craig Topper
4cd248ccb7 Revert r222957 "Replace std::map<K, V*> with std::map<K, V> to handle ownership and deletion of the values."
Upon further review I think the MultiClass is being copied into the map instead of being moved due to the copy constructor on the nested Record type. This ultimately got exposed when the vector in DefPrototype vector was changed to hold unique_ptrs in another commit. This caused gcc 4.7 to fail due to the use of the copy constructor on unique_ptr with the error pointing back to one of the insert calls from this commit. Not sure why clang was able to build.

This reverts commit 710cdf729f84b428bf41aa8d32dbdb35fff79fde.

llvm-svn: 222971
2014-11-30 01:20:17 +00:00
Hans Wennborg
0c573ecede Revert r222965 "Make MultiClass::DefPrototypes own their Records to fix memory leaks."
The bots started failing with the error below. I suspect this revision was the cause.

FAILED: /home/bb/bin/g++47   -DGTEST_HAS_RTTI=0 -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -fPIC -fvisibility-inlines-hidden -Wall -W -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wno-missing-field-initializers -pedantic -Wno-long-long -Wno-maybe-uninitialized -Wno-comment -std=c++11 -ffunction-sections -fdata-sections -O3 -DNDEBUG -Ilib/TableGen -I/home/bb/cmake-llvm-x86_64-linux/llvm-project/llvm/lib/TableGen -Iinclude -I/home/bb/cmake-llvm-x86_64-linux/llvm-project/llvm/include    -fno-exceptions -fno-rtti -MMD -MT lib/TableGen/CMakeFiles/LLVMTableGen.dir/TGParser.cpp.o -MF "lib/TableGen/CMakeFiles/LLVMTableGen.dir/TGParser.cpp.o.d" -o lib/TableGen/CMakeFiles/LLVMTableGen.dir/TGParser.cpp.o -c /home/bb/cmake-llvm-x86_64-linux/llvm-project/llvm/lib/TableGen/TGParser.cpp
In file included from /usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/bits/stl_tempbuf.h:62:0,
                 from /usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/bits/stl_algo.h:64,
                 from /usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/algorithm:63,
                 from /home/bb/cmake-llvm-x86_64-linux/llvm-project/llvm/include/llvm/ADT/StringRef.h:13,
                 from /home/bb/cmake-llvm-x86_64-linux/llvm-project/llvm/lib/TableGen/TGLexer.h:17,
                 from /home/bb/cmake-llvm-x86_64-linux/llvm-project/llvm/lib/TableGen/TGParser.h:17,
                 from /home/bb/cmake-llvm-x86_64-linux/llvm-project/llvm/lib/TableGen/TGParser.cpp:14:
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/bits/stl_construct.h: In instantiation of 'void std::_Construct(_T1*, _Args&& ...) [with _T1 = std::unique_ptr<llvm::Record>; _Args = {const std::unique_ptr<llvm::Record, std::default_delete<llvm::Record> >&}]':
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/bits/stl_uninitialized.h:77:3:   required from 'static _ForwardIterator std::__uninitialized_copy<_TrivialValueTypes>::__uninit_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = __gnu_cxx::__normal_iterator<const std::unique_ptr<llvm::Record>*, std::vector<std::unique_ptr<llvm::Record> > >; _ForwardIterator = std::unique_ptr<llvm::Record>*; bool _TrivialValueTypes = false]'
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/bits/stl_uninitialized.h:119:41:   required from '_ForwardIterator std::uninitialized_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = __gnu_cxx::__normal_iterator<const std::unique_ptr<llvm::Record>*, std::vector<std::unique_ptr<llvm::Record> > >; _ForwardIterator = std::unique_ptr<llvm::Record>*]'
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/bits/stl_uninitialized.h:260:63:   required from '_ForwardIterator std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator, std::allocator<_Tp>&) [with _InputIterator = __gnu_cxx::__normal_iterator<const std::unique_ptr<llvm::Record>*, std::vector<std::unique_ptr<llvm::Record> > >; _ForwardIterator = std::unique_ptr<llvm::Record>*; _Tp = std::unique_ptr<llvm::Record>]'
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/bits/stl_vector.h:310:9:   required from 'std::vector<_Tp, _Alloc>::vector(const std::vector<_Tp, _Alloc>&) [with _Tp = std::unique_ptr<llvm::Record>; _Alloc = std::allocator<std::unique_ptr<llvm::Record> >]'
/home/bb/cmake-llvm-x86_64-linux/llvm-project/llvm/include/llvm/TableGen/Record.h:1664:8:   required from 'constexpr std::pair<_T1, _T2>::pair(_U1&&, _U2&&) [with _U1 = std::basic_string<char>&; _U2 = llvm::MultiClass; <template-parameter-2-3> = void; _T1 = std::basic_string<char>; _T2 = llvm::MultiClass]'
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/bits/stl_pair.h:273:72:   required from 'constexpr std::pair<typename std::__decay_and_strip<_T1>::__type, typename std::__decay_and_strip<_T2>::__type> std::make_pair(_T1&&, _T2&&) [with _T1 = std::basic_string<char>&; _T2 = llvm::MultiClass; typename std::__decay_and_strip<_T2>::__type = llvm::MultiClass; typename std::__decay_and_strip<_T1>::__type = std::basic_string<char>]'
/home/bb/cmake-llvm-x86_64-linux/llvm-project/llvm/lib/TableGen/TGParser.cpp:2295:78:   required from here
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/bits/stl_construct.h:77:7: error: use of deleted function 'std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = llvm::Record; _Dp = std::default_delete<llvm::Record>]'
In file included from /usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/memory:86:0,
                 from /home/bb/cmake-llvm-x86_64-linux/llvm-project/llvm/include/llvm/ADT/STLExtras.h:25,
                 from /home/bb/cmake-llvm-x86_64-linux/llvm-project/llvm/include/llvm/ADT/ArrayRef.h:14,
                 from /home/bb/cmake-llvm-x86_64-linux/llvm-project/llvm/include/llvm/Support/SourceMgr.h:19,
                 from /home/bb/cmake-llvm-x86_64-linux/llvm-project/llvm/lib/TableGen/TGParser.h:19,
                 from /home/bb/cmake-llvm-x86_64-linux/llvm-project/llvm/lib/TableGen/TGParser.cpp:14:
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/bits/unique_ptr.h:262:7: error: declared here
ninja: build stopped: subcommand failed.

llvm-svn: 222970
2014-11-30 00:43:50 +00:00
Hans Wennborg
b74f5370d2 Qualify one more make_unique call.
The previous patch had effect, but missed this one. It seems MSVC
gets ADL-confused by the calls where the first argument is a function call?

llvm-svn: 222968
2014-11-30 00:31:49 +00:00
Hans Wennborg
973c525e58 Speculatively qualify some llvm::make_unique calls trying to please MSVC
It was failing with this kind of error:

C:\b\build\slave\CrWinClang\build\src\third_party\llvm\lib\TableGen\TGParser.cpp(1243) : error C2668: 'llvm::make_unique' : ambiguous call to overloaded function

        C:\b\build\slave\CrWinClang\build\src\third_party\llvm\include\llvm/ADT/STLExtras.h(408): could be 'std::unique_ptr<llvm::Record,std::default_delete<_Ty>> llvm::make_unique<llvm::Record,std::string,llvm::SMLoc&,llvm::RecordKeeper&,bool>(std::string &&,llvm::SMLoc &,llvm::RecordKeeper &,bool &&)'
        with
        [
            _Ty=llvm::Record
        ]
        C:\b\depot_tools\win_toolchain\vs2013_files\win8sdk\bin\..\..\VC\include\memory(1637): or       'std::unique_ptr<llvm::Record,std::default_delete<_Ty>> std::make_unique<llvm::Record,std::string,llvm::SMLoc&,llvm::RecordKeeper&,bool>(std::string &&,llvm::SMLoc &,llvm::RecordKeeper &,bool &&)' [found using argument-dependent lookup]
        with
        [
            _Ty=llvm::Record
        ]
        while trying to match the argument list '(std::string, llvm::SMLoc, llvm::RecordKeeper, bool)'

llvm-svn: 222967
2014-11-30 00:24:43 +00:00
Craig Topper
0bf67a778c Use an unsigned type because there seems to be no reason for it to be signed.
llvm-svn: 222966
2014-11-30 00:24:32 +00:00
Craig Topper
82854d6680 Make MultiClass::DefPrototypes own their Records to fix memory leaks.
llvm-svn: 222965
2014-11-30 00:19:28 +00:00
Craig Topper
3efbd6ab7b Replace std::map<K, V*> with std::map<K, V> to handle ownership and deletion of the values.
llvm-svn: 222957
2014-11-29 18:12:59 +00:00
Craig Topper
548d244470 Remove 'else' after 'return'. Fix formatting of a 'switch' statement.
llvm-svn: 222955
2014-11-29 16:05:27 +00:00
Craig Topper
19cca98c0c Make RecordKeeper::addClass/addDef take unique_ptrs instead of creating one internally.
llvm-svn: 222948
2014-11-29 05:52:51 +00:00
Craig Topper
2d10991762 Use unique_ptr to remove some explicit deletes on some error case returns. At least one spot of weird ownership passing that needs some future cleanup.
llvm-svn: 222947
2014-11-29 05:31:10 +00:00
Benjamin Kramer
4c9fb3d669 Eliminate some deep std::vector copies. NFC.
llvm-svn: 218999
2014-10-03 18:33:16 +00:00
Anton Yartsev
ab00cb374c Refactoring: raw pointer -> unique_ptr
llvm-svn: 218462
2014-09-25 19:55:58 +00:00
Adam Nemet
adc8e63b0f [TableGen] Fully resolve class-instance values before defs in multiclasses
By class-instance values I mean 'Class<Arg>' in 'Class<Arg>.Field' or in
'Other<Class<Arg>>' (syntactically s SimpleValue).  This is to differentiate
from unnamed/anonymous record definitions (syntactically an ObjectBody) which
are not affected by this change.

Consider the testcase:

    class Struct<int i> {
      int I = !shl(i, 1);
      int J = !shl(I, 1);
    }

    class Class<Struct s> {
        int Class_J = s.J;
    }

    multiclass MultiClass<int i> {
      def Def : Class<Struct<i>>;
    }

    defm Defm : MultiClass<2>;

Before this fix, DefmDef.Class_J yields !shl(I, 1) instead of 8.

This is the sequence of events.  We start with this:

    multiclass MultiClass<int i> {
      def Def : Class<Struct<i>>;
    }

During ParseDef the anonymous object for the class-instance value is created:

    multiclass Multiclass<int i> {
      def anonymous_0 : Struct<i>;

      def Def : Class<NAME#anonymous_0>;
    }

Then class Struct<i> is added to anonymous_0.  Also Class<NAME#anonymous_0> is
added to Def:

    multiclass Multiclass<int i> {
      def anonymous_0 {
        int I = !shl(i, 1);
        int J = !shl(I, 1);
      }

      def Def {
        int Class_J = NAME#anonymous_0.J;
      }
    }

So far so good but then we move on to instantiating this in the defm
by substituting the template arg 'i'.

This is how the anonymous prototype looks after fully instantiating.

    defm Defm = {
      def Defmanonymous_0 {
         int I = 4;
         int J = !shl(I, 1);
      }

Note that we only resolved the reference to the template arg.  The
non-template-arg reference in 'J' has not been resolved yet.

Then we go on to instantiating the Def prototype:

      def DefmDef {
         int Class_J = NAME#anonymous_0.J;
      }

Which is resolved to Defmanonymous_0.J and then to !shl(I, 1).

When we fully resolve each record in a defm, Defmanonymous_0.J does get set
to 8 but that's too late for its use.

The patch adds a new attribute to the Record class that indicates that this
def is actually a class-instance value that may be *used* by other defs in a
multiclass.  (This is unlike regular defs which don't reference each other and
thus can be resolved indepedently.)  They are then fully resolved before the
other defs while the multiclass is instantiated.

I added vg_leak to the new test.  I am not sure if this is necessary but I
don't think I have a way to test it.  I can also check in without the XFAIL
and let the bots test this part.

Also tested that X86.td.expanded and AAarch64.td.expanded were unchange before
and after this change.  (This issue triggering this problem is a WIP patch.)

Part of <rdar://problem/17688758>

llvm-svn: 217886
2014-09-16 17:14:13 +00:00
Jean-Luc Duprat
efdb754d1a Comment only: Annotate loop as per mailing list discussion
llvm-svn: 216798
2014-08-29 22:43:30 +00:00
Jean-Luc Duprat
9d6a52ea2b Tablegen fixes for new syntax when initializing bits from variables.
Followup to r215086.

llvm-svn: 216757
2014-08-29 19:41:04 +00:00
Rafael Espindola
1d5713d9bf Modernize raw_fd_ostream's constructor a bit.
Take a StringRef instead of a "const char *".
Take a "std::error_code &" instead of a "std::string &" for error.

A create static method would be even better, but this patch is already a bit too
big.

llvm-svn: 216393
2014-08-25 18:16:47 +00:00
Dylan Noblesmith
75d9deb1b7 TableGen: unique_ptr-ify RecordKeeper
llvm-svn: 216350
2014-08-24 19:10:57 +00:00
Dylan Noblesmith
3cc3c572cd TableGen: delete no-op code
This does nothing but remove the Record from the map, and
then re-add it, without actually changing it in between.

The Record's Name used to be changed before re-adding it
when the code was first committed in r137232, but the
name-changing lines were removed in r142510, and since
then this code seems to do nothing.

This was also the only caller of removeClass or removeDef,
so now RecordKeeper owns its Records unconditionally,
and could be unique_ptr-ified.

llvm-svn: 216349
2014-08-24 19:10:53 +00:00
Dylan Noblesmith
1e8ed68e13 TableGen: use auto and for-range
llvm-svn: 216348
2014-08-24 19:10:49 +00:00
David Blaikie
7a58463dea Explicitly pass ownership of the MemoryBuffer to AddNewSourceBuffer using std::unique_ptr
llvm-svn: 216223
2014-08-21 20:44:56 +00:00
Benjamin Kramer
da144ed5a2 Canonicalize header guards into a common format.
Add header guards to files that were missing guards. Remove #endif comments
as they don't seem common in LLVM (we can easily add them back if we decide
they're useful)

Changes made by clang-tidy with minor tweaks.

llvm-svn: 215558
2014-08-13 16:26:38 +00:00
Anton Yartsev
eb8d11ee02 [tablegen] - Eliminate memory leaks in TGParser.cpp
Ugly solution indicating that a refactoring is necessary to get the ownership under control.

llvm-svn: 215176
2014-08-08 00:29:54 +00:00
Aaron Ballman
e9caa4132c Silencing an MSVC C4334 warning ('<<' : result of 32-bit shift implicitly converted to 64 bits (was 64-bit shift intended?)). No functional changes intended.
llvm-svn: 215100
2014-08-07 12:07:33 +00:00
Pete Cooper
cbc13312c3 Update BitRecTy::convertValue to allow if expressions with bit values on both sides of the if
llvm-svn: 215087
2014-08-07 05:47:10 +00:00
Pete Cooper
5d88ea715c Change the { } expression in tablegen to accept sized binary literals which are not just 0 and 1.
It also allows nested { } expressions, as now that they are sized, we can merge pull bits from the nested value.

In the current behaviour, everything in { } must have been convertible to a single bit.
However, now that binary literals are sized, its useful to be able to initialize a range of bits.

So, for example, its now possible to do

bits<8> x = { 0, 1, { 0b1001 }, 0, 0b0 }

llvm-svn: 215086
2014-08-07 05:47:07 +00:00
Pete Cooper
5e735d5967 Change TableGen so that binary literals such as 0b001 are now sized.
Instead of these becoming an integer literal internally, they now become bits<n> values.

Prior to this change, 0b001 was 1 bit long.  This is confusing as clearly the user gave 3 bits.
This new type holds both the literal value and the size, and so can ensure sizes match on initializers.

For example, this used to be legal

bits<1> x = 0b00;

but now it must be written as

bits<2> x = 0b00;

llvm-svn: 215084
2014-08-07 05:47:00 +00:00
Pete Cooper
91540288e1 TableGen: Change { } to only accept bits<n> entries when n == 1.
Prior to this change, it was legal to do something like

  bits<2> opc = { 0, 1 };
  bits<2> opc2 = { 1, 0 };
  bits<2> a = { opc, opc2 };

This involved silently dropping bits from opc and opc2 which is very hard to debug.

Now the above test would be an error.  Having tested with an assert, none of LLVM/clang was relying on this behaviour.

Thanks to Adam Nemet for the above test.

llvm-svn: 215083
2014-08-07 05:46:57 +00:00
Joerg Sonnenberger
f820adb814 Allow binary and for tblgen math.
llvm-svn: 214851
2014-08-05 09:43:25 +00:00
Pete Cooper
0141b69686 Don't fail tablegen immediately after failing to set a value.
Instead allow the variable to be declared, but don't attach an initializer. This allows more than a single error to be emitted before we exit.

Test case to follow soon in another patch.

llvm-svn: 214375
2014-07-31 01:44:00 +00:00
Pete Cooper
fbba8abe2f Add a better error message when failing to assign one tablegen value to another
This is currently for assigning from one bit init to another.  It can easily be extended to other types.

Test to follow soon in another patch.

llvm-svn: 214374
2014-07-31 01:43:57 +00:00
Adam Nemet
3bb0a6b076 [TableGen] Allow shift operators to take bits<n>
Convert the operand to int if possible, i.e. if the value is properly
initialized.  (I suppose there is further room for improvement here to also
peform the shift if the uninitialized bits are shifted out.)

With this little change we can now compute the scaling factor for compressed
displacement with pure tablegen code in the X86 backend.  This is useful
because both the X86-disassembler-specific part of tablegen and the assembler
need this and TD is the natural sharing place.

The patch also adds the missing documentation for the shift and add operator.

llvm-svn: 213277
2014-07-17 17:04:27 +00:00
Rafael Espindola
858b9e1423 Update the MemoryBuffer API to use ErrorOr.
llvm-svn: 212405
2014-07-06 17:43:13 +00:00
Rafael Espindola
43905716e7 This only needs a StringRef.
llvm-svn: 212402
2014-07-06 14:24:03 +00:00
Alp Toker
0ca11b2493 SourceMgr: make valid buffer IDs start from one
Use 0 for the invalid buffer instead of -1/~0 and switch to unsigned
representation to enable more idiomatic usage.

Also introduce a trivial SourceMgr::getMainFileID() instead of hard-coding 0/1
to identify the main file.

llvm-svn: 212398
2014-07-06 10:33:31 +00:00
Alp Toker
97022b0c1f Revert "Introduce a string_ostream string builder facilty"
Temporarily back out commits r211749, r211752 and r211754.

llvm-svn: 211814
2014-06-26 22:52:05 +00:00
Alp Toker
fd9ead3b6f Introduce a string_ostream string builder facilty
string_ostream is a safe and efficient string builder that combines opaque
stack storage with a built-in ostream interface.

small_string_ostream<bytes> additionally permits an explicit stack storage size
other than the default 128 bytes to be provided. Beyond that, storage is
transferred to the heap.

This convenient class can be used in most places an
std::string+raw_string_ostream pair or SmallString<>+raw_svector_ostream pair
would previously have been used, in order to guarantee consistent access
without byte truncation.

The patch also converts much of LLVM to use the new facility. These changes
include several probable bug fixes for truncated output, a programming error
that's no longer possible with the new interface.

llvm-svn: 211749
2014-06-26 00:00:48 +00:00
Craig Topper
c20830d1c1 Convert some assert(0) to llvm_unreachable or fold an 'if' condition into the assert.
llvm-svn: 211254
2014-06-19 06:10:58 +00:00
James Molloy
ed6ddd8719 Move SetTheory from utils/TableGen into lib/TableGen so Clang can use it.
llvm-svn: 211100
2014-06-17 13:10:38 +00:00
Rafael Espindola
98710599c1 Remove 'using std::errro_code' from lib.
llvm-svn: 210871
2014-06-13 02:24:39 +00:00
Rafael Espindola
e0e308ff6d Don't use 'using std::error_code' in include/llvm.
This should make sure that most new uses use the std prefix.

llvm-svn: 210835
2014-06-12 21:46:39 +00:00
Rafael Espindola
38dc624425 Remove system_error.h.
This is a minimal change to remove the header. I will remove the occurrences
of "using std::error_code" in a followup patch.

llvm-svn: 210803
2014-06-12 17:38:55 +00:00
Matt Arsenault
a3dd1c8170 Fix error in tablegen when either operand of !if is an empty list.
!if([Something], []) would error with "No type for list".

llvm-svn: 210572
2014-06-10 20:10:08 +00:00