[cfe-commits] r39327 - in /cfe/cfe/trunk: AST/ASTContext.cpp AST/Builtins.cpp AST/Sema.h AST/SemaDecl.cpp AST/SemaExpr.cpp Lex/IdentifierTable.cpp Sema/Sema.h Sema/SemaDecl.cpp Sema/SemaExpr.cpp clang.xcodeproj/project.pbxproj include/clang/AST/Builtins.def include/clang/AST/Builtins.h include/clang/Basic/DiagnosticKinds.def include/clang/Lex/IdentifierTable.h

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


Author: sabre
Date: Wed Jul 11 11:43:08 2007
New Revision: 39327

URL: http://llvm.org/viewvc/llvm-project?rev=39327&view=rev
Log:
Add support for target-independent builtin functions (like __builtin_abs),
whose decl objects are lazily created the first time they are referenced.
Builtin functions are described by the clang/AST/Builtins.def file, which
makes it easy to add new ones.

This is missing two important pieces:
1. Support for the rest of the gcc builtins.
2. Support for target-specific builtins (e.g. __builtin_ia32_emms).

Just adding this builtins reduces the number of implicit function definitions
by 6, reducing the # diagnostics from 550 to 544 when parsing carbon.h.

I need to add all the i386-specific ones to eliminate several hundred more.
ugh.

Added:
    cfe/cfe/trunk/AST/Builtins.cpp   (with props)
    cfe/cfe/trunk/include/clang/AST/Builtins.def   (with props)
    cfe/cfe/trunk/include/clang/AST/Builtins.h   (with props)
Modified:
    cfe/cfe/trunk/AST/ASTContext.cpp
    cfe/cfe/trunk/AST/Sema.h
    cfe/cfe/trunk/AST/SemaDecl.cpp
    cfe/cfe/trunk/AST/SemaExpr.cpp
    cfe/cfe/trunk/Lex/IdentifierTable.cpp
    cfe/cfe/trunk/Sema/Sema.h
    cfe/cfe/trunk/Sema/SemaDecl.cpp
    cfe/cfe/trunk/Sema/SemaExpr.cpp
    cfe/cfe/trunk/clang.xcodeproj/project.pbxproj
    cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
    cfe/cfe/trunk/include/clang/Lex/IdentifierTable.h

Modified: cfe/cfe/trunk/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/ASTContext.cpp?rev=39327&r1=39326&r2=39327&view=diff

==============================================================================
--- cfe/cfe/trunk/AST/ASTContext.cpp (original)
+++ cfe/cfe/trunk/AST/ASTContext.cpp Wed Jul 11 11:43:08 2007
@@ -12,6 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/Builtins.h"
 #include "clang/AST/Decl.h"
 #include "clang/Lex/Preprocessor.h"
 #include "llvm/ADT/SmallVector.h"
