Coverage Report

Created: 2020-02-25 14:32

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