зеркало из https://github.com/microsoft/clang-1.git
Update UsingDecl, UnresolvedUsingTypenameDecl, and
UnresolvedUsingValueDecl to use NestedNameSpecifierLoc rather than the extremely-lossy NestedNameSpecifier/SourceRange pair it used to use, improving source-location information. Various infrastructure updates to support NestedNameSpecifierLoc: - AST/PCH (de-)serialization - Recursive AST visitor - libclang traversal (including the first tests of this functionality) git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@126459 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
670d6ed9f0
Коммит
dc355713be
|
@ -2002,15 +2002,11 @@ public:
|
|||
/// UsingDecl - Represents a C++ using-declaration. For example:
|
||||
/// using someNameSpace::someIdentifier;
|
||||
class UsingDecl : public NamedDecl {
|
||||
/// \brief The source range that covers the nested-name-specifier
|
||||
/// preceding the declaration name.
|
||||
SourceRange NestedNameRange;
|
||||
|
||||
/// \brief The source location of the "using" location itself.
|
||||
SourceLocation UsingLocation;
|
||||
|
||||
/// \brief Target nested name specifier.
|
||||
NestedNameSpecifier* TargetNestedName;
|
||||
/// \brief The nested-name-specifier that precedes the name.
|
||||
NestedNameSpecifierLoc QualifierLoc;
|
||||
|
||||
/// DNLoc - Provides source/type location info for the
|
||||
/// declaration name embedded in the ValueDecl base class.
|
||||
|
@ -2023,37 +2019,34 @@ class UsingDecl : public NamedDecl {
|
|||
// \brief Has 'typename' keyword.
|
||||
bool IsTypeName;
|
||||
|
||||
UsingDecl(DeclContext *DC, SourceRange NNR,
|
||||
SourceLocation UL, NestedNameSpecifier* TargetNNS,
|
||||
UsingDecl(DeclContext *DC, SourceLocation UL,
|
||||
NestedNameSpecifierLoc QualifierLoc,
|
||||
const DeclarationNameInfo &NameInfo, bool IsTypeNameArg)
|
||||
: NamedDecl(Using, DC, NameInfo.getLoc(), NameInfo.getName()),
|
||||
NestedNameRange(NNR), UsingLocation(UL), TargetNestedName(TargetNNS),
|
||||
UsingLocation(UL), QualifierLoc(QualifierLoc),
|
||||
DNLoc(NameInfo.getInfo()), FirstUsingShadow(0),IsTypeName(IsTypeNameArg) {
|
||||
}
|
||||
|
||||
public:
|
||||
/// \brief Returns the source range that covers the nested-name-specifier
|
||||
/// preceding the namespace name.
|
||||
SourceRange getNestedNameRange() const { return NestedNameRange; }
|
||||
|
||||
/// \brief Set the source range of the nested-name-specifier.
|
||||
void setNestedNameRange(SourceRange R) { NestedNameRange = R; }
|
||||
|
||||
// FIXME: Naming is inconsistent with other get*Loc functions.
|
||||
/// \brief Returns the source location of the "using" keyword.
|
||||
SourceLocation getUsingLocation() const { return UsingLocation; }
|
||||
|
||||
/// \brief Set the source location of the 'using' keyword.
|
||||
void setUsingLocation(SourceLocation L) { UsingLocation = L; }
|
||||
|
||||
/// \brief Get the target nested name declaration.
|
||||
NestedNameSpecifier* getTargetNestedNameDecl() const {
|
||||
return TargetNestedName;
|
||||
/// \brief Retrieve the nested-name-specifier that qualifies the name,
|
||||
/// with source-location information.
|
||||
NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
|
||||
|
||||
/// \brief Retrieve the nested-name-specifier that qualifies the name.
|
||||
NestedNameSpecifier *getQualifier() const {
|
||||
return QualifierLoc.getNestedNameSpecifier();
|
||||
}
|
||||
|
||||
/// \brief Set the target nested name declaration.
|
||||
void setTargetNestedNameDecl(NestedNameSpecifier *NNS) {
|
||||
TargetNestedName = NNS;
|
||||
/// \brief Retrieve the source range of the nested-name-specifier
|
||||
/// that qualifies the name.
|
||||
SourceRange getQualifierRange() const {
|
||||
return QualifierLoc.getSourceRange();
|
||||
}
|
||||
|
||||
DeclarationNameInfo getNameInfo() const {
|
||||
|
@ -2119,8 +2112,8 @@ public:
|
|||
void removeShadowDecl(UsingShadowDecl *S);
|
||||
|
||||
static UsingDecl *Create(ASTContext &C, DeclContext *DC,
|
||||
SourceRange NNR, SourceLocation UsingL,
|
||||
NestedNameSpecifier* TargetNNS,
|
||||
SourceLocation UsingL,
|
||||
NestedNameSpecifierLoc QualifierLoc,
|
||||
const DeclarationNameInfo &NameInfo,
|
||||
bool IsTypeNameArg);
|
||||
|
||||
|
@ -2145,61 +2138,55 @@ public:
|
|||
/// using Base<T>::foo;
|
||||
/// };
|
||||
class UnresolvedUsingValueDecl : public ValueDecl {
|
||||
/// \brief The source range that covers the nested-name-specifier
|
||||
/// preceding the declaration name.
|
||||
SourceRange TargetNestedNameRange;
|
||||
|
||||
/// \brief The source location of the 'using' keyword
|
||||
SourceLocation UsingLocation;
|
||||
|
||||
NestedNameSpecifier *TargetNestedNameSpecifier;
|
||||
/// \brief The nested-name-specifier that precedes the name.
|
||||
NestedNameSpecifierLoc QualifierLoc;
|
||||
|
||||
/// DNLoc - Provides source/type location info for the
|
||||
/// declaration name embedded in the ValueDecl base class.
|
||||
DeclarationNameLoc DNLoc;
|
||||
|
||||
UnresolvedUsingValueDecl(DeclContext *DC, QualType Ty,
|
||||
SourceLocation UsingLoc, SourceRange TargetNNR,
|
||||
NestedNameSpecifier *TargetNNS,
|
||||
SourceLocation UsingLoc,
|
||||
NestedNameSpecifierLoc QualifierLoc,
|
||||
const DeclarationNameInfo &NameInfo)
|
||||
: ValueDecl(UnresolvedUsingValue, DC,
|
||||
NameInfo.getLoc(), NameInfo.getName(), Ty),
|
||||
TargetNestedNameRange(TargetNNR), UsingLocation(UsingLoc),
|
||||
TargetNestedNameSpecifier(TargetNNS), DNLoc(NameInfo.getInfo())
|
||||
UsingLocation(UsingLoc), QualifierLoc(QualifierLoc),
|
||||
DNLoc(NameInfo.getInfo())
|
||||
{ }
|
||||
|
||||
public:
|
||||
/// \brief Returns the source range that covers the nested-name-specifier
|
||||
/// preceding the namespace name.
|
||||
SourceRange getTargetNestedNameRange() const { return TargetNestedNameRange; }
|
||||
|
||||
/// \brief Set the source range coverting the nested-name-specifier preceding
|
||||
/// the namespace name.
|
||||
void setTargetNestedNameRange(SourceRange R) { TargetNestedNameRange = R; }
|
||||
|
||||
/// \brief Get target nested name declaration.
|
||||
NestedNameSpecifier* getTargetNestedNameSpecifier() const {
|
||||
return TargetNestedNameSpecifier;
|
||||
}
|
||||
|
||||
/// \brief Set the nested name declaration.
|
||||
void setTargetNestedNameSpecifier(NestedNameSpecifier* NNS) {
|
||||
TargetNestedNameSpecifier = NNS;
|
||||
}
|
||||
|
||||
/// \brief Returns the source location of the 'using' keyword.
|
||||
SourceLocation getUsingLoc() const { return UsingLocation; }
|
||||
|
||||
/// \brief Set the source location of the 'using' keyword.
|
||||
void setUsingLoc(SourceLocation L) { UsingLocation = L; }
|
||||
|
||||
/// \brief Retrieve the nested-name-specifier that qualifies the name,
|
||||
/// with source-location information.
|
||||
NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
|
||||
|
||||
/// \brief Retrieve the nested-name-specifier that qualifies the name.
|
||||
NestedNameSpecifier *getQualifier() const {
|
||||
return QualifierLoc.getNestedNameSpecifier();
|
||||
}
|
||||
|
||||
/// \brief Retrieve the source range of the nested-name-specifier
|
||||
/// that qualifies the name.
|
||||
SourceRange getQualifierRange() const {
|
||||
return QualifierLoc.getSourceRange();
|
||||
}
|
||||
|
||||
DeclarationNameInfo getNameInfo() const {
|
||||
return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc);
|
||||
}
|
||||
|
||||
static UnresolvedUsingValueDecl *
|
||||
Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc,
|
||||
SourceRange TargetNNR, NestedNameSpecifier *TargetNNS,
|
||||
NestedNameSpecifierLoc QualifierLoc,
|
||||
const DeclarationNameInfo &NameInfo);
|
||||
|
||||
SourceRange getSourceRange() const {
|
||||
|
@ -2224,49 +2211,52 @@ public:
|
|||
/// The type associated with a unresolved using typename decl is
|
||||
/// currently always a typename type.
|
||||
class UnresolvedUsingTypenameDecl : public TypeDecl {
|
||||
/// \brief The source range that covers the nested-name-specifier
|
||||
/// preceding the declaration name.
|
||||
SourceRange TargetNestedNameRange;
|
||||
|
||||
/// \brief The source location of the 'using' keyword
|
||||
SourceLocation UsingLocation;
|
||||
|
||||
/// \brief The source location of the 'typename' keyword
|
||||
SourceLocation TypenameLocation;
|
||||
|
||||
NestedNameSpecifier *TargetNestedNameSpecifier;
|
||||
/// \brief The nested-name-specifier that precedes the name.
|
||||
NestedNameSpecifierLoc QualifierLoc;
|
||||
|
||||
UnresolvedUsingTypenameDecl(DeclContext *DC, SourceLocation UsingLoc,
|
||||
SourceLocation TypenameLoc,
|
||||
SourceRange TargetNNR, NestedNameSpecifier *TargetNNS,
|
||||
SourceLocation TargetNameLoc, IdentifierInfo *TargetName)
|
||||
SourceLocation TypenameLoc,
|
||||
NestedNameSpecifierLoc QualifierLoc,
|
||||
SourceLocation TargetNameLoc,
|
||||
IdentifierInfo *TargetName)
|
||||
: TypeDecl(UnresolvedUsingTypename, DC, TargetNameLoc, TargetName),
|
||||
TargetNestedNameRange(TargetNNR), UsingLocation(UsingLoc),
|
||||
TypenameLocation(TypenameLoc), TargetNestedNameSpecifier(TargetNNS)
|
||||
{ }
|
||||
UsingLocation(UsingLoc), TypenameLocation(TypenameLoc),
|
||||
QualifierLoc(QualifierLoc) { }
|
||||
|
||||
friend class ASTDeclReader;
|
||||
|
||||
public:
|
||||
/// \brief Returns the source range that covers the nested-name-specifier
|
||||
/// preceding the namespace name.
|
||||
SourceRange getTargetNestedNameRange() const { return TargetNestedNameRange; }
|
||||
|
||||
/// \brief Get target nested name declaration.
|
||||
NestedNameSpecifier* getTargetNestedNameSpecifier() {
|
||||
return TargetNestedNameSpecifier;
|
||||
}
|
||||
|
||||
/// \brief Returns the source location of the 'using' keyword.
|
||||
SourceLocation getUsingLoc() const { return UsingLocation; }
|
||||
|
||||
/// \brief Returns the source location of the 'typename' keyword.
|
||||
SourceLocation getTypenameLoc() const { return TypenameLocation; }
|
||||
|
||||
/// \brief Retrieve the nested-name-specifier that qualifies the name,
|
||||
/// with source-location information.
|
||||
NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
|
||||
|
||||
/// \brief Retrieve the nested-name-specifier that qualifies the name.
|
||||
NestedNameSpecifier *getQualifier() const {
|
||||
return QualifierLoc.getNestedNameSpecifier();
|
||||
}
|
||||
|
||||
/// \brief Retrieve the source range of the nested-name-specifier
|
||||
/// that qualifies the name.
|
||||
SourceRange getQualifierRange() const {
|
||||
return QualifierLoc.getSourceRange();
|
||||
}
|
||||
|
||||
// FIXME: DeclarationNameInfo
|
||||
static UnresolvedUsingTypenameDecl *
|
||||
Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc,
|
||||
SourceLocation TypenameLoc,
|
||||
SourceRange TargetNNR, NestedNameSpecifier *TargetNNS,
|
||||
SourceLocation TypenameLoc, NestedNameSpecifierLoc QualifierLoc,
|
||||
SourceLocation TargetNameLoc, DeclarationName TargetName);
|
||||
|
||||
SourceRange getSourceRange() const {
|
||||
|
|
|
@ -30,6 +30,7 @@ class NamespaceDecl;
|
|||
class IdentifierInfo;
|
||||
struct PrintingPolicy;
|
||||
class Type;
|
||||
class TypeLoc;
|
||||
class LangOptions;
|
||||
|
||||
/// \brief Represents a C++ nested name specifier, such as
|
||||
|
@ -245,7 +246,7 @@ public:
|
|||
/// For example, if this instance refers to a nested-name-specifier
|
||||
/// \c ::std::vector<int>::, the returned source range would cover
|
||||
/// from the initial '::' to the last '::'.
|
||||
SourceRange getSourceRange();
|
||||
SourceRange getSourceRange() const;
|
||||
|
||||
/// \brief Retrieve the source range covering just the last part of
|
||||
/// this nested-name-specifier, not including the prefix.
|
||||
|
@ -253,7 +254,19 @@ public:
|
|||
/// For example, if this instance refers to a nested-name-specifier
|
||||
/// \c ::std::vector<int>::, the returned source range would cover
|
||||
/// from "vector" to the last '::'.
|
||||
SourceRange getLocalSourceRange();
|
||||
SourceRange getLocalSourceRange() const;
|
||||
|
||||
/// \brief Retrieve the location of the beginning of this
|
||||
/// nested-name-specifier.
|
||||
SourceLocation getBeginLoc() const {
|
||||
return getSourceRange().getBegin();
|
||||
}
|
||||
|
||||
/// \brief Retrieve the location of the end of this
|
||||
/// nested-name-specifier.
|
||||
SourceLocation getEndLoc() const {
|
||||
return getSourceRange().getEnd();
|
||||
}
|
||||
|
||||
/// \brief Return the prefix of this nested-name-specifier.
|
||||
///
|
||||
|
@ -267,7 +280,11 @@ public:
|
|||
|
||||
return NestedNameSpecifierLoc(Qualifier->getPrefix(), Data);
|
||||
}
|
||||
|
||||
|
||||
/// \brief For a nested-name-specifier that refers to a type,
|
||||
/// retrieve the type with source-location information.
|
||||
TypeLoc getTypeLoc() const;
|
||||
|
||||
/// \brief Determines the data length for the entire
|
||||
/// nested-name-specifier.
|
||||
unsigned getDataLength() const { return getDataLength(Qualifier); }
|
||||
|
|
|
@ -181,6 +181,12 @@ public:
|
|||
/// \returns false if the visitation was terminated early, true otherwise.
|
||||
bool TraverseNestedNameSpecifier(NestedNameSpecifier *NNS);
|
||||
|
||||
/// \brief Recursively visit a C++ nested-name-specifier with location
|
||||
/// information.
|
||||
///
|
||||
/// \returns false if the visitation was terminated early, true otherwise.
|
||||
bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS);
|
||||
|
||||
/// \brief Recursively visit a template name and dispatch to the
|
||||
/// appropriate method.
|
||||
///
|
||||
|
@ -514,6 +520,31 @@ bool RecursiveASTVisitor<Derived>::TraverseNestedNameSpecifier(
|
|||
return true;
|
||||
}
|
||||
|
||||
template<typename Derived>
|
||||
bool RecursiveASTVisitor<Derived>::TraverseNestedNameSpecifierLoc(
|
||||
NestedNameSpecifierLoc NNS) {
|
||||
if (!NNS)
|
||||
return true;
|
||||
|
||||
if (NestedNameSpecifierLoc Prefix = NNS.getPrefix())
|
||||
TRY_TO(TraverseNestedNameSpecifierLoc(Prefix));
|
||||
|
||||
switch (NNS.getNestedNameSpecifier()->getKind()) {
|
||||
case NestedNameSpecifier::Identifier:
|
||||
case NestedNameSpecifier::Namespace:
|
||||
case NestedNameSpecifier::NamespaceAlias:
|
||||
case NestedNameSpecifier::Global:
|
||||
return true;
|
||||
|
||||
case NestedNameSpecifier::TypeSpec:
|
||||
case NestedNameSpecifier::TypeSpecWithTemplate:
|
||||
TRY_TO(TraverseTypeLoc(NNS.getTypeLoc()));
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename Derived>
|
||||
bool RecursiveASTVisitor<Derived>::TraverseTemplateName(TemplateName Template) {
|
||||
if (DependentTemplateName *DTN = Template.getAsDependentTemplateName())
|
||||
|
@ -1143,7 +1174,7 @@ DEF_TRAVERSE_DECL(ObjCPropertyDecl, {
|
|||
})
|
||||
|
||||
DEF_TRAVERSE_DECL(UsingDecl, {
|
||||
TRY_TO(TraverseNestedNameSpecifier(D->getTargetNestedNameDecl()));
|
||||
TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
|
||||
})
|
||||
|
||||
DEF_TRAVERSE_DECL(UsingDirectiveDecl, {
|
||||
|
@ -1313,7 +1344,7 @@ DEF_TRAVERSE_DECL(TypedefDecl, {
|
|||
DEF_TRAVERSE_DECL(UnresolvedUsingTypenameDecl, {
|
||||
// A dependent using declaration which was marked with 'typename'.
|
||||
// template<class T> class A : public B<T> { using typename B<T>::foo; };
|
||||
TRY_TO(TraverseNestedNameSpecifier(D->getTargetNestedNameSpecifier()));
|
||||
TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
|
||||
// We shouldn't traverse D->getTypeForDecl(); it's a result of
|
||||
// declaring the type, not something that was written in the
|
||||
// source.
|
||||
|
@ -1426,7 +1457,7 @@ DEF_TRAVERSE_DECL(EnumConstantDecl, {
|
|||
DEF_TRAVERSE_DECL(UnresolvedUsingValueDecl, {
|
||||
// Like UnresolvedUsingTypenameDecl, but without the 'typename':
|
||||
// template <class T> Class A : public Base<T> { using Base<T>::foo; };
|
||||
TRY_TO(TraverseNestedNameSpecifier(D->getTargetNestedNameSpecifier()));
|
||||
TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
|
||||
})
|
||||
|
||||
DEF_TRAVERSE_DECL(IndirectFieldDecl, {})
|
||||
|
|
|
@ -349,7 +349,7 @@ NODE_XML(UsingDecl, "Using")
|
|||
ID_ATTRIBUTE_XML
|
||||
ATTRIBUTE_FILE_LOCATION_XML
|
||||
ATTRIBUTE_XML(getDeclContext(), "context")
|
||||
ATTRIBUTE_XML(getTargetNestedNameDecl(), "target_nested_namespace_decl")
|
||||
ATTRIBUTE_XML(getQualifier(), "target_nested_namespace_decl")
|
||||
ATTRIBUTE_XML(isTypeName(), "is_typename")
|
||||
END_NODE_XML
|
||||
|
||||
|
|
|
@ -1133,6 +1133,10 @@ public:
|
|||
NestedNameSpecifier *ReadNestedNameSpecifier(const RecordData &Record,
|
||||
unsigned &Idx);
|
||||
|
||||
NestedNameSpecifierLoc ReadNestedNameSpecifierLoc(PerFileData &F,
|
||||
const RecordData &Record,
|
||||
unsigned &Idx);
|
||||
|
||||
/// \brief Read a template name.
|
||||
TemplateName ReadTemplateName(PerFileData &F, const RecordData &Record,
|
||||
unsigned &Idx);
|
||||
|
|
|
@ -443,6 +443,9 @@ public:
|
|||
/// \brief Emits a reference to a declarator info.
|
||||
void AddTypeSourceInfo(TypeSourceInfo *TInfo, RecordDataImpl &Record);
|
||||
|
||||
/// \brief Emits a type with source-location information.
|
||||
void AddTypeLoc(TypeLoc TL, RecordDataImpl &Record);
|
||||
|
||||
/// \brief Emits a template argument location info.
|
||||
void AddTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind,
|
||||
const TemplateArgumentLocInfo &Arg,
|
||||
|
@ -474,6 +477,10 @@ public:
|
|||
|
||||
/// \brief Emit a nested name specifier.
|
||||
void AddNestedNameSpecifier(NestedNameSpecifier *NNS, RecordDataImpl &Record);
|
||||
|
||||
/// \brief Emit a nested name specifier with source-location information.
|
||||
void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,
|
||||
RecordDataImpl &Record);
|
||||
|
||||
/// \brief Emit a template name.
|
||||
void AddTemplateName(TemplateName Name, RecordDataImpl &Record);
|
||||
|
|
|
@ -868,9 +868,13 @@ bool NamedDecl::declarationReplaces(NamedDecl *OldD) const {
|
|||
return cast<UsingShadowDecl>(this)->getTargetDecl() ==
|
||||
cast<UsingShadowDecl>(OldD)->getTargetDecl();
|
||||
|
||||
if (isa<UsingDecl>(this) && isa<UsingDecl>(OldD))
|
||||
return cast<UsingDecl>(this)->getTargetNestedNameDecl() ==
|
||||
cast<UsingDecl>(OldD)->getTargetNestedNameDecl();
|
||||
if (isa<UsingDecl>(this) && isa<UsingDecl>(OldD)) {
|
||||
ASTContext &Context = getASTContext();
|
||||
return Context.getCanonicalNestedNameSpecifier(
|
||||
cast<UsingDecl>(this)->getQualifier()) ==
|
||||
Context.getCanonicalNestedNameSpecifier(
|
||||
cast<UsingDecl>(OldD)->getQualifier());
|
||||
}
|
||||
|
||||
// For non-function declarations, if the declarations are of the
|
||||
// same kind then this must be a redeclaration, or semantic analysis
|
||||
|
|
|
@ -1337,35 +1337,31 @@ void UsingDecl::removeShadowDecl(UsingShadowDecl *S) {
|
|||
S->UsingOrNextShadow = this;
|
||||
}
|
||||
|
||||
UsingDecl *UsingDecl::Create(ASTContext &C, DeclContext *DC,
|
||||
SourceRange NNR, SourceLocation UL,
|
||||
NestedNameSpecifier* TargetNNS,
|
||||
UsingDecl *UsingDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation UL,
|
||||
NestedNameSpecifierLoc QualifierLoc,
|
||||
const DeclarationNameInfo &NameInfo,
|
||||
bool IsTypeNameArg) {
|
||||
return new (C) UsingDecl(DC, NNR, UL, TargetNNS, NameInfo, IsTypeNameArg);
|
||||
return new (C) UsingDecl(DC, UL, QualifierLoc, NameInfo, IsTypeNameArg);
|
||||
}
|
||||
|
||||
UnresolvedUsingValueDecl *
|
||||
UnresolvedUsingValueDecl::Create(ASTContext &C, DeclContext *DC,
|
||||
SourceLocation UsingLoc,
|
||||
SourceRange TargetNNR,
|
||||
NestedNameSpecifier *TargetNNS,
|
||||
NestedNameSpecifierLoc QualifierLoc,
|
||||
const DeclarationNameInfo &NameInfo) {
|
||||
return new (C) UnresolvedUsingValueDecl(DC, C.DependentTy, UsingLoc,
|
||||
TargetNNR, TargetNNS, NameInfo);
|
||||
QualifierLoc, NameInfo);
|
||||
}
|
||||
|
||||
UnresolvedUsingTypenameDecl *
|
||||
UnresolvedUsingTypenameDecl::Create(ASTContext &C, DeclContext *DC,
|
||||
SourceLocation UsingLoc,
|
||||
SourceLocation TypenameLoc,
|
||||
SourceRange TargetNNR,
|
||||
NestedNameSpecifier *TargetNNS,
|
||||
NestedNameSpecifierLoc QualifierLoc,
|
||||
SourceLocation TargetNameLoc,
|
||||
DeclarationName TargetName) {
|
||||
return new (C) UnresolvedUsingTypenameDecl(DC, UsingLoc, TypenameLoc,
|
||||
TargetNNR, TargetNNS,
|
||||
TargetNameLoc,
|
||||
QualifierLoc, TargetNameLoc,
|
||||
TargetName.getAsIdentifierInfo());
|
||||
}
|
||||
|
||||
|
|
|
@ -918,20 +918,20 @@ void DeclPrinter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PID) {
|
|||
|
||||
void DeclPrinter::VisitUsingDecl(UsingDecl *D) {
|
||||
Out << "using ";
|
||||
D->getTargetNestedNameDecl()->print(Out, Policy);
|
||||
D->getQualifier()->print(Out, Policy);
|
||||
Out << D;
|
||||
}
|
||||
|
||||
void
|
||||
DeclPrinter::VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D) {
|
||||
Out << "using typename ";
|
||||
D->getTargetNestedNameSpecifier()->print(Out, Policy);
|
||||
D->getQualifier()->print(Out, Policy);
|
||||
Out << D->getDeclName();
|
||||
}
|
||||
|
||||
void DeclPrinter::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
|
||||
Out << "using ";
|
||||
D->getTargetNestedNameSpecifier()->print(Out, Policy);
|
||||
D->getQualifier()->print(Out, Policy);
|
||||
Out << D->getDeclName();
|
||||
}
|
||||
|
||||
|
|
|
@ -320,7 +320,7 @@ namespace {
|
|||
}
|
||||
}
|
||||
|
||||
SourceRange NestedNameSpecifierLoc::getSourceRange() {
|
||||
SourceRange NestedNameSpecifierLoc::getSourceRange() const {
|
||||
NestedNameSpecifierLoc First = *this;
|
||||
while (NestedNameSpecifierLoc Prefix= First.getPrefix())
|
||||
First = Prefix;
|
||||
|
@ -329,7 +329,7 @@ SourceRange NestedNameSpecifierLoc::getSourceRange() {
|
|||
getLocalSourceRange().getEnd());
|
||||
}
|
||||
|
||||
SourceRange NestedNameSpecifierLoc::getLocalSourceRange() {
|
||||
SourceRange NestedNameSpecifierLoc::getLocalSourceRange() const {
|
||||
unsigned Offset = getDataLength(Qualifier->getPrefix());
|
||||
switch (Qualifier->getKind()) {
|
||||
case NestedNameSpecifier::Global:
|
||||
|
@ -354,3 +354,14 @@ SourceRange NestedNameSpecifierLoc::getLocalSourceRange() {
|
|||
|
||||
return SourceRange();
|
||||
}
|
||||
|
||||
TypeLoc NestedNameSpecifierLoc::getTypeLoc() const {
|
||||
assert((Qualifier->getKind() == NestedNameSpecifier::TypeSpec ||
|
||||
Qualifier->getKind() == NestedNameSpecifier::TypeSpecWithTemplate) &&
|
||||
"Nested-name-specifier location is not a type");
|
||||
|
||||
// The "void*" that points at the TypeLoc data.
|
||||
unsigned Offset = getDataLength(Qualifier->getPrefix());
|
||||
void *TypeData = LoadPointer(Data, Offset);
|
||||
return TypeLoc(Qualifier->getAsType(), TypeData);
|
||||
}
|
||||
|
|
|
@ -279,8 +279,8 @@ void StmtDumper::DumpDeclarator(Decl *D) {
|
|||
// print using decl (e.g. "using std::string;")
|
||||
const char *tn = UD->isTypeName() ? "typename " : "";
|
||||
OS << '"' << UD->getDeclKindName() << tn;
|
||||
UD->getTargetNestedNameDecl()->print(OS,
|
||||
PrintingPolicy(UD->getASTContext().getLangOptions()));
|
||||
UD->getQualifier()->print(OS,
|
||||
PrintingPolicy(UD->getASTContext().getLangOptions()));
|
||||
OS << ";\"";
|
||||
} else if (LabelDecl *LD = dyn_cast<LabelDecl>(D)) {
|
||||
OS << "label " << LD->getNameAsString();
|
||||
|
|
|
@ -3919,16 +3919,16 @@ bool Sema::CheckUsingShadowDecl(UsingDecl *Using, NamedDecl *Orig,
|
|||
if (OrigDC == CurContext) {
|
||||
Diag(Using->getLocation(),
|
||||
diag::err_using_decl_nested_name_specifier_is_current_class)
|
||||
<< Using->getNestedNameRange();
|
||||
<< Using->getQualifierLoc().getSourceRange();
|
||||
Diag(Orig->getLocation(), diag::note_using_decl_target);
|
||||
return true;
|
||||
}
|
||||
|
||||
Diag(Using->getNestedNameRange().getBegin(),
|
||||
Diag(Using->getQualifierLoc().getBeginLoc(),
|
||||
diag::err_using_decl_nested_name_specifier_is_not_base_class)
|
||||
<< Using->getTargetNestedNameDecl()
|
||||
<< Using->getQualifier()
|
||||
<< cast<CXXRecordDecl>(CurContext)
|
||||
<< Using->getNestedNameRange();
|
||||
<< Using->getQualifierLoc().getSourceRange();
|
||||
Diag(Orig->getLocation(), diag::note_using_decl_target);
|
||||
return true;
|
||||
}
|
||||
|
@ -4134,8 +4134,6 @@ NamedDecl *Sema::BuildUsingDeclaration(Scope *S, AccessSpecifier AS,
|
|||
LookupQualifiedName(Previous, CurContext);
|
||||
}
|
||||
|
||||
NestedNameSpecifier *NNS = SS.getScopeRep();
|
||||
|
||||
// Check for invalid redeclarations.
|
||||
if (CheckUsingDeclRedeclaration(UsingLoc, IsTypeName, SS, IdentLoc, Previous))
|
||||
return 0;
|
||||
|
@ -4146,22 +4144,21 @@ NamedDecl *Sema::BuildUsingDeclaration(Scope *S, AccessSpecifier AS,
|
|||
|
||||
DeclContext *LookupContext = computeDeclContext(SS);
|
||||
NamedDecl *D;
|
||||
NestedNameSpecifierLoc QualifierLoc = SS.getWithLocInContext(Context);
|
||||
if (!LookupContext) {
|
||||
if (IsTypeName) {
|
||||
// FIXME: not all declaration name kinds are legal here
|
||||
D = UnresolvedUsingTypenameDecl::Create(Context, CurContext,
|
||||
UsingLoc, TypenameLoc,
|
||||
SS.getRange(), NNS,
|
||||
QualifierLoc,
|
||||
IdentLoc, NameInfo.getName());
|
||||
} else {
|
||||
D = UnresolvedUsingValueDecl::Create(Context, CurContext,
|
||||
UsingLoc, SS.getRange(),
|
||||
NNS, NameInfo);
|
||||
D = UnresolvedUsingValueDecl::Create(Context, CurContext, UsingLoc,
|
||||
QualifierLoc, NameInfo);
|
||||
}
|
||||
} else {
|
||||
D = UsingDecl::Create(Context, CurContext,
|
||||
SS.getRange(), UsingLoc, NNS, NameInfo,
|
||||
IsTypeName);
|
||||
D = UsingDecl::Create(Context, CurContext, UsingLoc, QualifierLoc,
|
||||
NameInfo, IsTypeName);
|
||||
}
|
||||
D->setAccess(AS);
|
||||
CurContext->addDecl(D);
|
||||
|
@ -4252,7 +4249,7 @@ bool Sema::CheckInheritedConstructorUsingDecl(UsingDecl *UD) {
|
|||
return true;
|
||||
}
|
||||
|
||||
const Type *SourceType = UD->getTargetNestedNameDecl()->getAsType();
|
||||
const Type *SourceType = UD->getQualifier()->getAsType();
|
||||
assert(SourceType &&
|
||||
"Using decl naming constructor doesn't have type in scope spec.");
|
||||
CXXRecordDecl *TargetClass = cast<CXXRecordDecl>(CurContext);
|
||||
|
@ -4309,15 +4306,15 @@ bool Sema::CheckUsingDeclRedeclaration(SourceLocation UsingLoc,
|
|||
NestedNameSpecifier *DQual;
|
||||
if (UsingDecl *UD = dyn_cast<UsingDecl>(D)) {
|
||||
DTypename = UD->isTypeName();
|
||||
DQual = UD->getTargetNestedNameDecl();
|
||||
DQual = UD->getQualifier();
|
||||
} else if (UnresolvedUsingValueDecl *UD
|
||||
= dyn_cast<UnresolvedUsingValueDecl>(D)) {
|
||||
DTypename = false;
|
||||
DQual = UD->getTargetNestedNameSpecifier();
|
||||
DQual = UD->getQualifier();
|
||||
} else if (UnresolvedUsingTypenameDecl *UD
|
||||
= dyn_cast<UnresolvedUsingTypenameDecl>(D)) {
|
||||
DTypename = true;
|
||||
DQual = UD->getTargetNestedNameSpecifier();
|
||||
DQual = UD->getQualifier();
|
||||
} else continue;
|
||||
|
||||
// using decls differ if one says 'typename' and the other doesn't.
|
||||
|
|
|
@ -6036,7 +6036,7 @@ Sema::CheckTypenameType(ElaboratedTypeKeyword Keyword,
|
|||
<< Name << Ctx << FullRange;
|
||||
if (UnresolvedUsingValueDecl *Using
|
||||
= dyn_cast<UnresolvedUsingValueDecl>(Result.getRepresentativeDecl())){
|
||||
SourceLocation Loc = Using->getTargetNestedNameRange().getBegin();
|
||||
SourceLocation Loc = Using->getQualifierLoc().getBeginLoc();
|
||||
Diag(Loc, diag::note_using_value_decl_missing_typename)
|
||||
<< FixItHint::CreateInsertion(Loc, "typename ");
|
||||
}
|
||||
|
|
|
@ -1661,12 +1661,12 @@ Decl *TemplateDeclInstantiator::VisitUsingDecl(UsingDecl *D) {
|
|||
// template struct t<int>;
|
||||
// Here, in using s1::f1, s1 refers to t<T>::s1;
|
||||
// we need to substitute for t<int>::s1.
|
||||
NestedNameSpecifier *NNS =
|
||||
SemaRef.SubstNestedNameSpecifier(D->getTargetNestedNameDecl(),
|
||||
D->getNestedNameRange(),
|
||||
TemplateArgs);
|
||||
NestedNameSpecifier *NNS
|
||||
= SemaRef.SubstNestedNameSpecifier(D->getQualifier(),
|
||||
D->getQualifierRange(),
|
||||
TemplateArgs);
|
||||
if (!NNS)
|
||||
return 0;
|
||||
return 0;
|
||||
|
||||
// The name info is non-dependent, so no transformation
|
||||
// is required.
|
||||
|
@ -1680,16 +1680,18 @@ Decl *TemplateDeclInstantiator::VisitUsingDecl(UsingDecl *D) {
|
|||
LookupResult Prev(SemaRef, NameInfo, Sema::LookupUsingDeclName,
|
||||
Sema::ForRedeclaration);
|
||||
|
||||
CXXScopeSpec SS;
|
||||
if (NNS == D->getQualifier())
|
||||
SS.Adopt(D->getQualifierLoc());
|
||||
else
|
||||
SS.MakeTrivial(SemaRef.Context, NNS, D->getQualifierRange());
|
||||
|
||||
UsingDecl *NewUD = UsingDecl::Create(SemaRef.Context, Owner,
|
||||
D->getNestedNameRange(),
|
||||
D->getUsingLocation(),
|
||||
NNS,
|
||||
SS.getWithLocInContext(SemaRef.Context),
|
||||
NameInfo,
|
||||
D->isTypeName());
|
||||
|
||||
CXXScopeSpec SS;
|
||||
SS.MakeTrivial(SemaRef.Context, NNS, D->getNestedNameRange());
|
||||
|
||||
if (CheckRedeclaration) {
|
||||
Prev.setHideTags(false);
|
||||
SemaRef.LookupQualifiedName(Prev, Owner);
|
||||
|
@ -1749,14 +1751,13 @@ Decl *TemplateDeclInstantiator::VisitUsingShadowDecl(UsingShadowDecl *D) {
|
|||
Decl * TemplateDeclInstantiator
|
||||
::VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D) {
|
||||
NestedNameSpecifier *NNS =
|
||||
SemaRef.SubstNestedNameSpecifier(D->getTargetNestedNameSpecifier(),
|
||||
D->getTargetNestedNameRange(),
|
||||
SemaRef.SubstNestedNameSpecifier(D->getQualifier(), D->getQualifierRange(),
|
||||
TemplateArgs);
|
||||
if (!NNS)
|
||||
return 0;
|
||||
|
||||
CXXScopeSpec SS;
|
||||
SS.MakeTrivial(SemaRef.Context, NNS, D->getTargetNestedNameRange());
|
||||
SS.MakeTrivial(SemaRef.Context, NNS, D->getQualifierRange());
|
||||
|
||||
// Since NameInfo refers to a typename, it cannot be a C++ special name.
|
||||
// Hence, no tranformation is required for it.
|
||||
|
@ -1775,14 +1776,13 @@ Decl * TemplateDeclInstantiator
|
|||
Decl * TemplateDeclInstantiator
|
||||
::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
|
||||
NestedNameSpecifier *NNS =
|
||||
SemaRef.SubstNestedNameSpecifier(D->getTargetNestedNameSpecifier(),
|
||||
D->getTargetNestedNameRange(),
|
||||
SemaRef.SubstNestedNameSpecifier(D->getQualifier(), D->getQualifierRange(),
|
||||
TemplateArgs);
|
||||
if (!NNS)
|
||||
return 0;
|
||||
|
||||
CXXScopeSpec SS;
|
||||
SS.MakeTrivial(SemaRef.Context, NNS, D->getTargetNestedNameRange());
|
||||
SS.MakeTrivial(SemaRef.Context, NNS, D->getQualifierRange());
|
||||
|
||||
DeclarationNameInfo NameInfo
|
||||
= SemaRef.SubstDeclarationNameInfo(D->getNameInfo(), TemplateArgs);
|
||||
|
|
|
@ -4759,6 +4759,109 @@ ASTReader::ReadNestedNameSpecifier(const RecordData &Record, unsigned &Idx) {
|
|||
return NNS;
|
||||
}
|
||||
|
||||
NestedNameSpecifierLoc
|
||||
ASTReader::ReadNestedNameSpecifierLoc(PerFileData &F, const RecordData &Record,
|
||||
unsigned &Idx) {
|
||||
unsigned N = Record[Idx++];
|
||||
NestedNameSpecifier *NNS = 0, *Prev = 0;
|
||||
llvm::SmallVector<char, 32> LocationData;
|
||||
for (unsigned I = 0; I != N; ++I) {
|
||||
NestedNameSpecifier::SpecifierKind Kind
|
||||
= (NestedNameSpecifier::SpecifierKind)Record[Idx++];
|
||||
switch (Kind) {
|
||||
case NestedNameSpecifier::Identifier: {
|
||||
// Nested-name-specifier
|
||||
IdentifierInfo *II = GetIdentifierInfo(Record, Idx);
|
||||
NNS = NestedNameSpecifier::Create(*Context, Prev, II);
|
||||
|
||||
// Location information
|
||||
SourceRange Range = ReadSourceRange(F, Record, Idx);
|
||||
unsigned RawStart = Range.getBegin().getRawEncoding();
|
||||
unsigned RawEnd = Range.getEnd().getRawEncoding();
|
||||
LocationData.append(reinterpret_cast<char*>(&RawStart),
|
||||
reinterpret_cast<char*>(&RawStart) +sizeof(unsigned));
|
||||
LocationData.append(reinterpret_cast<char*>(&RawEnd),
|
||||
reinterpret_cast<char*>(&RawEnd) + sizeof(unsigned));
|
||||
break;
|
||||
}
|
||||
|
||||
case NestedNameSpecifier::Namespace: {
|
||||
// Nested-name-specifier
|
||||
NamespaceDecl *NS = cast<NamespaceDecl>(GetDecl(Record[Idx++]));
|
||||
NNS = NestedNameSpecifier::Create(*Context, Prev, NS);
|
||||
|
||||
// Location information
|
||||
SourceRange Range = ReadSourceRange(F, Record, Idx);
|
||||
unsigned RawStart = Range.getBegin().getRawEncoding();
|
||||
unsigned RawEnd = Range.getEnd().getRawEncoding();
|
||||
LocationData.append(reinterpret_cast<char*>(&RawStart),
|
||||
reinterpret_cast<char*>(&RawStart) +sizeof(unsigned));
|
||||
LocationData.append(reinterpret_cast<char*>(&RawEnd),
|
||||
reinterpret_cast<char*>(&RawEnd) + sizeof(unsigned));
|
||||
break;
|
||||
}
|
||||
|
||||
case NestedNameSpecifier::NamespaceAlias: {
|
||||
// Nested-name-specifier
|
||||
NamespaceAliasDecl *Alias
|
||||
= cast<NamespaceAliasDecl>(GetDecl(Record[Idx++]));
|
||||
NNS = NestedNameSpecifier::Create(*Context, Prev, Alias);
|
||||
|
||||
// Location information
|
||||
SourceRange Range = ReadSourceRange(F, Record, Idx);
|
||||
unsigned RawStart = Range.getBegin().getRawEncoding();
|
||||
unsigned RawEnd = Range.getEnd().getRawEncoding();
|
||||
LocationData.append(reinterpret_cast<char*>(&RawStart),
|
||||
reinterpret_cast<char*>(&RawStart) +sizeof(unsigned));
|
||||
LocationData.append(reinterpret_cast<char*>(&RawEnd),
|
||||
reinterpret_cast<char*>(&RawEnd) + sizeof(unsigned));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case NestedNameSpecifier::TypeSpec:
|
||||
case NestedNameSpecifier::TypeSpecWithTemplate: {
|
||||
// Nested-name-specifier
|
||||
bool Template = Record[Idx++];
|
||||
TypeSourceInfo *T = GetTypeSourceInfo(F, Record, Idx);
|
||||
if (!T)
|
||||
return NestedNameSpecifierLoc();
|
||||
NNS = NestedNameSpecifier::Create(*Context, Prev, Template,
|
||||
T->getType().getTypePtr());
|
||||
|
||||
// Location information.
|
||||
SourceLocation ColonColonLoc = ReadSourceLocation(F, Record, Idx);
|
||||
unsigned RawLocation = ColonColonLoc.getRawEncoding();
|
||||
void *OpaqueTypeData = T->getTypeLoc().getOpaqueData();
|
||||
LocationData.append(reinterpret_cast<char*>(&OpaqueTypeData),
|
||||
(reinterpret_cast<char*>(&OpaqueTypeData)
|
||||
+ sizeof(void *)));
|
||||
LocationData.append(reinterpret_cast<char*>(&RawLocation),
|
||||
(reinterpret_cast<char*>(&RawLocation) +
|
||||
sizeof(unsigned)));
|
||||
break;
|
||||
}
|
||||
|
||||
case NestedNameSpecifier::Global: {
|
||||
// Nested-name-specifier
|
||||
NNS = NestedNameSpecifier::GlobalSpecifier(*Context);
|
||||
|
||||
SourceLocation ColonColonLoc = ReadSourceLocation(F, Record, Idx);
|
||||
unsigned RawLocation = ColonColonLoc.getRawEncoding();
|
||||
LocationData.append(reinterpret_cast<char*>(&RawLocation),
|
||||
(reinterpret_cast<char*>(&RawLocation) +
|
||||
sizeof(unsigned)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
Prev = NNS;
|
||||
}
|
||||
|
||||
void *Mem = Context->Allocate(LocationData.size(), llvm::alignOf<void*>());
|
||||
memcpy(Mem, LocationData.data(), LocationData.size());
|
||||
return NestedNameSpecifierLoc(NNS, Mem);
|
||||
}
|
||||
|
||||
SourceRange
|
||||
ASTReader::ReadSourceRange(PerFileData &F, const RecordData &Record,
|
||||
unsigned &Idx) {
|
||||
|
|
|
@ -753,8 +753,7 @@ void ASTDeclReader::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
|
|||
void ASTDeclReader::VisitUsingDecl(UsingDecl *D) {
|
||||
VisitNamedDecl(D);
|
||||
D->setUsingLocation(ReadSourceLocation(Record, Idx));
|
||||
D->setNestedNameRange(ReadSourceRange(Record, Idx));
|
||||
D->setTargetNestedNameDecl(Reader.ReadNestedNameSpecifier(Record, Idx));
|
||||
D->QualifierLoc = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx);
|
||||
ReadDeclarationNameLoc(D->DNLoc, D->getDeclName(), Record, Idx);
|
||||
D->FirstUsingShadow = cast_or_null<UsingShadowDecl>(Reader.GetDecl(Record[Idx++]));
|
||||
D->setTypeName(Record[Idx++]);
|
||||
|
@ -785,19 +784,17 @@ void ASTDeclReader::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
|
|||
|
||||
void ASTDeclReader::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
|
||||
VisitValueDecl(D);
|
||||
D->setTargetNestedNameRange(ReadSourceRange(Record, Idx));
|
||||
D->setUsingLoc(ReadSourceLocation(Record, Idx));
|
||||
D->setTargetNestedNameSpecifier(Reader.ReadNestedNameSpecifier(Record, Idx));
|
||||
D->QualifierLoc = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx);
|
||||
ReadDeclarationNameLoc(D->DNLoc, D->getDeclName(), Record, Idx);
|
||||
}
|
||||
|
||||
void ASTDeclReader::VisitUnresolvedUsingTypenameDecl(
|
||||
UnresolvedUsingTypenameDecl *D) {
|
||||
VisitTypeDecl(D);
|
||||
D->TargetNestedNameRange = ReadSourceRange(Record, Idx);
|
||||
D->UsingLocation = ReadSourceLocation(Record, Idx);
|
||||
D->TypenameLocation = ReadSourceLocation(Record, Idx);
|
||||
D->TargetNestedNameSpecifier = Reader.ReadNestedNameSpecifier(Record, Idx);
|
||||
D->QualifierLoc = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx);
|
||||
}
|
||||
|
||||
void ASTDeclReader::ReadCXXDefinitionData(
|
||||
|
@ -1436,8 +1433,9 @@ Decl *ASTReader::ReadDeclRecord(unsigned Index, DeclID ID) {
|
|||
SourceLocation(), 0);
|
||||
break;
|
||||
case DECL_USING:
|
||||
D = UsingDecl::Create(*Context, 0, SourceRange(), SourceLocation(),
|
||||
0, DeclarationNameInfo(), false);
|
||||
D = UsingDecl::Create(*Context, 0, SourceLocation(),
|
||||
NestedNameSpecifierLoc(), DeclarationNameInfo(),
|
||||
false);
|
||||
break;
|
||||
case DECL_USING_SHADOW:
|
||||
D = UsingShadowDecl::Create(*Context, 0, SourceLocation(), 0, 0);
|
||||
|
@ -1449,13 +1447,14 @@ Decl *ASTReader::ReadDeclRecord(unsigned Index, DeclID ID) {
|
|||
break;
|
||||
case DECL_UNRESOLVED_USING_VALUE:
|
||||
D = UnresolvedUsingValueDecl::Create(*Context, 0, SourceLocation(),
|
||||
SourceRange(), 0,
|
||||
NestedNameSpecifierLoc(),
|
||||
DeclarationNameInfo());
|
||||
break;
|
||||
case DECL_UNRESOLVED_USING_TYPENAME:
|
||||
D = UnresolvedUsingTypenameDecl::Create(*Context, 0, SourceLocation(),
|
||||
SourceLocation(), SourceRange(),
|
||||
0, SourceLocation(),
|
||||
SourceLocation(),
|
||||
NestedNameSpecifierLoc(),
|
||||
SourceLocation(),
|
||||
DeclarationName());
|
||||
break;
|
||||
case DECL_CXX_RECORD:
|
||||
|
|
|
@ -3276,15 +3276,21 @@ void ASTWriter::AddTemplateArgumentLoc(const TemplateArgumentLoc &Arg,
|
|||
Record);
|
||||
}
|
||||
|
||||
void ASTWriter::AddTypeSourceInfo(TypeSourceInfo *TInfo, RecordDataImpl &Record) {
|
||||
void ASTWriter::AddTypeSourceInfo(TypeSourceInfo *TInfo,
|
||||
RecordDataImpl &Record) {
|
||||
if (TInfo == 0) {
|
||||
AddTypeRef(QualType(), Record);
|
||||
return;
|
||||
}
|
||||
|
||||
AddTypeRef(TInfo->getType(), Record);
|
||||
AddTypeLoc(TInfo->getTypeLoc(), Record);
|
||||
}
|
||||
|
||||
void ASTWriter::AddTypeLoc(TypeLoc TL, RecordDataImpl &Record) {
|
||||
AddTypeRef(TL.getType(), Record);
|
||||
|
||||
TypeLocWriter TLW(*this, Record);
|
||||
for (TypeLoc TL = TInfo->getTypeLoc(); !TL.isNull(); TL = TL.getNextTypeLoc())
|
||||
for (; !TL.isNull(); TL = TL.getNextTypeLoc())
|
||||
TLW.Visit(TL);
|
||||
}
|
||||
|
||||
|
@ -3487,6 +3493,55 @@ void ASTWriter::AddNestedNameSpecifier(NestedNameSpecifier *NNS,
|
|||
}
|
||||
}
|
||||
|
||||
void ASTWriter::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,
|
||||
RecordDataImpl &Record) {
|
||||
// Nested name specifiers usually aren't too long. I think that 8 would
|
||||
// typically accomodate the vast majority.
|
||||
llvm::SmallVector<NestedNameSpecifierLoc , 8> NestedNames;
|
||||
|
||||
// Push each of the nested-name-specifiers's onto a stack for
|
||||
// serialization in reverse order.
|
||||
while (NNS) {
|
||||
NestedNames.push_back(NNS);
|
||||
NNS = NNS.getPrefix();
|
||||
}
|
||||
|
||||
Record.push_back(NestedNames.size());
|
||||
while(!NestedNames.empty()) {
|
||||
NNS = NestedNames.pop_back_val();
|
||||
NestedNameSpecifier::SpecifierKind Kind
|
||||
= NNS.getNestedNameSpecifier()->getKind();
|
||||
Record.push_back(Kind);
|
||||
switch (Kind) {
|
||||
case NestedNameSpecifier::Identifier:
|
||||
AddIdentifierRef(NNS.getNestedNameSpecifier()->getAsIdentifier(), Record);
|
||||
AddSourceRange(NNS.getLocalSourceRange(), Record);
|
||||
break;
|
||||
|
||||
case NestedNameSpecifier::Namespace:
|
||||
AddDeclRef(NNS.getNestedNameSpecifier()->getAsNamespace(), Record);
|
||||
AddSourceRange(NNS.getLocalSourceRange(), Record);
|
||||
break;
|
||||
|
||||
case NestedNameSpecifier::NamespaceAlias:
|
||||
AddDeclRef(NNS.getNestedNameSpecifier()->getAsNamespaceAlias(), Record);
|
||||
AddSourceRange(NNS.getLocalSourceRange(), Record);
|
||||
break;
|
||||
|
||||
case NestedNameSpecifier::TypeSpec:
|
||||
case NestedNameSpecifier::TypeSpecWithTemplate:
|
||||
Record.push_back(Kind == NestedNameSpecifier::TypeSpecWithTemplate);
|
||||
AddTypeLoc(NNS.getTypeLoc(), Record);
|
||||
AddSourceLocation(NNS.getLocalSourceRange().getEnd(), Record);
|
||||
break;
|
||||
|
||||
case NestedNameSpecifier::Global:
|
||||
AddSourceLocation(NNS.getLocalSourceRange().getEnd(), Record);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ASTWriter::AddTemplateName(TemplateName Name, RecordDataImpl &Record) {
|
||||
TemplateName::NameKind Kind = Name.getKind();
|
||||
Record.push_back(Kind);
|
||||
|
|
|
@ -706,9 +706,8 @@ void ASTDeclWriter::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
|
|||
|
||||
void ASTDeclWriter::VisitUsingDecl(UsingDecl *D) {
|
||||
VisitNamedDecl(D);
|
||||
Writer.AddSourceRange(D->getNestedNameRange(), Record);
|
||||
Writer.AddSourceLocation(D->getUsingLocation(), Record);
|
||||
Writer.AddNestedNameSpecifier(D->getTargetNestedNameDecl(), Record);
|
||||
Writer.AddNestedNameSpecifierLoc(D->getQualifierLoc(), Record);
|
||||
Writer.AddDeclarationNameLoc(D->DNLoc, D->getDeclName(), Record);
|
||||
Writer.AddDeclRef(D->FirstUsingShadow, Record);
|
||||
Record.push_back(D->isTypeName());
|
||||
|
@ -737,9 +736,8 @@ void ASTDeclWriter::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
|
|||
|
||||
void ASTDeclWriter::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
|
||||
VisitValueDecl(D);
|
||||
Writer.AddSourceRange(D->getTargetNestedNameRange(), Record);
|
||||
Writer.AddSourceLocation(D->getUsingLoc(), Record);
|
||||
Writer.AddNestedNameSpecifier(D->getTargetNestedNameSpecifier(), Record);
|
||||
Writer.AddNestedNameSpecifierLoc(D->getQualifierLoc(), Record);
|
||||
Writer.AddDeclarationNameLoc(D->DNLoc, D->getDeclName(), Record);
|
||||
Code = serialization::DECL_UNRESOLVED_USING_VALUE;
|
||||
}
|
||||
|
@ -747,10 +745,9 @@ void ASTDeclWriter::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
|
|||
void ASTDeclWriter::VisitUnresolvedUsingTypenameDecl(
|
||||
UnresolvedUsingTypenameDecl *D) {
|
||||
VisitTypeDecl(D);
|
||||
Writer.AddSourceRange(D->getTargetNestedNameRange(), Record);
|
||||
Writer.AddSourceLocation(D->getUsingLoc(), Record);
|
||||
Writer.AddSourceLocation(D->getTypenameLoc(), Record);
|
||||
Writer.AddNestedNameSpecifier(D->getTargetNestedNameSpecifier(), Record);
|
||||
Writer.AddNestedNameSpecifierLoc(D->getQualifierLoc(), Record);
|
||||
Code = serialization::DECL_UNRESOLVED_USING_TYPENAME;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
namespace outer {
|
||||
namespace inner {
|
||||
template<typename T>
|
||||
struct vector {
|
||||
typedef T* iterator;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
namespace outer_alias = outer;
|
||||
|
||||
struct X { };
|
||||
|
||||
using outer_alias::inner::vector;
|
||||
|
||||
struct X_vector : outer_alias::inner::vector<X> {
|
||||
using outer_alias::inner::vector<X>::iterator;
|
||||
};
|
||||
|
||||
|
||||
|
||||
// RUN: c-index-test -test-annotate-tokens=%s:13:1:19: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
|
||||
// CHECK: Punctuation: "::" [14:18 - 14:20] UsingDeclaration=vector[4:12]
|
||||
// CHECK: Identifier: "inner" [14:20 - 14:25] NamespaceRef=inner:2:13
|
||||
// CHECK: Punctuation: "::" [14:25 - 14:27] UsingDeclaration=vector[4:12]
|
||||
// CHECK: Identifier: "vector" [14:27 - 14:33] OverloadedDeclRef=vector[4:12]
|
||||
// CHECK: Punctuation: ";" [14:33 - 14:34]
|
||||
// FIXME: Base specifiers, too
|
||||
// CHECK: Keyword: "using" [17:3 - 17:8] UsingDeclaration=iterator[5:18]
|
||||
// CHECK: Identifier: "outer_alias" [17:9 - 17:20] NamespaceRef=outer_alias:10:11
|
||||
// CHECK: Punctuation: "::" [17:20 - 17:22] UsingDeclaration=iterator[5:18]
|
||||
// CHECK: Identifier: "inner" [17:22 - 17:27] NamespaceRef=inner:2:13
|
||||
// CHECK: Punctuation: "::" [17:27 - 17:29] UsingDeclaration=iterator[5:18]
|
||||
// CHECK: Identifier: "vector" [17:29 - 17:35] TemplateRef=vector:4:12
|
||||
// CHECK: Punctuation: "<" [17:35 - 17:36] UsingDeclaration=iterator[5:18]
|
||||
// CHECK: Identifier: "X" [17:36 - 17:37] TypeRef=struct X:12:8
|
||||
// CHECK: Punctuation: ">" [17:37 - 17:38] UsingDeclaration=iterator[5:18]
|
||||
// CHECK: Punctuation: "::" [17:38 - 17:40] UsingDeclaration=iterator[5:18]
|
||||
// CHECK: Identifier: "iterator" [17:40 - 17:48] OverloadedDeclRef=iterator[5:18]
|
|
@ -310,6 +310,7 @@ public:
|
|||
// Name visitor
|
||||
bool VisitDeclarationNameInfo(DeclarationNameInfo Name);
|
||||
bool VisitNestedNameSpecifier(NestedNameSpecifier *NNS, SourceRange Range);
|
||||
bool VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS);
|
||||
|
||||
// Template visitors
|
||||
bool VisitTemplateParameters(const TemplateParameterList *Params);
|
||||
|
@ -1084,9 +1085,10 @@ bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
|
|||
|
||||
bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
|
||||
// Visit nested-name-specifier.
|
||||
if (NestedNameSpecifier *Qualifier = D->getTargetNestedNameDecl())
|
||||
if (VisitNestedNameSpecifier(Qualifier, D->getNestedNameRange()))
|
||||
if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
|
||||
if (VisitNestedNameSpecifierLoc(QualifierLoc))
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
|
||||
return true;
|
||||
|
@ -1106,9 +1108,10 @@ bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
|
|||
|
||||
bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
|
||||
// Visit nested-name-specifier.
|
||||
if (NestedNameSpecifier *Qualifier = D->getTargetNestedNameSpecifier())
|
||||
if (VisitNestedNameSpecifier(Qualifier, D->getTargetNestedNameRange()))
|
||||
if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
|
||||
if (VisitNestedNameSpecifierLoc(QualifierLoc))
|
||||
return true;
|
||||
}
|
||||
|
||||
return VisitDeclarationNameInfo(D->getNameInfo());
|
||||
}
|
||||
|
@ -1116,8 +1119,8 @@ bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
|
|||
bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
|
||||
UnresolvedUsingTypenameDecl *D) {
|
||||
// Visit nested-name-specifier.
|
||||
if (NestedNameSpecifier *Qualifier = D->getTargetNestedNameSpecifier())
|
||||
if (VisitNestedNameSpecifier(Qualifier, D->getTargetNestedNameRange()))
|
||||
if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
|
||||
if (VisitNestedNameSpecifierLoc(QualifierLoc))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
@ -1194,6 +1197,48 @@ bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
|
|||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
|
||||
llvm::SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
|
||||
for (; Qualifier; Qualifier = Qualifier.getPrefix())
|
||||
Qualifiers.push_back(Qualifier);
|
||||
|
||||
while (!Qualifiers.empty()) {
|
||||
NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
|
||||
NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
|
||||
switch (NNS->getKind()) {
|
||||
case NestedNameSpecifier::Namespace:
|
||||
if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
|
||||
Q.getLocalSourceRange().getBegin(),
|
||||
TU)))
|
||||
return true;
|
||||
|
||||
break;
|
||||
|
||||
case NestedNameSpecifier::NamespaceAlias:
|
||||
if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
|
||||
Q.getLocalSourceRange().getBegin(),
|
||||
TU)))
|
||||
return true;
|
||||
|
||||
break;
|
||||
|
||||
case NestedNameSpecifier::TypeSpec:
|
||||
case NestedNameSpecifier::TypeSpecWithTemplate:
|
||||
if (Visit(Q.getTypeLoc()))
|
||||
return true;
|
||||
|
||||
break;
|
||||
|
||||
case NestedNameSpecifier::Global:
|
||||
case NestedNameSpecifier::Identifier:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CursorVisitor::VisitTemplateParameters(
|
||||
const TemplateParameterList *Params) {
|
||||
if (!Params)
|
||||
|
|
Загрузка…
Ссылка в новой задаче