Index: docs/UsersManual.rst =================================================================== --- docs/UsersManual.rst +++ docs/UsersManual.rst @@ -577,12 +577,10 @@ Current limitations ^^^^^^^^^^^^^^^^^^^ -1. For :option:`-Rpass` to provide source location information, you - need to enable debug line tables and column information. That is, - you need to add :option:`-gmlt` (or any of the debug-generating - flags) and :option:`-gcolumn-info`. If you omit these options, - every remark will be accompanied by a note stating that line number - information is missing. +1. For :option:`-Rpass` to provide column information, you + need to enable it explicitly. That is, you need to add + :option:`-gcolumn-info`. If you omit this, remarks will only show + line information. 2. Optimization remarks that refer to function names will display the mangled name of the function. Since these remarks are emitted by the Index: include/clang/Basic/DiagnosticFrontendKinds.td =================================================================== --- include/clang/Basic/DiagnosticFrontendKinds.td +++ include/clang/Basic/DiagnosticFrontendKinds.td @@ -41,9 +41,6 @@ InGroup, DefaultRemark; def remark_fe_backend_optimization_remark_analysis : Remark<"%0">, BackendInfo, InGroup, DefaultRemark; -def note_fe_backend_optimization_remark_missing_loc : Note<"use " - "-gline-tables-only -gcolumn-info to track source location information " - "for this optimization remark">; def note_fe_backend_optimization_remark_invalid_loc : Note<"could " "not determine the original source location for %0:%1:%2">; Index: include/clang/Frontend/CodeGenOptions.h =================================================================== --- include/clang/Frontend/CodeGenOptions.h +++ include/clang/Frontend/CodeGenOptions.h @@ -53,6 +53,13 @@ enum DebugInfoKind { NoDebugInfo, /// Don't generate debug info. + LocTrackingOnly, /// Emit location information but do not generate + /// debug info in the output. This is useful in + /// cases where the backend wants to track source + /// locations for instructions without actually + /// emitting debug info for them (e.g., when -Rpass + /// is used). + DebugLineTablesOnly, /// Emit only debug info necessary for generating /// line number tables (-gline-tables-only). Index: include/clang/Frontend/CodeGenOptions.def =================================================================== --- include/clang/Frontend/CodeGenOptions.def +++ include/clang/Frontend/CodeGenOptions.def @@ -140,7 +140,7 @@ VALUE_CODEGENOPT(SSPBufferSize, 32, 0) /// The kind of generated debug info. -ENUM_CODEGENOPT(DebugInfo, DebugInfoKind, 2, NoDebugInfo) +ENUM_CODEGENOPT(DebugInfo, DebugInfoKind, 3, NoDebugInfo) /// Dwarf version. VALUE_CODEGENOPT(DwarfVersion, 3, 0) Index: lib/CodeGen/CGDebugInfo.cpp =================================================================== --- lib/CodeGen/CGDebugInfo.cpp +++ lib/CodeGen/CGDebugInfo.cpp @@ -375,9 +375,10 @@ TheCU = DBuilder.createCompileUnit( LangTag, Filename, getCurrentDirname(), Producer, LO.Optimize, CGM.getCodeGenOpts().DwarfDebugFlags, RuntimeVers, SplitDwarfFilename, - DebugKind == CodeGenOptions::DebugLineTablesOnly + DebugKind <= CodeGenOptions::DebugLineTablesOnly ? llvm::DIBuilder::LineTablesOnly - : llvm::DIBuilder::FullDebug); + : llvm::DIBuilder::FullDebug, + DebugKind != CodeGenOptions::LocTrackingOnly); } /// CreateType - Get the Basic type from the cache or create a new @@ -2341,7 +2342,7 @@ /// getFunctionDeclaration - Return debug info descriptor to describe method /// declaration for the given method definition. llvm::DISubprogram CGDebugInfo::getFunctionDeclaration(const Decl *D) { - if (!D || DebugKind == CodeGenOptions::DebugLineTablesOnly) + if (!D || DebugKind <= CodeGenOptions::DebugLineTablesOnly) return llvm::DISubprogram(); const FunctionDecl *FD = dyn_cast(D); @@ -2386,7 +2387,7 @@ llvm::DICompositeType CGDebugInfo::getOrCreateFunctionType(const Decl *D, QualType FnType, llvm::DIFile F) { - if (!D || DebugKind == CodeGenOptions::DebugLineTablesOnly) + if (!D || DebugKind <= CodeGenOptions::DebugLineTablesOnly) // Create fake but valid subroutine type. Otherwise // llvm::DISubprogram::Verify() would return false, and // subprogram DIE will miss DW_AT_decl_file and Index: lib/CodeGen/CodeGenAction.cpp =================================================================== --- lib/CodeGen/CodeGenAction.cpp +++ lib/CodeGen/CodeGenAction.cpp @@ -443,15 +443,7 @@ Diags.Report(Loc, DiagID) << AddFlagValue(D.getPassName()) << D.getMsg().str(); - if (Line == 0) - // If we could not extract a source location for the diagnostic, - // inform the user how they can get source locations back. - // - // FIXME: We should really be generating !srcloc annotations when - // -Rpass is used. !srcloc annotations need to be emitted in - // approximately the same spots as !dbg nodes. - Diags.Report(Loc, diag::note_fe_backend_optimization_remark_missing_loc); - else if (DILoc.isInvalid()) + if (DILoc.isInvalid()) // If we were not able to translate the file:line:col information // back to a SourceLocation, at least emit a note stating that // we could not translate this location. This can happen in the Index: lib/Frontend/CompilerInvocation.cpp =================================================================== --- lib/Frontend/CompilerInvocation.cpp +++ lib/Frontend/CompilerInvocation.cpp @@ -549,18 +549,30 @@ } Opts.DependentLibraries = Args.getAllArgValues(OPT_dependent_lib); + bool NeedLocTracking = false; - if (Arg *A = Args.getLastArg(OPT_Rpass_EQ)) + if (Arg *A = Args.getLastArg(OPT_Rpass_EQ)) { Opts.OptimizationRemarkPattern = GenerateOptimizationRemarkRegex(Diags, Args, A); + NeedLocTracking = true; + } - if (Arg *A = Args.getLastArg(OPT_Rpass_missed_EQ)) + if (Arg *A = Args.getLastArg(OPT_Rpass_missed_EQ)) { Opts.OptimizationRemarkMissedPattern = GenerateOptimizationRemarkRegex(Diags, Args, A); + NeedLocTracking = true; + } - if (Arg *A = Args.getLastArg(OPT_Rpass_analysis_EQ)) + if (Arg *A = Args.getLastArg(OPT_Rpass_analysis_EQ)) { Opts.OptimizationRemarkAnalysisPattern = GenerateOptimizationRemarkRegex(Diags, Args, A); + NeedLocTracking = true; + } + + // If the user requested one of the flags in the -Rpass family, make sure that + // the backend tracks source location information. + if (NeedLocTracking && Opts.getDebugInfo() == CodeGenOptions::NoDebugInfo) + Opts.setDebugInfo(CodeGenOptions::LocTrackingOnly); return Success; } Index: test/Frontend/optimization-remark.c =================================================================== --- test/Frontend/optimization-remark.c +++ test/Frontend/optimization-remark.c @@ -3,8 +3,18 @@ // always trigger the inliner, so it should be independent of the // optimization level. -// RUN: %clang_cc1 %s -Rpass=inline -Rpass-analysis=inline -Rpass-missed=inline -O0 -gline-tables-only -emit-llvm-only -verify +// RUN: %clang_cc1 %s -Rpass=inline -Rpass-analysis=inline -Rpass-missed=inline -O0 -emit-llvm-only -verify // RUN: %clang_cc1 %s -DNDEBUG -Rpass=inline -emit-llvm-only -verify +// RUN: %clang_cc1 %s -Rpass=inline -emit-llvm -o %t 2>/dev/null | FileCheck %s < %t + +// -Rpass should produce source location annotations, exclusively (just +// like -gmlt). +// CHECK: , !dbg ! +// CHECK-NOT: DW_TAG_base_type + +// But llvm.dbg.cu should be missing (to prevent writing debug info to +// the final output). +// CHECK-NOT: !llvm.dbg.cu = !{ int foo(int x, int y) __attribute__((always_inline)); int foo(int x, int y) { return x + y; } @@ -27,5 +37,5 @@ return foo(j, j - 2) * foz(j - 2, j); } #ifdef NDEBUG -// expected-remark@-2 {{foo inlined into bar}} expected-note@-2 {{use -gline-tables-only -gcolumn-info to track source location information for this optimization remark}} +// expected-remark@-3 {{foo inlined into bar}} #endif