| 1 | #include "Validate/FixEnumeratedArray.hpp"
|
|---|
| 2 |
|
|---|
| 3 | #include "AST/Pass.hpp" // WithCodeLocation
|
|---|
| 4 | #include "Validate/NoIdSymbolTable.hpp" // NoIdSymbolTable
|
|---|
| 5 |
|
|---|
| 6 | namespace Validate {
|
|---|
| 7 | namespace {
|
|---|
| 8 | struct FixEnumeratedArray : public NoIdSymbolTable,
|
|---|
| 9 |
|
|---|
| 10 | public ast::WithCodeLocation,
|
|---|
| 11 | public ast::WithShortCircuiting,
|
|---|
| 12 | public ast::WithDeclsToAdd<> {
|
|---|
| 13 |
|
|---|
| 14 | ast::ObjectDecl const * previsit( ast::ObjectDecl const * decl ) {
|
|---|
| 15 | if (decl->isTypeFixed) return decl;
|
|---|
| 16 | if (auto arrayDecl = decl->type.as<ast::ArrayType>()) {
|
|---|
| 17 | auto declaredType = arrayDecl->declaredType;
|
|---|
| 18 | if (!declaredType) return decl;
|
|---|
| 19 | auto initializers = decl->init.strict_as<ast::ListInit>();
|
|---|
| 20 | if (auto declaredEnum = declaredType.as<ast::EnumDecl>()) {
|
|---|
| 21 | auto forwardingEnum = mutate(declaredEnum);
|
|---|
| 22 | for (auto designation : initializers->designations) {
|
|---|
| 23 | std::deque<ast::ptr<ast::Expr>> designatorList =
|
|---|
| 24 | designation->designators;
|
|---|
| 25 | if (designatorList.size() != 1) {
|
|---|
| 26 | SemanticError(forwardingEnum,
|
|---|
| 27 | "Multiple Initialization in enumerated "
|
|---|
| 28 | "array is not supported.");
|
|---|
| 29 | }
|
|---|
| 30 | ast::ptr<ast::Expr> designator = designatorList.at(0);
|
|---|
| 31 |
|
|---|
| 32 | ast::ptr<ast::NameExpr> designatorAsName =
|
|---|
| 33 | designator.as<ast::NameExpr>();
|
|---|
| 34 | if (!designatorAsName) {
|
|---|
| 35 | SemanticError(
|
|---|
| 36 | forwardingEnum,
|
|---|
| 37 | "Enumerated Array with inlined enum declaration "
|
|---|
| 38 | "can only use string as its initializer");
|
|---|
| 39 | }
|
|---|
| 40 | ast::ObjectDecl* memberDecl = new ast::ObjectDecl(
|
|---|
| 41 | declaredEnum->location, designatorAsName->name,
|
|---|
| 42 | new ast::EnumInstType(declaredEnum, ast::CV::Const));
|
|---|
| 43 | forwardingEnum->members.push_back(memberDecl);
|
|---|
| 44 | }
|
|---|
| 45 | // addEnum(forwardingEnum);
|
|---|
| 46 | declsToAddBefore.push_back( forwardingEnum );
|
|---|
| 47 | }
|
|---|
| 48 | }
|
|---|
| 49 | return decl;
|
|---|
| 50 | }
|
|---|
| 51 |
|
|---|
| 52 | }; // namespace
|
|---|
| 53 |
|
|---|
| 54 | } // namespace
|
|---|
| 55 | void fixEnumeratedArray(ast::TranslationUnit& translationUnit) {
|
|---|
| 56 | ast::Pass<FixEnumeratedArray>::run(translationUnit);
|
|---|
| 57 | }
|
|---|
| 58 |
|
|---|
| 59 | }; // namespace Validate
|
|---|