logic: fixed policy for recording elements inside macro arguments and bodies
This commit is contained in:
@@ -645,12 +645,23 @@ ParseLocation CxxAstVisitor::getParseLocationOfFunctionBody(const clang::Functio
|
||||
return ParseLocation();
|
||||
}
|
||||
|
||||
ParseLocation CxxAstVisitor::getParseLocation(const clang::SourceLocation& loc) const
|
||||
ParseLocation CxxAstVisitor::getParseLocation(const clang::SourceLocation& sourceLocation) const
|
||||
{
|
||||
ParseLocation parseLocation;
|
||||
if (loc.isValid())
|
||||
if (sourceLocation.isValid())
|
||||
{
|
||||
clang::SourceManager& sourceManager = m_astContext->getSourceManager();
|
||||
|
||||
clang::SourceLocation loc = sourceLocation;
|
||||
if (sourceManager.isMacroBodyExpansion(sourceLocation))
|
||||
{
|
||||
loc = sourceManager.getExpansionLoc(sourceLocation);
|
||||
if (loc.isInvalid())
|
||||
{
|
||||
loc = sourceLocation;
|
||||
}
|
||||
}
|
||||
|
||||
clang::SourceLocation startLoc = sourceManager.getSpellingLoc(loc);
|
||||
clang::FileID fileId = sourceManager.getFileID(startLoc);
|
||||
|
||||
@@ -690,14 +701,37 @@ ParseLocation CxxAstVisitor::getParseLocation(const clang::SourceRange& sourceRa
|
||||
{
|
||||
const clang::SourceManager& sourceManager = m_astContext->getSourceManager();
|
||||
|
||||
const clang::SourceLocation endLoc = m_preprocessor->getLocForEndOfToken(sourceRange.getEnd());
|
||||
clang::SourceRange range = sourceRange;
|
||||
clang::SourceLocation endLoc = m_preprocessor->getLocForEndOfToken(range.getEnd());
|
||||
|
||||
const clang::PresumedLoc& presumedBegin = sourceManager.getPresumedLoc(sourceRange.getBegin(), false);
|
||||
const clang::PresumedLoc& presumedEnd = sourceManager.getPresumedLoc(endLoc.isValid() ? endLoc : sourceRange.getEnd(), false);
|
||||
if ((
|
||||
sourceManager.isMacroArgExpansion(range.getBegin()) ||
|
||||
sourceManager.isMacroBodyExpansion(range.getBegin())
|
||||
) &&
|
||||
(
|
||||
sourceManager.isMacroArgExpansion(range.getEnd()) ||
|
||||
sourceManager.isMacroBodyExpansion(range.getEnd())
|
||||
))
|
||||
{
|
||||
range = sourceManager.getExpansionRange(sourceRange);
|
||||
if (range.isValid())
|
||||
{
|
||||
endLoc = m_preprocessor->getLocForEndOfToken(range.getBegin());
|
||||
}
|
||||
else
|
||||
{
|
||||
range = sourceRange;
|
||||
}
|
||||
}
|
||||
|
||||
const clang::SourceLocation beginLoc = range.getBegin();
|
||||
|
||||
const clang::PresumedLoc presumedBegin = sourceManager.getPresumedLoc(beginLoc, false);
|
||||
const clang::PresumedLoc presumedEnd = sourceManager.getPresumedLoc(endLoc.isValid() ? endLoc : range.getEnd(), false);
|
||||
|
||||
FilePath filePath;
|
||||
{
|
||||
const clang::FileEntry* fileEntry = sourceManager.getFileEntryForID(sourceManager.getFileID(sourceRange.getBegin()));
|
||||
const clang::FileEntry* fileEntry = sourceManager.getFileEntryForID(sourceManager.getFileID(beginLoc));
|
||||
if (fileEntry != nullptr && fileEntry->isValid())
|
||||
{
|
||||
filePath = m_canonicalFilePathCache->getCanonicalFilePath(fileEntry);
|
||||
|
||||
@@ -795,7 +795,13 @@ bool CxxAstVisitorComponentIndexer::shouldVisitDecl(const clang::Decl* decl)
|
||||
{
|
||||
if (decl)
|
||||
{
|
||||
clang::SourceLocation loc = decl->getLocation();
|
||||
clang::SourceLocation loc = m_astContext->getSourceManager().getExpansionLoc(decl->getLocation());
|
||||
|
||||
if (loc.isInvalid())
|
||||
{
|
||||
loc = decl->getLocation();
|
||||
}
|
||||
|
||||
bool declIsImplicit = utility::isImplicit(decl);
|
||||
if ((declIsImplicit && isLocatedInProjectFile(loc)) ||
|
||||
(!declIsImplicit && isLocatedInUnparsedProjectFile(loc)))
|
||||
@@ -814,8 +820,14 @@ bool CxxAstVisitorComponentIndexer::shouldVisitReference(const clang::SourceLoca
|
||||
declIsImplicit = utility::isImplicit(contextDecl);
|
||||
}
|
||||
|
||||
if ((declIsImplicit && isLocatedInProjectFile(referenceLocation)) ||
|
||||
(!declIsImplicit && isLocatedInUnparsedProjectFile(referenceLocation)))
|
||||
clang::SourceLocation loc = m_astContext->getSourceManager().getExpansionLoc(referenceLocation);
|
||||
if (loc.isInvalid())
|
||||
{
|
||||
loc = referenceLocation;
|
||||
}
|
||||
|
||||
if ((declIsImplicit && isLocatedInProjectFile(loc)) ||
|
||||
(!declIsImplicit && isLocatedInUnparsedProjectFile(loc)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -3736,6 +3736,67 @@ public:
|
||||
));
|
||||
}
|
||||
|
||||
void test_cxx_parser_finds_macro_argument_location_for_field_definition_with_name_passed_as_argument_to_macro()
|
||||
{
|
||||
std::shared_ptr<TestParserClient> client = parseCode(
|
||||
"#define DEF_INT_FIELD(name) int name;\n"
|
||||
"class A {\n"
|
||||
" DEF_INT_FIELD(m_value)\n"
|
||||
"};\n"
|
||||
);
|
||||
|
||||
TS_ASSERT(utility::containsElement<std::string>(
|
||||
client->fields, "private int A::m_value <3:16 3:22>"
|
||||
));
|
||||
}
|
||||
|
||||
void test_cxx_parser_finds_macro_usage_location_for_field_definition_with_name_partially_passed_as_argument_to_macro()
|
||||
{
|
||||
std::shared_ptr<TestParserClient> client = parseCode(
|
||||
"#define DEF_INT_FIELD(name) int m_##name;\n"
|
||||
"class A {\n"
|
||||
" DEF_INT_FIELD(value)\n"
|
||||
"};\n"
|
||||
);
|
||||
|
||||
TS_ASSERT(utility::containsElement<std::string>(
|
||||
client->fields, "private int A::m_value <3:2 3:14>"
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
void test_cxx_parser_finds_macro_argument_location_for_function_call_in_code_passed_as_argument_to_macro()
|
||||
{
|
||||
std::shared_ptr<TestParserClient> client = parseCode(
|
||||
"#define DEF_INT_FIELD(name, init) int name = init;\n"
|
||||
"int foo() { return 5; }\n"
|
||||
"class A {\n"
|
||||
" DEF_INT_FIELD(m_value, foo())\n"
|
||||
"};\n"
|
||||
);
|
||||
|
||||
TS_ASSERT(utility::containsElement<std::string>(
|
||||
client->calls, "int A::m_value -> int foo() <4:25 4:27>"
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
void test_cxx_parser_finds_macro_usage_location_for_function_call_in_code_of_macro_body()
|
||||
{
|
||||
std::shared_ptr<TestParserClient> client = parseCode(
|
||||
"int foo() { return 5; }\n"
|
||||
"#define DEF_INT_FIELD(name) int name = foo();\n"
|
||||
"class A {\n"
|
||||
" DEF_INT_FIELD(m_value)\n"
|
||||
"};\n"
|
||||
);
|
||||
|
||||
TS_ASSERT(utility::containsElement<std::string>(
|
||||
client->calls, "int A::m_value -> int foo() <4:2 4:14>"
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
//void __test_cxx_parser_finds_type_template_argument_of_static_cast_expression()
|
||||
//{
|
||||
// std::shared_ptr<TestParserClient> client = parseCode(
|
||||
|
||||
Reference in New Issue
Block a user