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 }