예제 #1
0
파일: ASTUnit.cpp 프로젝트: YabinHu/mlang
/// \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));
  }
}
예제 #2
0
파일: main.cpp 프로젝트: CCJY/coliru
    	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;
    	}
예제 #3
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);
      }
    }
  }
}