diff --git a/CMakeLists.txt b/CMakeLists.txt index fb50e21a..ba43af79 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -83,7 +83,7 @@ set(CMAKE_C_STANDARD 99) # Settings --------------------------------------------------------------------- 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() # For debugging the release build on linux diff --git a/src/lib_cxx/data/parser/cxx/CxxAstVisitorComponentBraceRecorder.cpp b/src/lib_cxx/data/parser/cxx/CxxAstVisitorComponentBraceRecorder.cpp index e14cdf9f..9b90ff0c 100644 --- a/src/lib_cxx/data/parser/cxx/CxxAstVisitorComponentBraceRecorder.cpp +++ b/src/lib_cxx/data/parser/cxx/CxxAstVisitorComponentBraceRecorder.cpp @@ -42,7 +42,7 @@ void CxxAstVisitorComponentBraceRecorder::visitNamespaceDecl(clang::NamespaceDec { recordBraces( getFilePath(d->getBeginLoc()), - getParseLocation(getFirstLBraceLocation(d->getBeginLoc())), + getParseLocation(getFirstLBraceLocation(d->getBeginLoc(), d->getEndLoc())), getParseLocation(getLastRBraceLocation(d->getBeginLoc(), d->getEndLoc())) ); } @@ -142,11 +142,14 @@ void CxxAstVisitorComponentBraceRecorder::recordBraces( } clang::SourceLocation CxxAstVisitorComponentBraceRecorder::getFirstLBraceLocation( - clang::SourceLocation searchStartLoc) const + clang::SourceLocation searchStartLoc, clang::SourceLocation searchEndLoc) const { const clang::SourceManager& sm = m_astContext->getSourceManager(); const clang::LangOptions& opts = m_astContext->getLangOpts(); + searchStartLoc = sm.getExpansionLoc(searchStartLoc); + searchEndLoc = sm.getExpansionLoc(searchEndLoc); + { clang::Token token; if (clang::Lexer::getRawToken(searchStartLoc, token, sm, opts)) @@ -173,38 +176,41 @@ clang::SourceLocation CxxAstVisitorComponentBraceRecorder::getFirstLBraceLocatio { break; } + + if (searchEndLoc < searchStartLoc) + { + break; + } } return clang::SourceLocation(); } 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::LangOptions& opts = m_astContext->getLangOpts(); + searchStartLoc = sm.getExpansionLoc(searchStartLoc); + searchEndLoc = sm.getExpansionLoc(searchEndLoc); + { searchEndLoc = searchEndLoc.getLocWithOffset(-1); llvm::Optional 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) { 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) { break; diff --git a/src/lib_cxx/data/parser/cxx/CxxAstVisitorComponentBraceRecorder.h b/src/lib_cxx/data/parser/cxx/CxxAstVisitorComponentBraceRecorder.h index 84e2a1f5..4d9e2661 100644 --- a/src/lib_cxx/data/parser/cxx/CxxAstVisitorComponentBraceRecorder.h +++ b/src/lib_cxx/data/parser/cxx/CxxAstVisitorComponentBraceRecorder.h @@ -25,9 +25,10 @@ private: FilePath getFilePath(const clang::SourceLocation& loc); 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( - const clang::SourceLocation& searchStartLoc, clang::SourceLocation searchEndLoc) const; + clang::SourceLocation searchStartLoc, clang::SourceLocation searchEndLoc) const; clang::ASTContext* m_astContext; std::shared_ptr m_client; diff --git a/src/lib_cxx/data/parser/cxx/CxxAstVisitorComponentIndexer.cpp b/src/lib_cxx/data/parser/cxx/CxxAstVisitorComponentIndexer.cpp index 2e5d09b3..67622105 100644 --- a/src/lib_cxx/data/parser/cxx/CxxAstVisitorComponentIndexer.cpp +++ b/src/lib_cxx/data/parser/cxx/CxxAstVisitorComponentIndexer.cpp @@ -263,6 +263,11 @@ void CxxAstVisitorComponentIndexer::visitFieldDecl(clang::FieldDecl* d) { if (getAstVisitor()->shouldVisitDecl(d)) { + if (clang::isa(d)) + { + return; + } + const ParseLocation location = getParseLocation(d->getLocation()); Id fieldId = getOrCreateSymbolId(d); diff --git a/src/test/CxxParserTestSuite.h b/src/test/CxxParserTestSuite.h index 11ab50fa..362b0466 100644 --- a/src/test/CxxParserTestSuite.h +++ b/src/test/CxxParserTestSuite.h @@ -4304,6 +4304,46 @@ public: TS_ASSERT_EQUALS(client->localSymbols.size(), 8); } + void test_cxx_parser_finds_braces_with_closing_bracket_in_macro() + { + std::shared_ptr client = parseCode( +R"( +namespace constants +{ + +#define CONSTANT(name, x)\ + int name = x;\ + } namespace constants { + +CONSTANT(half, 5) +CONSTANT(third, 3) +} +)" + ); + + TS_ASSERT(utility::containsElement(client->localSymbols, L"input.cc<3:1> <3:1 3:1>")); + TS_ASSERT(utility::containsElement(client->localSymbols, L"input.cc<3:1> <7:2 7:2>")); + // TS_ASSERT(utility::containsElement(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(client->localSymbols, L"input.cc<7:1> <7:1 7:1>")); + // TS_ASSERT(utility::containsElement(client->localSymbols, L"input.cc<7:1> <10:1 10:1>")); // missing + // TS_ASSERT(utility::containsElement(client->localSymbols, L"<0:0> <10:1 10:1>")); // unwanted sideeffect + } + void test_cxx_parser_finds_correct_signature_location_of_constructor_with_initializer_list() { std::shared_ptr client = parseCode(