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 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());
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue