Clang import; MemberExpr

This commit is contained in:
Daniel Marjamäki 2020-01-08 09:51:35 +01:00
parent 86510664b4
commit 4b7e6c68b0
2 changed files with 48 additions and 8 deletions

View File

@ -17,6 +17,7 @@
*/
#include "clangastdump.h"
#include "settings.h"
#include "symboldatabase.h"
#include "tokenize.h"
#include "utils.h"
@ -35,6 +36,7 @@ static const std::string FunctionDecl = "FunctionDecl";
static const std::string IfStmt = "IfStmt";
static const std::string ImplicitCastExpr = "ImplicitCastExpr";
static const std::string IntegerLiteral = "IntegerLiteral";
static const std::string MemberExpr = "MemberExpr";
static const std::string ParmVarDecl = "ParmVarDecl";
static const std::string RecordDecl = "RecordDecl";
static const std::string ReturnStmt = "ReturnStmt";
@ -54,9 +56,11 @@ static std::vector<std::string> splitString(const std::string &line)
std::string::size_type pos2;
if (line[pos1] == '<')
pos2 = line.find(">", pos1);
else if (line[pos1] == '\'')
else if (line[pos1] == '\'') {
pos2 = line.find("\'", pos1+1);
else
if (line.compare(pos2, 3, "\':\'", 0, 3) == 0)
pos2 = line.find("\'", pos2 + 3);
} else
pos2 = line.find(" ", pos1) - 1;
ret.push_back(line.substr(pos1, pos2+1-pos1));
if (pos2 == std::string::npos)
@ -135,7 +139,7 @@ namespace clangastdump {
Token *createTokens(TokenList *tokenList);
private:
Token *addtoken(TokenList *tokenList, const std::string &str);
Token *addTypeTokens(TokenList *tokenList, const std::string &str);
void addTypeTokens(TokenList *tokenList, const std::string &str);
Scope *createScope(TokenList *tokenList, Scope::ScopeType scopeType, AstNodePtr astNode);
Scope *createScope(TokenList *tokenList, Scope::ScopeType scopeType, const std::vector<AstNodePtr> &children);
void createTokensVarDecl(TokenList *tokenList);
@ -211,11 +215,17 @@ Token *clangastdump::AstNode::addtoken(TokenList *tokenList, const std::string &
return tokenList->back();
}
Token *clangastdump::AstNode::addTypeTokens(TokenList *tokenList, const std::string &str)
void clangastdump::AstNode::addTypeTokens(TokenList *tokenList, const std::string &str)
{
if (str.find(" (") == std::string::npos)
return addtoken(tokenList, unquote(str));
return addtoken(tokenList, str.substr(1,str.find(" (")-1));
std::string type;
if (str.find(" (") != std::string::npos)
type = str.substr(1,str.find(" (")-1);
else if (str.find("\':\'") != std::string::npos)
type = str.substr(1, str.find("\':\'") - 1);
else
type = unquote(str);
for (const std::string &s: splitString(type))
addtoken(tokenList, s);
}
const Scope *clangastdump::AstNode::getNestedInScope(TokenList *tokenList)
@ -378,6 +388,15 @@ Token *clangastdump::AstNode::createTokens(TokenList *tokenList)
return children[0]->createTokens(tokenList);
if (nodeType == IntegerLiteral)
return addtoken(tokenList, mExtTokens.back());
if (nodeType == MemberExpr) {
Token *s = children[0]->createTokens(tokenList);
Token *dot = addtoken(tokenList, ".");
Token *member = addtoken(tokenList, getSpelling().substr(1));
mData->ref(mExtTokens.back(), member);
dot->astOperand1(s);
dot->astOperand2(member);
return dot;
}
if (nodeType == RecordDecl) {
const Token *classDef = addtoken(tokenList, "struct");
const std::string &recordName = getSpelling();
@ -480,6 +499,8 @@ void clangastdump::parseClangAstDump(Tokenizer *tokenizer, std::istream &f)
}
if (!tree.empty()) {
//if (tokenizer->getSettings()->debugnormal)
// tree[0]->dumpAst();
tree[0]->setLocations(tokenList, 0, 1, 1);
tree[0]->createTokens(tokenList);
}

View File

@ -32,6 +32,7 @@ private:
TEST_CASE(funcdecl1);
TEST_CASE(funcdecl2);
TEST_CASE(ifelse);
TEST_CASE(memberExpr);
TEST_CASE(recordDecl);
TEST_CASE(vardecl1);
TEST_CASE(vardecl2);
@ -86,6 +87,24 @@ private:
"else { } ; }", parse(clang));
}
void memberExpr() {
// C code:
// struct S { int x };
// int foo(struct S s) { return s.x; }
const char clang[] = "|-RecordDecl 0x2441a88 <1.c:1:1, col:18> col:8 struct S definition\n"
"| `-FieldDecl 0x2441b48 <col:12, col:16> col:16 referenced x 'int'\n"
"`-FunctionDecl 0x2441cf8 <line:2:1, col:35> col:5 foo 'int (struct S)'\n"
" |-ParmVarDecl 0x2441be8 <col:9, col:18> col:18 used s 'struct S':'struct S'\n"
" `-CompoundStmt 0x2441e70 <col:21, col:35>\n"
" `-ReturnStmt 0x2441e58 <col:23, col:32>\n"
" `-ImplicitCastExpr 0x2441e40 <col:30, col:32> 'int' <LValueToRValue>\n"
" `-MemberExpr 0x2441e08 <col:30, col:32> 'int' lvalue .x 0x2441b48\n"
" `-DeclRefExpr 0x2441de0 <col:30> 'struct S':'struct S' lvalue ParmVar 0x2441be8 's' 'struct S':'struct S'";
ASSERT_EQUALS("struct S { int x@1 ; }\n"
"int foo ( struct S s@2 ) { return s@2 . x@1 ; }",
parse(clang));
}
void recordDecl() {
const char clang[] = "`-RecordDecl 0x354eac8 <1.c:1:1, line:4:1> line:1:8 struct S definition\n"
" |-FieldDecl 0x354eb88 <line:2:3, col:7> col:7 x 'int'\n"
@ -119,7 +138,7 @@ private:
" | `-IntegerLiteral 0x3873d00 <col:5> 'int' 0\n"
" `-IntegerLiteral 0x3873d88 <col:10> 'int' 0\n";
ASSERT_EQUALS("int[10] a@1 ;\n"
ASSERT_EQUALS("int [10] a@1 ;\n" // <- TODO
"\n"
"void foo ( ) {\n"
"\n"