|
22 | 22 | #include "clang/Lex/HeaderSearch.h"
|
23 | 23 | #include "clang/Lex/Preprocessor.h"
|
24 | 24 | #include "clang/Lex/PreprocessorOptions.h"
|
| 25 | +#include "clang/Parse/ParseHLSLRootSignature.h" |
25 | 26 | #include "clang/Sema/TemplateInstCallback.h"
|
26 | 27 | #include "clang/Serialization/ASTReader.h"
|
27 | 28 | #include "clang/Serialization/ASTWriter.h"
|
@@ -1241,3 +1242,85 @@ void GetDependenciesByModuleNameAction::ExecuteAction() {
|
1241 | 1242 | PPCallbacks *CB = PP.getPPCallbacks();
|
1242 | 1243 | CB->moduleImport(SourceLocation(), Path, ModResult);
|
1243 | 1244 | }
|
| 1245 | + |
| 1246 | +//===----------------------------------------------------------------------===// |
| 1247 | +// HLSL Specific Actions |
| 1248 | +//===----------------------------------------------------------------------===// |
| 1249 | + |
| 1250 | +class InjectRootSignatureCallback : public PPCallbacks { |
| 1251 | +private: |
| 1252 | + Sema &Actions; |
| 1253 | + StringRef RootSigName; |
| 1254 | + llvm::dxbc::RootSignatureVersion Version; |
| 1255 | + |
| 1256 | + std::optional<StringLiteral *> processStringLiteral(ArrayRef<Token> Tokens) { |
| 1257 | + for (Token Tok : Tokens) |
| 1258 | + if (!tok::isStringLiteral(Tok.getKind())) |
| 1259 | + return std::nullopt; |
| 1260 | + |
| 1261 | + ExprResult StringResult = Actions.ActOnUnevaluatedStringLiteral(Tokens); |
| 1262 | + if (StringResult.isInvalid()) |
| 1263 | + return std::nullopt; |
| 1264 | + |
| 1265 | + if (auto Signature = dyn_cast<StringLiteral>(StringResult.get())) |
| 1266 | + return Signature; |
| 1267 | + |
| 1268 | + return std::nullopt; |
| 1269 | + } |
| 1270 | + |
| 1271 | +public: |
| 1272 | + void MacroDefined(const Token &MacroNameTok, |
| 1273 | + const MacroDirective *MD) override { |
| 1274 | + if (RootSigName != MacroNameTok.getIdentifierInfo()->getName()) |
| 1275 | + return; |
| 1276 | + |
| 1277 | + const MacroInfo *MI = MD->getMacroInfo(); |
| 1278 | + auto Signature = processStringLiteral(MI->tokens()); |
| 1279 | + if (!Signature.has_value()) { |
| 1280 | + Actions.getDiagnostics().Report(MI->getDefinitionLoc(), |
| 1281 | + diag::err_expected_string_literal) |
| 1282 | + << /*in attributes...*/ 4 << "RootSignature"; |
| 1283 | + return; |
| 1284 | + } |
| 1285 | + |
| 1286 | + IdentifierInfo *DeclIdent = |
| 1287 | + hlsl::ParseHLSLRootSignature(Actions, Version, *Signature); |
| 1288 | + Actions.HLSL().SetRootSignatureOverride(DeclIdent); |
| 1289 | + } |
| 1290 | + |
| 1291 | + InjectRootSignatureCallback(Sema &Actions, StringRef RootSigName, |
| 1292 | + llvm::dxbc::RootSignatureVersion Version) |
| 1293 | + : PPCallbacks(), Actions(Actions), RootSigName(RootSigName), |
| 1294 | + Version(Version) {} |
| 1295 | +}; |
| 1296 | + |
| 1297 | +void HLSLFrontendAction::ExecuteAction() { |
| 1298 | + // Pre-requisites to invoke |
| 1299 | + CompilerInstance &CI = getCompilerInstance(); |
| 1300 | + if (!CI.hasASTContext() || !CI.hasPreprocessor()) |
| 1301 | + return WrapperFrontendAction::ExecuteAction(); |
| 1302 | + |
| 1303 | + // InjectRootSignatureCallback requires access to invoke Sema to lookup/ |
| 1304 | + // register a root signature declaration. The wrapped action is required to |
| 1305 | + // account for this by only creating a Sema if one doesn't already exist |
| 1306 | + // (like we have done, and, ASTFrontendAction::ExecuteAction) |
| 1307 | + if (!CI.hasSema()) |
| 1308 | + CI.createSema(getTranslationUnitKind(), |
| 1309 | + /*CodeCompleteConsumer=*/nullptr); |
| 1310 | + Sema &S = CI.getSema(); |
| 1311 | + |
| 1312 | + // Register HLSL specific callbacks |
| 1313 | + auto LangOpts = CI.getLangOpts(); |
| 1314 | + auto MacroCallback = std::make_unique<InjectRootSignatureCallback>( |
| 1315 | + S, LangOpts.HLSLRootSigOverride, LangOpts.HLSLRootSigVer); |
| 1316 | + |
| 1317 | + Preprocessor &PP = CI.getPreprocessor(); |
| 1318 | + PP.addPPCallbacks(std::move(MacroCallback)); |
| 1319 | + |
| 1320 | + // Invoke as normal |
| 1321 | + WrapperFrontendAction::ExecuteAction(); |
| 1322 | +} |
| 1323 | + |
| 1324 | +HLSLFrontendAction::HLSLFrontendAction( |
| 1325 | + std::unique_ptr<FrontendAction> WrappedAction) |
| 1326 | + : WrapperFrontendAction(std::move(WrappedAction)) {} |
0 commit comments