diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 0693eb0d8..c18268e12 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -90,9 +90,12 @@ jobs: shell: bash run: build/build.sh prepack -platform $PLATFORM - - uses: actions/upload-artifact@v3 + - name: Upload Artifacts + uses: actions/upload-artifact@v4 with: name: intermediate + retention-days: 7 + overwrite: true path: | artifacts include/**/*.h @@ -116,7 +119,7 @@ jobs: - name: Set version run: nbgv cloud --all-vars - - uses: actions/download-artifact@v3 + - uses: actions/download-artifact@v4 with: name: intermediate @@ -129,7 +132,7 @@ jobs: run: build/build.sh pack - name: Upload package - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: CppSharp.nupkg path: | diff --git a/src/CppParser/Parser.cpp b/src/CppParser/Parser.cpp index 97d68c546..3e80f3d09 100644 --- a/src/CppParser/Parser.cpp +++ b/src/CppParser/Parser.cpp @@ -71,13 +71,13 @@ #define _assertm(condition, message, call) \ do{ \ if (!(condition)) { \ - std::cerr << "Assert at " \ + std::cerr << "Assert at `" \ << __FILE__ \ << ":" \ << __LINE__ \ - << " in " \ + << "` in `" \ << __FUNCTION__ \ - << "failed. " \ + << "` failed. " \ << message; \ call; \ } \ @@ -89,38 +89,57 @@ if (!(condition)) { \ const clang::SourceManager& _sm = sm; \ clang::SourceLocation _loc = loc; \ - std::cerr << "Assert at " \ + std::cerr << "Assert at `" \ << __FILE__ \ << ":" \ << __LINE__ \ - << " in " \ + << "` in `" \ << __FUNCTION__ \ - << "failed. " \ + << "` failed. " \ << message \ - << " Filename " \ + << " Filename `" \ << _sm.getFilename(_loc).str() \ << ":" \ << _sm.getSpellingLineNumber(_loc) \ - << "\n"; \ + << "`\n"; \ call; \ } \ }while(0) // Macros which output messages to console if parsing encounters oddity. -// If _DEBUG is defined but DEBUG_NO_ABORT is not macros abort. +// In debug builds, macros abort unless DEBUG_NO_ABORT is defined. // // Macro assertm outputs a message if condition is false. // Macro assertml outputs a message and parsing file and line on given source manager and source line. // // assertml adds newline ending. -#if defined(_DEBUG) && !defined(DEBUG_NO_ABORT) -#define assertm(condition, message) _assertm(condition, message, abort()) -#define assertml(condition, message, sm, source) _assertml(condition, message, sm, source, abort()) +#ifdef NDEBUG +#define debug_break() ((void)0) +#define debug_fail() ((void)0) #else -#define assertm(condition, message) _assertm(condition, message, ) -#define assertml(condition, message, sm, source) _assertml(condition, message, sm, source, ) + +#if __GNUC__ +#define debug_break() \ + __builtin_trap() +#elif _MSC_VER +#define debug_break() \ + __debugbreak() +#else +#define debug_break(c) \ + *reinterpret_cast(0) = 47283; +#endif + +#ifdef DEBUG_NO_ABORT +#define debug_fail() debug_break() +#else +#define debug_fail() debug_break(); abort() #endif +#endif + +#define assertm(condition, message) _assertm(condition, message, debug_fail()) +#define assertml(condition, message, sm, source) _assertml(condition, message, sm, source, debug_fail()) + using namespace CppSharp::CppParser; // We use this as a placeholder for pointer values that should be ignored. @@ -959,7 +978,14 @@ static clang::CXXRecordDecl* GetCXXRecordDeclFromBaseType(const clang::ASTContex return GetCXXRecordDeclFromTemplateName(TST->getTemplateName()); else if (auto Injected = Ty->getAs()) return Injected->getDecl(); + else if (auto TTPT = Ty->getAs()) { + return nullptr; + } + else if (auto DNT = Ty->getAs()) { + return nullptr; + } + Ty->dump(); assertml(0, "Could not get base CXX record from type. Unhandled type: ", context.getSourceManager(), base.getBeginLoc()); return nullptr; @@ -2695,41 +2721,59 @@ Type* Parser::WalkType(clang::QualType QualType, const clang::TypeLoc* TL, auto TST = new TemplateSpecializationType(); TemplateName Name = TS->getTemplateName(); - TST->_template = static_cast(WalkDeclaration( - Name.getAsTemplateDecl())); + TST->_template = static_cast(WalkDeclaration(Name.getAsTemplateDecl())); + if (TS->isSugared()) TST->desugared = GetQualifiedType(TS->getCanonicalTypeInternal(), TL); - TypeLoc UTL, ETL, ITL; + TemplateArgumentList TArgs(TemplateArgumentList::OnStack, TS->template_arguments()); - if (LocValid) + if (!LocValid) { - auto TypeLocClass = TL->getTypeLocClass(); - if (TypeLocClass == TypeLoc::Qualified) - { - UTL = TL->getUnqualifiedLoc(); - TL = &UTL; - } - else if (TypeLocClass == TypeLoc::Elaborated) - { - ETL = TL->getAs(); - ITL = ETL.getNextTypeLoc(); - TL = &ITL; - } - - assertm(TL->getTypeLocClass() == TypeLoc::TemplateSpecialization, "Only Template specialization accepted!\n"); + TST->Arguments = WalkTemplateArgumentList(&TArgs, (TemplateSpecializationTypeLoc*)nullptr); + Ty = TST; + break; } - TemplateSpecializationTypeLoc TSpecTL; - TemplateSpecializationTypeLoc *TSTL = 0; - if (LocValid) + TypeLoc UTL, ETL, ITL; + if (TL->getTypeLocClass() == TypeLoc::Qualified) { - TSpecTL = TL->getAs(); - TSTL = &TSpecTL; + UTL = TL->getUnqualifiedLoc(); + TL = &UTL; + } + + if (TL->getTypeLocClass() == TypeLoc::Elaborated) + { + ETL = TL->getAs(); + ITL = ETL.getNextTypeLoc(); + TL = &ITL; } - TemplateArgumentList TArgs(TemplateArgumentList::OnStack, TS->template_arguments()); - TST->Arguments = WalkTemplateArgumentList(&TArgs, TSTL); + switch (TL->getTypeLocClass()) { + case TypeLoc::DependentTemplateSpecialization: + { + DependentTemplateSpecializationTypeLoc TSpecTL = TL->getAs(); + TST->Arguments = WalkTemplateArgumentList(&TArgs, &TSpecTL); + Ty = TST; + break; + } + case TypeLoc::TemplateSpecialization: + { + TemplateSpecializationTypeLoc TSpecTL = TL->getAs(); + TST->Arguments = WalkTemplateArgumentList(&TArgs, &TSpecTL); + Ty = TST; + break; + } + case TypeLoc::TemplateTypeParm: + { + TemplateTypeParmTypeLoc TTPTL = TL->getAs(); + TST->Arguments = WalkTemplateArgumentList(&TArgs, (TemplateSpecializationTypeLoc*)nullptr); + break; + } + default: + assertml(0, "Unhandled TemplateSpecializationTypeLoc!\n", c->getSourceManager(), TL->getBeginLoc()); + break; + } Ty = TST; break; @@ -2741,38 +2785,52 @@ Type* Parser::WalkType(clang::QualType QualType, const clang::TypeLoc* TL, if (TS->isSugared()) TST->desugared = GetQualifiedType(TS->getCanonicalTypeInternal(), TL); + + TemplateArgumentList TArgs(TemplateArgumentList::OnStack, TS->template_arguments()); - TypeLoc UTL, ETL, ITL; - - if (LocValid) + if (!LocValid) { - auto TypeLocClass = TL->getTypeLocClass(); - if (TypeLocClass == TypeLoc::Qualified) - { - UTL = TL->getUnqualifiedLoc(); - TL = &UTL; - } - else if (TypeLocClass == TypeLoc::Elaborated) - { - ETL = TL->getAs(); - ITL = ETL.getNextTypeLoc(); - TL = &ITL; - } - assertml(TL->getTypeLocClass() == TypeLoc::DependentTemplateSpecialization, - "Dependent template only accepted!", - c->getSourceManager(), TL->getBeginLoc()); + TST->Arguments = WalkTemplateArgumentList(&TArgs, (DependentTemplateSpecializationTypeLoc*)nullptr); + Ty = TST; + break; } - DependentTemplateSpecializationTypeLoc TSpecTL; - DependentTemplateSpecializationTypeLoc *TSTL = 0; - if (LocValid) + TypeLoc UTL, ETL, ITL; + if (TL->getTypeLocClass() == TypeLoc::Qualified) { - TSpecTL = TL->getAs(); - TSTL = &TSpecTL; + UTL = TL->getUnqualifiedLoc(); + TL = &UTL; + } + + if (TL->getTypeLocClass() == TypeLoc::Elaborated) + { + ETL = TL->getAs(); + ITL = ETL.getNextTypeLoc(); + TL = &ITL; } - TemplateArgumentList TArgs(TemplateArgumentList::OnStack, TS->template_arguments()); - TST->Arguments = WalkTemplateArgumentList(&TArgs, TSTL); + switch (TL->getTypeLocClass()) { + case TypeLoc::DependentTemplateSpecialization: + { + DependentTemplateSpecializationTypeLoc TSpecTL = TL->getAs(); + TST->Arguments = WalkTemplateArgumentList(&TArgs, &TSpecTL); + break; + } + case TypeLoc::TemplateSpecialization: + { + TemplateSpecializationTypeLoc TSpecTL = TL->getAs(); + TST->Arguments = WalkTemplateArgumentList(&TArgs, &TSpecTL); + break; + } + case TypeLoc::TemplateTypeParm: + { + TST->Arguments = WalkTemplateArgumentList(&TArgs, (DependentTemplateSpecializationTypeLoc*)nullptr); + break; + } + default: + assertml(0, "Unhandled DependentTemplateSpecializationTypeLoc!\n", c->getSourceManager(), TL->getBeginLoc()); + break; + } Ty = TST; break;