Merge remote-tracking branch 'ms/master' into user/texr/integrate-master
This commit is contained in:
Коммит
2f5afecf67
|
@ -261,6 +261,8 @@ The namespace ``vk`` will be used for all Vulkan attributes:
|
||||||
and struct fields.
|
and struct fields.
|
||||||
- ``index(X)``: For specifying the index at a specific pixel shader output
|
- ``index(X)``: For specifying the index at a specific pixel shader output
|
||||||
location. Used for dual-source blending.
|
location. Used for dual-source blending.
|
||||||
|
- ``post_depth_coverage``: The input variable decorated with SampleMask will
|
||||||
|
reflect the result of the EarlyFragmentTests. Only valid on pixel shader entry points.
|
||||||
|
|
||||||
Only ``vk::`` attributes in the above list are supported. Other attributes will
|
Only ``vk::`` attributes in the above list are supported. Other attributes will
|
||||||
result in warnings and be ignored by the compiler. All C++11 attributes will
|
result in warnings and be ignored by the compiler. All C++11 attributes will
|
||||||
|
|
|
@ -59,27 +59,30 @@ public:
|
||||||
|
|
||||||
StackSave->eraseFromParent();
|
StackSave->eraseFromParent();
|
||||||
StackRestore->eraseFromParent();
|
StackRestore->eraseFromParent();
|
||||||
// Has stacksave/store mean alloca not in entry block.
|
|
||||||
if (bUpdated) {
|
// If stacksave/store is present, it means alloca not in the
|
||||||
// Make sure all allocas are in entry block.
|
// entry block. However, there could be other cases where allocas
|
||||||
for (Function &F : M.functions()) {
|
// could be present in the non-entry blocks.
|
||||||
MoveAllocasToEntryBlock(&F);
|
// Therefore, always go through all non-entry blocks and
|
||||||
}
|
// make sure all allocas are moved to the entry block.
|
||||||
|
for (Function &F : M.functions()) {
|
||||||
|
bUpdated |= MoveAllocasToEntryBlock(&F);
|
||||||
}
|
}
|
||||||
|
|
||||||
return bUpdated;
|
return bUpdated;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void MoveAllocasToEntryBlock(Function *F);
|
bool MoveAllocasToEntryBlock(Function *F);
|
||||||
};
|
};
|
||||||
|
|
||||||
char HLPreprocess::ID = 0;
|
char HLPreprocess::ID = 0;
|
||||||
|
|
||||||
// Make sure all allocas are in entry block.
|
// Make sure all allocas are in entry block.
|
||||||
void HLPreprocess::MoveAllocasToEntryBlock(Function *F) {
|
bool HLPreprocess::MoveAllocasToEntryBlock(Function *F) {
|
||||||
|
bool changed = false;
|
||||||
if (F->getBasicBlockList().size() < 2)
|
if (F->getBasicBlockList().size() < 2)
|
||||||
return;
|
return changed;
|
||||||
BasicBlock &Entry = F->getEntryBlock();
|
BasicBlock &Entry = F->getEntryBlock();
|
||||||
IRBuilder<> Builder(Entry.getFirstInsertionPt());
|
IRBuilder<> Builder(Entry.getFirstInsertionPt());
|
||||||
|
|
||||||
|
@ -92,9 +95,11 @@ void HLPreprocess::MoveAllocasToEntryBlock(Function *F) {
|
||||||
if (isa<AllocaInst>(I)) {
|
if (isa<AllocaInst>(I)) {
|
||||||
I->removeFromParent();
|
I->removeFromParent();
|
||||||
Builder.Insert(I);
|
Builder.Insert(I);
|
||||||
|
changed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -401,7 +401,10 @@ void PassManagerBuilder::populateModulePassManager(
|
||||||
//MPM.add(createLoopUnswitchPass(SizeLevel || OptLevel < 3)); // HLSL Change - may move barrier inside divergent if.
|
//MPM.add(createLoopUnswitchPass(SizeLevel || OptLevel < 3)); // HLSL Change - may move barrier inside divergent if.
|
||||||
MPM.add(createInstructionCombiningPass());
|
MPM.add(createInstructionCombiningPass());
|
||||||
MPM.add(createIndVarSimplifyPass()); // Canonicalize indvars
|
MPM.add(createIndVarSimplifyPass()); // Canonicalize indvars
|
||||||
MPM.add(createLoopIdiomPass()); // Recognize idioms like memset.
|
// HLSL Change Begins
|
||||||
|
// Don't allow loop idiom pass which may insert memset/memcpy thereby breaking the dxil
|
||||||
|
//MPM.add(createLoopIdiomPass()); // Recognize idioms like memset.
|
||||||
|
// HLSL Change Ends
|
||||||
MPM.add(createLoopDeletionPass()); // Delete dead loops
|
MPM.add(createLoopDeletionPass()); // Delete dead loops
|
||||||
if (EnableLoopInterchange) {
|
if (EnableLoopInterchange) {
|
||||||
MPM.add(createLoopInterchangePass()); // Interchange loops
|
MPM.add(createLoopInterchangePass()); // Interchange loops
|
||||||
|
|
|
@ -961,6 +961,13 @@ def VKConstantId : InheritableAttr {
|
||||||
let Documentation = [Undocumented];
|
let Documentation = [Undocumented];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def VKPostDepthCoverage : InheritableAttr {
|
||||||
|
let Spellings = [CXX11<"vk", "post_depth_coverage">];
|
||||||
|
let Subjects = SubjectList<[Function], ErrorDiag>;
|
||||||
|
let LangOpts = [SPIRV];
|
||||||
|
let Documentation = [Undocumented];
|
||||||
|
}
|
||||||
|
|
||||||
// SPIRV Change Ends
|
// SPIRV Change Ends
|
||||||
|
|
||||||
def C11NoReturn : InheritableAttr {
|
def C11NoReturn : InheritableAttr {
|
||||||
|
|
|
@ -7547,7 +7547,7 @@ def err_hlsl_unsupported_div_minint : Error<
|
||||||
def err_hlsl_unsupported_mod_double : Error<
|
def err_hlsl_unsupported_mod_double : Error<
|
||||||
"modulo cannot be used with doubles, cast to float first">;
|
"modulo cannot be used with doubles, cast to float first">;
|
||||||
def err_hlsl_unsupported_nested_struct : Error<
|
def err_hlsl_unsupported_nested_struct : Error<
|
||||||
"nested class/struct/interfaces are not supported in HLSL">;
|
"nested named class/struct/interfaces are not supported in HLSL">;
|
||||||
def err_hlsl_unsupported_nested_typedef : Error<
|
def err_hlsl_unsupported_nested_typedef : Error<
|
||||||
"nested typedefs are not supported in HLSL">;
|
"nested typedefs are not supported in HLSL">;
|
||||||
def err_hlsl_unsupported_operator : Error<
|
def err_hlsl_unsupported_operator : Error<
|
||||||
|
|
|
@ -34,6 +34,7 @@ enum class Extension {
|
||||||
KHR_device_group,
|
KHR_device_group,
|
||||||
KHR_multiview,
|
KHR_multiview,
|
||||||
KHR_shader_draw_parameters,
|
KHR_shader_draw_parameters,
|
||||||
|
KHR_post_depth_coverage,
|
||||||
EXT_descriptor_indexing,
|
EXT_descriptor_indexing,
|
||||||
EXT_fragment_fully_covered,
|
EXT_fragment_fully_covered,
|
||||||
EXT_shader_stencil_export,
|
EXT_shader_stencil_export,
|
||||||
|
|
|
@ -484,6 +484,9 @@ public:
|
||||||
llvm::ArrayRef<uint32_t> constituents);
|
llvm::ArrayRef<uint32_t> constituents);
|
||||||
uint32_t getConstantNull(uint32_t type);
|
uint32_t getConstantNull(uint32_t type);
|
||||||
|
|
||||||
|
// === Debug ===
|
||||||
|
void debugLine(uint32_t file, uint32_t line, uint32_t column);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// \brief Map from basic blocks' <label-id> to their structured
|
/// \brief Map from basic blocks' <label-id> to their structured
|
||||||
/// representation.
|
/// representation.
|
||||||
|
|
|
@ -2891,8 +2891,9 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
|
||||||
NonNestedClass = false;
|
NonNestedClass = false;
|
||||||
|
|
||||||
// HLSL Change Starts
|
// HLSL Change Starts
|
||||||
if (getLangOpts().HLSL) {
|
if (getLangOpts().HLSL && getLangOpts().HLSLVersion < 2016 &&
|
||||||
Diag(RecordLoc, diag::err_hlsl_unsupported_construct) << "nested class";
|
cast<NamedDecl>(TagDecl)->getDeclName()) {
|
||||||
|
Diag(RecordLoc, diag::err_hlsl_unsupported_nested_struct);
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
// HLSL Change Ends - succeeding block is now conditional
|
// HLSL Change Ends - succeeding block is now conditional
|
||||||
|
|
|
@ -113,6 +113,8 @@ Extension FeatureManager::getExtensionSymbol(llvm::StringRef name) {
|
||||||
Extension::AMD_shader_explicit_vertex_parameter)
|
Extension::AMD_shader_explicit_vertex_parameter)
|
||||||
.Case("SPV_GOOGLE_hlsl_functionality1",
|
.Case("SPV_GOOGLE_hlsl_functionality1",
|
||||||
Extension::GOOGLE_hlsl_functionality1)
|
Extension::GOOGLE_hlsl_functionality1)
|
||||||
|
.Case("SPV_KHR_post_depth_coverage",
|
||||||
|
Extension::KHR_post_depth_coverage)
|
||||||
.Default(Extension::Unknown);
|
.Default(Extension::Unknown);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,6 +130,8 @@ const char *FeatureManager::getExtensionName(Extension symbol) {
|
||||||
return "SPV_KHR_multiview";
|
return "SPV_KHR_multiview";
|
||||||
case Extension::KHR_shader_draw_parameters:
|
case Extension::KHR_shader_draw_parameters:
|
||||||
return "SPV_KHR_shader_draw_parameters";
|
return "SPV_KHR_shader_draw_parameters";
|
||||||
|
case Extension::KHR_post_depth_coverage:
|
||||||
|
return "SPV_KHR_post_depth_coverage";
|
||||||
case Extension::EXT_descriptor_indexing:
|
case Extension::EXT_descriptor_indexing:
|
||||||
return "SPV_EXT_descriptor_indexing";
|
return "SPV_EXT_descriptor_indexing";
|
||||||
case Extension::EXT_fragment_fully_covered:
|
case Extension::EXT_fragment_fully_covered:
|
||||||
|
|
|
@ -1258,6 +1258,11 @@ uint32_t ModuleBuilder::getConstantNull(uint32_t typeId) {
|
||||||
return constId;
|
return constId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ModuleBuilder::debugLine(uint32_t file, uint32_t line, uint32_t column) {
|
||||||
|
instBuilder.opLine(file, line, column).x();
|
||||||
|
insertPoint->appendInstruction(std::move(constructSite));
|
||||||
|
}
|
||||||
|
|
||||||
BasicBlock *ModuleBuilder::getBasicBlock(uint32_t labelId) {
|
BasicBlock *ModuleBuilder::getBasicBlock(uint32_t labelId) {
|
||||||
auto it = basicBlocks.find(labelId);
|
auto it = basicBlocks.find(labelId);
|
||||||
if (it == basicBlocks.end()) {
|
if (it == basicBlocks.end()) {
|
||||||
|
|
|
@ -590,7 +590,8 @@ SPIRVEmitter::SPIRVEmitter(CompilerInstance &ci, EmitSPIRVOptions &options)
|
||||||
featureManager, options),
|
featureManager, options),
|
||||||
entryFunctionId(0), curFunction(nullptr), curThis(0),
|
entryFunctionId(0), curFunction(nullptr), curThis(0),
|
||||||
seenPushConstantAt(), isSpecConstantMode(false),
|
seenPushConstantAt(), isSpecConstantMode(false),
|
||||||
foundNonUniformResourceIndex(false), needsLegalization(false) {
|
foundNonUniformResourceIndex(false), needsLegalization(false),
|
||||||
|
mainSourceFileId(0) {
|
||||||
if (shaderModel.GetKind() == hlsl::ShaderModel::Kind::Invalid)
|
if (shaderModel.GetKind() == hlsl::ShaderModel::Kind::Invalid)
|
||||||
emitError("unknown shader module: %0", {}) << shaderModel.GetName();
|
emitError("unknown shader module: %0", {}) << shaderModel.GetName();
|
||||||
|
|
||||||
|
@ -612,7 +613,8 @@ SPIRVEmitter::SPIRVEmitter(CompilerInstance &ci, EmitSPIRVOptions &options)
|
||||||
const auto &inputFiles = ci.getFrontendOpts().Inputs;
|
const auto &inputFiles = ci.getFrontendOpts().Inputs;
|
||||||
if (options.enableDebugInfo && !inputFiles.empty()) {
|
if (options.enableDebugInfo && !inputFiles.empty()) {
|
||||||
// File name
|
// File name
|
||||||
theBuilder.setSourceFileName(theContext.takeNextId(),
|
mainSourceFileId = theContext.takeNextId();
|
||||||
|
theBuilder.setSourceFileName(mainSourceFileId,
|
||||||
inputFiles.front().getFile().str());
|
inputFiles.front().getFile().str());
|
||||||
|
|
||||||
// Source code
|
// Source code
|
||||||
|
@ -1484,6 +1486,7 @@ void SPIRVEmitter::doDoStmt(const DoStmt *theDoStmt,
|
||||||
theBuilder.setInsertPoint(continueBB);
|
theBuilder.setInsertPoint(continueBB);
|
||||||
uint32_t condition = 0;
|
uint32_t condition = 0;
|
||||||
if (const Expr *check = theDoStmt->getCond()) {
|
if (const Expr *check = theDoStmt->getCond()) {
|
||||||
|
emitDebugLine(check->getLocStart());
|
||||||
condition = doExpr(check);
|
condition = doExpr(check);
|
||||||
} else {
|
} else {
|
||||||
condition = theBuilder.getConstantBool(true);
|
condition = theBuilder.getConstantBool(true);
|
||||||
|
@ -1583,6 +1586,7 @@ void SPIRVEmitter::doWhileStmt(const WhileStmt *whileStmt,
|
||||||
|
|
||||||
uint32_t condition = 0;
|
uint32_t condition = 0;
|
||||||
if (const Expr *check = whileStmt->getCond()) {
|
if (const Expr *check = whileStmt->getCond()) {
|
||||||
|
emitDebugLine(check->getLocStart());
|
||||||
condition = doExpr(check);
|
condition = doExpr(check);
|
||||||
} else {
|
} else {
|
||||||
condition = theBuilder.getConstantBool(true);
|
condition = theBuilder.getConstantBool(true);
|
||||||
|
@ -1674,6 +1678,7 @@ void SPIRVEmitter::doForStmt(const ForStmt *forStmt,
|
||||||
|
|
||||||
// Process the <init> block
|
// Process the <init> block
|
||||||
if (const Stmt *initStmt = forStmt->getInit()) {
|
if (const Stmt *initStmt = forStmt->getInit()) {
|
||||||
|
emitDebugLine(initStmt->getLocStart());
|
||||||
doStmt(initStmt);
|
doStmt(initStmt);
|
||||||
}
|
}
|
||||||
theBuilder.createBranch(checkBB);
|
theBuilder.createBranch(checkBB);
|
||||||
|
@ -1683,6 +1688,7 @@ void SPIRVEmitter::doForStmt(const ForStmt *forStmt,
|
||||||
theBuilder.setInsertPoint(checkBB);
|
theBuilder.setInsertPoint(checkBB);
|
||||||
uint32_t condition;
|
uint32_t condition;
|
||||||
if (const Expr *check = forStmt->getCond()) {
|
if (const Expr *check = forStmt->getCond()) {
|
||||||
|
emitDebugLine(check->getLocStart());
|
||||||
condition = doExpr(check);
|
condition = doExpr(check);
|
||||||
} else {
|
} else {
|
||||||
condition = theBuilder.getConstantBool(true);
|
condition = theBuilder.getConstantBool(true);
|
||||||
|
@ -1711,6 +1717,7 @@ void SPIRVEmitter::doForStmt(const ForStmt *forStmt,
|
||||||
// Process the <continue> block
|
// Process the <continue> block
|
||||||
theBuilder.setInsertPoint(continueBB);
|
theBuilder.setInsertPoint(continueBB);
|
||||||
if (const Expr *cont = forStmt->getInc()) {
|
if (const Expr *cont = forStmt->getInc()) {
|
||||||
|
emitDebugLine(cont->getLocStart());
|
||||||
doExpr(cont);
|
doExpr(cont);
|
||||||
}
|
}
|
||||||
theBuilder.createBranch(checkBB); // <continue> should jump back to header
|
theBuilder.createBranch(checkBB); // <continue> should jump back to header
|
||||||
|
@ -1784,6 +1791,7 @@ void SPIRVEmitter::doIfStmt(const IfStmt *ifStmt,
|
||||||
if (const auto *declStmt = ifStmt->getConditionVariableDeclStmt())
|
if (const auto *declStmt = ifStmt->getConditionVariableDeclStmt())
|
||||||
doDeclStmt(declStmt);
|
doDeclStmt(declStmt);
|
||||||
|
|
||||||
|
emitDebugLine(ifStmt->getCond()->getLocStart());
|
||||||
// First emit the instruction for evaluating the condition.
|
// First emit the instruction for evaluating the condition.
|
||||||
const uint32_t condition = doExpr(ifStmt->getCond());
|
const uint32_t condition = doExpr(ifStmt->getCond());
|
||||||
|
|
||||||
|
@ -1986,6 +1994,8 @@ SpirvEvalInfo SPIRVEmitter::doBinaryOperator(const BinaryOperator *expr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
SpirvEvalInfo SPIRVEmitter::doCallExpr(const CallExpr *callExpr) {
|
SpirvEvalInfo SPIRVEmitter::doCallExpr(const CallExpr *callExpr) {
|
||||||
|
emitDebugLine(callExpr->getLocStart());
|
||||||
|
|
||||||
if (const auto *operatorCall = dyn_cast<CXXOperatorCallExpr>(callExpr))
|
if (const auto *operatorCall = dyn_cast<CXXOperatorCallExpr>(callExpr))
|
||||||
return doCXXOperatorCallExpr(operatorCall);
|
return doCXXOperatorCallExpr(operatorCall);
|
||||||
|
|
||||||
|
@ -9223,6 +9233,13 @@ void SPIRVEmitter::processPixelShaderAttributes(const FunctionDecl *decl) {
|
||||||
theBuilder.addExecutionMode(entryFunctionId,
|
theBuilder.addExecutionMode(entryFunctionId,
|
||||||
spv::ExecutionMode::EarlyFragmentTests, {});
|
spv::ExecutionMode::EarlyFragmentTests, {});
|
||||||
}
|
}
|
||||||
|
if (decl->getAttr<VKPostDepthCoverageAttr>()) {
|
||||||
|
theBuilder.addExtension(Extension::KHR_post_depth_coverage,
|
||||||
|
"[[vk::post_depth_coverage]]", decl->getLocation());
|
||||||
|
theBuilder.requireCapability(spv::Capability::SampleMaskPostDepthCoverage);
|
||||||
|
theBuilder.addExecutionMode(entryFunctionId,
|
||||||
|
spv::ExecutionMode::PostDepthCoverage, {});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SPIRVEmitter::processComputeShaderAttributes(const FunctionDecl *decl) {
|
void SPIRVEmitter::processComputeShaderAttributes(const FunctionDecl *decl) {
|
||||||
|
@ -9950,5 +9967,13 @@ uint32_t SPIRVEmitter::extractVecFromVec4(uint32_t fromId,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SPIRVEmitter::emitDebugLine(SourceLocation loc) {
|
||||||
|
if (spirvOptions.enableDebugInfo && mainSourceFileId != 0) {
|
||||||
|
auto floc = FullSourceLoc(loc, theCompilerInstance.getSourceManager());
|
||||||
|
theBuilder.debugLine(mainSourceFileId, floc.getSpellingLineNumber(),
|
||||||
|
floc.getSpellingColumnNumber());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // end namespace spirv
|
} // end namespace spirv
|
||||||
} // end namespace clang
|
} // end namespace clang
|
||||||
|
|
|
@ -873,6 +873,9 @@ private:
|
||||||
uint32_t constOffsets, uint32_t sample,
|
uint32_t constOffsets, uint32_t sample,
|
||||||
uint32_t minLod, uint32_t residencyCodeId);
|
uint32_t minLod, uint32_t residencyCodeId);
|
||||||
|
|
||||||
|
/// \brief Emit an OpLine instruction for the given source location.
|
||||||
|
void emitDebugLine(SourceLocation);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// \brief Wrapper method to create a fatal error message and report it
|
/// \brief Wrapper method to create a fatal error message and report it
|
||||||
/// in the diagnostic engine associated with this consumer.
|
/// in the diagnostic engine associated with this consumer.
|
||||||
|
@ -1017,6 +1020,9 @@ private:
|
||||||
/// This is the Patch Constant Function. This function is not explicitly
|
/// This is the Patch Constant Function. This function is not explicitly
|
||||||
/// called from the entry point function.
|
/// called from the entry point function.
|
||||||
FunctionDecl *patchConstFunc;
|
FunctionDecl *patchConstFunc;
|
||||||
|
|
||||||
|
/// The <result-id> of the OpString containing the main source file's path.
|
||||||
|
uint32_t mainSourceFileId;
|
||||||
};
|
};
|
||||||
|
|
||||||
void SPIRVEmitter::doDeclStmt(const DeclStmt *declStmt) {
|
void SPIRVEmitter::doDeclStmt(const DeclStmt *declStmt) {
|
||||||
|
|
|
@ -10734,6 +10734,9 @@ void hlsl::HandleDeclAttributeForHLSL(Sema &S, Decl *D, const AttributeList &A,
|
||||||
declAttr = ::new (S.Context) VKConstantIdAttr(A.getRange(), S.Context,
|
declAttr = ::new (S.Context) VKConstantIdAttr(A.getRange(), S.Context,
|
||||||
ValidateAttributeIntArg(S, A), A.getAttributeSpellingListIndex());
|
ValidateAttributeIntArg(S, A), A.getAttributeSpellingListIndex());
|
||||||
break;
|
break;
|
||||||
|
case AttributeList::AT_VKPostDepthCoverage:
|
||||||
|
declAttr = ::new (S.Context) VKPostDepthCoverageAttr(A.getRange(), S.Context, A.getAttributeSpellingListIndex());
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
Handled = false;
|
Handled = false;
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
// RUN: %dxc /Tps_6_0 /Emain > %s | FileCheck %s
|
||||||
|
// CHECK: define void @main()
|
||||||
|
// CHECK: entry
|
||||||
|
|
||||||
|
float2 foo() {
|
||||||
|
return float2(1.0f, -1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
[RootSignature("")]
|
||||||
|
float main() : SV_Target {
|
||||||
|
for (int c = 0; c < 2; ++c) {
|
||||||
|
if (foo()[c] >= 1.0f) {
|
||||||
|
return foo()[c];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1.0f;
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
// RUN: %dxc /Tps_6_0 /Emain > %s | FileCheck %s
|
||||||
|
// CHECK: define void @main()
|
||||||
|
// CHECK: entry
|
||||||
|
|
||||||
|
#define MAX_INDEX 5
|
||||||
|
|
||||||
|
groupshared float g_Array[2][(MAX_INDEX * MAX_INDEX)];
|
||||||
|
|
||||||
|
[RootSignature("")] float4 main(uint GroupIndex
|
||||||
|
: A) : SV_Target {
|
||||||
|
uint idx;
|
||||||
|
float l_Array[(MAX_INDEX * MAX_INDEX)] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f};
|
||||||
|
for (idx = 0; idx < (MAX_INDEX * MAX_INDEX); idx++) {
|
||||||
|
g_Array[GroupIndex][idx] = l_Array[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
return float4(g_Array[GroupIndex][0], g_Array[GroupIndex][1], g_Array[GroupIndex][2], g_Array[GroupIndex][3]);
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
// RUN: %dxc /Tps_6_0 /Emain > %s | FileCheck %s
|
||||||
|
// CHECK: define void @main()
|
||||||
|
// CHECK: entry
|
||||||
|
|
||||||
|
#define MAX_INDEX 14
|
||||||
|
|
||||||
|
groupshared float g_Array[2][(MAX_INDEX * MAX_INDEX)];
|
||||||
|
|
||||||
|
[RootSignature("")] float4 main(uint GroupIndex
|
||||||
|
: A) : SV_Target {
|
||||||
|
uint idx;
|
||||||
|
for (idx = 0; idx < (MAX_INDEX * MAX_INDEX); idx++) {
|
||||||
|
g_Array[GroupIndex][idx] = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return float4(g_Array[GroupIndex][0], g_Array[GroupIndex][1], g_Array[GroupIndex][2], g_Array[GroupIndex][3]);
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
// Run: %dxc -T ps_6_0 -E main
|
||||||
|
|
||||||
|
// CHECK: OpCapability SampleMaskPostDepthCoverage
|
||||||
|
// CHECK: OpExtension "SPV_KHR_post_depth_coverage"
|
||||||
|
// CHECK: OpExecutionMode %main PostDepthCoverage
|
||||||
|
|
||||||
|
[[vk::post_depth_coverage]]
|
||||||
|
float4 main() : SV_Target { return 1.0; }
|
|
@ -0,0 +1,68 @@
|
||||||
|
// Run: %dxc -T ps_6_0 -E main -Zi
|
||||||
|
|
||||||
|
// CHECK: [[file:%\d+]] = OpString
|
||||||
|
// CHECK-SAME: spirv.debug.opline.hlsl
|
||||||
|
|
||||||
|
Texture2D MyTexture;
|
||||||
|
SamplerState MySampler;
|
||||||
|
|
||||||
|
uint foo(uint val) {
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note that we do two passes for debuging info: first preprocessing and then
|
||||||
|
// compiling the preprocessed source code.
|
||||||
|
// Because the preprocessor prepends a "#line 1 ..." line to the whole file,
|
||||||
|
// the compliation sees line numbers incremented by 1.
|
||||||
|
|
||||||
|
float4 main(uint val : A) : SV_Target {
|
||||||
|
// CHECK: OpLine [[file]] 23 12
|
||||||
|
// CHECK-NEXT: OpLoad %uint %val
|
||||||
|
// CHECK-NEXT: OpBitReverse
|
||||||
|
uint a = reversebits(val);
|
||||||
|
|
||||||
|
// CHECK: OpLine [[file]] 27 12
|
||||||
|
// CHECK-NEXT: OpLoad %uint %a
|
||||||
|
uint b = foo(a);
|
||||||
|
|
||||||
|
// CHECK: OpLine [[file]] 31 14
|
||||||
|
// CHECK-NEXT: OpLoad %type_2d_image %MyTexture
|
||||||
|
float4 c = MyTexture.Sample(MySampler, float2(0.1, 0.2));
|
||||||
|
|
||||||
|
// CHECK: OpLine [[file]] 36 7
|
||||||
|
// CHECK-NEXT: OpLoad %uint %val
|
||||||
|
// CHECK-NEXT: OpUGreaterThan
|
||||||
|
if (val > 10) {
|
||||||
|
a = 5;
|
||||||
|
} else {
|
||||||
|
a = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (
|
||||||
|
// CHECK: OpLine [[file]] 45 7
|
||||||
|
// CHECK-NEXT: OpStore %b %uint_0
|
||||||
|
b = 0;
|
||||||
|
// CHECK: OpLine [[file]] 49 7
|
||||||
|
// CHECK-NEXT: OpLoad %uint %b
|
||||||
|
// CHECK-NEXT: OpULessThan
|
||||||
|
b < 10;
|
||||||
|
// CHECK: OpLine [[file]] 53 7
|
||||||
|
// CHECK-NEXT: OpLoad %uint %b
|
||||||
|
// CHECK-NEXT: OpIAdd
|
||||||
|
++b) {
|
||||||
|
a += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK: OpLine [[file]] 60 10
|
||||||
|
// CHECK-NEXT: OpLoad %uint %b
|
||||||
|
// CHECK-NEXT: OpISub
|
||||||
|
while (--b > 0);
|
||||||
|
|
||||||
|
do {
|
||||||
|
c++;
|
||||||
|
// CHECK: OpLine [[file]] 66 12
|
||||||
|
// CHECK-NEXT: OpAccessChain %_ptr_Function_float %c %int_0
|
||||||
|
} while (c.x < 10);
|
||||||
|
|
||||||
|
return b * c;
|
||||||
|
}
|
|
@ -0,0 +1,651 @@
|
||||||
|
// RUN: %clang_cc1 -HV 2015 -fsyntax-only -Wno-unused-value -ffreestanding -verify %s
|
||||||
|
|
||||||
|
float f_arr_empty_init[] = { 1, 2, 3 };
|
||||||
|
float f_arr_empty_pack[] = { 1, 2 ... }; // expected-error {{expansion is unsupported in HLSL}}
|
||||||
|
|
||||||
|
struct s_arr_i_f { int i; float f; };
|
||||||
|
s_arr_i_f arr_struct_none[] = { }; // TODO: this should fail - see comments in HLSLExternalSource::InitializeInitSequenceForHLSL
|
||||||
|
s_arr_i_f arr_struct_one[] = { 1, 2 };
|
||||||
|
s_arr_i_f arr_struct_incomplete[] = { 1, 2, 3 }; // expected-error {{too few elements in vector initialization (expected 4 elements, have 3)}}
|
||||||
|
s_arr_i_f arr_struct_two[] = { 1, 2, 3, 4 };
|
||||||
|
|
||||||
|
int g_int;
|
||||||
|
typeof(g_int) g_typeof_int; // expected-error {{HLSL requires a type specifier for all declarations}} expected-error {{expected ';' after top level declarator}} expected-error {{unknown type name 'typeof'; did you mean 'typedef'?}}
|
||||||
|
typedef int (*fn_int)(int); // expected-error {{pointers are unsupported in HLSL}}
|
||||||
|
auto g_auto = 3; // expected-error {{'auto' is a reserved keyword in HLSL}} expected-error {{HLSL requires a type specifier for all declarations}}
|
||||||
|
__is_signed g_is_signed; // expected-error {{'__is_signed' is a reserved keyword in HLSL}} expected-error {{HLSL requires a type specifier for all declarations}}
|
||||||
|
register int g_register; // expected-error {{'register' is a reserved keyword in HLSL}}
|
||||||
|
__thread int g_thread; // expected-error {{'__thread' is a reserved keyword in HLSL}}
|
||||||
|
thread_local int g_threadLocal; // expected-error {{expected unqualified-id}} expected-error {{unknown type name 'thread_local'}}
|
||||||
|
_Thread_local int g_Thread_local; // expected-error {{'_Thread_local' is a reserved keyword in HLSL}}
|
||||||
|
_Alignas(float) int g_Alignas; // expected-error {{'_Alignas' is a reserved keyword in HLSL}}
|
||||||
|
alignas(float) int g_alignas; // expected-error {{HLSL requires a type specifier for all declarations}} expected-error {{expected ';' after top level declarator}}
|
||||||
|
constexpr int g_constexpr = 3; // expected-error {{expected unqualified-id}} expected-error {{unknown type name 'constexpr'}}
|
||||||
|
friend int f_friend; // expected-error {{'friend' is a reserved keyword in HLSL}}
|
||||||
|
|
||||||
|
// Alternate numerics and builtin types.
|
||||||
|
short g_short; // expected-error {{'short' is a reserved keyword in HLSL}} expected-error {{HLSL requires a type specifier for all declarations}}
|
||||||
|
long g_long; // expected-error {{'long' is a reserved keyword in HLSL}} expected-error {{HLSL requires a type specifier for all declarations}}
|
||||||
|
signed int g_signed_int; // expected-error {{'signed' is a reserved keyword in HLSL}}
|
||||||
|
unsigned int g_unsigned_int;
|
||||||
|
char g_char; // expected-error {{'char' is a reserved keyword in HLSL}} expected-error {{HLSL requires a type specifier for all declarations}}
|
||||||
|
_Bool g_Bool; // expected-error {{unknown type name '_Bool'}}
|
||||||
|
_vector int altivec_vector; // expected-error {{expected unqualified-id}} expected-error {{unknown type name '_vector'}}
|
||||||
|
|
||||||
|
restrict int g_restrict; // expected-error {{expected unqualified-id}} expected-error {{unknown type name 'restrict'}}
|
||||||
|
|
||||||
|
__underlying_type(int) g_underlying_type; // expected-error {{__underlying_type is unsupported in HLSL}}
|
||||||
|
_Atomic(something) g_Atomic; // expected-error {{'_Atomic' is a reserved keyword in HLSL}} expected-error {{HLSL requires a type specifier for all declarations}}
|
||||||
|
typeof(g_int) g_anotherInt; // expected-error {{HLSL requires a type specifier for all declarations}} expected-error {{expected ';' after top level declarator}} expected-error {{unknown type name 'typeof'; did you mean 'typedef'?}}
|
||||||
|
|
||||||
|
// More GNU-specific keywords.
|
||||||
|
_Decimal32 g__Decimal32; // expected-error {{GNU decimal type extension not supported}}
|
||||||
|
_Decimal64 g__Decimal64; // expected-error {{GNU decimal type extension not supported}}
|
||||||
|
_Decimal128 g__Decimal128; // expected-error {{GNU decimal type extension not supported}}
|
||||||
|
__null g___null; // expected-error {{expected unqualified-id}}
|
||||||
|
__alignof g___alignof; // expected-error {{expected unqualified-id}}
|
||||||
|
__imag g___imag; // expected-error {{expected unqualified-id}}
|
||||||
|
__int128 g___int128; // expected-error {{'__int128' is a reserved keyword in HLSL}} expected-error {{HLSL requires a type specifier for all declarations}}
|
||||||
|
__label__ g___label; // expected-error {{expected unqualified-id}}
|
||||||
|
__real g___real; // expected-error {{expected unqualified-id}}
|
||||||
|
__FUNCTION__ g___FUNCTION; // expected-error {{expected unqualified-id}}
|
||||||
|
__PRETTY__ g___PRETTY; // expected-error {{unknown type name '__PRETTY__'}}
|
||||||
|
|
||||||
|
struct s_with_bitfield {
|
||||||
|
int f_bitfield : 3;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct s_with_friend {
|
||||||
|
friend void some_fn(); // expected-error {{'friend' is a reserved keyword in HLSL}}
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef int (*fn_int_const)(int) const; // expected-error {{expected ';' after top level declarator}} expected-error {{pointers are unsupported in HLSL}} expected-warning {{declaration does not declare anything}}
|
||||||
|
typedef int (*fn_int_volatile)(int) volatile; // expected-error {{expected ';' after top level declarator}} expected-error {{pointers are unsupported in HLSL}} expected-warning {{declaration does not declare anything}}
|
||||||
|
|
||||||
|
void fn_throw() throw() { } // expected-error {{exception specification is unsupported in HLSL}}
|
||||||
|
|
||||||
|
// This would otherwise be 'exception specification is unsupported in HLSL', but noexcept is not a keyword for HLSL.
|
||||||
|
void fn_noexcept() noexcept { }; // expected-error {{expected function body after function declarator}}
|
||||||
|
|
||||||
|
// This would be a failure because of unsupported trailer return types, but we mis-parse it differently.
|
||||||
|
auto fn_trailing() -> int { return 1; } ; // expected-error {{'auto' is a reserved keyword in HLSL}} expected-error {{expected function body after function declarator}}
|
||||||
|
|
||||||
|
void fn_param_with_default(int val = 1) { }
|
||||||
|
void fn_with_variadic(int a, ...) { } // expected-error {{variadic arguments is unsupported in HLSL}}
|
||||||
|
|
||||||
|
float f_arr_empty_uninit[]; // expected-error {{definition of variable with array type needs an explicit size or an initializer}}
|
||||||
|
float f_arr_static[static 3]; // expected-error {{static keyword on array derivation is unsupported in HLSL}}
|
||||||
|
float f_arr_star[*]; // expected-error {{definition of variable with array type needs an explicit size or an initializer}} expected-error {{variable-length array is unsupported in HLSL}}
|
||||||
|
|
||||||
|
#define <<(x) (x) // expected-error {{macro name must be an identifier}}
|
||||||
|
|
||||||
|
typedef int bool; // expected-error {{redeclaration of HLSL built-in type 'bool'}} expected-warning {{typedef requires a name}}
|
||||||
|
|
||||||
|
// This would generate an 'unknown pragma ignored' warning, but the default configuration ignores the warning.
|
||||||
|
#pragma align(4)
|
||||||
|
|
||||||
|
// Objective-C @ support for NSString literals.
|
||||||
|
const bool b = @"hello" != @"goodbye"; // expected-error {{expected expression}}
|
||||||
|
|
||||||
|
int fn_eq_default() = default; // expected-error {{'= default' is a function definition and must occur in a standalone declaration}}
|
||||||
|
|
||||||
|
typename typedef float4 TFloat4; // expected-error {{'typename' is a reserved keyword in HLSL}}
|
||||||
|
|
||||||
|
class C {
|
||||||
|
int fn_eq_default() = default; // expected-error {{function deletion and defaulting is unsupported in HLSL}}
|
||||||
|
|
||||||
|
// Errors are a bit misleading here, but ultimate we don't support these.
|
||||||
|
void* operator new(); // expected-error {{'operator' is a reserved keyword in HLSL}} expected-error {{pointers are unsupported in HLSL}}
|
||||||
|
void* operator new(int); // expected-error {{'operator' is a reserved keyword in HLSL}} expected-error {{pointers are unsupported in HLSL}}
|
||||||
|
void* operator new(size_t); // expected-error {{'operator' is a reserved keyword in HLSL}} expected-error {{pointers are unsupported in HLSL}}
|
||||||
|
|
||||||
|
C() = delete; // expected-error {{HLSL requires a type specifier for all declarations}} expected-error {{constructor cannot have a return type}}
|
||||||
|
};
|
||||||
|
|
||||||
|
asm ("int 3c"); // expected-error {{expected unqualified-id}}
|
||||||
|
@property int at_property_int; // expected-error {{expected unqualified-id}}
|
||||||
|
-int minus_int; // expected-error {{expected external declaration}}
|
||||||
|
|
||||||
|
static int static_int() { return 1; }
|
||||||
|
|
||||||
|
#import "foo.h" // expected-error {{invalid preprocessing directive}}
|
||||||
|
|
||||||
|
int knr_fn(f) int f; { return 1; } // expected-error {{expected ';' after top level declarator}} expected-error {{expected unqualified-id}} expected-error {{unknown type name 'f'}}
|
||||||
|
|
||||||
|
// TODO: this should be an error, but there is no C++ mention in any errors in any case;
|
||||||
|
// the only error case we would have cared to fix is for Objective C++
|
||||||
|
// [[attribute]] int g_value;
|
||||||
|
|
||||||
|
int is_supported() {
|
||||||
|
// GNU Extensions (in impl-reserved namespace)
|
||||||
|
//KEYWORD(_Decimal32, KEYALL)
|
||||||
|
//KEYWORD(_Decimal64, KEYALL)
|
||||||
|
//KEYWORD(_Decimal128, KEYALL)
|
||||||
|
//KEYWORD(__null, KEYCXX)
|
||||||
|
//KEYWORD(__alignof, KEYALL)
|
||||||
|
//KEYWORD(__attribute, KEYALL)
|
||||||
|
//KEYWORD(__builtin_choose_expr, KEYALL)
|
||||||
|
//KEYWORD(__builtin_offsetof, KEYALL)
|
||||||
|
if (__builtin_types_compatible_p(int, int)) return 1; // expected-error {{expected '(' for function-style cast or type construction}} expected-error {{expected '(' for function-style cast or type construction}}
|
||||||
|
//KEYWORD(__builtin_va_arg, KEYALL)
|
||||||
|
//KEYWORD(__extension__, KEYALL)
|
||||||
|
//KEYWORD(__imag, KEYALL)
|
||||||
|
//KEYWORD(__int128, KEYALL)
|
||||||
|
//KEYWORD(__label__, KEYALL)
|
||||||
|
//KEYWORD(__real, KEYALL)
|
||||||
|
//KEYWORD(__thread, KEYALL)
|
||||||
|
//KEYWORD(__FUNCTION__, KEYALL)
|
||||||
|
//KEYWORD(__PRETTY_FUNCTION__, KEYALL)
|
||||||
|
|
||||||
|
// GNU and MS Type Traits
|
||||||
|
if (__has_nothrow_assign(int)) return 1; // expected-error {{__has_nothrow_assign is unsupported in HLSL}}
|
||||||
|
if (__has_nothrow_move_assign(int)) return 1; // expected-error {{__has_nothrow_move_assign is unsupported in HLSL}}
|
||||||
|
if (__has_nothrow_copy(int)) return 1; // expected-error {{__has_nothrow_copy is unsupported in HLSL}}
|
||||||
|
if (__has_nothrow_constructor(int)) return 1; // expected-error {{__has_nothrow_constructor is unsupported in HLSL}}
|
||||||
|
if (__has_trivial_assign(int)) return 1; // expected-error {{__has_trivial_assign is unsupported in HLSL}}
|
||||||
|
if (__has_trivial_move_assign(int)) return 1; // expected-error {{__has_trivial_move_assign is unsupported in HLSL}}
|
||||||
|
if (__has_trivial_copy(int)) return 1; // expected-error {{__has_trivial_copy is unsupported in HLSL}}
|
||||||
|
if (__has_trivial_constructor(int)) return 1; // expected-error {{__has_trivial_constructor is unsupported in HLSL}}
|
||||||
|
if (__has_trivial_move_constructor(int)) return 1; // expected-error {{__has_trivial_move_constructor is unsupported in HLSL}}
|
||||||
|
if (__has_trivial_destructor(int)) return 1; // expected-error {{__has_trivial_destructor is unsupported in HLSL}}
|
||||||
|
if (__has_virtual_destructor(int)) return 1; // expected-error {{__has_virtual_destructor is unsupported in HLSL}}
|
||||||
|
if (__is_abstract(int)) return 1; // expected-error {{__is_abstract is unsupported in HLSL}}
|
||||||
|
if (__is_base_of(int, int)) return 1; // expected-error {{__is_base_of is unsupported in HLSL}}
|
||||||
|
if (__is_class(int)) return 1; // expected-error {{__is_class is unsupported in HLSL}}
|
||||||
|
if (__is_convertible_to(int, int)) return 1; // expected-error {{__is_convertible_to is unsupported in HLSL}}
|
||||||
|
if (__is_empty(int)) return 1; // expected-error {{__is_empty is unsupported in HLSL}}
|
||||||
|
if (__is_enum(int)) return 1; // expected-error {{__is_enum is unsupported in HLSL}}
|
||||||
|
if (__is_final(int)) return 1; // expected-error {{__is_final is unsupported in HLSL}}
|
||||||
|
if (__is_literal(int)) return 1; // expected-error {{__is_literal is unsupported in HLSL}}
|
||||||
|
if (__is_literal_type(int)) return 1; // expected-error {{__is_literal is unsupported in HLSL}}
|
||||||
|
if (__is_pod(int)) return 1; // expected-error {{__is_pod is unsupported in HLSL}}
|
||||||
|
if (__is_polymorphic(int)) return 1; // expected-error {{__is_polymorphic is unsupported in HLSL}}
|
||||||
|
if (__is_trivial(int)) return 1; // expected-error {{__is_trivial is unsupported in HLSL}}
|
||||||
|
if (__is_union(int)) return 1; // expected-error {{__is_union is unsupported in HLSL}}
|
||||||
|
|
||||||
|
// Clang-only C++ Type Traits
|
||||||
|
if (__is_trivially_constructible(int)) return 1; // expected-error {{__is_trivially_constructible is unsupported in HLSL}}
|
||||||
|
if (__is_trivially_copyable(int)) return 1; // expected-error {{__is_trivially_copyable is unsupported in HLSL}}
|
||||||
|
if (__is_trivially_assignable(int, int)) return 1; // expected-error {{__is_trivially_assignable is unsupported in HLSL}}
|
||||||
|
|
||||||
|
// Embarcadero Expression Traits
|
||||||
|
if (__is_lvalue_expr(1)) return 1; // expected-error {{__is_lvalue_expr is unsupported in HLSL}}
|
||||||
|
if (__is_rvalue_expr(1)) return 1; // expected-error {{__is_rvalue_expr is unsupported in HLSL}}
|
||||||
|
|
||||||
|
// Embarcadero Unary Type Traits
|
||||||
|
if (__is_arithmetic(int)) return 1; // expected-error {{__is_arithmetic is unsupported in HLSL}}
|
||||||
|
if (__is_floating_point(int)) return 1; // expected-error {{__is_floating_point is unsupported in HLSL}}
|
||||||
|
if (__is_integral(int)) return 1; // expected-error {{__is_integral is unsupported in HLSL}}
|
||||||
|
if (__is_complete_type(int)) return 1; // expected-error {{__is_complete_type is unsupported in HLSL}}
|
||||||
|
if (__is_void(int)) return 1; // expected-error {{__is_void is unsupported in HLSL}}
|
||||||
|
if (__is_array(int)) return 1; // expected-error {{__is_array is unsupported in HLSL}}
|
||||||
|
if (__is_function(int)) return 1; // expected-error {{__is_function is unsupported in HLSL}}
|
||||||
|
if (__is_reference(int)) return 1; // expected-error {{__is_reference is unsupported in HLSL}}
|
||||||
|
if (__is_lvalue_reference(int)) return 1; // expected-error {{__is_lvalue_reference is unsupported in HLSL}}
|
||||||
|
if (__is_rvalue_reference(int)) return 1; // expected-error {{__is_rvalue_reference is unsupported in HLSL}}
|
||||||
|
if (__is_fundamental(int)) return 1; // expected-error {{__is_fundamental is unsupported in HLSL}}
|
||||||
|
if (__is_object(int)) return 1; // expected-error {{__is_object is unsupported in HLSL}}
|
||||||
|
if (__is_scalar(int)) return 1; // expected-error {{__is_scalar is unsupported in HLSL}}
|
||||||
|
if (__is_compound(int)) return 1; // expected-error {{__is_compound is unsupported in HLSL}}
|
||||||
|
if (__is_pointer(int)) return 1; // expected-error {{__is_pointer is unsupported in HLSL}}
|
||||||
|
if (__is_member_object_pointer(int)) return 1; // expected-error {{__is_member_object_pointer is unsupported in HLSL}}
|
||||||
|
if (__is_member_function_pointer(int)) return 1; // expected-error {{__is_member_function_pointer is unsupported in HLSL}}
|
||||||
|
if (__is_member_pointer(int)) return 1; // expected-error {{__is_member_pointer is unsupported in HLSL}}
|
||||||
|
if (__is_const(int)) return 1; // expected-error {{__is_const is unsupported in HLSL}}
|
||||||
|
if (__is_volatile(int)) return 1; // expected-error {{__is_volatile is unsupported in HLSL}}
|
||||||
|
if (__is_standard_layout(int)) return 1; // expected-error {{__is_standard_layout is unsupported in HLSL}}
|
||||||
|
if (__is_signed(int)) return 1; // expected-error {{__is_signed is unsupported in HLSL}}
|
||||||
|
if (__is_unsigned(int)) return 1; // expected-error {{__is_unsigned is unsupported in HLSL}}
|
||||||
|
|
||||||
|
// Embarcadero Binary Type Traits
|
||||||
|
if (__is_same(int, int)) return 1; // expected-error {{__is_same is unsupported in HLSL}}
|
||||||
|
if (__is_convertible(int, int)) return 1; // expected-error {{__is_convertible is unsupported in HLSL}}
|
||||||
|
if (__array_rank(int, 1)) return 1; // expected-error {{__array_rank is unsupported in HLSL}}
|
||||||
|
if (__array_extent(int, 1)) return 1; // expected-error {{__array_extent is unsupported in HLSL}}
|
||||||
|
|
||||||
|
__attribute__((common)) int i; // expected-error {{attribute annotations are unsupported in HLSL}}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
[availability(*, unavailable, renamed="somethingelse")] void fn_unavailable(); // expected-error {{'availability' is unsupported in HLSL}}
|
||||||
|
__declspec(align(16)) struct SAligned { int i; }; // expected-error {{'__declspec' is a reserved keyword in HLSL}}
|
||||||
|
void __fastcall fn_fastcall(); // expected-error {{'__fastcall' is a reserved keyword in HLSL}}
|
||||||
|
|
||||||
|
// These aren't even recognized as keywords.
|
||||||
|
int _pascal fn_pascal(); // expected-error {{expected ';' after top level declarator}}
|
||||||
|
int _kernel fn_kernel(); // expected-error {{expected ';' after top level declarator}}
|
||||||
|
int __private int__private; // expected-error {{expected ';' after top level declarator}}
|
||||||
|
int __global int__global; // expected-error {{expected ';' after top level declarator}}
|
||||||
|
int __local int__local; // expected-error {{expected ';' after top level declarator}}
|
||||||
|
int __constant int__constant; // expected-error {{expected ';' after top level declarator}}
|
||||||
|
int global intglobal; // expected-error {{expected ';' after top level declarator}}
|
||||||
|
int local intlocal; // expected-error {{expected ';' after top level declarator}}
|
||||||
|
int constant intconstant; // expected-error {{expected ';' after top level declarator}}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
// HLSL is different enough from C++ that this should be false.
|
||||||
|
#error __cplusplus is defined
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef void VOID_TYPE;
|
||||||
|
|
||||||
|
template <typename T> // expected-error {{'template' is a reserved keyword in HLSL}}
|
||||||
|
int fn_template(T t)
|
||||||
|
{
|
||||||
|
return (int)t;
|
||||||
|
}
|
||||||
|
|
||||||
|
int template; // expected-error {{'template' is a reserved keyword in HLSL}} expected-error {{expected unqualified-id}}
|
||||||
|
|
||||||
|
int get_value(VOID_TYPE) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" int get_value(int) { // expected-error {{expected unqualified-id}}
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
void vla(int size) {
|
||||||
|
int n[size]; // expected-error {{variable length arrays are not supported in HLSL}}
|
||||||
|
return n[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
enum MyEnum { MyEnum_MyVal1, MyEnum_MyVal2 }; // /* expected-error {{enum is unsupported in HLSL before 2017}} expected-warning {{declaration does not declare anything}} */
|
||||||
|
enum class MyEnumWithClass { MyEnumWithClass_MyVal1, MyEnumWithClass_MyVal2 }; // /* expected-error {{enum is unsupported in HLSL before 2017}} expected-warning {{declaration does not declare anything}} */
|
||||||
|
|
||||||
|
float4 fn_with_semantic() : SV_Target0{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
float4 fn_with_semantic_arg(float4 arg : SV_SOMETHING) : SV_Target0{
|
||||||
|
return arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fn_with_try_body()
|
||||||
|
try // expected-error {{expected function body after function declarator}}
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// unnamed namespace definition.
|
||||||
|
namespace { // expected-error {{expected identifier}}
|
||||||
|
int f_anon_ns_int;
|
||||||
|
}
|
||||||
|
|
||||||
|
// original namespace definition.
|
||||||
|
namespace MyNS {
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace MyNs::Nested { // expected-error {{nested namespace definition must define each namespace separately}}
|
||||||
|
}
|
||||||
|
|
||||||
|
// original namespace definition with inline.
|
||||||
|
inline namespace MyInlineNs { // expected-error {{expected unqualified-id}}
|
||||||
|
}
|
||||||
|
|
||||||
|
// extension namespace definition.
|
||||||
|
namespace MyNs {
|
||||||
|
int my_ns_extension;
|
||||||
|
}
|
||||||
|
|
||||||
|
// namespace alias definition.
|
||||||
|
namespace NamespaceAlias = MyNs; // expected-error {{expected identifier}}
|
||||||
|
|
||||||
|
using MyNS; // expected-error {{'using' is a reserved keyword in HLSL}}
|
||||||
|
int using; // expected-error {{'using' is a reserved keyword in HLSL}}
|
||||||
|
|
||||||
|
struct my_struct { };
|
||||||
|
|
||||||
|
class my_class { };
|
||||||
|
|
||||||
|
interface my_interface { };
|
||||||
|
|
||||||
|
class my_class_2 : my_class { };
|
||||||
|
|
||||||
|
class my_class_3 : my_interface { };
|
||||||
|
|
||||||
|
class my_class_4 : my_struct { };
|
||||||
|
|
||||||
|
struct my_struct_2 : my_struct { };
|
||||||
|
|
||||||
|
struct my_struct_3 : my_class { };
|
||||||
|
|
||||||
|
struct my_struct_4 : my_interface { };
|
||||||
|
struct my_struct_5 : my_class, my_interface { };
|
||||||
|
struct my_struct_6 : my_class, my_interface, my_struct { }; // expected-error {{multiple concrete base types specified}}
|
||||||
|
|
||||||
|
interface my_interface_2 : my_interface { }; // expected-error {{interfaces cannot inherit from other types}}
|
||||||
|
|
||||||
|
class my_class_public : public my_class { }; // expected-error {{base type access specifier is unsupported in HLSL}}
|
||||||
|
|
||||||
|
struct forward_struct; // this fails in fxc, but we allow it now /* expected-error {{struct declaration without definition is unsupported in HLSL}} */
|
||||||
|
struct my_struct_type_decl { int a; } my_struct_var_decl;
|
||||||
|
struct my_struct_type_decl_parens { int a; } (my_struct_var_decl_parens); // expected-error {{HLSL requires a type specifier for all declarations}} expected-error {{expected ';' after struct}}
|
||||||
|
struct my_struct_type_const { int a; } const my_struct_type_var; // // expected-error {{HLSL requires a type specifier for all declarations}} expected-error {{expected ';' after struct}}
|
||||||
|
struct my_struct_type_init { int a; } my_struct_type_init_one = { 1 }, my_struct_type_init_two = { 2 };
|
||||||
|
struct my_struct_type_static { int a; } static my_struct_type_static; // expected-error {{expected ';' after struct}} expected-warning {{declaration does not declare anything}}
|
||||||
|
struct { int my_anon_struct_field; } my_anon_struct_type;
|
||||||
|
|
||||||
|
void fn_my_struct_type_decl() {
|
||||||
|
my_struct_type_decl local_var;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct s_with_template_member {
|
||||||
|
template<typename T> T fn(); // expected-error {{'template' is a reserved keyword in HLSL}}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct s_with_using {
|
||||||
|
using MyNS; // expected-error {{'using' is a reserved keyword in HLSL}}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct s_with_init {
|
||||||
|
int i = 1; // expected-error {{struct/class members cannot have default values}}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct s_with_multiple {
|
||||||
|
int i, j;
|
||||||
|
};
|
||||||
|
|
||||||
|
class c_outer {
|
||||||
|
struct { int allowed; };
|
||||||
|
struct c_inner { int disallowed; }; // expected-error {{nested named class/struct/interfaces are not supported in HLSL}}
|
||||||
|
};
|
||||||
|
|
||||||
|
class c_outer_typedef {
|
||||||
|
typedef int local_int; // expected-error {{nested typedefs are not supported in HLSL}}
|
||||||
|
};
|
||||||
|
|
||||||
|
class c_outer_fn {
|
||||||
|
int fn() {
|
||||||
|
class local_class { int j; };
|
||||||
|
typedef int local_int;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class c_public {
|
||||||
|
public: int i; // expected-error {{'public' is a reserved keyword in HLSL}}
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace ns_with_struct {
|
||||||
|
struct s { int i; };
|
||||||
|
}
|
||||||
|
|
||||||
|
matrix<int...> g_matrix_pack; // expected-error {{ellipsis is unsupported in HLSL}}
|
||||||
|
matrix<ns_with_struct::s> g_matrix_ns; // expected-error {{'ns_with_struct::s' cannot be used as a type parameter where a scalar is required}}
|
||||||
|
matrix<int, 1, 2> g_matrix_simple;
|
||||||
|
matrix<s_with_multiple, 1, 2> g_matrix_user; // expected-error {{'s_with_multiple' cannot be used as a type parameter where a scalar is required}}
|
||||||
|
matrix<float2, 1, 1> g_matrix_vector_shorthand; // expected-error {{'float2' cannot be used as a type parameter where a scalar is required}}
|
||||||
|
matrix<template matrix<typename, 1, 2> > g_matrix_template_template; // expected-error {{expected expression}} expected-error {{expected unqualified-id}}
|
||||||
|
matrix<matrix<typename, 1, 2> > g_matrix_template_template_nokw; // expected-error {{expected a qualified name after 'typename'}} expected-error {{expected a type}} expected-error {{expected a type}}
|
||||||
|
matrix<matrix<float, 1, 2> ... > g_matrix_template_template_ellipsis; // expected-error {{ellipsis is unsupported in HLSL}}
|
||||||
|
|
||||||
|
#pragma unknown
|
||||||
|
|
||||||
|
int global_fn() { return 1; }
|
||||||
|
void fn_int_arg(int);
|
||||||
|
|
||||||
|
void statements()
|
||||||
|
{
|
||||||
|
int local_i = 1; // expected-note {{declared here}}
|
||||||
|
|
||||||
|
// attempt to parse a label.
|
||||||
|
my_label: local_i = 1; // expected-error {{label is unsupported in HLSL}}
|
||||||
|
|
||||||
|
// attempt to parse an obj-c statement
|
||||||
|
@throw local_i; // expected-error {{expected expression}}
|
||||||
|
|
||||||
|
// verify that compound statement blocks have their own scope
|
||||||
|
{
|
||||||
|
// inner block with scope
|
||||||
|
float local_f;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// inner block with scope
|
||||||
|
double local_f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// verify that GNU local label (__label__) is disallowed
|
||||||
|
{
|
||||||
|
__label__ X, Y; // expected-error {{local label is unsupported in HLSL}}
|
||||||
|
}
|
||||||
|
|
||||||
|
// expression statements
|
||||||
|
(void)local_i; // disallowed in fxc as the cast is impossible, but allowed for compat now
|
||||||
|
local_i;
|
||||||
|
|
||||||
|
if (local_i == 0) {
|
||||||
|
local_i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (int my_if_local = global_fn()) { // this is an addition to fxc HLSL
|
||||||
|
local_i++;
|
||||||
|
my_if_local++;
|
||||||
|
} else {
|
||||||
|
my_if_local--;
|
||||||
|
}
|
||||||
|
// declaration in 'if' conditional clause does not leak out
|
||||||
|
my_if_local++; // expected-error {{use of undeclared identifier 'my_if_local'}}
|
||||||
|
|
||||||
|
switch (int my_switch_local = global_fn()) {
|
||||||
|
case 0: my_switch_local--; return;
|
||||||
|
}
|
||||||
|
while (int my_while_local = global_fn()) {
|
||||||
|
my_while_local--;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(local_i) {
|
||||||
|
case 0:
|
||||||
|
local_i = 2;
|
||||||
|
break;
|
||||||
|
case 1 + 2:
|
||||||
|
local_i = 3;
|
||||||
|
break;
|
||||||
|
case local_i: // expected-error {{expression is not an integral constant expression}} expected-note {{read of non-const variable 'local_i' is not allowed in a constant expression}}
|
||||||
|
break;
|
||||||
|
case 10 ... 12: // expected-error {{case range is unsupported in HLSL}}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
local_i = 100;
|
||||||
|
// fall through
|
||||||
|
}
|
||||||
|
|
||||||
|
while (local_i > 0) {
|
||||||
|
local_i -= 1;
|
||||||
|
if (local_i == 1) continue;
|
||||||
|
if (local_i == 2) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
asm(); // expected-error {{'asm' is a reserved keyword in HLSL}}
|
||||||
|
|
||||||
|
try { // expected-error {{'try' is a reserved keyword in HLSL}}
|
||||||
|
local_i = 1;
|
||||||
|
} catch(...) {
|
||||||
|
local_i = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// do/while (without braces)
|
||||||
|
do local_i += 1; while (local_i < 3);
|
||||||
|
|
||||||
|
// for, leaking declaration from control part
|
||||||
|
for (int i = 0; i < 10; ++i) {
|
||||||
|
local_i = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
local_i = i - 1;
|
||||||
|
// for, not leaking declaration from body
|
||||||
|
for (int val = 0; i < 10; ++i) {
|
||||||
|
int val_inner = val;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
local_i = val_inner; // expected-error {{use of undeclared identifier 'val_inner'}}
|
||||||
|
// for, redeclaring local
|
||||||
|
int red_same; // expected-note {{previous definition is here}}
|
||||||
|
for (int red_same = 0;;) break; // expected-warning {{redefinition of 'red_same' shadows declaration in the outer scope; most recent declaration will be used}}
|
||||||
|
// for, redeclaring local with different type
|
||||||
|
int red_different; // expected-note {{previous definition is here}}
|
||||||
|
for (float red_different = 0;;) break; // expected-warning {{redefinition of 'red_different' with a different type: 'float' vs 'int' shadows declaration in the outer scope; most recent declaration will be used}}
|
||||||
|
|
||||||
|
// this proves that the more recent variable is in scope
|
||||||
|
int2 red_i_then_int = 0; // expected-note {{previous definition is here}}
|
||||||
|
for (int red_i_then_int = 0;;) break; //expected-warning {{redefinition of 'red_i_then_int' with a different type: 'int' vs 'int2' shadows declaration in the outer scope; most recent declaration will be used}}
|
||||||
|
fn_int_arg(red_i_then_int);
|
||||||
|
fn_int_arg(int2(0,0)); // int2 to int conversion is allowed // expected-warning {{implicit truncation of vector type}}
|
||||||
|
|
||||||
|
// for without declaration
|
||||||
|
for (local_i = 0; ;) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// for without initialization
|
||||||
|
for (int j;;) { break; }
|
||||||
|
// ranged for is disallowed
|
||||||
|
for (int n : local_i) { // expected-error {{expected ';' in 'for' statement specifier}} expected-error {{expected ';' in 'for' statement specifier}} expected-error {{semantic is not a valid modifier for a local variable}}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
for (int n_again in local_i) { // expected-error {{expected ';' in 'for' statement specifier}} expected-error {{expected unqualified-id}} expected-error {{unknown type name 'local_i'}} expected-error {{variable declaration in condition must have an initializer}}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if/else
|
||||||
|
if (local_i == 0)
|
||||||
|
local_i = 1;
|
||||||
|
else {
|
||||||
|
local_i = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// empty/null statements
|
||||||
|
;;;
|
||||||
|
|
||||||
|
switch (local_i) {
|
||||||
|
default: // expected-error {{label at end of compound statement: expected statement}}
|
||||||
|
}
|
||||||
|
|
||||||
|
// goto statement
|
||||||
|
goto my_label; // expected-error {{goto is unsupported in HLSL}}
|
||||||
|
|
||||||
|
// return statement
|
||||||
|
return;
|
||||||
|
|
||||||
|
// discard statement
|
||||||
|
discard;
|
||||||
|
}
|
||||||
|
|
||||||
|
void expressions()
|
||||||
|
{
|
||||||
|
int local_i;
|
||||||
|
local_i = 1 > 2 ? 0 : 1;
|
||||||
|
|
||||||
|
// GNU extension to ternary operator, missing second argument to mean first
|
||||||
|
local_i = 1 > 2 ? : 1; // expected-error {{use of GNU ?: conditional expression extension, omitting middle operand is unsupported in HLSL}}
|
||||||
|
|
||||||
|
// initializer lists as right-hand in binary operator (err_init_list_bin_op), but HLSL does not support init lists here
|
||||||
|
local_i = 1 + 2 * { 1 }; // expected-error {{expected expression}}
|
||||||
|
|
||||||
|
local_i = true;
|
||||||
|
local_i = __objc_no; // expected-error {{'__objc_no' is a reserved keyword in HLSL}}
|
||||||
|
local_i = __objc_yes; // expected-error {{'__objc_yes' is a reserved keyword in HLSL}}
|
||||||
|
local_i = nullptr; // expected-error {{use of undeclared identifier 'nullptr'}}
|
||||||
|
local_i = decltype(1)(1); // expected-error {{use of undeclared identifier 'decltype'}}
|
||||||
|
local_i = __is_integral(bool); // expected-error {{__is_integral is unsupported in HLSL}}
|
||||||
|
local_i = &local_i; // expected-error {{operator is not supported}}
|
||||||
|
local_i = 'c'; // this is fine
|
||||||
|
local_i = '\xFF'; // this is fine
|
||||||
|
local_i = 'ab'; // expected-error {{unsupported style of char literal - use a single-character char-based literal}} expected-warning {{multi-character character constant}}
|
||||||
|
local_i = L'a'; // expected-error {{non-ASCII/multiple-char character constant is unsupported in HLSL}}
|
||||||
|
local_i = L"AB"; // expected-error {{non-ASCII string constant is unsupported in HLSL}}
|
||||||
|
local_i = __FUNCTION__; // expected-error {{'__FUNCTION__' is a reserved keyword in HLSL}}
|
||||||
|
local_i = _Generic('a',default:0); // expected-error {{'_Generic' is a reserved keyword in HLSL}}
|
||||||
|
// for string literals, see string.hlsl
|
||||||
|
local_i = *local_i; // expected-error {{operator is not supported}}
|
||||||
|
local_i = +local_i;
|
||||||
|
local_i = -local_i;
|
||||||
|
local_i = ~local_i;
|
||||||
|
local_i = !local_i;
|
||||||
|
local_i = __real local_i; // expected-error {{'__real' is a reserved keyword in HLSL}}
|
||||||
|
local_i = __imag local_i; // expected-error {{'__imag' is a reserved keyword in HLSL}}
|
||||||
|
local_i = typeid 123; // expected-error {{'typeid' is a reserved keyword in HLSL}}
|
||||||
|
local_i = __uuidof(local_i); // expected-error {{use of undeclared identifier '__uuidof'}}
|
||||||
|
struct CInternal {
|
||||||
|
int i;
|
||||||
|
int fn() { return this.i; }
|
||||||
|
CInternal getSelf() { return this; }
|
||||||
|
int operator+(int); // expected-error {{'operator' is a reserved keyword in HLSL}}
|
||||||
|
};
|
||||||
|
if (__is_pod(int)) { } // expected-error {{__is_pod is unsupported in HLSL}}
|
||||||
|
^(int x){ return x + 1; }; // expected-error {{block is unsupported in HLSL}} expected-error {{compound literal is unsupported in HLSL}} expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||||
|
CInternal internal;
|
||||||
|
internal->fn(); // expected-error {{operator is not supported}}
|
||||||
|
local_i = (int3) { 1, 2, 3 }; // expected-error {{compound literal is unsupported in HLSL}}
|
||||||
|
|
||||||
|
Texture2D<::c_outer_fn> local_texture; // expected-error {{'::c_outer_fn' cannot be used as a type parameter}}
|
||||||
|
::new local_new; // expected-error {{new' is a reserved keyword in HLSL}}
|
||||||
|
::template foo local_template; // expected-error {{'template' is a reserved keyword in HLSL}} expected-error {{unknown type name 'foo'}}
|
||||||
|
|
||||||
|
class CInlineWithTry {
|
||||||
|
void fn()
|
||||||
|
try // expected-error {{expected function body after function declarator}}
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
}
|
||||||
|
catch(...)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void fn_other()
|
||||||
|
try // expected-error {{expected function body after function declarator}}
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int local_field_1 = 1; // expected-error {{struct/class members cannot have default values}}
|
||||||
|
int local_field_2[] = { 1 }; // expected-error {{array bound cannot be deduced from an in-class initializer}} expected-error {{array dimensions of struct/class members must be explicit}} expected-error {{struct/class members cannot have default values}}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pragmas.
|
||||||
|
// TODO: unhandled pragmas should result in a warning
|
||||||
|
int unused_i;
|
||||||
|
#pragma unused(unused_i)
|
||||||
|
#pragma unknown
|
||||||
|
#pragma GCC visibility push(public)
|
||||||
|
#pragma pack(push, 1)
|
||||||
|
#pragma ms_struct(on)
|
||||||
|
#pragma comment(lib, "kernel32.lib")
|
||||||
|
#pragma align 64
|
||||||
|
#pragma weak expressions
|
||||||
|
#pragma weak expressions = expressions
|
||||||
|
#pragma redefine_extname g_int new_name_g_int
|
||||||
|
#pragma STDC FP_CONTRACT on
|
||||||
|
#pragma OPENCL EXTENSION
|
||||||
|
#pragma clang __debug captured
|
||||||
|
#pragma
|
||||||
|
|
||||||
|
// Preprocessor directives.
|
||||||
|
#define A_DEFINE 1
|
||||||
|
#if (A_DEFINE==1)
|
||||||
|
#elif (A_DEFINE==2)
|
||||||
|
#else
|
||||||
|
#warning it does not work
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Verified this works but it trips the error processor.
|
||||||
|
// #error err
|
||||||
|
|
||||||
|
#ifdef A_DEFINE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#undef A_DEFINE
|
||||||
|
#ifndef A_DEFINE
|
||||||
|
#else
|
||||||
|
#error it does not work
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#line 321
|
||||||
|
int;
|
||||||
|
// expected-warning@321 {{declaration does not declare anything}}
|
||||||
|
|
||||||
|
float4 plain(float4 param4 /* : FOO */) /*: FOO */{
|
||||||
|
int i[0]; // expected-error {{array dimension must be between 1 and 65536}}
|
||||||
|
const j; // expected-error {{HLSL requires a type specifier for all declarations}}
|
||||||
|
long long ll; // expected-error {{'long' is a reserved keyword in HLSL}} expected-error {{'long' is a reserved keyword in HLSL}} expected-error {{HLSL requires a type specifier for all declarations}}
|
||||||
|
return is_supported();
|
||||||
|
}
|
|
@ -251,8 +251,8 @@ void vla(int size) {
|
||||||
return n[0];
|
return n[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
enum MyEnum { MyEnum_MyVal1, MyEnum_MyVal2 }; //
|
enum MyEnum { MyEnum_MyVal1, MyEnum_MyVal2 };
|
||||||
enum class MyEnumWithClass { MyEnumWithClass_MyVal1, MyEnumWithClass_MyVal2 }; //
|
enum class MyEnumWithClass { MyEnumWithClass_MyVal1, MyEnumWithClass_MyVal2 };
|
||||||
|
|
||||||
float4 fn_with_semantic() : SV_Target0{
|
float4 fn_with_semantic() : SV_Target0{
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -348,7 +348,8 @@ struct s_with_multiple {
|
||||||
};
|
};
|
||||||
|
|
||||||
class c_outer {
|
class c_outer {
|
||||||
class c_inner { int disallowed; }; // expected-error {{nested class is unsupported in HLSL}}
|
struct { int allowed; };
|
||||||
|
struct c_inner { int allowed_HV2016; };
|
||||||
};
|
};
|
||||||
|
|
||||||
class c_outer_typedef {
|
class c_outer_typedef {
|
||||||
|
@ -596,7 +597,7 @@ void expressions()
|
||||||
}
|
}
|
||||||
|
|
||||||
int local_field_1 = 1; // expected-error {{struct/class members cannot have default values}}
|
int local_field_1 = 1; // expected-error {{struct/class members cannot have default values}}
|
||||||
int local_field_2[] = { 1 }; // expected-error {{array dimensions of struct/class members must be explicit}} expected-error {{array bound cannot be deduced from an in-class initializer}} expected-error {{struct/class members cannot have default values}}
|
int local_field_2[] = { 1 }; // expected-error {{array bound cannot be deduced from an in-class initializer}} expected-error {{array dimensions of struct/class members must be explicit}} expected-error {{struct/class members cannot have default values}}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,7 @@ public:
|
||||||
TEST_METHOD(RunConstAssign)
|
TEST_METHOD(RunConstAssign)
|
||||||
TEST_METHOD(RunConstDefault)
|
TEST_METHOD(RunConstDefault)
|
||||||
TEST_METHOD(RunCppErrors)
|
TEST_METHOD(RunCppErrors)
|
||||||
|
TEST_METHOD(RunCppErrorsHV2015)
|
||||||
TEST_METHOD(RunCXX11Attributes)
|
TEST_METHOD(RunCXX11Attributes)
|
||||||
TEST_METHOD(RunEnums)
|
TEST_METHOD(RunEnums)
|
||||||
TEST_METHOD(RunFunctions)
|
TEST_METHOD(RunFunctions)
|
||||||
|
@ -152,6 +153,10 @@ TEST_F(VerifierTest, RunCppErrors) {
|
||||||
CheckVerifiesHLSL(L"cpp-errors.hlsl");
|
CheckVerifiesHLSL(L"cpp-errors.hlsl");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(VerifierTest, RunCppErrorsHV2015) {
|
||||||
|
CheckVerifiesHLSL(L"cpp-errors-hv2015.hlsl");
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(VerifierTest, RunCXX11Attributes) {
|
TEST_F(VerifierTest, RunCXX11Attributes) {
|
||||||
CheckVerifiesHLSL(L"cxx11-attributes.hlsl");
|
CheckVerifiesHLSL(L"cxx11-attributes.hlsl");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1008,6 +1008,9 @@ TEST_F(FileTest, IntrinsicsNonUniformResourceIndex) {
|
||||||
TEST_F(FileTest, AttributeEarlyDepthStencil) {
|
TEST_F(FileTest, AttributeEarlyDepthStencil) {
|
||||||
runFileTest("attribute.earlydepthstencil.ps.hlsl");
|
runFileTest("attribute.earlydepthstencil.ps.hlsl");
|
||||||
}
|
}
|
||||||
|
TEST_F(FileTest, AttributePostDepthCoverage) {
|
||||||
|
runFileTest("attribute.postdepthcoverage.ps.hlsl");
|
||||||
|
}
|
||||||
TEST_F(FileTest, AttributeNumThreads) {
|
TEST_F(FileTest, AttributeNumThreads) {
|
||||||
runFileTest("attribute.numthreads.hlsl");
|
runFileTest("attribute.numthreads.hlsl");
|
||||||
}
|
}
|
||||||
|
@ -1315,6 +1318,10 @@ TEST_F(FileTest, SpirvDebugOpSource) {
|
||||||
runFileTest("spirv.debug.opsource.hlsl");
|
runFileTest("spirv.debug.opsource.hlsl");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(FileTest, SpirvDebugOpLine) {
|
||||||
|
runFileTest("spirv.debug.opline.hlsl");
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(FileTest, VulkanAttributeErrors) {
|
TEST_F(FileTest, VulkanAttributeErrors) {
|
||||||
runFileTest("vk.attribute.error.hlsl", Expect::Failure);
|
runFileTest("vk.attribute.error.hlsl", Expect::Failure);
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче