diff options
author | Steve Naroff <snaroff@apple.com> | 2007-07-29 16:33:31 +0000 |
---|---|---|
committer | Steve Naroff <snaroff@apple.com> | 2007-07-29 16:33:31 +0000 |
commit | ddf5a1d7a6be3d55bcd65c28758cd392dc9a87b7 (patch) | |
tree | 2d8b795e9be5ae2248846b351e7d969b6f156b5c | |
parent | 5fecb80efac9466926aaadb3d9e67b78bc71fd21 (diff) | |
download | bcm5719-llvm-ddf5a1d7a6be3d55bcd65c28758cd392dc9a87b7.tar.gz bcm5719-llvm-ddf5a1d7a6be3d55bcd65c28758cd392dc9a87b7.zip |
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
~ ^ ~~~~~~~
llvm-svn: 40579
-rw-r--r-- | clang/Sema/Sema.h | 10 | ||||
-rw-r--r-- | clang/Sema/SemaDecl.cpp | 29 | ||||
-rw-r--r-- | clang/Sema/SemaExpr.cpp | 10 | ||||
-rw-r--r-- | clang/include/clang/AST/Decl.h | 1 |
4 files changed, 31 insertions, 19 deletions
diff --git a/clang/Sema/Sema.h b/clang/Sema/Sema.h index 589161bfab8..ea724ab44b2 100644 --- a/clang/Sema/Sema.h +++ b/clang/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<IdentifierInfo*, LabelStmt*> LabelMap; llvm::SmallVector<SwitchStmt*, 8> 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<TypedefDecl*, 24> OCUVectorDecls; public: Sema(Preprocessor &pp, ASTContext &ctxt, std::vector<Decl*> &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/clang/Sema/SemaDecl.cpp b/clang/Sema/SemaDecl.cpp index 3053d2e2a8a..722452b51a4 100644 --- a/clang/Sema/SemaDecl.cpp +++ b/clang/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<TypedefDecl>(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<TypedefDecl>(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<Expr *>(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/clang/Sema/SemaExpr.cpp b/clang/Sema/SemaExpr.cpp index 445b6b56688..8646c1a7927 100644 --- a/clang/Sema/SemaExpr.cpp +++ b/clang/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/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index b37ab1f99f9..a67762a6746 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/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; |