diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -3281,7 +3281,7 @@ } bool FunctionDecl::isInExternCContext() const { - if (hasAttr()) + if (hasAttr() || hasAttr()) return true; return getLexicalDeclContext()->isExternCContext(); } diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -16,6 +16,7 @@ #include "CGBlocks.h" #include "CGCXXABI.h" #include "CGCleanup.h" +#include "CGHLSLRuntime.h" #include "CGRecordLayout.h" #include "CodeGenFunction.h" #include "CodeGenModule.h" @@ -2601,6 +2602,11 @@ } assert(ArgNo == FI.arg_size()); + if (getLangOpts().HLSL && TargetDecl) { + if (const FunctionDecl *FD = dyn_cast_or_null(TargetDecl)) + getHLSLRuntime().addHLSLFunctionAttributes(FuncAttrs, RetAttrs, FD); + } + AttrList = llvm::AttributeList::get( getLLVMContext(), llvm::AttributeSet::get(getLLVMContext(), FuncAttrs), llvm::AttributeSet::get(getLLVMContext(), RetAttrs), ArgAttrs); diff --git a/clang/lib/CodeGen/CGHLSLRuntime.h b/clang/lib/CodeGen/CGHLSLRuntime.h --- a/clang/lib/CodeGen/CGHLSLRuntime.h +++ b/clang/lib/CodeGen/CGHLSLRuntime.h @@ -15,8 +15,13 @@ #ifndef LLVM_CLANG_LIB_CODEGEN_CGHLSLRUNTIME_H #define LLVM_CLANG_LIB_CODEGEN_CGHLSLRUNTIME_H +namespace llvm { +class AttrBuilder; +} namespace clang { +class FunctionDecl; + namespace CodeGen { class CodeGenModule; @@ -30,6 +35,10 @@ virtual ~CGHLSLRuntime() {} void finishCodeGen(); + + void addHLSLFunctionAttributes(llvm::AttrBuilder &FuncAttrs, + llvm::AttrBuilder &RetAttrs, + const FunctionDecl *); }; } // namespace CodeGen diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp b/clang/lib/CodeGen/CGHLSLRuntime.cpp --- a/clang/lib/CodeGen/CGHLSLRuntime.cpp +++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp @@ -50,3 +50,14 @@ llvm::Module &M = CGM.getModule(); addDxilValVersion(TargetOpts.DxilValidatorVersion, M); } + +void CGHLSLRuntime::addHLSLFunctionAttributes(llvm::AttrBuilder &FuncAttrs, + llvm::AttrBuilder &RetAttrs, + const FunctionDecl *FD) { + if (HLSLShaderAttr *ShaderAttr = FD->getAttr()) { + const StringRef ShaderAttrKindStr = "dx.shader"; + FuncAttrs.addAttribute( + ShaderAttrKindStr, + ShaderAttr->ConvertShaderTypeToStr(ShaderAttr->getType())); + } +} diff --git a/clang/test/CodeGenHLSL/entry.hlsl b/clang/test/CodeGenHLSL/entry.hlsl new file mode 100644 --- /dev/null +++ b/clang/test/CodeGenHLSL/entry.hlsl @@ -0,0 +1,10 @@ +// RUN: %clang --driver-mode=dxc -Tcs_6_1 -Efoo -fcgl -Fo - %s | FileCheck %s + +// Make sure not mangle entry. +// CHECK:define void @foo() +// Make sure add function attribute. +// CHECK:"dx.shader"="compute" +[numthreads(1,1,1)] +void foo() { + +} diff --git a/clang/test/CodeGenHLSL/shader_type_attr.hlsl b/clang/test/CodeGenHLSL/shader_type_attr.hlsl new file mode 100644 --- /dev/null +++ b/clang/test/CodeGenHLSL/shader_type_attr.hlsl @@ -0,0 +1,11 @@ +// RUN: %clang --driver-mode=dxc -Tlib_6_x -fcgl -Fo - %s | FileCheck %s + +// Make sure not mangle entry. +// CHECK:define void @foo() +// Make sure add function attribute. +// CHECK:"dx.shader"="compute" +[shader("compute")] +[numthreads(1,1,1)] +void foo() { + +}