[cfe-commits] r39229 - in /cfe/cfe/trunk: AST/SemaDecl.cpp Parse/ParseDecl.cpp Parse/Parser.cpp Sema/SemaDecl.cpp include/clang/Parse/DeclSpec.h

sabre at cs.uiuc.edu sabre at cs.uiuc.edu
Wed Jul 11 09:41:35 PDT 2007


Author: sabre
Date: Wed Jul 11 11:41:33 2007
New Revision: 39229

URL: http://llvm.org/viewvc/llvm-project?rev=39229&view=rev
Log:
First step towards accurately retaining information about function
parameters: build an array of ParamInfo structures and pass it to the
declarator for safe keeping (it owns the list).

Next step: actually populate the arg array with useful stuff.

Modified:
    cfe/cfe/trunk/AST/SemaDecl.cpp
    cfe/cfe/trunk/Parse/ParseDecl.cpp
    cfe/cfe/trunk/Parse/Parser.cpp
    cfe/cfe/trunk/Sema/SemaDecl.cpp
    cfe/cfe/trunk/include/clang/Parse/DeclSpec.h

Modified: cfe/cfe/trunk/AST/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/SemaDecl.cpp?rev=39229&r1=39228&r2=39229&view=diff

==============================================================================
--- cfe/cfe/trunk/AST/SemaDecl.cpp (original)
+++ cfe/cfe/trunk/AST/SemaDecl.cpp Wed Jul 11 11:41:33 2007
@@ -140,7 +140,7 @@
   bool Error = DS.SetTypeSpecType(DeclSpec::TST_int, Loc, Dummy);
   assert(!Error && "Error setting up implicit decl!");
   Declarator D(DS, Declarator::BlockContext);
-  D.AddTypeInfo(DeclaratorTypeInfo::getFunction(false, false, true, Loc));
+  D.AddTypeInfo(DeclaratorTypeInfo::getFunction(false, false, 0, 0, Loc));
   D.SetIdentifier(&II, Loc);
   
   Decl *Result = static_cast<Decl*>(ParseDeclarator(S, D, 0, 0));

Modified: cfe/cfe/trunk/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Parse/ParseDecl.cpp?rev=39229&r1=39228&r2=39229&view=diff

==============================================================================
--- cfe/cfe/trunk/Parse/ParseDecl.cpp (original)
+++ cfe/cfe/trunk/Parse/ParseDecl.cpp Wed Jul 11 11:41:33 2007
@@ -264,8 +264,8 @@
                                                CurScope)) {
           isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typedef, Loc, PrevSpec,
                                          TypeRep);
+          break;
         }
-        break;
       }
       // FALL THROUGH.
     default:
@@ -862,6 +862,7 @@
 ///         identifier
 ///         identifier-list ',' identifier
 ///
+#include <iostream>
 void Parser::ParseParenDeclarator(Declarator &D) {
   SourceLocation StartLoc = ConsumeParen();
   
@@ -912,14 +913,15 @@
   // identifier list of a K&R-style function.
   bool IsVariadic;
   bool HasPrototype;
-  bool IsEmpty = false;
   bool ErrorEmitted = false;
 
+  // Build up an array of information about the parsed arguments.
+  SmallVector<DeclaratorTypeInfo::ParamInfo, 16> ParamInfo;
+  
   if (Tok.getKind() == tok::r_paren) {
     // int() -> no prototype, no '...'.
     IsVariadic   = false;
     HasPrototype = false;
-    IsEmpty      = true;
   } else if (Tok.getKind() == tok::identifier &&
              // K&R identifier lists can't have typedefs as identifiers, per
              // C99 6.7.5.3p11.
@@ -935,6 +937,9 @@
     if (!D.getIdentifier())
       Diag(Tok, diag::ext_ident_list_in_param);
     
+    // FIXME: pass stuff.
+    ParamInfo.push_back(DeclaratorTypeInfo::ParamInfo());
+
     // TODO: Remember token.
     ConsumeToken();
     while (Tok.getKind() == tok::comma) {
@@ -945,6 +950,9 @@
         ErrorEmitted = true;
         break;
       }
+
+      // FIXME: pass stuff.
+      ParamInfo.push_back(DeclaratorTypeInfo::ParamInfo());
     }
     
     // K&R 'prototype'.
@@ -1010,6 +1018,10 @@
         DS.ClearStorageClassSpecs();
       }
       
