Repository navigation
Expand file tree
/
Copy pathreader.cpp
More file actions
95 lines (74 loc) · 2.75 KB
/
Copy pathreader.cpp
File metadata and controls
95 lines (74 loc) · 2.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
// I don't understand what half this LLVM code does. I just fought it long
// enough until I managed to visit the things I needed to visit.
class ReaderVisitor : public clang::RecursiveASTVisitor<ReaderVisitor> {
public:
explicit ReaderVisitor(clang::ASTContext *Context, arche::Info &info) : Context(Context), info(info) {}
bool VisitEnumDecl(const clang::EnumDecl *E) {
if (!E->isCompleteDefinition()) {
return true; // Continue visiting
}
// Get the file where the enum is defined
clang::SourceLocation loc = E->getLocation();
clang::PresumedLoc presumedLoc =
Context->getSourceManager().getPresumedLoc(loc);
std::string filename = presumedLoc.getFilename();
if (filename != info.filename) {
return true; // Continue visiting
}
llvm::StringRef name = E->getName();
arche::Enum &enum_ = info.enums[name];
enum_.name = name;
for (const clang::EnumConstantDecl *enum_const : E->enumerators()) {
arche::EnumElem elem;
elem.name = enum_const->getName();
enum_.elems.push_back(elem);
}
return true; // Continue visiting
}
bool VisitRecordDecl(const clang::RecordDecl *R) {
if (!R->isCompleteDefinition() || !R->isStruct()) {
return true; // Continue visiting
}
// Get the file where the enum is defined
clang::SourceLocation loc = R->getLocation();
clang::PresumedLoc presumedLoc =
Context->getSourceManager().getPresumedLoc(loc);
std::string filename = presumedLoc.getFilename();
if (filename != info.filename) {
return true; // Continue visiting
}
llvm::StringRef name = R->getName();
arche::Struct &struct_ = info.structs[name];
struct_.name = name;
// TODO: Handle nested structs and unions.
for (const clang::FieldDecl *field : R->fields()) {
arche::StructField field_info;
field_info.name = field->getName();
field_info.type = field->getType().getAsString();
struct_.fields.push_back(field_info);
}
return true; // Continue visiting
}
private:
clang::ASTContext *Context;
arche::Info &info;
};
class ReaderConsumer : public clang::ASTConsumer {
public:
explicit ReaderConsumer(clang::ASTContext *Context, arche::Info &info) : Visitor(Context, info) {}
void HandleTranslationUnit(clang::ASTContext &Context) override {
Visitor.TraverseDecl(Context.getTranslationUnitDecl());
}
private:
ReaderVisitor Visitor;
};
class ReaderAction : public clang::ASTFrontendAction {
public:
explicit ReaderAction(arche::Info &info) : info(info) {}
std::unique_ptr<clang::ASTConsumer> CreateASTConsumer(
clang::CompilerInstance &CI, llvm::StringRef InFile) override {
return std::make_unique<ReaderConsumer>(&CI.getASTContext(), info);
}
private:
arche::Info &info;
};