diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Frontend/CompilerInstance.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Lex/PreprocessingRecord.cpp | 98 | ||||
-rw-r--r-- | clang/lib/Lex/Preprocessor.cpp | 5 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReader.cpp | 4 |
4 files changed, 102 insertions, 7 deletions
diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp index bf3e3a8908d..c6838be7af0 100644 --- a/clang/lib/Frontend/CompilerInstance.cpp +++ b/clang/lib/Frontend/CompilerInstance.cpp @@ -257,7 +257,7 @@ void CompilerInstance::createPreprocessor() { } if (PPOpts.DetailedRecord) - PP->createPreprocessingRecord(); + PP->createPreprocessingRecord(PPOpts.DetailedRecordConditionalDirectives); InitializePreprocessor(*PP, PPOpts, getHeaderSearchOpts(), getFrontendOpts()); diff --git a/clang/lib/Lex/PreprocessingRecord.cpp b/clang/lib/Lex/PreprocessingRecord.cpp index c87088d2dec..b8e6152466b 100644 --- a/clang/lib/Lex/PreprocessingRecord.cpp +++ b/clang/lib/Lex/PreprocessingRecord.cpp @@ -37,9 +37,14 @@ InclusionDirective::InclusionDirective(PreprocessingRecord &PPRec, this->FileName = StringRef(Memory, FileName.size()); } -PreprocessingRecord::PreprocessingRecord(SourceManager &SM) - : SourceMgr(SM), ExternalSource(0) +PreprocessingRecord::PreprocessingRecord(SourceManager &SM, + bool RecordConditionalDirectives) + : SourceMgr(SM), + RecordCondDirectives(RecordConditionalDirectives), CondDirectiveNextIdx(0), + ExternalSource(0) { + if (RecordCondDirectives) + CondDirectiveStack.push_back(CondDirectiveNextIdx++); } /// \brief Returns a pair of [Begin, End) iterators of preprocessed entities @@ -397,6 +402,95 @@ 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)); + unsigned uppIdx; + if (upp != CondDirectiveLocs.end()) + uppIdx = upp->getIdx(); + else + uppIdx = 0; + + return low->getIdx() != uppIdx; +} + +unsigned PreprocessingRecord::findCondDirectiveIdx(SourceLocation Loc) const { + if (Loc.isInvalid()) + return 0; + + CondDirectiveLocsTy::const_iterator + low = std::lower_bound(CondDirectiveLocs.begin(), CondDirectiveLocs.end(), + Loc, CondDirectiveLoc::Comp(SourceMgr)); + if (low == CondDirectiveLocs.end()) + return 0; + return low->getIdx(); +} + +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(CondDirectiveNextIdx++); + } +} + +void PreprocessingRecord::Ifdef(SourceLocation Loc, const Token &MacroNameTok) { + if (RecordCondDirectives) { + addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back())); + CondDirectiveStack.push_back(CondDirectiveNextIdx++); + } +} + +void PreprocessingRecord::Ifndef(SourceLocation Loc,const Token &MacroNameTok) { + if (RecordCondDirectives) { + addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back())); + CondDirectiveStack.push_back(CondDirectiveNextIdx++); + } +} + +void PreprocessingRecord::Elif(SourceLocation Loc, SourceRange ConditionRange, + SourceLocation IfLoc) { + if (RecordCondDirectives) + addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back())); +} + +void PreprocessingRecord::Else(SourceLocation Loc, SourceLocation IfLoc) { + if (RecordCondDirectives) + addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back())); +} + +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/clang/lib/Lex/Preprocessor.cpp b/clang/lib/Lex/Preprocessor.cpp index b6ea65de499..06914c7cdcc 100644 --- a/clang/lib/Lex/Preprocessor.cpp +++ b/clang/lib/Lex/Preprocessor.cpp @@ -654,10 +654,11 @@ CommentHandler::~CommentHandler() { } CodeCompletionHandler::~CodeCompletionHandler() { } -void Preprocessor::createPreprocessingRecord() { +void Preprocessor::createPreprocessingRecord(bool RecordConditionalDirectives) { if (Record) return; - Record = new PreprocessingRecord(getSourceManager()); + Record = new PreprocessingRecord(getSourceManager(), + RecordConditionalDirectives); addPPCallbacks(Record); } diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index e1404bf5f37..39f24da6d40 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -1744,7 +1744,7 @@ ASTReader::ReadASTBlock(ModuleFile &F) { = F.PreprocessorDetailCursor.GetCurrentBitNo(); if (!PP.getPreprocessingRecord()) - PP.createPreprocessingRecord(); + PP.createPreprocessingRecord(/*RecordConditionalDirectives=*/false); if (!PP.getPreprocessingRecord()->getExternalSource()) PP.getPreprocessingRecord()->SetExternalSource(*this); break; @@ -2288,7 +2288,7 @@ ASTReader::ReadASTBlock(ModuleFile &F) { unsigned StartingID; if (!PP.getPreprocessingRecord()) - PP.createPreprocessingRecord(); + PP.createPreprocessingRecord(/*RecordConditionalDirectives=*/false); if (!PP.getPreprocessingRecord()->getExternalSource()) PP.getPreprocessingRecord()->SetExternalSource(*this); StartingID |