data: Fixed indexer crashes in Cinder after Clang update

This commit is contained in:
Eberhard Graether
2019-05-21 17:50:56 +02:00
parent 4d6cb464c4
commit e2157b8352
5 changed files with 68 additions and 16 deletions
+1 -1
View File
@@ -83,7 +83,7 @@ set(CMAKE_C_STANDARD 99)
# Settings --------------------------------------------------------------------- # Settings ---------------------------------------------------------------------
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang") if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unknown-warning-option -fcolor-diagnostics") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unknown-warning-option -fcolor-diagnostics -fvisibility-inlines-hidden")
endif() endif()
# For debugging the release build on linux # For debugging the release build on linux
@@ -42,7 +42,7 @@ void CxxAstVisitorComponentBraceRecorder::visitNamespaceDecl(clang::NamespaceDec
{ {
recordBraces( recordBraces(
getFilePath(d->getBeginLoc()), getFilePath(d->getBeginLoc()),
getParseLocation(getFirstLBraceLocation(d->getBeginLoc())), getParseLocation(getFirstLBraceLocation(d->getBeginLoc(), d->getEndLoc())),
getParseLocation(getLastRBraceLocation(d->getBeginLoc(), d->getEndLoc())) getParseLocation(getLastRBraceLocation(d->getBeginLoc(), d->getEndLoc()))
); );
} }
@@ -142,11 +142,14 @@ void CxxAstVisitorComponentBraceRecorder::recordBraces(
} }
clang::SourceLocation CxxAstVisitorComponentBraceRecorder::getFirstLBraceLocation( clang::SourceLocation CxxAstVisitorComponentBraceRecorder::getFirstLBraceLocation(
clang::SourceLocation searchStartLoc) const clang::SourceLocation searchStartLoc, clang::SourceLocation searchEndLoc) const
{ {
const clang::SourceManager& sm = m_astContext->getSourceManager(); const clang::SourceManager& sm = m_astContext->getSourceManager();
const clang::LangOptions& opts = m_astContext->getLangOpts(); const clang::LangOptions& opts = m_astContext->getLangOpts();
searchStartLoc = sm.getExpansionLoc(searchStartLoc);
searchEndLoc = sm.getExpansionLoc(searchEndLoc);
{ {
clang::Token token; clang::Token token;
if (clang::Lexer::getRawToken(searchStartLoc, token, sm, opts)) if (clang::Lexer::getRawToken(searchStartLoc, token, sm, opts))
@@ -173,38 +176,41 @@ clang::SourceLocation CxxAstVisitorComponentBraceRecorder::getFirstLBraceLocatio
{ {
break; break;
} }
if (searchEndLoc < searchStartLoc)
{
break;
}
} }
return clang::SourceLocation(); return clang::SourceLocation();
} }
clang::SourceLocation CxxAstVisitorComponentBraceRecorder::getLastRBraceLocation( clang::SourceLocation CxxAstVisitorComponentBraceRecorder::getLastRBraceLocation(
const clang::SourceLocation& searchStartLoc, clang::SourceLocation searchEndLoc) const clang::SourceLocation searchStartLoc, clang::SourceLocation searchEndLoc) const
{ {
const clang::SourceManager& sm = m_astContext->getSourceManager(); const clang::SourceManager& sm = m_astContext->getSourceManager();
const clang::LangOptions& opts = m_astContext->getLangOpts(); const clang::LangOptions& opts = m_astContext->getLangOpts();
searchStartLoc = sm.getExpansionLoc(searchStartLoc);
searchEndLoc = sm.getExpansionLoc(searchEndLoc);
{ {
searchEndLoc = searchEndLoc.getLocWithOffset(-1); searchEndLoc = searchEndLoc.getLocWithOffset(-1);
llvm::Optional<clang::Token> token = clang::Lexer::findNextToken(searchEndLoc, sm, opts); llvm::Optional<clang::Token> token = clang::Lexer::findNextToken(searchEndLoc, sm, opts);
if (token.hasValue()) if (token.hasValue() && token.getValue().getKind() == clang::tok::r_brace)
{ {
if (token.getValue().getKind() == clang::tok::r_brace) return token.getValue().getLocation();
{
return token.getValue().getLocation();
}
} }
} }
while (true) while (true)
{ {
clang::Token token; clang::Token token;
if (clang::Lexer::getRawToken(searchEndLoc, token, sm, opts)) if (clang::Lexer::getRawToken(searchEndLoc, token, sm, opts) && token.getKind() == clang::tok::r_brace)
{ {
if (token.getKind() == clang::tok::r_brace) return token.getLocation();
{
return token.getLocation();
}
} }
if (searchEndLoc < searchStartLoc) if (searchEndLoc < searchStartLoc)
{ {
break; break;
@@ -25,9 +25,10 @@ private:
FilePath getFilePath(const clang::SourceLocation& loc); FilePath getFilePath(const clang::SourceLocation& loc);
void recordBraces(const FilePath& filePath, const ParseLocation& lbraceLoc, const ParseLocation& rbraceLoc); void recordBraces(const FilePath& filePath, const ParseLocation& lbraceLoc, const ParseLocation& rbraceLoc);
clang::SourceLocation getFirstLBraceLocation(clang::SourceLocation searchStartLoc) const; clang::SourceLocation getFirstLBraceLocation(
clang::SourceLocation searchStartLoc, clang::SourceLocation searchEndLoc) const;
clang::SourceLocation getLastRBraceLocation( clang::SourceLocation getLastRBraceLocation(
const clang::SourceLocation& searchStartLoc, clang::SourceLocation searchEndLoc) const; clang::SourceLocation searchStartLoc, clang::SourceLocation searchEndLoc) const;
clang::ASTContext* m_astContext; clang::ASTContext* m_astContext;
std::shared_ptr<ParserClient> m_client; std::shared_ptr<ParserClient> m_client;
@@ -263,6 +263,11 @@ void CxxAstVisitorComponentIndexer::visitFieldDecl(clang::FieldDecl* d)
{ {
if (getAstVisitor()->shouldVisitDecl(d)) if (getAstVisitor()->shouldVisitDecl(d))
{ {
if (clang::isa<clang::ObjCIvarDecl>(d))
{
return;
}
const ParseLocation location = getParseLocation(d->getLocation()); const ParseLocation location = getParseLocation(d->getLocation());
Id fieldId = getOrCreateSymbolId(d); Id fieldId = getOrCreateSymbolId(d);
+40
View File
@@ -4304,6 +4304,46 @@ public:
TS_ASSERT_EQUALS(client->localSymbols.size(), 8); TS_ASSERT_EQUALS(client->localSymbols.size(), 8);
} }
void test_cxx_parser_finds_braces_with_closing_bracket_in_macro()
{
std::shared_ptr<TestIntermediateStorage> client = parseCode(
R"(
namespace constants
{
#define CONSTANT(name, x)\
int name = x;\
} namespace constants {
CONSTANT(half, 5)
CONSTANT(third, 3)
}
)"
);
TS_ASSERT(utility::containsElement<std::wstring>(client->localSymbols, L"input.cc<3:1> <3:1 3:1>"));
TS_ASSERT(utility::containsElement<std::wstring>(client->localSymbols, L"input.cc<3:1> <7:2 7:2>"));
// TS_ASSERT(utility::containsElement<std::wstring>(client->localSymbols, L"<0:0> <11:1 11:1>")); // unwanted sideeffect
client = parseCode(
R"(
#define CONSTANT(name, x)\
int name = x;\
} namespace constants {
namespace constants
{
CONSTANT(half, 5)
CONSTANT(third, 3)
}
)"
);
TS_ASSERT(utility::containsElement<std::wstring>(client->localSymbols, L"input.cc<7:1> <7:1 7:1>"));
// TS_ASSERT(utility::containsElement<std::wstring>(client->localSymbols, L"input.cc<7:1> <10:1 10:1>")); // missing
// TS_ASSERT(utility::containsElement<std::wstring>(client->localSymbols, L"<0:0> <10:1 10:1>")); // unwanted sideeffect
}
void test_cxx_parser_finds_correct_signature_location_of_constructor_with_initializer_list() void test_cxx_parser_finds_correct_signature_location_of_constructor_with_initializer_list()
{ {
std::shared_ptr<TestIntermediateStorage> client = parseCode( std::shared_ptr<TestIntermediateStorage> client = parseCode(