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 { class TypedefDecl : public TypeDecl {
/// UnderlyingType - This is the type the typedef is set to. /// UnderlyingType - This is the type the typedef is set to.
QualType UnderlyingType; DeclaratorInfo *DInfo;
TypedefDecl(DeclContext *DC, SourceLocation L, TypedefDecl(DeclContext *DC, SourceLocation L,
IdentifierInfo *Id, QualType T) IdentifierInfo *Id, DeclaratorInfo *DInfo)
: TypeDecl(Typedef, DC, L, Id), UnderlyingType(T) {} : TypeDecl(Typedef, DC, L, Id), DInfo(DInfo) {}
virtual ~TypedefDecl() {} virtual ~TypedefDecl() {}
public: public:
static TypedefDecl *Create(ASTContext &C, DeclContext *DC, static TypedefDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L,IdentifierInfo *Id, SourceLocation L, IdentifierInfo *Id,
QualType T); DeclaratorInfo *DInfo);
QualType getUnderlyingType() const { return UnderlyingType; } DeclaratorInfo *getTypeDeclaratorInfo() const {
void setUnderlyingType(QualType newType) { UnderlyingType = newType; } return DInfo;
}
QualType getUnderlyingType() const {
return DInfo->getType();
}
void setTypeDeclaratorInfo(DeclaratorInfo *newType) {
DInfo = newType;
}
// Implement isa/cast/dyncast/etc. // Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return D->getKind() == Typedef; } 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, TypedefDecl *TypedefDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation L, SourceLocation L, IdentifierInfo *Id,
IdentifierInfo *Id, QualType T) { DeclaratorInfo *DInfo) {
return new (C) TypedefDecl(DC, L, Id, T); return new (C) TypedefDecl(DC, L, Id, DInfo);
} }
EnumDecl *EnumDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, 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 // set the underlying type of the typedef *before* we try to read
// the type associated with the TypedefDecl. // the type associated with the TypedefDecl.
VisitNamedDecl(TD); VisitNamedDecl(TD);
TD->setUnderlyingType(Reader.GetType(Record[Idx + 1])); uint64_t TypeData = Record[Idx++];
TD->setTypeForDecl(Reader.GetType(Record[Idx]).getTypePtr()); TD->setTypeDeclaratorInfo(Reader.GetDeclaratorInfo(Record, Idx));
Idx += 2; TD->setTypeForDecl(Reader.GetType(TypeData).getTypePtr());
} }
void PCHDeclReader::VisitTagDecl(TagDecl *TD) { void PCHDeclReader::VisitTagDecl(TagDecl *TD) {
@ -612,7 +612,7 @@ Decl *PCHReader::ReadDeclRecord(uint64_t Offset, unsigned Index) {
D = Context->getTranslationUnitDecl(); D = Context->getTranslationUnitDecl();
break; break;
case pch::DECL_TYPEDEF: case pch::DECL_TYPEDEF:
D = TypedefDecl::Create(*Context, 0, SourceLocation(), 0, QualType()); D = TypedefDecl::Create(*Context, 0, SourceLocation(), 0, 0);
break; break;
case pch::DECL_ENUM: case pch::DECL_ENUM:
D = EnumDecl::Create(*Context, 0, SourceLocation(), 0, SourceLocation(), 0); 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) { void PCHDeclWriter::VisitTypedefDecl(TypedefDecl *D) {
VisitTypeDecl(D); VisitTypeDecl(D);
Writer.AddTypeRef(D->getUnderlyingType(), Record); Writer.AddDeclaratorInfo(D->getTypeDeclaratorInfo(), Record);
Code = pch::DECL_TYPEDEF; Code = pch::DECL_TYPEDEF;
} }

View File

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

View File

@ -45,6 +45,9 @@ protected:
if (DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) if (DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D))
if (ContainsLocation(DD->getDeclaratorInfo())) if (ContainsLocation(DD->getDeclaratorInfo()))
return ContainsLoc; return ContainsLoc;
if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
if (ContainsLocation(TD->getTypeDeclaratorInfo()))
return ContainsLoc;
return CheckRange(D->getSourceRange()); return CheckRange(D->getSourceRange());
} }
@ -109,6 +112,7 @@ public:
ASTLocation VisitVarDecl(VarDecl *D); ASTLocation VisitVarDecl(VarDecl *D);
ASTLocation VisitFunctionDecl(FunctionDecl *D); ASTLocation VisitFunctionDecl(FunctionDecl *D);
ASTLocation VisitObjCMethodDecl(ObjCMethodDecl *D); ASTLocation VisitObjCMethodDecl(ObjCMethodDecl *D);
ASTLocation VisitTypedefDecl(TypedefDecl *D);
ASTLocation VisitDecl(Decl *D); ASTLocation VisitDecl(Decl *D);
}; };
@ -278,6 +282,16 @@ ASTLocation DeclLocResolver::VisitDeclaratorDecl(DeclaratorDecl *D) {
return ASTLocation(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) { ASTLocation DeclLocResolver::VisitVarDecl(VarDecl *D) {
assert(ContainsLocation(D) && assert(ContainsLocation(D) &&
"Should visit only after verifying that loc is in range"); "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()); PushDeclContext(S, Context.getTranslationUnitDecl());
if (PP.getTargetInfo().getPointerWidth(0) >= 64) { if (PP.getTargetInfo().getPointerWidth(0) >= 64) {
DeclaratorInfo *DInfo;
// Install [u]int128_t for 64-bit targets. // Install [u]int128_t for 64-bit targets.
DInfo = Context.getTrivialDeclaratorInfo(Context.Int128Ty);
PushOnScopeChains(TypedefDecl::Create(Context, CurContext, PushOnScopeChains(TypedefDecl::Create(Context, CurContext,
SourceLocation(), SourceLocation(),
&Context.Idents.get("__int128_t"), &Context.Idents.get("__int128_t"),
Context.Int128Ty), TUScope); DInfo), TUScope);
DInfo = Context.getTrivialDeclaratorInfo(Context.UnsignedInt128Ty);
PushOnScopeChains(TypedefDecl::Create(Context, CurContext, PushOnScopeChains(TypedefDecl::Create(Context, CurContext,
SourceLocation(), SourceLocation(),
&Context.Idents.get("__uint128_t"), &Context.Idents.get("__uint128_t"),
Context.UnsignedInt128Ty), TUScope); DInfo), TUScope);
} }
@ -298,10 +303,10 @@ void Sema::ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) {
PushOnScopeChains(SelTag, TUScope); PushOnScopeChains(SelTag, TUScope);
QualType SelT = Context.getPointerType(Context.getTagDeclType(SelTag)); QualType SelT = Context.getPointerType(Context.getTagDeclType(SelTag));
TypedefDecl *SelTypedef = TypedefDecl::Create(Context, CurContext, DeclaratorInfo *SelInfo = Context.getTrivialDeclaratorInfo(SelT);
SourceLocation(), TypedefDecl *SelTypedef
&Context.Idents.get("SEL"), = TypedefDecl::Create(Context, CurContext, SourceLocation(),
SelT); &Context.Idents.get("SEL"), SelInfo);
PushOnScopeChains(SelTypedef, TUScope); PushOnScopeChains(SelTypedef, TUScope);
Context.setObjCSelType(Context.getTypeDeclType(SelTypedef)); Context.setObjCSelType(Context.getTypeDeclType(SelTypedef));
} }
@ -317,22 +322,23 @@ void Sema::ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) {
} }
// Create the built-in typedef for 'id'. // Create the built-in typedef for 'id'.
if (Context.getObjCIdType().isNull()) { if (Context.getObjCIdType().isNull()) {
TypedefDecl *IdTypedef = QualType IdT = Context.getObjCObjectPointerType(Context.ObjCBuiltinIdTy);
TypedefDecl::Create( DeclaratorInfo *IdInfo = Context.getTrivialDeclaratorInfo(IdT);
Context, CurContext, SourceLocation(), &Context.Idents.get("id"), TypedefDecl *IdTypedef
Context.getObjCObjectPointerType(Context.ObjCBuiltinIdTy) = TypedefDecl::Create(Context, CurContext, SourceLocation(),
); &Context.Idents.get("id"), IdInfo);
PushOnScopeChains(IdTypedef, TUScope); PushOnScopeChains(IdTypedef, TUScope);
Context.setObjCIdType(Context.getTypeDeclType(IdTypedef)); Context.setObjCIdType(Context.getTypeDeclType(IdTypedef));
Context.ObjCIdRedefinitionType = Context.getObjCIdType(); Context.ObjCIdRedefinitionType = Context.getObjCIdType();
} }
// Create the built-in typedef for 'Class'. // Create the built-in typedef for 'Class'.
if (Context.getObjCClassType().isNull()) { if (Context.getObjCClassType().isNull()) {
TypedefDecl *ClassTypedef = QualType ClassType
TypedefDecl::Create( = Context.getObjCObjectPointerType(Context.ObjCBuiltinClassTy);
Context, CurContext, SourceLocation(), &Context.Idents.get("Class"), DeclaratorInfo *ClassInfo = Context.getTrivialDeclaratorInfo(ClassType);
Context.getObjCObjectPointerType(Context.ObjCBuiltinClassTy) TypedefDecl *ClassTypedef
); = TypedefDecl::Create(Context, CurContext, SourceLocation(),
&Context.Idents.get("Class"), ClassInfo);
PushOnScopeChains(ClassTypedef, TUScope); PushOnScopeChains(ClassTypedef, TUScope);
Context.setObjCClassType(Context.getTypeDeclType(ClassTypedef)); Context.setObjCClassType(Context.getTypeDeclType(ClassTypedef));
Context.ObjCClassRedefinitionType = Context.getObjCClassType(); Context.ObjCClassRedefinitionType = Context.getObjCClassType();

View File

@ -767,7 +767,8 @@ public:
/// Subroutines of ActOnDeclarator(). /// 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); void MergeTypeDefDecl(TypedefDecl *New, Decl *Old);
bool MergeFunctionDecl(FunctionDecl *New, Decl *Old); bool MergeFunctionDecl(FunctionDecl *New, Decl *Old);
bool MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *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()) if (D.getDeclSpec().isThreadSpecified())
Diag(D.getDeclSpec().getThreadSpecLoc(), diag::err_invalid_thread); 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 (!NewTD) return 0;
if (D.isInvalidType())
NewTD->setInvalidDecl();
// Handle attributes prior to checking for duplicates in MergeVarDecl // Handle attributes prior to checking for duplicates in MergeVarDecl
ProcessDeclAttributes(S, NewTD, D); ProcessDeclAttributes(S, NewTD, D);
// Merge the decl with the existing one if appropriate. If the decl is // 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); TryToFixInvalidVariablyModifiedType(T, Context, SizeIsNegative);
if (!FixedTy.isNull()) { if (!FixedTy.isNull()) {
Diag(D.getIdentifierLoc(), diag::warn_illegal_constant_array_size); Diag(D.getIdentifierLoc(), diag::warn_illegal_constant_array_size);
NewTD->setUnderlyingType(FixedTy); NewTD->setTypeDeclaratorInfo(Context.getTrivialDeclaratorInfo(FixedTy));
} else { } else {
if (SizeIsNegative) if (SizeIsNegative)
Diag(D.getIdentifierLoc(), diag::err_typecheck_negative_array_size); 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(D.getIdentifier() && "Wrong callback for declspec without declarator");
assert(!T.isNull() && "GetTypeForDeclarator() returned null type"); 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. // Scope manipulation handled by caller.
TypedefDecl *NewTD = TypedefDecl::Create(Context, CurContext, TypedefDecl *NewTD = TypedefDecl::Create(Context, CurContext,
D.getIdentifierLoc(), D.getIdentifierLoc(),
D.getIdentifier(), D.getIdentifier(),
T); DInfo);
if (const TagType *TT = T->getAs<TagType>()) { if (const TagType *TT = T->getAs<TagType>()) {
TagDecl *TD = TT->getDecl(); TagDecl *TD = TT->getDecl();

View File

@ -193,7 +193,8 @@ static void HandleExtVectorTypeAttr(Scope *scope, Decl *d,
// This will run the reguired checks. // This will run the reguired checks.
QualType T = S.BuildExtVectorType(curType, S.Owned(sizeExpr), Attr.getLoc()); QualType T = S.BuildExtVectorType(curType, S.Owned(sizeExpr), Attr.getLoc());
if (!T.isNull()) { 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. // Remember this typedef decl, we will need it later for diagnostics.
S.ExtVectorDecls.push_back(tDecl); 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)) if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
VD->setType(CurType); VD->setType(CurType);
else else {
cast<TypedefDecl>(D)->setUnderlyingType(CurType); // 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) { 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. // Install the new type.
if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
TD->setUnderlyingType(NewTy); // FIXME: preserve existing source info.
else TD->setTypeDeclaratorInfo(S.Context.getTrivialDeclaratorInfo(NewTy));
} else
cast<ValueDecl>(D)->setType(NewTy); cast<ValueDecl>(D)->setType(NewTy);
} }

View File

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