[cfe-commits] r39192 - in /cfe/cfe/trunk: AST/Decl.cpp AST/Sema.h AST/SemaExpr.cpp Parse/ParseExpr.cpp Sema/Sema.h Sema/SemaExpr.cpp include/clang/AST/Decl.h include/clang/Basic/DiagnosticKinds.def include/clang/Parse/Action.h

sabre at cs.uiuc.edu sabre at cs.uiuc.edu
Wed Jul 11 09:40:53 PDT 2007


Author: sabre
Date: Wed Jul 11 11:40:53 2007
New Revision: 39192

URL: http://llvm.org/viewvc/llvm-project?rev=39192&view=rev
Log:
parse identifier expressions properly.  This allows us diagnose this:

typedef int X;

int A() {
  return X;
}

int B() {
  return Y;
}

as:

/Users/sabre/test.c:5:10: error: unexpected type name 'X': expected expression
return X;
       ^
/Users/sabre/test.c:9:10: error: use of undeclared 'Y' value
return Y;
       ^

Modified:
    cfe/cfe/trunk/AST/Decl.cpp
    cfe/cfe/trunk/AST/Sema.h
    cfe/cfe/trunk/AST/SemaExpr.cpp
    cfe/cfe/trunk/Parse/ParseExpr.cpp
    cfe/cfe/trunk/Sema/Sema.h
    cfe/cfe/trunk/Sema/SemaExpr.cpp
    cfe/cfe/trunk/include/clang/AST/Decl.h
    cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
    cfe/cfe/trunk/include/clang/Parse/Action.h

Modified: cfe/cfe/trunk/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/Decl.cpp?rev=39192&r1=39191&r2=39192&view=diff

==============================================================================
--- cfe/cfe/trunk/AST/Decl.cpp (original)
+++ cfe/cfe/trunk/AST/Decl.cpp Wed Jul 11 11:40:53 2007
@@ -12,9 +12,14 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/AST/Decl.h"
+#include "clang/Lex/IdentifierTable.h"
 using namespace llvm;
 using namespace clang;
 
 // Out-of-line virtual method providing a home for Decl.
 Decl::~Decl() {
 }
+
+const char *Decl::getName() const {
+  return getIdentifier()->getName();
+}

Modified: cfe/cfe/trunk/AST/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/Sema.h?rev=39192&r1=39191&r2=39192&view=diff

==============================================================================
--- cfe/cfe/trunk/AST/Sema.h (original)
+++ cfe/cfe/trunk/AST/Sema.h Wed Jul 11 11:40:53 2007
@@ -113,6 +113,8 @@
   // Expression Parsing Callbacks: SemaExpr.cpp.
 
   // Primary Expressions.
+  virtual ExprResult ParseIdentifierExpr(SourceLocation Loc,
+                                         IdentifierInfo &II);
   virtual ExprResult ParseSimplePrimaryExpr(SourceLocation Loc,
                                             tok::TokenKind Kind);
   virtual ExprResult ParseIntegerConstant(SourceLocation Loc);

Modified: cfe/cfe/trunk/AST/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/SemaExpr.cpp?rev=39192&r1=39191&r2=39192&view=diff

==============================================================================
--- cfe/cfe/trunk/AST/SemaExpr.cpp (original)
+++ cfe/cfe/trunk/AST/SemaExpr.cpp Wed Jul 11 11:40:53 2007
@@ -13,6 +13,7 @@
 
 #include "Sema.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
 #include "clang/AST/Expr.h"
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Basic/Diagnostic.h"
@@ -238,31 +239,42 @@
 }
 
 
