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