mirror of https://github.com/microsoft/clang.git
Split isFromMainFile into two functions.
Basically, isInMainFile considers line markers, and isWrittenInMainFile doesn't. Distinguishing between the two is useful when dealing with files which are preprocessed files or rewritten with -frewrite-includes (so we don't, for example, print useless warnings). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@188968 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
55a2b3dbff
commit
24146975f1
|
@ -1292,14 +1292,30 @@ public:
|
|||
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 {
|
||||
/// \brief Returns whether the PresumedLoc for a given SourceLocation is
|
||||
/// in the main file.
|
||||
///
|
||||
/// 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 isWrittenInMainFile() because it takes line marker directives into
|
||||
/// account.
|
||||
bool isInMainFile(SourceLocation Loc) const {
|
||||
return getPresumedLoc(Loc).getIncludeLoc().isInvalid();
|
||||
}
|
||||
|
||||
/// \brief Returns true if the spelling locations for both SourceLocations
|
||||
/// are part of the same file buffer.
|
||||
///
|
||||
/// This check ignores line marker directives.
|
||||
bool isWrittenInSameFile(SourceLocation Loc1, SourceLocation Loc2) const {
|
||||
return getFileID(Loc1) == getFileID(Loc2);
|
||||
}
|
||||
|
||||
/// \brief Returns true if the file of provided SourceLocation is the main
|
||||
/// file.
|
||||
bool isFromMainFile(SourceLocation Loc) const {
|
||||
/// \brief Returns true if the spelling location for the given location
|
||||
/// is in the main file buffer.
|
||||
///
|
||||
/// This check ignores line marker directives.
|
||||
bool isWrittenInMainFile(SourceLocation Loc) const {
|
||||
return getFileID(Loc) == getMainFileID();
|
||||
}
|
||||
|
||||
|
|
|
@ -628,11 +628,11 @@ static bool IsFromSameFile(SourceManager &SM, SourceLocation DirectiveLoc,
|
|||
while (DiagnosticLoc.isMacroID())
|
||||
DiagnosticLoc = SM.getImmediateMacroCallerLoc(DiagnosticLoc);
|
||||
|
||||
if (SM.isFromSameFile(DirectiveLoc, DiagnosticLoc))
|
||||
if (SM.isWrittenInSameFile(DirectiveLoc, DiagnosticLoc))
|
||||
return true;
|
||||
|
||||
const FileEntry *DiagFile = SM.getFileEntryForID(SM.getFileID(DiagnosticLoc));
|
||||
if (!DiagFile && SM.isFromMainFile(DirectiveLoc))
|
||||
if (!DiagFile && SM.isWrittenInMainFile(DirectiveLoc))
|
||||
return true;
|
||||
|
||||
return (DiagFile == SM.getFileEntryForID(SM.getFileID(DirectiveLoc)));
|
||||
|
|
|
@ -2040,7 +2040,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().isInMainFile(MI->getDefinitionLoc()) &&
|
||||
Diags->getDiagnosticLevel(diag::pp_macro_not_used,
|
||||
MI->getDefinitionLoc()) != DiagnosticsEngine::Ignored) {
|
||||
MI->setIsWarnIfUnused(true);
|
||||
|
|
|
@ -115,7 +115,7 @@ void clang::RewriteMacrosInInput(Preprocessor &PP, raw_ostream *OS) {
|
|||
SourceLocation PPLoc = SM.getExpansionLoc(PPTok.getLocation());
|
||||
|
||||
// If PPTok is from a different source file, ignore it.
|
||||
if (!SM.isFromMainFile(PPLoc)) {
|
||||
if (!SM.isWrittenInMainFile(PPLoc)) {
|
||||
PP.Lex(PPTok);
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -791,7 +791,7 @@ void RewriteModernObjC::HandleTopLevelSingleDecl(Decl *D) {
|
|||
}
|
||||
}
|
||||
// If we have a decl in the main file, see if we should rewrite it.
|
||||
if (SM->isFromMainFile(Loc))
|
||||
if (SM->isWrittenInMainFile(Loc))
|
||||
return HandleDeclInMainFile(D);
|
||||
}
|
||||
|
||||
|
|
|
@ -721,7 +721,7 @@ void RewriteObjC::HandleTopLevelSingleDecl(Decl *D) {
|
|||
}
|
||||
}
|
||||
// If we have a decl in the main file, see if we should rewrite it.
|
||||
if (SM->isFromMainFile(Loc))
|
||||
if (SM->isWrittenInMainFile(Loc))
|
||||
return HandleDeclInMainFile(D);
|
||||
}
|
||||
|
||||
|
|
|
@ -722,7 +722,7 @@ void Sema::ActOnEndOfTranslationUnit() {
|
|||
else {
|
||||
if (FD->getStorageClass() == SC_Static &&
|
||||
!FD->isInlineSpecified() &&
|
||||
!SourceMgr.isFromMainFile(
|
||||
!SourceMgr.isInMainFile(
|
||||
SourceMgr.getExpansionLoc(FD->getLocation())))
|
||||
Diag(DiagD->getLocation(), diag::warn_unneeded_static_internal_decl)
|
||||
<< DiagD->getDeclName();
|
||||
|
@ -743,7 +743,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.isInMainFile(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
|
||||
|
|
|
@ -6288,7 +6288,7 @@ void Sema::CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr,
|
|||
if (SourceMgr.isInSystemHeader(RBracketLoc)) {
|
||||
SourceLocation IndexLoc = SourceMgr.getSpellingLoc(
|
||||
IndexExpr->getLocStart());
|
||||
if (SourceMgr.isFromSameFile(RBracketLoc, IndexLoc))
|
||||
if (SourceMgr.isWrittenInSameFile(RBracketLoc, IndexLoc))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6710,7 +6710,7 @@ Decl *Sema::ActOnUsingDirective(Scope *S,
|
|||
IdentLoc, Named, CommonAncestor);
|
||||
|
||||
if (IsUsingDirectiveInToplevelContext(CurContext) &&
|
||||
!SourceMgr.isFromMainFile(SourceMgr.getExpansionLoc(IdentLoc))) {
|
||||
!SourceMgr.isInMainFile(SourceMgr.getExpansionLoc(IdentLoc))) {
|
||||
Diag(IdentLoc, diag::warn_using_directive_in_header);
|
||||
}
|
||||
|
||||
|
|
|
@ -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().isInMainFile(Loc);
|
||||
if (!DowngradeWarning && UsedFn)
|
||||
DowngradeWarning = UsedFn->isInlined() || UsedFn->hasAttr<ConstAttr>();
|
||||
|
||||
|
|
|
@ -2233,7 +2233,7 @@ static void removePunyEdges(PathPieces &path,
|
|||
SourceLocation FirstLoc = start->getLocStart();
|
||||
SourceLocation SecondLoc = end->getLocStart();
|
||||
|
||||
if (!SM.isFromSameFile(FirstLoc, SecondLoc))
|
||||
if (!SM.isWrittenInSameFile(FirstLoc, SecondLoc))
|
||||
continue;
|
||||
if (SM.isBeforeInTranslationUnit(SecondLoc, FirstLoc))
|
||||
std::swap(SecondLoc, FirstLoc);
|
||||
|
|
|
@ -741,7 +741,7 @@ bool ObjCMethodCall::canBeOverridenInSubclass(ObjCInterfaceDecl *IDecl,
|
|||
// TODO: It could actually be subclassed if the subclass is private as well.
|
||||
// This is probably very rare.
|
||||
SourceLocation InterfLoc = IDecl->getEndOfDefinitionLoc();
|
||||
if (InterfLoc.isValid() && SM.isFromMainFile(InterfLoc))
|
||||
if (InterfLoc.isValid() && SM.isInMainFile(InterfLoc))
|
||||
return false;
|
||||
|
||||
// Assume that property accessors are not overridden.
|
||||
|
@ -763,7 +763,7 @@ bool ObjCMethodCall::canBeOverridenInSubclass(ObjCInterfaceDecl *IDecl,
|
|||
return false;
|
||||
|
||||
// If outside the main file,
|
||||
if (D->getLocation().isValid() && !SM.isFromMainFile(D->getLocation()))
|
||||
if (D->getLocation().isValid() && !SM.isInMainFile(D->getLocation()))
|
||||
return true;
|
||||
|
||||
if (D->isOverriding()) {
|
||||
|
|
|
@ -764,7 +764,7 @@ static bool mayInlineDecl(const CallEvent &Call, AnalysisDeclContext *CalleeADC,
|
|||
// Conditionally control the inlining of methods on objects that look
|
||||
// like C++ containers.
|
||||
if (!Opts.mayInlineCXXContainerCtorsAndDtors())
|
||||
if (!Ctx.getSourceManager().isFromMainFile(FD->getLocation()))
|
||||
if (!Ctx.getSourceManager().isInMainFile(FD->getLocation()))
|
||||
if (isContainerCtorOrDtor(Ctx, FD))
|
||||
return false;
|
||||
|
||||
|
|
|
@ -129,11 +129,11 @@ getFirstStackedCallToHeaderFile(PathDiagnosticCallPiece *CP,
|
|||
if (CallLoc.isMacroID())
|
||||
return 0;
|
||||
|
||||
assert(SMgr.isFromMainFile(CallLoc) &&
|
||||
assert(SMgr.isInMainFile(CallLoc) &&
|
||||
"The call piece should be in the main file.");
|
||||
|
||||
// Check if CP represents a path through a function outside of the main file.
|
||||
if (!SMgr.isFromMainFile(CP->callEnterWithin.asLocation()))
|
||||
if (!SMgr.isInMainFile(CP->callEnterWithin.asLocation()))
|
||||
return CP;
|
||||
|
||||
const PathPieces &Path = CP->path;
|
||||
|
|
|
@ -596,7 +596,7 @@ AnalysisConsumer::getModeForDecl(Decl *D, AnalysisMode Mode) {
|
|||
// - System headers: don't run any checks.
|
||||
SourceManager &SM = Ctx->getSourceManager();
|
||||
SourceLocation SL = SM.getExpansionLoc(D->getLocation());
|
||||
if (!Opts->AnalyzeAll && !SM.isFromMainFile(SL)) {
|
||||
if (!Opts->AnalyzeAll && !SM.isInMainFile(SL)) {
|
||||
if (SL.isInvalid() || SM.isInSystemHeader(SL))
|
||||
return AM_None;
|
||||
return Mode & ~AM_Path;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -83,6 +83,19 @@ extern inline void defineStaticVarInExtern() {
|
|||
static int y = 0; // ok
|
||||
}
|
||||
|
||||
// Check behavior of line markers.
|
||||
# 1 "XXX.h" 1
|
||||
inline int useStaticMainFileInLineMarker() { // expected-note 2 {{use 'static' to give inline function 'useStaticMainFileInLineMarker' internal linkage}}
|
||||
staticFunction(); // expected-warning{{static function 'staticFunction' is used in an inline function with external linkage}}
|
||||
return staticVar; // expected-warning{{static variable 'staticVar' is used in an inline function with external linkage}}
|
||||
}
|
||||
# 100 "inline.c" 2
|
||||
|
||||
inline int useStaticMainFileAfterLineMarker() {
|
||||
staticFunction(); // no-warning
|
||||
return staticVar; // no-warning
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -57,4 +57,13 @@ using namespace dont_warn;
|
|||
// cc file.
|
||||
USING_MACRO
|
||||
|
||||
// Check behavior of line markers.
|
||||
namespace warn_header_with_line_marker {}
|
||||
# 1 "XXX.h" 1
|
||||
using namespace warn_header_with_line_marker; // expected-warning {{using namespace directive in global context in header}}
|
||||
# 70 "warn-using-namespace-in-header.cpp" 2
|
||||
|
||||
namespace nowarn_after_line_marker {}
|
||||
using namespace nowarn_after_line_marker;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -217,7 +217,7 @@ int clang_Location_isFromMainFile(CXSourceLocation location) {
|
|||
|
||||
const SourceManager &SM =
|
||||
*static_cast<const SourceManager*>(location.ptr_data[0]);
|
||||
return SM.isFromMainFile(Loc);
|
||||
return SM.isWrittenInMainFile(Loc);
|
||||
}
|
||||
|
||||
void clang_getExpansionLocation(CXSourceLocation location,
|
||||
|
|
Loading…
Reference in New Issue