/* ** MapQueueMove ** ** Applies a function to each element in a queue. If the function returns ** moveVal, it enqueues the element to q2, otherwise it requeues it to ** the original queue. */ int MapQueueMove(QUEUE q, int (*pFunc)(void *, void**), void **argv, int moveVal, QUEUE q2) { void *item; int count = QueueCount(q); int status = SUCCESS; TypeCheck(q,TYPE_QUEUE); TypeCheck(q2,TYPE_QUEUE); assert(! IS_ERROR(moveVal)); while (count--) { item = DeQueue(q); if (NULL == item) return(-1); status = (*pFunc)(item,argv); if (IS_ERROR(status)) return(status); if (status == moveVal) status = EnQueue(q2,item); else status = EnQueue(q,item); if (IS_ERROR(status)) return(status); } return(status); }
long CommandImplementation::GetLong(const wxString ¶mName) { CheckParam(paramName); const wxVariant &v = mParams[paramName]; TypeCheck(wxT("double"), paramName, v); return (long)v.GetDouble(); }
/* ** MapQueue ** Applies a function to all elements of a queue. ** ** As long as each function continues to return a non-negative value, ** MapQueue will apply it to the next element. When a negative return ** value occurs, MapQueue will stop. ** ** In any case, it returns the return value from the last call to the ** applied function, or SUCCESS if the queue is empty. ** ** Important note: ** Do not attempt to enqueue or dequeue in a MapQueue'd ** function. It will be ruinous. */ int MapQueue(QUEUE queue, int (*pFunc)(void *, void**), void **argv) { TRAY tray; int status; int count; assert(queue); TypeCheck(queue,TYPE_QUEUE); tray = queue->front; for (tray = queue->front, count = queue->count, status = SUCCESS; (! IS_ERROR(status)) && tray != NULL && count > 0; tray = (tray->next), count-- ) status = (*pFunc)(tray->item,argv); if (! IS_ERROR(status)) /* consistency check */ assert (NULL == tray && count == 0); return(status); }
void CqParseNodeFunctionCall::validTypes( std::list<std::pair<TqInt, TqInt> >& types) { // First do a typecheck, which will eliminate all candidates that don't // match the argument list. bool needsCast; TqInt bestType = TypeCheck( pAllTypes(), Type_Last - 1, needsCast, true ); // Create a map of types against suitability weights. std::map<TqInt, TqInt> suitableTypes; // For each candidate function, add it's real return type. std::vector<SqFuncRef>::iterator i; for ( i = m_aFuncRef.begin(); i != m_aFuncRef.end(); ++i ) { TqInt mainType = bestType; // Set a directly available type as a high priority no matter what. suitableTypes[mainType] = 99; // Now check the possible castable types, storing only if they have a weight greater than // an existing mapping. for(TqInt castType = Type_Nil; castType < Type_Last; ++castType) if(m_aaTypePriorities[mainType & Type_Mask][castType & Type_Mask] != 0 && castType != mainType && ( suitableTypes.find(castType) == suitableTypes.end() || suitableTypes[castType] < m_aaTypePriorities[mainType & Type_Mask][castType & Type_Mask]) ) suitableTypes[castType] = m_aaTypePriorities[mainType & Type_Mask][castType & Type_Mask]; } // Now copy the findings to the types list types.clear(); std::copy(suitableTypes.begin(), suitableTypes.end(), std::back_inserter(types)); }
void CivArchive::Store(uint8 *pbData, uint32 ulLen) { #ifdef ARCHIVE_TYPE_CHECK TypeCheck(TYPE_CHECK_ARRAY); #endif ARCHIVE_TYPE_CHECK Assert(m_bIsStoring); if ((m_ulLength + ulLen) >= m_ulAllocated) DoubleExpand(ulLen) ; memcpy(m_pbInsert, pbData, ulLen) ; m_pbInsert += ulLen ; m_ulLength += ulLen ; }
wxString CommandImplementation::GetString(const wxString ¶mName) { CheckParam(paramName); const wxVariant &v = mParams[paramName]; TypeCheck(wxT("string"), paramName, v); return v.GetString(); }
Function::Function(Symbol *s, const std::vector<Symbol *> &a, Stmt *c) { sym = s; args = a; code = c; maskSymbol = m->symbolTable->LookupVariable("__mask"); Assert(maskSymbol != NULL); if (code != NULL) { code = TypeCheck(code); if (code != NULL && g->debugPrint) { fprintf(stderr, "After typechecking function \"%s\":\n", sym->name.c_str()); code->Print(0); fprintf(stderr, "---------------------\n"); } if (code != NULL) { code = Optimize(code); if (g->debugPrint) { fprintf(stderr, "After optimizing function \"%s\":\n", sym->name.c_str()); code->Print(0); fprintf(stderr, "---------------------\n"); } } } if (g->debugPrint) { printf("Add Function %s\n", sym->name.c_str()); code->Print(0); printf("\n\n\n"); } const FunctionType *type = dynamic_cast<const FunctionType *>(sym->type); Assert(type != NULL); for (unsigned int i = 0; i < args.size(); ++i) if (dynamic_cast<const ReferenceType *>(args[i]->type) == NULL) args[i]->parentFunction = this; if (type->isTask) { threadIndexSym = m->symbolTable->LookupVariable("threadIndex"); Assert(threadIndexSym); threadCountSym = m->symbolTable->LookupVariable("threadCount"); Assert(threadCountSym); taskIndexSym = m->symbolTable->LookupVariable("taskIndex"); Assert(taskIndexSym); taskCountSym = m->symbolTable->LookupVariable("taskCount"); Assert(taskCountSym); } else threadIndexSym = threadCountSym = taskIndexSym = taskCountSym = NULL; }
void *DeQueue(QUEUE queue) { TRAY tray; void *item; TypeCheck(queue,TYPE_QUEUE); tray = queue->front; if (NULL == tray) return(NULL); queue->front = tray->next; if (NULL == queue->front) queue->back = NULL; queue->count--; item = tray->item; free(tray); return(item); }
void CivArchive::Load(uint8 *pbData, uint32 ulLen) { #ifdef ARCHIVE_TYPE_CHECK TypeCheck(TYPE_CHECK_ARRAY); #endif ARCHIVE_TYPE_CHECK #ifdef _DEBUG Assert(!m_bIsStoring); if (((m_pbInsert - m_pbBaseMemory) + ulLen) > m_ulLength) { { BOOL ARCHIVE_LOAD_MEMORY_ERROR=0; Assert(ARCHIVE_LOAD_MEMORY_ERROR); } exit(0); } #endif Assert(pbData); memcpy(pbData, m_pbInsert, ulLen) ; m_pbInsert += ulLen ; }
int EnQueue(QUEUE queue, void *item) { TRAY tray; TypeCheck(queue,TYPE_QUEUE); tray = (TRAY)malloc(sizeof(_TRAY_)); if (NULL == tray) return(FAILURE); tray->next = NULL; tray->item = item; /* Put item in back of the queue */ assert(0 <= queue->count); if (0 == queue->count) queue->front = tray; else { assert(NULL != queue->back); queue->back->next = tray; } queue->back = tray; queue->count++; return(SUCCESS); }
/**Function************************************************************* Synopsis [The main() procedure.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Abc_RealMain( int argc, char * argv[] ) { Abc_Frame_t * pAbc; char sCommandUsr[500] = {0}, sCommandTmp[100], sReadCmd[20], sWriteCmd[20]; const char * sOutFile, * sInFile; char * sCommand; int fStatus = 0; int c, fBatch, fInitSource, fInitRead, fFinalWrite; // added to detect memory leaks // watch for {,,msvcrtd.dll}*__p__crtBreakAlloc() // (http://support.microsoft.com/kb/151585) #if defined(_DEBUG) && defined(_MSC_VER) _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); #endif // get global frame (singleton pattern) // will be initialized on first call pAbc = Abc_FrameGetGlobalFrame(); pAbc->sBinary = argv[0]; #ifdef ABC_PYTHON_EMBED { PyObject* pModule; void init_pyabc(void); Py_SetProgramName(argv[0]); Py_NoSiteFlag = 1; Py_Initialize(); init_pyabc(); pModule = PyImport_ImportModule("pyabc"); if (pModule) { Py_DECREF(pModule); } else { fprintf( pAbc->Err, "error: pyabc.py not found. PYTHONPATH may not be set properly.\n"); } } #endif /* ABC_PYTHON_EMBED */ // default options fBatch = 0; fInitSource = 1; fInitRead = 0; fFinalWrite = 0; sInFile = sOutFile = NULL; sprintf( sReadCmd, "read" ); sprintf( sWriteCmd, "write" ); Extra_UtilGetoptReset(); while ((c = Extra_UtilGetopt(argc, argv, "c:C:hf:F:o:st:T:xb")) != EOF) { switch(c) { case 'c': strcpy( sCommandUsr, globalUtilOptarg ); fBatch = 1; break; case 'C': strcpy( sCommandUsr, globalUtilOptarg ); fBatch = 2; break; case 'f': sprintf(sCommandUsr, "source %s", globalUtilOptarg); fBatch = 1; break; case 'F': sprintf(sCommandUsr, "source -x %s", globalUtilOptarg); fBatch = 1; break; case 'h': goto usage; break; case 'o': sOutFile = globalUtilOptarg; fFinalWrite = 1; break; case 's': fInitSource = 0; break; case 't': if ( TypeCheck( pAbc, globalUtilOptarg ) ) { if ( !strcmp(globalUtilOptarg, "none") == 0 ) { fInitRead = 1; sprintf( sReadCmd, "read_%s", globalUtilOptarg ); } } else { goto usage; } fBatch = 1; break; case 'T': if ( TypeCheck( pAbc, globalUtilOptarg ) ) { if (!strcmp(globalUtilOptarg, "none") == 0) { fFinalWrite = 1; sprintf( sWriteCmd, "write_%s", globalUtilOptarg); } } else { goto usage; } fBatch = 1; break; case 'x': fFinalWrite = 0; fInitRead = 0; fBatch = 1; break; case 'b': Abc_FrameSetBridgeMode(); break; default: goto usage; } } if ( Abc_FrameIsBridgeMode() ) { extern Gia_Man_t * Gia_ManFromBridge( FILE * pFile, Vec_Int_t ** pvInit ); pAbc->pGia = Gia_ManFromBridge( stdin, NULL ); } else if ( fBatch && sCommandUsr[0] ) Abc_Print( 1, "ABC command line: \"%s\".\n\n", sCommandUsr ); if ( fBatch ) { pAbc->fBatchMode = 1; if (argc - globalUtilOptind == 0) { sInFile = NULL; } else if (argc - globalUtilOptind == 1) { fInitRead = 1; sInFile = argv[globalUtilOptind]; } else { Abc_UtilsPrintUsage( pAbc, argv[0] ); } // source the resource file if ( fInitSource ) { Abc_UtilsSource( pAbc ); } fStatus = 0; if ( fInitRead && sInFile ) { sprintf( sCommandTmp, "%s %s", sReadCmd, sInFile ); fStatus = Cmd_CommandExecute( pAbc, sCommandTmp ); } if ( fStatus == 0 ) { /* cmd line contains `source <file>' */ fStatus = Cmd_CommandExecute( pAbc, sCommandUsr ); if ( (fStatus == 0 || fStatus == -1) && fFinalWrite && sOutFile ) { sprintf( sCommandTmp, "%s %s", sWriteCmd, sOutFile ); fStatus = Cmd_CommandExecute( pAbc, sCommandTmp ); } } if (fBatch == 2){ fBatch = 0; pAbc->fBatchMode = 0; } } if ( !fBatch ) { // start interactive mode // print the hello line Abc_UtilsPrintHello( pAbc ); // print history of the recent commands Cmd_HistoryPrint( pAbc, 10 ); // source the resource file if ( fInitSource ) { Abc_UtilsSource( pAbc ); } // execute commands given by the user while ( !feof(stdin) ) { // print command line prompt and // get the command from the user sCommand = Abc_UtilsGetUsersInput( pAbc ); // execute the user's command fStatus = Cmd_CommandExecute( pAbc, sCommand ); // stop if the user quitted or an error occurred if ( fStatus == -1 || fStatus == -2 ) break; } } #ifdef ABC_PYTHON_EMBED { Py_Finalize(); } #endif /* ABC_PYTHON_EMBED */ // if the memory should be freed, quit packages // if ( fStatus < 0 ) { Abc_Stop(); } return 0; usage: Abc_UtilsPrintHello( pAbc ); Abc_UtilsPrintUsage( pAbc, argv[0] ); return 1; }
Function::Function(Symbol *s, Stmt *c) { sym = s; code = c; maskSymbol = m->symbolTable->LookupVariable("__mask"); Assert(maskSymbol != NULL); if (code != NULL) { code = TypeCheck(code); if (code != NULL && g->debugPrint) { printf("After typechecking function \"%s\":\n", sym->name.c_str()); code->Print(0); printf("---------------------\n"); } if (code != NULL) { code = Optimize(code); if (g->debugPrint) { printf("After optimizing function \"%s\":\n", sym->name.c_str()); code->Print(0); printf("---------------------\n"); } } } if (g->debugPrint) { printf("Add Function %s\n", sym->name.c_str()); code->Print(0); printf("\n\n\n"); } const FunctionType *type = CastType<FunctionType>(sym->type); Assert(type != NULL); for (int i = 0; i < type->GetNumParameters(); ++i) { const char *paramName = type->GetParameterName(i).c_str(); Symbol *sym = m->symbolTable->LookupVariable(paramName); if (sym == NULL) Assert(strncmp(paramName, "__anon_parameter_", 17) == 0); args.push_back(sym); const Type *t = type->GetParameterType(i); if (sym != NULL && CastType<ReferenceType>(t) == NULL) sym->parentFunction = this; } if (type->isTask #ifdef ISPC_NVPTX_ENABLED && (g->target->getISA() != Target::NVPTX) #endif ){ threadIndexSym = m->symbolTable->LookupVariable("threadIndex"); Assert(threadIndexSym); threadCountSym = m->symbolTable->LookupVariable("threadCount"); Assert(threadCountSym); taskIndexSym = m->symbolTable->LookupVariable("taskIndex"); Assert(taskIndexSym); taskCountSym = m->symbolTable->LookupVariable("taskCount"); Assert(taskCountSym); taskIndexSym0 = m->symbolTable->LookupVariable("taskIndex0"); Assert(taskIndexSym0); taskIndexSym1 = m->symbolTable->LookupVariable("taskIndex1"); Assert(taskIndexSym1); taskIndexSym2 = m->symbolTable->LookupVariable("taskIndex2"); Assert(taskIndexSym2); taskCountSym0 = m->symbolTable->LookupVariable("taskCount0"); Assert(taskCountSym0); taskCountSym1 = m->symbolTable->LookupVariable("taskCount1"); Assert(taskCountSym1); taskCountSym2 = m->symbolTable->LookupVariable("taskCount2"); Assert(taskCountSym2); } else { threadIndexSym = threadCountSym = taskIndexSym = taskCountSym = NULL; taskIndexSym0 = taskIndexSym1 = taskIndexSym2 = NULL; taskCountSym0 = taskCountSym1 = taskCountSym2 = NULL; } }
const Type * Declarator::GetType(const Type *base, DeclSpecs *ds) const { bool hasUniformQual = ((typeQualifiers & TYPEQUAL_UNIFORM) != 0); bool hasVaryingQual = ((typeQualifiers & TYPEQUAL_VARYING) != 0); bool isTask = ((typeQualifiers & TYPEQUAL_TASK) != 0); bool isConst = ((typeQualifiers & TYPEQUAL_CONST) != 0); if (hasUniformQual && hasVaryingQual) { Error(pos, "Can't provide both \"uniform\" and \"varying\" qualifiers."); return NULL; } if (kind != DK_FUNCTION && isTask) Error(pos, "\"task\" qualifier illegal in variable declaration."); const Type *type = base; switch (kind) { case DK_BASE: // All of the type qualifiers should be in the DeclSpecs for the // base declarator Assert(typeQualifiers == 0); Assert(child == NULL); return type; case DK_POINTER: type = new PointerType(type, hasUniformQual, isConst); if (child != NULL) return child->GetType(type, ds); else return type; break; case DK_REFERENCE: if (hasUniformQual) Error(pos, "\"uniform\" qualifier is illegal to apply to references."); if (hasVaryingQual) Error(pos, "\"varying\" qualifier is illegal to apply to references."); if (isConst) Error(pos, "\"const\" qualifier is to illegal apply to references."); // The parser should disallow this already, but double check. if (dynamic_cast<const ReferenceType *>(type) != NULL) { Error(pos, "References to references are illegal."); return NULL; } type = new ReferenceType(type); if (child != NULL) return child->GetType(type, ds); else return type; break; case DK_ARRAY: type = new ArrayType(type, arraySize); if (child) return child->GetType(type, ds); else return type; break; case DK_FUNCTION: { std::vector<const Type *> args; std::vector<std::string> argNames; std::vector<ConstExpr *> argDefaults; std::vector<SourcePos> argPos; // Loop over the function arguments and store the names, types, // default values (if any), and source file positions each one in // the corresponding vector. for (unsigned int i = 0; i < functionParams.size(); ++i) { Declaration *d = functionParams[i]; char buf[32]; Symbol *sym; if (d->declarators.size() == 0) { // function declaration like foo(float), w/o a name for // the parameter sprintf(buf, "__anon_parameter_%d", i); sym = new Symbol(buf, pos); sym->type = d->declSpecs->GetBaseType(pos); } else { sym = d->declarators[0]->GetSymbol(); if (sym == NULL) { // Handle more complex anonymous declarations like // float (float **). sprintf(buf, "__anon_parameter_%d", i); sym = new Symbol(buf, d->declarators[0]->pos); sym->type = d->declarators[0]->GetType(d->declSpecs); } } if (d->declSpecs->storageClass != SC_NONE) Error(sym->pos, "Storage class \"%s\" is illegal in " "function parameter declaration for parameter \"%s\".", lGetStorageClassName(d->declSpecs->storageClass), sym->name.c_str()); const ArrayType *at = dynamic_cast<const ArrayType *>(sym->type); if (at != NULL) { // As in C, arrays are passed to functions as pointers to // their element type. We'll just immediately make this // change now. (One shortcoming of losing the fact that // the it was originally an array is that any warnings or // errors later issued that print the function type will // report this differently than it was originally declared // in the function, but it's not clear that this is a // significant problem.) sym->type = PointerType::GetUniform(at->GetElementType()); // Make sure there are no unsized arrays (other than the // first dimension) in function parameter lists. at = dynamic_cast<const ArrayType *>(at->GetElementType()); while (at != NULL) { if (at->GetElementCount() == 0) Error(sym->pos, "Arrays with unsized dimensions in " "dimensions after the first one are illegal in " "function parameter lists."); at = dynamic_cast<const ArrayType *>(at->GetElementType()); } } args.push_back(sym->type); argNames.push_back(sym->name); argPos.push_back(sym->pos); ConstExpr *init = NULL; if (d->declarators.size()) { // Try to find an initializer expression; if there is one, // it lives down to the base declarator. Declarator *decl = d->declarators[0]; while (decl->child != NULL) { Assert(decl->initExpr == NULL); decl = decl->child; } if (decl->initExpr != NULL && (decl->initExpr = TypeCheck(decl->initExpr)) != NULL && (decl->initExpr = Optimize(decl->initExpr)) != NULL && (init = dynamic_cast<ConstExpr *>(decl->initExpr)) == NULL) { Error(decl->initExpr->pos, "Default value for parameter " "\"%s\" must be a compile-time constant.", sym->name.c_str()); } } argDefaults.push_back(init); } const Type *returnType = type; if (returnType == NULL) { Error(pos, "No return type provided in function declaration."); return NULL; } bool isExported = ds && (ds->storageClass == SC_EXPORT); bool isExternC = ds && (ds->storageClass == SC_EXTERN_C); bool isTask = ds && ((ds->typeQualifiers & TYPEQUAL_TASK) != 0); if (isExported && isTask) { Error(pos, "Function can't have both \"task\" and \"export\" " "qualifiers"); return NULL; } if (isExternC && isTask) { Error(pos, "Function can't have both \"extern \"C\"\" and \"task\" " "qualifiers"); return NULL; } if (isExternC && isExported) { Error(pos, "Function can't have both \"extern \"C\"\" and \"export\" " "qualifiers"); return NULL; } Type *functionType = new FunctionType(returnType, args, pos, argNames, argDefaults, argPos, isTask, isExported, isExternC); return child->GetType(functionType, ds); } default: FATAL("Unexpected decl kind"); return NULL; } #if 0 // Make sure we actually have an array of structs .. const StructType *childStructType = dynamic_cast<const StructType *>(childType); if (childStructType == NULL) { Error(pos, "Illegal to provide soa<%d> qualifier with non-struct " "type \"%s\".", soaWidth, childType->GetString().c_str()); return new ArrayType(childType, arraySize == -1 ? 0 : arraySize); } else if ((soaWidth & (soaWidth - 1)) != 0) { Error(pos, "soa<%d> width illegal. Value must be power of two.", soaWidth); return NULL; } else if (arraySize != -1 && (arraySize % soaWidth) != 0) { Error(pos, "soa<%d> width must evenly divide array size %d.", soaWidth, arraySize); return NULL; } return new SOAArrayType(childStructType, arraySize == -1 ? 0 : arraySize, soaWidth); #endif }
void Declarator::InitFromType(const Type *baseType, DeclSpecs *ds) { bool hasUniformQual = ((typeQualifiers & TYPEQUAL_UNIFORM) != 0); bool hasVaryingQual = ((typeQualifiers & TYPEQUAL_VARYING) != 0); bool isTask = ((typeQualifiers & TYPEQUAL_TASK) != 0); bool isExported = ((typeQualifiers & TYPEQUAL_EXPORT) != 0); bool isConst = ((typeQualifiers & TYPEQUAL_CONST) != 0); bool isUnmasked = ((typeQualifiers & TYPEQUAL_UNMASKED) != 0); if (hasUniformQual && hasVaryingQual) { Error(pos, "Can't provide both \"uniform\" and \"varying\" qualifiers."); return; } if (kind != DK_FUNCTION && isTask) { Error(pos, "\"task\" qualifier illegal in variable declaration."); return; } if (kind != DK_FUNCTION && isUnmasked) { Error(pos, "\"unmasked\" qualifier illegal in variable declaration."); return; } if (kind != DK_FUNCTION && isExported) { Error(pos, "\"export\" qualifier illegal in variable declaration."); return; } Variability variability(Variability::Unbound); if (hasUniformQual) variability = Variability::Uniform; else if (hasVaryingQual) variability = Variability::Varying; if (kind == DK_BASE) { // All of the type qualifiers should be in the DeclSpecs for the // base declarator AssertPos(pos, typeQualifiers == 0); AssertPos(pos, child == NULL); type = baseType; } else if (kind == DK_POINTER) { /* For now, any pointer to an SOA type gets the slice property; if we add the capability to declare pointers as slices or not, we'll want to set this based on a type qualifier here. */ const Type *ptrType = new PointerType(baseType, variability, isConst, baseType->IsSOAType()); if (child != NULL) { child->InitFromType(ptrType, ds); type = child->type; name = child->name; } else type = ptrType; } else if (kind == DK_REFERENCE) { if (hasUniformQual) { Error(pos, "\"uniform\" qualifier is illegal to apply to references."); return; } if (hasVaryingQual) { Error(pos, "\"varying\" qualifier is illegal to apply to references."); return; } if (isConst) { Error(pos, "\"const\" qualifier is to illegal apply to references."); return; } // The parser should disallow this already, but double check. if (CastType<ReferenceType>(baseType) != NULL) { Error(pos, "References to references are illegal."); return; } const Type *refType = new ReferenceType(baseType); if (child != NULL) { child->InitFromType(refType, ds); type = child->type; name = child->name; } else type = refType; } else if (kind == DK_ARRAY) { if (Type::Equal(baseType, AtomicType::Void)) { Error(pos, "Arrays of \"void\" type are illegal."); return; } if (CastType<ReferenceType>(baseType)) { Error(pos, "Arrays of references (type \"%s\") are illegal.", baseType->GetString().c_str()); return; } const Type *arrayType = new ArrayType(baseType, arraySize); if (child != NULL) { child->InitFromType(arrayType, ds); type = child->type; name = child->name; } else type = arrayType; } else if (kind == DK_FUNCTION) { llvm::SmallVector<const Type *, 8> args; llvm::SmallVector<std::string, 8> argNames; llvm::SmallVector<Expr *, 8> argDefaults; llvm::SmallVector<SourcePos, 8> argPos; // Loop over the function arguments and store the names, types, // default values (if any), and source file positions each one in // the corresponding vector. for (unsigned int i = 0; i < functionParams.size(); ++i) { Declaration *d = functionParams[i]; if (d == NULL) { AssertPos(pos, m->errorCount > 0); continue; } if (d->declarators.size() == 0) { // function declaration like foo(float), w/o a name for the // parameter; wire up a placeholder Declarator for it d->declarators.push_back(new Declarator(DK_BASE, pos)); d->declarators[0]->InitFromDeclSpecs(d->declSpecs); } AssertPos(pos, d->declarators.size() == 1); Declarator *decl = d->declarators[0]; if (decl == NULL || decl->type == NULL) { AssertPos(pos, m->errorCount > 0); continue; } if (decl->name == "") { // Give a name to any anonymous parameter declarations char buf[32]; sprintf(buf, "__anon_parameter_%d", i); decl->name = buf; } decl->type = decl->type->ResolveUnboundVariability(Variability::Varying); if (d->declSpecs->storageClass != SC_NONE) Error(decl->pos, "Storage class \"%s\" is illegal in " "function parameter declaration for parameter \"%s\".", lGetStorageClassName(d->declSpecs->storageClass), decl->name.c_str()); if (Type::Equal(decl->type, AtomicType::Void)) { Error(decl->pos, "Parameter with type \"void\" illegal in function " "parameter list."); decl->type = NULL; } const ArrayType *at = CastType<ArrayType>(decl->type); if (at != NULL) { // As in C, arrays are passed to functions as pointers to // their element type. We'll just immediately make this // change now. (One shortcoming of losing the fact that // the it was originally an array is that any warnings or // errors later issued that print the function type will // report this differently than it was originally declared // in the function, but it's not clear that this is a // significant problem.) const Type *targetType = at->GetElementType(); if (targetType == NULL) { AssertPos(pos, m->errorCount > 0); return; } decl->type = PointerType::GetUniform(targetType); // Make sure there are no unsized arrays (other than the // first dimension) in function parameter lists. at = CastType<ArrayType>(targetType); while (at != NULL) { if (at->GetElementCount() == 0) Error(decl->pos, "Arrays with unsized dimensions in " "dimensions after the first one are illegal in " "function parameter lists."); at = CastType<ArrayType>(at->GetElementType()); } } args.push_back(decl->type); argNames.push_back(decl->name); argPos.push_back(decl->pos); Expr *init = NULL; // Try to find an initializer expression. while (decl != NULL) { if (decl->initExpr != NULL) { decl->initExpr = TypeCheck(decl->initExpr); decl->initExpr = Optimize(decl->initExpr); if (decl->initExpr != NULL) { init = dynamic_cast<ConstExpr *>(decl->initExpr); if (init == NULL) init = dynamic_cast<NullPointerExpr *>(decl->initExpr); if (init == NULL) Error(decl->initExpr->pos, "Default value for parameter " "\"%s\" must be a compile-time constant.", decl->name.c_str()); } break; } else decl = decl->child; } argDefaults.push_back(init); } const Type *returnType = baseType; if (returnType == NULL) { Error(pos, "No return type provided in function declaration."); return; } if (CastType<FunctionType>(returnType) != NULL) { Error(pos, "Illegal to return function type from function."); return; } returnType = returnType->ResolveUnboundVariability(Variability::Varying); bool isExternC = ds && (ds->storageClass == SC_EXTERN_C); bool isExported = ds && ((ds->typeQualifiers & TYPEQUAL_EXPORT) != 0); bool isTask = ds && ((ds->typeQualifiers & TYPEQUAL_TASK) != 0); bool isUnmasked = ds && ((ds->typeQualifiers & TYPEQUAL_UNMASKED) != 0); if (isExported && isTask) { Error(pos, "Function can't have both \"task\" and \"export\" " "qualifiers"); return; } if (isExternC && isTask) { Error(pos, "Function can't have both \"extern \"C\"\" and \"task\" " "qualifiers"); return; } if (isExternC && isExported) { Error(pos, "Function can't have both \"extern \"C\"\" and \"export\" " "qualifiers"); return; } if (isUnmasked && isExported) Warning(pos, "\"unmasked\" qualifier is redundant for exported " "functions."); if (child == NULL) { AssertPos(pos, m->errorCount > 0); return; } const FunctionType *functionType = new FunctionType(returnType, args, argNames, argDefaults, argPos, isTask, isExported, isExternC, isUnmasked); // handle any explicit __declspecs on the function if (ds != NULL) { for (int i = 0; i < (int)ds->declSpecList.size(); ++i) { std::string str = ds->declSpecList[i].first; SourcePos pos = ds->declSpecList[i].second; if (str == "safe") (const_cast<FunctionType *>(functionType))->isSafe = true; else if (!strncmp(str.c_str(), "cost", 4)) { int cost = atoi(str.c_str() + 4); if (cost < 0) Error(pos, "Negative function cost %d is illegal.", cost); (const_cast<FunctionType *>(functionType))->costOverride = cost; } else Error(pos, "__declspec parameter \"%s\" unknown.", str.c_str()); } } child->InitFromType(functionType, ds); type = child->type; name = child->name; } }
Function::Function(Symbol *s, Stmt *c) { sym = s; code = c; maskSymbol = m->symbolTable->LookupVariable("__mask"); Assert(maskSymbol != NULL); if (code != NULL) { code = TypeCheck(code); if (code != NULL && g->debugPrint) { fprintf(stderr, "After typechecking function \"%s\":\n", sym->name.c_str()); code->Print(0); fprintf(stderr, "---------------------\n"); } if (code != NULL) { code = Optimize(code); if (g->debugPrint) { fprintf(stderr, "After optimizing function \"%s\":\n", sym->name.c_str()); code->Print(0); fprintf(stderr, "---------------------\n"); } } } if (g->debugPrint) { printf("Add Function %s\n", sym->name.c_str()); code->Print(0); printf("\n\n\n"); } const FunctionType *type = dynamic_cast<const FunctionType *>(sym->type); Assert(type != NULL); for (int i = 0; i < type->GetNumParameters(); ++i) { const char *paramName = type->GetParameterName(i).c_str(); Symbol *sym = m->symbolTable->LookupVariable(paramName); if (sym == NULL) Assert(strncmp(paramName, "__anon_parameter_", 17) == 0); args.push_back(sym); const Type *t = type->GetParameterType(i); if (sym != NULL && dynamic_cast<const ReferenceType *>(t) == NULL) sym->parentFunction = this; } if (type->isTask) { threadIndexSym = m->symbolTable->LookupVariable("threadIndex"); Assert(threadIndexSym); threadCountSym = m->symbolTable->LookupVariable("threadCount"); Assert(threadCountSym); taskIndexSym = m->symbolTable->LookupVariable("taskIndex"); Assert(taskIndexSym); taskCountSym = m->symbolTable->LookupVariable("taskCount"); Assert(taskCountSym); } else threadIndexSym = threadCountSym = taskIndexSym = taskCountSym = NULL; }
/* * There really is no good way for this. We can't return any value that * wouldn't be a valid one. It would be nice to throw an * exception but * we cannot. */ static void AssertTypeWord(Thing T) { assert(TypeCheck(T, WORD) == true); }
/**Function************************************************************* Synopsis [The main() procedure.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int main( int argc, char * argv[] ) { Abc_Frame_t * pAbc; char sCommandUsr[500], sCommandTmp[100], sReadCmd[20], sWriteCmd[20], c; char * sCommand, * sOutFile, * sInFile; int fStatus = 0; bool fBatch, fInitSource, fInitRead, fFinalWrite; // added to detect memory leaks: #ifdef _DEBUG _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); #endif // Npn_Experiment(); // Npn_Generate(); // get global frame (singleton pattern) // will be initialized on first call pAbc = Abc_FrameGetGlobalFrame(); // default options fBatch = 0; fInitSource = 1; fInitRead = 0; fFinalWrite = 0; sInFile = sOutFile = NULL; sprintf( sReadCmd, "read" ); sprintf( sWriteCmd, "write" ); Extra_UtilGetoptReset(); while ((c = Extra_UtilGetopt(argc, argv, "c:hf:F:o:st:T:x")) != EOF) { switch(c) { case 'c': strcpy( sCommandUsr, globalUtilOptarg ); fBatch = 1; break; case 'f': sprintf(sCommandUsr, "source %s", globalUtilOptarg); fBatch = 1; break; case 'F': sprintf(sCommandUsr, "source -x %s", globalUtilOptarg); fBatch = 1; break; case 'h': goto usage; break; case 'o': sOutFile = globalUtilOptarg; fFinalWrite = 1; break; case 's': fInitSource = 0; break; case 't': if ( TypeCheck( pAbc, globalUtilOptarg ) ) { if ( !strcmp(globalUtilOptarg, "none") == 0 ) { fInitRead = 1; sprintf( sReadCmd, "read_%s", globalUtilOptarg ); } } else { goto usage; } fBatch = 1; break; case 'T': if ( TypeCheck( pAbc, globalUtilOptarg ) ) { if (!strcmp(globalUtilOptarg, "none") == 0) { fFinalWrite = 1; sprintf( sWriteCmd, "write_%s", globalUtilOptarg); } } else { goto usage; } fBatch = 1; break; case 'x': fFinalWrite = 0; fInitRead = 0; fBatch = 1; break; default: goto usage; } } if ( fBatch ) { pAbc->fBatchMode = 1; if (argc - globalUtilOptind == 0) { sInFile = NULL; } else if (argc - globalUtilOptind == 1) { fInitRead = 1; sInFile = argv[globalUtilOptind]; } else { Abc_UtilsPrintUsage( pAbc, argv[0] ); } // source the resource file if ( fInitSource ) { Abc_UtilsSource( pAbc ); } fStatus = 0; if ( fInitRead && sInFile ) { sprintf( sCommandTmp, "%s %s", sReadCmd, sInFile ); fStatus = Cmd_CommandExecute( pAbc, sCommandTmp ); } if ( fStatus == 0 ) { /* cmd line contains `source <file>' */ fStatus = Cmd_CommandExecute( pAbc, sCommandUsr ); if ( (fStatus == 0 || fStatus == -1) && fFinalWrite && sOutFile ) { sprintf( sCommandTmp, "%s %s", sWriteCmd, sOutFile ); fStatus = Cmd_CommandExecute( pAbc, sCommandTmp ); } } } else { // start interactive mode // print the hello line Abc_UtilsPrintHello( pAbc ); // source the resource file if ( fInitSource ) { Abc_UtilsSource( pAbc ); } // execute commands given by the user while ( !feof(stdin) ) { // print command line prompt and // get the command from the user sCommand = Abc_UtilsGetUsersInput( pAbc ); // execute the user's command fStatus = Cmd_CommandExecute( pAbc, sCommand ); // stop if the user quitted or an error occurred if ( fStatus == -1 || fStatus == -2 ) break; } } // if the memory should be freed, quit packages if ( fStatus < 0 ) { Abc_Stop(); } return 0; usage: Abc_UtilsPrintHello( pAbc ); Abc_UtilsPrintUsage( pAbc, argv[0] ); return 1; }
Expr * TypeCheck(Expr *expr) { return (Expr *)TypeCheck((ASTNode *)expr); }
Stmt * TypeCheck(Stmt *stmt) { return (Stmt *)TypeCheck((ASTNode *)stmt); }
int QueueCount(QUEUE queue) { TypeCheck(queue,TYPE_QUEUE); return(queue->count); }