diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2011-12-26 22:42:47 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2011-12-26 22:42:47 +0000 |
commit | cde2c8f7d27f376279f36bd38097551ec717bed2 (patch) | |
tree | 0187d63ca8b9c6df1ab9fa442a3ce28f654980d6 /clang/lib/Sema/SemaDecl.cpp | |
parent | 8d302df4a43e95c89de272adff79c71c61249990 (diff) | |
download | bcm5719-llvm-cde2c8f7d27f376279f36bd38097551ec717bed2.tar.gz bcm5719-llvm-cde2c8f7d27f376279f36bd38097551ec717bed2.zip |
Delay checking of typedefs of dependent types. Fixes PR11630.
llvm-svn: 147281
Diffstat (limited to 'clang/lib/Sema/SemaDecl.cpp')
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 46 |
1 files changed, 26 insertions, 20 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 00c6b9fcf09..a13f1826b6f 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -1368,6 +1368,30 @@ NamedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned bid, return New; } +bool Sema::isIncompatibleTypedef(TypeDecl *Old, TypedefNameDecl *New) { + QualType OldType; + if (TypedefNameDecl *OldTypedef = dyn_cast<TypedefNameDecl>(Old)) + OldType = OldTypedef->getUnderlyingType(); + else + OldType = Context.getTypeDeclType(Old); + QualType NewType = New->getUnderlyingType(); + + if (OldType != NewType && + !OldType->isDependentType() && + !NewType->isDependentType() && + Context.getCanonicalType(OldType) != + Context.getCanonicalType(NewType)) { + int Kind = isa<TypeAliasDecl>(Old) ? 1 : 0; + Diag(New->getLocation(), diag::err_redefinition_different_typedef) + << Kind << NewType << OldType; + if (Old->getLocation().isValid()) + Diag(Old->getLocation(), diag::note_previous_definition); + New->setInvalidDecl(); + return true; + } + return false; +} + /// MergeTypedefNameDecl - We just parsed a typedef 'New' which has the /// same name and scope as a previous declaration 'Old'. Figure out /// how to resolve this situation, merging decls or emitting @@ -1426,28 +1450,10 @@ void Sema::MergeTypedefNameDecl(TypedefNameDecl *New, LookupResult &OldDecls) { if (Old->isInvalidDecl()) return New->setInvalidDecl(); - // Determine the "old" type we'll use for checking and diagnostics. - QualType OldType; - if (TypedefNameDecl *OldTypedef = dyn_cast<TypedefNameDecl>(Old)) - OldType = OldTypedef->getUnderlyingType(); - else - OldType = Context.getTypeDeclType(Old); - // If the typedef types are not identical, reject them in all languages and // with any extensions enabled. - - if (OldType != New->getUnderlyingType() && - Context.getCanonicalType(OldType) != - Context.getCanonicalType(New->getUnderlyingType())) { - int Kind = 0; - if (isa<TypeAliasDecl>(Old)) - Kind = 1; - Diag(New->getLocation(), diag::err_redefinition_different_typedef) - << Kind << New->getUnderlyingType() << OldType; - if (Old->getLocation().isValid()) - Diag(Old->getLocation(), diag::note_previous_definition); - return New->setInvalidDecl(); - } + if (isIncompatibleTypedef(Old, New)) + return; // The types match. Link up the redeclaration chain if the old // declaration was a typedef. |