xref: /aosp_15_r20/external/clang/include/clang/ASTMatchers/Dynamic/Diagnostics.h (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li //===--- Diagnostics.h - Helper class for error diagnostics -----*- C++ -*-===//
2*67e74705SXin Li //
3*67e74705SXin Li //                     The LLVM Compiler Infrastructure
4*67e74705SXin Li //
5*67e74705SXin Li // This file is distributed under the University of Illinois Open Source
6*67e74705SXin Li // License. See LICENSE.TXT for details.
7*67e74705SXin Li //
8*67e74705SXin Li //===----------------------------------------------------------------------===//
9*67e74705SXin Li ///
10*67e74705SXin Li /// \file
11*67e74705SXin Li /// \brief Diagnostics class to manage error messages.
12*67e74705SXin Li ///
13*67e74705SXin Li //===----------------------------------------------------------------------===//
14*67e74705SXin Li 
15*67e74705SXin Li #ifndef LLVM_CLANG_ASTMATCHERS_DYNAMIC_DIAGNOSTICS_H
16*67e74705SXin Li #define LLVM_CLANG_ASTMATCHERS_DYNAMIC_DIAGNOSTICS_H
17*67e74705SXin Li 
18*67e74705SXin Li #include "clang/ASTMatchers/Dynamic/VariantValue.h"
19*67e74705SXin Li #include "clang/Basic/LLVM.h"
20*67e74705SXin Li #include "llvm/ADT/ArrayRef.h"
21*67e74705SXin Li #include "llvm/ADT/StringRef.h"
22*67e74705SXin Li #include "llvm/ADT/Twine.h"
23*67e74705SXin Li #include "llvm/Support/raw_ostream.h"
24*67e74705SXin Li #include <string>
25*67e74705SXin Li #include <vector>
26*67e74705SXin Li 
27*67e74705SXin Li namespace clang {
28*67e74705SXin Li namespace ast_matchers {
29*67e74705SXin Li namespace dynamic {
30*67e74705SXin Li 
31*67e74705SXin Li struct SourceLocation {
SourceLocationSourceLocation32*67e74705SXin Li   SourceLocation() : Line(), Column() {}
33*67e74705SXin Li   unsigned Line;
34*67e74705SXin Li   unsigned Column;
35*67e74705SXin Li };
36*67e74705SXin Li 
37*67e74705SXin Li struct SourceRange {
38*67e74705SXin Li   SourceLocation Start;
39*67e74705SXin Li   SourceLocation End;
40*67e74705SXin Li };
41*67e74705SXin Li 
42*67e74705SXin Li /// \brief A VariantValue instance annotated with its parser context.
43*67e74705SXin Li struct ParserValue {
ParserValueParserValue44*67e74705SXin Li   ParserValue() : Text(), Range(), Value() {}
45*67e74705SXin Li   StringRef Text;
46*67e74705SXin Li   SourceRange Range;
47*67e74705SXin Li   VariantValue Value;
48*67e74705SXin Li };
49*67e74705SXin Li 
50*67e74705SXin Li /// \brief Helper class to manage error messages.
51*67e74705SXin Li class Diagnostics {
52*67e74705SXin Li public:
53*67e74705SXin Li   /// \brief Parser context types.
54*67e74705SXin Li   enum ContextType {
55*67e74705SXin Li     CT_MatcherArg = 0,
56*67e74705SXin Li     CT_MatcherConstruct = 1
57*67e74705SXin Li   };
58*67e74705SXin Li 
59*67e74705SXin Li   /// \brief All errors from the system.
60*67e74705SXin Li   enum ErrorType {
61*67e74705SXin Li     ET_None = 0,
62*67e74705SXin Li 
63*67e74705SXin Li     ET_RegistryMatcherNotFound = 1,
64*67e74705SXin Li     ET_RegistryWrongArgCount = 2,
65*67e74705SXin Li     ET_RegistryWrongArgType = 3,
66*67e74705SXin Li     ET_RegistryNotBindable = 4,
67*67e74705SXin Li     ET_RegistryAmbiguousOverload = 5,
68*67e74705SXin Li     ET_RegistryValueNotFound = 6,
69*67e74705SXin Li 
70*67e74705SXin Li     ET_ParserStringError = 100,
71*67e74705SXin Li     ET_ParserNoOpenParen = 101,
72*67e74705SXin Li     ET_ParserNoCloseParen = 102,
73*67e74705SXin Li     ET_ParserNoComma = 103,
74*67e74705SXin Li     ET_ParserNoCode = 104,
75*67e74705SXin Li     ET_ParserNotAMatcher = 105,
76*67e74705SXin Li     ET_ParserInvalidToken = 106,
77*67e74705SXin Li     ET_ParserMalformedBindExpr = 107,
78*67e74705SXin Li     ET_ParserTrailingCode = 108,
79*67e74705SXin Li     ET_ParserUnsignedError = 109,
80*67e74705SXin Li     ET_ParserOverloadedType = 110
81*67e74705SXin Li   };
82*67e74705SXin Li 
83*67e74705SXin Li   /// \brief Helper stream class.
84*67e74705SXin Li   class ArgStream {
85*67e74705SXin Li   public:
ArgStream(std::vector<std::string> * Out)86*67e74705SXin Li     ArgStream(std::vector<std::string> *Out) : Out(Out) {}
87*67e74705SXin Li     template <class T> ArgStream &operator<<(const T &Arg) {
88*67e74705SXin Li       return operator<<(Twine(Arg));
89*67e74705SXin Li     }
90*67e74705SXin Li     ArgStream &operator<<(const Twine &Arg);
91*67e74705SXin Li 
92*67e74705SXin Li   private:
93*67e74705SXin Li     std::vector<std::string> *Out;
94*67e74705SXin Li   };
95*67e74705SXin Li 
96*67e74705SXin Li   /// \brief Class defining a parser context.
97*67e74705SXin Li   ///
98*67e74705SXin Li   /// Used by the parser to specify (possibly recursive) contexts where the
99*67e74705SXin Li   /// parsing/construction can fail. Any error triggered within a context will
100*67e74705SXin Li   /// keep information about the context chain.
101*67e74705SXin Li   /// This class should be used as a RAII instance in the stack.
102*67e74705SXin Li   struct Context {
103*67e74705SXin Li   public:
104*67e74705SXin Li     /// \brief About to call the constructor for a matcher.
105*67e74705SXin Li     enum ConstructMatcherEnum { ConstructMatcher };
106*67e74705SXin Li     Context(ConstructMatcherEnum, Diagnostics *Error, StringRef MatcherName,
107*67e74705SXin Li             SourceRange MatcherRange);
108*67e74705SXin Li     /// \brief About to recurse into parsing one argument for a matcher.
109*67e74705SXin Li     enum MatcherArgEnum { MatcherArg };
110*67e74705SXin Li     Context(MatcherArgEnum, Diagnostics *Error, StringRef MatcherName,
111*67e74705SXin Li             SourceRange MatcherRange, unsigned ArgNumber);
112*67e74705SXin Li     ~Context();
113*67e74705SXin Li 
114*67e74705SXin Li   private:
115*67e74705SXin Li     Diagnostics *const Error;
116*67e74705SXin Li   };
117*67e74705SXin Li 
118*67e74705SXin Li   /// \brief Context for overloaded matcher construction.
119*67e74705SXin Li   ///
120*67e74705SXin Li   /// This context will take care of merging all errors that happen within it
121*67e74705SXin Li   /// as "candidate" overloads for the same matcher.
122*67e74705SXin Li   struct OverloadContext {
123*67e74705SXin Li   public:
124*67e74705SXin Li    OverloadContext(Diagnostics* Error);
125*67e74705SXin Li    ~OverloadContext();
126*67e74705SXin Li 
127*67e74705SXin Li    /// \brief Revert all errors that happened within this context.
128*67e74705SXin Li    void revertErrors();
129*67e74705SXin Li 
130*67e74705SXin Li   private:
131*67e74705SXin Li     Diagnostics *const Error;
132*67e74705SXin Li     unsigned BeginIndex;
133*67e74705SXin Li   };
134*67e74705SXin Li 
135*67e74705SXin Li   /// \brief Add an error to the diagnostics.
136*67e74705SXin Li   ///
137*67e74705SXin Li   /// All the context information will be kept on the error message.
138*67e74705SXin Li   /// \return a helper class to allow the caller to pass the arguments for the
139*67e74705SXin Li   /// error message, using the << operator.
140*67e74705SXin Li   ArgStream addError(SourceRange Range, ErrorType Error);
141*67e74705SXin Li 
142*67e74705SXin Li   /// \brief Information stored for one frame of the context.
143*67e74705SXin Li   struct ContextFrame {
144*67e74705SXin Li     ContextType Type;
145*67e74705SXin Li     SourceRange Range;
146*67e74705SXin Li     std::vector<std::string> Args;
147*67e74705SXin Li   };
148*67e74705SXin Li 
149*67e74705SXin Li   /// \brief Information stored for each error found.
150*67e74705SXin Li   struct ErrorContent {
151*67e74705SXin Li     std::vector<ContextFrame> ContextStack;
152*67e74705SXin Li     struct Message {
153*67e74705SXin Li       SourceRange Range;
154*67e74705SXin Li       ErrorType Type;
155*67e74705SXin Li       std::vector<std::string> Args;
156*67e74705SXin Li     };
157*67e74705SXin Li     std::vector<Message> Messages;
158*67e74705SXin Li   };
errors()159*67e74705SXin Li   ArrayRef<ErrorContent> errors() const { return Errors; }
160*67e74705SXin Li 
161*67e74705SXin Li   /// \brief Returns a simple string representation of each error.
162*67e74705SXin Li   ///
163*67e74705SXin Li   /// Each error only shows the error message without any context.
164*67e74705SXin Li   void printToStream(llvm::raw_ostream &OS) const;
165*67e74705SXin Li   std::string toString() const;
166*67e74705SXin Li 
167*67e74705SXin Li   /// \brief Returns the full string representation of each error.
168*67e74705SXin Li   ///
169*67e74705SXin Li   /// Each error message contains the full context.
170*67e74705SXin Li   void printToStreamFull(llvm::raw_ostream &OS) const;
171*67e74705SXin Li   std::string toStringFull() const;
172*67e74705SXin Li 
173*67e74705SXin Li private:
174*67e74705SXin Li   /// \brief Helper function used by the constructors of ContextFrame.
175*67e74705SXin Li   ArgStream pushContextFrame(ContextType Type, SourceRange Range);
176*67e74705SXin Li 
177*67e74705SXin Li   std::vector<ContextFrame> ContextStack;
178*67e74705SXin Li   std::vector<ErrorContent> Errors;
179*67e74705SXin Li };
180*67e74705SXin Li 
181*67e74705SXin Li }  // namespace dynamic
182*67e74705SXin Li }  // namespace ast_matchers
183*67e74705SXin Li }  // namespace clang
184*67e74705SXin Li 
185*67e74705SXin Li #endif  // LLVM_CLANG_AST_MATCHERS_DYNAMIC_DIAGNOSTICS_H
186