TString TStructure::buildMangledName() const { TString mangledName("struct-"); mangledName += *mName; for (size_t i = 0; i < mFields->size(); ++i) { mangledName += '-'; mangledName += (*mFields)[i]->type()->getMangledName(); } return mangledName; }
TString TFieldListCollection::buildMangledName() const { TString mangledName(mangledNamePrefix()); mangledName += *mName; for (size_t i = 0; i < mFields->size(); ++i) { mangledName += '-'; mangledName += (*mFields)[i]->type()->getMangledName(); } return mangledName; }
void CodeProfile::report() { dataLogF("<CodeProfiling %s:%d>\n", m_file.data(), m_lineNumber); // How many frames of C-code to print - 0, if not verbose, 1 if verbose, up to 1024 if very verbose. unsigned recursionLimit = CodeProfiling::beVeryVerbose() ? 1024 : CodeProfiling::beVerbose(); ProfileTreeNode profile; // Walk through the sample buffer. size_t trace = 0; while (trace < m_samples.size()) { // All traces are zero or more 'EngineFrame's, followed by a non-'EngineFrame'. // Scan to find the last sample in the trace. size_t lastInTrace = trace; while (m_samples[lastInTrace].type == EngineFrame) ++lastInTrace; // We use the last sample type to look up a name (used as a bucket in the profiler). ProfileTreeNode* callbacks = profile.sampleChild(s_codeTypeNames[m_samples[lastInTrace].type]); // If there are any samples in C-code, add up to recursionLimit of them into the profile tree. size_t lastEngineFrame = lastInTrace; for (unsigned count = 0; lastEngineFrame > trace && count < recursionLimit; ++count) { --lastEngineFrame; ASSERT(m_samples[lastEngineFrame].type == EngineFrame); const char* name = "<unknown>"; auto demangled = StackTrace::demangle(m_samples[lastEngineFrame].pc); if (demangled) name = demangled->demangledName() ? demangled->demangledName() : demangled->mangledName(); callbacks = callbacks->sampleChild(name); if (truncateTrace(name)) break; } // Move on to the next trace. trace = lastInTrace + 1; ASSERT(trace <= m_samples.size()); } // Output the profile tree. dataLogF("Total samples: %lld\n", static_cast<long long>(profile.childCount())); profile.dump(); for (size_t i = 0 ; i < m_children.size(); ++i) m_children[i]->report(); dataLogF("</CodeProfiling %s:%d>\n", m_file.data(), m_lineNumber); }
std::string getMangledName(FuncDeclaration *fdecl, LINK link) { std::string mangledName(mangleExact(fdecl)); // Hash the name if necessary if (((link == LINKd) || (link == LINKdefault)) && (global.params.hashThreshold != 0) && (mangledName.length() > global.params.hashThreshold)) { auto hashedName = hashSymbolName(mangledName, fdecl); mangledName = "_D" + hashedName + "Z"; } // TODO: Cache the result? return gABI->mangleFunctionForLLVM(std::move(mangledName), link); }
Node *Declaration::getMember(String name) { if (name.eq("mangleof")) return Tuple::makeStringLiteral(mangledName(), PrimType::c8, false, SourceLocation(0)); return Statement::getMember(name); }
void JSGlobalObjectInspectorController::appendAPIBacktrace(ScriptCallStack& callStack) { #if OS(DARWIN) || (OS(LINUX) && !PLATFORM(GTK)) static const int framesToShow = 31; static const int framesToSkip = 3; // WTFGetBacktrace, appendAPIBacktrace, reportAPIException. void* samples[framesToShow + framesToSkip]; int frames = framesToShow + framesToSkip; WTFGetBacktrace(samples, &frames); void** stack = samples + framesToSkip; int size = frames - framesToSkip; for (int i = 0; i < size; ++i) { auto demangled = StackTrace::demangle(stack[i]); if (demangled) callStack.append(ScriptCallFrame(demangled->demangledName() ? demangled->demangledName() : demangled->mangledName(), ASCIILiteral("[native code]"), noSourceID, 0, 0)); else callStack.append(ScriptCallFrame(ASCIILiteral("?"), ASCIILiteral("[native code]"), noSourceID, 0, 0)); } #else UNUSED_PARAM(callStack); #endif }
bool Type::operator==(const Type& that) const { // prob not the best way to check type equality...but what is??? return mangledName() == that.mangledName(); }
void DtoDeclareFunction(FuncDeclaration* fdecl) { DtoResolveFunction(fdecl); if (fdecl->ir.isDeclared()) return; fdecl->ir.setDeclared(); IF_LOG Logger::println("DtoDeclareFunction(%s): %s", fdecl->toPrettyChars(), fdecl->loc.toChars()); LOG_SCOPE; if (fdecl->isUnitTestDeclaration() && !global.params.useUnitTests) { Logger::println("unit tests not enabled"); return; } //printf("declare function: %s\n", fdecl->toPrettyChars()); // intrinsic sanity check if (fdecl->llvmInternal == LLVMintrinsic && fdecl->fbody) { error(fdecl->loc, "intrinsics cannot have function bodies"); fatal(); } // get TypeFunction* Type* t = fdecl->type->toBasetype(); TypeFunction* f = static_cast<TypeFunction*>(t); // create IrFunction IrFunction *irFunc = getIrFunc(fdecl, true); LLFunction* vafunc = 0; if (DtoIsVaIntrinsic(fdecl)) vafunc = DtoDeclareVaFunction(fdecl); // calling convention LINK link = f->linkage; if (vafunc || fdecl->llvmInternal == LLVMintrinsic // DMD treats _Dmain as having C calling convention and this has been // hardcoded into druntime, even if the frontend type has D linkage. // See Bugzilla issue 9028. || fdecl->isMain() ) { link = LINKc; } // mangled name std::string mangledName(mangleExact(fdecl)); mangledName = gABI->mangleForLLVM(mangledName, link); // construct function LLFunctionType* functype = DtoFunctionType(fdecl); LLFunction* func = vafunc ? vafunc : gIR->module->getFunction(mangledName); if (!func) { if(fdecl->llvmInternal == LLVMinline_ir) { func = DtoInlineIRFunction(fdecl); } else { // All function declarations are "external" - any other linkage type // is set when actually defining the function. func = LLFunction::Create(functype, llvm::GlobalValue::ExternalLinkage, mangledName, gIR->module); } } else if (func->getFunctionType() != functype) { error(fdecl->loc, "Function type does not match previously declared function with the same mangled name: %s", mangleExact(fdecl)); fatal(); } func->setCallingConv(gABI->callingConv(link)); IF_LOG Logger::cout() << "func = " << *func << std::endl; // add func to IRFunc irFunc->func = func; // parameter attributes if (!DtoIsIntrinsic(fdecl)) { set_param_attrs(f, func, fdecl); if (global.params.disableRedZone) { func->addFnAttr(LDC_ATTRIBUTE(NoRedZone)); } } // main if (fdecl->isMain()) { // Detect multiple main functions, which is disallowed. DMD checks this // in the glue code, so we need to do it here as well. if (gIR->mainFunc) { error(fdecl->loc, "only one main function allowed"); } gIR->mainFunc = func; } if (fdecl->neverInline) { irFunc->setNeverInline(); } if (fdecl->llvmInternal == LLVMglobal_crt_ctor || fdecl->llvmInternal == LLVMglobal_crt_dtor) { AppendFunctionToLLVMGlobalCtorsDtors(func, fdecl->priority, fdecl->llvmInternal == LLVMglobal_crt_ctor); } IrFuncTy &irFty = irFunc->irFty; // if (!declareOnly) { // name parameters llvm::Function::arg_iterator iarg = func->arg_begin(); if (irFty.arg_sret) { iarg->setName(".sret_arg"); irFunc->retArg = iarg; ++iarg; } if (irFty.arg_this) { iarg->setName(".this_arg"); irFunc->thisArg = iarg; VarDeclaration* v = fdecl->vthis; if (v) { // We already build the this argument here if we will need it // later for codegen'ing the function, just as normal // parameters below, because it can be referred to in nested // context types. Will be given storage in DtoDefineFunction. assert(!isIrParameterCreated(v)); IrParameter *irParam = getIrParameter(v, true); irParam->value = iarg; irParam->arg = irFty.arg_this; irParam->isVthis = true; } ++iarg; } else if (irFty.arg_nest) { iarg->setName(".nest_arg"); irFunc->nestArg = iarg; assert(irFunc->nestArg); ++iarg; } if (irFty.arg_arguments) { iarg->setName("._arguments"); irFunc->_arguments = iarg; ++iarg; } // we never reference parameters of function prototypes unsigned int k = 0; for (; iarg != func->arg_end(); ++iarg) { if (fdecl->parameters && fdecl->parameters->dim > k) { int paramIndex = irFty.reverseParams ? fdecl->parameters->dim-k-1 : k; Dsymbol* argsym = static_cast<Dsymbol*>(fdecl->parameters->data[paramIndex]); VarDeclaration* argvd = argsym->isVarDeclaration(); assert(argvd); assert(!isIrLocalCreated(argvd)); std::string str(argvd->ident->toChars()); str.append("_arg"); iarg->setName(str); IrParameter *irParam = getIrParameter(argvd, true); irParam->value = iarg; irParam->arg = irFty.args[paramIndex]; k++; } else { iarg->setName("unnamed"); } } } }