DIAGOPT(ShowFixits, 1, 1) /// Show fixit information.
DIAGOPT(ShowSourceRanges, 1, 0) /// Show source ranges in numeric form.
DIAGOPT(ShowParseableFixits, 1, 0) /// Show machine parseable fix-its.
+DIAGOPT(ShowPresumedLoc, 1, 0) /// Show presumed location for diagnostics.
DIAGOPT(ShowOptionNames, 1, 0) /// Show the option name for mappable
/// diagnostics.
DIAGOPT(ShowNoteIncludeStack, 1, 0) /// Show include stacks for notes.
/// presumed location cannot be calculate (e.g., because \p Loc is invalid
/// or the file containing \p Loc has changed on disk), returns an invalid
/// presumed location.
- PresumedLoc getPresumedLoc(SourceLocation Loc) const;
+ PresumedLoc getPresumedLoc(SourceLocation Loc,
+ bool UseLineDirectives = true) const;
/// \brief Returns true if both SourceLocations correspond to the same file.
bool isFromSameFile(SourceLocation Loc1, SourceLocation Loc2) const {
/// Get a presumed location suitable for displaying in a diagnostic message,
/// taking into account macro arguments and expansions.
- PresumedLoc getPresumedLocForDisplay(SourceLocation Loc) const {
+ PresumedLoc getPresumedLocForDisplay(SourceLocation Loc,
+ bool UseLineDirectives = true) const{
// This is a condensed form of the algorithm used by emitCaretDiagnostic to
// walk to the top of the macro call stack.
while (Loc.isMacroID()) {
Loc = getImmediateMacroCallerLoc(Loc);
}
- return getPresumedLoc(Loc);
+ return getPresumedLoc(Loc, UseLineDirectives);
}
/// Look through spelling locations for a macro argument expansion, and if
HelpText<"Change diagnostic formatting to match IDE and command line tools">;
def fdiagnostics_show_category : Separate<["-"], "fdiagnostics-show-category">,
HelpText<"Print diagnostic category">;
+def fno_diagnostics_use_presumed_location : Flag<["-"], "fno-diagnostics-use-presumed-location">,
+ HelpText<"Ignore #line directives when displaying diagnostic locations">;
def ftabstop : Separate<["-"], "ftabstop">, MetaVarName<"<N>">,
HelpText<"Set the tab stop distance.">;
def ferror_limit : Separate<["-"], "ferror-limit">, MetaVarName<"<N>">,
///
/// Note that a presumed location is always given as the expansion point of an
/// expansion location, not at the spelling location.
-PresumedLoc SourceManager::getPresumedLoc(SourceLocation Loc) const {
+PresumedLoc SourceManager::getPresumedLoc(SourceLocation Loc,
+ bool UseLineDirectives) const {
if (Loc.isInvalid()) return PresumedLoc();
// Presumed locations are always for expansion points.
// If we have #line directives in this file, update and overwrite the physical
// location info if appropriate.
- if (FI.hasLineDirectives()) {
+ if (UseLineDirectives && FI.hasLineDirectives()) {
assert(LineTable && "Can't have linetable entries without a LineTable!");
// See if there is a #line directive before this. If so, get it.
if (const LineEntry *Entry =
Opts.ShowSourceRanges = Args.hasArg(OPT_fdiagnostics_print_source_range_info);
Opts.ShowParseableFixits = Args.hasArg(OPT_fdiagnostics_parseable_fixits);
+ Opts.ShowPresumedLoc = !Args.hasArg(OPT_fno_diagnostics_use_presumed_location);
Opts.VerifyDiagnostics = Args.hasArg(OPT_verify);
Opts.ElideType = !Args.hasArg(OPT_fno_elide_type);
Opts.ShowTemplateTree = Args.hasArg(OPT_fdiagnostics_show_template_tree);
PresumedLoc PLoc;
if (Loc.isValid()) {
- PLoc = SM->getPresumedLocForDisplay(Loc);
+ PLoc = SM->getPresumedLocForDisplay(Loc, DiagOpts->ShowPresumedLoc);
// First, if this diagnostic is not in the main file, print out the
// "included from" lines.
if (Loc.isInvalid())
return;
- PresumedLoc PLoc = SM.getPresumedLoc(Loc);
+ PresumedLoc PLoc = SM.getPresumedLoc(Loc, DiagOpts->ShowPresumedLoc);
if (PLoc.isInvalid())
return;
--- /dev/null
+// RUN: %clang_cc1 -fsyntax-only -pedantic-errors %s 2>&1 | FileCheck %s --check-prefix=PRESUMED
+// RUN: %clang_cc1 -fsyntax-only -pedantic-errors -fno-diagnostics-use-presumed-location %s 2>&1 | FileCheck %s --check-prefix=SPELLING
+
+#line 100
+#define X(y) y
+X(int n = error);
+
+// PRESUMED: diag-presumed.c:101:11: error: use of undeclared identifier 'error'
+// PRESUMED: diag-presumed.c:100:14: note: expanded from
+// SPELLING: diag-presumed.c:6:11: error: use of undeclared identifier 'error'
+// SPELLING: diag-presumed.c:5:14: note: expanded from
+
+;
+// PRESUMED: diag-presumed.c:108:1: error: extra ';' outside of a functio
+// SPELLING: diag-presumed.c:13:1: error: extra ';' outside of a functio
+
+# 1 "thing1.cc" 1
+# 1 "thing1.h" 1
+# 1 "systemheader.h" 1 3
+;
+// No diagnostic here: we're in a system header, even if we're using spelling
+// locations for the diagnostics..
+// PRESUMED-NOT: extra ';'
+// SPELLING-NOT: extra ';'
+
+another error;
+// PRESUMED: included from {{.*}}diag-presumed.c:112:
+// PRESUMED: from thing1.cc:1:
+// PRESUMED: from thing1.h:1:
+// PRESUMED: systemheader.h:7:1: error: unknown type name 'another'
+
+// SPELLING-NOT: included from
+// SPELLING: diag-presumed.c:26:1: error: unknown type name 'another'
+
+# 1 "thing1.h" 2
+# 1 "thing1.cc" 2