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 //===-- ast/DeclRewriter.cpp ---------------------------------- -*- C++ -*-===// 00002 // 00003 // This file is distributed under the MIT license. See LICENSE.txt for details. 00004 // 00005 // Copyright (C) 2009-2010, Stephen Wilson 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 // Enumeration declarations do not require any rewriting. Just construct a 00103 // new declaration which is otherwise identical to the one given. 00104 // 00105 // Traverse the given decls region and extract each enumeration literal 00106 // therein. Note that the DeclRegion of an enumeration contains 00107 // declarations for its primitive operations as well. 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 // Inject rewrite rules mapping the old enumeration to the new. 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 // Just rewrite the index types into DSTDef's with the Type_DST tag. 00142 // There is no loss of type information (but the original syntax of the 00143 // declaration is gone, which is OK for a rewritten node). 00144 // 00145 // FIXME: It should be possible to construct an ArrayDecl over a set of 00146 // DiscreteType's instead of always requiring DSTDef's. 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 // Provide mappings from the first subtypes and base types of the source and 00182 // target. 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 // Provide mappings from the original first subtype to the new subtype. 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 // Provide a mapping from the original declaration to the new one. We do 00229 // this before rewriting the completion (if any) to avoid circularites. 00230 addTypeRewrite(ITD->getType(), result->getType()); 00231 addDeclRewrite(ITD, result); 00232 00233 // The new incomplete type declaration does not have a completion. If the 00234 // given ITD has a completion rewrite it as well. 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 // An access type can ultimately reference itself via the target type. If 00269 // we have an entry to ourselves we know a circularity is present and we are 00270 // done. 00271 // 00272 // FIXME: It might be better to construct an access decl without a target 00273 // type and insert it into the rewrite map immediately so that any recursive 00274 // references can simply be resolved. OTOH, the current approach depends on 00275 // the rewriter "bottoming out" thru an incomplete type when circularities 00276 // are present. In some sense, the current implementation "tests" that the 00277 // AST is sane at the expense of speed. 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 // When rewriting function calls we pay no respect to any keyed arguments in 00438 // the source expression. Just generate a positional call. 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 }