/* * This routine emits the appropriate string to call the call_scope from the * given scope. If the module scopes for the two match then do nothing. If * the module scopes are different, but the call_scope begins with the * entire module scope of scope then we can trim the top off the call_scope * (it is a sub-scope of the module that contains scope). Otherwise we need * to print the entire path of call_scope. */ void emit_scope_module_path(ivl_scope_t scope, ivl_scope_t call_scope) { ivl_scope_t mod_scope = get_module_scope(scope); ivl_scope_t call_mod_scope = get_module_scope(call_scope); if (mod_scope == call_mod_scope) return; emit_scope_piece(mod_scope, call_mod_scope); }
/* * This routine emits the appropriate string to call the call_scope from the * given scope. If the module scopes for the two match then just return the * base name of the call_scope. If the module scopes are different, but the * call_scope begins with the entire module scope of scope then we can trim * the top off the call_scope (it is a sub-scope of the module that contains * scope). Otherwise we need to print the entire path of call_scope. */ void emit_scope_path(ivl_scope_t scope, ivl_scope_t call_scope) { ivl_scope_t mod_scope = get_module_scope(scope); ivl_scope_t call_mod_scope = get_module_scope(call_scope); if (mod_scope == call_mod_scope) { emit_id(ivl_scope_basename(call_scope)); } else { emit_scope_path_piece(mod_scope, call_scope); } }
// HERE: Does this work correctly with an array reference created from @*? void emit_name_of_nexus(ivl_scope_t scope, ivl_nexus_t nex, unsigned allow_UD) { ivl_scope_t mod_scope; /* First look in the local scope for the nexus name. */ if (find_signal_in_nexus(scope, nex)) return; /* If the signal was not found in the passed scope then look in * the module scope if the passed scope was not the module scope. */ mod_scope = get_module_scope(scope); if (mod_scope != scope) { if (find_signal_in_nexus(mod_scope, nex)) return; } /* Look to see if this is a up/down reference. */ if (allow_UD && find_driving_signal(scope, nex)) return; /* If there is no signals driving this then look for a constant. */ if (find_const_nexus(scope, nex)) return; /* Module inputs that are split (arg[7:4], arg[3:0]) need to use * the local signal names. */ if (is_local_input(scope, nex)) return; // HERE: Need to check arr[var]? Can this be rebuilt? // Then look for down scopes and then any scope. For all this warn if // multiples are found in a given scope. This all needs to be before // the constant code. /* It is possible that the nexus does not have a name. For this * case do not print an actual name. */ fprintf(vlog_out, "/* Empty */"); // dump_nexus_information(scope, nex); }
/* This is the same as emit_scope_module_path() except we need to add down * references for variables, etc. */ void emit_scope_call_path(ivl_scope_t scope, ivl_scope_t call_scope) { ivl_scope_t mod_scope = get_module_scope(scope); ivl_scope_t call_mod_scope = get_module_scope(call_scope); if (mod_scope != call_mod_scope) { emit_scope_piece(mod_scope, call_mod_scope); } else if (scope != call_scope) { ivl_scope_t parent; /* We only emit a scope path if the scope is a parent of the * call scope. */ for (parent = ivl_scope_parent(call_scope); parent != 0; parent = ivl_scope_parent(parent)) { if (parent == scope) { emit_scope_piece(scope, call_scope); return; } } } }
void get_class::operator()(compilation_unit& unit) { // todo: first look in namespace of current compilation unit auto& module_scope = get_module_scope(unit); auto search_it = module_scope.find(search_.front()); if (search_it != module_scope.end()) { chilon::variant_apply(*search_it, class_dep(*this, unit, get_module(unit))); return; } // todo: then check parent modules // todo: throw error throw error::file_location("type not found", search_.front()); }
static void emit_select_name(ivl_scope_t scope, ivl_expr_t expr, unsigned wid) { /* A select of a number is really a parameter select. */ if (ivl_expr_type(expr) == IVL_EX_NUMBER) { /* Look in the current scope. */ if (emit_param_name_in_scope(scope, expr)) return; /* Now look in the enclosing module scope if this is not a * module scope. */ if (ivl_scope_type(scope) != IVL_SCT_MODULE) { if (emit_param_name_in_scope(get_module_scope(scope), expr)) return; } // HERE: For now we only look in the current and module scope for the // parameter that is being selected. We need to also look in other // scopes, but that involves a big search. fprintf(vlog_out, "<missing>"); fprintf(stderr, "%s:%u: vlog95 error: Unable to find parameter " "for select expression \n", ivl_expr_file(expr), ivl_expr_lineno(expr)); vlog_errors += 1; } else { emit_expr(scope, expr, wid); } }
LLVM_DITYPE debug_data::construct_type(Type *type) { llvm::MDNode *N = myGetType(type); if(N) return toDITYPE(N); GenInfo* info = gGenInfo; LLVM_TARGET_DATA *layout = info->targetData; llvm::Type* ty = type->symbol->llvmType; const char* name = type->symbol->name; ModuleSymbol* defModule = type->symbol->getModule(); const char* defFile = type->symbol->fname(); if (strstr(defFile, "/modules/")!=NULL || strcmp(defFile, "<internal>")==0) { #if HAVE_LLVM_VER >= 37 return NULL; #else return llvm::DIType(); #endif } int defLine = type->symbol->linenum(); if(!ty) { #if HAVE_LLVM_VER >= 37 return NULL; #else return llvm::DIType(); #endif } if(ty->isIntegerTy()) { N = this->dibuilder.createBasicType( name, layout->getTypeSizeInBits(ty), 8*layout->getABITypeAlignment(ty), (is_signed(type))? (llvm::dwarf::DW_ATE_signed): (llvm::dwarf::DW_ATE_unsigned)); myTypeDescriptors[type] = N; return toDITYPE(N); } else if(ty->isFloatingPointTy()) { N = this->dibuilder.createBasicType( name, layout->getTypeSizeInBits(ty), 8*layout->getABITypeAlignment(ty), llvm::dwarf::DW_ATE_float); myTypeDescriptors[type] = N; return toDITYPE(N); } else if(ty->isPointerTy()) { if(type != type->getValType()) {//Add this condition to avoid segFault N = this->dibuilder.createPointerType( get_type(type->getValType()),//it should return the pointee's DIType layout->getPointerSizeInBits(ty->getPointerAddressSpace()), 0, /* alignment */ name); myTypeDescriptors[type] = N; return toDITYPE(N); } else { if(type->astTag == E_PrimitiveType) { llvm::Type *PointeeTy = ty->getPointerElementType(); // handle string, c_string, c_string_copy, nil, opaque, c_void_ptr if(PointeeTy->isIntegerTy()) { LLVM_DITYPE pteIntDIType; //create the DI-pointeeType pteIntDIType = this->dibuilder.createBasicType( myGetTypeName(PointeeTy), layout->getTypeSizeInBits(PointeeTy), 8*layout->getABITypeAlignment(PointeeTy), llvm::dwarf::DW_ATE_unsigned); N = this->dibuilder.createPointerType( pteIntDIType, layout->getPointerSizeInBits(ty->getPointerAddressSpace()), 0, name); myTypeDescriptors[type] = N; return toDITYPE(N); } // handle qio_channel_ptr_t, _task_list, qio_file_ptr_t, syserr, _file else if(PointeeTy->isStructTy()) { LLVM_DITYPE pteStrDIType; //create the DI-pointeeType pteStrDIType = this->dibuilder.createStructType( get_module_scope(defModule), PointeeTy->getStructName(), get_file(defFile), 0, (PointeeTy->isSized()? layout->getTypeSizeInBits(PointeeTy): 8), (PointeeTy->isSized()? 8*layout->getABITypeAlignment(PointeeTy): 8), 0, toDITYPE(NULL), #if HAVE_LLVM_VER >= 37 NULL #else llvm::DIArray(NULL) #endif ); N = this->dibuilder.createPointerType( pteStrDIType, layout->getPointerSizeInBits(ty->getPointerAddressSpace()), 0, name); myTypeDescriptors[type] = N; return toDITYPE(N); } } else if(type->astTag == E_AggregateType) { // dealing with classes AggregateType *this_class = (AggregateType *)type; llvm::SmallVector<LLVM_METADATA_OPERAND_TYPE *, 8> EltTys; LLVM_DITYPE derivedFrom = nullptr; if( type->dispatchParents.length() > 0 ) derivedFrom = get_type(type->dispatchParents.first()); // solve the data class: _ddata if(this_class->symbol->hasFlag(FLAG_DATA_CLASS)) { Type* vt = getDataClassType(this_class->symbol)->typeInfo(); if(vt) { N = this->dibuilder.createPointerType( get_type(vt), layout->getPointerSizeInBits(ty->getPointerAddressSpace()), 0, name); myTypeDescriptors[type] = N; return toDITYPE(N); } } //Not sure whether we should directly return getType(vt) const llvm::StructLayout* slayout = NULL; const char *struct_name = this_class->classStructName(true); llvm::Type* st = getTypeLLVM(struct_name); if(st){ llvm::StructType* struct_type = llvm::cast<llvm::StructType>(st); if(!struct_type->isOpaque()){ N = this->dibuilder.createForwardDecl( llvm::dwarf::DW_TAG_structure_type, name, get_module_scope(defModule), get_file(defFile), defLine, 0, // RuntimeLang layout->getTypeSizeInBits(ty), 8*layout->getABITypeAlignment(ty)); //N is added to the map (early) so that element search below can find it, //so as to avoid infinite recursion for structs that contain pointers to //their own type. myTypeDescriptors[type] = N; slayout = layout->getStructLayout(struct_type); for_fields(field, this_class) { // field is a Symbol const char* fieldDefFile = field->defPoint->fname(); int fieldDefLine = field->defPoint->linenum(); TypeSymbol* fts = field->type->symbol; llvm::Type* fty = fts->llvmType; LLVM_DITYPE mty; LLVM_DITYPE fditype = get_type(field->type); if(fditype == NULL) // if field->type is an internal type, get_type returns null // which is not a good type for a MemberType). At the moment it // uses a nullptr type as a stub, but we should change it fditype = this->dibuilder.createNullPtrType(); //use the dummy type for 'BaseArr' mty = this->dibuilder.createMemberType( get_module_scope(defModule), field->name, get_file(fieldDefFile), fieldDefLine, layout->getTypeSizeInBits(fty), 8*layout->getABITypeAlignment(fty), slayout->getElementOffsetInBits(this_class->getMemberGEP(field->cname)), 0, fditype); EltTys.push_back(mty); } // Now create the DItype for the struct N = this->dibuilder.createStructType( get_module_scope(defModule), name, get_file(defFile), defLine, layout->getTypeSizeInBits(ty), 8*layout->getABITypeAlignment(ty), 0, // RuntimeLang derivedFrom, this->dibuilder.getOrCreateArray(EltTys)); return toDITYPE(N); }//end of if(!Opaque) }// end of if(st) } // end of astTag == E_AggregateTy } // end of else (type==type->getType)