File indexing completed on 2026-05-10 08:36:56
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef LLVM_CLANG_FRONTEND_VERIFYDIAGNOSTICCONSUMER_H
0010 #define LLVM_CLANG_FRONTEND_VERIFYDIAGNOSTICCONSUMER_H
0011
0012 #include "clang/Basic/Diagnostic.h"
0013 #include "clang/Basic/FileManager.h"
0014 #include "clang/Basic/LLVM.h"
0015 #include "clang/Basic/SourceLocation.h"
0016 #include "clang/Lex/Preprocessor.h"
0017 #include "llvm/ADT/DenseMap.h"
0018 #include "llvm/ADT/PointerIntPair.h"
0019 #include "llvm/ADT/StringRef.h"
0020 #include <cassert>
0021 #include <limits>
0022 #include <memory>
0023 #include <string>
0024 #include <vector>
0025
0026 namespace clang {
0027
0028 class FileEntry;
0029 class LangOptions;
0030 class SourceManager;
0031 class TextDiagnosticBuffer;
0032
0033
0034
0035
0036
0037
0038 class VerifyDiagnosticConsumer: public DiagnosticConsumer,
0039 public CommentHandler {
0040 public:
0041
0042
0043 class Directive {
0044 public:
0045 static std::unique_ptr<Directive>
0046 create(bool RegexKind, SourceLocation DirectiveLoc,
0047 SourceLocation DiagnosticLoc, bool MatchAnyFileAndLine,
0048 bool MatchAnyLine, StringRef Text, unsigned Min, unsigned Max);
0049
0050 public:
0051
0052 static const unsigned MaxCount = std::numeric_limits<unsigned>::max();
0053
0054 SourceLocation DirectiveLoc;
0055 SourceLocation DiagnosticLoc;
0056 const std::string Text;
0057 unsigned Min, Max;
0058 bool MatchAnyLine;
0059 bool MatchAnyFileAndLine;
0060
0061 Directive(const Directive &) = delete;
0062 Directive &operator=(const Directive &) = delete;
0063 virtual ~Directive() = default;
0064
0065
0066
0067 virtual bool isValid(std::string &Error) = 0;
0068
0069
0070 virtual bool match(StringRef S) = 0;
0071
0072 protected:
0073 Directive(SourceLocation DirectiveLoc, SourceLocation DiagnosticLoc,
0074 bool MatchAnyFileAndLine, bool MatchAnyLine, StringRef Text,
0075 unsigned Min, unsigned Max)
0076 : DirectiveLoc(DirectiveLoc), DiagnosticLoc(DiagnosticLoc), Text(Text),
0077 Min(Min), Max(Max), MatchAnyLine(MatchAnyLine || MatchAnyFileAndLine),
0078 MatchAnyFileAndLine(MatchAnyFileAndLine) {
0079 assert(!DirectiveLoc.isInvalid() && "DirectiveLoc is invalid!");
0080 assert((!DiagnosticLoc.isInvalid() || MatchAnyLine) &&
0081 "DiagnosticLoc is invalid!");
0082 }
0083 };
0084
0085 using DirectiveList = std::vector<std::unique_ptr<Directive>>;
0086
0087
0088 struct ExpectedData {
0089 DirectiveList Errors;
0090 DirectiveList Warnings;
0091 DirectiveList Remarks;
0092 DirectiveList Notes;
0093
0094 void Reset() {
0095 Errors.clear();
0096 Warnings.clear();
0097 Remarks.clear();
0098 Notes.clear();
0099 }
0100 };
0101
0102 enum DirectiveStatus {
0103 HasNoDirectives,
0104 HasNoDirectivesReported,
0105 HasExpectedNoDiagnostics,
0106 HasOtherExpectedDirectives
0107 };
0108
0109 class MarkerTracker;
0110
0111 private:
0112 DiagnosticsEngine &Diags;
0113 DiagnosticConsumer *PrimaryClient;
0114 std::unique_ptr<DiagnosticConsumer> PrimaryClientOwner;
0115 std::unique_ptr<TextDiagnosticBuffer> Buffer;
0116 std::unique_ptr<MarkerTracker> Markers;
0117 const Preprocessor *CurrentPreprocessor = nullptr;
0118 const LangOptions *LangOpts = nullptr;
0119 SourceManager *SrcManager = nullptr;
0120 unsigned ActiveSourceFiles = 0;
0121 DirectiveStatus Status;
0122 ExpectedData ED;
0123
0124 void CheckDiagnostics();
0125
0126 void setSourceManager(SourceManager &SM) {
0127 assert((!SrcManager || SrcManager == &SM) && "SourceManager changed!");
0128 SrcManager = &SM;
0129 }
0130
0131
0132 class UnparsedFileStatus {
0133 OptionalFileEntryRef File;
0134 bool FoundDirectives;
0135
0136 public:
0137 UnparsedFileStatus(OptionalFileEntryRef File, bool FoundDirectives)
0138 : File(File), FoundDirectives(FoundDirectives) {}
0139
0140 OptionalFileEntryRef getFile() const { return File; }
0141 bool foundDirectives() const { return FoundDirectives; }
0142 };
0143
0144 using ParsedFilesMap = llvm::DenseMap<FileID, const FileEntry *>;
0145 using UnparsedFilesMap = llvm::DenseMap<FileID, UnparsedFileStatus>;
0146
0147 ParsedFilesMap ParsedFiles;
0148 UnparsedFilesMap UnparsedFiles;
0149
0150 public:
0151
0152
0153
0154 VerifyDiagnosticConsumer(DiagnosticsEngine &Diags);
0155 ~VerifyDiagnosticConsumer() override;
0156
0157 void BeginSourceFile(const LangOptions &LangOpts,
0158 const Preprocessor *PP) override;
0159
0160 void EndSourceFile() override;
0161
0162 enum ParsedStatus {
0163
0164 IsParsed,
0165
0166
0167 IsUnparsed,
0168
0169
0170 IsUnparsedNoDirectives
0171 };
0172
0173
0174 void UpdateParsedFileStatus(SourceManager &SM, FileID FID, ParsedStatus PS);
0175
0176 bool HandleComment(Preprocessor &PP, SourceRange Comment) override;
0177
0178 void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
0179 const Diagnostic &Info) override;
0180 };
0181
0182 }
0183
0184 #endif