@@ -21,6 +22,7 @@
 ASTContext::ASTContext(Preprocessor &pp)
   : PP(pp), Target(pp.getTargetInfo()) {
   InitBuiltinTypes();
+  Builtin::InitializeBuiltins(PP.getIdentifierTable(), Target);
 }
 
 ASTContext::~ASTContext() {

Added: cfe/cfe/trunk/AST/Builtins.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/Builtins.cpp?rev=39327&view=auto

==============================================================================
--- cfe/cfe/trunk/AST/Builtins.cpp (added)
+++ cfe/cfe/trunk/AST/Builtins.cpp Wed Jul 11 11:43:08 2007
@@ -0,0 +1,112 @@
+//===--- Builtins.cpp - Builtin function implementation -------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements various things for builtin functions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/Builtins.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/Lex/IdentifierTable.h"
+using namespace llvm;
+using namespace clang;
+
+static const Builtin::Info BuiltinInfo[] = {
+  { "not a builtin function", 0, 0 },
+#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS },
+#include "clang/AST/Builtins.def"
+};
+
+/// Builtin::GetName - Return the identifier name for the specified builtin,
+/// e.g. "__builtin_abs".
+const char *Builtin::GetName(ID id) {
+  if (id >= Builtin::FirstTargetSpecificBuiltin)
+    return "target-builtin";
+  return BuiltinInfo[id].Name;
+}
+
+
+/// InitializeBuiltins - Mark the identifiers for all the builtins with their
+/// appropriate builtin ID # and mark any non-portable builtin identifiers as
+/// such.
+void Builtin::InitializeBuiltins(IdentifierTable &Table,
+                                 const TargetInfo &Target) {
+  // Step #1: mark all target-independent builtins with their ID's.
+  for (unsigned i = Builtin::NotBuiltin+1;
+       i != Builtin::FirstTargetSpecificBuiltin; ++i)
+    Table.get(BuiltinInfo[i].Name).setBuiltinID(i);
+  
+  // Step #2: handle target builtins.
+  // FIXME: implement.
+}
+
+/// DecodeTypeFromStr - This decodes one type descriptor from Str, advancing the
+/// pointer over the consumed characters.  This returns the resultant type.
+static TypeRef DecodeTypeFromStr(const char *&Str, ASTContext &Context) {
+  // Modifiers.
+  bool Long = false, LongLong = false, Signed = false, Unsigned = false;
+  
+  // Read the modifiers first.
+  bool Done = false;
+  while (!Done) {
+    switch (*Str++) {
+    default: Done = true; --Str; break; 
+    case 'S':
+      assert(!Unsigned && "Can't use both 'S' and 'U' modifiers!");
+      assert(!Signed && "Can't use 'S' modifier multiple times!");
+      Signed = true;
+      break;
+    case 'U':
+      assert(!Signed && "Can't use both 'S' and 'U' modifiers!");
+      assert(!Unsigned && "Can't use 'S' modifier multiple times!");
+      Unsigned = true;
+      break;
+    case 'L':
+      assert(!LongLong && "Can't have LLL modifier");
+      if (Long) 
+        LongLong = true;
+      else
+        Long = true;
+      break;
+    }
+  }
+
+  // Read the base type.
+  switch (*Str++) {
+  default: assert(0 && "Unknown builtin type letter!");
+  case 'f':
+    assert(!Long && !Signed && !Unsigned && "Bad modifiers used with 'f'!");
+    return Context.FloatTy;
+  case 'd':
+    assert(!LongLong && !Signed && !Unsigned && "Bad modifiers used with 'd'!");
+    if (Long)
+      return Context.LongDoubleTy;
+    return Context.DoubleTy;
+  //case 'i':
+  }
+}
+
+/// GetBuiltinType - Return the type for the specified builtin.
+TypeRef Builtin::GetBuiltinType(ID id, ASTContext &Context) {
+  assert(id < Builtin::FirstTargetSpecificBuiltin &&
+         "Can't handle target builtins yet!");
+  const char *TypeStr = BuiltinInfo[id].Type;
+  
+  SmallVector<TypeRef, 8> ArgTypes;
+  
+  TypeRef ResType = DecodeTypeFromStr(TypeStr, Context);
+  while (TypeStr[0] && TypeStr[0] != '.')
+    ArgTypes.push_back(DecodeTypeFromStr(TypeStr, Context));
+  
+  assert((TypeStr[0] != '.' || TypeStr[1] == 0) &&
+         "'.' should only occur at end of builtin type list!");
+  
+  return Context.getFunctionType(ResType, &ArgTypes[0], ArgTypes.size(),
+                                 TypeStr[0] == '.');
+}

Propchange: cfe/cfe/trunk/AST/Builtins.cpp

------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cfe/cfe/trunk/AST/Builtins.cpp

------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

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

==============================================================================
--- cfe/cfe/trunk/AST/Sema.h (original)
+++ cfe/cfe/trunk/AST/Sema.h Wed Jul 11 11:43:08 2007
@@ -74,7 +74,10 @@
   virtual DeclTy *ParseStartOfFunctionDef(Scope *S, Declarator &D);
   virtual DeclTy *ParseFunctionDefBody(DeclTy *Decl, StmtTy *Body);
   virtual void PopScope(SourceLocation Loc, Scope *S);
-  Decl *LookupScopedDecl(IdentifierInfo *II, unsigned NSI);
+  Decl *LookupScopedDecl(IdentifierInfo *II, unsigned NSI, SourceLocation IdLoc,
+                         Scope *S);
+  
+  Decl *LazilyCreateBuiltin(IdentifierInfo *II, unsigned ID, Scope *S);
   
   TypedefDecl *ParseTypedefDecl(Scope *S, Declarator &D);
   TypedefDecl *MergeTypeDefDecl(TypedefDecl *New, Decl *Old);

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

==============================================================================
--- cfe/cfe/trunk/AST/SemaDecl.cpp (original)
+++ cfe/cfe/trunk/AST/SemaDecl.cpp Wed Jul 11 11:43:08 2007
@@ -13,6 +13,7 @@
 
 #include "Sema.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/Builtins.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/Type.h"
@@ -20,6 +21,7 @@
 #include "clang/Parse/Scope.h"
 #include "clang/Lex/IdentifierTable.h"
 #include "clang/Basic/LangOptions.h"
+#include "clang/Basic/TargetInfo.h"
 #include "llvm/ADT/SmallSet.h"
 using namespace llvm;
 using namespace clang;
@@ -69,7 +71,8 @@
 
 /// LookupScopedDecl - Look up the inner-most declaration in the specified
 /// namespace.
-Decl *Sema::LookupScopedDecl(IdentifierInfo *II, unsigned NSI) {
+Decl *Sema::LookupScopedDecl(IdentifierInfo *II, unsigned NSI,
+                             SourceLocation IdLoc, Scope *S) {
   if (II == 0) return 0;
   Decl::IdentifierNamespace NS = (Decl::IdentifierNamespace)NSI;
   
@@ -80,10 +83,56 @@
     if (D->getIdentifierNamespace() == NS)
       return D;
   
-    
+  // If we didn't find a use of this identifier, and if the identifier
+  // corresponds to a compiler builtin, create the decl object for the builtin
+  // now, injecting it into translation unit scope, and return it.
+  if (NS == Decl::IDNS_Ordinary) {
+    // If this is a builtin on some other target, or if this builtin varies
+    // across targets (e.g. in type), emit a diagnostic and mark the translation
+    // unit non-portable for using it.
+    if (II->isNonPortableBuiltin()) {
+      // Only emit this diagnostic once for this builtin.
+      II->setNonPortableBuiltin(false);
+      Context.Target.DiagnoseNonPortability(IdLoc,
+                                            diag::port_target_builtin_use);
+    }
+    
+    // If this is a builtin on this (or all) targets, create the decl.
+    if (unsigned BuiltinID = II->getBuiltinID())
+      return LazilyCreateBuiltin(II, BuiltinID, S);
+  }
   return 0;
 }
 
+/// LazilyCreateBuiltin - The specified Builtin-ID was first used at file scope.
+/// lazily create a decl for it.
+Decl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned bid, Scope *S) {
+  Builtin::ID BID = (Builtin::ID)bid;
+
+  TypeRef R = Builtin::GetBuiltinType(BID, Context);
+  FunctionDecl *New = new FunctionDecl(SourceLocation(), II, R);
+  
+  // Find translation-unit scope to insert this function into.
+  while (S->getParent())
+    S = S->getParent();
+  S->AddDecl(New);
+  
+  // Add this decl to the end of the identifier info.
+  if (Decl *LastDecl = II->getFETokenInfo<Decl>()) {
+    // Scan until we find the last (outermost) decl in the id chain. 
+    while (LastDecl->getNext())
+      LastDecl = LastDecl->getNext();
+    // Insert before (outside) it.
+    LastDecl->setNext(New);
+  } else {
+    II->setFETokenInfo(New);
+  }    
+  // Make sure clients iterating over decls see this.
+  LastInGroupList.push_back(New);
+  
+  return New;
+}
+
 /// MergeTypeDefDecl - We just parsed a typedef 'New' which has the same name
 /// and scope as a previous declaration 'Old'.  Figure out how to resolve this
 /// situation, merging decls or emitting diagnostics as appropriate.
@@ -174,7 +223,8 @@
   IdentifierInfo *II = D.getIdentifier();
   
   // See if this is a redefinition of a variable in the same scope.
-  Decl *PrevDecl = LookupScopedDecl(II, Decl::IDNS_Ordinary);
+  Decl *PrevDecl = LookupScopedDecl(II, Decl::IDNS_Ordinary,
+                                    D.getIdentifierLoc(), S);
   if (!S->isDeclScope(PrevDecl))
     PrevDecl = 0;   // If in outer scope, it isn't the same thing.
 
@@ -239,7 +289,8 @@
   // TODO: CHECK FOR CONFLICTS, multiple decls with same name in one scope.
   // Can this happen for params?  We already checked that they don't conflict
   // among each other.  Here they can only shadow globals, which is ok.
-  if (Decl *PrevDecl = LookupScopedDecl(II, Decl::IDNS_Ordinary)) {
+  if (Decl *PrevDecl = LookupScopedDecl(II, Decl::IDNS_Ordinary,
+                                        PI.IdentLoc, FnScope)) {
     
   }
   
@@ -382,7 +433,8 @@
   // If this is a named struct, check to see if there was a previous forward
   // declaration or definition.
   if (TagDecl *PrevDecl = 
-          dyn_cast_or_null<TagDecl>(LookupScopedDecl(Name, Decl::IDNS_Tag))) {
+          dyn_cast_or_null<TagDecl>(LookupScopedDecl(Name, Decl::IDNS_Tag,
+                                                     NameLoc, S))) {
     
     // If this is a use of a previous tag, or if the tag is already declared in
     // the same scope (so that the definition/declaration completes or
@@ -604,7 +656,7 @@
 
   // Verify that there isn't already something declared with this name in this
   // scope.
-  if (Decl *PrevDecl = LookupScopedDecl(Id, Decl::IDNS_Ordinary)) {
+  if (Decl *PrevDecl = LookupScopedDecl(Id, Decl::IDNS_Ordinary, IdLoc, S)) {
     if (S->isDeclScope(PrevDecl)) {
       if (isa<EnumConstantDecl>(PrevDecl))
         Diag(IdLoc, diag::err_redefinition_of_enumerator, Id->getName());

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

==============================================================================
--- cfe/cfe/trunk/AST/SemaExpr.cpp (original)
+++ cfe/cfe/trunk/AST/SemaExpr.cpp Wed Jul 11 11:43:08 2007
@@ -247,14 +247,10 @@
                                            IdentifierInfo &II,
                                            bool HasTrailingLParen) {
   // Could be enum-constant or decl.
-  Decl *D = II.getFETokenInfo<Decl>();
+  Decl *D = LookupScopedDecl(&II, Decl::IDNS_Ordinary, Loc, S);
   if (D == 0) {
-    // FIXME: check to see if this is a use of a builtin.  By handling builtins
-    // here, we can avoid having to preload tons of decls for functions.
-
-    
-    // Otherwise, this is an imlicitly declared function reference (legal in
-    // C90, extension in C99).
+    // Otherwise, this could be an imlicitly declared function reference (legal
+    // in C90, extension in C99).
     if (HasTrailingLParen &&
         // Not in C++.
         !getLangOptions().CPlusPlus) {

Modified: cfe/cfe/trunk/Lex/IdentifierTable.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Lex/IdentifierTable.cpp?rev=39327&r1=39326&r2=39327&view=diff

==============================================================================
--- cfe/cfe/trunk/Lex/IdentifierTable.cpp (original)
+++ cfe/cfe/trunk/Lex/IdentifierTable.cpp Wed Jul 11 11:43:08 2007
@@ -28,6 +28,7 @@
   TokenID = tok::identifier;
   PPID = tok::pp_not_keyword;
   ObjCID = tok::objc_not_keyword;
+  BuiltinID = 0;
   IsExtension = false;
   IsPoisoned = false;
   IsOtherTargetMacro = false;

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

==============================================================================
--- cfe/cfe/trunk/Sema/Sema.h (original)
+++ cfe/cfe/trunk/Sema/Sema.h Wed Jul 11 11:43:08 2007
@@ -74,7 +74,10 @@
   virtual DeclTy *ParseStartOfFunctionDef(Scope *S, Declarator &D);
   virtual DeclTy *ParseFunctionDefBody(DeclTy *Decl, StmtTy *Body);
   virtual void PopScope(SourceLocation Loc, Scope *S);
-  Decl *LookupScopedDecl(IdentifierInfo *II, unsigned NSI);
+  Decl *LookupScopedDecl(IdentifierInfo *II, unsigned NSI, SourceLocation IdLoc,
+                         Scope *S);
+  
+  Decl *LazilyCreateBuiltin(IdentifierInfo *II, unsigned ID, Scope *S);
   
   TypedefDecl *ParseTypedefDecl(Scope *S, Declarator &D);
   TypedefDecl *MergeTypeDefDecl(TypedefDecl *New, Decl *Old);

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

==============================================================================
--- cfe/cfe/trunk/Sema/SemaDecl.cpp (original)
+++ cfe/cfe/trunk/Sema/SemaDecl.cpp Wed Jul 11 11:43:08 2007
@@ -13,6 +13,7 @@
 
 #include "Sema.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/Builtins.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/Type.h"
@@ -20,6 +21,7 @@
 #include "clang/Parse/Scope.h"
 #include "clang/Lex/IdentifierTable.h"
 #include "clang/Basic/LangOptions.h"
+#include "clang/Basic/TargetInfo.h"
 #include "llvm/ADT/SmallSet.h"
 using namespace llvm;
 using namespace clang;
@@ -69,7 +71,8 @@
 
 /// LookupScopedDecl - Look up the inner-most declaration in the specified
 /// namespace.
-Decl *Sema::LookupScopedDecl(IdentifierInfo *II, unsigned NSI) {
+Decl *Sema::LookupScopedDecl(IdentifierInfo *II, unsigned NSI,
+                             SourceLocation IdLoc, Scope *S) {
   if (II == 0) return 0;
   Decl::IdentifierNamespace NS = (Decl::IdentifierNamespace)NSI;
   
@@ -80,10 +83,56 @@
     if (D->getIdentifierNamespace() == NS)
       return D;
   
-    
+  // If we didn't find a use of this identifier, and if the identifier
+  // corresponds to a compiler builtin, create the decl object for the builtin
+  // now, injecting it into translation unit scope, and return it.
+  if (NS == Decl::IDNS_Ordinary) {
+    // If this is a builtin on some other target, or if this builtin varies
+    // across targets (e.g. in type), emit a diagnostic and mark the translation
+    // unit non-portable for using it.
+    if (II->isNonPortableBuiltin()) {
+      // Only emit this diagnostic once for this builtin.
+      II->setNonPortableBuiltin(false);
+      Context.Target.DiagnoseNonPortability(IdLoc,
+                                            diag::port_target_builtin_use);
+    }
+    
+    // If this is a builtin on this (or all) targets, create the decl.
+    if (unsigned BuiltinID = II->getBuiltinID())
+      return LazilyCreateBuiltin(II, BuiltinID, S);
+  }
   return 0;
 }
 
+/// LazilyCreateBuiltin - The specified Builtin-ID was first used at file scope.
+/// lazily create a decl for it.
+Decl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned bid, Scope *S) {
+  Builtin::ID BID = (Builtin::ID)bid;
+
+  TypeRef R = Builtin::GetBuiltinType(BID, Context);
+  FunctionDecl *New = new FunctionDecl(SourceLocation(), II, R);
+  
+  // Find translation-unit scope to insert this function into.
+  while (S->getParent())
+    S = S->getParent();
+  S->AddDecl(New);
+  
+  // Add this decl to the end of the identifier info.
+  if (Decl *LastDecl = II->getFETokenInfo<Decl>()) {
+    // Scan until we find the last (outermost) decl in the id chain. 
+    while (LastDecl->getNext())
+      LastDecl = LastDecl->getNext();
+    // Insert before (outside) it.
+    LastDecl->setNext(New);
+  } else {
+    II->setFETokenInfo(New);
+  }    
+  // Make sure clients iterating over decls see this.
+  LastInGroupList.push_back(New);
+  
+  return New;
+}
+
 /// MergeTypeDefDecl - We just parsed a typedef 'New' which has the same name
 /// and scope as a previous declaration 'Old'.  Figure out how to resolve this
 /// situation, merging decls or emitting diagnostics as appropriate.
@@ -174,7 +223,8 @@
   IdentifierInfo *II = D.getIdentifier();
   
   // See if this is a redefinition of a variable in the same scope.
-  Decl *PrevDecl = LookupScopedDecl(II, Decl::IDNS_Ordinary);
+  Decl *PrevDecl = LookupScopedDecl(II, Decl::IDNS_Ordinary,
+                                    D.getIdentifierLoc(), S);
   if (!S->isDeclScope(PrevDecl))
     PrevDecl = 0;   // If in outer scope, it isn't the same thing.
 
@@ -239,7 +289,8 @@
   // TODO: CHECK FOR CONFLICTS, multiple decls with same name in one scope.
   // Can this happen for params?  We already checked that they don't conflict
   // among each other.  Here they can only shadow globals, which is ok.
-  if (Decl *PrevDecl = LookupScopedDecl(II, Decl::IDNS_Ordinary)) {
+  if (Decl *PrevDecl = LookupScopedDecl(II, Decl::IDNS_Ordinary,
+                                        PI.IdentLoc, FnScope)) {
     
   }
   
@@ -382,7 +433,8 @@
   // If this is a named struct, check to see if there was a previous forward
   // declaration or definition.
   if (TagDecl *PrevDecl = 
-          dyn_cast_or_null<TagDecl>(LookupScopedDecl(Name, Decl::IDNS_Tag))) {
+          dyn_cast_or_null<TagDecl>(LookupScopedDecl(Name, Decl::IDNS_Tag,
+                                                     NameLoc, S))) {
     
     // If this is a use of a previous tag, or if the tag is already declared in
     // the same scope (so that the definition/declaration completes or
@@ -604,7 +656,7 @@
 
   // Verify that there isn't already something declared with this name in this
   // scope.
-  if (Decl *PrevDecl = LookupScopedDecl(Id, Decl::IDNS_Ordinary)) {
+  if (Decl *PrevDecl = LookupScopedDecl(Id, Decl::IDNS_Ordinary, IdLoc, S)) {
     if (S->isDeclScope(PrevDecl)) {
       if (isa<EnumConstantDecl>(PrevDecl))
         Diag(IdLoc, diag::err_redefinition_of_enumerator, Id->getName());

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

==============================================================================
--- cfe/cfe/trunk/Sema/SemaExpr.cpp (original)
+++ cfe/cfe/trunk/Sema/SemaExpr.cpp Wed Jul 11 11:43:08 2007
@@ -247,14 +247,10 @@
                                            IdentifierInfo &II,
                                            bool HasTrailingLParen) {
   // Could be enum-constant or decl.
-  Decl *D = II.getFETokenInfo<Decl>();
+  Decl *D = LookupScopedDecl(&II, Decl::IDNS_Ordinary, Loc, S);
   if (D == 0) {
-    // FIXME: check to see if this is a use of a builtin.  By handling builtins
-    // here, we can avoid having to preload tons of decls for functions.
-
-    
-    // Otherwise, this is an imlicitly declared function reference (legal in
-    // C90, extension in C99).
+    // Otherwise, this could be an imlicitly declared function reference (legal
+    // in C90, extension in C99).
     if (HasTrailingLParen &&
         // Not in C++.
         !getLangOptions().CPlusPlus) {

Modified: cfe/cfe/trunk/clang.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/clang.xcodeproj/project.pbxproj?rev=39327&r1=39326&r2=39327&view=diff

==============================================================================
--- cfe/cfe/trunk/clang.xcodeproj/project.pbxproj (original)
+++ cfe/cfe/trunk/clang.xcodeproj/project.pbxproj Wed Jul 11 11:43:08 2007
@@ -57,6 +57,9 @@
 		DED626C90AE0C065001E80A4 /* TargetInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DED626C80AE0C065001E80A4 /* TargetInfo.cpp */; };
 		DED627030AE0C51D001E80A4 /* Targets.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DED627020AE0C51D001E80A4 /* Targets.cpp */; };
 		DED62ABB0AE2EDF1001E80A4 /* Decl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DED62ABA0AE2EDF1001E80A4 /* Decl.cpp */; };
+		DED676D10B6C786700AAD4A3 /* Builtins.def in CopyFiles */ = {isa = PBXBuildFile; fileRef = DED676D00B6C786700AAD4A3 /* Builtins.def */; };
+		DED676FA0B6C797B00AAD4A3 /* Builtins.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DED676F90B6C797B00AAD4A3 /* Builtins.h */; };
+		DED677C90B6C854100AAD4A3 /* Builtins.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DED677C80B6C854100AAD4A3 /* Builtins.cpp */; };
 		DED7D7410A524295003AD0FB /* Diagnostic.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DED7D7310A524295003AD0FB /* Diagnostic.h */; };
 		DED7D7420A524295003AD0FB /* DiagnosticKinds.def in CopyFiles */ = {isa = PBXBuildFile; fileRef = DED7D7320A524295003AD0FB /* DiagnosticKinds.def */; };
 		DED7D7430A524295003AD0FB /* FileManager.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DED7D7330A524295003AD0FB /* FileManager.h */; };
@@ -134,6 +137,8 @@
 				DE75ED290B044DC90020CF81 /* ASTContext.h in CopyFiles */,
 				DE1733700B068DC60080B521 /* DeclSpec.h in CopyFiles */,
 				DE01DA490B12ADA300AC22CE /* PPCallbacks.h in CopyFiles */,
+				DED676D10B6C786700AAD4A3 /* Builtins.def in CopyFiles */,
+				DED676FA0B6C797B00AAD4A3 /* Builtins.h in CopyFiles */,
 			);
 			runOnlyForDeploymentPostprocessing = 1;
 		};
@@ -191,6 +196,9 @@
 		DED626C80AE0C065001E80A4 /* TargetInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = TargetInfo.cpp; sourceTree = "<group>"; };
 		DED627020AE0C51D001E80A4 /* Targets.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Targets.cpp; path = Driver/Targets.cpp; sourceTree = "<group>"; };
 		DED62ABA0AE2EDF1001E80A4 /* Decl.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Decl.cpp; path = AST/Decl.cpp; sourceTree = "<group>"; };
+		DED676D00B6C786700AAD4A3 /* Builtins.def */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; name = Builtins.def; path = clang/AST/Builtins.def; sourceTree = "<group>"; };
+		DED676F90B6C797B00AAD4A3 /* Builtins.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Builtins.h; path = clang/AST/Builtins.h; sourceTree = "<group>"; };
+		DED677C80B6C854100AAD4A3 /* Builtins.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Builtins.cpp; path = AST/Builtins.cpp; sourceTree = "<group>"; };
 		DED7D7310A524295003AD0FB /* Diagnostic.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Diagnostic.h; sourceTree = "<group>"; };
 		DED7D7320A524295003AD0FB /* DiagnosticKinds.def */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = DiagnosticKinds.def; sourceTree = "<group>"; };
 		DED7D7330A524295003AD0FB /* FileManager.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = FileManager.h; sourceTree = "<group>"; };
@@ -317,6 +325,8 @@
 				DEC8D9A30A94346E00353FCA /* AST.h */,
 				DE75ED280B044DC90020CF81 /* ASTContext.h */,
 				DEC8DABF0A94402500353FCA /* ASTStreamer.h */,
+				DED676D00B6C786700AAD4A3 /* Builtins.def */,
+				DED676F90B6C797B00AAD4A3 /* Builtins.h */,
 				DEC8D9900A9433CD00353FCA /* Decl.h */,
 				DE0FCA620A95859D00248FD5 /* Expr.h */,
 				DE3452800AEF1B1800DBC861 /* Stmt.h */,
@@ -332,6 +342,7 @@
 			children = (
 				DE1732FF0B068B700080B521 /* ASTContext.cpp */,
 				DEC8DAAC0A94400300353FCA /* ASTStreamer.cpp */,
+				DED677C80B6C854100AAD4A3 /* Builtins.cpp */,
 				DED62ABA0AE2EDF1001E80A4 /* Decl.cpp */,
 				DE0FCB330A9C21F100248FD5 /* Expr.cpp */,
 				DE3452400AEF1A2D00DBC861 /* Stmt.cpp */,
@@ -507,6 +518,7 @@
 				DE1733000B068B700080B521 /* ASTContext.cpp in Sources */,
 				DE17336E0B068DC20080B521 /* DeclSpec.cpp in Sources */,
 				DE1737A90B0847BC0080B521 /* SemaType.cpp in Sources */,
+				DED677C90B6C854100AAD4A3 /* Builtins.cpp in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};

Added: cfe/cfe/trunk/include/clang/AST/Builtins.def
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/AST/Builtins.def?rev=39327&view=auto

==============================================================================
--- cfe/cfe/trunk/include/clang/AST/Builtins.def (added)
+++ cfe/cfe/trunk/include/clang/AST/Builtins.def Wed Jul 11 11:43:08 2007
@@ -0,0 +1,52 @@
+//===--- Builtins.def - Builtin function info database ----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the standard builtin function database.  Users of this file
+// must define the BUILTIN macro to make use of this information.
+//
+//===----------------------------------------------------------------------===//
+
+// FIXME: this needs to be the full list supported by GCC.  Right now, I'm just
+// adding stuff on demand.
+//
+// FIXME: This should really be a .td file, but that requires modifying tblgen.
+// Perhaps tblgen should have plugins.
+
+// The first value provided to the macro specifies the function name of the
+// builtin, and results in a clang::builtin::BIXX enum value for XX.
+
+// The second value provided to the macro specifies the type of the function
+// (result value, then each argument) as follows:
+//  v -> void
+//  c -> char
+//  s -> short
+//  i -> int
+//  f -> float
+//  d -> double
+//  . -> "...".  This may only occur at the end of the function list.
+//
+// Types maybe prefixed with the following modifiers:
+//  L  -> long (e.g. Li for 'long int')
+//  LL -> long long
+//  S  -> signed
+//  U  -> unsigned
+
+// The third value provided to the macro specifies information about attributes
+// of the function.  Currently we have:
+//  n -> nothrow
+//  c -> const
+
+BUILTIN(__builtin_inf  , "d"   , "nc")
+BUILTIN(__builtin_inff , "f"   , "nc")
+BUILTIN(__builtin_infl , "Ld"  , "nc")
+BUILTIN(__builtin_fabs , "dd"  , "nc")
+BUILTIN(__builtin_fabsf, "ff"  , "nc")
+BUILTIN(__builtin_fabsl, "LdLd", "nc")
+
+#undef BUILTIN

Propchange: cfe/cfe/trunk/include/clang/AST/Builtins.def

------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cfe/cfe/trunk/include/clang/AST/Builtins.def

------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: cfe/cfe/trunk/include/clang/AST/Builtins.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/AST/Builtins.h?rev=39327&view=auto

==============================================================================
--- cfe/cfe/trunk/include/clang/AST/Builtins.h (added)
+++ cfe/cfe/trunk/include/clang/AST/Builtins.h Wed Jul 11 11:43:08 2007
@@ -0,0 +1,52 @@
+//===--- Builtins.h - Builtin function header -------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines enum values for all the target-independent builtin
+// functions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_BUILTINS_H
+#define LLVM_CLANG_AST_BUILTINS_H
+
+namespace llvm {
+namespace clang {
+  class TargetInfo;
+  class IdentifierTable;
+  class ASTContext;
+  class TypeRef;
+
+namespace Builtin {
+enum ID {
+  NotBuiltin  = 0,      // This is not a builtin function.
+#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
+#include "clang/AST/Builtins.def"
+  FirstTargetSpecificBuiltin
+};
+
+struct Info {
+  const char *Name, *Type, *Attributes;
+};
+
+/// Builtin::GetName - Return the identifier name for the specified builtin,
+/// e.g. "__builtin_abs".
+const char *GetName(ID id);
+
+/// InitializeBuiltins - Mark the identifiers for all the builtins with their
+/// appropriate builtin ID # and mark any non-portable builtin identifiers as
+/// such.
+void InitializeBuiltins(IdentifierTable &Table, const TargetInfo &Target);
+
+/// GetBuiltinType - Return the type for the specified builtin.
+TypeRef GetBuiltinType(ID id, ASTContext &Context);
+
+}
+} // end namespace clang
+} // end namespace llvm
+#endif

Propchange: cfe/cfe/trunk/include/clang/AST/Builtins.h

------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cfe/cfe/trunk/include/clang/AST/Builtins.h

------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

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=39327&r1=39326&r2=39327&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def Wed Jul 11 11:43:08 2007
@@ -27,6 +27,9 @@
 DIAG(port_target_macro_use, NOTE,
      "use of a target-specific macro, source is not 'portable'")
 
+DIAG(port_target_builtin_use, NOTE,
+     "use of a target-specific builtin function, source is not 'portable'")
+
 DIAG(port_wchar_t, NOTE,
      "sizeof(wchar_t) varies between targets, source is not 'portable'")
 

Modified: cfe/cfe/trunk/include/clang/Lex/IdentifierTable.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Lex/IdentifierTable.h?rev=39327&r1=39326&r2=39327&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/Lex/IdentifierTable.h (original)
+++ cfe/cfe/trunk/include/clang/Lex/IdentifierTable.h Wed Jul 11 11:43:08 2007
@@ -11,8 +11,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_CLANG_IDENTIFIERTABLE_H
-#define LLVM_CLANG_IDENTIFIERTABLE_H
+#ifndef LLVM_CLANG_LEX_IDENTIFIERTABLE_H
+#define LLVM_CLANG_LEX_IDENTIFIERTABLE_H
 
 #include "clang/Basic/TokenKinds.h"
 #include "llvm/ADT/CStringMap.h"
@@ -33,10 +33,12 @@
   tok::TokenKind TokenID      : 8; // Front-end token ID or tok::identifier.
   tok::PPKeywordKind PPID     : 5; // ID for preprocessor command like #'ifdef'.
   tok::ObjCKeywordKind ObjCID : 5; // ID for objc @ keyword like @'protocol'.
+  unsigned BuiltinID          :12; // ID if this is a builtin (__builtin_inf).
   bool IsExtension            : 1; // True if identifier is a lang extension.
   bool IsPoisoned             : 1; // True if identifier is poisoned.
   bool IsOtherTargetMacro     : 1; // True if ident is macro on another target.
   bool IsCPPOperatorKeyword   : 1; // True if ident is a C++ operator keyword.
+  bool IsNonPortableBuiltin   : 1; // True if builtin varies across targets.
   void *FETokenInfo;               // Managed by the language front-end.
   IdentifierInfo(const IdentifierInfo&);  // NONCOPYABLE.
 public:
@@ -74,6 +76,22 @@
   tok::ObjCKeywordKind getObjCKeywordID() const { return ObjCID; }
   void setObjCKeywordID(tok::ObjCKeywordKind ID) { ObjCID = ID; }
   
+  /// getBuiltinID - Return a value indicating whether this is a builtin
+  /// function.  0 is not-built-in.  1 is builtin-for-some-nonprimary-target.
+  /// 2+ are specific builtin functions.
+  unsigned getBuiltinID() const { return BuiltinID; }
+  void setBuiltinID(unsigned ID) {
+    assert(ID < (1 << 12) && "ID too large for field!");
+    BuiltinID = ID;
+  }
+  
+  /// isNonPortableBuiltin - Return true if this identifier corresponds to a
+  /// builtin on some other target, but isn't one on this target, or if it is on
+  /// the target but not on another, or if it is on both but it differs somehow
+  /// in behavior.
+  bool isNonPortableBuiltin() const { return IsNonPortableBuiltin; }
+  void setNonPortableBuiltin(bool Val) { IsNonPortableBuiltin = Val; }
+  
   /// get/setExtension - Initialize information about whether or not this
   /// language token is an extension.  This controls extension warnings, and is
   /// only valid if a custom token ID is set.





More information about the cfe-commits mailing list