Ich verwende Clang als Bibliothek einige Templat-Code zu kompilieren:Wie werden Template-Instanziierungen von Clang kompiliert?
template<typename T>
T getSevenTemplated() {
return 7;
}
int getSeven() {
return getSevenTemplated<int>();
}
Leider ist die kompilierte LLVM IR enthält nicht tatsächlich die Umsetzung von getSevenTemplated<int>
:
; ModuleID = './test.cpp'
source_filename = "./test.cpp"
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx10.12.0"
; Function Attrs: ssp uwtable
define i32 @_Z8getSevenv() #0 {
entry:
%call = call i32 @_Z17getSevenTemplatedIiET_v()
ret i32 %call
}
declare i32 @_Z17getSevenTemplatedIiET_v() #1
attributes #0 = { ssp uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="penryn" "target-features"="+cx16,+fxsr,+mmx,+sse,+sse2,+sse3,+sse4.1,+ssse3,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="penryn" "target-features"="+cx16,+fxsr,+mmx,+sse,+sse2,+sse3,+sse4.1,+ssse3,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
!llvm.module.flags = !{!0}
!llvm.ident = !{!1}
!0 = !{i32 1, !"PIC Level", i32 2}
!1 = !{!"clang version 5.0.0 (trunk 292778)"}
Hier ist der Code Ich benutze, um das LLVM Modul zu erzeugen:
auto* context = new llvm::LLVMContext(); // TODO: Fix leak
auto codeGenerator =
std::shared_ptr<clang::CodeGenerator>(
clang::CreateLLVMCodeGen(
compilerInstance.getDiagnostics(),
filePath,
compilerInstance.getHeaderSearchOpts(),
preprocessor.getPreprocessorOpts(),
compilerInstance.getCodeGenOpts(),
*context,
nullptr));
codeGenerator->Initialize(compilerInstance.getASTContext());
// declGroups are found by calling ParseAST with a special ASTConsumer earlier
for (auto declGroup : declGroups) {
codeGenerator->HandleTopLevelDecl(declGroup);
}
codeGenerator->HandleTranslationUnit(compilerInstance.getASTContext());
T o untersuchen, warum, ich sah durch the source-code und ich fand, dass die CodeGenerator
spezifische Logik für die Handhabung von Vorlagen hat: Es scheint zu überspringen, Funktion Vorlage Instanziierungen! Ich nehme an, dass es stattdessen die generierten Funktionen behandelt, aber ich weiß nicht, wie es wirklich funktioniert.
Meine Fragen sind:
- Auf einem hohen Niveau, wie funktioniert Clang gehen zu Vorlagen instanziieren und sie an den
ASTConsumer
für die Codegenerierung vorbei? - Gibt es spezielle Tricks, um die Erstellung von Funktionskörpern für instanziierte Vorlagen zu ermöglichen? Was fehlt mir im obigen Code?
Sie scheinen zu versuchen, eine Funktion zu instanziieren und es zugleich nennen. Versuchen Sie, die Zahl 7 oder die Funktion zurückzugeben, die int zurückgibt? – stark
@stark Ich möchte die LLVM IR für das obige Programm generieren – sdgfsdh