Make Declarator::getDeclSpec() return a const reference to avoid

cases where mutation can introduce bugs.  Propagate around 'const'.

llvm-svn: 52772
This commit is contained in:
Chris Lattner 2008-06-26 06:49:43 +00:00
parent 3e39fa365d
commit cf31de3760
5 changed files with 66 additions and 56 deletions

View File

@ -570,8 +570,15 @@ public:
/// getDeclSpec - Return the declaration-specifier that this declarator was /// getDeclSpec - Return the declaration-specifier that this declarator was
/// declared with. /// declared with.
DeclSpec &getDeclSpec() const { return DS; } const DeclSpec &getDeclSpec() const { return DS; }
/// getMutableDeclSpec - Return a non-const version of the DeclSpec. This
/// should be used with extreme care: declspecs can often be shared between
/// multiple declarators, so mutating the DeclSpec affects all of the
/// Declarators. This should only be done when the declspec is known to not
/// be shared or when in error recovery etc.
DeclSpec &getMutableDeclSpec() { return DS; }
TheContext getContext() const { return Context; } TheContext getContext() const { return Context; }
// getSourceRange - FIXME: This should be implemented. // getSourceRange - FIXME: This should be implemented.

View File

@ -473,7 +473,7 @@ Parser::DeclTy *Parser::ParseFunctionDefinition(Declarator &D) {
// declaration-specifiers are completely optional in the grammar. // declaration-specifiers are completely optional in the grammar.
if (getLang().ImplicitInt && D.getDeclSpec().getParsedSpecifiers() == 0) { if (getLang().ImplicitInt && D.getDeclSpec().getParsedSpecifiers() == 0) {
const char *PrevSpec; const char *PrevSpec;
D.getDeclSpec().SetTypeSpecType(DeclSpec::TST_int, D.getIdentifierLoc(), D.getMutableDeclSpec().SetTypeSpecType(DeclSpec::TST_int, D.getIdentifierLoc(),
PrevSpec); PrevSpec);
} }

View File

@ -296,9 +296,9 @@ private:
ScopedDecl *ImplicitlyDefineFunction(SourceLocation Loc, IdentifierInfo &II, ScopedDecl *ImplicitlyDefineFunction(SourceLocation Loc, IdentifierInfo &II,
Scope *S); Scope *S);
// Decl attributes - this routine is the top level dispatcher. // Decl attributes - this routine is the top level dispatcher.
void HandleDeclAttributes(Decl *New, AttributeList *declspec_prefix, void HandleDeclAttributes(Decl *New, const AttributeList *DeclSpecAttrs,
AttributeList *declarator_postfix); const AttributeList *DeclaratorAttrs);
void HandleDeclAttribute(Decl *New, AttributeList *rawAttr); void HandleDeclAttribute(Decl *New, const AttributeList *rawAttr);
/// HandleAddressSpaceTypeAttribute - this attribute is only applicable to /// HandleAddressSpaceTypeAttribute - this attribute is only applicable to
/// objects without automatic storage duration. /// objects without automatic storage duration.
@ -311,7 +311,7 @@ private:
/// primitive type. Note that this is a variable attribute, and not /// primitive type. Note that this is a variable attribute, and not
/// a type attribute. /// a type attribute.
QualType HandleModeTypeAttribute(QualType curType, QualType HandleModeTypeAttribute(QualType curType,
AttributeList *rawAttr); const AttributeList *rawAttr);
// HandleVectorTypeAttribute - this attribute is only applicable to // HandleVectorTypeAttribute - this attribute is only applicable to
// integral and float scalars, although arrays, pointers, and function // integral and float scalars, although arrays, pointers, and function
@ -321,24 +321,26 @@ private:
// The raw attribute should contain precisely 1 argument, the vector size // The raw attribute should contain precisely 1 argument, the vector size
// for the variable, measured in bytes. If curType and rawAttr are well // for the variable, measured in bytes. If curType and rawAttr are well
// formed, this routine will return a new vector type. // formed, this routine will return a new vector type.
QualType HandleVectorTypeAttribute(QualType curType, AttributeList *rawAttr); QualType HandleVectorTypeAttribute(QualType curType,
void HandleExtVectorTypeAttribute(TypedefDecl *d, AttributeList *rawAttr); const AttributeList *rawAttr);
void HandleExtVectorTypeAttribute(TypedefDecl *d,
const AttributeList *rawAttr);
void HandleAlignedAttribute(Decl *d, AttributeList *rawAttr); void HandleAlignedAttribute(Decl *d, const AttributeList *rawAttr);
void HandleAliasAttribute(Decl *d, AttributeList *rawAttr); void HandleAliasAttribute(Decl *d, const AttributeList *rawAttr);
void HandlePackedAttribute(Decl *d, AttributeList *rawAttr); void HandlePackedAttribute(Decl *d, const AttributeList *rawAttr);
void HandleAnnotateAttribute(Decl *d, AttributeList *rawAttr); void HandleAnnotateAttribute(Decl *d, const AttributeList *rawAttr);
void HandleNoReturnAttribute(Decl *d, AttributeList *rawAttr); void HandleNoReturnAttribute(Decl *d, const AttributeList *rawAttr);
void HandleDeprecatedAttribute(Decl *d, AttributeList *rawAttr); void HandleDeprecatedAttribute(Decl *d, const AttributeList *rawAttr);
void HandleWeakAttribute(Decl *d, AttributeList *rawAttr); void HandleWeakAttribute(Decl *d, const AttributeList *rawAttr);
void HandleDLLImportAttribute(Decl *d, AttributeList *rawAttr); void HandleDLLImportAttribute(Decl *d, const AttributeList *rawAttr);
void HandleDLLExportAttribute(Decl *d, AttributeList *rawAttr); void HandleDLLExportAttribute(Decl *d, const AttributeList *rawAttr);
void HandleVisibilityAttribute(Decl *d, AttributeList *rawAttr); void HandleVisibilityAttribute(Decl *d, const AttributeList *rawAttr);
void HandleNothrowAttribute(Decl *d, AttributeList *rawAttr); void HandleNothrowAttribute(Decl *d, const AttributeList *rawAttr);
void HandleFormatAttribute(Decl *d, AttributeList *rawAttr); void HandleFormatAttribute(Decl *d, const AttributeList *rawAttr);
void HandleStdCallAttribute(Decl *d, AttributeList *rawAttr); void HandleStdCallAttribute(Decl *d, const AttributeList *rawAttr);
void HandleFastCallAttribute(Decl *d, AttributeList *rawAttr); void HandleFastCallAttribute(Decl *d, const AttributeList *rawAttr);
void HandleTransparentUnionAttribute(Decl *d, AttributeList *rawAttr); void HandleTransparentUnionAttribute(Decl *d, const AttributeList *rawAttr);
void WarnUndefinedMethod(SourceLocation ImpLoc, ObjCMethodDecl *method, void WarnUndefinedMethod(SourceLocation ImpLoc, ObjCMethodDecl *method,
bool &IncompleteImpl); bool &IncompleteImpl);

View File

@ -1379,19 +1379,19 @@ Sema::DeclTy *Sema::FinalizeDeclaratorGroup(Scope *S, DeclTy *group) {
/// to introduce parameters into function prototype scope. /// to introduce parameters into function prototype scope.
Sema::DeclTy * Sema::DeclTy *
Sema::ActOnParamDeclarator(Scope *S, Declarator &D) { Sema::ActOnParamDeclarator(Scope *S, Declarator &D) {
DeclSpec &DS = D.getDeclSpec(); const DeclSpec &DS = D.getDeclSpec();
// Verify C99 6.7.5.3p2: The only SCS allowed is 'register'. // Verify C99 6.7.5.3p2: The only SCS allowed is 'register'.
if (DS.getStorageClassSpec() != DeclSpec::SCS_unspecified && if (DS.getStorageClassSpec() != DeclSpec::SCS_unspecified &&
DS.getStorageClassSpec() != DeclSpec::SCS_register) { DS.getStorageClassSpec() != DeclSpec::SCS_register) {
Diag(DS.getStorageClassSpecLoc(), Diag(DS.getStorageClassSpecLoc(),
diag::err_invalid_storage_class_in_func_decl); diag::err_invalid_storage_class_in_func_decl);
DS.ClearStorageClassSpecs(); D.getMutableDeclSpec().ClearStorageClassSpecs();
} }
if (DS.isThreadSpecified()) { if (DS.isThreadSpecified()) {
Diag(DS.getThreadSpecLoc(), Diag(DS.getThreadSpecLoc(),
diag::err_invalid_storage_class_in_func_decl); diag::err_invalid_storage_class_in_func_decl);
DS.ClearStorageClassSpecs(); D.getMutableDeclSpec().ClearStorageClassSpecs();
} }
// Check that there are no default arguments inside the type of this // Check that there are no default arguments inside the type of this
@ -2326,7 +2326,7 @@ Sema::DeclTy* Sema::ActOnLinkageSpec(SourceLocation Loc,
return LinkageSpecDecl::Create(Context, Loc, Language, dcl); return LinkageSpecDecl::Create(Context, Loc, Language, dcl);
} }
void Sema::HandleDeclAttribute(Decl *New, AttributeList *Attr) { void Sema::HandleDeclAttribute(Decl *New, const AttributeList *Attr) {
switch (Attr->getKind()) { switch (Attr->getKind()) {
case AttributeList::AT_vector_size: case AttributeList::AT_vector_size:
@ -2421,35 +2421,35 @@ void Sema::HandleDeclAttribute(Decl *New, AttributeList *Attr) {
} }
} }
void Sema::HandleDeclAttributes(Decl *New, AttributeList *declspec_prefix, void Sema::HandleDeclAttributes(Decl *New, const AttributeList *DeclSpecAttrs,
AttributeList *declarator_postfix) { const AttributeList *DeclaratorAttrs) {
if (declspec_prefix == 0 && declarator_postfix == 0) return; if (DeclSpecAttrs == 0 && DeclaratorAttrs == 0) return;
while (declspec_prefix) { while (DeclSpecAttrs) {
HandleDeclAttribute(New, declspec_prefix); HandleDeclAttribute(New, DeclSpecAttrs);
declspec_prefix = declspec_prefix->getNext(); DeclSpecAttrs = DeclSpecAttrs->getNext();
} }
// If there are any type attributes that were in the declarator, apply them to // If there are any type attributes that were in the declarator, apply them to
// its top level type. // its top level type.
if (ValueDecl *VD = dyn_cast<ValueDecl>(New)) { if (ValueDecl *VD = dyn_cast<ValueDecl>(New)) {
QualType DT = VD->getType(); QualType DT = VD->getType();
ProcessTypeAttributes(DT, declarator_postfix); ProcessTypeAttributes(DT, DeclaratorAttrs);
VD->setType(DT); VD->setType(DT);
} else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(New)) { } else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(New)) {
QualType DT = TD->getUnderlyingType(); QualType DT = TD->getUnderlyingType();
ProcessTypeAttributes(DT, declarator_postfix); ProcessTypeAttributes(DT, DeclaratorAttrs);
TD->setUnderlyingType(DT); TD->setUnderlyingType(DT);
} }
while (declarator_postfix) { while (DeclaratorAttrs) {
HandleDeclAttribute(New, declarator_postfix); HandleDeclAttribute(New, DeclaratorAttrs);
declarator_postfix = declarator_postfix->getNext(); DeclaratorAttrs = DeclaratorAttrs->getNext();
} }
} }
void Sema::HandleExtVectorTypeAttribute(TypedefDecl *tDecl, void Sema::HandleExtVectorTypeAttribute(TypedefDecl *tDecl,
AttributeList *rawAttr) { const AttributeList *rawAttr) {
QualType curType = tDecl->getUnderlyingType(); QualType curType = tDecl->getUnderlyingType();
// check the attribute arguments. // check the attribute arguments.
if (rawAttr->getNumArgs() != 1) { if (rawAttr->getNumArgs() != 1) {
@ -2488,7 +2488,7 @@ void Sema::HandleExtVectorTypeAttribute(TypedefDecl *tDecl,
} }
QualType Sema::HandleVectorTypeAttribute(QualType curType, QualType Sema::HandleVectorTypeAttribute(QualType curType,
AttributeList *rawAttr) { const AttributeList *rawAttr) {
// check the attribute arugments. // check the attribute arugments.
if (rawAttr->getNumArgs() != 1) { if (rawAttr->getNumArgs() != 1) {
Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments, Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
@ -2547,7 +2547,7 @@ QualType Sema::HandleVectorTypeAttribute(QualType curType,
return Context.getVectorType(curType, vectorSize/typeSize); return Context.getVectorType(curType, vectorSize/typeSize);
} }
void Sema::HandlePackedAttribute(Decl *d, AttributeList *rawAttr) { void Sema::HandlePackedAttribute(Decl *d, const AttributeList *rawAttr) {
// check the attribute arguments. // check the attribute arguments.
if (rawAttr->getNumArgs() > 0) { if (rawAttr->getNumArgs() > 0) {
Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments, Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
@ -2572,7 +2572,7 @@ void Sema::HandlePackedAttribute(Decl *d, AttributeList *rawAttr) {
rawAttr->getName()->getName()); rawAttr->getName()->getName());
} }
void Sema::HandleAliasAttribute(Decl *d, AttributeList *rawAttr) { void Sema::HandleAliasAttribute(Decl *d, const AttributeList *rawAttr) {
// check the attribute arguments. // check the attribute arguments.
if (rawAttr->getNumArgs() != 1) { if (rawAttr->getNumArgs() != 1) {
Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments, Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
@ -2598,7 +2598,7 @@ void Sema::HandleAliasAttribute(Decl *d, AttributeList *rawAttr) {
d->addAttr(new AliasAttr(std::string(Alias, AliasLen))); d->addAttr(new AliasAttr(std::string(Alias, AliasLen)));
} }
void Sema::HandleNoReturnAttribute(Decl *d, AttributeList *rawAttr) { void Sema::HandleNoReturnAttribute(Decl *d, const AttributeList *rawAttr) {
// check the attribute arguments. // check the attribute arguments.
if (rawAttr->getNumArgs() != 0) { if (rawAttr->getNumArgs() != 0) {
Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments, Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
@ -2617,7 +2617,7 @@ void Sema::HandleNoReturnAttribute(Decl *d, AttributeList *rawAttr) {
d->addAttr(new NoReturnAttr()); d->addAttr(new NoReturnAttr());
} }
void Sema::HandleDeprecatedAttribute(Decl *d, AttributeList *rawAttr) { void Sema::HandleDeprecatedAttribute(Decl *d, const AttributeList *rawAttr) {
// check the attribute arguments. // check the attribute arguments.
if (rawAttr->getNumArgs() != 0) { if (rawAttr->getNumArgs() != 0) {
Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments, Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
@ -2628,7 +2628,7 @@ void Sema::HandleDeprecatedAttribute(Decl *d, AttributeList *rawAttr) {
d->addAttr(new DeprecatedAttr()); d->addAttr(new DeprecatedAttr());
} }
void Sema::HandleVisibilityAttribute(Decl *d, AttributeList *rawAttr) { void Sema::HandleVisibilityAttribute(Decl *d, const AttributeList *rawAttr) {
// check the attribute arguments. // check the attribute arguments.
if (rawAttr->getNumArgs() != 1) { if (rawAttr->getNumArgs() != 1) {
Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments, Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
@ -2667,7 +2667,7 @@ void Sema::HandleVisibilityAttribute(Decl *d, AttributeList *rawAttr) {
d->addAttr(new VisibilityAttr(type)); d->addAttr(new VisibilityAttr(type));
} }
void Sema::HandleWeakAttribute(Decl *d, AttributeList *rawAttr) { void Sema::HandleWeakAttribute(Decl *d, const AttributeList *rawAttr) {
// check the attribute arguments. // check the attribute arguments.
if (rawAttr->getNumArgs() != 0) { if (rawAttr->getNumArgs() != 0) {
Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments, Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
@ -2678,7 +2678,7 @@ void Sema::HandleWeakAttribute(Decl *d, AttributeList *rawAttr) {
d->addAttr(new WeakAttr()); d->addAttr(new WeakAttr());
} }
void Sema::HandleDLLImportAttribute(Decl *d, AttributeList *rawAttr) { void Sema::HandleDLLImportAttribute(Decl *d, const AttributeList *rawAttr) {
// check the attribute arguments. // check the attribute arguments.
if (rawAttr->getNumArgs() != 0) { if (rawAttr->getNumArgs() != 0) {
Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments, Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
@ -2689,7 +2689,7 @@ void Sema::HandleDLLImportAttribute(Decl *d, AttributeList *rawAttr) {
d->addAttr(new DLLImportAttr()); d->addAttr(new DLLImportAttr());
} }
void Sema::HandleDLLExportAttribute(Decl *d, AttributeList *rawAttr) { void Sema::HandleDLLExportAttribute(Decl *d, const AttributeList *rawAttr) {
// check the attribute arguments. // check the attribute arguments.
if (rawAttr->getNumArgs() != 0) { if (rawAttr->getNumArgs() != 0) {
Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments, Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
@ -2700,7 +2700,7 @@ void Sema::HandleDLLExportAttribute(Decl *d, AttributeList *rawAttr) {
d->addAttr(new DLLExportAttr()); d->addAttr(new DLLExportAttr());
} }
void Sema::HandleStdCallAttribute(Decl *d, AttributeList *rawAttr) { void Sema::HandleStdCallAttribute(Decl *d, const AttributeList *rawAttr) {
// check the attribute arguments. // check the attribute arguments.
if (rawAttr->getNumArgs() != 0) { if (rawAttr->getNumArgs() != 0) {
Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments, Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
@ -2711,7 +2711,7 @@ void Sema::HandleStdCallAttribute(Decl *d, AttributeList *rawAttr) {
d->addAttr(new StdCallAttr()); d->addAttr(new StdCallAttr());
} }
void Sema::HandleFastCallAttribute(Decl *d, AttributeList *rawAttr) { void Sema::HandleFastCallAttribute(Decl *d, const AttributeList *rawAttr) {
// check the attribute arguments. // check the attribute arguments.
if (rawAttr->getNumArgs() != 0) { if (rawAttr->getNumArgs() != 0) {
Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments, Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
@ -2722,7 +2722,7 @@ void Sema::HandleFastCallAttribute(Decl *d, AttributeList *rawAttr) {
d->addAttr(new FastCallAttr()); d->addAttr(new FastCallAttr());
} }
void Sema::HandleNothrowAttribute(Decl *d, AttributeList *rawAttr) { void Sema::HandleNothrowAttribute(Decl *d, const AttributeList *rawAttr) {
// check the attribute arguments. // check the attribute arguments.
if (rawAttr->getNumArgs() != 0) { if (rawAttr->getNumArgs() != 0) {
Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments, Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
@ -2775,7 +2775,7 @@ static inline bool isNSStringType(QualType T, ASTContext &Ctx) {
/// Handle __attribute__((format(type,idx,firstarg))) attributes /// Handle __attribute__((format(type,idx,firstarg))) attributes
/// based on http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html /// based on http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
void Sema::HandleFormatAttribute(Decl *d, AttributeList *rawAttr) { void Sema::HandleFormatAttribute(Decl *d, const AttributeList *rawAttr) {
if (!rawAttr->getParameterName()) { if (!rawAttr->getParameterName()) {
Diag(rawAttr->getLoc(), diag::err_attribute_argument_n_not_string, Diag(rawAttr->getLoc(), diag::err_attribute_argument_n_not_string,
@ -2921,7 +2921,8 @@ void Sema::HandleFormatAttribute(Decl *d, AttributeList *rawAttr) {
Idx.getZExtValue(), FirstArg.getZExtValue())); Idx.getZExtValue(), FirstArg.getZExtValue()));
} }
void Sema::HandleTransparentUnionAttribute(Decl *d, AttributeList *rawAttr) { void Sema::HandleTransparentUnionAttribute(Decl *d,
const AttributeList *rawAttr) {
// check the attribute arguments. // check the attribute arguments.
if (rawAttr->getNumArgs() != 0) { if (rawAttr->getNumArgs() != 0) {
Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments, Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
@ -2944,7 +2945,7 @@ void Sema::HandleTransparentUnionAttribute(Decl *d, AttributeList *rawAttr) {
// Ty->addAttr(new TransparentUnionAttr()); // Ty->addAttr(new TransparentUnionAttr());
} }
void Sema::HandleAnnotateAttribute(Decl *d, AttributeList *rawAttr) { void Sema::HandleAnnotateAttribute(Decl *d, const AttributeList *rawAttr) {
// check the attribute arguments. // check the attribute arguments.
if (rawAttr->getNumArgs() != 1) { if (rawAttr->getNumArgs() != 1) {
Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments, Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
@ -2964,7 +2965,7 @@ void Sema::HandleAnnotateAttribute(Decl *d, AttributeList *rawAttr) {
SE->getByteLength()))); SE->getByteLength())));
} }
void Sema::HandleAlignedAttribute(Decl *d, AttributeList *rawAttr) void Sema::HandleAlignedAttribute(Decl *d, const AttributeList *rawAttr)
{ {
// check the attribute arguments. // check the attribute arguments.
if (rawAttr->getNumArgs() > 1) { if (rawAttr->getNumArgs() > 1) {

View File

@ -563,7 +563,7 @@ QualType Sema::HandleAddressSpaceTypeAttribute(QualType Type,
/// HandleModeTypeAttribute - Process a mode attribute on the /// HandleModeTypeAttribute - Process a mode attribute on the
/// specified type. /// specified type.
QualType Sema::HandleModeTypeAttribute(QualType Type, QualType Sema::HandleModeTypeAttribute(QualType Type,
AttributeList *Attr) { const AttributeList *Attr) {
// This attribute isn't documented, but glibc uses it. It changes // This attribute isn't documented, but glibc uses it. It changes
// the width of an int or unsigned int to the specified size. // the width of an int or unsigned int to the specified size.