diff options
Diffstat (limited to 'clang/tools/clang-cc')
| -rw-r--r-- | clang/tools/clang-cc/CacheTokens.cpp | 658 | ||||
| -rw-r--r-- | clang/tools/clang-cc/DependencyFile.cpp | 171 | ||||
| -rw-r--r-- | clang/tools/clang-cc/DiagChecker.cpp | 301 | ||||
| -rw-r--r-- | clang/tools/clang-cc/PrintParserCallbacks.cpp | 829 | ||||
| -rw-r--r-- | clang/tools/clang-cc/PrintPreprocessedOutput.cpp | 468 | ||||
| -rw-r--r-- | clang/tools/clang-cc/RewriteMacros.cpp | 215 | ||||
| -rw-r--r-- | clang/tools/clang-cc/RewriteTest.cpp | 39 | ||||
| -rw-r--r-- | clang/tools/clang-cc/Warnings.cpp | 106 | ||||
| -rw-r--r-- | clang/tools/clang-cc/clang-cc.cpp | 2 | ||||
| -rw-r--r-- | clang/tools/clang-cc/clang-cc.h | 79 |
10 files changed, 1 insertions, 2867 deletions
diff --git a/clang/tools/clang-cc/CacheTokens.cpp b/clang/tools/clang-cc/CacheTokens.cpp deleted file mode 100644 index 53352360fbc..00000000000 --- a/clang/tools/clang-cc/CacheTokens.cpp +++ /dev/null @@ -1,658 +0,0 @@ -//===--- CacheTokens.cpp - Caching of lexer tokens for PTH support --------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This provides a possible implementation of PTH support for Clang that is -// based on caching lexed tokens and identifiers. -// -//===----------------------------------------------------------------------===// - -#include "clang-cc.h" -#include "clang/Basic/FileManager.h" -#include "clang/Basic/SourceManager.h" -#include "clang/Basic/IdentifierTable.h" -#include "clang/Basic/Diagnostic.h" -#include "clang/Basic/OnDiskHashTable.h" -#include "clang/Lex/Lexer.h" -#include "clang/Lex/Preprocessor.h" -#include "llvm/ADT/StringMap.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/System/Path.h" -#include "llvm/Support/Compiler.h" -#include "llvm/Support/Streams.h" - -// FIXME: put this somewhere else? -#ifndef S_ISDIR -#define S_ISDIR(x) (((x)&_S_IFDIR)!=0) -#endif - -using namespace clang; -using namespace clang::io; - -//===----------------------------------------------------------------------===// -// PTH-specific stuff. -//===----------------------------------------------------------------------===// - -namespace { -class VISIBILITY_HIDDEN PTHEntry { - Offset TokenData, PPCondData; - -public: - PTHEntry() {} - - PTHEntry(Offset td, Offset ppcd) - : TokenData(td), PPCondData(ppcd) {} - - Offset getTokenOffset() const { return TokenData; } - Offset getPPCondTableOffset() const { return PPCondData; } -}; - - -class VISIBILITY_HIDDEN PTHEntryKeyVariant { - union { const FileEntry* FE; const char* Path; }; - enum { IsFE = 0x1, IsDE = 0x2, IsNoExist = 0x0 } Kind; - struct stat *StatBuf; -public: - PTHEntryKeyVariant(const FileEntry *fe) - : FE(fe), Kind(IsFE), StatBuf(0) {} - - PTHEntryKeyVariant(struct stat* statbuf, const char* path) - : Path(path), Kind(IsDE), StatBuf(new struct stat(*statbuf)) {} - - PTHEntryKeyVariant(const char* path) - : Path(path), Kind(IsNoExist), StatBuf(0) {} - - bool isFile() const { return Kind == IsFE; } - - const char* getCString() const { - return Kind == IsFE ? FE->getName() : Path; - } - - unsigned getKind() const { return (unsigned) Kind; } - - void EmitData(llvm::raw_ostream& Out) { - switch (Kind) { - case IsFE: - // Emit stat information. - ::Emit32(Out, FE->getInode()); - ::Emit32(Out, FE->getDevice()); - ::Emit16(Out, FE->getFileMode()); - ::Emit64(Out, FE->getModificationTime()); - ::Emit64(Out, FE->getSize()); - break; - case IsDE: - // Emit stat information. - ::Emit32(Out, (uint32_t) StatBuf->st_ino); - ::Emit32(Out, (uint32_t) StatBuf->st_dev); - ::Emit16(Out, (uint16_t) StatBuf->st_mode); - ::Emit64(Out, (uint64_t) StatBuf->st_mtime); - ::Emit64(Out, (uint64_t) StatBuf->st_size); - delete StatBuf; - break; - default: - break; - } - } - - unsigned getRepresentationLength() const { - return Kind == IsNoExist ? 0 : 4 + 4 + 2 + 8 + 8; - } -}; - -class VISIBILITY_HIDDEN FileEntryPTHEntryInfo { -public: - typedef PTHEntryKeyVariant key_type; - typedef key_type key_type_ref; - - typedef PTHEntry data_type; - typedef const PTHEntry& data_type_ref; - - static unsigned ComputeHash(PTHEntryKeyVariant V) { - return BernsteinHash(V.getCString()); - } - - static std::pair<unsigned,unsigned> - EmitKeyDataLength(llvm::raw_ostream& Out, PTHEntryKeyVariant V, - const PTHEntry& E) { - - unsigned n = strlen(V.getCString()) + 1 + 1; - ::Emit16(Out, n); - - unsigned m = V.getRepresentationLength() + (V.isFile() ? 4 + 4 : 0); - ::Emit8(Out, m); - - return std::make_pair(n, m); - } - - static void EmitKey(llvm::raw_ostream& Out, PTHEntryKeyVariant V, unsigned n){ - // Emit the entry kind. - ::Emit8(Out, (unsigned) V.getKind()); - // Emit the string. - Out.write(V.getCString(), n - 1); - } - - static void EmitData(llvm::raw_ostream& Out, PTHEntryKeyVariant V, - const PTHEntry& E, unsigned) { - - - // For file entries emit the offsets into the PTH file for token data - // and the preprocessor blocks table. - if (V.isFile()) { - ::Emit32(Out, E.getTokenOffset()); - ::Emit32(Out, E.getPPCondTableOffset()); - } - - // Emit any other data associated with the key (i.e., stat information). - V.EmitData(Out); - } -}; - -class OffsetOpt { - bool valid; - Offset off; -public: - OffsetOpt() : valid(false) {} - bool hasOffset() const { return valid; } - Offset getOffset() const { assert(valid); return off; } - void setOffset(Offset o) { off = o; valid = true; } -}; -} // end anonymous namespace - -typedef OnDiskChainedHashTableGenerator<FileEntryPTHEntryInfo> PTHMap; -typedef llvm::DenseMap<const IdentifierInfo*,uint32_t> IDMap; -typedef llvm::StringMap<OffsetOpt, llvm::BumpPtrAllocator> CachedStrsTy; - -namespace { -class VISIBILITY_HIDDEN PTHWriter { - IDMap IM; - llvm::raw_fd_ostream& Out; - Preprocessor& PP; - uint32_t idcount; - PTHMap PM; - CachedStrsTy CachedStrs; - Offset CurStrOffset; - std::vector<llvm::StringMapEntry<OffsetOpt>*> StrEntries; - - //// Get the persistent id for the given IdentifierInfo*. - uint32_t ResolveID(const IdentifierInfo* II); - - /// Emit a token to the PTH file. - void EmitToken(const Token& T); - - void Emit8(uint32_t V) { - Out << (unsigned char)(V); - } - - void Emit16(uint32_t V) { ::Emit16(Out, V); } - - void Emit24(uint32_t V) { - Out << (unsigned char)(V); - Out << (unsigned char)(V >> 8); - Out << (unsigned char)(V >> 16); - assert((V >> 24) == 0); - } - - void Emit32(uint32_t V) { ::Emit32(Out, V); } - - void EmitBuf(const char *Ptr, unsigned NumBytes) { - Out.write(Ptr, NumBytes); - } - - /// EmitIdentifierTable - Emits two tables to the PTH file. The first is - /// a hashtable mapping from identifier strings to persistent IDs. - /// The second is a straight table mapping from persistent IDs to string data - /// (the keys of the first table). - std::pair<Offset, Offset> EmitIdentifierTable(); - - /// EmitFileTable - Emit a table mapping from file name strings to PTH - /// token data. - Offset EmitFileTable() { return PM.Emit(Out); } - - PTHEntry LexTokens(Lexer& L); - Offset EmitCachedSpellings(); - -public: - PTHWriter(llvm::raw_fd_ostream& out, Preprocessor& pp) - : Out(out), PP(pp), idcount(0), CurStrOffset(0) {} - - PTHMap &getPM() { return PM; } - void GeneratePTH(const std::string *MainFile = 0); -}; -} // end anonymous namespace - -uint32_t PTHWriter::ResolveID(const IdentifierInfo* II) { - // Null IdentifierInfo's map to the persistent ID 0. - if (!II) - return 0; - - IDMap::iterator I = IM.find(II); - if (I != IM.end()) - return I->second; // We've already added 1. - - IM[II] = ++idcount; // Pre-increment since '0' is reserved for NULL. - return idcount; -} - -void PTHWriter::EmitToken(const Token& T) { - // Emit the token kind, flags, and length. - Emit32(((uint32_t) T.getKind()) | ((((uint32_t) T.getFlags())) << 8)| - (((uint32_t) T.getLength()) << 16)); - - if (!T.isLiteral()) { - Emit32(ResolveID(T.getIdentifierInfo())); - } else { - // We cache *un-cleaned* spellings. This gives us 100% fidelity with the - // source code. - const char* s = T.getLiteralData(); - unsigned len = T.getLength(); - - // Get the string entry. - llvm::StringMapEntry<OffsetOpt> *E = &CachedStrs.GetOrCreateValue(s, s+len); - - // If this is a new string entry, bump the PTH offset. - if (!E->getValue().hasOffset()) { - E->getValue().setOffset(CurStrOffset); - StrEntries.push_back(E); - CurStrOffset += len + 1; - } - - // Emit the relative offset into the PTH file for the spelling string. - Emit32(E->getValue().getOffset()); - } - - // Emit the offset into the original source file of this token so that we - // can reconstruct its SourceLocation. - Emit32(PP.getSourceManager().getFileOffset(T.getLocation())); -} - -PTHEntry PTHWriter::LexTokens(Lexer& L) { - // Pad 0's so that we emit tokens to a 4-byte alignment. - // This speed up reading them back in. - Pad(Out, 4); - Offset off = (Offset) Out.tell(); - - // Keep track of matching '#if' ... '#endif'. - typedef std::vector<std::pair<Offset, unsigned> > PPCondTable; - PPCondTable PPCond; - std::vector<unsigned> PPStartCond; - bool ParsingPreprocessorDirective = false; - Token Tok; - - do { - L.LexFromRawLexer(Tok); - NextToken: - - if ((Tok.isAtStartOfLine() || Tok.is(tok::eof)) && - ParsingPreprocessorDirective) { - // Insert an eom token into the token cache. It has the same - // position as the next token that is not on the same line as the - // preprocessor directive. Observe that we continue processing - // 'Tok' when we exit this branch. - Token Tmp = Tok; - Tmp.setKind(tok::eom); - Tmp.clearFlag(Token::StartOfLine); - Tmp.setIdentifierInfo(0); - EmitToken(Tmp); - ParsingPreprocessorDirective = false; - } - - if (Tok.is(tok::identifier)) { - Tok.setIdentifierInfo(PP.LookUpIdentifierInfo(Tok)); - EmitToken(Tok); - continue; - } - - if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) { - // Special processing for #include. Store the '#' token and lex - // the next token. - assert(!ParsingPreprocessorDirective); - Offset HashOff = (Offset) Out.tell(); - EmitToken(Tok); - - // Get the next token. - L.LexFromRawLexer(Tok); - - // If we see the start of line, then we had a null directive "#". - if (Tok.isAtStartOfLine()) - goto NextToken; - - // Did we see 'include'/'import'/'include_next'? - if (Tok.isNot(tok::identifier)) { - EmitToken(Tok); - continue; - } - - IdentifierInfo* II = PP.LookUpIdentifierInfo(Tok); - Tok.setIdentifierInfo(II); - tok::PPKeywordKind K = II->getPPKeywordID(); - - ParsingPreprocessorDirective = true; - - switch (K) { - case tok::pp_not_keyword: - // Invalid directives "#foo" can occur in #if 0 blocks etc, just pass - // them through. - default: - break; - - case tok::pp_include: - case tok::pp_import: - case tok::pp_include_next: { - // Save the 'include' token. - EmitToken(Tok); - // Lex the next token as an include string. - L.setParsingPreprocessorDirective(true); - L.LexIncludeFilename(Tok); - L.setParsingPreprocessorDirective(false); - assert(!Tok.isAtStartOfLine()); - if (Tok.is(tok::identifier)) - Tok.setIdentifierInfo(PP.LookUpIdentifierInfo(Tok)); - - break; - } - case tok::pp_if: - case tok::pp_ifdef: - case tok::pp_ifndef: { - // Add an entry for '#if' and friends. We initially set the target - // index to 0. This will get backpatched when we hit #endif. - PPStartCond.push_back(PPCond.size()); - PPCond.push_back(std::make_pair(HashOff, 0U)); - break; - } - case tok::pp_endif: { - // Add an entry for '#endif'. We set the target table index to itself. - // This will later be set to zero when emitting to the PTH file. We - // use 0 for uninitialized indices because that is easier to debug. - unsigned index = PPCond.size(); - // Backpatch the opening '#if' entry. - assert(!PPStartCond.empty()); - assert(PPCond.size() > PPStartCond.back()); - assert(PPCond[PPStartCond.back()].second == 0); - PPCond[PPStartCond.back()].second = index; - PPStartCond.pop_back(); - // Add the new entry to PPCond. - PPCond.push_back(std::make_pair(HashOff, index)); - EmitToken(Tok); - - // Some files have gibberish on the same line as '#endif'. - // Discard these tokens. - do - L.LexFromRawLexer(Tok); - while (Tok.isNot(tok::eof) && !Tok.isAtStartOfLine()); - // We have the next token in hand. - // Don't immediately lex the next one. - goto NextToken; - } - case tok::pp_elif: - case tok::pp_else: { - // Add an entry for #elif or #else. - // This serves as both a closing and opening of a conditional block. - // This means that its entry will get backpatched later. - unsigned index = PPCond.size(); - // Backpatch the previous '#if' entry. - assert(!PPStartCond.empty()); - assert(PPCond.size() > PPStartCond.back()); - assert(PPCond[PPStartCond.back()].second == 0); - PPCond[PPStartCond.back()].second = index; - PPStartCond.pop_back(); - // Now add '#elif' as a new block opening. - PPCond.push_back(std::make_pair(HashOff, 0U)); - PPStartCond.push_back(index); - break; - } - } - } - - EmitToken(Tok); - } - while (Tok.isNot(tok::eof)); - - assert(PPStartCond.empty() && "Error: imblanced preprocessor conditionals."); - - // Next write out PPCond. - Offset PPCondOff = (Offset) Out.tell(); - - // Write out the size of PPCond so that clients can identifer empty tables. - Emit32(PPCond.size()); - - for (unsigned i = 0, e = PPCond.size(); i!=e; ++i) { - Emit32(PPCond[i].first - off); - uint32_t x = PPCond[i].second; - assert(x != 0 && "PPCond entry not backpatched."); - // Emit zero for #endifs. This allows us to do checking when - // we read the PTH file back in. - Emit32(x == i ? 0 : x); - } - - return PTHEntry(off, PPCondOff); -} - -Offset PTHWriter::EmitCachedSpellings() { - // Write each cached strings to the PTH file. - Offset SpellingsOff = Out.tell(); - - for (std::vector<llvm::StringMapEntry<OffsetOpt>*>::iterator - I = StrEntries.begin(), E = StrEntries.end(); I!=E; ++I) - EmitBuf((*I)->getKeyData(), (*I)->getKeyLength()+1 /*nul included*/); - - return SpellingsOff; -} - -void PTHWriter::GeneratePTH(const std::string *MainFile) { - // Generate the prologue. - Out << "cfe-pth"; - Emit32(PTHManager::Version); - - // Leave 4 words for the prologue. - Offset PrologueOffset = Out.tell(); - for (unsigned i = 0; i < 4; ++i) - Emit32(0); - - // Write the name of the MainFile. - if (MainFile && !MainFile->empty()) { - Emit16(MainFile->length()); - EmitBuf(MainFile->data(), MainFile->length()); - } else { - // String with 0 bytes. - Emit16(0); - } - Emit8(0); - - // Iterate over all the files in SourceManager. Create a lexer - // for each file and cache the tokens. - SourceManager &SM = PP.getSourceManager(); - const LangOptions &LOpts = PP.getLangOptions(); - - for (SourceManager::fileinfo_iterator I = SM.fileinfo_begin(), - E = SM.fileinfo_end(); I != E; ++I) { - const SrcMgr::ContentCache &C = *I->second; - const FileEntry *FE = C.Entry; - - // FIXME: Handle files with non-absolute paths. - llvm::sys::Path P(FE->getName()); - if (!P.isAbsolute()) - continue; - - const llvm::MemoryBuffer *B = C.getBuffer(); - if (!B) continue; - - FileID FID = SM.createFileID(FE, SourceLocation(), SrcMgr::C_User); - Lexer L(FID, SM, LOpts); - PM.insert(FE, LexTokens(L)); - } - - // Write out the identifier table. - const std::pair<Offset,Offset> &IdTableOff = EmitIdentifierTable(); - - // Write out the cached strings table. - Offset SpellingOff = EmitCachedSpellings(); - - // Write out the file table. - Offset FileTableOff = EmitFileTable(); - - // Finally, write the prologue. - Out.seek(PrologueOffset); - Emit32(IdTableOff.first); - Emit32(IdTableOff.second); - Emit32(FileTableOff); - Emit32(SpellingOff); -} - -namespace { -/// StatListener - A simple "interpose" object used to monitor stat calls -/// invoked by FileManager while processing the original sources used -/// as input to PTH generation. StatListener populates the PTHWriter's -/// file map with stat information for directories as well as negative stats. -/// Stat information for files are populated elsewhere. -class StatListener : public StatSysCallCache { - PTHMap &PM; -public: - StatListener(PTHMap &pm) : PM(pm) {} - ~StatListener() {} - - int stat(const char *path, struct stat *buf) { - int result = ::stat(path, buf); - - if (result != 0) // Failed 'stat'. - PM.insert(path, PTHEntry()); - else if (S_ISDIR(buf->st_mode)) { - // Only cache directories with absolute paths. - if (!llvm::sys::Path(path).isAbsolute()) - return result; - - PM.insert(PTHEntryKeyVariant(buf, path), PTHEntry()); - } - - return result; - } -}; -} // end anonymous namespace - - -void clang::CacheTokens(Preprocessor &PP, llvm::raw_fd_ostream* OS) { - // Get the name of the main file. - const SourceManager &SrcMgr = PP.getSourceManager(); - const FileEntry *MainFile = SrcMgr.getFileEntryForID(SrcMgr.getMainFileID()); - llvm::sys::Path MainFilePath(MainFile->getName()); - std::string MainFileName; - - if (!MainFilePath.isAbsolute()) { - llvm::sys::Path P = llvm::sys::Path::GetCurrentDirectory(); - P.appendComponent(MainFilePath.toString()); - MainFileName = P.toString(); - } else { - MainFileName = MainFilePath.toString(); - } - - // Create the PTHWriter. - PTHWriter PW(*OS, PP); - - // Install the 'stat' system call listener in the FileManager. - PP.getFileManager().setStatCache(new StatListener(PW.getPM())); - - // Lex through the entire file. This will populate SourceManager with - // all of the header information. - Token Tok; - PP.EnterMainSourceFile(); - do { PP.Lex(Tok); } while (Tok.isNot(tok::eof)); - - // Generate the PTH file. - PP.getFileManager().setStatCache(0); - PW.GeneratePTH(&MainFileName); -} - -//===----------------------------------------------------------------------===// - -class PTHIdKey { -public: - const IdentifierInfo* II; - uint32_t FileOffset; -}; - -namespace { -class VISIBILITY_HIDDEN PTHIdentifierTableTrait { -public: - typedef PTHIdKey* key_type; - typedef key_type key_type_ref; - - typedef uint32_t data_type; - typedef data_type data_type_ref; - - static unsigned ComputeHash(PTHIdKey* key) { - return BernsteinHash(key->II->getName()); - } - - static std::pair<unsigned,unsigned> - EmitKeyDataLength(llvm::raw_ostream& Out, const PTHIdKey* key, uint32_t) { - unsigned n = strlen(key->II->getName()) + 1; - ::Emit16(Out, n); - return std::make_pair(n, sizeof(uint32_t)); - } - - static void EmitKey(llvm::raw_ostream& Out, PTHIdKey* key, unsigned n) { - // Record the location of the key data. This is used when generating - // the mapping from persistent IDs to strings. - key->FileOffset = Out.tell(); - Out.write(key->II->getName(), n); - } - - static void EmitData(llvm::raw_ostream& Out, PTHIdKey*, uint32_t pID, - unsigned) { - ::Emit32(Out, pID); - } -}; -} // end anonymous namespace - -/// EmitIdentifierTable - Emits two tables to the PTH file. The first is -/// a hashtable mapping from identifier strings to persistent IDs. The second -/// is a straight table mapping from persistent IDs to string data (the -/// keys of the first table). -/// -std::pair<Offset,Offset> PTHWriter::EmitIdentifierTable() { - // Build two maps: - // (1) an inverse map from persistent IDs -> (IdentifierInfo*,Offset) - // (2) a map from (IdentifierInfo*, Offset)* -> persistent IDs - - // Note that we use 'calloc', so all the bytes are 0. - PTHIdKey *IIDMap = (PTHIdKey*)calloc(idcount, sizeof(PTHIdKey)); - - // Create the hashtable. - OnDiskChainedHashTableGenerator<PTHIdentifierTableTrait> IIOffMap; - - // Generate mapping from persistent IDs -> IdentifierInfo*. - for (IDMap::iterator I = IM.begin(), E = IM.end(); I != E; ++I) { - // Decrement by 1 because we are using a vector for the lookup and - // 0 is reserved for NULL. - assert(I->second > 0); - assert(I->second-1 < idcount); - unsigned idx = I->second-1; - - // Store the mapping from persistent ID to IdentifierInfo* - IIDMap[idx].II = I->first; - - // Store the reverse mapping in a hashtable. - IIOffMap.insert(&IIDMap[idx], I->second); - } - - // Write out the inverse map first. This causes the PCIDKey entries to - // record PTH file offsets for the string data. This is used to write - // the second table. - Offset StringTableOffset = IIOffMap.Emit(Out); - - // Now emit the table mapping from persistent IDs to PTH file offsets. - Offset IDOff = Out.tell(); - Emit32(idcount); // Emit the number of identifiers. - for (unsigned i = 0 ; i < idcount; ++i) - Emit32(IIDMap[i].FileOffset); - - // Finally, release the inverse map. - free(IIDMap); - - return std::make_pair(IDOff, StringTableOffset); -} diff --git a/clang/tools/clang-cc/DependencyFile.cpp b/clang/tools/clang-cc/DependencyFile.cpp deleted file mode 100644 index 3306f82aea7..00000000000 --- a/clang/tools/clang-cc/DependencyFile.cpp +++ /dev/null @@ -1,171 +0,0 @@ -//===--- DependencyFile.cpp - Generate dependency file --------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This code generates dependency files. -// -//===----------------------------------------------------------------------===// - -#include "clang-cc.h" -#include "clang/Basic/SourceManager.h" -#include "clang/Basic/FileManager.h" -#include "clang/Lex/Preprocessor.h" -#include "clang/Lex/PPCallbacks.h" -#include "clang/Lex/DirectoryLookup.h" -#include "clang/Basic/SourceLocation.h" -#include "llvm/ADT/StringSet.h" -#include "llvm/System/Path.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/Compiler.h" -#include "llvm/Support/raw_ostream.h" -#include <string> - -using namespace clang; - -namespace { -class VISIBILITY_HIDDEN DependencyFileCallback : public PPCallbacks { - std::vector<std::string> Files; - llvm::StringSet<> FilesSet; - const Preprocessor *PP; - std::vector<std::string> Targets; - llvm::raw_ostream *OS; - bool IncludeSystemHeaders; - bool PhonyTarget; -private: - bool FileMatchesDepCriteria(const char *Filename, - SrcMgr::CharacteristicKind FileType); - void OutputDependencyFile(); - -public: - DependencyFileCallback(const Preprocessor *_PP, - llvm::raw_ostream *_OS, - const std::vector<std::string> &_Targets, - bool _IncludeSystemHeaders, - bool _PhonyTarget) - : PP(_PP), Targets(_Targets), OS(_OS), - IncludeSystemHeaders(_IncludeSystemHeaders), PhonyTarget(_PhonyTarget) {} - - ~DependencyFileCallback() { - OutputDependencyFile(); - OS->flush(); - delete OS; - } - - virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason, - SrcMgr::CharacteristicKind FileType); -}; -} - - - -void clang::AttachDependencyFileGen(Preprocessor *PP, llvm::raw_ostream *OS, - std::vector<std::string> &Targets, - bool IncludeSystemHeaders, - bool PhonyTarget) { - assert(!Targets.empty() && "Target required for dependency generation"); - - DependencyFileCallback *PPDep = - new DependencyFileCallback(PP, OS, Targets, IncludeSystemHeaders, - PhonyTarget); - PP->setPPCallbacks(PPDep); -} - -/// FileMatchesDepCriteria - Determine whether the given Filename should be -/// considered as a dependency. -bool DependencyFileCallback::FileMatchesDepCriteria(const char *Filename, - SrcMgr::CharacteristicKind FileType) { - if (strcmp("<built-in>", Filename) == 0) - return false; - - if (IncludeSystemHeaders) - return true; - - return FileType == SrcMgr::C_User; -} - -void DependencyFileCallback::FileChanged(SourceLocation Loc, - FileChangeReason Reason, - SrcMgr::CharacteristicKind FileType) { - if (Reason != PPCallbacks::EnterFile) - return; - - // Dependency generation really does want to go all the way to the - // file entry for a source location to find out what is depended on. - // We do not want #line markers to affect dependency generation! - SourceManager &SM = PP->getSourceManager(); - - const FileEntry *FE = - SM.getFileEntryForID(SM.getFileID(SM.getInstantiationLoc(Loc))); - if (FE == 0) return; - - const char *Filename = FE->getName(); - if (!FileMatchesDepCriteria(Filename, FileType)) - return; - - // Remove leading "./" - if (Filename[0] == '.' && Filename[1] == '/') - Filename = &Filename[2]; - - if (FilesSet.insert(Filename)) - Files.push_back(Filename); -} - -void DependencyFileCallback::OutputDependencyFile() { - // Write out the dependency targets, trying to avoid overly long - // lines when possible. We try our best to emit exactly the same - // dependency file as GCC (4.2), assuming the included files are the - // same. - const unsigned MaxColumns = 75; - unsigned Columns = 0; - - for (std::vector<std::string>::iterator - I = Targets.begin(), E = Targets.end(); I != E; ++I) { - unsigned N = I->length(); - if (Columns == 0) { - Columns += N; - *OS << *I; - } else if (Columns + N + 2 > MaxColumns) { - Columns = N + 2; - *OS << " \\\n " << *I; - } else { - Columns += N + 1; - *OS << ' ' << *I; - } - } - - *OS << ':'; - Columns += 1; - - // Now add each dependency in the order it was seen, but avoiding - // duplicates. - for (std::vector<std::string>::iterator I = Files.begin(), - E = Files.end(); I != E; ++I) { - // Start a new line if this would exceed the column limit. Make - // sure to leave space for a trailing " \" in case we need to - // break the line on the next iteration. - unsigned N = I->length(); - if (Columns + (N + 1) + 2 > MaxColumns) { - *OS << " \\\n "; - Columns = 2; - } - *OS << ' ' << *I; - Columns += N + 1; - } - *OS << '\n'; - - // Create phony targets if requested. - if (PhonyTarget) { - // Skip the first entry, this is always the input file itself. - for (std::vector<std::string>::iterator I = Files.begin() + 1, - E = Files.end(); I != E; ++I) { - *OS << '\n'; - *OS << *I << ":\n"; - } - } -} - diff --git a/clang/tools/clang-cc/DiagChecker.cpp b/clang/tools/clang-cc/DiagChecker.cpp deleted file mode 100644 index 5e964dcfb7a..00000000000 --- a/clang/tools/clang-cc/DiagChecker.cpp +++ /dev/null @@ -1,301 +0,0 @@ -//===--- DiagChecker.cpp - Diagnostic Checking Functions ------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Process the input files and check that the diagnostic messages are expected. -// -//===----------------------------------------------------------------------===// - -#include "clang-cc.h" -#include "clang/Frontend/TextDiagnosticBuffer.h" -#include "clang/Sema/ParseAST.h" -#include "clang/AST/ASTConsumer.h" -#include "clang/Basic/SourceManager.h" -#include "clang/Lex/Preprocessor.h" -using namespace clang; - -typedef TextDiagnosticBuffer::DiagList DiagList; -typedef TextDiagnosticBuffer::const_iterator const_diag_iterator; - -static void EmitError(Preprocessor &PP, SourceLocation Pos, const char *String){ - unsigned ID = PP.getDiagnostics().getCustomDiagID(Diagnostic::Error, String); - PP.Diag(Pos, ID); -} - - -// USING THE DIAGNOSTIC CHECKER: -// -// Indicating that a line expects an error or a warning is simple. Put a comment -// on the line that has the diagnostic, use "expected-{error,warning}" to tag -// if it's an expected error or warning, and place the expected text between {{ -// and }} markers. The full text doesn't have to be included, only enough to -// ensure that the correct diagnostic was emitted. -// -// Here's an example: -// -// int A = B; // expected-error {{use of undeclared identifier 'B'}} -// -// You can place as many diagnostics on one line as you wish. To make the code -// more readable, you can use slash-newline to separate out the diagnostics. -// -// The simple syntax above allows each specification to match exactly one error. -// You can use the extended syntax to customize this. The extended syntax is -// "expected-<type> <n> {{diag text}}", where <type> is one of "error", -// "warning" or "note", and <n> is a positive integer. This allows the -// diagnostic to appear as many times as specified. Example: -// -// void f(); // expected-note 2 {{previous declaration is here}} -// - -/// FindDiagnostics - Go through the comment and see if it indicates expected -/// diagnostics. If so, then put them in a diagnostic list. -/// -static void FindDiagnostics(const char *CommentStart, unsigned CommentLen, - DiagList &ExpectedDiags, - Preprocessor &PP, SourceLocation Pos, - const char *ExpectedStr) { - const char *CommentEnd = CommentStart+CommentLen; - unsigned ExpectedStrLen = strlen(ExpectedStr); - - // Find all expected-foo diagnostics in the string and add them to - // ExpectedDiags. - while (CommentStart != CommentEnd) { - CommentStart = std::find(CommentStart, CommentEnd, 'e'); - if (unsigned(CommentEnd-CommentStart) < ExpectedStrLen) return; - - // If this isn't expected-foo, ignore it. - if (memcmp(CommentStart, ExpectedStr, ExpectedStrLen)) { - ++CommentStart; - continue; - } - - CommentStart += ExpectedStrLen; - - // Skip whitespace. - while (CommentStart != CommentEnd && - isspace(CommentStart[0])) - ++CommentStart; - - // Default, if we find the '{' now, is 1 time. - int Times = 1; - int Temp = 0; - // In extended syntax, there could be a digit now. - while (CommentStart != CommentEnd && - CommentStart[0] >= '0' && CommentStart[0] <= '9') { - Temp *= 10; - Temp += CommentStart[0] - '0'; - ++CommentStart; - } - if (Temp > 0) - Times = Temp; - - // Skip whitespace again. - while (CommentStart != CommentEnd && - isspace(CommentStart[0])) - ++CommentStart; - - // We should have a {{ now. - if (CommentEnd-CommentStart < 2 || - CommentStart[0] != '{' || CommentStart[1] != '{') { - if (std::find(CommentStart, CommentEnd, '{') != CommentEnd) - EmitError(PP, Pos, "bogus characters before '{{' in expected string"); - else - EmitError(PP, Pos, "cannot find start ('{{') of expected string"); - return; - } - CommentStart += 2; - - // Find the }}. - const char *ExpectedEnd = CommentStart; - while (1) { - ExpectedEnd = std::find(ExpectedEnd, CommentEnd, '}'); - if (CommentEnd-ExpectedEnd < 2) { - EmitError(PP, Pos, "cannot find end ('}}') of expected string"); - return; - } - - if (ExpectedEnd[1] == '}') - break; - - ++ExpectedEnd; // Skip over singular }'s - } - - std::string Msg(CommentStart, ExpectedEnd); - std::string::size_type FindPos; - while ((FindPos = Msg.find("\\n")) != std::string::npos) - Msg.replace(FindPos, 2, "\n"); - // Add is possibly multiple times. - for (int i = 0; i < Times; ++i) - ExpectedDiags.push_back(std::make_pair(Pos, Msg)); - - CommentStart = ExpectedEnd; - } -} - -/// FindExpectedDiags - Lex the main source file to find all of the -// expected errors and warnings. -static void FindExpectedDiags(Preprocessor &PP, - DiagList &ExpectedErrors, - DiagList &ExpectedWarnings, - DiagList &ExpectedNotes) { - // Create a raw lexer to pull all the comments out of the main file. We don't - // want to look in #include'd headers for expected-error strings. - FileID FID = PP.getSourceManager().getMainFileID(); - - // Create a lexer to lex all the tokens of the main file in raw mode. - Lexer RawLex(FID, PP.getSourceManager(), PP.getLangOptions()); - - // Return comments as tokens, this is how we find expected diagnostics. - RawLex.SetCommentRetentionState(true); - - Token Tok; - Tok.setKind(tok::comment); - while (Tok.isNot(tok::eof)) { - RawLex.Lex(Tok); - if (!Tok.is(tok::comment)) continue; - - std::string Comment = PP.getSpelling(Tok); - if (Comment.empty()) continue; - - - // Find all expected errors. - FindDiagnostics(&Comment[0], Comment.size(), ExpectedErrors, PP, - Tok.getLocation(), "expected-error"); - - // Find all expected warnings. - FindDiagnostics(&Comment[0], Comment.size(), ExpectedWarnings, PP, - Tok.getLocation(), "expected-warning"); - - // Find all expected notes. - FindDiagnostics(&Comment[0], Comment.size(), ExpectedNotes, PP, - Tok.getLocation(), "expected-note"); - }; -} - -/// PrintProblem - This takes a diagnostic map of the delta between expected and -/// seen diagnostics. If there's anything in it, then something unexpected -/// happened. Print the map out in a nice format and return "true". If the map -/// is empty and we're not going to print things, then return "false". -/// -static bool PrintProblem(SourceManager &SourceMgr, - const_diag_iterator diag_begin, - const_diag_iterator diag_end, - const char *Msg) { - if (diag_begin == diag_end) return false; - - fprintf(stderr, "%s\n", Msg); - - for (const_diag_iterator I = diag_begin, E = diag_end; I != E; ++I) - fprintf(stderr, " Line %d: %s\n", - SourceMgr.getInstantiationLineNumber(I->first), - I->second.c_str()); - - return true; -} - -/// CompareDiagLists - Compare two diagnostic lists and return the difference -/// between them. -/// -static bool CompareDiagLists(SourceManager &SourceMgr, - const_diag_iterator d1_begin, - const_diag_iterator d1_end, - const_diag_iterator d2_begin, - const_diag_iterator d2_end, - const char *MsgLeftOnly, - const char *MsgRightOnly) { - DiagList LeftOnly; - DiagList Left(d1_begin, d1_end); - DiagList Right(d2_begin, d2_end); - - for (const_diag_iterator I = Left.begin(), E = Left.end(); I != E; ++I) { - unsigned LineNo1 = SourceMgr.getInstantiationLineNumber(I->first); - const std::string &Diag1 = I->second; - - DiagList::iterator II, IE; - for (II = Right.begin(), IE = Right.end(); II != IE; ++II) { - unsigned LineNo2 = SourceMgr.getInstantiationLineNumber(II->first); - if (LineNo1 != LineNo2) continue; - - const std::string &Diag2 = II->second; - if (Diag2.find(Diag1) != std::string::npos || - Diag1.find(Diag2) != std::string::npos) { - break; - } - } - if (II == IE) { - // Not found. - LeftOnly.push_back(*I); - } else { - // Found. The same cannot be found twice. - Right.erase(II); - } - } - // Now all that's left in Right are those that were not matched. - - return PrintProblem(SourceMgr, LeftOnly.begin(), LeftOnly.end(), MsgLeftOnly) - | PrintProblem(SourceMgr, Right.begin(), Right.end(), MsgRightOnly); -} - -/// CheckResults - This compares the expected results to those that -/// were actually reported. It emits any discrepencies. Return "true" if there -/// were problems. Return "false" otherwise. -/// -static bool CheckResults(Preprocessor &PP, - const DiagList &ExpectedErrors, - const DiagList &ExpectedWarnings, - const DiagList &ExpectedNotes) { - const DiagnosticClient *DiagClient = PP.getDiagnostics().getClient(); - assert(DiagClient != 0 && - "DiagChecker requires a valid TextDiagnosticBuffer"); - const TextDiagnosticBuffer &Diags = - static_cast<const TextDiagnosticBuffer&>(*DiagClient); - SourceManager &SourceMgr = PP.getSourceManager(); - - // We want to capture the delta between what was expected and what was - // seen. - // - // Expected \ Seen - set expected but not seen - // Seen \ Expected - set seen but not expected - bool HadProblem = false; - - // See if there are error mismatches. - HadProblem |= CompareDiagLists(SourceMgr, - ExpectedErrors.begin(), ExpectedErrors.end(), - Diags.err_begin(), Diags.err_end(), - "Errors expected but not seen:", - "Errors seen but not expected:"); - - // See if there are warning mismatches. - HadProblem |= CompareDiagLists(SourceMgr, - ExpectedWarnings.begin(), - ExpectedWarnings.end(), - Diags.warn_begin(), Diags.warn_end(), - "Warnings expected but not seen:", - "Warnings seen but not expected:"); - - // See if there are note mismatches. - HadProblem |= CompareDiagLists(SourceMgr, - ExpectedNotes.begin(), - ExpectedNotes.end(), - Diags.note_begin(), Diags.note_end(), - "Notes expected but not seen:", - "Notes seen but not expected:"); - - return HadProblem; -} - - -/// CheckDiagnostics - Gather the expected diagnostics and check them. -bool clang::CheckDiagnostics(Preprocessor &PP) { - // Gather the set of expected diagnostics. - DiagList ExpectedErrors, ExpectedWarnings, ExpectedNotes; - FindExpectedDiags(PP, ExpectedErrors, ExpectedWarnings, ExpectedNotes); - - // Check that the expected diagnostics occurred. - return CheckResults(PP, ExpectedErrors, ExpectedWarnings, ExpectedNotes); -} diff --git a/clang/tools/clang-cc/PrintParserCallbacks.cpp b/clang/tools/clang-cc/PrintParserCallbacks.cpp deleted file mode 100644 index e5b7d0455cf..00000000000 --- a/clang/tools/clang-cc/PrintParserCallbacks.cpp +++ /dev/null @@ -1,829 +0,0 @@ -//===--- PrintParserActions.cpp - Implement -parse-print-callbacks mode ---===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This code simply runs the preprocessor on the input file and prints out the -// result. This is the traditional behavior of the -E option. -// -//===----------------------------------------------------------------------===// - -#include "clang-cc.h" -#include "clang/Parse/Action.h" -#include "clang/Parse/DeclSpec.h" -#include "llvm/Support/raw_ostream.h" -using namespace clang; - -namespace { - class ParserPrintActions : public MinimalAction { - llvm::raw_ostream& Out; - - public: - ParserPrintActions(Preprocessor &PP, llvm::raw_ostream& OS) - : MinimalAction(PP), Out(OS) {} - - // Printing Functions which also must call MinimalAction - - /// ActOnDeclarator - This callback is invoked when a declarator is parsed - /// and 'Init' specifies the initializer if any. This is for things like: - /// "int X = 4" or "typedef int foo". - virtual DeclPtrTy ActOnDeclarator(Scope *S, Declarator &D) { - Out << __FUNCTION__ << " "; - if (IdentifierInfo *II = D.getIdentifier()) { - Out << "'" << II->getName() << "'"; - } else { - Out << "<anon>"; - } - Out << "\n"; - - // Pass up to EmptyActions so that the symbol table is maintained right. - return MinimalAction::ActOnDeclarator(S, D); - } - /// ActOnPopScope - This callback is called immediately before the specified - /// scope is popped and deleted. - virtual void ActOnPopScope(SourceLocation Loc, Scope *S) { - Out << __FUNCTION__ << "\n"; - return MinimalAction::ActOnPopScope(Loc, S); - } - - /// ActOnTranslationUnitScope - This callback is called once, immediately - /// after creating the translation unit scope (in Parser::Initialize). - virtual void ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) { - Out << __FUNCTION__ << "\n"; - MinimalAction::ActOnTranslationUnitScope(Loc, S); - } - - - Action::DeclPtrTy ActOnStartClassInterface(SourceLocation AtInterfaceLoc, - IdentifierInfo *ClassName, - SourceLocation ClassLoc, - IdentifierInfo *SuperName, - SourceLocation SuperLoc, - const DeclPtrTy *ProtoRefs, - unsigned NumProtocols, - SourceLocation EndProtoLoc, - AttributeList *AttrList) { - Out << __FUNCTION__ << "\n"; - return MinimalAction::ActOnStartClassInterface(AtInterfaceLoc, - ClassName, ClassLoc, - SuperName, SuperLoc, - ProtoRefs, NumProtocols, - EndProtoLoc, AttrList); - } - - /// ActOnForwardClassDeclaration - - /// Scope will always be top level file scope. - Action::DeclPtrTy ActOnForwardClassDeclaration(SourceLocation AtClassLoc, - IdentifierInfo **IdentList, - unsigned NumElts) { - Out << __FUNCTION__ << "\n"; - return MinimalAction::ActOnForwardClassDeclaration(AtClassLoc, IdentList, - NumElts); - } - - // Pure Printing - - /// ActOnParamDeclarator - This callback is invoked when a parameter - /// declarator is parsed. This callback only occurs for functions - /// with prototypes. S is the function prototype scope for the - /// parameters (C++ [basic.scope.proto]). - virtual DeclPtrTy ActOnParamDeclarator(Scope *S, Declarator &D) { - Out << __FUNCTION__ << " "; - if (IdentifierInfo *II = D.getIdentifier()) { - Out << "'" << II->getName() << "'"; - } else { - Out << "<anon>"; - } - Out << "\n"; - return DeclPtrTy(); - } - - /// AddInitializerToDecl - This action is called immediately after - /// ParseDeclarator (when an initializer is present). The code is factored - /// this way to make sure we are able to handle the following: - /// void func() { int xx = xx; } - /// This allows ActOnDeclarator to register "xx" prior to parsing the - /// initializer. The declaration above should still result in a warning, - /// since the reference to "xx" is uninitialized. - virtual void AddInitializerToDecl(DeclPtrTy Dcl, ExprArg Init) { - Out << __FUNCTION__ << "\n"; - } - - /// FinalizeDeclaratorGroup - After a sequence of declarators are parsed, - /// this gives the actions implementation a chance to process the group as - /// a whole. - virtual DeclGroupPtrTy FinalizeDeclaratorGroup(Scope *S, DeclPtrTy *Group, - unsigned NumDecls) { - Out << __FUNCTION__ << "\n"; - return DeclGroupPtrTy(); - } - - /// ActOnStartOfFunctionDef - This is called at the start of a function - /// definition, instead of calling ActOnDeclarator. The Declarator includes - /// information about formal arguments that are part of this function. - virtual DeclPtrTy ActOnStartOfFunctionDef(Scope *FnBodyScope, - Declarator &D){ - Out << __FUNCTION__ << "\n"; - return DeclPtrTy(); - } - - /// ActOnStartOfFunctionDef - This is called at the start of a function - /// definition, after the FunctionDecl has already been created. - virtual DeclPtrTy ActOnStartOfFunctionDef(Scope *FnBodyScope, DeclPtrTy D) { - Out << __FUNCTION__ << "\n"; - return DeclPtrTy(); - } - - virtual void ActOnStartOfObjCMethodDef(Scope *FnBodyScope, DeclPtrTy D) { - Out << __FUNCTION__ << "\n"; - } - - /// ActOnFunctionDefBody - This is called when a function body has completed - /// parsing. Decl is the DeclTy returned by ParseStartOfFunctionDef. - virtual DeclPtrTy ActOnFinishFunctionBody(DeclPtrTy Decl, StmtArg Body) { - Out << __FUNCTION__ << "\n"; - return DeclPtrTy(); - } - - virtual DeclPtrTy ActOnFileScopeAsmDecl(SourceLocation Loc, - ExprArg AsmString) { - Out << __FUNCTION__ << "\n"; - return DeclPtrTy(); - } - - /// ParsedFreeStandingDeclSpec - This method is invoked when a declspec with - /// no declarator (e.g. "struct foo;") is parsed. - virtual DeclPtrTy ParsedFreeStandingDeclSpec(Scope *S, DeclSpec &DS) { - Out << __FUNCTION__ << "\n"; - return DeclPtrTy(); - } - - /// ActOnLinkageSpec - Parsed a C++ linkage-specification that - /// contained braces. Lang/StrSize contains the language string that - /// was parsed at location Loc. Decls/NumDecls provides the - /// declarations parsed inside the linkage specification. - virtual DeclPtrTy ActOnLinkageSpec(SourceLocation Loc, - SourceLocation LBrace, - SourceLocation RBrace, const char *Lang, - unsigned StrSize, - DeclPtrTy *Decls, unsigned NumDecls) { - Out << __FUNCTION__ << "\n"; - return DeclPtrTy(); - } - - /// ActOnLinkageSpec - Parsed a C++ linkage-specification without - /// braces. Lang/StrSize contains the language string that was - /// parsed at location Loc. D is the declaration parsed. - virtual DeclPtrTy ActOnLinkageSpec(SourceLocation Loc, const char *Lang, - unsigned StrSize, DeclPtrTy D) { - return DeclPtrTy(); - } - - //===------------------------------------------------------------------===// - // Type Parsing Callbacks. - //===------------------------------------------------------------------===// - - virtual TypeResult ActOnTypeName(Scope *S, Declarator &D) { - Out << __FUNCTION__ << "\n"; - return TypeResult(); - } - - virtual DeclPtrTy ActOnTag(Scope *S, unsigned TagType, TagKind TK, - SourceLocation KWLoc, const CXXScopeSpec &SS, - IdentifierInfo *Name, SourceLocation NameLoc, - AttributeList *Attr, AccessSpecifier AS) { - // TagType is an instance of DeclSpec::TST, indicating what kind of tag this - // is (struct/union/enum/class). - Out << __FUNCTION__ << "\n"; - return DeclPtrTy(); - } - - /// Act on @defs() element found when parsing a structure. ClassName is the - /// name of the referenced class. - virtual void ActOnDefs(Scope *S, DeclPtrTy TagD, SourceLocation DeclStart, - IdentifierInfo *ClassName, - llvm::SmallVectorImpl<DeclPtrTy> &Decls) { - Out << __FUNCTION__ << "\n"; - } - - virtual DeclPtrTy ActOnField(Scope *S, DeclPtrTy TagD, - SourceLocation DeclStart, - Declarator &D, ExprTy *BitfieldWidth) { - Out << __FUNCTION__ << "\n"; - return DeclPtrTy(); - } - - virtual DeclPtrTy ActOnIvar(Scope *S, SourceLocation DeclStart, - Declarator &D, ExprTy *BitfieldWidth, - tok::ObjCKeywordKind visibility) { - Out << __FUNCTION__ << "\n"; - return DeclPtrTy(); - } - - virtual void ActOnFields(Scope* S, SourceLocation RecLoc, DeclPtrTy TagDecl, - DeclPtrTy *Fields, unsigned NumFields, - SourceLocation LBrac, SourceLocation RBrac, - AttributeList *AttrList) { - Out << __FUNCTION__ << "\n"; - } - - virtual DeclPtrTy ActOnEnumConstant(Scope *S, DeclPtrTy EnumDecl, - DeclPtrTy LastEnumConstant, - SourceLocation IdLoc,IdentifierInfo *Id, - SourceLocation EqualLoc, ExprTy *Val) { - Out << __FUNCTION__ << "\n"; - return DeclPtrTy(); - } - - virtual void ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc, - SourceLocation RBraceLoc, DeclPtrTy EnumDecl, - DeclPtrTy *Elements, unsigned NumElements) { - Out << __FUNCTION__ << "\n"; - } - - //===------------------------------------------------------------------===// - // Statement Parsing Callbacks. - //===------------------------------------------------------------------===// - - virtual OwningStmtResult ActOnNullStmt(SourceLocation SemiLoc) { - Out << __FUNCTION__ << "\n"; - return StmtEmpty(); - } - - virtual OwningStmtResult ActOnCompoundStmt(SourceLocation L, - SourceLocation R, - MultiStmtArg Elts, - bool isStmtExpr) { - Out << __FUNCTION__ << "\n"; - return StmtEmpty(); - } - virtual OwningStmtResult ActOnDeclStmt(DeclGroupPtrTy Decl, - SourceLocation StartLoc, - SourceLocation EndLoc) { - Out << __FUNCTION__ << "\n"; - return StmtEmpty(); - } - - virtual OwningStmtResult ActOnExprStmt(FullExprArg Expr) { - Out << __FUNCTION__ << "\n"; - return OwningStmtResult(*this, Expr->release()); - } - - /// ActOnCaseStmt - Note that this handles the GNU 'case 1 ... 4' extension, - /// which can specify an RHS value. - virtual OwningStmtResult ActOnCaseStmt(SourceLocation CaseLoc, - ExprArg LHSVal, - SourceLocation DotDotDotLoc, - ExprArg RHSVal, - SourceLocation ColonLoc) { - Out << __FUNCTION__ << "\n"; - return StmtEmpty(); - } - virtual OwningStmtResult ActOnDefaultStmt(SourceLocation DefaultLoc, - SourceLocation ColonLoc, - StmtArg SubStmt, Scope *CurScope){ - Out << __FUNCTION__ << "\n"; - return StmtEmpty(); - } - - virtual OwningStmtResult ActOnLabelStmt(SourceLocation IdentLoc, - IdentifierInfo *II, - SourceLocation ColonLoc, - StmtArg SubStmt) { - Out << __FUNCTION__ << "\n"; - return StmtEmpty(); - } - - virtual OwningStmtResult ActOnIfStmt(SourceLocation IfLoc, - FullExprArg CondVal, StmtArg ThenVal, - SourceLocation ElseLoc, - StmtArg ElseVal) { - Out << __FUNCTION__ << "\n"; - return StmtEmpty(); - } - - virtual OwningStmtResult ActOnStartOfSwitchStmt(ExprArg Cond) { - Out << __FUNCTION__ << "\n"; - return StmtEmpty(); - } - - virtual OwningStmtResult ActOnFinishSwitchStmt(SourceLocation SwitchLoc, - StmtArg Switch, - StmtArg Body) { - Out << __FUNCTION__ << "\n"; - return StmtEmpty(); - } - - virtual OwningStmtResult ActOnWhileStmt(SourceLocation WhileLoc, - FullExprArg Cond, StmtArg Body) { - Out << __FUNCTION__ << "\n"; - return StmtEmpty(); - } - virtual OwningStmtResult ActOnDoStmt(SourceLocation DoLoc, StmtArg Body, - SourceLocation WhileLoc, ExprArg Cond){ - Out << __FUNCTION__ << "\n"; - return StmtEmpty(); - } - virtual OwningStmtResult ActOnForStmt(SourceLocation ForLoc, - SourceLocation LParenLoc, - StmtArg First, ExprArg Second, - ExprArg Third, SourceLocation RParenLoc, - StmtArg Body) { - Out << __FUNCTION__ << "\n"; - return StmtEmpty(); - } - virtual OwningStmtResult ActOnObjCForCollectionStmt( - SourceLocation ForColLoc, - SourceLocation LParenLoc, - StmtArg First, ExprArg Second, - SourceLocation RParenLoc, StmtArg Body) { - Out << __FUNCTION__ << "\n"; - return StmtEmpty(); - } - virtual OwningStmtResult ActOnGotoStmt(SourceLocation GotoLoc, - SourceLocation LabelLoc, - IdentifierInfo *LabelII) { - Out << __FUNCTION__ << "\n"; - return StmtEmpty(); - } - virtual OwningStmtResult ActOnIndirectGotoStmt(SourceLocation GotoLoc, - SourceLocation StarLoc, - ExprArg DestExp) { - Out << __FUNCTION__ << "\n"; - return StmtEmpty(); - } - virtual OwningStmtResult ActOnContinueStmt(SourceLocation ContinueLoc, - Scope *CurScope) { - Out << __FUNCTION__ << "\n"; - return StmtEmpty(); - } - virtual OwningStmtResult ActOnBreakStmt(SourceLocation GotoLoc, - Scope *CurScope) { - Out << __FUNCTION__ << "\n"; - return StmtEmpty(); - } - virtual OwningStmtResult ActOnReturnStmt(SourceLocation ReturnLoc, - ExprArg RetValExp) { - Out << __FUNCTION__ << "\n"; - return StmtEmpty(); - } - virtual OwningStmtResult ActOnAsmStmt(SourceLocation AsmLoc, - bool IsSimple, - bool IsVolatile, - unsigned NumOutputs, - unsigned NumInputs, - std::string *Names, - MultiExprArg Constraints, - MultiExprArg Exprs, - ExprArg AsmString, - MultiExprArg Clobbers, - SourceLocation RParenLoc) { - Out << __FUNCTION__ << "\n"; - return StmtEmpty(); - } - - // Objective-c statements - virtual OwningStmtResult ActOnObjCAtCatchStmt(SourceLocation AtLoc, - SourceLocation RParen, - DeclPtrTy Parm, StmtArg Body, - StmtArg CatchList) { - Out << __FUNCTION__ << "\n"; - return StmtEmpty(); - } - - virtual OwningStmtResult ActOnObjCAtFinallyStmt(SourceLocation AtLoc, - StmtArg Body) { - Out << __FUNCTION__ << "\n"; - return StmtEmpty(); - } - - virtual OwningStmtResult ActOnObjCAtTryStmt(SourceLocation AtLoc, - StmtArg Try, StmtArg Catch, - StmtArg Finally) { - Out << __FUNCTION__ << "\n"; - return StmtEmpty(); - } - - virtual OwningStmtResult ActOnObjCAtThrowStmt(SourceLocation AtLoc, - ExprArg Throw, - Scope *CurScope) { - Out << __FUNCTION__ << "\n"; - return StmtEmpty(); - } - - virtual OwningStmtResult ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc, - ExprArg SynchExpr, - StmtArg SynchBody) { - Out << __FUNCTION__ << "\n"; - return StmtEmpty(); - } - - // C++ Statements - virtual DeclPtrTy ActOnExceptionDeclarator(Scope *S, Declarator &D) { - Out << __FUNCTION__ << "\n"; - return DeclPtrTy(); - } - - virtual OwningStmtResult ActOnCXXCatchBlock(SourceLocation CatchLoc, - DeclPtrTy ExceptionDecl, - StmtArg HandlerBlock) { - Out << __FUNCTION__ << "\n"; - return StmtEmpty(); - } - - virtual OwningStmtResult ActOnCXXTryBlock(SourceLocation TryLoc, - StmtArg TryBlock, - MultiStmtArg Handlers) { - Out << __FUNCTION__ << "\n"; - return StmtEmpty(); - } - - //===------------------------------------------------------------------===// - // Expression Parsing Callbacks. - //===------------------------------------------------------------------===// - - // Primary Expressions. - - /// ActOnIdentifierExpr - Parse an identifier in expression context. - /// 'HasTrailingLParen' indicates whether or not the identifier has a '(' - /// token immediately after it. - virtual OwningExprResult ActOnIdentifierExpr(Scope *S, SourceLocation Loc, - IdentifierInfo &II, - bool HasTrailingLParen, - const CXXScopeSpec *SS, - bool isAddressOfOperand) { - Out << __FUNCTION__ << "\n"; - return ExprEmpty(); - } - - virtual OwningExprResult ActOnCXXOperatorFunctionIdExpr( - Scope *S, SourceLocation OperatorLoc, - OverloadedOperatorKind Op, - bool HasTrailingLParen, const CXXScopeSpec &SS, - bool isAddressOfOperand) { - Out << __FUNCTION__ << "\n"; - return ExprEmpty(); - } - - virtual OwningExprResult ActOnCXXConversionFunctionExpr( - Scope *S, SourceLocation OperatorLoc, - TypeTy *Type, bool HasTrailingLParen, - const CXXScopeSpec &SS,bool isAddressOfOperand) { - Out << __FUNCTION__ << "\n"; - return ExprEmpty(); - } - - virtual OwningExprResult ActOnPredefinedExpr(SourceLocation Loc, - tok::TokenKind Kind) { - Out << __FUNCTION__ << "\n"; - return ExprEmpty(); - } - - virtual OwningExprResult ActOnCharacterConstant(const Token &) { - Out << __FUNCTION__ << "\n"; - return ExprEmpty(); - } - - virtual OwningExprResult ActOnNumericConstant(const Token &) { - Out << __FUNCTION__ << "\n"; - return ExprEmpty(); - } - - /// ActOnStringLiteral - The specified tokens were lexed as pasted string - /// fragments (e.g. "foo" "bar" L"baz"). - virtual OwningExprResult ActOnStringLiteral(const Token *Toks, - unsigned NumToks) { - Out << __FUNCTION__ << "\n"; - return ExprEmpty(); - } - - virtual OwningExprResult ActOnParenExpr(SourceLocation L, SourceLocation R, - ExprArg Val) { - Out << __FUNCTION__ << "\n"; - return move(Val); // Default impl returns operand. - } - - // Postfix Expressions. - virtual OwningExprResult ActOnPostfixUnaryOp(Scope *S, SourceLocation OpLoc, - tok::TokenKind Kind, - ExprArg Input) { - Out << __FUNCTION__ << "\n"; - return ExprEmpty(); - } - virtual OwningExprResult ActOnArraySubscriptExpr(Scope *S, ExprArg Base, - SourceLocation LLoc, - ExprArg Idx, - SourceLocation RLoc) { - Out << __FUNCTION__ << "\n"; - return ExprEmpty(); - } - virtual OwningExprResult ActOnMemberReferenceExpr(Scope *S, ExprArg Base, - SourceLocation OpLoc, - tok::TokenKind OpKind, - SourceLocation MemberLoc, - IdentifierInfo &Member, - DeclPtrTy ImplDecl) { - Out << __FUNCTION__ << "\n"; - return ExprEmpty(); - } - - virtual OwningExprResult ActOnCallExpr(Scope *S, ExprArg Fn, - SourceLocation LParenLoc, - MultiExprArg Args, - SourceLocation *CommaLocs, - SourceLocation RParenLoc) { - Out << __FUNCTION__ << "\n"; - return ExprEmpty(); - } - - // Unary Operators. 'Tok' is the token for the operator. - virtual OwningExprResult ActOnUnaryOp(Scope *S, SourceLocation OpLoc, - tok::TokenKind Op, ExprArg Input) { - Out << __FUNCTION__ << "\n"; - return ExprEmpty(); - } - virtual OwningExprResult - ActOnSizeOfAlignOfExpr(SourceLocation OpLoc, bool isSizeof, bool isType, - void *TyOrEx, const SourceRange &ArgRange) { - Out << __FUNCTION__ << "\n"; - return ExprEmpty(); - } - - virtual OwningExprResult ActOnCompoundLiteral(SourceLocation LParen, - TypeTy *Ty, - SourceLocation RParen, - ExprArg Op) { - Out << __FUNCTION__ << "\n"; - return ExprEmpty(); - } - virtual OwningExprResult ActOnInitList(SourceLocation LParenLoc, - MultiExprArg InitList, - SourceLocation RParenLoc) { - Out << __FUNCTION__ << "\n"; - return ExprEmpty(); - } - virtual OwningExprResult ActOnCastExpr(SourceLocation LParenLoc, TypeTy *Ty, - SourceLocation RParenLoc,ExprArg Op){ - Out << __FUNCTION__ << "\n"; - return ExprEmpty(); - } - - virtual OwningExprResult ActOnBinOp(Scope *S, SourceLocation TokLoc, - tok::TokenKind Kind, - ExprArg LHS, ExprArg RHS) { - Out << __FUNCTION__ << "\n"; - return ExprEmpty(); - } - - /// ActOnConditionalOp - Parse a ?: operation. Note that 'LHS' may be null - /// in the case of a the GNU conditional expr extension. - virtual OwningExprResult ActOnConditionalOp(SourceLocation QuestionLoc, - SourceLocation ColonLoc, - ExprArg Cond, ExprArg LHS, - ExprArg RHS) { - Out << __FUNCTION__ << "\n"; - return ExprEmpty(); - } - - //===--------------------- GNU Extension Expressions ------------------===// - - virtual OwningExprResult ActOnAddrLabel(SourceLocation OpLoc, - SourceLocation LabLoc, - IdentifierInfo *LabelII) {// "&&foo" - Out << __FUNCTION__ << "\n"; - return ExprEmpty(); - } - - virtual OwningExprResult ActOnStmtExpr(SourceLocation LPLoc, - StmtArg SubStmt, - SourceLocation RPLoc) { // "({..})" - Out << __FUNCTION__ << "\n"; - return ExprEmpty(); - } - - virtual OwningExprResult ActOnBuiltinOffsetOf(Scope *S, - SourceLocation BuiltinLoc, - SourceLocation TypeLoc, - TypeTy *Arg1, - OffsetOfComponent *CompPtr, - unsigned NumComponents, - SourceLocation RParenLoc) { - Out << __FUNCTION__ << "\n"; - return ExprEmpty(); - } - - // __builtin_types_compatible_p(type1, type2) - virtual OwningExprResult ActOnTypesCompatibleExpr(SourceLocation BuiltinLoc, - TypeTy *arg1,TypeTy *arg2, - SourceLocation RPLoc) { - Out << __FUNCTION__ << "\n"; - return ExprEmpty(); - } - // __builtin_choose_expr(constExpr, expr1, expr2) - virtual OwningExprResult ActOnChooseExpr(SourceLocation BuiltinLoc, - ExprArg cond, ExprArg expr1, - ExprArg expr2, - SourceLocation RPLoc) { - Out << __FUNCTION__ << "\n"; - return ExprEmpty(); - } - - // __builtin_va_arg(expr, type) - virtual OwningExprResult ActOnVAArg(SourceLocation BuiltinLoc, - ExprArg expr, TypeTy *type, - SourceLocation RPLoc) { - Out << __FUNCTION__ << "\n"; - return ExprEmpty(); - } - - virtual OwningExprResult ActOnGNUNullExpr(SourceLocation TokenLoc) { - Out << __FUNCTION__ << "\n"; - return ExprEmpty(); - } - - virtual void ActOnBlockStart(SourceLocation CaretLoc, Scope *CurScope) { - Out << __FUNCTION__ << "\n"; - } - - virtual void ActOnBlockArguments(Declarator &ParamInfo, Scope *CurScope) { - Out << __FUNCTION__ << "\n"; - } - - virtual void ActOnBlockError(SourceLocation CaretLoc, Scope *CurScope) { - Out << __FUNCTION__ << "\n"; - } - - virtual OwningExprResult ActOnBlockStmtExpr(SourceLocation CaretLoc, - StmtArg Body, - Scope *CurScope) { - Out << __FUNCTION__ << "\n"; - return ExprEmpty(); - } - - virtual DeclPtrTy ActOnStartNamespaceDef(Scope *S, SourceLocation IdentLoc, - IdentifierInfo *Ident, - SourceLocation LBrace) { - Out << __FUNCTION__ << "\n"; - return DeclPtrTy(); - } - - virtual void ActOnFinishNamespaceDef(DeclPtrTy Dcl, SourceLocation RBrace) { - Out << __FUNCTION__ << "\n"; - return; - } - -#if 0 - // FIXME: AttrList should be deleted by this function, but the definition - // would have to be available. - virtual DeclPtrTy ActOnUsingDirective(Scope *CurScope, - SourceLocation UsingLoc, - SourceLocation NamespcLoc, - const CXXScopeSpec &SS, - SourceLocation IdentLoc, - IdentifierInfo *NamespcName, - AttributeList *AttrList) { - Out << __FUNCTION__ << "\n"; - return DeclPtrTy(); - } -#endif - - virtual void ActOnParamDefaultArgument(DeclPtrTy param, - SourceLocation EqualLoc, - ExprArg defarg) { - Out << __FUNCTION__ << "\n"; - } - - virtual void ActOnParamUnparsedDefaultArgument(DeclPtrTy param, - SourceLocation EqualLoc) { - Out << __FUNCTION__ << "\n"; - } - - virtual void ActOnParamDefaultArgumentError(DeclPtrTy param) { - Out << __FUNCTION__ << "\n"; - } - - virtual void AddCXXDirectInitializerToDecl(DeclPtrTy Dcl, - SourceLocation LParenLoc, - MultiExprArg Exprs, - SourceLocation *CommaLocs, - SourceLocation RParenLoc) { - Out << __FUNCTION__ << "\n"; - return; - } - - virtual void ActOnStartDelayedCXXMethodDeclaration(Scope *S, - DeclPtrTy Method) - { - Out << __FUNCTION__ << "\n"; - } - - virtual void ActOnDelayedCXXMethodParameter(Scope *S, DeclPtrTy Param) { - Out << __FUNCTION__ << "\n"; - } - - virtual void ActOnFinishDelayedCXXMethodDeclaration(Scope *S, - DeclPtrTy Method) { - Out << __FUNCTION__ << "\n"; - } - - virtual DeclPtrTy ActOnStaticAssertDeclaration(SourceLocation AssertLoc, - ExprArg AssertExpr, - ExprArg AssertMessageExpr) { - Out << __FUNCTION__ << "\n"; - return DeclPtrTy(); - } - - virtual OwningExprResult ActOnCXXNamedCast(SourceLocation OpLoc, - tok::TokenKind Kind, - SourceLocation LAngleBracketLoc, - TypeTy *Ty, - SourceLocation RAngleBracketLoc, - SourceLocation LParenLoc, - ExprArg Op, - SourceLocation RParenLoc) { - Out << __FUNCTION__ << "\n"; - return ExprEmpty(); - } - - virtual OwningExprResult ActOnCXXTypeid(SourceLocation OpLoc, - SourceLocation LParenLoc, - bool isType, void *TyOrExpr, - SourceLocation RParenLoc) { - Out << __FUNCTION__ << "\n"; - return ExprEmpty(); - } - - virtual OwningExprResult ActOnCXXThis(SourceLocation ThisLoc) { - Out << __FUNCTION__ << "\n"; - return ExprEmpty(); - } - - virtual OwningExprResult ActOnCXXBoolLiteral(SourceLocation OpLoc, - tok::TokenKind Kind) { - Out << __FUNCTION__ << "\n"; - return ExprEmpty(); - } - - virtual OwningExprResult ActOnCXXThrow(SourceLocation OpLoc, ExprArg Op) { - Out << __FUNCTION__ << "\n"; - return ExprEmpty(); - } - - virtual OwningExprResult ActOnCXXTypeConstructExpr(SourceRange TypeRange, - TypeTy *TypeRep, - SourceLocation LParenLoc, - MultiExprArg Exprs, - SourceLocation *CommaLocs, - SourceLocation RParenLoc) { - Out << __FUNCTION__ << "\n"; - return ExprEmpty(); - } - - virtual OwningExprResult ActOnCXXConditionDeclarationExpr(Scope *S, - SourceLocation StartLoc, - Declarator &D, - SourceLocation EqualLoc, - ExprArg AssignExprVal) { - Out << __FUNCTION__ << "\n"; - return ExprEmpty(); - } - - virtual OwningExprResult ActOnCXXNew(SourceLocation StartLoc, - bool UseGlobal, - SourceLocation PlacementLParen, - MultiExprArg PlacementArgs, - SourceLocation PlacementRParen, - bool ParenTypeId, Declarator &D, - SourceLocation ConstructorLParen, - MultiExprArg ConstructorArgs, - SourceLocation ConstructorRParen) { - Out << __FUNCTION__ << "\n"; - return ExprEmpty(); - } - - virtual OwningExprResult ActOnCXXDelete(SourceLocation StartLoc, - bool UseGlobal, bool ArrayForm, - ExprArg Operand) { - Out << __FUNCTION__ << "\n"; - return ExprEmpty(); - } - - virtual OwningExprResult ActOnUnaryTypeTrait(UnaryTypeTrait OTT, - SourceLocation KWLoc, - SourceLocation LParen, - TypeTy *Ty, - SourceLocation RParen) { - Out << __FUNCTION__ << "\n"; - return ExprEmpty(); - } - }; -} - -MinimalAction *clang::CreatePrintParserActionsAction(Preprocessor &PP, - llvm::raw_ostream* OS) { - return new ParserPrintActions(PP, *OS); -} diff --git a/clang/tools/clang-cc/PrintPreprocessedOutput.cpp b/clang/tools/clang-cc/PrintPreprocessedOutput.cpp deleted file mode 100644 index 429b8296490..00000000000 --- a/clang/tools/clang-cc/PrintPreprocessedOutput.cpp +++ /dev/null @@ -1,468 +0,0 @@ -//===--- PrintPreprocessedOutput.cpp - Implement the -E mode --------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This code simply runs the preprocessor on the input file and prints out the -// result. This is the traditional behavior of the -E option. -// -//===----------------------------------------------------------------------===// - -#include "clang/Basic/SourceManager.h" -#include "clang-cc.h" -#include "clang/Lex/MacroInfo.h" -#include "clang/Lex/PPCallbacks.h" -#include "clang/Lex/Preprocessor.h" -#include "clang/Lex/Pragma.h" -#include "clang/Lex/TokenConcatenation.h" -#include "clang/Basic/SourceManager.h" -#include "clang/Basic/Diagnostic.h" -#include "llvm/ADT/SmallString.h" -#include "llvm/ADT/StringExtras.h" -#include "llvm/System/Path.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Config/config.h" -#include "llvm/Support/raw_ostream.h" -#include <cstdio> -using namespace clang; - -/// PrintMacroDefinition - Print a macro definition in a form that will be -/// properly accepted back as a definition. -static void PrintMacroDefinition(const IdentifierInfo &II, const MacroInfo &MI, - Preprocessor &PP, llvm::raw_ostream &OS) { - OS << "#define " << II.getName(); - - if (MI.isFunctionLike()) { - OS << '('; - if (MI.arg_empty()) - ; - else if (MI.getNumArgs() == 1) - OS << (*MI.arg_begin())->getName(); - else { - MacroInfo::arg_iterator AI = MI.arg_begin(), E = MI.arg_end(); - OS << (*AI++)->getName(); - while (AI != E) - OS << ',' << (*AI++)->getName(); - } - - if (MI.isVariadic()) { - if (!MI.arg_empty()) - OS << ','; - OS << "..."; - } - OS << ')'; - } - - // GCC always emits a space, even if the macro body is empty. However, do not - // want to emit two spaces if the first token has a leading space. - if (MI.tokens_empty() || !MI.tokens_begin()->hasLeadingSpace()) - OS << ' '; - - llvm::SmallVector<char, 128> SpellingBuffer; - for (MacroInfo::tokens_iterator I = MI.tokens_begin(), E = MI.tokens_end(); - I != E; ++I) { - if (I->hasLeadingSpace()) - OS << ' '; - - // Make sure we have enough space in the spelling buffer. - if (I->getLength() < SpellingBuffer.size()) - SpellingBuffer.resize(I->getLength()); - const char *Buffer = &SpellingBuffer[0]; - unsigned SpellingLen = PP.getSpelling(*I, Buffer); - OS.write(Buffer, SpellingLen); - } -} - -//===----------------------------------------------------------------------===// -// Preprocessed token printer -//===----------------------------------------------------------------------===// - -namespace { -class PrintPPOutputPPCallbacks : public PPCallbacks { - Preprocessor &PP; - TokenConcatenation ConcatInfo; -public: - llvm::raw_ostream &OS; -private: - unsigned CurLine; - bool EmittedTokensOnThisLine; - SrcMgr::CharacteristicKind FileType; - llvm::SmallString<512> CurFilename; - bool Initialized; - bool DisableLineMarkers; - bool DumpDefines; -public: - PrintPPOutputPPCallbacks(Preprocessor &pp, llvm::raw_ostream &os, - bool lineMarkers, bool defines) - : PP(pp), ConcatInfo(PP), OS(os), DisableLineMarkers(lineMarkers), - DumpDefines(defines) { - CurLine = 0; - CurFilename += "<uninit>"; - EmittedTokensOnThisLine = false; - FileType = SrcMgr::C_User; - Initialized = false; - } - - void SetEmittedTokensOnThisLine() { EmittedTokensOnThisLine = true; } - bool hasEmittedTokensOnThisLine() const { return EmittedTokensOnThisLine; } - - virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason, - SrcMgr::CharacteristicKind FileType); - virtual void Ident(SourceLocation Loc, const std::string &str); - virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind, - const std::string &Str); - - - bool HandleFirstTokOnLine(Token &Tok); - bool MoveToLine(SourceLocation Loc); - bool AvoidConcat(const Token &PrevTok, const Token &Tok) { - return ConcatInfo.AvoidConcat(PrevTok, Tok); - } - void WriteLineInfo(unsigned LineNo, const char *Extra=0, unsigned ExtraLen=0); - - /// MacroDefined - This hook is called whenever a macro definition is seen. - void MacroDefined(const IdentifierInfo *II, const MacroInfo *MI); - -}; -} // end anonymous namespace - -void PrintPPOutputPPCallbacks::WriteLineInfo(unsigned LineNo, - const char *Extra, - unsigned ExtraLen) { - if (EmittedTokensOnThisLine) { - OS << '\n'; - EmittedTokensOnThisLine = false; - } - - OS << '#' << ' ' << LineNo << ' ' << '"'; - OS.write(&CurFilename[0], CurFilename.size()); - OS << '"'; - - if (ExtraLen) - OS.write(Extra, ExtraLen); - - if (FileType == SrcMgr::C_System) - OS.write(" 3", 2); - else if (FileType == SrcMgr::C_ExternCSystem) - OS.write(" 3 4", 4); - OS << '\n'; -} - -/// MoveToLine - Move the output to the source line specified by the location -/// object. We can do this by emitting some number of \n's, or be emitting a -/// #line directive. This returns false if already at the specified line, true -/// if some newlines were emitted. -bool PrintPPOutputPPCallbacks::MoveToLine(SourceLocation Loc) { - unsigned LineNo = PP.getSourceManager().getInstantiationLineNumber(Loc); - - if (DisableLineMarkers) { - if (LineNo == CurLine) return false; - - CurLine = LineNo; - - if (!EmittedTokensOnThisLine) - return true; - - OS << '\n'; - EmittedTokensOnThisLine = false; - return true; - } - - // If this line is "close enough" to the original line, just print newlines, - // otherwise print a #line directive. - if (LineNo-CurLine <= 8) { - if (LineNo-CurLine == 1) - OS << '\n'; - else if (LineNo == CurLine) - return false; // Spelling line moved, but instantiation line didn't. - else { - const char *NewLines = "\n\n\n\n\n\n\n\n"; - OS.write(NewLines, LineNo-CurLine); - } - } else { - WriteLineInfo(LineNo, 0, 0); - } - - CurLine = LineNo; - return true; -} - - -/// FileChanged - Whenever the preprocessor enters or exits a #include file -/// it invokes this handler. Update our conception of the current source -/// position. -void PrintPPOutputPPCallbacks::FileChanged(SourceLocation Loc, - FileChangeReason Reason, - SrcMgr::CharacteristicKind NewFileType) { - // Unless we are exiting a #include, make sure to skip ahead to the line the - // #include directive was at. - SourceManager &SourceMgr = PP.getSourceManager(); - if (Reason == PPCallbacks::EnterFile) { - SourceLocation IncludeLoc = SourceMgr.getPresumedLoc(Loc).getIncludeLoc(); - if (IncludeLoc.isValid()) - MoveToLine(IncludeLoc); - } else if (Reason == PPCallbacks::SystemHeaderPragma) { - MoveToLine(Loc); - - // TODO GCC emits the # directive for this directive on the line AFTER the - // directive and emits a bunch of spaces that aren't needed. Emulate this - // strange behavior. - } - - Loc = SourceMgr.getInstantiationLoc(Loc); - // FIXME: Should use presumed line #! - CurLine = SourceMgr.getInstantiationLineNumber(Loc); - - if (DisableLineMarkers) return; - - CurFilename.clear(); - CurFilename += SourceMgr.getPresumedLoc(Loc).getFilename(); - Lexer::Stringify(CurFilename); - FileType = NewFileType; - - if (!Initialized) { - WriteLineInfo(CurLine); - Initialized = true; - } - - switch (Reason) { - case PPCallbacks::EnterFile: - WriteLineInfo(CurLine, " 1", 2); - break; - case PPCallbacks::ExitFile: - WriteLineInfo(CurLine, " 2", 2); - break; - case PPCallbacks::SystemHeaderPragma: - case PPCallbacks::RenameFile: - WriteLineInfo(CurLine); - break; - } -} - -/// Ident - Handle #ident directives when read by the preprocessor. -/// -void PrintPPOutputPPCallbacks::Ident(SourceLocation Loc, const std::string &S) { - MoveToLine(Loc); - - OS.write("#ident ", strlen("#ident ")); - OS.write(&S[0], S.size()); - EmittedTokensOnThisLine = true; -} - -/// MacroDefined - This hook is called whenever a macro definition is seen. -void PrintPPOutputPPCallbacks::MacroDefined(const IdentifierInfo *II, - const MacroInfo *MI) { - // Only print out macro definitions in -dD mode. - if (!DumpDefines || - // Ignore __FILE__ etc. - MI->isBuiltinMacro()) return; - - MoveToLine(MI->getDefinitionLoc()); - PrintMacroDefinition(*II, *MI, PP, OS); -} - - -void PrintPPOutputPPCallbacks::PragmaComment(SourceLocation Loc, - const IdentifierInfo *Kind, - const std::string &Str) { - MoveToLine(Loc); - OS << "#pragma comment(" << Kind->getName(); - - if (!Str.empty()) { - OS << ", \""; - - for (unsigned i = 0, e = Str.size(); i != e; ++i) { - unsigned char Char = Str[i]; - if (isprint(Char) && Char != '\\' && Char != '"') - OS << (char)Char; - else // Output anything hard as an octal escape. - OS << '\\' - << (char)('0'+ ((Char >> 6) & 7)) - << (char)('0'+ ((Char >> 3) & 7)) - << (char)('0'+ ((Char >> 0) & 7)); - } - OS << '"'; - } - - OS << ')'; - EmittedTokensOnThisLine = true; -} - - -/// HandleFirstTokOnLine - When emitting a preprocessed file in -E mode, this -/// is called for the first token on each new line. If this really is the start -/// of a new logical line, handle it and return true, otherwise return false. -/// This may not be the start of a logical line because the "start of line" -/// marker is set for spelling lines, not instantiation ones. -bool PrintPPOutputPPCallbacks::HandleFirstTokOnLine(Token &Tok) { - // Figure out what line we went to and insert the appropriate number of - // newline characters. - if (!MoveToLine(Tok.getLocation())) - return false; - - // Print out space characters so that the first token on a line is - // indented for easy reading. - const SourceManager &SourceMgr = PP.getSourceManager(); - unsigned ColNo = SourceMgr.getInstantiationColumnNumber(Tok.getLocation()); - - // This hack prevents stuff like: - // #define HASH # - // HASH define foo bar - // From having the # character end up at column 1, which makes it so it - // is not handled as a #define next time through the preprocessor if in - // -fpreprocessed mode. - if (ColNo <= 1 && Tok.is(tok::hash)) - OS << ' '; - - // Otherwise, indent the appropriate number of spaces. - for (; ColNo > 1; --ColNo) - OS << ' '; - - return true; -} - -namespace { -struct UnknownPragmaHandler : public PragmaHandler { - const char *Prefix; - PrintPPOutputPPCallbacks *Callbacks; - - UnknownPragmaHandler(const char *prefix, PrintPPOutputPPCallbacks *callbacks) - : PragmaHandler(0), Prefix(prefix), Callbacks(callbacks) {} - virtual void HandlePragma(Preprocessor &PP, Token &PragmaTok) { - // Figure out what line we went to and insert the appropriate number of - // newline characters. - Callbacks->MoveToLine(PragmaTok.getLocation()); - Callbacks->OS.write(Prefix, strlen(Prefix)); - - // Read and print all of the pragma tokens. - while (PragmaTok.isNot(tok::eom)) { - if (PragmaTok.hasLeadingSpace()) - Callbacks->OS << ' '; - std::string TokSpell = PP.getSpelling(PragmaTok); - Callbacks->OS.write(&TokSpell[0], TokSpell.size()); - PP.LexUnexpandedToken(PragmaTok); - } - Callbacks->OS << '\n'; - } -}; -} // end anonymous namespace - - -static void PrintPreprocessedTokens(Preprocessor &PP, Token &Tok, - PrintPPOutputPPCallbacks *Callbacks, - llvm::raw_ostream &OS) { - char Buffer[256]; - Token PrevTok; - while (1) { - - // If this token is at the start of a line, emit newlines if needed. - if (Tok.isAtStartOfLine() && Callbacks->HandleFirstTokOnLine(Tok)) { - // done. - } else if (Tok.hasLeadingSpace() || - // If we haven't emitted a token on this line yet, PrevTok isn't - // useful to look at and no concatenation could happen anyway. - (Callbacks->hasEmittedTokensOnThisLine() && - // Don't print "-" next to "-", it would form "--". - Callbacks->AvoidConcat(PrevTok, Tok))) { - OS << ' '; - } - - if (IdentifierInfo *II = Tok.getIdentifierInfo()) { - OS.write(II->getName(), II->getLength()); - } else if (Tok.isLiteral() && !Tok.needsCleaning() && - Tok.getLiteralData()) { - OS.write(Tok.getLiteralData(), Tok.getLength()); - } else if (Tok.getLength() < 256) { - const char *TokPtr = Buffer; - unsigned Len = PP.getSpelling(Tok, TokPtr); - OS.write(TokPtr, Len); - } else { - std::string S = PP.getSpelling(Tok); - OS.write(&S[0], S.size()); - } - Callbacks->SetEmittedTokensOnThisLine(); - - if (Tok.is(tok::eof)) break; - - PrevTok = Tok; - PP.Lex(Tok); - } -} - -namespace { - struct SortMacrosByID { - typedef std::pair<IdentifierInfo*, MacroInfo*> id_macro_pair; - bool operator()(const id_macro_pair &LHS, const id_macro_pair &RHS) const { - return strcmp(LHS.first->getName(), RHS.first->getName()) < 0; - } - }; -} - -void clang::DoPrintMacros(Preprocessor &PP, llvm::raw_ostream *OS) { - // -dM mode just scans and ignores all tokens in the files, then dumps out - // the macro table at the end. - PP.EnterMainSourceFile(); - - Token Tok; - do PP.Lex(Tok); - while (Tok.isNot(tok::eof)); - - std::vector<std::pair<IdentifierInfo*, MacroInfo*> > MacrosByID; - for (Preprocessor::macro_iterator I = PP.macro_begin(), E = PP.macro_end(); - I != E; ++I) - MacrosByID.push_back(*I); - std::sort(MacrosByID.begin(), MacrosByID.end(), SortMacrosByID()); - - for (unsigned i = 0, e = MacrosByID.size(); i != e; ++i) { - MacroInfo &MI = *MacrosByID[i].second; - // Ignore computed macros like __LINE__ and friends. - if (MI.isBuiltinMacro()) continue; - - PrintMacroDefinition(*MacrosByID[i].first, MI, PP, *OS); - *OS << "\n"; - } -} - -/// DoPrintPreprocessedInput - This implements -E mode. -/// -void clang::DoPrintPreprocessedInput(Preprocessor &PP, llvm::raw_ostream *OS, - bool EnableCommentOutput, - bool EnableMacroCommentOutput, - bool DisableLineMarkers, - bool DumpDefines) { - // Inform the preprocessor whether we want it to retain comments or not, due - // to -C or -CC. - PP.SetCommentRetentionState(EnableCommentOutput, EnableMacroCommentOutput); - - OS->SetBufferSize(64*1024); - - PrintPPOutputPPCallbacks *Callbacks = - new PrintPPOutputPPCallbacks(PP, *OS, DisableLineMarkers, DumpDefines); - PP.AddPragmaHandler(0, new UnknownPragmaHandler("#pragma", Callbacks)); - PP.AddPragmaHandler("GCC", new UnknownPragmaHandler("#pragma GCC", - Callbacks)); - - PP.setPPCallbacks(Callbacks); - - // After we have configured the preprocessor, enter the main file. - PP.EnterMainSourceFile(); - - // Consume all of the tokens that come from the predefines buffer. Those - // should not be emitted into the output and are guaranteed to be at the - // start. - const SourceManager &SourceMgr = PP.getSourceManager(); - Token Tok; - do PP.Lex(Tok); - while (Tok.isNot(tok::eof) && Tok.getLocation().isFileID() && - !strcmp(SourceMgr.getPresumedLoc(Tok.getLocation()).getFilename(), - "<built-in>")); - - // Read all the preprocessed tokens, printing them out to the stream. - PrintPreprocessedTokens(PP, Tok, Callbacks, *OS); - *OS << '\n'; -} - diff --git a/clang/tools/clang-cc/RewriteMacros.cpp b/clang/tools/clang-cc/RewriteMacros.cpp deleted file mode 100644 index c9c4444ad47..00000000000 --- a/clang/tools/clang-cc/RewriteMacros.cpp +++ /dev/null @@ -1,215 +0,0 @@ -//===--- RewriteMacros.cpp - Rewrite macros into their expansions ---------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This code rewrites macro invocations into their expansions. This gives you -// a macro expanded file that retains comments and #includes. -// -//===----------------------------------------------------------------------===// - -#include "clang-cc.h" -#include "clang/Rewrite/Rewriter.h" -#include "clang/Lex/Preprocessor.h" -#include "clang/Basic/SourceManager.h" -#include "llvm/Support/Streams.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/System/Path.h" -#include "llvm/ADT/OwningPtr.h" -using namespace clang; - -/// isSameToken - Return true if the two specified tokens start have the same -/// content. -static bool isSameToken(Token &RawTok, Token &PPTok) { - // If two tokens have the same kind and the same identifier info, they are - // obviously the same. - if (PPTok.getKind() == RawTok.getKind() && - PPTok.getIdentifierInfo() == RawTok.getIdentifierInfo()) - return true; - - // Otherwise, if they are different but have the same identifier info, they - // are also considered to be the same. This allows keywords and raw lexed - // identifiers with the same name to be treated the same. - if (PPTok.getIdentifierInfo() && - PPTok.getIdentifierInfo() == RawTok.getIdentifierInfo()) - return true; - - return false; -} - - -/// GetNextRawTok - Return the next raw token in the stream, skipping over -/// comments if ReturnComment is false. -static const Token &GetNextRawTok(const std::vector<Token> &RawTokens, - unsigned &CurTok, bool ReturnComment) { - assert(CurTok < RawTokens.size() && "Overran eof!"); - - // If the client doesn't want comments and we have one, skip it. - if (!ReturnComment && RawTokens[CurTok].is(tok::comment)) - ++CurTok; - - return RawTokens[CurTok++]; -} - - -/// LexRawTokensFromMainFile - Lets all the raw tokens from the main file into -/// the specified vector. -static void LexRawTokensFromMainFile(Preprocessor &PP, - std::vector<Token> &RawTokens) { - SourceManager &SM = PP.getSourceManager(); - - // Create a lexer to lex all the tokens of the main file in raw mode. Even - // though it is in raw mode, it will not return comments. - Lexer RawLex(SM.getMainFileID(), SM, PP.getLangOptions()); - - // Switch on comment lexing because we really do want them. - RawLex.SetCommentRetentionState(true); - - Token RawTok; - do { - RawLex.LexFromRawLexer(RawTok); - - // If we have an identifier with no identifier info for our raw token, look - // up the indentifier info. This is important for equality comparison of - // identifier tokens. - if (RawTok.is(tok::identifier) && !RawTok.getIdentifierInfo()) - RawTok.setIdentifierInfo(PP.LookUpIdentifierInfo(RawTok)); - - RawTokens.push_back(RawTok); - } while (RawTok.isNot(tok::eof)); -} - - -/// RewriteMacrosInInput - Implement -rewrite-macros mode. -void clang::RewriteMacrosInInput(Preprocessor &PP, llvm::raw_ostream *OS) { - SourceManager &SM = PP.getSourceManager(); - - Rewriter Rewrite; - Rewrite.setSourceMgr(SM, PP.getLangOptions()); - RewriteBuffer &RB = Rewrite.getEditBuffer(SM.getMainFileID()); - - std::vector<Token> RawTokens; - LexRawTokensFromMainFile(PP, RawTokens); - unsigned CurRawTok = 0; - Token RawTok = GetNextRawTok(RawTokens, CurRawTok, false); - - - // Get the first preprocessing token. - PP.EnterMainSourceFile(); - Token PPTok; - PP.Lex(PPTok); - - // Preprocess the input file in parallel with raw lexing the main file. Ignore - // all tokens that are preprocessed from a file other than the main file (e.g. - // a header). If we see tokens that are in the preprocessed file but not the - // lexed file, we have a macro expansion. If we see tokens in the lexed file - // that aren't in the preprocessed view, we have macros that expand to no - // tokens, or macro arguments etc. - while (RawTok.isNot(tok::eof) || PPTok.isNot(tok::eof)) { - SourceLocation PPLoc = SM.getInstantiationLoc(PPTok.getLocation()); - - // If PPTok is from a different source file, ignore it. - if (!SM.isFromMainFile(PPLoc)) { - PP.Lex(PPTok); - continue; - } - - // If the raw file hits a preprocessor directive, they will be extra tokens - // in the raw file that don't exist in the preprocsesed file. However, we - // choose to preserve them in the output file and otherwise handle them - // specially. - if (RawTok.is(tok::hash) && RawTok.isAtStartOfLine()) { - // If this is a #warning directive or #pragma mark (GNU extensions), - // comment the line out. - if (RawTokens[CurRawTok].is(tok::identifier)) { - const IdentifierInfo *II = RawTokens[CurRawTok].getIdentifierInfo(); - if (!strcmp(II->getName(), "warning")) { - // Comment out #warning. - RB.InsertTextAfter(SM.getFileOffset(RawTok.getLocation()), "//", 2); - } else if (!strcmp(II->getName(), "pragma") && - RawTokens[CurRawTok+1].is(tok::identifier) && - !strcmp(RawTokens[CurRawTok+1].getIdentifierInfo()->getName(), - "mark")){ - // Comment out #pragma mark. - RB.InsertTextAfter(SM.getFileOffset(RawTok.getLocation()), "//", 2); - } - } - - // Otherwise, if this is a #include or some other directive, just leave it - // in the file by skipping over the line. - RawTok = GetNextRawTok(RawTokens, CurRawTok, false); - while (!RawTok.isAtStartOfLine() && RawTok.isNot(tok::eof)) - RawTok = GetNextRawTok(RawTokens, CurRawTok, false); - continue; - } - - // Okay, both tokens are from the same file. Get their offsets from the - // start of the file. - unsigned PPOffs = SM.getFileOffset(PPLoc); - unsigned RawOffs = SM.getFileOffset(RawTok.getLocation()); - - // If the offsets are the same and the token kind is the same, ignore them. - if (PPOffs == RawOffs && isSameToken(RawTok, PPTok)) { - RawTok = GetNextRawTok(RawTokens, CurRawTok, false); - PP.Lex(PPTok); - continue; - } - - // If the PP token is farther along than the raw token, something was - // deleted. Comment out the raw token. - if (RawOffs <= PPOffs) { - // Comment out a whole run of tokens instead of bracketing each one with - // comments. Add a leading space if RawTok didn't have one. - bool HasSpace = RawTok.hasLeadingSpace(); - RB.InsertTextAfter(RawOffs, " /*"+HasSpace, 2+!HasSpace); - unsigned EndPos; - - do { - EndPos = RawOffs+RawTok.getLength(); - - RawTok = GetNextRawTok(RawTokens, CurRawTok, true); - RawOffs = SM.getFileOffset(RawTok.getLocation()); - - if (RawTok.is(tok::comment)) { - // Skip past the comment. - RawTok = GetNextRawTok(RawTokens, CurRawTok, false); - break; - } - - } while (RawOffs <= PPOffs && !RawTok.isAtStartOfLine() && - (PPOffs != RawOffs || !isSameToken(RawTok, PPTok))); - - RB.InsertTextBefore(EndPos, "*/", 2); - continue; - } - - // Otherwise, there was a replacement an expansion. Insert the new token - // in the output buffer. Insert the whole run of new tokens at once to get - // them in the right order. - unsigned InsertPos = PPOffs; - std::string Expansion; - while (PPOffs < RawOffs) { - Expansion += ' ' + PP.getSpelling(PPTok); - PP.Lex(PPTok); - PPLoc = SM.getInstantiationLoc(PPTok.getLocation()); - PPOffs = SM.getFileOffset(PPLoc); - } - Expansion += ' '; - RB.InsertTextBefore(InsertPos, &Expansion[0], Expansion.size()); - } - - // Get the buffer corresponding to MainFileID. If we haven't changed it, then - // we are done. - if (const RewriteBuffer *RewriteBuf = - Rewrite.getRewriteBufferFor(SM.getMainFileID())) { - //printf("Changed:\n"); - *OS << std::string(RewriteBuf->begin(), RewriteBuf->end()); - } else { - fprintf(stderr, "No changes\n"); - } - OS->flush(); -} diff --git a/clang/tools/clang-cc/RewriteTest.cpp b/clang/tools/clang-cc/RewriteTest.cpp deleted file mode 100644 index c4b3a779565..00000000000 --- a/clang/tools/clang-cc/RewriteTest.cpp +++ /dev/null @@ -1,39 +0,0 @@ -//===--- RewriteTest.cpp - Rewriter playground ----------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This is a testbed. -// -//===----------------------------------------------------------------------===// - -#include "clang-cc.h" -#include "clang/Lex/Preprocessor.h" -#include "clang/Rewrite/TokenRewriter.h" -#include "llvm/Support/raw_ostream.h" - -void clang::DoRewriteTest(Preprocessor &PP, llvm::raw_ostream* OS) { - SourceManager &SM = PP.getSourceManager(); - const LangOptions &LangOpts = PP.getLangOptions(); - - TokenRewriter Rewriter(SM.getMainFileID(), SM, LangOpts); - - // Throw <i> </i> tags around comments. - for (TokenRewriter::token_iterator I = Rewriter.token_begin(), - E = Rewriter.token_end(); I != E; ++I) { - if (I->isNot(tok::comment)) continue; - - Rewriter.AddTokenBefore(I, "<i>"); - Rewriter.AddTokenAfter(I, "</i>"); - } - - - // Print out the output. - for (TokenRewriter::token_iterator I = Rewriter.token_begin(), - E = Rewriter.token_end(); I != E; ++I) - *OS << PP.getSpelling(*I); -} diff --git a/clang/tools/clang-cc/Warnings.cpp b/clang/tools/clang-cc/Warnings.cpp deleted file mode 100644 index b3e21e10527..00000000000 --- a/clang/tools/clang-cc/Warnings.cpp +++ /dev/null @@ -1,106 +0,0 @@ -//===--- Warnings.cpp - C-Language Front-end ------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Command line warning options handler. -// -//===----------------------------------------------------------------------===// -// -// This file is responsible for handling all warning options. This includes -// a number of -Wfoo options and their variants, which are driven by TableGen- -// generated data, and the special cases -pedantic, -pedantic-errors, -w and -// -Werror. -// -// Each warning option controls any number of actual warnings. -// Given a warning option 'foo', the following are valid: -// -Wfoo, -Wno-foo, -Werror=foo -// -#include "clang-cc.h" -#include "clang/Basic/Diagnostic.h" -#include "clang/Sema/SemaDiagnostic.h" -#include "clang/Lex/LexDiagnostic.h" -#include "llvm/Support/CommandLine.h" -#include <cstdio> -#include <utility> -#include <algorithm> -using namespace clang; - -bool clang::ProcessWarningOptions(Diagnostic &Diags, - std::vector<std::string> &Warnings, - bool Pedantic, bool PedanticErrors, - bool NoWarnings) { - Diags.setSuppressSystemWarnings(true); // Default to -Wno-system-headers - Diags.setIgnoreAllWarnings(NoWarnings); - - // If -pedantic or -pedantic-errors was specified, then we want to map all - // extension diagnostics onto WARNING or ERROR unless the user has futz'd - // around with them explicitly. - if (PedanticErrors) - Diags.setExtensionHandlingBehavior(Diagnostic::Ext_Error); - else if (Pedantic) - Diags.setExtensionHandlingBehavior(Diagnostic::Ext_Warn); - else - Diags.setExtensionHandlingBehavior(Diagnostic::Ext_Ignore); - - // FIXME: -Wfatal-errors / -Wfatal-errors=foo - - for (unsigned i = 0, e = Warnings.size(); i != e; ++i) { - const std::string &Opt = Warnings[i]; - const char *OptStart = &Opt[0]; - const char *OptEnd = OptStart+Opt.size(); - assert(*OptEnd == 0 && "Expect null termination for lower-bound search"); - - // Check to see if this warning starts with "no-", if so, this is a negative - // form of the option. - bool isPositive = true; - if (OptEnd-OptStart > 3 && memcmp(OptStart, "no-", 3) == 0) { - isPositive = false; - OptStart += 3; - } - - // Figure out how this option affects the warning. If -Wfoo, map the - // diagnostic to a warning, if -Wno-foo, map it to ignore. - diag::Mapping Mapping = isPositive ? diag::MAP_WARNING : diag::MAP_IGNORE; - - // -Wsystem-headers is a special case, not driven by the option table. It - // cannot be controlled with -Werror. - if (OptEnd-OptStart == 14 && memcmp(OptStart, "system-headers", 14) == 0) { - Diags.setSuppressSystemWarnings(!isPositive); - continue; - } - - // -Werror/-Wno-error is a special case, not controlled by the option table. - // It also has the "specifier" form of -Werror=foo and -Werror-foo. - if (OptEnd-OptStart >= 5 && memcmp(OptStart, "error", 5) == 0) { - const char *Specifier = 0; - if (OptEnd-OptStart != 5) { // Specifier must be present. - if ((OptStart[5] != '=' && OptStart[5] != '-') || - OptEnd-OptStart == 6) { - fprintf(stderr, "warning: unknown -Werror warning specifier: -W%s\n", - Opt.c_str()); - continue; - } - Specifier = OptStart+6; - } - - if (Specifier == 0) { - Diags.setWarningsAsErrors(true); - continue; - } - - // -Werror=foo maps foo to Error, -Wno-error=foo maps it to Warning. - Mapping = isPositive ? diag::MAP_ERROR : diag::MAP_WARNING_NO_WERROR; - OptStart = Specifier; - } - - if (Diags.setDiagnosticGroupMapping(OptStart, Mapping)) - fprintf(stderr, "warning: unknown warning option: -W%s\n", Opt.c_str()); - } - - return false; -} diff --git a/clang/tools/clang-cc/clang-cc.cpp b/clang/tools/clang-cc/clang-cc.cpp index 40333d22d30..51b3ffda274 100644 --- a/clang/tools/clang-cc/clang-cc.cpp +++ b/clang/tools/clang-cc/clang-cc.cpp @@ -22,7 +22,6 @@ // //===----------------------------------------------------------------------===// -#include "clang-cc.h" #include "AnalysisConsumer.h" #include "clang/Frontend/ASTConsumers.h" #include "clang/Frontend/CompileOptions.h" @@ -34,6 +33,7 @@ #include "clang/Frontend/PCHReader.h" #include "clang/Frontend/TextDiagnosticBuffer.h" #include "clang/Frontend/TextDiagnosticPrinter.h" +#include "clang/Frontend/Utils.h" #include "clang/Analysis/PathDiagnostic.h" #include "clang/CodeGen/ModuleBuilder.h" #include "clang/Sema/ParseAST.h" diff --git a/clang/tools/clang-cc/clang-cc.h b/clang/tools/clang-cc/clang-cc.h deleted file mode 100644 index 354d73b9ac5..00000000000 --- a/clang/tools/clang-cc/clang-cc.h +++ /dev/null @@ -1,79 +0,0 @@ -//===--- clang-cc.h - C-Language Front-end --------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This is the header file that pulls together the top-level driver. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_CLANG_CC_H -#define LLVM_CLANG_CLANG_CC_H - -#include <vector> -#include <string> - -namespace llvm { -class raw_ostream; -class raw_fd_ostream; -} - -namespace clang { -class Preprocessor; -class MinimalAction; -class TargetInfo; -class Diagnostic; -class ASTConsumer; -class IdentifierTable; -class SourceManager; -class PreprocessorFactory; -class LangOptions; - -/// ProcessWarningOptions - Initialize the diagnostic client and process the -/// warning options specified on the command line. -bool ProcessWarningOptions(Diagnostic &Diags, - std::vector<std::string> &Warnings, - bool Pedantic, bool PedanticErrors, - bool NoWarnings); - -/// DoPrintPreprocessedInput - Implement -E -dM mode. -void DoPrintMacros(Preprocessor &PP, llvm::raw_ostream* OS); - -/// DoPrintPreprocessedInput - Implement -E mode. -void DoPrintPreprocessedInput(Preprocessor &PP, llvm::raw_ostream* OS, - bool EnableCommentOutput, - bool EnableMacroCommentOutput, - bool DisableLineMarkers, - bool DumpDefines); - -/// RewriteMacrosInInput - Implement -rewrite-macros mode. -void RewriteMacrosInInput(Preprocessor &PP, llvm::raw_ostream* OS); - -/// RewriteMacrosInInput - A simple test for the TokenRewriter class. -void DoRewriteTest(Preprocessor &PP, llvm::raw_ostream* OS); - -/// CreatePrintParserActionsAction - Return the actions implementation that -/// implements the -parse-print-callbacks option. -MinimalAction *CreatePrintParserActionsAction(Preprocessor &PP, - llvm::raw_ostream* OS); - -/// CheckDiagnostics - Gather the expected diagnostics and check them. -bool CheckDiagnostics(Preprocessor &PP); - -/// AttachDependencyFileGen - Create a dependency file generator, and attach -/// it to the given preprocessor. This takes ownership of the output stream. -void AttachDependencyFileGen(Preprocessor *PP, llvm::raw_ostream *OS, - std::vector<std::string> &Targets, - bool IncludeSystemHeaders, bool PhonyTarget); - -/// CacheTokens - Cache tokens for use with PCH. Note that this requires -/// a seekable stream. -void CacheTokens(Preprocessor& PP, llvm::raw_fd_ostream* OS); - -} // end namespace clang - -#endif |

