forked from OSchip/llvm-project
Push nested-name-specifier source-location information into
pseudo-destructor expressions. Also, clean up some template-instantiation and type-checking issues with pseudo-destructors. llvm-svn: 126498
This commit is contained in:
parent
40c5e1ada7
commit
a6ce608b97
|
@ -1331,13 +1331,9 @@ class CXXPseudoDestructorExpr : public Expr {
|
|||
|
||||
/// \brief The location of the '.' or '->' operator.
|
||||
SourceLocation OperatorLoc;
|
||||
|
||||
|
||||
/// \brief The nested-name-specifier that follows the operator, if present.
|
||||
NestedNameSpecifier *Qualifier;
|
||||
|
||||
/// \brief The source range that covers the nested-name-specifier, if
|
||||
/// present.
|
||||
SourceRange QualifierRange;
|
||||
NestedNameSpecifierLoc QualifierLoc;
|
||||
|
||||
/// \brief The type that precedes the '::' in a qualified pseudo-destructor
|
||||
/// expression.
|
||||
|
@ -1354,11 +1350,12 @@ class CXXPseudoDestructorExpr : public Expr {
|
|||
/// resolve the name.
|
||||
PseudoDestructorTypeStorage DestroyedType;
|
||||
|
||||
friend class ASTStmtReader;
|
||||
|
||||
public:
|
||||
CXXPseudoDestructorExpr(ASTContext &Context,
|
||||
Expr *Base, bool isArrow, SourceLocation OperatorLoc,
|
||||
NestedNameSpecifier *Qualifier,
|
||||
SourceRange QualifierRange,
|
||||
NestedNameSpecifierLoc QualifierLoc,
|
||||
TypeSourceInfo *ScopeType,
|
||||
SourceLocation ColonColonLoc,
|
||||
SourceLocation TildeLoc,
|
||||
|
@ -1366,36 +1363,32 @@ public:
|
|||
|
||||
explicit CXXPseudoDestructorExpr(EmptyShell Shell)
|
||||
: Expr(CXXPseudoDestructorExprClass, Shell),
|
||||
Base(0), IsArrow(false), Qualifier(0), ScopeType(0) { }
|
||||
Base(0), IsArrow(false), QualifierLoc(), ScopeType(0) { }
|
||||
|
||||
void setBase(Expr *E) { Base = E; }
|
||||
Expr *getBase() const { return cast<Expr>(Base); }
|
||||
|
||||
/// \brief Determines whether this member expression actually had
|
||||
/// a C++ nested-name-specifier prior to the name of the member, e.g.,
|
||||
/// x->Base::foo.
|
||||
bool hasQualifier() const { return Qualifier != 0; }
|
||||
|
||||
/// \brief If the member name was qualified, retrieves the source range of
|
||||
/// the nested-name-specifier that precedes the member name. Otherwise,
|
||||
/// returns an empty source range.
|
||||
SourceRange getQualifierRange() const { return QualifierRange; }
|
||||
void setQualifierRange(SourceRange R) { QualifierRange = R; }
|
||||
bool hasQualifier() const { return QualifierLoc; }
|
||||
|
||||
/// \brief Retrieves the nested-name-specifier that qualifies the type name,
|
||||
/// with source-location information.
|
||||
NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
|
||||
|
||||
/// \brief If the member name was qualified, retrieves the
|
||||
/// nested-name-specifier that precedes the member name. Otherwise, returns
|
||||
/// NULL.
|
||||
NestedNameSpecifier *getQualifier() const { return Qualifier; }
|
||||
void setQualifier(NestedNameSpecifier *NNS) { Qualifier = NNS; }
|
||||
NestedNameSpecifier *getQualifier() const {
|
||||
return QualifierLoc.getNestedNameSpecifier();
|
||||
}
|
||||
|
||||
/// \brief Determine whether this pseudo-destructor expression was written
|
||||
/// using an '->' (otherwise, it used a '.').
|
||||
bool isArrow() const { return IsArrow; }
|
||||
void setArrow(bool A) { IsArrow = A; }
|
||||
|
||||
/// \brief Retrieve the location of the '.' or '->' operator.
|
||||
SourceLocation getOperatorLoc() const { return OperatorLoc; }
|
||||
void setOperatorLoc(SourceLocation L) { OperatorLoc = L; }
|
||||
|
||||
/// \brief Retrieve the scope type in a qualified pseudo-destructor
|
||||
/// expression.
|
||||
|
@ -1407,16 +1400,13 @@ public:
|
|||
/// nested-name-specifier. It is stored as the "scope type" of the pseudo-
|
||||
/// destructor expression.
|
||||
TypeSourceInfo *getScopeTypeInfo() const { return ScopeType; }
|
||||
void setScopeTypeInfo(TypeSourceInfo *Info) { ScopeType = Info; }
|
||||
|
||||
/// \brief Retrieve the location of the '::' in a qualified pseudo-destructor
|
||||
/// expression.
|
||||
SourceLocation getColonColonLoc() const { return ColonColonLoc; }
|
||||
void setColonColonLoc(SourceLocation L) { ColonColonLoc = L; }
|
||||
|
||||
/// \brief Retrieve the location of the '~'.
|
||||
SourceLocation getTildeLoc() const { return TildeLoc; }
|
||||
void setTildeLoc(SourceLocation L) { TildeLoc = L; }
|
||||
|
||||
/// \brief Retrieve the source location information for the type
|
||||
/// being destroyed.
|
||||
|
|
|
@ -1846,7 +1846,7 @@ DEF_TRAVERSE_STMT(CXXDeleteExpr, { })
|
|||
DEF_TRAVERSE_STMT(ExprWithCleanups, { })
|
||||
DEF_TRAVERSE_STMT(CXXNullPtrLiteralExpr, { })
|
||||
DEF_TRAVERSE_STMT(CXXPseudoDestructorExpr, {
|
||||
TRY_TO(TraverseNestedNameSpecifier(S->getQualifier()));
|
||||
TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
|
||||
if (TypeSourceInfo *ScopeInfo = S->getScopeTypeInfo())
|
||||
TRY_TO(TraverseTypeLoc(ScopeInfo->getTypeLoc()));
|
||||
if (TypeSourceInfo *DestroyedTypeInfo = S->getDestroyedTypeInfo())
|
||||
|
|
|
@ -128,10 +128,10 @@ PseudoDestructorTypeStorage::PseudoDestructorTypeStorage(TypeSourceInfo *Info)
|
|||
}
|
||||
|
||||
CXXPseudoDestructorExpr::CXXPseudoDestructorExpr(ASTContext &Context,
|
||||
Expr *Base, bool isArrow, SourceLocation OperatorLoc,
|
||||
NestedNameSpecifier *Qualifier, SourceRange QualifierRange,
|
||||
TypeSourceInfo *ScopeType, SourceLocation ColonColonLoc,
|
||||
SourceLocation TildeLoc, PseudoDestructorTypeStorage DestroyedType)
|
||||
Expr *Base, bool isArrow, SourceLocation OperatorLoc,
|
||||
NestedNameSpecifierLoc QualifierLoc, TypeSourceInfo *ScopeType,
|
||||
SourceLocation ColonColonLoc, SourceLocation TildeLoc,
|
||||
PseudoDestructorTypeStorage DestroyedType)
|
||||
: Expr(CXXPseudoDestructorExprClass,
|
||||
Context.getPointerType(Context.getFunctionType(Context.VoidTy, 0, 0,
|
||||
FunctionProtoType::ExtProtoInfo())),
|
||||
|
@ -142,15 +142,16 @@ CXXPseudoDestructorExpr::CXXPseudoDestructorExpr(ASTContext &Context,
|
|||
/*isValueDependent=*/Base->isValueDependent(),
|
||||
// ContainsUnexpandedParameterPack
|
||||
(Base->containsUnexpandedParameterPack() ||
|
||||
(Qualifier && Qualifier->containsUnexpandedParameterPack()) ||
|
||||
(QualifierLoc &&
|
||||
QualifierLoc.getNestedNameSpecifier()
|
||||
->containsUnexpandedParameterPack()) ||
|
||||
(ScopeType &&
|
||||
ScopeType->getType()->containsUnexpandedParameterPack()) ||
|
||||
(DestroyedType.getTypeSourceInfo() &&
|
||||
DestroyedType.getTypeSourceInfo()->getType()
|
||||
->containsUnexpandedParameterPack()))),
|
||||
Base(static_cast<Stmt *>(Base)), IsArrow(isArrow),
|
||||
OperatorLoc(OperatorLoc), Qualifier(Qualifier),
|
||||
QualifierRange(QualifierRange),
|
||||
OperatorLoc(OperatorLoc), QualifierLoc(QualifierLoc),
|
||||
ScopeType(ScopeType), ColonColonLoc(ColonColonLoc), TildeLoc(TildeLoc),
|
||||
DestroyedType(DestroyedType) { }
|
||||
|
||||
|
|
|
@ -3664,7 +3664,7 @@ ExprResult Sema::BuildPseudoDestructorExpr(Expr *Base,
|
|||
Expr *Result
|
||||
= new (Context) CXXPseudoDestructorExpr(Context, Base,
|
||||
OpKind == tok::arrow, OpLoc,
|
||||
SS.getScopeRep(), SS.getRange(),
|
||||
SS.getWithLocInContext(Context),
|
||||
ScopeTypeInfo,
|
||||
CCLoc,
|
||||
TildeLoc,
|
||||
|
@ -3786,7 +3786,7 @@ ExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, Expr *Base,
|
|||
if (FirstTypeName.getKind() == UnqualifiedId::IK_Identifier) {
|
||||
ParsedType T = getTypeName(*FirstTypeName.Identifier,
|
||||
FirstTypeName.StartLocation,
|
||||
S, &SS, false, false, ObjectTypePtrForLookup);
|
||||
S, &SS, true, false, ObjectTypePtrForLookup);
|
||||
if (!T) {
|
||||
Diag(FirstTypeName.StartLocation,
|
||||
diag::err_pseudo_dtor_destructor_non_type)
|
||||
|
|
|
@ -1284,13 +1284,12 @@ public:
|
|||
/// By default, performs semantic analysis to build the new expression.
|
||||
/// Subclasses may override this routine to provide different behavior.
|
||||
ExprResult RebuildCXXPseudoDestructorExpr(Expr *Base,
|
||||
SourceLocation OperatorLoc,
|
||||
bool isArrow,
|
||||
NestedNameSpecifier *Qualifier,
|
||||
SourceRange QualifierRange,
|
||||
TypeSourceInfo *ScopeType,
|
||||
SourceLocation CCLoc,
|
||||
SourceLocation TildeLoc,
|
||||
SourceLocation OperatorLoc,
|
||||
bool isArrow,
|
||||
CXXScopeSpec &SS,
|
||||
TypeSourceInfo *ScopeType,
|
||||
SourceLocation CCLoc,
|
||||
SourceLocation TildeLoc,
|
||||
PseudoDestructorTypeStorage Destroyed);
|
||||
|
||||
/// \brief Build a new unary operator expression.
|
||||
|
@ -2597,9 +2596,7 @@ TreeTransform<Derived>::TransformNestedNameSpecifierLoc(
|
|||
}
|
||||
}
|
||||
|
||||
// The object type and qualifier-in-scope really apply to the
|
||||
// leftmost entity.
|
||||
ObjectType = QualType();
|
||||
// The qualifier-in-scope only applies to the leftmost entity.
|
||||
FirstQualifierInScope = 0;
|
||||
}
|
||||
|
||||
|
@ -6612,21 +6609,22 @@ TreeTransform<Derived>::TransformCXXPseudoDestructorExpr(
|
|||
return ExprError();
|
||||
|
||||
QualType ObjectType = ObjectTypePtr.get();
|
||||
NestedNameSpecifier *Qualifier = E->getQualifier();
|
||||
if (Qualifier) {
|
||||
Qualifier
|
||||
= getDerived().TransformNestedNameSpecifier(E->getQualifier(),
|
||||
E->getQualifierRange(),
|
||||
ObjectType);
|
||||
if (!Qualifier)
|
||||
NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc();
|
||||
if (QualifierLoc) {
|
||||
QualifierLoc
|
||||
= getDerived().TransformNestedNameSpecifierLoc(QualifierLoc, ObjectType);
|
||||
if (!QualifierLoc)
|
||||
return ExprError();
|
||||
}
|
||||
CXXScopeSpec SS;
|
||||
SS.Adopt(QualifierLoc);
|
||||
|
||||
PseudoDestructorTypeStorage Destroyed;
|
||||
if (E->getDestroyedTypeInfo()) {
|
||||
TypeSourceInfo *DestroyedTypeInfo
|
||||
= getDerived().TransformTypeInObjectScope(E->getDestroyedTypeInfo(),
|
||||
ObjectType, 0, Qualifier);
|
||||
ObjectType, 0,
|
||||
QualifierLoc.getNestedNameSpecifier());
|
||||
if (!DestroyedTypeInfo)
|
||||
return ExprError();
|
||||
Destroyed = DestroyedTypeInfo;
|
||||
|
@ -6637,10 +6635,6 @@ TreeTransform<Derived>::TransformCXXPseudoDestructorExpr(
|
|||
E->getDestroyedTypeLoc());
|
||||
} else {
|
||||
// Look for a destructor known with the given name.
|
||||
CXXScopeSpec SS;
|
||||
if (Qualifier)
|
||||
SS.MakeTrivial(SemaRef.Context, Qualifier, E->getQualifierRange());
|
||||
|
||||
ParsedType T = SemaRef.getDestructorName(E->getTildeLoc(),
|
||||
*E->getDestroyedTypeIdentifier(),
|
||||
E->getDestroyedTypeLoc(),
|
||||
|
@ -6665,8 +6659,7 @@ TreeTransform<Derived>::TransformCXXPseudoDestructorExpr(
|
|||
return getDerived().RebuildCXXPseudoDestructorExpr(Base.get(),
|
||||
E->getOperatorLoc(),
|
||||
E->isArrow(),
|
||||
Qualifier,
|
||||
E->getQualifierRange(),
|
||||
SS,
|
||||
ScopeTypeInfo,
|
||||
E->getColonColonLoc(),
|
||||
E->getTildeLoc(),
|
||||
|
@ -7930,16 +7923,11 @@ ExprResult
|
|||
TreeTransform<Derived>::RebuildCXXPseudoDestructorExpr(Expr *Base,
|
||||
SourceLocation OperatorLoc,
|
||||
bool isArrow,
|
||||
NestedNameSpecifier *Qualifier,
|
||||
SourceRange QualifierRange,
|
||||
CXXScopeSpec &SS,
|
||||
TypeSourceInfo *ScopeType,
|
||||
SourceLocation CCLoc,
|
||||
SourceLocation TildeLoc,
|
||||
PseudoDestructorTypeStorage Destroyed) {
|
||||
CXXScopeSpec SS;
|
||||
if (Qualifier)
|
||||
SS.MakeTrivial(SemaRef.Context, Qualifier, QualifierRange);
|
||||
|
||||
QualType BaseType = Base->getType();
|
||||
if (Base->isTypeDependent() || Destroyed.getIdentifier() ||
|
||||
(!isArrow && !BaseType->getAs<RecordType>()) ||
|
||||
|
|
|
@ -1167,14 +1167,13 @@ void ASTStmtReader::VisitCXXDeleteExpr(CXXDeleteExpr *E) {
|
|||
void ASTStmtReader::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
|
||||
VisitExpr(E);
|
||||
|
||||
E->setBase(Reader.ReadSubExpr());
|
||||
E->setArrow(Record[Idx++]);
|
||||
E->setOperatorLoc(ReadSourceLocation(Record, Idx));
|
||||
E->setQualifier(Reader.ReadNestedNameSpecifier(Record, Idx));
|
||||
E->setQualifierRange(ReadSourceRange(Record, Idx));
|
||||
E->setScopeTypeInfo(GetTypeSourceInfo(Record, Idx));
|
||||
E->setColonColonLoc(ReadSourceLocation(Record, Idx));
|
||||
E->setTildeLoc(ReadSourceLocation(Record, Idx));
|
||||
E->Base = Reader.ReadSubExpr();
|
||||
E->IsArrow = Record[Idx++];
|
||||
E->OperatorLoc = ReadSourceLocation(Record, Idx);
|
||||
E->QualifierLoc = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx);
|
||||
E->ScopeType = GetTypeSourceInfo(Record, Idx);
|
||||
E->ColonColonLoc = ReadSourceLocation(Record, Idx);
|
||||
E->TildeLoc = ReadSourceLocation(Record, Idx);
|
||||
|
||||
IdentifierInfo *II = Reader.GetIdentifierInfo(Record, Idx);
|
||||
if (II)
|
||||
|
|
|
@ -1150,8 +1150,7 @@ void ASTStmtWriter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
|
|||
Writer.AddStmt(E->getBase());
|
||||
Record.push_back(E->isArrow());
|
||||
Writer.AddSourceLocation(E->getOperatorLoc(), Record);
|
||||
Writer.AddNestedNameSpecifier(E->getQualifier(), Record);
|
||||
Writer.AddSourceRange(E->getQualifierRange(), Record);
|
||||
Writer.AddNestedNameSpecifierLoc(E->getQualifierLoc(), Record);
|
||||
Writer.AddTypeSourceInfo(E->getScopeTypeInfo(), Record);
|
||||
Writer.AddSourceLocation(E->getColonColonLoc(), Record);
|
||||
Writer.AddSourceLocation(E->getTildeLoc(), Record);
|
||||
|
|
|
@ -51,7 +51,14 @@ namespace outer {
|
|||
using namespace outer_alias::inner::secret;
|
||||
namespace super_secret = outer_alias::inner::secret;
|
||||
|
||||
// RUN: c-index-test -test-annotate-tokens=%s:13:1:53:1 %s | FileCheck %s
|
||||
template<typename T>
|
||||
struct X3 {
|
||||
void f(T *t) {
|
||||
t->::outer_alias::inner::template vector<T>::~vector<T>();
|
||||
}
|
||||
};
|
||||
|
||||
// RUN: c-index-test -test-annotate-tokens=%s:13:1:60:1 %s | FileCheck %s
|
||||
|
||||
// CHECK: Keyword: "using" [14:1 - 14:6] UsingDeclaration=vector[4:12]
|
||||
// CHECK: Identifier: "outer_alias" [14:7 - 14:18] NamespaceRef=outer_alias:10:11
|
||||
|
@ -120,3 +127,24 @@ namespace super_secret = outer_alias::inner::secret;
|
|||
// CHECK: Identifier: "secret" [52:46 - 52:52] NamespaceRef=secret:46:15
|
||||
// CHECK: Punctuation: ";" [52:52 - 52:53]
|
||||
|
||||
// Pseudo-destructor
|
||||
// CHECK: Identifier: "t" [57:5 - 57:6] DeclRefExpr=t:56:13
|
||||
// CHECK: Punctuation: "->" [57:6 - 57:8] UnexposedExpr=
|
||||
// CHECK: Punctuation: "::" [57:8 - 57:10] UnexposedExpr=
|
||||
// CHECK: Identifier: "outer_alias" [57:10 - 57:21] NamespaceRef=outer_alias:10:11
|
||||
// CHECK: Punctuation: "::" [57:21 - 57:23] UnexposedExpr=
|
||||
// CHECK: Identifier: "inner" [57:23 - 57:28] NamespaceRef=inner:45:13
|
||||
// CHECK: Punctuation: "::" [57:28 - 57:30] UnexposedExpr=
|
||||
// CHECK: Keyword: "template" [57:30 - 57:38] UnexposedExpr=
|
||||
// CHECK: Identifier: "vector" [57:39 - 57:45] TemplateRef=vector:4:12
|
||||
// CHECK: Punctuation: "<" [57:45 - 57:46] UnexposedExpr=
|
||||
// CHECK: Identifier: "T" [57:46 - 57:47] UnexposedExpr=
|
||||
// CHECK: Punctuation: ">" [57:47 - 57:48] UnexposedExpr=
|
||||
// CHECK: Punctuation: "::" [57:48 - 57:50] UnexposedExpr=
|
||||
// CHECK: Punctuation: "~" [57:50 - 57:51] UnexposedExpr=
|
||||
// CHECK: Identifier: "vector" [57:51 - 57:57] TemplateRef=vector:4:12
|
||||
// CHECK: Punctuation: "<" [57:57 - 57:58] UnexposedExpr=
|
||||
// CHECK: Identifier: "T" [57:58 - 57:59] UnexposedExpr=
|
||||
// CHECK: Punctuation: ">" [57:59 - 57:60] UnexposedExpr=
|
||||
// CHECK: Punctuation: "(" [57:60 - 57:61] CallExpr=
|
||||
// CHECK: Punctuation: ")" [57:61 - 57:62] CallExpr=
|
||||
|
|
|
@ -40,3 +40,24 @@ struct UnresolvedUsingTypenameDeclTester {
|
|||
|
||||
UnresolvedUsingTypenameDeclTester<int> UnresolvedUsingTypenameDeclCheck; // expected-note{{in instantiation of template class}}
|
||||
|
||||
|
||||
template<typename T, typename U>
|
||||
struct PseudoDestructorExprTester {
|
||||
void f(T *t) {
|
||||
t->T::template Inner<typename add_reference<U>::type
|
||||
* // expected-error{{as a pointer to a reference of type}}
|
||||
>::Blarg::~Blarg();
|
||||
}
|
||||
};
|
||||
|
||||
struct HasInnerTemplate {
|
||||
template<typename T>
|
||||
struct Inner;
|
||||
|
||||
typedef HasInnerTemplate T;
|
||||
};
|
||||
|
||||
void PseudoDestructorExprCheck(
|
||||
PseudoDestructorExprTester<HasInnerTemplate, float> tester) {
|
||||
tester.f(0); // expected-note{{in instantiation of member function}}
|
||||
}
|
||||
|
|
|
@ -140,6 +140,7 @@ public:
|
|||
DeclRefExprPartsKind, LabelRefVisitKind,
|
||||
ExplicitTemplateArgsVisitKind,
|
||||
NestedNameSpecifierVisitKind,
|
||||
NestedNameSpecifierLocVisitKind,
|
||||
DeclarationNameInfoVisitKind,
|
||||
MemberRefVisitKind, SizeOfPackExprPartsKind };
|
||||
protected:
|
||||
|
@ -1615,6 +1616,24 @@ public:
|
|||
return SourceRange(A, B);
|
||||
}
|
||||
};
|
||||
|
||||
class NestedNameSpecifierLocVisit : public VisitorJob {
|
||||
public:
|
||||
NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
|
||||
: VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
|
||||
Qualifier.getNestedNameSpecifier(),
|
||||
Qualifier.getOpaqueData()) { }
|
||||
|
||||
static bool classof(const VisitorJob *VJ) {
|
||||
return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
|
||||
}
|
||||
|
||||
NestedNameSpecifierLoc get() const {
|
||||
return NestedNameSpecifierLoc(static_cast<NestedNameSpecifier*>(data[0]),
|
||||
data[1]);
|
||||
}
|
||||
};
|
||||
|
||||
class DeclarationNameInfoVisit : public VisitorJob {
|
||||
public:
|
||||
DeclarationNameInfoVisit(Stmt *S, CXCursor parent)
|
||||
|
@ -1697,6 +1716,7 @@ public:
|
|||
private:
|
||||
void AddDeclarationNameInfo(Stmt *S);
|
||||
void AddNestedNameSpecifier(NestedNameSpecifier *NS, SourceRange R);
|
||||
void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
|
||||
void AddExplicitTemplateArgs(const ExplicitTemplateArgumentList *A);
|
||||
void AddMemberRef(FieldDecl *D, SourceLocation L);
|
||||
void AddStmt(Stmt *S);
|
||||
|
@ -1716,6 +1736,13 @@ void EnqueueVisitor::AddNestedNameSpecifier(NestedNameSpecifier *N,
|
|||
if (N)
|
||||
WL.push_back(NestedNameSpecifierVisit(N, R, Parent));
|
||||
}
|
||||
|
||||
void
|
||||
EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
|
||||
if (Qualifier)
|
||||
WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
|
||||
}
|
||||
|
||||
void EnqueueVisitor::AddStmt(Stmt *S) {
|
||||
if (S)
|
||||
WL.push_back(StmtVisit(S, Parent));
|
||||
|
@ -1800,8 +1827,8 @@ void EnqueueVisitor::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
|
|||
// but isn't.
|
||||
AddTypeLoc(E->getScopeTypeInfo());
|
||||
// Visit the nested-name-specifier.
|
||||
if (NestedNameSpecifier *Qualifier = E->getQualifier())
|
||||
AddNestedNameSpecifier(Qualifier, E->getQualifierRange());
|
||||
if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
|
||||
AddNestedNameSpecifierLoc(QualifierLoc);
|
||||
// Visit base expression.
|
||||
AddStmt(E->getBase());
|
||||
}
|
||||
|
@ -2048,12 +2075,21 @@ bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
|
|||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
case VisitorJob::NestedNameSpecifierVisitKind: {
|
||||
NestedNameSpecifierVisit *V = cast<NestedNameSpecifierVisit>(&LI);
|
||||
if (VisitNestedNameSpecifier(V->get(), V->getSourceRange()))
|
||||
return true;
|
||||
continue;
|
||||
}
|
||||
|
||||
case VisitorJob::NestedNameSpecifierLocVisitKind: {
|
||||
NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
|
||||
if (VisitNestedNameSpecifierLoc(V->get()))
|
||||
return true;
|
||||
continue;
|
||||
}
|
||||
|
||||
case VisitorJob::DeclarationNameInfoVisitKind: {
|
||||
if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
|
||||
->get()))
|
||||
|
|
Loading…
Reference in New Issue