Skip to content

Commit 2ebb085

Browse files
committed
[Frontend][HLSL] Define HLSLFrontendAction to add a PPCallback
1 parent 373add4 commit 2ebb085

File tree

7 files changed

+142
-0
lines changed

7 files changed

+142
-0
lines changed
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//===- HLSL/FrontendActions.h -----------------------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_CLANG_HLSL_FRONTEND_ACTIONS_H
10+
#define LLVM_CLANG_HLSL_FRONTEND_ACTIONS_H
11+
12+
#include "clang/Frontend/FrontendAction.h"
13+
14+
namespace clang {
15+
16+
class HLSLFrontendAction : public WrapperFrontendAction {
17+
protected:
18+
void ExecuteAction() override;
19+
20+
public:
21+
HLSLFrontendAction(std::unique_ptr<FrontendAction> WrappedAction);
22+
};
23+
24+
} // namespace clang
25+
26+
#endif // LLVM_CLANG_HLSL_FRONTEND_ACTIONS_H

clang/lib/CodeGen/CodeGenModule.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7534,6 +7534,9 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {
75347534
getContext().getCanonicalTagType(cast<EnumDecl>(D)));
75357535
break;
75367536

7537+
// Will be handled by attached function
7538+
case Decl::HLSLRootSignature:
7539+
break;
75377540
case Decl::HLSLBuffer:
75387541
getHLSLRuntime().addBuffer(cast<HLSLBufferDecl>(D));
75397542
break;

clang/lib/Frontend/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
add_subdirectory(Rewrite)
2+
add_subdirectory(HLSL)
23

34
set(LLVM_LINK_COMPONENTS
45
BitReader
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
set(LLVM_LINK_COMPONENTS
2+
Support
3+
)
4+
5+
add_clang_library(clangHLSLFrontend
6+
FrontendActions.cpp
7+
8+
LINK_LIBS
9+
clangAST
10+
clangBasic
11+
clangFrontend
12+
clangParse
13+
clangSema
14+
)
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
//===--- FrontendActions.cpp ----------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "clang/HLSL/Frontend/FrontendActions.h"
10+
#include "clang/Parse/ParseHLSLRootSignature.h"
11+
#include "clang/Sema/Sema.h"
12+
13+
namespace clang {
14+
15+
class InjectRootSignatureCallback : public PPCallbacks {
16+
private:
17+
Sema &Actions;
18+
StringRef RootSigName;
19+
llvm::dxbc::RootSignatureVersion Version;
20+
21+
std::optional<StringLiteral *> processStringLiteral(ArrayRef<Token> Tokens) {
22+
for (Token Tok : Tokens)
23+
if (!tok::isStringLiteral(Tok.getKind()))
24+
return std::nullopt;
25+
26+
ExprResult StringResult = Actions.ActOnUnevaluatedStringLiteral(Tokens);
27+
if (StringResult.isInvalid())
28+
return std::nullopt;
29+
30+
if (auto Signature = dyn_cast<StringLiteral>(StringResult.get()))
31+
return Signature;
32+
33+
return std::nullopt;
34+
}
35+
36+
public:
37+
void MacroDefined(const Token &MacroNameTok,
38+
const MacroDirective *MD) override {
39+
if (RootSigName != MacroNameTok.getIdentifierInfo()->getName())
40+
return;
41+
42+
const MacroInfo *MI = MD->getMacroInfo();
43+
auto Signature = processStringLiteral(MI->tokens());
44+
if (!Signature.has_value()) {
45+
Actions.getDiagnostics().Report(MI->getDefinitionLoc(),
46+
diag::err_expected_string_literal)
47+
<< /*in attributes...*/ 4 << "RootSignature";
48+
return;
49+
}
50+
51+
IdentifierInfo *DeclIdent =
52+
hlsl::ParseHLSLRootSignature(Actions, Version, *Signature);
53+
}
54+
55+
InjectRootSignatureCallback(Sema &Actions, StringRef RootSigName,
56+
llvm::dxbc::RootSignatureVersion Version)
57+
: PPCallbacks(), Actions(Actions), RootSigName(RootSigName),
58+
Version(Version) {}
59+
};
60+
61+
void HLSLFrontendAction::ExecuteAction() {
62+
// Pre-requisites to invoke
63+
CompilerInstance &CI = getCompilerInstance();
64+
if (!CI.hasASTContext() || !CI.hasPreprocessor())
65+
return WrapperFrontendAction::ExecuteAction();
66+
67+
// InjectRootSignatureCallback requires access to invoke Sema to lookup/
68+
// register a root signature declaration. The wrapped action is required to
69+
// account for this by only creating a Sema if one doesn't already exist
70+
// (like we have done, and, ASTFrontendAction::ExecuteAction)
71+
if (!CI.hasSema())
72+
CI.createSema(getTranslationUnitKind(),
73+
/*CodeCompleteConsumer=*/nullptr);
74+
Sema &S = CI.getSema();
75+
76+
// Register HLSL specific callbacks
77+
auto LangOpts = CI.getLangOpts();
78+
auto MacroCallback = std::make_unique<InjectRootSignatureCallback>(
79+
S, LangOpts.HLSLRootSigOverride, LangOpts.HLSLRootSigVer);
80+
81+
Preprocessor &PP = CI.getPreprocessor();
82+
PP.addPPCallbacks(std::move(MacroCallback));
83+
84+
// Invoke as normal
85+
WrapperFrontendAction::ExecuteAction();
86+
}
87+
88+
HLSLFrontendAction::HLSLFrontendAction(
89+
std::unique_ptr<FrontendAction> WrappedAction)
90+
: WrapperFrontendAction(std::move(WrappedAction)) {}
91+
92+
} // namespace clang

clang/lib/FrontendTool/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ set(link_libs
1010
clangExtractAPI
1111
clangFrontend
1212
clangRewriteFrontend
13+
clangHLSLFrontend
1314
)
1415

1516
set(deps)

clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "clang/Frontend/FrontendPluginRegistry.h"
2323
#include "clang/Frontend/Utils.h"
2424
#include "clang/FrontendTool/Utils.h"
25+
#include "clang/HLSL/Frontend/FrontendActions.h"
2526
#include "clang/Rewrite/Frontend/FrontendActions.h"
2627
#include "clang/StaticAnalyzer/Frontend/AnalyzerHelpFlags.h"
2728
#include "clang/StaticAnalyzer/Frontend/FrontendActions.h"
@@ -181,6 +182,10 @@ CreateFrontendAction(CompilerInstance &CI) {
181182

182183
const FrontendOptions &FEOpts = CI.getFrontendOpts();
183184

185+
if (CI.getLangOpts().HLSL) {
186+
Act = std::make_unique<HLSLFrontendAction>(std::move(Act));
187+
}
188+
184189
if (FEOpts.FixAndRecompile) {
185190
Act = std::make_unique<FixItRecompile>(std::move(Act));
186191
}

0 commit comments

Comments
 (0)