clang API Documentation
00001 //===--- Diagnostics.h - Helper class for error diagnostics -----*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 /// 00010 /// \file 00011 /// \brief Diagnostics class to manage error messages. 00012 /// 00013 //===----------------------------------------------------------------------===// 00014 00015 #ifndef LLVM_CLANG_ASTMATCHERS_DYNAMIC_DIAGNOSTICS_H 00016 #define LLVM_CLANG_ASTMATCHERS_DYNAMIC_DIAGNOSTICS_H 00017 00018 #include "clang/ASTMatchers/Dynamic/VariantValue.h" 00019 #include "clang/Basic/LLVM.h" 00020 #include "llvm/ADT/ArrayRef.h" 00021 #include "llvm/ADT/StringRef.h" 00022 #include "llvm/ADT/Twine.h" 00023 #include "llvm/Support/raw_ostream.h" 00024 #include <string> 00025 #include <vector> 00026 00027 namespace clang { 00028 namespace ast_matchers { 00029 namespace dynamic { 00030 00031 struct SourceLocation { 00032 SourceLocation() : Line(), Column() {} 00033 unsigned Line; 00034 unsigned Column; 00035 }; 00036 00037 struct SourceRange { 00038 SourceLocation Start; 00039 SourceLocation End; 00040 }; 00041 00042 /// \brief A VariantValue instance annotated with its parser context. 00043 struct ParserValue { 00044 ParserValue() : Text(), Range(), Value() {} 00045 StringRef Text; 00046 SourceRange Range; 00047 VariantValue Value; 00048 }; 00049 00050 /// \brief Helper class to manage error messages. 00051 class Diagnostics { 00052 public: 00053 /// \brief Parser context types. 00054 enum ContextType { 00055 CT_MatcherArg = 0, 00056 CT_MatcherConstruct = 1 00057 }; 00058 00059 /// \brief All errors from the system. 00060 enum ErrorType { 00061 ET_None = 0, 00062 00063 ET_RegistryMatcherNotFound = 1, 00064 ET_RegistryWrongArgCount = 2, 00065 ET_RegistryWrongArgType = 3, 00066 ET_RegistryNotBindable = 4, 00067 ET_RegistryAmbiguousOverload = 5, 00068 ET_RegistryValueNotFound = 6, 00069 00070 ET_ParserStringError = 100, 00071 ET_ParserNoOpenParen = 101, 00072 ET_ParserNoCloseParen = 102, 00073 ET_ParserNoComma = 103, 00074 ET_ParserNoCode = 104, 00075 ET_ParserNotAMatcher = 105, 00076 ET_ParserInvalidToken = 106, 00077 ET_ParserMalformedBindExpr = 107, 00078 ET_ParserTrailingCode = 108, 00079 ET_ParserUnsignedError = 109, 00080 ET_ParserOverloadedType = 110 00081 }; 00082 00083 /// \brief Helper stream class. 00084 class ArgStream { 00085 public: 00086 ArgStream(std::vector<std::string> *Out) : Out(Out) {} 00087 template <class T> ArgStream &operator<<(const T &Arg) { 00088 return operator<<(Twine(Arg)); 00089 } 00090 ArgStream &operator<<(const Twine &Arg); 00091 00092 private: 00093 std::vector<std::string> *Out; 00094 }; 00095 00096 /// \brief Class defining a parser context. 00097 /// 00098 /// Used by the parser to specify (possibly recursive) contexts where the 00099 /// parsing/construction can fail. Any error triggered within a context will 00100 /// keep information about the context chain. 00101 /// This class should be used as a RAII instance in the stack. 00102 struct Context { 00103 public: 00104 /// \brief About to call the constructor for a matcher. 00105 enum ConstructMatcherEnum { ConstructMatcher }; 00106 Context(ConstructMatcherEnum, Diagnostics *Error, StringRef MatcherName, 00107 const SourceRange &MatcherRange); 00108 /// \brief About to recurse into parsing one argument for a matcher. 00109 enum MatcherArgEnum { MatcherArg }; 00110 Context(MatcherArgEnum, Diagnostics *Error, StringRef MatcherName, 00111 const SourceRange &MatcherRange, unsigned ArgNumber); 00112 ~Context(); 00113 00114 private: 00115 Diagnostics *const Error; 00116 }; 00117 00118 /// \brief Context for overloaded matcher construction. 00119 /// 00120 /// This context will take care of merging all errors that happen within it 00121 /// as "candidate" overloads for the same matcher. 00122 struct OverloadContext { 00123 public: 00124 OverloadContext(Diagnostics* Error); 00125 ~OverloadContext(); 00126 00127 /// \brief Revert all errors that happened within this context. 00128 void revertErrors(); 00129 00130 private: 00131 Diagnostics *const Error; 00132 unsigned BeginIndex; 00133 }; 00134 00135 /// \brief Add an error to the diagnostics. 00136 /// 00137 /// All the context information will be kept on the error message. 00138 /// \return a helper class to allow the caller to pass the arguments for the 00139 /// error message, using the << operator. 00140 ArgStream addError(const SourceRange &Range, ErrorType Error); 00141 00142 /// \brief Information stored for one frame of the context. 00143 struct ContextFrame { 00144 ContextType Type; 00145 SourceRange Range; 00146 std::vector<std::string> Args; 00147 }; 00148 00149 /// \brief Information stored for each error found. 00150 struct ErrorContent { 00151 std::vector<ContextFrame> ContextStack; 00152 struct Message { 00153 SourceRange Range; 00154 ErrorType Type; 00155 std::vector<std::string> Args; 00156 }; 00157 std::vector<Message> Messages; 00158 }; 00159 ArrayRef<ErrorContent> errors() const { return Errors; } 00160 00161 /// \brief Returns a simple string representation of each error. 00162 /// 00163 /// Each error only shows the error message without any context. 00164 void printToStream(llvm::raw_ostream &OS) const; 00165 std::string toString() const; 00166 00167 /// \brief Returns the full string representation of each error. 00168 /// 00169 /// Each error message contains the full context. 00170 void printToStreamFull(llvm::raw_ostream &OS) const; 00171 std::string toStringFull() const; 00172 00173 private: 00174 /// \brief Helper function used by the constructors of ContextFrame. 00175 ArgStream pushContextFrame(ContextType Type, SourceRange Range); 00176 00177 std::vector<ContextFrame> ContextStack; 00178 std::vector<ErrorContent> Errors; 00179 }; 00180 00181 } // namespace dynamic 00182 } // namespace ast_matchers 00183 } // namespace clang 00184 00185 #endif // LLVM_CLANG_AST_MATCHERS_DYNAMIC_DIAGNOSTICS_H