Introduce Lexer::getSourceText() that returns a string for the source
that the given source range encompasses.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@148481 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Lex/Lexer.cpp b/lib/Lex/Lexer.cpp
index 1a469be..12cb767 100644
--- a/lib/Lex/Lexer.cpp
+++ b/lib/Lex/Lexer.cpp
@@ -813,6 +813,9 @@
 
   // 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 @@
   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) {