Fix bugs with default parameter values for pointer-typed function parameters.
In particular "void foo(int * ptr = NULL)" and the like work now. Issue #197.
This commit is contained in:
32
decl.cpp
32
decl.cpp
@@ -424,7 +424,7 @@ Declarator::GetType(const Type *base, DeclSpecs *ds) const {
|
|||||||
case DK_FUNCTION: {
|
case DK_FUNCTION: {
|
||||||
std::vector<const Type *> args;
|
std::vector<const Type *> args;
|
||||||
std::vector<std::string> argNames;
|
std::vector<std::string> argNames;
|
||||||
std::vector<ConstExpr *> argDefaults;
|
std::vector<Expr *> argDefaults;
|
||||||
std::vector<SourcePos> argPos;
|
std::vector<SourcePos> argPos;
|
||||||
|
|
||||||
// Loop over the function arguments and store the names, types,
|
// Loop over the function arguments and store the names, types,
|
||||||
@@ -482,23 +482,25 @@ Declarator::GetType(const Type *base, DeclSpecs *ds) const {
|
|||||||
argNames.push_back(sym->name);
|
argNames.push_back(sym->name);
|
||||||
argPos.push_back(sym->pos);
|
argPos.push_back(sym->pos);
|
||||||
|
|
||||||
ConstExpr *init = NULL;
|
Expr *init = NULL;
|
||||||
if (d->declarators.size()) {
|
if (d->declarators.size()) {
|
||||||
// Try to find an initializer expression; if there is one,
|
// Try to find an initializer expression.
|
||||||
// it lives down to the base declarator.
|
|
||||||
Declarator *decl = d->declarators[0];
|
Declarator *decl = d->declarators[0];
|
||||||
while (decl->child != NULL) {
|
while (decl->child != NULL) {
|
||||||
Assert(decl->initExpr == NULL);
|
if (decl->initExpr != NULL) {
|
||||||
decl = decl->child;
|
decl->initExpr = TypeCheck(decl->initExpr);
|
||||||
}
|
decl->initExpr = Optimize(decl->initExpr);
|
||||||
|
if (decl->initExpr != NULL &&
|
||||||
if (decl->initExpr != NULL &&
|
((init = dynamic_cast<ConstExpr *>(decl->initExpr)) == NULL) &&
|
||||||
(decl->initExpr = TypeCheck(decl->initExpr)) != NULL &&
|
((init = dynamic_cast<NullPointerExpr *>(decl->initExpr)) == NULL)) {
|
||||||
(decl->initExpr = Optimize(decl->initExpr)) != NULL &&
|
Error(decl->initExpr->pos, "Default value for parameter "
|
||||||
(init = dynamic_cast<ConstExpr *>(decl->initExpr)) == NULL) {
|
"\"%s\" must be a compile-time constant.",
|
||||||
Error(decl->initExpr->pos, "Default value for parameter "
|
sym->name.c_str());
|
||||||
"\"%s\" must be a compile-time constant.",
|
}
|
||||||
sym->name.c_str());
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
decl = decl->child;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
argDefaults.push_back(init);
|
argDefaults.push_back(init);
|
||||||
|
|||||||
@@ -547,7 +547,7 @@ Module::AddFunctionDeclaration(Symbol *funSym, bool isInline) {
|
|||||||
for (int i = 0; i < nArgs; ++i) {
|
for (int i = 0; i < nArgs; ++i) {
|
||||||
const Type *argType = functionType->GetParameterType(i);
|
const Type *argType = functionType->GetParameterType(i);
|
||||||
const std::string &argName = functionType->GetParameterName(i);
|
const std::string &argName = functionType->GetParameterName(i);
|
||||||
ConstExpr *defaultValue = functionType->GetParameterDefault(i);
|
Expr *defaultValue = functionType->GetParameterDefault(i);
|
||||||
const SourcePos &argPos = functionType->GetParameterSourcePos(i);
|
const SourcePos &argPos = functionType->GetParameterSourcePos(i);
|
||||||
|
|
||||||
// If the function is exported, make sure that the parameter
|
// If the function is exported, make sure that the parameter
|
||||||
|
|||||||
6
type.cpp
6
type.cpp
@@ -2330,7 +2330,7 @@ FunctionType::FunctionType(const Type *r, const std::vector<const Type *> &a,
|
|||||||
SourcePos p)
|
SourcePos p)
|
||||||
: isTask(false), isExported(false), isExternC(false), returnType(r),
|
: isTask(false), isExported(false), isExternC(false), returnType(r),
|
||||||
paramTypes(a), paramNames(std::vector<std::string>(a.size(), "")),
|
paramTypes(a), paramNames(std::vector<std::string>(a.size(), "")),
|
||||||
paramDefaults(std::vector<ConstExpr *>(a.size(), NULL)),
|
paramDefaults(std::vector<Expr *>(a.size(), NULL)),
|
||||||
paramPositions(std::vector<SourcePos>(a.size(), p)) {
|
paramPositions(std::vector<SourcePos>(a.size(), p)) {
|
||||||
Assert(returnType != NULL);
|
Assert(returnType != NULL);
|
||||||
isSafe = false;
|
isSafe = false;
|
||||||
@@ -2340,7 +2340,7 @@ FunctionType::FunctionType(const Type *r, const std::vector<const Type *> &a,
|
|||||||
|
|
||||||
FunctionType::FunctionType(const Type *r, const std::vector<const Type *> &a,
|
FunctionType::FunctionType(const Type *r, const std::vector<const Type *> &a,
|
||||||
const std::vector<std::string> &an,
|
const std::vector<std::string> &an,
|
||||||
const std::vector<ConstExpr *> &ad,
|
const std::vector<Expr *> &ad,
|
||||||
const std::vector<SourcePos> &ap,
|
const std::vector<SourcePos> &ap,
|
||||||
bool it, bool is, bool ec)
|
bool it, bool is, bool ec)
|
||||||
: isTask(it), isExported(is), isExternC(ec), returnType(r), paramTypes(a),
|
: isTask(it), isExported(is), isExternC(ec), returnType(r), paramTypes(a),
|
||||||
@@ -2614,7 +2614,7 @@ FunctionType::GetParameterType(int i) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ConstExpr *
|
Expr *
|
||||||
FunctionType::GetParameterDefault(int i) const {
|
FunctionType::GetParameterDefault(int i) const {
|
||||||
Assert(i < (int)paramDefaults.size());
|
Assert(i < (int)paramDefaults.size());
|
||||||
return paramDefaults[i];
|
return paramDefaults[i];
|
||||||
|
|||||||
6
type.h
6
type.h
@@ -745,7 +745,7 @@ public:
|
|||||||
FunctionType(const Type *returnType,
|
FunctionType(const Type *returnType,
|
||||||
const std::vector<const Type *> &argTypes,
|
const std::vector<const Type *> &argTypes,
|
||||||
const std::vector<std::string> &argNames,
|
const std::vector<std::string> &argNames,
|
||||||
const std::vector<ConstExpr *> &argDefaults,
|
const std::vector<Expr *> &argDefaults,
|
||||||
const std::vector<SourcePos> &argPos,
|
const std::vector<SourcePos> &argPos,
|
||||||
bool isTask, bool isExported, bool isExternC);
|
bool isTask, bool isExported, bool isExternC);
|
||||||
|
|
||||||
@@ -785,7 +785,7 @@ public:
|
|||||||
|
|
||||||
int GetNumParameters() const { return (int)paramTypes.size(); }
|
int GetNumParameters() const { return (int)paramTypes.size(); }
|
||||||
const Type *GetParameterType(int i) const;
|
const Type *GetParameterType(int i) const;
|
||||||
ConstExpr * GetParameterDefault(int i) const;
|
Expr * GetParameterDefault(int i) const;
|
||||||
const SourcePos &GetParameterSourcePos(int i) const;
|
const SourcePos &GetParameterSourcePos(int i) const;
|
||||||
const std::string &GetParameterName(int i) const;
|
const std::string &GetParameterName(int i) const;
|
||||||
|
|
||||||
@@ -818,7 +818,7 @@ private:
|
|||||||
const std::vector<std::string> paramNames;
|
const std::vector<std::string> paramNames;
|
||||||
/** Default values of the function's arguments. For arguments without
|
/** Default values of the function's arguments. For arguments without
|
||||||
default values provided, NULL is stored. */
|
default values provided, NULL is stored. */
|
||||||
mutable std::vector<ConstExpr *> paramDefaults;
|
mutable std::vector<Expr *> paramDefaults;
|
||||||
/** The names provided (if any) with the function arguments in the
|
/** The names provided (if any) with the function arguments in the
|
||||||
function's signature. These should only be used for error messages
|
function's signature. These should only be used for error messages
|
||||||
and the like and so not affect testing function types for equality,
|
and the like and so not affect testing function types for equality,
|
||||||
|
|||||||
Reference in New Issue
Block a user