Clang import: StringLiteral, funcdecl3, determine includes with clang -v
This commit is contained in:
parent
f51048e03b
commit
c4c929a6a7
|
@ -45,6 +45,7 @@ static const std::string NullStmt = "NullStmt";
|
||||||
static const std::string ParmVarDecl = "ParmVarDecl";
|
static const std::string ParmVarDecl = "ParmVarDecl";
|
||||||
static const std::string RecordDecl = "RecordDecl";
|
static const std::string RecordDecl = "RecordDecl";
|
||||||
static const std::string ReturnStmt = "ReturnStmt";
|
static const std::string ReturnStmt = "ReturnStmt";
|
||||||
|
static const std::string StringLiteral = "StringLiteral";
|
||||||
static const std::string TypedefDecl = "TypedefDecl";
|
static const std::string TypedefDecl = "TypedefDecl";
|
||||||
static const std::string UnaryOperator = "UnaryOperator";
|
static const std::string UnaryOperator = "UnaryOperator";
|
||||||
static const std::string VarDecl = "VarDecl";
|
static const std::string VarDecl = "VarDecl";
|
||||||
|
@ -171,6 +172,10 @@ namespace clangastdump {
|
||||||
|
|
||||||
std::string clangastdump::AstNode::getSpelling() const
|
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];
|
return mExtTokens[mExtTokens.size() - 2];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,6 +185,10 @@ std::string clangastdump::AstNode::getType() const
|
||||||
return unquote(mExtTokens[mExtTokens.size() - 2]);
|
return unquote(mExtTokens[mExtTokens.size() - 2]);
|
||||||
if (nodeType == DeclRefExpr)
|
if (nodeType == DeclRefExpr)
|
||||||
return unquote(mExtTokens.back());
|
return unquote(mExtTokens.back());
|
||||||
|
if (nodeType == FunctionDecl)
|
||||||
|
return unquote((mExtTokens.back() == "extern") ?
|
||||||
|
mExtTokens[mExtTokens.size() - 2] :
|
||||||
|
mExtTokens.back());
|
||||||
if (nodeType == IntegerLiteral)
|
if (nodeType == IntegerLiteral)
|
||||||
return unquote(mExtTokens[mExtTokens.size() - 2]);
|
return unquote(mExtTokens[mExtTokens.size() - 2]);
|
||||||
if (nodeType == TypedefDecl)
|
if (nodeType == TypedefDecl)
|
||||||
|
@ -362,8 +371,13 @@ Token *clangastdump::AstNode::createTokens(TokenList *tokenList)
|
||||||
}
|
}
|
||||||
if (nodeType == FunctionDecl) {
|
if (nodeType == FunctionDecl) {
|
||||||
SymbolDatabase *symbolDatabase = mData->mSymbolDatabase;
|
SymbolDatabase *symbolDatabase = mData->mSymbolDatabase;
|
||||||
addTypeTokens(tokenList, mExtTokens.back());
|
std::string name, rettype;
|
||||||
Token *nameToken = addtoken(tokenList, mExtTokens[mExtTokens.size() - 2]);
|
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());
|
Scope *nestedIn = const_cast<Scope *>(nameToken->scope());
|
||||||
symbolDatabase->scopeList.push_back(Scope(nullptr, nullptr, nestedIn));
|
symbolDatabase->scopeList.push_back(Scope(nullptr, nullptr, nestedIn));
|
||||||
Scope &scope = symbolDatabase->scopeList.back();
|
Scope &scope = symbolDatabase->scopeList.back();
|
||||||
|
@ -442,9 +456,13 @@ Token *clangastdump::AstNode::createTokens(TokenList *tokenList)
|
||||||
const std::string &recordName = getSpelling();
|
const std::string &recordName = getSpelling();
|
||||||
if (!recordName.empty())
|
if (!recordName.empty())
|
||||||
addtoken(tokenList, getSpelling());
|
addtoken(tokenList, getSpelling());
|
||||||
Scope *recordScope = createScope(tokenList, Scope::ScopeType::eStruct, children);
|
if (children.empty())
|
||||||
mData->mSymbolDatabase->typeList.push_back(Type(classDef, recordScope, classDef->scope()));
|
addtoken(tokenList, ";");
|
||||||
recordScope->definedType = &mData->mSymbolDatabase->typeList.back();
|
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;
|
return nullptr;
|
||||||
}
|
}
|
||||||
if (nodeType == ReturnStmt) {
|
if (nodeType == ReturnStmt) {
|
||||||
|
@ -453,6 +471,8 @@ Token *clangastdump::AstNode::createTokens(TokenList *tokenList)
|
||||||
tok1->astOperand1(children[0]->createTokens(tokenList));
|
tok1->astOperand1(children[0]->createTokens(tokenList));
|
||||||
return tok1;
|
return tok1;
|
||||||
}
|
}
|
||||||
|
if (nodeType == StringLiteral)
|
||||||
|
return addtoken(tokenList, mExtTokens.back());
|
||||||
if (nodeType == TypedefDecl) {
|
if (nodeType == TypedefDecl) {
|
||||||
addtoken(tokenList, "typedef");
|
addtoken(tokenList, "typedef");
|
||||||
addTypeTokens(tokenList, getType());
|
addTypeTokens(tokenList, getType());
|
||||||
|
|
|
@ -243,7 +243,26 @@ unsigned int CppCheck::check(const std::string &path)
|
||||||
{
|
{
|
||||||
if (mSettings.clang) {
|
if (mSettings.clang) {
|
||||||
/* Experimental: import clang ast dump */
|
/* 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);
|
std::pair<bool, std::string> res = executeCommand(cmd);
|
||||||
if (!res.first) {
|
if (!res.first) {
|
||||||
std::cerr << "Failed to execute '" + cmd + "'" << std::endl;
|
std::cerr << "Failed to execute '" + cmd + "'" << std::endl;
|
||||||
|
|
|
@ -34,6 +34,7 @@ private:
|
||||||
TEST_CASE(forStmt);
|
TEST_CASE(forStmt);
|
||||||
TEST_CASE(funcdecl1);
|
TEST_CASE(funcdecl1);
|
||||||
TEST_CASE(funcdecl2);
|
TEST_CASE(funcdecl2);
|
||||||
|
TEST_CASE(funcdecl3);
|
||||||
TEST_CASE(ifelse);
|
TEST_CASE(ifelse);
|
||||||
TEST_CASE(memberExpr);
|
TEST_CASE(memberExpr);
|
||||||
TEST_CASE(recordDecl);
|
TEST_CASE(recordDecl);
|
||||||
|
@ -116,6 +117,13 @@ private:
|
||||||
"return x@1 / y@2 ; }", parse(clang));
|
"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() {
|
void ifelse() {
|
||||||
const char clang[] = "`-FunctionDecl 0x2637ba8 <1.c:1:1, line:4:1> line:1:5 foo 'int (int)'\n"
|
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"
|
" |-ParmVarDecl 0x2637ae0 <col:9, col:13> col:13 used x 'int'\n"
|
||||||
|
|
Loading…
Reference in New Issue