Clang import; RecordDecl
This commit is contained in:
parent
c4131bbc5b
commit
a3abc75ca1
|
@ -19,6 +19,7 @@
|
||||||
#include "clangastdump.h"
|
#include "clangastdump.h"
|
||||||
#include "symboldatabase.h"
|
#include "symboldatabase.h"
|
||||||
#include "tokenize.h"
|
#include "tokenize.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -29,11 +30,13 @@ static const std::string BinaryOperator = "BinaryOperator";
|
||||||
static const std::string CallExpr = "CallExpr";
|
static const std::string CallExpr = "CallExpr";
|
||||||
static const std::string CompoundStmt = "CompoundStmt";
|
static const std::string CompoundStmt = "CompoundStmt";
|
||||||
static const std::string DeclRefExpr = "DeclRefExpr";
|
static const std::string DeclRefExpr = "DeclRefExpr";
|
||||||
|
static const std::string FieldDecl = "FieldDecl";
|
||||||
static const std::string FunctionDecl = "FunctionDecl";
|
static const std::string FunctionDecl = "FunctionDecl";
|
||||||
static const std::string IfStmt = "IfStmt";
|
static const std::string IfStmt = "IfStmt";
|
||||||
static const std::string ImplicitCastExpr = "ImplicitCastExpr";
|
static const std::string ImplicitCastExpr = "ImplicitCastExpr";
|
||||||
static const std::string IntegerLiteral = "IntegerLiteral";
|
static const std::string IntegerLiteral = "IntegerLiteral";
|
||||||
static const std::string ParmVarDecl = "ParmVarDecl";
|
static const std::string ParmVarDecl = "ParmVarDecl";
|
||||||
|
static const std::string RecordDecl = "RecordDecl";
|
||||||
static const std::string ReturnStmt = "ReturnStmt";
|
static const std::string ReturnStmt = "ReturnStmt";
|
||||||
static const std::string UnaryOperator = "UnaryOperator";
|
static const std::string UnaryOperator = "UnaryOperator";
|
||||||
static const std::string VarDecl = "VarDecl";
|
static const std::string VarDecl = "VarDecl";
|
||||||
|
@ -133,6 +136,7 @@ namespace clangastdump {
|
||||||
Scope *createScope(TokenList *tokenList, Scope::ScopeType scopeType, AstNode *astNode);
|
Scope *createScope(TokenList *tokenList, Scope::ScopeType scopeType, AstNode *astNode);
|
||||||
std::string getSpelling() const;
|
std::string getSpelling() const;
|
||||||
std::string getType() const;
|
std::string getType() const;
|
||||||
|
const Scope *getNestedInScope(TokenList *tokenList);
|
||||||
|
|
||||||
int mFile = 0;
|
int mFile = 0;
|
||||||
int mLine = 1;
|
int mLine = 1;
|
||||||
|
@ -147,9 +151,7 @@ namespace clangastdump {
|
||||||
|
|
||||||
std::string clangastdump::AstNode::getSpelling() const
|
std::string clangastdump::AstNode::getSpelling() const
|
||||||
{
|
{
|
||||||
if (nodeType == ParmVarDecl)
|
return mExtTokens[mExtTokens.size() - 2];
|
||||||
return mExtTokens[mExtTokens.size() - 2];
|
|
||||||
return "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string clangastdump::AstNode::getType() const
|
std::string clangastdump::AstNode::getType() const
|
||||||
|
@ -197,13 +199,7 @@ void clangastdump::AstNode::setLocations(TokenList *tokenList, int file, int lin
|
||||||
|
|
||||||
Token *clangastdump::AstNode::addtoken(TokenList *tokenList, const std::string &str)
|
Token *clangastdump::AstNode::addtoken(TokenList *tokenList, const std::string &str)
|
||||||
{
|
{
|
||||||
const Scope *scope;
|
const Scope *scope = getNestedInScope(tokenList);
|
||||||
if (!tokenList->back())
|
|
||||||
scope = &mData->mSymbolDatabase->scopeList.front();
|
|
||||||
else if (tokenList->back()->str() == "}")
|
|
||||||
scope = tokenList->back()->scope()->nestedIn;
|
|
||||||
else
|
|
||||||
scope = tokenList->back()->scope();
|
|
||||||
tokenList->addtoken(str, mLine, mFile);
|
tokenList->addtoken(str, mLine, mFile);
|
||||||
tokenList->back()->column(mCol);
|
tokenList->back()->column(mCol);
|
||||||
tokenList->back()->scope(scope);
|
tokenList->back()->scope(scope);
|
||||||
|
@ -219,17 +215,21 @@ Token *clangastdump::AstNode::addTypeTokens(TokenList *tokenList, const std::str
|
||||||
return addtoken(tokenList, str.substr(1,str.find(" (")-1));
|
return addtoken(tokenList, str.substr(1,str.find(" (")-1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Scope *clangastdump::AstNode::getNestedInScope(TokenList *tokenList)
|
||||||
|
{
|
||||||
|
if (!tokenList->back())
|
||||||
|
return &mData->mSymbolDatabase->scopeList.front();
|
||||||
|
if (tokenList->back()->str() == "}")
|
||||||
|
return tokenList->back()->scope()->nestedIn;
|
||||||
|
return tokenList->back()->scope();
|
||||||
|
}
|
||||||
|
|
||||||
Scope *clangastdump::AstNode::createScope(TokenList *tokenList, Scope::ScopeType scopeType, AstNode *astNode)
|
Scope *clangastdump::AstNode::createScope(TokenList *tokenList, Scope::ScopeType scopeType, AstNode *astNode)
|
||||||
{
|
{
|
||||||
SymbolDatabase *symbolDatabase = mData->mSymbolDatabase;
|
SymbolDatabase *symbolDatabase = mData->mSymbolDatabase;
|
||||||
|
|
||||||
const Scope *nestedIn;
|
const Scope *nestedIn = getNestedInScope(tokenList);
|
||||||
if (!tokenList->back())
|
|
||||||
nestedIn = &symbolDatabase->scopeList.front();
|
|
||||||
else if (tokenList->back()->str() == "}")
|
|
||||||
nestedIn = tokenList->back()->link()->previous()->scope();
|
|
||||||
else
|
|
||||||
nestedIn = tokenList->back()->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();
|
||||||
scope->type = scopeType;
|
scope->type = scopeType;
|
||||||
|
@ -297,6 +297,28 @@ Token *clangastdump::AstNode::createTokens(TokenList *tokenList)
|
||||||
mData->ref(addr, reftok);
|
mData->ref(addr, reftok);
|
||||||
return reftok;
|
return reftok;
|
||||||
}
|
}
|
||||||
|
if (nodeType == FieldDecl) {
|
||||||
|
bool isInit = mExtTokens.back() == "cinit";
|
||||||
|
const std::string addr = mExtTokens.front();
|
||||||
|
const std::string type = isInit ? mExtTokens[mExtTokens.size() - 2] : mExtTokens.back();
|
||||||
|
const std::string name = isInit ? mExtTokens[mExtTokens.size() - 3] : mExtTokens[mExtTokens.size() - 2];
|
||||||
|
addTypeTokens(tokenList, type);
|
||||||
|
Token *vartok1 = addtoken(tokenList, name);
|
||||||
|
Scope *scope = const_cast<Scope *>(tokenList->back()->scope());
|
||||||
|
const AccessControl accessControl = (scope->type == Scope::ScopeType::eGlobal) ? (AccessControl::Global) : (AccessControl::Local);
|
||||||
|
scope->varlist.push_back(Variable(vartok1, type, 0, accessControl, nullptr, scope));
|
||||||
|
mData->varDecl(addr, vartok1, &scope->varlist.back());
|
||||||
|
addtoken(tokenList, ";");
|
||||||
|
if (isInit) {
|
||||||
|
Token *vartok2 = addtoken(tokenList, name);
|
||||||
|
mData->ref(addr, vartok2);
|
||||||
|
Token *eq = addtoken(tokenList, "=");
|
||||||
|
eq->astOperand1(vartok2);
|
||||||
|
eq->astOperand2(children.back()->createTokens(tokenList));
|
||||||
|
addtoken(tokenList, ";");
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
if (nodeType == FunctionDecl) {
|
if (nodeType == FunctionDecl) {
|
||||||
SymbolDatabase *symbolDatabase = mData->mSymbolDatabase;
|
SymbolDatabase *symbolDatabase = mData->mSymbolDatabase;
|
||||||
addTypeTokens(tokenList, mExtTokens.back());
|
addTypeTokens(tokenList, mExtTokens.back());
|
||||||
|
@ -363,6 +385,26 @@ Token *clangastdump::AstNode::createTokens(TokenList *tokenList)
|
||||||
return children[0]->createTokens(tokenList);
|
return children[0]->createTokens(tokenList);
|
||||||
if (nodeType == IntegerLiteral)
|
if (nodeType == IntegerLiteral)
|
||||||
return addtoken(tokenList, mExtTokens.back());
|
return addtoken(tokenList, mExtTokens.back());
|
||||||
|
if (nodeType == RecordDecl) {
|
||||||
|
const Token *classDef = addtoken(tokenList, "struct");
|
||||||
|
/*const Token *nameToken =*/ addtoken(tokenList, getSpelling());
|
||||||
|
const Scope *nestedIn = getNestedInScope(tokenList);
|
||||||
|
mData->mSymbolDatabase->scopeList.push_back(Scope(nullptr, nullptr, nestedIn));
|
||||||
|
Scope *scope = &mData->mSymbolDatabase->scopeList.back();
|
||||||
|
scope->type = Scope::ScopeType::eStruct;
|
||||||
|
mData->mSymbolDatabase->typeList.push_back(Type(classDef, scope, nestedIn));
|
||||||
|
scope->definedType = &mData->mSymbolDatabase->typeList.back();
|
||||||
|
Token *bodyStart = addtoken(tokenList, "{");
|
||||||
|
bodyStart->scope(scope);
|
||||||
|
for (AstNodePtr child: children) {
|
||||||
|
child->createTokens(tokenList);
|
||||||
|
}
|
||||||
|
Token *bodyEnd = addtoken(tokenList, "}");
|
||||||
|
bodyStart->link(bodyEnd);
|
||||||
|
scope->bodyStart = bodyStart;
|
||||||
|
scope->bodyEnd = bodyEnd;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
if (nodeType == ReturnStmt) {
|
if (nodeType == ReturnStmt) {
|
||||||
Token *tok1 = addtoken(tokenList, "return");
|
Token *tok1 = addtoken(tokenList, "return");
|
||||||
if (!children.empty())
|
if (!children.empty())
|
||||||
|
@ -427,7 +469,7 @@ void clangastdump::parseClangAstDump(Tokenizer *tokenizer, std::istream &f)
|
||||||
const std::string nodeType = line.substr(pos1+1, pos2 - pos1 - 1);
|
const std::string nodeType = line.substr(pos1+1, pos2 - pos1 - 1);
|
||||||
const std::string ext = line.substr(pos2);
|
const std::string ext = line.substr(pos2);
|
||||||
|
|
||||||
if (pos1 == 1 && (nodeType == FunctionDecl || nodeType == VarDecl)) {
|
if (pos1 == 1 && endsWith(nodeType, "Decl", 4) && nodeType != "TypedefDecl") {
|
||||||
if (!tree.empty()) {
|
if (!tree.empty()) {
|
||||||
tree[0]->setLocations(tokenList, 0, 1, 1);
|
tree[0]->setLocations(tokenList, 0, 1, 1);
|
||||||
tree[0]->createTokens(tokenList);
|
tree[0]->createTokens(tokenList);
|
||||||
|
|
|
@ -32,6 +32,7 @@ private:
|
||||||
TEST_CASE(funcdecl1);
|
TEST_CASE(funcdecl1);
|
||||||
TEST_CASE(funcdecl2);
|
TEST_CASE(funcdecl2);
|
||||||
TEST_CASE(ifelse);
|
TEST_CASE(ifelse);
|
||||||
|
TEST_CASE(recordDecl);
|
||||||
TEST_CASE(vardecl1);
|
TEST_CASE(vardecl1);
|
||||||
TEST_CASE(vardecl2);
|
TEST_CASE(vardecl2);
|
||||||
}
|
}
|
||||||
|
@ -85,6 +86,16 @@ private:
|
||||||
"else { } ; }", parse(clang));
|
"else { } ; }", 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"
|
||||||
|
" `-FieldDecl 0x354ebe8 <line:3:3, col:7> col:7 y 'int'";
|
||||||
|
ASSERT_EQUALS("struct S {\n"
|
||||||
|
"int x@1 ;\n"
|
||||||
|
"int y@2 ; }",
|
||||||
|
parse(clang));
|
||||||
|
}
|
||||||
|
|
||||||
void vardecl1() {
|
void vardecl1() {
|
||||||
const char clang[] = "|-VarDecl 0x32b8aa0 <1.c:1:1, col:9> col:5 used a 'int' cinit\n"
|
const char clang[] = "|-VarDecl 0x32b8aa0 <1.c:1:1, col:9> col:5 used a 'int' cinit\n"
|
||||||
"| `-IntegerLiteral 0x32b8b40 <col:9> 'int' 1\n"
|
"| `-IntegerLiteral 0x32b8b40 <col:9> 'int' 1\n"
|
||||||
|
|
Loading…
Reference in New Issue