From 592affb984cf24a95622db133bde07fba282d40d Mon Sep 17 00:00:00 2001 From: Matt Pharr Date: Tue, 5 Jun 2012 12:51:21 -0700 Subject: [PATCH] Add experimental (and undocumented for now) export syntax. This allows adding types to the list that are included in the automatically-generated header files. struct Foo { . . . }; struct Bar { . . . }; export { Foo, Bar }; --- module.cpp | 28 ++++++++++++++++++++++++++++ module.h | 7 +++++++ parse.yy | 29 +++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+) diff --git a/module.cpp b/module.cpp index f69fa0f7..220ecd49 100644 --- a/module.cpp +++ b/module.cpp @@ -824,6 +824,22 @@ Module::AddFunctionDefinition(const std::string &name, const FunctionType *type, } +void +Module::AddExportedTypes(const std::vector > &types) { + for (int i = 0; i < (int)types.size(); ++i) { + if (CastType(types[i].first) == NULL && + CastType(types[i].first) == NULL && + CastType(types[i].first) == NULL) + Error(types[i].second, "Only struct, vector, and enum types, " + "not \"%s\", are allowed in type export lists.", + types[i].first->GetString().c_str()); + else + exportedTypes.push_back(types[i]); + } +} + + bool Module::writeOutput(OutputType outputType, const char *outFileName, const char *includeFileName) { @@ -1251,6 +1267,18 @@ Module::writeHeader(const char *fn) { lGetExportedParamTypes(externCFuncs, &exportedStructTypes, &exportedEnumTypes, &exportedVectorTypes); + // Go through the explicitly exported types + for (int i = 0; i < (int)exportedTypes.size(); ++i) { + if (const StructType *st = CastType(exportedTypes[i].first)) + exportedStructTypes.push_back(st->GetAsUniformType()); + else if (const EnumType *et = CastType(exportedTypes[i].first)) + exportedEnumTypes.push_back(et->GetAsUniformType()); + else if (const VectorType *vt = CastType(exportedTypes[i].first)) + exportedVectorTypes.push_back(vt->GetAsUniformType()); + else + FATAL("Unexpected type in export list"); + } + // And print them lEmitVectorTypedefs(exportedVectorTypes, f); lEmitEnumDecls(exportedEnumTypes, f); diff --git a/module.h b/module.h index d62728c8..f08a19d3 100644 --- a/module.h +++ b/module.h @@ -80,6 +80,11 @@ public: void AddFunctionDefinition(const std::string &name, const FunctionType *ftype, Stmt *code); + /** Adds the given type to the set of types that have their definitions + included in automatically generated header files. */ + void AddExportedTypes(const std::vector > &types); + /** After a source file has been compiled, output can be generated in a number of different formats. */ enum OutputType { Asm, /** Generate text assembly language output */ @@ -145,6 +150,8 @@ private: const char *filename; AST *ast; + std::vector > exportedTypes; + /** Write the corresponding output type to the given file. Returns true on success, false if there has been an error. The given filename may be NULL, indicating that output should go to standard diff --git a/parse.yy b/parse.yy index 33e19dbc..b1a498f0 100644 --- a/parse.yy +++ b/parse.yy @@ -151,6 +151,7 @@ struct ForeachDimension { Expr *expr; ExprList *exprList; const Type *type; + std::vector > *typeList; const AtomicType *atomicType; int typeQualifier; StorageClass storageClass; @@ -232,6 +233,7 @@ struct ForeachDimension { %type specifier_qualifier_list struct_or_union_specifier %type type_specifier type_name rate_qualified_type_specifier %type short_vec_specifier +%type type_specifier_list %type atomic_var_type_specifier %type type_qualifier type_qualifier_list @@ -826,6 +828,28 @@ type_specifier | enum_specifier { $$ = $1; } ; +type_specifier_list + : type_specifier + { + if ($1 == NULL) + $$ = NULL; + else { + std::vector > *vec = + new std::vector >; + vec->push_back(std::make_pair($1, @1)); + $$ = vec; + } + } + | type_specifier_list ',' type_specifier + { + $$ = $1; + if ($1 == NULL) + Assert(m->errorCount > 0); + else + $$->push_back(std::make_pair($3, @3)); + } + ; + atomic_var_type_specifier : TOKEN_VOID { $$ = AtomicType::Void; } | TOKEN_BOOL { $$ = AtomicType::UniformBool->GetAsUnboundVariabilityType(); } @@ -1837,6 +1861,11 @@ translation_unit external_declaration : function_definition | TOKEN_EXTERN TOKEN_STRING_C_LITERAL '{' declaration '}' + | TOKEN_EXPORT '{' type_specifier_list '}' ';' + { + if ($3 != NULL) + m->AddExportedTypes(*$3); + } | declaration { if ($1 != NULL)