//===--- SemaType.cpp - Semantic Analysis for Types -----------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements type-related semantic analysis.
//
//===----------------------------------------------------------------------===//
#include "Sema.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Expr.h"
#include "clang/Parse/DeclSpec.h"
using namespace clang;
/// \brief Perform adjustment on the parameter type of a function.
///
/// This routine adjusts the given parameter type @p T to the actual
/// parameter type used by semantic analysis (C99 6.7.5.3p[7,8],
/// C++ [dcl.fct]p3). The adjusted parameter type is returned.
QualType Sema::adjustParameterType(QualType T) {
// C99 6.7.5.3p7:
if (T->isArrayType()) {
// C99 6.7.5.3p7:
// A declaration of a parameter as "array of type" shall be
// adjusted to "qualified pointer to type", where the type
// qualifiers (if any) are those specified within the [ and ] of
// the array type derivation.
return Context.getArrayDecayedType(T);
} else if (T->isFunctionType())
// C99 6.7.5.3p8:
// A declaration of a parameter as "function returning type"
// shall be adjusted to "pointer to function returning type", as
// in 6.3.2.1.
return Context.getPointerType(T);
return T;
}
/// \brief Convert the specified declspec to the appropriate type
/// object.
/// \param DS the declaration specifiers
/// \param DeclLoc The location of the declarator identifier or invalid if none.
/// \returns The type described by the declaration specifiers. This function
/// never returns null.
QualType Sema::ConvertDeclSpecToType(const DeclSpec &DS,
SourceLocation DeclLoc,
bool &isInvalid) {
// FIXME: Should move the logic from DeclSpec::Finish to here for validity
// checking.
QualType Result;
switch (DS.getTypeSpecType()) {
case DeclSpec::TST_void:
Result = Context.VoidTy;
break;
case DeclSpec::TST_char:
if (DS.getTypeSpecSign() == DeclSpec::TSS_unspecified)
Result = Context.CharTy;
else if (DS.getTypeSpecSign() == DeclSpec::TSS_signed)
Result = Context.SignedCharTy;
else {
assert(DS.getTypeSpecSign() == DeclSpec::TSS_unsigned &&
"Unknown TSS value");
Result = Context.UnsignedCharTy;
}
break;
case DeclSpec::TST_wchar:
if (DS.getTypeSpecSign() == DeclSpec::TSS_unspecified)
Result = Context.WCharTy;
else if (DS.getTypeSpecSign() == DeclSpec::TSS_signed) {
Diag(DS.getTypeSpecSignLoc(), diag::ext_invalid_sign_spec)
<< DS.getSpecifierName(DS.getTypeSpecType());
Result = Context.getSignedWCharType();
} else {
assert(DS.getTypeSpecSign() == DeclSpec::TSS_unsigned &&
"Unknown TSS value");
Diag(DS.getTypeSpecSignLoc(), diag::ext_invalid_sign_spec)
<< DS.getSpecifierName(DS.getTypeSpecType());
Result = Context.getUnsignedWCharType();
}
break;
case DeclSpec::TST_unspecified:
// "<proto1,proto2>" is an objc qualified ID with a missing id.
if (DeclSpec::ProtocolQualifierListTy PQ = DS.getProtocolQualifiers()) {
Result = Context.getObjCQualifiedIdType((ObjCProtocolDecl**)PQ,
DS.getNumProtocolQualifiers());
break;
}
// Unspecified typespec defaults to int in C90. However, the C90 grammar
// [C90 6.5] only allows a decl-spec if there was *some* type-specifier,
// type-qualifier, or storage-class-specifier. If not, emit an extwarn.
// Note that the one exception to this is function definitions, which are
// allowed to be completely missing a declspec. This is handled in the
// parser already though by it pretending to have seen an 'int' in this
// case.
if (getLangOptions().ImplicitInt) {
// In C89 mode, we only warn if there is a completely missing declspec
// when one is not allowed.
if (DS.isEmpty()) {
if (DeclLoc.isInvalid())
DeclLoc = DS.getSourceRange().getBegin();
Diag(DeclLoc, diag::warn_missing_declspec)
<< DS.getSourceRange()