/// \brief Configure the diagnostics object for use with ASTUnit. void ASTUnit::ConfigureDiags(llvm::IntrusiveRefCntPtr<DiagnosticsEngine> &Diags, const char **ArgBegin, const char **ArgEnd, ASTUnit &AST, bool CaptureDiagnostics) { if (!Diags.getPtr()) { // No diagnostics engine was provided, so create our own diagnostics object // with the default options. DiagnosticOptions DiagOpts; DiagnosticConsumer *Client = 0; if (CaptureDiagnostics) Client = new StoredDiagnosticConsumer(AST.StoredDiagnostics); Diags = CompilerInstance::createDiagnostics(DiagOpts, ArgEnd- ArgBegin, ArgBegin, Client); } else if (CaptureDiagnostics) { Diags->setClient(new StoredDiagnosticConsumer(AST.StoredDiagnostics)); } }
bool Parse( Furrovine::String filename ) { class ASTDeclConsumer : public clang::ASTConsumer { public: ASTDeclConsumer( std::vector<clang::Decl*>& arg ) : vec( arg ) {} std::vector<clang::Decl*>& vec; bool HandleTopLevelDecl( clang::DeclGroupRef arg ) { for ( auto && x : arg ) { vec.push_back( x ); } return true; } }; ASTDeclConsumer astconsumer( declarations ); llvm::StringRef llvmfilename( reinterpret_cast<char*>( filename.data( ) ) ); clang::CompilerInstance ci; clang::DiagnosticsEngine diagnosticsengine( diagnosticids, llvmdiagnosticsoptions.getPtr(), new clang::TextDiagnosticPrinter( errorstream, llvmdiagnosticsoptions.getPtr(), false ), true ); clang::FileManager filemanager( filesystemoptions ); clang::SourceManager sourcemanager( diagnosticsengine, filemanager ); std::unique_ptr<clang::TargetInfo> targetinfo( clang::TargetInfo::CreateTargetInfo( diagnosticsengine, &targetoptions ) ); targetinfo->setCXXABI( clang::TargetCXXABI::Microsoft ); clang::HeaderSearchOptions& headersearchoptions = *llvmheadersearchoptions; clang::HeaderSearch hs( llvmheadersearchoptions, filemanager, diagnosticsengine, languageoptions, targetinfo.get( ) ); clang::PreprocessorOptions& preprocessoroptions = *llvmpreprocessoroptions; clang::Preprocessor preprocessor( llvmpreprocessoroptions, diagnosticsengine, languageoptions, targetinfo.get( ), sourcemanager, hs, ci ); clang::InitializePreprocessor( preprocessor, preprocessoroptions, headersearchoptions, frontendoptions ); preprocessor.getBuiltinInfo( ).InitializeBuiltins( preprocessor.getIdentifierTable( ), languageoptions ); clang::ASTContext astcontext( languageoptions, sourcemanager, targetinfo.get( ), preprocessor.getIdentifierTable( ), preprocessor.getSelectorTable( ), preprocessor.getBuiltinInfo( ), 1024 ); clang::Sema sema( preprocessor, astcontext, astconsumer, clang::TU_Complete, null ); const clang::DirectoryLookup* directlookup = nullptr; auto entry = hs.LookupFile( llvmfilename, true, nullptr, directlookup, nullptr, nullptr, nullptr, nullptr ); if ( !entry ) entry = filemanager.getFile( llvmfilename ); if ( !entry ) throw Furrovine::TException<std::exception>( "Could not find file " + filename ); auto fileid = sourcemanager.createFileID( entry, clang::SourceLocation( ), clang::SrcMgr::CharacteristicKind::C_User ); if ( fileid.isInvalid( ) ) throw Furrovine::TException<std::exception>( "Error translating file " + filename ); sourcemanager.setMainFileID( fileid ); diagnosticsengine.getClient( )->BeginSourceFile( languageoptions, &preprocessor ); clang::ParseAST( sema ); diagnosticsengine.getClient( )->EndSourceFile( ); return diagnosticsengine.getClient( )->getNumErrors() == 0; }
void clang::ProcessWarningOptions(DiagnosticsEngine &Diags, const DiagnosticOptions &Opts) { Diags.setSuppressSystemWarnings(true); // Default to -Wno-system-headers Diags.setIgnoreAllWarnings(Opts.IgnoreWarnings); Diags.setShowOverloads( static_cast<DiagnosticsEngine::OverloadsShown>(Opts.ShowOverloads)); // Handle -ferror-limit if (Opts.ErrorLimit) Diags.setErrorLimit(Opts.ErrorLimit); if (Opts.TemplateBacktraceLimit) Diags.setTemplateBacktraceLimit(Opts.TemplateBacktraceLimit); // If -pedantic or -pedantic-errors was specified, then we want to map all // extension diagnostics onto WARNING or ERROR unless the user has futz'd // around with them explicitly. if (Opts.PedanticErrors) Diags.setExtensionHandlingBehavior(DiagnosticsEngine::Ext_Error); else if (Opts.Pedantic) Diags.setExtensionHandlingBehavior(DiagnosticsEngine::Ext_Warn); else Diags.setExtensionHandlingBehavior(DiagnosticsEngine::Ext_Ignore); llvm::SmallVector<diag::kind, 10> _Diags; const llvm::IntrusiveRefCntPtr< DiagnosticIDs > DiagIDs = Diags.getDiagnosticIDs(); // We parse the warning options twice. The first pass sets diagnostic state, // while the second pass reports warnings/errors. This has the effect that // we follow the more canonical "last option wins" paradigm when there are // conflicting options. for (unsigned Report = 0, ReportEnd = 2; Report != ReportEnd; ++Report) { bool SetDiagnostic = (Report == 0); for (unsigned i = 0, e = Opts.Warnings.size(); i != e; ++i) { StringRef Opt = Opts.Warnings[i]; // Check to see if this warning starts with "no-", if so, this is a // negative form of the option. bool isPositive = true; if (Opt.startswith("no-")) { isPositive = false; Opt = Opt.substr(3); } // Figure out how this option affects the warning. If -Wfoo, map the // diagnostic to a warning, if -Wno-foo, map it to ignore. diag::Mapping Mapping = isPositive ? diag::MAP_WARNING : diag::MAP_IGNORE; // -Wsystem-headers is a special case, not driven by the option table. It // cannot be controlled with -Werror. if (Opt == "system-headers") { if (SetDiagnostic) Diags.setSuppressSystemWarnings(!isPositive); continue; } // -Weverything is a special case as well. It implicitly enables all // warnings, including ones not explicitly in a warning group. if (Opt == "everything") { if (SetDiagnostic) Diags.setEnableAllWarnings(true); continue; } // -Werror/-Wno-error is a special case, not controlled by the option // table. It also has the "specifier" form of -Werror=foo and -Werror-foo. if (Opt.startswith("error")) { StringRef Specifier; if (Opt.size() > 5) { // Specifier must be present. if ((Opt[5] != '=' && Opt[5] != '-') || Opt.size() == 6) { if (Report) Diags.Report(diag::warn_unknown_warning_specifier) << "-Werror" << ("-W" + Opt.str()); continue; } Specifier = Opt.substr(6); } if (Specifier.empty()) { if (SetDiagnostic) Diags.setWarningsAsErrors(isPositive); continue; } if (SetDiagnostic) { // Set the warning as error flag for this specifier. Diags.setDiagnosticGroupWarningAsError(Specifier, isPositive); } else if (DiagIDs->getDiagnosticsInGroup(Specifier, _Diags)) { EmitUnknownDiagWarning(Diags, "-Werror=", Specifier, isPositive); } continue; } // -Wfatal-errors is yet another special case. if (Opt.startswith("fatal-errors")) { StringRef Specifier; if (Opt.size() != 12) { if ((Opt[12] != '=' && Opt[12] != '-') || Opt.size() == 13) { if (Report) Diags.Report(diag::warn_unknown_warning_specifier) << "-Wfatal-errors" << ("-W" + Opt.str()); continue; } Specifier = Opt.substr(13); } if (Specifier.empty()) { if (SetDiagnostic) Diags.setErrorsAsFatal(isPositive); continue; } if (SetDiagnostic) { // Set the error as fatal flag for this specifier. Diags.setDiagnosticGroupErrorAsFatal(Specifier, isPositive); } else if (DiagIDs->getDiagnosticsInGroup(Specifier, _Diags)) { EmitUnknownDiagWarning(Diags, "-Wfatal-errors=", Specifier, isPositive); } continue; } if (Report) { if (DiagIDs->getDiagnosticsInGroup(Opt, _Diags)) EmitUnknownDiagWarning(Diags, "-W", Opt, isPositive); } else { Diags.setDiagnosticGroupMapping(Opt, Mapping); } } } }