From cf31de3760a0c3f59d19501138bc60a1bf80d5a6 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Thu, 26 Jun 2008 06:49:43 +0000 Subject: [PATCH] Make Declarator::getDeclSpec() return a const reference to avoid cases where mutation can introduce bugs. Propagate around 'const'. llvm-svn: 52772 --- clang/include/clang/Parse/DeclSpec.h | 9 +++- clang/lib/Parse/Parser.cpp | 2 +- clang/lib/Sema/Sema.h | 44 ++++++++++--------- clang/lib/Sema/SemaDecl.cpp | 65 ++++++++++++++-------------- clang/lib/Sema/SemaType.cpp | 2 +- 5 files changed, 66 insertions(+), 56 deletions(-) diff --git a/clang/include/clang/Parse/DeclSpec.h b/clang/include/clang/Parse/DeclSpec.h index 4526c76152cb..2524d882dafa 100644 --- a/clang/include/clang/Parse/DeclSpec.h +++ b/clang/include/clang/Parse/DeclSpec.h @@ -570,8 +570,15 @@ public: /// getDeclSpec - Return the declaration-specifier that this declarator was /// 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; } // getSourceRange - FIXME: This should be implemented. diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index 8ff7e9f186a9..281459a3005b 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -473,7 +473,7 @@ Parser::DeclTy *Parser::ParseFunctionDefinition(Declarator &D) { // declaration-specifiers are completely optional in the grammar. if (getLang().ImplicitInt && D.getDeclSpec().getParsedSpecifiers() == 0) { const char *PrevSpec; - D.getDeclSpec().SetTypeSpecType(DeclSpec::TST_int, D.getIdentifierLoc(), + D.getMutableDeclSpec().SetTypeSpecType(DeclSpec::TST_int, D.getIdentifierLoc(), PrevSpec); } diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 278c8415d6eb..e0d97585bd0a 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -296,9 +296,9 @@ private: ScopedDecl *ImplicitlyDefineFunction(SourceLocation Loc, IdentifierInfo &II, Scope *S); // Decl attributes - this routine is the top level dispatcher. - void HandleDeclAttributes(Decl *New, AttributeList *declspec_prefix, - AttributeList *declarator_postfix); - void HandleDeclAttribute(Decl *New, AttributeList *rawAttr); + void HandleDeclAttributes(Decl *New, const AttributeList *DeclSpecAttrs, + const AttributeList *DeclaratorAttrs); + void HandleDeclAttribute(Decl *New, const AttributeList *rawAttr); /// HandleAddressSpaceTypeAttribute - this attribute is only applicable to /// objects without automatic storage duration. @@ -311,7 +311,7 @@ private: /// primitive type. Note that this is a variable attribute, and not /// a type attribute. QualType HandleModeTypeAttribute(QualType curType, - AttributeList *rawAttr); + const AttributeList *rawAttr); // HandleVectorTypeAttribute - this attribute is only applicable to // 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 // 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); - void HandleExtVectorTypeAttribute(TypedefDecl *d, AttributeList *rawAttr); + QualType HandleVectorTypeAttribute(QualType curType, + const AttributeList *rawAttr); + void HandleExtVectorTypeAttribute(TypedefDecl *d, + const AttributeList *rawAttr); - void HandleAlignedAttribute(Decl *d, AttributeList *rawAttr); - void HandleAliasAttribute(Decl *d, AttributeList *rawAttr); - void HandlePackedAttribute(Decl *d, AttributeList *rawAttr); - void HandleAnnotateAttribute(Decl *d, AttributeList *rawAttr); - void HandleNoReturnAttribute(Decl *d, AttributeList *rawAttr); - void HandleDeprecatedAttribute(Decl *d, AttributeList *rawAttr); - void HandleWeakAttribute(Decl *d, AttributeList *rawAttr); - void HandleDLLImportAttribute(Decl *d, AttributeList *rawAttr); - void HandleDLLExportAttribute(Decl *d, AttributeList *rawAttr); - void HandleVisibilityAttribute(Decl *d, AttributeList *rawAttr); - void HandleNothrowAttribute(Decl *d, AttributeList *rawAttr); - void HandleFormatAttribute(Decl *d, AttributeList *rawAttr); - void HandleStdCallAttribute(Decl *d, AttributeList *rawAttr); - void HandleFastCallAttribute(Decl *d, AttributeList *rawAttr); - void HandleTransparentUnionAttribute(Decl *d, AttributeList *rawAttr); + void HandleAlignedAttribute(Decl *d, const AttributeList *rawAttr); + void HandleAliasAttribute(Decl *d, const AttributeList *rawAttr); + void HandlePackedAttribute(Decl *d, const AttributeList *rawAttr); + void HandleAnnotateAttribute(Decl *d, const AttributeList *rawAttr); + void HandleNoReturnAttribute(Decl *d, const AttributeList *rawAttr); + void HandleDeprecatedAttribute(Decl *d, const AttributeList *rawAttr); + void HandleWeakAttribute(Decl *d, const AttributeList *rawAttr); + void HandleDLLImportAttribute(Decl *d, const AttributeList *rawAttr); + void HandleDLLExportAttribute(Decl *d, const AttributeList *rawAttr); + void HandleVisibilityAttribute(Decl *d, const AttributeList *rawAttr); + void HandleNothrowAttribute(Decl *d, const AttributeList *rawAttr); + void HandleFormatAttribute(Decl *d, const AttributeList *rawAttr); + void HandleStdCallAttribute(Decl *d, const AttributeList *rawAttr); + void HandleFastCallAttribute(Decl *d, const AttributeList *rawAttr); + void HandleTransparentUnionAttribute(Decl *d, const AttributeList *rawAttr); void WarnUndefinedMethod(SourceLocation ImpLoc, ObjCMethodDecl *method, bool &IncompleteImpl); diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 86d3ef4b0e43..b954c8b2e114 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -1379,19 +1379,19 @@ Sema::DeclTy *Sema::FinalizeDeclaratorGroup(Scope *S, DeclTy *group) { /// to introduce parameters into function prototype scope. Sema::DeclTy * 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'. if (DS.getStorageClassSpec() != DeclSpec::SCS_unspecified && DS.getStorageClassSpec() != DeclSpec::SCS_register) { Diag(DS.getStorageClassSpecLoc(), diag::err_invalid_storage_class_in_func_decl); - DS.ClearStorageClassSpecs(); + D.getMutableDeclSpec().ClearStorageClassSpecs(); } if (DS.isThreadSpecified()) { Diag(DS.getThreadSpecLoc(), 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 @@ -2326,7 +2326,7 @@ Sema::DeclTy* Sema::ActOnLinkageSpec(SourceLocation Loc, 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()) { case AttributeList::AT_vector_size: @@ -2421,35 +2421,35 @@ void Sema::HandleDeclAttribute(Decl *New, AttributeList *Attr) { } } -void Sema::HandleDeclAttributes(Decl *New, AttributeList *declspec_prefix, - AttributeList *declarator_postfix) { - if (declspec_prefix == 0 && declarator_postfix == 0) return; +void Sema::HandleDeclAttributes(Decl *New, const AttributeList *DeclSpecAttrs, + const AttributeList *DeclaratorAttrs) { + if (DeclSpecAttrs == 0 && DeclaratorAttrs == 0) return; - while (declspec_prefix) { - HandleDeclAttribute(New, declspec_prefix); - declspec_prefix = declspec_prefix->getNext(); + while (DeclSpecAttrs) { + HandleDeclAttribute(New, DeclSpecAttrs); + DeclSpecAttrs = DeclSpecAttrs->getNext(); } // If there are any type attributes that were in the declarator, apply them to // its top level type. if (ValueDecl *VD = dyn_cast(New)) { QualType DT = VD->getType(); - ProcessTypeAttributes(DT, declarator_postfix); + ProcessTypeAttributes(DT, DeclaratorAttrs); VD->setType(DT); } else if (TypedefDecl *TD = dyn_cast(New)) { QualType DT = TD->getUnderlyingType(); - ProcessTypeAttributes(DT, declarator_postfix); + ProcessTypeAttributes(DT, DeclaratorAttrs); TD->setUnderlyingType(DT); } - while (declarator_postfix) { - HandleDeclAttribute(New, declarator_postfix); - declarator_postfix = declarator_postfix->getNext(); + while (DeclaratorAttrs) { + HandleDeclAttribute(New, DeclaratorAttrs); + DeclaratorAttrs = DeclaratorAttrs->getNext(); } } void Sema::HandleExtVectorTypeAttribute(TypedefDecl *tDecl, - AttributeList *rawAttr) { + const AttributeList *rawAttr) { QualType curType = tDecl->getUnderlyingType(); // check the attribute arguments. if (rawAttr->getNumArgs() != 1) { @@ -2488,7 +2488,7 @@ void Sema::HandleExtVectorTypeAttribute(TypedefDecl *tDecl, } QualType Sema::HandleVectorTypeAttribute(QualType curType, - AttributeList *rawAttr) { + const AttributeList *rawAttr) { // check the attribute arugments. if (rawAttr->getNumArgs() != 1) { Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments, @@ -2547,7 +2547,7 @@ QualType Sema::HandleVectorTypeAttribute(QualType curType, 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. if (rawAttr->getNumArgs() > 0) { Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments, @@ -2572,7 +2572,7 @@ void Sema::HandlePackedAttribute(Decl *d, AttributeList *rawAttr) { rawAttr->getName()->getName()); } -void Sema::HandleAliasAttribute(Decl *d, AttributeList *rawAttr) { +void Sema::HandleAliasAttribute(Decl *d, const AttributeList *rawAttr) { // check the attribute arguments. if (rawAttr->getNumArgs() != 1) { 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))); } -void Sema::HandleNoReturnAttribute(Decl *d, AttributeList *rawAttr) { +void Sema::HandleNoReturnAttribute(Decl *d, const AttributeList *rawAttr) { // check the attribute arguments. if (rawAttr->getNumArgs() != 0) { Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments, @@ -2617,7 +2617,7 @@ void Sema::HandleNoReturnAttribute(Decl *d, AttributeList *rawAttr) { d->addAttr(new NoReturnAttr()); } -void Sema::HandleDeprecatedAttribute(Decl *d, AttributeList *rawAttr) { +void Sema::HandleDeprecatedAttribute(Decl *d, const AttributeList *rawAttr) { // check the attribute arguments. if (rawAttr->getNumArgs() != 0) { Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments, @@ -2628,7 +2628,7 @@ void Sema::HandleDeprecatedAttribute(Decl *d, AttributeList *rawAttr) { d->addAttr(new DeprecatedAttr()); } -void Sema::HandleVisibilityAttribute(Decl *d, AttributeList *rawAttr) { +void Sema::HandleVisibilityAttribute(Decl *d, const AttributeList *rawAttr) { // check the attribute arguments. if (rawAttr->getNumArgs() != 1) { 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)); } -void Sema::HandleWeakAttribute(Decl *d, AttributeList *rawAttr) { +void Sema::HandleWeakAttribute(Decl *d, const AttributeList *rawAttr) { // check the attribute arguments. if (rawAttr->getNumArgs() != 0) { Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments, @@ -2678,7 +2678,7 @@ void Sema::HandleWeakAttribute(Decl *d, AttributeList *rawAttr) { d->addAttr(new WeakAttr()); } -void Sema::HandleDLLImportAttribute(Decl *d, AttributeList *rawAttr) { +void Sema::HandleDLLImportAttribute(Decl *d, const AttributeList *rawAttr) { // check the attribute arguments. if (rawAttr->getNumArgs() != 0) { Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments, @@ -2689,7 +2689,7 @@ void Sema::HandleDLLImportAttribute(Decl *d, AttributeList *rawAttr) { d->addAttr(new DLLImportAttr()); } -void Sema::HandleDLLExportAttribute(Decl *d, AttributeList *rawAttr) { +void Sema::HandleDLLExportAttribute(Decl *d, const AttributeList *rawAttr) { // check the attribute arguments. if (rawAttr->getNumArgs() != 0) { Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments, @@ -2700,7 +2700,7 @@ void Sema::HandleDLLExportAttribute(Decl *d, AttributeList *rawAttr) { d->addAttr(new DLLExportAttr()); } -void Sema::HandleStdCallAttribute(Decl *d, AttributeList *rawAttr) { +void Sema::HandleStdCallAttribute(Decl *d, const AttributeList *rawAttr) { // check the attribute arguments. if (rawAttr->getNumArgs() != 0) { Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments, @@ -2711,7 +2711,7 @@ void Sema::HandleStdCallAttribute(Decl *d, AttributeList *rawAttr) { d->addAttr(new StdCallAttr()); } -void Sema::HandleFastCallAttribute(Decl *d, AttributeList *rawAttr) { +void Sema::HandleFastCallAttribute(Decl *d, const AttributeList *rawAttr) { // check the attribute arguments. if (rawAttr->getNumArgs() != 0) { Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments, @@ -2722,7 +2722,7 @@ void Sema::HandleFastCallAttribute(Decl *d, AttributeList *rawAttr) { d->addAttr(new FastCallAttr()); } -void Sema::HandleNothrowAttribute(Decl *d, AttributeList *rawAttr) { +void Sema::HandleNothrowAttribute(Decl *d, const AttributeList *rawAttr) { // check the attribute arguments. if (rawAttr->getNumArgs() != 0) { 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 /// 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()) { 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())); } -void Sema::HandleTransparentUnionAttribute(Decl *d, AttributeList *rawAttr) { +void Sema::HandleTransparentUnionAttribute(Decl *d, + const AttributeList *rawAttr) { // check the attribute arguments. if (rawAttr->getNumArgs() != 0) { Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments, @@ -2944,7 +2945,7 @@ void Sema::HandleTransparentUnionAttribute(Decl *d, AttributeList *rawAttr) { // Ty->addAttr(new TransparentUnionAttr()); } -void Sema::HandleAnnotateAttribute(Decl *d, AttributeList *rawAttr) { +void Sema::HandleAnnotateAttribute(Decl *d, const AttributeList *rawAttr) { // check the attribute arguments. if (rawAttr->getNumArgs() != 1) { Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments, @@ -2964,7 +2965,7 @@ void Sema::HandleAnnotateAttribute(Decl *d, AttributeList *rawAttr) { SE->getByteLength()))); } -void Sema::HandleAlignedAttribute(Decl *d, AttributeList *rawAttr) +void Sema::HandleAlignedAttribute(Decl *d, const AttributeList *rawAttr) { // check the attribute arguments. if (rawAttr->getNumArgs() > 1) { diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index b8e20e45be57..9d6bcb9b0783 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -563,7 +563,7 @@ QualType Sema::HandleAddressSpaceTypeAttribute(QualType Type, /// HandleModeTypeAttribute - Process a mode attribute on the /// specified type. QualType Sema::HandleModeTypeAttribute(QualType Type, - AttributeList *Attr) { + const AttributeList *Attr) { // This attribute isn't documented, but glibc uses it. It changes // the width of an int or unsigned int to the specified size.