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