00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "ExportMap.h"
00010 #include "comma/ast/Decl.h"
00011 #include "comma/codegen/CodeGen.h"
00012
00013 #include <iostream>
00014
00015 using namespace comma;
00016
00017 using llvm::dyn_cast;
00018 using llvm::cast;
00019 using llvm::isa;
00020
00021 void ExportMap::initializeUsingSignature(SignatureEntry &entry,
00022 const Sigoid *sig)
00023 {
00024 typedef SignatureSet::const_iterator sig_iterator;
00025 typedef DeclRegion::ConstDeclIter decl_iterator;
00026
00027 unsigned index = 0;
00028
00029 entry.sigoid = sig;
00030 entry.offsets.push_back(index);
00031
00032 for (decl_iterator iter = sig->beginDecls();
00033 iter != sig->endDecls(); ++iter) {
00034 const SubroutineDecl *decl = dyn_cast<SubroutineDecl>(*iter);
00035 if (decl && decl->isImmediate()) {
00036 ExportPair pair(decl, index);
00037 entry.exports.push_back(pair);
00038 index++;
00039 }
00040 }
00041
00042
00043
00044 const SignatureSet &SS = sig->getSignatureSet();
00045 for (sig_iterator iter = SS.beginDirect(); iter != SS.endDirect(); ++iter) {
00046 const SignatureEntry superEntry = addSignature((*iter)->getSigoid());
00047
00048 for (offset_iterator osi = begin_offsets(superEntry);
00049 osi != end_offsets(superEntry); ++osi)
00050 entry.offsets.push_back(*osi + index);
00051
00052 index += superEntry.totalExports;
00053 }
00054
00055
00056 entry.totalExports = index;
00057 }
00058
00059 unsigned ExportMap::getSignatureOffset(const SubroutineDecl *decl)
00060 {
00061 typedef SignatureSet::const_iterator iterator;
00062
00063 const Sigoid *ctx = resolveSignatureContext(decl);
00064 const Sigoid *origin = resolveSignatureOrigin(decl);
00065
00066 if (ctx == origin)
00067 return 0;
00068
00069 const SignatureSet &SS = ctx->getSignatureSet();
00070 unsigned offset = 0;
00071 for (iterator iter = SS.begin(); iter != SS.end(); ++iter) {
00072 offset++;
00073 if ((*iter)->getSigoid() == origin)
00074 break;
00075 }
00076
00077 assert(offset != 0 && "Declaration origin not accessible thru context!");
00078 return offset;
00079 }
00080
00081 unsigned ExportMap::getLocalIndex(const SubroutineDecl *decl)
00082 {
00083 const SubroutineDecl *key = decl->resolveOrigin();
00084 const Sigoid *sig = resolveSignatureOrigin(decl);
00085 const SignatureEntry &entry = lookupSignature(sig);
00086
00087 for (std::vector<ExportPair>::const_iterator iter = entry.exports.begin();
00088 iter != entry.exports.end(); ++iter) {
00089 if (iter->first == key)
00090 return iter->second;
00091 }
00092
00093 assert(false && "Export lookup failed!");
00094 return ~0u;
00095 }
00096
00097 unsigned ExportMap::getIndex(const SubroutineDecl *decl)
00098 {
00099 unsigned sigIdx = getSignatureOffset(decl);
00100 unsigned localIdx = getLocalIndex(decl);
00101 const Sigoid *ctx = resolveSignatureContext(decl);
00102 const SignatureEntry &entry = lookupSignature(ctx);
00103
00104 return entry.offsets[sigIdx] + localIdx;
00105 }
00106
00107 const Sigoid *ExportMap::resolveSignatureOrigin(const SubroutineDecl *decl)
00108 {
00109 const SubroutineDecl *origin = decl->resolveOrigin();
00110 return cast<Sigoid>(origin->getDeclRegion());
00111 }
00112
00113 const Sigoid *ExportMap::resolveSignatureContext(const SubroutineDecl *decl)
00114 {
00115 const Sigoid *sigoid = 0;
00116 const DeclRegion *region = decl->getDeclRegion();
00117
00118 if (const AbstractDomainDecl *add = dyn_cast<AbstractDomainDecl>(region))
00119 sigoid = add->getSignatureType()->getSigoid();
00120 else if (isa<Domoid>(region)) {
00121 assert(!decl->isImmediate() &&
00122 "Cannot resolve declarations immediate to a domain!");
00123 const SubroutineDecl *origin = decl->getOrigin();
00124 sigoid = cast<Sigoid>(origin->getDeclRegion());
00125 }
00126 else
00127 sigoid = cast<Sigoid>(region);
00128
00129 return sigoid;
00130 }
00131
00132 void ExportMap::dump(const SignatureKey entry)
00133 {
00134 const Sigoid *sigoid = entry.sigoid;
00135
00136 std::cerr << "SignatureEntry : " << sigoid->getString() << '\n';
00137 std::cerr << " Offsets :";
00138 for (offset_iterator iter = begin_offsets(entry);
00139 iter != end_offsets(entry); ++iter)
00140 std::cerr << ' ' << *iter;
00141 std::cerr << '\n';
00142 std::cerr << " Total # Exports : " << entry.totalExports << '\n';
00143 std::cerr << " Direct Exports :\n";
00144 for (std::vector<ExportPair>::const_iterator iter = entry.exports.begin();
00145 iter != entry.exports.end(); ++iter) {
00146 std::cerr << " "
00147 << CodeGen::getLinkName(iter->first) << " : " << iter->second
00148 << '\n';
00149 }
00150
00151 std::cerr << " All Exports :\n";
00152 for (Sigoid::ConstDeclIter iter = sigoid->beginDecls();
00153 iter != sigoid->endDecls(); ++iter) {
00154 const Decl *decl = *iter;
00155 if (const SubroutineDecl *sr = dyn_cast<SubroutineDecl>(decl)) {
00156 std::cerr << " "
00157 << CodeGen::getLinkName(sr) << " : " << getIndex(sr)
00158 << '\n';
00159 }
00160 }
00161 }