Index: src/fortranscanner.l
===================================================================
--- src/fortranscanner.l	(revision 751)
+++ src/fortranscanner.l	(working copy)
@@ -87,6 +87,8 @@
   bool pointer;
   bool target;
   bool save;
+  bool deferred;
+  bool nonoverridable;
   bool nopass;
   bool pass;
   QCString passVar;
@@ -94,7 +96,7 @@
   SymbolModifiers() : type(), returnName(), protection(NONE_P), direction(NONE_D),
     optional(FALSE), dimension(), allocatable(FALSE),
     external(FALSE), intrinsic(FALSE), parameter(FALSE),
-    pointer(FALSE), target(FALSE), save(FALSE),
+    pointer(FALSE), target(FALSE), save(FALSE), deferred(FALSE), nonoverridable(FALSE),
     nopass(FALSE), pass(FALSE), passVar() {}
 
   SymbolModifiers& operator|=(const SymbolModifiers &mdfs);
@@ -195,6 +197,7 @@
 static void pushBuffer(QCString &buffer);
 static void popBuffer();
 static void extractPrefix(QCString& text);
+static QCString extractFromParens(const QCString name);
 
 //-----------------------------------------------------------------------------
 #undef	YY_INPUT
@@ -226,10 +229,10 @@
 NUM_TYPE  (complex|integer|logical|real)
 KIND      {ARGS}
 CHAR      (CHARACTER{ARGS}?|CHARACTER{BS}"*"({BS}[0-9]+|{ARGS}))
-TYPE_SPEC (({NUM_TYPE}({BS}"*"{BS}[0-9]+)?)|({NUM_TYPE}{KIND})|DOUBLE{BS_}PRECISION|{CHAR}|TYPE{ARGS}|PROCEDURE{ARGS})
+TYPE_SPEC (({NUM_TYPE}({BS}"*"{BS}[0-9]+)?)|({NUM_TYPE}{KIND})|DOUBLE{BS_}PRECISION|{CHAR}|TYPE{ARGS}|CLASS{ARGS}|PROCEDURE{ARGS}?)
 
 INTENT_SPEC intent{BS}"("{BS}(in|out|in{BS}out){BS}")"
-ATTR_SPEC (ALLOCATABLE|DIMENSION{ARGS}|EXTERNAL|{INTENT_SPEC}|INTRINSIC|OPTIONAL|PARAMETER|POINTER|PRIVATE|PUBLIC|SAVE|TARGET|NOPASS|PASS{ARGS})
+ATTR_SPEC (ALLOCATABLE|DIMENSION{ARGS}|EXTERNAL|{INTENT_SPEC}|INTRINSIC|OPTIONAL|PARAMETER|POINTER|PRIVATE|PUBLIC|SAVE|TARGET|NOPASS|PASS{ARGS}?|DEFERRED|NON_OVERRIDABLE)
 ACCESS_SPEC (PRIVATE|PUBLIC)
 LANGUAGE_BIND_SPEC BIND{BS}"("{BS}C{BS}(,{BS}NAME{BS}"="{BS}"\""(.*)"\""{BS})?")"
 /* Assume that attribute statements are almost the same as attributes. */
@@ -263,6 +266,7 @@
 %x      ArrayInitializer
 %x      Typedef
 %x      TypedefBody
+%x      TypedefBodyContains
 %x      InterfaceBody
 %x      StrIgnore
 %x      String
@@ -373,7 +377,7 @@
 
  /*------ use handling ------------------------------------------------------------*/
 
