@@ -175,6 +175,10 @@ static llvm::cl::opt<std::string>
175
175
OutputFilename (" output-filename" ,
176
176
llvm::cl::desc (" Path to the output file" ));
177
177
178
+ static llvm::cl::opt<std::string>
179
+ DiagsOutputFilename (" diags-output-filename" ,
180
+ llvm::cl::desc (" Path to the output file for parser diagnostics text" ));
181
+
178
182
static llvm::cl::opt<bool >
179
183
PrintVisualReuseInfo (" print-visual-reuse-info" ,
180
184
llvm::cl::desc (" Print a coloured output of which parts of "
@@ -556,12 +560,17 @@ bool verifyReusedRegions(ByteBasedSourceRangeSet ExpectedReparseRegions,
556
560
return NoUnexpectedParse;
557
561
}
558
562
563
+ struct ParseInfo {
564
+ SourceFile *SF;
565
+ SyntaxParsingCache *SyntaxCache;
566
+ std::string Diags;
567
+ };
568
+
559
569
// / Parse the given input file (incrementally if an old syntax tree was
560
570
// / provided) and call the action specific callback with the new syntax tree
561
571
int parseFile (
562
572
const char *MainExecutablePath, const StringRef InputFileName,
563
- llvm::function_ref<int (SourceFile *, SyntaxParsingCache *SyntaxCache)>
564
- ActionSpecificCallback) {
573
+ llvm::function_ref<int (ParseInfo)> ActionSpecificCallback) {
565
574
// The cache needs to be a heap allocated pointer since we construct it inside
566
575
// an if block but need to keep it alive until the end of the function.
567
576
SyntaxParsingCache *SyntaxCache = nullptr ;
@@ -608,7 +617,9 @@ int parseFile(
608
617
Invocation.setMainFileSyntaxParsingCache (SyntaxCache);
609
618
Invocation.setModuleName (" Test" );
610
619
611
- PrintingDiagnosticConsumer DiagConsumer;
620
+ std::string DiagsString;
621
+ llvm::raw_string_ostream DiagOS (DiagsString);
622
+ PrintingDiagnosticConsumer DiagConsumer (DiagOS);
612
623
CompilerInstance Instance;
613
624
Instance.addDiagnosticConsumer (&DiagConsumer);
614
625
if (Instance.setup (Invocation)) {
@@ -658,7 +669,8 @@ int parseFile(
658
669
}
659
670
}
660
671
661
- int ActionSpecificExitCode = ActionSpecificCallback (SF, SyntaxCache);
672
+ int ActionSpecificExitCode =
673
+ ActionSpecificCallback ({SF, SyntaxCache, DiagOS.str ()});
662
674
if (ActionSpecificExitCode != EXIT_SUCCESS) {
663
675
return ActionSpecificExitCode;
664
676
} else {
@@ -713,16 +725,18 @@ int doDumpRawTokenSyntax(const StringRef InputFile) {
713
725
int doFullParseRoundTrip (const char *MainExecutablePath,
714
726
const StringRef InputFile) {
715
727
return parseFile (MainExecutablePath, InputFile,
716
- [](SourceFile *SF, SyntaxParsingCache *SyntaxCache ) -> int {
717
- SF->getSyntaxRoot ().print (llvm::outs (), {});
728
+ [](ParseInfo info ) -> int {
729
+ info. SF ->getSyntaxRoot ().print (llvm::outs (), {});
718
730
return EXIT_SUCCESS;
719
731
});
720
732
}
721
733
722
734
int doSerializeRawTree (const char *MainExecutablePath,
723
735
const StringRef InputFile) {
724
736
return parseFile (MainExecutablePath, InputFile,
725
- [](SourceFile *SF, SyntaxParsingCache *SyntaxCache) -> int {
737
+ [](ParseInfo info) -> int {
738
+ auto SF = info.SF ;
739
+ auto SyntaxCache = info.SyntaxCache ;
726
740
auto Root = SF->getSyntaxRoot ().getRaw ();
727
741
std::unordered_set<unsigned > ReusedNodeIds;
728
742
if (options::IncrementalSerialization && SyntaxCache) {
@@ -780,6 +794,23 @@ int doSerializeRawTree(const char *MainExecutablePath,
780
794
SerializeTree (llvm::outs (), Root, SyntaxCache);
781
795
}
782
796
}
797
+
798
+ if (!options::DiagsOutputFilename.empty ()) {
799
+ std::error_code errorCode;
800
+ llvm::raw_fd_ostream os (options::DiagsOutputFilename, errorCode,
801
+ llvm::sys::fs::F_None);
802
+ if (errorCode) {
803
+ llvm::errs () << " error opening file '" << options::DiagsOutputFilename
804
+ << " ': " << errorCode.message () << ' \n ' ;
805
+ return EXIT_FAILURE;
806
+ }
807
+ if (!info.Diags .empty ())
808
+ os << info.Diags << ' \n ' ;
809
+ } else {
810
+ if (!info.Diags .empty ())
811
+ llvm::errs () << info.Diags << ' \n ' ;
812
+ }
813
+
783
814
return EXIT_SUCCESS;
784
815
});
785
816
}
@@ -800,27 +831,28 @@ int doDeserializeRawTree(const char *MainExecutablePath,
800
831
801
832
int doParseOnly (const char *MainExecutablePath, const StringRef InputFile) {
802
833
return parseFile (MainExecutablePath, InputFile,
803
- [](SourceFile *SF, SyntaxParsingCache *SyntaxCache ) {
804
- return SF ? EXIT_SUCCESS : EXIT_FAILURE;
834
+ [](ParseInfo info ) {
835
+ return info. SF ? EXIT_SUCCESS : EXIT_FAILURE;
805
836
});
806
837
}
807
838
808
839
int dumpParserGen (const char *MainExecutablePath, const StringRef InputFile) {
809
840
return parseFile (MainExecutablePath, InputFile,
810
- [](SourceFile *SF, SyntaxParsingCache *SyntaxCache ) {
841
+ [](ParseInfo info ) {
811
842
SyntaxPrintOptions Opts;
812
843
Opts.PrintSyntaxKind = options::PrintNodeKind;
813
844
Opts.Visual = options::Visual;
814
845
Opts.PrintTrivialNodeKind = options::PrintTrivialNodeKind;
815
- SF->getSyntaxRoot ().print (llvm::outs (), Opts);
846
+ info. SF ->getSyntaxRoot ().print (llvm::outs (), Opts);
816
847
return EXIT_SUCCESS;
817
848
});
818
849
}
819
850
820
851
int dumpEOFSourceLoc (const char *MainExecutablePath,
821
852
const StringRef InputFile) {
822
853
return parseFile (MainExecutablePath, InputFile,
823
- [](SourceFile *SF, SyntaxParsingCache *SyntaxCache) -> int {
854
+ [](ParseInfo info) -> int {
855
+ auto SF = info.SF ;
824
856
auto BufferId = *SF->getBufferID ();
825
857
auto Root = SF->getSyntaxRoot ();
826
858
auto AbPos = Root.getEOFToken ().getAbsolutePosition ();
@@ -841,8 +873,8 @@ int dumpEOFSourceLoc(const char *MainExecutablePath,
841
873
}
842
874
}// end of anonymous namespace
843
875
844
- int invokeCommand (const char *MainExecutablePath,
845
- const StringRef InputSourceFilename) {
876
+ static int invokeCommand (const char *MainExecutablePath,
877
+ const StringRef InputSourceFilename) {
846
878
int ExitCode = EXIT_SUCCESS;
847
879
848
880
switch (options::Action) {
0 commit comments