From 37ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17 Mon Sep 17 00:00:00 2001 From: Argyrios Kyrtzidis Date: Tue, 4 Dec 2012 07:27:05 +0000 Subject: [PATCH] Refactor recording the preprocessor conditional directive regions out of PreprocessingRecord and into its own class, PPConditionalDirectiveRecord. Decoupling allows a client to use the functionality of PPConditionalDirectiveRecord without needing a PreprocessingRecord. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@169229 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Edit/Commit.h | 6 +- include/clang/Edit/EditedSource.h | 10 +- .../clang/Lex/PPConditionalDirectiveRecord.h | 100 +++++++++++++++ include/clang/Lex/PreprocessingRecord.h | 65 +--------- include/clang/Lex/Preprocessor.h | 2 +- include/clang/Lex/PreprocessorOptions.h | 5 - lib/ARCMigrate/ObjCMT.cpp | 19 +-- lib/Edit/Commit.cpp | 4 +- lib/Frontend/CompilerInstance.cpp | 2 +- lib/Lex/PPConditionalDirectiveRecord.cpp | 118 ++++++++++++++++++ lib/Lex/PreprocessingRecord.cpp | 101 +-------------- lib/Lex/Preprocessor.cpp | 5 +- lib/Serialization/ASTReader.cpp | 4 +- ...p => PPConditionalDirectiveRecordTest.cpp} | 45 +++---- 14 files changed, 272 insertions(+), 214 deletions(-) create mode 100644 include/clang/Lex/PPConditionalDirectiveRecord.h create mode 100644 lib/Lex/PPConditionalDirectiveRecord.cpp rename unittests/Lex/{PreprocessingRecordTest.cpp => PPConditionalDirectiveRecordTest.cpp} (75%) diff --git a/include/clang/Edit/Commit.h b/include/clang/Edit/Commit.h index aaf6b18384..610112a716 100644 --- a/include/clang/Edit/Commit.h +++ b/include/clang/Edit/Commit.h @@ -16,7 +16,7 @@ namespace clang { class LangOptions; - class PreprocessingRecord; + class PPConditionalDirectiveRecord; namespace edit { class EditedSource; @@ -46,7 +46,7 @@ public: private: const SourceManager &SourceMgr; const LangOptions &LangOpts; - const PreprocessingRecord *PPRec; + const PPConditionalDirectiveRecord *PPRec; EditedSource *Editor; bool IsCommitable; @@ -55,7 +55,7 @@ private: public: explicit Commit(EditedSource &Editor); Commit(const SourceManager &SM, const LangOptions &LangOpts, - const PreprocessingRecord *PPRec = 0) + const PPConditionalDirectiveRecord *PPRec = 0) : SourceMgr(SM), LangOpts(LangOpts), PPRec(PPRec), Editor(0), IsCommitable(true) { } diff --git a/include/clang/Edit/EditedSource.h b/include/clang/Edit/EditedSource.h index c685753e4b..aae054605e 100644 --- a/include/clang/Edit/EditedSource.h +++ b/include/clang/Edit/EditedSource.h @@ -18,7 +18,7 @@ namespace clang { class LangOptions; - class PreprocessingRecord; + class PPConditionalDirectiveRecord; namespace edit { class Commit; @@ -27,7 +27,7 @@ namespace edit { class EditedSource { const SourceManager &SourceMgr; const LangOptions &LangOpts; - const PreprocessingRecord *PPRec; + const PPConditionalDirectiveRecord *PPRec; struct FileEdit { StringRef Text; @@ -45,13 +45,15 @@ class EditedSource { public: EditedSource(const SourceManager &SM, const LangOptions &LangOpts, - const PreprocessingRecord *PPRec = 0) + const PPConditionalDirectiveRecord *PPRec = 0) : SourceMgr(SM), LangOpts(LangOpts), PPRec(PPRec), StrAlloc(/*size=*/512) { } const SourceManager &getSourceManager() const { return SourceMgr; } const LangOptions &getLangOpts() const { return LangOpts; } - const PreprocessingRecord *getPreprocessingRecord() const { return PPRec; } + const PPConditionalDirectiveRecord *getPPCondDirectiveRecord() const { + return PPRec; + } bool canInsertInOffset(SourceLocation OrigLoc, FileOffset Offs); diff --git a/include/clang/Lex/PPConditionalDirectiveRecord.h b/include/clang/Lex/PPConditionalDirectiveRecord.h new file mode 100644 index 0000000000..36e6216beb --- /dev/null +++ b/include/clang/Lex/PPConditionalDirectiveRecord.h @@ -0,0 +1,100 @@ +//===--- PPConditionalDirectiveRecord.h - Preprocessing Directives-*- C++ -*-=// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the PPConditionalDirectiveRecord class, which maintains +// a record of conditional directive regions. +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_CLANG_LEX_PPCONDITIONALDIRECTIVERECORD_H +#define LLVM_CLANG_LEX_PPCONDITIONALDIRECTIVERECORD_H + +#include "clang/Lex/PPCallbacks.h" +#include "clang/Basic/SourceLocation.h" +#include "llvm/ADT/SmallVector.h" +#include + +namespace clang { + +/// \brief Records preprocessor conditional directive regions and allows +/// querying in which region source locations belong to. +class PPConditionalDirectiveRecord : public PPCallbacks { + SourceManager &SourceMgr; + + SmallVector CondDirectiveStack; + + class CondDirectiveLoc { + SourceLocation Loc; + SourceLocation RegionLoc; + + public: + CondDirectiveLoc(SourceLocation Loc, SourceLocation RegionLoc) + : Loc(Loc), RegionLoc(RegionLoc) {} + + SourceLocation getLoc() const { return Loc; } + SourceLocation getRegionLoc() const { return RegionLoc; } + + class Comp { + SourceManager &SM; + public: + explicit Comp(SourceManager &SM) : SM(SM) {} + bool operator()(const CondDirectiveLoc &LHS, + const CondDirectiveLoc &RHS) { + return SM.isBeforeInTranslationUnit(LHS.getLoc(), RHS.getLoc()); + } + bool operator()(const CondDirectiveLoc &LHS, SourceLocation RHS) { + return SM.isBeforeInTranslationUnit(LHS.getLoc(), RHS); + } + bool operator()(SourceLocation LHS, const CondDirectiveLoc &RHS) { + return SM.isBeforeInTranslationUnit(LHS, RHS.getLoc()); + } + }; + }; + + typedef std::vector CondDirectiveLocsTy; + /// \brief The locations of conditional directives in source order. + CondDirectiveLocsTy CondDirectiveLocs; + + void addCondDirectiveLoc(CondDirectiveLoc DirLoc); + +public: + /// \brief Construct a new preprocessing record. + explicit PPConditionalDirectiveRecord(SourceManager &SM); + + size_t getTotalMemory() const; + + SourceManager &getSourceManager() const { return SourceMgr; } + + /// \brief Returns true if the given range intersects with a conditional + /// directive. if a \#if/\#endif block is fully contained within the range, + /// this function will return false. + bool rangeIntersectsConditionalDirective(SourceRange Range) const; + + /// \brief Returns true if the given locations are in different regions, + /// separated by conditional directive blocks. + bool areInDifferentConditionalDirectiveRegion(SourceLocation LHS, + SourceLocation RHS) const { + return findConditionalDirectiveRegionLoc(LHS) != + findConditionalDirectiveRegionLoc(RHS); + } + + SourceLocation findConditionalDirectiveRegionLoc(SourceLocation Loc) const; + +private: + virtual void If(SourceLocation Loc, SourceRange ConditionRange); + virtual void Elif(SourceLocation Loc, SourceRange ConditionRange, + SourceLocation IfLoc); + virtual void Ifdef(SourceLocation Loc, const Token &MacroNameTok); + virtual void Ifndef(SourceLocation Loc, const Token &MacroNameTok); + virtual void Else(SourceLocation Loc, SourceLocation IfLoc); + virtual void Endif(SourceLocation Loc, SourceLocation IfLoc); +}; + +} // end namespace clang + +#endif // LLVM_CLANG_LEX_PPCONDITIONALDIRECTIVERECORD_H diff --git a/include/clang/Lex/PreprocessingRecord.h b/include/clang/Lex/PreprocessingRecord.h index 6189ee23ba..97bb33848d 100644 --- a/include/clang/Lex/PreprocessingRecord.h +++ b/include/clang/Lex/PreprocessingRecord.h @@ -303,44 +303,6 @@ namespace clang { /// and are referenced by the iterator using negative indices. std::vector LoadedPreprocessedEntities; - bool RecordCondDirectives; - SmallVector CondDirectiveStack; - - class CondDirectiveLoc { - SourceLocation Loc; - SourceLocation RegionLoc; - - public: - CondDirectiveLoc(SourceLocation Loc, SourceLocation RegionLoc) - : Loc(Loc), RegionLoc(RegionLoc) {} - - SourceLocation getLoc() const { return Loc; } - SourceLocation getRegionLoc() const { return RegionLoc; } - - class Comp { - SourceManager &SM; - public: - explicit Comp(SourceManager &SM) : SM(SM) {} - bool operator()(const CondDirectiveLoc &LHS, - const CondDirectiveLoc &RHS) { - return SM.isBeforeInTranslationUnit(LHS.getLoc(), RHS.getLoc()); - } - bool operator()(const CondDirectiveLoc &LHS, SourceLocation RHS) { - return SM.isBeforeInTranslationUnit(LHS.getLoc(), RHS); - } - bool operator()(SourceLocation LHS, const CondDirectiveLoc &RHS) { - return SM.isBeforeInTranslationUnit(LHS, RHS.getLoc()); - } - }; - }; - - typedef std::vector CondDirectiveLocsTy; - /// \brief The locations of conditional directives in source order. - CondDirectiveLocsTy CondDirectiveLocs; - - void addCondDirectiveLoc(CondDirectiveLoc DirLoc); - SourceLocation findCondDirectiveRegionLoc(SourceLocation Loc) const; - /// \brief Global (loaded or local) ID for a preprocessed entity. /// Negative values are used to indicate preprocessed entities /// loaded from the external source while non-negative values are used to @@ -398,7 +360,7 @@ namespace clang { public: /// \brief Construct a new preprocessing record. - PreprocessingRecord(SourceManager &SM, bool RecordConditionalDirectives); + explicit PreprocessingRecord(SourceManager &SM); /// \brief Allocate memory in the preprocessing record. void *Allocate(unsigned Size, unsigned Align = 8) { @@ -582,24 +544,6 @@ namespace clang { /// \brief Add a new preprocessed entity to this record. PPEntityID addPreprocessedEntity(PreprocessedEntity *Entity); - /// \brief Returns true if this PreprocessingRecord is keeping track of - /// conditional directives locations. - bool isRecordingConditionalDirectives() const { - return RecordCondDirectives; - } - - /// \brief Returns true if the given range intersects with a conditional - /// directive. if a \#if/\#endif block is fully contained within the range, - /// this function will return false. - bool rangeIntersectsConditionalDirective(SourceRange Range) const; - - /// \brief Returns true if the given locations are in different regions, - /// separated by conditional directive blocks. - bool areInDifferentConditionalDirectiveRegion(SourceLocation LHS, - SourceLocation RHS) const { - return findCondDirectiveRegionLoc(LHS) != findCondDirectiveRegionLoc(RHS); - } - /// \brief Set the external source for preprocessed entities. void SetExternalSource(ExternalPreprocessingRecordSource &Source); @@ -626,13 +570,6 @@ namespace clang { StringRef SearchPath, StringRef RelativePath, const Module *Imported); - virtual void If(SourceLocation Loc, SourceRange ConditionRange); - virtual void Elif(SourceLocation Loc, SourceRange ConditionRange, - SourceLocation IfLoc); - virtual void Ifdef(SourceLocation Loc, const Token &MacroNameTok); - virtual void Ifndef(SourceLocation Loc, const Token &MacroNameTok); - virtual void Else(SourceLocation Loc, SourceLocation IfLoc); - virtual void Endif(SourceLocation Loc, SourceLocation IfLoc); /// \brief Cached result of the last \see getPreprocessedEntitiesInRange /// query. diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h index 7e5c66cbd8..658e187156 100644 --- a/include/clang/Lex/Preprocessor.h +++ b/include/clang/Lex/Preprocessor.h @@ -611,7 +611,7 @@ public: /// \brief Create a new preprocessing record, which will keep track of /// all macro expansions, macro definitions, etc. - void createPreprocessingRecord(bool RecordConditionalDirectives); + void createPreprocessingRecord(); /// EnterMainSourceFile - Enter the specified FileID as the main source file, /// which implicitly adds the builtin defines etc. diff --git a/include/clang/Lex/PreprocessorOptions.h b/include/clang/Lex/PreprocessorOptions.h index a670267f02..ba61eb283a 100644 --- a/include/clang/Lex/PreprocessorOptions.h +++ b/include/clang/Lex/PreprocessorOptions.h @@ -53,10 +53,6 @@ public: unsigned DetailedRecord : 1; /// Whether we should maintain a detailed /// record of all macro definitions and /// expansions. - unsigned DetailedRecordConditionalDirectives : 1; /// Whether in the - /// preprocessing record we should also keep - /// track of locations of conditional directives - /// in non-system files. /// The implicit PCH included at the start of the translation unit, or empty. std::string ImplicitPCHInclude; @@ -179,7 +175,6 @@ public: public: PreprocessorOptions() : UsePredefines(true), DetailedRecord(false), - DetailedRecordConditionalDirectives(false), DisablePCHValidation(false), AllowPCHWithCompilerErrors(false), DumpDeserializedPCHDecls(false), diff --git a/lib/ARCMigrate/ObjCMT.cpp b/lib/ARCMigrate/ObjCMT.cpp index dfe14e2b5d..58499572a8 100644 --- a/lib/ARCMigrate/ObjCMT.cpp +++ b/lib/ARCMigrate/ObjCMT.cpp @@ -20,6 +20,7 @@ #include "clang/Edit/EditsReceiver.h" #include "clang/Rewrite/Core/Rewriter.h" #include "clang/Lex/Preprocessor.h" +#include "clang/Lex/PPConditionalDirectiveRecord.h" #include "clang/Basic/FileManager.h" #include "llvm/ADT/SmallString.h" @@ -39,7 +40,7 @@ public: llvm::OwningPtr Editor; FileRemapper &Remapper; FileManager &FileMgr; - const PreprocessingRecord *PPRec; + const PPConditionalDirectiveRecord *PPRec; bool IsOutputFile; ObjCMigrateASTConsumer(StringRef migrateDir, @@ -47,7 +48,7 @@ public: bool migrateSubscripting, FileRemapper &remapper, FileManager &fileMgr, - const PreprocessingRecord *PPRec, + const PPConditionalDirectiveRecord *PPRec, bool isOutputFile = false) : MigrateDir(migrateDir), MigrateLiterals(migrateLiterals), @@ -93,6 +94,9 @@ ObjCMigrateAction::ObjCMigrateAction(FrontendAction *WrappedAction, ASTConsumer *ObjCMigrateAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { + PPConditionalDirectiveRecord * + PPRec = new PPConditionalDirectiveRecord(CompInst->getSourceManager()); + CompInst->getPreprocessor().addPPCallbacks(PPRec); ASTConsumer * WrappedConsumer = WrapperFrontendAction::CreateASTConsumer(CI, InFile); ASTConsumer *MTConsumer = new ObjCMigrateASTConsumer(MigrateDir, @@ -100,7 +104,7 @@ ASTConsumer *ObjCMigrateAction::CreateASTConsumer(CompilerInstance &CI, MigrateSubscripting, Remapper, CompInst->getFileManager(), - CompInst->getPreprocessor().getPreprocessingRecord()); + PPRec); ASTConsumer *Consumers[] = { MTConsumer, WrappedConsumer }; return new MultiplexConsumer(Consumers); } @@ -110,8 +114,6 @@ bool ObjCMigrateAction::BeginInvocation(CompilerInstance &CI) { /*ignoreIfFilesChanges=*/true); CompInst = &CI; CI.getDiagnostics().setIgnoreAllWarnings(true); - CI.getPreprocessorOpts().DetailedRecord = true; - CI.getPreprocessorOpts().DetailedRecordConditionalDirectives = true; return true; } @@ -211,18 +213,19 @@ void ObjCMigrateASTConsumer::HandleTranslationUnit(ASTContext &Ctx) { bool MigrateSourceAction::BeginInvocation(CompilerInstance &CI) { CI.getDiagnostics().setIgnoreAllWarnings(true); - CI.getPreprocessorOpts().DetailedRecord = true; - CI.getPreprocessorOpts().DetailedRecordConditionalDirectives = true; return true; } ASTConsumer *MigrateSourceAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { + PPConditionalDirectiveRecord * + PPRec = new PPConditionalDirectiveRecord(CI.getSourceManager()); + CI.getPreprocessor().addPPCallbacks(PPRec); return new ObjCMigrateASTConsumer(CI.getFrontendOpts().OutputFile, /*MigrateLiterals=*/true, /*MigrateSubscripting=*/true, Remapper, CI.getFileManager(), - CI.getPreprocessor().getPreprocessingRecord(), + PPRec, /*isOutputFile=*/true); } diff --git a/lib/Edit/Commit.cpp b/lib/Edit/Commit.cpp index 41c72e42e6..3a9719ada0 100644 --- a/lib/Edit/Commit.cpp +++ b/lib/Edit/Commit.cpp @@ -10,7 +10,7 @@ #include "clang/Edit/Commit.h" #include "clang/Edit/EditedSource.h" #include "clang/Lex/Lexer.h" -#include "clang/Lex/PreprocessingRecord.h" +#include "clang/Lex/PPConditionalDirectiveRecord.h" #include "clang/Basic/SourceManager.h" using namespace clang; @@ -37,7 +37,7 @@ CharSourceRange Commit::Edit::getInsertFromRange(SourceManager &SM) const { Commit::Commit(EditedSource &Editor) : SourceMgr(Editor.getSourceManager()), LangOpts(Editor.getLangOpts()), - PPRec(Editor.getPreprocessingRecord()), + PPRec(Editor.getPPCondDirectiveRecord()), Editor(&Editor), IsCommitable(true) { } bool Commit::insert(SourceLocation loc, StringRef text, diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp index d481ebf511..e5c1512657 100644 --- a/lib/Frontend/CompilerInstance.cpp +++ b/lib/Frontend/CompilerInstance.cpp @@ -260,7 +260,7 @@ void CompilerInstance::createPreprocessor() { } if (PPOpts.DetailedRecord) - PP->createPreprocessingRecord(PPOpts.DetailedRecordConditionalDirectives); + PP->createPreprocessingRecord(); InitializePreprocessor(*PP, PPOpts, getHeaderSearchOpts(), getFrontendOpts()); diff --git a/lib/Lex/PPConditionalDirectiveRecord.cpp b/lib/Lex/PPConditionalDirectiveRecord.cpp new file mode 100644 index 0000000000..edcde871a0 --- /dev/null +++ b/lib/Lex/PPConditionalDirectiveRecord.cpp @@ -0,0 +1,118 @@ +//===--- PPConditionalDirectiveRecord.h - Preprocessing Directives-*- C++ -*-=// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the PPConditionalDirectiveRecord class, which maintains +// a record of conditional directive regions. +// +//===----------------------------------------------------------------------===// +#include "clang/Lex/PPConditionalDirectiveRecord.h" +#include "llvm/Support/Capacity.h" + +using namespace clang; + +PPConditionalDirectiveRecord::PPConditionalDirectiveRecord(SourceManager &SM) + : SourceMgr(SM) { + CondDirectiveStack.push_back(SourceLocation()); +} + +bool PPConditionalDirectiveRecord::rangeIntersectsConditionalDirective( + SourceRange Range) const { + if (Range.isInvalid()) + return false; + + CondDirectiveLocsTy::const_iterator + low = std::lower_bound(CondDirectiveLocs.begin(), CondDirectiveLocs.end(), + Range.getBegin(), CondDirectiveLoc::Comp(SourceMgr)); + if (low == CondDirectiveLocs.end()) + return false; + + if (SourceMgr.isBeforeInTranslationUnit(Range.getEnd(), low->getLoc())) + return false; + + CondDirectiveLocsTy::const_iterator + upp = std::upper_bound(low, CondDirectiveLocs.end(), + Range.getEnd(), CondDirectiveLoc::Comp(SourceMgr)); + SourceLocation uppRegion; + if (upp != CondDirectiveLocs.end()) + uppRegion = upp->getRegionLoc(); + + return low->getRegionLoc() != uppRegion; +} + +SourceLocation PPConditionalDirectiveRecord::findConditionalDirectiveRegionLoc( + SourceLocation Loc) const { + if (Loc.isInvalid()) + return SourceLocation(); + if (CondDirectiveLocs.empty()) + return SourceLocation(); + + if (SourceMgr.isBeforeInTranslationUnit(CondDirectiveLocs.back().getLoc(), + Loc)) + return CondDirectiveStack.back(); + + CondDirectiveLocsTy::const_iterator + low = std::lower_bound(CondDirectiveLocs.begin(), CondDirectiveLocs.end(), + Loc, CondDirectiveLoc::Comp(SourceMgr)); + assert(low != CondDirectiveLocs.end()); + return low->getRegionLoc(); +} + +void PPConditionalDirectiveRecord::addCondDirectiveLoc( + CondDirectiveLoc DirLoc) { + // Ignore directives in system headers. + if (SourceMgr.isInSystemHeader(DirLoc.getLoc())) + return; + + assert(CondDirectiveLocs.empty() || + SourceMgr.isBeforeInTranslationUnit(CondDirectiveLocs.back().getLoc(), + DirLoc.getLoc())); + CondDirectiveLocs.push_back(DirLoc); +} + +void PPConditionalDirectiveRecord::If(SourceLocation Loc, + SourceRange ConditionRange) { + addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back())); + CondDirectiveStack.push_back(Loc); +} + +void PPConditionalDirectiveRecord::Ifdef(SourceLocation Loc, + const Token &MacroNameTok) { + addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back())); + CondDirectiveStack.push_back(Loc); +} + +void PPConditionalDirectiveRecord::Ifndef(SourceLocation Loc, + const Token &MacroNameTok) { + addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back())); + CondDirectiveStack.push_back(Loc); +} + +void PPConditionalDirectiveRecord::Elif(SourceLocation Loc, + SourceRange ConditionRange, + SourceLocation IfLoc) { + addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back())); + CondDirectiveStack.back() = Loc; +} + +void PPConditionalDirectiveRecord::Else(SourceLocation Loc, + SourceLocation IfLoc) { + addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back())); + CondDirectiveStack.back() = Loc; +} + +void PPConditionalDirectiveRecord::Endif(SourceLocation Loc, + SourceLocation IfLoc) { + addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back())); + assert(!CondDirectiveStack.empty()); + CondDirectiveStack.pop_back(); +} + +size_t PPConditionalDirectiveRecord::getTotalMemory() const { + return llvm::capacity_in_bytes(CondDirectiveLocs); +} diff --git a/lib/Lex/PreprocessingRecord.cpp b/lib/Lex/PreprocessingRecord.cpp index 0376e449ae..5f1353c86e 100644 --- a/lib/Lex/PreprocessingRecord.cpp +++ b/lib/Lex/PreprocessingRecord.cpp @@ -38,14 +38,9 @@ InclusionDirective::InclusionDirective(PreprocessingRecord &PPRec, this->FileName = StringRef(Memory, FileName.size()); } -PreprocessingRecord::PreprocessingRecord(SourceManager &SM, - bool RecordConditionalDirectives) +PreprocessingRecord::PreprocessingRecord(SourceManager &SM) : SourceMgr(SM), - RecordCondDirectives(RecordConditionalDirectives), - ExternalSource(0) -{ - if (RecordCondDirectives) - CondDirectiveStack.push_back(SourceLocation()); + ExternalSource(0) { } /// \brief Returns a pair of [Begin, End) iterators of preprocessed entities @@ -438,98 +433,6 @@ void PreprocessingRecord::InclusionDirective( addPreprocessedEntity(ID); } -bool PreprocessingRecord::rangeIntersectsConditionalDirective( - SourceRange Range) const { - if (Range.isInvalid()) - return false; - - CondDirectiveLocsTy::const_iterator - low = std::lower_bound(CondDirectiveLocs.begin(), CondDirectiveLocs.end(), - Range.getBegin(), CondDirectiveLoc::Comp(SourceMgr)); - if (low == CondDirectiveLocs.end()) - return false; - - if (SourceMgr.isBeforeInTranslationUnit(Range.getEnd(), low->getLoc())) - return false; - - CondDirectiveLocsTy::const_iterator - upp = std::upper_bound(low, CondDirectiveLocs.end(), - Range.getEnd(), CondDirectiveLoc::Comp(SourceMgr)); - SourceLocation uppRegion; - if (upp != CondDirectiveLocs.end()) - uppRegion = upp->getRegionLoc(); - - return low->getRegionLoc() != uppRegion; -} - -SourceLocation -PreprocessingRecord::findCondDirectiveRegionLoc(SourceLocation Loc) const { - if (Loc.isInvalid()) - return SourceLocation(); - - CondDirectiveLocsTy::const_iterator - low = std::lower_bound(CondDirectiveLocs.begin(), CondDirectiveLocs.end(), - Loc, CondDirectiveLoc::Comp(SourceMgr)); - if (low == CondDirectiveLocs.end()) - return SourceLocation(); - return low->getRegionLoc(); -} - -void PreprocessingRecord::addCondDirectiveLoc(CondDirectiveLoc DirLoc) { - // Ignore directives in system headers. - if (SourceMgr.isInSystemHeader(DirLoc.getLoc())) - return; - - assert(CondDirectiveLocs.empty() || - SourceMgr.isBeforeInTranslationUnit(CondDirectiveLocs.back().getLoc(), - DirLoc.getLoc())); - CondDirectiveLocs.push_back(DirLoc); -} - -void PreprocessingRecord::If(SourceLocation Loc, SourceRange ConditionRange) { - if (RecordCondDirectives) { - addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back())); - CondDirectiveStack.push_back(Loc); - } -} - -void PreprocessingRecord::Ifdef(SourceLocation Loc, const Token &MacroNameTok) { - if (RecordCondDirectives) { - addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back())); - CondDirectiveStack.push_back(Loc); - } -} - -void PreprocessingRecord::Ifndef(SourceLocation Loc,const Token &MacroNameTok) { - if (RecordCondDirectives) { - addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back())); - CondDirectiveStack.push_back(Loc); - } -} - -void PreprocessingRecord::Elif(SourceLocation Loc, SourceRange ConditionRange, - SourceLocation IfLoc) { - if (RecordCondDirectives) { - addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back())); - CondDirectiveStack.back() = Loc; - } -} - -void PreprocessingRecord::Else(SourceLocation Loc, SourceLocation IfLoc) { - if (RecordCondDirectives) { - addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back())); - CondDirectiveStack.back() = Loc; - } -} - -void PreprocessingRecord::Endif(SourceLocation Loc, SourceLocation IfLoc) { - if (RecordCondDirectives) { - addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back())); - assert(!CondDirectiveStack.empty()); - CondDirectiveStack.pop_back(); - } -} - size_t PreprocessingRecord::getTotalMemory() const { return BumpAlloc.getTotalMemory() + llvm::capacity_in_bytes(MacroDefinitions) diff --git a/lib/Lex/Preprocessor.cpp b/lib/Lex/Preprocessor.cpp index 9488584105..b5fb89f091 100644 --- a/lib/Lex/Preprocessor.cpp +++ b/lib/Lex/Preprocessor.cpp @@ -765,11 +765,10 @@ CommentHandler::~CommentHandler() { } CodeCompletionHandler::~CodeCompletionHandler() { } -void Preprocessor::createPreprocessingRecord(bool RecordConditionalDirectives) { +void Preprocessor::createPreprocessingRecord() { if (Record) return; - Record = new PreprocessingRecord(getSourceManager(), - RecordConditionalDirectives); + Record = new PreprocessingRecord(getSourceManager()); addPPCallbacks(Record); } diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index 908d8c573c..bc08f3f5f6 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -1907,7 +1907,7 @@ bool ASTReader::ReadASTBlock(ModuleFile &F) { = F.PreprocessorDetailCursor.GetCurrentBitNo(); if (!PP.getPreprocessingRecord()) - PP.createPreprocessingRecord(/*RecordConditionalDirectives=*/false); + PP.createPreprocessingRecord(); if (!PP.getPreprocessingRecord()->getExternalSource()) PP.getPreprocessingRecord()->SetExternalSource(*this); break; @@ -2365,7 +2365,7 @@ bool ASTReader::ReadASTBlock(ModuleFile &F) { unsigned StartingID; if (!PP.getPreprocessingRecord()) - PP.createPreprocessingRecord(/*RecordConditionalDirectives=*/false); + PP.createPreprocessingRecord(); if (!PP.getPreprocessingRecord()->getExternalSource()) PP.getPreprocessingRecord()->SetExternalSource(*this); StartingID diff --git a/unittests/Lex/PreprocessingRecordTest.cpp b/unittests/Lex/PPConditionalDirectiveRecordTest.cpp similarity index 75% rename from unittests/Lex/PreprocessingRecordTest.cpp rename to unittests/Lex/PPConditionalDirectiveRecordTest.cpp index 2bf00483c0..21271f9b2f 100644 --- a/unittests/Lex/PreprocessingRecordTest.cpp +++ b/unittests/Lex/PPConditionalDirectiveRecordTest.cpp @@ -1,4 +1,4 @@ -//===- unittests/Lex/PreprocessingRecordTest.cpp - PreprocessingRecord tests =// +//===- unittests/Lex/PPConditionalDirectiveRecordTest.cpp-PP directive tests =// // // The LLVM Compiler Infrastructure // @@ -19,7 +19,7 @@ #include "clang/Lex/HeaderSearchOptions.h" #include "clang/Lex/Preprocessor.h" #include "clang/Lex/PreprocessorOptions.h" -#include "clang/Lex/PreprocessingRecord.h" +#include "clang/Lex/PPConditionalDirectiveRecord.h" #include "llvm/Config/config.h" #include "gtest/gtest.h" @@ -30,9 +30,9 @@ using namespace clang; namespace { // The test fixture. -class PreprocessingRecordTest : public ::testing::Test { +class PPConditionalDirectiveRecordTest : public ::testing::Test { protected: - PreprocessingRecordTest() + PPConditionalDirectiveRecordTest() : FileMgr(FileMgrOpts), DiagID(new DiagnosticIDs()), Diags(DiagID, new DiagnosticOptions, new IgnoringDiagConsumer()), @@ -62,7 +62,7 @@ class VoidModuleLoader : public ModuleLoader { } }; -TEST_F(PreprocessingRecordTest, PPRecAPI) { +TEST_F(PPConditionalDirectiveRecordTest, PPRecAPI) { const char *source = "0 1\n" "#if 1\n" @@ -93,7 +93,9 @@ TEST_F(PreprocessingRecordTest, PPRecAPI) { /*IILookup =*/ 0, /*OwnsHeaderSearch =*/false, /*DelayInitialization =*/ false); - PP.createPreprocessingRecord(true); + PPConditionalDirectiveRecord * + PPRec = new PPConditionalDirectiveRecord(SourceMgr); + PP.addPPCallbacks(PPRec); PP.EnterMainSourceFile(); std::vector toks; @@ -108,37 +110,36 @@ TEST_F(PreprocessingRecordTest, PPRecAPI) { // Make sure we got the tokens that we expected. ASSERT_EQ(10U, toks.size()); - PreprocessingRecord &PPRec = *PP.getPreprocessingRecord(); - EXPECT_FALSE(PPRec.rangeIntersectsConditionalDirective( + EXPECT_FALSE(PPRec->rangeIntersectsConditionalDirective( SourceRange(toks[0].getLocation(), toks[1].getLocation()))); - EXPECT_TRUE(PPRec.rangeIntersectsConditionalDirective( + EXPECT_TRUE(PPRec->rangeIntersectsConditionalDirective( SourceRange(toks[0].getLocation(), toks[2].getLocation()))); - EXPECT_FALSE(PPRec.rangeIntersectsConditionalDirective( + EXPECT_FALSE(PPRec->rangeIntersectsConditionalDirective( SourceRange(toks[3].getLocation(), toks[4].getLocation()))); - EXPECT_TRUE(PPRec.rangeIntersectsConditionalDirective( + EXPECT_TRUE(PPRec->rangeIntersectsConditionalDirective( SourceRange(toks[1].getLocation(), toks[5].getLocation()))); - EXPECT_TRUE(PPRec.rangeIntersectsConditionalDirective( + EXPECT_TRUE(PPRec->rangeIntersectsConditionalDirective( SourceRange(toks[2].getLocation(), toks[6].getLocation()))); - EXPECT_FALSE(PPRec.rangeIntersectsConditionalDirective( + EXPECT_FALSE(PPRec->rangeIntersectsConditionalDirective( SourceRange(toks[2].getLocation(), toks[5].getLocation()))); - EXPECT_FALSE(PPRec.rangeIntersectsConditionalDirective( + EXPECT_FALSE(PPRec->rangeIntersectsConditionalDirective( SourceRange(toks[0].getLocation(), toks[6].getLocation()))); - EXPECT_TRUE(PPRec.rangeIntersectsConditionalDirective( + EXPECT_TRUE(PPRec->rangeIntersectsConditionalDirective( SourceRange(toks[2].getLocation(), toks[8].getLocation()))); - EXPECT_FALSE(PPRec.rangeIntersectsConditionalDirective( + EXPECT_FALSE(PPRec->rangeIntersectsConditionalDirective( SourceRange(toks[0].getLocation(), toks[9].getLocation()))); - EXPECT_TRUE(PPRec.areInDifferentConditionalDirectiveRegion( + EXPECT_TRUE(PPRec->areInDifferentConditionalDirectiveRegion( toks[0].getLocation(), toks[2].getLocation())); - EXPECT_FALSE(PPRec.areInDifferentConditionalDirectiveRegion( + EXPECT_FALSE(PPRec->areInDifferentConditionalDirectiveRegion( toks[3].getLocation(), toks[4].getLocation())); - EXPECT_TRUE(PPRec.areInDifferentConditionalDirectiveRegion( + EXPECT_TRUE(PPRec->areInDifferentConditionalDirectiveRegion( toks[1].getLocation(), toks[5].getLocation())); - EXPECT_TRUE(PPRec.areInDifferentConditionalDirectiveRegion( + EXPECT_TRUE(PPRec->areInDifferentConditionalDirectiveRegion( toks[2].getLocation(), toks[0].getLocation())); - EXPECT_FALSE(PPRec.areInDifferentConditionalDirectiveRegion( + EXPECT_FALSE(PPRec->areInDifferentConditionalDirectiveRegion( toks[4].getLocation(), toks[3].getLocation())); - EXPECT_TRUE(PPRec.areInDifferentConditionalDirectiveRegion( + EXPECT_TRUE(PPRec->areInDifferentConditionalDirectiveRegion( toks[5].getLocation(), toks[1].getLocation())); } -- 2.40.0