Пример #1
0
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;
}
Пример #2
0
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;
}
Пример #3
0
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);
}
Пример #4
0
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);
}
Пример #5
0
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
}
Пример #7
0
bool Type::operator==(const Type& that) const {
  // prob not the best way to check type equality...but what is???
  return mangledName() == that.mangledName();
}
Пример #8
0
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");
            }
        }
    }
}