diff --git a/decl.cpp b/decl.cpp index e7b3cdef..8a10543b 100644 --- a/decl.cpp +++ b/decl.cpp @@ -69,8 +69,15 @@ lApplyTypeQualifiers(int typeQualifiers, const Type *type, SourcePos pos) { if (type == NULL) return NULL; - if ((typeQualifiers & TYPEQUAL_CONST) != 0) + if ((typeQualifiers & TYPEQUAL_CONST) != 0) { type = type->GetAsConstType(); + } + + if ( ((typeQualifiers & TYPEQUAL_UNIFORM) != 0) + && ((typeQualifiers & TYPEQUAL_VARYING) != 0) ) { + Error(pos, "Type \"%s\" cannot be qualified with both uniform and varying.", + type->GetString().c_str()); + } if ((typeQualifiers & TYPEQUAL_UNIFORM) != 0) { if (Type::Equal(type, AtomicType::Void)) @@ -84,9 +91,10 @@ lApplyTypeQualifiers(int typeQualifiers, const Type *type, SourcePos pos) { else type = type->GetAsVaryingType(); } - else + else { if (Type::Equal(type, AtomicType::Void) == false) type = type->GetAsUnboundVariabilityType(); + } if ((typeQualifiers & TYPEQUAL_UNSIGNED) != 0) { if ((typeQualifiers & TYPEQUAL_SIGNED) != 0) @@ -124,6 +132,17 @@ DeclSpecs::DeclSpecs(const Type *t, StorageClass sc, int tq) { typeQualifiers = tq; soaWidth = 0; vectorSize = 0; + if (t != NULL) { + if (m->symbolTable->ContainsType(t)) { + // Typedefs might have uniform/varying qualifiers inside. + if (t->IsVaryingType()) { + typeQualifiers |= TYPEQUAL_VARYING; + } + else if (t->IsUniformType()) { + typeQualifiers |= TYPEQUAL_UNIFORM; + } + } + } } @@ -229,6 +248,7 @@ Declarator::Declarator(DeclaratorKind dk, SourcePos p) void Declarator::InitFromDeclSpecs(DeclSpecs *ds) { const Type *baseType = ds->GetBaseType(pos); + InitFromType(baseType, ds); if (type == NULL) { @@ -591,6 +611,7 @@ Declaration::Declaration(DeclSpecs *ds, Declarator *d) { } + std::vector Declaration::GetVariableDeclarations() const { Assert(declSpecs->storageClass != SC_TYPEDEF); diff --git a/sym.cpp b/sym.cpp index f16f5e11..05f9996a 100644 --- a/sym.cpp +++ b/sym.cpp @@ -214,6 +214,17 @@ SymbolTable::LookupType(const char *name) const { return NULL; } +bool +SymbolTable::ContainsType(const Type *type) const { + TypeMapType::const_iterator iter = types.begin(); + while (iter != types.end()) { + if (iter->second == type) { + return true; + } + iter++; + } + return false; +} std::vector SymbolTable::ClosestVariableOrFunctionMatch(const char *str) const { diff --git a/sym.h b/sym.h index efb532a3..761c3612 100644 --- a/sym.h +++ b/sym.h @@ -219,6 +219,12 @@ public: @return Pointer to the Type, if found; otherwise NULL is returned. */ const Type *LookupType(const char *name) const; + + /** Look for a type given a pointer. + + @return True if found, False otherwise. + */ + bool ContainsType(const Type * type) const; /** This method returns zero or more strings with the names of symbols in the symbol table that nearly (but not exactly) match the given