Add string type and enable top level static const declaration of strings
in preparation for future features. Static const is always implied.
Arrays, vectors and matrices of string are prohibited. Strings in function
parameters, return values and bodies are currently not supported either.
This commit is contained in:
Helena Kotas 2018-10-17 20:15:38 -07:00 коммит произвёл GitHub
Родитель 16a5f94ab2
Коммит 527bfc4176
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
14 изменённых файлов: 291 добавлений и 24 удалений

Просмотреть файл

@ -842,6 +842,8 @@ public:
CanQualType Min12IntTy, Min10FloatTy;
CanQualType LitIntTy, LitFloatTy;
CanQualType HalfFloatTy, Min16FloatTy, Min16IntTy, Min16UIntTy;
CanQualType HLSLStringTy;
// HLSL Changes end
// Types for deductions in C++0x [stmt.ranged]'s desugaring. Built on demand.
@ -903,6 +905,11 @@ public:
/// \brief Retrieve the declaration for a 128-bit float stub type.
TypeDecl *getFloat128StubType() const;
// HLSL Change Starts
/// \brief Retrieve the declaration for HLSL string type.
TypedefDecl *getHLSLStringTypedef() const;
// HSLS CHange Ends
//===--------------------------------------------------------------------===//
// Type Constructors
//===--------------------------------------------------------------------===//

Просмотреть файл

@ -388,6 +388,11 @@ unsigned GetHLSLInputPatchCount(clang::QualType type);
clang::QualType GetHLSLOutputPatchElementType(clang::QualType type);
unsigned GetHLSLOutputPatchCount(clang::QualType type);
bool IsArrayConstantStringType(const clang::QualType type);
bool IsPointerStringType(const clang::QualType type);
bool IsStringType(const clang::QualType type);
bool IsStringLiteralType(const clang::QualType type);
void GetRowsAndColsForAny(clang::QualType type, uint32_t &rowCount,
uint32_t &colCount);
uint32_t GetElementCount(clang::QualType type);
@ -461,6 +466,13 @@ bool TryParseAny(
_Out_ int *colCount,
_In_ const clang::LangOptions& langOption);
_Success_(return != false)
bool TryParseString(
_In_count_(typenameLen)
const char* typeName,
size_t typeNameLen,
_In_ const clang::LangOptions& langOptions);
_Success_(return != false)
bool TryParseMatrixOrVectorDimension(
_In_count_(typeNameLen)

Просмотреть файл

@ -7650,6 +7650,8 @@ def warn_hlsl_effect_object : Warning <
def warn_hlsl_unused_call : Warning<
"ignoring return value of function that only reads data">,
InGroup<UnusedValue>;
def err_hlsl_string_not_global : Error<
"string declaration may only appear in global scope">;
def err_hlsl_func_in_func_decl : Error<
"function declaration is not allowed in function parameters">;
def err_hlsl_unsupported_keyword_for_version : Error<
@ -7675,6 +7677,8 @@ def err_hlsl_missing_patchconstantfunc_attr: Error<
"HS entry point must have the patchconstantfunc attribute">;
def err_hlsl_missing_inout_attr: Error<
"stream-output object must be an inout parameter">;
def err_hlsl_unsupported_string_decl: Error<
"%select{array|parameter|return value}0 of type string is not supported">;
// HLSL Change Ends
// SPIRV Change Starts

Просмотреть файл

@ -1102,6 +1102,9 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target) {
InitBuiltinType(HalfFloatTy, BuiltinType::HalfFloat);
InitBuiltinType(LitIntTy, BuiltinType::LitInt);
InitBuiltinType(LitFloatTy, BuiltinType::LitFloat);
HLSLStringTy = this->getPointerType(CharTy);
hlsl::InitializeASTContextForHLSL(*this); // Previously in constructor, guarded by !DelayInitialization
}
// HLSL Change Ends

Просмотреть файл

