[clang] 1db5b34 - Add kinded UDL for raw literal operator and numeric literal operator template

Eduardo Caldas via cfe-commits cfe-commits at lists.llvm.org
Fri Jul 10 09:21:25 PDT 2020


Author: Eduardo Caldas
Date: 2020-07-10T16:21:11Z
New Revision: 1db5b348c4c93b6610afb4fd515b389989efc302

URL: https://github.com/llvm/llvm-project/commit/1db5b348c4c93b6610afb4fd515b389989efc302
DIFF: https://github.com/llvm/llvm-project/commit/1db5b348c4c93b6610afb4fd515b389989efc302.diff

LOG: Add kinded UDL for raw literal operator and  numeric literal operator template

Added: 
    

Modified: 
    clang/include/clang/Tooling/Syntax/Nodes.h
    clang/lib/Tooling/Syntax/BuildTree.cpp
    clang/lib/Tooling/Syntax/Nodes.cpp
    clang/unittests/Tooling/Syntax/TreeTest.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Tooling/Syntax/Nodes.h b/clang/include/clang/Tooling/Syntax/Nodes.h
index fb63c36bc4cc..d97b127638bb 100644
--- a/clang/include/clang/Tooling/Syntax/Nodes.h
+++ b/clang/include/clang/Tooling/Syntax/Nodes.h
@@ -50,7 +50,6 @@ enum class NodeKind : uint16_t {
   StringLiteralExpression,
   BoolLiteralExpression,
   CxxNullPtrExpression,
-  UnknownUserDefinedLiteralExpression,
   IntegerUserDefinedLiteralExpression,
   FloatUserDefinedLiteralExpression,
   CharUserDefinedLiteralExpression,
@@ -340,8 +339,7 @@ class UserDefinedLiteralExpression : public Expression {
 public:
   UserDefinedLiteralExpression(NodeKind K) : Expression(K) {}
   static bool classof(const Node *N) {
-    return N->kind() == NodeKind::UnknownUserDefinedLiteralExpression ||
-           N->kind() == NodeKind::IntegerUserDefinedLiteralExpression ||
+    return N->kind() == NodeKind::IntegerUserDefinedLiteralExpression ||
            N->kind() == NodeKind::FloatUserDefinedLiteralExpression ||
            N->kind() == NodeKind::CharUserDefinedLiteralExpression ||
            N->kind() == NodeKind::StringUserDefinedLiteralExpression;
@@ -349,21 +347,6 @@ class UserDefinedLiteralExpression : public Expression {
   syntax::Leaf *literalToken();
 };
 
-// We cannot yet distinguish between user-defined-integer-literal and
-// user-defined-floating-point-literal, when using raw literal operator or
-// numeric literal operator. C++ [lex.ext]p3, p4
-/// Expression for an unknown user-defined-literal.
-class UnknownUserDefinedLiteralExpression final
-    : public UserDefinedLiteralExpression {
-public:
-  UnknownUserDefinedLiteralExpression()
-      : UserDefinedLiteralExpression(
-            NodeKind::UnknownUserDefinedLiteralExpression) {}
-  static bool classof(const Node *N) {
-    return N->kind() == NodeKind::UnknownUserDefinedLiteralExpression;
-  }
-};
-
 /// Expression for user-defined-integer-literal. C++ [lex.ext]
 class IntegerUserDefinedLiteralExpression final
     : public UserDefinedLiteralExpression {

diff  --git a/clang/lib/Tooling/Syntax/BuildTree.cpp b/clang/lib/Tooling/Syntax/BuildTree.cpp
index 8204d3fc66f3..5afe4965793a 100644
--- a/clang/lib/Tooling/Syntax/BuildTree.cpp
+++ b/clang/lib/Tooling/Syntax/BuildTree.cpp
@@ -23,6 +23,7 @@
 #include "clang/Basic/Specifiers.h"
 #include "clang/Basic/TokenKinds.h"
 #include "clang/Lex/Lexer.h"
+#include "clang/Lex/LiteralSupport.h"
 #include "clang/Tooling/Syntax/Nodes.h"
 #include "clang/Tooling/Syntax/Tokens.h"
 #include "clang/Tooling/Syntax/Tree.h"
@@ -552,8 +553,8 @@ class syntax::TreeBuilder {
 namespace {
 class BuildTreeVisitor : public RecursiveASTVisitor<BuildTreeVisitor> {
 public:
-  explicit BuildTreeVisitor(ASTContext &Ctx, syntax::TreeBuilder &Builder)
-      : Builder(Builder), LangOpts(Ctx.getLangOpts()) {}
+  explicit BuildTreeVisitor(ASTContext &Context, syntax::TreeBuilder &Builder)
+      : Builder(Builder), Context(Context) {}
 
   bool shouldTraversePostOrder() const { return true; }
 
@@ -718,30 +719,44 @@ class BuildTreeVisitor : public RecursiveASTVisitor<BuildTreeVisitor> {
     return WalkUpFromUserDefinedLiteral(S);
   }
 
-  syntax::NodeKind getUserDefinedLiteralKind(UserDefinedLiteral *S) {
+  syntax::UserDefinedLiteralExpression *
+  buildUserDefinedLiteral(UserDefinedLiteral *S) {
     switch (S->getLiteralOperatorKind()) {
     case clang::UserDefinedLiteral::LOK_Integer:
-      return syntax::NodeKind::IntegerUserDefinedLiteralExpression;
+      return new (allocator()) syntax::IntegerUserDefinedLiteralExpression;
     case clang::UserDefinedLiteral::LOK_Floating:
-      return syntax::NodeKind::FloatUserDefinedLiteralExpression;
+      return new (allocator()) syntax::FloatUserDefinedLiteralExpression;
     case clang::UserDefinedLiteral::LOK_Character:
-      return syntax::NodeKind::CharUserDefinedLiteralExpression;
+      return new (allocator()) syntax::CharUserDefinedLiteralExpression;
     case clang::UserDefinedLiteral::LOK_String:
-      return syntax::NodeKind::StringUserDefinedLiteralExpression;
+      return new (allocator()) syntax::StringUserDefinedLiteralExpression;
     case clang::UserDefinedLiteral::LOK_Raw:
     case clang::UserDefinedLiteral::LOK_Template:
-      // FIXME: Apply `NumericLiteralParser` to the underlying token to deduce
-      // the right UDL kind. That would require a `Preprocessor` though.
-      return syntax::NodeKind::UnknownUserDefinedLiteralExpression;
+      // For raw literal operator and numeric literal operator template we
+      // cannot get the type of the operand in the semantic AST. We get this
+      // information from the token. As integer and floating point have the same
+      // token kind, we run `NumericLiteralParser` again to distinguish them.
+      auto TokLoc = S->getBeginLoc();
+      auto buffer = SmallVector<char, 16>();
+      bool invalidSpelling = false;
+      auto TokSpelling =
+          Lexer::getSpelling(TokLoc, buffer, Context.getSourceManager(),
+                             Context.getLangOpts(), &invalidSpelling);
+      assert(!invalidSpelling);
+      auto Literal =
+          NumericLiteralParser(TokSpelling, TokLoc, Context.getSourceManager(),
+                               Context.getLangOpts(), Context.getTargetInfo(),
+                               Context.getDiagnostics());
+      if (Literal.isIntegerLiteral())
+        return new (allocator()) syntax::IntegerUserDefinedLiteralExpression;
+      else
+        return new (allocator()) syntax::FloatUserDefinedLiteralExpression;
     }
   }
 
   bool WalkUpFromUserDefinedLiteral(UserDefinedLiteral *S) {
     Builder.markChildToken(S->getBeginLoc(), syntax::NodeRole::LiteralToken);
-    Builder.foldNode(Builder.getExprRange(S),
-                     new (allocator()) syntax::UserDefinedLiteralExpression(
-                         getUserDefinedLiteralKind(S)),
-                     S);
+    Builder.foldNode(Builder.getExprRange(S), buildUserDefinedLiteral(S), S);
     return true;
   }
 
@@ -1262,7 +1277,7 @@ class BuildTreeVisitor : public RecursiveASTVisitor<BuildTreeVisitor> {
   llvm::BumpPtrAllocator &allocator() { return Builder.allocator(); }
 
   syntax::TreeBuilder &Builder;
-  const LangOptions &LangOpts;
+  const ASTContext &Context;
 };
 } // namespace
 

diff  --git a/clang/lib/Tooling/Syntax/Nodes.cpp b/clang/lib/Tooling/Syntax/Nodes.cpp
index e1aa2521a2a9..2435ae0a91dd 100644
--- a/clang/lib/Tooling/Syntax/Nodes.cpp
+++ b/clang/lib/Tooling/Syntax/Nodes.cpp
@@ -32,8 +32,6 @@ llvm::raw_ostream &syntax::operator<<(llvm::raw_ostream &OS, NodeKind K) {
     return OS << "BoolLiteralExpression";
   case NodeKind::CxxNullPtrExpression:
     return OS << "CxxNullPtrExpression";
-  case NodeKind::UnknownUserDefinedLiteralExpression:
-    return OS << "UnknownUserDefinedLiteralExpression";
   case NodeKind::IntegerUserDefinedLiteralExpression:
     return OS << "IntegerUserDefinedLiteralExpression";
   case NodeKind::FloatUserDefinedLiteralExpression:

diff  --git a/clang/unittests/Tooling/Syntax/TreeTest.cpp b/clang/unittests/Tooling/Syntax/TreeTest.cpp
index 91e7a8f33e4e..bd639aa58166 100644
--- a/clang/unittests/Tooling/Syntax/TreeTest.cpp
+++ b/clang/unittests/Tooling/Syntax/TreeTest.cpp
@@ -1190,32 +1190,45 @@ TEST_P(SyntaxTreeTest, UserDefinedLiteral) {
   }
   EXPECT_TRUE(treeDumpEqual(
       R"cpp(
+typedef decltype(sizeof(void *)) size_t;
+
 unsigned operator "" _i(unsigned long long);
 unsigned operator "" _f(long double);
 unsigned operator "" _c(char);
-
-unsigned operator "" _r(const char*); // raw-literal operator
-
+unsigned operator "" _s(const char*, size_t);
+unsigned operator "" _r(const char*);
 template <char...>
-unsigned operator "" _t();            // numeric literal operator template
+unsigned operator "" _t();
 
 void test() {
-  12_i;  // call: operator "" _i(12uLL)      | kind: integer
-  1.2_f; // call: operator "" _f(1.2L)       | kind: float
-  '2'_c; // call: operator "" _c('2')        | kind: char
+  12_i;   // call: operator "" _i(12uLL)      | kind: integer
+  1.2_f;  // call: operator "" _f(1.2L)       | kind: float
+  '2'_c;  // call: operator "" _c('2')        | kind: char
+  "12"_s; // call: operator "" _s("12")       | kind: string
 
-  // TODO: Generate `FloatUserDefinedLiteralExpression` and
-  // `IntegerUserDefinedLiteralExpression` instead of
-  // `UnknownUserDefinedLiteralExpression`. See `getUserDefinedLiteralKind`
-  12_r;  // call: operator "" _r("12")       | kind: integer
-  1.2_r; // call: operator "" _i("1.2")      | kind: float
-  12_t;  // call: operator<'1', '2'> "" _x() | kind: integer
-  1.2_t; // call: operator<'1', '2'> "" _x() | kind: float
+  12_r;   // call: operator "" _r("12")       | kind: integer
+  1.2_r;  // call: operator "" _i("1.2")      | kind: float
+  12_t;   // call: operator<'1', '2'> "" _x() | kind: integer
+  1.2_t;  // call: operator<'1', '2'> "" _x() | kind: float
 }
     )cpp",
       R"txt(
 *: TranslationUnit
 |-SimpleDeclaration
+| |-typedef
+| |-decltype
+| |-(
+| |-UnknownExpression
+| | |-sizeof
+| | |-(
+| | |-void
+| | |-*
+| | `-)
+| |-)
+| |-SimpleDeclarator
+| | `-size_t
+| `-;
+|-SimpleDeclaration
 | |-unsigned
 | |-SimpleDeclarator
 | | |-operator
@@ -1259,6 +1272,24 @@ void test() {
 | |-SimpleDeclarator
 | | |-operator
 | | |-""
+| | |-_s
+| | `-ParametersAndQualifiers
+| |   |-(
+| |   |-SimpleDeclaration
+| |   | |-const
+| |   | |-char
+| |   | `-SimpleDeclarator
+| |   |   `-*
+| |   |-,
+| |   |-SimpleDeclaration
+| |   | `-size_t
+| |   `-)
+| `-;
+|-SimpleDeclaration
+| |-unsigned
+| |-SimpleDeclarator
+| | |-operator
+| | |-""
 | | |-_r
 | | `-ParametersAndQualifiers
 | |   |-(
@@ -1308,88 +1339,29 @@ void test() {
     | | `-'2'_c
     | `-;
     |-ExpressionStatement
-    | |-UnknownUserDefinedLiteralExpression
+    | |-StringUserDefinedLiteralExpression
+    | | `-"12"_s
+    | `-;
+    |-ExpressionStatement
+    | |-IntegerUserDefinedLiteralExpression
     | | `-12_r
     | `-;
     |-ExpressionStatement
-    | |-UnknownUserDefinedLiteralExpression
+    | |-FloatUserDefinedLiteralExpression
     | | `-1.2_r
     | `-;
     |-ExpressionStatement
-    | |-UnknownUserDefinedLiteralExpression
+    | |-IntegerUserDefinedLiteralExpression
     | | `-12_t
     | `-;
     |-ExpressionStatement
-    | |-UnknownUserDefinedLiteralExpression
+    | |-FloatUserDefinedLiteralExpression
     | | `-1.2_t
     | `-;
     `-}
 )txt"));
 }
 
-TEST_P(SyntaxTreeTest, UserDefinedLiteralString) {
-  if (!GetParam().isCXX11OrLater()) {
-    return;
-  }
-  EXPECT_TRUE(treeDumpEqual(
-      R"cpp(
-typedef decltype(sizeof(void *)) size_t;
-unsigned operator "" _s(const char*, size_t);
-void test() {
-  "12"_s;// call: operator "" _s("12")       | kind: string
-}
-    )cpp",
-      R"txt(
-*: TranslationUnit
-|-SimpleDeclaration
-| |-typedef
-| |-decltype
-| |-(
-| |-UnknownExpression
-| | |-sizeof
-| | |-(
-| | |-void
-| | |-*
-| | `-)
-| |-)
-| |-SimpleDeclarator
-| | `-size_t
-| `-;
-|-SimpleDeclaration
-| |-unsigned
-| |-SimpleDeclarator
-| | |-operator
-| | |-""
-| | |-_s
-| | `-ParametersAndQualifiers
-| |   |-(
-| |   |-SimpleDeclaration
-| |   | |-const
-| |   | |-char
-| |   | `-SimpleDeclarator
-| |   |   `-*
-| |   |-,
-| |   |-SimpleDeclaration
-| |   | `-size_t
-| |   `-)
-| `-;
-`-SimpleDeclaration
-  |-void
-  |-SimpleDeclarator
-  | |-test
-  | `-ParametersAndQualifiers
-  |   |-(
-  |   `-)
-  `-CompoundStatement
-    |-{
-    |-ExpressionStatement
-    | |-StringUserDefinedLiteralExpression
-    | | `-"12"_s
-    | `-;
-    `-}
-)txt"));
-}
-
 TEST_P(SyntaxTreeTest, IntegerLiteralLongLong) {
   if (!GetParam().isCXX11OrLater()) {
     return;


        


More information about the cfe-commits mailing list