diff --git a/decl.cpp b/decl.cpp index 1a67e387..5dab985e 100644 --- a/decl.cpp +++ b/decl.cpp @@ -56,6 +56,7 @@ lPrintTypeQualifiers(int typeQualifiers) { if (typeQualifiers & TYPEQUAL_TASK) printf("task "); if (typeQualifiers & TYPEQUAL_SIGNED) printf("signed "); if (typeQualifiers & TYPEQUAL_UNSIGNED) printf("unsigned "); + if (typeQualifiers & TYPEQUAL_EXPORT) printf("export "); } @@ -189,7 +190,6 @@ lGetStorageClassName(StorageClass storageClass) { case SC_NONE: return ""; case SC_EXTERN: return "extern"; case SC_EXTERN_C: return "extern \"C\""; - case SC_EXPORT: return "export"; case SC_STATIC: return "static"; case SC_TYPEDEF: return "typedef"; default: FATAL("Unhandled storage class in lGetStorageClassName"); @@ -347,6 +347,7 @@ Declarator::GetType(const Type *base, DeclSpecs *ds) const { bool hasUniformQual = ((typeQualifiers & TYPEQUAL_UNIFORM) != 0); bool hasVaryingQual = ((typeQualifiers & TYPEQUAL_VARYING) != 0); bool isTask = ((typeQualifiers & TYPEQUAL_TASK) != 0); + bool isExported = ((typeQualifiers & TYPEQUAL_EXPORT) != 0); bool isConst = ((typeQualifiers & TYPEQUAL_CONST) != 0); if (hasUniformQual && hasVaryingQual) { @@ -355,6 +356,8 @@ Declarator::GetType(const Type *base, DeclSpecs *ds) const { } if (kind != DK_FUNCTION && isTask) Error(pos, "\"task\" qualifier illegal in variable declaration."); + if (kind != DK_FUNCTION && isExported) + Error(pos, "\"export\" qualifier illegal in variable declaration."); Variability variability(Variability::Unbound); if (hasUniformQual) @@ -519,8 +522,8 @@ Declarator::GetType(const Type *base, DeclSpecs *ds) const { return NULL; } - bool isExported = ds && (ds->storageClass == SC_EXPORT); bool isExternC = ds && (ds->storageClass == SC_EXTERN_C); + bool isExported = ds && ((ds->typeQualifiers & TYPEQUAL_EXPORT) != 0); bool isTask = ds && ((ds->typeQualifiers & TYPEQUAL_TASK) != 0); if (isExported && isTask) { @@ -731,10 +734,15 @@ GetStructTypesNamesPositions(const std::vector &sd, // FIXME: making this fake little DeclSpecs here is really // disgusting DeclSpecs ds(type); - if (type->IsUniformType()) - ds.typeQualifiers |= TYPEQUAL_UNIFORM; - else if (type->IsVaryingType()) - ds.typeQualifiers |= TYPEQUAL_VARYING; + if (Type::Equal(type, AtomicType::Void) == false) { + if (type->IsUniformType()) + ds.typeQualifiers |= TYPEQUAL_UNIFORM; + else if (type->IsVaryingType()) + ds.typeQualifiers |= TYPEQUAL_VARYING; + else if (type->GetSOAWidth() != 0) + ds.soaWidth = type->GetSOAWidth(); + // FIXME: ds.vectorSize? + } for (unsigned int j = 0; j < sd[i]->declarators->size(); ++j) { Declarator *d = (*sd[i]->declarators)[j]; diff --git a/decl.h b/decl.h index 0bae20b8..ff96e149 100644 --- a/decl.h +++ b/decl.h @@ -64,7 +64,6 @@ class Declarator; enum StorageClass { SC_NONE, SC_EXTERN, - SC_EXPORT, SC_STATIC, SC_TYPEDEF, SC_EXTERN_C @@ -82,6 +81,7 @@ enum StorageClass { #define TYPEQUAL_SIGNED (1<<4) #define TYPEQUAL_UNSIGNED (1<<5) #define TYPEQUAL_INLINE (1<<6) +#define TYPEQUAL_EXPORT (1<<7) /** @brief Representation of the declaration specifiers in a declaration. diff --git a/module.cpp b/module.cpp index f9e38d87..c7b2a424 100644 --- a/module.cpp +++ b/module.cpp @@ -584,7 +584,7 @@ Module::AddFunctionDeclaration(Symbol *funSym, bool isInline) { // Make sure that the return type isn't 'varying' if the function is // 'export'ed. - if (funSym->storageClass == SC_EXPORT && + if (functionType->isExported && lRecursiveCheckValidParamType(functionType->GetReturnType())) Error(funSym->pos, "Illegal to return a \"varying\" type from exported " "function \"%s\"", funSym->name.c_str()); @@ -608,7 +608,7 @@ Module::AddFunctionDeclaration(Symbol *funSym, bool isInline) { // If the function is exported, make sure that the parameter // doesn't have any varying stuff going on in it. - if (funSym->storageClass == SC_EXPORT) + if (functionType->isExported) lCheckForVaryingParameter(argType, argName, argPos); // ISPC assumes that no pointers alias. (It should be possible to diff --git a/parse.yy b/parse.yy index 978b11d7..8448a559 100644 --- a/parse.yy +++ b/parse.yy @@ -810,7 +810,6 @@ storage_class_specifier : TOKEN_TYPEDEF { $$ = SC_TYPEDEF; } | TOKEN_EXTERN { $$ = SC_EXTERN; } | TOKEN_EXTERN TOKEN_STRING_C_LITERAL { $$ = SC_EXTERN_C; } - | TOKEN_EXPORT { $$ = SC_EXPORT; } | TOKEN_STATIC { $$ = SC_STATIC; } ; @@ -985,6 +984,11 @@ specifier_qualifier_list "function declarations."); $$ = $2; } + else if ($1 == TYPEQUAL_EXPORT) { + Error(@1, "\"export\" qualifier is illegal outside of " + "function declarations."); + $$ = $2; + } else FATAL("Unhandled type qualifier in parser."); } @@ -1117,6 +1121,7 @@ type_qualifier | TOKEN_UNIFORM { $$ = TYPEQUAL_UNIFORM; } | TOKEN_VARYING { $$ = TYPEQUAL_VARYING; } | TOKEN_TASK { $$ = TYPEQUAL_TASK; } + | TOKEN_EXPORT { $$ = TYPEQUAL_EXPORT; } | TOKEN_INLINE { $$ = TYPEQUAL_INLINE; } | TOKEN_SIGNED { $$ = TYPEQUAL_SIGNED; } | TOKEN_UNSIGNED { $$ = TYPEQUAL_UNSIGNED; } @@ -2096,8 +2101,6 @@ lGetStorageClassString(StorageClass sc) { return ""; case SC_EXTERN: return "extern"; - case SC_EXPORT: - return "export"; case SC_STATIC: return "static"; case SC_TYPEDEF: