Parser::DeclGroupPtrTy ADecl; ExternalASTSource *External = S.getASTContext().getExternalSource(); if (External) External->StartTranslationUnit(Consumer);
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)); ...
voidCodeGenModule::EmitTopLevelDecl(Decl *D){ ... switch (D->getKind()) { case Decl::CXXConversion: case Decl::CXXMethod: case Decl::Function: // Skip function templates if (cast<FunctionDecl>(D)->getDescribedFunctionTemplate() || cast<FunctionDecl>(D)->isLateTemplateParsed()) return;
EmitGlobal(cast<FunctionDecl>(D)); // Always provide some coverage mapping // even for the functions that aren't emitted. AddDeferredUnusedCoverageMapping(D); break; ...
我们主要关注函数名生成所以看FunctionDecl的处理了。
在EmitTopLevelDecl中直接空降到函数体的处理
1 2 3 4 5 6 7 8
// Defer code generation to first use when possible, e.g. if this is an inline // function. If the global must always be emitted, do it eagerly if possible // to benefit from cache locality. if (MustBeEmitted(Global) && MayBeEmittedEagerly(Global)) { // Emit the definition if it can't be deferred. EmitGlobalDefinition(GD); return; }
if (constauto *Method = dyn_cast<CXXMethodDecl>(D)) { // Make sure to emit the definition(s) before we emit the thunks. // This is necessary for the generation of certain thunks. if (constauto *CD = dyn_cast<CXXConstructorDecl>(Method)) ABI->emitCXXStructor(CD, getFromCtorType(GD.getCtorType())); elseif (constauto *DD = dyn_cast<CXXDestructorDecl>(Method)) ABI->emitCXXStructor(DD, getFromDtorType(GD.getDtorType())); else EmitGlobalFunctionDefinition(GD, GV);
if (Method->isVirtual()) getVTables().EmitThunks(GD);
llvm::Constant *CodeGenModule::GetAddrOfFunction(GlobalDecl GD, llvm::Type *Ty, bool ForVTable, bool DontDefer, ForDefinition_t IsForDefinition){ // If there was no specific requested type, just convert it now. if (!Ty) { constauto *FD = cast<FunctionDecl>(GD.getDecl()); auto CanonTy = Context.getCanonicalType(FD->getType()); Ty = getTypes().ConvertFunctionType(CanonTy, FD); }