|
|
|
@ -45,7 +45,7 @@ namespace {
|
|
|
|
|
/// name-lookup routines to specify which declarations should be included in
|
|
|
|
|
/// the result set (when it returns true) and which declarations should be
|
|
|
|
|
/// filtered out (returns false).
|
|
|
|
|
typedef bool (ResultBuilder::*LookupFilter)(NamedDecl *) const;
|
|
|
|
|
typedef bool (ResultBuilder::*LookupFilter)(const NamedDecl *) const;
|
|
|
|
|
|
|
|
|
|
typedef CodeCompletionResult Result;
|
|
|
|
|
|
|
|
|
@ -56,9 +56,9 @@ namespace {
|
|
|
|
|
/// \brief A record of all of the declarations we have found and placed
|
|
|
|
|
/// into the result set, used to ensure that no declaration ever gets into
|
|
|
|
|
/// the result set twice.
|
|
|
|
|
llvm::SmallPtrSet<Decl*, 16> AllDeclsFound;
|
|
|
|
|
llvm::SmallPtrSet<const Decl*, 16> AllDeclsFound;
|
|
|
|
|
|
|
|
|
|
typedef std::pair<NamedDecl *, unsigned> DeclIndexPair;
|
|
|
|
|
typedef std::pair<const NamedDecl *, unsigned> DeclIndexPair;
|
|
|
|
|
|
|
|
|
|
/// \brief An entry in the shadow map, which is optimized to store
|
|
|
|
|
/// a single (declaration, index) mapping (the common case) but
|
|
|
|
@ -68,7 +68,7 @@ namespace {
|
|
|
|
|
|
|
|
|
|
/// \brief Contains either the solitary NamedDecl * or a vector
|
|
|
|
|
/// of (declaration, index) pairs.
|
|
|
|
|
llvm::PointerUnion<NamedDecl *, DeclIndexPairVector*> DeclOrVector;
|
|
|
|
|
llvm::PointerUnion<const NamedDecl *, DeclIndexPairVector*> DeclOrVector;
|
|
|
|
|
|
|
|
|
|
/// \brief When the entry contains a single declaration, this is
|
|
|
|
|
/// the index associated with that entry.
|
|
|
|
@ -77,7 +77,7 @@ namespace {
|
|
|
|
|
public:
|
|
|
|
|
ShadowMapEntry() : DeclOrVector(), SingleDeclIndex(0) { }
|
|
|
|
|
|
|
|
|
|
void Add(NamedDecl *ND, unsigned Index) {
|
|
|
|
|
void Add(const NamedDecl *ND, unsigned Index) {
|
|
|
|
|
if (DeclOrVector.isNull()) {
|
|
|
|
|
// 0 - > 1 elements: just set the single element information.
|
|
|
|
|
DeclOrVector = ND;
|
|
|
|
@ -85,7 +85,8 @@ namespace {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (NamedDecl *PrevND = DeclOrVector.dyn_cast<NamedDecl *>()) {
|
|
|
|
|
if (const NamedDecl *PrevND =
|
|
|
|
|
DeclOrVector.dyn_cast<const NamedDecl *>()) {
|
|
|
|
|
// 1 -> 2 elements: create the vector of results and push in the
|
|
|
|
|
// existing declaration.
|
|
|
|
|
DeclIndexPairVector *Vec = new DeclIndexPairVector;
|
|
|
|
@ -265,7 +266,8 @@ namespace {
|
|
|
|
|
///
|
|
|
|
|
/// \param AsNestedNameSpecifier will be set true if this declaration is
|
|
|
|
|
/// only interesting when it is a nested-name-specifier.
|
|
|
|
|
bool isInterestingDecl(NamedDecl *ND, bool &AsNestedNameSpecifier) const;
|
|
|
|
|
bool isInterestingDecl(const NamedDecl *ND,
|
|
|
|
|
bool &AsNestedNameSpecifier) const;
|
|
|
|
|
|
|
|
|
|
/// \brief Check whether the result is hidden by the Hiding declaration.
|
|
|
|
|
///
|
|
|
|
@ -274,7 +276,7 @@ namespace {
|
|
|
|
|
/// modified to describe how the result can be found (e.g., via extra
|
|
|
|
|
/// qualification).
|
|
|
|
|
bool CheckHiddenResult(Result &R, DeclContext *CurContext,
|
|
|
|
|
NamedDecl *Hiding);
|
|
|
|
|
const NamedDecl *Hiding);
|
|
|
|
|
|
|
|
|
|
/// \brief Add a new result to this result set (if it isn't already in one
|
|
|
|
|
/// of the shadow maps), or replace an existing result (for, e.g., a
|
|
|
|
@ -317,29 +319,29 @@ namespace {
|
|
|
|
|
/// results of name lookup. All of the predicates have the same type, so that
|
|
|
|
|
///
|
|
|
|
|
//@{
|
|
|
|
|
bool IsOrdinaryName(NamedDecl *ND) const;
|
|
|
|
|
bool IsOrdinaryNonTypeName(NamedDecl *ND) const;
|
|
|
|
|
bool IsIntegralConstantValue(NamedDecl *ND) const;
|
|
|
|
|
bool IsOrdinaryNonValueName(NamedDecl *ND) const;
|
|
|
|
|
bool IsNestedNameSpecifier(NamedDecl *ND) const;
|
|
|
|
|
bool IsEnum(NamedDecl *ND) const;
|
|
|
|
|
bool IsClassOrStruct(NamedDecl *ND) const;
|
|
|
|
|
bool IsUnion(NamedDecl *ND) const;
|
|
|
|
|
bool IsNamespace(NamedDecl *ND) const;
|
|
|
|
|
bool IsNamespaceOrAlias(NamedDecl *ND) const;
|
|
|
|
|
bool IsType(NamedDecl *ND) const;
|
|
|
|
|
bool IsMember(NamedDecl *ND) const;
|
|
|
|
|
bool IsObjCIvar(NamedDecl *ND) const;
|
|
|
|
|
bool IsObjCMessageReceiver(NamedDecl *ND) const;
|
|
|
|
|
bool IsObjCMessageReceiverOrLambdaCapture(NamedDecl *ND) const;
|
|
|
|
|
bool IsObjCCollection(NamedDecl *ND) const;
|
|
|
|
|
bool IsImpossibleToSatisfy(NamedDecl *ND) const;
|
|
|
|
|
bool IsOrdinaryName(const NamedDecl *ND) const;
|
|
|
|
|
bool IsOrdinaryNonTypeName(const NamedDecl *ND) const;
|
|
|
|
|
bool IsIntegralConstantValue(const NamedDecl *ND) const;
|
|
|
|
|
bool IsOrdinaryNonValueName(const NamedDecl *ND) const;
|
|
|
|
|
bool IsNestedNameSpecifier(const NamedDecl *ND) const;
|
|
|
|
|
bool IsEnum(const NamedDecl *ND) const;
|
|
|
|
|
bool IsClassOrStruct(const NamedDecl *ND) const;
|
|
|
|
|
bool IsUnion(const NamedDecl *ND) const;
|
|
|
|
|
bool IsNamespace(const NamedDecl *ND) const;
|
|
|
|
|
bool IsNamespaceOrAlias(const NamedDecl *ND) const;
|
|
|
|
|
bool IsType(const NamedDecl *ND) const;
|
|
|
|
|
bool IsMember(const NamedDecl *ND) const;
|
|
|
|
|
bool IsObjCIvar(const NamedDecl *ND) const;
|
|
|
|
|
bool IsObjCMessageReceiver(const NamedDecl *ND) const;
|
|
|
|
|
bool IsObjCMessageReceiverOrLambdaCapture(const NamedDecl *ND) const;
|
|
|
|
|
bool IsObjCCollection(const NamedDecl *ND) const;
|
|
|
|
|
bool IsImpossibleToSatisfy(const NamedDecl *ND) const;
|
|
|
|
|
//@}
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class ResultBuilder::ShadowMapEntry::iterator {
|
|
|
|
|
llvm::PointerUnion<NamedDecl*, const DeclIndexPair*> DeclOrIterator;
|
|
|
|
|
llvm::PointerUnion<const NamedDecl *, const DeclIndexPair *> DeclOrIterator;
|
|
|
|
|
unsigned SingleDeclIndex;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
@ -361,14 +363,14 @@ public:
|
|
|
|
|
|
|
|
|
|
iterator() : DeclOrIterator((NamedDecl *)0), SingleDeclIndex(0) { }
|
|
|
|
|
|
|
|
|
|
iterator(NamedDecl *SingleDecl, unsigned Index)
|
|
|
|
|
iterator(const NamedDecl *SingleDecl, unsigned Index)
|
|
|
|
|
: DeclOrIterator(SingleDecl), SingleDeclIndex(Index) { }
|
|
|
|
|
|
|
|
|
|
iterator(const DeclIndexPair *Iterator)
|
|
|
|
|
: DeclOrIterator(Iterator), SingleDeclIndex(0) { }
|
|
|
|
|
|
|
|
|
|
iterator &operator++() {
|
|
|
|
|
if (DeclOrIterator.is<NamedDecl *>()) {
|
|
|
|
|
if (DeclOrIterator.is<const NamedDecl *>()) {
|
|
|
|
|
DeclOrIterator = (NamedDecl *)0;
|
|
|
|
|
SingleDeclIndex = 0;
|
|
|
|
|
return *this;
|
|
|
|
@ -387,7 +389,7 @@ public:
|
|
|
|
|
}*/
|
|
|
|
|
|
|
|
|
|
reference operator*() const {
|
|
|
|
|
if (NamedDecl *ND = DeclOrIterator.dyn_cast<NamedDecl *>())
|
|
|
|
|
if (const NamedDecl *ND = DeclOrIterator.dyn_cast<const NamedDecl *>())
|
|
|
|
|
return reference(ND, SingleDeclIndex);
|
|
|
|
|
|
|
|
|
|
return *DeclOrIterator.get<const DeclIndexPair*>();
|
|
|
|
@ -413,7 +415,7 @@ ResultBuilder::ShadowMapEntry::begin() const {
|
|
|
|
|
if (DeclOrVector.isNull())
|
|
|
|
|
return iterator();
|
|
|
|
|
|
|
|
|
|
if (NamedDecl *ND = DeclOrVector.dyn_cast<NamedDecl *>())
|
|
|
|
|
if (const NamedDecl *ND = DeclOrVector.dyn_cast<const NamedDecl *>())
|
|
|
|
|
return iterator(ND, SingleDeclIndex);
|
|
|
|
|
|
|
|
|
|
return iterator(DeclOrVector.get<DeclIndexPairVector *>()->begin());
|
|
|
|
@ -421,7 +423,7 @@ ResultBuilder::ShadowMapEntry::begin() const {
|
|
|
|
|
|
|
|
|
|
ResultBuilder::ShadowMapEntry::iterator
|
|
|
|
|
ResultBuilder::ShadowMapEntry::end() const {
|
|
|
|
|
if (DeclOrVector.is<NamedDecl *>() || DeclOrVector.isNull())
|
|
|
|
|
if (DeclOrVector.is<const NamedDecl *>() || DeclOrVector.isNull())
|
|
|
|
|
return iterator();
|
|
|
|
|
|
|
|
|
|
return iterator(DeclOrVector.get<DeclIndexPairVector *>()->end());
|
|
|
|
@ -442,11 +444,11 @@ ResultBuilder::ShadowMapEntry::end() const {
|
|
|
|
|
/// NULL if no qualification is needed.
|
|
|
|
|
static NestedNameSpecifier *
|
|
|
|
|
getRequiredQualification(ASTContext &Context,
|
|
|
|
|
DeclContext *CurContext,
|
|
|
|
|
DeclContext *TargetContext) {
|
|
|
|
|
SmallVector<DeclContext *, 4> TargetParents;
|
|
|
|
|
const DeclContext *CurContext,
|
|
|
|
|
const DeclContext *TargetContext) {
|
|
|
|
|
SmallVector<const DeclContext *, 4> TargetParents;
|
|
|
|
|
|
|
|
|
|
for (DeclContext *CommonAncestor = TargetContext;
|
|
|
|
|
for (const DeclContext *CommonAncestor = TargetContext;
|
|
|
|
|
CommonAncestor && !CommonAncestor->Encloses(CurContext);
|
|
|
|
|
CommonAncestor = CommonAncestor->getLookupParent()) {
|
|
|
|
|
if (CommonAncestor->isTransparentContext() ||
|
|
|
|
@ -458,16 +460,16 @@ getRequiredQualification(ASTContext &Context,
|
|
|
|
|
|
|
|
|
|
NestedNameSpecifier *Result = 0;
|
|
|
|
|
while (!TargetParents.empty()) {
|
|
|
|
|
DeclContext *Parent = TargetParents.back();
|
|
|
|
|
const DeclContext *Parent = TargetParents.back();
|
|
|
|
|
TargetParents.pop_back();
|
|
|
|
|
|
|
|
|
|
if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Parent)) {
|
|
|
|
|
if (const NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Parent)) {
|
|
|
|
|
if (!Namespace->getIdentifier())
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
Result = NestedNameSpecifier::Create(Context, Result, Namespace);
|
|
|
|
|
}
|
|
|
|
|
else if (TagDecl *TD = dyn_cast<TagDecl>(Parent))
|
|
|
|
|
else if (const TagDecl *TD = dyn_cast<TagDecl>(Parent))
|
|
|
|
|
Result = NestedNameSpecifier::Create(Context, Result,
|
|
|
|
|
false,
|
|
|
|
|
Context.getTypeDeclType(TD).getTypePtr());
|
|
|
|
@ -475,7 +477,7 @@ getRequiredQualification(ASTContext &Context,
|
|
|
|
|
return Result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool ResultBuilder::isInterestingDecl(NamedDecl *ND,
|
|
|
|
|
bool ResultBuilder::isInterestingDecl(const NamedDecl *ND,
|
|
|
|
|
bool &AsNestedNameSpecifier) const {
|
|
|
|
|
AsNestedNameSpecifier = false;
|
|
|
|
|
|
|
|
|
@ -547,14 +549,15 @@ bool ResultBuilder::isInterestingDecl(NamedDecl *ND,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool ResultBuilder::CheckHiddenResult(Result &R, DeclContext *CurContext,
|
|
|
|
|
NamedDecl *Hiding) {
|
|
|
|
|
const NamedDecl *Hiding) {
|
|
|
|
|
// In C, there is no way to refer to a hidden name.
|
|
|
|
|
// FIXME: This isn't true; we can find a tag name hidden by an ordinary
|
|
|
|
|
// name if we introduce the tag type.
|
|
|
|
|
if (!SemaRef.getLangOpts().CPlusPlus)
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
DeclContext *HiddenCtx = R.Declaration->getDeclContext()->getRedeclContext();
|
|
|
|
|
const DeclContext *HiddenCtx =
|
|
|
|
|
R.Declaration->getDeclContext()->getRedeclContext();
|
|
|
|
|
|
|
|
|
|
// There is no way to qualify a name declared in a function or method.
|
|
|
|
|
if (HiddenCtx->isFunctionOrMethod())
|
|
|
|
@ -645,26 +648,27 @@ SimplifiedTypeClass clang::getSimplifiedTypeClass(CanQualType T) {
|
|
|
|
|
|
|
|
|
|
/// \brief Get the type that a given expression will have if this declaration
|
|
|
|
|
/// is used as an expression in its "typical" code-completion form.
|
|
|
|
|
QualType clang::getDeclUsageType(ASTContext &C, NamedDecl *ND) {
|
|
|
|
|
QualType clang::getDeclUsageType(ASTContext &C, const NamedDecl *ND) {
|
|
|
|
|
ND = cast<NamedDecl>(ND->getUnderlyingDecl());
|
|
|
|
|
|
|
|
|
|
if (TypeDecl *Type = dyn_cast<TypeDecl>(ND))
|
|
|
|
|
if (const TypeDecl *Type = dyn_cast<TypeDecl>(ND))
|
|
|
|
|
return C.getTypeDeclType(Type);
|
|
|
|
|
if (ObjCInterfaceDecl *Iface = dyn_cast<ObjCInterfaceDecl>(ND))
|
|
|
|
|
if (const ObjCInterfaceDecl *Iface = dyn_cast<ObjCInterfaceDecl>(ND))
|
|
|
|
|
return C.getObjCInterfaceType(Iface);
|
|
|
|
|
|
|
|
|
|
QualType T;
|
|
|
|
|
if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
|
|
|
|
|
if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
|
|
|
|
|
T = Function->getCallResultType();
|
|
|
|
|
else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
|
|
|
|
|
else if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
|
|
|
|
|
T = Method->getSendResultType();
|
|
|
|
|
else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
|
|
|
|
|
else if (const FunctionTemplateDecl *FunTmpl =
|
|
|
|
|
dyn_cast<FunctionTemplateDecl>(ND))
|
|
|
|
|
T = FunTmpl->getTemplatedDecl()->getCallResultType();
|
|
|
|
|
else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
|
|
|
|
|
else if (const EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
|
|
|
|
|
T = C.getTypeDeclType(cast<EnumDecl>(Enumerator->getDeclContext()));
|
|
|
|
|
else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
|
|
|
|
|
else if (const ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
|
|
|
|
|
T = Property->getType();
|
|
|
|
|
else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND))
|
|
|
|
|
else if (const ValueDecl *Value = dyn_cast<ValueDecl>(ND))
|
|
|
|
|
T = Value->getType();
|
|
|
|
|
else
|
|
|
|
|
return QualType();
|
|
|
|
@ -707,7 +711,7 @@ void ResultBuilder::AdjustResultPriorityForDecl(Result &R) {
|
|
|
|
|
// If this is an Objective-C method declaration whose selector matches our
|
|
|
|
|
// preferred selector, give it a priority boost.
|
|
|
|
|
if (!PreferredSelector.isNull())
|
|
|
|
|
if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(R.Declaration))
|
|
|
|
|
if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(R.Declaration))
|
|
|
|
|
if (PreferredSelector == Method->getSelector())
|
|
|
|
|
R.Priority += CCD_SelectorMatch;
|
|
|
|
|
|
|
|
|
@ -735,9 +739,9 @@ void ResultBuilder::MaybeAddConstructorResults(Result R) {
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
ASTContext &Context = SemaRef.Context;
|
|
|
|
|
NamedDecl *D = R.Declaration;
|
|
|
|
|
CXXRecordDecl *Record = 0;
|
|
|
|
|
if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D))
|
|
|
|
|
const NamedDecl *D = R.Declaration;
|
|
|
|
|
const CXXRecordDecl *Record = 0;
|
|
|
|
|
if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D))
|
|
|
|
|
Record = ClassTemplate->getTemplatedDecl();
|
|
|
|
|
else if ((Record = dyn_cast<CXXRecordDecl>(D))) {
|
|
|
|
|
// Skip specializations and partial specializations.
|
|
|
|
@ -757,9 +761,10 @@ void ResultBuilder::MaybeAddConstructorResults(Result R) {
|
|
|
|
|
DeclarationName ConstructorName
|
|
|
|
|
= Context.DeclarationNames.getCXXConstructorName(
|
|
|
|
|
Context.getCanonicalType(RecordTy));
|
|
|
|
|
DeclContext::lookup_result Ctors = Record->lookup(ConstructorName);
|
|
|
|
|
for (DeclContext::lookup_iterator I = Ctors.begin(), E = Ctors.end(); I != E;
|
|
|
|
|
++I) {
|
|
|
|
|
DeclContext::lookup_const_result Ctors = Record->lookup(ConstructorName);
|
|
|
|
|
for (DeclContext::lookup_const_iterator I = Ctors.begin(),
|
|
|
|
|
E = Ctors.end();
|
|
|
|
|
I != E; ++I) {
|
|
|
|
|
R.Declaration = *I;
|
|
|
|
|
R.CursorKind = getCursorKindForDecl(R.Declaration);
|
|
|
|
|
Results.push_back(R);
|
|
|
|
@ -776,12 +781,13 @@ void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Look through using declarations.
|
|
|
|
|
if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
|
|
|
|
|
if (const UsingShadowDecl *Using =
|
|
|
|
|
dyn_cast<UsingShadowDecl>(R.Declaration)) {
|
|
|
|
|
MaybeAddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Decl *CanonDecl = R.Declaration->getCanonicalDecl();
|
|
|
|
|
const Decl *CanonDecl = R.Declaration->getCanonicalDecl();
|
|
|
|
|
unsigned IDNS = CanonDecl->getIdentifierNamespace();
|
|
|
|
|
|
|
|
|
|
bool AsNestedNameSpecifier = false;
|
|
|
|
@ -801,7 +807,7 @@ void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (; I != IEnd; ++I) {
|
|
|
|
|
NamedDecl *ND = I->first;
|
|
|
|
|
const NamedDecl *ND = I->first;
|
|
|
|
|
unsigned Index = I->second;
|
|
|
|
|
if (ND->getCanonicalDecl() == CanonDecl) {
|
|
|
|
|
// This is a redeclaration. Always pick the newer declaration.
|
|
|
|
@ -860,10 +866,10 @@ void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) {
|
|
|
|
|
// If this result is supposed to have an informative qualifier, add one.
|
|
|
|
|
if (R.QualifierIsInformative && !R.Qualifier &&
|
|
|
|
|
!R.StartsNestedNameSpecifier) {
|
|
|
|
|
DeclContext *Ctx = R.Declaration->getDeclContext();
|
|
|
|
|
if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
|
|
|
|
|
const DeclContext *Ctx = R.Declaration->getDeclContext();
|
|
|
|
|
if (const NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
|
|
|
|
|
R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
|
|
|
|
|
else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
|
|
|
|
|
else if (const TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
|
|
|
|
|
R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
|
|
|
|
|
SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
|
|
|
|
|
else
|
|
|
|
@ -888,7 +894,7 @@ void ResultBuilder::AddResult(Result R, DeclContext *CurContext,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Look through using declarations.
|
|
|
|
|
if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
|
|
|
|
|
if (const UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
|
|
|
|
|
AddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext, Hiding);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
@ -922,10 +928,10 @@ void ResultBuilder::AddResult(Result R, DeclContext *CurContext,
|
|
|
|
|
// If this result is supposed to have an informative qualifier, add one.
|
|
|
|
|
if (R.QualifierIsInformative && !R.Qualifier &&
|
|
|
|
|
!R.StartsNestedNameSpecifier) {
|
|
|
|
|
DeclContext *Ctx = R.Declaration->getDeclContext();
|
|
|
|
|
if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
|
|
|
|
|
const DeclContext *Ctx = R.Declaration->getDeclContext();
|
|
|
|
|
if (const NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
|
|
|
|
|
R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
|
|
|
|
|
else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
|
|
|
|
|
else if (const TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
|
|
|
|
|
R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
|
|
|
|
|
SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
|
|
|
|
|
else
|
|
|
|
@ -939,7 +945,7 @@ void ResultBuilder::AddResult(Result R, DeclContext *CurContext,
|
|
|
|
|
AdjustResultPriorityForDecl(R);
|
|
|
|
|
|
|
|
|
|
if (HasObjectTypeQualifiers)
|
|
|
|
|
if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(R.Declaration))
|
|
|
|
|
if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(R.Declaration))
|
|
|
|
|
if (Method->isInstance()) {
|
|
|
|
|
Qualifiers MethodQuals
|
|
|
|
|
= Qualifiers::fromCVRMask(Method->getTypeQualifiers());
|
|
|
|
@ -983,7 +989,7 @@ void ResultBuilder::ExitScope() {
|
|
|
|
|
|
|
|
|
|
/// \brief Determines whether this given declaration will be found by
|
|
|
|
|
/// ordinary name lookup.
|
|
|
|
|
bool ResultBuilder::IsOrdinaryName(NamedDecl *ND) const {
|
|
|
|
|
bool ResultBuilder::IsOrdinaryName(const NamedDecl *ND) const {
|
|
|
|
|
ND = cast<NamedDecl>(ND->getUnderlyingDecl());
|
|
|
|
|
|
|
|
|
|
unsigned IDNS = Decl::IDNS_Ordinary;
|
|
|
|
@ -999,7 +1005,7 @@ bool ResultBuilder::IsOrdinaryName(NamedDecl *ND) const {
|
|
|
|
|
|
|
|
|
|
/// \brief Determines whether this given declaration will be found by
|
|
|
|
|
/// ordinary name lookup but is not a type name.
|
|
|
|
|
bool ResultBuilder::IsOrdinaryNonTypeName(NamedDecl *ND) const {
|
|
|
|
|
bool ResultBuilder::IsOrdinaryNonTypeName(const NamedDecl *ND) const {
|
|
|
|
|
ND = cast<NamedDecl>(ND->getUnderlyingDecl());
|
|
|
|
|
if (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND))
|
|
|
|
|
return false;
|
|
|
|
@ -1015,11 +1021,11 @@ bool ResultBuilder::IsOrdinaryNonTypeName(NamedDecl *ND) const {
|
|
|
|
|
return ND->getIdentifierNamespace() & IDNS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool ResultBuilder::IsIntegralConstantValue(NamedDecl *ND) const {
|
|
|
|
|
bool ResultBuilder::IsIntegralConstantValue(const NamedDecl *ND) const {
|
|
|
|
|
if (!IsOrdinaryNonTypeName(ND))
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
if (ValueDecl *VD = dyn_cast<ValueDecl>(ND->getUnderlyingDecl()))
|
|
|
|
|
if (const ValueDecl *VD = dyn_cast<ValueDecl>(ND->getUnderlyingDecl()))
|
|
|
|
|
if (VD->getType()->isIntegralOrEnumerationType())
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
@ -1028,7 +1034,7 @@ bool ResultBuilder::IsIntegralConstantValue(NamedDecl *ND) const {
|
|
|
|
|
|
|
|
|
|
/// \brief Determines whether this given declaration will be found by
|
|
|
|
|
/// ordinary name lookup.
|
|
|
|
|
bool ResultBuilder::IsOrdinaryNonValueName(NamedDecl *ND) const {
|
|
|
|
|
bool ResultBuilder::IsOrdinaryNonValueName(const NamedDecl *ND) const {
|
|
|
|
|
ND = cast<NamedDecl>(ND->getUnderlyingDecl());
|
|
|
|
|
|
|
|
|
|
unsigned IDNS = Decl::IDNS_Ordinary;
|
|
|
|
@ -1042,27 +1048,27 @@ bool ResultBuilder::IsOrdinaryNonValueName(NamedDecl *ND) const {
|
|
|
|
|
|
|
|
|
|
/// \brief Determines whether the given declaration is suitable as the
|
|
|
|
|
/// start of a C++ nested-name-specifier, e.g., a class or namespace.
|
|
|
|
|
bool ResultBuilder::IsNestedNameSpecifier(NamedDecl *ND) const {
|
|
|
|
|
bool ResultBuilder::IsNestedNameSpecifier(const NamedDecl *ND) const {
|
|
|
|
|
// Allow us to find class templates, too.
|
|
|
|
|
if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
|
|
|
|
|
if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
|
|
|
|
|
ND = ClassTemplate->getTemplatedDecl();
|
|
|
|
|
|
|
|
|
|
return SemaRef.isAcceptableNestedNameSpecifier(ND);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// \brief Determines whether the given declaration is an enumeration.
|
|
|
|
|
bool ResultBuilder::IsEnum(NamedDecl *ND) const {
|
|
|
|
|
bool ResultBuilder::IsEnum(const NamedDecl *ND) const {
|
|
|
|
|
return isa<EnumDecl>(ND);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// \brief Determines whether the given declaration is a class or struct.
|
|
|
|
|
bool ResultBuilder::IsClassOrStruct(NamedDecl *ND) const {
|
|
|
|
|
bool ResultBuilder::IsClassOrStruct(const NamedDecl *ND) const {
|
|
|
|
|
// Allow us to find class templates, too.
|
|
|
|
|
if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
|
|
|
|
|
if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
|
|
|
|
|
ND = ClassTemplate->getTemplatedDecl();
|
|
|
|
|
|
|
|
|
|
// For purposes of this check, interfaces match too.
|
|
|
|
|
if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
|
|
|
|
|
if (const RecordDecl *RD = dyn_cast<RecordDecl>(ND))
|
|
|
|
|
return RD->getTagKind() == TTK_Class ||
|
|
|
|
|
RD->getTagKind() == TTK_Struct ||
|
|
|
|
|
RD->getTagKind() == TTK_Interface;
|
|
|
|
@ -1071,31 +1077,31 @@ bool ResultBuilder::IsClassOrStruct(NamedDecl *ND) const {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// \brief Determines whether the given declaration is a union.
|
|
|
|
|
bool ResultBuilder::IsUnion(NamedDecl *ND) const {
|
|
|
|
|
bool ResultBuilder::IsUnion(const NamedDecl *ND) const {
|
|
|
|
|
// Allow us to find class templates, too.
|
|
|
|
|
if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
|
|
|
|
|
if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
|
|
|
|
|
ND = ClassTemplate->getTemplatedDecl();
|
|
|
|
|
|
|
|
|
|
if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
|
|
|
|
|
if (const RecordDecl *RD = dyn_cast<RecordDecl>(ND))
|
|
|
|
|
return RD->getTagKind() == TTK_Union;
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// \brief Determines whether the given declaration is a namespace.
|
|
|
|
|
bool ResultBuilder::IsNamespace(NamedDecl *ND) const {
|
|
|
|
|
bool ResultBuilder::IsNamespace(const NamedDecl *ND) const {
|
|
|
|
|
return isa<NamespaceDecl>(ND);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// \brief Determines whether the given declaration is a namespace or
|
|
|
|
|
/// namespace alias.
|
|
|
|
|
bool ResultBuilder::IsNamespaceOrAlias(NamedDecl *ND) const {
|
|
|
|
|
bool ResultBuilder::IsNamespaceOrAlias(const NamedDecl *ND) const {
|
|
|
|
|
return isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// \brief Determines whether the given declaration is a type.
|
|
|
|
|
bool ResultBuilder::IsType(NamedDecl *ND) const {
|
|
|
|
|
if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
|
|
|
|
|
bool ResultBuilder::IsType(const NamedDecl *ND) const {
|
|
|
|
|
if (const UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
|
|
|
|
|
ND = Using->getTargetDecl();
|
|
|
|
|
|
|
|
|
|
return isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND);
|
|
|
|
@ -1104,8 +1110,8 @@ bool ResultBuilder::IsType(NamedDecl *ND) const {
|
|
|
|
|
/// \brief Determines which members of a class should be visible via
|
|
|
|
|
/// "." or "->". Only value declarations, nested name specifiers, and
|
|
|
|
|
/// using declarations thereof should show up.
|
|
|
|
|
bool ResultBuilder::IsMember(NamedDecl *ND) const {
|
|
|
|
|
if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
|
|
|
|
|
bool ResultBuilder::IsMember(const NamedDecl *ND) const {
|
|
|
|
|
if (const UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
|
|
|
|
|
ND = Using->getTargetDecl();
|
|
|
|
|
|
|
|
|
|
return isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND) ||
|
|
|
|
@ -1145,7 +1151,7 @@ static bool isObjCReceiverType(ASTContext &C, QualType T) {
|
|
|
|
|
return T->isDependentType() || T->isRecordType();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool ResultBuilder::IsObjCMessageReceiver(NamedDecl *ND) const {
|
|
|
|
|
bool ResultBuilder::IsObjCMessageReceiver(const NamedDecl *ND) const {
|
|
|
|
|
QualType T = getDeclUsageType(SemaRef.Context, ND);
|
|
|
|
|
if (T.isNull())
|
|
|
|
|
return false;
|
|
|
|
@ -1154,18 +1160,18 @@ bool ResultBuilder::IsObjCMessageReceiver(NamedDecl *ND) const {
|
|
|
|
|
return isObjCReceiverType(SemaRef.Context, T);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool ResultBuilder::IsObjCMessageReceiverOrLambdaCapture(NamedDecl *ND) const {
|
|
|
|
|
bool ResultBuilder::IsObjCMessageReceiverOrLambdaCapture(const NamedDecl *ND) const {
|
|
|
|
|
if (IsObjCMessageReceiver(ND))
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
VarDecl *Var = dyn_cast<VarDecl>(ND);
|
|
|
|
|
const VarDecl *Var = dyn_cast<VarDecl>(ND);
|
|
|
|
|
if (!Var)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
return Var->hasLocalStorage() && !Var->hasAttr<BlocksAttr>();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool ResultBuilder::IsObjCCollection(NamedDecl *ND) const {
|
|
|
|
|
bool ResultBuilder::IsObjCCollection(const NamedDecl *ND) const {
|
|
|
|
|
if ((SemaRef.getLangOpts().CPlusPlus && !IsOrdinaryName(ND)) ||
|
|
|
|
|
(!SemaRef.getLangOpts().CPlusPlus && !IsOrdinaryNonTypeName(ND)))
|
|
|
|
|
return false;
|
|
|
|
@ -1180,13 +1186,13 @@ bool ResultBuilder::IsObjCCollection(NamedDecl *ND) const {
|
|
|
|
|
(SemaRef.getLangOpts().CPlusPlus && T->isRecordType());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool ResultBuilder::IsImpossibleToSatisfy(NamedDecl *ND) const {
|
|
|
|
|
bool ResultBuilder::IsImpossibleToSatisfy(const NamedDecl *ND) const {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// \brief Determines whether the given declaration is an Objective-C
|
|
|
|
|
/// instance variable.
|
|
|
|
|
bool ResultBuilder::IsObjCIvar(NamedDecl *ND) const {
|
|
|
|
|
bool ResultBuilder::IsObjCIvar(const NamedDecl *ND) const {
|
|
|
|
|
return isa<ObjCIvarDecl>(ND);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1998,7 +2004,7 @@ static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC,
|
|
|
|
|
/// type chunk.
|
|
|
|
|
static void AddResultTypeChunk(ASTContext &Context,
|
|
|
|
|
const PrintingPolicy &Policy,
|
|
|
|
|
NamedDecl *ND,
|
|
|
|
|
const NamedDecl *ND,
|
|
|
|
|
CodeCompletionBuilder &Result) {
|
|
|
|
|
if (!ND)
|
|
|
|
|
return;
|
|
|
|
@ -2010,19 +2016,20 @@ static void AddResultTypeChunk(ASTContext &Context,
|
|
|
|
|
|
|
|
|
|
// Determine the type of the declaration (if it has a type).
|
|
|
|
|
QualType T;
|
|
|
|
|
if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
|
|
|
|
|
if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
|
|
|
|
|
T = Function->getResultType();
|
|
|
|
|
else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
|
|
|
|
|
else if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
|
|
|
|
|
T = Method->getResultType();
|
|
|
|
|
else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
|
|
|
|
|
else if (const FunctionTemplateDecl *FunTmpl =
|
|
|
|
|
dyn_cast<FunctionTemplateDecl>(ND))
|
|
|
|
|
T = FunTmpl->getTemplatedDecl()->getResultType();
|
|
|
|
|
else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
|
|
|
|
|
else if (const EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
|
|
|
|
|
T = Context.getTypeDeclType(cast<TypeDecl>(Enumerator->getDeclContext()));
|
|
|
|
|
else if (isa<UnresolvedUsingValueDecl>(ND)) {
|
|
|
|
|
/* Do nothing: ignore unresolved using declarations*/
|
|
|
|
|
} else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND)) {
|
|
|
|
|
} else if (const ValueDecl *Value = dyn_cast<ValueDecl>(ND)) {
|
|
|
|
|
T = Value->getType();
|
|
|
|
|
} else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
|
|
|
|
|
} else if (const ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
|
|
|
|
|
T = Property->getType();
|
|
|
|
|
|
|
|
|
|
if (T.isNull() || Context.hasSameType(T, Context.DependentTy))
|
|
|
|
@ -2032,7 +2039,8 @@ static void AddResultTypeChunk(ASTContext &Context,
|
|
|
|
|
Result.getAllocator()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void MaybeAddSentinel(ASTContext &Context, NamedDecl *FunctionOrMethod,
|
|
|
|
|
static void MaybeAddSentinel(ASTContext &Context,
|
|
|
|
|
const NamedDecl *FunctionOrMethod,
|
|
|
|
|
CodeCompletionBuilder &Result) {
|
|
|
|
|
if (SentinelAttr *Sentinel = FunctionOrMethod->getAttr<SentinelAttr>())
|
|
|
|
|
if (Sentinel->getSentinel() == 0) {
|
|
|
|
@ -2065,7 +2073,7 @@ static std::string formatObjCParamQualifiers(unsigned ObjCQuals) {
|
|
|
|
|
|
|
|
|
|
static std::string FormatFunctionParameter(ASTContext &Context,
|
|
|
|
|
const PrintingPolicy &Policy,
|
|
|
|
|
ParmVarDecl *Param,
|
|
|
|
|
const ParmVarDecl *Param,
|
|
|
|
|
bool SuppressName = false,
|
|
|
|
|
bool SuppressBlock = false) {
|
|
|
|
|
bool ObjCMethodParam = isa<ObjCMethodDecl>(Param->getDeclContext());
|
|
|
|
@ -2196,14 +2204,14 @@ static std::string FormatFunctionParameter(ASTContext &Context,
|
|
|
|
|
/// \brief Add function parameter chunks to the given code completion string.
|
|
|
|
|
static void AddFunctionParameterChunks(ASTContext &Context,
|
|
|
|
|
const PrintingPolicy &Policy,
|
|
|
|
|
FunctionDecl *Function,
|
|
|
|
|
const FunctionDecl *Function,
|
|
|
|
|
CodeCompletionBuilder &Result,
|
|
|
|
|
unsigned Start = 0,
|
|
|
|
|
bool InOptional = false) {
|
|
|
|
|
bool FirstParameter = true;
|
|
|
|
|
|
|
|
|
|
for (unsigned P = Start, N = Function->getNumParams(); P != N; ++P) {
|
|
|
|
|
ParmVarDecl *Param = Function->getParamDecl(P);
|
|
|
|
|
const ParmVarDecl *Param = Function->getParamDecl(P);
|
|
|
|
|
|
|
|
|
|
if (Param->hasDefaultArg() && !InOptional) {
|
|
|
|
|
// When we see an optional default argument, put that argument and
|
|
|
|
@ -2249,7 +2257,7 @@ static void AddFunctionParameterChunks(ASTContext &Context,
|
|
|
|
|
/// \brief Add template parameter chunks to the given code completion string.
|
|
|
|
|
static void AddTemplateParameterChunks(ASTContext &Context,
|
|
|
|
|
const PrintingPolicy &Policy,
|
|
|
|
|
TemplateDecl *Template,
|
|
|
|
|
const TemplateDecl *Template,
|
|
|
|
|
CodeCompletionBuilder &Result,
|
|
|
|
|
unsigned MaxParameters = 0,
|
|
|
|
|
unsigned Start = 0,
|
|
|
|
@ -2347,7 +2355,7 @@ AddQualifierToCompletionString(CodeCompletionBuilder &Result,
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
AddFunctionTypeQualsToCompletionString(CodeCompletionBuilder &Result,
|
|
|
|
|
FunctionDecl *Function) {
|
|
|
|
|
const FunctionDecl *Function) {
|
|
|
|
|
const FunctionProtoType *Proto
|
|
|
|
|
= Function->getType()->getAs<FunctionProtoType>();
|
|
|
|
|
if (!Proto || !Proto->getTypeQuals())
|
|
|
|
@ -2384,7 +2392,8 @@ AddFunctionTypeQualsToCompletionString(CodeCompletionBuilder &Result,
|
|
|
|
|
|
|
|
|
|
/// \brief Add the name of the given declaration
|
|
|
|
|
static void AddTypedNameChunk(ASTContext &Context, const PrintingPolicy &Policy,
|
|
|
|
|
NamedDecl *ND, CodeCompletionBuilder &Result) {
|
|
|
|
|
const NamedDecl *ND,
|
|
|
|
|
CodeCompletionBuilder &Result) {
|
|
|
|
|
DeclarationName Name = ND->getDeclName();
|
|
|
|
|
if (!Name)
|
|
|
|
|
return;
|
|
|
|
@ -2541,7 +2550,7 @@ CodeCompletionResult::CreateCodeCompletionString(ASTContext &Ctx,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
assert(Kind == RK_Declaration && "Missed a result kind?");
|
|
|
|
|
NamedDecl *ND = Declaration;
|
|
|
|
|
const NamedDecl *ND = Declaration;
|
|
|
|
|
Result.addParentContext(ND->getDeclContext());
|
|
|
|
|
|
|
|
|
|
if (IncludeBriefComments) {
|
|
|
|
@ -2566,7 +2575,7 @@ CodeCompletionResult::CreateCodeCompletionString(ASTContext &Ctx,
|
|
|
|
|
|
|
|
|
|
AddResultTypeChunk(Ctx, Policy, ND, Result);
|
|
|
|
|
|
|
|
|
|
if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) {
|
|
|
|
|
if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) {
|
|
|
|
|
AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
|
|
|
|
|
Ctx, Policy);
|
|
|
|
|
AddTypedNameChunk(Ctx, Policy, ND, Result);
|
|
|
|
@ -2577,7 +2586,7 @@ CodeCompletionResult::CreateCodeCompletionString(ASTContext &Ctx,
|
|
|
|
|
return Result.TakeString();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND)) {
|
|
|
|
|
if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND)) {
|
|
|
|
|
AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
|
|
|
|
|
Ctx, Policy);
|
|
|
|
|
FunctionDecl *Function = FunTmpl->getTemplatedDecl();
|
|
|
|
@ -2631,7 +2640,7 @@ CodeCompletionResult::CreateCodeCompletionString(ASTContext &Ctx,
|
|
|
|
|
return Result.TakeString();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (TemplateDecl *Template = dyn_cast<TemplateDecl>(ND)) {
|
|
|
|
|
if (const TemplateDecl *Template = dyn_cast<TemplateDecl>(ND)) {
|
|
|
|
|
AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
|
|
|
|
|
Ctx, Policy);
|
|
|
|
|
Result.AddTypedTextChunk(
|
|
|
|
@ -2642,7 +2651,7 @@ CodeCompletionResult::CreateCodeCompletionString(ASTContext &Ctx,
|
|
|
|
|
return Result.TakeString();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) {
|
|
|
|
|
if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) {
|
|
|
|
|
Selector Sel = Method->getSelector();
|
|
|
|
|
if (Sel.isUnarySelector()) {
|
|
|
|
|
Result.AddTypedTextChunk(Result.getAllocator().CopyString(
|
|
|
|
@ -2663,8 +2672,8 @@ CodeCompletionResult::CreateCodeCompletionString(ASTContext &Ctx,
|
|
|
|
|
Result.AddTypedTextChunk("");
|
|
|
|
|
}
|
|
|
|
|
unsigned Idx = 0;
|
|
|
|
|
for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
|
|
|
|
|
PEnd = Method->param_end();
|
|
|
|
|
for (ObjCMethodDecl::param_const_iterator P = Method->param_begin(),
|
|
|
|
|
PEnd = Method->param_end();
|
|
|
|
|
P != PEnd; (void)++P, ++Idx) {
|
|
|
|
|
if (Idx > 0) {
|
|
|
|
|
std::string Keyword;
|
|
|
|
@ -5284,7 +5293,7 @@ static QualType getPreferredArgumentTypeForMessageSend(ResultBuilder &Results,
|
|
|
|
|
if (R.Kind == Result::RK_Declaration &&
|
|
|
|
|
isa<ObjCMethodDecl>(R.Declaration)) {
|
|
|
|
|
if (R.Priority <= BestPriority) {
|
|
|
|
|
ObjCMethodDecl *Method = cast<ObjCMethodDecl>(R.Declaration);
|
|
|
|
|
const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(R.Declaration);
|
|
|
|
|
if (NumSelIdents <= Method->param_size()) {
|
|
|
|
|
QualType MyPreferredType = Method->param_begin()[NumSelIdents - 1]
|
|
|
|
|
->getType();
|
|
|
|
|