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