Home | History | Annotate | Download | only in compiler
      1 //
      2 // Copyright (c) 2002-2012 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 //
      8 // Symbol table for parsing.  Most functionaliy and main ideas
      9 // are documented in the header file.
     10 //
     11 
     12 #if defined(_MSC_VER)
     13 #pragma warning(disable: 4718)
     14 #endif
     15 
     16 #include "compiler/SymbolTable.h"
     17 
     18 #include <stdio.h>
     19 #include <algorithm>
     20 #include <climits>
     21 
     22 TType::TType(const TPublicType &p) :
     23             type(p.type), precision(p.precision), qualifier(p.qualifier), size(p.size), matrix(p.matrix), array(p.array), arraySize(p.arraySize), structure(0)
     24 {
     25     if (p.userDef)
     26         structure = p.userDef->getStruct();
     27 }
     28 
     29 //
     30 // Recursively generate mangled names.
     31 //
     32 TString TType::buildMangledName() const
     33 {
     34     TString mangledName;
     35     if (isMatrix())
     36         mangledName += 'm';
     37     else if (isVector())
     38         mangledName += 'v';
     39 
     40     switch (type) {
     41     case EbtFloat:       mangledName += 'f';      break;
     42     case EbtInt:         mangledName += 'i';      break;
     43     case EbtBool:        mangledName += 'b';      break;
     44     case EbtSampler2D:   mangledName += "s2";     break;
     45     case EbtSamplerCube: mangledName += "sC";     break;
     46     case EbtStruct:      mangledName += structure->mangledName(); break;
     47     default:             break;
     48     }
     49 
     50     mangledName += static_cast<char>('0' + getNominalSize());
     51     if (isArray()) {
     52         char buf[20];
     53         snprintf(buf, sizeof(buf), "%d", arraySize);
     54         mangledName += '[';
     55         mangledName += buf;
     56         mangledName += ']';
     57     }
     58     return mangledName;
     59 }
     60 
     61 size_t TType::getObjectSize() const
     62 {
     63     size_t totalSize = 0;
     64 
     65     if (getBasicType() == EbtStruct)
     66         totalSize = structure->objectSize();
     67     else if (matrix)
     68         totalSize = size * size;
     69     else
     70         totalSize = size;
     71 
     72     if (isArray()) {
     73         size_t arraySize = getArraySize();
     74         if (arraySize > INT_MAX / totalSize)
     75             totalSize = INT_MAX;
     76         else
     77             totalSize *= arraySize;
     78     }
     79 
     80     return totalSize;
     81 }
     82 
     83 bool TStructure::containsArrays() const
     84 {
     85     for (size_t i = 0; i < mFields->size(); ++i) {
     86         const TType* fieldType = (*mFields)[i]->type();
     87         if (fieldType->isArray() || fieldType->isStructureContainingArrays())
     88             return true;
     89     }
     90     return false;
     91 }
     92 
     93 TString TStructure::buildMangledName() const
     94 {
     95     TString mangledName("struct-");
     96     mangledName += *mName;
     97     for (size_t i = 0; i < mFields->size(); ++i) {
     98         mangledName += '-';
     99         mangledName += (*mFields)[i]->type()->getMangledName();
    100     }
    101     return mangledName;
    102 }
    103 
    104 size_t TStructure::calculateObjectSize() const
    105 {
    106     size_t size = 0;
    107     for (size_t i = 0; i < mFields->size(); ++i) {
    108         size_t fieldSize = (*mFields)[i]->type()->getObjectSize();
    109         if (fieldSize > INT_MAX - size)
    110             size = INT_MAX;
    111         else
    112             size += fieldSize;
    113     }
    114     return size;
    115 }
    116 
    117 int TStructure::calculateDeepestNesting() const
    118 {
    119     int maxNesting = 0;
    120     for (size_t i = 0; i < mFields->size(); ++i) {
    121         maxNesting = std::max(maxNesting, (*mFields)[i]->type()->getDeepestStructNesting());
    122     }
    123     return 1 + maxNesting;
    124 }
    125 
    126 //
    127 // Dump functions.
    128 //
    129 
    130 void TVariable::dump(TInfoSink& infoSink) const
    131 {
    132     infoSink.debug << getName().c_str() << ": " << type.getQualifierString() << " " << type.getPrecisionString() << " " << type.getBasicString();
    133     if (type.isArray()) {
    134         infoSink.debug << "[0]";
    135     }
    136     infoSink.debug << "\n";
    137 }
    138 
    139 void TFunction::dump(TInfoSink &infoSink) const
    140 {
    141     infoSink.debug << getName().c_str() << ": " <<  returnType.getBasicString() << " " << getMangledName().c_str() << "\n";
    142 }
    143 
    144 void TSymbolTableLevel::dump(TInfoSink &infoSink) const
    145 {
    146     tLevel::const_iterator it;
    147     for (it = level.begin(); it != level.end(); ++it)
    148         (*it).second->dump(infoSink);
    149 }
    150 
    151 void TSymbolTable::dump(TInfoSink &infoSink) const
    152 {
    153     for (int level = currentLevel(); level >= 0; --level) {
    154         infoSink.debug << "LEVEL " << level << "\n";
    155         table[level]->dump(infoSink);
    156     }
    157 }
    158 
    159 //
    160 // Functions have buried pointers to delete.
    161 //
    162 TFunction::~TFunction()
    163 {
    164     for (TParamList::iterator i = parameters.begin(); i != parameters.end(); ++i)
    165         delete (*i).type;
    166 }
    167 
    168 //
    169 // Symbol table levels are a map of pointers to symbols that have to be deleted.
    170 //
    171 TSymbolTableLevel::~TSymbolTableLevel()
    172 {
    173     for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
    174         delete (*it).second;
    175 }
    176 
    177 //
    178 // Change all function entries in the table with the non-mangled name
    179 // to be related to the provided built-in operation.  This is a low
    180 // performance operation, and only intended for symbol tables that
    181 // live across a large number of compiles.
    182 //
    183 void TSymbolTableLevel::relateToOperator(const char* name, TOperator op)
    184 {
    185     tLevel::iterator it;
    186     for (it = level.begin(); it != level.end(); ++it) {
    187         if ((*it).second->isFunction()) {
    188             TFunction* function = static_cast<TFunction*>((*it).second);
    189             if (function->getName() == name)
    190                 function->relateToOperator(op);
    191         }
    192     }
    193 }
    194 
    195 //
    196 // Change all function entries in the table with the non-mangled name
    197 // to be related to the provided built-in extension. This is a low
    198 // performance operation, and only intended for symbol tables that
    199 // live across a large number of compiles.
    200 //
    201 void TSymbolTableLevel::relateToExtension(const char* name, const TString& ext)
    202 {
    203     for (tLevel::iterator it = level.begin(); it != level.end(); ++it) {
    204         TSymbol* symbol = it->second;
    205         if (symbol->getName() == name)
    206             symbol->relateToExtension(ext);
    207     }
    208 }
    209 
    210 TSymbolTable::~TSymbolTable()
    211 {
    212     for (size_t i = 0; i < table.size(); ++i)
    213         delete table[i];
    214     for (size_t i = 0; i < precisionStack.size(); ++i)
    215         delete precisionStack[i];
    216 }
    217