Add matchFunctionProto returning the decl only in case of exact match.
The new call is: const clang::FunctionDecl* matchFunctionProto(const clang::Decl* scopeDecl, llvm::StringRef funcName, llvm::StringRef funcProto, bool objectIsConst ) const; and the function must match in name and prototype (including constness). The only thing not checked is the actual declaration context.
This commit is contained in:
parent
d53e192286
commit
39d8a3e8a6
@ -96,6 +96,24 @@ namespace cling {
|
||||
bool objectIsConst = false) const;
|
||||
|
||||
|
||||
///\brief Lookup a function based on its Decl(Context), name and parameters.
|
||||
/// where the result if any must have exactly the arguments requested.
|
||||
///
|
||||
///\param[in] scopeDecl - the scope (namespace or tag) that is searched for
|
||||
/// the function.
|
||||
///\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] 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* matchFunctionProto(const clang::Decl* scopeDecl,
|
||||
llvm::StringRef funcName,
|
||||
llvm::StringRef funcProto,
|
||||
bool objectIsConst
|
||||
) const;
|
||||
|
||||
|
||||
///\brief Lookup given argument list and return each argument as an
|
||||
/// expression.
|
||||
///
|
||||
|
@ -416,7 +416,8 @@ namespace cling {
|
||||
static bool IsOverload(const ASTContext& C,
|
||||
const TemplateArgumentListInfo* FuncTemplateArgs,
|
||||
const llvm::SmallVector<QualType, 4>& GivenArgTypes,
|
||||
FunctionDecl* FD, bool UseUsingDeclRules) {
|
||||
const FunctionDecl* FD) {
|
||||
|
||||
//FunctionTemplateDecl* FTD = FD->getDescribedFunctionTemplate();
|
||||
QualType FQT = C.getCanonicalType(FD->getType());
|
||||
if (llvm::isa<FunctionNoProtoType>(FQT.getTypePtr())) {
|
||||
@ -547,6 +548,49 @@ namespace cling {
|
||||
return TheDecl;
|
||||
}
|
||||
|
||||
static
|
||||
const FunctionDecl* matchFunctionSelector(DeclContext* foundDC,
|
||||
bool objectIsConst,
|
||||
const llvm::SmallVector<Expr*, 4> &GivenArgs,
|
||||
LookupResult &Result,
|
||||
DeclarationNameInfo &FuncNameInfo,
|
||||
const TemplateArgumentListInfo* FuncTemplateArgs,
|
||||
ASTContext& Context, Parser &P, Sema &S) {
|
||||
//
|
||||
// Our return value.
|
||||
//
|
||||
const FunctionDecl* TheDecl = overloadFunctionSelector(foundDC, objectIsConst,
|
||||
GivenArgs, Result,
|
||||
FuncNameInfo,
|
||||
FuncTemplateArgs,
|
||||
Context,P,S);
|
||||
|
||||
if (TheDecl) {
|
||||
llvm::SmallVector<QualType, 4> GivenArgTypes;
|
||||
for( size_t s = 0 ; s < GivenArgs.size(); ++s) {
|
||||
GivenArgTypes.push_back( GivenArgs[s]->getType().getCanonicalType() );
|
||||
}
|
||||
if ( IsOverload( Context, FuncTemplateArgs, GivenArgTypes, TheDecl) ) {
|
||||
return 0;
|
||||
} else {
|
||||
// Double check const-ness.
|
||||
if (const clang::CXXMethodDecl *md =
|
||||
llvm::dyn_cast<clang::CXXMethodDecl>(TheDecl)) {
|
||||
if (md->getTypeQualifiers() & clang::Qualifiers::Const) {
|
||||
if (!objectIsConst) {
|
||||
TheDecl = 0;
|
||||
}
|
||||
} else {
|
||||
if (objectIsConst) {
|
||||
TheDecl = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return TheDecl;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T findFunction(DeclContext* foundDC, CXXScopeSpec &SS,
|
||||
llvm::StringRef funcName,
|
||||
@ -765,6 +809,49 @@ namespace cling {
|
||||
overloadFunctionSelector);
|
||||
}
|
||||
|
||||
const FunctionDecl* LookupHelper::matchFunctionProto(const Decl* scopeDecl,
|
||||
llvm::StringRef funcName,
|
||||
llvm::StringRef funcProto,
|
||||
bool objectIsConst
|
||||
) const {
|
||||
assert(scopeDecl && "Decl cannot be null");
|
||||
//
|
||||
// Some utilities.
|
||||
//
|
||||
// Use P for shortness
|
||||
Parser& P = *m_Parser;
|
||||
Sema& S = P.getActions();
|
||||
ASTContext& Context = S.getASTContext();
|
||||
|
||||
//
|
||||
// Convert the passed decl into a nested name specifier,
|
||||
// a scope spec, and a decl context.
|
||||
//
|
||||
// Do this 'early' to save on the expansive parser setup,
|
||||
// in case of failure.
|
||||
//
|
||||
CXXScopeSpec SS;
|
||||
DeclContext* foundDC = getContextAndSpec(SS,scopeDecl,Context,S);
|
||||
if (!foundDC) return 0;
|
||||
|
||||
//
|
||||
// Parse the prototype now.
|
||||
//
|
||||
ParserStateRAII ResetParserState(P);
|
||||
prepareForParsing(funcProto, llvm::StringRef("func.prototype.file"));
|
||||
|
||||
llvm::SmallVector<Expr*, 4> GivenArgs;
|
||||
if (!ParseProto(GivenArgs,Context,P,S) ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Interpreter::PushTransactionRAII pushedT(m_Interpreter);
|
||||
return findFunction(foundDC, SS,
|
||||
funcName, GivenArgs, objectIsConst,
|
||||
Context, P, S,
|
||||
matchFunctionSelector);
|
||||
}
|
||||
|
||||
static
|
||||
bool ParseArgs(llvm::SmallVector<Expr*, 4> &GivenArgs,
|
||||
ASTContext& Context, Parser &P, Sema &S) {
|
||||
|
@ -88,6 +88,8 @@ public:
|
||||
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; }
|
||||
long B_p(float) const { return 0; }
|
||||
int B_p(int) { return 0; }
|
||||
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); }
|
||||
@ -906,7 +908,7 @@ func_const_B_n_proto->print(llvm::errs());
|
||||
//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_m_proto = lookup.findFunctionProto(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
|
||||
@ -915,9 +917,53 @@ 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: return this->m_B_i;
|
||||
//CHECK-NEXT: }
|
||||
|
||||
// Test exact matches
|
||||
const clang::FunctionDecl* func_const_B_p_proto = lookup.findFunctionProto(class_A, "B_p", "double", true);
|
||||
printf("func_const_B_p_proto 1: 0x%lx\n", (unsigned long) func_const_B_p_proto);
|
||||
//CHECK: func_const_B_p_proto 1: 0x{{[1-9a-f][0-9a-f]*$}}
|
||||
func_const_B_p_proto->print(llvm::errs());
|
||||
//CHECK-NEXT: long B_p(float) const {
|
||||
//CHECK-NEXT: return 0;
|
||||
//CHECK-NEXT: }
|
||||
|
||||
func_const_B_p_proto = lookup.matchFunctionProto(class_A, "B_p", "double", true);
|
||||
printf("func_const_B_p_proto 2: 0x%lx\n", (unsigned long) func_const_B_p_proto);
|
||||
//CHECK: func_const_B_p_proto 2: 0x0
|
||||
|
||||
func_const_B_p_proto = lookup.matchFunctionProto(class_A, "B_p", "float", true);
|
||||
printf("func_const_B_p_proto 3: 0x%lx\n", (unsigned long) func_const_B_p_proto);
|
||||
//CHECK: func_const_B_p_proto 3: 0x{{[1-9a-f][0-9a-f]*$}}
|
||||
func_const_B_p_proto->print(llvm::errs());
|
||||
//CHECK-NEXT: long B_p(float) const {
|
||||
//CHECK-NEXT: return 0;
|
||||
//CHECK-NEXT: }
|
||||
|
||||
func_const_B_p_proto = lookup.matchFunctionProto(class_A, "B_p", "float", false);
|
||||
printf("func_const_B_p_proto 4: 0x%lx\n", (unsigned long) func_const_B_p_proto);
|
||||
//CHECK: func_const_B_p_proto 4: 0x0
|
||||
|
||||
func_const_B_p_proto = lookup.matchFunctionProto(class_A, "B_p", "int", false);
|
||||
printf("func_const_B_p_proto 5: 0x%lx\n", (unsigned long) func_const_B_p_proto);
|
||||
//CHECK: func_const_B_p_proto 5: 0x{{[1-9a-f][0-9a-f]*$}}
|
||||
func_const_B_p_proto->print(llvm::errs());
|
||||
//CHECK-NEXT: int B_p(int) {
|
||||
//CHECK-NEXT: return 0;
|
||||
//CHECK-NEXT: }
|
||||
|
||||
func_const_B_p_proto = lookup.matchFunctionProto(class_A, "B_p", "int", true);
|
||||
printf("func_const_B_p_proto 6: 0x%lx\n", (unsigned long) func_const_B_p_proto);
|
||||
//CHECK: func_const_B_p_proto 6: 0x0
|
||||
|
||||
func_const_B_p_proto = lookup.matchFunctionProto(class_A, "B_p", "short", false);
|
||||
printf("func_const_B_p_proto 6: 0x%lx\n", (unsigned long) func_const_B_p_proto);
|
||||
//CHECK: func_const_B_p_proto 6: 0x0
|
||||
|
||||
func_const_B_p_proto = lookup.matchFunctionProto(class_A, "B_p", "long", false);
|
||||
printf("func_const_B_p_proto 6: 0x%lx\n", (unsigned long) func_const_B_p_proto);
|
||||
//CHECK: func_const_B_p_proto 6: 0x0
|
||||
|
||||
//
|
||||
// Test finding constructors.
|
||||
|
Loading…
x
Reference in New Issue
Block a user