Windows 환경에서 clang(LLVM)을 사용하여 C++ 소스 코드에서 느낌 좋은 호출 차트를 만들기 전의 주석

5659 단어 WindowsC++

Windows 환경에서 clang(LLVM)을 사용하여 C++ 소스 코드에서 느낌 좋은 호출 차트를 만들기 전의 주석


평소에는 MSVC를 사용하고, 호출 도표를 만들 때doxygen 등을 사용하지만, 어쨌든 정밀도는 낮아진다.
clang(LLVM)도 할 수 있다고 하니 시행착오를 시도해 보세요.

전제 조건


다음 내용이 PATH를 통과한다고 가정합니다.
  • LLVM 6.0.1 Pre-build
  • Graphviz 2.38
  • 기본 방법


    여기https://yutopp.hateblo.jp/entry/2014/05/03/004049 등을 참고하여 아래 명령으로 호출 도표를 만들 수 있습니다.
    clang++ -S -emit-llvm main.cpp -o - | opt -analyze -dot-callgraph
    dot -Tpng callgraph.dot > callgraph.f.png
    

    clang으로 컴파일하기


    SVC로 컴파일된 원본 코드 (프로젝트) 라면 우선 clang으로 컴파일할 수 있어야 합니다.
    방법
  • Visual Studio에서 검사한 명령행
  • Visual Studio에서 조사한 명령행은 clang-cl ... 에서 실행되고 clang-cl -v ... 명령행으로 변경됩니다
  • C++ 소스 코드에서 콜 차트 생성 결과



    잘 조정되지 않은 호출 도표.


    만들어진 호출 도표에는 문제가 많다.
  • 생성된 호출 도표의 함수 이름이 표시됨
  • 가상 노드("external code"/"Node...")방해
  • 내장 함수("llvm*"/"_*") 간섭
  • 소환장


    헛소문을 퍼뜨리지 않으면 보기 어렵다.clang 등으로dot 파일을 방해합니다.
    근데dot 파일에 있는 탭 Undname.exe< 은 특수한 문자인 것 같아서 뜻을 바꿔야 합니다.> 를 사용하면 되지만 Windows 처럼 sed 로 변환됩니다.
    번거로운 것은 powershell 중에는 이미 전의(람다 등)를 당했기 때문에 전의를 하기 전에 잠시 전의를 해제하는 것이다.
    REM {$_  -replace "\<","<" -replace "\>",">" }
    powershell.exe -Command "Get-Content callgraph.dot | %% { $_ -replace \"\\^<\",\"^<\" -replace \"\\^>\",\"^>\" } " > callgraph1.dot 
    REM { $_ -replace "<","\<" -replace ">","\>"  -replace "-\\>","->" } 
    Undname.exe callgraph1.dot | powershell.exe -Command "$input | %% { $_ -replace \"\\^<\",\"^<\" -replace \"\\^>\",\"^>\" -replace \"^<\",\"\^<\" -replace \"^>\",\"\^>\" -replace \"-\\^>\",\"-^>\" } " > callgraph_demangled.dot
    

    방해되는 노드 삭제


    DOT 언어로 특정 노드를 제거(숨기기)하기 위해 지정opt하면 제거할 수 있을 것 같지만 [style=invis]의 매개 변수와 후처리 등에서 잘 제거되지 않습니다.
    결과적으로 LLVM의 소스 코드를 수정했습니다.
    --- CallPrinter.cpp.bak 2017-06-06 20:49:48.000000000 +0900
    +++ CallPrinter.cpp     2018-09-09 23:18:40.844019700 +0900
    @@ -33,6 +33,15 @@
    
         return "external node";
       }
    +
    +  /// isNodeHidden - If the function returns true, the given node is not
    +  /// displayed in the graph.
    +  static bool isNodeHidden(CallGraphNode *Node){
    +    if (Function *Func = Node->getFunction())
    +      return Func->isIntrinsic() || Func->getName().startswith("__");
    +    else
    +         return true;
    +  }
     };
    
     struct AnalysisCallGraphWrapperPassTraits {
    

    개선된 결과



    최종 명령 (배치 파일)

    @setlocal
    @set LLVM=D:\tmp\llvm-6.0.1.build\RelWithDebInfo
    @set PATH=%LLVM%\bin;%PATH%
    @set DOT=C:\usr\graphviz\bin\dot
    @set CXXFILT="C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.15.26726\bin\HostX64\x64\undname.exe"
    @set PS=powershell.exe
    
    @clang -cc1 -S -emit-llvm -D_DEBUG -D_MT -D_DLL -fcxx-exceptions -fexceptions -fms-volatile -v -D WIN32 -D _DEBUG -D _CONSOLE -D LLVM=C:/usr/LLVM -D _UNICODE -D UNICODE -internal-isystem "C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community\\VC\\Tools\\MSVC\\14.15.26726\\include" -internal-isystem "C:\\Program Files (x86)\\Windows Kits\\10\\Include\\10.0.17134.0\\ucrt" -internal-isystem "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.17134.0\\shared" -internal-isystem "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.17134.0\\um" -internal-isystem "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.17134.0\\winrt" -O0 -Wno-error -fms-extensions -fms-compatibility -fms-compatibility-version=19.15.26726 -std=c++2a -fdelayed-template-parsing -fdiagnostics-show-option -fcolor-diagnostics -isystemC:/usr/llvm/include -o - -x c++ main.cpp | opt -dot-callgraph
    
    @REM デマングル前に、エスケープされている"\<"を"<"に置換する
    @%PS% -Command "Get-Content callgraph.dot | %% { $_ -replace \"\\^<\",\"^<\" -replace \"\\^>\",\"^>\" } " > callgraph1.dot 
    @REM { $_ -replace "<","\<" -replace ">","\>"  -replace "-\\>","->" } 
    %CXXFILT% callgraph1.dot | %PS% -Command "$input | %% { $_ -replace \"\\^<\",\"^<\" -replace \"\\^>\",\"^>\" -replace \"^<\",\"\^<\" -replace \"^>\",\"\^>\" -replace \"-\\^>\",\"-^>\" } " > callgraph_demangled.dot
    
    @%DOT% -x -Tsvg -ocallgraph.svg callgraph_demangled.dot
    @endlocal
    

    남은 과제

  • opt 에서 방해를 풀 수 있습니다.LLVM 함수만 부르면 될 것 같아.)
  • 람다 함수는 해산할 수 없다.
  • STL 내의 함수를 생략할 수 있습니다.
  • 파워셸을 잘 사용하지 못한다.
  • 좋은 웹페이지 즐겨찾기