Added basic source locations to Elaborated and DependentName types.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@104169 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Abramo Bagnara 2010-05-19 21:37:53 +00:00
Родитель 2390a72a3e
Коммит e4da7a034a
11 изменённых файлов: 297 добавлений и 74 удалений

Просмотреть файл

@ -269,6 +269,16 @@ public:
return TypeClass::classof(Ty); return TypeClass::classof(Ty);
} }
static bool classof(const TypeLoc *TL) {
return Derived::classofType(TL->getTypePtr());
}
static bool classof(const UnqualTypeLoc *TL) {
return Derived::classofType(TL->getTypePtr());
}
static bool classof(const Derived *TL) {
return true;
}
TypeLoc getNextTypeLoc() const { TypeLoc getNextTypeLoc() const {
return getNextTypeLoc(asDerived()->getInnerType()); return getNextTypeLoc(asDerived()->getInnerType());
} }
@ -1188,18 +1198,110 @@ class DecltypeTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
DecltypeType> { DecltypeType> {
}; };
// FIXME: locations for the nested name specifier; at the very least, struct ElaboratedLocInfo {
// a SourceRange. SourceLocation KeywordLoc;
class ElaboratedTypeLoc : SourceRange QualifierRange;
public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
ElaboratedTypeLoc,
ElaboratedType> {
}; };
// FIXME: locations for the typename keyword and nested name specifier. class ElaboratedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
class DependentNameTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, ElaboratedTypeLoc,
DependentNameTypeLoc, ElaboratedType,
DependentNameType> { ElaboratedLocInfo> {
public:
SourceLocation getKeywordLoc() const {
return this->getLocalData()->KeywordLoc;
}
void setKeywordLoc(SourceLocation Loc) {
this->getLocalData()->KeywordLoc = Loc;
}
SourceRange getQualifierRange() const {
return this->getLocalData()->QualifierRange;
}
void setQualifierRange(SourceRange Range) {
this->getLocalData()->QualifierRange = Range;
}
SourceRange getSourceRange() const {
if (getKeywordLoc().isValid())
if (getQualifierRange().getEnd().isValid())
return SourceRange(getKeywordLoc(), getQualifierRange().getEnd());
else
return SourceRange(getKeywordLoc());
else
return getQualifierRange();
}
void initializeLocal(SourceLocation Loc) {
setKeywordLoc(Loc);
setQualifierRange(SourceRange(Loc));
}
TypeLoc getNamedTypeLoc() const {
return getInnerTypeLoc();
}
QualType getInnerType() const {
return getTypePtr()->getNamedType();
}
void copy(ElaboratedTypeLoc Loc) {
unsigned size = getFullDataSize();
assert(size == Loc.getFullDataSize());
memcpy(Data, Loc.Data, size);
}
};
struct DependentNameLocInfo {
SourceLocation KeywordLoc;
SourceRange QualifierRange;
SourceLocation NameLoc;
};
class DependentNameTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
DependentNameTypeLoc,
DependentNameType,
DependentNameLocInfo> {
public:
SourceLocation getKeywordLoc() const {
return this->getLocalData()->KeywordLoc;
}
void setKeywordLoc(SourceLocation Loc) {
this->getLocalData()->KeywordLoc = Loc;
}
SourceRange getQualifierRange() const {
return this->getLocalData()->QualifierRange;
}
void setQualifierRange(SourceRange Range) {
this->getLocalData()->QualifierRange = Range;
}
SourceLocation getNameLoc() const {
return this->getLocalData()->NameLoc;
}
void setNameLoc(SourceLocation Loc) {
this->getLocalData()->NameLoc = Loc;
}
SourceRange getSourceRange() const {
if (getKeywordLoc().isValid())
return SourceRange(getKeywordLoc(), getNameLoc());
else
return SourceRange(getQualifierRange().getBegin(), getNameLoc());
}
void copy(DependentNameTypeLoc Loc) {
unsigned size = getFullDataSize();
assert(size == Loc.getFullDataSize());
memcpy(Data, Loc.Data, size);
}
void initializeLocal(SourceLocation Loc) {
setKeywordLoc(Loc);
setQualifierRange(SourceRange(Loc));
setNameLoc(Loc);
}
}; };
} }

