[clang-tools-extra] r188795 - Revert "cpp11-migrate: Add a class to support include directives modifications"
Guillaume Papin
guillaume.papin at epitech.eu
Tue Aug 20 06:05:57 PDT 2013
Author: papin_g
Date: Tue Aug 20 08:05:57 2013
New Revision: 188795
URL: http://llvm.org/viewvc/llvm-project?rev=188795&view=rev
Log:
Revert "cpp11-migrate: Add a class to support include directives modifications"
This reverts commit r188791.
The Windows bots are still broken.
Removed:
clang-tools-extra/trunk/cpp11-migrate/Core/IncludeDirectives.cpp
clang-tools-extra/trunk/cpp11-migrate/Core/IncludeDirectives.h
clang-tools-extra/trunk/unittests/cpp11-migrate/IncludeDirectivesTest.cpp
Modified:
clang-tools-extra/trunk/cpp11-migrate/Core/CMakeLists.txt
clang-tools-extra/trunk/unittests/cpp11-migrate/CMakeLists.txt
clang-tools-extra/trunk/unittests/cpp11-migrate/VirtualFileHelper.h
Modified: clang-tools-extra/trunk/cpp11-migrate/Core/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/cpp11-migrate/Core/CMakeLists.txt?rev=188795&r1=188794&r2=188795&view=diff
==============================================================================
--- clang-tools-extra/trunk/cpp11-migrate/Core/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/cpp11-migrate/Core/CMakeLists.txt Tue Aug 20 08:05:57 2013
@@ -8,7 +8,6 @@ add_clang_library(migrateCore
IncludeExcludeInfo.cpp
PerfSupport.cpp
Reformatting.cpp
- IncludeDirectives.cpp
)
target_link_libraries(migrateCore
clangFormat
Removed: clang-tools-extra/trunk/cpp11-migrate/Core/IncludeDirectives.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/cpp11-migrate/Core/IncludeDirectives.cpp?rev=188794&view=auto
==============================================================================
--- clang-tools-extra/trunk/cpp11-migrate/Core/IncludeDirectives.cpp (original)
+++ clang-tools-extra/trunk/cpp11-migrate/Core/IncludeDirectives.cpp (removed)
@@ -1,474 +0,0 @@
-//===-- Core/IncludeDirectives.cpp - Include directives handling ----------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// \brief This file defines the IncludeDirectives class that helps with
-/// detecting and modifying \#include directives.
-///
-//===----------------------------------------------------------------------===//
-
-#include "IncludeDirectives.h"
-#include "clang/Basic/CharInfo.h"
-#include "clang/Frontend/CompilerInstance.h"
-#include "clang/Lex/HeaderSearch.h"
-#include "clang/Lex/Preprocessor.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/StringSwitch.h"
-#include <stack>
-
-using namespace clang;
-using namespace clang::tooling;
-using llvm::StringRef;
-
-/// \brief PPCallbacks that fills-in the include information in the given
-/// \c IncludeDirectives.
-class IncludeDirectivesPPCallback : public clang::PPCallbacks {
- // Struct helping the detection of header guards in the various callbacks
- struct GuardDetection {
- GuardDetection(FileID FID)
- : FID(FID), Count(0), TheMacro(0), CountAtEndif(0) {}
-
- FileID FID;
- // count for relevant preprocessor directives
- unsigned Count;
- // the macro that is tested in the top most ifndef for the header guard
- // (e.g: GUARD_H)
- const IdentifierInfo *TheMacro;
- // the hash locations of #ifndef, #define, #endif
- SourceLocation IfndefLoc, DefineLoc, EndifLoc;
- // the value of Count once the #endif is reached
- unsigned CountAtEndif;
-
- /// \brief Check that with all the information gathered if this is a
- /// potential header guard.
- ///
- /// Meaning a top-most \#ifndef has been found, followed by a define and the
- /// last preprocessor directive was the terminating \#endif.
- ///
- /// FIXME: accept the \#if !defined identifier form too.
- bool isPotentialHeaderGuard() const {
- return Count == CountAtEndif && DefineLoc.isValid();
- }
- };
-
-public:
- IncludeDirectivesPPCallback(IncludeDirectives *Self) : Self(Self), Guard(0) {}
-
-private:
- virtual ~IncludeDirectivesPPCallback() {}
- void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
- StringRef FileName, bool IsAngled,
- CharSourceRange FilenameRange, const FileEntry *File,
- StringRef SearchPath, StringRef RelativePath,
- const Module *Imported) LLVM_OVERRIDE {
- SourceManager &SM = Self->Sources;
- const FileEntry *FE = SM.getFileEntryForID(SM.getFileID(HashLoc));
- assert(FE && "Valid file expected.");
-
- IncludeDirectives::Entry E(HashLoc, File, IsAngled);
- Self->FileToEntries[FE].push_back(E);
- Self->IncludeAsWrittenToLocationsMap[FileName].push_back(HashLoc);
- }
-
- // Keep track of the current file in the stack
- virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,
- SrcMgr::CharacteristicKind FileType,
- FileID PrevFID) {
- SourceManager &SM = Self->Sources;
- switch (Reason) {
- case EnterFile:
- Files.push(GuardDetection(SM.getFileID(Loc)));
- Guard = &Files.top();
- break;
-
- case ExitFile:
- if (Guard->isPotentialHeaderGuard())
- handlePotentialHeaderGuard(*Guard);
- Files.pop();
- Guard = &Files.top();
- break;
-
- default:
- break;
- }
- }
-
- /// \brief Mark this header as guarded in the IncludeDirectives if it's a
- /// proper header guard.
- void handlePotentialHeaderGuard(const GuardDetection &Guard) {
- SourceManager &SM = Self->Sources;
- const FileEntry *File = SM.getFileEntryForID(Guard.FID);
- const LangOptions &LangOpts = Self->CI.getLangOpts();
-
- // Null file can happen for the <built-in> buffer for example. They
- // shouldn't have header guards though...
- if (!File)
- return;
-
- // The #ifndef should be the next thing after the preamble. We aren't
- // checking for equality because it can also be part of the preamble if the
- // preamble is the whole file.
- unsigned Preamble =
- Lexer::ComputePreamble(SM.getBuffer(Guard.FID), LangOpts).first;
- unsigned IfndefOffset = SM.getFileOffset(Guard.IfndefLoc);
- if (IfndefOffset > (Preamble + 1))
- return;
-
- // No code is allowed in the code remaining after the #endif.
- const llvm::MemoryBuffer *Buffer = SM.getBuffer(Guard.FID);
- Lexer Lex(SM.getLocForStartOfFile(Guard.FID), LangOpts,
- Buffer->getBufferStart(),
- Buffer->getBufferStart() + SM.getFileOffset(Guard.EndifLoc),
- Buffer->getBufferEnd());
-
- // Find the first newline not part of a multi-line comment.
- Token Tok;
- Lex.LexFromRawLexer(Tok); // skip endif
- Lex.LexFromRawLexer(Tok);
-
- // Not a proper header guard, the remainder of the file contains something
- // else than comments or whitespaces.
- if (Tok.isNot(tok::eof))
- return;
-
- // Add to the location of the define to the IncludeDirectives for this file.
- Self->HeaderToGuard[File] = Guard.DefineLoc;
- }
-
- virtual void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
- const MacroDirective *MD) {
- Guard->Count++;
-
- // If this #ifndef is the top-most directive and the symbol isn't defined
- // store those information in the guard detection, the next step will be to
- // check for the define.
- if (Guard->Count == 1 && MD == 0) {
- IdentifierInfo *MII = MacroNameTok.getIdentifierInfo();
-
- if (MII->hasMacroDefinition())
- return;
- Guard->IfndefLoc = Loc;
- Guard->TheMacro = MII;
- }
- }
-
- virtual void MacroDefined(const Token &MacroNameTok,
- const MacroDirective *MD) {
- Guard->Count++;
-
- // If this #define is the second directive of the file and the symbol
- // defined is the same as the one checked in the #ifndef then store the
- // information about this define.
- if (Guard->Count == 2 && Guard->TheMacro != 0) {
- IdentifierInfo *MII = MacroNameTok.getIdentifierInfo();
-
- // macro unrelated to the ifndef, doesn't look like a proper header guard
- if (MII->getName() != Guard->TheMacro->getName())
- return;
-
- Guard->DefineLoc = MacroNameTok.getLocation();
- }
- }
-
- virtual void Endif(SourceLocation Loc, SourceLocation IfLoc) {
- Guard->Count++;
-
- // If it's the #endif corresponding to the top-most #ifndef
- if (Self->Sources.getDecomposedLoc(Guard->IfndefLoc) !=
- Self->Sources.getDecomposedLoc(IfLoc))
- return;
-
- // And that the top-most #ifndef was followed by the right #define
- if (Guard->DefineLoc.isInvalid())
- return;
-
- // Then save the information about this #endif. Once the file is exited we
- // will check if it was the final preprocessor directive.
- Guard->CountAtEndif = Guard->Count;
- Guard->EndifLoc = Loc;
- }
-
- virtual void MacroExpands(const Token &, const MacroDirective *, SourceRange,
- const MacroArgs *) {
- Guard->Count++;
- }
- virtual void MacroUndefined(const Token &, const MacroDirective *) {
- Guard->Count++;
- }
- virtual void Defined(const Token &, const MacroDirective *, SourceRange) {
- Guard->Count++;
- }
- virtual void If(SourceLocation, SourceRange, bool) { Guard->Count++; }
- virtual void Elif(SourceLocation, SourceRange, bool, SourceLocation) {
- Guard->Count++;
- }
- virtual void Ifdef(SourceLocation, const Token &, const MacroDirective *) {
- Guard->Count++;
- }
- virtual void Else(SourceLocation, SourceLocation) { Guard->Count++; }
-
- IncludeDirectives *Self;
- // keep track of the guard info through the include stack
- std::stack<GuardDetection> Files;
- // convenience field pointing to Files.top().second
- GuardDetection *Guard;
-};
-
-// Flags that describes where to insert newlines.
-enum NewLineFlags {
- // Prepend a newline at the beginning of the insertion.
- NL_Prepend = 0x1,
-
- // Prepend another newline at the end of the insertion.
- NL_PrependAnother = 0x2,
-
- // Add two newlines at the end of the insertion.
- NL_AppendTwice = 0x4,
-
- // Convenience value to enable both \c NL_Prepend and \c NL_PrependAnother.
- NL_PrependTwice = NL_Prepend | NL_PrependAnother
-};
-
-/// \brief Guess the end-of-line sequence used in the given FileID. If the
-/// sequence can't be guessed return an Unix-style newline.
-static StringRef guessEOL(SourceManager &SM, FileID ID) {
- StringRef Content = SM.getBufferData(ID);
- StringRef Buffer = Content.substr(Content.find_first_of("\r\n"));
-
- return llvm::StringSwitch<StringRef>(Buffer)
- .StartsWith("\r\n", "\r\n")
- .StartsWith("\n\r", "\n\r")
- .StartsWith("\r", "\r")
- .Default("\n");
-}
-
-/// \brief Find the end of the end of the directive, either the beginning of a
-/// newline or the end of file.
-//
-// \return The offset into the file where the directive ends along with a
-// boolean value indicating whether the directive ends because the end of file
-// was reached or not.
-static std::pair<unsigned, bool> findDirectiveEnd(SourceLocation HashLoc,
- SourceManager &SM,
- const LangOptions &LangOpts) {
- FileID FID = SM.getFileID(HashLoc);
- unsigned Offset = SM.getFileOffset(HashLoc);
- StringRef Content = SM.getBufferData(FID);
- Lexer Lex(SM.getLocForStartOfFile(FID), LangOpts, Content.begin(),
- Content.begin() + Offset, Content.end());
- Lex.SetCommentRetentionState(true);
- Token Tok;
-
- // This loop look for the newline after our directive but avoids the ones part
- // of a multi-line comments:
- //
- // #include <foo> /* long \n comment */\n
- // ~~ no ~~ yes
- for (;;) {
- // find the beginning of the end-of-line sequence
- StringRef::size_type EOLOffset = Content.find_first_of("\r\n", Offset);
- // ends because EOF was reached
- if (EOLOffset == StringRef::npos)
- return std::make_pair(Content.size(), true);
-
- // find the token that contains our end-of-line
- unsigned TokEnd = 0;
- do {
- Lex.LexFromRawLexer(Tok);
- TokEnd = SM.getFileOffset(Tok.getLocation()) + Tok.getLength();
-
- // happens when the whitespaces are eaten after a multiline comment
- if (Tok.is(tok::eof))
- return std::make_pair(EOLOffset, false);
- } while (TokEnd < EOLOffset);
-
- // the end-of-line is not part of a multi-line comment, return its location
- if (Tok.isNot(tok::comment))
- return std::make_pair(EOLOffset, false);
-
- // for the next search to start after the end of this token
- Offset = TokEnd;
- }
-}
-
-IncludeDirectives::IncludeDirectives(clang::CompilerInstance &CI)
- : CI(CI), Sources(CI.getSourceManager()) {
- // addPPCallbacks takes ownership of the callback
- CI.getPreprocessor().addPPCallbacks(new IncludeDirectivesPPCallback(this));
-}
-
-bool IncludeDirectives::lookForInclude(const FileEntry *File,
- const LocationVec &IncludeLocs,
- SeenFilesSet &Seen) const {
- // mark this file as visited
- Seen.insert(File);
-
- // First check if included directly in this file
- for (LocationVec::const_iterator I = IncludeLocs.begin(),
- E = IncludeLocs.end();
- I != E; ++I)
- if (Sources.getFileEntryForID(Sources.getFileID(*I)) == File)
- return true;
-
- // Otherwise look recursively all the included files
- FileToEntriesMap::const_iterator EntriesIt = FileToEntries.find(File);
- if (EntriesIt == FileToEntries.end())
- return false;
- for (EntryVec::const_iterator I = EntriesIt->second.begin(),
- E = EntriesIt->second.end();
- I != E; ++I) {
- // skip if this header has already been checked before
- if (Seen.count(I->getIncludedFile()))
- continue;
- if (lookForInclude(I->getIncludedFile(), IncludeLocs, Seen))
- return true;
- }
- return false;
-}
-
-bool IncludeDirectives::hasInclude(const FileEntry *File,
- StringRef Include) const {
- llvm::StringMap<LocationVec>::const_iterator It =
- IncludeAsWrittenToLocationsMap.find(Include);
-
- // Include isn't included in any file
- if (It == IncludeAsWrittenToLocationsMap.end())
- return false;
-
- SeenFilesSet Seen;
- return lookForInclude(File, It->getValue(), Seen);
-}
-
-Replacement IncludeDirectives::addAngledInclude(const clang::FileEntry *File,
- llvm::StringRef Include) {
- FileID FID = Sources.translateFile(File);
- assert(!FID.isInvalid() && "Invalid file entry given!");
-
- if (hasInclude(File, Include))
- return Replacement();
-
- unsigned Offset, NLFlags;
- llvm::tie(Offset, NLFlags) = angledIncludeInsertionOffset(FID);
-
- StringRef EOL = guessEOL(Sources, FID);
- llvm::SmallString<32> InsertionText;
- if (NLFlags & NL_Prepend)
- InsertionText += EOL;
- if (NLFlags & NL_PrependAnother)
- InsertionText += EOL;
- InsertionText += "#include <";
- InsertionText += Include;
- InsertionText += ">";
- if (NLFlags & NL_AppendTwice) {
- InsertionText += EOL;
- InsertionText += EOL;
- }
- return Replacement(File->getName(), Offset, 0, InsertionText);
-}
-
-Replacement IncludeDirectives::addAngledInclude(llvm::StringRef File,
- llvm::StringRef Include) {
- const FileEntry *Entry = Sources.getFileManager().getFile(File);
- assert(Entry && "Invalid file given!");
- return addAngledInclude(Entry, Include);
-}
-
-std::pair<unsigned, unsigned>
-IncludeDirectives::findFileHeaderEndOffset(FileID FID) const {
- unsigned NLFlags = NL_Prepend;
- StringRef Content = Sources.getBufferData(FID);
- Lexer Lex(Sources.getLocForStartOfFile(FID), CI.getLangOpts(),
- Content.begin(), Content.begin(), Content.end());
- Lex.SetCommentRetentionState(true);
- Lex.SetKeepWhitespaceMode(true);
-
- // find the first newline not part of a multi-line comment
- Token Tok;
- do {
- Lex.LexFromRawLexer(Tok);
- unsigned Offset = Sources.getFileOffset(Tok.getLocation());
- // allow one newline between the comments
- if (Tok.is(tok::unknown) && isWhitespace(Content[Offset])) {
- StringRef Whitespaces(Content.substr(Offset, Tok.getLength()));
- if (Whitespaces.count('\n') == 1 || Whitespaces.count('\r') == 1)
- Lex.LexFromRawLexer(Tok);
- else {
- // add an empty line to separate the file header and the inclusion
- NLFlags = NL_PrependTwice;
- }
- }
- } while (Tok.is(tok::comment));
-
- // apparently there is no header, insertion point is the beginning of the file
- if (Tok.isNot(tok::unknown))
- return std::make_pair(0, NL_AppendTwice);
- return std::make_pair(Sources.getFileOffset(Tok.getLocation()), NLFlags);
-}
-
-SourceLocation
-IncludeDirectives::angledIncludeHintLoc(FileID FID) const {
- FileToEntriesMap::const_iterator EntriesIt =
- FileToEntries.find(Sources.getFileEntryForID(FID));
-
- if (EntriesIt == FileToEntries.end())
- return SourceLocation();
-
- HeaderSearch &HeaderInfo = CI.getPreprocessor().getHeaderSearchInfo();
- const EntryVec &Entries = EntriesIt->second;
- EntryVec::const_reverse_iterator QuotedCandidate = Entries.rend();
- for (EntryVec::const_reverse_iterator I = Entries.rbegin(),
- E = Entries.rend();
- I != E; ++I) {
- // Headers meant for multiple inclusion can potentially appears in the
- // middle of the code thus making them a poor choice for an insertion point.
- if (!HeaderInfo.isFileMultipleIncludeGuarded(I->getIncludedFile()))
- continue;
-
- // return preferably the last angled include
- if (I->isAngled())
- return I->getHashLocation();
-
- // keep track of the last quoted include that is guarded
- if (QuotedCandidate == Entries.rend())
- QuotedCandidate = I;
- }
-
- if (QuotedCandidate == Entries.rend())
- return SourceLocation();
-
- // return the last quoted-include if we couldn't find an angled one
- return QuotedCandidate->getHashLocation();
-}
-
-std::pair<unsigned, unsigned>
-IncludeDirectives::angledIncludeInsertionOffset(FileID FID) const {
- SourceLocation Hint = angledIncludeHintLoc(FID);
- unsigned NL_Flags = NL_Prepend;
-
- // If we can't find a similar include and we are in a header check if it's a
- // guarded header. If so the hint will be the location of the #define from the
- // guard.
- if (Hint.isInvalid()) {
- const FileEntry *File = Sources.getFileEntryForID(FID);
- HeaderToGuardMap::const_iterator GuardIt = HeaderToGuard.find(File);
- if (GuardIt != HeaderToGuard.end()) {
- // get the hash location from the #define
- Hint = GuardIt->second;
- // we want a blank line between the #define and the #include
- NL_Flags = NL_PrependTwice;
- }
- }
-
- // no hints, insertion is done after the file header
- if (Hint.isInvalid())
- return findFileHeaderEndOffset(FID);
-
- unsigned Offset = findDirectiveEnd(Hint, Sources, CI.getLangOpts()).first;
- return std::make_pair(Offset, NL_Flags);
-}
Removed: clang-tools-extra/trunk/cpp11-migrate/Core/IncludeDirectives.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/cpp11-migrate/Core/IncludeDirectives.h?rev=188794&view=auto
==============================================================================
--- clang-tools-extra/trunk/cpp11-migrate/Core/IncludeDirectives.h (original)
+++ clang-tools-extra/trunk/cpp11-migrate/Core/IncludeDirectives.h (removed)
@@ -1,141 +0,0 @@
-//===-- Core/IncludeDirectives.h - Include directives handling --*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// \brief This file declares the IncludeDirectives class that helps with
-/// detecting and modifying \#include directives.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef CPP11_MIGRATE_INCLUDE_DIRECTIVES_H
-#define CPP11_MIGRATE_INCLUDE_DIRECTIVES_H
-
-#include "clang/Basic/SourceLocation.h"
-#include "clang/Tooling/Refactoring.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include <vector>
-
-namespace clang {
-class Preprocessor;
-} // namespace clang
-
-/// \brief Support for include directives handling.
-///
-/// This class should be created with a \c clang::CompilerInstance before the
-/// file is preprocessed in order to collect the inclusion information. It can
-/// be queried as long as the compiler instance is valid.
-class IncludeDirectives {
-public:
- IncludeDirectives(clang::CompilerInstance &CI);
-
- /// \brief Add an angled include to a the given file.
- ///
- /// \param File A file accessible by a SourceManager
- /// \param Include The include file as it should be written in the code.
- ///
- /// \returns
- /// \li A null Replacement (check using \c Replacement::isApplicable()), if
- /// the \c Include is already visible from \c File.
- /// \li Otherwise, a non-null Replacement that, when applied, inserts an
- /// \c \#include into \c File.
- clang::tooling::Replacement addAngledInclude(llvm::StringRef File,
- llvm::StringRef Include);
- clang::tooling::Replacement addAngledInclude(const clang::FileEntry *File,
- llvm::StringRef Include);
-
- /// \brief Check if \p Include is included by \p File or any of the files
- /// \p File includes.
- bool hasInclude(const clang::FileEntry *File, llvm::StringRef Include) const;
-
-private:
- friend class IncludeDirectivesPPCallback;
-
- /// \brief Contains information about an inclusion.
- class Entry {
- public:
- Entry(clang::SourceLocation HashLoc, const clang::FileEntry *IncludedFile,
- bool Angled)
- : HashLoc(HashLoc), IncludedFile(IncludedFile), Angled(Angled) {}
-
- /// \brief The location of the '#'.
- clang::SourceLocation getHashLocation() const { return HashLoc; }
-
- /// \brief The file included by this include directive.
- const clang::FileEntry *getIncludedFile() const { return IncludedFile; }
-
- /// \brief \c true if the include use angle brackets, \c false otherwise
- /// when using of quotes.
- bool isAngled() const { return Angled; }
-
- private:
- clang::SourceLocation HashLoc;
- const clang::FileEntry *IncludedFile;
- bool Angled;
- };
-
- // A list of entries.
- typedef std::vector<Entry> EntryVec;
-
- // A list of source locations.
- typedef std::vector<clang::SourceLocation> LocationVec;
-
- // Associates files to their includes.
- typedef llvm::DenseMap<const clang::FileEntry *, EntryVec> FileToEntriesMap;
-
- // Associates headers to their include guards if any. The location is the
- // location of the hash from the #define.
- typedef llvm::DenseMap<const clang::FileEntry *, clang::SourceLocation>
- HeaderToGuardMap;
-
- /// \brief Type used by \c lookForInclude() to keep track of the files that
- /// have already been processed.
- typedef llvm::SmallPtrSet<const clang::FileEntry *, 32> SeenFilesSet;
-
- /// \brief Recursively look if an include is included by \p File or any of the
- /// headers \p File includes.
- ///
- /// \param File The file where to start the search.
- /// \param IncludeLocs These are the hash locations of the \#include
- /// directives we are looking for.
- /// \param Seen Used to avoid visiting a same file more than once during the
- /// recursion.
- bool lookForInclude(const clang::FileEntry *File,
- const LocationVec &IncludeLocs, SeenFilesSet &Seen) const;
-
- /// \brief Find the end of a file header and returns a pair (FileOffset,
- /// NewLineFlags).
- ///
- /// Source files often contain a file header (copyright, license, explanation
- /// of the file content). An \#include should preferrably be put after this.
- std::pair<unsigned, unsigned>
- findFileHeaderEndOffset(clang::FileID FID) const;
-
- /// \brief Finds the offset where an angled include should be added and
- /// returns a pair (FileOffset, NewLineFlags).
- std::pair<unsigned, unsigned>
- angledIncludeInsertionOffset(clang::FileID FID) const;
-
- /// \brief Find the location of an include directive that can be used to
- /// insert an inclusion after.
- ///
- /// If no such include exists returns a null SourceLocation.
- clang::SourceLocation angledIncludeHintLoc(clang::FileID FID) const;
-
- clang::CompilerInstance &CI;
- clang::SourceManager &Sources;
- FileToEntriesMap FileToEntries;
- // maps include filename as written in the source code to the source locations
- // where it appears
- llvm::StringMap<LocationVec> IncludeAsWrittenToLocationsMap;
- HeaderToGuardMap HeaderToGuard;
-};
-
-#endif // CPP11_MIGRATE_INCLUDE_DIRECTIVES_H
Modified: clang-tools-extra/trunk/unittests/cpp11-migrate/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/cpp11-migrate/CMakeLists.txt?rev=188795&r1=188794&r2=188795&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/cpp11-migrate/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/unittests/cpp11-migrate/CMakeLists.txt Tue Aug 20 08:05:57 2013
@@ -14,7 +14,6 @@ add_extra_unittest(Cpp11MigrateTests
ReplacementsYamlTest.cpp
TransformTest.cpp
UniqueHeaderNameTest.cpp
- IncludeDirectivesTest.cpp
)
target_link_libraries(Cpp11MigrateTests
Removed: clang-tools-extra/trunk/unittests/cpp11-migrate/IncludeDirectivesTest.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/cpp11-migrate/IncludeDirectivesTest.cpp?rev=188794&view=auto
==============================================================================
--- clang-tools-extra/trunk/unittests/cpp11-migrate/IncludeDirectivesTest.cpp (original)
+++ clang-tools-extra/trunk/unittests/cpp11-migrate/IncludeDirectivesTest.cpp (removed)
@@ -1,377 +0,0 @@
-//===- cpp11-migrate/IncludeDirectivesTest.cpp ----------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "Core/IncludeDirectives.h"
-#include "gtest/gtest.h"
-#include "VirtualFileHelper.h"
-
-#include "clang/Frontend/CompilerInstance.h"
-#include "clang/Frontend/FrontendActions.h"
-
-using namespace llvm;
-using namespace clang;
-
-/// \brief A convenience method around \c tooling::runToolOnCodeWithArgs() that
-/// add the current directory to the include search paths.
-///
-/// The current directory './' is used when mapping virtual files as they aren't
-/// found otherwise. This function allows the tests code to refer to the include
-/// without the path component.
-static void applyActionOnCode(FrontendAction *ToolAction, StringRef Code) {
- std::vector<std::string> Args(1, "-I./");
-
- EXPECT_TRUE(tooling::runToolOnCodeWithArgs(ToolAction, Code, Args));
-}
-
-namespace {
-class TestAddIncludeAction : public PreprocessOnlyAction {
-public:
- TestAddIncludeAction(StringRef Include, tooling::Replacements &Replaces,
- const char *HeaderToModify = 0)
- : Include(Include), Replaces(Replaces), HeaderToModify(HeaderToModify) {
- // some headers that the tests can include
- addVirtualFile("./foo-inner.h", "#pragma once\n");
- addVirtualFile("./foo.h", "#pragma once\n"
- "#include <foo-inner.h>\n");
- addVirtualFile("./bar-inner.h", "#pragma once\n");
- addVirtualFile("./bar.h", "#pragma once\n"
- "#include <bar-inner.h>\n");
- addVirtualFile("./xmacro.def", "X(Val1)\n"
- "X(Val2)\n"
- "X(Val3)\n");
- }
-
- /// \brief Map additional virtual files.
- ///
- /// \warning Note that you probably want \p FileName to contains the prefix
- /// \c "./" so that it can be found by \c applyActionOnCode().
- void addVirtualFile(StringRef FileName, StringRef Content) {
- VFHelper.mapFile(FileName, Content);
- }
-
-private:
- virtual bool BeginSourceFileAction(CompilerInstance &CI,
- StringRef FileName) LLVM_OVERRIDE {
- if (!PreprocessOnlyAction::BeginSourceFileAction(CI, FileName))
- return false;
- VFHelper.mapVirtualFiles(CI.getSourceManager());
-
- FileToModify = HeaderToModify ? HeaderToModify : FileName;
- FileIncludes.reset(new IncludeDirectives(CI));
- return true;
- }
-
- virtual void EndSourceFileAction() LLVM_OVERRIDE {
- const tooling::Replacement &Replace =
- FileIncludes->addAngledInclude(FileToModify, Include);
- if (Replace.isApplicable())
- Replaces.insert(Replace);
- }
-
- StringRef Include;
- VirtualFileHelper VFHelper;
- tooling::Replacements &Replaces;
- OwningPtr<IncludeDirectives> FileIncludes;
- StringRef FileToModify;
- // if non-null, add the include directives in this file instead of the main
- // file.
- const char *HeaderToModify;
-};
-
-std::string addIncludeInCode(StringRef Include, StringRef Code) {
- tooling::Replacements Replaces;
-
- applyActionOnCode(new TestAddIncludeAction(Include, Replaces), Code);
- return tooling::applyAllReplacements(Code, Replaces);
-}
-} // end anonymous namespace
-
-TEST(IncludeDirectivesTest, endOfLinesVariants) {
- EXPECT_EQ("#include <foo.h>\n"
- "#include <bar>\n",
- addIncludeInCode("bar", "#include <foo.h>\n"));
- EXPECT_EQ("#include <foo.h>\r\n"
- "#include <bar>\r\n",
- addIncludeInCode("bar", "#include <foo.h>\r\n"));
- EXPECT_EQ("#include <foo.h>\r"
- "#include <bar>\r",
- addIncludeInCode("bar", "#include <foo.h>\r"));
-}
-
-TEST(IncludeDirectivesTest, ppToken) {
- EXPECT_EQ("#define FOO <foo.h>\n"
- "#include FOO\n"
- "#include <bar>\n"
- "int i;\n",
- addIncludeInCode("bar", "#define FOO <foo.h>\n"
- "#include FOO\n"
- "int i;\n"));
-}
-
-TEST(IncludeDirectivesTest, noFileHeader) {
- EXPECT_EQ("#include <bar>\n"
- "\n"
- "int foo;\n",
- addIncludeInCode("bar", "int foo;\n"));
-}
-
-TEST(IncludeDirectivesTest, commentBeforeTopMostCode) {
- EXPECT_EQ("#include <bar>\n"
- "\n"
- "// Foo\n"
- "int foo;\n",
- addIncludeInCode("bar", "// Foo\n"
- "int foo;\n"));
-}
-
-TEST(IncludeDirectivesTest, multiLineComment) {
- EXPECT_EQ("#include <foo.h> /* \n */\n"
- "#include <bar>\n",
- addIncludeInCode("bar", "#include <foo.h> /* \n */\n"));
- EXPECT_EQ("#include <foo.h> /* \n */"
- "\n#include <bar>",
- addIncludeInCode("bar", "#include <foo.h> /* \n */"));
-}
-
-TEST(IncludeDirectivesTest, multilineCommentWithTrailingSpace) {
- EXPECT_EQ("#include <foo.h> /*\n*/ \n"
- "#include <bar>\n",
- addIncludeInCode("bar", "#include <foo.h> /*\n*/ \n"));
- EXPECT_EQ("#include <foo.h> /*\n*/ "
- "\n#include <bar>",
- addIncludeInCode("bar", "#include <foo.h> /*\n*/ "));
-}
-
-TEST(IncludeDirectivesTest, fileHeaders) {
- EXPECT_EQ("// this is a header\n"
- "// some license stuff here\n"
- "\n"
- "#include <bar>\n"
- "\n"
- "/// \\brief Foo\n"
- "int foo;\n",
- addIncludeInCode("bar", "// this is a header\n"
- "// some license stuff here\n"
- "\n"
- "/// \\brief Foo\n"
- "int foo;\n"));
-}
-
-TEST(IncludeDirectivesTest, preferablyAngledNextToAngled) {
- EXPECT_EQ("#include <foo.h>\n"
- "#include <bar>\n"
- "#include \"bar.h\"\n",
- addIncludeInCode("bar", "#include <foo.h>\n"
- "#include \"bar.h\"\n"));
- EXPECT_EQ("#include \"foo.h\"\n"
- "#include \"bar.h\"\n"
- "#include <bar>\n",
- addIncludeInCode("bar", "#include \"foo.h\"\n"
- "#include \"bar.h\"\n"));
-}
-
-TEST(IncludeDirectivesTest, avoidDuplicates) {
- EXPECT_EQ("#include <foo.h>\n",
- addIncludeInCode("foo.h", "#include <foo.h>\n"));
-}
-
-// Tests includes in the middle of the code are ignored.
-TEST(IncludeDirectivesTest, ignoreHeadersMeantForMultipleInclusion) {
- std::string Expected = "#include \"foo.h\"\n"
- "#include <bar>\n"
- "\n"
- "enum Kind {\n"
- "#define X(A) K_##A,\n"
- "#include \"xmacro.def\"\n"
- "#undef X\n"
- " K_NUM_KINDS\n"
- "};\n";
- std::string Result =
- addIncludeInCode("bar", "#include \"foo.h\"\n"
- "\n"
- "enum Kind {\n"
- "#define X(A) K_##A,\n"
- "#include \"xmacro.def\"\n"
- "#undef X\n"
- " K_NUM_KINDS\n"
- "};\n");
- EXPECT_EQ(Expected, Result);
-}
-
-namespace {
-TestAddIncludeAction *makeIndirectTestsAction(const char *HeaderToModify,
- tooling::Replacements &Replaces) {
- StringRef IncludeToAdd = "c.h";
- TestAddIncludeAction *TestAction =
- new TestAddIncludeAction(IncludeToAdd, Replaces, HeaderToModify);
- TestAction->addVirtualFile("./c.h", "#pragma once\n");
- TestAction->addVirtualFile("./a.h", "#pragma once\n"
- "#include <c.h>\n");
- TestAction->addVirtualFile("./b.h", "#pragma once\n");
- return TestAction;
-}
-} // end anonymous namespace
-
-TEST(IncludeDirectivesTest, indirectIncludes) {
- // In TestAddIncludeAction 'foo.h' includes 'foo-inner.h'. Check that we
- // aren't including foo-inner.h again.
- EXPECT_EQ(
- "#include <foo.h>\n",
- addIncludeInCode("foo-inner.h", "#include <foo.h>\n"));
-
- tooling::Replacements Replaces;
- StringRef Code = "#include <a.h>\n"
- "#include <b.h>\n";
- std::vector<std::string> Args(1, "-I./");
-
- // a.h already includes c.h
- {
- FrontendAction *Action = makeIndirectTestsAction("./a.h", Replaces);
- EXPECT_TRUE(tooling::runToolOnCodeWithArgs(Action, Code, Args));
- EXPECT_EQ(unsigned(0), Replaces.size());
- }
-
- // c.h is included before b.h but b.h doesn't include c.h directly, so check
- // that it will be inserted.
- {
- FrontendAction *Action = makeIndirectTestsAction("./b.h", Replaces);
- EXPECT_TRUE(tooling::runToolOnCodeWithArgs(Action, Code, Args));
- EXPECT_EQ("#include <c.h>\n\n\n",
- tooling::applyAllReplacements("\n", Replaces));
- }
-}
-
-/// \brief Convenience method to test header guards detection implementation.
-static std::string addIncludeInGuardedHeader(StringRef IncludeToAdd,
- StringRef GuardedHeaderCode) {
- const char *GuardedHeaderName = "./guarded.h";
- tooling::Replacements Replaces;
- TestAddIncludeAction *TestAction =
- new TestAddIncludeAction(IncludeToAdd, Replaces, GuardedHeaderName);
- TestAction->addVirtualFile(GuardedHeaderName, GuardedHeaderCode);
- applyActionOnCode(TestAction, "#include <guarded.h>\n");
- return tooling::applyAllReplacements(GuardedHeaderCode, Replaces);
-}
-
-TEST(IncludeDirectivesTest, insertInsideIncludeGuard) {
- EXPECT_EQ("#ifndef GUARD_H\n"
- "#define GUARD_H\n"
- "\n"
- "#include <foo>\n"
- "\n"
- "struct foo {};\n"
- "\n"
- "#endif // GUARD_H\n",
- addIncludeInGuardedHeader("foo", "#ifndef GUARD_H\n"
- "#define GUARD_H\n"
- "\n"
- "struct foo {};\n"
- "\n"
- "#endif // GUARD_H\n"));
-}
-
-TEST(IncludeDirectivesTest, guardAndHeader) {
- EXPECT_EQ("// File header\n"
- "\n"
- "#ifndef GUARD_H\n"
- "#define GUARD_H\n"
- "\n"
- "#include <foo>\n"
- "\n"
- "struct foo {};\n"
- "\n"
- "#endif // GUARD_H\n",
- addIncludeInGuardedHeader("foo", "// File header\n"
- "\n"
- "#ifndef GUARD_H\n"
- "#define GUARD_H\n"
- "\n"
- "struct foo {};\n"
- "\n"
- "#endif // GUARD_H\n"));
-}
-
-TEST(IncludeDirectivesTest, fullHeaderFitsAsAPreamble) {
- EXPECT_EQ("#ifndef GUARD_H\n"
- "#define GUARD_H\n"
- "\n"
- "#include <foo>\n"
- "\n"
- "#define FOO 1\n"
- "\n"
- "#endif // GUARD_H\n",
- addIncludeInGuardedHeader("foo", "#ifndef GUARD_H\n"
- "#define GUARD_H\n"
- "\n"
- "#define FOO 1\n"
- "\n"
- "#endif // GUARD_H\n"));
-}
-
-TEST(IncludeDirectivesTest, codeBeforeIfndef) {
- EXPECT_EQ("#include <foo>\n"
- "\n"
- "int bar;\n"
- "\n"
- "#ifndef GUARD_H\n"
- "#define GUARD_H\n"
- "\n"
- "struct foo;"
- "\n"
- "#endif // GUARD_H\n",
- addIncludeInGuardedHeader("foo", "int bar;\n"
- "\n"
- "#ifndef GUARD_H\n"
- "#define GUARD_H\n"
- "\n"
- "struct foo;"
- "\n"
- "#endif // GUARD_H\n"));
-}
-
-TEST(IncludeDirectivesTest, codeAfterEndif) {
- EXPECT_EQ("#include <foo>\n"
- "\n"
- "#ifndef GUARD_H\n"
- "#define GUARD_H\n"
- "\n"
- "struct foo;"
- "\n"
- "#endif // GUARD_H\n"
- "\n"
- "int bar;\n",
- addIncludeInGuardedHeader("foo", "#ifndef GUARD_H\n"
- "#define GUARD_H\n"
- "\n"
- "struct foo;"
- "\n"
- "#endif // GUARD_H\n"
- "\n"
- "int bar;\n"));
-}
-
-TEST(IncludeDirectivesTest, headerGuardWithInclude) {
- EXPECT_EQ("#ifndef GUARD_H\n"
- "#define GUARD_H\n"
- "\n"
- "#include <bar.h>\n"
- "#include <foo>\n"
- "\n"
- "struct foo;\n"
- "\n"
- "#endif // GUARD_H\n",
- addIncludeInGuardedHeader("foo", "#ifndef GUARD_H\n"
- "#define GUARD_H\n"
- "\n"
- "#include <bar.h>\n"
- "\n"
- "struct foo;\n"
- "\n"
- "#endif // GUARD_H\n"));
-}
Modified: clang-tools-extra/trunk/unittests/cpp11-migrate/VirtualFileHelper.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/cpp11-migrate/VirtualFileHelper.h?rev=188795&r1=188794&r2=188795&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/cpp11-migrate/VirtualFileHelper.h (original)
+++ clang-tools-extra/trunk/unittests/cpp11-migrate/VirtualFileHelper.h Tue Aug 20 08:05:57 2013
@@ -27,8 +27,8 @@ namespace clang {
/// map virtual files conveniently.
class VirtualFileHelper {
struct VirtualFile {
- std::string FileName;
- std::string Code;
+ llvm::StringRef FileName;
+ llvm::StringRef Code;
};
public:
@@ -49,21 +49,15 @@ public:
/// mapped to it.
SourceManager &getNewSourceManager() {
Sources.reset(new SourceManager(Diagnostics, Files));
- mapVirtualFiles(*Sources);
- return *Sources;
- }
-
- /// \brief Map the virtual file contents in the given \c SourceManager.
- void mapVirtualFiles(SourceManager &SM) const {
- for (llvm::SmallVectorImpl<VirtualFile>::const_iterator
- I = VirtualFiles.begin(),
- E = VirtualFiles.end();
+ for (llvm::SmallVectorImpl<VirtualFile>::iterator I = VirtualFiles.begin(),
+ E = VirtualFiles.end();
I != E; ++I) {
llvm::MemoryBuffer *Buf = llvm::MemoryBuffer::getMemBuffer(I->Code);
- const FileEntry *Entry = SM.getFileManager().getVirtualFile(
+ const FileEntry *Entry = Files.getVirtualFile(
I->FileName, Buf->getBufferSize(), /*ModificationTime=*/0);
- SM.overrideFileContents(Entry, Buf);
+ Sources->overrideFileContents(Entry, Buf);
}
+ return *Sources;
}
private:
More information about the cfe-commits
mailing list