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