diff options
-rw-r--r-- | include/clang/AST/Decl.h | 8 | ||||
-rw-r--r-- | lib/AST/Decl.cpp | 57 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 8 | ||||
-rw-r--r-- | test/CodeGen/func-decl-cleanup.c | 12 |
4 files changed, 17 insertions, 68 deletions
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index 6b3eccf30c..a90ebdd47d 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -446,6 +446,10 @@ public: return PreviousDeclaration; } + void setPreviousDeclaration(FunctionDecl * PrevDecl) { + PreviousDeclaration = PrevDecl; + } + // Iterator access to formal parameters. unsigned param_size() const { return getNumParams(); } typedef ParmVarDecl **param_iterator; @@ -492,10 +496,6 @@ public: } StorageClass getStorageClass() const { return StorageClass(SClass); } bool isInline() const { return IsInline; } - - /// AddRedeclaration - Adds the function declaration FD as a - /// redeclaration of this function. - void AddRedeclaration(FunctionDecl *FD); // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return D->getKind() == Function; } diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index a9afc816e2..8d87d1cb4a 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -502,63 +502,6 @@ unsigned FunctionDecl::getMinRequiredArguments() const { return NumRequiredArgs; } -/// AddRedeclaration - Specifies that this function declaration has been -/// redeclared by the function declaration FD. FD must be a -/// redeclaration of this based on the semantics of the language being -/// translated ("compatible" function types in C, same signatures in -/// C++). -void FunctionDecl::AddRedeclaration(FunctionDecl *FD) { - assert(FD->PreviousDeclaration == 0 && - "Redeclaration already has a previous declaration!"); - - // Insert FD into the list of previous declarations of this - // function. - FD->PreviousDeclaration = this->PreviousDeclaration; - this->PreviousDeclaration = FD; - - // Swap the contents of this function declaration and FD. This - // effectively transforms the original declaration into the most - // recent declaration, so that all references to this declaration - // remain valid (and have information from *all* declarations), - // while retaining all of the information about previous - // declarations as well. - - // Swap parameters, so that the most recent parameter names and - // exact types (e.g., enum vs int) show up in the original - // declaration. - std::swap(this->ParamInfo, FD->ParamInfo); - - // Swap the function body: all declarations share the same function - // body, but we keep track of who actually defined that function - // body by keeping the pointer to the body stored in that node. - std::swap(this->Body, FD->Body); - - // Swap type information: this is important because in C, later - // declarations can provide slightly different types (enum vs. int, - // for example). - QualType thisType = this->getType(); - this->setType(FD->getType()); - FD->setType(thisType); - - // Swap location information: this allows us to produce diagnostics - // later on that reference the most recent declaration (which has - // the most information!) while retaining the location of previous - // declarations (good for "redefinition" diagnostics). - SourceLocation thisLocation = this->getLocation(); - this->setLocation(FD->getLocation()); - FD->setLocation(thisLocation); - - // Swap attributes. FD will have the union of the attributes from - // all previous declarations. - this->swapAttrs(FD); - - // If any declaration is inline, the function is inline. - this->IsInline |= FD->IsInline; - - // FIXME: Is this the right way to handle storage specifiers? - if (FD->SClass) this->SClass = FD->SClass; -} - //===----------------------------------------------------------------------===// // RecordDecl Implementation //===----------------------------------------------------------------------===// diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 8b89045a71..2856403ccf 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -910,13 +910,7 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) { NewFD = MergeFunctionDecl(NewFD, PrevDecl, Redeclaration); if (NewFD == 0) return 0; if (Redeclaration) { - // Note that the new declaration is a redeclaration of the - // older declaration. Then return the older declaration: the - // new one is only kept within the set of previous - // declarations for this function. - FunctionDecl *OldFD = (FunctionDecl *)PrevDecl; - OldFD->AddRedeclaration(NewFD); - return OldFD; + NewFD->setPreviousDeclaration(cast<FunctionDecl>(PrevDecl)); } } New = NewFD; diff --git a/test/CodeGen/func-decl-cleanup.c b/test/CodeGen/func-decl-cleanup.c new file mode 100644 index 0000000000..fa1e3d69b1 --- /dev/null +++ b/test/CodeGen/func-decl-cleanup.c @@ -0,0 +1,12 @@ +// RUN: clang %s -emit-llvm -o - + + +// PR2360 +typedef void fn_t(); + +fn_t a,b; + +void b() +{ +} + |