Clang import: StringLiteral, funcdecl3, determine includes with clang -v

This commit is contained in:
Daniel Marjamäki 2020-01-08 16:36:51 +01:00
parent f51048e03b
commit c4c929a6a7
3 changed files with 53 additions and 6 deletions

View File

@ -45,6 +45,7 @@ static const std::string NullStmt = "NullStmt";
static const std::string ParmVarDecl = "ParmVarDecl";
static const std::string RecordDecl = "RecordDecl";
static const std::string ReturnStmt = "ReturnStmt";
static const std::string StringLiteral = "StringLiteral";
static const std::string TypedefDecl = "TypedefDecl";
static const std::string UnaryOperator = "UnaryOperator";
static const std::string VarDecl = "VarDecl";
@ -171,6 +172,10 @@ namespace clangastdump {
std::string clangastdump::AstNode::getSpelling() const
{
if (mExtTokens.back() == "extern")
return mExtTokens[mExtTokens.size() - 3];
if (mExtTokens[mExtTokens.size() - 2].compare(0,4,"col:") == 0)
return "";
return mExtTokens[mExtTokens.size() - 2];
}
@ -180,6 +185,10 @@ std::string clangastdump::AstNode::getType() const
return unquote(mExtTokens[mExtTokens.size() - 2]);
if (nodeType == DeclRefExpr)
return unquote(mExtTokens.back());
if (nodeType == FunctionDecl)
return unquote((mExtTokens.back() == "extern") ?
mExtTokens[mExtTokens.size() - 2] :
mExtTokens.back());
if (nodeType == IntegerLiteral)
return unquote(mExtTokens[mExtTokens.size() - 2]);
if (nodeType == TypedefDecl)
@ -362,8 +371,13 @@ Token *clangastdump::AstNode::createTokens(TokenList *tokenList)
}
if (nodeType == FunctionDecl) {
SymbolDatabase *symbolDatabase = mData->mSymbolDatabase;
addTypeTokens(tokenList, mExtTokens.back());
Token *nameToken = addtoken(tokenList, mExtTokens[mExtTokens.size() - 2]);
std::string name, rettype;
const int nameIndex = (mExtTokens.back() == "extern") ?
(mExtTokens.size() - 3) :
(mExtTokens.size() - 2);
const int retTypeIndex = nameIndex + 1;
addTypeTokens(tokenList, mExtTokens[retTypeIndex]);
Token *nameToken = addtoken(tokenList, mExtTokens[nameIndex]);
Scope *nestedIn = const_cast<Scope *>(nameToken->scope());
symbolDatabase->scopeList.push_back(Scope(nullptr, nullptr, nestedIn));
Scope &scope = symbolDatabase->scopeList.back();
@ -442,9 +456,13 @@ Token *clangastdump::AstNode::createTokens(TokenList *tokenList)
const std::string &recordName = getSpelling();
if (!recordName.empty())
addtoken(tokenList, getSpelling());
Scope *recordScope = createScope(tokenList, Scope::ScopeType::eStruct, children);
mData->mSymbolDatabase->typeList.push_back(Type(classDef, recordScope, classDef->scope()));
recordScope->definedType = &mData->mSymbolDatabase->typeList.back();
if (children.empty())
addtoken(tokenList, ";");
else {
Scope *recordScope = createScope(tokenList, Scope::ScopeType::eStruct, children);
mData->mSymbolDatabase->typeList.push_back(Type(classDef, recordScope, classDef->scope()));
recordScope->definedType = &mData->mSymbolDatabase->typeList.back();
}
return nullptr;
}
if (nodeType == ReturnStmt) {
@ -453,6 +471,8 @@ Token *clangastdump::AstNode::createTokens(TokenList *tokenList)
tok1->astOperand1(children[0]->createTokens(tokenList));
return tok1;
}
if (nodeType == StringLiteral)
return addtoken(tokenList, mExtTokens.back());
if (nodeType == TypedefDecl) {
addtoken(tokenList, "typedef");
addTypeTokens(tokenList, getType());

View File

@ -243,7 +243,26 @@ unsigned int CppCheck::check(const std::string &path)
{
if (mSettings.clang) {
/* Experimental: import clang ast dump */
const std::string cmd = "clang -cc1 -ast-dump " + path;
const std::string cmd1 = "clang -v -fsyntax-only " + path + " 2>&1";
const std::pair<bool, std::string> res1 = executeCommand(cmd1);
if (!res1.first) {
std::cerr << "Failed to execute '" + cmd1 + "'" << std::endl;
return 0;
}
std::istringstream details(res1.second);
std::string line;
std::string includes;
while (std::getline(details, line)) {
if (line.find(" -internal-isystem ") == std::string::npos)
continue;
const std::vector<std::string> options = split(line, " ");
for (int i = 0; i+1 < options.size(); i++) {
if (endsWith(options[i], "-isystem", 8))
includes += options[i] + " " + options[i+1] + " ";
}
}
const std::string cmd = "clang -cc1 -ast-dump " + includes + path;
std::pair<bool, std::string> res = executeCommand(cmd);
if (!res.first) {
std::cerr << "Failed to execute '" + cmd + "'" << std::endl;

View File

@ -34,6 +34,7 @@ private:
TEST_CASE(forStmt);
TEST_CASE(funcdecl1);
TEST_CASE(funcdecl2);
TEST_CASE(funcdecl3);
TEST_CASE(ifelse);
TEST_CASE(memberExpr);
TEST_CASE(recordDecl);
@ -116,6 +117,13 @@ private:
"return x@1 / y@2 ; }", parse(clang));
}
void funcdecl3() {
const char clang[] = "|-FunctionDecl 0x27cb6b8 <line:865:1, col:35> col:12 __overflow 'int (FILE *, int)' extern\n"
"| |-ParmVarDecl 0x27cb528 <col:24, col:29> col:30 'FILE *'\n"
"| `-ParmVarDecl 0x27cb5a0 <col:32> col:35 'int'";
ASSERT_EQUALS("int __overflow ( FILE * , int ) ;", parse(clang));
}
void ifelse() {
const char clang[] = "`-FunctionDecl 0x2637ba8 <1.c:1:1, line:4:1> line:1:5 foo 'int (int)'\n"
" |-ParmVarDecl 0x2637ae0 <col:9, col:13> col:13 used x 'int'\n"