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; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits