forked from OSchip/llvm-project
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:
parent
3db7bd27c2
commit
703a3f8a7b
|
@ -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);
|
||||
SourceLocation L, IdentifierInfo *Id,
|
||||
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; }
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
D->getLocation(), D->getDeclName());
|
||||
if (T.isNull()) {
|
||||
DeclaratorInfo *DI = D->getTypeDeclaratorInfo();
|
||||
if (DI->getType()->isDependentType()) {
|
||||
DI = SemaRef.SubstType(DI, TemplateArgs,
|
||||
D->getLocation(), D->getDeclName());
|
||||
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();
|
||||
|
||||
|
|
Loading…
Reference in New Issue