ClangExpressionParser::ClangExpressionParser (ExecutionContextScope *exe_scope, ClangExpression &expr, bool generate_debug_info) : m_expr (expr), m_compiler (), m_code_generator (), m_pp_callbacks(nullptr) { // 1. Create a new compiler instance. m_compiler.reset(new CompilerInstance()); // 2. Install the target. lldb::TargetSP target_sp; if (exe_scope) target_sp = exe_scope->CalculateTarget(); // TODO: figure out what to really do when we don't have a valid target. // Sometimes this will be ok to just use the host target triple (when we // evaluate say "2+3", but other expressions like breakpoint conditions // and other things that _are_ target specific really shouldn't just be // using the host triple. This needs to be fixed in a better way. if (target_sp && target_sp->GetArchitecture().IsValid()) { std::string triple = target_sp->GetArchitecture().GetTriple().str(); m_compiler->getTargetOpts().Triple = triple; } else { m_compiler->getTargetOpts().Triple = llvm::sys::getDefaultTargetTriple(); } if (target_sp->GetArchitecture().GetMachine() == llvm::Triple::x86 || target_sp->GetArchitecture().GetMachine() == llvm::Triple::x86_64) { m_compiler->getTargetOpts().Features.push_back("+sse"); m_compiler->getTargetOpts().Features.push_back("+sse2"); } // Any arm32 iOS environment, but not on arm64 if (m_compiler->getTargetOpts().Triple.find("arm64") == std::string::npos && m_compiler->getTargetOpts().Triple.find("arm") != std::string::npos && m_compiler->getTargetOpts().Triple.find("ios") != std::string::npos) { m_compiler->getTargetOpts().ABI = "apcs-gnu"; } m_compiler->createDiagnostics(); // Create the target instance. m_compiler->setTarget(TargetInfo::CreateTargetInfo( m_compiler->getDiagnostics(), m_compiler->getInvocation().TargetOpts)); assert (m_compiler->hasTarget()); // 3. Set options. lldb::LanguageType language = expr.Language(); switch (language) { case lldb::eLanguageTypeC: break; case lldb::eLanguageTypeObjC: m_compiler->getLangOpts().ObjC1 = true; m_compiler->getLangOpts().ObjC2 = true; break; case lldb::eLanguageTypeC_plus_plus: m_compiler->getLangOpts().CPlusPlus = true; m_compiler->getLangOpts().CPlusPlus11 = true; m_compiler->getHeaderSearchOpts().UseLibcxx = true; break; case lldb::eLanguageTypeObjC_plus_plus: default: m_compiler->getLangOpts().ObjC1 = true; m_compiler->getLangOpts().ObjC2 = true; m_compiler->getLangOpts().CPlusPlus = true; m_compiler->getLangOpts().CPlusPlus11 = true; m_compiler->getHeaderSearchOpts().UseLibcxx = true; break; } m_compiler->getLangOpts().Bool = true; m_compiler->getLangOpts().WChar = true; m_compiler->getLangOpts().Blocks = true; m_compiler->getLangOpts().DebuggerSupport = true; // Features specifically for debugger clients if (expr.DesiredResultType() == ClangExpression::eResultTypeId) m_compiler->getLangOpts().DebuggerCastResultToId = true; // Spell checking is a nice feature, but it ends up completing a // lot of types that we didn't strictly speaking need to complete. // As a result, we spend a long time parsing and importing debug // information. m_compiler->getLangOpts().SpellChecking = false; lldb::ProcessSP process_sp; if (exe_scope) process_sp = exe_scope->CalculateProcess(); if (process_sp && m_compiler->getLangOpts().ObjC1) { if (process_sp->GetObjCLanguageRuntime()) { if (process_sp->GetObjCLanguageRuntime()->GetRuntimeVersion() == eAppleObjC_V2) m_compiler->getLangOpts().ObjCRuntime.set(ObjCRuntime::MacOSX, VersionTuple(10, 7)); else m_compiler->getLangOpts().ObjCRuntime.set(ObjCRuntime::FragileMacOSX, VersionTuple(10, 7)); if (process_sp->GetObjCLanguageRuntime()->HasNewLiteralsAndIndexing()) m_compiler->getLangOpts().DebuggerObjCLiteral = true; } } m_compiler->getLangOpts().ThreadsafeStatics = false; m_compiler->getLangOpts().AccessControl = false; // Debuggers get universal access m_compiler->getLangOpts().DollarIdents = true; // $ indicates a persistent variable name // Set CodeGen options m_compiler->getCodeGenOpts().EmitDeclMetadata = true; m_compiler->getCodeGenOpts().InstrumentFunctions = false; m_compiler->getCodeGenOpts().DisableFPElim = true; m_compiler->getCodeGenOpts().OmitLeafFramePointer = false; if (generate_debug_info) m_compiler->getCodeGenOpts().setDebugInfo(CodeGenOptions::FullDebugInfo); else m_compiler->getCodeGenOpts().setDebugInfo(CodeGenOptions::NoDebugInfo); // Disable some warnings. m_compiler->getDiagnostics().setSeverityForGroup(clang::diag::Flavor::WarningOrError, "unused-value", clang::diag::Severity::Ignored, SourceLocation()); m_compiler->getDiagnostics().setSeverityForGroup(clang::diag::Flavor::WarningOrError, "odr", clang::diag::Severity::Ignored, SourceLocation()); // Inform the target of the language options // // FIXME: We shouldn't need to do this, the target should be immutable once // created. This complexity should be lifted elsewhere. m_compiler->getTarget().adjust(m_compiler->getLangOpts()); // 4. Set up the diagnostic buffer for reporting errors m_compiler->getDiagnostics().setClient(new clang::TextDiagnosticBuffer); // 5. Set up the source management objects inside the compiler clang::FileSystemOptions file_system_options; m_file_manager.reset(new clang::FileManager(file_system_options)); if (!m_compiler->hasSourceManager()) m_compiler->createSourceManager(*m_file_manager.get()); m_compiler->createFileManager(); m_compiler->createPreprocessor(TU_Complete); if (ClangModulesDeclVendor *decl_vendor = target_sp->GetClangModulesDeclVendor()) { std::unique_ptr<PPCallbacks> pp_callbacks(new LLDBPreprocessorCallbacks(*decl_vendor)); m_pp_callbacks = static_cast<LLDBPreprocessorCallbacks*>(pp_callbacks.get()); m_compiler->getPreprocessor().addPPCallbacks(std::move(pp_callbacks)); } // 6. Most of this we get from the CompilerInstance, but we // also want to give the context an ExternalASTSource. m_selector_table.reset(new SelectorTable()); m_builtin_context.reset(new Builtin::Context()); std::unique_ptr<clang::ASTContext> ast_context(new ASTContext(m_compiler->getLangOpts(), m_compiler->getSourceManager(), m_compiler->getPreprocessor().getIdentifierTable(), *m_selector_table.get(), *m_builtin_context.get())); ast_context->InitBuiltinTypes(m_compiler->getTarget()); ClangExpressionDeclMap *decl_map = m_expr.DeclMap(); if (decl_map) { llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> ast_source(decl_map->CreateProxy()); decl_map->InstallASTContext(ast_context.get()); ast_context->setExternalSource(ast_source); } m_compiler->setASTContext(ast_context.release()); std::string module_name("$__lldb_module"); m_llvm_context.reset(new LLVMContext()); m_code_generator.reset(CreateLLVMCodeGen(m_compiler->getDiagnostics(), module_name, m_compiler->getCodeGenOpts(), m_compiler->getTargetOpts(), *m_llvm_context)); }
ClangExpressionParser::ClangExpressionParser (ExecutionContextScope *exe_scope, ClangExpression &expr) : m_expr (expr), m_compiler (), m_code_generator () { // Initialize targets first, so that --version shows registered targets. static struct InitializeLLVM { InitializeLLVM() { llvm::InitializeAllTargets(); llvm::InitializeAllAsmPrinters(); llvm::InitializeAllTargetMCs(); llvm::InitializeAllDisassemblers(); llvm::DisablePrettyStackTrace = true; } } InitializeLLVM; // 1. Create a new compiler instance. m_compiler.reset(new CompilerInstance()); // 2. Install the target. lldb::TargetSP target_sp; if (exe_scope) target_sp = exe_scope->CalculateTarget(); // TODO: figure out what to really do when we don't have a valid target. // Sometimes this will be ok to just use the host target triple (when we // evaluate say "2+3", but other expressions like breakpoint conditions // and other things that _are_ target specific really shouldn't just be // using the host triple. This needs to be fixed in a better way. if (target_sp && target_sp->GetArchitecture().IsValid()) { std::string triple = target_sp->GetArchitecture().GetTriple().str(); int dash_count = 0; for (size_t i = 0; i < triple.size(); ++i) { if (triple[i] == '-') dash_count++; if (dash_count == 3) { triple.resize(i); break; } } m_compiler->getTargetOpts().Triple = triple; } else { m_compiler->getTargetOpts().Triple = llvm::sys::getDefaultTargetTriple(); } if (target_sp->GetArchitecture().GetMachine() == llvm::Triple::x86 || target_sp->GetArchitecture().GetMachine() == llvm::Triple::x86_64) { m_compiler->getTargetOpts().Features.push_back("+sse"); m_compiler->getTargetOpts().Features.push_back("+sse2"); } if (m_compiler->getTargetOpts().Triple.find("ios") != std::string::npos) m_compiler->getTargetOpts().ABI = "apcs-gnu"; m_compiler->createDiagnostics(); // Create the target instance. m_compiler->setTarget(TargetInfo::CreateTargetInfo(m_compiler->getDiagnostics(), &m_compiler->getTargetOpts())); assert (m_compiler->hasTarget()); // 3. Set options. lldb::LanguageType language = expr.Language(); switch (language) { case lldb::eLanguageTypeC: break; case lldb::eLanguageTypeObjC: m_compiler->getLangOpts().ObjC1 = true; m_compiler->getLangOpts().ObjC2 = true; break; case lldb::eLanguageTypeC_plus_plus: m_compiler->getLangOpts().CPlusPlus = true; m_compiler->getLangOpts().CPlusPlus11 = true; break; case lldb::eLanguageTypeObjC_plus_plus: default: m_compiler->getLangOpts().ObjC1 = true; m_compiler->getLangOpts().ObjC2 = true; m_compiler->getLangOpts().CPlusPlus = true; m_compiler->getLangOpts().CPlusPlus11 = true; break; } m_compiler->getLangOpts().Bool = true; m_compiler->getLangOpts().WChar = true; m_compiler->getLangOpts().Blocks = true; m_compiler->getLangOpts().DebuggerSupport = true; // Features specifically for debugger clients if (expr.DesiredResultType() == ClangExpression::eResultTypeId) m_compiler->getLangOpts().DebuggerCastResultToId = true; // Spell checking is a nice feature, but it ends up completing a // lot of types that we didn't strictly speaking need to complete. // As a result, we spend a long time parsing and importing debug // information. m_compiler->getLangOpts().SpellChecking = false; lldb::ProcessSP process_sp; if (exe_scope) process_sp = exe_scope->CalculateProcess(); if (process_sp && m_compiler->getLangOpts().ObjC1) { if (process_sp->GetObjCLanguageRuntime()) { if (process_sp->GetObjCLanguageRuntime()->GetRuntimeVersion() == eAppleObjC_V2) m_compiler->getLangOpts().ObjCRuntime.set(ObjCRuntime::MacOSX, VersionTuple(10, 7)); else m_compiler->getLangOpts().ObjCRuntime.set(ObjCRuntime::FragileMacOSX, VersionTuple(10, 7)); if (process_sp->GetObjCLanguageRuntime()->HasNewLiteralsAndIndexing()) m_compiler->getLangOpts().DebuggerObjCLiteral = true; } } m_compiler->getLangOpts().ThreadsafeStatics = false; m_compiler->getLangOpts().AccessControl = false; // Debuggers get universal access m_compiler->getLangOpts().DollarIdents = true; // $ indicates a persistent variable name // Set CodeGen options m_compiler->getCodeGenOpts().EmitDeclMetadata = true; m_compiler->getCodeGenOpts().InstrumentFunctions = false; // Disable some warnings. m_compiler->getDiagnostics().setDiagnosticGroupMapping("unused-value", clang::diag::MAP_IGNORE, SourceLocation()); m_compiler->getDiagnostics().setDiagnosticGroupMapping("odr", clang::diag::MAP_IGNORE, SourceLocation()); // Inform the target of the language options // // FIXME: We shouldn't need to do this, the target should be immutable once // created. This complexity should be lifted elsewhere. m_compiler->getTarget().setForcedLangOptions(m_compiler->getLangOpts()); // 4. Set up the diagnostic buffer for reporting errors m_compiler->getDiagnostics().setClient(new clang::TextDiagnosticBuffer); // 5. Set up the source management objects inside the compiler clang::FileSystemOptions file_system_options; m_file_manager.reset(new clang::FileManager(file_system_options)); if (!m_compiler->hasSourceManager()) m_compiler->createSourceManager(*m_file_manager.get()); m_compiler->createFileManager(); m_compiler->createPreprocessor(); // 6. Most of this we get from the CompilerInstance, but we // also want to give the context an ExternalASTSource. m_selector_table.reset(new SelectorTable()); m_builtin_context.reset(new Builtin::Context()); std::unique_ptr<clang::ASTContext> ast_context(new ASTContext(m_compiler->getLangOpts(), m_compiler->getSourceManager(), &m_compiler->getTarget(), m_compiler->getPreprocessor().getIdentifierTable(), *m_selector_table.get(), *m_builtin_context.get(), 0)); ClangExpressionDeclMap *decl_map = m_expr.DeclMap(); if (decl_map) { llvm::OwningPtr<clang::ExternalASTSource> ast_source(decl_map->CreateProxy()); decl_map->InstallASTContext(ast_context.get()); ast_context->setExternalSource(ast_source); } m_compiler->setASTContext(ast_context.release()); std::string module_name("$__lldb_module"); m_llvm_context.reset(new LLVMContext()); m_code_generator.reset(CreateLLVMCodeGen(m_compiler->getDiagnostics(), module_name, m_compiler->getCodeGenOpts(), m_compiler->getTargetOpts(), *m_llvm_context)); }