Improving code reuse in clang tools with clangmetatool Daniel Ruoso - - PowerPoint PPT Presentation

improving code reuse in clang tools with clangmetatool
SMART_READER_LITE
LIVE PREVIEW

Improving code reuse in clang tools with clangmetatool Daniel Ruoso - - PowerPoint PPT Presentation

Improving code reuse in clang tools with clangmetatool Daniel Ruoso druoso@bloomberg.net Bloomberg October 17, 2018 Static Analysis and Automated Refactoring at Bloomberg Static Analysis and Automated Refactoring at Bloomberg


slide-1
SLIDE 1

Improving code reuse in clang tools with clangmetatool

Daniel Ruoso druoso@bloomberg.net Bloomberg October 17, 2018

slide-2
SLIDE 2

Static Analysis and Automated Refactoring at Bloomberg

◮ ◮ ◮

slide-3
SLIDE 3

Static Analysis and Automated Refactoring at Bloomberg

◮ 30+ years of code ◮ ◮

slide-4
SLIDE 4

Static Analysis and Automated Refactoring at Bloomberg

◮ 30+ years of code ◮ substantial amount of reuse ◮

slide-5
SLIDE 5

Static Analysis and Automated Refactoring at Bloomberg

◮ 30+ years of code ◮ substantial amount of reuse ◮ continuously integrated and deployed

slide-6
SLIDE 6

Writing Language Tools – A brief History

◮ ◮ ◮

slide-7
SLIDE 7

Writing Language Tools – A brief History

◮ tools space with gcc ◮ ◮

slide-8
SLIDE 8

Writing Language Tools – A brief History

◮ tools space with gcc ◮ llvm3.8 boom ◮

slide-9
SLIDE 9

Writing Language Tools – A brief History

◮ tools space with gcc ◮ llvm3.8 boom ◮ clangTooling

slide-10
SLIDE 10

My first clang tool

◮ ◮ ◮

slide-11
SLIDE 11

My first clang tool

◮ exercise: re-implement include-what-you-use ◮ ◮

slide-12
SLIDE 12

My first clang tool

◮ exercise: re-implement include-what-you-use ◮ unsure about life-cycle? just use globals ◮

slide-13
SLIDE 13

My first clang tool

◮ exercise: re-implement include-what-you-use ◮ unsure about life-cycle? just use globals ◮ unsure about when to rewrite? just rewrite asap

slide-14
SLIDE 14

My first clang tool

◮ ◮ ◮

slide-15
SLIDE 15

My first clang tool

◮ so many stub doxygen docs ◮ ◮

slide-16
SLIDE 16

My first clang tool

◮ so many stub doxygen docs ◮ so many callbacks ◮

slide-17
SLIDE 17

My first clang tool

◮ so many stub doxygen docs ◮ so many callbacks ◮ life-cycle of objects unclear

slide-18
SLIDE 18

My first clang tool – Lessons

◮ ◮ ◮

slide-19
SLIDE 19

My first clang tool – Lessons

◮ writing a clang tool is actually not that hard ◮ ◮

slide-20
SLIDE 20

My first clang tool – Lessons

◮ writing a clang tool is actually not that hard ◮ not a single line of reusable code ◮

slide-21
SLIDE 21

My first clang tool – Lessons

◮ writing a clang tool is actually not that hard ◮ not a single line of reusable code ◮ tightly coupling: analysis, rewriting, data collection

slide-22
SLIDE 22

Principles

◮ ◮ ◮

slide-23
SLIDE 23

Principles

◮ Refactoring tool should make smallest possible change ◮ ◮

slide-24
SLIDE 24

Principles

◮ Refactoring tool should make smallest possible change ◮ Create the tool, run it, throw it away ◮

slide-25
SLIDE 25

Principles

◮ Refactoring tool should make smallest possible change ◮ Create the tool, run it, throw it away ◮ Design Patterns: Collect, Analyze, Rewrite

slide-26
SLIDE 26

Design Pattern: Data Collectors

◮ ◮ ◮

slide-27
SLIDE 27

Design Pattern: Data Collectors

◮ Register callbacks, stores data in member ◮ ◮

slide-28
SLIDE 28

Design Pattern: Data Collectors

