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 |
---|