[cfe-commits] [PATCH] Type safety attributes (was: Compile-time MPI_Datatype checking)
Douglas Gregor
dgregor at apple.com
Tue Aug 7 09:50:24 PDT 2012
On Aug 4, 2012, at 10:52 PM, Dmitri Gribenko <gribozavr at gmail.com> wrote:
> On Sat, Aug 4, 2012 at 10:42 PM, Dmitri Gribenko <gribozavr at gmail.com> wrote:
>> On Tue, Jun 12, 2012 at 10:46 AM, Jordan Rose <jordan_rose at apple.com> wrote:
>>> Hi, Dmitri. I'd like for this patch not to get lost with your new comment-parsing work, though it might be too late for that.
>>
>> Thank you for the review! Finally, I got back to this.
>
> [...]
>
> Hi Doug,
>
> Could you comment on this, please? If I understand correctly, I'll
> need your review to commit this since this adds new attributes.
>
> In support of this patch, I should say that MPICH2 developers have
> already committed the corresponding patch for mpi.h and they build
> their own version of clang with this patch to check their MPI
> projects.
This is a good extension. Even if the MPI community isn't large enough to justify the addition, the API design pattern that this set of attributes describes is fairly common in the C world. The patch looks good, and I have just a few minor comments:
+ llvm::APSInt MagicValueInt;
+ if (!MagicValueExpr->isIntegerConstantExpr(MagicValueInt, Context)) {
+ Diag(I->getRange().getBegin(),
+ diag::warn_type_tag_for_datatype_not_ice)
+ << LangOpts.CPlusPlus << MagicValueExpr->getSourceRange();
+ continue;
+ }
+ uint64_t MagicValue = MagicValueInt.getZExtValue();
Should check for > 64 active bits in the magic value.
+bool isLayoutCompatibleStruct(ASTContext &C,
+ RecordDecl *RD1,
+ RecordDecl *RD2) {
+ // If both records are C++ classes, check that base classes match.
+ if (const CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(RD1)) {
+ if (const CXXRecordDecl *D2CXX = dyn_cast<CXXRecordDecl>(RD2)) {
CXXRecordDecls are used in C++, bare RecordDecls are used in C, so if one of the RecordDecls is a CXXRecordDecl, you know that the other one is, so you can just cast<CXXRecordDecl>(RD2) an eliminate the inner "if".
+ /// \brief A map from magic value to associated dataype. We can not use
+ /// DenseMap here because it reserves two key values for its internal needs.
+ typedef std::map<uint64_t, TypeTagData> TypeTagForDatatypeMagicValuesType;
+
+private:
+ /// \brief A map from ArgumentKind identifier name to registered magic
+ /// values.
+ OwningPtr<llvm::StringMap<TypeTagForDatatypeMagicValuesType> >
+ TypeTagForDatatypeMagicValues;
This is a really heavy data structure. Could we perhaps use a single DenseMap<std::pair<IdentifierInfo*, uint64_t>, TypeTagData>, which has much smaller value types?
+ if (VD) {
+ for (specific_attr_iterator<TypeTagForDatatypeAttr>
+ I = VD->specific_attr_begin<TypeTagForDatatypeAttr>(),
+ E = VD->specific_attr_end<TypeTagForDatatypeAttr>();
+ I != E; ++I) {
+ if (I->getPointerKind() != PointerKind) {
+ FoundWrongKind = true;
+ return false;
+ }
+ TypeInfo.Type = I->getMatchingCType();
+ TypeInfo.LayoutCompatible = I->getLayoutCompatible();
+ TypeInfo.MustBeNull = I->getMustBeNull();
+ return true;
+ }
+ return false;
+ } else {
Since you're returning along every path in the if (VD) case, I suggest de-nesting the rest.
+namespace {
+bool IsSameCharType(QualType T1, QualType T2) {
+ if (!isa<BuiltinType>(T1) ||
+ !isa<BuiltinType>(T2))
+ return false;
+
+ BuiltinType::Kind T1Kind = cast<BuiltinType>(T1)->getKind();
+ BuiltinType::Kind T2Kind = cast<BuiltinType>(T2)->getKind();
Do you mean to use T1->getAs<BuiltinType>() and T2->getAs<BuiltinType>() here? It's not clear that IsSameCharType is always getting canonical types.
Everything else looks great, thanks!
- Doug
More information about the cfe-commits
mailing list