diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/ASTDumper.cpp | 6 | ||||
-rw-r--r-- | lib/AST/Decl.cpp | 4 | ||||
-rw-r--r-- | lib/AST/DeclBase.cpp | 10 | ||||
-rw-r--r-- | lib/AST/ODRHash.cpp | 80 | ||||
-rw-r--r-- | lib/CodeGen/CGDebugInfo.cpp | 2 | ||||
-rw-r--r-- | lib/Driver/ToolChains/MSVC.cpp | 11 | ||||
-rw-r--r-- | lib/Frontend/ASTUnit.cpp | 23 | ||||
-rw-r--r-- | lib/Headers/xmmintrin.h | 25 | ||||
-rw-r--r-- | lib/Lex/Lexer.cpp | 4 | ||||
-rw-r--r-- | lib/Sema/Sema.cpp | 9 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 15 | ||||
-rw-r--r-- | lib/Sema/SemaLookup.cpp | 57 | ||||
-rw-r--r-- | lib/Serialization/ASTReader.cpp | 31 |
13 files changed, 134 insertions, 143 deletions
diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp index ef491ab06f8c..d89be0d9e6fa 100644 --- a/lib/AST/ASTDumper.cpp +++ b/lib/AST/ASTDumper.cpp @@ -1038,10 +1038,10 @@ void ASTDumper::dumpDecl(const Decl *D) { dumpSourceRange(D->getSourceRange()); OS << ' '; dumpLocation(D->getLocation()); - if (Module *M = D->getImportedOwningModule()) + if (D->isFromASTFile()) + OS << " imported"; + if (Module *M = D->getOwningModule()) OS << " in " << M->getFullModuleName(); - else if (Module *M = D->getLocalOwningModule()) - OS << " in (local) " << M->getFullModuleName(); if (auto *ND = dyn_cast<NamedDecl>(D)) for (Module *M : D->getASTContext().getModulesWithMergedDefinition( const_cast<NamedDecl *>(ND))) diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index 0f2558e24ba5..a1342f477b68 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -47,9 +47,7 @@ bool Decl::isOutOfLine() const { TranslationUnitDecl::TranslationUnitDecl(ASTContext &ctx) : Decl(TranslationUnit, nullptr, SourceLocation()), - DeclContext(TranslationUnit), Ctx(ctx), AnonymousNamespace(nullptr) { - Hidden = Ctx.getLangOpts().ModulesLocalVisibility; -} + DeclContext(TranslationUnit), Ctx(ctx), AnonymousNamespace(nullptr) {} //===----------------------------------------------------------------------===// // NamedDecl Implementation diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp index 5c2c9cbd0180..f6f81692611d 100644 --- a/lib/AST/DeclBase.cpp +++ b/lib/AST/DeclBase.cpp @@ -75,7 +75,7 @@ void *Decl::operator new(std::size_t Size, const ASTContext &Ctx, assert(!Parent || &Parent->getParentASTContext() == &Ctx); // With local visibility enabled, we track the owning module even for local // declarations. - if (Ctx.getLangOpts().ModulesLocalVisibility) { + if (Ctx.getLangOpts().trackLocalOwningModule()) { // Ensure required alignment of the resulting object by adding extra // padding at the start if required. size_t ExtraAlign = @@ -83,7 +83,9 @@ void *Decl::operator new(std::size_t Size, const ASTContext &Ctx, char *Buffer = reinterpret_cast<char *>( ::operator new(ExtraAlign + sizeof(Module *) + Size + Extra, Ctx)); Buffer += ExtraAlign; - return new (Buffer) Module*(nullptr) + 1; + auto *ParentModule = + Parent ? cast<Decl>(Parent)->getOwningModule() : nullptr; + return new (Buffer) Module*(ParentModule) + 1; } return ::operator new(Size + Extra, Ctx); } @@ -94,7 +96,7 @@ Module *Decl::getOwningModuleSlow() const { } bool Decl::hasLocalOwningModuleStorage() const { - return getASTContext().getLangOpts().ModulesLocalVisibility; + return getASTContext().getLangOpts().trackLocalOwningModule(); } const char *Decl::getDeclKindName() const { @@ -273,6 +275,8 @@ void Decl::setLexicalDeclContext(DeclContext *DC) { getMultipleDC()->LexicalDC = DC; } Hidden = cast<Decl>(DC)->Hidden; + if (Hidden && !isFromASTFile() && hasLocalOwningModuleStorage()) + setLocalOwningModule(cast<Decl>(DC)->getOwningModule()); } void Decl::setDeclContextsImpl(DeclContext *SemaDC, DeclContext *LexicalDC, diff --git a/lib/AST/ODRHash.cpp b/lib/AST/ODRHash.cpp index f4d314a6dd0d..24371db64d07 100644 --- a/lib/AST/ODRHash.cpp +++ b/lib/AST/ODRHash.cpp @@ -81,7 +81,35 @@ void ODRHash::AddDeclarationName(DeclarationName Name) { } } -void ODRHash::AddNestedNameSpecifier(const NestedNameSpecifier *NNS) {} +void ODRHash::AddNestedNameSpecifier(const NestedNameSpecifier *NNS) { + assert(NNS && "Expecting non-null pointer."); + const auto *Prefix = NNS->getPrefix(); + AddBoolean(Prefix); + if (Prefix) { + AddNestedNameSpecifier(Prefix); + } + auto Kind = NNS->getKind(); + ID.AddInteger(Kind); + switch (Kind) { + case NestedNameSpecifier::Identifier: + AddIdentifierInfo(NNS->getAsIdentifier()); + break; + case NestedNameSpecifier::Namespace: + AddDecl(NNS->getAsNamespace()); + break; + case NestedNameSpecifier::NamespaceAlias: + AddDecl(NNS->getAsNamespaceAlias()); + break; + case NestedNameSpecifier::TypeSpec: + case NestedNameSpecifier::TypeSpecWithTemplate: + AddType(NNS->getAsType()); + break; + case NestedNameSpecifier::Global: + case NestedNameSpecifier::Super: + break; + } +} + void ODRHash::AddTemplateName(TemplateName Name) {} void ODRHash::AddTemplateArgument(TemplateArgument TA) {} void ODRHash::AddTemplateParameterList(const TemplateParameterList *TPL) {} @@ -335,6 +363,20 @@ public: Hash.AddQualType(T); } + void AddNestedNameSpecifier(const NestedNameSpecifier *NNS) { + Hash.AddBoolean(NNS); + if (NNS) { + Hash.AddNestedNameSpecifier(NNS); + } + } + + void AddIdentifierInfo(const IdentifierInfo *II) { + Hash.AddBoolean(II); + if (II) { + Hash.AddIdentifierInfo(II); + } + } + void VisitQualifiers(Qualifiers Quals) { ID.AddInteger(Quals.getAsOpaqueValue()); } @@ -414,6 +456,42 @@ public: AddQualType(T->getDecl()->getUnderlyingType().getCanonicalType()); VisitType(T); } + + void VisitTagType(const TagType *T) { + AddDecl(T->getDecl()); + VisitType(T); + } + + void VisitRecordType(const RecordType *T) { VisitTagType(T); } + void VisitEnumType(const EnumType *T) { VisitTagType(T); } + + void VisitTypeWithKeyword(const TypeWithKeyword *T) { + ID.AddInteger(T->getKeyword()); + VisitType(T); + }; + + void VisitDependentNameType(const DependentNameType *T) { + AddNestedNameSpecifier(T->getQualifier()); + AddIdentifierInfo(T->getIdentifier()); + VisitTypeWithKeyword(T); + } + + void VisitDependentTemplateSpecializationType( + const DependentTemplateSpecializationType *T) { + AddIdentifierInfo(T->getIdentifier()); + AddNestedNameSpecifier(T->getQualifier()); + ID.AddInteger(T->getNumArgs()); + for (const auto &TA : T->template_arguments()) { + Hash.AddTemplateArgument(TA); + } + VisitTypeWithKeyword(T); + } + + void VisitElaboratedType(const ElaboratedType *T) { + AddNestedNameSpecifier(T->getQualifier()); + AddQualType(T->getNamedType()); + VisitTypeWithKeyword(T); + } }; void ODRHash::AddType(const Type *T) { diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp index 9d77c61bd52c..bf178dd7fd80 100644 --- a/lib/CodeGen/CGDebugInfo.cpp +++ b/lib/CodeGen/CGDebugInfo.cpp @@ -2860,7 +2860,7 @@ void CGDebugInfo::collectFunctionDeclProps(GlobalDecl GD, llvm::DIFile *Unit, if (DebugKind >= codegenoptions::LimitedDebugInfo) { if (const NamespaceDecl *NSDecl = - dyn_cast_or_null<NamespaceDecl>(FD->getLexicalDeclContext())) + dyn_cast_or_null<NamespaceDecl>(FD->getDeclContext())) FDContext = getOrCreateNamespace(NSDecl); else if (const RecordDecl *RDecl = dyn_cast_or_null<RecordDecl>(FD->getDeclContext())) { diff --git a/lib/Driver/ToolChains/MSVC.cpp b/lib/Driver/ToolChains/MSVC.cpp index a09304814ca6..6f5f54165b3b 100644 --- a/lib/Driver/ToolChains/MSVC.cpp +++ b/lib/Driver/ToolChains/MSVC.cpp @@ -125,8 +125,15 @@ static bool findVCToolChainViaEnvironment(std::string &Path, continue; // whatever/VC/bin --> old toolchain, VC dir is toolchain dir. - if (llvm::sys::path::filename(PathEntry) == "bin") { - llvm::StringRef ParentPath = llvm::sys::path::parent_path(PathEntry); + llvm::StringRef TestPath = PathEntry; + bool IsBin = llvm::sys::path::filename(TestPath).equals_lower("bin"); + if (!IsBin) { + // Strip any architecture subdir like "amd64". + TestPath = llvm::sys::path::parent_path(TestPath); + IsBin = llvm::sys::path::filename(TestPath).equals_lower("bin"); + } + if (IsBin) { + llvm::StringRef ParentPath = llvm::sys::path::parent_path(TestPath); if (llvm::sys::path::filename(ParentPath) == "VC") { Path = ParentPath; IsVS2017OrNewer = false; diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp index 32ee9d3e9961..6ee211c2de67 100644 --- a/lib/Frontend/ASTUnit.cpp +++ b/lib/Frontend/ASTUnit.cpp @@ -84,13 +84,6 @@ namespace { /// \brief The file in which the precompiled preamble is stored. std::string PreambleFile; - /// \brief Temporary files that should be removed when the ASTUnit is - /// destroyed. - SmallVector<std::string, 4> TemporaryFiles; - - /// \brief Erase temporary files. - void CleanTemporaryFiles(); - /// \brief Erase the preamble file. void CleanPreambleFile(); @@ -163,12 +156,6 @@ static const std::string &getPreambleFile(const ASTUnit *AU) { return getOnDiskData(AU).PreambleFile; } -void OnDiskData::CleanTemporaryFiles() { - for (StringRef File : TemporaryFiles) - llvm::sys::fs::remove(File); - TemporaryFiles.clear(); -} - void OnDiskData::CleanPreambleFile() { if (!PreambleFile.empty()) { llvm::sys::fs::remove(PreambleFile); @@ -177,7 +164,6 @@ void OnDiskData::CleanPreambleFile() { } void OnDiskData::Cleanup() { - CleanTemporaryFiles(); CleanPreambleFile(); } @@ -194,14 +180,6 @@ void ASTUnit::clearFileLevelDecls() { llvm::DeleteContainerSeconds(FileDecls); } -void ASTUnit::CleanTemporaryFiles() { - getOnDiskData(this).CleanTemporaryFiles(); -} - -void ASTUnit::addTemporaryFile(StringRef TempFile) { - getOnDiskData(this).TemporaryFiles.push_back(TempFile); -} - /// \brief After failing to build a precompiled preamble (due to /// errors in the source that occurs in the preamble), the number of /// reparses during which we'll skip even trying to precompile the @@ -1100,7 +1078,6 @@ bool ASTUnit::Parse(std::shared_ptr<PCHContainerOperations> PCHContainerOps, // Clear out old caches and data. TopLevelDecls.clear(); clearFileLevelDecls(); - CleanTemporaryFiles(); if (!OverrideMainBuffer) { checkAndRemoveNonDriverDiags(StoredDiagnostics); diff --git a/lib/Headers/xmmintrin.h b/lib/Headers/xmmintrin.h index 9773acb840a5..5a1c572ce614 100644 --- a/lib/Headers/xmmintrin.h +++ b/lib/Headers/xmmintrin.h @@ -2133,7 +2133,7 @@ void _mm_sfence(void); /// \headerfile <x86intrin.h> /// /// \code -/// void _mm_extract_pi(__m64 a, int n); +/// int _mm_extract_pi16(__m64 a, int n); /// \endcode /// /// This intrinsic corresponds to the <c> VPEXTRW / PEXTRW </c> instruction. @@ -2157,7 +2157,7 @@ void _mm_sfence(void); /// \headerfile <x86intrin.h> /// /// \code -/// void _mm_insert_pi(__m64 a, int d, int n); +/// __m64 _mm_insert_pi16(__m64 a, int d, int n); /// \endcode /// /// This intrinsic corresponds to the <c> VPINSRW / PINSRW </c> instruction. @@ -2680,8 +2680,7 @@ _mm_movelh_ps(__m128 __a, __m128 __b) /// /// \headerfile <x86intrin.h> /// -/// This intrinsic corresponds to the <c> CVTPI2PS + \c COMPOSITE </c> -/// instruction. +/// This intrinsic corresponds to the <c> CVTPI2PS + COMPOSITE </c> instruction. /// /// \param __a /// A 64-bit vector of [4 x i16]. The elements of the destination are copied @@ -2711,8 +2710,7 @@ _mm_cvtpi16_ps(__m64 __a) /// /// \headerfile <x86intrin.h> /// -/// This intrinsic corresponds to the <c> CVTPI2PS + \c COMPOSITE </c> -/// instruction. +/// This intrinsic corresponds to the <c> CVTPI2PS + COMPOSITE </c> instruction. /// /// \param __a /// A 64-bit vector of 16-bit unsigned integer values. The elements of the @@ -2741,8 +2739,7 @@ _mm_cvtpu16_ps(__m64 __a) /// /// \headerfile <x86intrin.h> /// -/// This intrinsic corresponds to the <c> CVTPI2PS + \c COMPOSITE </c> -/// instruction. +/// This intrinsic corresponds to the <c> CVTPI2PS + COMPOSITE </c> instruction. /// /// \param __a /// A 64-bit vector of [8 x i8]. The elements of the destination are copied @@ -2766,8 +2763,7 @@ _mm_cvtpi8_ps(__m64 __a) /// /// \headerfile <x86intrin.h> /// -/// This intrinsic corresponds to the <c> CVTPI2PS + \c COMPOSITE </c> -/// instruction. +/// This intrinsic corresponds to the <c> CVTPI2PS + COMPOSITE </c> instruction. /// /// \param __a /// A 64-bit vector of unsigned 8-bit integer values. The elements of the @@ -2791,8 +2787,7 @@ _mm_cvtpu8_ps(__m64 __a) /// /// \headerfile <x86intrin.h> /// -/// This intrinsic corresponds to the <c> CVTPI2PS + \c COMPOSITE </c> -/// instruction. +/// This intrinsic corresponds to the <c> CVTPI2PS + COMPOSITE </c> instruction. /// /// \param __a /// A 64-bit vector of [2 x i32]. The lower elements of the destination are @@ -2826,8 +2821,7 @@ _mm_cvtpi32x2_ps(__m64 __a, __m64 __b) /// /// \headerfile <x86intrin.h> /// -/// This intrinsic corresponds to the <c> CVTPS2PI + \c COMPOSITE </c> -/// instruction. +/// This intrinsic corresponds to the <c> CVTPS2PI + COMPOSITE </c> instruction. /// /// \param __a /// A 128-bit floating-point vector of [4 x float]. @@ -2857,8 +2851,7 @@ _mm_cvtps_pi16(__m128 __a) /// /// \headerfile <x86intrin.h> /// -/// This intrinsic corresponds to the <c> CVTPS2PI + \c COMPOSITE </c> -/// instruction. +/// This intrinsic corresponds to the <c> CVTPS2PI + COMPOSITE </c> instruction. /// /// \param __a /// 128-bit floating-point vector of [4 x float]. diff --git a/lib/Lex/Lexer.cpp b/lib/Lex/Lexer.cpp index 3d6fe91115a9..92942fd09a0c 100644 --- a/lib/Lex/Lexer.cpp +++ b/lib/Lex/Lexer.cpp @@ -43,6 +43,8 @@ using namespace clang; /// isObjCAtKeyword - Return true if we have an ObjC keyword identifier. bool Token::isObjCAtKeyword(tok::ObjCKeywordKind objcKey) const { + if (isAnnotation()) + return false; if (IdentifierInfo *II = getIdentifierInfo()) return II->getObjCKeywordID() == objcKey; return false; @@ -50,6 +52,8 @@ bool Token::isObjCAtKeyword(tok::ObjCKeywordKind objcKey) const { /// getObjCKeywordID - Return the ObjC keyword kind. tok::ObjCKeywordKind Token::getObjCKeywordID() const { + if (isAnnotation()) + return tok::objc_not_keyword; IdentifierInfo *specId = getIdentifierInfo(); return specId ? specId->getObjCKeywordID() : tok::objc_not_keyword; } diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp index ca1d27e9505f..e7b0914641ff 100644 --- a/lib/Sema/Sema.cpp +++ b/lib/Sema/Sema.cpp @@ -93,11 +93,10 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer, ValueWithBytesObjCTypeMethod(nullptr), NSArrayDecl(nullptr), ArrayWithObjectsMethod(nullptr), NSDictionaryDecl(nullptr), DictionaryWithObjectsMethod(nullptr), GlobalNewDeleteDeclared(false), - TUKind(TUKind), NumSFINAEErrors(0), CachedFakeTopLevelModule(nullptr), - AccessCheckingSFINAE(false), InNonInstantiationSFINAEContext(false), - NonInstantiationEntries(0), ArgumentPackSubstitutionIndex(-1), - CurrentInstantiationScope(nullptr), DisableTypoCorrection(false), - TyposCorrected(0), AnalysisWarnings(*this), + TUKind(TUKind), NumSFINAEErrors(0), AccessCheckingSFINAE(false), + InNonInstantiationSFINAEContext(false), NonInstantiationEntries(0), + ArgumentPackSubstitutionIndex(-1), CurrentInstantiationScope(nullptr), + DisableTypoCorrection(false), TyposCorrected(0), AnalysisWarnings(*this), ThreadSafetyDeclCache(nullptr), VarDataSharingAttributesStack(nullptr), CurScope(nullptr), Ident_super(nullptr), Ident___float128(nullptr) { TUScope = nullptr; diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 2e069a9defaa..dca51b0e8c8e 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -16047,6 +16047,14 @@ void Sema::ActOnModuleBegin(SourceLocation DirectiveLoc, Module *Mod) { ModuleScopes.back().OuterVisibleModules = std::move(VisibleModules); VisibleModules.setVisible(Mod, DirectiveLoc); + + // The enclosing context is now part of this module. + // FIXME: Consider creating a child DeclContext to hold the entities + // lexically within the module. + if (getLangOpts().trackLocalOwningModule()) { + cast<Decl>(CurContext)->setHidden(true); + cast<Decl>(CurContext)->setLocalOwningModule(Mod); + } } void Sema::ActOnModuleEnd(SourceLocation EomLoc, Module *Mod) { @@ -16075,6 +16083,13 @@ void Sema::ActOnModuleEnd(SourceLocation EomLoc, Module *Mod) { DirectiveLoc = EomLoc; } BuildModuleInclude(DirectiveLoc, Mod); + + // Any further declarations are in whatever module we returned to. + if (getLangOpts().trackLocalOwningModule()) { + cast<Decl>(CurContext)->setLocalOwningModule(getCurrentModule()); + if (!getCurrentModule()) + cast<Decl>(CurContext)->setHidden(false); + } } void Sema::createImplicitModuleImportForErrorRecovery(SourceLocation Loc, diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp index c5b579a4b2e9..04350831c681 100644 --- a/lib/Sema/SemaLookup.cpp +++ b/lib/Sema/SemaLookup.cpp @@ -1326,62 +1326,6 @@ bool Sema::CppLookupName(LookupResult &R, Scope *S) { return !R.empty(); } -Module *Sema::getOwningModule(Decl *Entity) { - // If it's imported, grab its owning module. - Module *M = Entity->getImportedOwningModule(); - if (M || !isa<NamedDecl>(Entity) || !cast<NamedDecl>(Entity)->isHidden()) - return M; - assert(!Entity->isFromASTFile() && - "hidden entity from AST file has no owning module"); - - if (!getLangOpts().ModulesLocalVisibility) { - // If we're not tracking visibility locally, the only way a declaration - // can be hidden and local is if it's hidden because it's parent is (for - // instance, maybe this is a lazily-declared special member of an imported - // class). - auto *Parent = cast<NamedDecl>(Entity->getDeclContext()); - assert(Parent->isHidden() && "unexpectedly hidden decl"); - return getOwningModule(Parent); - } - - // It's local and hidden; grab or compute its owning module. - M = Entity->getLocalOwningModule(); - if (M) - return M; - - if (auto *Containing = - PP.getModuleContainingLocation(Entity->getLocation())) { - M = Containing; - } else if (Entity->isInvalidDecl() || Entity->getLocation().isInvalid()) { - // Don't bother tracking visibility for invalid declarations with broken - // locations. - cast<NamedDecl>(Entity)->setHidden(false); - } else { - // We need to assign a module to an entity that exists outside of any - // module, so that we can hide it from modules that we textually enter. - // Invent a fake module for all such entities. - if (!CachedFakeTopLevelModule) { - CachedFakeTopLevelModule = - PP.getHeaderSearchInfo().getModuleMap().findOrCreateModule( - "<top-level>", nullptr, false, false).first; - - auto &SrcMgr = PP.getSourceManager(); - SourceLocation StartLoc = - SrcMgr.getLocForStartOfFile(SrcMgr.getMainFileID()); - auto &TopLevel = ModuleScopes.empty() - ? VisibleModules - : ModuleScopes[0].OuterVisibleModules; - TopLevel.setVisible(CachedFakeTopLevelModule, StartLoc); - } - - M = CachedFakeTopLevelModule; - } - - if (M) - Entity->setLocalOwningModule(M); - return M; -} - void Sema::makeMergedDefinitionVisible(NamedDecl *ND) { if (auto *M = getCurrentModule()) Context.mergeDefinitionIntoModule(ND, M); @@ -1520,7 +1464,6 @@ bool LookupResult::isVisibleSlow(Sema &SemaRef, NamedDecl *D) { if (SemaRef.getLangOpts().ModulesLocalVisibility) { DeclModule = SemaRef.getOwningModule(D); if (!DeclModule) { - // getOwningModule() may have decided the declaration should not be hidden. assert(!D->isHidden() && "hidden decl not from a module"); return true; } diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index ef8481488302..5cabd0e6740d 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -9348,12 +9348,6 @@ void ASTReader::diagnoseOdrViolations() { return Hash.CalculateHash(); }; - auto ComputeDeclNameODRHash = [&Hash](const DeclarationName Name) { - Hash.clear(); - Hash.AddDeclarationName(Name); - return Hash.CalculateHash(); - }; - auto ComputeQualTypeODRHash = [&Hash](QualType Ty) { Hash.clear(); Hash.AddQualType(Ty); @@ -9446,11 +9440,8 @@ void ASTReader::diagnoseOdrViolations() { QualType FirstType = FirstField->getType(); QualType SecondType = SecondField->getType(); - const TypedefType *FirstTypedef = dyn_cast<TypedefType>(FirstType); - const TypedefType *SecondTypedef = dyn_cast<TypedefType>(SecondType); - - if ((FirstTypedef && !SecondTypedef) || - (!FirstTypedef && SecondTypedef)) { + if (ComputeQualTypeODRHash(FirstType) != + ComputeQualTypeODRHash(SecondType)) { ODRDiagError(FirstField->getLocation(), FirstField->getSourceRange(), FieldTypeName) << FirstII << FirstType; @@ -9462,24 +9453,6 @@ void ASTReader::diagnoseOdrViolations() { break; } - if (FirstTypedef && SecondTypedef) { - unsigned FirstHash = ComputeDeclNameODRHash( - FirstTypedef->getDecl()->getDeclName()); - unsigned SecondHash = ComputeDeclNameODRHash( - SecondTypedef->getDecl()->getDeclName()); - if (FirstHash != SecondHash) { - ODRDiagError(FirstField->getLocation(), - FirstField->getSourceRange(), FieldTypeName) - << FirstII << FirstType; - ODRDiagNote(SecondField->getLocation(), - SecondField->getSourceRange(), FieldTypeName) - << SecondII << SecondType; - - Diagnosed = true; - break; - } - } - const bool IsFirstBitField = FirstField->isBitField(); const bool IsSecondBitField = SecondField->isBitField(); if (IsFirstBitField != IsSecondBitField) { |