+      
+      // FIXME: pass stuff.
+      ParamInfo.push_back(DeclaratorTypeInfo::ParamInfo());
+      
       // Inform the actions module about the parameter declarator, so it gets
       // added to the current scope.
       Actions.ParseDeclarator(CurScope, DeclaratorInfo, 0, 0);
@@ -1027,11 +1039,16 @@
     ExitScope();
   }
   
-  // TODO: capture argument info.
+  DeclaratorTypeInfo::ParamInfo *ParamArray = 0;
+  if (!ParamInfo.empty()) {
+    ParamArray = new DeclaratorTypeInfo::ParamInfo[ParamInfo.size()];
+    memcpy(ParamArray, &ParamInfo[0], sizeof(ParamInfo[0])*ParamInfo.size());
+  }
   
   // Remember that we parsed a function type, and remember the attributes.
   D.AddTypeInfo(DeclaratorTypeInfo::getFunction(HasPrototype, IsVariadic,
-                                                IsEmpty, StartLoc));
+                                                ParamInfo.size(), ParamArray,
+                                                StartLoc));
   
   
   // If we have the closing ')', eat it and we're done.

Modified: cfe/cfe/trunk/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Parse/Parser.cpp?rev=39229&r1=39228&r2=39229&view=diff

==============================================================================
--- cfe/cfe/trunk/Parse/Parser.cpp (original)
+++ cfe/cfe/trunk/Parse/Parser.cpp Wed Jul 11 11:41:33 2007
@@ -413,7 +413,7 @@
   // If this declaration was formed with a K&R-style identifier list for the
   // arguments, parse declarations for all of the args next.
   // int foo(a,b) int a; float b; {}
-  if (!FnTypeInfo.Fun.hasPrototype && !FnTypeInfo.Fun.isEmpty) {
+  if (!FnTypeInfo.Fun.hasPrototype && FnTypeInfo.Fun.NumArgs != 0) {
     // Read all the argument declarations.
     while (isDeclarationSpecifier())
       ParseDeclaration(Declarator::KNRTypeListContext);

Modified: cfe/cfe/trunk/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/SemaDecl.cpp?rev=39229&r1=39228&r2=39229&view=diff

==============================================================================
--- cfe/cfe/trunk/Sema/SemaDecl.cpp (original)
+++ cfe/cfe/trunk/Sema/SemaDecl.cpp Wed Jul 11 11:41:33 2007
@@ -140,7 +140,7 @@
   bool Error = DS.SetTypeSpecType(DeclSpec::TST_int, Loc, Dummy);
   assert(!Error && "Error setting up implicit decl!");
   Declarator D(DS, Declarator::BlockContext);
-  D.AddTypeInfo(DeclaratorTypeInfo::getFunction(false, false, true, Loc));
+  D.AddTypeInfo(DeclaratorTypeInfo::getFunction(false, false, 0, 0, Loc));
   D.SetIdentifier(&II, Loc);
   
   Decl *Result = static_cast<Decl*>(ParseDeclarator(S, D, 0, 0));

Modified: cfe/cfe/trunk/include/clang/Parse/DeclSpec.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Parse/DeclSpec.h?rev=39229&r1=39228&r2=39229&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/Parse/DeclSpec.h (original)
+++ cfe/cfe/trunk/include/clang/Parse/DeclSpec.h Wed Jul 11 11:41:33 2007
@@ -215,7 +215,7 @@
   /// Finish - This does final analysis of the declspec, issuing diagnostics for
   /// things like "_Imaginary" (lacking an FP type).  After calling this method,
   /// DeclSpec is guaranteed self-consistent, even if an error occurred.
-  void Finish(Diagnostic &D,const LangOptions &Lang);
+  void Finish(Diagnostic &D, const LangOptions &Lang);
 };
 
 
@@ -249,6 +249,20 @@
     /// FIXME: make this be an expression* when we have expressions.
     void *NumElts;
   };
