Browse Source

Initial commit supporting Clang 19

pull/1942/head
Christopher Franzwa 9 months ago
parent
commit
291e226c8a
  1. 2
      build/llvm/LLVM-commit
  2. 9
      build/llvm/LLVM.lua
  3. 8
      src/CppParser/ASTNameMangler.cpp
  4. 287
      src/CppParser/Comments.cpp
  5. 4
      src/CppParser/Link.cpp
  6. 2
      src/CppParser/ParseExpr.cpp
  7. 137
      src/CppParser/Parser.cpp
  8. 4
      src/CppParser/Parser.h

2
build/llvm/LLVM-commit

@ -1 +1 @@
6eb36aed86ea276695697093eb8136554c29286b cd708029e0b2869e80abe31ddb175f7c35361f90

9
build/llvm/LLVM.lua

@ -263,6 +263,8 @@ function cmake(gen, conf, builddir, options)
.. ' -DLLVM_INCLUDE_TESTS=false' .. ' -DLLVM_INCLUDE_TESTS=false'
.. ' -DLLVM_ENABLE_LIBEDIT=false' .. ' -DLLVM_ENABLE_LIBEDIT=false'
.. ' -DLLVM_ENABLE_LIBXML2=false' .. ' -DLLVM_ENABLE_LIBXML2=false'
.. ' -DLLVM_ENABLE_HIP=false'
.. ' -DLLVM_ENABLE_MLGO=false'
.. ' -DLLVM_ENABLE_TERMINFO=false' .. ' -DLLVM_ENABLE_TERMINFO=false'
.. ' -DLLVM_ENABLE_ZLIB=false' .. ' -DLLVM_ENABLE_ZLIB=false'
.. ' -DLLVM_ENABLE_ZSTD=false' .. ' -DLLVM_ENABLE_ZSTD=false'
@ -326,7 +328,7 @@ function cmake(gen, conf, builddir, options)
.. ' -DLLVM_TOOL_LLVM_MODEXTRACT_BUILD=false' .. ' -DLLVM_TOOL_LLVM_MODEXTRACT_BUILD=false'
.. ' -DLLVM_TOOL_LLVM_MT_BUILD=false' .. ' -DLLVM_TOOL_LLVM_MT_BUILD=false'
.. ' -DLLVM_TOOL_LLVM_NM_BUILD=false' .. ' -DLLVM_TOOL_LLVM_NM_BUILD=false'
.. ' -DLLVM_TOOL_LLVM_OBJCOPY_BUILD=false' .. ' -DLLVM_TOOL_LLVM_OBJCOPY_BUILD=true'
.. ' -DLLVM_TOOL_LLVM_OBJDUMP_BUILD=false' .. ' -DLLVM_TOOL_LLVM_OBJDUMP_BUILD=false'
.. ' -DLLVM_TOOL_LLVM_OPT_FUZZER_BUILD=false' .. ' -DLLVM_TOOL_LLVM_OPT_FUZZER_BUILD=false'
.. ' -DLLVM_TOOL_LLVM_OPT_REPORT_BUILD=false' .. ' -DLLVM_TOOL_LLVM_OPT_REPORT_BUILD=false'
@ -366,7 +368,8 @@ function cmake(gen, conf, builddir, options)
.. ' -DLLVM_TOOL_VERIFY_USELISTORDER_BUILD=false' .. ' -DLLVM_TOOL_VERIFY_USELISTORDER_BUILD=false'
.. ' -DLLVM_TOOL_VFABI_DEMANGLE_FUZZER_BUILD=false' .. ' -DLLVM_TOOL_VFABI_DEMANGLE_FUZZER_BUILD=false'
.. ' -DLLVM_TOOL_XCODE_TOOLCHAIN_BUILD=false' .. ' -DLLVM_TOOL_XCODE_TOOLCHAIN_BUILD=false'
.. ' -DLLVM_TOOL_YAML2OBJ_BUILD=false' .. ' -DLLVM_TOOL_YAML2OBJ_BUILD=true'
.. ' -DLLVM_TOOL_LLVM_OBJCOPY_BUILD=true'
.. ' -DLLVM_HAVE_LIBXAR=false' .. ' -DLLVM_HAVE_LIBXAR=false'
.. ' -DCLANG_BUILD_EXAMPLES=false ' .. ' -DCLANG_BUILD_EXAMPLES=false '
.. ' -DCLANG_BUILD_TOOLS=false' .. ' -DCLANG_BUILD_TOOLS=false'
@ -376,6 +379,8 @@ function cmake(gen, conf, builddir, options)
.. ' -DCLANG_INCLUDE_TESTS=false' .. ' -DCLANG_INCLUDE_TESTS=false'
.. ' -DCLANG_TOOL_AMDGPU_ARCH_BUILD=false' .. ' -DCLANG_TOOL_AMDGPU_ARCH_BUILD=false'
.. ' -DCLANG_TOOL_APINOTES_TEST_BUILD=false' .. ' -DCLANG_TOOL_APINOTES_TEST_BUILD=false'
.. ' -DCLANG_ENABLE_HIP=false'
.. ' -DCLANG_ENABLE_API_NOTES=false'
.. ' -DCLANG_TOOL_ARCMT_TEST_BUILD=false' .. ' -DCLANG_TOOL_ARCMT_TEST_BUILD=false'
.. ' -DCLANG_TOOL_CLANG_CHECK_BUILD=false' .. ' -DCLANG_TOOL_CLANG_CHECK_BUILD=false'
.. ' -DCLANG_TOOL_CLANG_DIFF_BUILD=false' .. ' -DCLANG_TOOL_CLANG_DIFF_BUILD=false'

