Clang import; MemberExpr
This commit is contained in:
parent
86510664b4
commit
4b7e6c68b0
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue