From f80a371d44f3fa18698b9c122d1b5bdc26f03360 Mon Sep 17 00:00:00 2001 From: malte_langkabel Date: Tue, 1 Nov 2016 15:23:21 +0100 Subject: [PATCH] src: fixed crashes on parsing Coati * also fixed log path getting messed up by indexing a project using a CDB --- src/lib/utility/UserPaths.cpp | 2 +- src/lib_cxx/data/parser/cxx/CxxASTVisitor.cpp | 186 ++++++++++-------- .../data/parser/cxx/CxxVerboseAstVisitor.cpp | 31 ++- .../data/parser/cxx/CxxVerboseAstVisitor.h | 1 - .../platform_includes/includesWindows.h | 5 + 5 files changed, 120 insertions(+), 105 deletions(-) diff --git a/src/lib/utility/UserPaths.cpp b/src/lib/utility/UserPaths.cpp index 1acc18c3..d8b08b5d 100644 --- a/src/lib/utility/UserPaths.cpp +++ b/src/lib/utility/UserPaths.cpp @@ -1,6 +1,6 @@ #include "utility/UserPaths.h" -std::string UserPaths::s_userDataPath = "user/"; +std::string UserPaths::s_userDataPath = ""; std::string UserPaths::getUserDataPath() { diff --git a/src/lib_cxx/data/parser/cxx/CxxASTVisitor.cpp b/src/lib_cxx/data/parser/cxx/CxxASTVisitor.cpp index 38c502bf..a76d2f4f 100644 --- a/src/lib_cxx/data/parser/cxx/CxxASTVisitor.cpp +++ b/src/lib_cxx/data/parser/cxx/CxxASTVisitor.cpp @@ -288,8 +288,10 @@ bool CxxAstVisitor::TraverseTemplateArgumentLoc(const clang::TemplateArgumentLoc removeContextFunctor = std::make_shared([this](){ m_contextStack.pop_back(); }); } - if (loc.getArgument().getKind() == clang::TemplateArgument::Template) - { + if ( + (loc.getArgument().getKind() == clang::TemplateArgument::Template) && + (isLocatedInUnparsedProjectFile(loc.getLocation())) // TODO: rather test if the context is implicit + ){ // TODO: maybe move this to VisitTemplateName m_client->recordReference( m_typeRefContext, @@ -717,7 +719,7 @@ bool CxxAstVisitor::VisitNamedDecl(clang::NamedDecl* d) bool CxxAstVisitor::VisitTypeLoc(clang::TypeLoc tl) { - if ((isLocatedInUnparsedProjectFile(tl.getBeginLoc())) && + if ((isLocatedInUnparsedProjectFile(tl.getBeginLoc())) && // TODO: rather test if the context is implicit (!checkIgnoresTypeLoc(tl))) { clang::SourceLocation loc; @@ -744,25 +746,27 @@ bool CxxAstVisitor::VisitTypeLoc(clang::TypeLoc tl) bool CxxAstVisitor::VisitDeclRefExpr(clang::DeclRefExpr* s) { clang::ValueDecl* decl = s->getDecl(); - - if ((clang::isa(decl)) || - (clang::isa(decl) && decl->getParentFunctionOrMethod() != NULL) - ) { - ParseLocation declLocation = getParseLocation(decl->getLocation()); - std::string name = declLocation.filePath.fileName() + "<" + - std::to_string(declLocation.startLineNumber) + ":" + - std::to_string(declLocation.startColumnNumber) + ">"; - - m_client->onLocalSymbolParsed(name, getParseLocation(s->getLocation())); - } - else + if (isLocatedInUnparsedProjectFile(s->getLocation())) // TODO: rather test if the context is implicit { - m_client->recordReference( - m_typeRefContext == REFERENCE_TYPE_USAGE ? m_declRefContext : m_typeRefContext, - m_declNameCache->getValue(s->getDecl()), - getContextName(), - getParseLocation(s->getLocation()) - ); + if ((clang::isa(decl)) || + (clang::isa(decl) && decl->getParentFunctionOrMethod() != NULL) + ) { + ParseLocation declLocation = getParseLocation(decl->getLocation()); + std::string name = declLocation.filePath.fileName() + "<" + + std::to_string(declLocation.startLineNumber) + ":" + + std::to_string(declLocation.startColumnNumber) + ">"; + + m_client->onLocalSymbolParsed(name, getParseLocation(s->getLocation())); + } + else + { + m_client->recordReference( + m_typeRefContext == REFERENCE_TYPE_USAGE ? m_declRefContext : m_typeRefContext, + m_declNameCache->getValue(s->getDecl()), + getContextName(), + getParseLocation(s->getLocation()) + ); + } } return true; @@ -770,94 +774,106 @@ bool CxxAstVisitor::VisitDeclRefExpr(clang::DeclRefExpr* s) bool CxxAstVisitor::VisitMemberExpr(clang::MemberExpr* s) { - m_client->recordReference( - m_typeRefContext == REFERENCE_TYPE_USAGE ? m_declRefContext : m_typeRefContext, - m_declNameCache->getValue(s->getMemberDecl()), - getContextName(), - getParseLocation(s->getMemberLoc()) - ); + if (isLocatedInUnparsedProjectFile(s->getMemberLoc())) // TODO: rather test if the context is implicit + { + m_client->recordReference( + m_typeRefContext == REFERENCE_TYPE_USAGE ? m_declRefContext : m_typeRefContext, + m_declNameCache->getValue(s->getMemberDecl()), + getContextName(), + getParseLocation(s->getMemberLoc()) + ); + } return true; } bool CxxAstVisitor::VisitCXXConstructExpr(clang::CXXConstructExpr* s) { - //if (e->getParenOrBraceRange().isValid()) { - // // XXX: This code is a kludge. Recording calls to constructors is - // // troublesome because there isn't an obvious location to associate the - // // call with. Consider: - // // A::A() : field(1, 2, 3) {} - // // new A(1, 2, 3) - // // struct A { A(B); }; A f() { B b; return b; } - // // Implicit calls to conversion operator methods pose a similar - // // problem. - // // - // // Recording constructor calls is very useful, though, so, as a - // // temporary measure, when there are constructor arguments surrounded - // // by parentheses, associate the call with the right parenthesis. - // // - // // Perhaps the right fix is to associate the call with the line itself - // // or with a larger span which may have other references nested within - // // it. The fix may have implications for the navigator GUI. - // RecordDeclRefExpr( - // e->getConstructor(), - // e->getParenOrBraceRange().getEnd(), - // e, - // CF_Called); - //} - clang::SourceLocation loc; - clang::SourceLocation braceBeginLoc = s->getParenOrBraceRange().getBegin(); - clang::SourceLocation nameBeginLoc = s->getSourceRange().getBegin(); - if (braceBeginLoc.isValid()) + if (isLocatedInUnparsedProjectFile(s->getLocation())) // TODO: rather test if the context is implicit { - if (braceBeginLoc == nameBeginLoc) + //if (e->getParenOrBraceRange().isValid()) { + // // XXX: This code is a kludge. Recording calls to constructors is + // // troublesome because there isn't an obvious location to associate the + // // call with. Consider: + // // A::A() : field(1, 2, 3) {} + // // new A(1, 2, 3) + // // struct A { A(B); }; A f() { B b; return b; } + // // Implicit calls to conversion operator methods pose a similar + // // problem. + // // + // // Recording constructor calls is very useful, though, so, as a + // // temporary measure, when there are constructor arguments surrounded + // // by parentheses, associate the call with the right parenthesis. + // // + // // Perhaps the right fix is to associate the call with the line itself + // // or with a larger span which may have other references nested within + // // it. The fix may have implications for the navigator GUI. + // RecordDeclRefExpr( + // e->getConstructor(), + // e->getParenOrBraceRange().getEnd(), + // e, + // CF_Called); + //} + clang::SourceLocation loc; + clang::SourceLocation braceBeginLoc = s->getParenOrBraceRange().getBegin(); + clang::SourceLocation nameBeginLoc = s->getSourceRange().getBegin(); + if (braceBeginLoc.isValid()) { - loc = nameBeginLoc; + if (braceBeginLoc == nameBeginLoc) + { + loc = nameBeginLoc; + } + else + { + loc = braceBeginLoc.getLocWithOffset(-1); + } } else { - loc = braceBeginLoc.getLocWithOffset(-1); + loc = s->getSourceRange().getEnd(); } - } - else - { - loc = s->getSourceRange().getEnd(); - } - loc = clang::Lexer::GetBeginningOfToken(loc, m_astContext->getSourceManager(), m_astContext->getLangOpts()); + loc = clang::Lexer::GetBeginningOfToken(loc, m_astContext->getSourceManager(), m_astContext->getLangOpts()); - m_client->recordReference( - m_typeRefContext == REFERENCE_TYPE_USAGE ? m_declRefContext : m_typeRefContext, - m_declNameCache->getValue(s->getConstructor()), - getContextName(), - getParseLocation(loc) - ); + m_client->recordReference( + m_typeRefContext == REFERENCE_TYPE_USAGE ? m_declRefContext : m_typeRefContext, + m_declNameCache->getValue(s->getConstructor()), + getContextName(), + getParseLocation(loc) + ); + } return true; } bool CxxAstVisitor::VisitLambdaExpr(clang::LambdaExpr* s) { clang::CXXMethodDecl* methodDecl = s->getCallOperator(); - m_client->recordSymbol( - m_declNameCache->getValue(methodDecl), - SYMBOL_FUNCTION, - getParseLocation(s->getLocStart()), - getParseLocationOfFunctionBody(methodDecl), - ACCESS_NONE, // TODO: introduce AccessLambda - isImplicit(methodDecl) - ); + if (shouldVisitDecl(methodDecl)) + { + m_client->recordSymbol( + m_declNameCache->getValue(methodDecl), + SYMBOL_FUNCTION, + getParseLocation(s->getLocStart()), + getParseLocationOfFunctionBody(methodDecl), + ACCESS_NONE, // TODO: introduce AccessLambda + isImplicit(methodDecl) + ); + } return true; } bool CxxAstVisitor::VisitConstructorInitializer(clang::CXXCtorInitializer* init) { - // record the field usage here because it is not a DeclRefExpr - if (clang::FieldDecl* memberDecl = init->getMember()) + if (isLocatedInUnparsedProjectFile(init->getMemberLocation())) // TODO: rather test if the context is implicit { - m_client->recordReference( - REFERENCE_USAGE, - m_declNameCache->getValue(memberDecl), - getContextName(), - getParseLocation(init->getMemberLocation()) - ); + // record the field usage here because it is not a DeclRefExpr + if (clang::FieldDecl* memberDecl = init->getMember()) + { + m_client->recordReference( + REFERENCE_USAGE, + m_declNameCache->getValue(memberDecl), + getContextName(), + getParseLocation(init->getMemberLocation()) + ); + } } return true; } diff --git a/src/lib_cxx/data/parser/cxx/CxxVerboseAstVisitor.cpp b/src/lib_cxx/data/parser/cxx/CxxVerboseAstVisitor.cpp index b2fa7890..aa43b344 100644 --- a/src/lib_cxx/data/parser/cxx/CxxVerboseAstVisitor.cpp +++ b/src/lib_cxx/data/parser/cxx/CxxVerboseAstVisitor.cpp @@ -66,28 +66,23 @@ bool CxxVerboseAstVisitor::TraverseStmt(clang::Stmt *stmt) return true; } -bool CxxVerboseAstVisitor::TraverseType(clang::QualType t) -{ - LOG_INFO_STREAM_BARE(<< "Indexer - " << getIndentString() << t->getTypeClassName() << "Type"); - { - ScopedSwitcher switcher(m_indentation, m_indentation + 1); - return base::TraverseType(t); - } -} - bool CxxVerboseAstVisitor::TraverseTypeLoc(clang::TypeLoc tl) { - ParseLocation loc = getParseLocation(tl.getSourceRange()); - LOG_INFO_STREAM_BARE( - << "Indexer - " - << getIndentString() << typeLocClassToString(tl) - << "TypeLoc <" << loc.startLineNumber << ":" << loc.startColumnNumber - << ", " << loc.endLineNumber << ":" << loc.endColumnNumber << ">" - ); + if (!tl.isNull()) { - ScopedSwitcher switcher(m_indentation, m_indentation + 1); - return base::TraverseTypeLoc(tl); + ParseLocation loc = getParseLocation(tl.getSourceRange()); + LOG_WARNING_STREAM_BARE( + << "Indexer - " + << getIndentString() << typeLocClassToString(tl) + << "TypeLoc <" << loc.startLineNumber << ":" << loc.startColumnNumber + << ", " << loc.endLineNumber << ":" << loc.endColumnNumber << ">" + ); + { + ScopedSwitcher switcher(m_indentation, m_indentation + 1); + return base::TraverseTypeLoc(tl); + } } + return true; } std::string CxxVerboseAstVisitor::getIndentString() const diff --git a/src/lib_cxx/data/parser/cxx/CxxVerboseAstVisitor.h b/src/lib_cxx/data/parser/cxx/CxxVerboseAstVisitor.h index ff417066..bd889405 100644 --- a/src/lib_cxx/data/parser/cxx/CxxVerboseAstVisitor.h +++ b/src/lib_cxx/data/parser/cxx/CxxVerboseAstVisitor.h @@ -19,7 +19,6 @@ private: virtual bool TraverseDecl(clang::Decl *d); virtual bool TraverseStmt(clang::Stmt *stmt); - virtual bool TraverseType(clang::QualType t); virtual bool TraverseTypeLoc(clang::TypeLoc tl); std::string getIndentString() const; diff --git a/src/lib_gui/platform_includes/includesWindows.h b/src/lib_gui/platform_includes/includesWindows.h index 139738f4..0c4d30e1 100644 --- a/src/lib_gui/platform_includes/includesWindows.h +++ b/src/lib_gui/platform_includes/includesWindows.h @@ -2,6 +2,7 @@ #define INCLUDES_WINDOWS_H #include +#include #include "vld.h" @@ -19,6 +20,10 @@ void setupApp(int argc, char *argv[]) std::string path = std::getenv("APPDATA"); path += "/../local/Coati Software/Coati/"; UserPaths::setUserDataPath(path); +#else + std::string path = QDir::currentPath().toStdString(); + path += "/user/"; + UserPaths::setUserDataPath(path); #endif }