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()