Clang import: CXXRecordDecl, CXXMethodDecl
This commit is contained in:
parent
5ffd6d744c
commit
64953f36b3
|
@ -32,6 +32,8 @@ static const std::string BreakStmt = "BreakStmt";
|
|||
static const std::string CallExpr = "CallExpr";
|
||||
static const std::string CompoundStmt = "CompoundStmt";
|
||||
static const std::string ContinueStmt = "ContinueStmt";
|
||||
static const std::string CXXMethodDecl = "CXXMethodDecl";
|
||||
static const std::string CXXRecordDecl = "CXXRecordDecl";
|
||||
static const std::string DeclRefExpr = "DeclRefExpr";
|
||||
static const std::string DeclStmt = "DeclStmt";
|
||||
static const std::string FieldDecl = "FieldDecl";
|
||||
|
@ -158,6 +160,7 @@ namespace clangastdump {
|
|||
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 createTokensFunctionDecl(TokenList *tokenList);
|
||||
Token *createTokensVarDecl(TokenList *tokenList);
|
||||
std::string getSpelling() const;
|
||||
std::string getType() const;
|
||||
|
@ -344,6 +347,25 @@ Token *clangastdump::AstNode::createTokens(TokenList *tokenList)
|
|||
}
|
||||
if (nodeType == ContinueStmt)
|
||||
return addtoken(tokenList, "continue");
|
||||
if (nodeType == CXXMethodDecl) {
|
||||
createTokensFunctionDecl(tokenList);
|
||||
return nullptr;
|
||||
}
|
||||
if (nodeType == CXXRecordDecl) {
|
||||
Token *classToken = addtoken(tokenList, "class");
|
||||
Token *nameToken = addtoken(tokenList, mExtTokens[mExtTokens.size() - 2]);
|
||||
std::vector<AstNodePtr> children2;
|
||||
for (auto child: children) {
|
||||
if (child->nodeType == "CXXMethodDecl")
|
||||
children2.push_back(child);
|
||||
}
|
||||
Scope *scope = createScope(tokenList, Scope::ScopeType::eClass, children2);
|
||||
scope->classDef = classToken;
|
||||
scope->className = nameToken->str();
|
||||
mData->mSymbolDatabase->typeList.push_back(Type(classToken, scope, classToken->scope()));
|
||||
scope->definedType = &mData->mSymbolDatabase->typeList.back();
|
||||
return nullptr;
|
||||
}
|
||||
if (nodeType == DeclStmt)
|
||||
return children[0]->createTokens(tokenList);
|
||||
if (nodeType == DeclRefExpr) {
|
||||
|
@ -374,52 +396,7 @@ Token *clangastdump::AstNode::createTokens(TokenList *tokenList)
|
|||
return nullptr;
|
||||
}
|
||||
if (nodeType == FunctionDecl) {
|
||||
SymbolDatabase *symbolDatabase = mData->mSymbolDatabase;
|
||||
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();
|
||||
symbolDatabase->functionScopes.push_back(&scope);
|
||||
nestedIn->functionList.push_back(Function(nameToken));
|
||||
scope.function = &nestedIn->functionList.back();
|
||||
scope.type = Scope::ScopeType::eFunction;
|
||||
scope.className = nameToken->str();
|
||||
mData->funcDecl(mExtTokens.front(), nameToken, scope.function);
|
||||
Token *par1 = addtoken(tokenList, "(");
|
||||
// Function arguments
|
||||
for (AstNodePtr child: children) {
|
||||
if (child->nodeType != ParmVarDecl)
|
||||
continue;
|
||||
if (tokenList->back() != par1)
|
||||
addtoken(tokenList, ",");
|
||||
addTypeTokens(tokenList, child->mExtTokens.back());
|
||||
const std::string spelling = child->getSpelling();
|
||||
if (!spelling.empty()) {
|
||||
const std::string addr = child->mExtTokens[0];
|
||||
Token *vartok = addtoken(tokenList, spelling);
|
||||
scope.function->argumentList.push_back(Variable(vartok, nullptr, nullptr, 0, AccessControl::Argument, nullptr, &scope, nullptr));
|
||||
mData->varDecl(addr, vartok, &scope.function->argumentList.back());
|
||||
}
|
||||
}
|
||||
Token *par2 = addtoken(tokenList, ")");
|
||||
par1->link(par2);
|
||||
// Function body
|
||||
if (!children.empty() && children.back()->nodeType == CompoundStmt) {
|
||||
Token *bodyStart = addtoken(tokenList, "{");
|
||||
bodyStart->scope(&scope);
|
||||
children.back()->createTokens(tokenList);
|
||||
Token *bodyEnd = addtoken(tokenList, "}");
|
||||
scope.bodyStart = bodyStart;
|
||||
scope.bodyEnd = bodyEnd;
|
||||
bodyStart->link(bodyEnd);
|
||||
} else {
|
||||
addtoken(tokenList, ";");
|
||||
}
|
||||
createTokensFunctionDecl(tokenList);
|
||||
return nullptr;
|
||||
}
|
||||
if (nodeType == IfStmt) {
|
||||
|
@ -515,6 +492,56 @@ Token *clangastdump::AstNode::createTokens(TokenList *tokenList)
|
|||
return addtoken(tokenList, "?" + nodeType + "?");
|
||||
}
|
||||
|
||||
void clangastdump::AstNode::createTokensFunctionDecl(TokenList *tokenList)
|
||||
{
|
||||
SymbolDatabase *symbolDatabase = mData->mSymbolDatabase;
|
||||
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();
|
||||
symbolDatabase->functionScopes.push_back(&scope);
|
||||
nestedIn->functionList.push_back(Function(nameToken));
|
||||
scope.function = &nestedIn->functionList.back();
|
||||
scope.type = Scope::ScopeType::eFunction;
|
||||
scope.className = nameToken->str();
|
||||
mData->funcDecl(mExtTokens.front(), nameToken, scope.function);
|
||||
Token *par1 = addtoken(tokenList, "(");
|
||||
// Function arguments
|
||||
for (AstNodePtr child: children) {
|
||||
if (child->nodeType != ParmVarDecl)
|
||||
continue;
|
||||
if (tokenList->back() != par1)
|
||||
addtoken(tokenList, ",");
|
||||
addTypeTokens(tokenList, child->mExtTokens.back());
|
||||
const std::string spelling = child->getSpelling();
|
||||
if (!spelling.empty()) {
|
||||
const std::string addr = child->mExtTokens[0];
|
||||
Token *vartok = addtoken(tokenList, spelling);
|
||||
scope.function->argumentList.push_back(Variable(vartok, nullptr, nullptr, 0, AccessControl::Argument, nullptr, &scope, nullptr));
|
||||
mData->varDecl(addr, vartok, &scope.function->argumentList.back());
|
||||
}
|
||||
}
|
||||
Token *par2 = addtoken(tokenList, ")");
|
||||
par1->link(par2);
|
||||
// Function body
|
||||
if (!children.empty() && children.back()->nodeType == CompoundStmt) {
|
||||
Token *bodyStart = addtoken(tokenList, "{");
|
||||
bodyStart->scope(&scope);
|
||||
children.back()->createTokens(tokenList);
|
||||
Token *bodyEnd = addtoken(tokenList, "}");
|
||||
scope.bodyStart = bodyStart;
|
||||
scope.bodyEnd = bodyEnd;
|
||||
bodyStart->link(bodyEnd);
|
||||
} else {
|
||||
addtoken(tokenList, ";");
|
||||
}
|
||||
}
|
||||
|
||||
Token * clangastdump::AstNode::createTokensVarDecl(TokenList *tokenList)
|
||||
{
|
||||
const std::string addr = mExtTokens.front();
|
||||
|
|
|
@ -30,6 +30,7 @@ public:
|
|||
private:
|
||||
void run() OVERRIDE {
|
||||
TEST_CASE(breakStmt);
|
||||
TEST_CASE(class1);
|
||||
TEST_CASE(continueStmt);
|
||||
TEST_CASE(forStmt);
|
||||
TEST_CASE(funcdecl1);
|
||||
|
@ -49,9 +50,6 @@ private:
|
|||
TEST_CASE(vardecl4);
|
||||
TEST_CASE(vardecl5);
|
||||
TEST_CASE(whileStmt);
|
||||
|
||||
// C++..
|
||||
TEST_CASE(namespaceDecl);
|
||||
}
|
||||
|
||||
std::string parse(const char clang[]) {
|
||||
|
@ -72,6 +70,21 @@ private:
|
|||
ASSERT_EQUALS("void foo ( ) { while ( 0 ) { break ; } ; }", parse(clang));
|
||||
}
|
||||
|
||||
void class1() {
|
||||
const char clang[] = "`-CXXRecordDecl 0x274c638 <a.cpp:1:1, col:25> col:7 class C definition\n"
|
||||
" |-DefinitionData pass_in_registers empty aggregate standard_layout trivially_copyable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init\n"
|
||||
" | |-DefaultConstructor exists trivial constexpr needs_implicit defaulted_is_constexpr\n"
|
||||
" | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param\n"
|
||||
" | |-MoveConstructor exists simple trivial needs_implicit\n"
|
||||
" | |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param\n"
|
||||
" | |-MoveAssignment exists simple trivial needs_implicit\n"
|
||||
" | `-Destructor simple irrelevant trivial needs_implicit\n"
|
||||
" |-CXXRecordDecl 0x274c758 <col:1, col:7> col:7 implicit class C\n"
|
||||
" `-CXXMethodDecl 0x274c870 <col:11, col:23> col:16 foo 'void ()'\n"
|
||||
" `-CompoundStmt 0x274c930 <col:22, col:23>";
|
||||
ASSERT_EQUALS("class C { void foo ( ) { } }", parse(clang));
|
||||
}
|
||||
|
||||
void continueStmt() {
|
||||
const char clang[] = "`-FunctionDecl 0x2c31b18 <1.c:1:1, col:34> col:6 foo 'void ()'\n"
|
||||
" `-CompoundStmt 0x2c31c40 <col:12, col:34>\n"
|
||||
|
|
Loading…
Reference in New Issue