[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