Preserve type source information in TypedefDecls. Preserve it across

template instantiation.  Preserve it through PCH.  Show it off to the indexer.

I'm healthily ignoring the vector type cases because we don't have a sensible
TypeLoc implementation for them anyway.

llvm-svn: 84994
This commit is contained in:
John McCall 2009-10-24 08:00:42 +00:00
parent 3db7bd27c2
commit 703a3f8a7b
11 changed files with 93 additions and 53 deletions

View File

@ -1311,20 +1311,29 @@ public:
class TypedefDecl : public TypeDecl {
/// UnderlyingType - This is the type the typedef is set to.
QualType UnderlyingType;
DeclaratorInfo *DInfo;
TypedefDecl(DeclContext *DC, SourceLocation L,
IdentifierInfo *Id, QualType T)
: TypeDecl(Typedef, DC, L, Id), UnderlyingType(T) {}
IdentifierInfo *Id, DeclaratorInfo *DInfo)
: TypeDecl(Typedef, DC, L, Id), DInfo(DInfo) {}
virtual ~TypedefDecl() {}
public:
static TypedefDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id,
QualType T);
DeclaratorInfo *DInfo);
QualType getUnderlyingType() const { return UnderlyingType; }
void setUnderlyingType(QualType newType) { UnderlyingType = newType; }
DeclaratorInfo *getTypeDeclaratorInfo() const {
return DInfo;
}
QualType getUnderlyingType() const {
return DInfo->getType();
}
void setTypeDeclaratorInfo(DeclaratorInfo *newType) {
DInfo = newType;
}
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return D->getKind() == Typedef; }

View File

@ -178,9 +178,9 @@ void EnumConstantDecl::Destroy(ASTContext& C) {
}
TypedefDecl *TypedefDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation L,
IdentifierInfo *Id, QualType T) {
return new (C) TypedefDecl(DC, L, Id, T);
SourceLocation L, IdentifierInfo *Id,
DeclaratorInfo *DInfo) {
return new (C) TypedefDecl(DC, L, Id, DInfo);
}
EnumDecl *EnumDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,

View File

