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. llvm-svn: 39327
This commit is contained in:
parent
b6738ec361
commit
9561a0b3e7
|
@ -12,6 +12,7 @@
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "clang/AST/ASTContext.h"
|
#include "clang/AST/ASTContext.h"
|
||||||
|
#include "clang/AST/Builtins.h"
|
||||||
#include "clang/AST/Decl.h"
|
#include "clang/AST/Decl.h"
|
||||||
#include "clang/Lex/Preprocessor.h"
|
#include "clang/Lex/Preprocessor.h"
|
||||||
#include "llvm/ADT/SmallVector.h"
|
#include "llvm/ADT/SmallVector.h"
|
||||||
|
@ -21,6 +22,7 @@ using namespace clang;
|
||||||
ASTContext::ASTContext(Preprocessor &pp)
|
ASTContext::ASTContext(Preprocessor &pp)
|
||||||
: PP(pp), Target(pp.getTargetInfo()) {
|
: PP(pp), Target(pp.getTargetInfo()) {
|
||||||
InitBuiltinTypes();
|
InitBuiltinTypes();
|
||||||
|
Builtin::InitializeBuiltins(PP.getIdentifierTable(), Target);
|
||||||
}
|
}
|
||||||
|
|
||||||
ASTContext::~ASTContext() {
|
ASTContext::~ASTContext() {
|
||||||
|
|
|
@ -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] == '.');
|
||||||
|
}
|
|
@ -74,7 +74,10 @@ public:
|
||||||
virtual DeclTy *ParseStartOfFunctionDef(Scope *S, Declarator &D);
|
virtual DeclTy *ParseStartOfFunctionDef(Scope *S, Declarator &D);
|
||||||
virtual DeclTy *ParseFunctionDefBody(DeclTy *Decl, StmtTy *Body);
|
virtual DeclTy *ParseFunctionDefBody(DeclTy *Decl, StmtTy *Body);
|
||||||
virtual void PopScope(SourceLocation Loc, Scope *S);
|
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 *ParseTypedefDecl(Scope *S, Declarator &D);
|
||||||
TypedefDecl *MergeTypeDefDecl(TypedefDecl *New, Decl *Old);
|
TypedefDecl *MergeTypeDefDecl(TypedefDecl *New, Decl *Old);
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
|
|
||||||
#include "Sema.h"
|
#include "Sema.h"
|
||||||
#include "clang/AST/ASTContext.h"
|
#include "clang/AST/ASTContext.h"
|
||||||
|
#include "clang/AST/Builtins.h"
|
||||||
#include "clang/AST/Decl.h"
|
#include "clang/AST/Decl.h"
|
||||||
#include "clang/AST/Expr.h"
|
#include "clang/AST/Expr.h"
|
||||||
#include "clang/AST/Type.h"
|
#include "clang/AST/Type.h"
|
||||||
|
@ -20,6 +21,7 @@
|
||||||
#include "clang/Parse/Scope.h"
|
#include "clang/Parse/Scope.h"
|
||||||
#include "clang/Lex/IdentifierTable.h"
|
#include "clang/Lex/IdentifierTable.h"
|
||||||
#include "clang/Basic/LangOptions.h"
|
#include "clang/Basic/LangOptions.h"
|
||||||
|
#include "clang/Basic/TargetInfo.h"
|
||||||
#include "llvm/ADT/SmallSet.h"
|
#include "llvm/ADT/SmallSet.h"
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
using namespace clang;
|
using namespace clang;
|
||||||
|
@ -69,7 +71,8 @@ void Sema::PopScope(SourceLocation Loc, Scope *S) {
|
||||||
|
|
||||||
/// LookupScopedDecl - Look up the inner-most declaration in the specified
|
/// LookupScopedDecl - Look up the inner-most declaration in the specified
|
||||||
/// namespace.
|
/// namespace.
|
||||||
Decl *Sema::LookupScopedDecl(IdentifierInfo *II, unsigned NSI) {
|
Decl *Sema::LookupScopedDecl(IdentifierInfo *II, unsigned NSI,
|
||||||
|
SourceLocation IdLoc, Scope *S) {
|
||||||
if (II == 0) return 0;
|
if (II == 0) return 0;
|
||||||
Decl::IdentifierNamespace NS = (Decl::IdentifierNamespace)NSI;
|
Decl::IdentifierNamespace NS = (Decl::IdentifierNamespace)NSI;
|
||||||
|
|
||||||
|
@ -80,10 +83,56 @@ Decl *Sema::LookupScopedDecl(IdentifierInfo *II, unsigned NSI) {
|
||||||
if (D->getIdentifierNamespace() == NS)
|
if (D->getIdentifierNamespace() == NS)
|
||||||
return D;
|
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;
|
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
|
/// 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
|
/// and scope as a previous declaration 'Old'. Figure out how to resolve this
|
||||||
/// situation, merging decls or emitting diagnostics as appropriate.
|
/// situation, merging decls or emitting diagnostics as appropriate.
|
||||||
|
@ -174,7 +223,8 @@ Sema::ParseDeclarator(Scope *S, Declarator &D, ExprTy *Init,
|
||||||
IdentifierInfo *II = D.getIdentifier();
|
IdentifierInfo *II = D.getIdentifier();
|
||||||
|
|
||||||
// See if this is a redefinition of a variable in the same scope.
|
// 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))
|
if (!S->isDeclScope(PrevDecl))
|
||||||
PrevDecl = 0; // If in outer scope, it isn't the same thing.
|
PrevDecl = 0; // If in outer scope, it isn't the same thing.
|
||||||
|
|
||||||
|
@ -239,7 +289,8 @@ Sema::ParseParamDeclarator(DeclaratorChunk &FTI, unsigned ArgNo,
|
||||||
// TODO: CHECK FOR CONFLICTS, multiple decls with same name in one scope.
|
// 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
|
// 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.
|
// 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 @@ Sema::DeclTy *Sema::ParseTag(Scope *S, unsigned TagType, TagKind TK,
|
||||||
// If this is a named struct, check to see if there was a previous forward
|
// If this is a named struct, check to see if there was a previous forward
|
||||||
// declaration or definition.
|
// declaration or definition.
|
||||||
if (TagDecl *PrevDecl =
|
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
|
// 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
|
// the same scope (so that the definition/declaration completes or
|
||||||
|
@ -604,7 +656,7 @@ Sema::DeclTy *Sema::ParseEnumConstant(Scope *S, DeclTy *EnumDeclX,
|
||||||
|
|
||||||
// Verify that there isn't already something declared with this name in this
|
// Verify that there isn't already something declared with this name in this
|
||||||
// scope.
|
// scope.
|
||||||
if (Decl *PrevDecl = LookupScopedDecl(Id, Decl::IDNS_Ordinary)) {
|
if (Decl *PrevDecl = LookupScopedDecl(Id, Decl::IDNS_Ordinary, IdLoc, S)) {
|
||||||
if (S->isDeclScope(PrevDecl)) {
|
if (S->isDeclScope(PrevDecl)) {
|
||||||
if (isa<EnumConstantDecl>(PrevDecl))
|
if (isa<EnumConstantDecl>(PrevDecl))
|
||||||
Diag(IdLoc, diag::err_redefinition_of_enumerator, Id->getName());
|
Diag(IdLoc, diag::err_redefinition_of_enumerator, Id->getName());
|
||||||
|
|
|
@ -247,14 +247,10 @@ Sema::ExprResult Sema::ParseIdentifierExpr(Scope *S, SourceLocation Loc,
|
||||||
IdentifierInfo &II,
|
IdentifierInfo &II,
|
||||||
bool HasTrailingLParen) {
|
bool HasTrailingLParen) {
|
||||||
// Could be enum-constant or decl.
|
// Could be enum-constant or decl.
|
||||||
Decl *D = II.getFETokenInfo<Decl>();
|
Decl *D = LookupScopedDecl(&II, Decl::IDNS_Ordinary, Loc, S);
|
||||||
if (D == 0) {
|
if (D == 0) {
|
||||||
// FIXME: check to see if this is a use of a builtin. By handling builtins
|
// Otherwise, this could be an imlicitly declared function reference (legal
|
||||||
// here, we can avoid having to preload tons of decls for functions.
|
// in C90, extension in C99).
|
||||||
|
|
||||||
|
|
||||||
// Otherwise, this is an imlicitly declared function reference (legal in
|
|
||||||
// C90, extension in C99).
|
|
||||||
if (HasTrailingLParen &&
|
if (HasTrailingLParen &&
|
||||||
// Not in C++.
|
// Not in C++.
|
||||||
!getLangOptions().CPlusPlus) {
|
!getLangOptions().CPlusPlus) {
|
||||||
|
|
|
@ -28,6 +28,7 @@ IdentifierInfo::IdentifierInfo() {
|
||||||
TokenID = tok::identifier;
|
TokenID = tok::identifier;
|
||||||
PPID = tok::pp_not_keyword;
|
PPID = tok::pp_not_keyword;
|
||||||
ObjCID = tok::objc_not_keyword;
|
ObjCID = tok::objc_not_keyword;
|
||||||
|
BuiltinID = 0;
|
||||||
IsExtension = false;
|
IsExtension = false;
|
||||||
IsPoisoned = false;
|
IsPoisoned = false;
|
||||||
IsOtherTargetMacro = false;
|
IsOtherTargetMacro = false;
|
||||||
|
|
|
@ -74,7 +74,10 @@ public:
|
||||||
virtual DeclTy *ParseStartOfFunctionDef(Scope *S, Declarator &D);
|
virtual DeclTy *ParseStartOfFunctionDef(Scope *S, Declarator &D);
|
||||||
virtual DeclTy *ParseFunctionDefBody(DeclTy *Decl, StmtTy *Body);
|
virtual DeclTy *ParseFunctionDefBody(DeclTy *Decl, StmtTy *Body);
|
||||||
virtual void PopScope(SourceLocation Loc, Scope *S);
|
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 *ParseTypedefDecl(Scope *S, Declarator &D);
|
||||||
TypedefDecl *MergeTypeDefDecl(TypedefDecl *New, Decl *Old);
|
TypedefDecl *MergeTypeDefDecl(TypedefDecl *New, Decl *Old);
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
|
|
||||||
#include "Sema.h"
|
#include "Sema.h"
|
||||||
#include "clang/AST/ASTContext.h"
|
#include "clang/AST/ASTContext.h"
|
||||||
|
#include "clang/AST/Builtins.h"
|
||||||
#include "clang/AST/Decl.h"
|
#include "clang/AST/Decl.h"
|
||||||
#include "clang/AST/Expr.h"
|
#include "clang/AST/Expr.h"
|
||||||
#include "clang/AST/Type.h"
|
#include "clang/AST/Type.h"
|
||||||
|
@ -20,6 +21,7 @@
|
||||||
#include "clang/Parse/Scope.h"
|
#include "clang/Parse/Scope.h"
|
||||||
#include "clang/Lex/IdentifierTable.h"
|
#include "clang/Lex/IdentifierTable.h"
|
||||||
#include "clang/Basic/LangOptions.h"
|
#include "clang/Basic/LangOptions.h"
|
||||||
|
#include "clang/Basic/TargetInfo.h"
|
||||||
#include "llvm/ADT/SmallSet.h"
|
#include "llvm/ADT/SmallSet.h"
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
using namespace clang;
|
using namespace clang;
|
||||||
|
@ -69,7 +71,8 @@ void Sema::PopScope(SourceLocation Loc, Scope *S) {
|
||||||
|
|
||||||
/// LookupScopedDecl - Look up the inner-most declaration in the specified
|
/// LookupScopedDecl - Look up the inner-most declaration in the specified
|
||||||
/// namespace.
|
/// namespace.
|
||||||
Decl *Sema::LookupScopedDecl(IdentifierInfo *II, unsigned NSI) {
|
Decl *Sema::LookupScopedDecl(IdentifierInfo *II, unsigned NSI,
|
||||||
|
SourceLocation IdLoc, Scope *S) {
|
||||||
if (II == 0) return 0;
|
if (II == 0) return 0;
|
||||||
Decl::IdentifierNamespace NS = (Decl::IdentifierNamespace)NSI;
|
Decl::IdentifierNamespace NS = (Decl::IdentifierNamespace)NSI;
|
||||||
|
|
||||||
|
@ -80,10 +83,56 @@ Decl *Sema::LookupScopedDecl(IdentifierInfo *II, unsigned NSI) {
|
||||||
if (D->getIdentifierNamespace() == NS)
|
if (D->getIdentifierNamespace() == NS)
|
||||||
return D;
|
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;
|
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
|
/// 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
|
/// and scope as a previous declaration 'Old'. Figure out how to resolve this
|
||||||
/// situation, merging decls or emitting diagnostics as appropriate.
|
/// situation, merging decls or emitting diagnostics as appropriate.
|
||||||
|
@ -174,7 +223,8 @@ Sema::ParseDeclarator(Scope *S, Declarator &D, ExprTy *Init,
|
||||||
IdentifierInfo *II = D.getIdentifier();
|
IdentifierInfo *II = D.getIdentifier();
|
||||||
|
|
||||||
// See if this is a redefinition of a variable in the same scope.
|
// 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))
|
if (!S->isDeclScope(PrevDecl))
|
||||||
PrevDecl = 0; // If in outer scope, it isn't the same thing.
|
PrevDecl = 0; // If in outer scope, it isn't the same thing.
|
||||||
|
|
||||||
|
@ -239,7 +289,8 @@ Sema::ParseParamDeclarator(DeclaratorChunk &FTI, unsigned ArgNo,
|
||||||
// TODO: CHECK FOR CONFLICTS, multiple decls with same name in one scope.
|
// 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
|
// 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.
|
// 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 @@ Sema::DeclTy *Sema::ParseTag(Scope *S, unsigned TagType, TagKind TK,
|
||||||
// If this is a named struct, check to see if there was a previous forward
|
// If this is a named struct, check to see if there was a previous forward
|
||||||
// declaration or definition.
|
// declaration or definition.
|
||||||
if (TagDecl *PrevDecl =
|
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
|
// 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
|
// the same scope (so that the definition/declaration completes or
|
||||||
|
@ -604,7 +656,7 @@ Sema::DeclTy *Sema::ParseEnumConstant(Scope *S, DeclTy *EnumDeclX,
|
||||||
|
|
||||||
// Verify that there isn't already something declared with this name in this
|
// Verify that there isn't already something declared with this name in this
|
||||||
// scope.
|
// scope.
|
||||||
if (Decl *PrevDecl = LookupScopedDecl(Id, Decl::IDNS_Ordinary)) {
|
if (Decl *PrevDecl = LookupScopedDecl(Id, Decl::IDNS_Ordinary, IdLoc, S)) {
|
||||||
if (S->isDeclScope(PrevDecl)) {
|
if (S->isDeclScope(PrevDecl)) {
|
||||||
if (isa<EnumConstantDecl>(PrevDecl))
|
if (isa<EnumConstantDecl>(PrevDecl))
|
||||||
Diag(IdLoc, diag::err_redefinition_of_enumerator, Id->getName());
|
Diag(IdLoc, diag::err_redefinition_of_enumerator, Id->getName());
|
||||||
|
|
|
@ -247,14 +247,10 @@ Sema::ExprResult Sema::ParseIdentifierExpr(Scope *S, SourceLocation Loc,
|
||||||
IdentifierInfo &II,
|
IdentifierInfo &II,
|
||||||
bool HasTrailingLParen) {
|
bool HasTrailingLParen) {
|
||||||
// Could be enum-constant or decl.
|
// Could be enum-constant or decl.
|
||||||
Decl *D = II.getFETokenInfo<Decl>();
|
Decl *D = LookupScopedDecl(&II, Decl::IDNS_Ordinary, Loc, S);
|
||||||
if (D == 0) {
|
if (D == 0) {
|
||||||
// FIXME: check to see if this is a use of a builtin. By handling builtins
|
// Otherwise, this could be an imlicitly declared function reference (legal
|
||||||
// here, we can avoid having to preload tons of decls for functions.
|
// in C90, extension in C99).
|
||||||
|
|
||||||
|
|
||||||
// Otherwise, this is an imlicitly declared function reference (legal in
|
|
||||||
// C90, extension in C99).
|
|
||||||
if (HasTrailingLParen &&
|
if (HasTrailingLParen &&
|
||||||
// Not in C++.
|
// Not in C++.
|
||||||
!getLangOptions().CPlusPlus) {
|
!getLangOptions().CPlusPlus) {
|
||||||
|
|
|
@ -57,6 +57,9 @@
|
||||||
DED626C90AE0C065001E80A4 /* TargetInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DED626C80AE0C065001E80A4 /* TargetInfo.cpp */; };
|
DED626C90AE0C065001E80A4 /* TargetInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DED626C80AE0C065001E80A4 /* TargetInfo.cpp */; };
|
||||||
DED627030AE0C51D001E80A4 /* Targets.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DED627020AE0C51D001E80A4 /* Targets.cpp */; };
|
DED627030AE0C51D001E80A4 /* Targets.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DED627020AE0C51D001E80A4 /* Targets.cpp */; };
|
||||||
DED62ABB0AE2EDF1001E80A4 /* Decl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DED62ABA0AE2EDF1001E80A4 /* Decl.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 */; };
|
DED7D7410A524295003AD0FB /* Diagnostic.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DED7D7310A524295003AD0FB /* Diagnostic.h */; };
|
||||||
DED7D7420A524295003AD0FB /* DiagnosticKinds.def in CopyFiles */ = {isa = PBXBuildFile; fileRef = DED7D7320A524295003AD0FB /* DiagnosticKinds.def */; };
|
DED7D7420A524295003AD0FB /* DiagnosticKinds.def in CopyFiles */ = {isa = PBXBuildFile; fileRef = DED7D7320A524295003AD0FB /* DiagnosticKinds.def */; };
|
||||||
DED7D7430A524295003AD0FB /* FileManager.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DED7D7330A524295003AD0FB /* FileManager.h */; };
|
DED7D7430A524295003AD0FB /* FileManager.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DED7D7330A524295003AD0FB /* FileManager.h */; };
|
||||||
|
@ -134,6 +137,8 @@
|
||||||
DE75ED290B044DC90020CF81 /* ASTContext.h in CopyFiles */,
|
DE75ED290B044DC90020CF81 /* ASTContext.h in CopyFiles */,
|
||||||
DE1733700B068DC60080B521 /* DeclSpec.h in CopyFiles */,
|
DE1733700B068DC60080B521 /* DeclSpec.h in CopyFiles */,
|
||||||
DE01DA490B12ADA300AC22CE /* PPCallbacks.h in CopyFiles */,
|
DE01DA490B12ADA300AC22CE /* PPCallbacks.h in CopyFiles */,
|
||||||
|
DED676D10B6C786700AAD4A3 /* Builtins.def in CopyFiles */,
|
||||||
|
DED676FA0B6C797B00AAD4A3 /* Builtins.h in CopyFiles */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 1;
|
runOnlyForDeploymentPostprocessing = 1;
|
||||||
};
|
};
|
||||||
|
@ -191,6 +196,9 @@
|
||||||
DED626C80AE0C065001E80A4 /* TargetInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = TargetInfo.cpp; sourceTree = "<group>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
DED7D7330A524295003AD0FB /* FileManager.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = FileManager.h; sourceTree = "<group>"; };
|
||||||
|
@ -317,6 +325,8 @@
|
||||||
DEC8D9A30A94346E00353FCA /* AST.h */,
|
DEC8D9A30A94346E00353FCA /* AST.h */,
|
||||||
DE75ED280B044DC90020CF81 /* ASTContext.h */,
|
DE75ED280B044DC90020CF81 /* ASTContext.h */,
|
||||||
DEC8DABF0A94402500353FCA /* ASTStreamer.h */,
|
DEC8DABF0A94402500353FCA /* ASTStreamer.h */,
|
||||||
|
DED676D00B6C786700AAD4A3 /* Builtins.def */,
|
||||||
|
DED676F90B6C797B00AAD4A3 /* Builtins.h */,
|
||||||
DEC8D9900A9433CD00353FCA /* Decl.h */,
|
DEC8D9900A9433CD00353FCA /* Decl.h */,
|
||||||
DE0FCA620A95859D00248FD5 /* Expr.h */,
|
DE0FCA620A95859D00248FD5 /* Expr.h */,
|
||||||
DE3452800AEF1B1800DBC861 /* Stmt.h */,
|
DE3452800AEF1B1800DBC861 /* Stmt.h */,
|
||||||
|
@ -332,6 +342,7 @@
|
||||||
children = (
|
children = (
|
||||||
DE1732FF0B068B700080B521 /* ASTContext.cpp */,
|
DE1732FF0B068B700080B521 /* ASTContext.cpp */,
|
||||||
DEC8DAAC0A94400300353FCA /* ASTStreamer.cpp */,
|
DEC8DAAC0A94400300353FCA /* ASTStreamer.cpp */,
|
||||||
|
DED677C80B6C854100AAD4A3 /* Builtins.cpp */,
|
||||||
DED62ABA0AE2EDF1001E80A4 /* Decl.cpp */,
|
DED62ABA0AE2EDF1001E80A4 /* Decl.cpp */,
|
||||||
DE0FCB330A9C21F100248FD5 /* Expr.cpp */,
|
DE0FCB330A9C21F100248FD5 /* Expr.cpp */,
|
||||||
DE3452400AEF1A2D00DBC861 /* Stmt.cpp */,
|
DE3452400AEF1A2D00DBC861 /* Stmt.cpp */,
|
||||||
|
@ -507,6 +518,7 @@
|
||||||
DE1733000B068B700080B521 /* ASTContext.cpp in Sources */,
|
DE1733000B068B700080B521 /* ASTContext.cpp in Sources */,
|
||||||
DE17336E0B068DC20080B521 /* DeclSpec.cpp in Sources */,
|
DE17336E0B068DC20080B521 /* DeclSpec.cpp in Sources */,
|
||||||
DE1737A90B0847BC0080B521 /* SemaType.cpp in Sources */,
|
DE1737A90B0847BC0080B521 /* SemaType.cpp in Sources */,
|
||||||
|
DED677C90B6C854100AAD4A3 /* Builtins.cpp in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -27,6 +27,9 @@
|
||||||
DIAG(port_target_macro_use, NOTE,
|
DIAG(port_target_macro_use, NOTE,
|
||||||
"use of a target-specific macro, source is not 'portable'")
|
"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,
|
DIAG(port_wchar_t, NOTE,
|
||||||
"sizeof(wchar_t) varies between targets, source is not 'portable'")
|
"sizeof(wchar_t) varies between targets, source is not 'portable'")
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,8 @@
|
||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#ifndef LLVM_CLANG_IDENTIFIERTABLE_H
|
#ifndef LLVM_CLANG_LEX_IDENTIFIERTABLE_H
|
||||||
#define LLVM_CLANG_IDENTIFIERTABLE_H
|
#define LLVM_CLANG_LEX_IDENTIFIERTABLE_H
|
||||||
|
|
||||||
#include "clang/Basic/TokenKinds.h"
|
#include "clang/Basic/TokenKinds.h"
|
||||||
#include "llvm/ADT/CStringMap.h"
|
#include "llvm/ADT/CStringMap.h"
|
||||||
|
@ -33,10 +33,12 @@ class IdentifierInfo {
|
||||||
tok::TokenKind TokenID : 8; // Front-end token ID or tok::identifier.
|
tok::TokenKind TokenID : 8; // Front-end token ID or tok::identifier.
|
||||||
tok::PPKeywordKind PPID : 5; // ID for preprocessor command like #'ifdef'.
|
tok::PPKeywordKind PPID : 5; // ID for preprocessor command like #'ifdef'.
|
||||||
tok::ObjCKeywordKind ObjCID : 5; // ID for objc @ keyword like @'protocol'.
|
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 IsExtension : 1; // True if identifier is a lang extension.
|
||||||
bool IsPoisoned : 1; // True if identifier is poisoned.
|
bool IsPoisoned : 1; // True if identifier is poisoned.
|
||||||
bool IsOtherTargetMacro : 1; // True if ident is macro on another target.
|
bool IsOtherTargetMacro : 1; // True if ident is macro on another target.
|
||||||
bool IsCPPOperatorKeyword : 1; // True if ident is a C++ operator keyword.
|
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.
|
void *FETokenInfo; // Managed by the language front-end.
|
||||||
IdentifierInfo(const IdentifierInfo&); // NONCOPYABLE.
|
IdentifierInfo(const IdentifierInfo&); // NONCOPYABLE.
|
||||||
public:
|
public:
|
||||||
|
@ -74,6 +76,22 @@ public:
|
||||||
tok::ObjCKeywordKind getObjCKeywordID() const { return ObjCID; }
|
tok::ObjCKeywordKind getObjCKeywordID() const { return ObjCID; }
|
||||||
void setObjCKeywordID(tok::ObjCKeywordKind ID) { ObjCID = ID; }
|
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
|
/// get/setExtension - Initialize information about whether or not this
|
||||||
/// language token is an extension. This controls extension warnings, and is
|
/// language token is an extension. This controls extension warnings, and is
|
||||||
/// only valid if a custom token ID is set.
|
/// only valid if a custom token ID is set.
|
||||||
|
|
Loading…
Reference in New Issue