AzslcException.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #pragma once
  9. #include "StdUtils.h"
  10. #include "GenericUtils.h"
  11. #include "PreprocessorLineDirectiveFinder.h"
  12. #include "antlr4-runtime.h"
  13. using namespace antlr4;
  14. using namespace antlrcpp;
  15. // NOTE: number the enum entries for quicker look-up
  16. namespace AZ::ShaderCompiler
  17. {
  18. enum AzslcErrorCode : uint16_t
  19. {
  20. PARSER_SYNTAX_ERROR = 1u,
  21. // orchestrator error codes
  22. ORCHESTRATOR_DEPORTED_METHOD_DEFINITION = 2u,
  23. ORCHESTRATOR_DEFINITION_FOREIGN_SCOPE = 3u,
  24. ORCHESTRATOR_NO_DECLERATION = 4u,
  25. ORCHESTRATOR_UNEXPECTED_KIND = 5u,
  26. ORCHESTRATOR_OVERLY_QUALIFIED = 6u,
  27. ORCHESTRATOR_DEPORTED_METHOD = 7u,
  28. ORCHESTRATOR_FUNCTION_ALREADY_DEFINED = 8u,
  29. ORCHESTRATOR_INVALID_INLINED_QUALIFIER = 9u,
  30. ORCHESTRATOR_INVALID_NONGLOBAL_OPTION_OR_ROOTCONSTANT = 11u,
  31. ORCHESTRATOR_ILLEGAL_GLOBAL_VARIABLE = 12u,
  32. ORCHESTRATOR_ILLEGAL_MEMBER_VARIABLE_IN_INTERFACE = 13u,
  33. ORCHESTRATOR_ILLEGAL_FOLDABLE_ARRAY_DIMENSIONS = 14u,
  34. ORCHESTRATOR_INVALID_QUALIFIER_MIX = 15u,
  35. ORCHESTRATOR_UNSPECIFIED_BASE_SYMBOL = 16u,
  36. ORCHESTRATOR_INVALID_INTERFACE = 17u,
  37. ORCHESTRATOR_CLASS_REDEFINE = 18u,
  38. ORCHESTRATOR_UNREGISTERED_METHOD = 19u,
  39. ORCHESTRATOR_HIDING_SYMBOL_BASE = 20u,
  40. ORCHESTRATOR_INVALID_OVERRIDE_SPECIFIER_CLASS = 21u,
  41. ORCHESTRATOR_INVALID_OVERRIDE_SPECIFIER_BASE = 22u,
  42. ORCHESTRATOR_INVALID_SEMANTIC_DECLARATION = 23u,
  43. ORCHESTRATOR_INVALID_SEMANTIC_DECLARATION_TYPE = 24u,
  44. ORCHESTRATOR_INVALID_EXTERNAL_BOUND_RESOURCE_VIEW = 25u,
  45. ORCHESTRATOR_INVALID_GENERIC_TYPE_CONSTANTBUFFER = 26u,
  46. ORCHESTRATOR_UNDECLARED_GENERIC_TYPE_CONSTANTBUFFER = 27u,
  47. ORCHESTRATOR_INVALID_GENERIC_TYPE_CONSTANTBUFFER_STRUCT = 28u,
  48. ORCHESTRATOR_LITERAL_REQUIRED_SRG_SEMANTIC = 29u,
  49. ORCHESTRATOR_INVALID_INTEGER_CONSTANT = 30u,
  50. ORCHESTRATOR_INVALID_RANGE_FREQUENCY_ID = 31u,
  51. ORCHESTRATOR_ODR_VIOLATION = 32u, // One Definition Rule
  52. ORCHESTRATOR_DISALLOWED_FUNCTION_MODIFIER = 33u,
  53. ORCHESTRATOR_MULTIPLE_HIDDEN_SYMBOLS = 34u,
  54. ORCHESTRATOR_SCOPE_NOT_FOUND = 35u,
  55. ORCHESTRATOR_INVALID_TYPEALIAS_TARGET = 36u,
  56. ORCHESTRATOR_NO_DOUBLE_DEFAULT_DECLARATION = 37u,
  57. ORCHESTRATOR_NO_DEFAULT_PARAM_WITH_OVERLOADS = 38u,
  58. ORCHESTRATOR_FUNCTION_INCONSISTENT_RETURN_TYPE = 39u,
  59. ORCHESTRATOR_NO_INLINE_UDT_IN_PARAMETERS = 40u,
  60. ORCHESTRATOR_OVERLOAD_RESOLUTION_HARD_FAILURE = 41u,
  61. ORCHESTRATOR_EXTERNAL_VARIABLE_WITH_INITIALIZER = 42u,
  62. ORCHESTRATOR_MEMBER_VARIABLE_WITH_INITIALIZER = 43u,
  63. ORCHESTRATOR_SRG_REUSES_A_FREQUENCY = 44u,
  64. ORCHESTRATOR_NON_PACKABLE_TYPE_IN_SRG_CONSTANT = 45u,
  65. ORCHESTRATOR_TRYING_TO_EXTEND_NOT_PARTIAL_SRG = 46u,
  66. ORCHESTRATOR_SRG_EXTENSION_HAS_DIFFERENT_SEMANTIC = 47u,
  67. ORCHESTRATOR_UNBOUNDED_RESOURCE_ISSUE = 48u,
  68. ORCHESTRATOR_UNKNOWN_OPTION_TYPE = 49u,
  69. ORCHESTRATOR_CONSTANT_FOLDING_FAULT = 50u,
  70. ORCHESTRATOR_TYPE_LOOKUP_FAULT = 51u,
  71. // Treat all compiler warnings as errors
  72. WX_WARNINGS_AS_ERRORS = 127u,
  73. // intermediate representation error codes
  74. IR_MULTIPLE_SRG_FALLBACK = 128u,
  75. IR_NO_FALLBACK_ASSIGNED = 129u,
  76. IR_SRG_WITHOUT_SEMANTIC = 130u,
  77. IR_POTENTIAL_DX12_VS_VULKAN_ALIGNMENT_ERROR = 131u,
  78. IR_INVALID_PAD_TO_ARGUMENTS = 132u,
  79. IR_INVALID_PAD_TO_LOCATION = 133u,
  80. IR_PAD_TO_CASE_REQUIRES_POWER_OF_TWO = 134u,
  81. // emitter error codes
  82. EMITTER_INVALID_ARRAY_DIMENSIONS = 256u,
  83. EMITTER_RECURSION_NOT_PERMITTED = 257u,
  84. EMITTER_OVERFLOW_BIT_BOUNDARY = 258u,
  85. EMITTER_OPTION_EXCEEDING_BITS_COUNT = 259u,
  86. EMITTER_INTEGER_RANGE_NEEDS_ATTRIBUTE = 260u,
  87. EMITTER_INTEGER_RANGE_MIN_IS_NOT_CONST = 261u,
  88. EMITTER_INTEGER_RANGE_MAX_IS_NOT_CONST = 262u,
  89. EMITTER_INTEGER_RANGE_MIN_IS_BIGGER_THAN_MAX = 263u,
  90. EMITTER_INTEGER_HAS_NO_RANGE = 264u,
  91. EMITTER_OPTION_HAS_UNSUPPORTED_TYPE = 265u,
  92. EMITTER_UNEXPECTED_EXPRESSION = 266u,
  93. EMITTER_UNDEFINED_SRG_MEMBER = 267u,
  94. // others
  95. ADVANCED_SYNTAX_DOUBLE_SCOPE_RESOLUTION = 514u,
  96. ADVANCED_RESERVED_NAME_USED = 515u,
  97. ADVANCED_SYNTAX_FUNCTION_IN_STRUCT = 516u,
  98. };
  99. class AzslcException : public antlr4::RuntimeException
  100. {
  101. public:
  102. AzslcException(uint32_t errorCode, const char* const errorType, optional<size_t> line, optional<size_t> column, const string& message)
  103. : antlr4::RuntimeException(message),
  104. m_errorCode(errorCode),
  105. m_errorType(errorType),
  106. m_line(line),
  107. m_column(column),
  108. m_errorMessage("")
  109. {
  110. BakeErrorMessage();
  111. }
  112. AzslcException(uint32_t errorCode, const char* const errorType, Token* token, const string& message)
  113. : RuntimeException(message),
  114. m_token(token),
  115. m_errorCode(errorCode),
  116. m_errorType(errorType),
  117. m_errorMessage("")
  118. {
  119. if (m_token)
  120. {
  121. m_line = m_token->getLine();
  122. m_column = m_token->getCharPositionInLine();
  123. }
  124. else
  125. {
  126. m_line = none;
  127. m_column = none;
  128. }
  129. BakeErrorMessage();
  130. }
  131. AzslcException(uint32_t errorCode, const char* const errorType, const string& message)
  132. : RuntimeException(message),
  133. m_token(nullptr),
  134. m_errorCode(errorCode),
  135. m_errorType(errorType),
  136. m_line(none),
  137. m_column(none),
  138. m_errorMessage("")
  139. {
  140. BakeErrorMessage();
  141. }
  142. const char* what() const NOEXCEPT
  143. {
  144. return m_errorMessage.c_str();
  145. }
  146. inline uint16_t GetErrorCode() const
  147. {
  148. return m_errorCode;
  149. }
  150. static string MakeErrorMessage(string_view filename, string_view line, string_view column, string_view errorType, bool error, string_view code, string_view message)
  151. {
  152. // global filename for error messages. visual studio standard build-tool error format is:
  153. // {filename(line# [, column#]) | toolname} : [ any text ] {error | warning} code+number:localizable string [ any text ]
  154. // so to respect this, we're going to simplify the API by setting the report file here.
  155. return ConcatString(filename,
  156. "(", line, ",", column, ") : ",
  157. errorType,
  158. error ? " error" : " warning",
  159. code.empty() ? "" : " #", code, ": ",
  160. message);
  161. }
  162. protected:
  163. void BakeErrorMessage()
  164. {
  165. m_errorMessage = MakeErrorMessage(s_lineFinder->GetVirtualFileName(m_line ? *m_line : 0),
  166. m_line ? ToString(s_lineFinder->GetVirtualLineNumber(*m_line)) : "",
  167. m_column ? ToString(*m_column) : "",
  168. m_errorType ? m_errorType : "",
  169. m_errorCode != WX_WARNINGS_AS_ERRORS,
  170. ToString(m_errorCode),
  171. RuntimeException::what());
  172. }
  173. public:
  174. static inline PreprocessorLineDirectiveFinder* s_lineFinder;
  175. protected:
  176. const uint16_t m_errorCode;
  177. const char* const m_errorType;
  178. const Token* m_token;
  179. string m_errorMessage;
  180. optional<size_t> m_line;
  181. optional<size_t> m_column;
  182. };
  183. class AzslcOrchestratorException final : public AzslcException
  184. {
  185. private:
  186. inline static const char* const ErrorType = "Semantic";
  187. public:
  188. AzslcOrchestratorException(uint32_t errorCode, optional<size_t> line, optional<size_t> column, const string& message)
  189. : AzslcException(errorCode,
  190. ErrorType,
  191. line,
  192. column,
  193. message)
  194. {}
  195. AzslcOrchestratorException(uint32_t errorCode, Token* token, const string& message)
  196. : AzslcException(errorCode,
  197. ErrorType,
  198. token,
  199. message)
  200. {}
  201. AzslcOrchestratorException(uint32_t errorCode, const string& message)
  202. : AzslcException(errorCode,
  203. ErrorType,
  204. message)
  205. {}
  206. };
  207. class AzslcIrException final : public AzslcException
  208. {
  209. private:
  210. inline static const char* const ErrorType = "IR";
  211. public:
  212. AzslcIrException(uint32_t errorCode, const string& message, optional<size_t> line = none)
  213. : AzslcException(errorCode,
  214. ErrorType,
  215. line,
  216. none,
  217. message)
  218. {}
  219. };
  220. class AzslcEmitterException final : public AzslcException
  221. {
  222. private:
  223. inline static const char* const ErrorType = "Emitter";
  224. public:
  225. AzslcEmitterException(uint32_t errorCode, optional<size_t> line, optional<size_t> column, const string& message)
  226. : AzslcException(errorCode,
  227. ErrorType,
  228. line,
  229. column,
  230. message)
  231. {}
  232. AzslcEmitterException(uint32_t errorCode, Token* token, const string& message)
  233. : AzslcException(errorCode,
  234. ErrorType,
  235. token,
  236. message)
  237. {}
  238. AzslcEmitterException(uint32_t errorCode, const string& message)
  239. : AzslcException(errorCode,
  240. ErrorType,
  241. message)
  242. {}
  243. };
  244. class AzslParserEventListener final : public antlr4::BaseErrorListener
  245. {
  246. public:
  247. void syntaxError(antlr4::Recognizer* recognizer, antlr4::Token* offendingSymbol, size_t line,
  248. size_t charPositionInLine, const string& msg, std::exception_ptr e) override
  249. {
  250. bool isKeyword = m_isKeywordPredicate(recognizer, offendingSymbol);
  251. using Ex = AzslcException;
  252. string errorMessage = Ex::MakeErrorMessage(Ex::s_lineFinder->GetVirtualFileName(line),
  253. ToString(Ex::s_lineFinder->GetVirtualLineNumber(line)),
  254. ToString(charPositionInLine + 1),
  255. "syntax",
  256. true,
  257. ToString(PARSER_SYNTAX_ERROR),
  258. ConcatString(msg, " (", offendingSymbol->getText(), isKeyword ? " is a keyword)" : " was unexpected)"));
  259. antlr4::ParseCancellationException parseException(errorMessage);
  260. if (e)
  261. {
  262. throw_with_nested(parseException);
  263. }
  264. else
  265. {
  266. throw parseException;
  267. }
  268. }
  269. std::function<bool(antlr4::Recognizer*, antlr4::Token* )> m_isKeywordPredicate;
  270. void reportAmbiguity(antlr4::Parser *recognizer, const antlr4::dfa::DFA &dfa, size_t startIndex, size_t stopIndex, bool exact,
  271. const antlrcpp::BitSet &ambigAlts, antlr4::atn::ATNConfigSet *configs) override
  272. {
  273. }
  274. void reportAttemptingFullContext(antlr4::Parser *recognizer, const antlr4::dfa::DFA &dfa, size_t startIndex, size_t stopIndex,
  275. const antlrcpp::BitSet &conflictingAlts, antlr4::atn::ATNConfigSet *configs) override
  276. {
  277. }
  278. void reportContextSensitivity(antlr4::Parser *recognizer, const antlr4::dfa::DFA &dfa, size_t startIndex, size_t stopIndex,
  279. size_t prediction, antlr4::atn::ATNConfigSet *configs) override
  280. {
  281. }
  282. };
  283. inline void OutputNestedAndException(const exception& e)
  284. {
  285. std::cerr << e.what() << std::endl;
  286. try
  287. {
  288. rethrow_if_nested(e);
  289. }
  290. catch (const exception& ne)
  291. {
  292. OutputNestedAndException(ne);
  293. }
  294. catch (...)
  295. {
  296. std::cerr << "Unknown exception" << std::endl;
  297. }
  298. }
  299. };