blob: 01305ec182e057198761fb523c5f246b8a1e4cb2 [file] [log] [blame]
Ben Clayton6b4924f2021-02-17 20:13:34 +00001// Copyright 2021 The Tint Authors.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#include "src/debug.h"
16
17#include <stdio.h>
18
19#include <sstream>
20#include <string>
21#include <vector>
22
23#include "src/diagnostic/diagnostic.h"
24
25namespace tint {
26namespace {
27
28InternalCompilerErrorReporter* ice_reporter = nullptr;
29
Ben Clayton89036852021-02-18 20:23:09 +000030/// Note - this class is _not_ thread safe. If we have multiple internal
31/// compiler errors occurring at the same time on different threads, then
32/// we're in serious trouble.
Ben Clayton6b4924f2021-02-17 20:13:34 +000033class SourceFileToDelete {
Ben Clayton89036852021-02-18 20:23:09 +000034 static SourceFileToDelete* instance;
35
Ben Clayton6b4924f2021-02-17 20:13:34 +000036 public:
Ben Clayton89036852021-02-18 20:23:09 +000037 /// Adds file to the list that will be deleted on call to Free()
38 static void Add(Source::File* file) {
39 if (!instance) {
40 instance = new SourceFileToDelete();
41 }
42 instance->files.emplace_back(file);
Ben Clayton6b4924f2021-02-17 20:13:34 +000043 }
44
Ben Clayton6b4924f2021-02-17 20:13:34 +000045 /// Free deletes all the source files added by calls to Add() and then this
Ben Clayton89036852021-02-18 20:23:09 +000046 /// SourceFileToDelete object.
47 static void Free() {
48 if (instance) {
49 for (auto* file : instance->files) {
50 delete file;
51 }
52 delete instance;
53 instance = nullptr;
Ben Clayton6b4924f2021-02-17 20:13:34 +000054 }
Ben Clayton6b4924f2021-02-17 20:13:34 +000055 }
56
57 private:
58 std::vector<Source::File*> files;
59};
60
Ben Clayton89036852021-02-18 20:23:09 +000061SourceFileToDelete* SourceFileToDelete::instance = nullptr;
62
Ben Clayton6b4924f2021-02-17 20:13:34 +000063} // namespace
64
65void FreeInternalCompilerErrors() {
Ben Clayton89036852021-02-18 20:23:09 +000066 SourceFileToDelete::Free();
Ben Clayton6b4924f2021-02-17 20:13:34 +000067}
68
69void SetInternalCompilerErrorReporter(InternalCompilerErrorReporter* reporter) {
70 ice_reporter = reporter;
71}
72
Ben Clayton3a9a55e2021-02-18 16:33:38 +000073InternalCompilerError::InternalCompilerError(const char* file,
74 size_t line,
75 diag::List& diagnostics)
76 : file_(file), line_(line), diagnostics_(diagnostics) {}
77
78InternalCompilerError::~InternalCompilerError() {
79 auto* file = new Source::File(file_, "");
Ben Clayton6b4924f2021-02-17 20:13:34 +000080
Ben Clayton89036852021-02-18 20:23:09 +000081 SourceFileToDelete::Add(file);
Ben Clayton6b4924f2021-02-17 20:13:34 +000082
Ben Clayton3a9a55e2021-02-18 16:33:38 +000083 Source source{Source::Range{Source::Location{line_}}, file};
84 diagnostics_.add_ice(msg_.str(), source);
Ben Clayton6b4924f2021-02-17 20:13:34 +000085
86 if (ice_reporter) {
Ben Clayton3a9a55e2021-02-18 16:33:38 +000087 ice_reporter(diagnostics_);
Ben Clayton6b4924f2021-02-17 20:13:34 +000088 }
89}
90
91} // namespace tint