summaryrefslogtreecommitdiffstats
path: root/lib/AST/ASTImporter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/AST/ASTImporter.cpp')
-rw-r--r--lib/AST/ASTImporter.cpp163
1 files changed, 100 insertions, 63 deletions
diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp
index 0d4f303..d2e6d29 100644
--- a/lib/AST/ASTImporter.cpp
+++ b/lib/AST/ASTImporter.cpp
@@ -12,7 +12,6 @@
//
//===----------------------------------------------------------------------===//
#include "clang/AST/ASTImporter.h"
-
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTDiagnostic.h"
#include "clang/AST/DeclCXX.h"
@@ -122,6 +121,7 @@ namespace clang {
bool IsStructuralMatch(RecordDecl *FromRecord, RecordDecl *ToRecord,
bool Complain = true);
bool IsStructuralMatch(EnumDecl *FromEnum, EnumDecl *ToRecord);
+ bool IsStructuralMatch(EnumConstantDecl *FromEC, EnumConstantDecl *ToEC);
bool IsStructuralMatch(ClassTemplateDecl *From, ClassTemplateDecl *To);
Decl *VisitDecl(Decl *D);
Decl *VisitTranslationUnitDecl(TranslationUnitDecl *D);
@@ -206,12 +206,16 @@ namespace {
/// \brief Whether to complain about failures.
bool Complain;
+ /// \brief \c true if the last diagnostic came from C2.
+ bool LastDiagFromC2;
+
StructuralEquivalenceContext(ASTContext &C1, ASTContext &C2,
llvm::DenseSet<std::pair<Decl *, Decl *> > &NonEquivalentDecls,
bool StrictTypeSpelling = false,
bool Complain = true)
: C1(C1), C2(C2), NonEquivalentDecls(NonEquivalentDecls),
- StrictTypeSpelling(StrictTypeSpelling), Complain(Complain) { }
+ StrictTypeSpelling(StrictTypeSpelling), Complain(Complain),
+ LastDiagFromC2(false) {}
/// \brief Determine whether the two declarations are structurally
/// equivalent.
@@ -229,11 +233,17 @@ namespace {
public:
DiagnosticBuilder Diag1(SourceLocation Loc, unsigned DiagID) {
assert(Complain && "Not allowed to complain");
+ if (LastDiagFromC2)
+ C1.getDiagnostics().notePriorDiagnosticFrom(C2.getDiagnostics());
+ LastDiagFromC2 = false;
return C1.getDiagnostics().Report(Loc, DiagID);
}
DiagnosticBuilder Diag2(SourceLocation Loc, unsigned DiagID) {
assert(Complain && "Not allowed to complain");
+ if (!LastDiagFromC2)
+ C2.getDiagnostics().notePriorDiagnosticFrom(C1.getDiagnostics());
+ LastDiagFromC2 = true;
return C2.getDiagnostics().Report(Loc, DiagID);
}
};
@@ -892,14 +902,13 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
/// including the next assigned index (if none of them match). Returns an
/// empty option if the context is not a record, i.e.. if the anonymous
/// struct/union is at namespace or block scope.
-static llvm::Optional<unsigned>
-findAnonymousStructOrUnionIndex(RecordDecl *Anon) {
+static Optional<unsigned> findAnonymousStructOrUnionIndex(RecordDecl *Anon) {
ASTContext &Context = Anon->getASTContext();
QualType AnonTy = Context.getRecordType(Anon);
RecordDecl *Owner = dyn_cast<RecordDecl>(Anon->getDeclContext());
if (!Owner)
- return llvm::Optional<unsigned>();
+ return None;
unsigned Index = 0;
for (DeclContext::decl_iterator D = Owner->noload_decls_begin(),
@@ -934,10 +943,8 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
if (D1->isAnonymousStructOrUnion() && D2->isAnonymousStructOrUnion()) {
// If both anonymous structs/unions are in a record context, make sure
// they occur in the same location in the context records.
- if (llvm::Optional<unsigned> Index1
- = findAnonymousStructOrUnionIndex(D1)) {
- if (llvm::Optional<unsigned> Index2
- = findAnonymousStructOrUnionIndex(D2)) {
+ if (Optional<unsigned> Index1 = findAnonymousStructOrUnionIndex(D1)) {
+ if (Optional<unsigned> Index2 = findAnonymousStructOrUnionIndex(D2)) {
if (*Index1 != *Index2)
return false;
}
@@ -1612,8 +1619,7 @@ QualType ASTNodeImporter::VisitFunctionProtoType(const FunctionProtoType *T) {
ToEPI.ExceptionSpecTemplate = cast_or_null<FunctionDecl>(
Importer.Import(FromEPI.ExceptionSpecTemplate));
- return Importer.getToContext().getFunctionType(ToResultType, ArgTypes.data(),
- ArgTypes.size(), ToEPI);
+ return Importer.getToContext().getFunctionType(ToResultType, ArgTypes, ToEPI);
}
QualType ASTNodeImporter::VisitParenType(const ParenType *T) {
@@ -1825,7 +1831,7 @@ void ASTNodeImporter::ImportDefinitionIfNeeded(Decl *FromD, Decl *ToD) {
if (RecordDecl *FromRecord = dyn_cast<RecordDecl>(FromD)) {
if (RecordDecl *ToRecord = cast_or_null<RecordDecl>(ToD)) {
- if (FromRecord->getDefinition() && !ToRecord->getDefinition()) {
+ if (FromRecord->getDefinition() && FromRecord->isCompleteDefinition() && !ToRecord->getDefinition()) {
ImportDefinition(FromRecord, ToRecord);
}
}
@@ -1907,11 +1913,7 @@ bool ASTNodeImporter::ImportDefinition(RecordDecl *From, RecordDecl *To,
struct CXXRecordDecl::DefinitionData &ToData = ToCXX->data();
struct CXXRecordDecl::DefinitionData &FromData = FromCXX->data();
ToData.UserDeclaredConstructor = FromData.UserDeclaredConstructor;
- ToData.UserDeclaredCopyConstructor = FromData.UserDeclaredCopyConstructor;
- ToData.UserDeclaredMoveConstructor = FromData.UserDeclaredMoveConstructor;
- ToData.UserDeclaredCopyAssignment = FromData.UserDeclaredCopyAssignment;
- ToData.UserDeclaredMoveAssignment = FromData.UserDeclaredMoveAssignment;
- ToData.UserDeclaredDestructor = FromData.UserDeclaredDestructor;
+ ToData.UserDeclaredSpecialMembers = FromData.UserDeclaredSpecialMembers;
ToData.Aggregate = FromData.Aggregate;
ToData.PlainOldData = FromData.PlainOldData;
ToData.Empty = FromData.Empty;
@@ -1925,30 +1927,41 @@ bool ASTNodeImporter::ImportDefinition(RecordDecl *From, RecordDecl *To,
ToData.HasMutableFields = FromData.HasMutableFields;
ToData.HasOnlyCMembers = FromData.HasOnlyCMembers;
ToData.HasInClassInitializer = FromData.HasInClassInitializer;
- ToData.HasTrivialDefaultConstructor = FromData.HasTrivialDefaultConstructor;
+ ToData.HasUninitializedReferenceMember
+ = FromData.HasUninitializedReferenceMember;
+ ToData.NeedOverloadResolutionForMoveConstructor
+ = FromData.NeedOverloadResolutionForMoveConstructor;
+ ToData.NeedOverloadResolutionForMoveAssignment
+ = FromData.NeedOverloadResolutionForMoveAssignment;
+ ToData.NeedOverloadResolutionForDestructor
+ = FromData.NeedOverloadResolutionForDestructor;
+ ToData.DefaultedMoveConstructorIsDeleted
+ = FromData.DefaultedMoveConstructorIsDeleted;
+ ToData.DefaultedMoveAssignmentIsDeleted
+ = FromData.DefaultedMoveAssignmentIsDeleted;
+ ToData.DefaultedDestructorIsDeleted = FromData.DefaultedDestructorIsDeleted;
+ ToData.HasTrivialSpecialMembers = FromData.HasTrivialSpecialMembers;
+ ToData.HasIrrelevantDestructor = FromData.HasIrrelevantDestructor;
ToData.HasConstexprNonCopyMoveConstructor
= FromData.HasConstexprNonCopyMoveConstructor;
ToData.DefaultedDefaultConstructorIsConstexpr
= FromData.DefaultedDefaultConstructorIsConstexpr;
ToData.HasConstexprDefaultConstructor
= FromData.HasConstexprDefaultConstructor;
- ToData.HasTrivialCopyConstructor = FromData.HasTrivialCopyConstructor;
- ToData.HasTrivialMoveConstructor = FromData.HasTrivialMoveConstructor;
- ToData.HasTrivialCopyAssignment = FromData.HasTrivialCopyAssignment;
- ToData.HasTrivialMoveAssignment = FromData.HasTrivialMoveAssignment;
- ToData.HasTrivialDestructor = FromData.HasTrivialDestructor;
- ToData.HasIrrelevantDestructor = FromData.HasIrrelevantDestructor;
ToData.HasNonLiteralTypeFieldsOrBases
= FromData.HasNonLiteralTypeFieldsOrBases;
// ComputedVisibleConversions not imported.
ToData.UserProvidedDefaultConstructor
= FromData.UserProvidedDefaultConstructor;
- ToData.DeclaredDefaultConstructor = FromData.DeclaredDefaultConstructor;
- ToData.DeclaredCopyConstructor = FromData.DeclaredCopyConstructor;
- ToData.DeclaredMoveConstructor = FromData.DeclaredMoveConstructor;
- ToData.DeclaredCopyAssignment = FromData.DeclaredCopyAssignment;
- ToData.DeclaredMoveAssignment = FromData.DeclaredMoveAssignment;
- ToData.DeclaredDestructor = FromData.DeclaredDestructor;
+ ToData.DeclaredSpecialMembers = FromData.DeclaredSpecialMembers;
+ ToData.ImplicitCopyConstructorHasConstParam
+ = FromData.ImplicitCopyConstructorHasConstParam;
+ ToData.ImplicitCopyAssignmentHasConstParam
+ = FromData.ImplicitCopyAssignmentHasConstParam;
+ ToData.HasDeclaredCopyConstructorWithConstParam
+ = FromData.HasDeclaredCopyConstructorWithConstParam;
+ ToData.HasDeclaredCopyAssignmentWithConstParam
+ = FromData.HasDeclaredCopyAssignmentWithConstParam;
ToData.FailedImplicitMoveConstructor
= FromData.FailedImplicitMoveConstructor;
ToData.FailedImplicitMoveAssignment = FromData.FailedImplicitMoveAssignment;
@@ -2143,7 +2156,18 @@ bool ASTNodeImporter::IsStructuralMatch(EnumDecl *FromEnum, EnumDecl *ToEnum) {
return Ctx.IsStructurallyEquivalent(FromEnum, ToEnum);
}
-bool ASTNodeImporter::IsStructuralMatch(ClassTemplateDecl *From,
+bool ASTNodeImporter::IsStructuralMatch(EnumConstantDecl *FromEC,
+ EnumConstantDecl *ToEC)
+{
+ const llvm::APSInt &FromVal = FromEC->getInitVal();
+ const llvm::APSInt &ToVal = ToEC->getInitVal();
+
+ return FromVal.isSigned() == ToVal.isSigned() &&
+ FromVal.getBitWidth() == ToVal.getBitWidth() &&
+ FromVal == ToVal;
+}
+
+bool ASTNodeImporter::IsStructuralMatch(ClassTemplateDecl *From,
ClassTemplateDecl *To) {
StructuralEquivalenceContext Ctx(Importer.getFromContext(),
Importer.getToContext(),
@@ -2185,7 +2209,7 @@ Decl *ASTNodeImporter::VisitNamespaceDecl(NamespaceDecl *D) {
MergeWithNamespace = cast<NamespaceDecl>(DC)->getAnonymousNamespace();
} else {
SmallVector<NamedDecl *, 4> ConflictingDecls;
- llvm::SmallVector<NamedDecl *, 2> FoundDecls;
+ SmallVector<NamedDecl *, 2> FoundDecls;
DC->localUncachedLookup(Name, FoundDecls);
for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
if (!FoundDecls[I]->isInIdentifierNamespace(Decl::IDNS_Namespace))
@@ -2248,7 +2272,7 @@ Decl *ASTNodeImporter::VisitTypedefNameDecl(TypedefNameDecl *D, bool IsAlias) {
if (!DC->isFunctionOrMethod()) {
SmallVector<NamedDecl *, 4> ConflictingDecls;
unsigned IDNS = Decl::IDNS_Ordinary;
- llvm::SmallVector<NamedDecl *, 2> FoundDecls;
+ SmallVector<NamedDecl *, 2> FoundDecls;
DC->localUncachedLookup(Name, FoundDecls);
for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
if (!FoundDecls[I]->isInIdentifierNamespace(IDNS))
@@ -2328,7 +2352,7 @@ Decl *ASTNodeImporter::VisitEnumDecl(EnumDecl *D) {
// We may already have an enum of the same name; try to find and match it.
if (!DC->isFunctionOrMethod() && SearchName) {
SmallVector<NamedDecl *, 4> ConflictingDecls;
- llvm::SmallVector<NamedDecl *, 2> FoundDecls;
+ SmallVector<NamedDecl *, 2> FoundDecls;
DC->localUncachedLookup(SearchName, FoundDecls);
for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
if (!FoundDecls[I]->isInIdentifierNamespace(IDNS))
@@ -2414,7 +2438,7 @@ Decl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
RecordDecl *AdoptDecl = 0;
if (!DC->isFunctionOrMethod()) {
SmallVector<NamedDecl *, 4> ConflictingDecls;
- llvm::SmallVector<NamedDecl *, 2> FoundDecls;
+ SmallVector<NamedDecl *, 2> FoundDecls;
DC->localUncachedLookup(SearchName, FoundDecls);
for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
if (!FoundDecls[I]->isInIdentifierNamespace(IDNS))
@@ -2431,10 +2455,10 @@ Decl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
FoundRecord->isAnonymousStructOrUnion()) {
// If both anonymous structs/unions are in a record context, make sure
// they occur in the same location in the context records.
- if (llvm::Optional<unsigned> Index1
+ if (Optional<unsigned> Index1
= findAnonymousStructOrUnionIndex(D)) {
- if (llvm::Optional<unsigned> Index2
- = findAnonymousStructOrUnionIndex(FoundRecord)) {
+ if (Optional<unsigned> Index2 =
+ findAnonymousStructOrUnionIndex(FoundRecord)) {
if (*Index1 != *Index2)
continue;
}
@@ -2521,12 +2545,18 @@ Decl *ASTNodeImporter::VisitEnumConstantDecl(EnumConstantDecl *D) {
if (!LexicalDC->isFunctionOrMethod()) {
SmallVector<NamedDecl *, 4> ConflictingDecls;
unsigned IDNS = Decl::IDNS_Ordinary;
- llvm::SmallVector<NamedDecl *, 2> FoundDecls;
+ SmallVector<NamedDecl *, 2> FoundDecls;
DC->localUncachedLookup(Name, FoundDecls);
for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
if (!FoundDecls[I]->isInIdentifierNamespace(IDNS))
continue;
-
+
+ if (EnumConstantDecl *FoundEnumConstant
+ = dyn_cast<EnumConstantDecl>(FoundDecls[I])) {
+ if (IsStructuralMatch(D, FoundEnumConstant))
+ return Importer.Imported(D, FoundEnumConstant);
+ }
+
ConflictingDecls.push_back(FoundDecls[I]);
}
@@ -2567,7 +2597,7 @@ Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
if (!LexicalDC->isFunctionOrMethod()) {
SmallVector<NamedDecl *, 4> ConflictingDecls;
unsigned IDNS = Decl::IDNS_Ordinary;
- llvm::SmallVector<NamedDecl *, 2> FoundDecls;
+ SmallVector<NamedDecl *, 2> FoundDecls;
DC->localUncachedLookup(Name, FoundDecls);
for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
if (!FoundDecls[I]->isInIdentifierNamespace(IDNS))
@@ -2629,8 +2659,8 @@ Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
FunctionProtoType::ExtProtoInfo DefaultEPI;
FromTy = Importer.getFromContext().getFunctionType(
FromFPT->getResultType(),
- FromFPT->arg_type_begin(),
- FromFPT->arg_type_end() - FromFPT->arg_type_begin(),
+ ArrayRef<QualType>(FromFPT->arg_type_begin(),
+ FromFPT->getNumArgs()),
DefaultEPI);
usedDifferentExceptionSpec = true;
}
@@ -2686,8 +2716,7 @@ Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
cast<CXXRecordDecl>(DC),
D->getInnerLocStart(),
NameInfo, T, TInfo,
- Method->isStatic(),
- Method->getStorageClassAsWritten(),
+ Method->getStorageClass(),
Method->isInlineSpecified(),
D->isConstexpr(),
Importer.Import(D->getLocEnd()));
@@ -2695,7 +2724,6 @@ Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
ToFunction = FunctionDecl::Create(Importer.getToContext(), DC,
D->getInnerLocStart(),
NameInfo, T, TInfo, D->getStorageClass(),
- D->getStorageClassAsWritten(),
D->isInlineSpecified(),
D->hasWrittenPrototype(),
D->isConstexpr());
@@ -2777,7 +2805,7 @@ Decl *ASTNodeImporter::VisitFieldDecl(FieldDecl *D) {
return 0;
// Determine whether we've already imported this field.
- llvm::SmallVector<NamedDecl *, 2> FoundDecls;
+ SmallVector<NamedDecl *, 2> FoundDecls;
DC->localUncachedLookup(Name, FoundDecls);
for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
if (FieldDecl *FoundField = dyn_cast<FieldDecl>(FoundDecls[I])) {
@@ -2833,7 +2861,7 @@ Decl *ASTNodeImporter::VisitIndirectFieldDecl(IndirectFieldDecl *D) {
return 0;
// Determine whether we've already imported this field.
- llvm::SmallVector<NamedDecl *, 2> FoundDecls;
+ SmallVector<NamedDecl *, 2> FoundDecls;
DC->localUncachedLookup(Name, FoundDecls);
for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
if (IndirectFieldDecl *FoundField
@@ -2898,7 +2926,7 @@ Decl *ASTNodeImporter::VisitObjCIvarDecl(ObjCIvarDecl *D) {
return 0;
// Determine whether we've already imported this ivar
- llvm::SmallVector<NamedDecl *, 2> FoundDecls;
+ SmallVector<NamedDecl *, 2> FoundDecls;
DC->localUncachedLookup(Name, FoundDecls);
for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
if (ObjCIvarDecl *FoundIvar = dyn_cast<ObjCIvarDecl>(FoundDecls[I])) {
@@ -2953,7 +2981,7 @@ Decl *ASTNodeImporter::VisitVarDecl(VarDecl *D) {
VarDecl *MergeWithVar = 0;
SmallVector<NamedDecl *, 4> ConflictingDecls;
unsigned IDNS = Decl::IDNS_Ordinary;
- llvm::SmallVector<NamedDecl *, 2> FoundDecls;
+ SmallVector<NamedDecl *, 2> FoundDecls;
DC->localUncachedLookup(Name, FoundDecls);
for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
if (!FoundDecls[I]->isInIdentifierNamespace(IDNS))
@@ -3046,8 +3074,7 @@ Decl *ASTNodeImporter::VisitVarDecl(VarDecl *D) {
Importer.Import(D->getInnerLocStart()),
Loc, Name.getAsIdentifierInfo(),
T, TInfo,
- D->getStorageClass(),
- D->getStorageClassAsWritten());
+ D->getStorageClass());
ToVar->setQualifierInfo(Importer.Import(D->getQualifierLoc()));
ToVar->setAccess(D->getAccess());
ToVar->setLexicalDeclContext(LexicalDC);
@@ -3115,7 +3142,6 @@ Decl *ASTNodeImporter::VisitParmVarDecl(ParmVarDecl *D) {
Importer.Import(D->getInnerLocStart()),
Loc, Name.getAsIdentifierInfo(),
T, TInfo, D->getStorageClass(),
- D->getStorageClassAsWritten(),
/*FIXME: Default argument*/ 0);
ToParm->setHasInheritedDefaultArg(D->hasInheritedDefaultArg());
return Importer.Imported(D, ToParm);
@@ -3129,7 +3155,7 @@ Decl *ASTNodeImporter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
return 0;
- llvm::SmallVector<NamedDecl *, 2> FoundDecls;
+ SmallVector<NamedDecl *, 2> FoundDecls;
DC->localUncachedLookup(Name, FoundDecls);
for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
if (ObjCMethodDecl *FoundMethod = dyn_cast<ObjCMethodDecl>(FoundDecls[I])) {
@@ -3376,7 +3402,7 @@ Decl *ASTNodeImporter::VisitObjCProtocolDecl(ObjCProtocolDecl *D) {
return 0;
ObjCProtocolDecl *MergeWithProtocol = 0;
- llvm::SmallVector<NamedDecl *, 2> FoundDecls;
+ SmallVector<NamedDecl *, 2> FoundDecls;
DC->localUncachedLookup(Name, FoundDecls);
for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
if (!FoundDecls[I]->isInIdentifierNamespace(Decl::IDNS_ObjCProtocol))
@@ -3480,10 +3506,13 @@ bool ASTNodeImporter::ImportDefinition(ObjCInterfaceDecl *From,
// Import categories. When the categories themselves are imported, they'll
// hook themselves into this interface.
- for (ObjCCategoryDecl *FromCat = From->getCategoryList(); FromCat;
- FromCat = FromCat->getNextClassCategory())
- Importer.Import(FromCat);
-
+ for (ObjCInterfaceDecl::known_categories_iterator
+ Cat = From->known_categories_begin(),
+ CatEnd = From->known_categories_end();
+ Cat != CatEnd; ++Cat) {
+ Importer.Import(*Cat);
+ }
+
// If we have an @implementation, import it as well.
if (From->getImplementation()) {
ObjCImplementationDecl *Impl = cast_or_null<ObjCImplementationDecl>(
@@ -3523,7 +3552,7 @@ Decl *ASTNodeImporter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
// Look for an existing interface with the same name.
ObjCInterfaceDecl *MergeWithIface = 0;
- llvm::SmallVector<NamedDecl *, 2> FoundDecls;
+ SmallVector<NamedDecl *, 2> FoundDecls;
DC->localUncachedLookup(Name, FoundDecls);
for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
if (!FoundDecls[I]->isInIdentifierNamespace(Decl::IDNS_Ordinary))
@@ -3675,7 +3704,7 @@ Decl *ASTNodeImporter::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
return 0;
// Check whether we have already imported this property.
- llvm::SmallVector<NamedDecl *, 2> FoundDecls;
+ SmallVector<NamedDecl *, 2> FoundDecls;
DC->localUncachedLookup(Name, FoundDecls);
for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
if (ObjCPropertyDecl *FoundProp
@@ -3908,7 +3937,7 @@ Decl *ASTNodeImporter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
// We may already have a template of the same name; try to find and match it.
if (!DC->isFunctionOrMethod()) {
SmallVector<NamedDecl *, 4> ConflictingDecls;
- llvm::SmallVector<NamedDecl *, 2> FoundDecls;
+ SmallVector<NamedDecl *, 2> FoundDecls;
DC->localUncachedLookup(Name, FoundDecls);
for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
if (!FoundDecls[I]->isInIdentifierNamespace(Decl::IDNS_Ordinary))
@@ -4295,7 +4324,7 @@ ASTImporter::ASTImporter(ASTContext &ToContext, FileManager &ToFileManager,
bool MinimalImport)
: ToContext(ToContext), FromContext(FromContext),
ToFileManager(ToFileManager), FromFileManager(FromFileManager),
- Minimal(MinimalImport)
+ Minimal(MinimalImport), LastDiagFromFrom(false)
{
ImportedDecls[FromContext.getTranslationUnitDecl()]
= ToContext.getTranslationUnitDecl();
@@ -4798,10 +4827,18 @@ DeclarationName ASTImporter::HandleNameConflict(DeclarationName Name,
}
DiagnosticBuilder ASTImporter::ToDiag(SourceLocation Loc, unsigned DiagID) {
+ if (LastDiagFromFrom)
+ ToContext.getDiagnostics().notePriorDiagnosticFrom(
+ FromContext.getDiagnostics());
+ LastDiagFromFrom = false;
return ToContext.getDiagnostics().Report(Loc, DiagID);
}
DiagnosticBuilder ASTImporter::FromDiag(SourceLocation Loc, unsigned DiagID) {
+ if (!LastDiagFromFrom)
+ FromContext.getDiagnostics().notePriorDiagnosticFrom(
+ ToContext.getDiagnostics());
+ LastDiagFromFrom = true;
return FromContext.getDiagnostics().Report(Loc, DiagID);
}
OpenPOWER on IntegriCloud