Add the location of the tag keyword into TagDecl. From Enea

Zaffanella, with tweaks from Abramo Bagnara.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@76576 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Douglas Gregor 2009-07-21 14:46:17 +00:00
Родитель 98f2cca4b2
Коммит 741dd9a7e1
9 изменённых файлов: 41 добавлений и 25 удалений

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

@ -1176,12 +1176,14 @@ private:
/// this points to the TypedefDecl. Used for mangling. /// this points to the TypedefDecl. Used for mangling.
TypedefDecl *TypedefForAnonDecl; TypedefDecl *TypedefForAnonDecl;
SourceLocation TagKeywordLoc;
SourceLocation RBraceLoc; SourceLocation RBraceLoc;
protected: protected:
TagDecl(Kind DK, TagKind TK, DeclContext *DC, SourceLocation L, TagDecl(Kind DK, TagKind TK, DeclContext *DC, SourceLocation L,
IdentifierInfo *Id) IdentifierInfo *Id, SourceLocation TKL = SourceLocation())
: TypeDecl(DK, DC, L, Id), DeclContext(DK), TypedefForAnonDecl(0) { : TypeDecl(DK, DC, L, Id), DeclContext(DK), TypedefForAnonDecl(0),
TagKeywordLoc(TKL) {
assert((DK != Enum || TK == TK_enum) &&"EnumDecl not matched with TK_enum"); assert((DK != Enum || TK == TK_enum) &&"EnumDecl not matched with TK_enum");
TagDeclKind = TK; TagDeclKind = TK;
IsDefinition = false; IsDefinition = false;
@ -1191,6 +1193,9 @@ public:
SourceLocation getRBraceLoc() const { return RBraceLoc; } SourceLocation getRBraceLoc() const { return RBraceLoc; }
void setRBraceLoc(SourceLocation L) { RBraceLoc = L; } void setRBraceLoc(SourceLocation L) { RBraceLoc = L; }
SourceLocation getTagKeywordLoc() const { return TagKeywordLoc; }
void setTagKeywordLoc(SourceLocation TKL) { TagKeywordLoc = TKL; }
virtual SourceRange getSourceRange() const; virtual SourceRange getSourceRange() const;
virtual TagDecl* getCanonicalDecl(); virtual TagDecl* getCanonicalDecl();
@ -1278,14 +1283,14 @@ class EnumDecl : public TagDecl {
EnumDecl *InstantiatedFrom; EnumDecl *InstantiatedFrom;
EnumDecl(DeclContext *DC, SourceLocation L, EnumDecl(DeclContext *DC, SourceLocation L,
IdentifierInfo *Id) IdentifierInfo *Id, SourceLocation TKL)
: TagDecl(Enum, TK_enum, DC, L, Id), InstantiatedFrom(0) { : TagDecl(Enum, TK_enum, DC, L, Id, TKL), InstantiatedFrom(0) {
IntegerType = QualType(); IntegerType = QualType();
} }
public: public:
static EnumDecl *Create(ASTContext &C, DeclContext *DC, static EnumDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id, SourceLocation L, IdentifierInfo *Id,
EnumDecl *PrevDecl); SourceLocation TKL, EnumDecl *PrevDecl);
virtual void Destroy(ASTContext& C); virtual void Destroy(ASTContext& C);
@ -1351,12 +1356,13 @@ class RecordDecl : public TagDecl {
protected: protected:
RecordDecl(Kind DK, TagKind TK, DeclContext *DC, RecordDecl(Kind DK, TagKind TK, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id); SourceLocation L, IdentifierInfo *Id, SourceLocation TKL);
virtual ~RecordDecl(); virtual ~RecordDecl();
public: public:
static RecordDecl *Create(ASTContext &C, TagKind TK, DeclContext *DC, static RecordDecl *Create(ASTContext &C, TagKind TK, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id, SourceLocation L, IdentifierInfo *Id,
SourceLocation TKL = SourceLocation(),
RecordDecl* PrevDecl = 0); RecordDecl* PrevDecl = 0);
virtual void Destroy(ASTContext& C); virtual void Destroy(ASTContext& C);

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

@ -335,7 +335,8 @@ class CXXRecordDecl : public RecordDecl {
protected: protected:
CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC, CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id); SourceLocation L, IdentifierInfo *Id,
SourceLocation TKL = SourceLocation());
~CXXRecordDecl(); ~CXXRecordDecl();
@ -350,6 +351,7 @@ public:
static CXXRecordDecl *Create(ASTContext &C, TagKind TK, DeclContext *DC, static CXXRecordDecl *Create(ASTContext &C, TagKind TK, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id, SourceLocation L, IdentifierInfo *Id,
SourceLocation TKL = SourceLocation(),
CXXRecordDecl* PrevDecl=0, CXXRecordDecl* PrevDecl=0,
bool DelayTypeCreation = false); bool DelayTypeCreation = false);

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

@ -182,9 +182,9 @@ TypedefDecl *TypedefDecl::Create(ASTContext &C, DeclContext *DC,
} }
EnumDecl *EnumDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, EnumDecl *EnumDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
IdentifierInfo *Id, IdentifierInfo *Id, SourceLocation TKL,
EnumDecl *PrevDecl) { EnumDecl *PrevDecl) {
EnumDecl *Enum = new (C) EnumDecl(DC, L, Id); EnumDecl *Enum = new (C) EnumDecl(DC, L, Id, TKL);
C.getTypeDeclType(Enum, PrevDecl); C.getTypeDeclType(Enum, PrevDecl);
return Enum; return Enum;
} }
@ -654,7 +654,7 @@ void FunctionDecl::setExplicitSpecialization(bool ES) {
SourceRange TagDecl::getSourceRange() const { SourceRange TagDecl::getSourceRange() const {
SourceLocation E = RBraceLoc.isValid() ? RBraceLoc : getLocation(); SourceLocation E = RBraceLoc.isValid() ? RBraceLoc : getLocation();
return SourceRange(getLocation(), E); return SourceRange(TagKeywordLoc, E);
} }
TagDecl* TagDecl::getCanonicalDecl() { TagDecl* TagDecl::getCanonicalDecl() {
@ -692,8 +692,8 @@ TagDecl* TagDecl::getDefinition(ASTContext& C) const {
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
RecordDecl::RecordDecl(Kind DK, TagKind TK, DeclContext *DC, SourceLocation L, RecordDecl::RecordDecl(Kind DK, TagKind TK, DeclContext *DC, SourceLocation L,
IdentifierInfo *Id) IdentifierInfo *Id, SourceLocation TKL)
: TagDecl(DK, TK, DC, L, Id) { : TagDecl(DK, TK, DC, L, Id, TKL) {
HasFlexibleArrayMember = false; HasFlexibleArrayMember = false;
AnonymousStructOrUnion = false; AnonymousStructOrUnion = false;
HasObjectMember = false; HasObjectMember = false;
@ -702,9 +702,9 @@ RecordDecl::RecordDecl(Kind DK, TagKind TK, DeclContext *DC, SourceLocation L,
RecordDecl *RecordDecl::Create(ASTContext &C, TagKind TK, DeclContext *DC, RecordDecl *RecordDecl::Create(ASTContext &C, TagKind TK, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id, SourceLocation L, IdentifierInfo *Id,
RecordDecl* PrevDecl) { SourceLocation TKL, RecordDecl* PrevDecl) {
RecordDecl* R = new (C) RecordDecl(Record, TK, DC, L, Id); RecordDecl* R = new (C) RecordDecl(Record, TK, DC, L, Id, TKL);
C.getTypeDeclType(R, PrevDecl); C.getTypeDeclType(R, PrevDecl);
return R; return R;
} }

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

@ -24,8 +24,9 @@ using namespace clang;
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
CXXRecordDecl::CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC, CXXRecordDecl::CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id) SourceLocation L, IdentifierInfo *Id,
: RecordDecl(K, TK, DC, L, Id), SourceLocation TKL)
: RecordDecl(K, TK, DC, L, Id, TKL),
UserDeclaredConstructor(false), UserDeclaredCopyConstructor(false), UserDeclaredConstructor(false), UserDeclaredCopyConstructor(false),
UserDeclaredCopyAssignment(false), UserDeclaredDestructor(false), UserDeclaredCopyAssignment(false), UserDeclaredDestructor(false),
Aggregate(true), PlainOldData(true), Polymorphic(false), Abstract(false), Aggregate(true), PlainOldData(true), Polymorphic(false), Abstract(false),
@ -36,9 +37,10 @@ CXXRecordDecl::CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC,
CXXRecordDecl *CXXRecordDecl::Create(ASTContext &C, TagKind TK, DeclContext *DC, CXXRecordDecl *CXXRecordDecl::Create(ASTContext &C, TagKind TK, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id, SourceLocation L, IdentifierInfo *Id,
SourceLocation TKL,
CXXRecordDecl* PrevDecl, CXXRecordDecl* PrevDecl,
bool DelayTypeCreation) { bool DelayTypeCreation) {
CXXRecordDecl* R = new (C) CXXRecordDecl(CXXRecord, TK, DC, L, Id); CXXRecordDecl* R = new (C) CXXRecordDecl(CXXRecord, TK, DC, L, Id, TKL);
if (!DelayTypeCreation) if (!DelayTypeCreation)
C.getTypeDeclType(R, PrevDecl); C.getTypeDeclType(R, PrevDecl);
return R; return R;

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

@ -117,6 +117,7 @@ void PCHDeclReader::VisitTagDecl(TagDecl *TD) {
TD->setTypedefForAnonDecl( TD->setTypedefForAnonDecl(
cast_or_null<TypedefDecl>(Reader.GetDecl(Record[Idx++]))); cast_or_null<TypedefDecl>(Reader.GetDecl(Record[Idx++])));
TD->setRBraceLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); TD->setRBraceLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
TD->setTagKeywordLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
} }
void PCHDeclReader::VisitEnumDecl(EnumDecl *ED) { void PCHDeclReader::VisitEnumDecl(EnumDecl *ED) {
@ -607,11 +608,11 @@ Decl *PCHReader::ReadDeclRecord(uint64_t Offset, unsigned Index) {
D = TypedefDecl::Create(*Context, 0, SourceLocation(), 0, QualType()); D = TypedefDecl::Create(*Context, 0, SourceLocation(), 0, QualType());
break; break;
case pch::DECL_ENUM: case pch::DECL_ENUM:
D = EnumDecl::Create(*Context, 0, SourceLocation(), 0, 0); D = EnumDecl::Create(*Context, 0, SourceLocation(), 0, SourceLocation(), 0);
break; break;
case pch::DECL_RECORD: case pch::DECL_RECORD:
D = RecordDecl::Create(*Context, TagDecl::TK_struct, 0, SourceLocation(), D = RecordDecl::Create(*Context, TagDecl::TK_struct, 0, SourceLocation(),
0, 0); 0, SourceLocation(), 0);
break; break;
case pch::DECL_ENUM_CONSTANT: case pch::DECL_ENUM_CONSTANT:
D = EnumConstantDecl::Create(*Context, 0, SourceLocation(), 0, QualType(), D = EnumConstantDecl::Create(*Context, 0, SourceLocation(), 0, QualType(),

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

@ -113,6 +113,7 @@ void PCHDeclWriter::VisitTagDecl(TagDecl *D) {
Record.push_back(D->isDefinition()); Record.push_back(D->isDefinition());
Writer.AddDeclRef(D->getTypedefForAnonDecl(), Record); Writer.AddDeclRef(D->getTypedefForAnonDecl(), Record);
Writer.AddSourceLocation(D->getRBraceLoc(), Record); Writer.AddSourceLocation(D->getRBraceLoc(), Record);
Writer.AddSourceLocation(D->getTagKeywordLoc(), Record);
} }
void PCHDeclWriter::VisitEnumDecl(EnumDecl *D) { void PCHDeclWriter::VisitEnumDecl(EnumDecl *D) {

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

@ -3711,7 +3711,7 @@ CreateNewDecl:
if (Kind == TagDecl::TK_enum) { if (Kind == TagDecl::TK_enum) {
// FIXME: Tag decls should be chained to any simultaneous vardecls, e.g.: // FIXME: Tag decls should be chained to any simultaneous vardecls, e.g.:
// enum X { A, B, C } D; D should chain to X. // enum X { A, B, C } D; D should chain to X.
New = EnumDecl::Create(Context, SearchDC, Loc, Name, New = EnumDecl::Create(Context, SearchDC, Loc, Name, KWLoc,
cast_or_null<EnumDecl>(PrevDecl)); cast_or_null<EnumDecl>(PrevDecl));
// If this is an undefined enum, warn. // If this is an undefined enum, warn.
if (TK != TK_Definition && !Invalid) { if (TK != TK_Definition && !Invalid) {
@ -3726,10 +3726,10 @@ CreateNewDecl:
// struct X { int A; } D; D should chain to X. // struct X { int A; } D; D should chain to X.
if (getLangOptions().CPlusPlus) if (getLangOptions().CPlusPlus)
// FIXME: Look for a way to use RecordDecl for simple structs. // FIXME: Look for a way to use RecordDecl for simple structs.
New = CXXRecordDecl::Create(Context, Kind, SearchDC, Loc, Name, New = CXXRecordDecl::Create(Context, Kind, SearchDC, Loc, Name, KWLoc,
cast_or_null<CXXRecordDecl>(PrevDecl)); cast_or_null<CXXRecordDecl>(PrevDecl));
else else
New = RecordDecl::Create(Context, Kind, SearchDC, Loc, Name, New = RecordDecl::Create(Context, Kind, SearchDC, Loc, Name, KWLoc,
cast_or_null<RecordDecl>(PrevDecl)); cast_or_null<RecordDecl>(PrevDecl));
} }
@ -3831,7 +3831,9 @@ void Sema::ActOnTagStartDefinition(Scope *S, DeclPtrTy TagD) {
CXXRecordDecl *InjectedClassName CXXRecordDecl *InjectedClassName
= CXXRecordDecl::Create(Context, Record->getTagKind(), = CXXRecordDecl::Create(Context, Record->getTagKind(),
CurContext, Record->getLocation(), CurContext, Record->getLocation(),
Record->getIdentifier(), Record); Record->getIdentifier(),
Record->getTagKeywordLoc(),
Record);
InjectedClassName->setImplicit(); InjectedClassName->setImplicit();
InjectedClassName->setAccess(AS_public); InjectedClassName->setAccess(AS_public);
if (ClassTemplateDecl *Template = Record->getDescribedClassTemplate()) if (ClassTemplateDecl *Template = Record->getDescribedClassTemplate())

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

@ -522,7 +522,7 @@ Sema::ActOnClassTemplate(Scope *S, unsigned TagSpec, TagKind TK,
// declaration! // declaration!
CXXRecordDecl *NewClass = CXXRecordDecl *NewClass =
CXXRecordDecl::Create(Context, Kind, SemanticContext, NameLoc, Name, CXXRecordDecl::Create(Context, Kind, SemanticContext, NameLoc, Name, KWLoc,
PrevClassTemplate? PrevClassTemplate?
PrevClassTemplate->getTemplatedDecl() : 0, PrevClassTemplate->getTemplatedDecl() : 0,
/*DelayTypeCreation=*/true); /*DelayTypeCreation=*/true);

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

@ -217,6 +217,7 @@ Decl *TemplateDeclInstantiator::VisitStaticAssertDecl(StaticAssertDecl *D) {
Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) { Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) {
EnumDecl *Enum = EnumDecl::Create(SemaRef.Context, Owner, EnumDecl *Enum = EnumDecl::Create(SemaRef.Context, Owner,
D->getLocation(), D->getIdentifier(), D->getLocation(), D->getIdentifier(),
D->getTagKeywordLoc(),
/*PrevDecl=*/0); /*PrevDecl=*/0);
Enum->setInstantiationOfMemberEnum(D); Enum->setInstantiationOfMemberEnum(D);
Enum->setAccess(D->getAccess()); Enum->setAccess(D->getAccess());
@ -284,7 +285,8 @@ Decl *TemplateDeclInstantiator::VisitCXXRecordDecl(CXXRecordDecl *D) {
CXXRecordDecl *Record CXXRecordDecl *Record
= CXXRecordDecl::Create(SemaRef.Context, D->getTagKind(), Owner, = CXXRecordDecl::Create(SemaRef.Context, D->getTagKind(), Owner,
D->getLocation(), D->getIdentifier(), PrevDecl); D->getLocation(), D->getIdentifier(),
D->getTagKeywordLoc(), PrevDecl);
Record->setImplicit(D->isImplicit()); Record->setImplicit(D->isImplicit());
Record->setAccess(D->getAccess()); Record->setAccess(D->getAccess());
if (!D->isInjectedClassName()) if (!D->isInjectedClassName())