+  
+  /// ParamInfo - An array of paraminfo objects is allocated whenever a function
+  /// declarator is parsed.  There are two interesting styles of arguments here:
+  /// K&R-style identifier lists and parameter type lists.  K&R-style identifier
+  /// lists will have information about the identifier, but no type information.
+  /// Parameter type lists will have type info (if the actions module provides
+  /// it), but may have null identifier info: e.g. for 'void foo(int X, int)'.
+  struct ParamInfo {
+    /// Ident - In a K&R 
+    IdentifierInfo *Ident;
+    SourceLocation IdentLoc;
+    void *TypeInfo;
+  };
+  
   struct FunctionTypeInfo {
     /// hasPrototype - This is true if the function had at least one typed
     /// argument.  If the function is () or (a,b,c), then it has no prototype,
@@ -258,8 +272,15 @@
     /// isVariadic - If this function has a prototype, and if that proto ends
     /// with ',...)', this is true.
     bool isVariadic : 1;
-    // TODO: capture argument info.
-    bool isEmpty : 1;
+
+    /// NumArgs - This is the number of formal arguments provided for the
+    /// declarator.
+    unsigned NumArgs;
+
+    /// ArgInfo - This is a pointer to a new[]'d array of ParamInfo objects that
+    /// describe the arguments for this function declarator.  This is null if
+    /// there are no arguments specified.
+    ParamInfo *ArgInfo;
   };
   
   union {
@@ -294,17 +315,18 @@
     return I;
   }
   
-  /// getFunction - Return a DeclaratorTypeInfo for a function.
-  ///
+  /// getFunction - Return a DeclaratorTypeInfo for a function.  ArgInfo should
+  /// be a new[]'d array with NumArgs elements in it, or null if NumArgs is 0.
   static DeclaratorTypeInfo getFunction(bool hasProto, bool isVariadic,
-                                        bool isEmpty /*fixme arg info*/,
+                                        unsigned NumArgs, ParamInfo *ArgInfo,
                                         SourceLocation Loc) {
     DeclaratorTypeInfo I;
     I.Kind             = Function;
     I.Loc              = Loc;
     I.Fun.hasPrototype = hasProto;
     I.Fun.isVariadic   = isVariadic;
-    I.Fun.isEmpty      = isEmpty;
+    I.Fun.NumArgs      = NumArgs;
+    I.Fun.ArgInfo      = ArgInfo;
     return I;
   }
 };
@@ -350,15 +372,26 @@
   Declarator(const DeclSpec &ds, TheContext C)
     : DS(ds), Identifier(0), Context(C) {
   }
+  
+  ~Declarator() {
+    clear();
+  }
 
   /// getDeclSpec - Return the declaration-specifier that this declarator was
   /// declared with.
   const DeclSpec &getDeclSpec() const { return DS; }
   
+  TheContext getContext() const { return Context; }
+  
   /// clear - Reset the contents of this Declarator.
   void clear() {
     Identifier = 0;
     IdentifierLoc = SourceLocation();
+    
+    for (unsigned i = 0, e = DeclTypeInfo.size(); i != e; ++i)
+      if (DeclTypeInfo[i].Kind == DeclaratorTypeInfo::Function)
+        delete [] DeclTypeInfo[i].Fun.ArgInfo;
+        
     DeclTypeInfo.clear();
   }
   





More information about the cfe-commits mailing list