Home | History | Annotate | Download | only in compiler
      1 //
      2 // Copyright (c) 2002-2010 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 #include "compiler/SymbolTable.h"
     13 
     14 #include <stdio.h>
     15 
     16 //
     17 // TType helper function needs a place to live.
     18 //
     19 
     20 //
     21 // Recursively generate mangled names.
     22 //
     23 void TType::buildMangledName(TString& mangledName)
     24 {
     25     if (isMatrix())
     26         mangledName += 'm';
     27     else if (isVector())
     28         mangledName += 'v';
     29 
     30     switch (type) {
     31     case EbtFloat:              mangledName += 'f';      break;
     32     case EbtInt:                mangledName += 'i';      break;
     33     case EbtBool:               mangledName += 'b';      break;
     34     case EbtSampler2D:          mangledName += "s2";     break;
     35     case EbtSamplerCube:        mangledName += "sC";     break;
     36     case EbtStruct:
     37         mangledName += "struct-";
     38         if (typeName)
     39             mangledName += *typeName;
     40         {// support MSVC++6.0
     41             for (unsigned int i = 0; i < structure->size(); ++i) {
     42                 mangledName += '-';
     43                 (*structure)[i].type->buildMangledName(mangledName);
     44             }
     45         }
     46     default:
     47         break;
     48     }
     49 
     50     mangledName += static_cast<char>('0' + getNominalSize());
     51     if (isArray()) {
     52         char buf[20];
     53         sprintf(buf, "%d", arraySize);
     54         mangledName += '[';
     55         mangledName += buf;
     56         mangledName += ']';
     57     }
     58 }
     59 
     60 int TType::getStructSize() const
     61 {
     62     if (!getStruct()) {
     63         assert(false && "Not a struct");
     64         return 0;
     65     }
     66 
     67     if (structureSize == 0)
     68         for (TTypeList::const_iterator tl = getStruct()->begin(); tl != getStruct()->end(); tl++)
     69             structureSize += ((*tl).type)->getObjectSize();
     70 
     71     return structureSize;
     72 }
     73 
     74 //
     75 // Dump functions.
     76 //
     77 
     78 void TVariable::dump(TInfoSink& infoSink) const
     79 {
     80     infoSink.debug << getName().c_str() << ": " << type.getQualifierString() << " " << type.getPrecisionString() << " " << type.getBasicString();
     81     if (type.isArray()) {
     82         infoSink.debug << "[0]";
     83     }
     84     infoSink.debug << "\n";
     85 }
     86 
     87 void TFunction::dump(TInfoSink &infoSink) const
     88 {
     89     infoSink.debug << getName().c_str() << ": " <<  returnType.getBasicString() << " " << getMangledName().c_str() << "\n";
     90 }
     91 
     92 void TSymbolTableLevel::dump(TInfoSink &infoSink) const
     93 {
     94     tLevel::const_iterator it;
     95     for (it = level.begin(); it != level.end(); ++it)
     96         (*it).second->dump(infoSink);
     97 }
     98 
     99 void TSymbolTable::dump(TInfoSink &infoSink) const
    100 {
    101     for (int level = currentLevel(); level >= 0; --level) {
    102         infoSink.debug << "LEVEL " << level << "\n";
    103         table[level]->dump(infoSink);
    104     }
    105 }
    106 
    107 //
    108 // Functions have buried pointers to delete.
    109 //
    110 TFunction::~TFunction()
    111 {
    112     for (TParamList::iterator i = parameters.begin(); i != parameters.end(); ++i)
    113         delete (*i).type;
    114 }
    115 
    116 //
    117 // Symbol table levels are a map of pointers to symbols that have to be deleted.
    118 //
    119 TSymbolTableLevel::~TSymbolTableLevel()
    120 {
    121     for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
    122         delete (*it).second;
    123 }
    124 
    125 //
    126 // Change all function entries in the table with the non-mangled name
    127 // to be related to the provided built-in operation.  This is a low
    128 // performance operation, and only intended for symbol tables that
    129 // live across a large number of compiles.
    130 //
    131 void TSymbolTableLevel::relateToOperator(const char* name, TOperator op)
    132 {
    133     tLevel::iterator it;
    134     for (it = level.begin(); it != level.end(); ++it) {
    135         if ((*it).second->isFunction()) {
    136             TFunction* function = static_cast<TFunction*>((*it).second);
    137             if (function->getName() == name)
    138                 function->relateToOperator(op);
    139         }
    140     }
    141 }
    142 
    143 //
    144 // Change all function entries in the table with the non-mangled name
    145 // to be related to the provided built-in extension. This is a low
    146 // performance operation, and only intended for symbol tables that
    147 // live across a large number of compiles.
    148 //
    149 void TSymbolTableLevel::relateToExtension(const char* name, const TString& ext)
    150 {
    151     for (tLevel::iterator it = level.begin(); it != level.end(); ++it) {
    152         if (it->second->isFunction()) {
    153             TFunction* function = static_cast<TFunction*>(it->second);
    154             if (function->getName() == name)
    155                 function->relateToExtension(ext);
    156         }
    157     }
    158 }
    159 
    160 TSymbol::TSymbol(const TSymbol& copyOf)
    161 {
    162     name = NewPoolTString(copyOf.name->c_str());
    163     uniqueId = copyOf.uniqueId;
    164 }
    165 
    166 TVariable::TVariable(const TVariable& copyOf, TStructureMap& remapper) : TSymbol(copyOf)
    167 {
    168     type.copyType(copyOf.type, remapper);
    169     userType = copyOf.userType;
    170     // for builtIn symbol table level, unionArray and arrayInformation pointers should be NULL
    171     assert(copyOf.arrayInformationType == 0);
    172     arrayInformationType = 0;
    173 
    174     if (copyOf.unionArray) {
    175         assert(!copyOf.type.getStruct());
    176         assert(copyOf.type.getObjectSize() == 1);
    177         unionArray = new ConstantUnion[1];
    178         unionArray[0] = copyOf.unionArray[0];
    179     } else
    180         unionArray = 0;
    181 }
    182 
    183 TVariable* TVariable::clone(TStructureMap& remapper)
    184 {
    185     TVariable *variable = new TVariable(*this, remapper);
    186 
    187     return variable;
    188 }
    189 
    190 TFunction::TFunction(const TFunction& copyOf, TStructureMap& remapper) : TSymbol(copyOf)
    191 {
    192     for (unsigned int i = 0; i < copyOf.parameters.size(); ++i) {
    193         TParameter param;
    194         parameters.push_back(param);
    195         parameters.back().copyParam(copyOf.parameters[i], remapper);
    196     }
    197 
    198     returnType.copyType(copyOf.returnType, remapper);
    199     mangledName = copyOf.mangledName;
    200     op = copyOf.op;
    201     defined = copyOf.defined;
    202 }
    203 
    204 TFunction* TFunction::clone(TStructureMap& remapper)
    205 {
    206     TFunction *function = new TFunction(*this, remapper);
    207 
    208     return function;
    209 }
    210 
    211 TSymbolTableLevel* TSymbolTableLevel::clone(TStructureMap& remapper)
    212 {
    213     TSymbolTableLevel *symTableLevel = new TSymbolTableLevel();
    214     tLevel::iterator iter;
    215     for (iter = level.begin(); iter != level.end(); ++iter) {
    216         symTableLevel->insert(*iter->second->clone(remapper));
    217     }
    218 
    219     return symTableLevel;
    220 }
    221 
    222 void TSymbolTable::copyTable(const TSymbolTable& copyOf)
    223 {
    224     TStructureMap remapper;
    225     uniqueId = copyOf.uniqueId;
    226     for (unsigned int i = 0; i < copyOf.table.size(); ++i) {
    227         table.push_back(copyOf.table[i]->clone(remapper));
    228     }
    229     for( unsigned int i = 0; i < copyOf.precisionStack.size(); i++) {
    230         precisionStack.push_back( copyOf.precisionStack[i] );
    231     }
    232 }
    233