LCOV - code coverage report
Current view: top level - gfx/angle/src/compiler/translator - PruneEmptyDeclarations.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 35 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 6 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //
       2             : // Copyright (c) 2002-2015 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             : // The PruneEmptyDeclarations function prunes unnecessary empty declarations and declarators from the AST.
       7             : 
       8             : #include "compiler/translator/PruneEmptyDeclarations.h"
       9             : 
      10             : #include "compiler/translator/IntermNode.h"
      11             : 
      12             : namespace sh
      13             : {
      14             : 
      15             : namespace
      16             : {
      17             : 
      18           0 : class PruneEmptyDeclarationsTraverser : private TIntermTraverser
      19             : {
      20             :   public:
      21             :     static void apply(TIntermNode *root);
      22             :   private:
      23             :     PruneEmptyDeclarationsTraverser();
      24             :     bool visitDeclaration(Visit, TIntermDeclaration *node) override;
      25             : };
      26             : 
      27           0 : void PruneEmptyDeclarationsTraverser::apply(TIntermNode *root)
      28             : {
      29           0 :     PruneEmptyDeclarationsTraverser prune;
      30           0 :     root->traverse(&prune);
      31           0 :     prune.updateTree();
      32           0 : }
      33             : 
      34           0 : PruneEmptyDeclarationsTraverser::PruneEmptyDeclarationsTraverser()
      35           0 :     : TIntermTraverser(true, false, false)
      36             : {
      37           0 : }
      38             : 
      39           0 : bool PruneEmptyDeclarationsTraverser::visitDeclaration(Visit, TIntermDeclaration *node)
      40             : {
      41           0 :     TIntermSequence *sequence = node->getSequence();
      42           0 :     if (sequence->size() >= 1)
      43             :     {
      44           0 :         TIntermSymbol *sym = sequence->front()->getAsSymbolNode();
      45             :         // Prune declarations without a variable name, unless it's an interface block declaration.
      46           0 :         if (sym != nullptr && sym->getSymbol() == "" && !sym->isInterfaceBlock())
      47             :         {
      48           0 :             if (sequence->size() > 1)
      49             :             {
      50             :                 // Generate a replacement that will remove the empty declarator in the beginning of
      51             :                 // a declarator list. Example of a declaration that will be changed:
      52             :                 // float, a;
      53             :                 // will be changed to
      54             :                 // float a;
      55             :                 // This applies also to struct declarations.
      56           0 :                 TIntermSequence emptyReplacement;
      57           0 :                 mMultiReplacements.push_back(
      58           0 :                     NodeReplaceWithMultipleEntry(node, sym, emptyReplacement));
      59             :             }
      60           0 :             else if (sym->getBasicType() != EbtStruct)
      61             :             {
      62             :                 // Single struct declarations may just declare the struct type and no variables, so
      63             :                 // they should not be pruned. All other single empty declarations can be pruned
      64             :                 // entirely. Example of an empty declaration that will be pruned:
      65             :                 // float;
      66           0 :                 TIntermSequence emptyReplacement;
      67           0 :                 TIntermBlock *parentAsBlock = getParentNode()->getAsBlock();
      68             :                 // The declaration may be inside a block or in a loop init expression.
      69           0 :                 ASSERT(parentAsBlock != nullptr || getParentNode()->getAsLoopNode() != nullptr);
      70           0 :                 if (parentAsBlock)
      71             :                 {
      72           0 :                     mMultiReplacements.push_back(
      73           0 :                         NodeReplaceWithMultipleEntry(parentAsBlock, node, emptyReplacement));
      74             :                 }
      75             :                 else
      76             :                 {
      77           0 :                     queueReplacement(node, nullptr, OriginalNode::IS_DROPPED);
      78             :                 }
      79             :             }
      80           0 :             else if (sym->getType().getQualifier() != EvqGlobal &&
      81           0 :                      sym->getType().getQualifier() != EvqTemporary)
      82             :             {
      83             :                 // We've hit an empty struct declaration with a qualifier, for example like
      84             :                 // this:
      85             :                 // const struct a { int i; };
      86             :                 // NVIDIA GL driver version 367.27 doesn't accept this kind of declarations, so
      87             :                 // we convert the declaration to a regular struct declaration. This is okay,
      88             :                 // since ESSL 1.00 spec section 4.1.8 says about structs that "The optional
      89             :                 // qualifiers only apply to any declarators, and are not part of the type being
      90             :                 // defined for name."
      91             : 
      92           0 :                 if (mInGlobalScope)
      93             :                 {
      94           0 :                     sym->getTypePointer()->setQualifier(EvqGlobal);
      95             :                 }
      96             :                 else
      97             :                 {
      98           0 :                     sym->getTypePointer()->setQualifier(EvqTemporary);
      99             :                 }
     100             :             }
     101             :         }
     102             :     }
     103           0 :     return false;
     104             : }
     105             : 
     106             : } // namespace
     107             : 
     108           0 : void PruneEmptyDeclarations(TIntermNode *root)
     109             : {
     110           0 :     PruneEmptyDeclarationsTraverser::apply(root);
     111           0 : }
     112             : 
     113             : }  // namespace sh

Generated by: LCOV version 1.13