16
16
17
17
#include " clang/AST/Decl.h"
18
18
#include " clang/AST/Stmt.h"
19
+ #include " llvm/Support/Debug.h"
19
20
20
21
namespace clang {
21
22
22
- using DefMapTy = llvm::DenseMap<const VarDecl *, std::vector<const VarDecl *>>;
23
+ using VarGrpTy = std::vector<const VarDecl *>;
24
+ using VarGrpRef = ArrayRef<const VarDecl *>;
25
+
26
+ class VariableGroupsManager {
27
+ public:
28
+ VariableGroupsManager () = default ;
29
+ virtual ~VariableGroupsManager () = default ;
30
+ // / Returns the set of variables (including `Var`) that need to be fixed
31
+ // / together in one step.
32
+ // /
33
+ // / `Var` must be a variable that needs fix (so it must be in a group).
34
+ // / `HasParm` is an optional argument that will be set to true if the set of
35
+ // / variables, where `Var` is in, contains parameters.
36
+ virtual VarGrpRef getGroupOfVar (const VarDecl *Var,
37
+ bool *HasParm = nullptr ) const = 0;
38
+
39
+ // / Returns the non-empty group of variables that include parameters of the
40
+ // / analyzing function, if such a group exists. An empty group, otherwise.
41
+ virtual VarGrpRef getGroupOfParms () const = 0;
42
+ };
23
43
24
44
// / The interface that lets the caller handle unsafe buffer usage analysis
25
45
// / results by overriding this class's handle... methods.
26
46
class UnsafeBufferUsageHandler {
47
+ #ifndef NDEBUG
48
+ public:
49
+ // A self-debugging facility that you can use to notify the user when
50
+ // suggestions or fixits are incomplete.
51
+ // Uses std::function to avoid computing the message when it won't
52
+ // actually be displayed.
53
+ using DebugNote = std::pair<SourceLocation, std::string>;
54
+ using DebugNoteList = std::vector<DebugNote>;
55
+ using DebugNoteByVar = std::map<const VarDecl *, DebugNoteList>;
56
+ DebugNoteByVar DebugNotesByVar;
57
+ #endif
58
+
27
59
public:
28
60
UnsafeBufferUsageHandler () = default ;
29
61
virtual ~UnsafeBufferUsageHandler () = default ;
@@ -37,12 +69,35 @@ class UnsafeBufferUsageHandler {
37
69
bool IsRelatedToDecl) = 0;
38
70
39
71
// / Invoked when a fix is suggested against a variable. This function groups
40
- // / all variables that must be fixed together (i.e their types must be changed to the
41
- // / same target type to prevent type mismatches) into a single fixit.
72
+ // / all variables that must be fixed together (i.e their types must be changed
73
+ // / to the same target type to prevent type mismatches) into a single fixit.
74
+ // /
75
+ // / `D` is the declaration of the callable under analysis that owns `Variable`
76
+ // / and all of its group mates.
42
77
virtual void handleUnsafeVariableGroup (const VarDecl *Variable,
43
- const DefMapTy &VarGrpMap ,
44
- FixItList &&Fixes) = 0;
78
+ const VariableGroupsManager &VarGrpMgr ,
79
+ FixItList &&Fixes, const Decl *D ) = 0;
45
80
81
+ #ifndef NDEBUG
82
+ public:
83
+ bool areDebugNotesRequested () {
84
+ DEBUG_WITH_TYPE (" SafeBuffers" , return true );
85
+ return false ;
86
+ }
87
+
88
+ void addDebugNoteForVar (const VarDecl *VD, SourceLocation Loc,
89
+ std::string Text) {
90
+ if (areDebugNotesRequested ())
91
+ DebugNotesByVar[VD].push_back (std::make_pair (Loc, Text));
92
+ }
93
+
94
+ void clearDebugNotes () {
95
+ if (areDebugNotesRequested ())
96
+ DebugNotesByVar.clear ();
97
+ }
98
+ #endif
99
+
100
+ public:
46
101
// / Returns a reference to the `Preprocessor`:
47
102
virtual bool isSafeBufferOptOut (const SourceLocation &Loc) const = 0;
48
103
0 commit comments