aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Sema/SemaModule.cpp
diff options
context:
space:
mode:
authorHelena Kotas <hekotas@microsoft.com>2024-07-01 13:55:25 -0700
committerGitHub <noreply@github.com>2024-07-01 13:55:25 -0700
commit938cbdb4cf428bf08558c24d845aeac9174c7022 (patch)
treeff71a9e064a10f5fb75ff743e70877a58312e2b1 /clang/lib/Sema/SemaModule.cpp
parent6e93e37fe917833ad2d4d09ceda150ffe755b03e (diff)
downloadllvm-938cbdb4cf428bf08558c24d845aeac9174c7022.zip
llvm-938cbdb4cf428bf08558c24d845aeac9174c7022.tar.gz
llvm-938cbdb4cf428bf08558c24d845aeac9174c7022.tar.bz2
[HLSL] Implement `export` keyword (#96823)
Implements `export` keyword in HLSL. There are two ways the `export` keyword can be used: 1. On individual function declarations ``` export void f() {} ``` 2. On a group of function declaration: ``` export { void f1(); void f2() {} } ``` Functions declared with the `export` keyword have external linkage. The implementation does not include validation of when a function can or cannot be exported, such as when it has resource argument or semantic annotations. That will be covered by llvm/llvm-project#93330. Currently all function declarations in global or named namespaces have external linkage by default so there are no specific code changes required right now to make sure exported function have external linkage as well. That will change as part of llvm/llvm-project#92071. Any additional changes to make sure exported functions still have external linkage will be done as part of this work item. Fixes #92812
Diffstat (limited to 'clang/lib/Sema/SemaModule.cpp')
-rw-r--r--clang/lib/Sema/SemaModule.cpp52
1 files changed, 33 insertions, 19 deletions
diff --git a/clang/lib/Sema/SemaModule.cpp b/clang/lib/Sema/SemaModule.cpp
index 9655a39..3b84e7b 100644
--- a/clang/lib/Sema/SemaModule.cpp
+++ b/clang/lib/Sema/SemaModule.cpp
@@ -855,23 +855,25 @@ Decl *Sema::ActOnStartExportDecl(Scope *S, SourceLocation ExportLoc,
// An export-declaration shall appear only [...] in the purview of a module
// interface unit. An export-declaration shall not appear directly or
// indirectly within [...] a private-module-fragment.
- if (!isCurrentModulePurview()) {
- Diag(ExportLoc, diag::err_export_not_in_module_interface) << 0;
- D->setInvalidDecl();
- return D;
- } else if (currentModuleIsImplementation()) {
- Diag(ExportLoc, diag::err_export_not_in_module_interface) << 1;
- Diag(ModuleScopes.back().BeginLoc,
- diag::note_not_module_interface_add_export)
- << FixItHint::CreateInsertion(ModuleScopes.back().BeginLoc, "export ");
- D->setInvalidDecl();
- return D;
- } else if (ModuleScopes.back().Module->Kind ==
- Module::PrivateModuleFragment) {
- Diag(ExportLoc, diag::err_export_in_private_module_fragment);
- Diag(ModuleScopes.back().BeginLoc, diag::note_private_module_fragment);
- D->setInvalidDecl();
- return D;
+ if (!getLangOpts().HLSL) {
+ if (!isCurrentModulePurview()) {
+ Diag(ExportLoc, diag::err_export_not_in_module_interface) << 0;
+ D->setInvalidDecl();
+ return D;
+ } else if (currentModuleIsImplementation()) {
+ Diag(ExportLoc, diag::err_export_not_in_module_interface) << 1;
+ Diag(ModuleScopes.back().BeginLoc,
+ diag::note_not_module_interface_add_export)
+ << FixItHint::CreateInsertion(ModuleScopes.back().BeginLoc, "export ");
+ D->setInvalidDecl();
+ return D;
+ } else if (ModuleScopes.back().Module->Kind ==
+ Module::PrivateModuleFragment) {
+ Diag(ExportLoc, diag::err_export_in_private_module_fragment);
+ Diag(ModuleScopes.back().BeginLoc, diag::note_private_module_fragment);
+ D->setInvalidDecl();
+ return D;
+ }
}
for (const DeclContext *DC = CurContext; DC; DC = DC->getLexicalParent()) {
@@ -891,7 +893,7 @@ Decl *Sema::ActOnStartExportDecl(Scope *S, SourceLocation ExportLoc,
//
// Defer exporting the namespace until after we leave it, in order to
// avoid marking all subsequent declarations in the namespace as exported.
- if (!DeferredExportedNamespaces.insert(ND).second)
+ if (!getLangOpts().HLSL && !DeferredExportedNamespaces.insert(ND).second)
break;
}
}
@@ -906,7 +908,9 @@ Decl *Sema::ActOnStartExportDecl(Scope *S, SourceLocation ExportLoc,
return D;
}
- D->setModuleOwnershipKind(Decl::ModuleOwnershipKind::VisibleWhenImported);
+ if (!getLangOpts().HLSL)
+ D->setModuleOwnershipKind(Decl::ModuleOwnershipKind::VisibleWhenImported);
+
return D;
}
@@ -924,6 +928,16 @@ static bool checkExportedDeclContext(Sema &S, DeclContext *DC,
/// Check that it's valid to export \p D.
static bool checkExportedDecl(Sema &S, Decl *D, SourceLocation BlockStart) {
+ // HLSL: export declaration is valid only on functions
+ if (S.getLangOpts().HLSL) {
+ // Export-within-export was already diagnosed in ActOnStartExportDecl
+ if (!dyn_cast<FunctionDecl>(D) && !dyn_cast<ExportDecl>(D)) {
+ S.Diag(D->getBeginLoc(), diag::err_hlsl_export_not_on_function);
+ D->setInvalidDecl();
+ return false;
+ }
+ }
+
// C++20 [module.interface]p3:
// [...] it shall not declare a name with internal linkage.
bool HasName = false;