diff options
author | Helena Kotas <hekotas@microsoft.com> | 2024-07-01 13:55:25 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-07-01 13:55:25 -0700 |
commit | 938cbdb4cf428bf08558c24d845aeac9174c7022 (patch) | |
tree | ff71a9e064a10f5fb75ff743e70877a58312e2b1 /clang/lib/Sema/SemaModule.cpp | |
parent | 6e93e37fe917833ad2d4d09ceda150ffe755b03e (diff) | |
download | llvm-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.cpp | 52 |
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; |