-
Notifications
You must be signed in to change notification settings - Fork 31
Enable template features #215
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
c565a2a
Add interfaces enabling template function logic
aaronj0 84fd0a6
Update interfaces to pass return by ref(out param)
aaronj0 5e8f4d5
Remove redundant interfaces
aaronj0 5ce073e
Check scope before casting to CXXRecordDecl
aaronj0 0f4e8ea
Update tests to use new GetClassMethods interface
aaronj0 488ef5f
Remove unused filter param
aaronj0 423b3e1
Refactoring, move common code to static function
aaronj0 22c1e0d
Update function documentation and tests
aaronj0 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -719,39 +719,46 @@ namespace Cpp { | |
return ComputeBaseOffset(getSema().getASTContext(), DCXXRD, Paths.front()); | ||
} | ||
|
||
// FIXME: We should make the std::vector<TCppFunction_t> an out parameter to | ||
// avoid copies. | ||
std::vector<TCppFunction_t> GetClassMethods(TCppScope_t klass) | ||
{ | ||
|
||
template <typename DeclType> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We do not need a template, we can take a DeclKind as a parameter. |
||
static void GetClassDecls(TCppScope_t klass, | ||
std::vector<TCppFunction_t>& methods) { | ||
if (!klass) | ||
return {}; | ||
return; | ||
|
||
auto *D = (clang::Decl *) klass; | ||
auto* D = (clang::Decl*)klass; | ||
aaronj0 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
if (auto *TD = dyn_cast<TypedefNameDecl>(D)) | ||
if (auto* TD = dyn_cast<TypedefNameDecl>(D)) | ||
D = GetScopeFromType(TD->getUnderlyingType()); | ||
|
||
std::vector<TCppFunction_t> methods; | ||
if (auto *CXXRD = dyn_cast_or_null<CXXRecordDecl>(D)) { | ||
getSema().ForceDeclarationOfImplicitMembers(CXXRD); | ||
for (Decl* DI : CXXRD->decls()) { | ||
if (auto* MD = dyn_cast<CXXMethodDecl>(DI)) | ||
if (!D || !isa<CXXRecordDecl>(D)) | ||
return; | ||
|
||
auto* CXXRD = dyn_cast<CXXRecordDecl>(D); | ||
getSema().ForceDeclarationOfImplicitMembers(CXXRD); | ||
for (Decl* DI : CXXRD->decls()) { | ||
if (auto* MD = dyn_cast<DeclType>(DI)) | ||
methods.push_back(MD); | ||
else if (auto* USD = dyn_cast<UsingShadowDecl>(DI)) | ||
if (auto* MD = dyn_cast<DeclType>(USD->getTargetDecl())) | ||
methods.push_back(MD); | ||
else if (auto* USD = dyn_cast<UsingShadowDecl>(DI)) | ||
if (auto* MD = dyn_cast<CXXMethodDecl>(USD->getTargetDecl())) | ||
methods.push_back(MD); | ||
} | ||
} | ||
return methods; | ||
} | ||
|
||
void GetClassMethods(TCppScope_t klass, | ||
std::vector<TCppFunction_t>& methods) { | ||
GetClassDecls<CXXMethodDecl>(klass, methods); | ||
} | ||
|
||
void GetFunctionTemplatedDecls(TCppScope_t klass, | ||
std::vector<TCppFunction_t>& methods) { | ||
GetClassDecls<FunctionTemplateDecl>(klass, methods); | ||
} | ||
|
||
bool HasDefaultConstructor(TCppScope_t scope) { | ||
auto *D = (clang::Decl *) scope; | ||
|
||
if (auto *CXXRD = llvm::dyn_cast_or_null<CXXRecordDecl>(D)) { | ||
if (auto* CXXRD = llvm::dyn_cast_or_null<CXXRecordDecl>(D)) | ||
return CXXRD->hasDefaultConstructor(); | ||
} | ||
|
||
return false; | ||
} | ||
|
@@ -818,21 +825,19 @@ namespace Cpp { | |
TCppType_t GetFunctionReturnType(TCppFunction_t func) | ||
{ | ||
auto *D = (clang::Decl *) func; | ||
if (auto *FD = llvm::dyn_cast_or_null<clang::FunctionDecl>(D)) { | ||
return FD->getReturnType().getAsOpaquePtr(); | ||
} | ||
if (auto* FD = llvm::dyn_cast_or_null<clang::FunctionDecl>(D)) | ||
return FD->getReturnType().getAsOpaquePtr(); | ||
|
||
if (auto* FD = llvm::dyn_cast_or_null<clang::FunctionTemplateDecl>(D)) { | ||
return (FD->getTemplatedDecl())->getReturnType().getAsOpaquePtr(); | ||
} | ||
if (auto* FD = llvm::dyn_cast_or_null<clang::FunctionTemplateDecl>(D)) | ||
return (FD->getTemplatedDecl())->getReturnType().getAsOpaquePtr(); | ||
|
||
return 0; | ||
} | ||
|
||
TCppIndex_t GetFunctionNumArgs(TCppFunction_t func) | ||
{ | ||
auto *D = (clang::Decl *) func; | ||
if (auto *FD = llvm::dyn_cast_or_null<FunctionDecl>(D)) | ||
if (auto* FD = llvm::dyn_cast_or_null<FunctionDecl>(D)) | ||
return FD->getNumParams(); | ||
|
||
if (auto* FD = llvm::dyn_cast_or_null<clang::FunctionTemplateDecl>(D)) | ||
|
@@ -844,9 +849,8 @@ namespace Cpp { | |
TCppIndex_t GetFunctionRequiredArgs(TCppConstFunction_t func) | ||
{ | ||
auto *D = (const clang::Decl *) func; | ||
if (auto *FD = llvm::dyn_cast_or_null<FunctionDecl> (D)) { | ||
if (auto* FD = llvm::dyn_cast_or_null<FunctionDecl>(D)) | ||
return FD->getMinRequiredArguments(); | ||
} | ||
|
||
if (auto* FD = llvm::dyn_cast_or_null<clang::FunctionTemplateDecl>(D)) | ||
return (FD->getTemplatedDecl())->getMinRequiredArguments(); | ||
|
@@ -868,8 +872,7 @@ namespace Cpp { | |
return 0; | ||
} | ||
|
||
std::string GetFunctionSignature(TCppFunction_t func) | ||
{ | ||
std::string GetFunctionSignature(TCppFunction_t func) { | ||
if (!func) | ||
return "<unknown>"; | ||
|
||
|
@@ -886,6 +889,7 @@ namespace Cpp { | |
SS.flush(); | ||
return Signature; | ||
} | ||
|
||
return "<unknown>"; | ||
} | ||
|
||
|
@@ -925,7 +929,7 @@ namespace Cpp { | |
{ | ||
DeclContext *Within = 0; | ||
if (parent) { | ||
auto *D = (Decl *)parent; | ||
auto* D = (Decl*)parent; | ||
aaronj0 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
Within = llvm::dyn_cast<DeclContext>(D); | ||
} | ||
|
||
|
@@ -941,6 +945,72 @@ namespace Cpp { | |
return true; | ||
} | ||
|
||
void GetClassTemplatedMethods(const std::string& name, TCppScope_t parent, | ||
std::vector<TCppFunction_t>& funcs) { | ||
|
||
auto* D = (Decl*)parent; | ||
aaronj0 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
if (!parent || name.empty()) | ||
aaronj0 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
return; | ||
|
||
D = GetUnderlyingScope(D); | ||
|
||
llvm::StringRef Name(name); | ||
auto& S = getSema(); | ||
DeclarationName DName = &getASTContext().Idents.get(name); | ||
clang::LookupResult R(S, DName, SourceLocation(), Sema::LookupOrdinaryName, | ||
Sema::ForVisibleRedeclaration); | ||
|
||
Cpp_utils::Lookup::Named(&S, R, Decl::castToDeclContext(D)); | ||
|
||
if (R.empty()) | ||
return; | ||
|
||
R.resolveKind(); | ||
|
||
for (auto* Found : R) | ||
if (llvm::isa<FunctionTemplateDecl>(Found)) | ||
funcs.push_back(Found); | ||
} | ||
|
||
TCppFunction_t | ||
BestTemplateFunctionMatch(const std::vector<TCppFunction_t>& candidates, | ||
const std::vector<TemplateArgInfo>& explicit_types, | ||
const std::vector<TemplateArgInfo>& arg_types) { | ||
|
||
for (const auto& candidate : candidates) { | ||
auto* TFD = (FunctionTemplateDecl*)candidate; | ||
clang::TemplateParameterList* tpl = TFD->getTemplateParameters(); | ||
|
||
// template parameter size does not match | ||
if (tpl->size() < explicit_types.size()) | ||
continue; | ||
|
||
// right now uninstantiated functions give template typenames instead of | ||
// actual types. We make this match solely based on count | ||
|
||
const FunctionDecl* func = TFD->getTemplatedDecl(); | ||
if (func->getNumParams() != arg_types.size()) | ||
continue; | ||
|
||
// FIXME : first score based on the type similarity before forcing | ||
// instantiation try instantiating | ||
TCppFunction_t instantiated = | ||
InstantiateTemplate(candidate, arg_types.data(), arg_types.size()); | ||
if (instantiated) | ||
return instantiated; | ||
|
||
// Force the instantiation with template params in case of no args | ||
// maybe steer instantiation better with arg set returned from | ||
// TemplateProxy? | ||
instantiated = InstantiateTemplate(candidate, explicit_types.data(), | ||
explicit_types.size()); | ||
if (instantiated) | ||
return instantiated; | ||
} | ||
return nullptr; | ||
} | ||
|
||
// Gets the AccessSpecifier of the function and checks if it is equal to | ||
// the provided AccessSpecifier. | ||
bool CheckMethodAccess(TCppFunction_t method, AccessSpecifier AS) | ||
|
@@ -2836,7 +2906,7 @@ namespace Cpp { | |
} | ||
|
||
TCppScope_t InstantiateTemplate(TCppScope_t tmpl, | ||
TemplateArgInfo* template_args, | ||
const TemplateArgInfo* template_args, | ||
size_t template_args_size) { | ||
ASTContext &C = getASTContext(); | ||
|
||
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.