| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581 |
- ///////////////////////////////////////////////////////////////////////////////
- // //
- // CompilationResult.h //
- // Copyright (C) Microsoft Corporation. All rights reserved. //
- // This file is distributed under the University of Illinois Open Source //
- // License. See LICENSE.TXT for details. //
- // //
- // This file provides a class to parse a translation unit and return the //
- // diagnostic results and AST tree. //
- // //
- ///////////////////////////////////////////////////////////////////////////////
- #include <memory>
- #include <vector>
- #include <string>
- #include <iostream>
- #include <cassert>
- #include <sstream>
- #include <algorithm>
- #include <atomic>
- #include "dxc/Support/WinIncludes.h"
- #include "dxc/dxcapi.h"
- #include "dxc/dxcisense.h"
- #include "dxc/Support/dxcapi.use.h"
- #include "llvm/Support/Atomic.h"
- inline HRESULT IFE(HRESULT hr) {
- if (FAILED(hr)) {
- throw std::runtime_error("COM call failed");
- }
- return hr;
- }
- inline HRESULT GetFirstChildFromCursor(IDxcCursor *cursor,
- IDxcCursor **pResult) {
- HRESULT hr;
- IDxcCursor **children = nullptr;
- unsigned childrenCount;
- hr = cursor->GetChildren(0, 1, &childrenCount, &children);
- if (SUCCEEDED(hr) && childrenCount == 1) {
- *pResult = children[0];
- } else {
- *pResult = nullptr;
- hr = E_FAIL;
- }
- CoTaskMemFree(children);
- return hr;
- }
- class TrivialDxcUnsavedFile : IDxcUnsavedFile
- {
- private:
- volatile std::atomic<llvm::sys::cas_flag> m_dwRef;
- LPCSTR m_fileName;
- LPCSTR m_contents;
- unsigned m_length;
- public:
- TrivialDxcUnsavedFile(LPCSTR fileName, LPCSTR contents)
- : m_dwRef(0), m_fileName(fileName), m_contents(contents)
- {
- m_length = (unsigned)strlen(m_contents);
- }
- static HRESULT Create(LPCSTR fileName, LPCSTR contents, IDxcUnsavedFile** pResult)
- {
- CComPtr<TrivialDxcUnsavedFile> pNewValue = new TrivialDxcUnsavedFile(fileName, contents);
- return pNewValue.QueryInterface(pResult);
- }
- ULONG STDMETHODCALLTYPE AddRef() { return (ULONG)++m_dwRef; }
- ULONG STDMETHODCALLTYPE Release() {
- ULONG result = (ULONG)--m_dwRef;
- if (result == 0) delete this;
- return result;
- }
- HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObject)
- {
- if (ppvObject == nullptr) return E_POINTER;
- if (IsEqualIID(iid, __uuidof(IUnknown)) ||
- IsEqualIID(iid, __uuidof(INoMarshal)) ||
- IsEqualIID(iid, __uuidof(IDxcUnsavedFile)))
- {
- *ppvObject = reinterpret_cast<IDxcUnsavedFile*>(this);
- reinterpret_cast<IDxcUnsavedFile*>(this)->AddRef();
- return S_OK;
- }
- return E_NOINTERFACE;
- }
- HRESULT STDMETHODCALLTYPE GetFileName(LPSTR* pFileName)
- {
- *pFileName = (LPSTR)CoTaskMemAlloc(1 + strlen(m_fileName));
- strcpy(*pFileName, m_fileName);
- return S_OK;
- }
- HRESULT STDMETHODCALLTYPE GetContents(LPSTR* pContents)
- {
- *pContents = (LPSTR)CoTaskMemAlloc(m_length + 1);
- memcpy(*pContents, m_contents, m_length + 1);
- return S_OK;
- }
- HRESULT STDMETHODCALLTYPE GetLength(unsigned* pLength)
- {
- *pLength = m_length;
- return S_OK;
- }
- };
- class HlslIntellisenseSupport : public dxc::DxcDllSupport {
- public:
- HlslIntellisenseSupport() {}
- HlslIntellisenseSupport(HlslIntellisenseSupport &&other)
- : dxc::DxcDllSupport(std::move(other)) {}
- HRESULT CreateIntellisense(_Outptr_ IDxcIntelliSense **pResult) {
- return CreateInstance(CLSID_DxcIntelliSense, pResult);
- }
- };
- /// Summary of the results of a clang compilation operation.
- class CompilationResult
- {
- private:
- // Keep Intellisense alive.
- std::shared_ptr<HlslIntellisenseSupport> IsenseSupport;
- /// The top-level Intellisense object.
- CComPtr<IDxcIntelliSense> Intellisense;
- /// The libclang index for the compilation operation.
- CComPtr<IDxcIndex> Index;
- /// The number of diagnostic messages emitted.
- unsigned NumDiagnostics;
- /// The number of diagnostic messages emitted that indicate errors.
- unsigned NumErrorDiagnostics;
- /// The diagnostic messages emitted.
- std::vector<std::string> DiagnosticMessages;
- /// The severity of diagnostic messages.
- std::vector<DxcDiagnosticSeverity> DiagnosticSeverities;
- // Hide the copy constructor.
- CompilationResult(const CompilationResult&);
- public:
- CompilationResult(std::shared_ptr<HlslIntellisenseSupport> support, IDxcIntelliSense* isense, IDxcIndex* index, IDxcTranslationUnit* tu) :
- IsenseSupport(support),
- Intellisense(isense),
- Index(index),
- NumErrorDiagnostics(0),
- TU(tu)
- {
- if (tu) {
- IFE(tu->GetNumDiagnostics(&NumDiagnostics));
- } else {
- NumDiagnostics = 0;
- }
- DxcDiagnosticDisplayOptions diagnosticOptions;
- IFE(isense->GetDefaultDiagnosticDisplayOptions(&diagnosticOptions));
- for (unsigned i = 0; i < NumDiagnostics; i++) {
- CComPtr<IDxcDiagnostic> diagnostic;
- IFE(tu->GetDiagnostic(i, &diagnostic));
- LPSTR format;
- IFE(diagnostic->FormatDiagnostic(diagnosticOptions, &format));
- DiagnosticMessages.push_back(std::string(format));
- CoTaskMemFree(format);
- DxcDiagnosticSeverity severity;
- IFE(diagnostic->GetSeverity(&severity));
- DiagnosticSeverities.push_back(severity);
- if (IsErrorSeverity(severity)) {
- NumErrorDiagnostics++;
- }
- }
- assert(NumErrorDiagnostics <= NumDiagnostics && "else counting code in loop is incorrect");
- assert(DiagnosticMessages.size() == NumDiagnostics && "else some diagnostics have no message");
- assert(DiagnosticSeverities.size() == NumDiagnostics && "else some diagnostics have no severity");
- }
-
- CompilationResult(CompilationResult&& other) :
- IsenseSupport(std::move(other.IsenseSupport)) {
- // Allow move constructor.
- Intellisense = other.Intellisense; other.Intellisense = nullptr;
- Index = other.Index; other.Index = nullptr;
- TU = other.TU; other.TU = nullptr;
- NumDiagnostics = other.NumDiagnostics;
- NumErrorDiagnostics = other.NumErrorDiagnostics;
- DiagnosticMessages = std::move(other.DiagnosticMessages);
- DiagnosticSeverities = std::move(other.DiagnosticSeverities);
- }
- ~CompilationResult() { Dispose(); }
- /// The translation unit resulting from the compilation.
- CComPtr<IDxcTranslationUnit> TU;
- static const char *getDefaultFileName() { return "filename.hlsl"; }
- static std::shared_ptr<HlslIntellisenseSupport> DefaultHlslSupport;
- static std::shared_ptr<HlslIntellisenseSupport> GetHlslSupport() {
- if (DefaultHlslSupport.get() != nullptr) {
- return DefaultHlslSupport;
- }
- std::shared_ptr<HlslIntellisenseSupport> result = std::make_shared<HlslIntellisenseSupport>();
- IFE(result->Initialize());
- return result;
- }
- static CompilationResult CreateForProgramAndArgs(const char* text, size_t textLen,
- _In_count_(commandLineArgsCount) const char* commandLineArgs[],
- unsigned commandLineArgsCount,
- _In_opt_ DxcTranslationUnitFlags* options = nullptr)
- {
- std::shared_ptr<HlslIntellisenseSupport> support(GetHlslSupport());
- CComPtr<IDxcIntelliSense> isense;
- IFE(support->CreateIntellisense(&isense));
- CComPtr<IDxcIndex> tuIndex;
- CComPtr<IDxcTranslationUnit> tu;
- const char *fileName = getDefaultFileName();
- if (textLen == 0) textLen = strlen(text);
- IFE(isense->CreateIndex(&tuIndex));
- CComPtr<IDxcUnsavedFile> unsavedFile;
- IFE(TrivialDxcUnsavedFile::Create(fileName, text, &unsavedFile));
- DxcTranslationUnitFlags localOptions;
- if (options == nullptr)
- {
- IFE(isense->GetDefaultEditingTUOptions(&localOptions));
- }
- else
- {
- localOptions = *options;
- }
- IFE(tuIndex->ParseTranslationUnit(fileName,
- commandLineArgs, commandLineArgsCount,
- &(unsavedFile.p), 1, localOptions, &tu));
-
- return CompilationResult(support, isense.p, tuIndex.p, tu.p);
- }
- static CompilationResult
- CreateForProgram(const char *text, size_t textLen,
- _In_opt_ DxcTranslationUnitFlags *options = nullptr) {
- const char *commandLineArgs[] = {"-c", "-ferror-limit=200"};
- unsigned commandLineArgsCount = _countof(commandLineArgs);
- return CreateForProgramAndArgs(text, textLen, commandLineArgs,
- commandLineArgsCount, options);
- }
- static CompilationResult CreateForCommandLine(char* arguments, const char* fileName) {
- std::shared_ptr<HlslIntellisenseSupport> support(GetHlslSupport());
- return CreateForCommandLine(arguments, fileName, support);
- }
- static CompilationResult CreateForCommandLine(char* arguments, const char* fileName, std::shared_ptr<HlslIntellisenseSupport> support) {
- CComPtr<IDxcIntelliSense> isense;
- IFE(support->CreateIntellisense(&isense));
- CComPtr<IDxcIndex> tuIndex;
- CComPtr<IDxcTranslationUnit> tu;
- const char* commandLineArgs[32];
- unsigned commandLineArgsCount = 0;
- char* nextArg = arguments;
- // Set a very high number of errors to avoid giving up too early.
- commandLineArgs[commandLineArgsCount++] = "-ferror-limit=2000";
- // Turn on spell checking for compatibility. This produces error messages
- // that suggest corrected spellings.
- commandLineArgs[commandLineArgsCount++] = "-fspell-checking";
- // Turn off color diagnostics to avoid control characters in diagnostic
- // stream.
- commandLineArgs[commandLineArgsCount++] = "-fno-color-diagnostics";
- IFE(isense->CreateIndex(&tuIndex));
- // Split command line arguments by spaces
- if (nextArg) {
- // skip leading spaces
- while (*nextArg == ' ')
- nextArg++;
- commandLineArgs[commandLineArgsCount++] = nextArg;
- while ((*nextArg != '\0')) {
- if (*nextArg == ' ') {
- *nextArg = 0;
- commandLineArgs[commandLineArgsCount++] = nextArg + 1;
- }
- nextArg++;
- }
- }
- DxcTranslationUnitFlags options;
- IFE(isense->GetDefaultEditingTUOptions(&options));
- IFE(tuIndex->ParseTranslationUnit(fileName, commandLineArgs,
- commandLineArgsCount, nullptr, 0, options,
- &tu));
- return CompilationResult(support, isense.p, tuIndex.p, tu.p);
- }
- bool IsTUAvailable() const { return TU != nullptr; }
- bool ParseSucceeded() const { return TU != nullptr && NumErrorDiagnostics == 0; }
- static bool IsErrorSeverity(DxcDiagnosticSeverity severity)
- {
- return (severity == DxcDiagnostic_Error || severity == DxcDiagnostic_Fatal);
- }
- /// Gets a string with all error messages concatenated, one per line.
- std::string GetTextForErrors() const {
- assert(DiagnosticMessages.size() == NumDiagnostics && "otherwise some diagnostics have no message");
- assert(DiagnosticSeverities.size() == NumDiagnostics && "otherwise some diagnostics have no severity");
- std::stringstream ostr;
- for (size_t i = 0; i < DiagnosticMessages.size(); i++) {
- if (IsErrorSeverity(DiagnosticSeverities[i])) {
- ostr << DiagnosticMessages[i] << '\n';
- }
- }
- return ostr.str();
- }
- /// Releases resources, including the translation unit AST.
- void Dispose()
- {
- TU = nullptr;
- Index = nullptr;
- Intellisense = nullptr;
- IsenseSupport = nullptr;
- }
- private:
- #if SUPPORTS_CURSOR_WALK
- struct CursorStringData {
- std::stringstream &ostr;
- std::vector<CXCursor> cursors;
- CursorStringData(std::stringstream &the_ostr) : ostr(the_ostr) {}
- };
- static
- CXChildVisitResult AppendCursorStringCallback(
- CXCursor cursor, CXCursor parent, CXClientData client_data)
- {
- CursorStringData* d = (CursorStringData*)client_data;
- auto cursorsStart = std::begin(d->cursors);
- auto cursorsEnd = std::end(d->cursors);
- auto parentLocation = std::find(cursorsStart, cursorsEnd, parent);
- assert(parentLocation != cursorsEnd && "otherwise the parent was not visited previously");
- AppendCursorString(cursor, parentLocation - cursorsStart, d->ostr);
- d->cursors.resize(1 + (parentLocation - cursorsStart));
- d->cursors.push_back(cursor);
- return CXChildVisit_Recurse;
- }
- #endif
- static
- void AppendCursorString(IDxcCursor* cursor, size_t indent, std::stringstream& ostr)
- {
- if (indent > 0) {
- std::streamsize prior = ostr.width();
- ostr.width(indent);
- ostr << ' ';
- ostr.width(prior);
- }
- CComPtr<IDxcType> type;
- DxcCursorKind kind;
- cursor->GetKind(&kind);
- cursor->GetCursorType(&type);
- switch (kind)
- {
- case DxcCursor_UnexposedDecl: ostr << "UnexposedDecl"; break;
- case DxcCursor_StructDecl: ostr << "StructDecl"; break;
- case DxcCursor_UnionDecl: ostr << "UnionDecl"; break;
- case DxcCursor_ClassDecl: ostr << "ClassDecl"; break;
- case DxcCursor_EnumDecl: ostr << "EnumDecl"; break;
- case DxcCursor_FieldDecl: ostr << "FieldDecl"; break;
- case DxcCursor_EnumConstantDecl: ostr << "EnumConstantDecl"; break;
- case DxcCursor_FunctionDecl: ostr << "FunctionDecl"; break;
- case DxcCursor_VarDecl: ostr << "VarDecl"; break;
- case DxcCursor_ParmDecl: ostr << "ParmDecl"; break;
- case DxcCursor_ObjCInterfaceDecl: ostr << "ObjCInterfaceDecl"; break;
- case DxcCursor_ObjCCategoryDecl: ostr << "ObjCCategoryDecl"; break;
- case DxcCursor_ObjCProtocolDecl: ostr << "ObjCProtocolDecl"; break;
- case DxcCursor_ObjCPropertyDecl: ostr << "ObjCPropertyDecl"; break;
- case DxcCursor_ObjCIvarDecl: ostr << "ObjCIvarDecl"; break;
- case DxcCursor_ObjCInstanceMethodDecl: ostr << "ObjCInstanceMethodDecl"; break;
- case DxcCursor_ObjCClassMethodDecl: ostr << "ObjCClassMethodDecl"; break;
- case DxcCursor_ObjCImplementationDecl: ostr << "ObjCImplementationDecl"; break;
- case DxcCursor_ObjCCategoryImplDecl: ostr << "ObjCCategoryImplDecl"; break;
- case DxcCursor_TypedefDecl: ostr << "TypedefDecl"; break;
- case DxcCursor_CXXMethod: ostr << "CXXMethod"; break;
- case DxcCursor_Namespace: ostr << "Namespace"; break;
- case DxcCursor_LinkageSpec: ostr << "LinkageSpec"; break;
- case DxcCursor_Constructor: ostr << "Constructor"; break;
- case DxcCursor_Destructor: ostr << "Destructor"; break;
- case DxcCursor_ConversionFunction: ostr << "ConversionFunction"; break;
- case DxcCursor_TemplateTypeParameter: ostr << "TemplateTypeParameter"; break;
- case DxcCursor_NonTypeTemplateParameter: ostr << "NonTypeTemplateParameter"; break;
- case DxcCursor_TemplateTemplateParameter: ostr << "TemplateTemplateParameter"; break;
- case DxcCursor_FunctionTemplate: ostr << "FunctionTemplate"; break;
- case DxcCursor_ClassTemplate: ostr << "ClassTemplate"; break;
- case DxcCursor_ClassTemplatePartialSpecialization: ostr << "ClassTemplatePartialSpecialization"; break;
- case DxcCursor_NamespaceAlias: ostr << "NamespaceAlias"; break;
- case DxcCursor_UsingDirective: ostr << "UsingDirective"; break;
- case DxcCursor_UsingDeclaration: ostr << "UsingDeclaration"; break;
- case DxcCursor_TypeAliasDecl: ostr << "TypeAliasDecl"; break;
- case DxcCursor_ObjCSynthesizeDecl: ostr << "ObjCSynthesizeDecl"; break;
- case DxcCursor_ObjCDynamicDecl: ostr << "ObjCDynamicDecl"; break;
- case DxcCursor_CXXAccessSpecifier: ostr << "CXXAccessSpecifier"; break;
- case DxcCursor_ObjCSuperClassRef: ostr << "ObjCSuperClassRef"; break;
- case DxcCursor_ObjCProtocolRef: ostr << "ObjCProtocolRef"; break;
- case DxcCursor_ObjCClassRef: ostr << "ObjCClassRef"; break;
- case DxcCursor_TypeRef: ostr << "TypeRef"; break;
- case DxcCursor_CXXBaseSpecifier: ostr << "CXXBaseSpecifier"; break;
- case DxcCursor_TemplateRef: ostr << "TemplateRef"; break;
- case DxcCursor_NamespaceRef: ostr << "NamespaceRef"; break;
- case DxcCursor_MemberRef: ostr << "MemberRef"; break;
- case DxcCursor_LabelRef: ostr << "LabelRef"; break;
- case DxcCursor_OverloadedDeclRef: ostr << "OverloadedDeclRef"; break;
- case DxcCursor_VariableRef: ostr << "VariableRef"; break;
- case DxcCursor_InvalidFile: ostr << "InvalidFile"; break;
- case DxcCursor_NoDeclFound: ostr << "NoDeclFound"; break;
- case DxcCursor_NotImplemented: ostr << "NotImplemented"; break;
- case DxcCursor_InvalidCode: ostr << "InvalidCode"; break;
- case DxcCursor_UnexposedExpr: ostr << "UnexposedExpr"; break;
- case DxcCursor_DeclRefExpr: ostr << "DeclRefExpr"; break;
- case DxcCursor_MemberRefExpr: ostr << "MemberRefExpr"; break;
- case DxcCursor_CallExpr: ostr << "CallExpr"; break;
- case DxcCursor_ObjCMessageExpr: ostr << "ObjCMessageExpr"; break;
- case DxcCursor_BlockExpr: ostr << "BlockExpr"; break;
- case DxcCursor_IntegerLiteral: ostr << "IntegerLiteral"; break;
- case DxcCursor_FloatingLiteral: ostr << "FloatingLiteral"; break;
- case DxcCursor_ImaginaryLiteral: ostr << "ImaginaryLiteral"; break;
- case DxcCursor_StringLiteral: ostr << "StringLiteral"; break;
- case DxcCursor_CharacterLiteral: ostr << "CharacterLiteral"; break;
- case DxcCursor_ParenExpr: ostr << "ParenExpr"; break;
- case DxcCursor_UnaryOperator: ostr << "UnaryOperator"; break;
- case DxcCursor_ArraySubscriptExpr: ostr << "ArraySubscriptExpr"; break;
- case DxcCursor_BinaryOperator: ostr << "BinaryOperator"; break;
- case DxcCursor_CompoundAssignOperator: ostr << "CompoundAssignOperator"; break;
- case DxcCursor_ConditionalOperator: ostr << "ConditionalOperator"; break;
- case DxcCursor_CStyleCastExpr: ostr << "CStyleCastExpr"; break;
- case DxcCursor_CompoundLiteralExpr: ostr << "CompoundLiteralExpr"; break;
- case DxcCursor_InitListExpr: ostr << "InitListExpr"; break;
- case DxcCursor_AddrLabelExpr: ostr << "AddrLabelExpr"; break;
- case DxcCursor_StmtExpr: ostr << "StmtExpr"; break;
- case DxcCursor_GenericSelectionExpr: ostr << "GenericSelectionExpr"; break;
- case DxcCursor_GNUNullExpr: ostr << "GNUNullExpr"; break;
- case DxcCursor_CXXStaticCastExpr: ostr << "CXXStaticCastExpr"; break;
- case DxcCursor_CXXDynamicCastExpr: ostr << "CXXDynamicCastExpr"; break;
- case DxcCursor_CXXReinterpretCastExpr: ostr << "CXXReinterpretCastExpr"; break;
- case DxcCursor_CXXConstCastExpr: ostr << "CXXConstCastExpr"; break;
- case DxcCursor_CXXFunctionalCastExpr: ostr << "CXXFunctionalCastExpr"; break;
- case DxcCursor_CXXTypeidExpr: ostr << "CXXTypeidExpr"; break;
- case DxcCursor_CXXBoolLiteralExpr: ostr << "CXXBoolLiteralExpr"; break;
- case DxcCursor_CXXNullPtrLiteralExpr: ostr << "CXXNullPtrLiteralExpr"; break;
- case DxcCursor_CXXThisExpr: ostr << "CXXThisExpr"; break;
- case DxcCursor_CXXThrowExpr: ostr << "CXXThrowExpr"; break;
- case DxcCursor_CXXNewExpr: ostr << "CXXNewExpr"; break;
- case DxcCursor_CXXDeleteExpr: ostr << "CXXDeleteExpr"; break;
- case DxcCursor_UnaryExpr: ostr << "UnaryExpr"; break;
- case DxcCursor_ObjCStringLiteral: ostr << "ObjCStringLiteral"; break;
- case DxcCursor_ObjCEncodeExpr: ostr << "ObjCEncodeExpr"; break;
- case DxcCursor_ObjCSelectorExpr: ostr << "ObjCSelectorExpr"; break;
- case DxcCursor_ObjCProtocolExpr: ostr << "ObjCProtocolExpr"; break;
- case DxcCursor_ObjCBridgedCastExpr: ostr << "ObjCBridgedCastExpr"; break;
- case DxcCursor_PackExpansionExpr: ostr << "PackExpansionExpr"; break;
- case DxcCursor_SizeOfPackExpr: ostr << "SizeOfPackExpr"; break;
- case DxcCursor_LambdaExpr: ostr << "LambdaExpr"; break;
- case DxcCursor_ObjCBoolLiteralExpr: ostr << "ObjCBoolLiteralExpr"; break;
- case DxcCursor_ObjCSelfExpr: ostr << "ObjCSelfExpr"; break;
- case DxcCursor_UnexposedStmt: ostr << "UnexposedStmt"; break;
- case DxcCursor_LabelStmt: ostr << "LabelStmt"; break;
- case DxcCursor_CompoundStmt: ostr << "CompoundStmt"; break;
- case DxcCursor_CaseStmt: ostr << "CaseStmt"; break;
- case DxcCursor_DefaultStmt: ostr << "DefaultStmt"; break;
- case DxcCursor_IfStmt: ostr << "IfStmt"; break;
- case DxcCursor_SwitchStmt: ostr << "SwitchStmt"; break;
- case DxcCursor_WhileStmt: ostr << "WhileStmt"; break;
- case DxcCursor_DoStmt: ostr << "DoStmt"; break;
- case DxcCursor_ForStmt: ostr << "ForStmt"; break;
- case DxcCursor_GotoStmt: ostr << "GotoStmt"; break;
- case DxcCursor_IndirectGotoStmt: ostr << "IndirectGotoStmt"; break;
- case DxcCursor_ContinueStmt: ostr << "ContinueStmt"; break;
- case DxcCursor_BreakStmt: ostr << "BreakStmt"; break;
- case DxcCursor_ReturnStmt: ostr << "ReturnStmt"; break;
- case DxcCursor_GCCAsmStmt: ostr << "GCCAsmStmt"; break;
- case DxcCursor_ObjCAtTryStmt: ostr << "ObjCAtTryStmt"; break;
- case DxcCursor_ObjCAtCatchStmt: ostr << "ObjCAtCatchStmt"; break;
- case DxcCursor_ObjCAtFinallyStmt: ostr << "ObjCAtFinallyStmt"; break;
- case DxcCursor_ObjCAtThrowStmt: ostr << "ObjCAtThrowStmt"; break;
- case DxcCursor_ObjCAtSynchronizedStmt: ostr << "ObjCAtSynchronizedStmt"; break;
- case DxcCursor_ObjCAutoreleasePoolStmt: ostr << "ObjCAutoreleasePoolStmt"; break;
- case DxcCursor_ObjCForCollectionStmt: ostr << "ObjCForCollectionStmt"; break;
- case DxcCursor_CXXCatchStmt: ostr << "CXXCatchStmt"; break;
- case DxcCursor_CXXTryStmt: ostr << "CXXTryStmt"; break;
- case DxcCursor_CXXForRangeStmt: ostr << "CXXForRangeStmt"; break;
- case DxcCursor_SEHTryStmt: ostr << "SEHTryStmt"; break;
- case DxcCursor_SEHExceptStmt: ostr << "SEHExceptStmt"; break;
- case DxcCursor_SEHFinallyStmt: ostr << "SEHFinallyStmt"; break;
- case DxcCursor_MSAsmStmt: ostr << "MSAsmStmt"; break;
- case DxcCursor_NullStmt: ostr << "NullStmt"; break;
- case DxcCursor_DeclStmt: ostr << "DeclStmt"; break;
- case DxcCursor_OMPParallelDirective: ostr << "OMPParallelDirective"; break;
- case DxcCursor_TranslationUnit: ostr << "TranslationUnit"; break;
- case DxcCursor_UnexposedAttr: ostr << "UnexposedAttr"; break;
- #if 0
- CXCursor_IBActionAttr = 401,
- CXCursor_IBOutletAttr = 402,
- CXCursor_IBOutletCollectionAttr = 403,
- CXCursor_CXXFinalAttr = 404,
- CXCursor_CXXOverrideAttr = 405,
- CXCursor_AnnotateAttr = 406,
- CXCursor_AsmLabelAttr = 407,
- CXCursor_PackedAttr = 408,
-
- /* Preprocessing */
- CXCursor_PreprocessingDirective = 500,
- CXCursor_MacroDefinition = 501,
- CXCursor_MacroExpansion = 502,
- CXCursor_InclusionDirective = 503,
- case CXCursor_FunctionDecl:
- break;
- case CXCursor_ClassDecl:
- ostr << "class decl";
- break;
- case CXCursor_TranslationUnit:
- ostr << "translation unit";
- break;
- #endif
- default:
- ostr << "unknown/unhandled cursor kind " << kind;
- break;
- }
- DxcTypeKind typeKind;
- if (type != nullptr && SUCCEEDED(type->GetKind(&typeKind)) &&
- typeKind != DxcTypeKind_Invalid) {
- LPSTR name;
- type->GetSpelling(&name);
- ostr << " [type " << name << "]";
- CoTaskMemFree(name);
- }
- ostr << '\n';
- // Recurse.
- IDxcCursor** children = nullptr;
- unsigned childrenCount;
- cursor->GetChildren(0, 64, &childrenCount, &children);
- for (unsigned i = 0; i < childrenCount; i++) {
- AppendCursorString(children[i], indent + 1, ostr);
- children[i]->Release();
- }
- CoTaskMemFree(children);
- }
- public:
- std::string BuildASTString() {
- if (TU == nullptr) {
- return "<failed to build - TU is null>";
- }
- CComPtr<IDxcCursor> cursor;
- std::stringstream ostr;
- this->TU->GetCursor(&cursor);
- AppendCursorString(cursor, 0, ostr);
- return ostr.str();
- }
- };
|