Coverage Report

Created: 2021-08-24 07:12

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Tooling/Syntax/Synthesis.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- Synthesis.cpp ------------------------------------------*- C++ -*-=====//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
#include "clang/Basic/TokenKinds.h"
9
#include "clang/Tooling/Syntax/BuildTree.h"
10
#include "clang/Tooling/Syntax/Tree.h"
11
12
using namespace clang;
13
14
/// Exposes private syntax tree APIs required to implement node synthesis.
15
/// Should not be used for anything else.
16
class clang::syntax::FactoryImpl {
17
public:
18
3.29k
  static void setCanModify(syntax::Node *N) { N->CanModify = true; }
19
20
  static void prependChildLowLevel(syntax::Tree *T, syntax::Node *Child,
21
0
                                   syntax::NodeRole R) {
22
0
    T->prependChildLowLevel(Child, R);
23
0
  }
24
  static void appendChildLowLevel(syntax::Tree *T, syntax::Node *Child,
25
2.34k
                                  syntax::NodeRole R) {
26
2.34k
    T->appendChildLowLevel(Child, R);
27
2.34k
  }
28
29
  static std::pair<FileID, ArrayRef<Token>>
30
1.70k
  lexBuffer(syntax::Arena &A, std::unique_ptr<llvm::MemoryBuffer> Buffer) {
31
1.70k
    return A.lexBuffer(std::move(Buffer));
32
1.70k
  }
33
};
34
35
// FIXME: `createLeaf` is based on `syntax::tokenize` internally, as such it
36
// doesn't support digraphs or line continuations.
37
syntax::Leaf *clang::syntax::createLeaf(syntax::Arena &A, tok::TokenKind K,
38
1.70k
                                        StringRef Spelling) {
39
1.70k
  auto Tokens =
40
1.70k
      FactoryImpl::lexBuffer(A, llvm::MemoryBuffer::getMemBufferCopy(Spelling))
41
1.70k
          .second;
42
1.70k
  assert(Tokens.size() == 1);
43
0
  assert(Tokens.front().kind() == K &&
44
1.70k
         "spelling is not lexed into the expected kind of token");
45
46
0
  auto *Leaf = new (A.getAllocator()) syntax::Leaf(Tokens.begin());
47
1.70k
  syntax::FactoryImpl::setCanModify(Leaf);
48
1.70k
  Leaf->assertInvariants();
49
1.70k
  return Leaf;
50
1.70k
}
51
52
398
syntax::Leaf *clang::syntax::createLeaf(syntax::Arena &A, tok::TokenKind K) {
53
398
  const auto *Spelling = tok::getPunctuatorSpelling(K);
54
398
  if (!Spelling)
55
36
    Spelling = tok::getKeywordSpelling(K);
56
398
  assert(Spelling &&
57
398
         "Cannot infer the spelling of the token from its token kind.");
58
0
  return createLeaf(A, K, Spelling);
59
398
}
60
61
namespace {
62
// Allocates the concrete syntax `Tree` according to its `NodeKind`.
63
1.59k
syntax::Tree *allocateTree(syntax::Arena &A, syntax::NodeKind Kind) {
64
1.59k
  switch (Kind) {
65
0
  case syntax::NodeKind::Leaf:
66
0
    assert(false);
67
0
    break;
68
29
  case syntax::NodeKind::TranslationUnit:
69
29
    return new (A.getAllocator()) syntax::TranslationUnit;
70
1.10k
  case syntax::NodeKind::UnknownExpression:
71
1.10k
    return new (A.getAllocator()) syntax::UnknownExpression;
72
14
  case syntax::NodeKind::ParenExpression:
73
14
    return new (A.getAllocator()) syntax::ParenExpression;
74
0
  case syntax::NodeKind::ThisExpression:
75
0
    return new (A.getAllocator()) syntax::ThisExpression;
76
56
  case syntax::NodeKind::IntegerLiteralExpression:
77
56
    return new (A.getAllocator()) syntax::IntegerLiteralExpression;
78
0
  case syntax::NodeKind::CharacterLiteralExpression:
79
0
    return new (A.getAllocator()) syntax::CharacterLiteralExpression;
80
0
  case syntax::NodeKind::FloatingLiteralExpression:
81
0
    return new (A.getAllocator()) syntax::FloatingLiteralExpression;
82
0
  case syntax::NodeKind::StringLiteralExpression:
83
0
    return new (A.getAllocator()) syntax::StringLiteralExpression;
84
0
  case syntax::NodeKind::BoolLiteralExpression:
85
0
    return new (A.getAllocator()) syntax::BoolLiteralExpression;
86
0
  case syntax::NodeKind::CxxNullPtrExpression:
87
0
    return new (A.getAllocator()) syntax::CxxNullPtrExpression;
88
0
  case syntax::NodeKind::IntegerUserDefinedLiteralExpression:
89
0
    return new (A.getAllocator()) syntax::IntegerUserDefinedLiteralExpression;
90
0
  case syntax::NodeKind::FloatUserDefinedLiteralExpression:
91
0
    return new (A.getAllocator()) syntax::FloatUserDefinedLiteralExpression;
92
0
  case syntax::NodeKind::CharUserDefinedLiteralExpression:
93
0
    return new (A.getAllocator()) syntax::CharUserDefinedLiteralExpression;
94
0
  case syntax::NodeKind::StringUserDefinedLiteralExpression:
95
0
    return new (A.getAllocator()) syntax::StringUserDefinedLiteralExpression;
96
0
  case syntax::NodeKind::PrefixUnaryOperatorExpression:
97
0
    return new (A.getAllocator()) syntax::PrefixUnaryOperatorExpression;
98
0
  case syntax::NodeKind::PostfixUnaryOperatorExpression:
99
0
    return new (A.getAllocator()) syntax::PostfixUnaryOperatorExpression;
100
28
  case syntax::NodeKind::BinaryOperatorExpression:
101
28
    return new (A.getAllocator()) syntax::BinaryOperatorExpression;
102
0
  case syntax::NodeKind::UnqualifiedId:
103
0
    return new (A.getAllocator()) syntax::UnqualifiedId;
104
0
  case syntax::NodeKind::IdExpression:
105
0
    return new (A.getAllocator()) syntax::IdExpression;
106
0
  case syntax::NodeKind::CallExpression:
107
0
    return new (A.getAllocator()) syntax::CallExpression;
108
0
  case syntax::NodeKind::UnknownStatement:
109
0
    return new (A.getAllocator()) syntax::UnknownStatement;
110
0
  case syntax::NodeKind::DeclarationStatement:
111
0
    return new (A.getAllocator()) syntax::DeclarationStatement;
112
28
  case syntax::NodeKind::EmptyStatement:
113
28
    return new (A.getAllocator()) syntax::EmptyStatement;
114
0
  case syntax::NodeKind::SwitchStatement:
115
0
    return new (A.getAllocator()) syntax::SwitchStatement;
116
0
  case syntax::NodeKind::CaseStatement:
117
0
    return new (A.getAllocator()) syntax::CaseStatement;
118
0
  case syntax::NodeKind::DefaultStatement:
119
0
    return new (A.getAllocator()) syntax::DefaultStatement;
120
14
  case syntax::NodeKind::IfStatement:
121
14
    return new (A.getAllocator()) syntax::IfStatement;
122
0
  case syntax::NodeKind::ForStatement:
123
0
    return new (A.getAllocator()) syntax::ForStatement;
124
0
  case syntax::NodeKind::WhileStatement:
125
0
    return new (A.getAllocator()) syntax::WhileStatement;
126
28
  case syntax::NodeKind::ContinueStatement:
127
28
    return new (A.getAllocator()) syntax::ContinueStatement;
128
0
  case syntax::NodeKind::BreakStatement:
129
0
    return new (A.getAllocator()) syntax::BreakStatement;
130
0
  case syntax::NodeKind::ReturnStatement:
131
0
    return new (A.getAllocator()) syntax::ReturnStatement;
132
0
  case syntax::NodeKind::RangeBasedForStatement:
133
0
    return new (A.getAllocator()) syntax::RangeBasedForStatement;
134
14
  case syntax::NodeKind::ExpressionStatement:
135
14
    return new (A.getAllocator()) syntax::ExpressionStatement;
136
42
  case syntax::NodeKind::CompoundStatement:
137
42
    return new (A.getAllocator()) syntax::CompoundStatement;
138
0
  case syntax::NodeKind::UnknownDeclaration:
139
0
    return new (A.getAllocator()) syntax::UnknownDeclaration;
140
0
  case syntax::NodeKind::EmptyDeclaration:
141
0
    return new (A.getAllocator()) syntax::EmptyDeclaration;
142
0
  case syntax::NodeKind::StaticAssertDeclaration:
143
0
    return new (A.getAllocator()) syntax::StaticAssertDeclaration;
144
0
  case syntax::NodeKind::LinkageSpecificationDeclaration:
145
0
    return new (A.getAllocator()) syntax::LinkageSpecificationDeclaration;
146
42
  case syntax::NodeKind::SimpleDeclaration:
147
42
    return new (A.getAllocator()) syntax::SimpleDeclaration;
148
0
  case syntax::NodeKind::TemplateDeclaration:
149
0
    return new (A.getAllocator()) syntax::TemplateDeclaration;
150
0
  case syntax::NodeKind::ExplicitTemplateInstantiation:
151
0
    return new (A.getAllocator()) syntax::ExplicitTemplateInstantiation;
152
0
  case syntax::NodeKind::NamespaceDefinition:
153
0
    return new (A.getAllocator()) syntax::NamespaceDefinition;
154
0
  case syntax::NodeKind::NamespaceAliasDefinition:
155
0
    return new (A.getAllocator()) syntax::NamespaceAliasDefinition;
156
0
  case syntax::NodeKind::UsingNamespaceDirective:
157
0
    return new (A.getAllocator()) syntax::UsingNamespaceDirective;
158
0
  case syntax::NodeKind::UsingDeclaration:
159
0
    return new (A.getAllocator()) syntax::UsingDeclaration;
160
0
  case syntax::NodeKind::TypeAliasDeclaration:
161
0
    return new (A.getAllocator()) syntax::TypeAliasDeclaration;
162
42
  case syntax::NodeKind::SimpleDeclarator:
163
42
    return new (A.getAllocator()) syntax::SimpleDeclarator;
164
0
  case syntax::NodeKind::ParenDeclarator:
165
0
    return new (A.getAllocator()) syntax::ParenDeclarator;
166
0
  case syntax::NodeKind::ArraySubscript:
167
0
    return new (A.getAllocator()) syntax::ArraySubscript;
168
0
  case syntax::NodeKind::TrailingReturnType:
169
0
    return new (A.getAllocator()) syntax::TrailingReturnType;
170
14
  case syntax::NodeKind::ParametersAndQualifiers:
171
14
    return new (A.getAllocator()) syntax::ParametersAndQualifiers;
172
0
  case syntax::NodeKind::MemberPointer:
173
0
    return new (A.getAllocator()) syntax::MemberPointer;
174
0
  case syntax::NodeKind::GlobalNameSpecifier:
175
0
    return new (A.getAllocator()) syntax::GlobalNameSpecifier;
176
0
  case syntax::NodeKind::DecltypeNameSpecifier:
177
0
    return new (A.getAllocator()) syntax::DecltypeNameSpecifier;
178
0
  case syntax::NodeKind::IdentifierNameSpecifier:
179
0
    return new (A.getAllocator()) syntax::IdentifierNameSpecifier;
180
0
  case syntax::NodeKind::SimpleTemplateNameSpecifier:
181
0
    return new (A.getAllocator()) syntax::SimpleTemplateNameSpecifier;
182
40
  case syntax::NodeKind::NestedNameSpecifier:
183
40
    return new (A.getAllocator()) syntax::NestedNameSpecifier;
184
0
  case syntax::NodeKind::MemberExpression:
185
0
    return new (A.getAllocator()) syntax::MemberExpression;
186
56
  case syntax::NodeKind::CallArguments:
187
56
    return new (A.getAllocator()) syntax::CallArguments;
188
0
  case syntax::NodeKind::ParameterDeclarationList:
189
0
    return new (A.getAllocator()) syntax::ParameterDeclarationList;
190
42
  case syntax::NodeKind::DeclaratorList:
191
42
    return new (A.getAllocator()) syntax::DeclaratorList;
192
1.59k
  }
193
0
  llvm_unreachable("unknown node kind");
194
0
}
195
} // namespace
196
197
syntax::Tree *clang::syntax::createTree(
198
    syntax::Arena &A,
199
    ArrayRef<std::pair<syntax::Node *, syntax::NodeRole>> Children,
200
1.59k
    syntax::NodeKind K) {
201
1.59k
  auto *T = allocateTree(A, K);
202
1.59k
  FactoryImpl::setCanModify(T);
203
1.59k
  for (const auto &Child : Children)
204
2.34k
    FactoryImpl::appendChildLowLevel(T, Child.first, Child.second);
205
206
1.59k
  T->assertInvariants();
207
1.59k
  return T;
208
1.59k
}
209
210
syntax::Node *clang::syntax::deepCopyExpandingMacros(syntax::Arena &A,
211
1.79k
                                                     const syntax::Node *N) {
212
1.79k
  if (const auto *L = dyn_cast<syntax::Leaf>(N))
213
    // `L->getToken()` gives us the expanded token, thus we implicitly expand
214
    // any macros here.
215
994
    return createLeaf(A, L->getToken()->kind(),
216
994
                      L->getToken()->text(A.getSourceManager()));
217
218
798
  const auto *T = cast<syntax::Tree>(N);
219
798
  std::vector<std::pair<syntax::Node *, syntax::NodeRole>> Children;
220
1.72k
  for (const auto *Child = T->getFirstChild(); Child;
221
924
       Child = Child->getNextSibling())
222
924
    Children.push_back({deepCopyExpandingMacros(A, Child), Child->getRole()});
223
224
798
  return createTree(A, Children, N->getKind());
225
1.79k
}
226
227
28
syntax::EmptyStatement *clang::syntax::createEmptyStatement(syntax::Arena &A) {
228
28
  return cast<EmptyStatement>(
229
28
      createTree(A, {{createLeaf(A, tok::semi), NodeRole::Unknown}},
230
28
                 NodeKind::EmptyStatement));
231
28
}