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