[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