8
src/CppParser/ASTNameMangler.cpp

@ -99,14 +99,18 @@ std::string ASTNameMangler::GetMangledStructor(const NamedDecl* ND, unsigned Str
return FrontendBuf; return FrontendBuf;
} }
std::string ASTNameMangler::GetMangledThunk(const CXXMethodDecl* MD, const ThunkInfo& T, bool /*ElideOverrideInfo*/) const std::string ASTNameMangler::GetMangledThunk(const CXXMethodDecl* MD, const ThunkInfo& T, bool ElideOverrideInfo) const
{ {
std::string FrontendBuf; std::string FrontendBuf;
llvm::raw_string_ostream FOS(FrontendBuf); llvm::raw_string_ostream FOS(FrontendBuf);
// TODO: Enable `ElideOverrideInfo` param if clang is updated to 19 // TODO: Enable `ElideOverrideInfo` param if clang is updated to 19
MC->mangleThunk(MD, T, /*ElideOverrideInfo,*/ FOS);
#if LLVM_VERSION_MAJOR >= 19
MC->mangleThunk(MD, T, ElideOverrideInfo, FOS);
#else
MC->mangleThunk(MD, T, FOS);
#endif
return FrontendBuf; return FrontendBuf;
} }

287
src/CppParser/Comments.cpp

