Browse Source

Fixed a possible crash when instantiating template functions in the parser.

Signed-off-by: Dimitar Dobrev <dpldobrev@protonmail.com>
pull/1011/head
Dimitar Dobrev 8 years ago
parent
commit
97e24602c3
  1. 27
      src/CppParser/Parser.cpp
  2. 2
      src/CppParser/Parser.h

27
src/CppParser/Parser.cpp

@ -3013,6 +3013,29 @@ static bool IsInvalid(clang::Stmt* Body, std::unordered_set<clang::Stmt*>& Bodie @@ -3013,6 +3013,29 @@ static bool IsInvalid(clang::Stmt* Body, std::unordered_set<clang::Stmt*>& Bodie
return false;
}
std::stack<clang::Scope> Parser::GetScopesFor(clang::FunctionDecl* FD)
{
using namespace clang;
std::stack<DeclContext*> Contexts;
DeclContext* DC = FD;
while (DC)
{
Contexts.push(DC);
DC = DC->getParent();
}
std::stack<Scope> Scopes;
while (!Contexts.empty())
{
Scope S(Scopes.empty() ? 0 : &Scopes.top(),
Scope::ScopeFlags::DeclScope, c->getDiagnostics());
S.setEntity(Contexts.top());
Scopes.push(S);
Contexts.pop();
}
return Scopes;
}
void Parser::MarkValidity(Function* F)
{
using namespace clang;
@ -3028,8 +3051,12 @@ void Parser::MarkValidity(Function* F) @@ -3028,8 +3051,12 @@ void Parser::MarkValidity(Function* F)
auto Diagnostics = c->getSema().getDiagnostics().getClient();
auto SemaDiagnostics = static_cast<::DiagnosticConsumer*>(Diagnostics);
SemaDiagnostics->Decl = FD;
auto TUScope = c->getSema().TUScope;
std::stack<Scope> Scopes = GetScopesFor(FD);
c->getSema().TUScope = &Scopes.top();
c->getSema().InstantiateFunctionDefinition(FD->getLocStart(), FD,
/*Recursive*/true);
c->getSema().TUScope = TUScope;
F->isInvalid = FD->isInvalidDecl();
if (!F->isInvalid)
{

2
src/CppParser/Parser.h

@ -16,6 +16,7 @@ @@ -16,6 +16,7 @@
#include <clang/AST/Type.h>
#include <clang/Basic/TargetInfo.h>
#include <clang/Frontend/CompilerInstance.h>
#include <clang/Sema/Scope.h>
#include "CXXABI.h"
#include "CppParser.h"
@ -120,6 +121,7 @@ private: @@ -120,6 +121,7 @@ private:
Parameter* WalkParameter(const clang::ParmVarDecl* PVD,
const clang::SourceLocation& ParamStartLoc);
void SetBody(const clang::FunctionDecl* FD, Function* F);
std::stack<clang::Scope> GetScopesFor(clang::FunctionDecl* FD);
void MarkValidity(Function* F);
void WalkFunction(const clang::FunctionDecl* FD, Function* F,
bool IsDependent = false);

Loading…
Cancel
Save