class LabelStmt;
class SwitchStmt;
class OCUVectorType;
-
+ class TypedefDecl;
+
/// Sema - This implements semantic analysis and AST building for C.
class Sema : public Action {
Preprocessor &PP;
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);
// 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.
}
}
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...
}
}
}
-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.).
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.
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,
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::