Add support for restricting the function search to const functions.
Add an optional argument objectIsConst to findFunctionArgs and findFunctionProto: const clang::FunctionDecl* findFunctionProto(const clang::Decl* scopeDecl, llvm::StringRef funcName, llvm::StringRef funcProto, bool objectIsConst) const; const clang::FunctionDecl* findFunctionArgs(const clang::Decl* scopeDecl, llvm::StringRef funcName, llvm::StringRef funcArgs, bool objectIsConst) const;
This commit is contained in:
parent
bc5c795693
commit
31b60e0ab5
@ -81,14 +81,20 @@ namespace cling {
|
||||
///\param[in] funcName - the name of the function to find.
|
||||
///\param[in] funcProto - the function parameter list (without enclosing
|
||||
/// parantheses). Example: "size_t,int".
|
||||
///\param[in,optional] objectIsConst - if true search fo function that can
|
||||
/// be called on a const object ; default to false.
|
||||
///\returns The function found or null.
|
||||
const clang::FunctionDecl* findFunctionProto(const clang::Decl* scopeDecl,
|
||||
llvm::StringRef funcName,
|
||||
llvm::StringRef funcProto) const;
|
||||
llvm::StringRef funcProto,
|
||||
bool objectIsConst = false
|
||||
) const;
|
||||
|
||||
const clang::FunctionDecl* findFunctionArgs(const clang::Decl* scopeDecl,
|
||||
llvm::StringRef funcName,
|
||||
llvm::StringRef funcArgs) const;
|
||||
llvm::StringRef funcArgs,
|
||||
bool objectIsConst = false) const;
|
||||
|
||||
|
||||
///\brief Lookup given argument list and return each argument as an
|
||||
/// expression.
|
||||
|
@ -400,6 +400,7 @@ namespace cling {
|
||||
|
||||
static
|
||||
const FunctionDecl* overloadFunctionSelector(DeclContext* foundDC,
|
||||
bool objectIsConst,
|
||||
const llvm::SmallVector<Expr*, 4> &GivenArgs,
|
||||
LookupResult &Result,
|
||||
DeclarationNameInfo &FuncNameInfo,
|
||||
@ -420,7 +421,9 @@ namespace cling {
|
||||
Expr* ObjExpr = 0;
|
||||
Expr::Classification ObjExprClassification;
|
||||
if (CXXRecordDecl* CRD = dyn_cast<CXXRecordDecl>(foundDC)) {
|
||||
ClassType = Context.getTypeDeclType(CRD).getCanonicalType();
|
||||
if (objectIsConst)
|
||||
ClassType = Context.getTypeDeclType(CRD).getCanonicalType().withConst();
|
||||
else ClassType = Context.getTypeDeclType(CRD).getCanonicalType();
|
||||
OpaqueValueExpr ObjExpr(SourceLocation(),
|
||||
ClassType, VK_LValue);
|
||||
ObjExprClassification = ObjExpr.Classify(Context);
|
||||
@ -514,8 +517,10 @@ namespace cling {
|
||||
T findFunction(DeclContext* foundDC, CXXScopeSpec &SS,
|
||||
llvm::StringRef funcName,
|
||||
const llvm::SmallVector<Expr*, 4> &GivenArgs,
|
||||
bool objectIsConst,
|
||||
ASTContext& Context, Parser &P, Sema &S,
|
||||
T (*functionSelector)(DeclContext* foundDC,
|
||||
bool objectIsConst,
|
||||
const llvm::SmallVector<Expr*, 4> &GivenArgs,
|
||||
LookupResult &Result,
|
||||
DeclarationNameInfo &FuncNameInfo,
|
||||
@ -625,7 +630,7 @@ namespace cling {
|
||||
// Lookup failed.
|
||||
return TheDecl;
|
||||
}
|
||||
return functionSelector(foundDC,GivenArgs,
|
||||
return functionSelector(foundDC,objectIsConst,GivenArgs,
|
||||
Result,
|
||||
FuncNameInfo,
|
||||
FuncTemplateArgs,
|
||||
@ -633,8 +638,8 @@ namespace cling {
|
||||
}
|
||||
|
||||
static
|
||||
bool findFunctionParseProto(llvm::SmallVector<Expr*, 4> &GivenArgs,
|
||||
ASTContext& Context, Parser &P,Sema &S) {
|
||||
bool ParseProto(llvm::SmallVector<Expr*, 4> &GivenArgs,
|
||||
ASTContext& Context, Parser &P,Sema &S) {
|
||||
//
|
||||
// Parse the prototype now.
|
||||
//
|
||||
@ -686,7 +691,9 @@ namespace cling {
|
||||
|
||||
const FunctionDecl* LookupHelper::findFunctionProto(const Decl* scopeDecl,
|
||||
llvm::StringRef funcName,
|
||||
llvm::StringRef funcProto) const {
|
||||
llvm::StringRef funcProto,
|
||||
bool objectIsConst
|
||||
) const {
|
||||
assert(scopeDecl && "Decl cannot be null");
|
||||
//
|
||||
// Some utilities.
|
||||
@ -714,19 +721,19 @@ namespace cling {
|
||||
prepareForParsing(funcProto, llvm::StringRef("func.prototype.file"));
|
||||
|
||||
llvm::SmallVector<Expr*, 4> GivenArgs;
|
||||
if (!findFunctionParseProto(GivenArgs,Context,P,S) ) {
|
||||
if (!ParseProto(GivenArgs,Context,P,S) ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return findFunction(foundDC, SS,
|
||||
funcName, GivenArgs,
|
||||
funcName, GivenArgs, objectIsConst,
|
||||
Context, P, S,
|
||||
overloadFunctionSelector);
|
||||
}
|
||||
|
||||
static
|
||||
bool findFunctionParseArgs(llvm::SmallVector<Expr*, 4> &GivenArgs,
|
||||
ASTContext& Context, Parser &P, Sema &S) {
|
||||
bool ParseArgs(llvm::SmallVector<Expr*, 4> &GivenArgs,
|
||||
ASTContext& Context, Parser &P, Sema &S) {
|
||||
|
||||
//
|
||||
// Parse the arguments now.
|
||||
@ -784,8 +791,10 @@ namespace cling {
|
||||
}
|
||||
|
||||
const FunctionDecl* LookupHelper::findFunctionArgs(const Decl* scopeDecl,
|
||||
llvm::StringRef funcName,
|
||||
llvm::StringRef funcArgs) const {
|
||||
llvm::StringRef funcName,
|
||||
llvm::StringRef funcArgs,
|
||||
bool objectIsConst
|
||||
) const {
|
||||
assert(scopeDecl && "Decl cannot be null");
|
||||
//
|
||||
// Some utilities.
|
||||
@ -813,12 +822,12 @@ namespace cling {
|
||||
prepareForParsing(funcArgs, llvm::StringRef("func.args.file"));
|
||||
|
||||
llvm::SmallVector<Expr*, 4> GivenArgs;
|
||||
if (!findFunctionParseArgs(GivenArgs,Context,P,S) ) {
|
||||
if (!ParseArgs(GivenArgs,Context,P,S) ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return findFunction(foundDC, SS,
|
||||
funcName, GivenArgs,
|
||||
funcName, GivenArgs, objectIsConst,
|
||||
Context, P, S, overloadFunctionSelector);
|
||||
}
|
||||
|
||||
@ -897,6 +906,7 @@ namespace cling {
|
||||
|
||||
static
|
||||
bool hasFunctionSelector(DeclContext* ,
|
||||
bool /* objectIsConst */,
|
||||
const llvm::SmallVector<Expr*, 4> &,
|
||||
LookupResult &Result,
|
||||
DeclarationNameInfo &,
|
||||
@ -945,7 +955,7 @@ namespace cling {
|
||||
llvm::SmallVector<Expr*, 4> GivenArgs;
|
||||
|
||||
return findFunction(foundDC, SS,
|
||||
funcName, GivenArgs,
|
||||
funcName, GivenArgs, false /* objectIsConst */,
|
||||
Context, P, S, hasFunctionSelector);
|
||||
}
|
||||
|
||||
|
@ -85,6 +85,9 @@ public:
|
||||
void B_j(int vi, double vd) { int x = vi; double y = vd; }
|
||||
template <class T> void B_k(T v) { T x = v; }
|
||||
void B_m(const int& v) { int y = v; }
|
||||
const long &B_n() const { return m_B_i; }
|
||||
long &B_n() { return m_B_i; }
|
||||
const long &B_o() const { return m_B_i; }
|
||||
void* operator new(std::size_t sz) { return ::operator new(sz); }
|
||||
void* operator new(std::size_t sz, void* arena) { return arena; }
|
||||
void* operator new[](std::size_t sz) { return ::operator new[](sz); }
|
||||
@ -844,8 +847,6 @@ func_B_k2_proto->print(llvm::errs());
|
||||
//CHECK-NEXT: double x = v;
|
||||
//CHECK-NEXT: }
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Test finding a member function taking a const int reference arg in a base class.
|
||||
//
|
||||
@ -868,6 +869,55 @@ func_B_m_proto->print(llvm::errs());
|
||||
//CHECK-NEXT: }
|
||||
|
||||
|
||||
//
|
||||
// Test finding a member function that const or not
|
||||
//
|
||||
|
||||
const clang::FunctionDecl* func_B_n_args = lookup.findFunctionArgs(class_A, "B_n", "", false);
|
||||
const clang::FunctionDecl* func_B_n_proto = lookup.findFunctionProto(class_A, "B_n", "", false);
|
||||
|
||||
printf("func_B_n_args: 0x%lx\n", (unsigned long) func_B_n_args);
|
||||
//CHECK: func_B_n_args: 0x{{[1-9a-f][0-9a-f]*$}}
|
||||
func_B_n_args->print(llvm::errs());
|
||||
//CHECK-NEXT: long &B_n() {
|
||||
//CHECK-NEXT: return this->m_B_i;
|
||||
//CHECK-NEXT: }
|
||||
|
||||
printf("func_B_n_proto: 0x%lx\n", (unsigned long) func_B_n_proto);
|
||||
//CHECK: func_B_n_proto: 0x{{[1-9a-f][0-9a-f]*$}}
|
||||
func_B_n_proto->print(llvm::errs());
|
||||
//CHECK-NEXT: long &B_n() {
|
||||
//CHECK-NEXT: return this->m_B_i;
|
||||
//CHECK-NEXT: }
|
||||
|
||||
const clang::FunctionDecl* func_const_B_n_args = lookup.findFunctionArgs(class_A, "B_n", "", true);
|
||||
const clang::FunctionDecl* func_const_B_n_proto = lookup.findFunctionProto(class_A, "B_n", "", true);
|
||||
printf("func_const_B_n_args: 0x%lx\n", (unsigned long) func_const_B_n_args);
|
||||
//CHECK: func_const_B_n_args: 0x{{[1-9a-f][0-9a-f]*$}}
|
||||
func_const_B_n_args->print(llvm::errs());
|
||||
//CHECK-NEXT: const long &B_n() const {
|
||||
//CHECK-NEXT: return this->m_B_i;
|
||||
//CHECK-NEXT: }
|
||||
|
||||
printf("func_const_B_n_proto: 0x%lx\n", (unsigned long) func_const_B_n_proto);
|
||||
//CHECK: func_const_B_n_proto: 0x{{[1-9a-f][0-9a-f]*$}}
|
||||
func_const_B_n_proto->print(llvm::errs());
|
||||
//CHECK-NEXT: const long &B_n() const {
|
||||
//CHECK-NEXT: return this->m_B_i;
|
||||
//CHECK-NEXT: }
|
||||
|
||||
const clang::FunctionDecl* func_const_B_m_proto = lookup.findFunctionArgs(class_A, "B_m", "const int&", true);
|
||||
const clang::FunctionDecl* func_const_B_o_proto = lookup.findFunctionProto(class_A, "B_o", "", true);
|
||||
printf("func_const_B_m_proto: 0x%lx\n", (unsigned long) func_const_B_m_proto);
|
||||
//CHECK: func_const_B_m_proto: 0x0
|
||||
|
||||
printf("func_const_B_o_proto: 0x%lx\n", (unsigned long) func_const_B_o_proto);
|
||||
//CHECK: func_const_B_o_proto: 0x{{[1-9a-f][0-9a-f]*$}}
|
||||
func_const_B_o_proto->print(llvm::errs());
|
||||
//CHECK-NEXT: const long &B_o() const {
|
||||
//CHECK-NEXT: return this->m_B_i;
|
||||
//CHECK-NEXT: }
|
||||
|
||||
|
||||
//
|
||||
// Test finding constructors.
|
||||
|
Loading…
x
Reference in New Issue
Block a user