00001 
00002 
00003 
00004 
00005 
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             
00125             
00126             if (target == candidate)
00127                 return true;
00128 
00129             
00130             
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     
00192     std::pair<const PercentDecl*, const SubroutineDecl*> percentImage;
00193     percentImage = getPercentImage(srDecl);
00194 
00195     
00196     
00197     if (getRegionIndex(percentImage.first, idInfo,
00198                        percentImage.second, index))
00199         return index;
00200 
00201     
00202     
00203     const AddDecl *add = cast<AddDecl>(srDecl->getDeclRegion());
00204     if (getRegionIndex(add, idInfo, srDecl, index))
00205         return index;
00206 
00207     
00208     assert(false && "Decl not a member of its context!");
00209     return 0;
00210 }
00211 
00212 } 
00213 
00214 std::string comma::mangle::getLinkName(const DomainInstanceDecl *instance,
00215                                        const SubroutineDecl *srDecl)
00216 {
00217     
00218     
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     
00238     
00239     
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             
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     
00289     
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 }