зеркало из https://github.com/microsoft/clang-1.git
Typedefs can be redeclared. That seems like something we should record in
the AST lest we run into some crazy canonicalization bug like PR5874. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@92283 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
4df6ec10e0
Коммит
5126fd0dd9
|
@ -1449,7 +1449,7 @@ public:
|
|||
};
|
||||
|
||||
|
||||
class TypedefDecl : public TypeDecl {
|
||||
class TypedefDecl : public TypeDecl, public Redeclarable<TypedefDecl> {
|
||||
/// UnderlyingType - This is the type the typedef is set to.
|
||||
TypeSourceInfo *TInfo;
|
||||
|
||||
|
@ -1457,7 +1457,7 @@ class TypedefDecl : public TypeDecl {
|
|||
IdentifierInfo *Id, TypeSourceInfo *TInfo)
|
||||
: TypeDecl(Typedef, DC, L, Id), TInfo(TInfo) {}
|
||||
|
||||
virtual ~TypedefDecl() {}
|
||||
virtual ~TypedefDecl();
|
||||
public:
|
||||
|
||||
static TypedefDecl *Create(ASTContext &C, DeclContext *DC,
|
||||
|
@ -1468,6 +1468,14 @@ public:
|
|||
return TInfo;
|
||||
}
|
||||
|
||||
/// Retrieves the canonical declaration of this typedef.
|
||||
TypedefDecl *getCanonicalDecl() {
|
||||
return getFirstDeclaration();
|
||||
}
|
||||
const TypedefDecl *getCanonicalDecl() const {
|
||||
return getFirstDeclaration();
|
||||
}
|
||||
|
||||
QualType getUnderlyingType() const {
|
||||
return TInfo->getType();
|
||||
}
|
||||
|
|
|
@ -212,6 +212,9 @@ TypedefDecl *TypedefDecl::Create(ASTContext &C, DeclContext *DC,
|
|||
return new (C) TypedefDecl(DC, L, Id, TInfo);
|
||||
}
|
||||
|
||||
// Anchor TypedefDecl's vtable here.
|
||||
TypedefDecl::~TypedefDecl() {}
|
||||
|
||||
EnumDecl *EnumDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
|
||||
IdentifierInfo *Id, SourceLocation TKL,
|
||||
EnumDecl *PrevDecl) {
|
||||
|
|
|
@ -696,9 +696,8 @@ void Sema::MergeTypeDefDecl(TypedefDecl *New, LookupResult &OldDecls) {
|
|||
}
|
||||
|
||||
// Verify the old decl was also a type.
|
||||
TypeDecl *Old = 0;
|
||||
if (!OldDecls.isSingleResult() ||
|
||||
!(Old = dyn_cast<TypeDecl>(OldDecls.getFoundDecl()))) {
|
||||
TypeDecl *Old = OldDecls.getAsSingle<TypeDecl>();
|
||||
if (!Old) {
|
||||
Diag(New->getLocation(), diag::err_redefinition_different_kind)
|
||||
<< New->getDeclName();
|
||||
|
||||
|
@ -733,6 +732,13 @@ void Sema::MergeTypeDefDecl(TypedefDecl *New, LookupResult &OldDecls) {
|
|||
return New->setInvalidDecl();
|
||||
}
|
||||
|
||||
// The types match. Link up the redeclaration chain if the old
|
||||
// declaration was a typedef.
|
||||
// FIXME: this is a potential source of wierdness if the type
|
||||
// spellings don't match exactly.
|
||||
if (isa<TypedefDecl>(Old))
|
||||
New->setPreviousDeclaration(cast<TypedefDecl>(Old));
|
||||
|
||||
if (getLangOptions().Microsoft)
|
||||
return;
|
||||
|
||||
|
|
|
@ -145,6 +145,11 @@ Decl *TemplateDeclInstantiator::VisitTypedefDecl(TypedefDecl *D) {
|
|||
if (Invalid)
|
||||
Typedef->setInvalidDecl();
|
||||
|
||||
if (TypedefDecl *Prev = D->getPreviousDeclaration()) {
|
||||
NamedDecl *InstPrev = SemaRef.FindInstantiatedDecl(Prev, TemplateArgs);
|
||||
Typedef->setPreviousDeclaration(cast<TypedefDecl>(InstPrev));
|
||||
}
|
||||
|
||||
Owner->addDecl(Typedef);
|
||||
|
||||
return Typedef;
|
||||
|
|
|
@ -29,3 +29,11 @@ typedef I I;
|
|||
|
||||
struct s { };
|
||||
|
||||
// PR5874
|
||||
namespace test1 {
|
||||
typedef int foo;
|
||||
namespace a { using test1::foo; };
|
||||
typedef int foo;
|
||||
using namespace a;
|
||||
foo x;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче