aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Tooling/Syntax/BuildTree.cpp
diff options
context:
space:
mode:
authorEduardo Caldas <ecaldas@google.com>2020-06-15 17:08:39 +0000
committerEduardo Caldas <ecaldas@google.com>2020-07-10 16:21:11 +0000
commitf33c2c27a8d4ea831aa7c2c2649066be91318d85 (patch)
tree1824386289595d9de6ec3af9dc83c83e01612a3b /clang/lib/Tooling/Syntax/BuildTree.cpp
parente5123ea248eb460c6695dc28ed2f1cc53495356b (diff)
downloadllvm-f33c2c27a8d4ea831aa7c2c2649066be91318d85.zip
llvm-f33c2c27a8d4ea831aa7c2c2649066be91318d85.tar.gz
llvm-f33c2c27a8d4ea831aa7c2c2649066be91318d85.tar.bz2
Fix crash on `user defined literals`
Summary: Given an UserDefinedLiteral `1.2_w`: Problem: Lexer generates one Token for the literal, but ClangAST references two source locations Fix: Ignore the operator and interpret it as the underlying literal. e.g.: `1.2_w` token generates syntax node IntegerLiteral(1.2_w) Subscribers: cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D82157
Diffstat (limited to 'clang/lib/Tooling/Syntax/BuildTree.cpp')
-rw-r--r--clang/lib/Tooling/Syntax/BuildTree.cpp45
1 files changed, 41 insertions, 4 deletions
diff --git a/clang/lib/Tooling/Syntax/BuildTree.cpp b/clang/lib/Tooling/Syntax/BuildTree.cpp
index f9fdf47..8204d3f 100644
--- a/clang/lib/Tooling/Syntax/BuildTree.cpp
+++ b/clang/lib/Tooling/Syntax/BuildTree.cpp
@@ -216,7 +216,8 @@ static SourceRange getDeclaratorRange(const SourceManager &SM, TypeLoc T,
}
if (Initializer.isValid()) {
auto InitializerEnd = Initializer.getEnd();
- assert(SM.isBeforeInTranslationUnit(End, InitializerEnd) || End == InitializerEnd);
+ assert(SM.isBeforeInTranslationUnit(End, InitializerEnd) ||
+ End == InitializerEnd);
End = InitializerEnd;
}
return SourceRange(Start, End);
@@ -708,6 +709,42 @@ public:
return NNS;
}
+ bool TraverseUserDefinedLiteral(UserDefinedLiteral *S) {
+ // The semantic AST node `UserDefinedLiteral` (UDL) may have one child node
+ // referencing the location of the UDL suffix (`_w` in `1.2_w`). The
+ // UDL suffix location does not point to the beginning of a token, so we
+ // can't represent the UDL suffix as a separate syntax tree node.
+
+ return WalkUpFromUserDefinedLiteral(S);
+ }
+
+ syntax::NodeKind getUserDefinedLiteralKind(UserDefinedLiteral *S) {
+ switch (S->getLiteralOperatorKind()) {
+ case clang::UserDefinedLiteral::LOK_Integer:
+ return syntax::NodeKind::IntegerUserDefinedLiteralExpression;
+ case clang::UserDefinedLiteral::LOK_Floating:
+ return syntax::NodeKind::FloatUserDefinedLiteralExpression;
+ case clang::UserDefinedLiteral::LOK_Character:
+ return syntax::NodeKind::CharUserDefinedLiteralExpression;
+ case clang::UserDefinedLiteral::LOK_String:
+ return syntax::NodeKind::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;
+ }
+ }
+
+ bool WalkUpFromUserDefinedLiteral(UserDefinedLiteral *S) {
+ Builder.markChildToken(S->getBeginLoc(), syntax::NodeRole::LiteralToken);
+ Builder.foldNode(Builder.getExprRange(S),
+ new (allocator()) syntax::UserDefinedLiteralExpression(
+ getUserDefinedLiteralKind(S)),
+ S);
+ return true;
+ }
+
bool WalkUpFromDeclRefExpr(DeclRefExpr *S) {
if (auto *NNS = BuildNestedNameSpecifier(S->getQualifierLoc()))
Builder.markChild(NNS, syntax::NodeRole::IdExpression_qualifier);
@@ -817,9 +854,9 @@ public:
bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *S) {
if (getOperatorNodeKind(*S) ==
syntax::NodeKind::PostfixUnaryOperatorExpression) {
- // A postfix unary operator is declared as taking two operands. The second
- // operand is used to distinguish from its prefix counterpart. In the
- // semantic AST this "phantom" operand is represented as a
+ // A postfix unary operator is declared as taking two operands. The
+ // second operand is used to distinguish from its prefix counterpart. In
+ // the semantic AST this "phantom" operand is represented as a
// `IntegerLiteral` with invalid `SourceLocation`. We skip visiting this
// operand because it does not correspond to anything written in source
// code