Changeset View
Changeset View
Standalone View
Standalone View
clang/lib/AST/ODRDiagsEmitter.cpp
Show First 20 Lines • Show All 490 Lines • ▼ Show 20 Lines | if (FirstName != SecondName) { | ||||
DiagError(Name) << FirstName; | DiagError(Name) << FirstName; | ||||
DiagNote(Name) << SecondName; | DiagNote(Name) << SecondName; | ||||
return true; | return true; | ||||
} | } | ||||
return false; | return false; | ||||
} | } | ||||
bool ODRDiagsEmitter::diagnoseSubMismatchObjCProperty( | |||||
const NamedDecl *FirstObjCContainer, StringRef FirstModule, | |||||
StringRef SecondModule, const ObjCPropertyDecl *FirstProp, | |||||
const ObjCPropertyDecl *SecondProp) const { | |||||
enum ODRPropertyDifference { | |||||
Name, | |||||
Type, | |||||
ControlLevel, // optional/required | |||||
Attribute, | |||||
}; | |||||
auto DiagError = [FirstObjCContainer, FirstModule, FirstProp, | |||||
this](SourceLocation Loc, ODRPropertyDifference DiffType) { | |||||
return Diag(Loc, diag::err_module_odr_violation_objc_property) | |||||
<< FirstObjCContainer << FirstModule.empty() << FirstModule | |||||
<< FirstProp->getSourceRange() << DiffType; | |||||
}; | |||||
auto DiagNote = [SecondModule, SecondProp, | |||||
this](SourceLocation Loc, ODRPropertyDifference DiffType) { | |||||
return Diag(Loc, diag::note_module_odr_violation_objc_property) | |||||
<< SecondModule << SecondProp->getSourceRange() << DiffType; | |||||
}; | |||||
IdentifierInfo *FirstII = FirstProp->getIdentifier(); | |||||
IdentifierInfo *SecondII = SecondProp->getIdentifier(); | |||||
if (FirstII->getName() != SecondII->getName()) { | |||||
DiagError(FirstProp->getLocation(), Name) << FirstII; | |||||
DiagNote(SecondProp->getLocation(), Name) << SecondII; | |||||
return true; | |||||
} | |||||
if (computeODRHash(FirstProp->getType()) != | |||||
computeODRHash(SecondProp->getType())) { | |||||
DiagError(FirstProp->getLocation(), Type) | |||||
<< FirstII << FirstProp->getType(); | |||||
DiagNote(SecondProp->getLocation(), Type) | |||||
<< SecondII << SecondProp->getType(); | |||||
return true; | |||||
} | |||||
if (FirstProp->getPropertyImplementation() != | |||||
SecondProp->getPropertyImplementation()) { | |||||
DiagError(FirstProp->getLocation(), ControlLevel) | |||||
<< FirstProp->getPropertyImplementation(); | |||||
DiagNote(SecondProp->getLocation(), ControlLevel) | |||||
<< SecondProp->getPropertyImplementation(); | |||||
return true; | |||||
} | |||||
// Go over the property attributes and stop at the first mismatch. | |||||
unsigned FirstAttrs = (unsigned)FirstProp->getPropertyAttributes(); | |||||
unsigned SecondAttrs = (unsigned)SecondProp->getPropertyAttributes(); | |||||
if (FirstAttrs != SecondAttrs) { | |||||
for (unsigned I = 0; I < NumObjCPropertyAttrsBits; ++I) { | |||||
unsigned CheckedAttr = (1 << I); | |||||
if ((FirstAttrs & CheckedAttr) == (SecondAttrs & CheckedAttr)) | |||||
continue; | |||||
bool IsFirstWritten = | |||||
(unsigned)FirstProp->getPropertyAttributesAsWritten() & CheckedAttr; | |||||
bool IsSecondWritten = | |||||
(unsigned)SecondProp->getPropertyAttributesAsWritten() & CheckedAttr; | |||||
DiagError(IsFirstWritten ? FirstProp->getLParenLoc() | |||||
: FirstProp->getLocation(), | |||||
Attribute) | |||||
<< FirstII << (I + 1) << IsFirstWritten; | |||||
DiagNote(IsSecondWritten ? SecondProp->getLParenLoc() | |||||
: SecondProp->getLocation(), | |||||
Attribute) | |||||
<< SecondII << (I + 1); | |||||
return true; | |||||
} | |||||
} | |||||
return false; | |||||
} | |||||
ODRDiagsEmitter::DiffResult | ODRDiagsEmitter::DiffResult | ||||
ODRDiagsEmitter::FindTypeDiffs(DeclHashes &FirstHashes, | ODRDiagsEmitter::FindTypeDiffs(DeclHashes &FirstHashes, | ||||
DeclHashes &SecondHashes) { | DeclHashes &SecondHashes) { | ||||
auto DifferenceSelector = [](const Decl *D) { | auto DifferenceSelector = [](const Decl *D) { | ||||
assert(D && "valid Decl required"); | assert(D && "valid Decl required"); | ||||
switch (D->getKind()) { | switch (D->getKind()) { | ||||
default: | default: | ||||
return Other; | return Other; | ||||
Show All 24 Lines | auto DifferenceSelector = [](const Decl *D) { | ||||
case Decl::Var: | case Decl::Var: | ||||
return Var; | return Var; | ||||
case Decl::Friend: | case Decl::Friend: | ||||
return Friend; | return Friend; | ||||
case Decl::FunctionTemplate: | case Decl::FunctionTemplate: | ||||
return FunctionTemplate; | return FunctionTemplate; | ||||
case Decl::ObjCMethod: | case Decl::ObjCMethod: | ||||
return ObjCMethod; | return ObjCMethod; | ||||
case Decl::ObjCProperty: | |||||
return ObjCProperty; | |||||
} | } | ||||
}; | }; | ||||
DiffResult DR; | DiffResult DR; | ||||
auto FirstIt = FirstHashes.begin(); | auto FirstIt = FirstHashes.begin(); | ||||
auto SecondIt = SecondHashes.begin(); | auto SecondIt = SecondHashes.begin(); | ||||
while (FirstIt != FirstHashes.end() || SecondIt != SecondHashes.end()) { | while (FirstIt != FirstHashes.end() || SecondIt != SecondHashes.end()) { | ||||
if (FirstIt != FirstHashes.end() && SecondIt != SecondHashes.end() && | if (FirstIt != FirstHashes.end() && SecondIt != SecondHashes.end() && | ||||
▲ Show 20 Lines • Show All 339 Lines • ▼ Show 20 Lines | bool ODRDiagsEmitter::diagnoseMismatch( | ||||
assert(FirstDiffType == SecondDiffType); | assert(FirstDiffType == SecondDiffType); | ||||
switch (FirstDiffType) { | switch (FirstDiffType) { | ||||
case Other: | case Other: | ||||
case EndOfClass: | case EndOfClass: | ||||
case PublicSpecifer: | case PublicSpecifer: | ||||
case PrivateSpecifer: | case PrivateSpecifer: | ||||
case ProtectedSpecifer: | case ProtectedSpecifer: | ||||
case ObjCMethod: | case ObjCMethod: | ||||
case ObjCProperty: | |||||
llvm_unreachable("Invalid diff type"); | llvm_unreachable("Invalid diff type"); | ||||
case StaticAssert: { | case StaticAssert: { | ||||
const StaticAssertDecl *FirstSA = cast<StaticAssertDecl>(FirstDecl); | const StaticAssertDecl *FirstSA = cast<StaticAssertDecl>(FirstDecl); | ||||
const StaticAssertDecl *SecondSA = cast<StaticAssertDecl>(SecondDecl); | const StaticAssertDecl *SecondSA = cast<StaticAssertDecl>(SecondDecl); | ||||
const Expr *FirstExpr = FirstSA->getAssertExpr(); | const Expr *FirstExpr = FirstSA->getAssertExpr(); | ||||
const Expr *SecondExpr = SecondSA->getAssertExpr(); | const Expr *SecondExpr = SecondSA->getAssertExpr(); | ||||
▲ Show 20 Lines • Show All 944 Lines • ▼ Show 20 Lines | case FunctionTemplate: | ||||
llvm_unreachable("Invalid diff type"); | llvm_unreachable("Invalid diff type"); | ||||
case ObjCMethod: { | case ObjCMethod: { | ||||
if (diagnoseSubMismatchObjCMethod(FirstProtocol, FirstModule, SecondModule, | if (diagnoseSubMismatchObjCMethod(FirstProtocol, FirstModule, SecondModule, | ||||
cast<ObjCMethodDecl>(FirstDecl), | cast<ObjCMethodDecl>(FirstDecl), | ||||
cast<ObjCMethodDecl>(SecondDecl))) | cast<ObjCMethodDecl>(SecondDecl))) | ||||
return true; | return true; | ||||
break; | break; | ||||
} | } | ||||
case ObjCProperty: { | |||||
if (diagnoseSubMismatchObjCProperty(FirstProtocol, FirstModule, | |||||
SecondModule, | |||||
cast<ObjCPropertyDecl>(FirstDecl), | |||||
cast<ObjCPropertyDecl>(SecondDecl))) | |||||
return true; | |||||
break; | |||||
} | |||||
} | } | ||||
Diag(FirstDecl->getLocation(), | Diag(FirstDecl->getLocation(), | ||||
diag::err_module_odr_violation_mismatch_decl_unknown) | diag::err_module_odr_violation_mismatch_decl_unknown) | ||||
<< FirstProtocol << FirstModule.empty() << FirstModule << FirstDiffType | << FirstProtocol << FirstModule.empty() << FirstModule << FirstDiffType | ||||
<< FirstDecl->getSourceRange(); | << FirstDecl->getSourceRange(); | ||||
Diag(SecondDecl->getLocation(), | Diag(SecondDecl->getLocation(), | ||||
diag::note_module_odr_violation_mismatch_decl_unknown) | diag::note_module_odr_violation_mismatch_decl_unknown) | ||||
<< SecondModule << FirstDiffType << SecondDecl->getSourceRange(); | << SecondModule << FirstDiffType << SecondDecl->getSourceRange(); | ||||
return true; | return true; | ||||
} | } |