User-defined literal support for character literals.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@152277 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Lex/LiteralSupport.cpp b/lib/Lex/LiteralSupport.cpp
index e3ff77f..e0bdc5f 100644
--- a/lib/Lex/LiteralSupport.cpp
+++ b/lib/Lex/LiteralSupport.cpp
@@ -791,6 +791,7 @@
       --end;
     } while (end[-1] != '\'');
     UDSuffixBuf.assign(end, UDSuffixEnd);
+    UDSuffixOffset = end - begin + 1;
   }
 
   // Trim the ending quote.
@@ -1113,6 +1114,8 @@
 
       if (UDSuffixBuf.empty()) {
         UDSuffixBuf.assign(UDSuffix);
+        UDSuffixToken = i;
+        UDSuffixOffset = ThisTokEnd - ThisTokBuf;
         UDSuffixTokLoc = StringToks[i].getLocation();
       } else if (!UDSuffixBuf.equals(UDSuffix)) {
         // C++11 [lex.ext]p8: At the end of phase 6, if a string literal is the
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 7d99732..f82ff43 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -1122,6 +1122,14 @@
                  ResultIndex));
 }
 
+/// getUDSuffixLoc - Create a SourceLocation for a ud-suffix, given the
+/// location of the token and the offset of the ud-suffix within it.
+static SourceLocation getUDSuffixLoc(Sema &S, SourceLocation TokLoc,
+                                     unsigned Offset) {
+  return Lexer::AdvanceToTokenCharacter(TokLoc, Offset, S.getSourceManager(),
+                                        S.getLangOptions());
+}
+
 /// ActOnStringLiteral - The specified tokens were lexed as pasted string
 /// fragments (e.g. "foo" "bar" L"baz").  The result string has to handle string
 /// concatenation ([C99 5.1.1.2, translation phase #6]), so it may come from
@@ -1181,8 +1189,9 @@
 
   // We're building a user-defined literal.
   IdentifierInfo *UDSuffix = &Context.Idents.get(Literal.getUDSuffix());
-  SourceLocation UDSuffixLoc = StringTokLocs[0];
-  // FIXME: = Literal.getUDSuffixLoc(getSourceManager());
+  SourceLocation UDSuffixLoc =
+    getUDSuffixLoc(*this, StringTokLocs[Literal.getUDSuffixToken()],
+                   Literal.getUDSuffixOffset());
 
   // C++11 [lex.ext]p5: The literal L is treated as a call of the form
   //   operator "" X (str, len)
@@ -2404,8 +2413,22 @@
   else if (Literal.isUTF32())
     Kind = CharacterLiteral::UTF32;
 
-  return Owned(new (Context) CharacterLiteral(Literal.getValue(), Kind, Ty,
-                                              Tok.getLocation()));
+  Expr *Lit = new (Context) CharacterLiteral(Literal.getValue(), Kind, Ty,
+                                             Tok.getLocation());
+
+  if (Literal.getUDSuffix().empty())
+    return Owned(Lit);
+
+  // We're building a user-defined literal.
+  IdentifierInfo *UDSuffix = &Context.Idents.get(Literal.getUDSuffix());
+  SourceLocation UDSuffixLoc =
+    getUDSuffixLoc(*this, Tok.getLocation(), Literal.getUDSuffixOffset());
+
+  // C++11 [lex.ext]p6: The literal L is treated as a call of the form
+  //   operator "" X (ch)
+  return BuildLiteralOperatorCall(UDSuffix, UDSuffixLoc,
+                                  llvm::makeArrayRef(&Lit, 1),
+                                  Tok.getLocation());
 }
 
 ExprResult Sema::ActOnIntegerConstant(SourceLocation Loc, uint64_t Val) {