@ -49,41 +49,22 @@ RawComment* Parser::WalkRawComment(const clang::RawComment* RC)
} }
static InlineCommandComment::RenderKind static InlineCommandComment::RenderKind
ConvertRenderKind(clang::comments::InlineCommandComment::RenderKind Kind) ConvertRenderKind(std::string Kind)
{ {
using namespace clang::comments; using namespace clang::comments;
switch (Kind) if (Kind == "b")
{ return AST::InlineCommandComment::RenderKind::RenderBold;
case clang::comments::InlineCommandComment::RenderNormal: else if (Kind == "c")
return CppSharp::CppParser::AST::InlineCommandComment::RenderKind::RenderNormal; return AST::InlineCommandComment::RenderKind::RenderMonospaced;
case clang::comments::InlineCommandComment::RenderBold: else if (Kind == "a")
return CppSharp::CppParser::AST::InlineCommandComment::RenderKind::RenderBold; return AST::InlineCommandComment::RenderKind::RenderAnchor;
case clang::comments::InlineCommandComment::RenderMonospaced: else if (Kind == "e")
return CppSharp::CppParser::AST::InlineCommandComment::RenderKind::RenderMonospaced; return AST::InlineCommandComment::RenderKind::RenderEmphasized;
case clang::comments::InlineCommandComment::RenderEmphasized: else
return CppSharp::CppParser::AST::InlineCommandComment::RenderKind::RenderEmphasized; return AST::InlineCommandComment::RenderKind::RenderNormal;
case clang::comments::InlineCommandComment::RenderAnchor:
return CppSharp::CppParser::AST::InlineCommandComment::RenderKind::RenderAnchor;
}
llvm_unreachable("Unknown render kind"); llvm_unreachable("Unknown render kind");
} }
static ParamCommandComment::PassDirection
ConvertParamPassDirection(clang::comments::ParamCommandComment::PassDirection Dir)
{
using namespace clang::comments;
switch (Dir)
{
case clang::comments::ParamCommandComment::In:
return CppSharp::CppParser::AST::ParamCommandComment::PassDirection::In;
case clang::comments::ParamCommandComment::Out:
return CppSharp::CppParser::AST::ParamCommandComment::PassDirection::Out;
case clang::comments::ParamCommandComment::InOut:
return CppSharp::CppParser::AST::ParamCommandComment::PassDirection::InOut;
}
llvm_unreachable("Unknown parameter pass direction");
}
static void HandleInlineContent(const clang::comments::InlineContentComment* CK, static void HandleInlineContent(const clang::comments::InlineContentComment* CK,
InlineContentComment* IC) InlineContentComment* IC)
{ {
@ -102,158 +83,120 @@ static void HandleBlockCommand(const clang::comments::BlockCommandComment* CK,
} }
} }
static Comment* ConvertCommentBlock(clang::comments::Comment* C) static Comment* ConvertCommentBlock(clang::comments::Comment* C, clang::CompilerInstance* CI)
{ {
using namespace clang; using namespace clang;
using clang::comments::Comment; using clang::comments::Comment;
// This needs to have an underscore else we get an ICE under VS2012. // This needs to have an underscore else we get an ICE under VS2012.
CppSharp::CppParser::AST::Comment* _Comment = 0; CppSharp::CppParser::AST::Comment* _Comment = nullptr;
auto kind = C->getCommentKind();
switch (C->getCommentKind()) if (auto CK = dyn_cast<const comments::FullComment>(C))
{ {
case Comment::FullCommentKind: auto FC = new FullComment();
{ _Comment = FC;
auto CK = cast<clang::comments::FullComment>(C); for (auto I = CK->child_begin(), E = CK->child_end(); I != E; ++I)
auto FC = new FullComment(); FC->Blocks.push_back(static_cast<BlockContentComment*>(ConvertCommentBlock(*I, CI)));
_Comment = FC; }
for (auto I = CK->child_begin(), E = CK->child_end(); I != E; ++I) else if (auto CK = dyn_cast<const comments::BlockCommandComment>(C))
{ {
auto Content = ConvertCommentBlock(*I); auto BC = new BlockCommandComment();
FC->Blocks.push_back(static_cast<BlockContentComment*>(Content)); _Comment = BC;
} HandleBlockCommand(CK, BC);
break; BC->paragraphComment = static_cast<ParagraphComment*>(ConvertCommentBlock(CK->getParagraph(), CI));
} }
case Comment::BlockCommandCommentKind: else if (auto CK = dyn_cast<const comments::ParamCommandComment>(C))
{ {
auto CK = cast<const clang::comments::BlockCommandComment>(C); auto PC = new ParamCommandComment();
auto BC = new BlockCommandComment(); _Comment = PC;
_Comment = BC; HandleBlockCommand(CK, PC);
HandleBlockCommand(CK, BC); if (CK->isParamIndexValid() && !CK->isVarArgParam())
BC->paragraphComment = static_cast<ParagraphComment*>(ConvertCommentBlock(CK->getParagraph())); PC->paramIndex = CK->getParamIndex();
break; PC->paragraphComment = static_cast<ParagraphComment*>(ConvertCommentBlock(CK->getParagraph(), CI));
} }
case Comment::ParamCommandCommentKind: else if (auto CK = dyn_cast<const comments::TParamCommandComment>(C))
{ {
auto CK = cast<clang::comments::ParamCommandComment>(C); auto TC = new TParamCommandComment();
auto PC = new ParamCommandComment(); _Comment = TC;
_Comment = PC; HandleBlockCommand(CK, TC);
HandleBlockCommand(CK, PC); if (CK->isPositionValid())
PC->direction = ConvertParamPassDirection(CK->getDirection()); for (unsigned I = 0, E = CK->getDepth(); I != E; ++I)
if (CK->isParamIndexValid() && !CK->isVarArgParam()) TC->Position.push_back(CK->getIndex(I));
PC->paramIndex = CK->getParamIndex(); TC->paragraphComment = static_cast<ParagraphComment*>(ConvertCommentBlock(CK->getParagraph(), CI));
PC->paragraphComment = static_cast<ParagraphComment*>(ConvertCommentBlock(CK->getParagraph())); }
break; else if (auto CK = dyn_cast<const comments::VerbatimBlockComment>(C))
} {
case Comment::TParamCommandCommentKind: auto VB = new VerbatimBlockComment();
{ _Comment = VB;
auto CK = cast<clang::comments::TParamCommandComment>(C); for (auto I = CK->child_begin(), E = CK->child_end(); I != E; ++I)
_Comment = new TParamCommandComment(); VB->Lines.push_back(static_cast<VerbatimBlockLineComment*>(ConvertCommentBlock(*I, CI)));
auto TC = new TParamCommandComment(); }
_Comment = TC; else if (auto CK = dyn_cast<const comments::VerbatimLineComment>(C))
HandleBlockCommand(CK, TC); {
if (CK->isPositionValid()) auto VL = new VerbatimLineComment();
for (unsigned I = 0, E = CK->getDepth(); I != E; ++I) _Comment = VL;
TC->Position.push_back(CK->getIndex(I)); VL->text = CK->getText().str();
TC->paragraphComment = static_cast<ParagraphComment*>(ConvertCommentBlock(CK->getParagraph())); }
break; else if (auto CK = dyn_cast<const comments::ParagraphComment>(C))
} {
case Comment::VerbatimBlockCommentKind: auto PC = new ParagraphComment();
{ _Comment = PC;
auto CK = cast<clang::comments::VerbatimBlockComment>(C); for (auto I = CK->child_begin(), E = CK->child_end(); I != E; ++I)
auto VB = new VerbatimBlockComment(); PC->Content.push_back(static_cast<InlineContentComment*>(ConvertCommentBlock(*I, CI)));
_Comment = VB; PC->isWhitespace = CK->isWhitespace();
for (auto I = CK->child_begin(), E = CK->child_end(); I != E; ++I) }
{ else if (auto CK = dyn_cast<const comments::HTMLStartTagComment>(C))
auto Line = ConvertCommentBlock(*I); {
VB->Lines.push_back(static_cast<VerbatimBlockLineComment*>(Line)); auto TC = new HTMLStartTagComment();
} _Comment = TC;
break; HandleInlineContent(CK, TC);
} TC->tagName = CK->getTagName().str();
case Comment::VerbatimLineCommentKind: for (unsigned I = 0, E = CK->getNumAttrs(); I != E; ++I)
{
auto CK = cast<clang::comments::VerbatimLineComment>(C);
auto VL = new VerbatimLineComment();
_Comment = VL;
VL->text = CK->getText().str();
break;
}
case Comment::ParagraphCommentKind:
{
auto CK = cast<clang::comments::ParagraphComment>(C);
auto PC = new ParagraphComment();
_Comment = PC;
for (auto I = CK->child_begin(), E = CK->child_end(); I != E; ++I)
{
auto Content = ConvertCommentBlock(*I);
PC->Content.push_back(static_cast<InlineContentComment*>(Content));
}
PC->isWhitespace = CK->isWhitespace();
break;
}
case Comment::HTMLStartTagCommentKind:
{
auto CK = cast<clang::comments::HTMLStartTagComment>(C);
auto TC = new HTMLStartTagComment();
_Comment = TC;
HandleInlineContent(CK, TC);
TC->tagName = CK->getTagName().str();
for (unsigned I = 0, E = CK->getNumAttrs(); I != E; ++I)
{
auto A = CK->getAttr(I);
auto Attr = HTMLStartTagComment::Attribute();
Attr.name = A.Name.str();
Attr.value = A.Value.str();
TC->Attributes.push_back(Attr);
}
break;
}
case Comment::HTMLEndTagCommentKind:
{
auto CK = cast<clang::comments::HTMLEndTagComment>(C);
auto TC = new HTMLEndTagComment();
_Comment = TC;
HandleInlineContent(CK, TC);
TC->tagName = CK->getTagName().str();
break;
}
case Comment::TextCommentKind:
{
auto CK = cast<clang::comments::TextComment>(C);
auto TC = new TextComment();
_Comment = TC;
HandleInlineContent(CK, TC);
TC->text = CK->getText().str();
break;
}
case Comment::InlineCommandCommentKind:
{ {
auto CK = cast<clang::comments::InlineCommandComment>(C); auto A = CK->getAttr(I);
auto IC = new InlineCommandComment(); auto Attr = HTMLStartTagComment::Attribute();
_Comment = IC; Attr.name = A.Name.str();
HandleInlineContent(CK, IC); Attr.value = A.Value.str();
IC->commandId = CK->getCommandID(); TC->Attributes.push_back(Attr);
IC->commentRenderKind = ConvertRenderKind(CK->getRenderKind());
for (unsigned I = 0, E = CK->getNumArgs(); I != E; ++I)
{
auto Arg = InlineCommandComment::Argument();
Arg.text = CK->getArgText(I).str();
IC->Arguments.push_back(Arg);
}
break;
} }
case Comment::VerbatimBlockLineCommentKind: }
else if (auto CK = dyn_cast<const comments::HTMLEndTagComment>(C))
{
auto TC = new HTMLEndTagComment();
_Comment = TC;
HandleInlineContent(CK, TC);
TC->tagName = CK->getTagName().str();
}
else if (auto CK = dyn_cast<const comments::TextComment>(C))
{
auto TC = new TextComment();
_Comment = TC;
HandleInlineContent(CK, TC);
TC->text = CK->getText().str();
}
else if (auto CK = dyn_cast<const comments::InlineCommandComment>(C))
{
auto IC = new InlineCommandComment();
_Comment = IC;
HandleInlineContent(CK, IC);
IC->commandId = CK->getCommandID();
IC->commentRenderKind = ConvertRenderKind(CK->getCommandName(CI->getASTContext().getCommentCommandTraits()).str());
for (unsigned I = 0, E = CK->getNumArgs(); I != E; ++I)
{ {
auto CK = cast<clang::comments::VerbatimBlockLineComment>(C); auto Arg = InlineCommandComment::Argument();
auto VL = new VerbatimBlockLineComment(); Arg.text = CK->getArgText(I).str();
_Comment = VL; IC->Arguments.push_back(Arg);
VL->text = CK->getText().str();
break;
} }
case Comment::NoCommentKind: return nullptr;
default:
llvm_unreachable("Unknown comment kind");
} }
else if (auto CK = dyn_cast<const comments::VerbatimBlockLineComment>(C))
{
auto VL = new VerbatimBlockLineComment();
_Comment = VL;
VL->text = CK->getText().str();
}
else
llvm_unreachable("Unknown comment kind");
assert(_Comment && "Invalid comment instance"); assert(_Comment && "Invalid comment instance");
return _Comment; return _Comment;
@ -272,7 +215,7 @@ void Parser::HandleComments(const clang::Decl* D, Declaration* Decl)
if (clang::comments::FullComment* FC = RC->parse(c->getASTContext(), &c->getPreprocessor(), D)) if (clang::comments::FullComment* FC = RC->parse(c->getASTContext(), &c->getPreprocessor(), D))
{ {
auto CB = static_cast<FullComment*>(ConvertCommentBlock(FC)); auto CB = static_cast<FullComment*>(ConvertCommentBlock(FC, c.get()));
RawComment->fullCommentBlock = CB; RawComment->fullCommentBlock = CB;
} }
} }

