]> granicus.if.org Git - clang/commitdiff
Simplify FunctionDecl::AddRedeclaration a bit by using std::swap.
authorChris Lattner <sabre@nondot.org>
Sun, 4 May 2008 02:29:49 +0000 (02:29 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 4 May 2008 02:29:49 +0000 (02:29 +0000)
Fix 'swapping' of attributes to not insert null values into the
DeclAttrs map.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@50612 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/DeclBase.h
lib/AST/Decl.cpp
lib/CodeGen/CodeGenFunction.cpp
lib/CodeGen/CodeGenModule.cpp

index 98a72ea7f0b58a46d6a85dbec843d7a4568f6fa5..f8ef8d41de605bd9c542ee99a2b0d9b9e8f8d08f 100644 (file)
@@ -135,6 +135,7 @@ public:
   
   void addAttr(Attr *attr);
   const Attr *getAttrs() const;
+  void swapAttrs(Decl *D);
 
   template<typename T> const T *getAttr() const {
     for (const Attr *attr = getAttrs(); attr; attr = attr->getNext())
index d2febb9cd3ce6beed08e51d84b20557d9d51a65c..1a7eecac32ad2a0be7024049529988ffeb969e0e 100644 (file)
@@ -341,6 +341,31 @@ const Attr *Decl::getAttrs() const {
   return (*DeclAttrs)[this];
 }
 
+void Decl::swapAttrs(Decl *RHS) {
+  bool HasLHSAttr = this->HasAttrs;
+  bool HasRHSAttr = RHS->HasAttrs;
+  
+  // Usually, neither decl has attrs, nothing to do.
+  if (!HasLHSAttr && !HasRHSAttr) return;
+  
+  // If 'this' has no attrs, swap the other way.
+  if (!HasLHSAttr)
+    return RHS->swapAttrs(this);
+  
+  // Handle the case when both decls have attrs.
+  if (HasRHSAttr) {
+    std::swap((*DeclAttrs)[this], (*DeclAttrs)[RHS]);
+    return;
+  }
+  
+  // Otherwise, LHS has an attr and RHS doesn't.
+  (*DeclAttrs)[RHS] = (*DeclAttrs)[this];
+  (*DeclAttrs).erase(this);
+  this->HasAttrs = false;
+  RHS->HasAttrs = true;
+}
+
+
 #define CASE(KIND) \
   case KIND: \
     static_cast<KIND##Decl *>(const_cast<Decl *>(this))->~KIND##Decl(); \
@@ -487,16 +512,12 @@ void FunctionDecl::AddRedeclaration(FunctionDecl *FD) {
   // Swap parameters, so that the most recent parameter names and
   // exact types (e.g., enum vs int) show up in the original
   // declaration.
-  ParmVarDecl **thisParamInfo = this->ParamInfo;
-  this->ParamInfo = FD->ParamInfo;
-  FD->ParamInfo = thisParamInfo;
+  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.
-  Stmt *thisBody = this->Body;
-  this->Body = FD->Body;
-  FD->Body = thisBody;
+  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,
@@ -515,11 +536,7 @@ void FunctionDecl::AddRedeclaration(FunctionDecl *FD) {
   
   // Swap attributes. FD will have the union of the attributes from
   // all previous declarations.
-  if (DeclAttrs) {
-    Attr *thisAttr = (*DeclAttrs)[this];
-    (*DeclAttrs)[this] = (*DeclAttrs)[FD];
-    (*DeclAttrs)[FD] = thisAttr;
-  }
+  this->swapAttrs(FD);
 
   // If any declaration is inline, the function is inline.
   this->IsInline |= FD->IsInline;
index bacb610a50a51d3cc21411ef1aa9b9072874bf12..d050278406f84b105e79a4e71bf8ce7a4bc65d57 100644 (file)
@@ -153,6 +153,7 @@ void CodeGenFunction::GenerateCode(const FunctionDecl *FD) {
   CurFuncDecl = FD;
   FnRetTy = FD->getType()->getAsFunctionType()->getResultType();
 
+  FD->getType().dump();
 
   CurFn = cast<llvm::Function>(CGM.GetAddrOfFunctionDecl(FD, true));
   assert(CurFn->isDeclaration() && "Function already has body?");
index 306abd120bdd0fde412f7f3c9c166c4cdaddadcf..d8b1fc327a9a209d305a060a3e899f49fc06d0fe 100644 (file)
@@ -303,28 +303,30 @@ void CodeGenModule::EmitObjCMethod(const ObjCMethodDecl *OMD) {
 
 void CodeGenModule::EmitFunction(const FunctionDecl *FD) {
   // If this is not a prototype, emit the body.
-  if (FD->getBody()) {
-    // If the function is a static, defer code generation until later so we can
-    // easily omit unused statics.
-    if (FD->getStorageClass() == FunctionDecl::Static) {
-      // We need to check the Module here to see if GetAddrOfFunctionDecl() has
-      // already added this function to the Module because the address of the
-      // function's prototype was taken.  If this is the case, call 
-      // GetAddrOfFunctionDecl to insert the static FunctionDecl into the used
-      // GlobalDeclsMap, so that EmitStatics will generate code for it later.
-      //
-      // Example:
-      // static int foo();
-      // int bar() { return foo(); }
-      // static int foo() { return 5; }
-      if (getModule().getFunction(FD->getName()))
-        GetAddrOfFunctionDecl(FD, true);
-
-      StaticDecls.push_back(FD);
-      return;
-    }
+  if (!FD->isThisDeclarationADefinition())
+    return;
+  
+  // If the function is a static, defer code generation until later so we can
+  // easily omit unused statics.
+  if (FD->getStorageClass() != FunctionDecl::Static) {
     CodeGenFunction(*this).GenerateCode(FD);
+    return;
   }
+      
+  // We need to check the Module here to see if GetAddrOfFunctionDecl() has
+  // already added this function to the Module because the address of the
+  // function's prototype was taken.  If this is the case, call 
+  // GetAddrOfFunctionDecl to insert the static FunctionDecl into the used
+  // GlobalDeclsMap, so that EmitStatics will generate code for it later.
+  //
+  // Example:
+  // static int foo();
+  // int bar() { return foo(); }
+  // static int foo() { return 5; }
+  if (getModule().getFunction(FD->getName()))
+    GetAddrOfFunctionDecl(FD, true);
+
+  StaticDecls.push_back(FD);
 }
 
 void CodeGenModule::EmitStatics() {