1 //===--- SymbolOccurrences.h - Clang refactoring library ------------------===//
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 LLVM_CLANG_TOOLING_REFACTOR_RENAME_SYMBOL_OCCURRENCES_H
10 #define LLVM_CLANG_TOOLING_REFACTOR_RENAME_SYMBOL_OCCURRENCES_H
11 
12 #include "clang/Basic/LLVM.h"
13 #include "clang/Basic/SourceLocation.h"
14 #include "llvm/ADT/ArrayRef.h"
15 #include "llvm/ADT/StringRef.h"
16 #include <vector>
17 
18 namespace clang {
19 namespace tooling {
20 
21 class SymbolName;
22 
23 /// An occurrence of a symbol in the source.
24 ///
25 /// Occurrences can have difference kinds, that describe whether this occurrence
26 /// is an exact semantic match, or whether this is a weaker textual match that's
27 /// not guaranteed to represent the exact declaration.
28 ///
29 /// A single occurrence of a symbol can span more than one source range. For
30 /// example, Objective-C selectors can contain multiple argument labels:
31 ///
32 /// \code
33 /// [object selectorPiece1: ... selectorPiece2: ...];
34 /// //      ^~~ range 0 ~~      ^~~ range 1 ~~
35 /// \endcode
36 ///
37 /// We have to replace the text in both range 0 and range 1 when renaming the
38 /// Objective-C method 'selectorPiece1:selectorPiece2'.
39 class SymbolOccurrence {
40 public:
41   enum OccurrenceKind {
42     /// This occurrence is an exact match and can be renamed automatically.
43     ///
44     /// Note:
45     /// Symbol occurrences in macro arguments that expand to different
46     /// declarations get marked as exact matches, and thus the renaming engine
47     /// will rename them e.g.:
48     ///
49     /// \code
50     ///   #define MACRO(x) x + ns::x
51     ///   int foo(int var) {
52     ///     return MACRO(var); // var is renamed automatically here when
53     ///                        // either var or ns::var is renamed.
54     ///   };
55     /// \endcode
56     ///
57     /// The user will have to fix their code manually after performing such a
58     /// rename.
59     /// FIXME: The rename verifier should notify user about this issue.
60     MatchingSymbol
61   };
62 
63   SymbolOccurrence(const SymbolName &Name, OccurrenceKind Kind,
64                    ArrayRef<SourceLocation> Locations);
65 
66   SymbolOccurrence(SymbolOccurrence &&) = default;
67   SymbolOccurrence &operator=(SymbolOccurrence &&) = default;
68 
69   OccurrenceKind getKind() const { return Kind; }
70 
71   ArrayRef<SourceRange> getNameRanges() const {
72     if (MultipleRanges)
73       return llvm::makeArrayRef(MultipleRanges.get(), NumRanges);
74     return SingleRange;
75   }
76 
77 private:
78   OccurrenceKind Kind;
79   std::unique_ptr<SourceRange[]> MultipleRanges;
80   union {
81     SourceRange SingleRange;
82     unsigned NumRanges;
83   };
84 };
85 
86 using SymbolOccurrences = std::vector<SymbolOccurrence>;
87 
88 } // end namespace tooling
89 } // end namespace clang
90 
91 #endif // LLVM_CLANG_TOOLING_REFACTOR_RENAME_SYMBOL_OCCURRENCES_H
92