4
src/CppParser/Link.cpp

@ -70,9 +70,9 @@ bool Parser::LinkWindows(const CppLinkerOptions* LinkerOptions,
} }
const Triple& Triple = c->getTarget().getTriple(); const Triple& Triple = c->getTarget().getTriple();
driver::Driver D("", Triple.str(), c->getDiagnostics()); clang::driver::Driver D("", Triple.str(), c->getDiagnostics());
opt::InputArgList Args(0, 0); opt::InputArgList Args(0, 0);
driver::toolchains::MSVCToolChain TC(D, Triple, Args); clang::driver::toolchains::MSVCToolChain TC(D, Triple, Args);
std::vector<std::string> LibraryPaths; std::vector<std::string> LibraryPaths;
LibraryPaths.push_back("-libpath:" + TC.getSubDirectoryPath( LibraryPaths.push_back("-libpath:" + TC.getSubDirectoryPath(

2
src/CppParser/ParseExpr.cpp

@ -2322,7 +2322,7 @@ AST::Expr* Parser::WalkExpression(const clang::Expr* Expr)
_S->hasExplicitTemplateArgs = S->hasExplicitTemplateArgs(); _S->hasExplicitTemplateArgs = S->hasExplicitTemplateArgs();
_S->numTemplateArgs = S->getNumTemplateArgs(); _S->numTemplateArgs = S->getNumTemplateArgs();
_S->requiresADL = S->requiresADL(); _S->requiresADL = S->requiresADL();
_S->isOverloaded = S->isOverloaded(); _S->isOverloaded = S->getNumDecls() > 1;
_Expr = _S; _Expr = _S;
break; break;
} }

137
src/CppParser/Parser.cpp

@ -17,6 +17,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <llvm/TargetParser/Host.h> #include <llvm/TargetParser/Host.h>
#include <llvm/Support/ManagedStatic.h>
#include <llvm/Support/Path.h> #include <llvm/Support/Path.h>
#include <llvm/Support/raw_ostream.h> #include <llvm/Support/raw_ostream.h>
#include <llvm/Support/TargetSelect.h> #include <llvm/Support/TargetSelect.h>
@ -36,6 +37,7 @@
#include <clang/AST/Comment.h> #include <clang/AST/Comment.h>
#include <clang/AST/DeclFriend.h> #include <clang/AST/DeclFriend.h>
#include <clang/AST/ExprCXX.h> #include <clang/AST/ExprCXX.h>
#include "clang/AST/TemplateBase.h"
#include <clang/CodeGen/CodeGenAction.h> #include <clang/CodeGen/CodeGenAction.h>
#include <clang/Lex/DirectoryLookup.h> #include <clang/Lex/DirectoryLookup.h>
#include <clang/Lex/HeaderSearch.h> #include <clang/Lex/HeaderSearch.h>
@ -1097,15 +1099,15 @@ static TagKind ConvertToTagKind(clang::TagTypeKind AS)
{ {
switch (AS) switch (AS)
{ {
case clang::TagTypeKind::TTK_Struct: case clang::TagTypeKind::Struct:
return TagKind::Struct; return TagKind::Struct;
case clang::TagTypeKind::TTK_Interface: case clang::TagTypeKind::Interface:
return TagKind::Interface; return TagKind::Interface;
case clang::TagTypeKind::TTK_Union: case clang::TagTypeKind::Union:
return TagKind::Union; return TagKind::Union;
case clang::TagTypeKind::TTK_Class: case clang::TagTypeKind::Class:
return TagKind::Class; return TagKind::Class;
case clang::TagTypeKind::TTK_Enum: case clang::TagTypeKind::Enum:
return TagKind::Enum; return TagKind::Enum;
} }
@ -1394,17 +1396,9 @@ Parser::WalkClassTemplateSpecialization(const clang::ClassTemplateSpecialization
CT->Specializations.push_back(TS); CT->Specializations.push_back(TS);
auto& TAL = CTS->getTemplateArgs(); auto& TAL = CTS->getTemplateArgs();
auto TSI = CTS->getTypeAsWritten(); TemplateSpecializationTypeLoc TSL;
if (TSI)
{ TS->Arguments = WalkTemplateArgumentList(&TAL, nullptr);
auto TL = TSI->getTypeLoc();
auto TSL = TL.getAs<TemplateSpecializationTypeLoc>();
TS->Arguments = WalkTemplateArgumentList(&TAL, &TSL);
}
else
{
TS->Arguments = WalkTemplateArgumentList(&TAL, (TemplateSpecializationTypeLoc*)0);
}
if (CTS->isCompleteDefinition()) if (CTS->isCompleteDefinition())
{ {
@ -1448,13 +1442,8 @@ Parser::WalkClassTemplatePartialSpecialization(const clang::ClassTemplatePartial
TS->specializationKind = WalkTemplateSpecializationKind(CTS->getSpecializationKind()); TS->specializationKind = WalkTemplateSpecializationKind(CTS->getSpecializationKind());
CT->Specializations.push_back(TS); CT->Specializations.push_back(TS);
auto& TAL = CTS->getTemplateArgs(); const TemplateArgumentList& TAL = CTS->getTemplateArgs();
if (auto TSI = CTS->getTypeAsWritten()) WalkTemplateArgumentList(&TAL, nullptr);
{
auto TL = TSI->getTypeLoc();
auto TSL = TL.getAs<TemplateSpecializationTypeLoc>();
TS->Arguments = WalkTemplateArgumentList(&TAL, &TSL);
}
if (CTS->isCompleteDefinition()) if (CTS->isCompleteDefinition())
{ {
@ -1567,7 +1556,11 @@ TypeTemplateParameter* Parser::WalkTypeTemplateParameter(const clang::TemplateTy
HandleDeclaration(TTPD, TP); HandleDeclaration(TTPD, TP);
if (TTPD->hasDefaultArgument()) if (TTPD->hasDefaultArgument())
TP->defaultArgument = GetQualifiedType(TTPD->getDefaultArgument()); {
auto TSI = TTPD->getDefaultArgument().getTypeSourceInfo();
if (TSI)
TP->defaultArgument = GetQualifiedType(TSI->getType());
}
TP->depth = TTPD->getDepth(); TP->depth = TTPD->getDepth();
TP->index = TTPD->getIndex(); TP->index = TTPD->getIndex();
TP->isParameterPack = TTPD->isParameterPack(); TP->isParameterPack = TTPD->isParameterPack();
@ -1591,7 +1584,7 @@ NonTypeTemplateParameter* Parser::WalkNonTypeTemplateParameter(const clang::NonT
HandleDeclaration(NTTPD, NTP); HandleDeclaration(NTTPD, NTP);
if (NTTPD->hasDefaultArgument()) if (NTTPD->hasDefaultArgument())
NTP->defaultArgument = WalkExpressionObsolete(NTTPD->getDefaultArgument()); NTP->defaultArgument = WalkExpressionObsolete(NTTPD->getDefaultArgument().getSourceExpression());
NTP->type = GetQualifiedType(NTTPD->getType()); NTP->type = GetQualifiedType(NTTPD->getType());
NTP->depth = NTTPD->getDepth(); NTP->depth = NTTPD->getDepth();
NTP->index = NTTPD->getIndex(); NTP->index = NTTPD->getIndex();
@ -1641,6 +1634,39 @@ std::vector<TemplateArgument> Parser::WalkTemplateArgumentList(const clang::Temp
//-----------------------------------// //-----------------------------------//
template <typename TypeLoc>
std::vector<TemplateArgument> Parser::WalkTemplateArgumentList(
llvm::ArrayRef<clang::TemplateArgument> TAL, TypeLoc* TSTL)
{
using namespace clang;
const bool LocValid = TSTL && !TSTL->isNull() && TSTL->getTypePtr();
std::vector<AST::TemplateArgument> params;
const size_t typeLocNumArgs = LocValid ? TSTL->getNumArgs() : 0;
for (size_t i = 0, e = TAL.size(); i < e; ++i)
{
const clang::TemplateArgument& TA = TAL[i];
TemplateArgumentLoc TArgLoc;
TemplateArgumentLoc* ArgLoc = nullptr;
if (i < typeLocNumArgs && e == typeLocNumArgs)
{
TArgLoc = TSTL->getArgLoc(i);
ArgLoc = &TArgLoc;
}
auto Arg = WalkTemplateArgument(TA, ArgLoc);
params.push_back(Arg);
}
return params;
}
//-----------------------------------//
std::vector<TemplateArgument> std::vector<TemplateArgument>
Parser::WalkTemplateArgumentList(const clang::TemplateArgumentList* TAL, Parser::WalkTemplateArgumentList(const clang::TemplateArgumentList* TAL,
const clang::ASTTemplateArgumentListInfo* TALI) const clang::ASTTemplateArgumentListInfo* TALI)
@ -1893,7 +1919,7 @@ Parser::WalkVarTemplateSpecialization(const clang::VarTemplateSpecializationDecl
VT->Specializations.push_back(TS); VT->Specializations.push_back(TS);
auto& TAL = VTS->getTemplateArgs(); auto& TAL = VTS->getTemplateArgs();
auto TSI = VTS->getTypeAsWritten(); auto TSI = VTS->getTypeSourceInfo();
if (TSI) if (TSI)
{ {
auto TL = TSI->getTypeLoc(); auto TL = TSI->getTypeLoc();
@ -1933,7 +1959,7 @@ Parser::WalkVarTemplatePartialSpecialization(const clang::VarTemplatePartialSpec
VT->Specializations.push_back(TS); VT->Specializations.push_back(TS);
auto& TAL = VTS->getTemplateArgs(); auto& TAL = VTS->getTemplateArgs();
if (auto TSI = VTS->getTypeAsWritten()) if (auto TSI = VTS->getTypeSourceInfo())
{ {
auto TL = TSI->getTypeLoc(); auto TL = TSI->getTypeLoc();
auto TSL = TL.getAs<TemplateSpecializationTypeLoc>(); auto TSL = TL.getAs<TemplateSpecializationTypeLoc>();
@ -2812,11 +2838,9 @@ Type* Parser::WalkType(clang::QualType QualType, const clang::TypeLoc* TL, bool
if (TS->isSugared()) if (TS->isSugared())
TST->desugared = GetQualifiedType(TS->getCanonicalTypeInternal(), TL); TST->desugared = GetQualifiedType(TS->getCanonicalTypeInternal(), TL);
TemplateArgumentList TArgs(TemplateArgumentList::OnStack, TS->template_arguments());
if (!LocValid) if (!LocValid)
{ {
TST->Arguments = WalkTemplateArgumentList(&TArgs, (TemplateSpecializationTypeLoc*)nullptr); TST->Arguments = WalkTemplateArgumentList(TS->template_arguments(), (TemplateSpecializationTypeLoc*)nullptr);
Ty = TST; Ty = TST;
break; break;
} }
@ -2840,21 +2864,21 @@ Type* Parser::WalkType(clang::QualType QualType, const clang::TypeLoc* TL, bool
case TypeLoc::DependentTemplateSpecialization: case TypeLoc::DependentTemplateSpecialization:
{ {
DependentTemplateSpecializationTypeLoc TSpecTL = TL->getAs<DependentTemplateSpecializationTypeLoc>(); DependentTemplateSpecializationTypeLoc TSpecTL = TL->getAs<DependentTemplateSpecializationTypeLoc>();
TST->Arguments = WalkTemplateArgumentList(&TArgs, &TSpecTL); TST->Arguments = WalkTemplateArgumentList(TS->template_arguments(), &TSpecTL);
Ty = TST; Ty = TST;
break; break;
} }
case TypeLoc::TemplateSpecialization: case TypeLoc::TemplateSpecialization:
{ {
TemplateSpecializationTypeLoc TSpecTL = TL->getAs<TemplateSpecializationTypeLoc>(); TemplateSpecializationTypeLoc TSpecTL = TL->getAs<TemplateSpecializationTypeLoc>();
TST->Arguments = WalkTemplateArgumentList(&TArgs, &TSpecTL); TST->Arguments = WalkTemplateArgumentList(TS->template_arguments(), &TSpecTL);
Ty = TST; Ty = TST;
break; break;
} }
case TypeLoc::TemplateTypeParm: case TypeLoc::TemplateTypeParm:
{ {
TemplateTypeParmTypeLoc TTPTL = TL->getAs<TemplateTypeParmTypeLoc>(); TemplateTypeParmTypeLoc TTPTL = TL->getAs<TemplateTypeParmTypeLoc>();
TST->Arguments = WalkTemplateArgumentList(&TArgs, (TemplateSpecializationTypeLoc*)nullptr); TST->Arguments = WalkTemplateArgumentList(TS->template_arguments(), (TemplateSpecializationTypeLoc*)nullptr);
break; break;
} }
default: default:
@ -2873,11 +2897,9 @@ Type* Parser::WalkType(clang::QualType QualType, const clang::TypeLoc* TL, bool
if (TS->isSugared()) if (TS->isSugared())
TST->desugared = GetQualifiedType(TS->getCanonicalTypeInternal(), TL); TST->desugared = GetQualifiedType(TS->getCanonicalTypeInternal(), TL);
TemplateArgumentList TArgs(TemplateArgumentList::OnStack, TS->template_arguments());
if (!LocValid) if (!LocValid)
{ {
TST->Arguments = WalkTemplateArgumentList(&TArgs, (DependentTemplateSpecializationTypeLoc*)nullptr); TST->Arguments = WalkTemplateArgumentList(TS->template_arguments(), (DependentTemplateSpecializationTypeLoc*)nullptr);
Ty = TST; Ty = TST;
break; break;
} }
@ -2901,18 +2923,18 @@ Type* Parser::WalkType(clang::QualType QualType, const clang::TypeLoc* TL, bool
case TypeLoc::DependentTemplateSpecialization: case TypeLoc::DependentTemplateSpecialization:
{ {
DependentTemplateSpecializationTypeLoc TSpecTL = TL->getAs<DependentTemplateSpecializationTypeLoc>(); DependentTemplateSpecializationTypeLoc TSpecTL = TL->getAs<DependentTemplateSpecializationTypeLoc>();
TST->Arguments = WalkTemplateArgumentList(&TArgs, &TSpecTL); TST->Arguments = WalkTemplateArgumentList(TS->template_arguments(), &TSpecTL);
break; break;
} }
case TypeLoc::TemplateSpecialization: case TypeLoc::TemplateSpecialization:
{ {
TemplateSpecializationTypeLoc TSpecTL = TL->getAs<TemplateSpecializationTypeLoc>(); TemplateSpecializationTypeLoc TSpecTL = TL->getAs<TemplateSpecializationTypeLoc>();
TST->Arguments = WalkTemplateArgumentList(&TArgs, &TSpecTL); TST->Arguments = WalkTemplateArgumentList(TS->template_arguments(), &TSpecTL);
break; break;
} }
case TypeLoc::TemplateTypeParm: case TypeLoc::TemplateTypeParm:
{ {
TST->Arguments = WalkTemplateArgumentList(&TArgs, (DependentTemplateSpecializationTypeLoc*)nullptr); TST->Arguments = WalkTemplateArgumentList(TS->template_arguments(), (DependentTemplateSpecializationTypeLoc*)nullptr);
break; break;
} }
default: default:
@ -3510,7 +3532,7 @@ void Parser::WalkFunction(const clang::FunctionDecl* FD, Function* F)
F->isConstExpr = FD->isConstexpr(); F->isConstExpr = FD->isConstexpr();
F->isVariadic = FD->isVariadic(); F->isVariadic = FD->isVariadic();
F->isDependent = FD->isDependentContext(); F->isDependent = FD->isDependentContext();
F->isPure = FD->isPure(); F->isPure = FD->isPureVirtual();
F->isDeleted = FD->isDeleted(); F->isDeleted = FD->isDeleted();
F->isDefaulted = FD->isDefaulted(); F->isDefaulted = FD->isDefaulted();
SetBody(FD, F); SetBody(FD, F);
@ -4476,7 +4498,6 @@ Declaration* Parser::WalkDeclaration(const clang::Decl* D)
break; break;
} }
case Decl::BuiltinTemplate: case Decl::BuiltinTemplate:
case Decl::ClassScopeFunctionSpecialization:
case Decl::PragmaComment: case Decl::PragmaComment:
case Decl::PragmaDetectMismatch: case Decl::PragmaDetectMismatch:
case Decl::Empty: case Decl::Empty:
@ -4614,31 +4635,31 @@ void Parser::SetupLLVMCodegen()
} }
bool Parser::SetupSourceFiles(const std::vector<std::string>& SourceFiles, bool Parser::SetupSourceFiles(const std::vector<std::string>& SourceFiles,
std::vector<const clang::FileEntry*>& FileEntries) std::vector<clang::OptionalFileEntryRef>& FileEntries)
{ {
// Check that the file is reachable. clang::ConstSearchDirIterator* Dir = nullptr;
clang::ConstSearchDirIterator* Dir = 0; llvm::ArrayRef<std::pair<clang::OptionalFileEntryRef, clang::DirectoryEntryRef>> EmptyIncluders;
llvm::ArrayRef<std::pair<const clang::FileEntry*, clang::DirectoryEntryRef>> Includers;
for (const auto& SourceFile : SourceFiles) for (const auto& SourceFile : SourceFiles)
{ {
auto FileEntry = c->getPreprocessor().getHeaderSearchInfo().LookupFile(SourceFile, auto FileEntry = c->getPreprocessor().getHeaderSearchInfo().LookupFile(
clang::SourceLocation(), /*isAngled*/ true, SourceFile,
nullptr, Dir, Includers, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr); clang::SourceLocation(),
/*isAngled*/ true,
nullptr, Dir,
EmptyIncluders,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr);
if (!FileEntry) if (!FileEntry)
return false; return false;
FileEntries.push_back(&FileEntry.getPointer()->getFileEntry()); FileEntries.push_back(FileEntry);
} }
// Create a virtual file that includes the header. This gets rid of some
// Clang warnings about parsing an header file as the main file.
std::string source; std::string source;
for (const auto& SourceFile : SourceFiles) for (const auto& SourceFile : SourceFiles)
{ {
source += "#include \"" + SourceFile + "\"" + "\n"; source += "#include \"" + SourceFile + "\"\n";
} }
source += "\0"; source += "\0";
@ -4652,7 +4673,7 @@ bool Parser::SetupSourceFiles(const std::vector<std::string>& SourceFiles,
class SemaConsumer : public clang::SemaConsumer class SemaConsumer : public clang::SemaConsumer
{ {
public: public:
SemaConsumer(Parser& parser, std::vector<const clang::FileEntry*>& entries) SemaConsumer(Parser& parser, std::vector<clang::OptionalFileEntryRef>& entries)
: Parser(parser) : Parser(parser)
, FileEntries(entries) , FileEntries(entries)
{ {
@ -4662,7 +4683,7 @@ public:
private: private:
Parser& Parser; Parser& Parser;
std::vector<const clang::FileEntry*>& FileEntries; std::vector<clang::OptionalFileEntryRef>& FileEntries;
}; };
void SemaConsumer::HandleTranslationUnit(clang::ASTContext& Ctx) void SemaConsumer::HandleTranslationUnit(clang::ASTContext& Ctx)
@ -4675,7 +4696,7 @@ void SemaConsumer::HandleTranslationUnit(clang::ASTContext& Ctx)
Parser.HandleDeclaration(TU, Unit); Parser.HandleDeclaration(TU, Unit);
if (Unit->originalPtr == nullptr) if (Unit->originalPtr == nullptr)
Unit->originalPtr = (void*)FileEntry; Unit->originalPtr = (void*)&FileEntry->getFileEntry();
Parser.WalkAST(TU); Parser.WalkAST(TU);
} }
@ -4695,7 +4716,7 @@ ParserResult* Parser::Parse(const std::vector<std::string>& SourceFiles)
Setup(); Setup();
SetupLLVMCodegen(); SetupLLVMCodegen();
std::vector<const clang::FileEntry*> FileEntries; std::vector<clang::OptionalFileEntryRef> FileEntries;
if (!SetupSourceFiles(SourceFiles, FileEntries)) if (!SetupSourceFiles(SourceFiles, FileEntries))
{ {
res->kind = ParserResultKind::FileNotFound; res->kind = ParserResultKind::FileNotFound;
@ -4829,7 +4850,7 @@ ParserResultKind Parser::ParseSharedLib(const std::string& File,
for (const auto& ImportedSymbol : COFFObjectFile->import_directories()) for (const auto& ImportedSymbol : COFFObjectFile->import_directories())
{ {
llvm::StringRef Name; llvm::StringRef Name;
if (!ImportedSymbol.getName(Name) && (Name.endswith(".dll") || Name.endswith(".DLL"))) if (!ImportedSymbol.getName(Name) && (Name.ends_with(".dll") || Name.ends_with(".DLL")))
NativeLib->Dependencies.push_back(Name.str()); NativeLib->Dependencies.push_back(Name.str());
} }

4
src/CppParser/Parser.h

@ -70,7 +70,7 @@ namespace CppSharp { namespace CppParser {
void SetupLLVMCodegen(); void SetupLLVMCodegen();
bool SetupSourceFiles(const std::vector<std::string>& SourceFiles, bool SetupSourceFiles(const std::vector<std::string>& SourceFiles,
std::vector<const clang::FileEntry*>& FileEntries); std::vector<clang::OptionalFileEntryRef>& FileEntries);
bool IsSupported(const clang::NamedDecl* ND); bool IsSupported(const clang::NamedDecl* ND);
bool IsSupported(const clang::CXXMethodDecl* MD); bool IsSupported(const clang::CXXMethodDecl* MD);
@ -114,6 +114,8 @@ namespace CppSharp { namespace CppParser {
WalkVarTemplatePartialSpecialization(const clang::VarTemplatePartialSpecializationDecl* VTS); WalkVarTemplatePartialSpecialization(const clang::VarTemplatePartialSpecializationDecl* VTS);
template <typename TypeLoc> template <typename TypeLoc>
std::vector<AST::TemplateArgument> WalkTemplateArgumentList(const clang::TemplateArgumentList* TAL, TypeLoc* TSTL); std::vector<AST::TemplateArgument> WalkTemplateArgumentList(const clang::TemplateArgumentList* TAL, TypeLoc* TSTL);
template <typename TypeLoc>
std::vector<AST::TemplateArgument> WalkTemplateArgumentList(llvm::ArrayRef<clang::TemplateArgument> TAL,TypeLoc* TSTL);
std::vector<AST::TemplateArgument> WalkTemplateArgumentList(const clang::TemplateArgumentList* TAL, const clang::ASTTemplateArgumentListInfo* TSTL); std::vector<AST::TemplateArgument> WalkTemplateArgumentList(const clang::TemplateArgumentList* TAL, const clang::ASTTemplateArgumentListInfo* TSTL);
void WalkVTable(const clang::CXXRecordDecl* RD, AST::Class* C); void WalkVTable(const clang::CXXRecordDecl* RD, AST::Class* C);
AST::QualifiedType GetQualifiedType(clang::QualType qual, const clang::TypeLoc* TL = 0); AST::QualifiedType GetQualifiedType(clang::QualType qual, const clang::TypeLoc* TL = 0);

Loading…
Cancel
Save