const LangOptions &LangOpts;
const PPConditionalDirectiveRecord *PPRec;
EditedSource *Editor;
-
+
+ const bool ForceCommitInSystemHeader;
bool IsCommitable;
SmallVector<Edit, 8> CachedEdits;
Commit(const SourceManager &SM, const LangOptions &LangOpts,
const PPConditionalDirectiveRecord *PPRec = 0)
: SourceMgr(SM), LangOpts(LangOpts), PPRec(PPRec), Editor(0),
- IsCommitable(true) { }
+ ForceCommitInSystemHeader(true), IsCommitable(true) { }
bool isCommitable() const { return IsCommitable; }
const SourceManager &SourceMgr;
const LangOptions &LangOpts;
const PPConditionalDirectiveRecord *PPRec;
+ const bool ForceCommitInSystemHeader;
struct FileEdit {
StringRef Text;
public:
EditedSource(const SourceManager &SM, const LangOptions &LangOpts,
- const PPConditionalDirectiveRecord *PPRec = 0)
+ const PPConditionalDirectiveRecord *PPRec = 0,
+ const bool FCommitInSystemHeader = true)
: SourceMgr(SM), LangOpts(LangOpts), PPRec(PPRec),
+ ForceCommitInSystemHeader(FCommitInSystemHeader),
StrAlloc(/*size=*/512) { }
const SourceManager &getSourceManager() const { return SourceMgr; }
const PPConditionalDirectiveRecord *getPPCondDirectiveRecord() const {
return PPRec;
}
+
+ bool getForceCommitInSystemHeader() const {
+ return ForceCommitInSystemHeader;
+ }
bool canInsertInOffset(SourceLocation OrigLoc, FileOffset Offs);
NSAPIObj.reset(new NSAPI(Context));
Editor.reset(new edit::EditedSource(Context.getSourceManager(),
Context.getLangOpts(),
- PPRec));
+ PPRec, false));
}
virtual bool HandleTopLevelDecl(DeclGroupRef DG) {
}
+static bool
+IsReallyASystemHeader(ASTContext &Ctx, const FileEntry *file, FileID FID) {
+ bool Invalid = false;
+ const SrcMgr::SLocEntry &SEntry =
+ Ctx.getSourceManager().getSLocEntry(FID, &Invalid);
+ if (!Invalid && SEntry.isFile()) {
+ const SrcMgr::FileInfo &FI = SEntry.getFile();
+ if (!FI.hasLineDirectives()) {
+ if (FI.getFileCharacteristic() == SrcMgr::C_ExternCSystem)
+ return true;
+ if (FI.getFileCharacteristic() == SrcMgr::C_System) {
+ // This file is in a system header directory. Continue with commiting change
+ // only if it is a user specified system directory because user put a
+ // .system_framework file in the framework directory.
+ StringRef Directory(file->getDir()->getName());
+ size_t Ix = Directory.rfind(".framework");
+ if (Ix == StringRef::npos)
+ return true;
+ std::string PatchToSystemFramework = Directory.slice(0, Ix+sizeof(".framework"));
+ PatchToSystemFramework += ".system_framework";
+ if (!llvm::sys::fs::exists(PatchToSystemFramework.data()))
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
void ObjCMigrateASTConsumer::HandleTranslationUnit(ASTContext &Ctx) {
TranslationUnitDecl *TU = Ctx.getTranslationUnitDecl();
RewriteBuffer &buf = I->second;
const FileEntry *file = Ctx.getSourceManager().getFileEntryForID(FID);
assert(file);
+ if (IsReallyASystemHeader(Ctx, file, FID))
+ continue;
SmallString<512> newText;
llvm::raw_svector_ostream vecOS(newText);
buf.write(vecOS);
Commit::Commit(EditedSource &Editor)
: SourceMgr(Editor.getSourceManager()), LangOpts(Editor.getLangOpts()),
PPRec(Editor.getPPCondDirectiveRecord()),
- Editor(&Editor), IsCommitable(true) { }
+ Editor(&Editor),
+ ForceCommitInSystemHeader(Editor.getForceCommitInSystemHeader()),
+ IsCommitable(true) { }
bool Commit::insert(SourceLocation loc, StringRef text,
bool afterToken, bool beforePreviousInsertions) {
if (!isAtStartOfMacroExpansion(loc, &loc))
return false;
- if (SM.isInSystemHeader(loc))
+ if (SM.isInSystemHeader(loc) && ForceCommitInSystemHeader)
return false;
std::pair<FileID, unsigned> locInfo = SM.getDecomposedLoc(loc);
if (!isAtEndOfMacroExpansion(loc, &loc))
return false;
- if (SM.isInSystemHeader(loc))
+ if (SM.isInSystemHeader(loc) && ForceCommitInSystemHeader)
return false;
loc = Lexer::getLocForEndOfToken(loc, 0, SourceMgr, LangOpts);
if (range.getBegin().isMacroID() || range.getEnd().isMacroID())
return false;
- if (SM.isInSystemHeader(range.getBegin()) ||
- SM.isInSystemHeader(range.getEnd()))
+ if ((SM.isInSystemHeader(range.getBegin()) ||
+ SM.isInSystemHeader(range.getEnd())) && ForceCommitInSystemHeader)
return false;
if (PPRec && PPRec->rangeIntersectsConditionalDirective(range.getAsRange()))