-<Start,ModuleBody,TypedefBody,SubprogBody>"use"{BS_} {
+<Start,ModuleBody,SubprogBody>"use"{BS_} {
                                           if(YY_START == Start)
                                           {
                                             addModule(NULL); 
@@ -424,7 +428,7 @@
                                           // interface body is a scope of its own
                                         }
 
-^{BS}interface{BS_}{ID}                 { ifType = IF_GENERIC;
+^{BS}interface{BS_}{ID}{ARGS}?          { ifType = IF_GENERIC;
                                           yy_push_state(InterfaceBody);
 
                                           // extract generic name
@@ -473,6 +477,7 @@
                                         }
 <ModuleBody>^{BS}{CONTAINS}/({BS}|\n|!)   { BEGIN(ModuleBodyContains); }
 <SubprogBody>^{BS}{CONTAINS}/({BS}|\n|!)  { BEGIN(SubprogBodyContains); }
+<TypedefBody>^{BS}{CONTAINS}/({BS}|\n|!)  { BEGIN(TypedefBodyContains); }
 
  /*------ module handling ------------------------------------------------------------*/ 
 <Start>module|program{BS_}             {  //
@@ -506,49 +511,104 @@
 
  /*------- type definition  -------------------------------------------------------------------------------*/
 
-<Start,ModuleBody>"type"({BS_}|({COMMA}{ACCESS_SPEC}|{COMMA}{LANGUAGE_BIND_SPEC})) {
+<Start,ModuleBody>^{BS}type             {
                                           if(YY_START == Start)
                                           {
                                             addModule(NULL); 
                                             yy_push_state(ModuleBody); //anon program
                                           }
 
- 					    yy_push_state(Typedef);
-					    current->protection = defaultProtection;
+                                          yy_push_state(Typedef);
+                                          current->protection = defaultProtection;
                                         }
-<Typedef>{ACCESS_SPEC}          	{ 	
-                                            QCString type= yytext;				    
+<Typedef>{
+{COMMA}                                 {}
+
+{BS}"::"{BS}                            {}
+
+abstract                                {
+                                          current->spec |= Entry::AbstractClass;
                                         }
-<Typedef>{LANGUAGE_BIND_SPEC}           {
-                                            /* ignored for now */
+extends{ARGS}                           {
+                                          QCString basename = extractFromParens(yytext);
+                                          current->extends->append(new BaseInfo(basename, Public, Normal));
                                         }
-<Typedef>{ID}                        	{ /* type name found */
-                                            //cout << "=========> got typedef " << yytext << ": " << yyLineNr << endl; 
-                                            current->section = Entry::CLASS_SEC; // was Entry::STRUCT_SEC;
-   					    current->spec = Entry::Struct;        	
-  					    current->name = yytext;
+public                                  {
+                                          current->protection = Public;
+                                        }
+private                                 {
+                                          current->protection = Private;
+                                        }
+{LANGUAGE_BIND_SPEC}                    {
+                                          /* ignored for now */
+                                        }
+{ID}                                    { /* type name found */
+                                          current->section = Entry::CLASS_SEC;
+                                          current->spec |= Entry::Struct;
+                                          current->name = yytext;
+                                          current->fileName = yyFileName;
+                                          current->bodyLine  = yyLineNr; 
 
-                                            /* if type is part of a module, mod name is necessary for output */
-                                            if ((current_root) && 
-                                               (current_root->section ==  Entry::CLASS_SEC ||
-					        current_root->section ==  Entry::NAMESPACE_SEC))
-						//current_root->section ==  Entry::INTERFACE_SEC)) 
-					    {
-                                              current->name= current_root->name+"::"+current->name;
-                                            }
-					    current->fileName = yyFileName;
-					    current->bodyLine  = yyLineNr; 
-                                            addCurrentEntry();
-					    startScope(last_entry); 
-                                            BEGIN(TypedefBody);
+                                          /* if type is part of a module, mod name is necessary for output */
+                                          if ((current_root) && 
+                                              (current_root->section == Entry::CLASS_SEC
+                                               || current_root->section == Entry::NAMESPACE_SEC))
+                                          {
+                                            current->name = current_root->name + "::" + current->name;
+                                          }
+
+                                          addCurrentEntry();
+                                          startScope(last_entry); 
+                                          BEGIN(TypedefBody);
                                         }
-<TypedefBody>^{BS}"end"{BS}"type"({BS_}{ID})?{BS}/(\n|!)         { /* end type definition */
-                                           //printf("=========> got typedef end \n"); 
-					   if (!endScope(current_root))
-					     yyterminate();
-                                           yy_pop_state();
-                                        } 
+}
 
+<TypedefBodyContains>{                  /* Type Bound Procedures */
+^{BS}PROCEDURE{ARGS}?                   {
+                                          current->type = QCString(yytext).simplifyWhiteSpace();
+                                        }
+^{BS}final                              {
+                                          current->spec |= Entry::Final;
+                                          current->type = QCString(yytext).simplifyWhiteSpace();
+                                        }
+^{BS}generic                            {
+                                          current->type = QCString(yytext).simplifyWhiteSpace();
+                                        }
+{COMMA}                                 {
+                                        }
+{ATTR_SPEC}                             {
+                                          currentModifiers |= QCString(yytext);
+                                        }
+{BS}"::"{BS}                            {
+                                        }
+{ID}                                    {
+                                          QCString name = yytext;
+                                          modifiers[current_root][name.lower()] |= currentModifiers;
+                                          current->section  = Entry::FUNCTION_SEC;
+                                          current->name     = name;
+                                          current->fileName = yyFileName;
+                                          current->bodyLine = yyLineNr;
+                                          addCurrentEntry();
+                                        }
+{BS}"=>"[^(\n|\!)]*                     { /* Specific bindings come after the ID. */
+                                          last_entry->args = yytext;
+                                        }
+"\n"                                    {
+                                          currentModifiers = SymbolModifiers();
+                                          yyLineNr++; yyLineNr+=lineCountPrepass; lineCountPrepass=0;
+                                          docBlock.resize(0);
+                                        }
+}
+
+
+<TypedefBody,TypedefBodyContains>{
+^{BS}"end"{BS}"type"({BS_}{ID})?{BS}/(\n|!) { /* end type definition */
+                                          if (!endScope(current_root))
+                                            yyterminate();
+                                          yy_pop_state();
+                                        }
+}
+
  /*------- module/global/typedef variable ---------------------------------------------------*/
 
 <SubprogBody,SubprogBodyContains>^{BS}[0-9]*{BS}"end"({BS}{SUBPROG}({BS_}{ID})?)?{BS}/(\n|!) {  
@@ -563,19 +623,16 @@
 					   if (!endScope(current_root))
 					     yyterminate();
 					   yy_pop_state() ;
-				       } 
+				        }
 <Start,ModuleBody,TypedefBody,SubprogBody>{
-^{BS}{TYPE_SPEC}/{SEPARATE}			{
+^{BS}{TYPE_SPEC}/{SEPARATE}             {
                                           /* variable declaration starts */
                                           if(YY_START == Start)
                                           {
                                             addModule(NULL); 
                                             yy_push_state(ModuleBody); //anon program
                                           }
-                                          //fprintf(stderr,"4=========> got variable type: %s\n",yytext);
- 					  QCString help=yytext;
-					  help= help.simplifyWhiteSpace();
-					  argType= help;
+					  argType = QCString(yytext).simplifyWhiteSpace();
 					  yy_push_state(AttributeList);
                                         }
 ^{BS}{PP_ID}{KIND}?			{ /* check for preprocessor symbol expand to type */
@@ -721,7 +778,7 @@
 <Start,ModuleBody,SubprogBody,InterfaceBody,ModuleBodyContains,SubprogBodyContains>^{BS}({PREFIX}{BS_})?{TYPE_SPEC}{BS}/{SUBPROG}{BS_} {
                                          if (ifType == IF_ABSTRACT || ifType == IF_SPECIFIC)
                                          {
-                                           addInterface(yytext, ifType);
+                                           addInterface("$interface$", ifType);
                                            startScope(last_entry);
                                          }
 
@@ -823,7 +880,7 @@
                                           yy_pop_state();
  					 }
    
-<Start,SubprogBody,ModuleBody,TypedefBody,InterfaceBody,ModuleBodyContains,SubprogBodyContains>"!>"  {
+<Start,SubprogBody,ModuleBody,TypedefBody,InterfaceBody,ModuleBodyContains,SubprogBodyContains,TypedefBodyContains>"!>"  {
                                           yy_push_state(YY_START);
 					  current->docLine  = yyLineNr;
  					  docBlockJavaStyle = FALSE;
@@ -1208,6 +1265,8 @@
   pointer |= mdfs.pointer;
   target |= mdfs.target;
   save |= mdfs.save;
+  deferred |= mdfs.deferred;
+  nonoverridable |= mdfs.nonoverridable;
   nopass |= mdfs.nopass;
   pass |= mdfs.pass;
   passVar = mdfs.passVar;
@@ -1277,10 +1336,21 @@
   {
     newMdf.nopass = TRUE;
   }
+  else if (mdfString=="deferred")
+  {
+    newMdf.deferred = TRUE;
+  }
+  else if (mdfString=="non_overridable")
+  {
+    newMdf.nonoverridable = TRUE;
+  }
   else if (mdfString.contains("pass"))
   {
     newMdf.pass = TRUE;
-    newMdf.passVar = extractFromParens(mdfString);
+    if (mdfString.contains("("))
+      newMdf.passVar = extractFromParens(mdfString);
+    else
+      newMdf.passVar = "";
   }
 
   (*this) |= newMdf;
@@ -1388,6 +1458,16 @@
     typeName += ",";
     typeName += "save";
   }
+  if (mdfs.deferred) 
+  {
+    typeName += ",";
+    typeName += "deferred";
+  }
+  if (mdfs.nonoverridable) 
+  {
+    typeName += ",";
+    typeName += "non_overridable";
+  }
   if (mdfs.nopass) 
   {
     typeName += ",";
@@ -1396,7 +1476,9 @@
   if (mdfs.pass) 
   {
     typeName += ",";
-    typeName += "pass(" + mdfs.passVar + ")";
+    typeName += "pass";
+    if (!mdfs.passVar.isEmpty())
+      typeName += "(" + mdfs.passVar + ")";
   }
   if (mdfs.protection == SymbolModifiers::PUBLIC)
   {
