• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2020 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 
7 #include <algorithm>
8 
9 #include "compiler/translator/TranslatorMetalDirect/AstHelpers.h"
10 #include "compiler/translator/TranslatorMetalDirect/SeparateCompoundStructDeclarations.h"
11 #include "compiler/translator/tree_ops/SeparateDeclarations.h"
12 #include "compiler/translator/tree_util/IntermTraverse.h"
13 
14 using namespace sh;
15 
16 ////////////////////////////////////////////////////////////////////////////////
17 
18 namespace
19 {
20 
21 class Separator : public TIntermTraverser
22 {
23   public:
24     std::unordered_map<int, TIntermSymbol *> replacementMap;
Separator(TSymbolTable & symbolTable,IdGen & idGen)25     Separator(TSymbolTable &symbolTable, IdGen &idGen)
26         : TIntermTraverser(false, false, true, &symbolTable), mIdGen(idGen)
27     {}
28     IdGen &mIdGen;
visitDeclaration(Visit,TIntermDeclaration * declNode)29     bool visitDeclaration(Visit, TIntermDeclaration *declNode) override
30     {
31         ASSERT(declNode->getChildCount() == 1);
32         Declaration declaration = ViewDeclaration(*declNode);
33 
34         const TVariable &var        = declaration.symbol.variable();
35         const TType &type           = var.getType();
36         const SymbolType symbolType = var.symbolType();
37         if (type.isStructSpecifier() && symbolType != SymbolType::Empty)
38         {
39             const TStructure *structure = type.getStruct();
40             TVariable *structVar        = nullptr;
41             TType *instanceType         = nullptr;
42             // Name unnamed inline structs
43             if (structure->symbolType() == SymbolType::Empty)
44             {
45                 const TStructure *structDefn =
46                     new TStructure(mSymbolTable, mIdGen.createNewName("__unnamed").rawName(),
47                                    &(structure->fields()), SymbolType::AngleInternal);
48                 structVar    = new TVariable(mSymbolTable, ImmutableString(""),
49                                           new TType(structDefn, true), SymbolType::Empty);
50                 instanceType = new TType(structDefn, false);
51             }
52             else
53             {
54                 structVar    = new TVariable(mSymbolTable, ImmutableString(""),
55                                           new TType(structure, true), SymbolType::Empty);
56                 instanceType = new TType(structure, false);
57             }
58             instanceType->setQualifier(type.getQualifier());
59             auto *instanceVar =
60                 new TVariable(mSymbolTable, var.name(), instanceType, symbolType, var.extensions());
61 
62             TIntermSequence replacements;
63             replacements.push_back(new TIntermSymbol(structVar));
64 
65             TIntermSymbol *instanceSymbol    = new TIntermSymbol(instanceVar);
66             TIntermNode *instanceReplacement = instanceSymbol;
67             if (declaration.initExpr)
68             {
69                 instanceReplacement =
70                     new TIntermBinary(EOpInitialize, instanceSymbol, declaration.initExpr);
71             }
72             replacements.push_back(instanceReplacement);
73 
74             replacementMap[declaration.symbol.uniqueId().get()] = instanceSymbol;
75             mMultiReplacements.push_back(NodeReplaceWithMultipleEntry(
76                 declNode, declNode->getChildNode(0), std::move(replacements)));
77         }
78 
79         return false;
80     }
81 
visitSymbol(TIntermSymbol * decl)82     void visitSymbol(TIntermSymbol *decl) override
83     {
84         auto symbol = replacementMap.find(decl->uniqueId().get());
85         if (symbol != replacementMap.end())
86         {
87             queueReplacement(symbol->second->deepCopy(), OriginalNode::IS_DROPPED);
88         }
89     }
90 };
91 
92 }  // anonymous namespace
93 
94 ////////////////////////////////////////////////////////////////////////////////
95 
SeparateCompoundStructDeclarations(TCompiler & compiler,IdGen & idGen,TIntermBlock & root)96 bool sh::SeparateCompoundStructDeclarations(TCompiler &compiler, IdGen &idGen, TIntermBlock &root)
97 {
98     Separator separator(compiler.getSymbolTable(), idGen);
99     root.traverse(&separator);
100     if (!separator.updateTree(&compiler, &root))
101     {
102         return false;
103     }
104 
105     if (!SeparateDeclarations(&compiler, &root))
106     {
107         return false;
108     }
109 
110     return true;
111 }
112