File indexing completed on 2024-05-12 04:39:14
0001 /* 0002 SPDX-FileCopyrightText: 2013 Milian Wolff <mail@milianw.de> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include <KAboutData> 0008 0009 #include <language/util/debuglanguageparserhelper.h> 0010 0011 #include "../duchain/parsesession.h" 0012 #include "../duchain/debugvisitor.h" 0013 #include "../duchain/clangindex.h" 0014 #include "../util/clangtypes.h" 0015 0016 using namespace KDevelop; 0017 using namespace KDevelopUtils; 0018 0019 class ClangParser 0020 { 0021 public: 0022 ClangParser(const bool printAst, const bool printTokens) 0023 : m_session({}) 0024 , m_printAst(printAst) 0025 , m_printTokens(printTokens) 0026 { 0027 } 0028 0029 /// parse contents of a file 0030 void parseFile( const QString &fileName ) 0031 { 0032 if (!QFile::exists(fileName)) { 0033 qerr << "File to parse does not exist: " << fileName << Qt::endl; 0034 return; 0035 } 0036 m_session.setData(ParseSessionData::Ptr(new ParseSessionData({}, &m_index, environment(fileName)))); 0037 runSession(); 0038 } 0039 0040 /// parse code directly 0041 void parseCode( const QString &code ) 0042 { 0043 const QString fileName = QStringLiteral("stdin.cpp"); 0044 m_session.setData(ParseSessionData::Ptr(new ParseSessionData({UnsavedFile(fileName, {code})}, 0045 &m_index, environment(fileName)))); 0046 runSession(); 0047 } 0048 0049 void setIncludePaths(const QStringList& paths) 0050 { 0051 m_includePaths = paths; 0052 } 0053 0054 void setCustomArgs(const QString& args) 0055 { 0056 m_customArgs = args; 0057 } 0058 private: 0059 /** 0060 * actually run the parse session 0061 */ 0062 void runSession() 0063 { 0064 if (!m_session.unit()) { 0065 qerr << "failed to parse code" << Qt::endl; 0066 } 0067 if (m_printTokens) { 0068 CXTranslationUnit TU = m_session.unit(); 0069 auto cursor = clang_getTranslationUnitCursor(TU); 0070 CXSourceRange range = clang_getCursorExtent(cursor); 0071 const ClangTokens tokens(TU, range); 0072 for (CXToken token : tokens) { 0073 CXString spelling = clang_getTokenSpelling(TU, token); 0074 qout << "token= " << clang_getCString(spelling) << Qt::endl; 0075 clang_disposeString(spelling); 0076 } 0077 } 0078 0079 if (!m_session.unit()) { 0080 qerr << "no AST tree could be generated" << Qt::endl; 0081 exit(255); 0082 return; 0083 } 0084 0085 qout << "AST tree successfully generated" << Qt::endl; 0086 auto file = m_session.mainFile(); 0087 0088 if (m_printAst) { 0089 DebugVisitor visitor(&m_session); 0090 visitor.visit(m_session.unit(), file); 0091 } 0092 0093 const auto problems = m_session.problemsForFile(file); 0094 if (!problems.isEmpty()) { 0095 qerr << "\nproblems encountered during parsing:" << Qt::endl; 0096 for (const ProblemPointer& problem : problems) { 0097 qerr << problem->toString() << Qt::endl; 0098 } 0099 } else { 0100 qout << "no problems encountered during parsing" << Qt::endl; 0101 } 0102 } 0103 0104 ClangParsingEnvironment environment(const QString& fileName) const 0105 { 0106 ClangParsingEnvironment environment; 0107 environment.setTranslationUnitUrl(IndexedString(fileName)); 0108 environment.setParserSettings(ClangSettingsManager::self()->parserSettings(fileName)); 0109 environment.addIncludes(toPathList(m_includePaths)); 0110 environment.addParserArguments(m_customArgs); 0111 return environment; 0112 } 0113 ParseSession m_session; 0114 const bool m_printAst; 0115 const bool m_printTokens; 0116 ClangIndex m_index; 0117 QStringList m_includePaths; 0118 QString m_customArgs; 0119 }; 0120 0121 namespace KDevelopUtils { 0122 template<> 0123 void setupCustomArgs<ClangParser>(QCommandLineParser* args) 0124 { 0125 args->addOption(QCommandLineOption{QStringList{"I", "include"}, i18n("add include path"), QStringLiteral("include")}); 0126 args->addOption(QCommandLineOption{QStringList{"custom-arg"}, i18n("custom clang args"), QStringLiteral("arg")}); 0127 } 0128 0129 template<> 0130 void setCustomArgs<ClangParser>(ClangParser* parser, QCommandLineParser* args) 0131 { 0132 parser->setIncludePaths(args->values(QStringLiteral("include"))); 0133 parser->setCustomArgs(args->values(QStringLiteral("custom-arg")).join(QLatin1String(" "))); 0134 } 0135 } 0136 0137 int main(int argc, char* argv[]) 0138 { 0139 KAboutData aboutData( QStringLiteral("clang-parser"), i18n( "clang-parser" ), 0140 QStringLiteral("1"), i18n("KDevelop Clang parser debugging utility"), KAboutLicense::GPL, 0141 i18n( "2013 Milian Wolff" ), QString(), QStringLiteral("https://www.kdevelop.org/") ); 0142 0143 return KDevelopUtils::initAndRunParser<ClangParser>(aboutData, argc, argv); 0144 }