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