◮ Register callbacks, stores data in member ◮ No specific analysis performed ◮

slide-29
SLIDE 29

Design Pattern: Data Collectors

◮ Register callbacks, stores data in member ◮ No specific analysis performed ◮ Expose the data in a useful way

slide-30
SLIDE 30

Design Pattern: Analysis

◮ ◮ ◮

slide-31
SLIDE 31

Design Pattern: Analysis

◮ Single entry point ◮ ◮

slide-32
SLIDE 32

Design Pattern: Analysis

◮ Single entry point ◮ Straight-forward imperative code ◮

slide-33
SLIDE 33

Design Pattern: Analysis

◮ Single entry point ◮ Straight-forward imperative code ◮ As little tool-specific code as possible

slide-34
SLIDE 34

Design Pattern: Refactoring

◮ ◮ ◮

slide-35
SLIDE 35

Design Pattern: Refactoring

◮ Already part of the tooling API ◮ ◮

slide-36
SLIDE 36

Design Pattern: Refactoring

◮ Already part of the tooling API ◮ Just fill in the ReplacementsMap ◮

slide-37
SLIDE 37

Design Pattern: Refactoring

◮ Already part of the tooling API ◮ Just fill in the ReplacementsMap ◮ Handles coherency for you

slide-38
SLIDE 38

clangmetatool

◮ Life-cycle management ◮ Data collectors ◮ Reusable Analysis

slide-39
SLIDE 39

clangmetatool: life-cycle management

1

int main(int argc, const char* argv[]) {

2

llvm::cl::OptionCategory MyToolCategory("my-tool options");

3

llvm::cl::extrahelp CommonHelp

4

(clang::tooling::CommonOptionsParser::HelpMessage);

5

clang::tooling::CommonOptionsParser

6

  • ptionsParser(argc, argv, MyToolCategory);

7

clang::tooling::RefactoringTool tool(optionsParser.getCompilations(),

8

  • ptionsParser.getSourcePathList());

9

clangmetatool::MetaToolFactory< clangmetatool::MetaTool<MyTool> >

10

raf(tool.getReplacements());

11

int r = tool.runAndSave(&raf);

12

return r;

13

}

slide-40
SLIDE 40

clangmetatool: life-cycle management

1

class MyTool {

2

private:

3

SomeDataCollector collector1;

4

SomeOtherDataCollector collector2;

5

public:

6

MyTool(clang::CompilerInstance* ci, clang::ast_matchers::MatchFinder *f)

7

:collector1(ci, f), collector2(ci, f) {

8

// the individual collectors will register their callbacks in their

9

// constructor, the tool doesn’t really need to do anything else here.

10

}

11

void postProcessing

12

(std::map<std::string, clang::tooling::Replacements> &replacementsMap) {

13

// use data from collector1 and collector2

14

// generate warnings and notices

15

// add replacements to replacementsMap

16

}

17

};

slide-41
SLIDE 41

clangmetatool: reusable data-collector

1

class WhoCallsIt {

2

private:

3

clangmetatool::collectors::FindCalls fc;

4

public:

5

MyTool(clang::CompilerInstance* ci, clang::ast_matchers::MatchFinder *f)

6

:(ci, f, "legacyfunction") {

7

}

8

void postProcessing

9

(std::map<std::string, clang::tooling::Replacements> &replacementsMap) {

10

FindCallsData *fcd = fc.getData();

11

auto calls_it = fcd->call_ref.begin();

12

while (calls_it != fcd->call_ref.end()) {

13

// do something for each call to legacyfunction

14

}

15

}

16

};

slide-42
SLIDE 42

clangmetatool: reusable analysis

1

clangmetatool::propagation::ConstantCStringPropagator prop(ci);

2

PropagationResult<std::string> r = prop.runPropagation(funcdecl, vdrefexpr);

3

if (!r.isUnresolved()) {

4

std::cout

5

<< "value of variable at this point is "

6

<< r.getResult()

7

<< std::endl;

8

}

slide-43
SLIDE 43

Impact at Bloomberg

◮ low cost to writing new tools ◮ custom static analysis accessible ◮ automated refactoring on the rise

slide-44
SLIDE 44

Questions?

druoso@bloomberg.net https://bloomberg.github.io/clangmetatool