Просмотреть файл

@ -2356,12 +2356,15 @@ void TypeLocReader::VisitTemplateSpecializationTypeLoc(
Record, Idx)); Record, Idx));
} }
void TypeLocReader::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) { void TypeLocReader::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); TL.setKeywordLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
TL.setQualifierRange(Reader.ReadSourceRange(Record, Idx));
} }
void TypeLocReader::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) { void TypeLocReader::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
} }
void TypeLocReader::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) { void TypeLocReader::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
TL.setKeywordLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
TL.setQualifierRange(Reader.ReadSourceRange(Record, Idx));
TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
} }
void TypeLocReader::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) { void TypeLocReader::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {

Просмотреть файл

@ -397,12 +397,15 @@ void TypeLocWriter::VisitTemplateSpecializationTypeLoc(
Writer.AddTemplateArgumentLoc(TL.getArgLoc(i), Record); Writer.AddTemplateArgumentLoc(TL.getArgLoc(i), Record);
} }
void TypeLocWriter::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) { void TypeLocWriter::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
Writer.AddSourceLocation(TL.getNameLoc(), Record); Writer.AddSourceLocation(TL.getKeywordLoc(), Record);
Writer.AddSourceRange(TL.getQualifierRange(), Record);
} }
void TypeLocWriter::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) { void TypeLocWriter::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
Writer.AddSourceLocation(TL.getNameLoc(), Record); Writer.AddSourceLocation(TL.getNameLoc(), Record);
} }
void TypeLocWriter::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) { void TypeLocWriter::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
Writer.AddSourceLocation(TL.getKeywordLoc(), Record);
Writer.AddSourceRange(TL.getQualifierRange(), Record);
Writer.AddSourceLocation(TL.getNameLoc(), Record); Writer.AddSourceLocation(TL.getNameLoc(), Record);
} }
void TypeLocWriter::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) { void TypeLocWriter::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {

Просмотреть файл

@ -1877,7 +1877,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
if (Tok.is(tok::kw___attribute)) if (Tok.is(tok::kw___attribute))
Attr.reset(ParseGNUAttributes()); Attr.reset(ParseGNUAttributes());
CXXScopeSpec SS; CXXScopeSpec &SS = DS.getTypeSpecScope();
if (getLang().CPlusPlus) { if (getLang().CPlusPlus) {
if (ParseOptionalCXXScopeSpecifier(SS, 0, false)) if (ParseOptionalCXXScopeSpecifier(SS, 0, false))
return; return;

Просмотреть файл

@ -3117,7 +3117,9 @@ public:
QualType CheckTypenameType(ElaboratedTypeKeyword Keyword, QualType CheckTypenameType(ElaboratedTypeKeyword Keyword,
NestedNameSpecifier *NNS, NestedNameSpecifier *NNS,
const IdentifierInfo &II, const IdentifierInfo &II,
SourceRange Range); SourceLocation KeywordLoc,
SourceRange NNSRange,
SourceLocation IILoc);
TypeSourceInfo *RebuildTypeInCurrentInstantiation(TypeSourceInfo *T, TypeSourceInfo *RebuildTypeInCurrentInstantiation(TypeSourceInfo *T,
SourceLocation Loc, SourceLocation Loc,

Просмотреть файл

@ -90,8 +90,9 @@ Sema::TypeTy *Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
// We know from the grammar that this name refers to a type, so build a // We know from the grammar that this name refers to a type, so build a
// DependentNameType node to describe the type. // DependentNameType node to describe the type.
return CheckTypenameType(ETK_None, return CheckTypenameType(ETK_None,
(NestedNameSpecifier *)SS->getScopeRep(), (NestedNameSpecifier *)SS->getScopeRep(), II,
II, SS->getRange()).getAsOpaquePtr(); SourceLocation(), SS->getRange(), NameLoc
).getAsOpaquePtr();
} }
return 0; return 0;

Просмотреть файл

@ -1136,7 +1136,8 @@ Sema::ActOnMemInitializer(DeclPtrTy ConstructorD,
// specialization, we take it as a type name. // specialization, we take it as a type name.
BaseType = CheckTypenameType(ETK_None, BaseType = CheckTypenameType(ETK_None,
(NestedNameSpecifier *)SS.getScopeRep(), (NestedNameSpecifier *)SS.getScopeRep(),
*MemberOrBase, SS.getRange()); *MemberOrBase, SourceLocation(),
SS.getRange(), IdLoc);
if (BaseType.isNull()) if (BaseType.isNull())
return true; return true;

Просмотреть файл

@ -261,7 +261,8 @@ Action::TypeTy *Sema::getDestructorName(SourceLocation TildeLoc,
Range = SourceRange(NameLoc); Range = SourceRange(NameLoc);
} }
return CheckTypenameType(ETK_None, NNS, II, Range).getAsOpaquePtr(); return CheckTypenameType(ETK_None, NNS, II, SourceLocation(),
Range, NameLoc).getAsOpaquePtr();
} }
if (ObjectTypePtr) if (ObjectTypePtr)

Просмотреть файл

@ -5184,16 +5184,19 @@ Sema::ActOnDependentTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
static void FillTypeLoc(DependentNameTypeLoc TL, static void FillTypeLoc(DependentNameTypeLoc TL,
SourceLocation TypenameLoc, SourceLocation TypenameLoc,
SourceRange QualifierRange) { SourceRange QualifierRange,
// FIXME: typename, qualifier range SourceLocation NameLoc) {
TL.setNameLoc(TypenameLoc); TL.setKeywordLoc(TypenameLoc);
TL.setQualifierRange(QualifierRange);
TL.setNameLoc(NameLoc);
} }
static void FillTypeLoc(ElaboratedTypeLoc TL, static void FillTypeLoc(ElaboratedTypeLoc TL,
SourceLocation TypenameLoc, SourceLocation TypenameLoc,
SourceRange QualifierRange) { SourceRange QualifierRange) {
// FIXME: typename, qualifier range // FIXME: inner locations.
TL.setNameLoc(TypenameLoc); TL.setKeywordLoc(TypenameLoc);
TL.setQualifierRange(QualifierRange);
} }
Sema::TypeResult Sema::TypeResult
@ -5205,7 +5208,7 @@ Sema::ActOnTypenameType(SourceLocation TypenameLoc, const CXXScopeSpec &SS,
return true; return true;
QualType T = CheckTypenameType(ETK_Typename, NNS, II, QualType T = CheckTypenameType(ETK_Typename, NNS, II,
SourceRange(TypenameLoc, IdLoc)); TypenameLoc, SS.getRange(), IdLoc);
if (T.isNull()) if (T.isNull())
return true; return true;
@ -5213,7 +5216,7 @@ Sema::ActOnTypenameType(SourceLocation TypenameLoc, const CXXScopeSpec &SS,
if (isa<DependentNameType>(T)) { if (isa<DependentNameType>(T)) {
DependentNameTypeLoc TL = cast<DependentNameTypeLoc>(TSI->getTypeLoc()); DependentNameTypeLoc TL = cast<DependentNameTypeLoc>(TSI->getTypeLoc());
// FIXME: fill inner type loc // FIXME: fill inner type loc
FillTypeLoc(TL, TypenameLoc, SS.getRange()); FillTypeLoc(TL, TypenameLoc, SS.getRange(), IdLoc);
} else { } else {
ElaboratedTypeLoc TL = cast<ElaboratedTypeLoc>(TSI->getTypeLoc()); ElaboratedTypeLoc TL = cast<ElaboratedTypeLoc>(TSI->getTypeLoc());
// FIXME: fill inner type loc // FIXME: fill inner type loc
@ -5249,7 +5252,7 @@ Sema::ActOnTypenameType(SourceLocation TypenameLoc, const CXXScopeSpec &SS,
TypeSourceInfo *TSI = Context.CreateTypeSourceInfo(T); TypeSourceInfo *TSI = Context.CreateTypeSourceInfo(T);
DependentNameTypeLoc TL = cast<DependentNameTypeLoc>(TSI->getTypeLoc()); DependentNameTypeLoc TL = cast<DependentNameTypeLoc>(TSI->getTypeLoc());
// FIXME: fill inner type loc // FIXME: fill inner type loc
FillTypeLoc(TL, TypenameLoc, SS.getRange()); FillTypeLoc(TL, TypenameLoc, SS.getRange(), TemplateLoc);
return CreateLocInfoType(T, TSI).getAsOpaquePtr(); return CreateLocInfoType(T, TSI).getAsOpaquePtr();
} }
@ -5258,10 +5261,11 @@ Sema::ActOnTypenameType(SourceLocation TypenameLoc, const CXXScopeSpec &SS,
QualType QualType
Sema::CheckTypenameType(ElaboratedTypeKeyword Keyword, Sema::CheckTypenameType(ElaboratedTypeKeyword Keyword,
NestedNameSpecifier *NNS, const IdentifierInfo &II, NestedNameSpecifier *NNS, const IdentifierInfo &II,
SourceRange Range) { SourceLocation KeywordLoc, SourceRange NNSRange,
SourceLocation IILoc) {
CXXScopeSpec SS; CXXScopeSpec SS;
SS.setScopeRep(NNS); SS.setScopeRep(NNS);
SS.setRange(Range); SS.setRange(NNSRange);
DeclContext *Ctx = computeDeclContext(SS); DeclContext *Ctx = computeDeclContext(SS);
if (!Ctx) { if (!Ctx) {
@ -5281,7 +5285,7 @@ Sema::CheckTypenameType(ElaboratedTypeKeyword Keyword,
return QualType(); return QualType();
DeclarationName Name(&II); DeclarationName Name(&II);
LookupResult Result(*this, Name, Range.getEnd(), LookupOrdinaryName); LookupResult Result(*this, Name, IILoc, LookupOrdinaryName);
LookupQualifiedName(Result, Ctx); LookupQualifiedName(Result, Ctx);
unsigned DiagID = 0; unsigned DiagID = 0;
Decl *Referenced = 0; Decl *Referenced = 0;
@ -5321,7 +5325,9 @@ Sema::CheckTypenameType(ElaboratedTypeKeyword Keyword,
// If we get here, it's because name lookup did not find a // If we get here, it's because name lookup did not find a
// type. Emit an appropriate diagnostic and return an error. // type. Emit an appropriate diagnostic and return an error.
Diag(Range.getEnd(), DiagID) << Range << Name << Ctx; SourceRange FullRange(KeywordLoc.isValid() ? KeywordLoc : NNSRange.getBegin(),
IILoc);
Diag(IILoc, DiagID) << FullRange << Name << Ctx;
if (Referenced) if (Referenced)
Diag(Referenced->getLocation(), diag::note_typename_refers_here) Diag(Referenced->getLocation(), diag::note_typename_refers_here)
<< Name; << Name;
@ -5393,7 +5399,7 @@ CurrentInstantiationRebuilder::TransformDependentNameType(TypeLocBuilder &TLB,
NestedNameSpecifier *NNS NestedNameSpecifier *NNS
= TransformNestedNameSpecifier(T->getQualifier(), = TransformNestedNameSpecifier(T->getQualifier(),
/*FIXME:*/SourceRange(getBaseLocation()), TL.getQualifierRange(),
ObjectType); ObjectType);
if (!NNS) if (!NNS)
return QualType(); return QualType();
@ -5402,7 +5408,7 @@ CurrentInstantiationRebuilder::TransformDependentNameType(TypeLocBuilder &TLB,
// context corresponding to the nested-name-specifier, then this // context corresponding to the nested-name-specifier, then this
// typename type will not change; exit early. // typename type will not change; exit early.
CXXScopeSpec SS; CXXScopeSpec SS;
SS.setRange(SourceRange(getBaseLocation())); SS.setRange(TL.getQualifierRange());
SS.setScopeRep(NNS); SS.setScopeRep(NNS);
QualType Result; QualType Result;
@ -5421,18 +5427,38 @@ CurrentInstantiationRebuilder::TransformDependentNameType(TypeLocBuilder &TLB,
NewTemplateId == QualType(TemplateId, 0)) NewTemplateId == QualType(TemplateId, 0))
Result = QualType(T, 0); Result = QualType(T, 0);
else else
Result = getDerived().RebuildDependentNameType(T->getKeyword(), Result = getDerived().RebuildDependentNameType(T->getKeyword(),
NNS, NewTemplateId); NNS, NewTemplateId);
} else } else
Result = getDerived().RebuildDependentNameType(T->getKeyword(), Result = getDerived().RebuildDependentNameType(T->getKeyword(), NNS,
NNS, T->getIdentifier(), T->getIdentifier(),
SourceRange(TL.getNameLoc())); TL.getKeywordLoc(),
TL.getQualifierRange(),
TL.getNameLoc());
if (Result.isNull()) if (Result.isNull())
return QualType(); return QualType();
DependentNameTypeLoc NewTL = TLB.push<DependentNameTypeLoc>(Result); if (const ElaboratedType* ElabT = Result->getAs<ElaboratedType>()) {
NewTL.setNameLoc(TL.getNameLoc()); QualType NamedT = ElabT->getNamedType();
if (isa<TemplateSpecializationType>(NamedT)) {
TemplateSpecializationTypeLoc NamedTLoc
= TLB.push<TemplateSpecializationTypeLoc>(NamedT);
// FIXME: fill locations
NamedTLoc.initializeLocal(TL.getNameLoc());
} else {
TLB.pushTypeSpec(NamedT).setNameLoc(TL.getNameLoc());
}
ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
NewTL.setKeywordLoc(TL.getKeywordLoc());
NewTL.setQualifierRange(TL.getQualifierRange());
}
else {
DependentNameTypeLoc NewTL = TLB.push<DependentNameTypeLoc>(Result);
NewTL.setKeywordLoc(TL.getKeywordLoc());
NewTL.setQualifierRange(TL.getQualifierRange());
NewTL.setNameLoc(TL.getNameLoc());
}
return Result; return Result;
} }

Просмотреть файл

@ -25,6 +25,8 @@
#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ErrorHandling.h"
using namespace clang; using namespace clang;
#include <iostream>
/// \brief Perform adjustment on the parameter type of a function. /// \brief Perform adjustment on the parameter type of a function.
/// ///
/// This routine adjusts the given parameter type @p T to the actual /// This routine adjusts the given parameter type @p T to the actual
@ -1437,9 +1439,15 @@ namespace {
return; return;
} }
TemplateSpecializationTypeLoc OldTL = TypeLoc OldTL = TInfo->getTypeLoc();
cast<TemplateSpecializationTypeLoc>(TInfo->getTypeLoc()); if (TInfo->getType()->getAs<ElaboratedType>()) {
TL.copy(OldTL); ElaboratedTypeLoc ElabTL = cast<ElaboratedTypeLoc>(OldTL);
TemplateSpecializationTypeLoc NamedTL =
cast<TemplateSpecializationTypeLoc>(ElabTL.getNamedTypeLoc());
TL.copy(NamedTL);
}
else
TL.copy(cast<TemplateSpecializationTypeLoc>(OldTL));
} }
void VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) { void VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
assert(DS.getTypeSpecType() == DeclSpec::TST_typeofExpr); assert(DS.getTypeSpecType() == DeclSpec::TST_typeofExpr);
@ -1470,6 +1478,44 @@ namespace {
TL.setBuiltinLoc(DS.getTypeSpecWidthLoc()); TL.setBuiltinLoc(DS.getTypeSpecWidthLoc());
} }
} }
void VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
ElaboratedTypeKeyword Keyword
= TypeWithKeyword::getKeywordForTypeSpec(DS.getTypeSpecType());
if (Keyword == ETK_Typename) {
TypeSourceInfo *TInfo = 0;
Sema::GetTypeFromParser(DS.getTypeRep(), &TInfo);
if (TInfo) {
TL.copy(cast<ElaboratedTypeLoc>(TInfo->getTypeLoc()));
return;
}
}
TL.setKeywordLoc(Keyword != ETK_None
? DS.getTypeSpecTypeLoc()
: SourceLocation());
const CXXScopeSpec& SS = DS.getTypeSpecScope();
TL.setQualifierRange(SS.isEmpty() ? SourceRange(): SS.getRange());
Visit(TL.getNextTypeLoc().getUnqualifiedLoc());
}
void VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
ElaboratedTypeKeyword Keyword
= TypeWithKeyword::getKeywordForTypeSpec(DS.getTypeSpecType());
if (Keyword == ETK_Typename) {
TypeSourceInfo *TInfo = 0;
Sema::GetTypeFromParser(DS.getTypeRep(), &TInfo);
if (TInfo) {
TL.copy(cast<DependentNameTypeLoc>(TInfo->getTypeLoc()));
return;
}
}
TL.setKeywordLoc(Keyword != ETK_None
? DS.getTypeSpecTypeLoc()
: SourceLocation());
const CXXScopeSpec& SS = DS.getTypeSpecScope();
TL.setQualifierRange(SS.isEmpty() ? SourceRange() : SS.getRange());
// FIXME: load appropriate source location.
TL.setNameLoc(DS.getTypeSpecTypeLoc());
}
void VisitTypeLoc(TypeLoc TL) { void VisitTypeLoc(TypeLoc TL) {
// FIXME: add other typespec types and change this to an assert. // FIXME: add other typespec types and change this to an assert.
TL.initialize(DS.getTypeSpecTypeLoc()); TL.initialize(DS.getTypeSpecTypeLoc());
@ -2081,7 +2127,7 @@ QualType Sema::getElaboratedType(ElaboratedTypeKeyword Keyword,
if (T.isNull()) if (T.isNull())
return T; return T;
NestedNameSpecifier *NNS; NestedNameSpecifier *NNS;
if (SS.isSet() && !SS.isInvalid()) if (SS.isValid())
NNS = static_cast<NestedNameSpecifier *>(SS.getScopeRep()); NNS = static_cast<NestedNameSpecifier *>(SS.getScopeRep());
else { else {
if (Keyword == ETK_None) if (Keyword == ETK_None)

Просмотреть файл

@ -530,10 +530,9 @@ public:
/// \brief Build a new typename type that refers to a template-id. /// \brief Build a new typename type that refers to a template-id.
/// ///
/// By default, builds a new DependentNameType type from the /// By default, builds a new DependentNameType type from the
/// nested-name-specifier /// nested-name-specifier and the given type. Subclasses may override
/// and the given type. Subclasses may override this routine to provide /// this routine to provide different behavior.
/// different behavior.
QualType RebuildDependentNameType(ElaboratedTypeKeyword Keyword, QualType RebuildDependentNameType(ElaboratedTypeKeyword Keyword,
NestedNameSpecifier *NNS, QualType T) { NestedNameSpecifier *NNS, QualType T) {
if (NNS->isDependent()) { if (NNS->isDependent()) {
@ -551,15 +550,18 @@ public:
/// \brief Build a new typename type that refers to an identifier. /// \brief Build a new typename type that refers to an identifier.
/// ///
/// By default, performs semantic analysis when building the typename type /// By default, performs semantic analysis when building the typename type
/// (or qualified name type). Subclasses may override this routine to provide /// (or elaborated type). Subclasses may override this routine to provide
/// different behavior. /// different behavior.
QualType RebuildDependentNameType(ElaboratedTypeKeyword Keyword, QualType RebuildDependentNameType(ElaboratedTypeKeyword Keyword,
NestedNameSpecifier *NNS, NestedNameSpecifier *NNS,
const IdentifierInfo *Id, const IdentifierInfo *Id,
SourceRange SR) { SourceLocation KeywordLoc,
SourceRange NNSRange,
SourceLocation IdLoc) {
CXXScopeSpec SS; CXXScopeSpec SS;
SS.setScopeRep(NNS); SS.setScopeRep(NNS);
SS.setRange(NNSRange);
if (NNS->isDependent()) { if (NNS->isDependent()) {
// If the name is still dependent, just build a new dependent name type. // If the name is still dependent, just build a new dependent name type.
if (!SemaRef.computeDeclContext(SS)) if (!SemaRef.computeDeclContext(SS))
@ -567,14 +569,15 @@ public:
} }
if (Keyword == ETK_None || Keyword == ETK_Typename) if (Keyword == ETK_None || Keyword == ETK_Typename)
return SemaRef.CheckTypenameType(Keyword, NNS, *Id, SR); return SemaRef.CheckTypenameType(Keyword, NNS, *Id,
KeywordLoc, NNSRange, IdLoc);
TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForKeyword(Keyword); TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForKeyword(Keyword);
// We had a dependent elaborated-type-specifier that as been transformed // We had a dependent elaborated-type-specifier that has been transformed
// into a non-dependent elaborated-type-specifier. Find the tag we're // into a non-dependent elaborated-type-specifier. Find the tag we're
// referring to. // referring to.
LookupResult Result(SemaRef, Id, SR.getEnd(), Sema::LookupTagName); LookupResult Result(SemaRef, Id, IdLoc, Sema::LookupTagName);
DeclContext *DC = SemaRef.computeDeclContext(SS, false); DeclContext *DC = SemaRef.computeDeclContext(SS, false);
if (!DC) if (!DC)
return QualType(); return QualType();
@ -602,14 +605,13 @@ public:
if (!Tag) { if (!Tag) {
// FIXME: Would be nice to highlight just the source range. // FIXME: Would be nice to highlight just the source range.
SemaRef.Diag(SR.getEnd(), diag::err_not_tag_in_scope) SemaRef.Diag(IdLoc, diag::err_not_tag_in_scope)
<< Kind << Id << DC; << Kind << Id << DC;
return QualType(); return QualType();
} }
// FIXME: Terrible location information if (!SemaRef.isAcceptableTagRedeclaration(Tag, Kind, IdLoc, *Id)) {
if (!SemaRef.isAcceptableTagRedeclaration(Tag, Kind, SR.getEnd(), *Id)) { SemaRef.Diag(KeywordLoc, diag::err_use_with_wrong_tag) << Id;
SemaRef.Diag(SR.getBegin(), diag::err_use_with_wrong_tag) << Id;
SemaRef.Diag(Tag->getLocation(), diag::note_previous_use); SemaRef.Diag(Tag->getLocation(), diag::note_previous_use);
return QualType(); return QualType();
} }
@ -3237,27 +3239,45 @@ TreeTransform<Derived>::TransformElaboratedType(TypeLocBuilder &TLB,
// NOTE: the qualifier in an ElaboratedType is optional. // NOTE: the qualifier in an ElaboratedType is optional.
if (T->getQualifier() != 0) { if (T->getQualifier() != 0) {
NNS = getDerived().TransformNestedNameSpecifier(T->getQualifier(), NNS = getDerived().TransformNestedNameSpecifier(T->getQualifier(),
SourceRange(), TL.getQualifierRange(),
ObjectType); ObjectType);
if (!NNS) if (!NNS)
return QualType(); return QualType();
} }
QualType Named = getDerived().TransformType(T->getNamedType()); QualType NamedT;
if (Named.isNull()) // FIXME: this test is meant to workaround a problem (failing assertion)
return QualType(); // occurring if directly executing the code in the else branch.
if (isa<TemplateSpecializationTypeLoc>(TL.getNamedTypeLoc())) {
TemplateSpecializationTypeLoc OldNamedTL
= cast<TemplateSpecializationTypeLoc>(TL.getNamedTypeLoc());
const TemplateSpecializationType* OldTST
= OldNamedTL.getType()->getAs<TemplateSpecializationType>();
NamedT = TransformTemplateSpecializationType(OldTST, ObjectType);
if (NamedT.isNull())
return QualType();
TemplateSpecializationTypeLoc NewNamedTL
= TLB.push<TemplateSpecializationTypeLoc>(NamedT);
NewNamedTL.copy(OldNamedTL);
}
else {
NamedT = getDerived().TransformType(TLB, TL.getNamedTypeLoc());
if (NamedT.isNull())
return QualType();
}
QualType Result = TL.getType(); QualType Result = TL.getType();
if (getDerived().AlwaysRebuild() || if (getDerived().AlwaysRebuild() ||
NNS != T->getQualifier() || NNS != T->getQualifier() ||
Named != T->getNamedType()) { NamedT != T->getNamedType()) {
Result = getDerived().RebuildElaboratedType(T->getKeyword(), NNS, Named); Result = getDerived().RebuildElaboratedType(T->getKeyword(), NNS, NamedT);
if (Result.isNull()) if (Result.isNull())
return QualType(); return QualType();
} }
ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result); ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
NewTL.setNameLoc(TL.getNameLoc()); NewTL.setKeywordLoc(TL.getKeywordLoc());
NewTL.setQualifierRange(TL.getQualifierRange());
return Result; return Result;
} }
@ -3268,11 +3288,9 @@ QualType TreeTransform<Derived>::TransformDependentNameType(TypeLocBuilder &TLB,
QualType ObjectType) { QualType ObjectType) {
DependentNameType *T = TL.getTypePtr(); DependentNameType *T = TL.getTypePtr();
/* FIXME: preserve source information better than this */
SourceRange SR(TL.getNameLoc());
NestedNameSpecifier *NNS NestedNameSpecifier *NNS
= getDerived().TransformNestedNameSpecifier(T->getQualifier(), SR, = getDerived().TransformNestedNameSpecifier(T->getQualifier(),
TL.getQualifierRange(),
ObjectType); ObjectType);
if (!NNS) if (!NNS)
return QualType(); return QualType();
@ -3290,18 +3308,38 @@ QualType TreeTransform<Derived>::TransformDependentNameType(TypeLocBuilder &TLB,
NewTemplateId == QualType(TemplateId, 0)) NewTemplateId == QualType(TemplateId, 0))
return QualType(T, 0); return QualType(T, 0);
Result = getDerived().RebuildDependentNameType(T->getKeyword(), NNS, Result = getDerived().RebuildDependentNameType(T->getKeyword(), NNS,
NewTemplateId); NewTemplateId);
} else { } else {
Result = getDerived().RebuildDependentNameType(T->getKeyword(), NNS, Result = getDerived().RebuildDependentNameType(T->getKeyword(), NNS,
T->getIdentifier(), SR); T->getIdentifier(),
TL.getKeywordLoc(),
TL.getQualifierRange(),
TL.getNameLoc());
} }
if (Result.isNull()) if (Result.isNull())
return QualType(); return QualType();
DependentNameTypeLoc NewTL = TLB.push<DependentNameTypeLoc>(Result); if (const ElaboratedType* ElabT = Result->getAs<ElaboratedType>()) {
NewTL.setNameLoc(TL.getNameLoc()); QualType NamedT = ElabT->getNamedType();
if (isa<TemplateSpecializationType>(NamedT)) {
TemplateSpecializationTypeLoc NamedTLoc
= TLB.push<TemplateSpecializationTypeLoc>(NamedT);
// FIXME: fill locations
NamedTLoc.initializeLocal(TL.getNameLoc());
} else {
TLB.pushTypeSpec(NamedT).setNameLoc(TL.getNameLoc());
}
ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
NewTL.setKeywordLoc(TL.getKeywordLoc());
NewTL.setQualifierRange(TL.getQualifierRange());
}
else {
DependentNameTypeLoc NewTL = TLB.push<DependentNameTypeLoc>(Result);
NewTL.setKeywordLoc(TL.getKeywordLoc());
NewTL.setQualifierRange(TL.getQualifierRange());
NewTL.setNameLoc(TL.getNameLoc());
}
return Result; return Result;
} }