+Sema::ExprResult Sema::ParseIdentifierExpr(SourceLocation Loc,
+                                           IdentifierInfo &II) {
+  // Could be enum-constant or decl.
+  Decl *D = II.getFETokenInfo<Decl>();
+  if (D == 0) {
+    Diag(Loc, diag::err_undeclared_var_use, II.getName());
+    return true;
+  }
+  
+  if (isa<TypeDecl>(D)) {
+    Diag(Loc, diag::err_unexpected_typedef, II.getName());
+    return true;
+  }
+    
+    
+  return new DeclRefExpr(*(Decl*)0);
+}
 
-Action::ExprResult Sema::ParseSimplePrimaryExpr(SourceLocation Loc,
-                                                tok::TokenKind Kind) {
+Sema::ExprResult Sema::ParseSimplePrimaryExpr(SourceLocation Loc,
+                                              tok::TokenKind Kind) {
   switch (Kind) {
   default:
     assert(0 && "Unknown simple primary expr!");
-  case tok::identifier: {
-    // Could be enum-constant or decl.
-    //Tok.getIdentifierInfo()
-    return new DeclRefExpr(*(Decl*)0);
-  }
-    
   case tok::char_constant:     // constant: character-constant
+    // TODO: MOVE this to be some other callback.
   case tok::kw___func__:       // primary-expression: __func__ [C99 6.4.2.2]
   case tok::kw___FUNCTION__:   // primary-expression: __FUNCTION__ [GNU]
   case tok::kw___PRETTY_FUNCTION__:  // primary-expression: __P..Y_F..N__ [GNU]
-    //assert(0 && "FIXME: Unimp so far!");
-    return new DeclRefExpr(*(Decl*)0);
+    return 0;
   }
 }
 
-Action::ExprResult Sema::ParseIntegerConstant(SourceLocation Loc) {
+Sema::ExprResult Sema::ParseIntegerConstant(SourceLocation Loc) {
   return new IntegerConstant();
 }
-Action::ExprResult Sema::ParseFloatingConstant(SourceLocation Loc) {
+Sema::ExprResult Sema::ParseFloatingConstant(SourceLocation Loc) {
   return new FloatingConstant();
 }
 

Modified: cfe/cfe/trunk/Parse/ParseExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Parse/ParseExpr.cpp?rev=39192&r1=39191&r2=39192&view=diff

==============================================================================
--- cfe/cfe/trunk/Parse/ParseExpr.cpp (original)
+++ cfe/cfe/trunk/Parse/ParseExpr.cpp Wed Jul 11 11:40:53 2007
@@ -201,8 +201,8 @@
   //   primary-expression: identifier
   
   // Let the actions module handle the identifier.
-  ExprResult Res = Actions.ParseSimplePrimaryExpr(Tok.getLocation(),
-                                                  Tok.getKind());
+  ExprResult Res = Actions.ParseIdentifierExpr(Tok.getLocation(),
+                                               *Tok.getIdentifierInfo());
   
   // Because we have to parse an entire cast-expression before starting the
   // ParseRHSOfBinaryExpression method (which parses any trailing binops), we
@@ -231,8 +231,8 @@
   //   primary-expression: identifier
   
   // Let the actions module handle the identifier.
-  ExprResult Res = Actions.ParseSimplePrimaryExpr(Tok.getLocation(),
-                                                  Tok.getKind());
+  ExprResult Res = Actions.ParseIdentifierExpr(Tok.getLocation(),
+                                               *Tok.getIdentifierInfo());
   
   // Because we have to parse an entire cast-expression before starting the
   // ParseRHSOfBinaryExpression method (which parses any trailing binops), we
@@ -481,6 +481,11 @@
 
   case tok::identifier:        // primary-expression: identifier
                                // constant: enumeration-constant
+    Res = Actions.ParseIdentifierExpr(Tok.getLocation(),
+                                      *Tok.getIdentifierInfo());
+    ConsumeToken();
+    // These can be followed by postfix-expr pieces.
+    return ParsePostfixExpressionSuffix(Res);
   case tok::char_constant:     // constant: character-constant
   case tok::kw___func__:       // primary-expression: __func__ [C99 6.4.2.2]
   case tok::kw___FUNCTION__:   // primary-expression: __FUNCTION__ [GNU]

Modified: cfe/cfe/trunk/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/Sema.h?rev=39192&r1=39191&r2=39192&view=diff

==============================================================================
--- cfe/cfe/trunk/Sema/Sema.h (original)
+++ cfe/cfe/trunk/Sema/Sema.h Wed Jul 11 11:40:53 2007
@@ -113,6 +113,8 @@
   // Expression Parsing Callbacks: SemaExpr.cpp.
 
   // Primary Expressions.
+  virtual ExprResult ParseIdentifierExpr(SourceLocation Loc,
+                                         IdentifierInfo &II);
   virtual ExprResult ParseSimplePrimaryExpr(SourceLocation Loc,
                                             tok::TokenKind Kind);
   virtual ExprResult ParseIntegerConstant(SourceLocation Loc);

Modified: cfe/cfe/trunk/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/SemaExpr.cpp?rev=39192&r1=39191&r2=39192&view=diff

==============================================================================
--- cfe/cfe/trunk/Sema/SemaExpr.cpp (original)
+++ cfe/cfe/trunk/Sema/SemaExpr.cpp Wed Jul 11 11:40:53 2007
@@ -13,6 +13,7 @@
 
 #include "Sema.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
 #include "clang/AST/Expr.h"
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Basic/Diagnostic.h"
@@ -238,31 +239,42 @@
 }
 
 
+Sema::ExprResult Sema::ParseIdentifierExpr(SourceLocation Loc,
+                                           IdentifierInfo &II) {
+  // Could be enum-constant or decl.
+  Decl *D = II.getFETokenInfo<Decl>();
+  if (D == 0) {
+    Diag(Loc, diag::err_undeclared_var_use, II.getName());
+    return true;
+  }
+  
+  if (isa<TypeDecl>(D)) {
+    Diag(Loc, diag::err_unexpected_typedef, II.getName());
+    return true;
+  }
+    
+    
+  return new DeclRefExpr(*(Decl*)0);
+}
 
-Action::ExprResult Sema::ParseSimplePrimaryExpr(SourceLocation Loc,
-                                                tok::TokenKind Kind) {
+Sema::ExprResult Sema::ParseSimplePrimaryExpr(SourceLocation Loc,
+                                              tok::TokenKind Kind) {
   switch (Kind) {
   default:
     assert(0 && "Unknown simple primary expr!");
-  case tok::identifier: {
-    // Could be enum-constant or decl.
-    //Tok.getIdentifierInfo()
-    return new DeclRefExpr(*(Decl*)0);
-  }
-    
   case tok::char_constant:     // constant: character-constant
+    // TODO: MOVE this to be some other callback.
   case tok::kw___func__:       // primary-expression: __func__ [C99 6.4.2.2]
   case tok::kw___FUNCTION__:   // primary-expression: __FUNCTION__ [GNU]
   case tok::kw___PRETTY_FUNCTION__:  // primary-expression: __P..Y_F..N__ [GNU]
-    //assert(0 && "FIXME: Unimp so far!");
-    return new DeclRefExpr(*(Decl*)0);
+    return 0;
   }
 }
 
-Action::ExprResult Sema::ParseIntegerConstant(SourceLocation Loc) {
+Sema::ExprResult Sema::ParseIntegerConstant(SourceLocation Loc) {
   return new IntegerConstant();
 }
-Action::ExprResult Sema::ParseFloatingConstant(SourceLocation Loc) {
+Sema::ExprResult Sema::ParseFloatingConstant(SourceLocation Loc) {
   return new FloatingConstant();
 }
 

Modified: cfe/cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/AST/Decl.h?rev=39192&r1=39191&r2=39192&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/cfe/trunk/include/clang/AST/Decl.h Wed Jul 11 11:40:53 2007
@@ -52,7 +52,8 @@
   virtual ~Decl();
   
   const IdentifierInfo *getIdentifier() const { return Identifier; }
-
+  const char *getName() const;
+  
   TypeRef getType() const { return DeclType; }
   Kind getKind() const { return DeclKind; }
   Decl *getNext() const { return Next; }
@@ -84,14 +85,41 @@
   static bool classof(const TypedefDecl *D) { return true; }
 };
 
+/// ObjectDecl - ObjectDecl - Represents a declaration of a value.
+class ObjectDecl : public Decl {
+protected:
+  ObjectDecl(Kind DK, IdentifierInfo *Id, TypeRef T, Decl *Next)
+    : Decl(DK, Id, T, Next) {}
+public:
+  
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) {
+    return D->getKind() == Variable || D->getKind() == Function;
+  }
+  static bool classof(const ObjectDecl *D) { return true; }
+};
+
+/// VarDecl - An instance of this class is created to represent a variable
+/// declaration or definition.
+class VarDecl : public ObjectDecl {
+  // TODO: Initializer.
+public:
+  VarDecl(IdentifierInfo *Id, TypeRef T, Decl *Next)
+    : ObjectDecl(Variable, Id, T, Next) {}
+  
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return D->getKind() == Variable; }
+  static bool classof(const VarDecl *D) { return true; }
+};
+
 /// FunctionDecl - An instance of this class is created to represent a function
 /// declaration or definition.
-class FunctionDecl : public Decl {
+class FunctionDecl : public ObjectDecl {
   // Args etc.
   Stmt *Body;  // Null if a prototype.
 public:
   FunctionDecl(IdentifierInfo *Id, TypeRef T, Decl *Next)
-    : Decl(Function, Id, T, Next), Body(0) {}
+  : ObjectDecl(Function, Id, T, Next), Body(0) {}
   
   Stmt *getBody() const { return Body; }
   void setBody(Stmt *B) { Body = B; }
@@ -102,19 +130,6 @@
   static bool classof(const FunctionDecl *D) { return true; }
 };
 
-/// VarDecl - An instance of this class is created to represent a variable
-/// declaration or definition.
-class VarDecl : public Decl {
-  // Initializer.
-public:
-  VarDecl(IdentifierInfo *Id, TypeRef T, Decl *Next)
-    : Decl(Variable, Id, T, Next) {}
-  
-  
-  // Implement isa/cast/dyncast/etc.
-  static bool classof(const Decl *D) { return D->getKind() == Variable; }
-  static bool classof(const VarDecl *D) { return true; }
-};
   
 }  // end namespace clang
 }  // end namespace llvm

Modified: cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=39192&r1=39191&r2=39192&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def Wed Jul 11 11:40:53 2007
@@ -389,6 +389,11 @@
 DIAG(err_unspecified_vla_size_with_static, ERROR,
      "'static' may not be used with an unspecified variable length array size")
 
+DIAG(err_unexpected_typedef, ERROR,
+     "unexpected type name '%s': expected expression")
+DIAG(err_undeclared_var_use, ERROR,
+     "use of undeclared '%s' value")
+
 DIAG(err_continue_not_in_loop, ERROR,
      "'continue' statement not in loop statement")
 DIAG(err_break_not_in_loop_or_switch, ERROR,

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

==============================================================================
--- cfe/cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/cfe/trunk/include/clang/Parse/Action.h Wed Jul 11 11:40:53 2007
@@ -211,6 +211,11 @@
   //===--------------------------------------------------------------------===//
   
   // Primary Expressions.
+  virtual ExprResult ParseIdentifierExpr(SourceLocation Loc,
+                                         IdentifierInfo &II) {
+    return 0;
+  }
+  
   virtual ExprResult ParseSimplePrimaryExpr(SourceLocation Loc,
                                             tok::TokenKind Kind) {
     return 0;





More information about the cfe-commits mailing list