]> granicus.if.org Git - clang/commitdiff
Introduce Lexer::getSourceText() that returns a string for the source
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Thu, 19 Jan 2012 15:59:19 +0000 (15:59 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Thu, 19 Jan 2012 15:59:19 +0000 (15:59 +0000)
that the given source range encompasses.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@148481 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Lex/Lexer.h
lib/Lex/Lexer.cpp
unittests/Lex/LexerTest.cpp

index eb8ad347d62f112312f168e50ebaed7dcbb43efe..a935718e6f0c70225639e0abb63278b1ed95dbad 100644 (file)
@@ -339,6 +339,12 @@ public:
                                            const SourceManager &SM,
                                            const LangOptions &LangOpts);
 
+  /// \brief Returns a string for the source that the range encompasses.
+  static StringRef getSourceText(CharSourceRange Range,
+                                 const SourceManager &SM,
+                                 const LangOptions &LangOpts,
+                                 bool *Invalid = 0);
+
   /// \brief Retrieve the name of the immediate macro expansion.
   ///
   /// This routine starts from a source location, and finds the name of the macro
index 1a469bef488e0ad8e6dd7845061aa95e5571c97c..12cb76722bf7e4fc0618d72b32eb9372b211a3f6 100644 (file)
@@ -813,6 +813,9 @@ CharSourceRange Lexer::makeFileCharRange(SourceRange TokenRange,
 
   // Break down the source locations.
   std::pair<FileID, unsigned> beginInfo = SM.getDecomposedLoc(Begin);
+  if (beginInfo.first.isInvalid())
+    return CharSourceRange();
+
   unsigned EndOffs;
   if (!SM.isInFileID(End, beginInfo.first, &EndOffs) ||
       beginInfo.second > EndOffs)
@@ -821,6 +824,45 @@ CharSourceRange Lexer::makeFileCharRange(SourceRange TokenRange,
   return CharSourceRange::getCharRange(Begin, End);
 }
 
+StringRef Lexer::getSourceText(CharSourceRange Range,
+                               const SourceManager &SM,
+                               const LangOptions &LangOpts,
+                               bool *Invalid) {
+  if (Range.isTokenRange())
+    Range = makeFileCharRange(Range.getAsRange(), SM, LangOpts);
+
+  if (Range.isInvalid() ||
+      Range.getBegin().isMacroID() || Range.getEnd().isMacroID()) {
+    if (Invalid) *Invalid = true;
+    return StringRef();
+  }
+
+  // Break down the source location.
+  std::pair<FileID, unsigned> beginInfo = SM.getDecomposedLoc(Range.getBegin());
+  if (beginInfo.first.isInvalid()) {
+    if (Invalid) *Invalid = true;
+    return StringRef();
+  }
+
+  unsigned EndOffs;
+  if (!SM.isInFileID(Range.getEnd(), beginInfo.first, &EndOffs) ||
+      beginInfo.second > EndOffs) {
+    if (Invalid) *Invalid = true;
+    return StringRef();
+  }
+
+  // Try to the load the file buffer.
+  bool invalidTemp = false;
+  StringRef file = SM.getBufferData(beginInfo.first, &invalidTemp);
+  if (invalidTemp) {
+    if (Invalid) *Invalid = true;
+    return StringRef();
+  }
+
+  if (Invalid) *Invalid = false;
+  return file.substr(beginInfo.second, EndOffs - beginInfo.second);
+}
+
 StringRef Lexer::getImmediateMacroName(SourceLocation Loc,
                                        const SourceManager &SM,
                                        const LangOptions &LangOpts) {
index 05478eef9f43915c0afdccd7b30fe0fd1e5163a7..fecdb7fc05428e3d1dd263d02a850750452bffb5 100644 (file)
@@ -114,6 +114,11 @@ TEST_F(LexerTest, LexAPI) {
   EXPECT_EQ(range.getAsRange(),
             SourceRange(macroRange.getBegin(),
                         macroRange.getEnd().getLocWithOffset(1)));
+
+  StringRef text = Lexer::getSourceText(
+                  CharSourceRange::getTokenRange(SourceRange(lsqrLoc, rsqrLoc)),
+                  SourceMgr, LangOpts);
+  EXPECT_EQ(text, "M(foo)");
 }
 
 } // anonymous namespace