@ -106,9 +106,9 @@ void PCHDeclReader::VisitTypedefDecl(TypedefDecl *TD) {
// set the underlying type of the typedef *before* we try to read
// the type associated with the TypedefDecl.
VisitNamedDecl(TD);
TD->setUnderlyingType(Reader.GetType(Record[Idx + 1]));
TD->setTypeForDecl(Reader.GetType(Record[Idx]).getTypePtr());
Idx += 2;
uint64_t TypeData = Record[Idx++];
TD->setTypeDeclaratorInfo(Reader.GetDeclaratorInfo(Record, Idx));
TD->setTypeForDecl(Reader.GetType(TypeData).getTypePtr());
}
void PCHDeclReader::VisitTagDecl(TagDecl *TD) {
@ -612,7 +612,7 @@ Decl *PCHReader::ReadDeclRecord(uint64_t Offset, unsigned Index) {
D = Context->getTranslationUnitDecl();
break;
case pch::DECL_TYPEDEF:
D = TypedefDecl::Create(*Context, 0, SourceLocation(), 0, QualType());
D = TypedefDecl::Create(*Context, 0, SourceLocation(), 0, 0);
break;
case pch::DECL_ENUM:
D = EnumDecl::Create(*Context, 0, SourceLocation(), 0, SourceLocation(), 0);

View File

@ -106,7 +106,7 @@ void PCHDeclWriter::VisitTypeDecl(TypeDecl *D) {
void PCHDeclWriter::VisitTypedefDecl(TypedefDecl *D) {
VisitTypeDecl(D);
Writer.AddTypeRef(D->getUnderlyingType(), Record);
Writer.AddDeclaratorInfo(D->getTypeDeclaratorInfo(), Record);
Code = pch::DECL_TYPEDEF;
}

View File

@ -2609,10 +2609,12 @@ Stmt *RewriteObjC::RewriteMessageExpr(ObjCMessageExpr *Exp) {
// typedef struct objc_object Protocol;
QualType RewriteObjC::getProtocolType() {
if (!ProtocolTypeDecl) {
DeclaratorInfo *DInfo
= Context->getTrivialDeclaratorInfo(Context->getObjCIdType());
ProtocolTypeDecl = TypedefDecl::Create(*Context, TUDecl,
SourceLocation(),
&Context->Idents.get("Protocol"),
Context->getObjCIdType());
DInfo);
}
return Context->getTypeDeclType(ProtocolTypeDecl);
}

View File

@ -45,6 +45,9 @@ protected:
if (DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D))
if (ContainsLocation(DD->getDeclaratorInfo()))
return ContainsLoc;
if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
if (ContainsLocation(TD->getTypeDeclaratorInfo()))
return ContainsLoc;
return CheckRange(D->getSourceRange());
}
@ -109,6 +112,7 @@ public:
ASTLocation VisitVarDecl(VarDecl *D);
ASTLocation VisitFunctionDecl(FunctionDecl *D);
ASTLocation VisitObjCMethodDecl(ObjCMethodDecl *D);
ASTLocation VisitTypedefDecl(TypedefDecl *D);
ASTLocation VisitDecl(Decl *D);
};
@ -278,6 +282,16 @@ ASTLocation DeclLocResolver::VisitDeclaratorDecl(DeclaratorDecl *D) {
return ASTLocation(D);
}
ASTLocation DeclLocResolver::VisitTypedefDecl(TypedefDecl *D) {
assert(ContainsLocation(D) &&
"Should visit only after verifying that loc is in range");
if (ContainsLocation(D->getTypeDeclaratorInfo()))
return ResolveInDeclarator(D, /*Stmt=*/0, D->getTypeDeclaratorInfo());
return ASTLocation(D);
}
ASTLocation DeclLocResolver::VisitVarDecl(VarDecl *D) {
assert(ContainsLocation(D) &&
"Should visit only after verifying that loc is in range");

View File

@ -277,15 +277,20 @@ void Sema::ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) {
PushDeclContext(S, Context.getTranslationUnitDecl());
if (PP.getTargetInfo().getPointerWidth(0) >= 64) {
DeclaratorInfo *DInfo;
// Install [u]int128_t for 64-bit targets.
DInfo = Context.getTrivialDeclaratorInfo(Context.Int128Ty);
PushOnScopeChains(TypedefDecl::Create(Context, CurContext,
SourceLocation(),
&Context.Idents.get("__int128_t"),
Context.Int128Ty), TUScope);
DInfo), TUScope);
DInfo = Context.getTrivialDeclaratorInfo(Context.UnsignedInt128Ty);
PushOnScopeChains(TypedefDecl::Create(Context, CurContext,
SourceLocation(),
&Context.Idents.get("__uint128_t"),
Context.UnsignedInt128Ty), TUScope);
DInfo), TUScope);
}
@ -298,10 +303,10 @@ void Sema::ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) {
PushOnScopeChains(SelTag, TUScope);
QualType SelT = Context.getPointerType(Context.getTagDeclType(SelTag));
TypedefDecl *SelTypedef = TypedefDecl::Create(Context, CurContext,
SourceLocation(),
&Context.Idents.get("SEL"),
SelT);
DeclaratorInfo *SelInfo = Context.getTrivialDeclaratorInfo(SelT);
TypedefDecl *SelTypedef
= TypedefDecl::Create(Context, CurContext, SourceLocation(),
&Context.Idents.get("SEL"), SelInfo);
PushOnScopeChains(SelTypedef, TUScope);
Context.setObjCSelType(Context.getTypeDeclType(SelTypedef));
}
@ -317,22 +322,23 @@ void Sema::ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) {
}
// Create the built-in typedef for 'id'.
if (Context.getObjCIdType().isNull()) {
TypedefDecl *IdTypedef =
TypedefDecl::Create(
Context, CurContext, SourceLocation(), &Context.Idents.get("id"),
Context.getObjCObjectPointerType(Context.ObjCBuiltinIdTy)
);
QualType IdT = Context.getObjCObjectPointerType(Context.ObjCBuiltinIdTy);
DeclaratorInfo *IdInfo = Context.getTrivialDeclaratorInfo(IdT);
TypedefDecl *IdTypedef
= TypedefDecl::Create(Context, CurContext, SourceLocation(),
&Context.Idents.get("id"), IdInfo);
PushOnScopeChains(IdTypedef, TUScope);
Context.setObjCIdType(Context.getTypeDeclType(IdTypedef));
Context.ObjCIdRedefinitionType = Context.getObjCIdType();
}
// Create the built-in typedef for 'Class'.
if (Context.getObjCClassType().isNull()) {
TypedefDecl *ClassTypedef =
TypedefDecl::Create(
Context, CurContext, SourceLocation(), &Context.Idents.get("Class"),
Context.getObjCObjectPointerType(Context.ObjCBuiltinClassTy)
);
QualType ClassType
= Context.getObjCObjectPointerType(Context.ObjCBuiltinClassTy);
DeclaratorInfo *ClassInfo = Context.getTrivialDeclaratorInfo(ClassType);
TypedefDecl *ClassTypedef
= TypedefDecl::Create(Context, CurContext, SourceLocation(),
&Context.Idents.get("Class"), ClassInfo);
PushOnScopeChains(ClassTypedef, TUScope);
Context.setObjCClassType(Context.getTypeDeclType(ClassTypedef));
Context.ObjCClassRedefinitionType = Context.getObjCClassType();

View File

@ -767,7 +767,8 @@ public:
/// Subroutines of ActOnDeclarator().
TypedefDecl *ParseTypedefDecl(Scope *S, Declarator &D, QualType T);
TypedefDecl *ParseTypedefDecl(Scope *S, Declarator &D, QualType T,
DeclaratorInfo *DInfo);
void MergeTypeDefDecl(TypedefDecl *New, Decl *Old);
bool MergeFunctionDecl(FunctionDecl *New, Decl *Old);
bool MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old);

