From: Steve Naroff Date: Sun, 29 Jul 2007 16:33:31 +0000 (+0000) Subject: Implement pretty diagnostics when doing on-the-fly vector sizing (for vector componen... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=bea0b34d99dddb7829857bbc96628713ab9c274b;p=clang Implement pretty diagnostics when doing on-the-fly vector sizing (for vector component access). For example, before this commit, the following diagnostics would be emitted... ocu.c:49:12: error: incompatible types assigning 'float __attribute__((ocu_vector_type(3)))' to 'float4' vec4_2 = vec4.rgb; // shorten ~~~~~~ ^ ~~~~~~~~ ocu.c:51:7: error: incompatible types assigning 'float __attribute__((ocu_vector_type(2)))' to 'float' f = vec2.xx; // shorten ~ ^ ~~~~~~~ Now, the diagnostics look as you would expect... ocu.c:49:12: error: incompatible types assigning 'float3' to 'float4' vec4_2 = vec4.rgb; // shorten ~~~~~~ ^ ~~~~~~~~ ocu.c:51:7: error: incompatible types assigning 'float2' to 'float' f = vec2.xx; // shorten ~ ^ ~~~~~~~ git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@40579 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/Sema/Sema.h b/Sema/Sema.h index 589161bfab..ea724ab44b 100644 --- a/Sema/Sema.h +++ b/Sema/Sema.h @@ -39,7 +39,8 @@ namespace clang { class LabelStmt; class SwitchStmt; class OCUVectorType; - + class TypedefDecl; + /// Sema - This implements semantic analysis and AST building for C. class Sema : public Action { Preprocessor &PP; @@ -62,6 +63,11 @@ class Sema : public Action { llvm::DenseMap LabelMap; llvm::SmallVector SwitchStack; + + /// OCUVectorDecls - This is a list all the OCU vector types. This allows + /// us to associate a raw vector type with one of the OCU type names. + /// This is only necessary for issuing pretty diagnostics. + llvm::SmallVector OCUVectorDecls; public: Sema(Preprocessor &pp, ASTContext &ctxt, std::vector &prevInGroup); @@ -158,7 +164,7 @@ private: // for the variable, measured in bytes. If curType and rawAttr are well // formed, this routine will return a new vector type. QualType HandleVectorTypeAttribute(QualType curType, AttributeList *rawAttr); - QualType HandleOCUVectorTypeAttribute(QualType curType, AttributeList *rawAttr); + void HandleOCUVectorTypeAttribute(TypedefDecl *d, AttributeList *rawAttr); //===--------------------------------------------------------------------===// // Statement Parsing Callbacks: SemaStmt.cpp. diff --git a/Sema/SemaDecl.cpp b/Sema/SemaDecl.cpp index 3053d2e2a8..722452b51a 100644 --- a/Sema/SemaDecl.cpp +++ b/Sema/SemaDecl.cpp @@ -965,15 +965,11 @@ void Sema::HandleDeclAttribute(Decl *New, AttributeList *rawAttr) { } } if (strcmp(rawAttr->getAttributeName()->getName(), "ocu_vector_type") == 0) { - if (TypedefDecl *tDecl = dyn_cast(New)) { - QualType newType = HandleOCUVectorTypeAttribute(tDecl->getUnderlyingType(), - rawAttr); - if (!newType.isNull()) // install the new vector type into the decl - tDecl->setUnderlyingType(newType); - } else { + if (TypedefDecl *tDecl = dyn_cast(New)) + HandleOCUVectorTypeAttribute(tDecl, rawAttr); + else Diag(rawAttr->getAttributeLoc(), diag::err_typecheck_ocu_vector_not_typedef); - } } // FIXME: add other attributes... } @@ -990,20 +986,21 @@ void Sema::HandleDeclAttributes(Decl *New, AttributeList *declspec_prefix, } } -QualType Sema::HandleOCUVectorTypeAttribute(QualType curType, - AttributeList *rawAttr) { +void Sema::HandleOCUVectorTypeAttribute(TypedefDecl *tDecl, + AttributeList *rawAttr) { + QualType curType = tDecl->getUnderlyingType(); // check the attribute arugments. if (rawAttr->getNumArgs() != 1) { Diag(rawAttr->getAttributeLoc(), diag::err_attribute_wrong_number_arguments, std::string("1")); - return QualType(); + return; } Expr *sizeExpr = static_cast(rawAttr->getArg(0)); llvm::APSInt vecSize(32); if (!sizeExpr->isIntegerConstantExpr(vecSize, Context)) { Diag(rawAttr->getAttributeLoc(), diag::err_attribute_vector_size_not_int, sizeExpr->getSourceRange()); - return QualType(); + return; } // unlike gcc's vector_size attribute, we do not allow vectors to be defined // in conjunction with complex types (pointers, arrays, functions, etc.). @@ -1011,7 +1008,7 @@ QualType Sema::HandleOCUVectorTypeAttribute(QualType curType, if (!(canonType->isIntegerType() || canonType->isRealFloatingType())) { Diag(rawAttr->getAttributeLoc(), diag::err_attribute_invalid_vector_type, curType.getCanonicalType().getAsString()); - return QualType(); + return; } // unlike gcc's vector_size attribute, the size is specified as the // number of elements, not the number of bytes. @@ -1020,10 +1017,12 @@ QualType Sema::HandleOCUVectorTypeAttribute(QualType curType, if (vectorSize == 0) { Diag(rawAttr->getAttributeLoc(), diag::err_attribute_zero_size, sizeExpr->getSourceRange()); - return QualType(); + return; } - // Instantiate the vector type, the number of elements is > 0. - return Context.getOCUVectorType(curType, vectorSize); + // Instantiate/Install the vector type, the number of elements is > 0. + tDecl->setUnderlyingType(Context.getOCUVectorType(curType, vectorSize)); + // Remember this typedef decl, we will need it later for diagnostics. + OCUVectorDecls.push_back(tDecl); } QualType Sema::HandleVectorTypeAttribute(QualType curType, diff --git a/Sema/SemaExpr.cpp b/Sema/SemaExpr.cpp index 445b6b5668..8646c1a792 100644 --- a/Sema/SemaExpr.cpp +++ b/Sema/SemaExpr.cpp @@ -387,7 +387,15 @@ CheckOCUVectorComponent(QualType baseType, SourceLocation OpLoc, unsigned CompSize = strlen(CompName.getName()); if (CompSize == 1) return vecType->getElementType(); - return Context.getOCUVectorType(vecType->getElementType(), CompSize); + + QualType VT = Context.getOCUVectorType(vecType->getElementType(), CompSize); + // Now look up the TypeDefDecl from the vector type. Without this, + // diagostics look bad. We want OCU vector types to appear built-in. + for (unsigned i = 0, e = OCUVectorDecls.size(); i != e; ++i) { + if (OCUVectorDecls[i]->getUnderlyingType() == VT) + return Context.getTypedefType(OCUVectorDecls[i]); + } + return VT; // should never get here (a typedef type should always be found). } Action::ExprResult Sema:: diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index b37ab1f99f..a67762a674 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -313,7 +313,6 @@ protected: TypeDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, Decl *PrevDecl) : Decl(DK, L, Id, PrevDecl), TypeForDecl(0) {} public: - // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return D->getKind() >= Typedef && D->getKind() <= Enum;