This machine mirrors various open-source projects.
20 Gbit/s uplink.
If there are any issues or you want another project mirrored, please contact
mirror-service -=AT=- netcologne DOT de !
00001 //===-- codegen/Mangle.cpp ------------------------------------ -*- C++ -*-===// 00002 // 00003 // This file is distributed under the MIT license. See LICENSE.txt for details. 00004 // 00005 // Copyright (C) 2009, Stephen Wilson 00006 // 00007 //===----------------------------------------------------------------------===// 00008 00009 #include "comma/ast/Decl.h" 00010 #include "comma/codegen/Mangle.h" 00011 00012 #include <sstream> 00013 00014 using namespace comma; 00015 using llvm::dyn_cast_or_null; 00016 using llvm::dyn_cast; 00017 using llvm::cast; 00018 using llvm::isa; 00019 00020 namespace { 00021 00027 std::string getSubroutineName(const SubroutineDecl *srd) 00028 { 00029 const char *name = srd->getIdInfo()->getString(); 00030 00031 switch (strlen(name)) { 00032 00033 default: 00034 return name; 00035 00036 case 1: 00037 if (strncmp(name, "!", 1) == 0) 00038 return "0bang"; 00039 else if (strncmp(name, "&", 1) == 0) 00040 return "0amper"; 00041 else if (strncmp(name, "#", 1) == 0) 00042 return "0hash"; 00043 else if (strncmp(name, "*", 1) == 0) 00044 return "0multiply"; 00045 else if (strncmp(name, "+", 1) == 0) 00046 return "0plus"; 00047 else if (strncmp(name, "-", 1) == 0) 00048 return "0minus"; 00049 else if (strncmp(name, "<", 1) == 0) 00050 return "0less"; 00051 else if (strncmp(name, "=", 1) == 0) 00052 return "0equal"; 00053 else if (strncmp(name, "/=", 1) == 0) 00054 return "0nequal"; 00055 else if (strncmp(name, ">", 1) == 0) 00056 return "0great"; 00057 else if (strncmp(name, "@", 1) == 0) 00058 return "0at"; 00059 else if (strncmp(name, "\\", 1) == 0) 00060 return "0bslash"; 00061 else if (strncmp(name, "^", 1) == 0) 00062 return "0hat"; 00063 else if (strncmp(name, "`", 1) == 0) 00064 return "0grave"; 00065 else if (strncmp(name, "|", 1) == 0) 00066 return "0bar"; 00067 else if (strncmp(name, "/", 1) == 0) 00068 return "0fslash"; 00069 else if (strncmp(name, "~", 1) == 0) 00070 return "0tilde"; 00071 else 00072 return name; 00073 00074 case 2: 00075 if (strncmp(name, "<=", 2) == 0) 00076 return "0leq"; 00077 else if (strncmp(name, "<>", 2) == 0) 00078 return "0diamond"; 00079 else if (strncmp(name, "<<", 2) == 0) 00080 return "0dless"; 00081 else if (strncmp(name, "==", 2) == 0) 00082 return "0dequal"; 00083 else if (strncmp(name, ">=", 2) == 0) 00084 return "0geq"; 00085 else if (strncmp(name, ">>", 2) == 0) 00086 return "0dgreat"; 00087 else if (strncmp(name, "||", 2) == 0) 00088 return "0dbar"; 00089 else if (strncmp(name, "~=", 2) == 0) 00090 return "0nequal"; 00091 else 00092 return name; 00093 } 00094 } 00095 00114 unsigned getRegionIndex(const DeclRegion *region, IdentifierInfo *idInfo, 00115 const Decl *target, unsigned &index) 00116 { 00117 typedef DeclRegion::ConstDeclIter iterator; 00118 iterator I = region->beginDecls(); 00119 iterator E = region->endDecls(); 00120 00121 for ( ; I != E; ++I) { 00122 const Decl *candidate = *I; 00123 if (idInfo == candidate->getIdInfo()) { 00124 // If the target matches the current declaration, terminate the 00125 // index count. 00126 if (target == candidate) 00127 return true; 00128 00129 // Do not increment the index if a foward declaration exists (we 00130 // would be counting the same declaration twice). 00131 if (const SubroutineDecl *SR = dyn_cast<SubroutineDecl>(candidate)) 00132 if (SR->hasForwardDeclaration()) 00133 continue; 00134 00135 index++; 00136 } 00137 } 00138 return false; 00139 } 00140 00146 std::pair<const PercentDecl*, const SubroutineDecl*> 00147 getPercentImage(const SubroutineDecl *srDecl) 00148 { 00149 typedef std::pair<const PercentDecl*, const SubroutineDecl*> Pair; 00150 00151 const DeclRegion *region = srDecl->getDeclRegion(); 00152 const PercentDecl *percent = 0; 00153 const SubroutineDecl *target = 0; 00154 00157 if ((percent = dyn_cast<PercentDecl>(region))) 00158 return Pair(percent, srDecl); 00159 00163 if (isa<DomainInstanceDecl>(region)) { 00164 target = srDecl->getOrigin(); 00165 percent = cast<PercentDecl>(target->getDeclRegion()); 00166 return Pair(percent, target); 00167 } 00168 00174 const AddDecl *add = cast<AddDecl>(region); 00175 percent = cast<PercentDecl>(add->getParent()); 00176 target = srDecl->getForwardDeclaration(); 00177 return Pair(percent, target); 00178 } 00179 00186 unsigned getOverloadIndex(const SubroutineDecl *srDecl) 00187 { 00188 unsigned index = 0; 00189 IdentifierInfo *idInfo = srDecl->getIdInfo(); 00190 00191 // Resolve the PercentDecl corresponding to this subroutine. 00192 std::pair<const PercentDecl*, const SubroutineDecl*> percentImage; 00193 percentImage = getPercentImage(srDecl); 00194 00195 // Generate the index wrt the resolved PercentDecl. If there is a match, 00196 // return the computed index. 00197 if (getRegionIndex(percentImage.first, idInfo, 00198 percentImage.second, index)) 00199 return index; 00200 00201 // Otherwise, srDecl must denote a declaration which is private to the 00202 // corresponding domain. Search the body of the domain for a match. 00203 const AddDecl *add = cast<AddDecl>(srDecl->getDeclRegion()); 00204 if (getRegionIndex(add, idInfo, srDecl, index)) 00205 return index; 00206 00207 // We should always find a match. 00208 assert(false && "Decl not a member of its context!"); 00209 return 0; 00210 } 00211 00212 } // end anonymous namespace. 00213 00214 std::string comma::mangle::getLinkName(const DomainInstanceDecl *instance, 00215 const SubroutineDecl *srDecl) 00216 { 00217 // If the given subroutine is imported use the external name given by the 00218 // pragma. 00219 if (const PragmaImport *pragma = 00220 dyn_cast_or_null<PragmaImport>(srDecl->findPragma(pragma::Import))) 00221 return pragma->getExternalName(); 00222 00223 std::string name = getLinkName(instance) + "__"; 00224 name.append(getSubroutineName(srDecl)); 00225 00226 unsigned index = getOverloadIndex(srDecl); 00227 if (index) { 00228 std::ostringstream ss; 00229 ss << "__" << index; 00230 name += ss.str(); 00231 } 00232 return name; 00233 } 00234 00235 std::string comma::mangle::getLinkName(const SubroutineDecl *srDecl) 00236 { 00237 // All subroutine decls must either be resolved within the context of a 00238 // domain (non-parameterized) or be an external declaration provided by an 00239 // instance. 00240 const DeclRegion *region = srDecl->getDeclRegion(); 00241 const DomainInstanceDecl *instance; 00242 00243 if (isa<AddDecl>(region)) 00244 region = cast<PercentDecl>(region->getParent()); 00245 00246 if (const PercentDecl *percent = dyn_cast<PercentDecl>(region)) { 00247 const DomainDecl *domain = cast<DomainDecl>(percent->getDefinition()); 00248 instance = domain->getInstance(); 00249 } 00250 else 00251 instance = cast<DomainInstanceDecl>(region); 00252 00253 return getLinkName(instance, srDecl); 00254 } 00255 00256 std::string comma::mangle::getLinkName(const Domoid *domoid) 00257 { 00258 return domoid->getString(); 00259 } 00260 00261 std::string comma::mangle::getLinkName(const DomainInstanceDecl *instance) 00262 { 00263 assert(!instance->isDependent() && 00264 "Cannot form link names for dependent instance declarations!"); 00265 00266 std::string name = instance->getString(); 00267 for (unsigned i = 0; i < instance->getArity(); ++i) { 00268 const DomainType *param = 00269 cast<DomainType>(instance->getActualParamType(i)); 00270 std::ostringstream ss; 00271 00272 if (param->denotesPercent()) { 00273 // Mangle percent nodes to the name of the corresponding domain. 00274 const PercentDecl *percent = param->getPercentDecl(); 00275 const Domoid *model = cast<Domoid>(percent->getDefinition()); 00276 ss << "__" << i << getLinkName(model); 00277 } 00278 else { 00279 ss << "__" << i << getLinkName(param->getInstanceDecl()); 00280 name += ss.str(); 00281 } 00282 } 00283 return name; 00284 } 00285 00286 std::string comma::mangle::getLinkName(const ExceptionDecl *exception) 00287 { 00288 // FIXME: Factor out and share with implementation of getLinkName for 00289 // subroutine declarations. 00290 const DeclRegion *region = exception->getDeclRegion(); 00291 const DomainInstanceDecl *instance; 00292 if (isa<AddDecl>(region)) 00293 region = cast<PercentDecl>(region->getParent()); 00294 00295 if (const PercentDecl *percent = dyn_cast<PercentDecl>(region)) { 00296 const DomainDecl *domain = cast<DomainDecl>(percent->getDefinition()); 00297 instance = domain->getInstance(); 00298 } 00299 else 00300 instance = cast<DomainInstanceDecl>(region); 00301 00302 std::string name = getLinkName(instance) + "__"; 00303 name.append(exception->getString()); 00304 return name; 00305 }