[PATCH] Correctly check for the main file in the presence of line markers
Eli Friedman
eli.friedman at gmail.com
Mon Jul 29 18:33:20 PDT 2013
Patch attached. Basically, the idea is that even if a SourceLocation
is technically in the main file, we might want to treat it differently
in the presence of line markers. I added
SourceManager::isPresumedFromMainFile to check this.
I'm particularly looking for suggestions about the name of the method;
having isFromMainFile and isPresumedFromMainFile seems very confusing,
but I don't really have any better ideas.
-Eli
-------------- next part --------------
diff --git a/include/clang/Basic/SourceManager.h b/include/clang/Basic/SourceManager.h
index 9fc4885..b55d662 100644
--- a/include/clang/Basic/SourceManager.h
+++ b/include/clang/Basic/SourceManager.h
@@ -1292,6 +1292,17 @@ public:
PresumedLoc getPresumedLoc(SourceLocation Loc,
bool UseLineDirectives = true) const;
+ /// \brief Returns whether the PresumedLoc for a given SourceLocation is
+ /// from a #include directive.
+ ///
+ /// This computes the "presumed" location for a SourceLocation, then checks
+ /// whether it came from a file other than the main file. This is different
+ // from isFromMainFile() because it takes line marker directives into
+ // account.
+ bool isPresumedFromMainFile(SourceLocation Loc) const {
+ return getPresumedLoc(Loc).getIncludeLoc().isInvalid();
+ }
+
/// \brief Returns true if both SourceLocations correspond to the same file.
bool isFromSameFile(SourceLocation Loc1, SourceLocation Loc2) const {
return getFileID(Loc1) == getFileID(Loc2);
diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp
index c70019f..45a3fc0 100644
--- a/lib/Lex/PPDirectives.cpp
+++ b/lib/Lex/PPDirectives.cpp
@@ -2037,7 +2037,7 @@ void Preprocessor::HandleDefineDirective(Token &DefineTok,
assert(!MI->isUsed());
// If we need warning for not using the macro, add its location in the
// warn-because-unused-macro set. If it gets used it will be removed from set.
- if (isInPrimaryFile() && // don't warn for include'd macros.
+ if (getSourceManager().isPresumedFromMainFile(MI->getDefinitionLoc()) &&
Diags->getDiagnosticLevel(diag::pp_macro_not_used,
MI->getDefinitionLoc()) != DiagnosticsEngine::Ignored) {
MI->setIsWarnIfUnused(true);
diff --git a/lib/Lex/Pragma.cpp b/lib/Lex/Pragma.cpp
index 324bbd2..81500e8 100644
--- a/lib/Lex/Pragma.cpp
+++ b/lib/Lex/Pragma.cpp
@@ -349,7 +349,7 @@ void Preprocessor::HandleMicrosoft__pragma(Token &Tok) {
/// HandlePragmaOnce - Handle \#pragma once. OnceTok is the 'once'.
///
void Preprocessor::HandlePragmaOnce(Token &OnceTok) {
- if (isInPrimaryFile()) {
+ if (getSourceManager().isPresumedFromMainFile(OnceTok.getLocation())) {
Diag(OnceTok, diag::pp_pragma_once_in_main_file);
return;
}
@@ -413,7 +413,7 @@ void Preprocessor::HandlePragmaPoison(Token &PoisonTok) {
/// HandlePragmaSystemHeader - Implement \#pragma GCC system_header. We know
/// that the whole directive has been parsed.
void Preprocessor::HandlePragmaSystemHeader(Token &SysHeaderTok) {
- if (isInPrimaryFile()) {
+ if (getSourceManager().isPresumedFromMainFile(SysHeaderTok.getLocation())) {
Diag(SysHeaderTok, diag::pp_pragma_sysheader_in_main_file);
return;
}
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp
index 8faa919..034db95 100644
--- a/lib/Sema/Sema.cpp
+++ b/lib/Sema/Sema.cpp
@@ -721,7 +721,7 @@ void Sema::ActOnEndOfTranslationUnit() {
else {
if (FD->getStorageClass() == SC_Static &&
!FD->isInlineSpecified() &&
- !SourceMgr.isFromMainFile(
+ !SourceMgr.isPresumedFromMainFile(
SourceMgr.getExpansionLoc(FD->getLocation())))
Diag(DiagD->getLocation(), diag::warn_unneeded_static_internal_decl)
<< DiagD->getDeclName();
@@ -742,7 +742,7 @@ void Sema::ActOnEndOfTranslationUnit() {
if (DiagD->isReferenced()) {
Diag(DiagD->getLocation(), diag::warn_unneeded_internal_decl)
<< /*variable*/1 << DiagD->getDeclName();
- } else if (getSourceManager().isFromMainFile(DiagD->getLocation())) {
+ } else if (SourceMgr.isPresumedFromMainFile(DiagD->getLocation())) {
// If the declaration is in a header which is included into multiple
// TUs, it will declare one variable per TU, and one of the other
// variables may be used. So, only warn if the declaration is in the
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 3df0472..9af8a8e 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -6717,7 +6717,8 @@ Decl *Sema::ActOnUsingDirective(Scope *S,
IdentLoc, Named, CommonAncestor);
if (IsUsingDirectiveInToplevelContext(CurContext) &&
- !SourceMgr.isFromMainFile(SourceMgr.getExpansionLoc(IdentLoc))) {
+ !SourceMgr.isPresumedFromMainFile(
+ SourceMgr.getExpansionLoc(IdentLoc))) {
Diag(IdentLoc, diag::warn_using_directive_in_header);
}
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 5b0029a..246e8f5 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -229,7 +229,7 @@ static void diagnoseUseOfInternalDeclInInlineFunction(Sema &S,
// This last can give us false negatives, but it's better than warning on
// wrappers for simple C library functions.
const FunctionDecl *UsedFn = dyn_cast<FunctionDecl>(D);
- bool DowngradeWarning = S.getSourceManager().isFromMainFile(Loc);
+ bool DowngradeWarning = S.getSourceManager().isPresumedFromMainFile(Loc);
if (!DowngradeWarning && UsedFn)
DowngradeWarning = UsedFn->isInlined() || UsedFn->hasAttr<ConstAttr>();
diff --git a/test/Preprocessor/warn-macro-unused.c b/test/Preprocessor/warn-macro-unused.c
index c33aeb5..a305cc9 100644
--- a/test/Preprocessor/warn-macro-unused.c
+++ b/test/Preprocessor/warn-macro-unused.c
@@ -2,6 +2,10 @@
#include "warn-macro-unused.h"
+# 1 "warn-macro-unused-fake-header.h" 1
+#define unused_from_fake_header
+# 5 "warn-macro-unused.c" 2
+
#define unused // expected-warning {{macro is not used}}
#define unused
unused
More information about the cfe-commits
mailing list