calltree

Text Only
/home/ken/workspace/OpenCL_Compiler/build/bin/clang-9(+0x3383d6)[0x55f4df8983d6]  Lexer::lex()
/home/ken/workspace/OpenCL_Compiler/build/bin/clang-9(clang::Preprocessor::Lex(clang::Token&)+0x34)[0x55f4e0111072]  
/home/ken/workspace/OpenCL_Compiler/build/bin/clang-9(+0x83e70f)[0x55f4dfd9e70f]  ConsumeToken()
/home/ken/workspace/OpenCL_Compiler/build/bin/clang-9(clang::ParseAST(clang::Sema&, bool, bool)+0x1cd)[0x55f4dfd9de75]
/home/ken/workspace/OpenCL_Compiler/build/bin/clang-9(clang::FrontendAction::Execute()+0x5b)[0x55f4dfbd79cf]
/home/ken/workspace/OpenCL_Compiler/build/bin/clang-9(clang::CompilerInstance::ExecuteAction(clang::FrontendAction&)+0x281)[0x55f4dfbcba3f]
/home/ken/workspace/OpenCL_Compiler/build/bin/clang-9(clang::ExecuteCompilerInvocation(clang::CompilerInstance*)+0x2bc)[0x55f4dfc30f47]
/home/ken/workspace/OpenCL_Compiler/build/bin/clang-9(cc1_main(llvm::ArrayRef<char const*>, char const*, void*)+0x737)[0x55f4df8a7f39]
/home/ken/workspace/OpenCL_Compiler/build/bin/clang-9(main+0x575)[0x55f4df898953]
/lib/x86_64-linux-gnu/libc.so.6(+0x29d90)[0x7ff114029d90]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0x80)[0x7ff114029e40]
/home/ken/workspace/OpenCL_Compiler/build/bin/clang-9(_start+0x25)[0x55f4df8a6335]
clang-9: error: unable to execute command: Aborted (core dumped)
C++
void clang::ParseAST(Sema &S, bool PrintStats, bool SkipFunctionBodies) {
 ...
  if (HaveLexer) {
    llvm::TimeTraceScope TimeScope("Frontend", StringRef(""));
    P.Initialize();   // 词法分析和预处理

    Parser::DeclGroupPtrTy ADecl;

    for (bool AtEOF = P.ParseFirstTopLevelDecl(ADecl); !AtEOF;
         AtEOF = P.ParseTopLevelDecl(ADecl)) { // 语义分析
      // If we got a null return and something *was* parsed, ignore it.  This
      // is due to a top-level semicolon, an action override, or a parse error
      // skipping something.
      if (ADecl && !Consumer->HandleTopLevelDecl(ADecl.get()))
        return;
    }
  }

  // Process any TopLevelDecls generated by #pragma weak.
  for (Decl *D : S.WeakTopLevelDecls())
    Consumer->HandleTopLevelDecl(DeclGroupRef(D));

  Consumer->HandleTranslationUnit(S.getASTContext());
...
}

预处理

Text Only
ASTFrontendAction::Execute()-> ParseAST() -> Parser::Initialize() -> Parser::ConsumeToken() -> Preprocessor::Lex() -> Lexer::lex() -> Lexer::LexTokenInternal() 根据token种类进入不同分支 -> HandleDirective() 对#关键字符的处理-> HandleDefineDirective() 处理tok::pp_define

语法分析

Text Only
ASTFrontendAction::Execute() -> ParseAST() -> 循环调用ParseFirstTopLevelDecl() -> ParseTopLevelDecl() -> Parse*系列解析函数

语义分析

Text Only
Parse::ParseTopLevelDecl() ->
Parse::ParseExternalDeclaration() ->
Parser::ParseDeclarationOrFunctionDefinition() ->
Parse::ParseDeclOrFunctionDefInternal() ->
Parser::ParseDeclGroup() ->
Parser::ParseFunctionDefinition()
Sema::ActOnStartOfFunctionDef()
Text Only
CodeGenAction::ExecuteAction() -> clang::EmitBackendOutput() -> EmitAssemblyHelper::EmitAssembly()
C++
void EmitAssemblyHelper::EmitAssembly(BackendAction Action,
                                      std::unique_ptr<raw_pwrite_stream> OS) {

  switch (Action) {
  case Backend_EmitNothing:
    break;

  case Backend_EmitBC:
...
      PerModulePasses.add(createWriteThinLTOBitcodePass(
          *OS, ThinLinkOS ? &ThinLinkOS->os() : nullptr));
  case Backend_EmitLL:
    PerModulePasses.add(
        createPrintModulePass(*OS, "", CodeGenOpts.EmitLLVMUseLists));
    break;

  default:
    if (!CodeGenOpts.SplitDwarfOutput.empty()) {
      DwoOS = openOutputFile(CodeGenOpts.SplitDwarfOutput);
      if (!DwoOS)
        return;
    }
    if (!AddEmitPasses(CodeGenPasses, Action, *OS,
                       DwoOS ? &DwoOS->os() : nullptr))
      return;
  }
    ...
}
Text Only
HandleTopLevelDecl
EmitTopLevelDecl



bool HandleTopLevelDecl(DeclGroupRef D) override {
      PrettyStackTraceDecl CrashInfo(*D.begin(), SourceLocation(),
                                     Context->getSourceManager(),
                                     "LLVM IR generation of declaration");

      // Recurse.
      if (FrontendTimesIsEnabled) {
        LLVMIRGenerationRefCount += 1;
        if (LLVMIRGenerationRefCount == 1)
          LLVMIRGeneration.startTimer();
      }

      Gen->HandleTopLevelDecl(D);

      if (FrontendTimesIsEnabled) {
        LLVMIRGenerationRefCount -= 1;
        if (LLVMIRGenerationRefCount == 0)
          LLVMIRGeneration.stopTimer(); 
      }

      return true;
    }

CodeGenAction中有成员变量BackendConsumer *BEConsumer,

CodeGenAction::CreateASTConsumer中构造BackendConsumer,

BackendConsumer构造函数中调用Gen(CreateLLVMCodeGen(Diags, InFile, HeaderSearchOpts, PPOpts,

​ CodeGenOpts, C, CoverageInfo)), 给Gen赋值。

Text Only
clang::ParseAST()
BackendConsumer::HandleTopLevelDecl() ->
CodeGenerator::HandleTopLevelDecl()
CodeGenModule::EmitTopLevelDecl()
CodeGenModule::EmitDeclContext()
遍历调用CodeGenModule::EmitTopLevelDecl根据不同的Decl::调用不同的Emit方法
EmitGlobal()处理函数,方法,转换等
GetOrCreateLLVMFunction()对于函数
llvm::Function::Creat()