Clang import: Better type handling
This commit is contained in:
parent
eece8ee66b
commit
198bbc8a5a
|
@ -267,7 +267,7 @@ namespace clangimport {
|
|||
private:
|
||||
Token *createTokens(TokenList *tokenList);
|
||||
Token *addtoken(TokenList *tokenList, const std::string &str, bool valueType=true);
|
||||
void addTypeTokens(TokenList *tokenList, const std::string &str);
|
||||
const ::Type *addTypeTokens(TokenList *tokenList, const std::string &str, const Scope *scope = nullptr);
|
||||
Scope *createScope(TokenList *tokenList, Scope::ScopeType scopeType, AstNodePtr astNode, const Token *def);
|
||||
Scope *createScope(TokenList *tokenList, Scope::ScopeType scopeType, const std::vector<AstNodePtr> &children, const Token *def);
|
||||
Token *createTokensCall(TokenList *tokenList);
|
||||
|
@ -430,11 +430,10 @@ Token *clangimport::AstNode::addtoken(TokenList *tokenList, const std::string &s
|
|||
return tokenList->back();
|
||||
}
|
||||
|
||||
void clangimport::AstNode::addTypeTokens(TokenList *tokenList, const std::string &str)
|
||||
const ::Type * clangimport::AstNode::addTypeTokens(TokenList *tokenList, const std::string &str, const Scope *scope)
|
||||
{
|
||||
if (str.find("\':\'") != std::string::npos) {
|
||||
addTypeTokens(tokenList, str.substr(0, str.find("\':\'") + 1));
|
||||
return;
|
||||
return addTypeTokens(tokenList, str.substr(0, str.find("\':\'") + 1), scope);
|
||||
}
|
||||
|
||||
std::string type;
|
||||
|
@ -448,6 +447,23 @@ void clangimport::AstNode::addTypeTokens(TokenList *tokenList, const std::string
|
|||
|
||||
for (const std::string &s: splitString(type))
|
||||
addtoken(tokenList, s, false);
|
||||
|
||||
// Set Type
|
||||
if (!scope) {
|
||||
scope = tokenList->back() ? tokenList->back()->scope() : nullptr;
|
||||
if (!scope)
|
||||
return nullptr;
|
||||
}
|
||||
for (const Token *typeToken = tokenList->back(); Token::Match(typeToken, "&|*|%name%"); typeToken = typeToken->previous()) {
|
||||
if (!typeToken->isName())
|
||||
continue;
|
||||
const ::Type *recordType = scope->findType(typeToken->str());
|
||||
if (recordType) {
|
||||
const_cast<Token*>(typeToken)->type(recordType);
|
||||
return recordType;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const Scope *clangimport::AstNode::getNestedInScope(TokenList *tokenList)
|
||||
|
@ -469,7 +485,7 @@ void clangimport::AstNode::setValueType(Token *tok)
|
|||
continue;
|
||||
|
||||
TokenList decl(nullptr);
|
||||
addTypeTokens(&decl, type);
|
||||
addTypeTokens(&decl, type, tok->scope());
|
||||
if (!decl.front())
|
||||
break;
|
||||
|
||||
|
@ -965,8 +981,10 @@ Token *clangimport::AstNode::createTokens(TokenList *tokenList)
|
|||
Scope *recordScope = createScope(tokenList, Scope::ScopeType::eStruct, children, classDef);
|
||||
mData->mSymbolDatabase->typeList.push_back(Type(classDef, recordScope, classDef->scope()));
|
||||
recordScope->definedType = &mData->mSymbolDatabase->typeList.back();
|
||||
if (!recordName.empty())
|
||||
if (!recordName.empty()) {
|
||||
recordScope->className = recordName;
|
||||
const_cast<Scope *>(classDef->scope())->definedTypesMap[recordName] = recordScope->definedType;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -1145,14 +1163,14 @@ void clangimport::AstNode::createTokensFunctionDecl(TokenList *tokenList)
|
|||
continue;
|
||||
if (tokenList->back() != par1)
|
||||
addtoken(tokenList, ",");
|
||||
addTypeTokens(tokenList, child->mExtTokens.back());
|
||||
const Type *recordType = addTypeTokens(tokenList, child->mExtTokens.back(), nestedIn);
|
||||
const Token *typeEndToken = tokenList->back();
|
||||
const std::string spelling = child->getSpelling();
|
||||
Token *vartok = nullptr;
|
||||
if (!spelling.empty())
|
||||
vartok = child->addtoken(tokenList, spelling);
|
||||
if (!prev) {
|
||||
function->argumentList.push_back(Variable(vartok, child->getType(), nullptr, typeEndToken, i, AccessControl::Argument, nullptr, scope));
|
||||
function->argumentList.push_back(Variable(vartok, child->getType(), nullptr, typeEndToken, i, AccessControl::Argument, recordType, scope));
|
||||
if (vartok) {
|
||||
const std::string addr = child->mExtTokens[0];
|
||||
mData->varDecl(addr, vartok, &function->argumentList.back());
|
||||
|
@ -1218,6 +1236,7 @@ void clangimport::AstNode::createTokensForCXXRecord(TokenList *tokenList)
|
|||
scope->className = className;
|
||||
mData->mSymbolDatabase->typeList.push_back(Type(classToken, scope, classToken->scope()));
|
||||
scope->definedType = &mData->mSymbolDatabase->typeList.back();
|
||||
const_cast<Scope *>(classToken->scope())->definedTypesMap[className] = scope->definedType;
|
||||
}
|
||||
addtoken(tokenList, ";");
|
||||
const_cast<Token *>(tokenList->back())->scope(classToken->scope());
|
||||
|
@ -1234,7 +1253,7 @@ Token * clangimport::AstNode::createTokensVarDecl(TokenList *tokenList)
|
|||
typeIndex--;
|
||||
const std::string type = mExtTokens[typeIndex];
|
||||
const std::string name = mExtTokens[typeIndex - 1];
|
||||
addTypeTokens(tokenList, type);
|
||||
const ::Type *recordType = addTypeTokens(tokenList, type);
|
||||
if (!startToken && tokenList->back()) {
|
||||
startToken = tokenList->back();
|
||||
while (Token::Match(startToken->previous(), "%type%|*|&|&&"))
|
||||
|
@ -1242,7 +1261,7 @@ Token * clangimport::AstNode::createTokensVarDecl(TokenList *tokenList)
|
|||
}
|
||||
Token *vartok1 = addtoken(tokenList, name);
|
||||
Scope *scope = const_cast<Scope *>(tokenList->back()->scope());
|
||||
scope->varlist.push_back(Variable(vartok1, type, startToken, vartok1->previous(), 0, scope->defaultAccess(), nullptr, scope));
|
||||
scope->varlist.push_back(Variable(vartok1, type, startToken, vartok1->previous(), 0, scope->defaultAccess(), recordType, scope));
|
||||
mData->varDecl(addr, vartok1, &scope->varlist.back());
|
||||
if (mExtTokens.back() == "cinit" && !children.empty()) {
|
||||
Token *eq = addtoken(tokenList, "=");
|
||||
|
|
|
@ -1840,6 +1840,8 @@ Variable::Variable(const Token *name_, const std::string &clangType, const Token
|
|||
mTypeStartToken = mTypeStartToken->previous();
|
||||
if (mTypeStartToken->str() == "const")
|
||||
mTypeStartToken = mTypeStartToken->next();
|
||||
if (mTypeStartToken->str() == "struct")
|
||||
mTypeStartToken = mTypeStartToken->next();
|
||||
}
|
||||
if (Token::simpleMatch(mTypeStartToken, "static"))
|
||||
setFlag(fIsStatic, true);
|
||||
|
|
|
@ -99,6 +99,9 @@ def test_symbol_database_5():
|
|||
def test_symbol_database_6():
|
||||
check_symbol_database('inline static int foo(int x) { return x; }')
|
||||
|
||||
def test_symbol_database_7():
|
||||
check_symbol_database('struct S {int x;}; void f(struct S *s) {}')
|
||||
|
||||
def test_symbol_database_operator():
|
||||
check_symbol_database('struct Fred { void operator=(int x); };')
|
||||
|
||||
|
|
Loading…
Reference in New Issue