2017-10-31 3 views
2

방문자 패턴을 구현하는 LLVM InstVisitor.h 파일을보고 있습니다. 그들의 구현은 Visitor Pattern에서 본 것과는 아주 다릅니다. 문서에서LLVM InstVisitor - 가상 기능 없음?

나는이 발견

이는 '하위 클래스'템플릿 매개 변수에 대한 귀하의 새로운 유형을 지정,이 클래스에서 상속, 그리고에서 "재정의"visitXXX 기능을 자신의 방문자를 정의하는 방법을 당신의 수업. 이 클래스는 가상 함수가 아니라 정적으로 오버로드되는 오버플로 관점에서 으로 정의되었으므로 "오버 라이드"라고 말합니다.

...이 클래스는 특별히 가상 함수 호출 오버 헤드를 피하기 위해 주형으로 설계되어

참고. InstVisitor를 정의하고 사용하는 것은 지침 opcode를 통해 자신의 switch 문을 사용하는 것만 큼 효율적일뿐 입니다.

this answer는 LLVM이 구현 방문자 패턴을 사용 말한다 때문에 내가 해달라고 부탁하지만 내가 본 다른 구현과 너무 다른 이유를 알아낼 수 없습니다.

방문자 패턴이 파일에서 정확히 어떻게 사용됩니까?

+0

에주의를 패턴이 지정이나 다형성이 달성 방법에 대해 신경 쓰지 않는다는 사실에 :

사용의 예는 문서가 설명 그대로입니다. 그것은 일반적으로 런타임 다형성 및 동적 디스패치로 배웁니다. 그러나 이것은 컴파일 타임의 다형성과 오리 - 타이핑과 똑같이 달성 될 수 있습니다. – StoryTeller

+0

@StoryTeller 설명해 주셔서 감사합니다. 그러나 이해할 수없는 것은 비 가상 함수를 어떻게 "오버라이드"하고 패턴의 의도 된 결과를 얻는 지에 대한 것입니다. – Everyone

답변

2

llvm::InstVisitor은 방문 멤버 함수의 정적 디스패치를 ​​수행하는 데 사용되는 C++ 관용구 인 CRTP (Curiously Recurring Template Pattern)를 사용합니다.

이렇게하면 올바른 visitXXX 호출이 정적 인 (컴파일 타임에) 해결되어 동적 가상 호출 해결의 추가 비용을 피할 수 있습니다. 당신이 한 번 방문 기능에 대한 정확한 함수 서명과 일치하지 않을 경우, 그것은을 호출합니다 :

// The compiler will choose the Derived implementation of visitXXX 
// if exists, but will fallback to the Base implementation as Derived 
// inherits from Base. All done at compile time. 
void Base::do_visit() { 
    return static_cast<Derived *>(this)->visitXXX(); 
} 

메커니즘과 같은 "재정의"가 아님을 유의하십시오

이 이런 식으로 뭔가를 호출하여 작동 기본 클래스 구현이 아니라 자신의 기본 구현.

struct CountAllocaVisitor : public InstVisitor<CountAllocaVisitor> { 
    unsigned Count; 
    CountAllocaVisitor() : Count(0) {} 
    void visitAllocaInst(AllocaInst &AI) { ++Count; } 
}; 

// And this class would be used like this: 
CountAllocaVisitor CAV; 
CAV.visit(function); 
NumAllocas = CAV.Count;