aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Naroff <snaroff@apple.com>2007-07-29 16:33:31 +0000
committerSteve Naroff <snaroff@apple.com>2007-07-29 16:33:31 +0000
commitbea0b34d99dddb7829857bbc96628713ab9c274b (patch)
treef30715d2e600d8aec62291e3cfebef2573f01420
parent31a458462c6cf417a84e0c47852b18fb22d79acb (diff)
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
-rw-r--r--Sema/Sema.h10
-rw-r--r--Sema/SemaDecl.cpp29
-rw-r--r--Sema/SemaExpr.cpp10
-rw-r--r--include/clang/AST/Decl.h1
4 files changed, 31 insertions, 19 deletions
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<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/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<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/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;