Skip to content

Commit c3048ae

Browse files
committed
Fixed a crash when trying to get a source location for an implicit declaration.
Signed-off-by: Dimitar Dobrev <[email protected]>
1 parent fd9c952 commit c3048ae

File tree

1 file changed

+36
-12
lines changed

1 file changed

+36
-12
lines changed

src/CppParser/Parser.cpp

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,17 @@ static clang::Decl* GetPreviousDeclInContext(const clang::Decl* D)
481481
return nullptr;
482482
}
483483

484+
bool IsExplicit(const clang::Decl* D)
485+
{
486+
using namespace clang;
487+
488+
auto CTS = llvm::dyn_cast<ClassTemplateSpecializationDecl>(D);
489+
return !CTS ||
490+
CTS->getSpecializationKind() == TSK_ExplicitSpecialization ||
491+
CTS->getSpecializationKind() == TSK_ExplicitInstantiationDeclaration ||
492+
CTS->getSpecializationKind() == TSK_ExplicitInstantiationDefinition;
493+
}
494+
484495
static clang::SourceLocation GetDeclStartLocation(clang::CompilerInstance* C,
485496
const clang::Decl* D)
486497
{
@@ -500,7 +511,7 @@ static clang::SourceLocation GetDeclStartLocation(clang::CompilerInstance* C,
500511
return lineBeginLoc;
501512

502513
auto prevDecl = GetPreviousDeclInContext(D);
503-
if(!prevDecl)
514+
if(!prevDecl || !IsExplicit(prevDecl))
504515
return lineBeginLoc;
505516

506517
auto prevDeclEndLoc = SM.getExpansionLoc(prevDecl->getLocEnd());
@@ -816,15 +827,18 @@ void Parser::WalkRecord(const clang::RecordDecl* Record, Class* RC)
816827
if (Record->isImplicit())
817828
return;
818829

819-
auto headStartLoc = GetDeclStartLocation(c.get(), Record);
820-
auto headEndLoc = Record->getLocation(); // identifier location
821-
auto bodyEndLoc = Record->getLocEnd();
830+
if (IsExplicit(Record))
831+
{
832+
auto headStartLoc = GetDeclStartLocation(c.get(), Record);
833+
auto headEndLoc = Record->getLocation(); // identifier location
834+
auto bodyEndLoc = Record->getLocEnd();
822835

823-
auto headRange = clang::SourceRange(headStartLoc, headEndLoc);
824-
auto bodyRange = clang::SourceRange(headEndLoc, bodyEndLoc);
836+
auto headRange = clang::SourceRange(headStartLoc, headEndLoc);
837+
auto bodyRange = clang::SourceRange(headEndLoc, bodyEndLoc);
825838

826-
HandlePreprocessedEntities(RC, headRange, MacroLocation::ClassHead);
827-
HandlePreprocessedEntities(RC, bodyRange, MacroLocation::ClassBody);
839+
HandlePreprocessedEntities(RC, headRange, MacroLocation::ClassHead);
840+
HandlePreprocessedEntities(RC, bodyRange, MacroLocation::ClassBody);
841+
}
828842

829843
auto& Sema = c->getSema();
830844

@@ -3429,8 +3443,17 @@ void Parser::HandleDeclaration(const clang::Decl* D, Declaration* Decl)
34293443
Decl->USR = GetDeclUSR(D);
34303444
Decl->isImplicit = D->isImplicit();
34313445
Decl->location = SourceLocation(D->getLocation().getRawEncoding());
3432-
Decl->lineNumberStart = c->getSourceManager().getExpansionLineNumber(D->getLocStart());
3433-
Decl->lineNumberEnd = c->getSourceManager().getExpansionLineNumber(D->getLocEnd());
3446+
auto IsDeclExplicit = IsExplicit(D);
3447+
if (IsDeclExplicit)
3448+
{
3449+
Decl->lineNumberStart = c->getSourceManager().getExpansionLineNumber(D->getLocStart());
3450+
Decl->lineNumberEnd = c->getSourceManager().getExpansionLineNumber(D->getLocEnd());
3451+
}
3452+
else
3453+
{
3454+
Decl->lineNumberStart = -1;
3455+
Decl->lineNumberEnd = -1;
3456+
}
34343457

34353458
if (Decl->PreprocessedEntities.empty() && !D->isImplicit())
34363459
{
@@ -3442,7 +3465,7 @@ void Parser::HandleDeclaration(const clang::Decl* D, Declaration* Decl)
34423465
{
34433466
// Ignore function parameters as we already walk their preprocessed entities.
34443467
}
3445-
else
3468+
else if (IsDeclExplicit)
34463469
{
34473470
auto startLoc = GetDeclStartLocation(c.get(), D);
34483471
auto endLoc = D->getLocEnd();
@@ -3452,7 +3475,8 @@ void Parser::HandleDeclaration(const clang::Decl* D, Declaration* Decl)
34523475
}
34533476
}
34543477

3455-
HandleOriginalText(D, Decl);
3478+
if (IsDeclExplicit)
3479+
HandleOriginalText(D, Decl);
34563480
HandleComments(D, Decl);
34573481

34583482
if (const clang::ValueDecl *VD = clang::dyn_cast_or_null<clang::ValueDecl>(D))

0 commit comments

Comments
 (0)