Skip to content

Commit 34e1ed1

Browse files
committed
[clang-doc] Use DiagnosticsEngine to handle diagnostic output
Right now we use a combination of outs() and errs() to handle tool output. Instead, we can use existing diagnostic support in clang and LLVM to ensure our tool has a consistent behavior with other tools.
1 parent 9324dae commit 34e1ed1

22 files changed

+344
-220
lines changed

clang-tools-extra/clang-doc/BitcodeReader.cpp

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,16 @@
88

99
#include "BitcodeReader.h"
1010
#include "llvm/Support/Error.h"
11+
#include "llvm/Support/ErrorHandling.h"
1112
#include "llvm/Support/TimeProfiler.h"
1213
#include "llvm/Support/raw_ostream.h"
1314
#include <optional>
1415

1516
namespace clang {
1617
namespace doc {
1718

19+
static llvm::ExitOnError ExitOnErr("clang-doc error: ");
20+
1821
using Record = llvm::SmallVector<uint64_t, 1024>;
1922

2023
// This implements decode for SmallString.
@@ -716,8 +719,8 @@ llvm::Error addReference(FriendInfo *Friend, Reference &&R, FieldId F) {
716719

717720
template <typename T, typename ChildInfoType>
718721
static void addChild(T I, ChildInfoType &&R) {
719-
llvm::errs() << "invalid child type for info";
720-
exit(1);
722+
ExitOnErr(llvm::createStringError(llvm::inconvertibleErrorCode(),
723+
"invalid child type for info"));
721724
}
722725

723726
// Namespace children:
@@ -766,8 +769,9 @@ template <> void addChild(BaseRecordInfo *I, FunctionInfo &&R) {
766769
// parameters) or TemplateSpecializationInfo (for the specialization's
767770
// parameters).
768771
template <typename T> static void addTemplateParam(T I, TemplateParamInfo &&P) {
769-
llvm::errs() << "invalid container for template parameter";
770-
exit(1);
772+
ExitOnErr(
773+
llvm::createStringError(llvm::inconvertibleErrorCode(),
774+
"invalid container for template parameter"));
771775
}
772776
template <> void addTemplateParam(TemplateInfo *I, TemplateParamInfo &&P) {
773777
I->Params.emplace_back(std::move(P));
@@ -779,8 +783,8 @@ void addTemplateParam(TemplateSpecializationInfo *I, TemplateParamInfo &&P) {
779783

780784
// Template info. These apply to either records or functions.
781785
template <typename T> static void addTemplate(T I, TemplateInfo &&P) {
782-
llvm::errs() << "invalid container for template info";
783-
exit(1);
786+
ExitOnErr(llvm::createStringError(llvm::inconvertibleErrorCode(),
787+
"invalid container for template info"));
784788
}
785789
template <> void addTemplate(RecordInfo *I, TemplateInfo &&P) {
786790
I->Template.emplace(std::move(P));
@@ -798,8 +802,9 @@ template <> void addTemplate(FriendInfo *I, TemplateInfo &&P) {
798802
// Template specializations go only into template records.
799803
template <typename T>
800804
static void addTemplateSpecialization(T I, TemplateSpecializationInfo &&TSI) {
801-
llvm::errs() << "invalid container for template specialization info";
802-
exit(1);
805+
ExitOnErr(llvm::createStringError(
806+
llvm::inconvertibleErrorCode(),
807+
"invalid container for template specialization info"));
803808
}
804809
template <>
805810
void addTemplateSpecialization(TemplateInfo *I,
@@ -808,8 +813,8 @@ void addTemplateSpecialization(TemplateInfo *I,
808813
}
809814

810815
template <typename T> static void addConstraint(T I, ConstraintInfo &&C) {
811-
llvm::errs() << "invalid container for constraint info";
812-
exit(1);
816+
ExitOnErr(llvm::createStringError(llvm::inconvertibleErrorCode(),
817+
"invalid container for constraint info"));
813818
}
814819
template <> void addConstraint(TemplateInfo *I, ConstraintInfo &&C) {
815820
I->Constraints.emplace_back(std::move(C));

clang-tools-extra/clang-doc/BitcodeReader.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ namespace doc {
2727
// Class to read bitstream into an InfoSet collection
2828
class ClangDocBitcodeReader {
2929
public:
30-
ClangDocBitcodeReader(llvm::BitstreamCursor &Stream) : Stream(Stream) {}
30+
ClangDocBitcodeReader(llvm::BitstreamCursor &Stream, DiagnosticsEngine &Diags)
31+
: Stream(Stream), Diags(Diags) {}
3132

3233
// Main entry point, calls readBlock to read each block in the given stream.
3334
llvm::Expected<std::vector<std::unique_ptr<Info>>> readBitcode();
@@ -72,6 +73,7 @@ class ClangDocBitcodeReader {
7273
llvm::BitstreamCursor &Stream;
7374
std::optional<llvm::BitstreamBlockInfo> BlockInfo;
7475
FieldId CurrentReferenceField;
76+
DiagnosticsEngine &Diags;
7577
};
7678

7779
} // namespace doc

clang-tools-extra/clang-doc/BitcodeWriter.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -769,7 +769,9 @@ bool ClangDocBitcodeWriter::dispatchInfoForWrite(Info *I) {
769769
emitBlock(*static_cast<FriendInfo *>(I));
770770
break;
771771
case InfoType::IT_default:
772-
llvm::errs() << "Unexpected info, unable to write.\n";
772+
unsigned ID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
773+
"Unexpected info, unable to write.");
774+
Diags.Report(ID);
773775
return true;
774776
}
775777
return false;

clang-tools-extra/clang-doc/BitcodeWriter.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_DOC_BITCODEWRITER_H
1717

1818
#include "Representation.h"
19+
#include "clang/Basic/Diagnostic.h"
1920
#include "llvm/ADT/DenseMap.h"
2021
#include "llvm/Bitstream/BitstreamWriter.h"
2122
#include <vector>
@@ -175,7 +176,8 @@ enum class FieldId {
175176

176177
class ClangDocBitcodeWriter {
177178
public:
178-
ClangDocBitcodeWriter(llvm::BitstreamWriter &Stream) : Stream(Stream) {
179+
ClangDocBitcodeWriter(llvm::BitstreamWriter &Stream, DiagnosticsEngine &Diags)
180+
: Stream(Stream), Diags(Diags) {
179181
emitHeader();
180182
emitBlockInfoBlock();
181183
emitVersionBlock();
@@ -260,6 +262,7 @@ class ClangDocBitcodeWriter {
260262
SmallVector<uint32_t, BitCodeConstants::RecordSize> Record;
261263
llvm::BitstreamWriter &Stream;
262264
AbbreviationMap Abbrevs;
265+
DiagnosticsEngine &Diags;
263266
};
264267

265268
} // namespace doc

clang-tools-extra/clang-doc/Generators.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -121,10 +121,11 @@ Error MustacheGenerator::generateDocumentation(
121121

122122
auto File = MemoryBuffer::getFile(Path);
123123
if (EC = File.getError(); EC) {
124-
// TODO: Buffer errors to report later, look into using Clang
125-
// diagnostics.
126-
llvm::errs() << "Failed to open file: " << Path << " " << EC.message()
127-
<< '\n';
124+
unsigned ID = CDCtx.Diags.getCustomDiagID(DiagnosticsEngine::Warning,
125+
"Failed to open file: %0 %1");
126+
CDCtx.Diags.Report(ID) << Path << EC.message();
127+
JSONIter.increment(EC);
128+
continue;
128129
}
129130

130131
auto Parsed = json::parse((*File)->getBuffer());

clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "Generators.h"
1616
#include "Representation.h"
1717
#include "support/File.h"
18+
#include "clang/Basic/Diagnostic.h"
1819
#include "llvm/Support/Error.h"
1920
#include "llvm/Support/Path.h"
2021

clang-tools-extra/clang-doc/Mapper.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,10 +95,10 @@ bool MapASTVisitor::mapDecl(const T *D, bool IsDefinition) {
9595
// this decl for some reason (e.g. we're only reporting public decls).
9696
if (Child)
9797
CDCtx.ECtx->reportResult(llvm::toHex(llvm::toStringRef(Child->USR)),
98-
serialize::serialize(Child));
98+
serialize::serialize(Child, CDCtx.Diags));
9999
if (Parent)
100100
CDCtx.ECtx->reportResult(llvm::toHex(llvm::toStringRef(Parent->USR)),
101-
serialize::serialize(Parent));
101+
serialize::serialize(Parent, CDCtx.Diags));
102102
}
103103
return true;
104104
}

clang-tools-extra/clang-doc/Representation.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -481,10 +481,11 @@ ClangDocContext::ClangDocContext(tooling::ExecutionContext *ECtx,
481481
StringRef RepositoryUrl,
482482
StringRef RepositoryLinePrefix, StringRef Base,
483483
std::vector<std::string> UserStylesheets,
484+
clang::DiagnosticsEngine &Diags,
484485
bool FTimeTrace)
485-
: ECtx(ECtx), ProjectName(ProjectName), PublicOnly(PublicOnly),
486-
FTimeTrace(FTimeTrace), OutDirectory(OutDirectory),
487-
UserStylesheets(UserStylesheets), Base(Base) {
486+
: ECtx(ECtx), ProjectName(ProjectName), OutDirectory(OutDirectory),
487+
SourceRoot(std::string(SourceRoot)), UserStylesheets(UserStylesheets),
488+
Base(Base), Diags(Diags), PublicOnly(PublicOnly), FTimeTrace(FTimeTrace) {
488489
llvm::SmallString<128> SourceRootDir(SourceRoot);
489490
if (SourceRoot.empty())
490491
// If no SourceRoot was provided the current path is used as the default

clang-tools-extra/clang-doc/Representation.h

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_DOC_REPRESENTATION_H
1616

1717
#include "clang/AST/Type.h"
18+
#include "clang/Basic/Diagnostic.h"
1819
#include "clang/Basic/Specifiers.h"
1920
#include "clang/Tooling/Execution.h"
2021
#include "llvm/ADT/SmallVector.h"
@@ -598,17 +599,13 @@ llvm::Expected<std::unique_ptr<Info>>
598599
mergeInfos(std::vector<std::unique_ptr<Info>> &Values);
599600

600601
struct ClangDocContext {
601-
ClangDocContext() = default;
602602
ClangDocContext(tooling::ExecutionContext *ECtx, StringRef ProjectName,
603603
bool PublicOnly, StringRef OutDirectory, StringRef SourceRoot,
604604
StringRef RepositoryUrl, StringRef RepositoryCodeLinePrefix,
605605
StringRef Base, std::vector<std::string> UserStylesheets,
606-
bool FTimeTrace = false);
606+
clang::DiagnosticsEngine &Diags, bool FTimeTrace = false);
607607
tooling::ExecutionContext *ECtx;
608-
std::string ProjectName; // Name of project clang-doc is documenting.
609-
bool PublicOnly; // Indicates if only public declarations are documented.
610-
bool FTimeTrace; // Indicates if ftime trace is turned on
611-
int Granularity; // Granularity of ftime trace
608+
std::string ProjectName; // Name of project clang-doc is documenting.
612609
std::string OutDirectory; // Directory for outputting generated files.
613610
std::string SourceRoot; // Directory where processed files are stored. Links
614611
// to definition locations will only be generated if
@@ -627,7 +624,12 @@ struct ClangDocContext {
627624
// Maps mustache template types to specific mustache template files.
628625
// Ex. comment-template -> /path/to/comment-template.mustache
629626
llvm::StringMap<std::string> MustacheTemplates;
627+
// A pointer to a DiagnosticsEngine for error reporting.
628+
clang::DiagnosticsEngine &Diags;
630629
Index Idx;
630+
int Granularity; // Granularity of ftime trace
631+
bool PublicOnly; // Indicates if only public declarations are documented.
632+
bool FTimeTrace; // Indicates if ftime trace is turned on
631633
};
632634

633635
} // namespace doc

clang-tools-extra/clang-doc/Serialize.cpp

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -337,28 +337,29 @@ static std::string getSourceCode(const Decl *D, const SourceRange &R) {
337337
.str();
338338
}
339339

340-
template <typename T> static std::string serialize(T &I) {
340+
template <typename T>
341+
static std::string serialize(T &I, DiagnosticsEngine &Diags) {
341342
SmallString<2048> Buffer;
342343
llvm::BitstreamWriter Stream(Buffer);
343-
ClangDocBitcodeWriter Writer(Stream);
344+
ClangDocBitcodeWriter Writer(Stream, Diags);
344345
Writer.emitBlock(I);
345346
return Buffer.str().str();
346347
}
347348

348-
std::string serialize(std::unique_ptr<Info> &I) {
349+
std::string serialize(std::unique_ptr<Info> &I, DiagnosticsEngine &Diags) {
349350
switch (I->IT) {
350351
case InfoType::IT_namespace:
351-
return serialize(*static_cast<NamespaceInfo *>(I.get()));
352+
return serialize(*static_cast<NamespaceInfo *>(I.get()), Diags);
352353
case InfoType::IT_record:
353-
return serialize(*static_cast<RecordInfo *>(I.get()));
354+
return serialize(*static_cast<RecordInfo *>(I.get()), Diags);
354355
case InfoType::IT_enum:
355-
return serialize(*static_cast<EnumInfo *>(I.get()));
356+
return serialize(*static_cast<EnumInfo *>(I.get()), Diags);
356357
case InfoType::IT_function:
357-
return serialize(*static_cast<FunctionInfo *>(I.get()));
358+
return serialize(*static_cast<FunctionInfo *>(I.get()), Diags);
358359
case InfoType::IT_concept:
359-
return serialize(*static_cast<ConceptInfo *>(I.get()));
360+
return serialize(*static_cast<ConceptInfo *>(I.get()), Diags);
360361
case InfoType::IT_variable:
361-
return serialize(*static_cast<VarInfo *>(I.get()));
362+
return serialize(*static_cast<VarInfo *>(I.get()), Diags);
362363
case InfoType::IT_friend:
363364
case InfoType::IT_typedef:
364365
case InfoType::IT_default:

0 commit comments

Comments
 (0)