1 #ifndef CATA_TOOLS_CLANG_TIDY_PLUGIN_STRINGLITERALITERATOR_H
2 #define CATA_TOOLS_CLANG_TIDY_PLUGIN_STRINGLITERALITERATOR_H
3 
4 #include <clang/Basic/SourceLocation.h>
5 #include <clang/Basic/TargetInfo.h>
6 #include <cstddef>
7 #include <cstdint>
8 #include <functional>
9 #include <iterator>
10 
11 namespace clang
12 {
13 class LangOptions;
14 class SourceManager;
15 class StringLiteral;
16 
17 namespace tidy
18 {
19 namespace cata
20 {
21 
22 // Currently only supports utf8 becasue StringLiteral only has full support
23 // for single-byte ascii/utf8 strings
24 class StringLiteralIterator
25 {
26     public:
27         // This assumes that ind points to the start of a valid utf8 sequence
28         StringLiteralIterator( const StringLiteral &str, size_t ind );
29 
30         // Get the source location corresponding to the character pointed to
31         // by the iterator.
32         // Do note that clang crashes when the string literal is a predefined
33         // expression such as __func__, so you may want to exclude them using
34         // the matcher `unless( hasAncestor( predefinedExpr() ) )` or something
35         // to that effect.
36         SourceLocation toSourceLocation( const SourceManager &SrcMgr, const LangOptions &LangOpts,
37                                          const TargetInfo &Info ) const;
38 
39         // All following operators assume that StringLiteral contains a valid
40         // utf8 string
41         uint32_t operator*() const;
42 
43         bool operator<( const StringLiteralIterator &rhs ) const;
44         bool operator>( const StringLiteralIterator &rhs ) const;
45         bool operator<=( const StringLiteralIterator &rhs ) const;
46         bool operator>=( const StringLiteralIterator &rhs ) const;
47         bool operator==( const StringLiteralIterator &rhs ) const;
48         bool operator!=( const StringLiteralIterator &rhs ) const;
49 
50         StringLiteralIterator &operator+=( ptrdiff_t inc );
51         StringLiteralIterator &operator-=( ptrdiff_t dec );
52         StringLiteralIterator operator+( ptrdiff_t inc ) const;
53         StringLiteralIterator operator-( ptrdiff_t dec ) const;
54         StringLiteralIterator &operator++();
55         StringLiteralIterator operator++( int );
56         StringLiteralIterator &operator--();
57         StringLiteralIterator operator--( int );
58 
59         static StringLiteralIterator begin( const StringLiteral &str );
60         static StringLiteralIterator end( const StringLiteral &str );
61 
62         static ptrdiff_t distance( const StringLiteralIterator &beg,
63                                    const StringLiteralIterator &end );
64 
65     private:
66         std::reference_wrapper<const StringLiteral> str;
67         size_t ind;
68 };
69 
70 } // namespace cata
71 } // namespace tidy
72 } // namespace clang
73 
74 namespace std
75 {
76 template<>
77 struct iterator_traits<clang::tidy::cata::StringLiteralIterator> {
78     using difference_type = ptrdiff_t;
79     using value_type = uint32_t;
80     using pointer = const uint32_t *;
81     using reference = const uint32_t &;
82     // randome_access_iterator_tag requires constant increment/decrement time,
83     // which StringLiteralIterator doesn't satisfy.
84     using iterator_category = bidirectional_iterator_tag;
85 };
86 } // namespace std
87 
88 #endif // CATA_TOOLS_CLANG_TIDY_PLUGIN_STRINGLITERALITERATOR_H
89