View File

@ -1986,12 +1986,9 @@ Sema::ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC,
if (D.getDeclSpec().isThreadSpecified())
Diag(D.getDeclSpec().getThreadSpecLoc(), diag::err_invalid_thread);
TypedefDecl *NewTD = ParseTypedefDecl(S, D, R);
TypedefDecl *NewTD = ParseTypedefDecl(S, D, R, DInfo);
if (!NewTD) return 0;
if (D.isInvalidType())
NewTD->setInvalidDecl();
// Handle attributes prior to checking for duplicates in MergeVarDecl
ProcessDeclAttributes(S, NewTD, D);
// Merge the decl with the existing one if appropriate. If the decl is
@ -2013,7 +2010,7 @@ Sema::ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC,
TryToFixInvalidVariablyModifiedType(T, Context, SizeIsNegative);
if (!FixedTy.isNull()) {
Diag(D.getIdentifierLoc(), diag::warn_illegal_constant_array_size);
NewTD->setUnderlyingType(FixedTy);
NewTD->setTypeDeclaratorInfo(Context.getTrivialDeclaratorInfo(FixedTy));
} else {
if (SizeIsNegative)
Diag(D.getIdentifierLoc(), diag::err_typecheck_negative_array_size);
@ -4097,15 +4094,21 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) {
}
}
TypedefDecl *Sema::ParseTypedefDecl(Scope *S, Declarator &D, QualType T) {
TypedefDecl *Sema::ParseTypedefDecl(Scope *S, Declarator &D, QualType T,
DeclaratorInfo *DInfo) {
assert(D.getIdentifier() && "Wrong callback for declspec without declarator");
assert(!T.isNull() && "GetTypeForDeclarator() returned null type");
if (!DInfo) {
assert(D.isInvalidType() && "no declarator info for valid type");
DInfo = Context.getTrivialDeclaratorInfo(T);
}
// Scope manipulation handled by caller.
TypedefDecl *NewTD = TypedefDecl::Create(Context, CurContext,
D.getIdentifierLoc(),
D.getIdentifier(),
T);
DInfo);
if (const TagType *TT = T->getAs<TagType>()) {
TagDecl *TD = TT->getDecl();

View File

@ -193,7 +193,8 @@ static void HandleExtVectorTypeAttr(Scope *scope, Decl *d,
// This will run the reguired checks.
QualType T = S.BuildExtVectorType(curType, S.Owned(sizeExpr), Attr.getLoc());
if (!T.isNull()) {
tDecl->setUnderlyingType(T);
// FIXME: preserve the old source info.
tDecl->setTypeDeclaratorInfo(S.Context.getTrivialDeclaratorInfo(T));
// Remember this typedef decl, we will need it later for diagnostics.
S.ExtVectorDecls.push_back(tDecl);
@ -278,8 +279,11 @@ static void HandleVectorSizeAttr(Decl *D, const AttributeList &Attr, Sema &S) {
if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
VD->setType(CurType);
else
cast<TypedefDecl>(D)->setUnderlyingType(CurType);
else {
// FIXME: preserve existing source info.
DeclaratorInfo *DInfo = S.Context.getTrivialDeclaratorInfo(CurType);
cast<TypedefDecl>(D)->setTypeDeclaratorInfo(DInfo);
}
}
static void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@ -1636,9 +1640,10 @@ static void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) {
}
// Install the new type.
if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
TD->setUnderlyingType(NewTy);
else
if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
// FIXME: preserve existing source info.
TD->setTypeDeclaratorInfo(S.Context.getTrivialDeclaratorInfo(NewTy));
} else
cast<ValueDecl>(D)->setType(NewTy);
}

View File

@ -99,20 +99,20 @@ TemplateDeclInstantiator::VisitNamespaceDecl(NamespaceDecl *D) {
Decl *TemplateDeclInstantiator::VisitTypedefDecl(TypedefDecl *D) {
bool Invalid = false;
QualType T = D->getUnderlyingType();
if (T->isDependentType()) {
T = SemaRef.SubstType(T, TemplateArgs,
DeclaratorInfo *DI = D->getTypeDeclaratorInfo();
if (DI->getType()->isDependentType()) {
DI = SemaRef.SubstType(DI, TemplateArgs,
D->getLocation(), D->getDeclName());
if (T.isNull()) {
if (!DI) {
Invalid = true;
T = SemaRef.Context.IntTy;
DI = SemaRef.Context.getTrivialDeclaratorInfo(SemaRef.Context.IntTy);
}
}
// Create the new typedef
TypedefDecl *Typedef
= TypedefDecl::Create(SemaRef.Context, Owner, D->getLocation(),
D->getIdentifier(), T);
D->getIdentifier(), DI);
if (Invalid)
Typedef->setInvalidDecl();