forked from OSchip/llvm-project
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
This commit is contained in:
parent
5fecb80efa
commit
ddf5a1d7a6
|
@ -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.
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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::
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue