diff --git a/include/clang/Lex/PPCallbacks.h b/include/clang/Lex/PPCallbacks.h index ddd7415c293629135594308d64ad29169115ece1..ec29eec13a89ab36f56f95f746a7917fc630b707 100644 --- a/include/clang/Lex/PPCallbacks.h +++ b/include/clang/Lex/PPCallbacks.h @@ -71,6 +71,51 @@ public: } }; +/// PPChainedCallbacks - Simple wrapper class for chaining callbacks. +class PPChainedCallbacks : public PPCallbacks { + PPCallbacks *First, *Second; + +public: + PPChainedCallbacks(PPCallbacks *_First, PPCallbacks *_Second) + : First(_First), Second(_Second) {} + ~PPChainedCallbacks() { + delete Second; + delete First; + } + + virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason, + SrcMgr::CharacteristicKind FileType) { + First->FileChanged(Loc, Reason, FileType); + Second->FileChanged(Loc, Reason, FileType); + } + + virtual void Ident(SourceLocation Loc, const std::string &str) { + First->Ident(Loc, str); + Second->Ident(Loc, str); + } + + virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind, + const std::string &Str) { + First->PragmaComment(Loc, Kind, Str); + Second->PragmaComment(Loc, Kind, Str); + } + + virtual void MacroExpands(const Token &Id, const MacroInfo* MI) { + First->MacroExpands(Id, MI); + Second->MacroExpands(Id, MI); + } + + virtual void MacroDefined(const IdentifierInfo *II, const MacroInfo *MI) { + First->MacroDefined(II, MI); + Second->MacroDefined(II, MI); + } + + virtual void MacroUndefined(const IdentifierInfo *II, const MacroInfo *MI) { + First->MacroUndefined(II, MI); + Second->MacroUndefined(II, MI); + } +}; + } // end namespace clang #endif diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h index 2184acf0e3510244a3fa9e1906f23976cda6c041..5b9959c32a2d6bc3b64a92ffe9d55178eb70db49 100644 --- a/include/clang/Lex/Preprocessor.h +++ b/include/clang/Lex/Preprocessor.h @@ -241,7 +241,8 @@ public: /// it. PPCallbacks *getPPCallbacks() const { return Callbacks; } void setPPCallbacks(PPCallbacks *C) { - delete Callbacks; + if (Callbacks) + C = new PPChainedCallbacks(C, Callbacks); Callbacks = C; } diff --git a/test/Preprocessor/depencies-and-pp.c b/test/Preprocessor/dependencies-and-pp.c similarity index 60% rename from test/Preprocessor/depencies-and-pp.c rename to test/Preprocessor/dependencies-and-pp.c index ec66c73f75ece1b4da5af3890760b665bd3ce276..1dc4d026b18df9da7c4bd7d1ccde9f08795020de 100644 --- a/test/Preprocessor/depencies-and-pp.c +++ b/test/Preprocessor/dependencies-and-pp.c @@ -1,4 +1,5 @@ // RUN: clang -E -o %t.1 %s && // RUN: clang -E -MD -MF %t.d -MT foo -o %t.2 %s && // RUN: diff %t.1 %t.2 && -// RUN: grep "foo:" %t.d +// RUN: grep "foo:" %t.d && +// RUN: grep "dependencies-and-pp.c" %t.d diff --git a/tools/clang-cc/DependencyFile.cpp b/tools/clang-cc/DependencyFile.cpp index 9ef209eeebbb8050b489731eb39f9dab3b2e30df..34b6ecfcab8615fadadf68c4d3d21c3797c82336 100644 --- a/tools/clang-cc/DependencyFile.cpp +++ b/tools/clang-cc/DependencyFile.cpp @@ -35,10 +35,6 @@ class VISIBILITY_HIDDEN DependencyFileCallback : public PPCallbacks { std::vector<std::string> Targets; llvm::raw_ostream *OS; - // FIXME: This functionality should be moved into a common class for - // chaining callbacks. - PPCallbacks *PrevCallbacks; - private: bool FileMatchesDepCriteria(const char *Filename, SrcMgr::CharacteristicKind FileType); @@ -47,14 +43,11 @@ private: public: DependencyFileCallback(const Preprocessor *_PP, llvm::raw_ostream *_OS, - const std::vector<std::string> &_Targets, - PPCallbacks *_PrevCallbacks) - : PP(_PP), Targets(_Targets), OS(_OS), PrevCallbacks(_PrevCallbacks) { + const std::vector<std::string> &_Targets) + : PP(_PP), Targets(_Targets), OS(_OS) { } ~DependencyFileCallback() { - if (PrevCallbacks) - delete PrevCallbacks; OutputDependencyFile(); OS->flush(); delete OS; @@ -62,32 +55,6 @@ public: virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason, SrcMgr::CharacteristicKind FileType); - - virtual void Ident(SourceLocation Loc, const std::string &str) { - if (PrevCallbacks) - PrevCallbacks->Ident(Loc, str); - } - - virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind, - const std::string &Str) { - if (PrevCallbacks) - PrevCallbacks->PragmaComment(Loc, Kind, Str); - } - - virtual void MacroExpands(const Token &Id, const MacroInfo* MI) { - if (PrevCallbacks) - PrevCallbacks->MacroExpands(Id, MI); - } - - virtual void MacroDefined(const IdentifierInfo *II, const MacroInfo *MI) { - if (PrevCallbacks) - PrevCallbacks->MacroDefined(II, MI); - } - - virtual void MacroUndefined(const IdentifierInfo *II, const MacroInfo *MI) { - if (PrevCallbacks) - PrevCallbacks->MacroUndefined(II, MI); - } }; } @@ -135,13 +102,8 @@ bool clang::CreateDependencyFileGen(Preprocessor *PP, } } - // Claim any previous callbacks. - PPCallbacks *Prev = PP->getPPCallbacks(); - if (Prev) - PP->setPPCallbacks(0); - DependencyFileCallback *PPDep = - new DependencyFileCallback(PP, OS, DependencyTargets, Prev); + new DependencyFileCallback(PP, OS, DependencyTargets); PP->setPPCallbacks(PPDep); return true; } @@ -162,9 +124,6 @@ bool DependencyFileCallback::FileMatchesDepCriteria(const char *Filename, void DependencyFileCallback::FileChanged(SourceLocation Loc, FileChangeReason Reason, SrcMgr::CharacteristicKind FileType) { - if (PrevCallbacks) - PrevCallbacks->FileChanged(Loc, Reason, FileType); - if (Reason != PPCallbacks::EnterFile) return;