Clang import: Better handling of methods that are defined after declaration
This commit is contained in:
parent
8fd0839fea
commit
66ee3a0afc
|
@ -214,6 +214,10 @@ namespace clangimport {
|
|||
return ret;
|
||||
}
|
||||
|
||||
bool hasDecl(const std::string &addr) const {
|
||||
return mDeclMap.find(addr) != mDeclMap.end();
|
||||
}
|
||||
|
||||
// "}" tokens that are not end-of-scope
|
||||
std::set<Token *> mNotScope;
|
||||
private:
|
||||
|
@ -678,6 +682,10 @@ Token *clangimport::AstNode::createTokens(TokenList *tokenList)
|
|||
return nullptr;
|
||||
}
|
||||
if (nodeType == CXXMethodDecl) {
|
||||
for (int i = 0; i+1 < mExtTokens.size(); ++i) {
|
||||
if (mExtTokens[i] == "prev" && !mData->hasDecl(mExtTokens[i+1]))
|
||||
return nullptr;
|
||||
}
|
||||
createTokensFunctionDecl(tokenList);
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -1053,19 +1061,38 @@ Token * clangimport::AstNode::createTokensCall(TokenList *tokenList)
|
|||
|
||||
void clangimport::AstNode::createTokensFunctionDecl(TokenList *tokenList)
|
||||
{
|
||||
const bool prev = (std::find(mExtTokens.begin(), mExtTokens.end(), "prev") != mExtTokens.end());
|
||||
const bool hasBody = mFile == 0 && !children.empty() && children.back()->nodeType == CompoundStmt;
|
||||
|
||||
SymbolDatabase *symbolDatabase = mData->mSymbolDatabase;
|
||||
addTypeTokens(tokenList, '\'' + getType() + '\'');
|
||||
Token *nameToken = addtoken(tokenList, getSpelling() + getTemplateParameters());
|
||||
Scope *nestedIn = const_cast<Scope *>(nameToken->scope());
|
||||
symbolDatabase->scopeList.push_back(Scope(nullptr, nullptr, nestedIn));
|
||||
Scope &scope = symbolDatabase->scopeList.back();
|
||||
nestedIn->functionList.push_back(Function(nameToken));
|
||||
scope.function = &nestedIn->functionList.back();
|
||||
scope.type = Scope::ScopeType::eFunction;
|
||||
scope.className = nameToken->str();
|
||||
mData->funcDecl(mExtTokens.front(), nameToken, scope.function);
|
||||
|
||||
if (!prev) {
|
||||
nestedIn->functionList.push_back(Function(nameToken));
|
||||
mData->funcDecl(mExtTokens.front(), nameToken, &nestedIn->functionList.back());
|
||||
} else {
|
||||
const std::string addr = *(std::find(mExtTokens.begin(), mExtTokens.end(), "prev") + 1);
|
||||
mData->ref(addr, nameToken);
|
||||
}
|
||||
|
||||
Function * const function = const_cast<Function*>(nameToken->function());
|
||||
|
||||
Scope *scope = nullptr;
|
||||
if (hasBody) {
|
||||
symbolDatabase->scopeList.push_back(Scope(nullptr, nullptr, nestedIn));
|
||||
scope = &symbolDatabase->scopeList.back();
|
||||
scope->function = function;
|
||||
scope->type = Scope::ScopeType::eFunction;
|
||||
scope->className = nameToken->str();
|
||||
nestedIn->nestedList.push_back(scope);
|
||||
function->hasBody(true);
|
||||
}
|
||||
|
||||
Token *par1 = addtoken(tokenList, "(");
|
||||
// Function arguments
|
||||
function->argumentList.clear();
|
||||
for (int i = 0; i < children.size(); ++i) {
|
||||
AstNodePtr child = children[i];
|
||||
if (child->nodeType != ParmVarDecl)
|
||||
|
@ -1077,24 +1104,25 @@ void clangimport::AstNode::createTokensFunctionDecl(TokenList *tokenList)
|
|||
Token *vartok = nullptr;
|
||||
if (!spelling.empty())
|
||||
vartok = child->addtoken(tokenList, spelling);
|
||||
scope.function->argumentList.push_back(Variable(vartok, child->getType(), nullptr, i, AccessControl::Argument, nullptr, &scope));
|
||||
function->argumentList.push_back(Variable(vartok, child->getType(), nullptr, i, AccessControl::Argument, nullptr, scope));
|
||||
if (vartok) {
|
||||
const std::string addr = child->mExtTokens[0];
|
||||
mData->varDecl(addr, vartok, &scope.function->argumentList.back());
|
||||
mData->varDecl(addr, vartok, &function->argumentList.back());
|
||||
}
|
||||
}
|
||||
Token *par2 = addtoken(tokenList, ")");
|
||||
par1->link(par2);
|
||||
par2->link(par1);
|
||||
|
||||
// Function body
|
||||
if (mFile == 0 && !children.empty() && children.back()->nodeType == CompoundStmt) {
|
||||
symbolDatabase->functionScopes.push_back(&scope);
|
||||
if (hasBody) {
|
||||
symbolDatabase->functionScopes.push_back(scope);
|
||||
Token *bodyStart = addtoken(tokenList, "{");
|
||||
bodyStart->scope(&scope);
|
||||
bodyStart->scope(scope);
|
||||
children.back()->createTokens(tokenList);
|
||||
Token *bodyEnd = addtoken(tokenList, "}");
|
||||
scope.bodyStart = bodyStart;
|
||||
scope.bodyEnd = bodyEnd;
|
||||
scope->bodyStart = bodyStart;
|
||||
scope->bodyEnd = bodyEnd;
|
||||
bodyStart->link(bodyEnd);
|
||||
bodyEnd->link(bodyStart);
|
||||
} else {
|
||||
|
|
|
@ -50,7 +50,9 @@ private:
|
|||
TEST_CASE(cxxForRangeStmt1);
|
||||
TEST_CASE(cxxForRangeStmt2);
|
||||
TEST_CASE(cxxMemberCall);
|
||||
TEST_CASE(cxxMethodDecl);
|
||||
TEST_CASE(cxxMethodDecl1);
|
||||
TEST_CASE(cxxMethodDecl2);
|
||||
TEST_CASE(cxxMethodDecl3);
|
||||
TEST_CASE(cxxNewExpr);
|
||||
TEST_CASE(cxxNullPtrLiteralExpr);
|
||||
TEST_CASE(cxxOperatorCallExpr);
|
||||
|
@ -435,7 +437,7 @@ private:
|
|||
ASSERT_EQUALS("void bar ( ) { C<int> c@1 ( C<int> ( ) ) ; c@1 . foo ( ) ; }", parse(clang));
|
||||
}
|
||||
|
||||
void cxxMethodDecl() {
|
||||
void cxxMethodDecl1() {
|
||||
const char clang[] = "|-CXXMethodDecl 0x55c786f5ad60 <line:56:5, col:179> col:10 analyzeFile '_Bool (const std::string &, const std::string &, const std::string &, unsigned long long, std::list<ErrorLogger::ErrorMessage> *)'\n"
|
||||
"| |-ParmVarDecl 0x55c786f5a4c8 <col:22, col:41> col:41 buildDir 'const std::string &'\n"
|
||||
"| |-ParmVarDecl 0x55c786f5a580 <col:51, col:70> col:70 sourcefile 'const std::string &'\n"
|
||||
|
@ -446,6 +448,34 @@ private:
|
|||
ASSERT_EQUALS("_Bool analyzeFile ( const std::string & buildDir@1 , const std::string & sourcefile@2 , const std::string & cfg@3 , unsigned long long checksum@4 , std::list<ErrorLogger::ErrorMessage> * errors@5 ) { }", parse(clang));
|
||||
}
|
||||
|
||||
void cxxMethodDecl2() { // "unexpanded" template method
|
||||
const char clang[] = "`-CXXMethodDecl 0x220ecb0 parent 0x21e4c28 prev 0x21e5338 <line:11:1, line:18:1> line:14:1 find 'const typename char_traits<_CharT>::char_type *(const char_traits::char_type *, int, const char_traits::char_type &)'\n"
|
||||
" `-CompoundStmt 0x220ede0 <line:15:1, line:18:1>\n"
|
||||
" `-ReturnStmt 0x220edd0 <line:17:5, col:12>\n"
|
||||
" `-IntegerLiteral 0x220edb0 <col:12> 'int' 0";
|
||||
ASSERT_EQUALS("", parse(clang));
|
||||
}
|
||||
|
||||
void cxxMethodDecl3() {
|
||||
const char clang[] = "|-CXXRecordDecl 0x21cca40 <2.cpp:2:1, line:4:1> line:2:7 class Fred definition\n"
|
||||
"| |-DefinitionData pass_in_registers empty aggregate standard_layout trivially_copyable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init\n"
|
||||
"| | |-DefaultConstructor exists trivial constexpr needs_implicit defaulted_is_constexpr\n"
|
||||
"| | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param\n"
|
||||
"| | |-MoveConstructor exists simple trivial needs_implicit\n"
|
||||
"| | |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param\n"
|
||||
"| | |-MoveAssignment exists simple trivial needs_implicit\n"
|
||||
"| | `-Destructor simple irrelevant trivial needs_implicit\n"
|
||||
"| |-CXXRecordDecl 0x21ccb58 <col:1, col:7> col:7 implicit class Fred\n"
|
||||
"| `-CXXMethodDecl 0x21ccc68 <line:3:1, col:10> col:6 foo 'void ()'\n"
|
||||
"`-CXXMethodDecl 0x21ccd60 parent 0x21cca40 prev 0x21ccc68 <line:6:1, col:19> col:12 foo 'void ()'\n"
|
||||
" `-CompoundStmt 0x21cce50 <col:18, col:19>";
|
||||
ASSERT_EQUALS("class Fred\n"
|
||||
"{ void foo ( ) ; }\n"
|
||||
"\n"
|
||||
"\n"
|
||||
"void foo ( ) { }", parse(clang));
|
||||
}
|
||||
|
||||
void cxxNewExpr() {
|
||||
const char clang[] = "|-VarDecl 0x3a97680 <1.cpp:2:1, col:14> col:6 i 'int *' cinit\n"
|
||||
"| `-CXXNewExpr 0x3a97d18 <col:10, col:14> 'int *' Function 0x3a97778 'operator new' 'void *(unsigned long)'\n"
|
||||
|
|
Loading…
Reference in New Issue