00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "DeclProducer.h"
00015 #include "comma/ast/AstResource.h"
00016 #include "comma/ast/Decl.h"
00017 #include "comma/ast/Expr.h"
00018 #include "comma/ast/Type.h"
00019
00020 using namespace comma;
00021
00022 using llvm::dyn_cast;
00023 using llvm::cast;
00024 using llvm::isa;
00025
00026 DeclProducer::DeclProducer(AstResource *resource)
00027 : resource(resource),
00028 theBoolDecl(0),
00029 theIntegerDecl(0)
00030 {
00031 createTheBoolDecl();
00032 createTheIntegerDecl();
00033
00034 createImplicitDecls(theBoolDecl);
00035 createImplicitDecls(theIntegerDecl);
00036 }
00037
00041 void DeclProducer::createTheBoolDecl()
00042 {
00043 IdentifierInfo *boolId = resource->getIdentifierInfo("Bool");
00044 IdentifierInfo *trueId = resource->getIdentifierInfo("true");
00045 IdentifierInfo *falseId = resource->getIdentifierInfo("false");
00046
00047
00048
00049 theBoolDecl = new EnumerationDecl(boolId, 0, 0);
00050 new EnumLiteral(theBoolDecl, falseId, 0);
00051 new EnumLiteral(theBoolDecl, trueId, 0);
00052 }
00053
00056 void DeclProducer::createTheIntegerDecl()
00057 {
00058 IdentifierInfo *integerId = resource->getIdentifierInfo("Integer");
00059
00060
00061
00062 llvm::APInt lowVal(64, 1UL << 63);
00063 llvm::APInt highVal(64, ~(1UL << 63));
00064 IntegerLiteral *lowExpr = new IntegerLiteral(lowVal, 0);
00065 IntegerLiteral *highExpr = new IntegerLiteral(highVal, 0);
00066 IntegerType *intTy = resource->getIntegerType(lowVal, highVal);
00067
00068 theIntegerDecl = new IntegerDecl(integerId, 0, lowExpr, highExpr, intTy, 0);
00069 }
00070
00071
00073 EnumerationDecl *DeclProducer::getBoolDecl() const
00074 {
00075 return theBoolDecl;
00076 }
00077
00079 EnumerationType *DeclProducer::getBoolType() const
00080 {
00081 return theBoolDecl->getType();
00082 }
00083
00085 IntegerDecl *DeclProducer::getIntegerDecl() const
00086 {
00087 return theIntegerDecl;
00088 }
00089
00091 TypedefType *DeclProducer::getIntegerType() const
00092 {
00093 return theIntegerDecl->getType();
00094 }
00095
00097 IdentifierInfo *DeclProducer::getPredicateName(PredicateKind kind)
00098 {
00099 switch (kind) {
00100 default:
00101 assert(false && "Bad kind of predicate!");
00102 return 0;
00103 case EQ_pred:
00104 return resource->getIdentifierInfo("=");
00105 case LT_pred:
00106 return resource->getIdentifierInfo("<");
00107 case GT_pred:
00108 return resource->getIdentifierInfo(">");
00109 case LTEQ_pred:
00110 return resource->getIdentifierInfo("<=");
00111 case GTEQ_pred:
00112 return resource->getIdentifierInfo(">=");
00113 }
00114 }
00115
00117 PO::PrimitiveID DeclProducer::getPredicatePrimitive(PredicateKind kind)
00118 {
00119 switch (kind) {
00120 default:
00121 assert(false && "Bad kind of predicate!");
00122 return PO::NotPrimitive;
00123 case EQ_pred:
00124 return PO::Equality;
00125 case LT_pred:
00126 return PO::LessThan;
00127 case GT_pred:
00128 return PO::GreaterThan;
00129 case LTEQ_pred:
00130 return PO::LessThanOrEqual;
00131 case GTEQ_pred:
00132 return PO::GreaterThanOrEqual;
00133 }
00134 }
00135
00138 void DeclProducer::createImplicitDecls(EnumerationDecl *enumDecl)
00139 {
00140
00141 FunctionDecl *equals =
00142 createPredicate(EQ_pred, enumDecl->getType(), enumDecl);
00143 enumDecl->addDecl(equals);
00144 }
00145
00148 void DeclProducer::createImplicitDecls(IntegerDecl *intDecl)
00149 {
00150 FunctionDecl *equals =
00151 createPredicate(EQ_pred, intDecl->getType(), intDecl);
00152 FunctionDecl *lt =
00153 createPredicate(LT_pred, intDecl->getType(), intDecl);
00154 FunctionDecl *gt =
00155 createPredicate(GT_pred, intDecl->getType(), intDecl);
00156 FunctionDecl *lteq =
00157 createPredicate(LTEQ_pred, intDecl->getType(), intDecl);
00158 FunctionDecl *gteq =
00159 createPredicate(GTEQ_pred, intDecl->getType(), intDecl);
00160 FunctionDecl *plus =
00161 createBinaryArithOp(PLUS_arith, intDecl->getType(), intDecl);
00162 FunctionDecl *minus =
00163 createBinaryArithOp(MINUS_arith, intDecl->getType(), intDecl);
00164
00165 intDecl->addDecl(equals);
00166 intDecl->addDecl(lt);
00167 intDecl->addDecl(gt);
00168 intDecl->addDecl(lteq);
00169 intDecl->addDecl(gteq);
00170 intDecl->addDecl(plus);
00171 intDecl->addDecl(minus);
00172 }
00173
00174 FunctionDecl *
00175 DeclProducer::createPredicate(PredicateKind kind, Type *paramType,
00176 DeclRegion *parent)
00177 {
00178 IdentifierInfo *name = getPredicateName(kind);
00179 IdentifierInfo *paramX = resource->getIdentifierInfo("X");
00180 IdentifierInfo *paramY = resource->getIdentifierInfo("Y");
00181
00182 ParamValueDecl *params[] = {
00183 new ParamValueDecl(paramX, paramType, PM::MODE_DEFAULT, 0),
00184 new ParamValueDecl(paramY, paramType, PM::MODE_DEFAULT, 0)
00185 };
00186
00187 FunctionDecl *pred =
00188 new FunctionDecl(name, 0, params, 2, theBoolDecl->getType(),
00189 parent);
00190 pred->setAsPrimitive(getPredicatePrimitive(kind));
00191 return pred;
00192 }
00193
00194 IdentifierInfo *DeclProducer::getArithName(ArithKind kind)
00195 {
00196 switch (kind) {
00197 default:
00198 assert(false && "Bad arithmetic kind!");
00199 return 0;
00200 case PLUS_arith:
00201 return resource->getIdentifierInfo("+");
00202 case MINUS_arith:
00203 return resource->getIdentifierInfo("-");
00204 }
00205 }
00206
00207 PO::PrimitiveID DeclProducer::getArithPrimitive(ArithKind kind)
00208 {
00209 switch (kind) {
00210 default:
00211 assert(false && "Bad arithmetic kind!");
00212 return PO::NotPrimitive;
00213 case PLUS_arith:
00214 return PO::Plus;
00215 case MINUS_arith:
00216 return PO::Minus;
00217 }
00218 }
00219
00220 FunctionDecl *
00221 DeclProducer::createBinaryArithOp(ArithKind kind, Type *Ty, DeclRegion *parent)
00222 {
00223 IdentifierInfo *name = getArithName(kind);
00224 IdentifierInfo *paramX = resource->getIdentifierInfo("X");
00225 IdentifierInfo *paramY = resource->getIdentifierInfo("Y");
00226
00227 ParamValueDecl *params[] = {
00228 new ParamValueDecl(paramX, Ty, PM::MODE_DEFAULT, 0),
00229 new ParamValueDecl(paramY, Ty, PM::MODE_DEFAULT, 0)
00230 };
00231
00232 FunctionDecl *op = new FunctionDecl(name, 0, params, 2, Ty, parent);
00233 op->setAsPrimitive(getArithPrimitive(kind));
00234 return op;
00235 }