00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 #include "comma/ast/AstResource.h"
00010 #include "comma/ast/AttribExpr.h"
00011 #include "comma/ast/Decl.h"
00012 #include "comma/ast/DeclRewriter.h"
00013 #include "comma/ast/DSTDefinition.h"
00014 #include "comma/ast/Expr.h"
00015 
00016 using namespace comma;
00017 using llvm::cast_or_null;
00018 using llvm::dyn_cast;
00019 using llvm::cast;
00020 using llvm::isa;
00021 
00022 void DeclRewriter::mirrorRegion(DeclRegion *source, DeclRegion *target)
00023 {
00024     typedef DeclRegion::DeclIter iterator;
00025     iterator I = source->beginDecls();
00026     iterator E = source->endDecls();
00027 
00028     for ( ; I != E; ++I) {
00029         Decl *sourceDecl = *I;
00030         IdentifierInfo *idInfo = sourceDecl->getIdInfo();
00031         Type *sourceType = 0;
00032 
00033         if (SubroutineDecl *SR = dyn_cast<SubroutineDecl>(sourceDecl))
00034             sourceType = SR->getType();
00035         else if (TypeDecl *TD = dyn_cast<TypeDecl>(sourceDecl))
00036             sourceType = TD->getType();
00037         else {
00038             assert(false && "Cannot mirror this kind of declaration yet!");
00039             return;
00040         }
00041 
00042         Type *targetType = rewriteType(sourceType);
00043         Decl *targetDecl = target->findDecl(idInfo, targetType);
00044         assert(targetDecl && "Could not resolve declaration!");
00045         addDeclRewrite(sourceDecl, targetDecl);
00046     }
00047 }
00048 
00049 FunctionDecl *DeclRewriter::rewriteFunctionDecl(FunctionDecl *fdecl)
00050 {
00051     llvm::SmallVector<ParamValueDecl*, 8> params;
00052     unsigned arity = fdecl->getArity();
00053 
00054     for (unsigned i = 0; i < arity; ++i) {
00055         ParamValueDecl *origParam = fdecl->getParam(i);
00056         Type *newType = rewriteType(origParam->getType());
00057         ParamValueDecl *newParam =
00058             new ParamValueDecl(origParam->getIdInfo(), newType,
00059                                origParam->getExplicitParameterMode(), 0);
00060         params.push_back(newParam);
00061     }
00062 
00063     FunctionDecl *result =
00064         new FunctionDecl(getAstResource(),
00065                          fdecl->getIdInfo(), 0, params.data(), arity,
00066                          rewriteType(fdecl->getReturnType()), context);
00067     result->setOrigin(fdecl);
00068     addDeclRewrite(fdecl, result);
00069     return result;
00070 }
00071 
00072 ProcedureDecl *DeclRewriter::rewriteProcedureDecl(ProcedureDecl *pdecl)
00073 {
00074     llvm::SmallVector<ParamValueDecl*, 8> params;
00075     unsigned arity = pdecl->getArity();
00076 
00077     for (unsigned i = 0; i < arity; ++i) {
00078         ParamValueDecl *origParam = pdecl->getParam(i);
00079         Type *newType = rewriteType(origParam->getType());
00080         ParamValueDecl *newParam =
00081             new ParamValueDecl(origParam->getIdInfo(), newType,
00082                                origParam->getExplicitParameterMode(), 0);
00083         params.push_back(newParam);
00084     }
00085 
00086     ProcedureDecl *result =
00087         new ProcedureDecl(getAstResource(),
00088                           pdecl->getIdInfo(), 0, params.data(), arity, context);
00089     result->setOrigin(pdecl);
00090     addDeclRewrite(pdecl, result);
00091     return result;
00092 }
00093 
00094 EnumerationDecl *
00095 DeclRewriter::rewriteEnumerationDecl(EnumerationDecl *edecl)
00096 {
00097     typedef std::pair<IdentifierInfo*, Location> Pair;
00098 
00099     IdentifierInfo *name = edecl->getIdInfo();
00100     llvm::SmallVector<Pair, 8> elems;
00101 
00102     
00103     
00104     
00105     
00106     
00107     
00108     typedef DeclRegion::DeclIter iterator;
00109     iterator I = edecl->beginDecls();
00110     iterator E = edecl->endDecls();
00111     for ( ; I != E; ++I) {
00112         EnumLiteral *lit = dyn_cast<EnumLiteral>(*I);
00113         if (!lit)
00114             continue;
00115         IdentifierInfo *litId = lit->getIdInfo();
00116         elems.push_back(Pair(litId, 0));
00117     }
00118 
00119     AstResource &resource = getAstResource();
00120     EnumerationDecl *result =
00121         resource.createEnumDecl(name, 0, &elems[0], elems.size(), context);
00122     result->generateImplicitDeclarations(resource);
00123     result->setOrigin(edecl);
00124 
00125     
00126     addDeclRewrite(edecl, result);
00127     addTypeRewrite(edecl->getType(), result->getType());
00128     mirrorRegion(edecl, result);
00129     return result;
00130 }
00131 
00132 ArrayDecl *DeclRewriter::rewriteArrayDecl(ArrayDecl *adecl)
00133 {
00134     IdentifierInfo *name = adecl->getIdInfo();
00135     unsigned rank = adecl->getRank();
00136     bool isConstrained = adecl->isConstrained();
00137     Type *component = rewriteType(adecl->getComponentType());
00138     DSTDefinition *indices[rank];
00139 
00140     for (unsigned i = 0; i < rank; ++i) {
00141         
00142         
00143         
00144         
00145         
00146         
00147         DiscreteType *indexTy;
00148         indexTy = cast<DiscreteType>(rewriteType(adecl->getIndexType(i)));
00149         indices[i] = new DSTDefinition(0, indexTy, DSTDefinition::Type_DST);
00150     }
00151 
00152     ArrayDecl *result;
00153     AstResource &resource = getAstResource();
00154     result = resource.createArrayDecl(name, 0, rank, &indices[0],
00155                                       component, isConstrained, context);
00156     result->setOrigin(adecl);
00157 
00160     addDeclRewrite(adecl, result);
00161     addTypeRewrite(adecl->getType(), result->getType());
00162     return result;
00163 }
00164 
00165 IntegerDecl *DeclRewriter::rewriteIntegerDecl(IntegerDecl *idecl)
00166 {
00167     IdentifierInfo *name = idecl->getIdInfo();
00168     Expr *lower = rewriteExpr(idecl->getLowBoundExpr());
00169     Expr *upper = rewriteExpr(idecl->getHighBoundExpr());
00170 
00171     IntegerDecl *result;
00172     AstResource &resource = getAstResource();
00173 
00174     result = resource.createIntegerDecl(name, 0, lower, upper, context);
00175     result->generateImplicitDeclarations(resource);
00176     result->setOrigin(idecl);
00177 
00178     IntegerType *sourceTy = idecl->getType();
00179     IntegerType *targetTy = result->getType();
00180 
00181     
00182     
00183     addTypeRewrite(sourceTy, targetTy);
00184     addTypeRewrite(sourceTy->getRootType()->getBaseSubtype(),
00185                    targetTy->getRootType()->getBaseSubtype());
00186 
00187     addDeclRewrite(idecl, result);
00188     mirrorRegion(idecl, result);
00189     return result;
00190 }
00191 
00192 RecordDecl *DeclRewriter::rewriteRecordDecl(RecordDecl *decl)
00193 {
00194     RecordDecl *result;
00195     if ((result = cast_or_null<RecordDecl>(findRewrite(decl))))
00196         return result;
00197 
00198     IdentifierInfo *name = decl->getIdInfo();
00199     AstResource &resource = getAstResource();
00200     result = resource.createRecordDecl(name, 0, context);
00201 
00202     typedef DeclRegion::DeclIter decl_iterator;
00203     decl_iterator I = decl->beginDecls();
00204     decl_iterator E = decl->endDecls();
00205     for ( ; I != E; ++I) {
00206         if (ComponentDecl *orig = dyn_cast<ComponentDecl>(*I)) {
00207             Type *componentTy = rewriteType(orig->getType());
00208             result->addComponent(orig->getIdInfo(), 0, componentTy);
00209         }
00210     }
00211 
00212     
00213     addTypeRewrite(decl->getType(), result->getType());
00214     addDeclRewrite(decl, result);
00215     return result;
00216 }
00217 
00218 IncompleteTypeDecl *
00219 DeclRewriter::rewriteIncompleteTypeDecl(IncompleteTypeDecl *ITD)
00220 {
00221     IncompleteTypeDecl *result;
00222     if ((result = cast_or_null<IncompleteTypeDecl>(findRewrite(ITD))))
00223         return result;
00224 
00225     IdentifierInfo *name = ITD->getIdInfo();
00226     result = getAstResource().createIncompleteTypeDecl(name, 0, context);
00227 
00228     
00229     
00230     addTypeRewrite(ITD->getType(), result->getType());
00231     addDeclRewrite(ITD, result);
00232 
00233     
00234     
00235     if (ITD->hasCompletion()) {
00236         TypeDecl *completion = rewriteTypeDecl(ITD->getCompletion());
00237         result->setCompletion(completion);
00238     }
00239 
00240     return result;
00241 }
00242 
00243 CarrierDecl *DeclRewriter::rewriteCarrierDecl(CarrierDecl *carrier)
00244 {
00245     CarrierDecl *result;
00246     if ((result = cast_or_null<CarrierDecl>(findRewrite(carrier))))
00247         return result;
00248 
00249     IdentifierInfo *name = carrier->getIdInfo();
00250     PrimaryType *rep = cast<PrimaryType>(rewriteType(carrier->getType()));
00251     result = new CarrierDecl(getAstResource(), name, rep, 0);
00252 
00253     addTypeRewrite(carrier->getType(), result->getType());
00254     addDeclRewrite(carrier, result);
00255     return result;
00256 }
00257 
00258 AccessDecl *DeclRewriter::rewriteAccessDecl(AccessDecl *access)
00259 {
00260     AccessDecl *result;
00261     if ((result = cast_or_null<AccessDecl>(findRewrite(access))))
00262         return result;
00263 
00264     AstResource &resource = getAstResource();
00265     IdentifierInfo *name = access->getIdInfo();
00266     Type *targetType = rewriteType(access->getType()->getTargetType());
00267 
00268     
00269     
00270     
00271     
00272     
00273     
00274     
00275     
00276     
00277     
00278     if ((result = cast_or_null<AccessDecl>(findRewrite(access))))
00279         return result;
00280 
00281     result = resource.createAccessDecl(name, 0, targetType, context);
00282     result->generateImplicitDeclarations(resource);
00283     result->setOrigin(access);
00284     addTypeRewrite(access->getType(), result->getType());
00285     addDeclRewrite(access, result);
00286     mirrorRegion(access, result);
00287     return result;
00288 }
00289 
00290 TypeDecl *DeclRewriter::rewriteTypeDecl(TypeDecl *decl)
00291 {
00292     TypeDecl *result = 0;
00293 
00294     switch (decl->getKind()) {
00295 
00296     default:
00297         assert(false && "Do not yet know how to rewrite the given decl!");
00298         break;
00299 
00300     case Ast::AST_IntegerDecl:
00301         result = rewriteIntegerDecl(cast<IntegerDecl>(decl));
00302         break;
00303 
00304     case Ast::AST_EnumerationDecl:
00305         result = rewriteEnumerationDecl(cast<EnumerationDecl>(decl));
00306         break;
00307 
00308     case Ast::AST_ArrayDecl:
00309         result = rewriteArrayDecl(cast<ArrayDecl>(decl));
00310         break;
00311 
00312     case Ast::AST_RecordDecl:
00313         result = rewriteRecordDecl(cast<RecordDecl>(decl));
00314         break;
00315 
00316     case Ast::AST_IncompleteTypeDecl:
00317         result = rewriteIncompleteTypeDecl(cast<IncompleteTypeDecl>(decl));
00318         break;
00319 
00320     case Ast::AST_CarrierDecl:
00321         result = rewriteCarrierDecl(cast<CarrierDecl>(decl));
00322         break;
00323 
00324     case Ast::AST_AccessDecl:
00325         result = rewriteAccessDecl(cast<AccessDecl>(decl));
00326         break;
00327 
00328     }
00329 
00330     return result;
00331 }
00332 
00333 Decl *DeclRewriter::rewriteDecl(Decl *decl)
00334 {
00335     Decl *result = 0;
00336     if ((result = findRewrite(decl)))
00337         return result;
00338 
00339     switch (decl->getKind()) {
00340 
00341     default:
00342         result = rewriteTypeDecl(cast<TypeDecl>(decl));
00343         break;
00344 
00345     case Ast::AST_FunctionDecl:
00346         result = rewriteFunctionDecl(cast<FunctionDecl>(decl));
00347         break;
00348 
00349     case Ast::AST_ProcedureDecl:
00350         result = rewriteProcedureDecl(cast<ProcedureDecl>(decl));
00351         break;
00352     };
00353 
00354     return result;
00355 }
00356 
00357 Type *DeclRewriter::rewriteType(Type *type)
00358 {
00359     Type *result = 0;
00360     if ((result = AstRewriter::findRewrite(type)))
00361         return result;
00362 
00363     switch (type->getKind()) {
00364 
00365     default:
00366         result = AstRewriter::rewriteType(type);
00367         break;
00368 
00369     case Ast::AST_AccessType:
00370         result = rewriteAccessType(cast<AccessType>(type));
00371         break;
00372 
00373     case Ast::AST_RecordType:
00374         result = rewriteRecordType(cast<RecordType>(type));
00375         break;
00376 
00377     case Ast::AST_IncompleteType:
00378         result = rewriteIncompleteType(cast<IncompleteType>(type));
00379         break;
00380 
00381     case Ast::AST_ArrayType:
00382         result = rewriteArrayType(cast<ArrayType>(type));
00383         break;
00384     }
00385     return result;
00386 }
00387 
00388 AccessType *DeclRewriter::rewriteAccessType(AccessType *type)
00389 {
00390     AccessDecl *declaration = type->getDefiningDecl();
00391     if (declaration->getDeclRegion() != origin)
00392         return type;
00393     return rewriteAccessDecl(declaration)->getType();
00394 }
00395 
00396 RecordType *DeclRewriter::rewriteRecordType(RecordType *type)
00397 {
00398     RecordDecl *declaration = type->getDefiningDecl();
00399     if (declaration->getDeclRegion() != origin)
00400         return type;
00401     return rewriteRecordDecl(declaration)->getType();
00402 }
00403 
00404 IncompleteType *DeclRewriter::rewriteIncompleteType(IncompleteType *type)
00405 {
00406     IncompleteTypeDecl *declaration = type->getDefiningDecl();
00407     if (declaration->getDeclRegion() != origin)
00408         return type;
00409     return rewriteIncompleteTypeDecl(declaration)->getType();
00410 }
00411 
00412 ArrayType *DeclRewriter::rewriteArrayType(ArrayType *type)
00413 {
00414     ArrayDecl *declaration = type->getDefiningDecl();
00415     if (declaration->getDeclRegion() != origin)
00416         return type;
00417     return rewriteArrayDecl(declaration)->getType();
00418 }
00419 
00420 IntegerLiteral *DeclRewriter::rewriteIntegerLiteral(IntegerLiteral *lit)
00421 {
00422     IntegerType *targetTy = cast<IntegerType>(rewriteType(lit->getType()));
00423     const llvm::APInt &value = lit->getValue();
00424     return new IntegerLiteral(value, targetTy, 0);
00425 }
00426 
00427 FunctionCallExpr *
00428 DeclRewriter::rewriteFunctionCall(FunctionCallExpr *call)
00429 {
00430     FunctionDecl *connective = call->getConnective();
00431     unsigned numArgs = call->getNumArgs();
00432     Expr *args[numArgs];
00433 
00434     if (Decl *rewrite = findRewrite(connective))
00435         connective = cast<FunctionDecl>(rewrite);
00436 
00437     
00438     
00439     FunctionCallExpr::arg_iterator I = call->begin_arguments();
00440     FunctionCallExpr::arg_iterator E = call->end_arguments();
00441     for (unsigned idx = 0; I != E; ++I, ++idx)
00442         args[idx] = rewriteExpr(*I);
00443 
00444     SubroutineRef *ref = new SubroutineRef(0, connective);
00445     return new FunctionCallExpr(ref, args, numArgs, 0, 0);
00446 }
00447 
00448 AttribExpr *DeclRewriter::rewriteAttrib(AttribExpr *attrib)
00449 {
00450     AttribExpr *result = 0;
00451 
00452     if (ScalarBoundAE *bound = dyn_cast<ScalarBoundAE>(attrib)) {
00453         IntegerType *prefix;
00454         prefix = cast<IntegerType>(rewriteType(bound->getPrefix()));
00455 
00456         if (bound->isFirst())
00457             result = new FirstAE(prefix, 0);
00458         else
00459             result = new LastAE(prefix, 0);
00460     }
00461     else {
00462         ArrayBoundAE *bound = cast<ArrayBoundAE>(attrib);
00463         Expr *prefix = rewriteExpr(bound->getPrefix());
00464 
00465         if (bound->hasImplicitDimension()) {
00466             if (bound->isFirst())
00467                 result = new FirstArrayAE(prefix, 0);
00468             else
00469                 result = new LastArrayAE(prefix, 0);
00470         }
00471         else {
00472             Expr *dim = rewriteExpr(bound->getDimensionExpr());
00473             if (bound->isFirst())
00474                 result = new FirstArrayAE(prefix, dim, 0);
00475             else
00476                 result = new LastArrayAE(prefix, dim, 0);
00477         }
00478     }
00479     return result;
00480 }
00481 
00482 ConversionExpr *DeclRewriter::rewriteConversion(ConversionExpr *conv)
00483 {
00484     Expr *operand = rewriteExpr(conv->getOperand());
00485     Type *targetTy = rewriteType(conv->getType());
00486     return new ConversionExpr(operand, targetTy, 0);
00487 }
00488 
00489 Expr *DeclRewriter::rewriteExpr(Expr *expr)
00490 {
00491     Expr *result = 0;
00492 
00493     switch (expr->getKind()) {
00494 
00495     default:
00496         if (AttribExpr *attrib = dyn_cast<AttribExpr>(expr))
00497             result = rewriteAttrib(attrib);
00498         else
00499             assert(false && "Cannot rewrite this kind of expr yet!");
00500         break;
00501 
00502     case Ast::AST_FunctionCallExpr:
00503         result = rewriteFunctionCall(cast<FunctionCallExpr>(expr));
00504         break;
00505 
00506     case Ast::AST_IntegerLiteral:
00507         result = rewriteIntegerLiteral(cast<IntegerLiteral>(expr));
00508         break;
00509 
00510     case Ast::AST_ConversionExpr:
00511         result = rewriteConversion(cast<ConversionExpr>(expr));
00512         break;
00513     };
00514 
00515     return result;
00516 }