1 /**
2 Copyright: Copyright (c) 2017, Joakim Brännström. All rights reserved.
3 License: MPL-2
4 Author: Joakim Brännström (joakim.brannstrom@gmx.com)
5 
6 This Source Code Form is subject to the terms of the Mozilla Public License,
7 v.2.0. If a copy of the MPL was not distributed with this file, You can obtain
8 one at http://mozilla.org/MPL/2.0/.
9 */
10 module dextool.plugin.intercept.backend.analyzer;
11 
12 import logger = std.experimental.logger;
13 
14 import cpptooling.analyzer.clang.ast : Visitor;
15 import cpptooling.data : CppRoot, CppClass, CppMethod, CppCtor, CppDtor,
16     CFunction, CppNamespace, LocationTag, Location, USRType;
17 
18 import dextool.plugin.intercept.backend.interface_;
19 
20 /// Data derived during analyze.
21 struct AnalyzeData {
22     static auto make() {
23         auto r = AnalyzeData(CppRoot.make);
24         return r;
25     }
26 
27     CppRoot root;
28     alias root this;
29 }
30 
31 final class TUVisitor : Visitor {
32     import std.typecons : scoped, NullableRef;
33 
34     import cpptooling.analyzer.clang.ast : UnexposedDecl, FunctionDecl,
35         TranslationUnit, generateIndentIncrDecr;
36     import cpptooling.analyzer.clang.analyze_helper : analyzeFunctionDecl;
37     import cpptooling.data : CxReturnType;
38     import cpptooling.data.symbol : Container;
39     import cpptooling.analyzer.clang.cursor_logger : logNode, mixinNodeLog;
40 
41     alias visit = Visitor.visit;
42 
43     mixin generateIndentIncrDecr;
44 
45     NullableRef!Container container;
46     AnalyzeData root;
47 
48     this(NullableRef!Container container) {
49         this.container = container;
50         this.root = AnalyzeData.make;
51     }
52 
53     override void visit(const(UnexposedDecl) v) {
54         mixin(mixinNodeLog!());
55 
56         // An unexposed may be:
57 
58         // an extern "C"
59         // UnexposedDecl "" extern "C" {...
60         //   FunctionDecl "fun_c_linkage" void func_c_linkage
61         v.accept(this);
62     }
63 
64     override void visit(const(FunctionDecl) v) {
65         mixin(mixinNodeLog!());
66 
67         auto result = analyzeFunctionDecl(v, container, indent);
68         if (result.isValid) {
69             auto func = CFunction(result.type.kind.usr, result.name, result.params,
70                     CxReturnType(result.returnType), result.isVariadic, result.storageClass);
71             root.put(func);
72         }
73     }
74 
75     override void visit(const(TranslationUnit) v) {
76         mixin(mixinNodeLog!());
77         v.accept(this);
78     }
79 }