diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Frontend')
11 files changed, 349 insertions, 377 deletions
diff --git a/contrib/llvm/tools/clang/lib/Frontend/ASTConsumers.cpp b/contrib/llvm/tools/clang/lib/Frontend/ASTConsumers.cpp index ecd6ef4..28d312a 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/ASTConsumers.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/ASTConsumers.cpp @@ -173,7 +173,7 @@ void DeclContextPrinter::PrintDeclContext(const DeclContext* DC, break; case Decl::Function: { const FunctionDecl* FD = cast<FunctionDecl>(DC); - if (FD->isThisDeclarationADefinition()) + if (FD->doesThisDeclarationHaveABody()) Out << "[function] "; else Out << "<function> "; diff --git a/contrib/llvm/tools/clang/lib/Frontend/ASTUnit.cpp b/contrib/llvm/tools/clang/lib/Frontend/ASTUnit.cpp index 2a12448..8827116 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/ASTUnit.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/ASTUnit.cpp @@ -102,6 +102,7 @@ ASTUnit::ASTUnit(bool _MainFileIsAST) ConcurrencyCheckValue(CheckUnlocked), PreambleRebuildCounter(0), SavedMainFileBuffer(0), PreambleBuffer(0), ShouldCacheCodeCompletionResults(false), + NestedMacroInstantiations(true), CompletionCacheTopLevelHashValue(0), PreambleTopLevelHashValue(0), CurrentTopLevelHashValue(0), @@ -579,6 +580,11 @@ ASTUnit *ASTUnit::LoadFromASTFile(const std::string &Filename, Reader.reset(new ASTReader(AST->getSourceManager(), AST->getFileManager(), AST->getDiagnostics())); + + // Recover resources if we crash before exiting this method. + llvm::CrashRecoveryContextCleanupRegistrar<ASTReader> + ReaderCleanup(Reader.get()); + Reader->setListener(new ASTInfoCollector(LangInfo, HeaderInfo, TargetTriple, Predefines, Counter)); @@ -633,6 +639,11 @@ ASTUnit *ASTUnit::LoadFromASTFile(const std::string &Filename, // AST file as needed. ASTReader *ReaderPtr = Reader.get(); llvm::OwningPtr<ExternalASTSource> Source(Reader.take()); + + // Unregister the cleanup for ASTReader. It will get cleaned up + // by the ASTUnit cleanup. + ReaderCleanup.unregister(); + Context.setExternalSource(Source); // Create an AST consumer, even though it isn't used. @@ -917,6 +928,8 @@ bool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) { // If the main file has been overridden due to the use of a preamble, // make that override happen and introduce the preamble. PreprocessorOptions &PreprocessorOpts = Clang->getPreprocessorOpts(); + PreprocessorOpts.DetailedRecordIncludesNestedMacroInstantiations + = NestedMacroInstantiations; std::string PriorImplicitPCHInclude; if (OverrideMainBuffer) { PreprocessorOpts.addRemappedFile(OriginalSourceFile, OverrideMainBuffer); @@ -1554,6 +1567,119 @@ ASTUnit *ASTUnit::create(CompilerInvocation *CI, return AST.take(); } +ASTUnit *ASTUnit::LoadFromCompilerInvocationAction(CompilerInvocation *CI, + llvm::IntrusiveRefCntPtr<Diagnostic> Diags, + ASTFrontendAction *Action) { + assert(CI && "A CompilerInvocation is required"); + + // Create the AST unit. + llvm::OwningPtr<ASTUnit> AST; + AST.reset(new ASTUnit(false)); + ConfigureDiags(Diags, 0, 0, *AST, /*CaptureDiagnostics*/false); + AST->Diagnostics = Diags; + AST->OnlyLocalDecls = false; + AST->CaptureDiagnostics = false; + AST->CompleteTranslationUnit = Action ? Action->usesCompleteTranslationUnit() + : true; + AST->ShouldCacheCodeCompletionResults = false; + AST->Invocation = CI; + + // Recover resources if we crash before exiting this method. + llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit> + ASTUnitCleanup(AST.get()); + llvm::CrashRecoveryContextCleanupRegistrar<Diagnostic, + llvm::CrashRecoveryContextReleaseRefCleanup<Diagnostic> > + DiagCleanup(Diags.getPtr()); + + // We'll manage file buffers ourselves. + CI->getPreprocessorOpts().RetainRemappedFileBuffers = true; + CI->getFrontendOpts().DisableFree = false; + ProcessWarningOptions(AST->getDiagnostics(), CI->getDiagnosticOpts()); + + // Save the target features. + AST->TargetFeatures = CI->getTargetOpts().Features; + + // Create the compiler instance to use for building the AST. + llvm::OwningPtr<CompilerInstance> Clang(new CompilerInstance()); + + // Recover resources if we crash before exiting this method. + llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance> + CICleanup(Clang.get()); + + Clang->setInvocation(CI); + AST->OriginalSourceFile = Clang->getFrontendOpts().Inputs[0].second; + + // Set up diagnostics, capturing any diagnostics that would + // otherwise be dropped. + Clang->setDiagnostics(&AST->getDiagnostics()); + + // Create the target instance. + Clang->getTargetOpts().Features = AST->TargetFeatures; + Clang->setTarget(TargetInfo::CreateTargetInfo(Clang->getDiagnostics(), + Clang->getTargetOpts())); + if (!Clang->hasTarget()) + return 0; + + // 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. + Clang->getTarget().setForcedLangOptions(Clang->getLangOpts()); + + assert(Clang->getFrontendOpts().Inputs.size() == 1 && + "Invocation must have exactly one source file!"); + assert(Clang->getFrontendOpts().Inputs[0].first != IK_AST && + "FIXME: AST inputs not yet supported here!"); + assert(Clang->getFrontendOpts().Inputs[0].first != IK_LLVM_IR && + "IR inputs not supported here!"); + + // Configure the various subsystems. + AST->FileSystemOpts = Clang->getFileSystemOpts(); + AST->FileMgr = new FileManager(AST->FileSystemOpts); + AST->SourceMgr = new SourceManager(AST->getDiagnostics(), *AST->FileMgr); + AST->TheSema.reset(); + AST->Ctx = 0; + AST->PP = 0; + + // Create a file manager object to provide access to and cache the filesystem. + Clang->setFileManager(&AST->getFileManager()); + + // Create the source manager. + Clang->setSourceManager(&AST->getSourceManager()); + + ASTFrontendAction *Act = Action; + + llvm::OwningPtr<TopLevelDeclTrackerAction> TrackerAct; + if (!Act) { + TrackerAct.reset(new TopLevelDeclTrackerAction(*AST)); + Act = TrackerAct.get(); + } + + // Recover resources if we crash before exiting this method. + llvm::CrashRecoveryContextCleanupRegistrar<TopLevelDeclTrackerAction> + ActCleanup(TrackerAct.get()); + + if (!Act->BeginSourceFile(*Clang.get(), + Clang->getFrontendOpts().Inputs[0].second, + Clang->getFrontendOpts().Inputs[0].first)) + return 0; + + Act->Execute(); + + // Steal the created target, context, and preprocessor. + AST->TheSema.reset(Clang->takeSema()); + AST->Consumer.reset(Clang->takeASTConsumer()); + AST->Ctx = &Clang->getASTContext(); + AST->PP = &Clang->getPreprocessor(); + Clang->setSourceManager(0); + Clang->setFileManager(0); + AST->Target = &Clang->getTarget(); + + Act->EndSourceFile(); + + return AST.take(); +} + bool ASTUnit::LoadFromCompilerInvocation(bool PrecompilePreamble) { if (!Invocation) return true; @@ -1589,7 +1715,8 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocation(CompilerInvocation *CI, bool CaptureDiagnostics, bool PrecompilePreamble, bool CompleteTranslationUnit, - bool CacheCodeCompletionResults) { + bool CacheCodeCompletionResults, + bool NestedMacroInstantiations) { // Create the AST unit. llvm::OwningPtr<ASTUnit> AST; AST.reset(new ASTUnit(false)); @@ -1600,6 +1727,7 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocation(CompilerInvocation *CI, AST->CompleteTranslationUnit = CompleteTranslationUnit; AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults; AST->Invocation = CI; + AST->NestedMacroInstantiations = NestedMacroInstantiations; // Recover resources if we crash before exiting this method. llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit> @@ -1624,7 +1752,8 @@ ASTUnit *ASTUnit::LoadFromCommandLine(const char **ArgBegin, bool CompleteTranslationUnit, bool CacheCodeCompletionResults, bool CXXPrecompilePreamble, - bool CXXChainedPCH) { + bool CXXChainedPCH, + bool NestedMacroInstantiations) { if (!Diags.getPtr()) { // No diagnostics engine was provided, so create our own diagnostics object // with the default options. @@ -1691,6 +1820,7 @@ ASTUnit *ASTUnit::LoadFromCommandLine(const char **ArgBegin, AST->NumStoredDiagnosticsInPreamble = StoredDiagnostics.size(); AST->StoredDiagnostics.swap(StoredDiagnostics); AST->Invocation = CI; + AST->NestedMacroInstantiations = NestedMacroInstantiations; // Recover resources if we crash before exiting this method. llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit> @@ -2142,6 +2272,9 @@ void ASTUnit::CodeComplete(llvm::StringRef File, unsigned Line, unsigned Column, PreprocessorOpts.PrecompiledPreambleBytes.second = false; } + // Disable the preprocessing record + PreprocessorOpts.DetailedRecord = false; + llvm::OwningPtr<SyntaxOnlyAction> Act; Act.reset(new SyntaxOnlyAction); if (Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0].second, diff --git a/contrib/llvm/tools/clang/lib/Frontend/CompilerInstance.cpp b/contrib/llvm/tools/clang/lib/Frontend/CompilerInstance.cpp index ace3c5a..38fcfe3 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/CompilerInstance.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/CompilerInstance.cpp @@ -227,7 +227,8 @@ CompilerInstance::createPreprocessor(Diagnostic &Diags, } if (PPOpts.DetailedRecord) - PP->createPreprocessingRecord(); + PP->createPreprocessingRecord( + PPOpts.DetailedRecordIncludesNestedMacroInstantiations); InitializePreprocessor(*PP, PPOpts, HSOpts, FEOpts); diff --git a/contrib/llvm/tools/clang/lib/Frontend/CompilerInvocation.cpp b/contrib/llvm/tools/clang/lib/Frontend/CompilerInvocation.cpp index 495c6a8..a4a656f 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/CompilerInvocation.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/CompilerInvocation.cpp @@ -277,6 +277,14 @@ static void DiagnosticOptsToArgs(const DiagnosticOptions &Opts, Res.push_back("-fdiagnostics-show-category=id"); else if (Opts.ShowCategories == 2) Res.push_back("-fdiagnostics-show-category=name"); + switch (Opts.Format) { + case DiagnosticOptions::Clang: + Res.push_back("-fdiagnostics-format=clang"); break; + case DiagnosticOptions::Msvc: + Res.push_back("-fdiagnostics-format=msvc"); break; + case DiagnosticOptions::Vi: + Res.push_back("-fdiagnostics-format=vi"); break; + } if (Opts.ErrorLimit) { Res.push_back("-ferror-limit"); Res.push_back(llvm::utostr(Opts.ErrorLimit)); @@ -664,6 +672,9 @@ static void LangOptsToArgs(const LangOptions &Opts, Res.push_back("-fobjc-gc-only"); } } + if (Opts.ObjCInferRelatedResultType) + Res.push_back("-fobjc-infer-related-result-type"); + if (Opts.AppleKext) Res.push_back("-fapple-kext"); @@ -976,6 +987,7 @@ static void ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.InstrumentForProfiling = Args.hasArg(OPT_pg); Opts.EmitGcovArcs = Args.hasArg(OPT_femit_coverage_data); Opts.EmitGcovNotes = Args.hasArg(OPT_femit_coverage_notes); + Opts.CoverageFile = Args.getLastArgValue(OPT_coverage_file); if (Arg *A = Args.getLastArg(OPT_fobjc_dispatch_method_EQ)) { llvm::StringRef Name = A->getValue(Args); @@ -1012,7 +1024,9 @@ static void ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args, Opts.PedanticErrors = Args.hasArg(OPT_pedantic_errors); Opts.ShowCarets = !Args.hasArg(OPT_fno_caret_diagnostics); Opts.ShowColors = Args.hasArg(OPT_fcolor_diagnostics); - Opts.ShowColumn = !Args.hasArg(OPT_fno_show_column); + Opts.ShowColumn = Args.hasFlag(OPT_fshow_column, + OPT_fno_show_column, + /*Default=*/true); Opts.ShowFixits = !Args.hasArg(OPT_fno_diagnostics_fixit_info); Opts.ShowLocation = !Args.hasArg(OPT_fno_show_source_location); Opts.ShowNames = Args.hasArg(OPT_fdiagnostics_show_name); @@ -1049,6 +1063,19 @@ static void ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args, << Args.getLastArg(OPT_fdiagnostics_show_category)->getAsString(Args) << ShowCategory; + llvm::StringRef Format = + Args.getLastArgValue(OPT_fdiagnostics_format, "clang"); + if (Format == "clang") + Opts.Format = DiagnosticOptions::Clang; + else if (Format == "msvc") + Opts.Format = DiagnosticOptions::Msvc; + else if (Format == "vi") + Opts.Format = DiagnosticOptions::Vi; + else + Diags.Report(diag::err_drv_invalid_value) + << Args.getLastArg(OPT_fdiagnostics_format)->getAsString(Args) + << Format; + Opts.ShowSourceRanges = Args.hasArg(OPT_fdiagnostics_print_source_range_info); Opts.ShowParseableFixits = Args.hasArg(OPT_fdiagnostics_parseable_fixits); Opts.VerifyDiagnostics = Args.hasArg(OPT_verify); @@ -1399,6 +1426,40 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, if (LangStd == LangStandard::lang_unspecified) Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << A->getValue(Args); + else { + // Valid standard, check to make sure language and standard are compatable. + const LangStandard &Std = LangStandard::getLangStandardForKind(LangStd); + switch (IK) { + case IK_C: + case IK_ObjC: + case IK_PreprocessedC: + case IK_PreprocessedObjC: + if (!(Std.isC89() || Std.isC99())) + Diags.Report(diag::err_drv_argument_not_allowed_with) + << A->getAsString(Args) << "C/ObjC"; + break; + case IK_CXX: + case IK_ObjCXX: + case IK_PreprocessedCXX: + case IK_PreprocessedObjCXX: + if (!Std.isCPlusPlus()) + Diags.Report(diag::err_drv_argument_not_allowed_with) + << A->getAsString(Args) << "C++/ObjC++"; + break; + case IK_OpenCL: + if (!Std.isC99()) + Diags.Report(diag::err_drv_argument_not_allowed_with) + << A->getAsString(Args) << "OpenCL"; + break; + case IK_CUDA: + if (!Std.isCPlusPlus()) + Diags.Report(diag::err_drv_argument_not_allowed_with) + << A->getAsString(Args) << "CUDA"; + break; + default: + break; + } + } } if (const Arg *A = Args.getLastArg(OPT_cl_std_EQ)) { @@ -1421,11 +1482,17 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, if (Args.hasArg(OPT_fno_operator_names)) Opts.CXXOperatorNames = 0; + if (Args.hasArg(OPT_fgnu89_inline)) + Opts.GNUInline = 1; + if (Args.hasArg(OPT_fobjc_gc_only)) Opts.setGCMode(LangOptions::GCOnly); else if (Args.hasArg(OPT_fobjc_gc)) Opts.setGCMode(LangOptions::HybridGC); + if (Args.hasArg(OPT_fobjc_infer_related_result_type)) + Opts.ObjCInferRelatedResultType = 1; + if (Args.hasArg(OPT_fapple_kext)) { if (!Opts.CPlusPlus) Diags.Report(diag::warn_c_kext); diff --git a/contrib/llvm/tools/clang/lib/Frontend/CreateInvocationFromCommandLine.cpp b/contrib/llvm/tools/clang/lib/Frontend/CreateInvocationFromCommandLine.cpp index 0005f91..42b648a 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/CreateInvocationFromCommandLine.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/CreateInvocationFromCommandLine.cpp @@ -65,7 +65,7 @@ clang::createInvocationFromCommandLine(llvm::ArrayRef<const char *> ArgList, // We expect to get back exactly one command job, if we didn't something // failed. const driver::JobList &Jobs = C->getJobs(); - if (Jobs.size() != 1 || !isa<driver::Command>(Jobs.begin())) { + if (Jobs.size() != 1 || !isa<driver::Command>(*Jobs.begin())) { llvm::SmallString<256> Msg; llvm::raw_svector_ostream OS(Msg); C->PrintJob(OS, C->getJobs(), "; ", true); diff --git a/contrib/llvm/tools/clang/lib/Frontend/DiagChecker.cpp b/contrib/llvm/tools/clang/lib/Frontend/DiagChecker.cpp deleted file mode 100644 index 66d7ed7..0000000 --- a/contrib/llvm/tools/clang/lib/Frontend/DiagChecker.cpp +++ /dev/null @@ -1,301 +0,0 @@ -//===--- DiagChecker.cpp - Diagnostic Checking Functions ------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Process the input files and check that the diagnostic messages are expected. -// -//===----------------------------------------------------------------------===// - -#include "clang/Frontend/Utils.h" -#include "clang/Frontend/TextDiagnosticBuffer.h" -#include "clang/Parse/ParseAST.h" -#include "clang/AST/ASTConsumer.h" -#include "clang/Basic/SourceManager.h" -#include "clang/Lex/Preprocessor.h" -#include "llvm/Support/raw_ostream.h" -using namespace clang; - -typedef TextDiagnosticBuffer::DiagList DiagList; -typedef TextDiagnosticBuffer::const_iterator const_diag_iterator; - -static void EmitError(Preprocessor &PP, SourceLocation Pos, const char *String){ - unsigned ID = PP.getDiagnostics().getCustomDiagID(Diagnostic::Error, String); - PP.Diag(Pos, ID); -} - - -// USING THE DIAGNOSTIC CHECKER: -// -// Indicating that a line expects an error or a warning is simple. Put a comment -// on the line that has the diagnostic, use "expected-{error,warning}" to tag -// if it's an expected error or warning, and place the expected text between {{ -// and }} markers. The full text doesn't have to be included, only enough to -// ensure that the correct diagnostic was emitted. -// -// Here's an example: -// -// int A = B; // expected-error {{use of undeclared identifier 'B'}} -// -// You can place as many diagnostics on one line as you wish. To make the code -// more readable, you can use slash-newline to separate out the diagnostics. -// -// The simple syntax above allows each specification to match exactly one error. -// You can use the extended syntax to customize this. The extended syntax is -// "expected-<type> <n> {{diag text}}", where <type> is one of "error", -// "warning" or "note", and <n> is a positive integer. This allows the -// diagnostic to appear as many times as specified. Example: -// -// void f(); // expected-note 2 {{previous declaration is here}} -// - -/// FindDiagnostics - Go through the comment and see if it indicates expected -/// diagnostics. If so, then put them in a diagnostic list. -/// -static void FindDiagnostics(const char *CommentStart, unsigned CommentLen, - DiagList &ExpectedDiags, - Preprocessor &PP, SourceLocation Pos, - const char *ExpectedStr) { - const char *CommentEnd = CommentStart+CommentLen; - unsigned ExpectedStrLen = strlen(ExpectedStr); - - // Find all expected-foo diagnostics in the string and add them to - // ExpectedDiags. - while (CommentStart != CommentEnd) { - CommentStart = std::find(CommentStart, CommentEnd, 'e'); - if (unsigned(CommentEnd-CommentStart) < ExpectedStrLen) return; - - // If this isn't expected-foo, ignore it. - if (memcmp(CommentStart, ExpectedStr, ExpectedStrLen)) { - ++CommentStart; - continue; - } - - CommentStart += ExpectedStrLen; - - // Skip whitespace. - while (CommentStart != CommentEnd && - isspace(CommentStart[0])) - ++CommentStart; - - // Default, if we find the '{' now, is 1 time. - int Times = 1; - int Temp = 0; - // In extended syntax, there could be a digit now. - while (CommentStart != CommentEnd && - CommentStart[0] >= '0' && CommentStart[0] <= '9') { - Temp *= 10; - Temp += CommentStart[0] - '0'; - ++CommentStart; - } - if (Temp > 0) - Times = Temp; - - // Skip whitespace again. - while (CommentStart != CommentEnd && - isspace(CommentStart[0])) - ++CommentStart; - - // We should have a {{ now. - if (CommentEnd-CommentStart < 2 || - CommentStart[0] != '{' || CommentStart[1] != '{') { - if (std::find(CommentStart, CommentEnd, '{') != CommentEnd) - EmitError(PP, Pos, "bogus characters before '{{' in expected string"); - else - EmitError(PP, Pos, "cannot find start ('{{') of expected string"); - return; - } - CommentStart += 2; - - // Find the }}. - const char *ExpectedEnd = CommentStart; - while (1) { - ExpectedEnd = std::find(ExpectedEnd, CommentEnd, '}'); - if (CommentEnd-ExpectedEnd < 2) { - EmitError(PP, Pos, "cannot find end ('}}') of expected string"); - return; - } - - if (ExpectedEnd[1] == '}') - break; - - ++ExpectedEnd; // Skip over singular }'s - } - - std::string Msg(CommentStart, ExpectedEnd); - std::string::size_type FindPos; - while ((FindPos = Msg.find("\\n")) != std::string::npos) - Msg.replace(FindPos, 2, "\n"); - // Add is possibly multiple times. - for (int i = 0; i < Times; ++i) - ExpectedDiags.push_back(std::make_pair(Pos, Msg)); - - CommentStart = ExpectedEnd; - } -} - -/// FindExpectedDiags - Lex the main source file to find all of the -// expected errors and warnings. -static void FindExpectedDiags(Preprocessor &PP, - DiagList &ExpectedErrors, - DiagList &ExpectedWarnings, - DiagList &ExpectedNotes) { - // Create a raw lexer to pull all the comments out of the main file. We don't - // want to look in #include'd headers for expected-error strings. - FileID FID = PP.getSourceManager().getMainFileID(); - - // Create a lexer to lex all the tokens of the main file in raw mode. - const llvm::MemoryBuffer *FromFile = PP.getSourceManager().getBuffer(FID); - Lexer RawLex(FID, FromFile, PP.getSourceManager(), PP.getLangOptions()); - - // Return comments as tokens, this is how we find expected diagnostics. - RawLex.SetCommentRetentionState(true); - - Token Tok; - Tok.setKind(tok::comment); - while (Tok.isNot(tok::eof)) { - RawLex.Lex(Tok); - if (!Tok.is(tok::comment)) continue; - - std::string Comment = PP.getSpelling(Tok); - if (Comment.empty()) continue; - - - // Find all expected errors. - FindDiagnostics(&Comment[0], Comment.size(), ExpectedErrors, PP, - Tok.getLocation(), "expected-error"); - - // Find all expected warnings. - FindDiagnostics(&Comment[0], Comment.size(), ExpectedWarnings, PP, - Tok.getLocation(), "expected-warning"); - - // Find all expected notes. - FindDiagnostics(&Comment[0], Comment.size(), ExpectedNotes, PP, - Tok.getLocation(), "expected-note"); - }; -} - -/// PrintProblem - This takes a diagnostic map of the delta between expected and -/// seen diagnostics. If there's anything in it, then something unexpected -/// happened. Print the map out in a nice format and return "true". If the map -/// is empty and we're not going to print things, then return "false". -/// -static bool PrintProblem(SourceManager &SourceMgr, - const_diag_iterator diag_begin, - const_diag_iterator diag_end, - const char *Msg) { - if (diag_begin == diag_end) return false; - - llvm::errs() << Msg << "\n"; - for (const_diag_iterator I = diag_begin, E = diag_end; I != E; ++I) - llvm::errs() << " Line " << SourceMgr.getInstantiationLineNumber(I->first) - << " " << I->second << "\n"; - - return true; -} - -/// CompareDiagLists - Compare two diagnostic lists and return the difference -/// between them. -/// -static bool CompareDiagLists(SourceManager &SourceMgr, - const_diag_iterator d1_begin, - const_diag_iterator d1_end, - const_diag_iterator d2_begin, - const_diag_iterator d2_end, - const char *MsgLeftOnly, - const char *MsgRightOnly) { - DiagList LeftOnly; - DiagList Left(d1_begin, d1_end); - DiagList Right(d2_begin, d2_end); - - for (const_diag_iterator I = Left.begin(), E = Left.end(); I != E; ++I) { - unsigned LineNo1 = SourceMgr.getInstantiationLineNumber(I->first); - const std::string &Diag1 = I->second; - - DiagList::iterator II, IE; - for (II = Right.begin(), IE = Right.end(); II != IE; ++II) { - unsigned LineNo2 = SourceMgr.getInstantiationLineNumber(II->first); - if (LineNo1 != LineNo2) continue; - - const std::string &Diag2 = II->second; - if (Diag2.find(Diag1) != std::string::npos || - Diag1.find(Diag2) != std::string::npos) { - break; - } - } - if (II == IE) { - // Not found. - LeftOnly.push_back(*I); - } else { - // Found. The same cannot be found twice. - Right.erase(II); - } - } - // Now all that's left in Right are those that were not matched. - - return PrintProblem(SourceMgr, LeftOnly.begin(), LeftOnly.end(), MsgLeftOnly) - | PrintProblem(SourceMgr, Right.begin(), Right.end(), MsgRightOnly); -} - -/// CheckResults - This compares the expected results to those that -/// were actually reported. It emits any discrepencies. Return "true" if there -/// were problems. Return "false" otherwise. -/// -static bool CheckResults(Preprocessor &PP, - const DiagList &ExpectedErrors, - const DiagList &ExpectedWarnings, - const DiagList &ExpectedNotes) { - const DiagnosticClient *DiagClient = PP.getDiagnostics().getClient(); - assert(DiagClient != 0 && - "DiagChecker requires a valid TextDiagnosticBuffer"); - const TextDiagnosticBuffer &Diags = - static_cast<const TextDiagnosticBuffer&>(*DiagClient); - SourceManager &SourceMgr = PP.getSourceManager(); - - // We want to capture the delta between what was expected and what was - // seen. - // - // Expected \ Seen - set expected but not seen - // Seen \ Expected - set seen but not expected - bool HadProblem = false; - - // See if there are error mismatches. - HadProblem |= CompareDiagLists(SourceMgr, - ExpectedErrors.begin(), ExpectedErrors.end(), - Diags.err_begin(), Diags.err_end(), - "Errors expected but not seen:", - "Errors seen but not expected:"); - - // See if there are warning mismatches. - HadProblem |= CompareDiagLists(SourceMgr, - ExpectedWarnings.begin(), - ExpectedWarnings.end(), - Diags.warn_begin(), Diags.warn_end(), - "Warnings expected but not seen:", - "Warnings seen but not expected:"); - - // See if there are note mismatches. - HadProblem |= CompareDiagLists(SourceMgr, - ExpectedNotes.begin(), - ExpectedNotes.end(), - Diags.note_begin(), Diags.note_end(), - "Notes expected but not seen:", - "Notes seen but not expected:"); - - return HadProblem; -} - - -/// CheckDiagnostics - Gather the expected diagnostics and check them. -bool clang::CheckDiagnostics(Preprocessor &PP) { - // Gather the set of expected diagnostics. - DiagList ExpectedErrors, ExpectedWarnings, ExpectedNotes; - FindExpectedDiags(PP, ExpectedErrors, ExpectedWarnings, ExpectedNotes); - - // Check that the expected diagnostics occurred. - return CheckResults(PP, ExpectedErrors, ExpectedWarnings, ExpectedNotes); -} diff --git a/contrib/llvm/tools/clang/lib/Frontend/InitHeaderSearch.cpp b/contrib/llvm/tools/clang/lib/Frontend/InitHeaderSearch.cpp index 3795c65..2e5ad17 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/InitHeaderSearch.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/InitHeaderSearch.cpp @@ -567,6 +567,19 @@ void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple, AddPath(CLANG_PREFIX "/usr/include/clang/" CLANG_VERSION_STRING, System, false, false, false); break; + case llvm::Triple::Linux: + // Generic Debian multiarch support: + if (triple.getArch() == llvm::Triple::x86_64) { + AddPath("/usr/include/x86_64-linux-gnu", System, false, false, false); + AddPath("/usr/include/i686-linux-gnu/64", System, false, false, false); + AddPath("/usr/include/i486-linux-gnu/64", System, false, false, false); + } else if (triple.getArch() == llvm::Triple::x86) { + AddPath("/usr/include/x86_64-linux-gnu/32", System, false, false, false); + AddPath("/usr/include/i686-linux-gnu", System, false, false, false); + AddPath("/usr/include/i486-linux-gnu", System, false, false, false); + } else if (triple.getArch() == llvm::Triple::arm) { + AddPath("/usr/include/arm-linux-gnueabi", System, false, false, false); + } default: break; } @@ -659,6 +672,27 @@ AddDefaultCPlusPlusIncludePaths(const llvm::Triple &triple) { // Debian based distros. // Note: these distros symlink /usr/include/c++/X.Y.Z -> X.Y //===------------------------------------------------------------------===// + + // Ubuntu 11.11 "Oneiric Ocelot" -- gcc-4.6.0 + AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.6", + "x86_64-linux-gnu", "32", "", triple); + AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.6", + "i686-linux-gnu", "", "64", triple); + AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.6", + "i486-linux-gnu", "", "64", triple); + AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.6", + "arm-linux-gnueabi", "", "", triple); + + // Ubuntu 11.04 "Natty Narwhal" -- gcc-4.5.2 + AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.5", + "x86_64-linux-gnu", "32", "", triple); + AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.5", + "i686-linux-gnu", "", "64", triple); + AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.5", + "i486-linux-gnu", "", "64", triple); + AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.5", + "arm-linux-gnueabi", "", "", triple); + // Ubuntu 10.10 "Maverick Meerkat" -- gcc-4.4.5 AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4", "i686-linux-gnu", "", "64", triple); @@ -742,6 +776,13 @@ AddDefaultCPlusPlusIncludePaths(const llvm::Triple &triple) { "x86_64-redhat-linux", "", "", triple); AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.1.2", "i386-redhat-linux", "", "", triple); + + // RHEL 5 + AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.1.1", + "x86_64-redhat-linux", "32", "", triple); + AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.1.1", + "i386-redhat-linux", "", "", triple); + //===------------------------------------------------------------------===// @@ -769,6 +810,11 @@ AddDefaultCPlusPlusIncludePaths(const llvm::Triple &triple) { AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.5", "x86_64-suse-linux", "", "", triple); + // openSUSE 12.1 + AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.6", + "i586-suse-linux", "", "", triple); + AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.6", + "x86_64-suse-linux", "", "", triple); // Arch Linux 2008-06-24 AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3.1", "i686-pc-linux-gnu", "", "", triple); @@ -997,6 +1043,8 @@ void InitHeaderSearch::Realize(const LangOptions &Lang) { if (it->first == Angled) SearchList.push_back(it->second); } + RemoveDuplicates(SearchList, quoted, Verbose); + unsigned angled = SearchList.size(); for (path_iterator it = IncludePath.begin(), ie = IncludePath.end(); it != ie; ++it) { @@ -1010,10 +1058,10 @@ void InitHeaderSearch::Realize(const LangOptions &Lang) { SearchList.push_back(it->second); } - RemoveDuplicates(SearchList, quoted, Verbose); + RemoveDuplicates(SearchList, angled, Verbose); bool DontSearchCurDir = false; // TODO: set to true if -I- is set? - Headers.SetSearchPaths(SearchList, quoted, DontSearchCurDir); + Headers.SetSearchPaths(SearchList, quoted, angled, DontSearchCurDir); // If verbose, print the list of directories that will be searched. if (Verbose) { diff --git a/contrib/llvm/tools/clang/lib/Frontend/InitPreprocessor.cpp b/contrib/llvm/tools/clang/lib/Frontend/InitPreprocessor.cpp index abe251d..147a8df0 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/InitPreprocessor.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/InitPreprocessor.cpp @@ -221,6 +221,40 @@ static void DefineExactWidthIntType(TargetInfo::IntType Ty, ConstSuffix); } +static void InitializeStandardPredefinedMacros(const TargetInfo &TI, + const LangOptions &LangOpts, + const FrontendOptions &FEOpts, + MacroBuilder &Builder) { + if (!LangOpts.Microsoft && !LangOpts.TraditionalCPP) + Builder.defineMacro("__STDC__"); + if (LangOpts.Freestanding) + Builder.defineMacro("__STDC_HOSTED__", "0"); + else + Builder.defineMacro("__STDC_HOSTED__"); + + if (!LangOpts.CPlusPlus) { + if (LangOpts.C99) + Builder.defineMacro("__STDC_VERSION__", "199901L"); + else if (!LangOpts.GNUMode && LangOpts.Digraphs) + Builder.defineMacro("__STDC_VERSION__", "199409L"); + } else { + if (LangOpts.GNUMode) + Builder.defineMacro("__cplusplus"); + else + // C++ [cpp.predefined]p1: + // The name_ _cplusplus is defined to the value 199711L when compiling a + // C++ translation unit. + Builder.defineMacro("__cplusplus", "199711L"); + } + + if (LangOpts.ObjC1) + Builder.defineMacro("__OBJC__"); + + // Not "standard" per se, but available even with the -undef flag. + if (LangOpts.AsmPreprocessor) + Builder.defineMacro("__ASSEMBLER__"); +} + static void InitializePredefinedMacros(const TargetInfo &TI, const LangOptions &LangOpts, const FrontendOptions &FEOpts, @@ -256,20 +290,6 @@ static void InitializePredefinedMacros(const TargetInfo &TI, // Initialize language-specific preprocessor defines. - // These should all be defined in the preprocessor according to the - // current language configuration. - if (!LangOpts.Microsoft && !LangOpts.TraditionalCPP) - Builder.defineMacro("__STDC__"); - if (LangOpts.AsmPreprocessor) - Builder.defineMacro("__ASSEMBLER__"); - - if (!LangOpts.CPlusPlus) { - if (LangOpts.C99) - Builder.defineMacro("__STDC_VERSION__", "199901L"); - else if (!LangOpts.GNUMode && LangOpts.Digraphs) - Builder.defineMacro("__STDC_VERSION__", "199409L"); - } - // Standard conforming mode? if (!LangOpts.GNUMode) Builder.defineMacro("__STRICT_ANSI__"); @@ -277,13 +297,7 @@ static void InitializePredefinedMacros(const TargetInfo &TI, if (LangOpts.CPlusPlus0x) Builder.defineMacro("__GXX_EXPERIMENTAL_CXX0X__"); - if (LangOpts.Freestanding) - Builder.defineMacro("__STDC_HOSTED__", "0"); - else - Builder.defineMacro("__STDC_HOSTED__"); - if (LangOpts.ObjC1) { - Builder.defineMacro("__OBJC__"); if (LangOpts.ObjCNonFragileABI) { Builder.defineMacro("__OBJC2__"); Builder.defineMacro("OBJC_ZEROCOST_EXCEPTIONS"); @@ -324,13 +338,6 @@ static void InitializePredefinedMacros(const TargetInfo &TI, if (LangOpts.CPlusPlus) { Builder.defineMacro("__GNUG__", "4"); Builder.defineMacro("__GXX_WEAK__"); - if (LangOpts.GNUMode) - Builder.defineMacro("__cplusplus"); - else - // C++ [cpp.predefined]p1: - // The name_ _cplusplusis defined to the value 199711L when compiling a - // C++ translation unit. - Builder.defineMacro("__cplusplus", "199711L"); Builder.defineMacro("__private_extern__", "extern"); } @@ -343,6 +350,8 @@ static void InitializePredefinedMacros(const TargetInfo &TI, // Since we define wchar_t in C++ mode. Builder.defineMacro("_WCHAR_T_DEFINED"); Builder.defineMacro("_NATIVE_WCHAR_T_DEFINED"); + // FIXME: Support Microsoft's __identifier extension in the lexer. + Builder.append("#define __identifier(x) x"); Builder.append("class type_info;"); } @@ -570,6 +579,12 @@ void clang::InitializePreprocessor(Preprocessor &PP, InitializePredefinedMacros(PP.getTargetInfo(), PP.getLangOptions(), FEOpts, Builder); + // Even with predefines off, some macros are still predefined. + // These should all be defined in the preprocessor according to the + // current language configuration. + InitializeStandardPredefinedMacros(PP.getTargetInfo(), PP.getLangOptions(), + FEOpts, Builder); + // Add on the predefines from the driver. Wrap in a #line directive to report // that they come from the command line. if (!PP.getLangOptions().AsmPreprocessor) diff --git a/contrib/llvm/tools/clang/lib/Frontend/LogDiagnosticPrinter.cpp b/contrib/llvm/tools/clang/lib/Frontend/LogDiagnosticPrinter.cpp index 954bad4..78eb1b2 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/LogDiagnosticPrinter.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/LogDiagnosticPrinter.cpp @@ -99,7 +99,7 @@ void LogDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level, DiagnosticClient::HandleDiagnostic(Level, Info); // Initialize the main file name, if we haven't already fetched it. - if (MainFilename.empty()) { + if (MainFilename.empty() && Info.hasSourceManager()) { const SourceManager &SM = Info.getSourceManager(); FileID FID = SM.getMainFileID(); if (!FID.isInvalid()) { @@ -122,7 +122,7 @@ void LogDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level, // Set the location information. DE.Filename = ""; DE.Line = DE.Column = 0; - if (Info.getLocation().isValid()) { + if (Info.getLocation().isValid() && Info.hasSourceManager()) { const SourceManager &SM = Info.getSourceManager(); PresumedLoc PLoc = SM.getPresumedLoc(Info.getLocation()); diff --git a/contrib/llvm/tools/clang/lib/Frontend/TextDiagnosticPrinter.cpp b/contrib/llvm/tools/clang/lib/Frontend/TextDiagnosticPrinter.cpp index 47c942c..1c47bf7 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/TextDiagnosticPrinter.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/TextDiagnosticPrinter.cpp @@ -343,7 +343,7 @@ void TextDiagnosticPrinter::EmitCaretDiagnostic(Diagnostic::Level Level, // "included from" lines. if (LastWarningLoc != PLoc.getIncludeLoc()) { LastWarningLoc = PLoc.getIncludeLoc(); - PrintIncludeStack(Level, LastWarningLoc, SM); + PrintIncludeStack(Diagnostic::Note, LastWarningLoc, SM); } if (DiagOpts->ShowLocation) { @@ -819,16 +819,28 @@ void TextDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level, if (DiagOpts->ShowColors) OS.changeColor(savedColor, true); - // Emit a Visual Studio compatible line number syntax. - if (LangOpts && LangOpts->Microsoft) { - OS << PLoc.getFilename() << '(' << LineNo << ')'; - OS << " : "; - } else { - OS << PLoc.getFilename() << ':' << LineNo << ':'; - if (DiagOpts->ShowColumn) - if (unsigned ColNo = PLoc.getColumn()) - OS << ColNo << ':'; + OS << PLoc.getFilename(); + switch (DiagOpts->Format) { + case DiagnosticOptions::Clang: OS << ':' << LineNo; break; + case DiagnosticOptions::Msvc: OS << '(' << LineNo; break; + case DiagnosticOptions::Vi: OS << " +" << LineNo; break; + } + if (DiagOpts->ShowColumn) + if (unsigned ColNo = PLoc.getColumn()) { + if (DiagOpts->Format == DiagnosticOptions::Msvc) { + OS << ','; + ColNo--; + } else + OS << ':'; + OS << ColNo; + } + switch (DiagOpts->Format) { + case DiagnosticOptions::Clang: + case DiagnosticOptions::Vi: OS << ':'; break; + case DiagnosticOptions::Msvc: OS << ") : "; break; } + + if (DiagOpts->ShowSourceRanges && Info.getNumRanges()) { FileID CaretFileID = SM.getFileID(SM.getInstantiationLoc(Info.getLocation())); @@ -927,8 +939,8 @@ void TextDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level, OptionName += "-Werror"; } - if (const char * - Opt = DiagnosticIDs::getWarningOptionForDiag(Info.getID())) { + llvm::StringRef Opt = DiagnosticIDs::getWarningOptionForDiag(Info.getID()); + if (!Opt.empty()) { if (!OptionName.empty()) OptionName += ','; OptionName += "-W"; diff --git a/contrib/llvm/tools/clang/lib/Frontend/Warnings.cpp b/contrib/llvm/tools/clang/lib/Frontend/Warnings.cpp index 8cc5616..f12b484 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/Warnings.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/Warnings.cpp @@ -55,17 +55,14 @@ void clang::ProcessWarningOptions(Diagnostic &Diags, Diags.setExtensionHandlingBehavior(Diagnostic::Ext_Ignore); for (unsigned i = 0, e = Opts.Warnings.size(); i != e; ++i) { - const std::string &Opt = Opts.Warnings[i]; - const char *OptStart = &Opt[0]; - const char *OptEnd = OptStart+Opt.size(); - assert(*OptEnd == 0 && "Expect null termination for lower-bound search"); + llvm::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 (OptEnd-OptStart > 3 && memcmp(OptStart, "no-", 3) == 0) { + if (Opt.startswith("no-")) { isPositive = false; - OptStart += 3; + Opt = Opt.substr(3); } // Figure out how this option affects the warning. If -Wfoo, map the @@ -74,49 +71,47 @@ void clang::ProcessWarningOptions(Diagnostic &Diags, // -Wsystem-headers is a special case, not driven by the option table. It // cannot be controlled with -Werror. - if (OptEnd-OptStart == 14 && memcmp(OptStart, "system-headers", 14) == 0) { + if (Opt == "system-headers") { Diags.setSuppressSystemWarnings(!isPositive); 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 (OptEnd-OptStart >= 5 && memcmp(OptStart, "error", 5) == 0) { - const char *Specifier = 0; - if (OptEnd-OptStart != 5) { // Specifier must be present. - if ((OptStart[5] != '=' && OptStart[5] != '-') || - OptEnd-OptStart == 6) { + if (Opt.startswith("error")) { + llvm::StringRef Specifier; + if (Opt.size() > 5) { // Specifier must be present. + if ((Opt[5] != '=' && Opt[5] != '-') || Opt.size() == 6) { Diags.Report(diag::warn_unknown_warning_specifier) - << "-Werror" << ("-W" + Opt); + << "-Werror" << ("-W" + Opt.str()); continue; } - Specifier = OptStart+6; + Specifier = Opt.substr(6); } - if (Specifier == 0) { + if (Specifier.empty()) { Diags.setWarningsAsErrors(isPositive); continue; } // -Werror=foo maps foo to Error, -Wno-error=foo maps it to Warning. Mapping = isPositive ? diag::MAP_ERROR : diag::MAP_WARNING_NO_WERROR; - OptStart = Specifier; + Opt = Specifier; } // -Wfatal-errors is yet another special case. - if (OptEnd-OptStart >= 12 && memcmp(OptStart, "fatal-errors", 12) == 0) { - const char* Specifier = 0; - if (OptEnd-OptStart != 12) { - if ((OptStart[12] != '=' && OptStart[12] != '-') || - OptEnd-OptStart == 13) { + if (Opt.startswith("fatal-errors")) { + llvm::StringRef Specifier; + if (Opt.size() != 12) { + if ((Opt[12] != '=' && Opt[12] != '-') || Opt.size() == 13) { Diags.Report(diag::warn_unknown_warning_specifier) - << "-Wfatal-errors" << ("-W" + Opt); + << "-Wfatal-errors" << ("-W" + Opt.str()); continue; } - Specifier = OptStart + 13; + Specifier = Opt.substr(13); } - if (Specifier == 0) { + if (Specifier.empty()) { Diags.setErrorsAsFatal(isPositive); continue; } @@ -124,10 +119,12 @@ void clang::ProcessWarningOptions(Diagnostic &Diags, // -Wfatal-errors=foo maps foo to Fatal, -Wno-fatal-errors=foo // maps it to Error. Mapping = isPositive ? diag::MAP_FATAL : diag::MAP_ERROR_NO_WFATAL; - OptStart = Specifier; + Opt = Specifier; } - if (Diags.setDiagnosticGroupMapping(OptStart, Mapping)) - Diags.Report(diag::warn_unknown_warning_option) << ("-W" + Opt); + if (Diags.setDiagnosticGroupMapping(Opt, Mapping)) + Diags.Report(isPositive ? diag::warn_unknown_warning_option : + diag::warn_unknown_negative_warning_option) + << ("-W" + Opt.str()); } } |