@ -1071,6 +1071,20 @@ bool hlsl::TryParseAny(
return false;
}
/// <summary>Parse string hlsl type</summary>
_Use_decl_annotations_
bool hlsl::TryParseString(
_In_count_(typenameLen)
const char* typeName,
size_t typeNameLen,
_In_ const clang::LangOptions& langOptions) {
if (typeNameLen == 6 && typeName[0] == 's' && strncmp(typeName, "string", 6) == 0) {
return true;
}
return false;
}
/// <summary>Parse any kind of dimension for vector or matrix (e.g 4,3 in int4x3).
/// If it's a matrix type, rowCount and colCount will be nonzero. If it's a vector type, colCount is 0.
/// Otherwise both rowCount and colCount is 0. Returns true if either matrix or vector dimensions detected. </summary>

Просмотреть файл

@ -13,6 +13,7 @@
// //
///////////////////////////////////////////////////////////////////////////////
#include "dxc/Support/Global.h"
#include "clang/AST/CanonicalType.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/HlslTypes.h"
@ -276,6 +277,26 @@ void GetRowsAndCols(clang::QualType type, uint32_t &rowCount,
colCount = colSize.getLimitedValue();
}
bool IsArrayConstantStringType(const QualType type) {
DXASSERT_NOMSG(type->isArrayType());
return type->getArrayElementTypeNoTypeQual()->isSpecificBuiltinType(BuiltinType::Char_S);
}
bool IsPointerStringType(const QualType type) {
DXASSERT_NOMSG(type->isPointerType());
return type->getPointeeType()->isSpecificBuiltinType(BuiltinType::Char_S);
}
bool IsStringType(const QualType type) {
QualType canType = type.getCanonicalType();
return canType->isPointerType() && IsPointerStringType(canType);
}
bool IsStringLiteralType(const QualType type) {
QualType canType = type.getCanonicalType();
return canType->isArrayType() && IsArrayConstantStringType(canType);
}
void GetRowsAndColsForAny(QualType type, uint32_t &rowCount,
uint32_t &colCount) {
assert(!type.isNull());
@ -284,7 +305,7 @@ void GetRowsAndColsForAny(QualType type, uint32_t &rowCount,
rowCount = 1;
colCount = 1;
const Type *Ty = type.getCanonicalType().getTypePtr();
if (type->isArrayType()) {
if (type->isArrayType() && !IsArrayConstantStringType(type)) {
if (type->isConstantArrayType()) {
const ConstantArrayType *arrayType =
(const ConstantArrayType *)type->getAsArrayTypeUnsafe();
@ -479,6 +500,7 @@ bool IsHLSLResourceType(clang::QualType type) {
}
return false;
}
QualType GetHLSLResourceResultType(QualType type) {
type = type.getCanonicalType();
const RecordType *RT = cast<RecordType>(type);

Просмотреть файл

@ -254,6 +254,11 @@ public:
Value *VisitCharacterLiteral(const CharacterLiteral *E) {
return llvm::ConstantInt::get(ConvertType(E->getType()), E->getValue());
}
// HLSL Change Start
Value *VisitStringLiteral(const StringLiteral *E) {
return CGF.CGM.GetConstantArrayFromStringLiteral(E);
}
// HLSL Change End
Value *VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *E) {
return llvm::ConstantInt::get(ConvertType(E->getType()), E->getValue());
}

Просмотреть файл

@ -156,6 +156,10 @@ private:
std::unordered_map<Value *, DebugLoc> debugInfoMap;
DxilRootSignatureVersion rootSigVer;
// Strings
std::vector<GlobalVariable *> globalStringsDecls;
std::vector<GlobalVariable *> globalStringsConstants;
Value *EmitHLSLMatrixLoad(CGBuilderTy &Builder, Value *Ptr, QualType Ty);
void EmitHLSLMatrixStore(CGBuilderTy &Builder, Value *Val, Value *DestPtr,
@ -244,6 +248,10 @@ public:
void SetPatchConstantFunctionWithAttr(
const EntryFunctionInfo &EntryFunc,
const clang::HLSLPatchConstantFuncAttr *PatchConstantFuncAttr);
void AddGlobalStringDecl(const clang::VarDecl *D, llvm::GlobalVariable *GV) override;
void AddGlobalStringConstant(llvm::GlobalVariable *GV) override;
void FinishCodeGen() override;
bool IsTrivalInitListExpr(CodeGenFunction &CGF, InitListExpr *E) override;
Value *EmitHLSLInitListExpr(CodeGenFunction &CGF, InitListExpr *E, Value *DestPtr) override;
@ -1043,6 +1051,9 @@ unsigned CGMSHLSLRuntime::AddTypeAnnotation(QualType Ty,
AddTypeAnnotation(GetHLSLResourceResultType(Ty), dxilTypeSys, arrayEltSize);
// Resource don't count for cbuffer size.
return 0;
} else if (IsStringType(Ty)) {
// string won't be included in cbuffer
return 0;
} else {
unsigned arraySize = 0;
QualType arrayElementTy = Ty;
@ -4570,6 +4581,20 @@ static void CreateWriteEnabledStaticGlobals(llvm::Module *M,
}
}
void CGMSHLSLRuntime::AddGlobalStringDecl(const clang::VarDecl *D, llvm::GlobalVariable *GV) {
DXASSERT_NOMSG(hlsl::IsStringType(D->getType()));
DXASSERT(D->getDeclContext()->isTranslationUnit(), "must be a global");
globalStringsDecls.emplace_back(GV);
}
void CGMSHLSLRuntime::AddGlobalStringConstant(llvm::GlobalVariable *GV) {
DXASSERT(GV->getType()->isPointerTy() &&
GV->getType()->getPointerElementType()->isArrayTy() &&
GV->getType()->getPointerElementType()->getArrayElementType() == llvm::Type::getInt8Ty(Context), "must be i8[]");
globalStringsConstants.emplace_back(GV);
}
void CGMSHLSLRuntime::FinishCodeGen() {
// Library don't have entry.
if (!m_bIsLib) {

Просмотреть файл

@ -19,6 +19,7 @@ template <typename T, unsigned N> class SmallVector;
class Value;
class Constant;
class TerminatorInst;
class GlobalVariable;
class Type;
template <typename T> class ArrayRef;
}
@ -116,6 +117,9 @@ public:
virtual void AddHLSLFunctionInfo(llvm::Function *, const FunctionDecl *FD) = 0;
virtual void EmitHLSLFunctionProlog(llvm::Function *, const FunctionDecl *FD) = 0;
virtual void AddGlobalStringDecl(const clang::VarDecl *D, llvm::GlobalVariable *GV) = 0;
virtual void AddGlobalStringConstant(llvm::GlobalVariable *GV) = 0;
virtual bool IsHlslObjectType(llvm::Type *Ty) = 0;
virtual void AddControlFlowHint(CodeGenFunction &CGF, const Stmt &S, llvm::TerminatorInst *TI, llvm::ArrayRef<const Attr *> Attrs) = 0;

Просмотреть файл

@ -1869,6 +1869,12 @@ CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName,
if (AddrSpace != Ty->getAddressSpace() && !LangOpts.HLSL) // HLSL Change -TODO: do we put address space in type?
return llvm::ConstantExpr::getAddrSpaceCast(GV, Ty);
// HLSL Change start
if (hlsl::IsStringType(D->getType())) {
getHLSLRuntime().AddGlobalStringDecl(D, GV);
}
// HLSL Change end
return GV;
}
@ -3043,6 +3049,10 @@ GenerateStringLiteral(llvm::Constant *C, llvm::GlobalValue::LinkageTypes LT,
GV->setComdat(M.getOrInsertComdat(GV->getName()));
}
// HLSL Change Start
CGM.getHLSLRuntime().AddGlobalStringConstant(GV);
// HLSL CHange End
return GV;
}

Просмотреть файл

@ -10266,6 +10266,11 @@ Decl *Sema::ActOnParamDeclarator(Scope *S, Declarator &D) {
// HLSL Change Starts
if (getLangOpts().HLSL) {
const bool IsParm = true;
if (hlsl::IsStringType(parmDeclType)) {
static const unsigned selectParamIdx = 1;
Diag(D.getLocStart(), diag::err_hlsl_unsupported_string_decl) << selectParamIdx;
D.setInvalidType();
}
if (!DiagnoseHLSLDecl(D, Context.getTranslationUnitDecl(), TInfo, IsParm)) {
assert(D.isInvalidType() && "otherwise DiagnoseHLSLDecl failed but "
"didn't invalidate declaration");

Просмотреть файл

@ -84,6 +84,7 @@ enum ArBasicKind {
AR_BASIC_ENUM_CLASS,
AR_OBJECT_NULL,
AR_OBJECT_STRING_LITERAL,
AR_OBJECT_STRING,
// AR_OBJECT_TEXTURE,
@ -360,6 +361,7 @@ const UINT g_uBasicKindProps[] =
BPROP_ENUM, // AR_BASIC_ENUM_CLASS
BPROP_OBJECT | BPROP_RBUFFER, // AR_OBJECT_NULL
BPROP_OBJECT | BPROP_RBUFFER, // AR_OBJECT_STRING_LITERAL
BPROP_OBJECT | BPROP_RBUFFER, // AR_OBJECT_STRING
@ -541,6 +543,7 @@ enum ArTypeObjectKind {
AR_TOBJ_QUALIFIER, // Represents another type plus an ArTypeQualifier.
AR_TOBJ_INNER_OBJ, // Represents a built-in inner object, such as an
// indexer object used to implement .mips[1].
AR_TOBJ_STRING, // Represents a string
};
enum TYPE_CONVERSION_FLAGS
@ -1087,6 +1090,7 @@ static const ArBasicKind g_UDTCT[] =
static const ArBasicKind g_StringCT[] =
{
AR_OBJECT_STRING_LITERAL,
AR_OBJECT_STRING,
AR_BASIC_UNKNOWN
};
@ -1424,6 +1428,7 @@ const char* g_ArBasicTypeNames[] =
"enum class",
"null",
"literal string",
"string",
// "texture",
"Texture1D",
@ -2592,6 +2597,10 @@ private:
// BuiltinType for each scalar type.
QualType m_baseTypes[HLSLScalarTypeCount];
// String type
QualType m_hlslStringType;
TypedefDecl* m_hlslStringTypedef;
// Built-in object types declarations, indexed by basic kind constant.
CXXRecordDecl* m_objectTypeDecls[_countof(g_ArBasicKindsAsTypes)];
// Map from object decl to the object index.
@ -2608,6 +2617,9 @@ private:
/// <summary>Adds all supporting declarations to reference scalar types.</summary>
void AddHLSLScalarTypes();
/// <summary>Adds string type QualType for HSLS string declarations</summary>
void AddHLSLStringType();
QualType GetTemplateObjectDataType(_In_ CXXRecordDecl* recordDecl)
{
DXASSERT_NOMSG(recordDecl != nullptr);
@ -3111,7 +3123,8 @@ public:
m_matrixTemplateDecl(nullptr),
m_vectorTemplateDecl(nullptr),
m_context(nullptr),
m_sema(nullptr)
m_sema(nullptr),
m_hlslStringTypedef(nullptr)
{
memset(m_matrixTypes, 0, sizeof(m_matrixTypes));
memset(m_matrixShorthandTypes, 0, sizeof(m_matrixShorthandTypes));
@ -3194,6 +3207,15 @@ public:
return qt;
}
TypedefDecl* GetStringTypedef() {
if (m_hlslStringTypedef == nullptr) {
m_hlslStringTypedef = CreateGlobalTypedef(m_context, "string", m_hlslStringType);
m_hlslStringType = m_context->getTypeDeclType(m_hlslStringTypedef);
}
DXASSERT_NOMSG(m_hlslStringTypedef != nullptr);
return m_hlslStringTypedef;
}
void WarnMinPrecision(HLSLScalarType type, SourceLocation loc) {
// TODO: enalbe this once we introduce precise master option
bool UseMinPrecision = m_context->getLangOpts().UseMinPrecision;
@ -3297,6 +3319,11 @@ public:
}
return true;
}
// string
else if (TryParseString(nameIdentifier.data(), nameIdentifier.size(), getSema()->getLangOpts())) {
TypedefDecl *strDecl = GetStringTypedef();
R.addDecl(strDecl);
}
return false;
}
@ -3377,9 +3404,11 @@ public:
type = GetStructuralForm(type);
if (type->isVoidType()) return AR_TOBJ_VOID;
if (type->isArrayType()) return AR_TOBJ_ARRAY;
if (type->isArrayType()) {
return hlsl::IsArrayConstantStringType(type) ? AR_TOBJ_STRING : AR_TOBJ_ARRAY;
}
if (type->isPointerType()) {
return AR_TOBJ_POINTER;
return hlsl::IsPointerStringType(type) ? AR_TOBJ_STRING : AR_TOBJ_POINTER;
}
if (type->isStructureOrClassType()) {
const RecordType* recordType = type->getAs<RecordType>();
@ -3461,6 +3490,10 @@ public:
return GetTypeElementKind(elementType);
}
if (kind == AR_TOBJ_STRING) {
return type->isArrayType() ? AR_OBJECT_STRING_LITERAL : AR_OBJECT_STRING;
}
if (type->isArrayType()) {
const ArrayType* arrayType = type->getAsArrayTypeUnsafe();
return GetTypeElementKind(arrayType->getElementType());
@ -3625,8 +3658,8 @@ public:
case AR_BASIC_ENUM: return m_context->IntTy;
case AR_BASIC_ENUM_CLASS: return m_context->IntTy;
case AR_OBJECT_STRING: return QualType();
case AR_OBJECT_STRING: return m_hlslStringType;
case AR_OBJECT_LEGACY_EFFECT: // used for all legacy effect object types
case AR_OBJECT_TEXTURE1D:
@ -3900,6 +3933,7 @@ public:
m_hlslNSDecl->setImplicit();
AddBaseTypes();
AddHLSLScalarTypes();
AddHLSLStringType();
AddHLSLVectorTemplate(*m_context, &m_vectorTemplateDecl);
DXASSERT(m_vectorTemplateDecl != nullptr, "AddHLSLVectorTypes failed to return the vector template declaration");
@ -4678,6 +4712,10 @@ void HLSLExternalSource::AddHLSLScalarTypes()
m_scalarTypes[HLSLScalarType_int_lit] = m_baseTypes[HLSLScalarType_int_lit];
}
void HLSLExternalSource::AddHLSLStringType() {
m_hlslStringType = m_context->HLSLStringTy;
}
FunctionDecl* HLSLExternalSource::AddSubscriptSpecialization(
_In_ FunctionTemplateDecl* functionTemplate,
QualType objectElement,
@ -5701,6 +5739,7 @@ unsigned HLSLExternalSource::GetNumElements(QualType anyType) {
switch (kind) {
case AR_TOBJ_BASIC:
case AR_TOBJ_OBJECT:
case AR_TOBJ_STRING:
return 1;
case AR_TOBJ_COMPOUND: {
// TODO: consider caching this value for perf
@ -5736,6 +5775,7 @@ unsigned HLSLExternalSource::GetNumBasicElements(QualType anyType) {
switch (kind) {
case AR_TOBJ_BASIC:
case AR_TOBJ_OBJECT:
case AR_TOBJ_STRING:
return 1;
case AR_TOBJ_COMPOUND: {
// TODO: consider caching this value for perf
@ -5834,6 +5874,7 @@ QualType HLSLExternalSource::GetNthElementType(QualType type, unsigned index) {
switch (kind) {
case AR_TOBJ_BASIC:
case AR_TOBJ_OBJECT:
case AR_TOBJ_STRING:
return (index == 0) ? type : QualType();
case AR_TOBJ_COMPOUND: {
// TODO: consider caching this value for perf
@ -6693,6 +6734,7 @@ bool HLSLExternalSource::IsTypeNumeric(QualType type, UINT* count)
*count = GetElementCount(type);
return IsBasicKindNumeric(GetTypeElementKind(type));
case AR_TOBJ_OBJECT:
case AR_TOBJ_STRING:
return false;
}
}
@ -7655,6 +7697,14 @@ static bool ConvertDimensions(ArTypeInfo TargetInfo, ArTypeInfo SourceInfo,
break;
}
case AR_TOBJ_STRING:
if (SourceInfo.ShapeKind == AR_TOBJ_STRING) {
Second = ICK_Identity;
break;
}
else {
return false;
}
default:
return false;
@ -7709,6 +7759,16 @@ static bool ConvertComponent(ArTypeInfo TargetInfo, ArTypeInfo SourceInfo,
// enum -> int/float
ComponentConversion = ICK_Integral_Conversion;
}
else if (TargetInfo.EltKind == AR_OBJECT_STRING)
{
if (SourceInfo.EltKind == AR_OBJECT_STRING_LITERAL) {
ComponentConversion = ICK_Array_To_Pointer;
}
else
{
return false;
}
}
else
{
bool targetIsInt = IS_BASIC_AINT(TargetInfo.EltKind);
@ -7954,6 +8014,9 @@ lSuccess:
case ICK_Boolean_Conversion:
standard->First = ICK_Lvalue_To_Rvalue;
break;
case ICK_Array_To_Pointer:
standard->First = ICK_Array_To_Pointer;
break;
default:
// Only potential assignments above covered.
break;
@ -7969,7 +8032,8 @@ lSuccess:
// Scalar to scalar type conversion, use normal mechanism (Second)
Second = ComponentConversion;
ComponentConversion = ICK_Identity;
} else {
}
else if (TargetInfo.ShapeKind != AR_TOBJ_STRING) {
// vector or matrix dimensions are not being changed, but component type
// is being converted, so change Second to signal the conversion
Second = ICK_HLSLVector_Conversion;
@ -9802,7 +9866,8 @@ bool FlattenedTypeIterator::considerLeaf()
case FlattenedIterKind::FK_Simple: {
ArTypeObjectKind objectKind = m_source.GetTypeObjectKind(tracker.Type);
if (objectKind != ArTypeObjectKind::AR_TOBJ_BASIC &&
objectKind != ArTypeObjectKind::AR_TOBJ_OBJECT) {
objectKind != ArTypeObjectKind::AR_TOBJ_OBJECT &&
objectKind != ArTypeObjectKind::AR_TOBJ_STRING) {
if (pushTrackerForType(tracker.Type, tracker.CurrentExpr)) {
result = considerLeaf();
}
@ -9998,6 +10063,12 @@ bool FlattenedTypeIterator::pushTrackerForType(QualType type, MultiExprArg::iter
type.getCanonicalType(), 1, expression));
return true;
}
case ArTypeObjectKind::AR_TOBJ_STRING: {
// Strings have no sub-types.
m_typeTrackers.push_back(FlattenedTypeIterator::FlattenedTypeTracker(
type.getCanonicalType(), 1, expression));
return true;
}
default:
DXASSERT(false, "unreachable");
return false;
@ -11085,6 +11156,26 @@ bool Sema::DiagnoseHLSLDecl(Declarator &D, DeclContext *DC,
}
}
// diagnose string declarations
if (hlsl::IsStringType(qt) && !D.isInvalidType()) {
// string are supported only as top level global variables
if (!DC->isTranslationUnit()) {
Diag(D.getLocStart(), diag::err_hlsl_string_not_global);
result = false;
}
// const and static modifiers are implied - add them if missing
const char *PrevSpec = nullptr;
unsigned DiagID = 0;
if (!isStatic) {
D.getMutableDeclSpec().SetStorageClassSpec(*this, DeclSpec::SCS_static, D.getLocStart(), PrevSpec, DiagID, Context.getPrintingPolicy());
isStatic = true;
}
if (!isConst) {
D.getMutableDeclSpec().SetTypeQual(DeclSpec::TQ_const, D.getLocStart(), PrevSpec, DiagID, getLangOpts());
isConst = true;
}
}
const char* declarationType =
(isLocalVar) ? "local variable" :
(isTypedef) ? "typedef" :
@ -11099,6 +11190,13 @@ bool Sema::DiagnoseHLSLDecl(Declarator &D, DeclContext *DC,
if (pFP) {
qt = pFP->getReturnType();
pType = qt.getTypePtrOrNull();
// prohibit string as a return type
if (hlsl::IsStringType(qt)) {
static const unsigned selectReturnValueIdx = 2;
Diag(D.getLocStart(), diag::err_hlsl_unsupported_string_decl) << selectReturnValueIdx;
D.setInvalidType();
}
}
}

Просмотреть файл

@ -1987,6 +1987,15 @@ QualType Sema::BuildArrayType(QualType T, ArrayType::ArraySizeModifier ASM,
return QualType();
}
// HLSL Change Start
// no arrays of strings in HLSL
if (getLangOpts().HLSL && hlsl::IsStringType(T)) {
static const unsigned selectArrayIdx = 0;
Diag(Loc, diag::err_hlsl_unsupported_string_decl) << selectArrayIdx;
return QualType();
}
// HLSL Change End
if (RequireNonAbstractType(Brackets.getBegin(), T,
diag::err_array_of_abstract_type))
return QualType();

Просмотреть файл

@ -1,27 +1,76 @@
// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value -ffreestanding -verify %s
// expected-no-diagnostics
static const string s_global1 = "my global string 1";
/*verify-ast
VarDecl <col:1, col:33> col:21 used s_global1 'string':'string' static cinit
`-ImplicitCastExpr <col:33> 'const string' <ArrayToPointerDecay>
`-StringLiteral <col:33> 'const char [19]' lvalue "my global string 1"
*/
#if 0
string s_global2 = "my global string 2";
string s_global = "string";
string s_global_concat = "string" "with "
"broken up"
"parts";
string s_global3 = s_global1;
/*verify-ast
VarDecl <col:1, col:20> col:8 s_global3 'string':'string' static cinit
`-DeclRefExpr <col:20> 'string':'string' lvalue Var 's_global1' 'string':'string'
*/
void hello_here(string message, string s, float f) {
string s_global_concat = "my string " "with "
/*verify-ast
VarDecl <col:1, line:25:4> line:18:8 s_global_concat 'string':'string' static cinit
`-ImplicitCastExpr <col:26, line:25:4> 'const string' <ArrayToPointerDecay>
`-StringLiteral <col:26, line:25:4> 'const char [31]' lvalue "my string with broken up parts"
*/
"broken up"
" parts";
static const bool b1 = s_global1; /* expected-error {{cannot initialize a variable of type 'const bool' with an lvalue of type 'string'}} fxc-error {{X3017: cannot implicitly convert from 'const string' to 'const bool'}} */
static const bool b2 = false;
static const string s_global4 = true; /* expected-error {{cannot initialize a variable of type 'string' with an rvalue of type 'bool'}} fxc-error {{X3017: cannot implicitly convert from 'bool' to 'const string'}} */
static const string s_global5 = b2; /* expected-error {{cannot initialize a variable of type 'string' with an lvalue of type 'const bool'}} fxc-error {{X3017: cannot implicitly convert from 'const bool' to 'const string'}} */
static const int i1 = s_global1; /* expected-error {{cannot initialize a variable of type 'const int' with an lvalue of type 'string'}} fxc-error {{X3017: cannot implicitly convert from 'const string' to 'const int'}} */
static const int i2 = 10;
static const string s_global6 = 10; /* expected-error {{cannot initialize a variable of type 'string' with an rvalue of type 'literal int'}} fxc-error {{X3017: cannot implicitly convert from 'int' to 'const string'}} */
static const string s_global7 = i2; /* expected-error {{cannot initialize a variable of type 'string' with an lvalue of type 'const int'}} fxc-error {{X3017: cannot implicitly convert from 'const int' to 'const string'}} */
static const float f1 = s_global1; /* expected-error {{cannot initialize a variable of type 'const float' with an lvalue of type 'string'}} fxc-error {{X3017: cannot implicitly convert from 'const string' to 'const float'}} */
static const float f2 = 3.15;
static const string s_global8= 3.14; /* expected-error {{cannot initialize a variable of type 'string' with an rvalue of type 'literal float'}} fxc-error {{X3017: cannot implicitly convert from 'float' to 'const string'}} */
static const string s_global9= f2; /* expected-error {{cannot initialize a variable of type 'string' with an lvalue of type 'const float'}} fxc-error {{X3017: cannot implicitly convert from 'const float' to 'const string'}} */
static const string s_global10 = { 'A', 'B', 'C' }; /* expected-error {{too many elements in vector initialization (expected 1 element, have 3)}} fxc-error {{X3017: 's_global10': initializer does not match type}} */
static const string s_global11 = { 1, 2, 3 }; /* expected-error {{too many elements in vector initialization (expected 1 element, have 3)}} fxc-error {{X3017: 's_global11': initializer does not match type}} */
static const string s_global12 = { "ABC" };
string g_strArray[5]; /* expected-error {{array of type string is not supported}} fxc-pass {{}} */
vector<string, 4> g_strVector1; /* expected-error {{'string' cannot be used as a type parameter where a scalar is required}} fxc-error {{X3122: vector element type must be a scalar type}} */
matrix<string, 4, 4> g_strMatrix1; /* expected-error {{'string' cannot be used as a type parameter where a scalar is required}} fxc-error {{X3123: matrix element type must be a scalar type}} */
void hello_here(string message, string s, float f) { /* expected-error {{parameter of type string is not supported}} expected-error {{parameter of type string is not supported}} fxc-pass {{}} */
printf(s);
printf(message);
printf("%f", f);
printf("%f", f); /* expected-error {{use of undeclared identifier 'printf'}} fxc-pass {{}} */
}
float4 main() : SV_Target0{
float4 cp4_local = cp4;
int i = 0;
cp4_local.x = a("hi" "bob");
printf("hi mom", 1, 2, 3);
string get_message() { /* expected-error {{return value of type string is not supported}} fxc-error {{X3038: 'get_message': function return value cannot contain Effects objects}} */
return "foo";
}
struct test {
string field; /* expected-error {{string declaration may only appear in global scope}} fxc-pass {{}} */
};
float4 main() : SV_Target0 { /* */
string str; /* expected-error {{string declaration may only appear in global scope}} fxc-pass {{}} */
str = s_global2; /* expected-error {{use of undeclared identifier 'str'}} fxc-pass {{}} */
string strArray[5]; /* expected-error {{array of type string is not supported}} fxc-pass {{}} */
vector<string, 4> strVector1; /* expected-error {{'string' cannot be used as a type parameter where a scalar is required}} fxc-error {{X3122: vector element type must be a scalar type}} */
matrix<string, 4, 4> strMatrix1; /* expected-error {{'string' cannot be used as a type parameter where a scalar is required}} fxc-error {{X3123: matrix element type must be a scalar type}} */
float4 cp4_local;
printf("hi mom", 1, 2, 3); /* expected-error {{use of undeclared identifier 'printf'}} fxc-pass {{}} */
hello_here("a", "b", 1);
return cp4_local;
}
#endif
}