From: Eli Friedman Date: Thu, 22 Aug 2013 00:27:10 +0000 (+0000) Subject: Split isFromMainFile into two functions. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=24146975f1af8c1b4b14e8545f218129d0e7dfeb;p=clang 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 --- diff --git a/include/clang/Basic/SourceManager.h b/include/clang/Basic/SourceManager.h index 9fc4885220..c2bf2c5da0 100644 --- a/include/clang/Basic/SourceManager.h +++ b/include/clang/Basic/SourceManager.h @@ -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(); } diff --git a/lib/Frontend/VerifyDiagnosticConsumer.cpp b/lib/Frontend/VerifyDiagnosticConsumer.cpp index efe6005ed7..f5555291a8 100644 --- a/lib/Frontend/VerifyDiagnosticConsumer.cpp +++ b/lib/Frontend/VerifyDiagnosticConsumer.cpp @@ -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))); diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp index ef0cbd656f..86d6ad9eb8 100644 --- a/lib/Lex/PPDirectives.cpp +++ b/lib/Lex/PPDirectives.cpp @@ -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); diff --git a/lib/Rewrite/Frontend/RewriteMacros.cpp b/lib/Rewrite/Frontend/RewriteMacros.cpp index 3c1d2e1190..4f6a93f7e0 100644 --- a/lib/Rewrite/Frontend/RewriteMacros.cpp +++ b/lib/Rewrite/Frontend/RewriteMacros.cpp @@ -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; } diff --git a/lib/Rewrite/Frontend/RewriteModernObjC.cpp b/lib/Rewrite/Frontend/RewriteModernObjC.cpp index 546f9217ae..80b6b4110c 100644 --- a/lib/Rewrite/Frontend/RewriteModernObjC.cpp +++ b/lib/Rewrite/Frontend/RewriteModernObjC.cpp @@ -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); } diff --git a/lib/Rewrite/Frontend/RewriteObjC.cpp b/lib/Rewrite/Frontend/RewriteObjC.cpp index 316009fc51..d265c51f5b 100644 --- a/lib/Rewrite/Frontend/RewriteObjC.cpp +++ b/lib/Rewrite/Frontend/RewriteObjC.cpp @@ -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); } diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp index 26f26316d1..6cc596cec1 100644 --- a/lib/Sema/Sema.cpp +++ b/lib/Sema/Sema.cpp @@ -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 diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index 6fd3aa1fd4..5e0acc0787 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -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; } } diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 528396d559..6ebfb57974 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -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); } diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 2dbc82dc7a..1c5e24e278 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(D); - bool DowngradeWarning = S.getSourceManager().isFromMainFile(Loc); + bool DowngradeWarning = S.getSourceManager().isInMainFile(Loc); if (!DowngradeWarning && UsedFn) DowngradeWarning = UsedFn->isInlined() || UsedFn->hasAttr(); diff --git a/lib/StaticAnalyzer/Core/BugReporter.cpp b/lib/StaticAnalyzer/Core/BugReporter.cpp index 2123a45181..1df3053edf 100644 --- a/lib/StaticAnalyzer/Core/BugReporter.cpp +++ b/lib/StaticAnalyzer/Core/BugReporter.cpp @@ -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); diff --git a/lib/StaticAnalyzer/Core/CallEvent.cpp b/lib/StaticAnalyzer/Core/CallEvent.cpp index 9ab6874756..59cdfbb7f9 100644 --- a/lib/StaticAnalyzer/Core/CallEvent.cpp +++ b/lib/StaticAnalyzer/Core/CallEvent.cpp @@ -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()) { diff --git a/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp b/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp index 63dccff374..4fb6523944 100644 --- a/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp +++ b/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp @@ -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; diff --git a/lib/StaticAnalyzer/Core/PathDiagnostic.cpp b/lib/StaticAnalyzer/Core/PathDiagnostic.cpp index 82d8f37105..5f26085cab 100644 --- a/lib/StaticAnalyzer/Core/PathDiagnostic.cpp +++ b/lib/StaticAnalyzer/Core/PathDiagnostic.cpp @@ -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; diff --git a/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp b/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp index abc1e9fc52..9efe99767e 100644 --- a/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp +++ b/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp @@ -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; diff --git a/test/Preprocessor/warn-macro-unused.c b/test/Preprocessor/warn-macro-unused.c index c33aeb5df9..a305cc9966 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 diff --git a/test/Sema/inline.c b/test/Sema/inline.c index 496e282eca..8a3835b71a 100644 --- a/test/Sema/inline.c +++ b/test/Sema/inline.c @@ -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 diff --git a/test/SemaCXX/warn-using-namespace-in-header.cpp b/test/SemaCXX/warn-using-namespace-in-header.cpp index f68b99893a..6b84e6e70a 100644 --- a/test/SemaCXX/warn-using-namespace-in-header.cpp +++ b/test/SemaCXX/warn-using-namespace-in-header.cpp @@ -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 diff --git a/tools/libclang/CXSourceLocation.cpp b/tools/libclang/CXSourceLocation.cpp index 71e425d1f7..a33c9d4f26 100644 --- a/tools/libclang/CXSourceLocation.cpp +++ b/tools/libclang/CXSourceLocation.cpp @@ -217,7 +217,7 @@ int clang_Location_isFromMainFile(CXSourceLocation location) { const SourceManager &SM = *static_cast(location.ptr_data[0]); - return SM.isFromMainFile(Loc); + return SM.isWrittenInMainFile(Loc); } void clang_getExpansionLocation(CXSourceLocation location,