forked from vgvassilev/creduce
-
Notifications
You must be signed in to change notification settings - Fork 0
/
CommonTemplateArgumentVisitor.h
115 lines (95 loc) · 3.38 KB
/
CommonTemplateArgumentVisitor.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
//===----------------------------------------------------------------------===//
//
// Copyright (c) 2012, 2013, 2014 The University of Utah
// All rights reserved.
//
// This file is distributed under the University of Illinois Open Source
// License. See the file COPYING for details.
//
//===----------------------------------------------------------------------===//
#ifndef COMMON_TEMPLATE_ARGUMENT_VISITOR_H
#define COMMON_TEMPLATE_ARGUMENT_VISITOR_H
#include "clang/AST/RecursiveASTVisitor.h"
namespace clang_delta_common_visitor {
template<typename T, typename Trans>
class CommonTemplateArgumentVisitor : public clang::RecursiveASTVisitor<T> {
public:
explicit CommonTemplateArgumentVisitor(Trans *Instance)
: ConsumerInstance(Instance)
{ }
bool VisitClassTemplatePartialSpecializationDecl(
clang::ClassTemplatePartialSpecializationDecl *D);
bool VisitTemplateSpecializationTypeLoc(
clang::TemplateSpecializationTypeLoc TLoc);
bool VisitFunctionDecl(clang::FunctionDecl *D);
bool VisitDeclRefExpr(clang::DeclRefExpr *E);
protected:
Trans *ConsumerInstance;
};
template<typename T, typename Trans>
bool CommonTemplateArgumentVisitor<T, Trans>::
VisitTemplateSpecializationTypeLoc(
clang::TemplateSpecializationTypeLoc TLoc)
{
ConsumerInstance->handleTemplateSpecializationTypeLoc(TLoc);
return true;
}
template<typename T, typename Trans>
bool CommonTemplateArgumentVisitor<T, Trans>::
VisitClassTemplatePartialSpecializationDecl(
clang::ClassTemplatePartialSpecializationDecl *D)
{
ConsumerInstance->handleTemplateArgumentLocs(
D->getSpecializedTemplate(),
D->getTemplateArgsAsWritten()->getTemplateArgs(),
D->getTemplateArgsAsWritten()->NumTemplateArgs);
return true;
}
template<typename T, typename Trans>
bool CommonTemplateArgumentVisitor<T, Trans>::VisitFunctionDecl(
clang::FunctionDecl *D)
{
const clang::FunctionTemplateSpecializationInfo *FTSI =
D->getTemplateSpecializationInfo();
if (!FTSI)
return true;
if ((FTSI->getTemplateSpecializationKind() == clang::TSK_Undeclared) ||
(FTSI->getTemplateSpecializationKind() ==
clang::TSK_ImplicitInstantiation))
return true;
if (const clang::ASTTemplateArgumentListInfo *TALI =
FTSI->TemplateArgumentsAsWritten) {
ConsumerInstance->handleTemplateArgumentLocs(
D->getPrimaryTemplate(),
TALI->getTemplateArgs(),
TALI->NumTemplateArgs);
}
return true;
}
template<typename T, typename Trans>
bool CommonTemplateArgumentVisitor<T, Trans>::VisitDeclRefExpr(
clang::DeclRefExpr *E)
{
const clang::ValueDecl *VD = E->getDecl();
const clang::TemplateDecl *TempD = NULL;
if (const clang::FunctionDecl *FD =
clang::dyn_cast<clang::FunctionDecl>(VD)) {
TempD = FD->getDescribedFunctionTemplate();
}
else {
const clang::Type *Ty = VD->getType().getTypePtr();
if (Ty->isPointerType() || Ty->isReferenceType())
Ty = ConsumerInstance->getBasePointerElemType(Ty);
const clang::CXXRecordDecl *CXXRD = ConsumerInstance->getBaseDeclFromType(Ty);
if (!CXXRD)
return true;
TempD = CXXRD->getDescribedClassTemplate();
}
if (!TempD)
return true;
ConsumerInstance->handleTemplateArgumentLocs(TempD, E->getTemplateArgs(),
E->getNumTemplateArgs());
return true;
}
#endif
} // end namespace clang_delta_common_visitor