summaryrefslogtreecommitdiffstats
path: root/clang/lib/Rewrite/TokenRewriter.cpp
diff options
context:
space:
mode:
authorAlp Toker <alp@nuanti.com>2014-07-16 16:48:33 +0000
committerAlp Toker <alp@nuanti.com>2014-07-16 16:48:33 +0000
commit0621cb2e7dfd89f558a045f145f900b62379dcc2 (patch)
treefe7aa0e9718ccaa2199ec99044c72add529205d8 /clang/lib/Rewrite/TokenRewriter.cpp
parentdb829de6d6a3dd4c13b0ee75ac35e42b7b92b7e6 (diff)
downloadbcm5719-llvm-0621cb2e7dfd89f558a045f145f900b62379dcc2.tar.gz
bcm5719-llvm-0621cb2e7dfd89f558a045f145f900b62379dcc2.zip
Make clang's rewrite engine a core feature
The rewrite facility's footprint is small so it's not worth going to these lengths to support disabling at configure time, particularly since key compiler features now depend on it. Meanwhile the Objective-C rewriters have been moved under the ENABLE_CLANG_ARCMT umbrella for now as they're comparatively heavy and still potentially worth excluding from lightweight builds. Tests are now passing with any combination of feature flags. The flags historically haven't been tested by LLVM's build servers so caveat emptor. llvm-svn: 213171
Diffstat (limited to 'clang/lib/Rewrite/TokenRewriter.cpp')
-rw-r--r--clang/lib/Rewrite/TokenRewriter.cpp99
1 files changed, 99 insertions, 0 deletions
diff --git a/clang/lib/Rewrite/TokenRewriter.cpp b/clang/lib/Rewrite/TokenRewriter.cpp
new file mode 100644
index 00000000000..494defdedaa
--- /dev/null
+++ b/clang/lib/Rewrite/TokenRewriter.cpp
@@ -0,0 +1,99 @@
+//===--- TokenRewriter.cpp - Token-based code rewriting interface ---------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the TokenRewriter class, which is used for code
+// transformations.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Rewrite/Core/TokenRewriter.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Lex/ScratchBuffer.h"
+using namespace clang;
+
+TokenRewriter::TokenRewriter(FileID FID, SourceManager &SM,
+ const LangOptions &LangOpts) {
+ ScratchBuf.reset(new ScratchBuffer(SM));
+
+ // Create a lexer to lex all the tokens of the main file in raw mode.
+ const llvm::MemoryBuffer *FromFile = SM.getBuffer(FID);
+ Lexer RawLex(FID, FromFile, SM, LangOpts);
+
+ // Return all comments and whitespace as tokens.
+ RawLex.SetKeepWhitespaceMode(true);
+
+ // Lex the file, populating our datastructures.
+ Token RawTok;
+ RawLex.LexFromRawLexer(RawTok);
+ while (RawTok.isNot(tok::eof)) {
+#if 0
+ if (Tok.is(tok::raw_identifier)) {
+ // Look up the identifier info for the token. This should use
+ // IdentifierTable directly instead of PP.
+ PP.LookUpIdentifierInfo(Tok);
+ }
+#endif
+
+ AddToken(RawTok, TokenList.end());
+ RawLex.LexFromRawLexer(RawTok);
+ }
+}
+
+TokenRewriter::~TokenRewriter() {
+}
+
+
+/// RemapIterator - Convert from token_iterator (a const iterator) to
+/// TokenRefTy (a non-const iterator).
+TokenRewriter::TokenRefTy TokenRewriter::RemapIterator(token_iterator I) {
+ if (I == token_end()) return TokenList.end();
+
+ // FIXME: This is horrible, we should use our own list or something to avoid
+ // this.
+ std::map<SourceLocation, TokenRefTy>::iterator MapIt =
+ TokenAtLoc.find(I->getLocation());
+ assert(MapIt != TokenAtLoc.end() && "iterator not in rewriter?");
+ return MapIt->second;
+}
+
+
+/// AddToken - Add the specified token into the Rewriter before the other
+/// position.
+TokenRewriter::TokenRefTy
+TokenRewriter::AddToken(const Token &T, TokenRefTy Where) {
+ Where = TokenList.insert(Where, T);
+
+ bool InsertSuccess = TokenAtLoc.insert(std::make_pair(T.getLocation(),
+ Where)).second;
+ assert(InsertSuccess && "Token location already in rewriter!");
+ (void)InsertSuccess;
+ return Where;
+}
+
+
+TokenRewriter::token_iterator
+TokenRewriter::AddTokenBefore(token_iterator I, const char *Val) {
+ unsigned Len = strlen(Val);
+
+ // Plop the string into the scratch buffer, then create a token for this
+ // string.
+ Token Tok;
+ Tok.startToken();
+ const char *Spelling;
+ Tok.setLocation(ScratchBuf->getToken(Val, Len, Spelling));
+ Tok.setLength(Len);
+
+ // TODO: Form a whole lexer around this and relex the token! For now, just
+ // set kind to tok::unknown.
+ Tok.setKind(tok::unknown);
+
+ return AddToken(Tok, RemapIterator(I));
+}
+
OpenPOWER on IntegriCloud