Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:36:46

0001 //===--- Diagnostics.h - Helper class for error diagnostics -----*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 ///
0009 /// \file
0010 /// Diagnostics class to manage error messages.
0011 ///
0012 //===----------------------------------------------------------------------===//
0013 
0014 #ifndef LLVM_CLANG_ASTMATCHERS_DYNAMIC_DIAGNOSTICS_H
0015 #define LLVM_CLANG_ASTMATCHERS_DYNAMIC_DIAGNOSTICS_H
0016 
0017 #include "clang/ASTMatchers/Dynamic/VariantValue.h"
0018 #include "clang/Basic/LLVM.h"
0019 #include "llvm/ADT/ArrayRef.h"
0020 #include "llvm/ADT/StringRef.h"
0021 #include "llvm/ADT/Twine.h"
0022 #include "llvm/Support/raw_ostream.h"
0023 #include <string>
0024 #include <vector>
0025 
0026 namespace clang {
0027 namespace ast_matchers {
0028 namespace dynamic {
0029 
0030 struct SourceLocation {
0031   SourceLocation() = default;
0032   unsigned Line = 0;
0033   unsigned Column = 0;
0034 };
0035 
0036 struct SourceRange {
0037   SourceLocation Start;
0038   SourceLocation End;
0039 };
0040 
0041 /// A VariantValue instance annotated with its parser context.
0042 struct ParserValue {
0043   ParserValue() {}
0044   StringRef Text;
0045   SourceRange Range;
0046   VariantValue Value;
0047 };
0048 
0049 /// Helper class to manage error messages.
0050 class Diagnostics {
0051 public:
0052   /// Parser context types.
0053   enum ContextType {
0054     CT_MatcherArg = 0,
0055     CT_MatcherConstruct = 1
0056   };
0057 
0058   /// All errors from the system.
0059   enum ErrorType {
0060     ET_None = 0,
0061 
0062     ET_RegistryMatcherNotFound = 1,
0063     ET_RegistryWrongArgCount = 2,
0064     ET_RegistryWrongArgType = 3,
0065     ET_RegistryNotBindable = 4,
0066     ET_RegistryAmbiguousOverload = 5,
0067     ET_RegistryValueNotFound = 6,
0068     ET_RegistryUnknownEnumWithReplace = 7,
0069     ET_RegistryNonNodeMatcher = 8,
0070     ET_RegistryMatcherNoWithSupport = 9,
0071 
0072     ET_ParserStringError = 100,
0073     ET_ParserNoOpenParen = 101,
0074     ET_ParserNoCloseParen = 102,
0075     ET_ParserNoComma = 103,
0076     ET_ParserNoCode = 104,
0077     ET_ParserNotAMatcher = 105,
0078     ET_ParserInvalidToken = 106,
0079     ET_ParserMalformedBindExpr = 107,
0080     ET_ParserTrailingCode = 108,
0081     ET_ParserNumberError = 109,
0082     ET_ParserOverloadedType = 110,
0083     ET_ParserMalformedChainedExpr = 111,
0084     ET_ParserFailedToBuildMatcher = 112
0085   };
0086 
0087   /// Helper stream class.
0088   class ArgStream {
0089   public:
0090     ArgStream(std::vector<std::string> *Out) : Out(Out) {}
0091     template <class T> ArgStream &operator<<(const T &Arg) {
0092       return operator<<(Twine(Arg));
0093     }
0094     ArgStream &operator<<(const Twine &Arg);
0095 
0096   private:
0097     std::vector<std::string> *Out;
0098   };
0099 
0100   /// Class defining a parser context.
0101   ///
0102   /// Used by the parser to specify (possibly recursive) contexts where the
0103   /// parsing/construction can fail. Any error triggered within a context will
0104   /// keep information about the context chain.
0105   /// This class should be used as a RAII instance in the stack.
0106   struct Context {
0107   public:
0108     /// About to call the constructor for a matcher.
0109     enum ConstructMatcherEnum { ConstructMatcher };
0110     Context(ConstructMatcherEnum, Diagnostics *Error, StringRef MatcherName,
0111             SourceRange MatcherRange);
0112     /// About to recurse into parsing one argument for a matcher.
0113     enum MatcherArgEnum { MatcherArg };
0114     Context(MatcherArgEnum, Diagnostics *Error, StringRef MatcherName,
0115             SourceRange MatcherRange, unsigned ArgNumber);
0116     ~Context();
0117 
0118   private:
0119     Diagnostics *const Error;
0120   };
0121 
0122   /// Context for overloaded matcher construction.
0123   ///
0124   /// This context will take care of merging all errors that happen within it
0125   /// as "candidate" overloads for the same matcher.
0126   struct OverloadContext {
0127   public:
0128    OverloadContext(Diagnostics* Error);
0129    ~OverloadContext();
0130 
0131    /// Revert all errors that happened within this context.
0132    void revertErrors();
0133 
0134   private:
0135     Diagnostics *const Error;
0136     unsigned BeginIndex;
0137   };
0138 
0139   /// Add an error to the diagnostics.
0140   ///
0141   /// All the context information will be kept on the error message.
0142   /// \return a helper class to allow the caller to pass the arguments for the
0143   /// error message, using the << operator.
0144   ArgStream addError(SourceRange Range, ErrorType Error);
0145 
0146   /// Information stored for one frame of the context.
0147   struct ContextFrame {
0148     ContextType Type;
0149     SourceRange Range;
0150     std::vector<std::string> Args;
0151   };
0152 
0153   /// Information stored for each error found.
0154   struct ErrorContent {
0155     std::vector<ContextFrame> ContextStack;
0156     struct Message {
0157       SourceRange Range;
0158       ErrorType Type;
0159       std::vector<std::string> Args;
0160     };
0161     std::vector<Message> Messages;
0162   };
0163   ArrayRef<ErrorContent> errors() const { return Errors; }
0164 
0165   /// Returns a simple string representation of each error.
0166   ///
0167   /// Each error only shows the error message without any context.
0168   void printToStream(llvm::raw_ostream &OS) const;
0169   std::string toString() const;
0170 
0171   /// Returns the full string representation of each error.
0172   ///
0173   /// Each error message contains the full context.
0174   void printToStreamFull(llvm::raw_ostream &OS) const;
0175   std::string toStringFull() const;
0176 
0177 private:
0178   /// Helper function used by the constructors of ContextFrame.
0179   ArgStream pushContextFrame(ContextType Type, SourceRange Range);
0180 
0181   std::vector<ContextFrame> ContextStack;
0182   std::vector<ErrorContent> Errors;
0183 };
0184 
0185 }  // namespace dynamic
0186 }  // namespace ast_matchers
0187 }  // namespace clang
0188 
0189 #endif // LLVM_CLANG_ASTMATCHERS_DYNAMIC_DIAGNOSTICS_H